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 egress acl table miss flow.
146 * @param dpId the dp id
148 private void addEgressAclTableMissFlow(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, "Egress ACL Table Miss Flow", 0, 0,
157 AclConstants.COOKIE_ACL_BASE, mkMatches, mkInstructions);
158 mdsalManager.installFlow(flowEntity);
160 addEgressAclRemoteAclTableMissFlow(dpId);
162 FlowEntity nextTblFlowEntity = MDSALUtil.buildFlowEntity(dpId, NwConstants.EGRESS_ACL_FILTER_TABLE,
163 getTableMissFlowId(NwConstants.EGRESS_ACL_FILTER_TABLE), 0, "Egress ACL Filter Table Miss Flow",
164 0, 0, AclConstants.COOKIE_ACL_BASE, mkMatches, mkInstructions);
165 mdsalManager.installFlow(nextTblFlowEntity);
167 LOG.debug("Added Engress ACL Table Miss Flows for dpn {}", dpId);
171 * Adds the egress acl table miss flow.
173 * @param dpId the dp id
175 private void addEgressAclRemoteAclTableMissFlow(BigInteger dpId) {
176 List<MatchInfo> mkMatches = new ArrayList<>();
177 List<InstructionInfo> mkInstructions = new ArrayList<>();
178 mkInstructions.add(new InstructionGotoTable(NwConstants.EGRESS_ACL_FILTER_TABLE));
180 FlowEntity flowEntity = MDSALUtil.buildFlowEntity(dpId, NwConstants.EGRESS_ACL_REMOTE_ACL_TABLE,
181 getTableMissFlowId(NwConstants.EGRESS_ACL_REMOTE_ACL_TABLE), 0, "Egress ACL Remote Table Miss Flow",
182 0, 0, AclConstants.COOKIE_ACL_BASE, mkMatches, mkInstructions);
183 mdsalManager.installFlow(flowEntity);
185 LOG.debug("Added Egress ACL Table Miss Flows for dpn {}", dpId);
188 private void addLearnEgressAclTableMissFlow(BigInteger dpId) {
189 List<InstructionInfo> mkInstructions = new ArrayList<>();
190 List<ActionInfo> actionsInfos = new ArrayList<>();
191 actionsInfos.add(new ActionNxResubmit(NwConstants.EGRESS_LEARN_TABLE));
192 actionsInfos.add(new ActionNxResubmit(NwConstants.EGRESS_LEARN_ACL_REMOTE_ACL_TABLE));
193 mkInstructions.add(new InstructionApplyActions(actionsInfos));
195 List<MatchInfo> mkMatches = new ArrayList<>();
196 FlowEntity doubleResubmitTable = MDSALUtil.buildFlowEntity(dpId, NwConstants.EGRESS_ACL_TABLE,
197 "RESUB-" + getTableMissFlowId(NwConstants.EGRESS_ACL_TABLE),
198 AclConstants.PROTO_MATCH_PRIORITY, "Egress resubmit ACL Table Block", 0, 0,
199 AclConstants.COOKIE_ACL_BASE, mkMatches, mkInstructions);
200 mdsalManager.installFlow(doubleResubmitTable);
202 mkMatches = new ArrayList<>();
203 mkInstructions = new ArrayList<>();
204 actionsInfos = new ArrayList<>();
205 actionsInfos.add(new ActionDrop());
206 mkInstructions.add(new InstructionApplyActions(actionsInfos));
208 addLearnEgressAclRemoteAclTableMissFlow(dpId);
210 FlowEntity flowEntity = MDSALUtil.buildFlowEntity(dpId, NwConstants.EGRESS_LEARN_ACL_FILTER_TABLE,
211 "LEARN-" + getTableMissFlowId(NwConstants.EGRESS_LEARN_ACL_FILTER_TABLE), 0,
212 "Egress Learn2 ACL Table Miss Flow", 0, 0,
213 AclConstants.COOKIE_ACL_BASE, mkMatches, mkInstructions);
214 mdsalManager.installFlow(flowEntity);
216 List<NxMatchInfo> nxMkMatches = new ArrayList<>();
217 nxMkMatches.add(new NxMatchInfo(NxMatchFieldType.nxm_reg_5,
218 new long[] {Long.valueOf(AclConstants.LEARN_MATCH_REG_VALUE)}));
220 short dispatcherTableId = NwConstants.EGRESS_LPORT_DISPATCHER_TABLE;
221 List<InstructionInfo> instructions = new ArrayList<>();
222 actionsInfos.add(new ActionNxResubmit(dispatcherTableId));
223 instructions.add(new InstructionApplyActions(actionsInfos));
225 flowEntity = MDSALUtil.buildFlowEntity(dpId, NwConstants.EGRESS_LEARN_ACL_FILTER_TABLE,
226 "LEARN2-REG-" + getTableMissFlowId(NwConstants.EGRESS_LEARN_ACL_FILTER_TABLE),
227 AclConstants.PROTO_MATCH_PRIORITY, "Egress Learn2 ACL Table match reg Flow", 0, 0,
228 AclConstants.COOKIE_ACL_BASE, nxMkMatches, instructions);
229 mdsalManager.installFlow(flowEntity);
230 LOG.debug("Added learn ACL Table Miss Flows for dpn {}", dpId);
234 * Adds the egress acl table miss flow.
236 * @param dpId the dp id
238 private void addLearnEgressAclRemoteAclTableMissFlow(BigInteger dpId) {
239 List<MatchInfo> mkMatches = new ArrayList<>();
240 List<InstructionInfo> mkInstructions = new ArrayList<>();
241 mkInstructions.add(new InstructionGotoTable(NwConstants.EGRESS_LEARN_ACL_FILTER_TABLE));
243 FlowEntity flowEntity = MDSALUtil.buildFlowEntity(dpId, NwConstants.EGRESS_LEARN_ACL_REMOTE_ACL_TABLE,
244 getTableMissFlowId(NwConstants.EGRESS_LEARN_ACL_REMOTE_ACL_TABLE), 0,
245 "Egress ACL Remote Table Miss Flow", 0, 0, AclConstants.COOKIE_ACL_BASE, mkMatches, mkInstructions);
246 mdsalManager.installFlow(flowEntity);
248 LOG.debug("Added Egress ACL Table Miss Flows for dpn {}", dpId);
251 private void addLearnIngressAclTableMissFlow(BigInteger dpId) {
252 List<InstructionInfo> mkInstructions = new ArrayList<>();
253 List<ActionInfo> actionsInfos = new ArrayList<>();
254 actionsInfos.add(new ActionNxResubmit(NwConstants.INGRESS_LEARN_TABLE));
255 actionsInfos.add(new ActionNxResubmit(NwConstants.INGRESS_LEARN_ACL_REMOTE_ACL_TABLE));
256 mkInstructions.add(new InstructionApplyActions(actionsInfos));
258 List<MatchInfo> mkMatches = new ArrayList<>();
259 FlowEntity doubleResubmitTable = MDSALUtil.buildFlowEntity(dpId, NwConstants.INGRESS_ACL_TABLE,
260 "RESUB-" + getTableMissFlowId(NwConstants.INGRESS_ACL_TABLE),
261 AclConstants.PROTO_MATCH_PRIORITY, "Ingress resubmit ACL Table Block", 0, 0,
262 AclConstants.COOKIE_ACL_BASE, mkMatches, mkInstructions);
263 mdsalManager.installFlow(doubleResubmitTable);
265 mkMatches = new ArrayList<>();
266 mkInstructions = new ArrayList<>();
267 actionsInfos = new ArrayList<>();
268 actionsInfos.add(new ActionDrop());
269 mkInstructions.add(new InstructionApplyActions(actionsInfos));
271 addLearnIngressAclRemoteAclTableMissFlow(dpId);
273 FlowEntity flowEntity = MDSALUtil.buildFlowEntity(dpId, NwConstants.INGRESS_LEARN_ACL_FILTER_TABLE,
274 "LEARN-" + getTableMissFlowId(NwConstants.INGRESS_LEARN_ACL_FILTER_TABLE), 0,
275 "Ingress Learn2 ACL Table Miss Flow", 0, 0,
276 AclConstants.COOKIE_ACL_BASE, mkMatches, mkInstructions);
277 mdsalManager.installFlow(flowEntity);
279 List<NxMatchInfo> nxMkMatches = new ArrayList<>();
280 nxMkMatches.add(new NxMatchInfo(NxMatchFieldType.nxm_reg_5,
281 new long[] {Long.valueOf(AclConstants.LEARN_MATCH_REG_VALUE)}));
283 short dispatcherTableId = NwConstants.LPORT_DISPATCHER_TABLE;
284 List<InstructionInfo> instructions = new ArrayList<>();
285 actionsInfos.add(new ActionNxResubmit(dispatcherTableId));
286 instructions.add(new InstructionApplyActions(actionsInfos));
288 flowEntity = MDSALUtil.buildFlowEntity(dpId, NwConstants.INGRESS_LEARN_ACL_FILTER_TABLE,
289 "LEARN2-REG-" + getTableMissFlowId(NwConstants.INGRESS_LEARN_ACL_FILTER_TABLE),
290 AclConstants.PROTO_MATCH_PRIORITY, "Egress Learn2 ACL Table match reg Flow", 0, 0,
291 AclConstants.COOKIE_ACL_BASE, nxMkMatches, instructions);
292 mdsalManager.installFlow(flowEntity);
293 LOG.debug("Added learn ACL Table Miss Flows for dpn {}", dpId);
298 * Adds the ingress acl table miss flow.
300 * @param dpId the dp id
302 private void addLearnIngressAclRemoteAclTableMissFlow(BigInteger dpId) {
303 List<MatchInfo> mkMatches = new ArrayList<>();
304 List<InstructionInfo> mkInstructions = new ArrayList<>();
305 mkInstructions.add(new InstructionGotoTable(NwConstants.INGRESS_LEARN_ACL_FILTER_TABLE));
307 FlowEntity flowEntity = MDSALUtil.buildFlowEntity(dpId, NwConstants.INGRESS_LEARN_ACL_REMOTE_ACL_TABLE,
308 getTableMissFlowId(NwConstants.INGRESS_LEARN_ACL_REMOTE_ACL_TABLE), 0,
309 "Ingress ACL Remote Table Miss Flow", 0, 0, AclConstants.COOKIE_ACL_BASE, mkMatches, mkInstructions);
310 mdsalManager.installFlow(flowEntity);
312 LOG.debug("Added Ingress ACL Table Miss Flows for dpn {}", dpId);
316 * Adds the ingress acl table transparent flow.
318 * @param dpId the dp id
320 private void addTransparentIngressAclTableMissFlow(BigInteger dpId) {
321 List<MatchInfo> mkMatches = new ArrayList<>();
322 List<InstructionInfo> allowAllInstructions = new ArrayList<>();
323 allowAllInstructions.add(new InstructionGotoTable(NwConstants.INGRESS_ACL_FILTER_TABLE));
325 FlowEntity nextTblFlowEntity = MDSALUtil.buildFlowEntity(dpId, NwConstants.INGRESS_ACL_TABLE,
326 getTableMissFlowId(NwConstants.INGRESS_ACL_TABLE), 0, "Ingress ACL Table allow all Flow",
327 0, 0, AclConstants.COOKIE_ACL_BASE, mkMatches, allowAllInstructions);
328 mdsalManager.installFlow(nextTblFlowEntity);
330 short dispatcherTableId = NwConstants.LPORT_DISPATCHER_TABLE;
332 List<ActionInfo> actionsInfos = new ArrayList<>();
333 List<InstructionInfo> dispatcherInstructions = new ArrayList<>();
334 actionsInfos.add(new ActionNxResubmit(dispatcherTableId));
335 dispatcherInstructions.add(new InstructionApplyActions(actionsInfos));
337 addIngressAclRemoteAclTableMissFlow(dpId);
339 nextTblFlowEntity = MDSALUtil.buildFlowEntity(dpId, NwConstants.INGRESS_ACL_FILTER_TABLE,
340 getTableMissFlowId(NwConstants.INGRESS_ACL_FILTER_TABLE), 0, "Ingress ACL Filter Table allow all Flow",
341 0, 0, AclConstants.COOKIE_ACL_BASE, mkMatches, dispatcherInstructions);
342 mdsalManager.installFlow(nextTblFlowEntity);
344 LOG.debug("Added Transparent Ingress ACL Table allow all Flows for dpn {}", dpId);
348 * Adds the egress acl table transparent flow.
350 * @param dpId the dp id
352 private void addTransparentEgressAclTableMissFlow(BigInteger dpId) {
353 List<MatchInfo> mkMatches = new ArrayList<>();
354 List<InstructionInfo> allowAllInstructions = new ArrayList<>();
355 allowAllInstructions.add(new InstructionGotoTable(NwConstants.EGRESS_ACL_REMOTE_ACL_TABLE));
357 FlowEntity nextTblFlowEntity = MDSALUtil.buildFlowEntity(dpId, NwConstants.EGRESS_ACL_TABLE,
358 getTableMissFlowId(NwConstants.EGRESS_ACL_TABLE), 0, "Egress ACL Table allow all Flow",
359 0, 0, AclConstants.COOKIE_ACL_BASE, mkMatches, allowAllInstructions);
360 mdsalManager.installFlow(nextTblFlowEntity);
362 short dispatcherTableId = NwConstants.EGRESS_LPORT_DISPATCHER_TABLE;
364 List<ActionInfo> actionsInfos = new ArrayList<>();
365 List<InstructionInfo> instructions = new ArrayList<>();
366 actionsInfos.add(new ActionNxResubmit(dispatcherTableId));
367 instructions.add(new InstructionApplyActions(actionsInfos));
369 addEgressAclRemoteAclTableMissFlow(dpId);
371 nextTblFlowEntity = MDSALUtil.buildFlowEntity(dpId, NwConstants.EGRESS_ACL_FILTER_TABLE,
372 getTableMissFlowId(NwConstants.EGRESS_ACL_FILTER_TABLE), 0, "Egress ACL Filter Table allow all Flow",
373 0, 0, AclConstants.COOKIE_ACL_BASE, mkMatches, instructions);
374 mdsalManager.installFlow(nextTblFlowEntity);
376 LOG.debug("Added Transparent Egress ACL Table allow all Flows for dpn {}", dpId);
380 * Adds the ingress acl table miss flow.
382 * @param dpId the dp id
384 private void addStatelessIngressAclTableMissFlow(BigInteger dpId) {
385 List<MatchInfo> synMatches = new ArrayList<>();
386 synMatches.add(MatchEthernetType.IPV4);
387 synMatches.add(MatchIpProtocol.TCP);
389 synMatches.add(MatchTcpFlags.SYN);
391 List<ActionInfo> dropActionsInfos = new ArrayList<>();
392 dropActionsInfos.add(new ActionDrop());
393 List<InstructionInfo> synInstructions = new ArrayList<>();
394 synInstructions.add(new InstructionApplyActions(dropActionsInfos));
396 FlowEntity synFlowEntity = MDSALUtil.buildFlowEntity(dpId, NwConstants.EGRESS_ACL_TABLE,
397 "SYN-" + getTableMissFlowId(NwConstants.EGRESS_ACL_TABLE),
398 AclConstants.PROTO_MATCH_SYN_DROP_PRIORITY, "Ingress Syn ACL Table Block", 0, 0,
399 AclConstants.COOKIE_ACL_BASE, synMatches, synInstructions);
400 mdsalManager.installFlow(synFlowEntity);
402 synMatches = new ArrayList<>();
403 synMatches.add(MatchEthernetType.IPV4);
404 synMatches.add(MatchIpProtocol.TCP);
405 synMatches.add(MatchTcpFlags.SYN_ACK);
407 List<InstructionInfo> allowAllInstructions = new ArrayList<>();
408 allowAllInstructions.add(new InstructionGotoTable(NwConstants.EGRESS_ACL_REMOTE_ACL_TABLE));
410 FlowEntity synAckFlowEntity = MDSALUtil.buildFlowEntity(dpId, NwConstants.EGRESS_ACL_TABLE,
411 "SYN-ACK-ALLOW-" + getTableMissFlowId(NwConstants.EGRESS_ACL_TABLE),
412 AclConstants.PROTO_MATCH_SYN_ACK_ALLOW_PRIORITY, "Ingress Syn Ack ACL Table Allow", 0, 0,
413 AclConstants.COOKIE_ACL_BASE, synMatches, allowAllInstructions);
414 mdsalManager.installFlow(synAckFlowEntity);
417 List<MatchInfo> mkMatches = new ArrayList<>();
418 FlowEntity flowEntity = MDSALUtil.buildFlowEntity(dpId, NwConstants.EGRESS_ACL_TABLE,
419 getTableMissFlowId(NwConstants.EGRESS_ACL_TABLE), 0, "Ingress Stateless ACL Table Miss Flow",
420 0, 0, AclConstants.COOKIE_ACL_BASE, mkMatches, allowAllInstructions);
421 mdsalManager.installFlow(flowEntity);
423 short dispatcherTableId = NwConstants.EGRESS_LPORT_DISPATCHER_TABLE;
425 List<ActionInfo> actionsInfos = new ArrayList<>();
426 List<InstructionInfo> instructions = new ArrayList<>();
427 actionsInfos.add(new ActionNxResubmit(dispatcherTableId));
428 instructions.add(new InstructionApplyActions(actionsInfos));
430 addIngressAclRemoteAclTableMissFlow(dpId);
432 FlowEntity nextTblFlowEntity = MDSALUtil.buildFlowEntity(dpId, NwConstants.EGRESS_ACL_FILTER_TABLE,
433 getTableMissFlowId(NwConstants.EGRESS_ACL_FILTER_TABLE), 0,
434 "Ingress Stateless Next ACL Table Miss Flow", 0, 0, AclConstants.COOKIE_ACL_BASE,
435 mkMatches, instructions);
436 mdsalManager.installFlow(nextTblFlowEntity);
438 LOG.debug("Added Stateless Ingress ACL Table Miss Flows for dpn {}.", dpId);
442 * Adds the stateless egress acl table miss flow.
444 * @param dpId the dp id
446 private void addStatelessEgressAclTableMissFlow(BigInteger dpId) {
447 List<InstructionInfo> allowAllInstructions = new ArrayList<>();
448 allowAllInstructions.add(new InstructionGotoTable(NwConstants.INGRESS_ACL_FILTER_TABLE));
450 List<MatchInfo> synMatches = new ArrayList<>();
451 synMatches.add(MatchEthernetType.IPV4);
452 synMatches.add(MatchIpProtocol.TCP);
453 synMatches.add(MatchTcpFlags.SYN);
455 List<ActionInfo> synActionsInfos = new ArrayList<>();
456 synActionsInfos.add(new ActionDrop());
457 List<InstructionInfo> synInstructions = new ArrayList<>();
458 synInstructions.add(new InstructionApplyActions(synActionsInfos));
460 FlowEntity synFlowEntity = MDSALUtil.buildFlowEntity(dpId, NwConstants.INGRESS_ACL_TABLE,
461 "SYN-" + getTableMissFlowId(NwConstants.INGRESS_ACL_TABLE),
462 AclConstants.PROTO_MATCH_SYN_DROP_PRIORITY, "Egress Syn ACL Table Block", 0, 0,
463 AclConstants.COOKIE_ACL_BASE, synMatches, synInstructions);
464 mdsalManager.installFlow(synFlowEntity);
466 synMatches = new ArrayList<>();
467 synMatches.add(MatchEthernetType.IPV4);
468 synMatches.add(MatchIpProtocol.TCP);
469 synMatches.add(MatchTcpFlags.SYN_ACK);
471 FlowEntity synAckFlowEntity = MDSALUtil.buildFlowEntity(dpId, NwConstants.INGRESS_ACL_TABLE,
472 "SYN-ACK-ALLOW-" + getTableMissFlowId(NwConstants.INGRESS_ACL_TABLE),
473 AclConstants.PROTO_MATCH_SYN_ACK_ALLOW_PRIORITY, "Egress Syn Ack ACL Table Allow", 0, 0,
474 AclConstants.COOKIE_ACL_BASE, synMatches, allowAllInstructions);
475 mdsalManager.installFlow(synAckFlowEntity);
477 List<MatchInfo> mkMatches = new ArrayList<>();
478 FlowEntity flowEntity = MDSALUtil.buildFlowEntity(dpId, NwConstants.INGRESS_ACL_TABLE,
479 getTableMissFlowId(NwConstants.INGRESS_ACL_TABLE), 0, "Egress Stateless ACL Table Miss Flow", 0, 0,
480 AclConstants.COOKIE_ACL_BASE, mkMatches, allowAllInstructions);
481 mdsalManager.installFlow(flowEntity);
483 short dispatcherTableId = NwConstants.LPORT_DISPATCHER_TABLE;
485 List<ActionInfo> actionsInfos = new ArrayList<>();
486 List<InstructionInfo> dispatcherInstructions = new ArrayList<>();
487 actionsInfos.add(new ActionNxResubmit(dispatcherTableId));
488 dispatcherInstructions.add(new InstructionApplyActions(actionsInfos));
490 addEgressAclRemoteAclTableMissFlow(dpId);
492 FlowEntity nextTblFlowEntity = MDSALUtil.buildFlowEntity(dpId, NwConstants.INGRESS_ACL_FILTER_TABLE,
493 getTableMissFlowId(NwConstants.INGRESS_ACL_FILTER_TABLE), 0,
494 "Egress Stateless Next ACL Table Miss Flow", 0, 0, AclConstants.COOKIE_ACL_BASE, mkMatches,
495 dispatcherInstructions);
496 mdsalManager.installFlow(nextTblFlowEntity);
498 LOG.debug("Added Stateless Egress ACL Table Miss Flows for dpn {}", dpId);
502 * Adds the ingress acl table miss flow.
504 * @param dpId the dp id
506 private void addIngressAclTableMissFlow(BigInteger dpId) {
507 List<MatchInfo> mkMatches = new ArrayList<>();
508 List<InstructionInfo> mkInstructions = new ArrayList<>();
509 List<ActionInfo> actionsInfos = new ArrayList<>();
510 actionsInfos.add(new ActionDrop());
511 mkInstructions.add(new InstructionApplyActions(actionsInfos));
513 FlowEntity flowEntity = MDSALUtil.buildFlowEntity(dpId, NwConstants.INGRESS_ACL_TABLE,
514 getTableMissFlowId(NwConstants.INGRESS_ACL_TABLE), 0, "Ingress ACL Table Miss Flow", 0, 0,
515 AclConstants.COOKIE_ACL_BASE, mkMatches, mkInstructions);
516 mdsalManager.installFlow(flowEntity);
518 addIngressAclRemoteAclTableMissFlow(dpId);
520 FlowEntity nextTblFlowEntity = MDSALUtil.buildFlowEntity(dpId, NwConstants.INGRESS_ACL_FILTER_TABLE,
521 getTableMissFlowId(NwConstants.INGRESS_ACL_FILTER_TABLE), 0, "Ingress ACL Table Miss Flow", 0, 0,
522 AclConstants.COOKIE_ACL_BASE, mkMatches, mkInstructions);
523 mdsalManager.installFlow(nextTblFlowEntity);
525 LOG.debug("Added Ingress ACL Table Miss Flows for dpn {}", dpId);
529 * Adds the ingress acl table miss flow.
531 * @param dpId the dp id
533 private void addIngressAclRemoteAclTableMissFlow(BigInteger dpId) {
534 List<MatchInfo> mkMatches = new ArrayList<>();
535 List<InstructionInfo> mkInstructions = new ArrayList<>();
536 mkInstructions.add(new InstructionGotoTable(NwConstants.INGRESS_ACL_FILTER_TABLE));
538 FlowEntity flowEntity = MDSALUtil.buildFlowEntity(dpId, NwConstants.INGRESS_ACL_REMOTE_ACL_TABLE,
539 getTableMissFlowId(NwConstants.INGRESS_ACL_REMOTE_ACL_TABLE), 0, "Ingress ACL Remote Table Miss Flow",
540 0, 0, AclConstants.COOKIE_ACL_BASE, mkMatches, mkInstructions);
541 mdsalManager.installFlow(flowEntity);
543 LOG.debug("Added Ingress ACL Table Miss Flows for dpn {}", dpId);
546 private void addConntrackRules(BigInteger dpnId, short dispatcherTableId,short tableId, int write) {
547 programConntrackForwardRule(dpnId, AclConstants.CT_STATE_TRACKED_EXIST_PRIORITY,
548 "Tracked_Established", AclConstants.TRACKED_EST_CT_STATE, AclConstants.TRACKED_EST_CT_STATE_MASK,
549 dispatcherTableId, tableId, write);
550 programConntrackForwardRule(dpnId, AclConstants.CT_STATE_TRACKED_EXIST_PRIORITY,"Tracked_Related", AclConstants
551 .TRACKED_REL_CT_STATE, AclConstants.TRACKED_REL_CT_STATE_MASK, dispatcherTableId, tableId, write);
555 * Adds the rule to forward the packets known packets.
557 * @param dpId the dpId
558 * @param priority the priority of the flow
559 * @param flowId the flowId
560 * @param conntrackState the conntrack state of the packets thats should be
562 * @param conntrackMask the conntrack mask
563 * @param dispatcherTableId the dispatcher table id
564 * @param tableId the table id
565 * @param addOrRemove whether to add or remove the flow
567 private void programConntrackForwardRule(BigInteger dpId, Integer priority, String flowId,
568 int conntrackState, int conntrackMask, short dispatcherTableId, short tableId, int addOrRemove) {
569 List<MatchInfoBase> matches = new ArrayList<>();
570 matches.add(new NxMatchInfo(NxMatchFieldType.ct_state, new long[] {conntrackState, conntrackMask}));
572 List<InstructionInfo> instructions = getDispatcherTableResubmitInstructions(
573 new ArrayList<>(),dispatcherTableId);
575 flowId = "Fixed_Conntrk_Trk_" + dpId + "_" + flowId + dispatcherTableId;
576 syncFlow(dpId, tableId, flowId, priority, "ACL", 0, 0,
577 AclConstants.COOKIE_ACL_BASE, matches, instructions, addOrRemove);
581 * Gets the dispatcher table resubmit instructions.
583 * @param actionsInfos the actions infos
584 * @param dispatcherTableId the dispatcher table id
585 * @return the instructions for dispatcher table resubmit
587 private List<InstructionInfo> getDispatcherTableResubmitInstructions(List<ActionInfo> actionsInfos,
588 short dispatcherTableId) {
589 List<InstructionInfo> instructions = new ArrayList<>();
590 actionsInfos.add(new ActionNxResubmit(dispatcherTableId));
591 instructions.add(new InstructionApplyActions(actionsInfos));
596 * Writes/remove the flow to/from the datastore.
597 * @param dpId the dpId
598 * @param tableId the tableId
599 * @param flowId the flowId
600 * @param priority the priority
601 * @param flowName the flow name
602 * @param idleTimeOut the idle timeout
603 * @param hardTimeOut the hard timeout
604 * @param cookie the cookie
605 * @param matches the list of matches to be written
606 * @param instructions the list of instruction to be written.
607 * @param addOrRemove add or remove the entries.
609 protected void syncFlow(BigInteger dpId, short tableId, String flowId, int priority, String flowName,
610 int idleTimeOut, int hardTimeOut, BigInteger cookie, List<? extends MatchInfoBase> matches,
611 List<InstructionInfo> instructions, int addOrRemove) {
612 if (addOrRemove == NwConstants.DEL_FLOW) {
613 FlowEntity flowEntity = MDSALUtil.buildFlowEntity(dpId, tableId,flowId,
614 priority, flowName , idleTimeOut, hardTimeOut, cookie, matches, null);
615 LOG.trace("Removing Acl Flow DpnId {}, flowId {}", dpId, flowId);
616 mdsalManager.removeFlow(flowEntity);
618 FlowEntity flowEntity = MDSALUtil.buildFlowEntity(dpId, tableId, flowId,
619 priority, flowName, idleTimeOut, hardTimeOut, cookie, matches, instructions);
620 LOG.trace("Installing DpnId {}, flowId {}", dpId, flowId);
621 mdsalManager.installFlow(flowEntity);
626 * Gets the table miss flow id.
628 * @param tableId the table id
629 * @return the table miss flow id
631 private String getTableMissFlowId(short tableId) {
632 return String.valueOf(tableId);
636 protected AclNodeListener getDataTreeChangeListener() {
637 return AclNodeListener.this;