101101import java .util .Timer ;
102102import java .util .concurrent .ScheduledExecutorService ;
103103import java .util .concurrent .TimeUnit ;
104+ import java .util .concurrent .atomic .AtomicBoolean ;
104105
105106import static java .util .concurrent .Executors .newScheduledThreadPool ;
106107import static java .util .concurrent .Executors .newSingleThreadScheduledExecutor ;
@@ -209,6 +210,15 @@ public boolean requireMplsPop() {
209210 return true ;
210211 }
211212
213+ /**
214+ * Determines whether this pipeline requires one additional flow matching on ethType 0x86dd in ACL table.
215+ *
216+ * @return true to create one additional flow matching on ethType 0x86dd in ACL table
217+ */
218+ protected boolean requireEthType () {
219+ return true ;
220+ }
221+
212222 /**
213223 * Determines whether this pipeline requires MPLS BOS match.
214224 *
@@ -1173,6 +1183,8 @@ protected Collection<FlowRule> processEgress(ForwardingObjective fwd) {
11731183 protected Collection <FlowRule > processVersatile (ForwardingObjective fwd ) {
11741184 log .debug ("Processing versatile forwarding objective:{} in dev:{}" ,
11751185 fwd .id (), deviceId );
1186+ List <FlowRule > flowRules = new ArrayList <>();
1187+ final AtomicBoolean ethTypeUsed = new AtomicBoolean (false );
11761188
11771189 if (fwd .nextId () == null && fwd .treatment () == null ) {
11781190 log .error ("Forwarding objective {} from {} must contain "
@@ -1181,30 +1193,6 @@ protected Collection<FlowRule> processVersatile(ForwardingObjective fwd) {
11811193 return Collections .emptySet ();
11821194 }
11831195
1184- TrafficSelector .Builder sbuilder = versatileSelectorBuilder (fwd );
1185- TrafficTreatment .Builder ttBuilder = versatileTreatmentBuilder (fwd );
1186- if (ttBuilder == null ) {
1187- return Collections .emptySet ();
1188- }
1189-
1190- FlowRule .Builder ruleBuilder = DefaultFlowRule .builder ()
1191- .fromApp (fwd .appId ())
1192- .withPriority (fwd .priority ())
1193- .forDevice (deviceId )
1194- .withSelector (sbuilder .build ())
1195- .withTreatment (ttBuilder .build ())
1196- .makePermanent ()
1197- .forTable (ACL_TABLE );
1198- return Collections .singletonList (ruleBuilder .build ());
1199- }
1200-
1201- /**
1202- * Helper function to create traffic selector builder for versatile forwarding objectives.
1203- *
1204- * @param fwd original forwarding objective
1205- * @return selector builder for the flow rule
1206- */
1207- protected TrafficSelector .Builder versatileSelectorBuilder (ForwardingObjective fwd ) {
12081196 TrafficSelector .Builder sbuilder = DefaultTrafficSelector .builder ();
12091197 fwd .selector ().criteria ().forEach (criterion -> {
12101198 if (criterion instanceof VlanIdCriterion ) {
@@ -1244,11 +1232,45 @@ protected TrafficSelector.Builder versatileSelectorBuilder(ForwardingObjective f
12441232 } else {
12451233 sbuilder .add (criterion );
12461234 }
1235+ } else if (criterion instanceof EthTypeCriterion ) {
1236+ sbuilder .add (criterion );
1237+ ethTypeUsed .set (true );
12471238 } else {
12481239 sbuilder .add (criterion );
12491240 }
12501241 });
1251- return sbuilder ;
1242+
1243+ TrafficTreatment .Builder ttBuilder = versatileTreatmentBuilder (fwd );
1244+ if (ttBuilder == null ) {
1245+ return Collections .emptySet ();
1246+ }
1247+
1248+ FlowRule .Builder ruleBuilder = DefaultFlowRule .builder ()
1249+ .fromApp (fwd .appId ())
1250+ .withPriority (fwd .priority ())
1251+ .forDevice (deviceId )
1252+ .withSelector (sbuilder .build ())
1253+ .withTreatment (ttBuilder .build ())
1254+ .makePermanent ()
1255+ .forTable (ACL_TABLE );
1256+
1257+ flowRules .add (ruleBuilder .build ());
1258+
1259+ if (!ethTypeUsed .get () && requireEthType ()) {
1260+ log .debug ("{} doesn't match on ethType but requireEthType is true, adding complementary ACL flow." ,
1261+ sbuilder .toString ());
1262+ sbuilder .matchEthType (Ethernet .TYPE_IPV6 );
1263+ FlowRule .Builder ethTypeRuleBuilder = DefaultFlowRule .builder ()
1264+ .fromApp (fwd .appId ())
1265+ .withPriority (fwd .priority ())
1266+ .forDevice (deviceId )
1267+ .withSelector (sbuilder .build ())
1268+ .withTreatment (ttBuilder .build ())
1269+ .makePermanent ()
1270+ .forTable (ACL_TABLE );
1271+ flowRules .add (ethTypeRuleBuilder .build ());
1272+ }
1273+ return flowRules ;
12521274 }
12531275
12541276 /**
0 commit comments