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.ActionType;
22 import org.opendaylight.genius.mdsalutil.FlowEntity;
23 import org.opendaylight.genius.mdsalutil.InstructionInfo;
24 import org.opendaylight.genius.mdsalutil.InstructionType;
25 import org.opendaylight.genius.mdsalutil.MDSALUtil;
26 import org.opendaylight.genius.mdsalutil.MatchFieldType;
27 import org.opendaylight.genius.mdsalutil.MatchInfo;
28 import org.opendaylight.genius.mdsalutil.MatchInfoBase;
29 import org.opendaylight.genius.mdsalutil.NwConstants;
30 import org.opendaylight.genius.mdsalutil.NxMatchFieldType;
31 import org.opendaylight.genius.mdsalutil.NxMatchInfo;
32 import org.opendaylight.genius.mdsalutil.interfaces.IMdsalApiManager;
33 import org.opendaylight.genius.mdsalutil.packet.IPProtocols;
34 import org.opendaylight.netvirt.aclservice.utils.AclClusterUtil;
35 import org.opendaylight.netvirt.aclservice.utils.AclConstants;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.aclservice.config.rev160806.AclserviceConfig;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.aclservice.config.rev160806.AclserviceConfig.SecurityGroupMode;
42 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
43 import org.slf4j.Logger;
44 import org.slf4j.LoggerFactory;
47 * Listener to handle flow capable node updates.
50 @SuppressWarnings("deprecation")
51 public class AclNodeListener extends AsyncDataTreeChangeListenerBase<FlowCapableNode, AclNodeListener>
52 implements AutoCloseable {
54 private static final Logger LOG = LoggerFactory.getLogger(AclNodeListener.class);
56 private final IMdsalApiManager mdsalManager;
57 private final AclClusterUtil aclClusterUtil;
58 private final AclserviceConfig config;
59 private final DataBroker dataBroker;
61 private SecurityGroupMode securityGroupMode = null;
64 public AclNodeListener(final IMdsalApiManager mdsalManager, DataBroker dataBroker, AclserviceConfig config,
65 AclClusterUtil aclClusterUtil) {
66 super(FlowCapableNode.class, AclNodeListener.class);
68 this.mdsalManager = mdsalManager;
69 this.aclClusterUtil = aclClusterUtil;
70 this.dataBroker = dataBroker;
77 LOG.info("{} start", getClass().getSimpleName());
79 this.securityGroupMode = config.getSecurityGroupMode();
81 registerListener(LogicalDatastoreType.OPERATIONAL, dataBroker);
82 LOG.info("AclserviceConfig: {}", this.config);
86 protected InstanceIdentifier<FlowCapableNode> getWildCardPath() {
87 return InstanceIdentifier.create(Nodes.class).child(Node.class).augmentation(FlowCapableNode.class);
91 protected void remove(InstanceIdentifier<FlowCapableNode> key, FlowCapableNode dataObjectModification) {
96 protected void update(InstanceIdentifier<FlowCapableNode> key, FlowCapableNode dataObjectModificationBefore,
97 FlowCapableNode dataObjectModificationAfter) {
102 protected void add(InstanceIdentifier<FlowCapableNode> key, FlowCapableNode dataObjectModification) {
103 LOG.trace("FlowCapableNode Added: key: {}", key);
104 if (!aclClusterUtil.isEntityOwner()) {
107 NodeKey nodeKey = key.firstKeyOf(Node.class);
108 BigInteger dpnId = MDSALUtil.getDpnIdFromNodeName(nodeKey.getId());
109 createTableDefaultEntries(dpnId);
113 * Creates the table miss entries.
115 * @param dpnId the dpn id
117 private void createTableDefaultEntries(BigInteger dpnId) {
118 LOG.info("Adding default ACL entries for mode: "
119 + (securityGroupMode == null ? SecurityGroupMode.Stateful : securityGroupMode));
120 if (securityGroupMode == null || securityGroupMode == SecurityGroupMode.Stateful) {
121 addIngressAclTableMissFlow(dpnId);
122 addEgressAclTableMissFlow(dpnId);
123 addConntrackRules(dpnId, NwConstants.LPORT_DISPATCHER_TABLE, NwConstants.INGRESS_ACL_FILTER_TABLE,
124 NwConstants.ADD_FLOW);
125 addConntrackRules(dpnId, NwConstants.EGRESS_LPORT_DISPATCHER_TABLE, NwConstants.EGRESS_ACL_FILTER_TABLE,
126 NwConstants.ADD_FLOW);
127 } else if (securityGroupMode == SecurityGroupMode.Transparent) {
128 addTransparentIngressAclTableMissFlow(dpnId);
129 addTransparentEgressAclTableMissFlow(dpnId);
130 } else if (securityGroupMode == SecurityGroupMode.Stateless) {
131 addStatelessIngressAclTableMissFlow(dpnId);
132 addStatelessEgressAclTableMissFlow(dpnId);
133 } else if (securityGroupMode == SecurityGroupMode.Learn) {
134 addLearnIngressAclTableMissFlow(dpnId);
135 addLearnEgressAclTableMissFlow(dpnId);
140 * Adds the ingress acl table miss flow.
142 * @param dpId the dp id
144 private void addIngressAclTableMissFlow(BigInteger dpId) {
145 List<MatchInfo> mkMatches = new ArrayList<>();
146 List<InstructionInfo> mkInstructions = new ArrayList<>();
147 List<ActionInfo> actionsInfos = new ArrayList<>();
148 actionsInfos.add(new ActionInfo(ActionType.drop_action, new String[] {}));
149 mkInstructions.add(new InstructionInfo(InstructionType.apply_actions, actionsInfos));
151 FlowEntity flowEntity = MDSALUtil.buildFlowEntity(dpId, NwConstants.EGRESS_ACL_TABLE,
152 getTableMissFlowId(NwConstants.EGRESS_ACL_TABLE), 0, "Ingress ACL Table Miss Flow", 0, 0,
153 AclConstants.COOKIE_ACL_BASE, mkMatches, mkInstructions);
154 mdsalManager.installFlow(flowEntity);
156 FlowEntity nextTblFlowEntity = MDSALUtil.buildFlowEntity(dpId, NwConstants.EGRESS_ACL_FILTER_TABLE,
157 getTableMissFlowId(NwConstants.EGRESS_ACL_FILTER_TABLE), 0, "Ingress ACL Filter Table Miss Flow",
158 0, 0, AclConstants.COOKIE_ACL_BASE, mkMatches, mkInstructions);
159 mdsalManager.installFlow(nextTblFlowEntity);
161 LOG.debug("Added Ingress ACL Table Miss Flows for dpn {}", dpId);
164 private void addLearnEgressAclTableMissFlow(BigInteger dpId) {
165 List<InstructionInfo> mkInstructions = new ArrayList<>();
166 List<ActionInfo> actionsInfos = new ArrayList<>();
167 actionsInfos.add(new ActionInfo(ActionType.nx_resubmit,
168 new String[] {Short.toString(NwConstants.EGRESS_LEARN_TABLE) }));
169 actionsInfos.add(new ActionInfo(ActionType.nx_resubmit,
170 new String[] {Short.toString(NwConstants.EGRESS_LEARN2_TABLE) }));
171 mkInstructions.add(new InstructionInfo(InstructionType.apply_actions, actionsInfos));
173 List<MatchInfo> mkMatches = new ArrayList<>();
174 FlowEntity doubleResubmitTable = MDSALUtil.buildFlowEntity(dpId, NwConstants.EGRESS_ACL_TABLE,
175 "RESUB-" + getTableMissFlowId(NwConstants.EGRESS_ACL_TABLE),
176 AclConstants.PROTO_MATCH_PRIORITY, "Egress resubmit ACL Table Block", 0, 0,
177 AclConstants.COOKIE_ACL_BASE, mkMatches, mkInstructions);
178 mdsalManager.installFlow(doubleResubmitTable);
180 mkMatches = new ArrayList<>();
181 mkInstructions = new ArrayList<>();
182 actionsInfos = new ArrayList<>();
183 actionsInfos.add(new ActionInfo(ActionType.drop_action, new String[] {}));
184 mkInstructions.add(new InstructionInfo(InstructionType.apply_actions, actionsInfos));
186 FlowEntity flowEntity = MDSALUtil.buildFlowEntity(dpId, NwConstants.EGRESS_LEARN_TABLE,
187 "LEARN-" + getTableMissFlowId(NwConstants.EGRESS_LEARN_TABLE), 0,
188 "Egress Learn ACL Table Miss Flow", 0, 0,
189 AclConstants.COOKIE_ACL_BASE, mkMatches, mkInstructions);
190 mdsalManager.installFlow(flowEntity);
192 flowEntity = MDSALUtil.buildFlowEntity(dpId, NwConstants.EGRESS_LEARN2_TABLE,
193 "LEARN-" + getTableMissFlowId(NwConstants.EGRESS_LEARN2_TABLE), 0,
194 "Egress Learn2 ACL Table Miss Flow", 0, 0,
195 AclConstants.COOKIE_ACL_BASE, mkMatches, mkInstructions);
196 mdsalManager.installFlow(flowEntity);
198 List<NxMatchInfo> nxMkMatches = new ArrayList<>();
199 nxMkMatches.add(new NxMatchInfo(NxMatchFieldType.nxm_reg_6,
200 new long[] {Long.valueOf(AclConstants.LEARN_MATCH_REG_VALUE)}));
202 short dispatcherTableId = NwConstants.EGRESS_LPORT_DISPATCHER_TABLE;
203 List<InstructionInfo> instructions = new ArrayList<>();
204 actionsInfos.add(new ActionInfo(ActionType.nx_resubmit, new String[] {Short.toString(dispatcherTableId)}));
205 instructions.add(new InstructionInfo(InstructionType.apply_actions, actionsInfos));
207 flowEntity = MDSALUtil.buildFlowEntity(dpId, NwConstants.EGRESS_LEARN2_TABLE,
208 "LEARN2-REG-" + getTableMissFlowId(NwConstants.EGRESS_LEARN2_TABLE),
209 AclConstants.PROTO_MATCH_PRIORITY, "Egress Learn2 ACL Table match reg Flow", 0, 0,
210 AclConstants.COOKIE_ACL_BASE, nxMkMatches, instructions);
211 mdsalManager.installFlow(flowEntity);
212 LOG.debug("Added learn ACL Table Miss Flows for dpn {}", dpId);
215 private void addLearnIngressAclTableMissFlow(BigInteger dpId) {
216 List<InstructionInfo> mkInstructions = new ArrayList<>();
217 List<ActionInfo> actionsInfos = new ArrayList<>();
218 actionsInfos.add(new ActionInfo(ActionType.nx_resubmit,
219 new String[] {Short.toString(NwConstants.INGRESS_LEARN_TABLE) }));
220 actionsInfos.add(new ActionInfo(ActionType.nx_resubmit,
221 new String[] {Short.toString(NwConstants.INGRESS_LEARN2_TABLE) }));
222 mkInstructions.add(new InstructionInfo(InstructionType.apply_actions, actionsInfos));
224 List<MatchInfo> mkMatches = new ArrayList<>();
225 FlowEntity doubleResubmitTable = MDSALUtil.buildFlowEntity(dpId, NwConstants.INGRESS_ACL_TABLE,
226 "RESUB-" + getTableMissFlowId(NwConstants.INGRESS_ACL_TABLE),
227 AclConstants.PROTO_MATCH_PRIORITY, "Ingress resubmit ACL Table Block", 0, 0,
228 AclConstants.COOKIE_ACL_BASE, mkMatches, mkInstructions);
229 mdsalManager.installFlow(doubleResubmitTable);
231 mkMatches = new ArrayList<>();
232 mkInstructions = new ArrayList<>();
233 actionsInfos = new ArrayList<>();
234 actionsInfos.add(new ActionInfo(ActionType.drop_action, new String[] {}));
235 mkInstructions.add(new InstructionInfo(InstructionType.apply_actions, actionsInfos));
237 FlowEntity flowEntity = MDSALUtil.buildFlowEntity(dpId, NwConstants.INGRESS_LEARN_TABLE,
238 "LEARN-" + getTableMissFlowId(NwConstants.INGRESS_LEARN_TABLE), 0,
239 "Ingress Learn ACL Table Miss Flow", 0, 0,
240 AclConstants.COOKIE_ACL_BASE, mkMatches, mkInstructions);
241 mdsalManager.installFlow(flowEntity);
243 flowEntity = MDSALUtil.buildFlowEntity(dpId, NwConstants.INGRESS_LEARN2_TABLE,
244 "LEARN-" + getTableMissFlowId(NwConstants.INGRESS_LEARN2_TABLE), 0,
245 "Ingress Learn2 ACL Table Miss Flow", 0, 0,
246 AclConstants.COOKIE_ACL_BASE, mkMatches, mkInstructions);
247 mdsalManager.installFlow(flowEntity);
249 List<NxMatchInfo> nxMkMatches = new ArrayList<>();
250 nxMkMatches.add(new NxMatchInfo(NxMatchFieldType.nxm_reg_6,
251 new long[] {Long.valueOf(AclConstants.LEARN_MATCH_REG_VALUE)}));
253 short dispatcherTableId = NwConstants.LPORT_DISPATCHER_TABLE;
254 List<InstructionInfo> instructions = new ArrayList<>();
255 actionsInfos.add(new ActionInfo(ActionType.nx_resubmit, new String[] {Short.toString(dispatcherTableId)}));
256 instructions.add(new InstructionInfo(InstructionType.apply_actions, actionsInfos));
258 flowEntity = MDSALUtil.buildFlowEntity(dpId, NwConstants.INGRESS_LEARN2_TABLE,
259 "LEARN2-REG-" + getTableMissFlowId(NwConstants.INGRESS_LEARN2_TABLE),
260 AclConstants.PROTO_MATCH_PRIORITY, "Egress Learn2 ACL Table match reg Flow", 0, 0,
261 AclConstants.COOKIE_ACL_BASE, nxMkMatches, instructions);
262 mdsalManager.installFlow(flowEntity);
263 LOG.debug("Added learn ACL Table Miss Flows for dpn {}", dpId);
268 * Adds the ingress acl table transparent flow.
270 * @param dpId the dp id
272 private void addTransparentIngressAclTableMissFlow(BigInteger dpId) {
273 List<MatchInfo> mkMatches = new ArrayList<>();
274 List<InstructionInfo> allowAllInstructions = new ArrayList<>();
275 allowAllInstructions.add(
276 new InstructionInfo(InstructionType.goto_table,
277 new long[] { NwConstants.INGRESS_ACL_FILTER_TABLE }));
279 FlowEntity nextTblFlowEntity = MDSALUtil.buildFlowEntity(dpId, NwConstants.INGRESS_ACL_TABLE,
280 getTableMissFlowId(NwConstants.INGRESS_ACL_TABLE), 0, "Ingress ACL Table allow all Flow",
281 0, 0, AclConstants.COOKIE_ACL_BASE, mkMatches, allowAllInstructions);
282 mdsalManager.installFlow(nextTblFlowEntity);
284 short dispatcherTableId = NwConstants.LPORT_DISPATCHER_TABLE;
286 List<ActionInfo> actionsInfos = new ArrayList<>();
287 List<InstructionInfo> dispatcherInstructions = new ArrayList<>();
288 actionsInfos.add(new ActionInfo(ActionType.nx_resubmit, new String[] {Short.toString(dispatcherTableId)}));
289 dispatcherInstructions.add(new InstructionInfo(InstructionType.apply_actions, actionsInfos));
291 nextTblFlowEntity = MDSALUtil.buildFlowEntity(dpId, NwConstants.INGRESS_ACL_FILTER_TABLE,
292 getTableMissFlowId(NwConstants.INGRESS_ACL_FILTER_TABLE), 0, "Ingress ACL Filter Table allow all Flow",
293 0, 0, AclConstants.COOKIE_ACL_BASE, mkMatches, dispatcherInstructions);
294 mdsalManager.installFlow(nextTblFlowEntity);
296 LOG.debug("Added Transparent Ingress ACL Table allow all Flows for dpn {}", dpId);
300 * Adds the egress acl table transparent flow.
302 * @param dpId the dp id
304 private void addTransparentEgressAclTableMissFlow(BigInteger dpId) {
305 List<MatchInfo> mkMatches = new ArrayList<>();
306 List<InstructionInfo> allowAllInstructions = new ArrayList<>();
307 allowAllInstructions.add(
308 new InstructionInfo(InstructionType.goto_table,
309 new long[] { NwConstants.EGRESS_ACL_FILTER_TABLE }));
311 FlowEntity nextTblFlowEntity = MDSALUtil.buildFlowEntity(dpId, NwConstants.EGRESS_ACL_TABLE,
312 getTableMissFlowId(NwConstants.EGRESS_ACL_TABLE), 0, "Egress ACL Table allow all Flow",
313 0, 0, AclConstants.COOKIE_ACL_BASE, mkMatches, allowAllInstructions);
314 mdsalManager.installFlow(nextTblFlowEntity);
316 short dispatcherTableId = NwConstants.EGRESS_LPORT_DISPATCHER_TABLE;
318 List<ActionInfo> actionsInfos = new ArrayList<>();
319 List<InstructionInfo> instructions = new ArrayList<>();
320 actionsInfos.add(new ActionInfo(ActionType.nx_resubmit, new String[] {Short.toString(dispatcherTableId)}));
321 instructions.add(new InstructionInfo(InstructionType.apply_actions, actionsInfos));
323 nextTblFlowEntity = MDSALUtil.buildFlowEntity(dpId, NwConstants.EGRESS_ACL_FILTER_TABLE,
324 getTableMissFlowId(NwConstants.EGRESS_ACL_FILTER_TABLE), 0, "Egress ACL Filter Table allow all Flow",
325 0, 0, AclConstants.COOKIE_ACL_BASE, mkMatches, instructions);
326 mdsalManager.installFlow(nextTblFlowEntity);
328 LOG.debug("Added Transparent Egress ACL Table allow all Flows for dpn {}", dpId);
332 * Adds the ingress acl table miss flow.
334 * @param dpId the dp id
336 private void addStatelessIngressAclTableMissFlow(BigInteger dpId) {
337 List<MatchInfo> synMatches = new ArrayList<>();
338 synMatches.add(new MatchInfo(MatchFieldType.eth_type,
339 new long[] { NwConstants.ETHTYPE_IPV4 }));
340 synMatches.add(new MatchInfo(MatchFieldType.ip_proto,
341 new long[] { IPProtocols.TCP.intValue() }));
343 synMatches.add(new MatchInfo(MatchFieldType.tcp_flags, new long[] { AclConstants.TCP_FLAG_SYN }));
345 List<ActionInfo> dropActionsInfos = new ArrayList<>();
346 dropActionsInfos.add(new ActionInfo(ActionType.drop_action, new String[] {}));
347 List<InstructionInfo> synInstructions = new ArrayList<>();
348 synInstructions.add(new InstructionInfo(InstructionType.apply_actions, dropActionsInfos));
350 FlowEntity synFlowEntity = MDSALUtil.buildFlowEntity(dpId, NwConstants.EGRESS_ACL_TABLE,
351 "SYN-" + getTableMissFlowId(NwConstants.EGRESS_ACL_TABLE),
352 AclConstants.PROTO_MATCH_SYN_DROP_PRIORITY, "Ingress Syn ACL Table Block", 0, 0,
353 AclConstants.COOKIE_ACL_BASE, synMatches, synInstructions);
354 mdsalManager.installFlow(synFlowEntity);
356 synMatches = new ArrayList<>();
357 synMatches.add(new MatchInfo(MatchFieldType.eth_type,
358 new long[] { NwConstants.ETHTYPE_IPV4 }));
359 synMatches.add(new MatchInfo(MatchFieldType.ip_proto,
360 new long[] { IPProtocols.TCP.intValue() }));
361 synMatches.add(new MatchInfo(MatchFieldType.tcp_flags, new long[] { AclConstants.TCP_FLAG_SYN_ACK }));
363 List<InstructionInfo> allowAllInstructions = new ArrayList<>();
364 allowAllInstructions.add(
365 new InstructionInfo(InstructionType.goto_table,
366 new long[] { NwConstants.EGRESS_ACL_FILTER_TABLE }));
368 FlowEntity synAckFlowEntity = MDSALUtil.buildFlowEntity(dpId, NwConstants.EGRESS_ACL_TABLE,
369 "SYN-ACK-ALLOW-" + getTableMissFlowId(NwConstants.EGRESS_ACL_TABLE),
370 AclConstants.PROTO_MATCH_SYN_ACK_ALLOW_PRIORITY, "Ingress Syn Ack ACL Table Allow", 0, 0,
371 AclConstants.COOKIE_ACL_BASE, synMatches, allowAllInstructions);
372 mdsalManager.installFlow(synAckFlowEntity);
375 List<MatchInfo> mkMatches = new ArrayList<>();
376 FlowEntity flowEntity = MDSALUtil.buildFlowEntity(dpId, NwConstants.EGRESS_ACL_TABLE,
377 getTableMissFlowId(NwConstants.EGRESS_ACL_TABLE), 0, "Ingress Stateless ACL Table Miss Flow",
378 0, 0, AclConstants.COOKIE_ACL_BASE, mkMatches, allowAllInstructions);
379 mdsalManager.installFlow(flowEntity);
381 short dispatcherTableId = NwConstants.EGRESS_LPORT_DISPATCHER_TABLE;
383 List<ActionInfo> actionsInfos = new ArrayList<>();
384 List<InstructionInfo> instructions = new ArrayList<>();
385 actionsInfos.add(new ActionInfo(ActionType.nx_resubmit, new String[] {Short.toString(dispatcherTableId)}));
386 instructions.add(new InstructionInfo(InstructionType.apply_actions, actionsInfos));
388 FlowEntity nextTblFlowEntity = MDSALUtil.buildFlowEntity(dpId, NwConstants.EGRESS_ACL_FILTER_TABLE,
389 getTableMissFlowId(NwConstants.EGRESS_ACL_FILTER_TABLE), 0,
390 "Ingress Stateless Next ACL Table Miss Flow", 0, 0, AclConstants.COOKIE_ACL_BASE,
391 mkMatches, instructions);
392 mdsalManager.installFlow(nextTblFlowEntity);
394 LOG.debug("Added Stateless Ingress ACL Table Miss Flows for dpn {}.", dpId);
398 * Adds the stateless egress acl table miss flow.
400 * @param dpId the dp id
402 private void addStatelessEgressAclTableMissFlow(BigInteger dpId) {
403 List<InstructionInfo> allowAllInstructions = new ArrayList<>();
404 allowAllInstructions.add(
405 new InstructionInfo(InstructionType.goto_table, new long[] { NwConstants.INGRESS_ACL_FILTER_TABLE }));
407 List<MatchInfo> synMatches = new ArrayList<>();
408 synMatches.add(new MatchInfo(MatchFieldType.eth_type,
409 new long[] { NwConstants.ETHTYPE_IPV4 }));
410 synMatches.add(new MatchInfo(MatchFieldType.ip_proto,
411 new long[] { IPProtocols.TCP.intValue() }));
412 synMatches.add(new MatchInfo(MatchFieldType.tcp_flags, new long[] { AclConstants.TCP_FLAG_SYN }));
414 List<ActionInfo> synActionsInfos = new ArrayList<>();
415 synActionsInfos.add(new ActionInfo(ActionType.drop_action, new String[] {}));
416 List<InstructionInfo> synInstructions = new ArrayList<>();
417 synInstructions.add(new InstructionInfo(InstructionType.apply_actions, synActionsInfos));
419 FlowEntity synFlowEntity = MDSALUtil.buildFlowEntity(dpId, NwConstants.INGRESS_ACL_TABLE,
420 "SYN-" + getTableMissFlowId(NwConstants.INGRESS_ACL_TABLE),
421 AclConstants.PROTO_MATCH_SYN_DROP_PRIORITY, "Egress Syn ACL Table Block", 0, 0,
422 AclConstants.COOKIE_ACL_BASE, synMatches, synInstructions);
423 mdsalManager.installFlow(synFlowEntity);
425 synMatches = new ArrayList<>();
426 synMatches.add(new MatchInfo(MatchFieldType.eth_type,
427 new long[] { NwConstants.ETHTYPE_IPV4 }));
428 synMatches.add(new MatchInfo(MatchFieldType.ip_proto,
429 new long[] { IPProtocols.TCP.intValue() }));
430 synMatches.add(new MatchInfo(MatchFieldType.tcp_flags, new long[] { AclConstants.TCP_FLAG_SYN_ACK }));
432 FlowEntity synAckFlowEntity = MDSALUtil.buildFlowEntity(dpId, NwConstants.INGRESS_ACL_TABLE,
433 "SYN-ACK-ALLOW-" + getTableMissFlowId(NwConstants.INGRESS_ACL_TABLE),
434 AclConstants.PROTO_MATCH_SYN_ACK_ALLOW_PRIORITY, "Egress Syn Ack ACL Table Allow", 0, 0,
435 AclConstants.COOKIE_ACL_BASE, synMatches, allowAllInstructions);
436 mdsalManager.installFlow(synAckFlowEntity);
438 List<MatchInfo> mkMatches = new ArrayList<>();
439 FlowEntity flowEntity = MDSALUtil.buildFlowEntity(dpId, NwConstants.INGRESS_ACL_TABLE,
440 getTableMissFlowId(NwConstants.INGRESS_ACL_TABLE), 0, "Egress Stateless ACL Table Miss Flow", 0, 0,
441 AclConstants.COOKIE_ACL_BASE, mkMatches, allowAllInstructions);
442 mdsalManager.installFlow(flowEntity);
444 short dispatcherTableId = NwConstants.LPORT_DISPATCHER_TABLE;
446 List<ActionInfo> actionsInfos = new ArrayList<>();
447 List<InstructionInfo> dispatcherInstructions = new ArrayList<>();
448 actionsInfos.add(new ActionInfo(ActionType.nx_resubmit, new String[] {Short.toString(dispatcherTableId)}));
449 dispatcherInstructions.add(new InstructionInfo(InstructionType.apply_actions, actionsInfos));
451 FlowEntity nextTblFlowEntity = MDSALUtil.buildFlowEntity(dpId, NwConstants.INGRESS_ACL_FILTER_TABLE,
452 getTableMissFlowId(NwConstants.INGRESS_ACL_FILTER_TABLE), 0,
453 "Egress Stateless Next ACL Table Miss Flow", 0, 0, AclConstants.COOKIE_ACL_BASE, mkMatches,
454 dispatcherInstructions);
455 mdsalManager.installFlow(nextTblFlowEntity);
457 LOG.debug("Added Stateless Egress ACL Table Miss Flows for dpn {}", dpId);
461 * Adds the egress acl table miss flow.
463 * @param dpId the dp id
465 private void addEgressAclTableMissFlow(BigInteger dpId) {
466 List<MatchInfo> mkMatches = new ArrayList<>();
467 List<InstructionInfo> mkInstructions = new ArrayList<>();
468 List<ActionInfo> actionsInfos = new ArrayList<>();
469 actionsInfos.add(new ActionInfo(ActionType.drop_action, new String[] {}));
470 mkInstructions.add(new InstructionInfo(InstructionType.apply_actions, actionsInfos));
472 FlowEntity flowEntity = MDSALUtil.buildFlowEntity(dpId, NwConstants.INGRESS_ACL_TABLE,
473 getTableMissFlowId(NwConstants.INGRESS_ACL_TABLE), 0, "Egress ACL Table Miss Flow", 0, 0,
474 AclConstants.COOKIE_ACL_BASE, mkMatches, mkInstructions);
475 mdsalManager.installFlow(flowEntity);
477 FlowEntity nextTblFlowEntity = MDSALUtil.buildFlowEntity(dpId, NwConstants.INGRESS_ACL_FILTER_TABLE,
478 getTableMissFlowId(NwConstants.INGRESS_ACL_FILTER_TABLE), 0, "Egress ACL Table Miss Flow", 0, 0,
479 AclConstants.COOKIE_ACL_BASE, mkMatches, mkInstructions);
480 mdsalManager.installFlow(nextTblFlowEntity);
482 LOG.debug("Added Egress ACL Table Miss Flows for dpn {}", dpId);
485 private void addConntrackRules(BigInteger dpnId, short dispatcherTableId,short tableId, int write) {
486 programConntrackForwardRule(dpnId, AclConstants.CT_STATE_TRACKED_EXIST_PRIORITY,
487 "Tracked_Established", AclConstants.TRACKED_EST_CT_STATE, AclConstants.TRACKED_EST_CT_STATE_MASK,
488 dispatcherTableId, tableId, write );
489 programConntrackForwardRule(dpnId, AclConstants.CT_STATE_TRACKED_EXIST_PRIORITY,"Tracked_Related", AclConstants
490 .TRACKED_REL_CT_STATE, AclConstants.TRACKED_REL_CT_STATE_MASK, dispatcherTableId, tableId, write );
491 programConntrackDropRule(dpnId, AclConstants.CT_STATE_NEW_PRIORITY_DROP,"Tracked_New",
492 AclConstants.TRACKED_NEW_CT_STATE, AclConstants.TRACKED_NEW_CT_STATE_MASK, tableId, write );
493 programConntrackDropRule(dpnId, AclConstants.CT_STATE_NEW_PRIORITY_DROP, "Tracked_Invalid",
494 AclConstants.TRACKED_INV_CT_STATE, AclConstants.TRACKED_INV_CT_STATE_MASK, tableId, write );
499 * Adds the rule to forward the packets known packets.
501 * @param dpId the dpId
502 * @param lportTag the lport tag
503 * @param priority the priority of the flow
504 * @param flowId the flowId
505 * @param conntrackState the conntrack state of the packets thats should be
507 * @param conntrackMask the conntrack mask
508 * @param addOrRemove whether to add or remove the flow
510 private void programConntrackForwardRule(BigInteger dpId, Integer priority, String flowId,
511 int conntrackState, int conntrackMask, short dispatcherTableId, short tableId, int addOrRemove) {
512 List<MatchInfoBase> matches = new ArrayList<>();
513 matches.add(new NxMatchInfo(NxMatchFieldType.ct_state, new long[] {conntrackState, conntrackMask}));
515 List<InstructionInfo> instructions = getDispatcherTableResubmitInstructions(
516 new ArrayList<>(),dispatcherTableId);
518 flowId = "Fixed_Conntrk_Trk_" + dpId + "_" + flowId + dispatcherTableId;
519 syncFlow(dpId, tableId, flowId, priority, "ACL", 0, 0,
520 AclConstants.COOKIE_ACL_BASE, matches, instructions, addOrRemove);
524 * Adds the rule to drop the unknown/invalid packets .
526 * @param dpId the dpId
527 * @param lportTag the lport tag
528 * @param priority the priority of the flow
529 * @param flowId the flowId
530 * @param conntrackState the conntrack state of the packets thats should be
532 * @param conntrackMask the conntrack mask
533 * @param addOrRemove whether to add or remove the flow
535 private void programConntrackDropRule(BigInteger dpId, Integer priority, String flowId,
536 int conntrackState, int conntrackMask, short tableId, int addOrRemove) {
537 List<MatchInfoBase> matches = new ArrayList<>();
538 matches.add(new NxMatchInfo(NxMatchFieldType.ct_state, new long[] {conntrackState, conntrackMask}));
540 List<InstructionInfo> instructions = new ArrayList<>();
541 List<ActionInfo> actionsInfos = new ArrayList<>();
542 actionsInfos.add(new ActionInfo(ActionType.drop_action, new String[] {}));
543 instructions.add(new InstructionInfo(InstructionType.write_actions, actionsInfos));
544 flowId = "Fixed_Conntrk_NewDrop_" + dpId + "_" + flowId + tableId;
545 syncFlow(dpId, tableId, flowId, priority, "ACL", 0, 0,
546 AclConstants.COOKIE_ACL_BASE, matches, instructions, addOrRemove);
550 * Gets the dispatcher table resubmit instructions.
552 * @param actionsInfos the actions infos
553 * @return the instructions for dispatcher table resubmit
555 private List<InstructionInfo> getDispatcherTableResubmitInstructions(List<ActionInfo> actionsInfos,
556 short dispatcherTableId) {
557 List<InstructionInfo> instructions = new ArrayList<>();
558 actionsInfos.add(new ActionInfo(ActionType.nx_resubmit, new String[] {Short.toString(dispatcherTableId)}));
559 instructions.add(new InstructionInfo(InstructionType.apply_actions, actionsInfos));
564 * Writes/remove the flow to/from the datastore.
565 * @param dpId the dpId
566 * @param tableId the tableId
567 * @param flowId the flowId
568 * @param priority the priority
569 * @param flowName the flow name
570 * @param idleTimeOut the idle timeout
571 * @param hardTimeOut the hard timeout
572 * @param cookie the cookie
573 * @param matches the list of matches to be written
574 * @param instructions the list of instruction to be written.
575 * @param addOrRemove add or remove the entries.
577 protected void syncFlow(BigInteger dpId, short tableId, String flowId, int priority, String flowName,
578 int idleTimeOut, int hardTimeOut, BigInteger cookie, List<? extends MatchInfoBase> matches,
579 List<InstructionInfo> instructions, int addOrRemove) {
580 if (addOrRemove == NwConstants.DEL_FLOW) {
581 FlowEntity flowEntity = MDSALUtil.buildFlowEntity(dpId, tableId,flowId,
582 priority, flowName , idleTimeOut, hardTimeOut, cookie, matches, null);
583 LOG.trace("Removing Acl Flow DpnId {}, flowId {}", dpId, flowId);
584 mdsalManager.removeFlow(flowEntity);
586 FlowEntity flowEntity = MDSALUtil.buildFlowEntity(dpId, tableId, flowId,
587 priority, flowName, idleTimeOut, hardTimeOut, cookie, matches, instructions);
588 LOG.trace("Installing DpnId {}, flowId {}", dpId, flowId);
589 mdsalManager.installFlow(flowEntity);
594 * Gets the table miss flow id.
596 * @param tableId the table id
597 * @return the table miss flow id
599 private String getTableMissFlowId(short tableId) {
600 return String.valueOf(tableId);
604 protected AclNodeListener getDataTreeChangeListener() {
605 return AclNodeListener.this;