[SDFAB-522] Fix port type for pair ports
Additionally standardize the usage of the 64 bits carried in the metadata instruction
Change-Id: I023ddd7d86cfe55f3816f63aaa932803c0626df4
diff --git a/impl/src/main/java/org/onosproject/segmentrouting/RoutingRulePopulator.java b/impl/src/main/java/org/onosproject/segmentrouting/RoutingRulePopulator.java
index e933d3e..5e29dde 100644
--- a/impl/src/main/java/org/onosproject/segmentrouting/RoutingRulePopulator.java
+++ b/impl/src/main/java/org/onosproject/segmentrouting/RoutingRulePopulator.java
@@ -79,6 +79,11 @@
import static org.onlab.packet.ICMP6.ROUTER_ADVERTISEMENT;
import static org.onlab.packet.ICMP6.ROUTER_SOLICITATION;
import static org.onlab.packet.IPv6.PROTOCOL_ICMP6;
+import static org.onosproject.segmentrouting.metadata.SRObjectiveMetadata.CLEANUP_DOUBLE_TAGGED_HOST_ENTRIES;
+import static org.onosproject.segmentrouting.metadata.SRObjectiveMetadata.INFRA_PORT;
+import static org.onosproject.segmentrouting.metadata.SRObjectiveMetadata.INTERFACE_CONFIG_UPDATE;
+import static org.onosproject.segmentrouting.metadata.SRObjectiveMetadata.PAIR_PORT;
+import static org.onosproject.segmentrouting.metadata.SRObjectiveMetadata.EDGE_PORT;
/**
* Populator of segment routing flow rules.
@@ -93,10 +98,6 @@
private DeviceConfiguration config;
private RouteSimplifierUtils routeSimplifierUtils;
- // used for signalling the driver to remove vlan table and tmac entry also
- private static final long CLEANUP_DOUBLE_TAGGED_HOST_ENTRIES = 1;
- // used for signalling the driver when not remove tmac entries
- private static final long INTERFACE_CONFIG_UPDATE = 2;
private static final long METADATA_MASK = 0xffffffffffffffffL;
/**
@@ -819,12 +820,8 @@
* @param routerIp the router ip representing the destination switch
* @return a collection of fwdobjective
*/
- private Collection<ForwardingObjective> handleMpls(
- DeviceId targetSwId,
- DeviceId destSwId,
- Set<DeviceId> nextHops,
- int segmentId,
- IpAddress routerIp,
+ private Collection<ForwardingObjective> handleMpls(DeviceId targetSwId, DeviceId destSwId,
+ Set<DeviceId> nextHops, int segmentId, IpAddress routerIp,
boolean isMplsBos) {
TrafficSelector.Builder sbuilder = DefaultTrafficSelector.builder();
@@ -847,20 +844,13 @@
+ "label {} in switch {} with pop to next-hops {}",
segmentId, targetSwId, nextHops);
ForwardingObjective.Builder fwdObjNoBosBuilder =
- getMplsForwardingObjective(targetSwId,
- nextHops,
- true,
- isMplsBos,
- metabuilder.build(),
- routerIp,
- segmentId,
- destSwId);
+ getMplsForwardingObjective(targetSwId, nextHops, true, isMplsBos,
+ metabuilder.build(), routerIp, segmentId, destSwId);
// Error case, we cannot handle, exit.
if (fwdObjNoBosBuilder == null) {
return Collections.emptyList();
}
fwdObjBuilders.add(fwdObjNoBosBuilder);
-
} else {
// next hop is not destination, irrespective of the number of next
// hops (1 or more) -- SR CONTINUE case (swap with self)
@@ -868,20 +858,13 @@
+ "label {} in switch {} without pop to next-hops {}",
segmentId, targetSwId, nextHops);
ForwardingObjective.Builder fwdObjNoBosBuilder =
- getMplsForwardingObjective(targetSwId,
- nextHops,
- false,
- isMplsBos,
- metabuilder.build(),
- routerIp,
- segmentId,
- destSwId);
+ getMplsForwardingObjective(targetSwId, nextHops, false, isMplsBos,
+ metabuilder.build(), routerIp, segmentId, destSwId);
// Error case, we cannot handle, exit.
if (fwdObjNoBosBuilder == null) {
return Collections.emptyList();
}
fwdObjBuilders.add(fwdObjNoBosBuilder);
-
}
List<ForwardingObjective> fwdObjs = Lists.newArrayList();
@@ -895,11 +878,9 @@
.withFlag(ForwardingObjective.Flag.SPECIFIC);
ObjectiveContext context = new DefaultObjectiveContext(
- (objective) ->
- log.debug("MPLS rule {} for SID {} populated in dev:{} ",
+ (objective) -> log.debug("MPLS rule {} for SID {} populated in dev:{} ",
objective.id(), segmentId, targetSwId),
- (objective, error) ->
- log.warn("Failed to populate MPLS rule {} for SID {}: {} in dev:{}",
+ (objective, error) -> log.warn("Failed to populate MPLS rule {} for SID {}: {} in dev:{}",
objective.id(), segmentId, error, targetSwId));
ForwardingObjective fob = fwdObjBuilder.add(context);
@@ -923,15 +904,9 @@
* @param destSw the destination sw
* @return the mpls forwarding objective builder
*/
- private ForwardingObjective.Builder getMplsForwardingObjective(
- DeviceId targetSw,
- Set<DeviceId> nextHops,
- boolean phpRequired,
- boolean isBos,
- TrafficSelector meta,
- IpAddress routerIp,
- int segmentId,
- DeviceId destSw) {
+ private ForwardingObjective.Builder getMplsForwardingObjective(DeviceId targetSw, Set<DeviceId> nextHops,
+ boolean phpRequired, boolean isBos, TrafficSelector meta,
+ IpAddress routerIp, int segmentId, DeviceId destSw) {
ForwardingObjective.Builder fwdBuilder = DefaultForwardingObjective
.builder().withFlag(ForwardingObjective.Flag.SPECIFIC);
@@ -996,7 +971,7 @@
return null;
} else {
log.debug("nextObjId found:{} for mpls rule on device:{} to ds:{}",
- nextId, targetSw, ds);
+ nextId, targetSw, ds);
}
fwdBuilder.nextStep(nextId);
@@ -1162,8 +1137,11 @@
boolean pushVlan, VlanId vlanId,
boolean doTMAC, boolean update) {
MacAddress deviceMac;
+ long metadata = 0;
+ boolean isPairPort;
try {
deviceMac = config.getDeviceMac(deviceId);
+ isPairPort = portnum.equals(config.getPairLocalPort(deviceId));
} catch (DeviceConfigNotFoundException e) {
log.warn(e.getMessage() + " Processing SinglePortFilters aborted");
return null;
@@ -1194,16 +1172,20 @@
if (noMoreEnabledPort(deviceId, vlanId)) {
tBuilder.wipeDeferred();
}
-
// NOTE: Some switch hardware share the same tmac flow among different vlans.
// We use this metadata to let the driver know that there is still a vlan
// configuration associated to that port
if (update) {
- tBuilder.writeMetadata(INTERFACE_CONFIG_UPDATE, METADATA_MASK);
+ metadata = metadata | INTERFACE_CONFIG_UPDATE;
+ }
+ // NOTE: Metadata to signal the driver the port type
+ metadata = metadata | portType(VlanId.NONE, vlanId, isPairPort);
+ // NOTE: metadata equals 0 is rejected by the driver
+ if (metadata > 0) {
+ tBuilder.writeMetadata(metadata, METADATA_MASK);
}
fob.withMeta(tBuilder.build());
-
fob.permit().fromApp(srManager.appId);
return fob;
}
@@ -1222,9 +1204,8 @@
// We should trigger the removal of double tagged rules only when removing
// the filtering objective and no other hosts are connected to the same device port.
boolean cleanupDoubleTaggedRules = !anyDoubleTaggedHost(deviceId, portNum) && !install;
- FilteringObjective.Builder fob = buildDoubleTaggedFilteringObj(deviceId, portNum,
- outerVlan, innerVlan,
- cleanupDoubleTaggedRules);
+ FilteringObjective.Builder fob = buildDoubleTaggedFilteringObj(deviceId, portNum, outerVlan,
+ innerVlan, cleanupDoubleTaggedRules);
if (fob == null) {
// error encountered during build
return;
@@ -1264,8 +1245,11 @@
VlanId outerVlan, VlanId innerVlan,
boolean cleanupDoubleTaggedRules) {
MacAddress deviceMac;
+ long metadata = 0;
+ boolean isPairPort;
try {
deviceMac = config.getDeviceMac(deviceId);
+ isPairPort = portNum.equals(config.getPairLocalPort(deviceId));
} catch (DeviceConfigNotFoundException e) {
log.warn(e.getMessage() + " Processing DoubleTaggedFilters aborted");
return null;
@@ -1282,13 +1266,16 @@
// Pop outer vlan
tBuilder.popVlan();
- // special metadata for driver
+ // NOTE: Special metadata for driver to signal when clean up double tagged entries
if (cleanupDoubleTaggedRules) {
- tBuilder.writeMetadata(CLEANUP_DOUBLE_TAGGED_HOST_ENTRIES, METADATA_MASK);
- } else {
- tBuilder.writeMetadata(0, METADATA_MASK);
+ metadata = metadata | CLEANUP_DOUBLE_TAGGED_HOST_ENTRIES;
}
-
+ // NOTE: Metadata to signal the port type to the driver
+ metadata = metadata | portType(innerVlan, outerVlan, isPairPort);
+ // NOTE: metadata equals 0 is rejected by the driver
+ if (metadata > 0) {
+ tBuilder.writeMetadata(metadata, METADATA_MASK);
+ }
// NOTE: Some switch hardware share the same filtering flow among different ports.
// We use this metadata to let the driver know that there is no more enabled port
// within the same VLAN on this device.
@@ -1297,11 +1284,31 @@
}
fob.withMeta(tBuilder.build());
-
fob.permit().fromApp(srManager.appId);
return fob;
}
+ // Returns port type based on the input parameters
+ private long portType(VlanId innerVlanId, VlanId outerVlanId, boolean isPairPort) {
+ if (isPairPort) {
+ return PAIR_PORT;
+ }
+
+ // Look at the vlan config to determine if it is an INFRA or an EDGE port
+ boolean outerVlanValid = outerVlanId != null && !outerVlanId.equals(VlanId.NONE);
+ boolean innerVlanValid = innerVlanId != null && !innerVlanId.equals(VlanId.NONE);
+
+ // double tagged interfaces are always edge ports. Edge ports do not match on the
+ // transport vlans (default internal vlan and pw transport vlan)
+ if ((innerVlanValid && outerVlanValid) ||
+ (outerVlanValid && !outerVlanId.equals(srManager.getDefaultInternalVlan()) &&
+ !outerVlanId.equals(srManager.getPwTransportVlan()))) {
+ return EDGE_PORT;
+ }
+
+ return INFRA_PORT;
+ }
+
/**
* Creates packet requests to punt all IP packets for the router.
* @param deviceId the switch dpid for the router
@@ -1409,7 +1416,6 @@
void manageSingleIpPunts(DeviceId deviceId, IpAddress ipAddress, boolean request) {
TrafficSelector.Builder sbuilder = buildIpSelectorFromIpAddress(ipAddress);
Optional<DeviceId> optDeviceId = Optional.of(deviceId);
-
if (request) {
srManager.packetService.requestPackets(sbuilder.build(),
PacketPriority.CONTROL, srManager.appId, optDeviceId);