use of org.onosproject.net.PortNumber in project onos by opennetworkinglab.
the class Ofdpa2GroupHandler method prepareL2InterfaceGroup.
private List<GroupInfo> prepareL2InterfaceGroup(NextObjective nextObj, VlanId assignedVlan) {
ImmutableList.Builder<GroupInfo> groupInfoBuilder = ImmutableList.builder();
// break up broadcast next objective to multiple groups
Collection<TrafficTreatment> buckets = nextObj.nextTreatments().stream().filter(nt -> nt.type() == NextTreatment.Type.TREATMENT).map(nt -> ((DefaultNextTreatment) nt).treatment()).collect(Collectors.toSet());
// Each treatment is converted to an L2 interface group
for (TrafficTreatment treatment : buckets) {
TrafficTreatment.Builder newTreatment = DefaultTrafficTreatment.builder();
PortNumber portNum = null;
VlanId egressVlan = null;
// ensure that the only allowed treatments are pop-vlan and output
for (Instruction ins : treatment.allInstructions()) {
if (ins.type() == Instruction.Type.L2MODIFICATION) {
L2ModificationInstruction l2ins = (L2ModificationInstruction) ins;
switch(l2ins.subtype()) {
case VLAN_POP:
newTreatment.add(l2ins);
break;
case VLAN_ID:
egressVlan = ((L2ModificationInstruction.ModVlanIdInstruction) l2ins).vlanId();
break;
default:
log.debug("action {} not permitted for broadcast nextObj", l2ins.subtype());
break;
}
} else if (ins.type() == Instruction.Type.OUTPUT) {
portNum = ((Instructions.OutputInstruction) ins).port();
newTreatment.add(ins);
} else {
log.debug("TrafficTreatment of type {} not permitted in " + " broadcast nextObjective", ins.type());
}
}
if (portNum == null) {
log.debug("Can't find output port for the bucket {}.", treatment);
continue;
}
// assemble info for l2 interface group
VlanId l2InterfaceGroupVlan = (egressVlan != null && !assignedVlan.equals(egressVlan)) ? egressVlan : assignedVlan;
int l2gk = l2InterfaceGroupKey(deviceId, l2InterfaceGroupVlan, portNum.toLong());
final GroupKey l2InterfaceGroupKey = new DefaultGroupKey(appKryo.serialize(l2gk));
int l2InterfaceGroupId = L2_INTERFACE_TYPE | ((l2InterfaceGroupVlan.toShort() & THREE_NIBBLE_MASK) << PORT_LEN) | ((int) portNum.toLong() & FOUR_NIBBLE_MASK);
GroupBucket l2InterfaceGroupBucket = DefaultGroupBucket.createIndirectGroupBucket(newTreatment.build());
GroupDescription l2InterfaceGroupDescription = new DefaultGroupDescription(deviceId, GroupDescription.Type.INDIRECT, new GroupBuckets(Collections.singletonList(l2InterfaceGroupBucket)), l2InterfaceGroupKey, l2InterfaceGroupId, nextObj.appId());
log.debug("Trying L2-Interface: device:{} gid:{} gkey:{} nextid:{}", deviceId, Integer.toHexString(l2InterfaceGroupId), l2InterfaceGroupKey, nextObj.id());
groupInfoBuilder.add(new GroupInfo(l2InterfaceGroupDescription, l2InterfaceGroupDescription));
}
return groupInfoBuilder.build();
}
use of org.onosproject.net.PortNumber in project onos by opennetworkinglab.
the class Ofdpa2Pipeline method processEthDstFilter.
/**
* Allows routed packets with correct destination MAC to be directed
* to unicast routing table, multicast routing table or MPLS forwarding table.
*
* @param portCriterion port on device for which this filter is programmed
* @param ethCriterion dstMac of device for which is filter is programmed
* @param vidCriterion vlan assigned to port, or NONE for untagged
* @param assignedVlan assigned vlan-id for untagged packets
* @param unicastMac some switches require a unicast TMAC flow to be programmed before multicast
* TMAC flow. This MAC address will be used for the unicast TMAC flow.
* This is unused if the filtering objective is a unicast.
* @param applicationId for application programming this filter
* @return stages of flow rules for port-vlan filters
*/
protected List<List<FlowRule>> processEthDstFilter(PortCriterion portCriterion, EthCriterion ethCriterion, VlanIdCriterion vidCriterion, VlanId assignedVlan, MacAddress unicastMac, ApplicationId applicationId) {
// Consider PortNumber.ANY as wildcard. Match ETH_DST only
if (portCriterion != null && PortNumber.ANY.equals(portCriterion.port())) {
return processEthDstOnlyFilter(ethCriterion, applicationId);
}
// Multicast MAC
if (ethCriterion.mask() != null) {
return processMcastEthDstFilter(ethCriterion, assignedVlan, unicastMac, applicationId);
}
// handling untagged packets via assigned VLAN
if (vidCriterion != null && vidCriterion.vlanId() == VlanId.NONE) {
vidCriterion = (VlanIdCriterion) Criteria.matchVlanId(assignedVlan);
}
List<FlowRule> rules = new ArrayList<>();
OfdpaMatchVlanVid ofdpaMatchVlanVid = null;
if (vidCriterion != null && requireVlanExtensions()) {
ofdpaMatchVlanVid = new OfdpaMatchVlanVid(vidCriterion.vlanId());
}
// ofdpa cannot match on ALL portnumber, so we need to use separate
// rules for each port.
List<PortNumber> portnums = new ArrayList<>();
if (portCriterion != null) {
if (PortNumber.ALL.equals(portCriterion.port())) {
for (Port port : deviceService.getPorts(deviceId)) {
if (port.number().toLong() > 0 && port.number().toLong() < OFPP_MAX) {
portnums.add(port.number());
}
}
} else {
portnums.add(portCriterion.port());
}
for (PortNumber pnum : portnums) {
rules.add(buildTmacRuleForIpv4(ethCriterion, vidCriterion, ofdpaMatchVlanVid, applicationId, pnum));
rules.add(buildTmacRuleForMpls(ethCriterion, vidCriterion, ofdpaMatchVlanVid, applicationId, pnum));
rules.add(buildTmacRuleForIpv6(ethCriterion, vidCriterion, ofdpaMatchVlanVid, applicationId, pnum));
}
} else {
rules.add(buildTmacRuleForIpv4(ethCriterion, vidCriterion, ofdpaMatchVlanVid, applicationId, null));
rules.add(buildTmacRuleForMpls(ethCriterion, vidCriterion, ofdpaMatchVlanVid, applicationId, null));
rules.add(buildTmacRuleForIpv6(ethCriterion, vidCriterion, ofdpaMatchVlanVid, applicationId, null));
}
return ImmutableList.of(rules);
}
use of org.onosproject.net.PortNumber in project onos by opennetworkinglab.
the class OfdpaGroupHandlerUtility method getExistingOutputPorts.
/**
* Returns the set of existing output ports in the group represented by
* allActiveKeys.
*
* @param allActiveKeys list of group key chain
* @param groupService the group service to get group information
* @param deviceId the device id to get group
* @return a set of output port from the list of group key chain
*/
public static Set<PortNumber> getExistingOutputPorts(List<Deque<GroupKey>> allActiveKeys, GroupService groupService, DeviceId deviceId) {
Set<PortNumber> existingPorts = Sets.newHashSet();
allActiveKeys.forEach(keyChain -> {
GroupKey ifaceGroupKey = keyChain.peekLast();
Group ifaceGroup = groupService.getGroup(deviceId, ifaceGroupKey);
if (ifaceGroup != null && !ifaceGroup.buckets().buckets().isEmpty()) {
ifaceGroup.buckets().buckets().forEach(bucket -> {
PortNumber portNumber = readOutPortFromTreatment(bucket.treatment());
if (portNumber != null) {
existingPorts.add(portNumber);
}
});
}
});
return existingPorts;
}
use of org.onosproject.net.PortNumber in project onos by opennetworkinglab.
the class OvsOfdpaPipeline method processEgress.
/**
* In the OF-DPA 2.0 pipeline, egress forwarding objectives go to the
* egress tables.
* @param fwd the forwarding objective of type 'egress'
* @return a collection of flow rules to be sent to the switch. An empty
* collection may be returned if there is a problem in processing
* the flow rule
*/
@Override
protected Collection<FlowRule> processEgress(ForwardingObjective fwd) {
log.debug("Processing egress forwarding objective:{} in dev:{}", fwd, deviceId);
List<FlowRule> rules = new ArrayList<>();
// Build selector
TrafficSelector.Builder sb = DefaultTrafficSelector.builder();
VlanIdCriterion vlanIdCriterion = (VlanIdCriterion) fwd.selector().getCriterion(Criterion.Type.VLAN_VID);
if (vlanIdCriterion == null) {
log.error("Egress forwarding objective:{} must include vlanId", fwd.id());
fail(fwd, ObjectiveError.BADPARAMS);
return rules;
}
Optional<Instruction> outInstr = fwd.treatment().allInstructions().stream().filter(instruction -> instruction instanceof Instructions.OutputInstruction).findFirst();
if (!outInstr.isPresent()) {
log.error("Egress forwarding objective:{} must include output port", fwd.id());
fail(fwd, ObjectiveError.BADPARAMS);
return rules;
}
PortNumber portNumber = ((Instructions.OutputInstruction) outInstr.get()).port();
sb.matchVlanId(vlanIdCriterion.vlanId());
OfdpaMatchActsetOutput actsetOutput = new OfdpaMatchActsetOutput(portNumber);
sb.extension(actsetOutput, deviceId);
// Build a flow rule for Egress VLAN Flow table
TrafficTreatment.Builder tb = DefaultTrafficTreatment.builder();
tb.transition(UNICAST_ROUTING_TABLE_1);
if (fwd.treatment() != null) {
for (Instruction instr : fwd.treatment().allInstructions()) {
if (instr instanceof L2ModificationInstruction && ((L2ModificationInstruction) instr).subtype() == L2ModificationInstruction.L2SubType.VLAN_ID) {
tb.immediate().add(instr);
}
if (instr instanceof L2ModificationInstruction && ((L2ModificationInstruction) instr).subtype() == L2ModificationInstruction.L2SubType.VLAN_PUSH) {
EthType ethType = ((L2ModificationInstruction.ModVlanHeaderInstruction) instr).ethernetType();
tb.immediate().pushVlan(ethType);
}
}
}
FlowRule.Builder ruleBuilder = DefaultFlowRule.builder().fromApp(fwd.appId()).withPriority(fwd.priority()).forDevice(deviceId).withSelector(sb.build()).withTreatment(tb.build()).makePermanent().forTable(EGRESS_VLAN_FLOW_TABLE_IN_INGRESS);
rules.add(ruleBuilder.build());
return rules;
}
use of org.onosproject.net.PortNumber in project onos by opennetworkinglab.
the class OvsOfdpaPipeline method processDoubleVlanIdFilter.
/**
* Internal implementation of processDoubleVlanIdFilter.
*
* @param portCriterion port on device for which this filter is programmed
* @param innerVidCriterion inner vlan
* @param outerVidCriterion outer vlan
* @param popVlan true if outer vlan header needs to be removed
* @param applicationId for application programming this filter
* @return flow rules for port-vlan filters
*/
private List<FlowRule> processDoubleVlanIdFilter(PortCriterion portCriterion, VlanIdCriterion innerVidCriterion, VlanIdCriterion outerVidCriterion, boolean popVlan, ApplicationId applicationId) {
List<FlowRule> rules = new ArrayList<>();
TrafficSelector.Builder outerSelector = DefaultTrafficSelector.builder();
TrafficTreatment.Builder outerTreatment = DefaultTrafficTreatment.builder();
TrafficSelector.Builder innerSelector = DefaultTrafficSelector.builder();
TrafficTreatment.Builder innerTreatment = DefaultTrafficTreatment.builder();
VlanId outerVlanId = outerVidCriterion.vlanId();
VlanId innerVlanId = innerVidCriterion.vlanId();
PortNumber portNumber = portCriterion.port();
// Check arguments
if (PortNumber.ALL.equals(portNumber) || outerVlanId.equals(VlanId.NONE) || innerVlanId.equals(VlanId.NONE)) {
log.warn("Incomplete Filtering Objective. " + "VLAN Table cannot be programmed for {}", deviceId);
return ImmutableList.of();
} else {
outerSelector.matchInPort(portNumber);
innerSelector.matchInPort(portNumber);
outerTreatment.transition(VLAN_1_TABLE);
innerTreatment.transition(TMAC_TABLE);
outerTreatment.writeMetadata(outerVlanId.toShort(), 0xFFF);
outerSelector.matchVlanId(outerVlanId);
innerSelector.matchVlanId(innerVlanId);
// force recompilation
// FIXME might be issue due tu /fff mask
innerSelector.matchMetadata(outerVlanId.toShort());
if (popVlan) {
outerTreatment.popVlan();
}
}
// NOTE: for double-tagged packets, restore original outer vlan
// before sending it to the controller.
GroupKey groupKey = popVlanPuntGroupKey();
Group group = groupService.getGroup(deviceId, groupKey);
if (group != null) {
// push outer vlan and send to controller
TrafficSelector.Builder sbuilder = DefaultTrafficSelector.builder().matchInPort(portNumber).matchVlanId(innerVlanId);
Host host = handler().get(HostService.class).getConnectedHosts(ConnectPoint.deviceConnectPoint(deviceId + "/" + portNumber.toLong())).stream().filter(h -> h.vlan().equals(outerVlanId)).findFirst().orElse(null);
EthType vlanType = EthType.EtherType.VLAN.ethType();
if (host != null) {
vlanType = host.tpid();
}
TrafficTreatment.Builder tbuilder = DefaultTrafficTreatment.builder().pushVlan(vlanType).setVlanId(outerVlanId).punt();
rules.add(DefaultFlowRule.builder().forDevice(deviceId).withSelector(sbuilder.build()).withTreatment(tbuilder.build()).withPriority(PacketPriority.CONTROL.priorityValue()).fromApp(driverId).makePermanent().forTable(PUNT_TABLE).build());
} else {
log.info("popVlanPuntGroup not found in dev:{}", deviceId);
return Collections.emptyList();
}
FlowRule outerRule = DefaultFlowRule.builder().forDevice(deviceId).withSelector(outerSelector.build()).withTreatment(outerTreatment.build()).withPriority(DEFAULT_PRIORITY).fromApp(applicationId).makePermanent().forTable(VLAN_TABLE).build();
FlowRule innerRule = DefaultFlowRule.builder().forDevice(deviceId).withSelector(innerSelector.build()).withTreatment(innerTreatment.build()).withPriority(DEFAULT_PRIORITY).fromApp(applicationId).makePermanent().forTable(VLAN_1_TABLE).build();
rules.add(outerRule);
rules.add(innerRule);
return rules;
}
Aggregations