Only remove TMAC flow when it is the last port within the same VLAN if TMAC doesn't support in_port matching
Change-Id: Iafb72153eddd126c5598960a46130c50ddfe3cbd
diff --git a/src/main/java/org/onosproject/segmentrouting/RoutingRulePopulator.java b/src/main/java/org/onosproject/segmentrouting/RoutingRulePopulator.java
index bae299f..a76e966 100644
--- a/src/main/java/org/onosproject/segmentrouting/RoutingRulePopulator.java
+++ b/src/main/java/org/onosproject/segmentrouting/RoutingRulePopulator.java
@@ -827,15 +827,33 @@
.addCondition(Criteria.matchEthDst(deviceMac))
.withPriority(SegmentRoutingService.DEFAULT_PRIORITY);
+ TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment.builder();
+
if (pushVlan) {
fob.addCondition(Criteria.matchVlanId(VlanId.NONE));
- TrafficTreatment tt = DefaultTrafficTreatment.builder()
- .pushVlan().setVlanId(vlanId).build();
- fob.withMeta(tt);
+ tBuilder.pushVlan().setVlanId(vlanId);
} else {
fob.addCondition(Criteria.matchVlanId(vlanId));
}
+ // 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.
+ boolean noMoreEnabledPort = srManager.interfaceService.getInterfaces().stream()
+ .filter(intf -> intf.connectPoint().deviceId().equals(deviceId))
+ .filter(intf -> intf.vlanTagged().contains(vlanId) ||
+ intf.vlanUntagged().equals(vlanId) ||
+ intf.vlanNative().equals(vlanId))
+ .noneMatch(intf -> {
+ Port port = srManager.deviceService.getPort(intf.connectPoint());
+ return port != null && port.isEnabled();
+ });
+ if (noMoreEnabledPort) {
+ tBuilder.wipeDeferred();
+ }
+
+ fob.withMeta(tBuilder.build());
+
fob.permit().fromApp(srManager.appId);
return fob;
}