use of org.onosproject.driver.extensions.OfdpaMatchVlanVid 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.driver.extensions.OfdpaMatchVlanVid in project onos by opennetworkinglab.
the class Ofdpa2Pipeline method processEthDstSpecific.
/**
* Handles forwarding rules to the L2 bridging table. Flow actions are not
* allowed in the bridging table - instead we use L2 Interface group or
* L2 flood group
*
* @param fwd the forwarding objective
* @return A collection of flow rules, or an empty set
*/
protected Collection<FlowRule> processEthDstSpecific(ForwardingObjective fwd) {
List<FlowRule> rules = new ArrayList<>();
// Build filtered selector
TrafficSelector selector = fwd.selector();
EthCriterion ethCriterion = (EthCriterion) selector.getCriterion(Criterion.Type.ETH_DST);
VlanIdCriterion vlanIdCriterion = (VlanIdCriterion) selector.getCriterion(Criterion.Type.VLAN_VID);
if (vlanIdCriterion == null) {
log.warn("Forwarding objective for bridging requires vlan. Not " + "installing fwd:{} in dev:{}", fwd.id(), deviceId);
fail(fwd, ObjectiveError.BADPARAMS);
return Collections.emptySet();
}
TrafficSelector.Builder filteredSelectorBuilder = DefaultTrafficSelector.builder();
if (!ethCriterion.mac().equals(NONE) && !ethCriterion.mac().equals(BROADCAST)) {
filteredSelectorBuilder.matchEthDst(ethCriterion.mac());
log.debug("processing L2 forwarding objective:{} -> next:{} in dev:{}", fwd.id(), fwd.nextId(), deviceId);
} else {
// Use wildcard DST_MAC if the MacAddress is None or Broadcast
log.debug("processing L2 Broadcast forwarding objective:{} -> next:{} " + "in dev:{} for vlan:{}", fwd.id(), fwd.nextId(), deviceId, vlanIdCriterion.vlanId());
}
if (requireVlanExtensions()) {
OfdpaMatchVlanVid ofdpaMatchVlanVid = new OfdpaMatchVlanVid(vlanIdCriterion.vlanId());
filteredSelectorBuilder.extension(ofdpaMatchVlanVid, deviceId);
} else {
filteredSelectorBuilder.matchVlanId(vlanIdCriterion.vlanId());
}
TrafficSelector filteredSelector = filteredSelectorBuilder.build();
if (fwd.treatment() != null) {
log.warn("Ignoring traffic treatment in fwd rule {} meant for L2 table" + "for dev:{}. Expecting only nextId", fwd.id(), deviceId);
}
TrafficTreatment.Builder treatmentBuilder = DefaultTrafficTreatment.builder();
if (fwd.nextId() != null) {
NextGroup next = getGroupForNextObjective(fwd.nextId());
if (next != null) {
List<Deque<GroupKey>> gkeys = appKryo.deserialize(next.data());
// we only need the top level group's key to point the flow to it
Group group = groupService.getGroup(deviceId, gkeys.get(0).peekFirst());
if (group != null) {
treatmentBuilder.deferred().group(group.id());
} else {
log.warn("Group with key:{} for next-id:{} not found in dev:{}", gkeys.get(0).peekFirst(), fwd.nextId(), deviceId);
fail(fwd, ObjectiveError.GROUPMISSING);
return Collections.emptySet();
}
}
}
treatmentBuilder.immediate().transition(ACL_TABLE);
TrafficTreatment filteredTreatment = treatmentBuilder.build();
// Build bridging table entries
FlowRule.Builder flowRuleBuilder = DefaultFlowRule.builder();
flowRuleBuilder.fromApp(fwd.appId()).withPriority(fwd.priority()).forDevice(deviceId).withSelector(filteredSelector).withTreatment(filteredTreatment).forTable(BRIDGING_TABLE);
if (fwd.permanent()) {
flowRuleBuilder.makePermanent();
} else {
flowRuleBuilder.makeTemporary(fwd.timeout());
}
rules.add(flowRuleBuilder.build());
return rules;
}
use of org.onosproject.driver.extensions.OfdpaMatchVlanVid in project onos by opennetworkinglab.
the class Ofdpa2Pipeline method processVersatile.
/**
* In the OF-DPA 2.0 pipeline, versatile forwarding objectives go to the
* ACL table.
* @param fwd the forwarding objective of type 'versatile'
* @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
*/
protected Collection<FlowRule> processVersatile(ForwardingObjective fwd) {
log.debug("Processing versatile forwarding objective:{} in dev:{}", fwd.id(), deviceId);
List<FlowRule> flowRules = new ArrayList<>();
final AtomicBoolean ethTypeUsed = new AtomicBoolean(false);
if (fwd.nextId() == null && fwd.treatment() == null) {
log.error("Forwarding objective {} from {} must contain " + "nextId or Treatment", fwd.selector(), fwd.appId());
fail(fwd, ObjectiveError.BADPARAMS);
return Collections.emptySet();
}
TrafficSelector.Builder sbuilder = DefaultTrafficSelector.builder();
fwd.selector().criteria().forEach(criterion -> {
if (criterion instanceof VlanIdCriterion) {
VlanId vlanId = ((VlanIdCriterion) criterion).vlanId();
// match untagged packets this way in the ACL table.
if (vlanId.equals(VlanId.NONE)) {
return;
}
if (requireVlanExtensions()) {
OfdpaMatchVlanVid ofdpaMatchVlanVid = new OfdpaMatchVlanVid(vlanId);
sbuilder.extension(ofdpaMatchVlanVid, deviceId);
} else {
sbuilder.matchVlanId(vlanId);
}
} else if (criterion instanceof Icmpv6TypeCriterion) {
byte icmpv6Type = (byte) ((Icmpv6TypeCriterion) criterion).icmpv6Type();
sbuilder.matchIcmpv6Type(icmpv6Type);
} else if (criterion instanceof Icmpv6CodeCriterion) {
byte icmpv6Code = (byte) ((Icmpv6CodeCriterion) criterion).icmpv6Code();
sbuilder.matchIcmpv6Type(icmpv6Code);
} else if (criterion instanceof TcpPortCriterion || criterion instanceof UdpPortCriterion) {
// We need to revisit this if L4 dst port is used for other purpose in the future.
if (!supportIpv6L4Dst() && isIpv6(fwd.selector())) {
switch(criterion.type()) {
case UDP_DST:
case UDP_DST_MASKED:
case TCP_DST:
case TCP_DST_MASKED:
break;
default:
sbuilder.add(criterion);
}
} else {
sbuilder.add(criterion);
}
} else if (criterion instanceof EthTypeCriterion) {
sbuilder.add(criterion);
ethTypeUsed.set(true);
} else {
sbuilder.add(criterion);
}
});
TrafficTreatment.Builder ttBuilder = versatileTreatmentBuilder(fwd);
if (ttBuilder == null) {
return Collections.emptySet();
}
FlowRule.Builder ruleBuilder = DefaultFlowRule.builder().fromApp(fwd.appId()).withPriority(fwd.priority()).forDevice(deviceId).withSelector(sbuilder.build()).withTreatment(ttBuilder.build()).makePermanent().forTable(ACL_TABLE);
flowRules.add(ruleBuilder.build());
if (!ethTypeUsed.get() && requireEthType()) {
log.debug("{} doesn't match on ethType but requireEthType is true, adding complementary ACL flow.", sbuilder.toString());
sbuilder.matchEthType(Ethernet.TYPE_IPV6);
FlowRule.Builder ethTypeRuleBuilder = DefaultFlowRule.builder().fromApp(fwd.appId()).withPriority(fwd.priority()).forDevice(deviceId).withSelector(sbuilder.build()).withTreatment(ttBuilder.build()).makePermanent().forTable(ACL_TABLE);
flowRules.add(ethTypeRuleBuilder.build());
}
return flowRules;
}
use of org.onosproject.driver.extensions.OfdpaMatchVlanVid in project onos by opennetworkinglab.
the class Ofdpa2Pipeline method buildIpv6Selector.
/**
* Helper method to build Ipv6 selector using the selector provided by
* a forwarding objective.
*
* @param builderToUpdate the builder to update
* @param fwd the selector to read
* @return 0 if the update ends correctly. -1 if the matches
* are not yet supported
*/
int buildIpv6Selector(TrafficSelector.Builder builderToUpdate, ForwardingObjective fwd) {
TrafficSelector selector = fwd.selector();
IpPrefix ipv6Dst = ((IPCriterion) selector.getCriterion(Criterion.Type.IPV6_DST)).ip();
if (ipv6Dst.isMulticast()) {
if (ipv6Dst.prefixLength() != IpAddress.INET6_BIT_LENGTH) {
log.warn("Multicast specific forwarding objective can only be /128");
fail(fwd, ObjectiveError.BADPARAMS);
return -1;
}
VlanId assignedVlan = readVlanFromSelector(fwd.meta());
if (assignedVlan == null) {
log.warn("VLAN ID required by multicast specific fwd obj is missing. Abort.");
fail(fwd, ObjectiveError.BADPARAMS);
return -1;
}
if (requireVlanExtensions()) {
OfdpaMatchVlanVid ofdpaMatchVlanVid = new OfdpaMatchVlanVid(assignedVlan);
builderToUpdate.extension(ofdpaMatchVlanVid, deviceId);
} else {
builderToUpdate.matchVlanId(assignedVlan);
}
builderToUpdate.matchEthType(Ethernet.TYPE_IPV6).matchIPv6Dst(ipv6Dst);
log.debug("processing IPv6 multicast specific forwarding objective {} -> next:{}" + " in dev:{}", fwd.id(), fwd.nextId(), deviceId);
} else {
if (ipv6Dst.prefixLength() != 0) {
builderToUpdate.matchIPv6Dst(ipv6Dst);
}
builderToUpdate.matchEthType(Ethernet.TYPE_IPV6);
log.debug("processing IPv6 unicast specific forwarding objective {} -> next:{}" + " in dev:{}", fwd.id(), fwd.nextId(), deviceId);
}
return 0;
}
use of org.onosproject.driver.extensions.OfdpaMatchVlanVid in project onos by opennetworkinglab.
the class Ofdpa2Pipeline method buildIpv4Selector.
private int buildIpv4Selector(TrafficSelector.Builder builderToUpdate, TrafficSelector.Builder extBuilder, ForwardingObjective fwd, boolean allowDefaultRoute) {
TrafficSelector selector = fwd.selector();
IpPrefix ipv4Dst = ((IPCriterion) selector.getCriterion(Criterion.Type.IPV4_DST)).ip();
if (ipv4Dst.isMulticast()) {
if (ipv4Dst.prefixLength() != 32) {
log.warn("Multicast specific forwarding objective can only be /32");
fail(fwd, ObjectiveError.BADPARAMS);
return -1;
}
VlanId assignedVlan = readVlanFromSelector(fwd.meta());
if (assignedVlan == null) {
log.warn("VLAN ID required by multicast specific fwd obj is missing. Abort.");
fail(fwd, ObjectiveError.BADPARAMS);
return -1;
}
if (requireVlanExtensions()) {
OfdpaMatchVlanVid ofdpaMatchVlanVid = new OfdpaMatchVlanVid(assignedVlan);
builderToUpdate.extension(ofdpaMatchVlanVid, deviceId);
} else {
builderToUpdate.matchVlanId(assignedVlan);
}
builderToUpdate.matchEthType(Ethernet.TYPE_IPV4).matchIPDst(ipv4Dst);
log.debug("processing IPv4 multicast specific forwarding objective {} -> next:{}" + " in dev:{}", fwd.id(), fwd.nextId(), deviceId);
} else {
if (ipv4Dst.prefixLength() == 0) {
if (allowDefaultRoute) {
// The entire IPV4_DST field is wildcarded intentionally
builderToUpdate.matchEthType(Ethernet.TYPE_IPV4);
} else {
// NOTE: The switch does not support matching 0.0.0.0/0
// Split it into 0.0.0.0/1 and 128.0.0.0/1
builderToUpdate.matchEthType(Ethernet.TYPE_IPV4).matchIPDst(IpPrefix.valueOf("0.0.0.0/1"));
extBuilder.matchEthType(Ethernet.TYPE_IPV4).matchIPDst(IpPrefix.valueOf("128.0.0.0/1"));
}
} else {
builderToUpdate.matchEthType(Ethernet.TYPE_IPV4).matchIPDst(ipv4Dst);
}
log.debug("processing IPv4 unicast specific forwarding objective {} -> next:{}" + " in dev:{}", fwd.id(), fwd.nextId(), deviceId);
}
return 0;
}
Aggregations