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;
15 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
16 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
17 import org.opendaylight.genius.datastoreutils.AsyncDataTreeChangeListenerBase;
18 import org.opendaylight.genius.mdsalutil.ActionInfo;
19 import org.opendaylight.genius.mdsalutil.ActionType;
20 import org.opendaylight.genius.mdsalutil.FlowEntity;
21 import org.opendaylight.genius.mdsalutil.InstructionInfo;
22 import org.opendaylight.genius.mdsalutil.InstructionType;
23 import org.opendaylight.genius.mdsalutil.MDSALUtil;
24 import org.opendaylight.genius.mdsalutil.MatchFieldType;
25 import org.opendaylight.genius.mdsalutil.MatchInfo;
26 import org.opendaylight.genius.mdsalutil.MatchInfoBase;
27 import org.opendaylight.genius.mdsalutil.NwConstants;
28 import org.opendaylight.genius.mdsalutil.NxMatchFieldType;
29 import org.opendaylight.genius.mdsalutil.NxMatchInfo;
30 import org.opendaylight.genius.mdsalutil.interfaces.IMdsalApiManager;
31 import org.opendaylight.genius.mdsalutil.packet.IPProtocols;
32 import org.opendaylight.netvirt.aclservice.utils.AclClusterUtil;
33 import org.opendaylight.netvirt.aclservice.utils.AclConstants;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.aclservice.config.rev160806.AclserviceConfig;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.aclservice.config.rev160806.AclserviceConfig.SecurityGroupMode;
40 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
41 import org.slf4j.Logger;
42 import org.slf4j.LoggerFactory;
47 * Listener to handle flow capable node updates.
49 @SuppressWarnings("deprecation")
50 public class AclNodeListener extends AsyncDataTreeChangeListenerBase<FlowCapableNode, AclNodeListener>
51 implements AutoCloseable {
53 /** The Constant LOG. */
54 private static final Logger LOG = LoggerFactory.getLogger(AclNodeListener.class);
56 /** The mdsal manager. */
57 private final IMdsalApiManager mdsalManager;
59 /** The data broker. */
60 private final DataBroker dataBroker;
62 private SecurityGroupMode securityGroupMode = null;
64 private AclserviceConfig config;
67 * Instantiates a new acl node listener.
69 * @param mdsalManager the mdsal manager
70 * @param dataBroker the data broker
71 * @param config aclservice configuration
73 public AclNodeListener(final IMdsalApiManager mdsalManager, DataBroker dataBroker, AclserviceConfig config) {
74 super(FlowCapableNode.class, AclNodeListener.class);
76 this.mdsalManager = mdsalManager;
77 this.dataBroker = dataBroker;
82 LOG.info("{} start", getClass().getSimpleName());
84 this.securityGroupMode = config.getSecurityGroupMode();
86 registerListener(LogicalDatastoreType.OPERATIONAL, dataBroker);
87 LOG.info("AclserviceConfig: {}", this.config);
94 * org.opendaylight.genius.datastoreutils.AsyncDataTreeChangeListenerBase#
98 protected InstanceIdentifier<FlowCapableNode> getWildCardPath() {
99 return InstanceIdentifier.create(Nodes.class).child(Node.class).augmentation(FlowCapableNode.class);
106 * org.opendaylight.genius.datastoreutils.AsyncDataTreeChangeListenerBase#
107 * remove(org.opendaylight.yangtools.yang.binding.InstanceIdentifier,
108 * org.opendaylight.yangtools.yang.binding.DataObject)
111 protected void remove(InstanceIdentifier<FlowCapableNode> key, FlowCapableNode dataObjectModification) {
120 * org.opendaylight.genius.datastoreutils.AsyncDataTreeChangeListenerBase#
121 * update(org.opendaylight.yangtools.yang.binding.InstanceIdentifier,
122 * org.opendaylight.yangtools.yang.binding.DataObject,
123 * org.opendaylight.yangtools.yang.binding.DataObject)
126 protected void update(InstanceIdentifier<FlowCapableNode> key, FlowCapableNode dataObjectModificationBefore,
127 FlowCapableNode dataObjectModificationAfter) {
136 * org.opendaylight.genius.datastoreutils.AsyncDataTreeChangeListenerBase#
137 * add(org.opendaylight.yangtools.yang.binding.InstanceIdentifier,
138 * org.opendaylight.yangtools.yang.binding.DataObject)
141 protected void add(InstanceIdentifier<FlowCapableNode> key, FlowCapableNode dataObjectModification) {
142 LOG.trace("FlowCapableNode Added: key: {}", key);
143 if (!AclClusterUtil.isEntityOwner()) {
146 NodeKey nodeKey = key.firstKeyOf(Node.class);
147 BigInteger dpnId = MDSALUtil.getDpnIdFromNodeName(nodeKey.getId());
148 createTableDefaultEntries(dpnId);
152 * Creates the table miss entries.
154 * @param dpnId the dpn id
156 private void createTableDefaultEntries(BigInteger dpnId) {
157 LOG.info("Adding default ACL entries for mode: "
158 + (securityGroupMode == null ? SecurityGroupMode.Stateful : securityGroupMode));
159 if (securityGroupMode == null || securityGroupMode == SecurityGroupMode.Stateful) {
160 addIngressAclTableMissFlow(dpnId);
161 addEgressAclTableMissFlow(dpnId);
162 addConntrackRules(dpnId, NwConstants.LPORT_DISPATCHER_TABLE, NwConstants.INGRESS_ACL_FILTER_TABLE,
163 NwConstants.ADD_FLOW);
164 addConntrackRules(dpnId, NwConstants.EGRESS_LPORT_DISPATCHER_TABLE, NwConstants.EGRESS_ACL_FILTER_TABLE,
165 NwConstants.ADD_FLOW);
166 } else if (securityGroupMode == SecurityGroupMode.Transparent) {
167 addTransparentIngressAclTableMissFlow(dpnId);
168 addTransparentEgressAclTableMissFlow(dpnId);
169 } else if (securityGroupMode == SecurityGroupMode.Stateless) {
170 addStatelessIngressAclTableMissFlow(dpnId);
171 addStatelessEgressAclTableMissFlow(dpnId);
172 } else if (securityGroupMode == SecurityGroupMode.Learn) {
173 addLearnIngressAclTableMissFlow(dpnId);
174 addLearnEgressAclTableMissFlow(dpnId);
179 * Adds the ingress acl table miss flow.
181 * @param dpId the dp id
183 private void addIngressAclTableMissFlow(BigInteger dpId) {
184 List<MatchInfo> mkMatches = new ArrayList<>();
185 List<InstructionInfo> mkInstructions = new ArrayList<>();
186 List<ActionInfo> actionsInfos = new ArrayList<>();
187 actionsInfos.add(new ActionInfo(ActionType.drop_action, new String[] {}));
188 mkInstructions.add(new InstructionInfo(InstructionType.apply_actions, actionsInfos));
190 FlowEntity flowEntity = MDSALUtil.buildFlowEntity(dpId, NwConstants.EGRESS_ACL_TABLE,
191 getTableMissFlowId(NwConstants.EGRESS_ACL_TABLE), 0, "Ingress ACL Table Miss Flow", 0, 0,
192 AclConstants.COOKIE_ACL_BASE, mkMatches, mkInstructions);
193 mdsalManager.installFlow(flowEntity);
195 FlowEntity nextTblFlowEntity = MDSALUtil.buildFlowEntity(dpId, NwConstants.EGRESS_ACL_FILTER_TABLE,
196 getTableMissFlowId(NwConstants.EGRESS_ACL_FILTER_TABLE), 0, "Ingress ACL Filter Table Miss Flow",
197 0, 0, AclConstants.COOKIE_ACL_BASE, mkMatches, mkInstructions);
198 mdsalManager.installFlow(nextTblFlowEntity);
200 LOG.debug("Added Ingress ACL Table Miss Flows for dpn {}", dpId);
203 private void addLearnEgressAclTableMissFlow(BigInteger dpId) {
204 List<InstructionInfo> mkInstructions = new ArrayList<>();
205 List<ActionInfo> actionsInfos = new ArrayList<>();
206 actionsInfos.add(new ActionInfo(ActionType.nx_resubmit,
207 new String[] {Short.toString(NwConstants.EGRESS_LEARN_TABLE) }));
208 actionsInfos.add(new ActionInfo(ActionType.nx_resubmit,
209 new String[] {Short.toString(NwConstants.EGRESS_LEARN2_TABLE) }));
210 mkInstructions.add(new InstructionInfo(InstructionType.apply_actions, actionsInfos));
212 List<MatchInfo> mkMatches = new ArrayList<>();
213 FlowEntity doubleResubmitTable = MDSALUtil.buildFlowEntity(dpId, NwConstants.EGRESS_ACL_TABLE,
214 "RESUB-" + getTableMissFlowId(NwConstants.EGRESS_ACL_TABLE),
215 AclConstants.PROTO_MATCH_PRIORITY, "Egress resubmit ACL Table Block", 0, 0,
216 AclConstants.COOKIE_ACL_BASE, mkMatches, mkInstructions);
217 mdsalManager.installFlow(doubleResubmitTable);
219 mkMatches = new ArrayList<>();
220 mkInstructions = new ArrayList<>();
221 actionsInfos = new ArrayList<>();
222 actionsInfos.add(new ActionInfo(ActionType.drop_action, new String[] {}));
223 mkInstructions.add(new InstructionInfo(InstructionType.apply_actions, actionsInfos));
225 FlowEntity flowEntity = MDSALUtil.buildFlowEntity(dpId, NwConstants.EGRESS_LEARN_TABLE,
226 "LEARN-" + getTableMissFlowId(NwConstants.EGRESS_LEARN_TABLE), 0,
227 "Egress Learn ACL Table Miss Flow", 0, 0,
228 AclConstants.COOKIE_ACL_BASE, mkMatches, mkInstructions);
229 mdsalManager.installFlow(flowEntity);
231 flowEntity = MDSALUtil.buildFlowEntity(dpId, NwConstants.EGRESS_LEARN2_TABLE,
232 "LEARN-" + getTableMissFlowId(NwConstants.EGRESS_LEARN2_TABLE), 0,
233 "Egress 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_6,
239 new long[] {Long.valueOf(AclConstants.LEARN_MATCH_REG_VALUE)}));
241 short dispatcherTableId = NwConstants.EGRESS_LPORT_DISPATCHER_TABLE;
242 List<InstructionInfo> instructions = new ArrayList<>();
243 actionsInfos.add(new ActionInfo(ActionType.nx_resubmit, new String[] {Short.toString(dispatcherTableId)}));
244 instructions.add(new InstructionInfo(InstructionType.apply_actions, actionsInfos));
246 flowEntity = MDSALUtil.buildFlowEntity(dpId, NwConstants.EGRESS_LEARN2_TABLE,
247 "LEARN2-REG-" + getTableMissFlowId(NwConstants.EGRESS_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);
254 private void addLearnIngressAclTableMissFlow(BigInteger dpId) {
255 List<InstructionInfo> mkInstructions = new ArrayList<>();
256 List<ActionInfo> actionsInfos = new ArrayList<>();
257 actionsInfos.add(new ActionInfo(ActionType.nx_resubmit,
258 new String[] {Short.toString(NwConstants.INGRESS_LEARN_TABLE) }));
259 actionsInfos.add(new ActionInfo(ActionType.nx_resubmit,
260 new String[] {Short.toString(NwConstants.INGRESS_LEARN2_TABLE) }));
261 mkInstructions.add(new InstructionInfo(InstructionType.apply_actions, actionsInfos));
263 List<MatchInfo> mkMatches = new ArrayList<>();
264 FlowEntity doubleResubmitTable = MDSALUtil.buildFlowEntity(dpId, NwConstants.INGRESS_ACL_TABLE,
265 "RESUB-" + getTableMissFlowId(NwConstants.INGRESS_ACL_TABLE),
266 AclConstants.PROTO_MATCH_PRIORITY, "Ingress resubmit ACL Table Block", 0, 0,
267 AclConstants.COOKIE_ACL_BASE, mkMatches, mkInstructions);
268 mdsalManager.installFlow(doubleResubmitTable);
270 mkMatches = new ArrayList<>();
271 mkInstructions = new ArrayList<>();
272 actionsInfos = new ArrayList<>();
273 actionsInfos.add(new ActionInfo(ActionType.drop_action, new String[] {}));
274 mkInstructions.add(new InstructionInfo(InstructionType.apply_actions, actionsInfos));
276 FlowEntity flowEntity = MDSALUtil.buildFlowEntity(dpId, NwConstants.INGRESS_LEARN_TABLE,
277 "LEARN-" + getTableMissFlowId(NwConstants.INGRESS_LEARN_TABLE), 0,
278 "Ingress Learn ACL Table Miss Flow", 0, 0,
279 AclConstants.COOKIE_ACL_BASE, mkMatches, mkInstructions);
280 mdsalManager.installFlow(flowEntity);
282 flowEntity = MDSALUtil.buildFlowEntity(dpId, NwConstants.INGRESS_LEARN2_TABLE,
283 "LEARN-" + getTableMissFlowId(NwConstants.INGRESS_LEARN2_TABLE), 0,
284 "Ingress Learn2 ACL Table Miss Flow", 0, 0,
285 AclConstants.COOKIE_ACL_BASE, mkMatches, mkInstructions);
286 mdsalManager.installFlow(flowEntity);
288 List<NxMatchInfo> nxMkMatches = new ArrayList<>();
289 nxMkMatches.add(new NxMatchInfo(NxMatchFieldType.nxm_reg_6,
290 new long[] {Long.valueOf(AclConstants.LEARN_MATCH_REG_VALUE)}));
292 short dispatcherTableId = NwConstants.LPORT_DISPATCHER_TABLE;
293 List<InstructionInfo> instructions = new ArrayList<>();
294 actionsInfos.add(new ActionInfo(ActionType.nx_resubmit, new String[] {Short.toString(dispatcherTableId)}));
295 instructions.add(new InstructionInfo(InstructionType.apply_actions, actionsInfos));
297 flowEntity = MDSALUtil.buildFlowEntity(dpId, NwConstants.INGRESS_LEARN2_TABLE,
298 "LEARN2-REG-" + getTableMissFlowId(NwConstants.INGRESS_LEARN2_TABLE),
299 AclConstants.PROTO_MATCH_PRIORITY, "Egress Learn2 ACL Table match reg Flow", 0, 0,
300 AclConstants.COOKIE_ACL_BASE, nxMkMatches, instructions);
301 mdsalManager.installFlow(flowEntity);
302 LOG.debug("Added learn ACL Table Miss Flows for dpn {}", dpId);
307 * Adds the ingress acl table transparent flow.
309 * @param dpId the dp id
311 private void addTransparentIngressAclTableMissFlow(BigInteger dpId) {
312 List<MatchInfo> mkMatches = new ArrayList<>();
313 List<InstructionInfo> allowAllInstructions = new ArrayList<>();
314 allowAllInstructions.add(
315 new InstructionInfo(InstructionType.goto_table,
316 new long[] { NwConstants.INGRESS_ACL_FILTER_TABLE }));
318 FlowEntity nextTblFlowEntity = MDSALUtil.buildFlowEntity(dpId, NwConstants.INGRESS_ACL_TABLE,
319 getTableMissFlowId(NwConstants.INGRESS_ACL_TABLE), 0, "Ingress ACL Table allow all Flow",
320 0, 0, AclConstants.COOKIE_ACL_BASE, mkMatches, allowAllInstructions);
321 mdsalManager.installFlow(nextTblFlowEntity);
323 short dispatcherTableId = NwConstants.LPORT_DISPATCHER_TABLE;
325 List<ActionInfo> actionsInfos = new ArrayList<>();
326 List<InstructionInfo> dispatcherInstructions = new ArrayList<>();
327 actionsInfos.add(new ActionInfo(ActionType.nx_resubmit, new String[] {Short.toString(dispatcherTableId)}));
328 dispatcherInstructions.add(new InstructionInfo(InstructionType.apply_actions, actionsInfos));
330 nextTblFlowEntity = MDSALUtil.buildFlowEntity(dpId, NwConstants.INGRESS_ACL_FILTER_TABLE,
331 getTableMissFlowId(NwConstants.INGRESS_ACL_FILTER_TABLE), 0, "Ingress ACL Filter Table allow all Flow",
332 0, 0, AclConstants.COOKIE_ACL_BASE, mkMatches, dispatcherInstructions);
333 mdsalManager.installFlow(nextTblFlowEntity);
335 LOG.debug("Added Transparent Ingress ACL Table allow all Flows for dpn {}", dpId);
339 * Adds the egress acl table transparent flow.
341 * @param dpId the dp id
343 private void addTransparentEgressAclTableMissFlow(BigInteger dpId) {
344 List<MatchInfo> mkMatches = new ArrayList<>();
345 List<InstructionInfo> allowAllInstructions = new ArrayList<>();
346 allowAllInstructions.add(
347 new InstructionInfo(InstructionType.goto_table,
348 new long[] { NwConstants.EGRESS_ACL_FILTER_TABLE }));
350 FlowEntity nextTblFlowEntity = MDSALUtil.buildFlowEntity(dpId, NwConstants.EGRESS_ACL_TABLE,
351 getTableMissFlowId(NwConstants.EGRESS_ACL_TABLE), 0, "Egress ACL Table allow all Flow",
352 0, 0, AclConstants.COOKIE_ACL_BASE, mkMatches, allowAllInstructions);
353 mdsalManager.installFlow(nextTblFlowEntity);
355 short dispatcherTableId = NwConstants.EGRESS_LPORT_DISPATCHER_TABLE;
357 List<ActionInfo> actionsInfos = new ArrayList<>();
358 List<InstructionInfo> instructions = new ArrayList<>();
359 actionsInfos.add(new ActionInfo(ActionType.nx_resubmit, new String[] {Short.toString(dispatcherTableId)}));
360 instructions.add(new InstructionInfo(InstructionType.apply_actions, actionsInfos));
362 nextTblFlowEntity = MDSALUtil.buildFlowEntity(dpId, NwConstants.EGRESS_ACL_FILTER_TABLE,
363 getTableMissFlowId(NwConstants.EGRESS_ACL_FILTER_TABLE), 0, "Egress ACL Filter Table allow all Flow",
364 0, 0, AclConstants.COOKIE_ACL_BASE, mkMatches, instructions);
365 mdsalManager.installFlow(nextTblFlowEntity);
367 LOG.debug("Added Transparent Egress ACL Table allow all Flows for dpn {}", dpId);
371 * Adds the ingress acl table miss flow.
373 * @param dpId the dp id
375 private void addStatelessIngressAclTableMissFlow(BigInteger dpId) {
376 List<MatchInfo> synMatches = new ArrayList<>();
377 synMatches.add(new MatchInfo(MatchFieldType.eth_type,
378 new long[] { NwConstants.ETHTYPE_IPV4 }));
379 synMatches.add(new MatchInfo(MatchFieldType.ip_proto,
380 new long[] { IPProtocols.TCP.intValue() }));
382 synMatches.add(new MatchInfo(MatchFieldType.tcp_flags, new long[] { AclConstants.TCP_FLAG_SYN }));
384 List<ActionInfo> dropActionsInfos = new ArrayList<>();
385 dropActionsInfos.add(new ActionInfo(ActionType.drop_action, new String[] {}));
386 List<InstructionInfo> synInstructions = new ArrayList<>();
387 synInstructions.add(new InstructionInfo(InstructionType.apply_actions, dropActionsInfos));
389 FlowEntity synFlowEntity = MDSALUtil.buildFlowEntity(dpId, NwConstants.EGRESS_ACL_TABLE,
390 "SYN-" + getTableMissFlowId(NwConstants.EGRESS_ACL_TABLE),
391 AclConstants.PROTO_MATCH_SYN_DROP_PRIORITY, "Ingress Syn ACL Table Block", 0, 0,
392 AclConstants.COOKIE_ACL_BASE, synMatches, synInstructions);
393 mdsalManager.installFlow(synFlowEntity);
395 synMatches = new ArrayList<>();
396 synMatches.add(new MatchInfo(MatchFieldType.eth_type,
397 new long[] { NwConstants.ETHTYPE_IPV4 }));
398 synMatches.add(new MatchInfo(MatchFieldType.ip_proto,
399 new long[] { IPProtocols.TCP.intValue() }));
400 synMatches.add(new MatchInfo(MatchFieldType.tcp_flags, new long[] { AclConstants.TCP_FLAG_SYN_ACK }));
402 List<InstructionInfo> allowAllInstructions = new ArrayList<>();
403 allowAllInstructions.add(
404 new InstructionInfo(InstructionType.goto_table,
405 new long[] { NwConstants.EGRESS_ACL_FILTER_TABLE }));
407 FlowEntity synAckFlowEntity = MDSALUtil.buildFlowEntity(dpId, NwConstants.EGRESS_ACL_TABLE,
408 "SYN-ACK-ALLOW-" + getTableMissFlowId(NwConstants.EGRESS_ACL_TABLE),
409 AclConstants.PROTO_MATCH_SYN_ACK_ALLOW_PRIORITY, "Ingress Syn Ack ACL Table Allow", 0, 0,
410 AclConstants.COOKIE_ACL_BASE, synMatches, allowAllInstructions);
411 mdsalManager.installFlow(synAckFlowEntity);
414 List<MatchInfo> mkMatches = new ArrayList<>();
415 FlowEntity flowEntity = MDSALUtil.buildFlowEntity(dpId, NwConstants.EGRESS_ACL_TABLE,
416 getTableMissFlowId(NwConstants.EGRESS_ACL_TABLE), 0, "Ingress Stateless ACL Table Miss Flow",
417 0, 0, AclConstants.COOKIE_ACL_BASE, mkMatches, allowAllInstructions);
418 mdsalManager.installFlow(flowEntity);
420 short dispatcherTableId = NwConstants.EGRESS_LPORT_DISPATCHER_TABLE;
422 List<ActionInfo> actionsInfos = new ArrayList<>();
423 List<InstructionInfo> instructions = new ArrayList<>();
424 actionsInfos.add(new ActionInfo(ActionType.nx_resubmit, new String[] {Short.toString(dispatcherTableId)}));
425 instructions.add(new InstructionInfo(InstructionType.apply_actions, actionsInfos));
427 FlowEntity nextTblFlowEntity = MDSALUtil.buildFlowEntity(dpId, NwConstants.EGRESS_ACL_FILTER_TABLE,
428 getTableMissFlowId(NwConstants.EGRESS_ACL_FILTER_TABLE), 0,
429 "Ingress Stateless Next ACL Table Miss Flow", 0, 0, AclConstants.COOKIE_ACL_BASE,
430 mkMatches, instructions);
431 mdsalManager.installFlow(nextTblFlowEntity);
433 LOG.debug("Added Stateless Ingress ACL Table Miss Flows for dpn {}.", dpId);
437 * Adds the stateless egress acl table miss flow.
439 * @param dpId the dp id
441 private void addStatelessEgressAclTableMissFlow(BigInteger dpId) {
442 List<InstructionInfo> allowAllInstructions = new ArrayList<>();
443 allowAllInstructions.add(
444 new InstructionInfo(InstructionType.goto_table, new long[] { NwConstants.INGRESS_ACL_FILTER_TABLE }));
446 List<MatchInfo> synMatches = new ArrayList<>();
447 synMatches.add(new MatchInfo(MatchFieldType.eth_type,
448 new long[] { NwConstants.ETHTYPE_IPV4 }));
449 synMatches.add(new MatchInfo(MatchFieldType.ip_proto,
450 new long[] { IPProtocols.TCP.intValue() }));
451 synMatches.add(new MatchInfo(MatchFieldType.tcp_flags, new long[] { AclConstants.TCP_FLAG_SYN }));
453 List<ActionInfo> synActionsInfos = new ArrayList<>();
454 synActionsInfos.add(new ActionInfo(ActionType.drop_action, new String[] {}));
455 List<InstructionInfo> synInstructions = new ArrayList<>();
456 synInstructions.add(new InstructionInfo(InstructionType.apply_actions, synActionsInfos));
458 FlowEntity synFlowEntity = MDSALUtil.buildFlowEntity(dpId, NwConstants.INGRESS_ACL_TABLE,
459 "SYN-" + getTableMissFlowId(NwConstants.INGRESS_ACL_TABLE),
460 AclConstants.PROTO_MATCH_SYN_DROP_PRIORITY, "Egress Syn ACL Table Block", 0, 0,
461 AclConstants.COOKIE_ACL_BASE, synMatches, synInstructions);
462 mdsalManager.installFlow(synFlowEntity);
464 synMatches = new ArrayList<>();
465 synMatches.add(new MatchInfo(MatchFieldType.eth_type,
466 new long[] { NwConstants.ETHTYPE_IPV4 }));
467 synMatches.add(new MatchInfo(MatchFieldType.ip_proto,
468 new long[] { IPProtocols.TCP.intValue() }));
469 synMatches.add(new MatchInfo(MatchFieldType.tcp_flags, new long[] { AclConstants.TCP_FLAG_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 ActionInfo(ActionType.nx_resubmit, new String[] {Short.toString(dispatcherTableId)}));
488 dispatcherInstructions.add(new InstructionInfo(InstructionType.apply_actions, actionsInfos));
490 FlowEntity nextTblFlowEntity = MDSALUtil.buildFlowEntity(dpId, NwConstants.INGRESS_ACL_FILTER_TABLE,
491 getTableMissFlowId(NwConstants.INGRESS_ACL_FILTER_TABLE), 0,
492 "Egress Stateless Next ACL Table Miss Flow", 0, 0, AclConstants.COOKIE_ACL_BASE, mkMatches,
493 dispatcherInstructions);
494 mdsalManager.installFlow(nextTblFlowEntity);
496 LOG.debug("Added Stateless Egress ACL Table Miss Flows for dpn {}", dpId);
500 * Adds the egress acl table miss flow.
502 * @param dpId the dp id
504 private void addEgressAclTableMissFlow(BigInteger dpId) {
505 List<MatchInfo> mkMatches = new ArrayList<>();
506 List<InstructionInfo> mkInstructions = new ArrayList<>();
507 List<ActionInfo> actionsInfos = new ArrayList<>();
508 actionsInfos.add(new ActionInfo(ActionType.drop_action, new String[] {}));
509 mkInstructions.add(new InstructionInfo(InstructionType.apply_actions, actionsInfos));
511 FlowEntity flowEntity = MDSALUtil.buildFlowEntity(dpId, NwConstants.INGRESS_ACL_TABLE,
512 getTableMissFlowId(NwConstants.INGRESS_ACL_TABLE), 0, "Egress ACL Table Miss Flow", 0, 0,
513 AclConstants.COOKIE_ACL_BASE, mkMatches, mkInstructions);
514 mdsalManager.installFlow(flowEntity);
516 FlowEntity nextTblFlowEntity = MDSALUtil.buildFlowEntity(dpId, NwConstants.INGRESS_ACL_FILTER_TABLE,
517 getTableMissFlowId(NwConstants.INGRESS_ACL_FILTER_TABLE), 0, "Egress ACL Table Miss Flow", 0, 0,
518 AclConstants.COOKIE_ACL_BASE, mkMatches, mkInstructions);
519 mdsalManager.installFlow(nextTblFlowEntity);
521 LOG.debug("Added Egress ACL Table Miss Flows for dpn {}", dpId);
524 private void addConntrackRules(BigInteger dpnId, short dispatcherTableId,short tableId, int write) {
525 programConntrackForwardRule(dpnId, AclConstants.CT_STATE_TRACKED_EXIST_PRIORITY,
526 "Tracked_Established", AclConstants.TRACKED_EST_CT_STATE, AclConstants.TRACKED_EST_CT_STATE_MASK,
527 dispatcherTableId, tableId, write );
528 programConntrackForwardRule(dpnId, AclConstants.CT_STATE_TRACKED_EXIST_PRIORITY,"Tracked_Related", AclConstants
529 .TRACKED_REL_CT_STATE, AclConstants.TRACKED_REL_CT_STATE_MASK, dispatcherTableId, tableId, write );
530 programConntrackDropRule(dpnId, AclConstants.CT_STATE_NEW_PRIORITY_DROP,"Tracked_New",
531 AclConstants.TRACKED_NEW_CT_STATE, AclConstants.TRACKED_NEW_CT_STATE_MASK, tableId, write );
532 programConntrackDropRule(dpnId, AclConstants.CT_STATE_NEW_PRIORITY_DROP, "Tracked_Invalid",
533 AclConstants.TRACKED_INV_CT_STATE, AclConstants.TRACKED_INV_CT_STATE_MASK, tableId, write );
538 * Adds the rule to forward the packets known packets.
540 * @param dpId the dpId
541 * @param lportTag the lport tag
542 * @param priority the priority of the flow
543 * @param flowId the flowId
544 * @param conntrackState the conntrack state of the packets thats should be
546 * @param conntrackMask the conntrack mask
547 * @param addOrRemove whether to add or remove the flow
549 private void programConntrackForwardRule(BigInteger dpId, Integer priority, String flowId,
550 int conntrackState, int conntrackMask, short dispatcherTableId, short tableId, int addOrRemove) {
551 List<MatchInfoBase> matches = new ArrayList<>();
552 matches.add(new NxMatchInfo(NxMatchFieldType.ct_state, new long[] {conntrackState, conntrackMask}));
554 List<InstructionInfo> instructions = getDispatcherTableResubmitInstructions(
555 new ArrayList<>(),dispatcherTableId);
557 flowId = "Fixed_Conntrk_Trk_" + dpId + "_" + flowId + dispatcherTableId;
558 syncFlow(dpId, tableId, flowId, priority, "ACL", 0, 0,
559 AclConstants.COOKIE_ACL_BASE, matches, instructions, addOrRemove);
563 * Adds the rule to drop the unknown/invalid packets .
565 * @param dpId the dpId
566 * @param lportTag the lport tag
567 * @param priority the priority of the flow
568 * @param flowId the flowId
569 * @param conntrackState the conntrack state of the packets thats should be
571 * @param conntrackMask the conntrack mask
572 * @param addOrRemove whether to add or remove the flow
574 private void programConntrackDropRule(BigInteger dpId, Integer priority, String flowId,
575 int conntrackState, int conntrackMask, short tableId, int addOrRemove) {
576 List<MatchInfoBase> matches = new ArrayList<>();
577 matches.add(new NxMatchInfo(NxMatchFieldType.ct_state, new long[] {conntrackState, conntrackMask}));
579 List<InstructionInfo> instructions = new ArrayList<>();
580 List<ActionInfo> actionsInfos = new ArrayList<>();
581 actionsInfos.add(new ActionInfo(ActionType.drop_action, new String[] {}));
582 instructions.add(new InstructionInfo(InstructionType.write_actions, actionsInfos));
583 flowId = "Fixed_Conntrk_NewDrop_" + dpId + "_" + flowId + tableId;
584 syncFlow(dpId, tableId, flowId, priority, "ACL", 0, 0,
585 AclConstants.COOKIE_ACL_BASE, matches, instructions, addOrRemove);
589 * Gets the dispatcher table resubmit instructions.
591 * @param actionsInfos the actions infos
592 * @return the instructions for dispatcher table resubmit
594 private List<InstructionInfo> getDispatcherTableResubmitInstructions(List<ActionInfo> actionsInfos,
595 short dispatcherTableId) {
596 List<InstructionInfo> instructions = new ArrayList<>();
597 actionsInfos.add(new ActionInfo(ActionType.nx_resubmit, new String[] {Short.toString(dispatcherTableId)}));
598 instructions.add(new InstructionInfo(InstructionType.apply_actions, actionsInfos));
603 * Writes/remove the flow to/from the datastore.
604 * @param dpId the dpId
605 * @param tableId the tableId
606 * @param flowId the flowId
607 * @param priority the priority
608 * @param flowName the flow name
609 * @param idleTimeOut the idle timeout
610 * @param hardTimeOut the hard timeout
611 * @param cookie the cookie
612 * @param matches the list of matches to be written
613 * @param instructions the list of instruction to be written.
614 * @param addOrRemove add or remove the entries.
616 protected void syncFlow(BigInteger dpId, short tableId, String flowId, int priority, String flowName,
617 int idleTimeOut, int hardTimeOut, BigInteger cookie, List<? extends MatchInfoBase> matches,
618 List<InstructionInfo> instructions, int addOrRemove) {
619 if (addOrRemove == NwConstants.DEL_FLOW) {
620 FlowEntity flowEntity = MDSALUtil.buildFlowEntity(dpId, tableId,flowId,
621 priority, flowName , idleTimeOut, hardTimeOut, cookie, matches, null);
622 LOG.trace("Removing Acl Flow DpnId {}, flowId {}", dpId, flowId);
623 mdsalManager.removeFlow(flowEntity);
625 FlowEntity flowEntity = MDSALUtil.buildFlowEntity(dpId, tableId, flowId,
626 priority, flowName, idleTimeOut, hardTimeOut, cookie, matches, instructions);
627 LOG.trace("Installing DpnId {}, flowId {}", dpId, flowId);
628 mdsalManager.installFlow(flowEntity);
633 * Gets the table miss flow id.
635 * @param tableId the table id
636 * @return the table miss flow id
638 private String getTableMissFlowId(short tableId) {
639 return String.valueOf(tableId);
646 * org.opendaylight.genius.datastoreutils.AsyncDataTreeChangeListenerBase#
647 * getDataTreeChangeListener()
650 protected AclNodeListener getDataTreeChangeListener() {
651 return AclNodeListener.this;