5b18dadaca97f4c6c008a6371f8d37c44ae0198c
[netvirt.git] / vpnservice / aclservice / impl / src / main / java / org / opendaylight / netvirt / aclservice / listeners / AclNodeListener.java
1 /*
2  * Copyright (c) 2016 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.listeners;
10
11 import java.math.BigInteger;
12 import java.util.ArrayList;
13 import java.util.List;
14 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
15 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
16 import org.opendaylight.genius.datastoreutils.AsyncDataTreeChangeListenerBase;
17 import org.opendaylight.genius.mdsalutil.ActionInfo;
18 import org.opendaylight.genius.mdsalutil.ActionType;
19 import org.opendaylight.genius.mdsalutil.FlowEntity;
20 import org.opendaylight.genius.mdsalutil.InstructionInfo;
21 import org.opendaylight.genius.mdsalutil.InstructionType;
22 import org.opendaylight.genius.mdsalutil.MDSALUtil;
23 import org.opendaylight.genius.mdsalutil.MatchFieldType;
24 import org.opendaylight.genius.mdsalutil.MatchInfo;
25 import org.opendaylight.genius.mdsalutil.MatchInfoBase;
26 import org.opendaylight.genius.mdsalutil.NwConstants;
27 import org.opendaylight.genius.mdsalutil.NxMatchFieldType;
28 import org.opendaylight.genius.mdsalutil.NxMatchInfo;
29 import org.opendaylight.genius.mdsalutil.interfaces.IMdsalApiManager;
30 import org.opendaylight.genius.mdsalutil.packet.IPProtocols;
31 import org.opendaylight.netvirt.aclservice.utils.AclConstants;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.aclservice.config.rev160806.AclserviceConfig;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.aclservice.config.rev160806.AclserviceConfig.SecurityGroupMode;
38 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
39 import org.slf4j.Logger;
40 import org.slf4j.LoggerFactory;
41
42 /**
43  * Listener to handle flow capable node updates.
44  */
45 @SuppressWarnings("deprecation")
46 public class AclNodeListener extends AsyncDataTreeChangeListenerBase<FlowCapableNode, AclNodeListener>
47         implements AutoCloseable {
48
49     /** The Constant LOG. */
50     private static final Logger LOG = LoggerFactory.getLogger(AclNodeListener.class);
51
52     /** The mdsal manager. */
53     private final IMdsalApiManager mdsalManager;
54
55     /** The data broker. */
56     private final DataBroker dataBroker;
57
58     private SecurityGroupMode securityGroupMode = null;
59
60     private AclserviceConfig config;
61
62     /**
63      * Instantiates a new acl node listener.
64      *
65      * @param mdsalManager the mdsal manager
66      * @param dataBroker the data broker
67      * @param config - acl service configuration
68      */
69     public AclNodeListener(final IMdsalApiManager mdsalManager, DataBroker dataBroker, AclserviceConfig config) {
70         super(FlowCapableNode.class, AclNodeListener.class);
71
72         this.mdsalManager = mdsalManager;
73         this.dataBroker = dataBroker;
74         this.config = config;
75     }
76
77     public void start() {
78         LOG.info("{} start", getClass().getSimpleName());
79         this.securityGroupMode = config.getSecurityGroupMode();
80         registerListener(LogicalDatastoreType.OPERATIONAL, dataBroker);
81         LOG.info("AclserviceConfig: {}", config);
82     }
83
84     /*
85      * (non-Javadoc)
86      *
87      * @see
88      * org.opendaylight.genius.datastoreutils.AsyncDataTreeChangeListenerBase#
89      * getWildCardPath()
90      */
91     @Override
92     protected InstanceIdentifier<FlowCapableNode> getWildCardPath() {
93         return InstanceIdentifier.create(Nodes.class).child(Node.class).augmentation(FlowCapableNode.class);
94     }
95
96     /*
97      * (non-Javadoc)
98      *
99      * @see
100      * org.opendaylight.genius.datastoreutils.AsyncDataTreeChangeListenerBase#
101      * remove(org.opendaylight.yangtools.yang.binding.InstanceIdentifier,
102      * org.opendaylight.yangtools.yang.binding.DataObject)
103      */
104     @Override
105     protected void remove(InstanceIdentifier<FlowCapableNode> key, FlowCapableNode dataObjectModification) {
106         // do nothing
107
108     }
109
110     /*
111      * (non-Javadoc)
112      *
113      * @see
114      * org.opendaylight.genius.datastoreutils.AsyncDataTreeChangeListenerBase#
115      * update(org.opendaylight.yangtools.yang.binding.InstanceIdentifier,
116      * org.opendaylight.yangtools.yang.binding.DataObject,
117      * org.opendaylight.yangtools.yang.binding.DataObject)
118      */
119     @Override
120     protected void update(InstanceIdentifier<FlowCapableNode> key, FlowCapableNode dataObjectModificationBefore,
121             FlowCapableNode dataObjectModificationAfter) {
122         // do nothing
123
124     }
125
126     /*
127      * (non-Javadoc)
128      *
129      * @see
130      * org.opendaylight.genius.datastoreutils.AsyncDataTreeChangeListenerBase#
131      * add(org.opendaylight.yangtools.yang.binding.InstanceIdentifier,
132      * org.opendaylight.yangtools.yang.binding.DataObject)
133      */
134     @Override
135     protected void add(InstanceIdentifier<FlowCapableNode> key, FlowCapableNode dataObjectModification) {
136         LOG.trace("FlowCapableNode Added: key: {}", key);
137
138         NodeKey nodeKey = key.firstKeyOf(Node.class);
139         BigInteger dpnId = MDSALUtil.getDpnIdFromNodeName(nodeKey.getId());
140         createTableDefaultEntries(dpnId);
141     }
142
143     /**
144      * Creates the table miss entries.
145      *
146      * @param dpnId the dpn id
147      */
148     private void createTableDefaultEntries(BigInteger dpnId) {
149         LOG.info("installing security group default rule in mode {}", this.securityGroupMode);
150         if (securityGroupMode == null || securityGroupMode == SecurityGroupMode.Stateful) {
151             addIngressAclTableMissFlow(dpnId);
152             addEgressAclTableMissFlow(dpnId);
153             addConntrackRules(dpnId, NwConstants.LPORT_DISPATCHER_TABLE, NwConstants.INGRESS_ACL_FILTER_TABLE,
154                     NwConstants.ADD_FLOW);
155             addConntrackRules(dpnId, NwConstants.EGRESS_LPORT_DISPATCHER_TABLE, NwConstants.EGRESS_ACL_FILTER_TABLE,
156                     NwConstants.ADD_FLOW);
157         } else if (securityGroupMode == SecurityGroupMode.Transparent) {
158             addTransparentIngressAclTableMissFlow(dpnId);
159             addTransparentEgressAclTableMissFlow(dpnId);
160         } else {
161             addStatelessIngressAclTableMissFlow(dpnId);
162             addStatelessEgressAclTableMissFlow(dpnId);
163         }
164     }
165
166     /**
167      * Adds the ingress acl table miss flow.
168      *
169      * @param dpId the dp id
170      */
171     private void addIngressAclTableMissFlow(BigInteger dpId) {
172         List<MatchInfo> mkMatches = new ArrayList<>();
173         List<InstructionInfo> mkInstructions = new ArrayList<>();
174         List<ActionInfo> actionsInfos = new ArrayList<>();
175         actionsInfos.add(new ActionInfo(ActionType.drop_action, new String[] {}));
176         mkInstructions.add(new InstructionInfo(InstructionType.apply_actions, actionsInfos));
177
178         FlowEntity flowEntity = MDSALUtil.buildFlowEntity(dpId, NwConstants.EGRESS_ACL_TABLE,
179                 getTableMissFlowId(NwConstants.EGRESS_ACL_TABLE), 0, "Ingress ACL Table Miss Flow", 0, 0,
180                 AclConstants.COOKIE_ACL_BASE, mkMatches, mkInstructions);
181         mdsalManager.installFlow(flowEntity);
182
183         FlowEntity nextTblFlowEntity = MDSALUtil.buildFlowEntity(dpId, NwConstants.EGRESS_ACL_FILTER_TABLE,
184                 getTableMissFlowId(NwConstants.EGRESS_ACL_FILTER_TABLE), 0, "Ingress ACL Filter Table Miss Flow",
185                 0, 0, AclConstants.COOKIE_ACL_BASE, mkMatches, mkInstructions);
186         mdsalManager.installFlow(nextTblFlowEntity);
187
188         LOG.debug("Added Ingress ACL Table Miss Flows for dpn {}", dpId);
189     }
190
191     /**
192      * Adds the ingress acl table transparent flow.
193      *
194      * @param dpId the dp id
195      */
196     private void addTransparentIngressAclTableMissFlow(BigInteger dpId) {
197         List<MatchInfo> mkMatches = new ArrayList<>();
198         List<InstructionInfo> allowAllInstructions = new ArrayList<>();
199         allowAllInstructions.add(
200             new InstructionInfo(InstructionType.goto_table,
201                     new long[] { NwConstants.INGRESS_ACL_FILTER_TABLE }));
202
203         FlowEntity nextTblFlowEntity = MDSALUtil.buildFlowEntity(dpId, NwConstants.INGRESS_ACL_TABLE,
204                 getTableMissFlowId(NwConstants.INGRESS_ACL_TABLE), 0, "Ingress ACL Table allow all Flow",
205                 0, 0, AclConstants.COOKIE_ACL_BASE, mkMatches, allowAllInstructions);
206         mdsalManager.installFlow(nextTblFlowEntity);
207
208         short dispatcherTableId = NwConstants.LPORT_DISPATCHER_TABLE;
209
210         List<ActionInfo> actionsInfos = new ArrayList<>();
211         List<InstructionInfo> dispatcherInstructions = new ArrayList<>();
212         actionsInfos.add(new ActionInfo(ActionType.nx_resubmit, new String[] {Short.toString(dispatcherTableId)}));
213         dispatcherInstructions.add(new InstructionInfo(InstructionType.apply_actions, actionsInfos));
214
215         nextTblFlowEntity = MDSALUtil.buildFlowEntity(dpId, NwConstants.INGRESS_ACL_FILTER_TABLE,
216                 getTableMissFlowId(NwConstants.INGRESS_ACL_FILTER_TABLE), 0, "Ingress ACL Filter Table allow all Flow",
217                 0, 0, AclConstants.COOKIE_ACL_BASE, mkMatches, dispatcherInstructions);
218         mdsalManager.installFlow(nextTblFlowEntity);
219
220         LOG.debug("Added Transparent Ingress ACL Table allow all Flows for dpn {}", dpId);
221     }
222
223     /**
224      * Adds the egress acl table transparent flow.
225      *
226      * @param dpId the dp id
227      */
228     private void addTransparentEgressAclTableMissFlow(BigInteger dpId) {
229         List<MatchInfo> mkMatches = new ArrayList<>();
230         List<InstructionInfo> allowAllInstructions = new ArrayList<>();
231         allowAllInstructions.add(
232             new InstructionInfo(InstructionType.goto_table,
233                     new long[] { NwConstants.EGRESS_ACL_FILTER_TABLE }));
234
235         FlowEntity nextTblFlowEntity = MDSALUtil.buildFlowEntity(dpId, NwConstants.EGRESS_ACL_TABLE,
236                 getTableMissFlowId(NwConstants.EGRESS_ACL_TABLE), 0, "Egress ACL Table allow all Flow",
237                 0, 0, AclConstants.COOKIE_ACL_BASE, mkMatches, allowAllInstructions);
238         mdsalManager.installFlow(nextTblFlowEntity);
239
240         short dispatcherTableId =  NwConstants.EGRESS_LPORT_DISPATCHER_TABLE;
241
242         List<ActionInfo> actionsInfos = new ArrayList<>();
243         List<InstructionInfo> instructions = new ArrayList<>();
244         actionsInfos.add(new ActionInfo(ActionType.nx_resubmit, new String[] {Short.toString(dispatcherTableId)}));
245         instructions.add(new InstructionInfo(InstructionType.apply_actions, actionsInfos));
246
247         nextTblFlowEntity = MDSALUtil.buildFlowEntity(dpId, NwConstants.EGRESS_ACL_FILTER_TABLE,
248                 getTableMissFlowId(NwConstants.EGRESS_ACL_FILTER_TABLE), 0, "Egress ACL Filter Table allow all Flow",
249                 0, 0, AclConstants.COOKIE_ACL_BASE, mkMatches, instructions);
250         mdsalManager.installFlow(nextTblFlowEntity);
251
252         LOG.debug("Added Transparent Egress ACL Table allow all Flows for dpn {}", dpId);
253     }
254
255     /**
256      * Adds the ingress acl table miss flow.
257      *
258      * @param dpId the dp id
259      */
260     private void addStatelessIngressAclTableMissFlow(BigInteger dpId) {
261         List<MatchInfo> synMatches = new ArrayList<>();
262         synMatches.add(new MatchInfo(MatchFieldType.eth_type,
263                 new long[] { NwConstants.ETHTYPE_IPV4 }));
264         synMatches.add(new MatchInfo(MatchFieldType.ip_proto,
265                 new long[] { IPProtocols.TCP.intValue() }));
266
267         synMatches.add(new MatchInfo(MatchFieldType.tcp_flags, new long[] { AclConstants.TCP_FLAG_SYN }));
268
269         List<ActionInfo> dropActionsInfos = new ArrayList<>();
270         dropActionsInfos.add(new ActionInfo(ActionType.drop_action, new String[] {}));
271         List<InstructionInfo> synInstructions = new ArrayList<>();
272         synInstructions.add(new InstructionInfo(InstructionType.apply_actions, dropActionsInfos));
273
274         FlowEntity synFlowEntity = MDSALUtil.buildFlowEntity(dpId, NwConstants.EGRESS_ACL_TABLE,
275                 "SYN-" + getTableMissFlowId(NwConstants.EGRESS_ACL_TABLE),
276                 AclConstants.PROTO_MATCH_SYN_DROP_PRIORITY, "Ingress Syn ACL Table Block", 0, 0,
277                 AclConstants.COOKIE_ACL_BASE, synMatches, synInstructions);
278         mdsalManager.installFlow(synFlowEntity);
279
280         synMatches = new ArrayList<>();
281         synMatches.add(new MatchInfo(MatchFieldType.eth_type,
282                 new long[] { NwConstants.ETHTYPE_IPV4 }));
283         synMatches.add(new MatchInfo(MatchFieldType.ip_proto,
284                 new long[] { IPProtocols.TCP.intValue() }));
285         synMatches.add(new MatchInfo(MatchFieldType.tcp_flags, new long[] { AclConstants.TCP_FLAG_SYN_ACK }));
286
287         List<InstructionInfo> allowAllInstructions = new ArrayList<>();
288         allowAllInstructions.add(
289             new InstructionInfo(InstructionType.goto_table,
290                     new long[] { NwConstants.EGRESS_ACL_FILTER_TABLE }));
291
292         FlowEntity synAckFlowEntity = MDSALUtil.buildFlowEntity(dpId, NwConstants.EGRESS_ACL_TABLE,
293                 "SYN-ACK-ALLOW-" + getTableMissFlowId(NwConstants.EGRESS_ACL_TABLE),
294                 AclConstants.PROTO_MATCH_SYN_ACK_ALLOW_PRIORITY, "Ingress Syn Ack ACL Table Allow", 0, 0,
295                 AclConstants.COOKIE_ACL_BASE, synMatches, allowAllInstructions);
296         mdsalManager.installFlow(synAckFlowEntity);
297
298
299         List<MatchInfo> mkMatches = new ArrayList<>();
300         FlowEntity flowEntity = MDSALUtil.buildFlowEntity(dpId, NwConstants.EGRESS_ACL_TABLE,
301                 getTableMissFlowId(NwConstants.EGRESS_ACL_TABLE), 0, "Ingress Stateless ACL Table Miss Flow",
302                 0, 0, AclConstants.COOKIE_ACL_BASE, mkMatches, allowAllInstructions);
303         mdsalManager.installFlow(flowEntity);
304
305         short dispatcherTableId =  NwConstants.EGRESS_LPORT_DISPATCHER_TABLE;
306
307         List<ActionInfo> actionsInfos = new ArrayList<>();
308         List<InstructionInfo> instructions = new ArrayList<>();
309         actionsInfos.add(new ActionInfo(ActionType.nx_resubmit, new String[] {Short.toString(dispatcherTableId)}));
310         instructions.add(new InstructionInfo(InstructionType.apply_actions, actionsInfos));
311
312         FlowEntity nextTblFlowEntity = MDSALUtil.buildFlowEntity(dpId, NwConstants.EGRESS_ACL_FILTER_TABLE,
313                 getTableMissFlowId(NwConstants.EGRESS_ACL_FILTER_TABLE), 0,
314                 "Ingress Stateless Next ACL Table Miss Flow", 0, 0, AclConstants.COOKIE_ACL_BASE,
315                 mkMatches, instructions);
316         mdsalManager.installFlow(nextTblFlowEntity);
317
318         LOG.debug("Added Stateless Ingress ACL Table Miss Flows for dpn {}.", dpId);
319     }
320
321     /**
322      * Adds the stateless egress acl table miss flow.
323      *
324      * @param dpId the dp id
325      */
326     private void addStatelessEgressAclTableMissFlow(BigInteger dpId) {
327         List<InstructionInfo> allowAllInstructions = new ArrayList<>();
328         allowAllInstructions.add(
329                 new InstructionInfo(InstructionType.goto_table, new long[] { NwConstants.INGRESS_ACL_FILTER_TABLE }));
330
331         List<MatchInfo> synMatches = new ArrayList<>();
332         synMatches.add(new MatchInfo(MatchFieldType.eth_type,
333                 new long[] { NwConstants.ETHTYPE_IPV4 }));
334         synMatches.add(new MatchInfo(MatchFieldType.ip_proto,
335                 new long[] { IPProtocols.TCP.intValue() }));
336         synMatches.add(new MatchInfo(MatchFieldType.tcp_flags, new long[] { AclConstants.TCP_FLAG_SYN }));
337
338         List<ActionInfo> synActionsInfos = new ArrayList<>();
339         synActionsInfos.add(new ActionInfo(ActionType.drop_action, new String[] {}));
340         List<InstructionInfo> synInstructions = new ArrayList<>();
341         synInstructions.add(new InstructionInfo(InstructionType.apply_actions, synActionsInfos));
342
343         FlowEntity synFlowEntity = MDSALUtil.buildFlowEntity(dpId, NwConstants.INGRESS_ACL_TABLE,
344                 "SYN-" + getTableMissFlowId(NwConstants.INGRESS_ACL_TABLE),
345                 AclConstants.PROTO_MATCH_SYN_DROP_PRIORITY, "Egress Syn ACL Table Block", 0, 0,
346                 AclConstants.COOKIE_ACL_BASE, synMatches, synInstructions);
347         mdsalManager.installFlow(synFlowEntity);
348
349         synMatches = new ArrayList<>();
350         synMatches.add(new MatchInfo(MatchFieldType.eth_type,
351                 new long[] { NwConstants.ETHTYPE_IPV4 }));
352         synMatches.add(new MatchInfo(MatchFieldType.ip_proto,
353                 new long[] { IPProtocols.TCP.intValue() }));
354         synMatches.add(new MatchInfo(MatchFieldType.tcp_flags, new long[] { AclConstants.TCP_FLAG_SYN_ACK }));
355
356         FlowEntity synAckFlowEntity = MDSALUtil.buildFlowEntity(dpId, NwConstants.INGRESS_ACL_TABLE,
357                 "SYN-ACK-ALLOW-" + getTableMissFlowId(NwConstants.INGRESS_ACL_TABLE),
358                 AclConstants.PROTO_MATCH_SYN_ACK_ALLOW_PRIORITY, "Egress Syn Ack ACL Table Allow", 0, 0,
359                 AclConstants.COOKIE_ACL_BASE, synMatches, allowAllInstructions);
360         mdsalManager.installFlow(synAckFlowEntity);
361
362         List<MatchInfo> mkMatches = new ArrayList<>();
363         FlowEntity flowEntity = MDSALUtil.buildFlowEntity(dpId, NwConstants.INGRESS_ACL_TABLE,
364                 getTableMissFlowId(NwConstants.INGRESS_ACL_TABLE), 0, "Egress Stateless ACL Table Miss Flow", 0, 0,
365                 AclConstants.COOKIE_ACL_BASE, mkMatches, allowAllInstructions);
366         mdsalManager.installFlow(flowEntity);
367
368         short dispatcherTableId = NwConstants.LPORT_DISPATCHER_TABLE;
369
370         List<ActionInfo> actionsInfos = new ArrayList<>();
371         List<InstructionInfo> dispatcherInstructions = new ArrayList<>();
372         actionsInfos.add(new ActionInfo(ActionType.nx_resubmit, new String[] {Short.toString(dispatcherTableId)}));
373         dispatcherInstructions.add(new InstructionInfo(InstructionType.apply_actions, actionsInfos));
374
375         FlowEntity nextTblFlowEntity = MDSALUtil.buildFlowEntity(dpId, NwConstants.INGRESS_ACL_FILTER_TABLE,
376                 getTableMissFlowId(NwConstants.INGRESS_ACL_FILTER_TABLE), 0,
377                 "Egress Stateless Next ACL Table Miss Flow", 0, 0, AclConstants.COOKIE_ACL_BASE, mkMatches,
378                 dispatcherInstructions);
379         mdsalManager.installFlow(nextTblFlowEntity);
380
381         LOG.debug("Added Stateless Egress ACL Table Miss Flows for dpn {}", dpId);
382     }
383
384     /**
385      * Adds the egress acl table miss flow.
386      *
387      * @param dpId the dp id
388      */
389     private void addEgressAclTableMissFlow(BigInteger dpId) {
390         List<MatchInfo> mkMatches = new ArrayList<>();
391         List<InstructionInfo> mkInstructions = new ArrayList<>();
392         List<ActionInfo> actionsInfos = new ArrayList<>();
393         actionsInfos.add(new ActionInfo(ActionType.drop_action, new String[] {}));
394         mkInstructions.add(new InstructionInfo(InstructionType.apply_actions, actionsInfos));
395
396         FlowEntity flowEntity = MDSALUtil.buildFlowEntity(dpId, NwConstants.INGRESS_ACL_TABLE,
397                 getTableMissFlowId(NwConstants.INGRESS_ACL_TABLE), 0, "Egress ACL Table Miss Flow", 0, 0,
398                 AclConstants.COOKIE_ACL_BASE, mkMatches, mkInstructions);
399         mdsalManager.installFlow(flowEntity);
400
401         FlowEntity nextTblFlowEntity = MDSALUtil.buildFlowEntity(dpId, NwConstants.INGRESS_ACL_FILTER_TABLE,
402                 getTableMissFlowId(NwConstants.INGRESS_ACL_FILTER_TABLE), 0, "Egress ACL Table Miss Flow", 0, 0,
403                 AclConstants.COOKIE_ACL_BASE, mkMatches, mkInstructions);
404         mdsalManager.installFlow(nextTblFlowEntity);
405
406         LOG.debug("Added Egress ACL Table Miss Flows for dpn {}", dpId);
407     }
408
409     private void addConntrackRules(BigInteger dpnId, short dispatcherTableId,short tableId, int write) {
410         programConntrackForwardRule(dpnId, AclConstants.CT_STATE_TRACKED_EXIST_PRIORITY,
411             "Tracked_Established", AclConstants.TRACKED_EST_CT_STATE, AclConstants.TRACKED_EST_CT_STATE_MASK,
412             dispatcherTableId, tableId, write );
413         programConntrackForwardRule(dpnId, AclConstants.CT_STATE_TRACKED_EXIST_PRIORITY,"Tracked_Related", AclConstants
414             .TRACKED_REL_CT_STATE, AclConstants.TRACKED_REL_CT_STATE_MASK, dispatcherTableId, tableId, write );
415         programConntrackDropRule(dpnId, AclConstants.CT_STATE_NEW_PRIORITY_DROP,"Tracked_New",
416             AclConstants.TRACKED_NEW_CT_STATE, AclConstants.TRACKED_NEW_CT_STATE_MASK, tableId, write );
417         programConntrackDropRule(dpnId, AclConstants.CT_STATE_NEW_PRIORITY_DROP, "Tracked_Invalid",
418             AclConstants.TRACKED_INV_CT_STATE, AclConstants.TRACKED_INV_CT_STATE_MASK, tableId, write );
419
420     }
421
422     /**
423      * Adds the rule to forward the packets known packets.
424      *
425      * @param dpId the dpId
426      * @param lportTag the lport tag
427      * @param priority the priority of the flow
428      * @param flowId the flowId
429      * @param conntrackState the conntrack state of the packets thats should be
430      *        send
431      * @param conntrackMask the conntrack mask
432      * @param addOrRemove whether to add or remove the flow
433      */
434     private void programConntrackForwardRule(BigInteger dpId, Integer priority, String flowId,
435             int conntrackState, int conntrackMask, short dispatcherTableId, short tableId, int addOrRemove) {
436         List<MatchInfoBase> matches = new ArrayList<>();
437         matches.add(new NxMatchInfo(NxMatchFieldType.ct_state, new long[] {conntrackState, conntrackMask}));
438
439         List<InstructionInfo> instructions = getDispatcherTableResubmitInstructions(
440             new ArrayList<>(),dispatcherTableId);
441
442         flowId = "Fixed_Conntrk_Trk_" + dpId + "_" + flowId + dispatcherTableId;
443         syncFlow(dpId, tableId, flowId, priority, "ACL", 0, 0,
444                 AclConstants.COOKIE_ACL_BASE, matches, instructions, addOrRemove);
445     }
446
447     /**
448      * Adds the rule to drop the unknown/invalid packets .
449      *
450      * @param dpId the dpId
451      * @param lportTag the lport tag
452      * @param priority the priority of the flow
453      * @param flowId the flowId
454      * @param conntrackState the conntrack state of the packets thats should be
455      *        send
456      * @param conntrackMask the conntrack mask
457      * @param addOrRemove whether to add or remove the flow
458      */
459     private void programConntrackDropRule(BigInteger dpId, Integer priority, String flowId,
460             int conntrackState, int conntrackMask, short tableId, int addOrRemove) {
461         List<MatchInfoBase> matches = new ArrayList<>();
462         matches.add(new NxMatchInfo(NxMatchFieldType.ct_state, new long[] {conntrackState, conntrackMask}));
463
464         List<InstructionInfo> instructions = new ArrayList<>();
465         List<ActionInfo> actionsInfos = new ArrayList<>();
466         actionsInfos.add(new ActionInfo(ActionType.drop_action, new String[] {}));
467         instructions.add(new InstructionInfo(InstructionType.write_actions, actionsInfos));
468         flowId = "Fixed_Conntrk_NewDrop_" + dpId + "_" + flowId + tableId;
469         syncFlow(dpId, tableId, flowId, priority, "ACL", 0, 0,
470                 AclConstants.COOKIE_ACL_BASE, matches, instructions, addOrRemove);
471     }
472
473     /**
474      * Gets the dispatcher table resubmit instructions.
475      *
476      * @param actionsInfos the actions infos
477      * @return the instructions for dispatcher table resubmit
478      */
479     private List<InstructionInfo> getDispatcherTableResubmitInstructions(List<ActionInfo> actionsInfos,
480                                                                          short dispatcherTableId) {
481         List<InstructionInfo> instructions = new ArrayList<>();
482         actionsInfos.add(new ActionInfo(ActionType.nx_resubmit, new String[] {Short.toString(dispatcherTableId)}));
483         instructions.add(new InstructionInfo(InstructionType.apply_actions, actionsInfos));
484         return instructions;
485     }
486
487     /**
488      * Writes/remove the flow to/from the datastore.
489      * @param dpId the dpId
490      * @param tableId the tableId
491      * @param flowId the flowId
492      * @param priority the priority
493      * @param flowName the flow name
494      * @param idleTimeOut the idle timeout
495      * @param hardTimeOut the hard timeout
496      * @param cookie the cookie
497      * @param matches the list of matches to be written
498      * @param instructions the list of instruction to be written.
499      * @param addOrRemove add or remove the entries.
500      */
501     protected void syncFlow(BigInteger dpId, short tableId, String flowId, int priority, String flowName,
502                           int idleTimeOut, int hardTimeOut, BigInteger cookie, List<? extends MatchInfoBase>  matches,
503                           List<InstructionInfo> instructions, int addOrRemove) {
504         if (addOrRemove == NwConstants.DEL_FLOW) {
505             FlowEntity flowEntity = MDSALUtil.buildFlowEntity(dpId, tableId,flowId,
506                 priority, flowName , idleTimeOut, hardTimeOut, cookie, matches, null);
507             LOG.trace("Removing Acl Flow DpnId {}, flowId {}", dpId, flowId);
508             mdsalManager.removeFlow(flowEntity);
509         } else {
510             FlowEntity flowEntity = MDSALUtil.buildFlowEntity(dpId, tableId, flowId,
511                 priority, flowName, idleTimeOut, hardTimeOut, cookie, matches, instructions);
512             LOG.trace("Installing DpnId {}, flowId {}", dpId, flowId);
513             mdsalManager.installFlow(flowEntity);
514         }
515     }
516
517     /**
518      * Gets the table miss flow id.
519      *
520      * @param tableId the table id
521      * @return the table miss flow id
522      */
523     private String getTableMissFlowId(short tableId) {
524         return String.valueOf(tableId);
525     }
526
527     /*
528      * (non-Javadoc)
529      *
530      * @see
531      * org.opendaylight.genius.datastoreutils.AsyncDataTreeChangeListenerBase#
532      * getDataTreeChangeListener()
533      */
534     @Override
535     protected AclNodeListener getDataTreeChangeListener() {
536         return AclNodeListener.this;
537     }
538 }