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/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/RoutingRulePopulator.java b/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/RoutingRulePopulator.java
index bae299f..a76e966 100644
--- a/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/RoutingRulePopulator.java
+++ b/apps/segmentrouting/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;
}
diff --git a/drivers/default/src/main/java/org/onosproject/driver/pipeline/ofdpa/Ofdpa2Pipeline.java b/drivers/default/src/main/java/org/onosproject/driver/pipeline/ofdpa/Ofdpa2Pipeline.java
index 1fdf2ab..430d424 100644
--- a/drivers/default/src/main/java/org/onosproject/driver/pipeline/ofdpa/Ofdpa2Pipeline.java
+++ b/drivers/default/src/main/java/org/onosproject/driver/pipeline/ofdpa/Ofdpa2Pipeline.java
@@ -407,12 +407,11 @@
VlanId assignedVlan = null;
if (vidCriterion != null) {
- // Use the VLAN in metadata whenever a metadata is provided
- if (filt.meta() != null) {
- assignedVlan = readVlanFromTreatment(filt.meta());
// Use the VLAN in criterion if metadata is not present and the traffic is tagged
- } else if (!vidCriterion.vlanId().equals(VlanId.NONE)) {
+ if (!vidCriterion.vlanId().equals(VlanId.NONE)) {
assignedVlan = vidCriterion.vlanId();
+ } else if (filt.meta() != null) {
+ assignedVlan = readVlanFromTreatment(filt.meta());
}
if (assignedVlan == null) {
@@ -434,7 +433,18 @@
applicationId)) {
log.trace("{} MAC filtering rules in TMAC table: {} for dev: {}",
(install) ? "adding" : "removing", tmacRule, deviceId);
- ops = install ? ops.add(tmacRule) : ops.remove(tmacRule);
+
+ if (install) {
+ ops = ops.add(tmacRule);
+ } else {
+ // NOTE: Only remove TMAC flow when there is no more enabled port within the
+ // same VLAN on this device if TMAC doesn't support matching on in_port.
+ if (matchInPortTmacTable() || (filt.meta() != null && filt.meta().clearedDeferred())) {
+ ops = ops.remove(tmacRule);
+ } else {
+ log.debug("Abort TMAC flow removal on {}. Some other ports still share this TMAC flow");
+ }
+ }
}
}
@@ -703,11 +713,11 @@
/**
* Builds TMAC rules for IPv4 packets.
*
- * @param ethCriterion
- * @param vidCriterion
- * @param ofdpaMatchVlanVid
- * @param applicationId
- * @param pnum
+ * @param ethCriterion dst mac matching
+ * @param vidCriterion vlan id assigned to the port
+ * @param ofdpaMatchVlanVid OFDPA vlan id matching
+ * @param applicationId application id
+ * @param pnum port number
* @return TMAC rule for IPV4 packets
*/
private FlowRule buildTmacRuleForIpv4(EthCriterion ethCriterion,
@@ -748,11 +758,11 @@
/**
* Builds TMAC rule for MPLS packets.
*
- * @param ethCriterion
- * @param vidCriterion
- * @param ofdpaMatchVlanVid
- * @param applicationId
- * @param pnum
+ * @param ethCriterion dst mac matching
+ * @param vidCriterion vlan id assigned to the port
+ * @param ofdpaMatchVlanVid OFDPA vlan id matching
+ * @param applicationId application id
+ * @param pnum port number
* @return TMAC rule for MPLS packets
*/
private FlowRule buildTmacRuleForMpls(EthCriterion ethCriterion,
@@ -793,11 +803,11 @@
/**
* Builds TMAC rules for IPv6 packets.
*
- * @param ethCriterion
- * @param vidCriterion
- * @param ofdpaMatchVlanVid
- * @param applicationId
- * @param pnum
+ * @param ethCriterion dst mac matching
+ * @param vidCriterion vlan id assigned to the port
+ * @param ofdpaMatchVlanVid OFDPA vlan id matching
+ * @param applicationId application id
+ * @param pnum port number
* @return TMAC rule for IPV6 packets
*/
private FlowRule buildTmacRuleForIpv6(EthCriterion ethCriterion,