2 * Copyright (c) 2016 Ericsson India Global Services Pvt Ltd. and others. All rights reserved.
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
9 package org.opendaylight.netvirt.aclservice.listeners;
11 import java.math.BigInteger;
12 import java.util.ArrayList;
13 import java.util.List;
14 import javax.annotation.PostConstruct;
15 import javax.inject.Inject;
16 import javax.inject.Singleton;
17 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
18 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
19 import org.opendaylight.genius.datastoreutils.AsyncDataTreeChangeListenerBase;
20 import org.opendaylight.genius.mdsalutil.ActionInfo;
21 import org.opendaylight.genius.mdsalutil.FlowEntity;
22 import org.opendaylight.genius.mdsalutil.InstructionInfo;
23 import org.opendaylight.genius.mdsalutil.MDSALUtil;
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.actions.ActionDrop;
30 import org.opendaylight.genius.mdsalutil.actions.ActionNxResubmit;
31 import org.opendaylight.genius.mdsalutil.instructions.InstructionApplyActions;
32 import org.opendaylight.genius.mdsalutil.instructions.InstructionGotoTable;
33 import org.opendaylight.genius.mdsalutil.interfaces.IMdsalApiManager;
34 import org.opendaylight.genius.mdsalutil.matches.MatchEthernetType;
35 import org.opendaylight.genius.mdsalutil.matches.MatchIpProtocol;
36 import org.opendaylight.genius.mdsalutil.matches.MatchTcpFlags;
37 import org.opendaylight.netvirt.aclservice.utils.AclConstants;
38 import org.opendaylight.netvirt.aclservice.utils.AclServiceUtils;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.aclservice.config.rev160806.AclserviceConfig;
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.aclservice.config.rev160806.AclserviceConfig.SecurityGroupMode;
45 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
46 import org.slf4j.Logger;
47 import org.slf4j.LoggerFactory;
50 * Listener to handle flow capable node updates.
53 @SuppressWarnings("deprecation")
54 public class AclNodeListener extends AsyncDataTreeChangeListenerBase<FlowCapableNode, AclNodeListener>
55 implements AutoCloseable {
57 private static final Logger LOG = LoggerFactory.getLogger(AclNodeListener.class);
59 private final IMdsalApiManager mdsalManager;
60 private final AclserviceConfig config;
61 private final DataBroker dataBroker;
62 private final AclServiceUtils aclServiceUtils;
64 private SecurityGroupMode securityGroupMode = null;
67 public AclNodeListener(final IMdsalApiManager mdsalManager, DataBroker dataBroker, AclserviceConfig config,
68 AclServiceUtils aclServiceUtils) {
69 super(FlowCapableNode.class, AclNodeListener.class);
71 this.mdsalManager = mdsalManager;
72 this.dataBroker = dataBroker;
74 this.aclServiceUtils = aclServiceUtils;
80 LOG.info("{} start", getClass().getSimpleName());
82 this.securityGroupMode = config.getSecurityGroupMode();
84 registerListener(LogicalDatastoreType.OPERATIONAL, dataBroker);
85 LOG.info("AclserviceConfig: {}", this.config);
89 protected InstanceIdentifier<FlowCapableNode> getWildCardPath() {
90 return InstanceIdentifier.create(Nodes.class).child(Node.class).augmentation(FlowCapableNode.class);
94 protected void remove(InstanceIdentifier<FlowCapableNode> key, FlowCapableNode dataObjectModification) {
95 NodeKey nodeKey = key.firstKeyOf(Node.class);
96 BigInteger dpnId = MDSALUtil.getDpnIdFromNodeName(nodeKey.getId());
97 this.aclServiceUtils.deleteAclIdPools(dpnId);
101 protected void update(InstanceIdentifier<FlowCapableNode> key, FlowCapableNode dataObjectModificationBefore,
102 FlowCapableNode dataObjectModificationAfter) {
107 protected void add(InstanceIdentifier<FlowCapableNode> key, FlowCapableNode dataObjectModification) {
108 LOG.trace("FlowCapableNode Added: key: {}", key);
109 NodeKey nodeKey = key.firstKeyOf(Node.class);
110 BigInteger dpnId = MDSALUtil.getDpnIdFromNodeName(nodeKey.getId());
111 createTableDefaultEntries(dpnId);
113 this.aclServiceUtils.createAclIdPools(dpnId);
117 * Creates the table miss entries.
119 * @param dpnId the dpn id
121 private void createTableDefaultEntries(BigInteger dpnId) {
122 LOG.info("Adding default ACL entries for mode: "
123 + (securityGroupMode == null ? SecurityGroupMode.Stateful : securityGroupMode));
124 if (securityGroupMode == null || securityGroupMode == SecurityGroupMode.Stateful) {
125 addIngressAclTableMissFlow(dpnId);
126 addEgressAclTableMissFlow(dpnId);
127 addConntrackRules(dpnId, NwConstants.LPORT_DISPATCHER_TABLE, NwConstants.INGRESS_ACL_FILTER_TABLE,
128 NwConstants.ADD_FLOW);
129 addConntrackRules(dpnId, NwConstants.EGRESS_LPORT_DISPATCHER_TABLE, NwConstants.EGRESS_ACL_FILTER_TABLE,
130 NwConstants.ADD_FLOW);
131 } else if (securityGroupMode == SecurityGroupMode.Transparent) {
132 addTransparentIngressAclTableMissFlow(dpnId);
133 addTransparentEgressAclTableMissFlow(dpnId);
134 } else if (securityGroupMode == SecurityGroupMode.Stateless) {
135 addStatelessIngressAclTableMissFlow(dpnId);
136 addStatelessEgressAclTableMissFlow(dpnId);
137 } else if (securityGroupMode == SecurityGroupMode.Learn) {
138 addLearnIngressAclTableMissFlow(dpnId);
139 addLearnEgressAclTableMissFlow(dpnId);
144 * Adds the ingress acl table miss flow.
146 * @param dpId the dp id
148 private void addIngressAclTableMissFlow(BigInteger dpId) {
149 List<MatchInfo> mkMatches = new ArrayList<>();
150 List<InstructionInfo> mkInstructions = new ArrayList<>();
151 List<ActionInfo> actionsInfos = new ArrayList<>();
152 actionsInfos.add(new ActionDrop());
153 mkInstructions.add(new InstructionApplyActions(actionsInfos));
155 FlowEntity flowEntity = MDSALUtil.buildFlowEntity(dpId, NwConstants.EGRESS_ACL_TABLE,
156 getTableMissFlowId(NwConstants.EGRESS_ACL_TABLE), 0, "Ingress ACL Table Miss Flow", 0, 0,
157 AclConstants.COOKIE_ACL_BASE, mkMatches, mkInstructions);
158 mdsalManager.installFlow(flowEntity);
160 FlowEntity nextTblFlowEntity = MDSALUtil.buildFlowEntity(dpId, NwConstants.EGRESS_ACL_FILTER_TABLE,
161 getTableMissFlowId(NwConstants.EGRESS_ACL_FILTER_TABLE), 0, "Ingress ACL Filter Table Miss Flow",
162 0, 0, AclConstants.COOKIE_ACL_BASE, mkMatches, mkInstructions);
163 mdsalManager.installFlow(nextTblFlowEntity);
165 LOG.debug("Added Ingress ACL Table Miss Flows for dpn {}", dpId);
168 private void addLearnEgressAclTableMissFlow(BigInteger dpId) {
169 List<InstructionInfo> mkInstructions = new ArrayList<>();
170 List<ActionInfo> actionsInfos = new ArrayList<>();
171 actionsInfos.add(new ActionNxResubmit(NwConstants.EGRESS_LEARN_TABLE));
172 actionsInfos.add(new ActionNxResubmit(NwConstants.EGRESS_LEARN2_TABLE));
173 mkInstructions.add(new InstructionApplyActions(actionsInfos));
175 List<MatchInfo> mkMatches = new ArrayList<>();
176 FlowEntity doubleResubmitTable = MDSALUtil.buildFlowEntity(dpId, NwConstants.EGRESS_ACL_TABLE,
177 "RESUB-" + getTableMissFlowId(NwConstants.EGRESS_ACL_TABLE),
178 AclConstants.PROTO_MATCH_PRIORITY, "Egress resubmit ACL Table Block", 0, 0,
179 AclConstants.COOKIE_ACL_BASE, mkMatches, mkInstructions);
180 mdsalManager.installFlow(doubleResubmitTable);
182 mkMatches = new ArrayList<>();
183 mkInstructions = new ArrayList<>();
184 actionsInfos = new ArrayList<>();
185 actionsInfos.add(new ActionDrop());
186 mkInstructions.add(new InstructionApplyActions(actionsInfos));
188 FlowEntity flowEntity = MDSALUtil.buildFlowEntity(dpId, NwConstants.EGRESS_LEARN2_TABLE,
189 "LEARN-" + getTableMissFlowId(NwConstants.EGRESS_LEARN2_TABLE), 0,
190 "Egress Learn2 ACL Table Miss Flow", 0, 0,
191 AclConstants.COOKIE_ACL_BASE, mkMatches, mkInstructions);
192 mdsalManager.installFlow(flowEntity);
194 List<NxMatchInfo> nxMkMatches = new ArrayList<>();
195 nxMkMatches.add(new NxMatchInfo(NxMatchFieldType.nxm_reg_5,
196 new long[] {Long.valueOf(AclConstants.LEARN_MATCH_REG_VALUE)}));
198 short dispatcherTableId = NwConstants.EGRESS_LPORT_DISPATCHER_TABLE;
199 List<InstructionInfo> instructions = new ArrayList<>();
200 actionsInfos.add(new ActionNxResubmit(dispatcherTableId));
201 instructions.add(new InstructionApplyActions(actionsInfos));
203 flowEntity = MDSALUtil.buildFlowEntity(dpId, NwConstants.EGRESS_LEARN2_TABLE,
204 "LEARN2-REG-" + getTableMissFlowId(NwConstants.EGRESS_LEARN2_TABLE),
205 AclConstants.PROTO_MATCH_PRIORITY, "Egress Learn2 ACL Table match reg Flow", 0, 0,
206 AclConstants.COOKIE_ACL_BASE, nxMkMatches, instructions);
207 mdsalManager.installFlow(flowEntity);
208 LOG.debug("Added learn ACL Table Miss Flows for dpn {}", dpId);
211 private void addLearnIngressAclTableMissFlow(BigInteger dpId) {
212 List<InstructionInfo> mkInstructions = new ArrayList<>();
213 List<ActionInfo> actionsInfos = new ArrayList<>();
214 actionsInfos.add(new ActionNxResubmit(NwConstants.INGRESS_LEARN_TABLE));
215 actionsInfos.add(new ActionNxResubmit(NwConstants.INGRESS_LEARN2_TABLE));
216 mkInstructions.add(new InstructionApplyActions(actionsInfos));
218 List<MatchInfo> mkMatches = new ArrayList<>();
219 FlowEntity doubleResubmitTable = MDSALUtil.buildFlowEntity(dpId, NwConstants.INGRESS_ACL_TABLE,
220 "RESUB-" + getTableMissFlowId(NwConstants.INGRESS_ACL_TABLE),
221 AclConstants.PROTO_MATCH_PRIORITY, "Ingress resubmit ACL Table Block", 0, 0,
222 AclConstants.COOKIE_ACL_BASE, mkMatches, mkInstructions);
223 mdsalManager.installFlow(doubleResubmitTable);
225 mkMatches = new ArrayList<>();
226 mkInstructions = new ArrayList<>();
227 actionsInfos = new ArrayList<>();
228 actionsInfos.add(new ActionDrop());
229 mkInstructions.add(new InstructionApplyActions(actionsInfos));
231 FlowEntity flowEntity = MDSALUtil.buildFlowEntity(dpId, NwConstants.INGRESS_LEARN2_TABLE,
232 "LEARN-" + getTableMissFlowId(NwConstants.INGRESS_LEARN2_TABLE), 0,
233 "Ingress Learn2 ACL Table Miss Flow", 0, 0,
234 AclConstants.COOKIE_ACL_BASE, mkMatches, mkInstructions);
235 mdsalManager.installFlow(flowEntity);
237 List<NxMatchInfo> nxMkMatches = new ArrayList<>();
238 nxMkMatches.add(new NxMatchInfo(NxMatchFieldType.nxm_reg_5,
239 new long[] {Long.valueOf(AclConstants.LEARN_MATCH_REG_VALUE)}));
241 short dispatcherTableId = NwConstants.LPORT_DISPATCHER_TABLE;
242 List<InstructionInfo> instructions = new ArrayList<>();
243 actionsInfos.add(new ActionNxResubmit(dispatcherTableId));
244 instructions.add(new InstructionApplyActions(actionsInfos));
246 flowEntity = MDSALUtil.buildFlowEntity(dpId, NwConstants.INGRESS_LEARN2_TABLE,
247 "LEARN2-REG-" + getTableMissFlowId(NwConstants.INGRESS_LEARN2_TABLE),
248 AclConstants.PROTO_MATCH_PRIORITY, "Egress Learn2 ACL Table match reg Flow", 0, 0,
249 AclConstants.COOKIE_ACL_BASE, nxMkMatches, instructions);
250 mdsalManager.installFlow(flowEntity);
251 LOG.debug("Added learn ACL Table Miss Flows for dpn {}", dpId);
256 * Adds the ingress acl table transparent flow.
258 * @param dpId the dp id
260 private void addTransparentIngressAclTableMissFlow(BigInteger dpId) {
261 List<MatchInfo> mkMatches = new ArrayList<>();
262 List<InstructionInfo> allowAllInstructions = new ArrayList<>();
263 allowAllInstructions.add(new InstructionGotoTable(NwConstants.INGRESS_ACL_FILTER_TABLE));
265 FlowEntity nextTblFlowEntity = MDSALUtil.buildFlowEntity(dpId, NwConstants.INGRESS_ACL_TABLE,
266 getTableMissFlowId(NwConstants.INGRESS_ACL_TABLE), 0, "Ingress ACL Table allow all Flow",
267 0, 0, AclConstants.COOKIE_ACL_BASE, mkMatches, allowAllInstructions);
268 mdsalManager.installFlow(nextTblFlowEntity);
270 short dispatcherTableId = NwConstants.LPORT_DISPATCHER_TABLE;
272 List<ActionInfo> actionsInfos = new ArrayList<>();
273 List<InstructionInfo> dispatcherInstructions = new ArrayList<>();
274 actionsInfos.add(new ActionNxResubmit(dispatcherTableId));
275 dispatcherInstructions.add(new InstructionApplyActions(actionsInfos));
277 nextTblFlowEntity = MDSALUtil.buildFlowEntity(dpId, NwConstants.INGRESS_ACL_FILTER_TABLE,
278 getTableMissFlowId(NwConstants.INGRESS_ACL_FILTER_TABLE), 0, "Ingress ACL Filter Table allow all Flow",
279 0, 0, AclConstants.COOKIE_ACL_BASE, mkMatches, dispatcherInstructions);
280 mdsalManager.installFlow(nextTblFlowEntity);
282 LOG.debug("Added Transparent Ingress ACL Table allow all Flows for dpn {}", dpId);
286 * Adds the egress acl table transparent flow.
288 * @param dpId the dp id
290 private void addTransparentEgressAclTableMissFlow(BigInteger dpId) {
291 List<MatchInfo> mkMatches = new ArrayList<>();
292 List<InstructionInfo> allowAllInstructions = new ArrayList<>();
293 allowAllInstructions.add(new InstructionGotoTable(NwConstants.EGRESS_ACL_FILTER_TABLE));
295 FlowEntity nextTblFlowEntity = MDSALUtil.buildFlowEntity(dpId, NwConstants.EGRESS_ACL_TABLE,
296 getTableMissFlowId(NwConstants.EGRESS_ACL_TABLE), 0, "Egress ACL Table allow all Flow",
297 0, 0, AclConstants.COOKIE_ACL_BASE, mkMatches, allowAllInstructions);
298 mdsalManager.installFlow(nextTblFlowEntity);
300 short dispatcherTableId = NwConstants.EGRESS_LPORT_DISPATCHER_TABLE;
302 List<ActionInfo> actionsInfos = new ArrayList<>();
303 List<InstructionInfo> instructions = new ArrayList<>();
304 actionsInfos.add(new ActionNxResubmit(dispatcherTableId));
305 instructions.add(new InstructionApplyActions(actionsInfos));
307 nextTblFlowEntity = MDSALUtil.buildFlowEntity(dpId, NwConstants.EGRESS_ACL_FILTER_TABLE,
308 getTableMissFlowId(NwConstants.EGRESS_ACL_FILTER_TABLE), 0, "Egress ACL Filter Table allow all Flow",
309 0, 0, AclConstants.COOKIE_ACL_BASE, mkMatches, instructions);
310 mdsalManager.installFlow(nextTblFlowEntity);
312 LOG.debug("Added Transparent Egress ACL Table allow all Flows for dpn {}", dpId);
316 * Adds the ingress acl table miss flow.
318 * @param dpId the dp id
320 private void addStatelessIngressAclTableMissFlow(BigInteger dpId) {
321 List<MatchInfo> synMatches = new ArrayList<>();
322 synMatches.add(MatchEthernetType.IPV4);
323 synMatches.add(MatchIpProtocol.TCP);
325 synMatches.add(MatchTcpFlags.SYN);
327 List<ActionInfo> dropActionsInfos = new ArrayList<>();
328 dropActionsInfos.add(new ActionDrop());
329 List<InstructionInfo> synInstructions = new ArrayList<>();
330 synInstructions.add(new InstructionApplyActions(dropActionsInfos));
332 FlowEntity synFlowEntity = MDSALUtil.buildFlowEntity(dpId, NwConstants.EGRESS_ACL_TABLE,
333 "SYN-" + getTableMissFlowId(NwConstants.EGRESS_ACL_TABLE),
334 AclConstants.PROTO_MATCH_SYN_DROP_PRIORITY, "Ingress Syn ACL Table Block", 0, 0,
335 AclConstants.COOKIE_ACL_BASE, synMatches, synInstructions);
336 mdsalManager.installFlow(synFlowEntity);
338 synMatches = new ArrayList<>();
339 synMatches.add(MatchEthernetType.IPV4);
340 synMatches.add(MatchIpProtocol.TCP);
341 synMatches.add(MatchTcpFlags.SYN_ACK);
343 List<InstructionInfo> allowAllInstructions = new ArrayList<>();
344 allowAllInstructions.add(new InstructionGotoTable(NwConstants.EGRESS_ACL_FILTER_TABLE));
346 FlowEntity synAckFlowEntity = MDSALUtil.buildFlowEntity(dpId, NwConstants.EGRESS_ACL_TABLE,
347 "SYN-ACK-ALLOW-" + getTableMissFlowId(NwConstants.EGRESS_ACL_TABLE),
348 AclConstants.PROTO_MATCH_SYN_ACK_ALLOW_PRIORITY, "Ingress Syn Ack ACL Table Allow", 0, 0,
349 AclConstants.COOKIE_ACL_BASE, synMatches, allowAllInstructions);
350 mdsalManager.installFlow(synAckFlowEntity);
353 List<MatchInfo> mkMatches = new ArrayList<>();
354 FlowEntity flowEntity = MDSALUtil.buildFlowEntity(dpId, NwConstants.EGRESS_ACL_TABLE,
355 getTableMissFlowId(NwConstants.EGRESS_ACL_TABLE), 0, "Ingress Stateless ACL Table Miss Flow",
356 0, 0, AclConstants.COOKIE_ACL_BASE, mkMatches, allowAllInstructions);
357 mdsalManager.installFlow(flowEntity);
359 short dispatcherTableId = NwConstants.EGRESS_LPORT_DISPATCHER_TABLE;
361 List<ActionInfo> actionsInfos = new ArrayList<>();
362 List<InstructionInfo> instructions = new ArrayList<>();
363 actionsInfos.add(new ActionNxResubmit(dispatcherTableId));
364 instructions.add(new InstructionApplyActions(actionsInfos));
366 FlowEntity nextTblFlowEntity = MDSALUtil.buildFlowEntity(dpId, NwConstants.EGRESS_ACL_FILTER_TABLE,
367 getTableMissFlowId(NwConstants.EGRESS_ACL_FILTER_TABLE), 0,
368 "Ingress Stateless Next ACL Table Miss Flow", 0, 0, AclConstants.COOKIE_ACL_BASE,
369 mkMatches, instructions);
370 mdsalManager.installFlow(nextTblFlowEntity);
372 LOG.debug("Added Stateless Ingress ACL Table Miss Flows for dpn {}.", dpId);
376 * Adds the stateless egress acl table miss flow.
378 * @param dpId the dp id
380 private void addStatelessEgressAclTableMissFlow(BigInteger dpId) {
381 List<InstructionInfo> allowAllInstructions = new ArrayList<>();
382 allowAllInstructions.add(new InstructionGotoTable(NwConstants.INGRESS_ACL_FILTER_TABLE));
384 List<MatchInfo> synMatches = new ArrayList<>();
385 synMatches.add(MatchEthernetType.IPV4);
386 synMatches.add(MatchIpProtocol.TCP);
387 synMatches.add(MatchTcpFlags.SYN);
389 List<ActionInfo> synActionsInfos = new ArrayList<>();
390 synActionsInfos.add(new ActionDrop());
391 List<InstructionInfo> synInstructions = new ArrayList<>();
392 synInstructions.add(new InstructionApplyActions(synActionsInfos));
394 FlowEntity synFlowEntity = MDSALUtil.buildFlowEntity(dpId, NwConstants.INGRESS_ACL_TABLE,
395 "SYN-" + getTableMissFlowId(NwConstants.INGRESS_ACL_TABLE),
396 AclConstants.PROTO_MATCH_SYN_DROP_PRIORITY, "Egress Syn ACL Table Block", 0, 0,
397 AclConstants.COOKIE_ACL_BASE, synMatches, synInstructions);
398 mdsalManager.installFlow(synFlowEntity);
400 synMatches = new ArrayList<>();
401 synMatches.add(MatchEthernetType.IPV4);
402 synMatches.add(MatchIpProtocol.TCP);
403 synMatches.add(MatchTcpFlags.SYN_ACK);
405 FlowEntity synAckFlowEntity = MDSALUtil.buildFlowEntity(dpId, NwConstants.INGRESS_ACL_TABLE,
406 "SYN-ACK-ALLOW-" + getTableMissFlowId(NwConstants.INGRESS_ACL_TABLE),
407 AclConstants.PROTO_MATCH_SYN_ACK_ALLOW_PRIORITY, "Egress Syn Ack ACL Table Allow", 0, 0,
408 AclConstants.COOKIE_ACL_BASE, synMatches, allowAllInstructions);
409 mdsalManager.installFlow(synAckFlowEntity);
411 List<MatchInfo> mkMatches = new ArrayList<>();
412 FlowEntity flowEntity = MDSALUtil.buildFlowEntity(dpId, NwConstants.INGRESS_ACL_TABLE,
413 getTableMissFlowId(NwConstants.INGRESS_ACL_TABLE), 0, "Egress Stateless ACL Table Miss Flow", 0, 0,
414 AclConstants.COOKIE_ACL_BASE, mkMatches, allowAllInstructions);
415 mdsalManager.installFlow(flowEntity);
417 short dispatcherTableId = NwConstants.LPORT_DISPATCHER_TABLE;
419 List<ActionInfo> actionsInfos = new ArrayList<>();
420 List<InstructionInfo> dispatcherInstructions = new ArrayList<>();
421 actionsInfos.add(new ActionNxResubmit(dispatcherTableId));
422 dispatcherInstructions.add(new InstructionApplyActions(actionsInfos));
424 FlowEntity nextTblFlowEntity = MDSALUtil.buildFlowEntity(dpId, NwConstants.INGRESS_ACL_FILTER_TABLE,
425 getTableMissFlowId(NwConstants.INGRESS_ACL_FILTER_TABLE), 0,
426 "Egress Stateless Next ACL Table Miss Flow", 0, 0, AclConstants.COOKIE_ACL_BASE, mkMatches,
427 dispatcherInstructions);
428 mdsalManager.installFlow(nextTblFlowEntity);
430 LOG.debug("Added Stateless Egress ACL Table Miss Flows for dpn {}", dpId);
434 * Adds the egress acl table miss flow.
436 * @param dpId the dp id
438 private void addEgressAclTableMissFlow(BigInteger dpId) {
439 List<MatchInfo> mkMatches = new ArrayList<>();
440 List<InstructionInfo> mkInstructions = new ArrayList<>();
441 List<ActionInfo> actionsInfos = new ArrayList<>();
442 actionsInfos.add(new ActionDrop());
443 mkInstructions.add(new InstructionApplyActions(actionsInfos));
445 FlowEntity flowEntity = MDSALUtil.buildFlowEntity(dpId, NwConstants.INGRESS_ACL_TABLE,
446 getTableMissFlowId(NwConstants.INGRESS_ACL_TABLE), 0, "Egress ACL Table Miss Flow", 0, 0,
447 AclConstants.COOKIE_ACL_BASE, mkMatches, mkInstructions);
448 mdsalManager.installFlow(flowEntity);
450 FlowEntity nextTblFlowEntity = MDSALUtil.buildFlowEntity(dpId, NwConstants.INGRESS_ACL_FILTER_TABLE,
451 getTableMissFlowId(NwConstants.INGRESS_ACL_FILTER_TABLE), 0, "Egress ACL Table Miss Flow", 0, 0,
452 AclConstants.COOKIE_ACL_BASE, mkMatches, mkInstructions);
453 mdsalManager.installFlow(nextTblFlowEntity);
455 LOG.debug("Added Egress ACL Table Miss Flows for dpn {}", dpId);
458 private void addConntrackRules(BigInteger dpnId, short dispatcherTableId,short tableId, int write) {
459 programConntrackForwardRule(dpnId, AclConstants.CT_STATE_TRACKED_EXIST_PRIORITY,
460 "Tracked_Established", AclConstants.TRACKED_EST_CT_STATE, AclConstants.TRACKED_EST_CT_STATE_MASK,
461 dispatcherTableId, tableId, write);
462 programConntrackForwardRule(dpnId, AclConstants.CT_STATE_TRACKED_EXIST_PRIORITY,"Tracked_Related", AclConstants
463 .TRACKED_REL_CT_STATE, AclConstants.TRACKED_REL_CT_STATE_MASK, dispatcherTableId, tableId, write);
467 * Adds the rule to forward the packets known packets.
469 * @param dpId the dpId
470 * @param priority the priority of the flow
471 * @param flowId the flowId
472 * @param conntrackState the conntrack state of the packets thats should be
474 * @param conntrackMask the conntrack mask
475 * @param dispatcherTableId the dispatcher table id
476 * @param tableId the table id
477 * @param addOrRemove whether to add or remove the flow
479 private void programConntrackForwardRule(BigInteger dpId, Integer priority, String flowId,
480 int conntrackState, int conntrackMask, short dispatcherTableId, short tableId, int addOrRemove) {
481 List<MatchInfoBase> matches = new ArrayList<>();
482 matches.add(new NxMatchInfo(NxMatchFieldType.ct_state, new long[] {conntrackState, conntrackMask}));
484 List<InstructionInfo> instructions = getDispatcherTableResubmitInstructions(
485 new ArrayList<>(),dispatcherTableId);
487 flowId = "Fixed_Conntrk_Trk_" + dpId + "_" + flowId + dispatcherTableId;
488 syncFlow(dpId, tableId, flowId, priority, "ACL", 0, 0,
489 AclConstants.COOKIE_ACL_BASE, matches, instructions, addOrRemove);
493 * Gets the dispatcher table resubmit instructions.
495 * @param actionsInfos the actions infos
496 * @param dispatcherTableId the dispatcher table id
497 * @return the instructions for dispatcher table resubmit
499 private List<InstructionInfo> getDispatcherTableResubmitInstructions(List<ActionInfo> actionsInfos,
500 short dispatcherTableId) {
501 List<InstructionInfo> instructions = new ArrayList<>();
502 actionsInfos.add(new ActionNxResubmit(dispatcherTableId));
503 instructions.add(new InstructionApplyActions(actionsInfos));
508 * Writes/remove the flow to/from the datastore.
509 * @param dpId the dpId
510 * @param tableId the tableId
511 * @param flowId the flowId
512 * @param priority the priority
513 * @param flowName the flow name
514 * @param idleTimeOut the idle timeout
515 * @param hardTimeOut the hard timeout
516 * @param cookie the cookie
517 * @param matches the list of matches to be written
518 * @param instructions the list of instruction to be written.
519 * @param addOrRemove add or remove the entries.
521 protected void syncFlow(BigInteger dpId, short tableId, String flowId, int priority, String flowName,
522 int idleTimeOut, int hardTimeOut, BigInteger cookie, List<? extends MatchInfoBase> matches,
523 List<InstructionInfo> instructions, int addOrRemove) {
524 if (addOrRemove == NwConstants.DEL_FLOW) {
525 FlowEntity flowEntity = MDSALUtil.buildFlowEntity(dpId, tableId,flowId,
526 priority, flowName , idleTimeOut, hardTimeOut, cookie, matches, null);
527 LOG.trace("Removing Acl Flow DpnId {}, flowId {}", dpId, flowId);
528 mdsalManager.removeFlow(flowEntity);
530 FlowEntity flowEntity = MDSALUtil.buildFlowEntity(dpId, tableId, flowId,
531 priority, flowName, idleTimeOut, hardTimeOut, cookie, matches, instructions);
532 LOG.trace("Installing DpnId {}, flowId {}", dpId, flowId);
533 mdsalManager.installFlow(flowEntity);
538 * Gets the table miss flow id.
540 * @param tableId the table id
541 * @return the table miss flow id
543 private String getTableMissFlowId(short tableId) {
544 return String.valueOf(tableId);
548 protected AclNodeListener getDataTreeChangeListener() {
549 return AclNodeListener.this;