Switch to JDT annotations for Nullable and NonNull
[netvirt.git] / aclservice / impl / src / main / java / org / opendaylight / netvirt / aclservice / utils / AclNodeDefaultFlowsTxBuilder.java
1 /*
2  * Copyright (c) 2018 Ericsson India Global Services Pvt Ltd. and others. All rights reserved.
3  *
4  * This program and the accompanying materials are made available under the
5  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6  * and is available at http://www.eclipse.org/legal/epl-v10.html
7  */
8
9 package org.opendaylight.netvirt.aclservice.utils;
10
11 import com.google.common.collect.Lists;
12 import java.math.BigInteger;
13 import java.util.ArrayList;
14 import java.util.Collections;
15 import java.util.List;
16 import org.eclipse.jdt.annotation.Nullable;
17 import org.opendaylight.genius.infra.Datastore.Configuration;
18 import org.opendaylight.genius.infra.TypedWriteTransaction;
19 import org.opendaylight.genius.mdsalutil.ActionInfo;
20 import org.opendaylight.genius.mdsalutil.FlowEntity;
21 import org.opendaylight.genius.mdsalutil.InstructionInfo;
22 import org.opendaylight.genius.mdsalutil.MDSALUtil;
23 import org.opendaylight.genius.mdsalutil.MatchInfo;
24 import org.opendaylight.genius.mdsalutil.MatchInfoBase;
25 import org.opendaylight.genius.mdsalutil.MetaDataUtil;
26 import org.opendaylight.genius.mdsalutil.NwConstants;
27 import org.opendaylight.genius.mdsalutil.actions.ActionNxCtClear;
28 import org.opendaylight.genius.mdsalutil.actions.ActionNxResubmit;
29 import org.opendaylight.genius.mdsalutil.instructions.InstructionApplyActions;
30 import org.opendaylight.genius.mdsalutil.instructions.InstructionGotoTable;
31 import org.opendaylight.genius.mdsalutil.interfaces.IMdsalApiManager;
32 import org.opendaylight.genius.mdsalutil.matches.MatchEthernetType;
33 import org.opendaylight.genius.mdsalutil.matches.MatchIcmpv6;
34 import org.opendaylight.genius.mdsalutil.matches.MatchIpProtocol;
35 import org.opendaylight.genius.mdsalutil.matches.MatchMetadata;
36 import org.opendaylight.genius.mdsalutil.matches.MatchUdpDestinationPort;
37 import org.opendaylight.genius.mdsalutil.matches.MatchUdpSourcePort;
38 import org.opendaylight.genius.mdsalutil.nxmatches.NxMatchCtMark;
39 import org.opendaylight.genius.mdsalutil.nxmatches.NxMatchCtState;
40 import org.opendaylight.genius.mdsalutil.packet.IPProtocols;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.aclservice.config.rev160806.AclserviceConfig;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.aclservice.config.rev160806.AclserviceConfig.DefaultBehavior;
43 import org.slf4j.Logger;
44 import org.slf4j.LoggerFactory;
45
46 /**
47  * The transaction builder class for ACL node default flows.
48  *
49  * @author Somashekar Byrappa
50  */
51 public class AclNodeDefaultFlowsTxBuilder {
52
53     private static final Logger LOG = LoggerFactory.getLogger(AclNodeDefaultFlowsTxBuilder.class);
54
55     private final BigInteger dpId;
56     private final IMdsalApiManager mdsalManager;
57     private final AclserviceConfig config;
58     private final TypedWriteTransaction<Configuration> tx;
59
60     public AclNodeDefaultFlowsTxBuilder(BigInteger dpId, IMdsalApiManager mdsalManager, AclserviceConfig config,
61             TypedWriteTransaction<Configuration> tx) {
62         this.dpId = dpId;
63         this.mdsalManager = mdsalManager;
64         this.config = config;
65         this.tx = tx;
66     }
67
68     public void build() {
69         createTableDefaultEntries();
70     }
71
72
73     /**
74      * Creates the table default entries.
75      */
76     private void createTableDefaultEntries() {
77         addStatefulIngressDefaultFlows();
78         addStatefulEgressDefaultFlows();
79     }
80
81     private void addStatefulIngressDefaultFlows() {
82         addIngressAclTableMissFlows();
83         addIngressDropFlows();
84         addIngressAntiSpoofingTableGotoFlows();
85         addIngressConntrackClassifierFlows();
86         addIngressConntrackStateRules();
87     }
88
89     private void addStatefulEgressDefaultFlows() {
90         addEgressAclTableMissFlows();
91         addEgressDropFlows();
92         addEgressConntrackClassifierFlows();
93         addEgressConntrackStateRules();
94         addEgressAllowBroadcastFlow();
95         addEgressCtClearRule();
96     }
97
98     /**
99      * Adds the ingress acl table miss flows.
100      */
101     private void addIngressAclTableMissFlows() {
102         InstructionInfo writeMetatdata = AclServiceUtils.getWriteMetadataForDropFlag();
103         List<InstructionInfo> instructions = Lists.newArrayList(writeMetatdata);
104         addGotoOrResubmitTableMissFlow(NwConstants.INGRESS_ACL_ANTI_SPOOFING_TABLE,
105                 NwConstants.INGRESS_ACL_COMMITTER_TABLE, instructions);
106
107         writeMetatdata = AclServiceUtils
108                 .getWriteMetadataForAclClassifierType(AclConntrackClassifierType.NON_CONNTRACK_SUPPORTED);
109         instructions = Lists.newArrayList(writeMetatdata);
110         addGotoOrResubmitTableMissFlow(NwConstants.INGRESS_ACL_CONNTRACK_CLASSIFIER_TABLE,
111                 NwConstants.INGRESS_ACL_FILTER_CUM_DISPATCHER_TABLE, instructions);
112
113         addDropOrAllowTableMissFlow(NwConstants.INGRESS_ACL_CONNTRACK_SENDER_TABLE,
114                 NwConstants.INGRESS_ACL_FOR_EXISTING_TRAFFIC_TABLE);
115         addGotoOrResubmitTableMissFlow(NwConstants.INGRESS_ACL_FOR_EXISTING_TRAFFIC_TABLE,
116                 NwConstants.INGRESS_ACL_FILTER_CUM_DISPATCHER_TABLE);
117         addDropOrAllowTableMissFlow(NwConstants.INGRESS_ACL_FILTER_CUM_DISPATCHER_TABLE,
118                 NwConstants.INGRESS_ACL_RULE_BASED_FILTER_TABLE);
119         addGotoOrResubmitTableMissFlow(NwConstants.INGRESS_ACL_RULE_BASED_FILTER_TABLE,
120                 NwConstants.INGRESS_ACL_FILTER_CUM_DISPATCHER_TABLE);
121         addGotoOrResubmitTableMissFlow(NwConstants.INGRESS_REMOTE_ACL_TABLE,
122                 NwConstants.INGRESS_ACL_FILTER_CUM_DISPATCHER_TABLE);
123         addDropOrAllowTableMissFlow(NwConstants.INGRESS_ACL_COMMITTER_TABLE, NwConstants.LPORT_DISPATCHER_TABLE);
124
125         LOG.debug("Added Stateful Ingress ACL Table Miss Flows for dpn {}", dpId);
126     }
127
128     /**
129      * Adds the egress acl table miss flow.
130      */
131     private void addEgressAclTableMissFlows() {
132         // EGRESS_ACL_DUMMY_TABLE exists on egress side only.
133         addGotoOrResubmitTableMissFlow(NwConstants.EGRESS_ACL_DUMMY_TABLE, NwConstants.EGRESS_ACL_ANTI_SPOOFING_TABLE);
134
135         InstructionInfo writeMetatdata = AclServiceUtils.getWriteMetadataForDropFlag();
136         List<InstructionInfo> instructions = Lists.newArrayList(writeMetatdata);
137         addGotoOrResubmitTableMissFlow(NwConstants.EGRESS_ACL_ANTI_SPOOFING_TABLE,
138                 NwConstants.EGRESS_ACL_COMMITTER_TABLE, instructions);
139
140         writeMetatdata = AclServiceUtils
141                 .getWriteMetadataForAclClassifierType(AclConntrackClassifierType.NON_CONNTRACK_SUPPORTED);
142         instructions = Lists.newArrayList(writeMetatdata);
143         addGotoOrResubmitTableMissFlow(NwConstants.EGRESS_ACL_CONNTRACK_CLASSIFIER_TABLE,
144                 NwConstants.EGRESS_ACL_FILTER_CUM_DISPATCHER_TABLE, instructions);
145
146         addDropOrAllowTableMissFlow(NwConstants.EGRESS_ACL_CONNTRACK_SENDER_TABLE,
147                 NwConstants.EGRESS_ACL_FOR_EXISTING_TRAFFIC_TABLE);
148         addGotoOrResubmitTableMissFlow(NwConstants.EGRESS_ACL_FOR_EXISTING_TRAFFIC_TABLE,
149                 NwConstants.EGRESS_ACL_FILTER_CUM_DISPATCHER_TABLE);
150         addDropOrAllowTableMissFlow(NwConstants.EGRESS_ACL_FILTER_CUM_DISPATCHER_TABLE,
151                 NwConstants.EGRESS_ACL_RULE_BASED_FILTER_TABLE);
152         addGotoOrResubmitTableMissFlow(NwConstants.EGRESS_ACL_RULE_BASED_FILTER_TABLE,
153                 NwConstants.EGRESS_ACL_FILTER_CUM_DISPATCHER_TABLE);
154         addGotoOrResubmitTableMissFlow(NwConstants.EGRESS_REMOTE_ACL_TABLE,
155                 NwConstants.EGRESS_ACL_FILTER_CUM_DISPATCHER_TABLE);
156         addDropOrAllowTableMissFlow(NwConstants.EGRESS_ACL_COMMITTER_TABLE, NwConstants.LPORT_DISPATCHER_TABLE);
157
158         LOG.debug("Added Stateful Egress ACL Table Miss Flows for dpn {}", dpId);
159     }
160
161     private void addIngressDropFlows() {
162         List<InstructionInfo> dropInstructions = AclServiceOFFlowBuilder.getDropInstructionInfo();
163         addFlowToTx(NwConstants.INGRESS_ACL_COMMITTER_TABLE, "Ingress_Committer_Drop_Flow",
164                 AclConstants.COMMITTER_TABLE_DROP_PRIORITY, getMetadataForCommitterDropFlag(), dropInstructions);
165     }
166
167     private void addEgressDropFlows() {
168         List<InstructionInfo> dropInstructions = AclServiceOFFlowBuilder.getDropInstructionInfo();
169         addFlowToTx(NwConstants.EGRESS_ACL_COMMITTER_TABLE, "Egress_Committer_Drop_Flow",
170                 AclConstants.COMMITTER_TABLE_DROP_PRIORITY, getMetadataForCommitterDropFlag(), dropInstructions);
171     }
172
173     private void addIngressAntiSpoofingTableGotoFlows() {
174         InstructionInfo writeMetatdata = AclServiceUtils.getWriteMetadataForDropFlag();
175         List<InstructionInfo> gotoInstructions = AclServiceOFFlowBuilder
176                 .getGotoInstructionInfo(NwConstants.INGRESS_ACL_COMMITTER_TABLE);
177         gotoInstructions.add(writeMetatdata);
178
179         List<MatchInfoBase> arpGotoMatches = new ArrayList<>();
180         arpGotoMatches.add(MatchEthernetType.ARP);
181         addFlowToTx(NwConstants.INGRESS_ACL_ANTI_SPOOFING_TABLE, "Ingress_ACL_Table_ARP_GOTO_Flow",
182                 AclConstants.PROTO_ARP_TRAFFIC_DROP_PRIORITY, arpGotoMatches, gotoInstructions);
183
184         List<MatchInfoBase> ipGotoMatches = new ArrayList<>();
185         ipGotoMatches.add(MatchEthernetType.IPV4);
186         addFlowToTx(NwConstants.INGRESS_ACL_ANTI_SPOOFING_TABLE, "Ingress_ACL_Table_IP_GOTO_Flow",
187                 AclConstants.PROTO_IP_TRAFFIC_DROP_PRIORITY, ipGotoMatches, gotoInstructions);
188
189         List<MatchInfoBase> ipv6GotoMatches = new ArrayList<>();
190         ipv6GotoMatches.add(MatchEthernetType.IPV6);
191         addFlowToTx(NwConstants.INGRESS_ACL_ANTI_SPOOFING_TABLE, "Ingress_ACL_Table_IPv6_GOTO_Flow",
192                 AclConstants.PROTO_IP_TRAFFIC_DROP_PRIORITY, ipv6GotoMatches, gotoInstructions);
193
194         addIngressAclDhcpServerTrafficFlow(gotoInstructions);
195         addIngressAclDhcpv6ServerTrafficFlow(gotoInstructions);
196         addIngressAclIcmpv6RouterAdvtsFlow(gotoInstructions);
197     }
198
199     private void addIngressAclDhcpServerTrafficFlow(List<InstructionInfo> gotoInstructions) {
200         List<MatchInfoBase> matches = new ArrayList<>();
201         matches.add(MatchEthernetType.IPV4);
202         matches.add(MatchIpProtocol.UDP);
203         matches.add(new MatchUdpDestinationPort(AclConstants.DHCP_CLIENT_PORT_IPV4));
204         matches.add(new MatchUdpSourcePort(AclConstants.DHCP_SERVER_PORT_IPV4));
205
206         addFlowToTx(NwConstants.INGRESS_ACL_ANTI_SPOOFING_TABLE, "Egress_DHCP_Server_v4_GOTO_FLOW",
207                 AclConstants.PROTO_MATCH_PRIORITY, matches, gotoInstructions);
208     }
209
210     private void addIngressAclDhcpv6ServerTrafficFlow(List<InstructionInfo> gotoInstructions) {
211         List<MatchInfoBase> matches = new ArrayList<>();
212         matches.add(MatchEthernetType.IPV6);
213         matches.add(MatchIpProtocol.UDP);
214         matches.add(new MatchUdpDestinationPort(AclConstants.DHCP_CLIENT_PORT_IPV6));
215         matches.add(new MatchUdpSourcePort(AclConstants.DHCP_SERVER_PORT_IPV6));
216
217         addFlowToTx(NwConstants.INGRESS_ACL_ANTI_SPOOFING_TABLE, "Egress_DHCP_Server_v6_GOTO_FLOW",
218                 AclConstants.PROTO_MATCH_PRIORITY, matches, gotoInstructions);
219     }
220
221     private void addIngressAclIcmpv6RouterAdvtsFlow(List<InstructionInfo> gotoInstructions) {
222         List<MatchInfoBase> matches = new ArrayList<>();
223         matches.add(MatchEthernetType.IPV6);
224         matches.add(MatchIpProtocol.ICMPV6);
225         matches.add(new MatchIcmpv6((short) AclConstants.ICMPV6_TYPE_RA, (short) 0));
226
227         addFlowToTx(NwConstants.INGRESS_ACL_ANTI_SPOOFING_TABLE,
228                 "Egress_ICMPv6_" + AclConstants.ICMPV6_TYPE_RA + "_GOTO_FLOW",
229                 AclConstants.PROTO_IPV6_DROP_PRIORITY, matches, gotoInstructions);
230     }
231
232     private List<MatchInfoBase> getMetadataForCommitterDropFlag() {
233         List<MatchInfoBase> matches = new ArrayList<>();
234         BigInteger metaData = MetaDataUtil.METADATA_MASK_ACL_DROP
235                 .and(AclConstants.METADATA_DROP_FLAG.shiftLeft(2));
236         BigInteger metaDataMask = MetaDataUtil.METADATA_MASK_ACL_DROP
237                 .and(AclConstants.METADATA_DROP_FLAG.shiftLeft(2));
238         matches.add(new MatchMetadata(metaData, metaDataMask));
239
240         return matches;
241     }
242
243     private void addDropOrAllowTableMissFlow(short tableId, short nextTableId) {
244         List<MatchInfo> matches = Collections.emptyList();
245         List<InstructionInfo> instructions;
246         if (config.getDefaultBehavior() == DefaultBehavior.Deny) {
247             instructions = AclServiceOFFlowBuilder.getDropInstructionInfo();
248         } else {
249             instructions = getGotoOrResubmitInstructions(tableId, nextTableId);
250         }
251         addFlowToTx(tableId, getTableMissFlowId(tableId), AclConstants.ACL_TABLE_MISS_PRIORITY, matches, instructions);
252     }
253
254     private void addGotoOrResubmitTableMissFlow(short tableId, short nextTableId) {
255         addGotoOrResubmitTableMissFlow(tableId, nextTableId, null);
256     }
257
258     private void addGotoOrResubmitTableMissFlow(short tableId, short nextTableId,
259             @Nullable List<InstructionInfo> instructions) {
260         List<MatchInfoBase> matches = Collections.emptyList();
261         List<InstructionInfo> ins = getGotoOrResubmitInstructions(tableId, nextTableId);
262         if (instructions != null && !instructions.isEmpty()) {
263             ins.addAll(instructions);
264         }
265         addFlowToTx(tableId, getTableMissFlowId(tableId), AclConstants.ACL_TABLE_MISS_PRIORITY, matches, ins);
266     }
267
268     private List<InstructionInfo> getGotoOrResubmitInstructions(short tableId, short nextTableId) {
269         List<InstructionInfo> instructions;
270         if (tableId < nextTableId) {
271             instructions = AclServiceOFFlowBuilder.getGotoInstructionInfo(nextTableId);
272         } else {
273             instructions = AclServiceOFFlowBuilder.getResubmitInstructionInfo(nextTableId);
274         }
275         return instructions;
276     }
277
278     private void addIngressConntrackStateRules() {
279         addConntrackStateRules(NwConstants.LPORT_DISPATCHER_TABLE,
280                 NwConstants.INGRESS_ACL_FILTER_CUM_DISPATCHER_TABLE);
281         addConntrackUntrackedRule(NwConstants.INGRESS_ACL_FILTER_CUM_DISPATCHER_TABLE,
282                 NwConstants.INGRESS_ACL_CONNTRACK_SENDER_TABLE);
283     }
284
285     private void addEgressConntrackStateRules() {
286         addConntrackStateRules(NwConstants.EGRESS_LPORT_DISPATCHER_TABLE,
287                 NwConstants.EGRESS_ACL_FILTER_CUM_DISPATCHER_TABLE);
288         addConntrackUntrackedRule(NwConstants.EGRESS_ACL_FILTER_CUM_DISPATCHER_TABLE,
289                 NwConstants.EGRESS_ACL_CONNTRACK_SENDER_TABLE);
290     }
291
292     private void addIngressConntrackClassifierFlows() {
293         addConntrackClassifierFlows(NwConstants.INGRESS_ACL_CONNTRACK_CLASSIFIER_TABLE,
294                 NwConstants.INGRESS_ACL_CONNTRACK_SENDER_TABLE);
295     }
296
297     private void addEgressConntrackClassifierFlows() {
298         addConntrackClassifierFlows(NwConstants.EGRESS_ACL_CONNTRACK_CLASSIFIER_TABLE,
299                 NwConstants.EGRESS_ACL_CONNTRACK_SENDER_TABLE);
300     }
301
302     private void addConntrackClassifierFlows(short tableId, short gotoTableId) {
303         for (IPProtocols protocol : AclConstants.PROTOCOLS_SUPPORTED_BY_CONNTRACK) {
304             switch (protocol) {
305                 case TCP:
306                 case UDP:
307                     // For tcp and udp, create one flow each for IPv4 and IPv6
308                     programConntrackClassifierFlow(tableId, gotoTableId, MatchEthernetType.IPV4, protocol);
309                     programConntrackClassifierFlow(tableId, gotoTableId, MatchEthernetType.IPV6, protocol);
310                     break;
311                 case ICMP:
312                     programConntrackClassifierFlow(tableId, gotoTableId, MatchEthernetType.IPV4, protocol);
313                     break;
314                 case IPV6ICMP:
315                     programConntrackClassifierFlow(tableId, gotoTableId, MatchEthernetType.IPV6, protocol);
316                     break;
317                 default:
318                     LOG.error("Invalid protocol [{}] for conntrack", protocol);
319             }
320         }
321     }
322
323     private void programConntrackClassifierFlow(short tableId, short gotoTableId, MatchEthernetType etherType,
324             IPProtocols protocol) {
325         String flowId = "Fixed_Conntrk_Classifier_" + dpId + "_" + tableId + "_" + etherType + "_" + protocol.name();
326
327         List<MatchInfoBase> matches = new ArrayList<>();
328         matches.addAll(AclServiceUtils.buildIpProtocolMatches(etherType, protocol));
329
330         List<InstructionInfo> instructions = AclServiceOFFlowBuilder.getGotoInstructionInfo(gotoTableId);
331         InstructionInfo writeMetatdata =
332                 AclServiceUtils.getWriteMetadataForAclClassifierType(AclConntrackClassifierType.CONNTRACK_SUPPORTED);
333         instructions.add(writeMetatdata);
334
335         addFlowToTx(tableId, flowId, AclConstants.ACL_DEFAULT_PRIORITY, matches, instructions);
336     }
337
338     private void addEgressAllowBroadcastFlow() {
339         final List<MatchInfoBase> ipBroadcastMatches =
340                 AclServiceUtils.buildBroadcastIpV4Matches(AclConstants.IPV4_ALL_SUBNET_BROADCAST_ADDR);
341         List<InstructionInfo> ipBroadcastInstructions =
342                 AclServiceOFFlowBuilder.getGotoInstructionInfo(NwConstants.EGRESS_ACL_CONNTRACK_CLASSIFIER_TABLE);
343         String ipBroadcastflowName = "Ingress_v4_Broadcast_" + dpId + "_Permit";
344         addFlowToTx(NwConstants.EGRESS_ACL_ANTI_SPOOFING_TABLE, ipBroadcastflowName, AclConstants.PROTO_MATCH_PRIORITY,
345                 ipBroadcastMatches, ipBroadcastInstructions);
346
347         final List<MatchInfoBase> l2BroadcastMatch = AclServiceUtils.buildL2BroadcastMatches();
348         List<InstructionInfo> l2BroadcastInstructions =
349                 AclServiceOFFlowBuilder.getResubmitInstructionInfo(NwConstants.EGRESS_LPORT_DISPATCHER_TABLE);
350         String l2BroadcastflowName = "Ingress_L2_Broadcast_" + dpId + "_Permit";
351         addFlowToTx(NwConstants.EGRESS_ACL_ANTI_SPOOFING_TABLE, l2BroadcastflowName,
352                 AclConstants.PROTO_L2BROADCAST_TRAFFIC_MATCH_PRIORITY, l2BroadcastMatch, l2BroadcastInstructions);
353     }
354
355     private void addConntrackStateRules(short dispatcherTableId, short tableId) {
356         programConntrackForwardRule(AclConstants.CT_STATE_TRACKED_EXIST_PRIORITY, "Tracked_Established",
357                 AclConstants.TRACKED_EST_CT_STATE, AclConstants.TRACKED_EST_CT_STATE_MASK,
358                 dispatcherTableId, tableId, true);
359         programConntrackForwardRule(AclConstants.CT_STATE_TRACKED_EXIST_PRIORITY, "Tracked_Related",
360                 AclConstants.TRACKED_REL_CT_STATE, AclConstants.TRACKED_REL_CT_STATE_MASK,
361                 dispatcherTableId, tableId, true);
362     }
363
364     private void addConntrackUntrackedRule(short tableId, short gotoTableId) {
365         programConntrackUntrackedRule(AclConstants.CT_STATE_TRACKED_EXIST_PRIORITY, "Untracked_Related",
366                 AclConstants.UNTRACKED_CT_STATE, AclConstants.TRACKED_CT_STATE_MASK, tableId, gotoTableId);
367     }
368
369     private void programConntrackUntrackedRule(Integer priority, String flowId, int conntrackState, int conntrackMask,
370             short tableId, short gotoTableId) {
371         List<MatchInfoBase> matches = new ArrayList<>();
372         matches.add(new NxMatchCtState(conntrackState, conntrackMask));
373         matches.add(AclServiceUtils.buildAclConntrackClassifierTypeMatch(
374                 AclConntrackClassifierType.CONNTRACK_SUPPORTED));
375
376         List<ActionInfo> actionsInfos = new ArrayList<>();
377         actionsInfos.add(new ActionNxCtClear());
378         actionsInfos.add(new ActionNxResubmit(gotoTableId));
379         List<InstructionInfo> instructions = new ArrayList<>();
380         instructions.add(new InstructionApplyActions(actionsInfos));
381         flowId = "Fixed_Conntrk_Trk_" + dpId + "_" + flowId + gotoTableId;
382         addFlowToTx(tableId, flowId, priority, matches, instructions);
383     }
384
385     /**
386      * Adds the rule to forward the known packets.
387      *
388      * @param priority the priority of the flow
389      * @param flowId the flowId
390      * @param conntrackState the conntrack state of the packets thats should be
391      *        send
392      * @param conntrackMask the conntrack mask
393      * @param dispatcherTableId the dispatcher table id
394      * @param tableId the table id
395      */
396     private void programConntrackForwardRule(Integer priority, String flowId, int conntrackState, int conntrackMask,
397             short dispatcherTableId, short tableId, boolean shouldMatchMark) {
398         List<MatchInfoBase> matches = new ArrayList<>();
399         matches.add(new NxMatchCtState(conntrackState, conntrackMask));
400         if (shouldMatchMark) {
401             matches.add(new NxMatchCtMark(AclConstants.CT_MARK_EST_STATE, AclConstants.CT_MARK_EST_STATE_MASK));
402         }
403         List<ActionInfo> actionsInfos = new ArrayList<>();
404         actionsInfos.add(new ActionNxCtClear());
405         actionsInfos.add(new ActionNxResubmit(dispatcherTableId));
406         List<InstructionInfo> instructions = new ArrayList<>();
407         instructions.add(new InstructionApplyActions(actionsInfos));
408         flowId = "Fixed_Conntrk_Trk_" + dpId + "_" + flowId + dispatcherTableId;
409         addFlowToTx(tableId, flowId, priority, matches, instructions);
410     }
411
412     private void addEgressCtClearRule() {
413         List<MatchInfoBase> matches = new ArrayList<>();
414         matches.add(MatchEthernetType.IPV4);
415         List<InstructionInfo> instructions = new ArrayList<>();
416         List<ActionInfo> actionsInfos = new ArrayList<>();
417         actionsInfos.add(new ActionNxCtClear());
418         instructions.add(new InstructionApplyActions(actionsInfos));
419         instructions.add(new InstructionGotoTable(NwConstants.EGRESS_ACL_ANTI_SPOOFING_TABLE));
420         String flowName = "Egress_Fixed_Ct_Clear_Table_Ipv4_" + this.dpId;
421         addFlowToTx(NwConstants.EGRESS_ACL_DUMMY_TABLE, flowName, AclConstants.ACL_DEFAULT_PRIORITY, matches,
422                 instructions);
423         matches = new ArrayList<>();
424         matches.add(MatchEthernetType.IPV6);
425         flowName = "Egress_Fixed_Ct_Clear_Table_Ipv6_" + this.dpId;
426         addFlowToTx(NwConstants.EGRESS_ACL_DUMMY_TABLE, flowName, AclConstants.ACL_DEFAULT_PRIORITY, matches,
427                 instructions);
428     }
429
430     private void addFlowToTx(short tableId, String flowId, int priority, List<? extends MatchInfoBase> matches,
431             List<InstructionInfo> instructions) {
432         int idleTimeOut = 0;
433         int hardTimeOut = 0;
434         BigInteger cookie = AclConstants.COOKIE_ACL_BASE;
435         FlowEntity flowEntity = MDSALUtil.buildFlowEntity(this.dpId, tableId, flowId, priority, flowId, idleTimeOut,
436                                                           hardTimeOut, cookie, matches, instructions);
437         LOG.trace("Installing Acl default Flow:: DpnId: {}, flowId: {}, flowName: {}, tableId: {}", dpId, flowId,
438                   flowId, tableId);
439         mdsalManager.addFlow(tx, flowEntity);
440     }
441
442     /**
443      * Gets the table miss flow id.
444      *
445      * @param tableId the table id
446      * @return the table miss flow id
447      */
448     private String getTableMissFlowId(short tableId) {
449         return String.valueOf(tableId);
450     }
451 }