Remove TMac mcast flows when there are no more enabled ports
Change-Id: I6ad6b224ed82ea9b74b3f2c5228d4657f87cfb8b
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 b80919b..3f8cf77 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
@@ -105,10 +105,7 @@
import static java.util.concurrent.Executors.newScheduledThreadPool;
import static java.util.concurrent.Executors.newSingleThreadScheduledExecutor;
-import static org.onlab.packet.MacAddress.BROADCAST;
-import static org.onlab.packet.MacAddress.IPV4_MULTICAST;
-import static org.onlab.packet.MacAddress.IPV6_MULTICAST;
-import static org.onlab.packet.MacAddress.NONE;
+import static org.onlab.packet.MacAddress.*;
import static org.onlab.util.Tools.groupedThreads;
import static org.onosproject.driver.extensions.Ofdpa3CopyField.OXM_ID_PACKET_REG_1;
import static org.onosproject.driver.extensions.Ofdpa3CopyField.OXM_ID_VLAN_VID;
@@ -545,17 +542,29 @@
ops.newStage();
for (FlowRule flowRule : flowRules) {
- log.trace("{} flow rules in TMAC table: {} for dev: {}",
- (install) ? "adding" : "removing", flowRules, deviceId);
+ log.trace("{} flow rule in TMAC table: {} for dev: {}",
+ (install) ? "adding" : "removing", flowRule, deviceId);
if (install) {
ops = ops.add(flowRule);
} 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())) {
+ if (filt.meta() != null && filt.meta().clearedDeferred()) {
+ // TMac mcast does not match on the input port - we have to remove it
+ // only if this is the last port
+ FlowRule rule = buildTmacRuleForMcastFromUnicast(flowRule, applicationId);
+ // IPv6 or IPv4 tmac rule
+ if (rule != null) {
+ // Add first the mcast rule and then open a new stage for the unicast
+ ops = ops.remove(rule);
+ ops.newStage();
+ }
+ ops = ops.remove(flowRule);
+ } else if (matchInPortTmacTable()) {
ops = ops.remove(flowRule);
} else {
- log.debug("Abort TMAC flow removal on {}. Some other ports still share this TMAC flow");
+ log.debug("Abort TMAC flow removal on {}. " +
+ "Some other ports still share this TMAC flow", deviceId);
}
}
}
@@ -976,6 +985,48 @@
return ImmutableList.of(builder.add(rule).build());
}
+ private FlowRule buildTmacRuleForMcastFromUnicast(FlowRule tmacRuleForUnicast, ApplicationId applicationId) {
+ final TrafficSelector.Builder selector = DefaultTrafficSelector.builder();
+ final TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder();
+ FlowRule rule;
+ // Build the selector
+ for (Criterion criterion : tmacRuleForUnicast.selector().criteria()) {
+ if (criterion instanceof VlanIdCriterion) {
+ if (requireVlanExtensions()) {
+ OfdpaMatchVlanVid ofdpaMatchVlanVid = new OfdpaMatchVlanVid(((VlanIdCriterion) criterion).vlanId());
+ selector.extension(ofdpaMatchVlanVid, deviceId);
+ } else {
+ selector.add(criterion);
+ }
+ } else if (criterion instanceof EthTypeCriterion) {
+ selector.add(criterion);
+ if (Objects.equals(((EthTypeCriterion) criterion).ethType(),
+ EtherType.IPV4.ethType())) {
+ selector.matchEthDstMasked(IPV4_MULTICAST, IPV4_MULTICAST_MASK);
+ } else if (Objects.equals(((EthTypeCriterion) criterion).ethType(),
+ EtherType.IPV6.ethType())) {
+ selector.matchEthDstMasked(IPV6_MULTICAST, IPV6_MULTICAST_MASK);
+ } else {
+ // We don't need for mpls rules
+ return null;
+ }
+ }
+ }
+ // Build the treatment
+ treatment.transition(MULTICAST_ROUTING_TABLE);
+ // Build the flowrule
+ rule = DefaultFlowRule.builder()
+ .forDevice(deviceId)
+ .withSelector(selector.build())
+ .withTreatment(treatment.build())
+ .withPriority(DEFAULT_PRIORITY)
+ .fromApp(applicationId)
+ .makePermanent()
+ .forTable(TMAC_TABLE).build();
+ log.info("Building flowRule {}", rule);
+ return rule;
+ }
+
List<List<FlowRule>> processMcastEthDstFilter(EthCriterion ethCriterion,
VlanId assignedVlan,
MacAddress unicastMac,