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.annotation.PreDestroy;
16 import javax.inject.Inject;
17 import javax.inject.Singleton;
18 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
19 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
20 import org.opendaylight.genius.datastoreutils.AsyncDataTreeChangeListenerBase;
21 import org.opendaylight.genius.mdsalutil.ActionInfo;
22 import org.opendaylight.genius.mdsalutil.ActionType;
23 import org.opendaylight.genius.mdsalutil.FlowEntity;
24 import org.opendaylight.genius.mdsalutil.InstructionInfo;
25 import org.opendaylight.genius.mdsalutil.InstructionType;
26 import org.opendaylight.genius.mdsalutil.MDSALUtil;
27 import org.opendaylight.genius.mdsalutil.MatchFieldType;
28 import org.opendaylight.genius.mdsalutil.MatchInfo;
29 import org.opendaylight.genius.mdsalutil.MatchInfoBase;
30 import org.opendaylight.genius.mdsalutil.NwConstants;
31 import org.opendaylight.genius.mdsalutil.NxMatchFieldType;
32 import org.opendaylight.genius.mdsalutil.NxMatchInfo;
33 import org.opendaylight.genius.mdsalutil.interfaces.IMdsalApiManager;
34 import org.opendaylight.genius.mdsalutil.packet.IPProtocols;
35 import org.opendaylight.netvirt.aclservice.utils.AclClusterUtil;
36 import org.opendaylight.netvirt.aclservice.utils.AclConstants;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.aclservice.config.rev160806.AclserviceConfig;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.aclservice.config.rev160806.AclserviceConfig.SecurityGroupMode;
43 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
44 import org.slf4j.Logger;
45 import org.slf4j.LoggerFactory;
48 * Listener to handle flow capable node updates.
51 @SuppressWarnings("deprecation")
52 public class AclNodeListener extends AsyncDataTreeChangeListenerBase<FlowCapableNode, AclNodeListener>
53 implements AutoCloseable {
55 private static final Logger LOG = LoggerFactory.getLogger(AclNodeListener.class);
57 private final IMdsalApiManager mdsalManager;
58 private final AclClusterUtil aclClusterUtil;
59 private final AclserviceConfig config;
60 private final DataBroker dataBroker;
62 private SecurityGroupMode securityGroupMode = null;
65 public AclNodeListener(final IMdsalApiManager mdsalManager, DataBroker dataBroker, AclserviceConfig config,
66 AclClusterUtil aclClusterUtil) {
67 super(FlowCapableNode.class, AclNodeListener.class);
69 this.mdsalManager = mdsalManager;
70 this.aclClusterUtil = aclClusterUtil;
71 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);
87 public void close() throws Exception {
92 protected InstanceIdentifier<FlowCapableNode> getWildCardPath() {
93 return InstanceIdentifier.create(Nodes.class).child(Node.class).augmentation(FlowCapableNode.class);
97 protected void remove(InstanceIdentifier<FlowCapableNode> key, FlowCapableNode dataObjectModification) {
102 protected void update(InstanceIdentifier<FlowCapableNode> key, FlowCapableNode dataObjectModificationBefore,
103 FlowCapableNode dataObjectModificationAfter) {
108 protected void add(InstanceIdentifier<FlowCapableNode> key, FlowCapableNode dataObjectModification) {
109 LOG.trace("FlowCapableNode Added: key: {}", key);
110 if (!aclClusterUtil.isEntityOwner()) {
113 NodeKey nodeKey = key.firstKeyOf(Node.class);
114 BigInteger dpnId = MDSALUtil.getDpnIdFromNodeName(nodeKey.getId());
115 createTableDefaultEntries(dpnId);
119 * Creates the table miss entries.
121 * @param dpnId the dpn id
123 private void createTableDefaultEntries(BigInteger dpnId) {
124 LOG.info("Adding default ACL entries for mode: "
125 + (securityGroupMode == null ? SecurityGroupMode.Stateful : securityGroupMode));
126 if (securityGroupMode == null || securityGroupMode == SecurityGroupMode.Stateful) {
127 addIngressAclTableMissFlow(dpnId);
128 addEgressAclTableMissFlow(dpnId);
129 addConntrackRules(dpnId, NwConstants.LPORT_DISPATCHER_TABLE, NwConstants.INGRESS_ACL_FILTER_TABLE,
130 NwConstants.ADD_FLOW);
131 addConntrackRules(dpnId, NwConstants.EGRESS_LPORT_DISPATCHER_TABLE, NwConstants.EGRESS_ACL_FILTER_TABLE,
132 NwConstants.ADD_FLOW);
133 } else if (securityGroupMode == SecurityGroupMode.Transparent) {
134 addTransparentIngressAclTableMissFlow(dpnId);
135 addTransparentEgressAclTableMissFlow(dpnId);
136 } else if (securityGroupMode == SecurityGroupMode.Stateless) {
137 addStatelessIngressAclTableMissFlow(dpnId);
138 addStatelessEgressAclTableMissFlow(dpnId);
139 } else if (securityGroupMode == SecurityGroupMode.Learn) {
140 addLearnIngressAclTableMissFlow(dpnId);
141 addLearnEgressAclTableMissFlow(dpnId);
146 * Adds the ingress acl table miss flow.
148 * @param dpId the dp id
150 private void addIngressAclTableMissFlow(BigInteger dpId) {
151 List<MatchInfo> mkMatches = new ArrayList<>();
152 List<InstructionInfo> mkInstructions = new ArrayList<>();
153 List<ActionInfo> actionsInfos = new ArrayList<>();
154 actionsInfos.add(new ActionInfo(ActionType.drop_action, new String[] {}));
155 mkInstructions.add(new InstructionInfo(InstructionType.apply_actions, actionsInfos));
157 FlowEntity flowEntity = MDSALUtil.buildFlowEntity(dpId, NwConstants.EGRESS_ACL_TABLE,
158 getTableMissFlowId(NwConstants.EGRESS_ACL_TABLE), 0, "Ingress ACL Table Miss Flow", 0, 0,
159 AclConstants.COOKIE_ACL_BASE, mkMatches, mkInstructions);
160 mdsalManager.installFlow(flowEntity);
162 FlowEntity nextTblFlowEntity = MDSALUtil.buildFlowEntity(dpId, NwConstants.EGRESS_ACL_FILTER_TABLE,
163 getTableMissFlowId(NwConstants.EGRESS_ACL_FILTER_TABLE), 0, "Ingress ACL Filter Table Miss Flow",
164 0, 0, AclConstants.COOKIE_ACL_BASE, mkMatches, mkInstructions);
165 mdsalManager.installFlow(nextTblFlowEntity);
167 LOG.debug("Added Ingress ACL Table Miss Flows for dpn {}", dpId);
170 private void addLearnEgressAclTableMissFlow(BigInteger dpId) {
171 List<InstructionInfo> mkInstructions = new ArrayList<>();
172 List<ActionInfo> actionsInfos = new ArrayList<>();
173 actionsInfos.add(new ActionInfo(ActionType.nx_resubmit,
174 new String[] {Short.toString(NwConstants.EGRESS_LEARN_TABLE) }));
175 actionsInfos.add(new ActionInfo(ActionType.nx_resubmit,
176 new String[] {Short.toString(NwConstants.EGRESS_LEARN2_TABLE) }));
177 mkInstructions.add(new InstructionInfo(InstructionType.apply_actions, actionsInfos));
179 List<MatchInfo> mkMatches = new ArrayList<>();
180 FlowEntity doubleResubmitTable = MDSALUtil.buildFlowEntity(dpId, NwConstants.EGRESS_ACL_TABLE,
181 "RESUB-" + getTableMissFlowId(NwConstants.EGRESS_ACL_TABLE),
182 AclConstants.PROTO_MATCH_PRIORITY, "Egress resubmit ACL Table Block", 0, 0,
183 AclConstants.COOKIE_ACL_BASE, mkMatches, mkInstructions);
184 mdsalManager.installFlow(doubleResubmitTable);
186 mkMatches = new ArrayList<>();
187 mkInstructions = new ArrayList<>();
188 actionsInfos = new ArrayList<>();
189 actionsInfos.add(new ActionInfo(ActionType.drop_action, new String[] {}));
190 mkInstructions.add(new InstructionInfo(InstructionType.apply_actions, actionsInfos));
192 FlowEntity flowEntity = MDSALUtil.buildFlowEntity(dpId, NwConstants.EGRESS_LEARN_TABLE,
193 "LEARN-" + getTableMissFlowId(NwConstants.EGRESS_LEARN_TABLE), 0,
194 "Egress Learn ACL Table Miss Flow", 0, 0,
195 AclConstants.COOKIE_ACL_BASE, mkMatches, mkInstructions);
196 mdsalManager.installFlow(flowEntity);
198 flowEntity = MDSALUtil.buildFlowEntity(dpId, NwConstants.EGRESS_LEARN2_TABLE,
199 "LEARN-" + getTableMissFlowId(NwConstants.EGRESS_LEARN2_TABLE), 0,
200 "Egress Learn2 ACL Table Miss Flow", 0, 0,
201 AclConstants.COOKIE_ACL_BASE, mkMatches, mkInstructions);
202 mdsalManager.installFlow(flowEntity);
204 List<NxMatchInfo> nxMkMatches = new ArrayList<>();
205 nxMkMatches.add(new NxMatchInfo(NxMatchFieldType.nxm_reg_6,
206 new long[] {Long.valueOf(AclConstants.LEARN_MATCH_REG_VALUE)}));
208 short dispatcherTableId = NwConstants.EGRESS_LPORT_DISPATCHER_TABLE;
209 List<InstructionInfo> instructions = new ArrayList<>();
210 actionsInfos.add(new ActionInfo(ActionType.nx_resubmit, new String[] {Short.toString(dispatcherTableId)}));
211 instructions.add(new InstructionInfo(InstructionType.apply_actions, actionsInfos));
213 flowEntity = MDSALUtil.buildFlowEntity(dpId, NwConstants.EGRESS_LEARN2_TABLE,
214 "LEARN2-REG-" + getTableMissFlowId(NwConstants.EGRESS_LEARN2_TABLE),
215 AclConstants.PROTO_MATCH_PRIORITY, "Egress Learn2 ACL Table match reg Flow", 0, 0,
216 AclConstants.COOKIE_ACL_BASE, nxMkMatches, instructions);
217 mdsalManager.installFlow(flowEntity);
218 LOG.debug("Added learn ACL Table Miss Flows for dpn {}", dpId);
221 private void addLearnIngressAclTableMissFlow(BigInteger dpId) {
222 List<InstructionInfo> mkInstructions = new ArrayList<>();
223 List<ActionInfo> actionsInfos = new ArrayList<>();
224 actionsInfos.add(new ActionInfo(ActionType.nx_resubmit,
225 new String[] {Short.toString(NwConstants.INGRESS_LEARN_TABLE) }));
226 actionsInfos.add(new ActionInfo(ActionType.nx_resubmit,
227 new String[] {Short.toString(NwConstants.INGRESS_LEARN2_TABLE) }));
228 mkInstructions.add(new InstructionInfo(InstructionType.apply_actions, actionsInfos));
230 List<MatchInfo> mkMatches = new ArrayList<>();
231 FlowEntity doubleResubmitTable = MDSALUtil.buildFlowEntity(dpId, NwConstants.INGRESS_ACL_TABLE,
232 "RESUB-" + getTableMissFlowId(NwConstants.INGRESS_ACL_TABLE),
233 AclConstants.PROTO_MATCH_PRIORITY, "Ingress resubmit ACL Table Block", 0, 0,
234 AclConstants.COOKIE_ACL_BASE, mkMatches, mkInstructions);
235 mdsalManager.installFlow(doubleResubmitTable);
237 mkMatches = new ArrayList<>();
238 mkInstructions = new ArrayList<>();
239 actionsInfos = new ArrayList<>();
240 actionsInfos.add(new ActionInfo(ActionType.drop_action, new String[] {}));
241 mkInstructions.add(new InstructionInfo(InstructionType.apply_actions, actionsInfos));
243 FlowEntity flowEntity = MDSALUtil.buildFlowEntity(dpId, NwConstants.INGRESS_LEARN_TABLE,
244 "LEARN-" + getTableMissFlowId(NwConstants.INGRESS_LEARN_TABLE), 0,
245 "Ingress Learn ACL Table Miss Flow", 0, 0,
246 AclConstants.COOKIE_ACL_BASE, mkMatches, mkInstructions);
247 mdsalManager.installFlow(flowEntity);
249 flowEntity = MDSALUtil.buildFlowEntity(dpId, NwConstants.INGRESS_LEARN2_TABLE,
250 "LEARN-" + getTableMissFlowId(NwConstants.INGRESS_LEARN2_TABLE), 0,
251 "Ingress Learn2 ACL Table Miss Flow", 0, 0,
252 AclConstants.COOKIE_ACL_BASE, mkMatches, mkInstructions);
253 mdsalManager.installFlow(flowEntity);
255 List<NxMatchInfo> nxMkMatches = new ArrayList<>();
256 nxMkMatches.add(new NxMatchInfo(NxMatchFieldType.nxm_reg_6,
257 new long[] {Long.valueOf(AclConstants.LEARN_MATCH_REG_VALUE)}));
259 short dispatcherTableId = NwConstants.LPORT_DISPATCHER_TABLE;
260 List<InstructionInfo> instructions = new ArrayList<>();
261 actionsInfos.add(new ActionInfo(ActionType.nx_resubmit, new String[] {Short.toString(dispatcherTableId)}));
262 instructions.add(new InstructionInfo(InstructionType.apply_actions, actionsInfos));
264 flowEntity = MDSALUtil.buildFlowEntity(dpId, NwConstants.INGRESS_LEARN2_TABLE,
265 "LEARN2-REG-" + getTableMissFlowId(NwConstants.INGRESS_LEARN2_TABLE),
266 AclConstants.PROTO_MATCH_PRIORITY, "Egress Learn2 ACL Table match reg Flow", 0, 0,
267 AclConstants.COOKIE_ACL_BASE, nxMkMatches, instructions);
268 mdsalManager.installFlow(flowEntity);
269 LOG.debug("Added learn ACL Table Miss Flows for dpn {}", dpId);
274 * Adds the ingress acl table transparent flow.
276 * @param dpId the dp id
278 private void addTransparentIngressAclTableMissFlow(BigInteger dpId) {
279 List<MatchInfo> mkMatches = new ArrayList<>();
280 List<InstructionInfo> allowAllInstructions = new ArrayList<>();
281 allowAllInstructions.add(
282 new InstructionInfo(InstructionType.goto_table,
283 new long[] { NwConstants.INGRESS_ACL_FILTER_TABLE }));
285 FlowEntity nextTblFlowEntity = MDSALUtil.buildFlowEntity(dpId, NwConstants.INGRESS_ACL_TABLE,
286 getTableMissFlowId(NwConstants.INGRESS_ACL_TABLE), 0, "Ingress ACL Table allow all Flow",
287 0, 0, AclConstants.COOKIE_ACL_BASE, mkMatches, allowAllInstructions);
288 mdsalManager.installFlow(nextTblFlowEntity);
290 short dispatcherTableId = NwConstants.LPORT_DISPATCHER_TABLE;
292 List<ActionInfo> actionsInfos = new ArrayList<>();
293 List<InstructionInfo> dispatcherInstructions = new ArrayList<>();
294 actionsInfos.add(new ActionInfo(ActionType.nx_resubmit, new String[] {Short.toString(dispatcherTableId)}));
295 dispatcherInstructions.add(new InstructionInfo(InstructionType.apply_actions, actionsInfos));
297 nextTblFlowEntity = MDSALUtil.buildFlowEntity(dpId, NwConstants.INGRESS_ACL_FILTER_TABLE,
298 getTableMissFlowId(NwConstants.INGRESS_ACL_FILTER_TABLE), 0, "Ingress ACL Filter Table allow all Flow",
299 0, 0, AclConstants.COOKIE_ACL_BASE, mkMatches, dispatcherInstructions);
300 mdsalManager.installFlow(nextTblFlowEntity);
302 LOG.debug("Added Transparent Ingress ACL Table allow all Flows for dpn {}", dpId);
306 * Adds the egress acl table transparent flow.
308 * @param dpId the dp id
310 private void addTransparentEgressAclTableMissFlow(BigInteger dpId) {
311 List<MatchInfo> mkMatches = new ArrayList<>();
312 List<InstructionInfo> allowAllInstructions = new ArrayList<>();
313 allowAllInstructions.add(
314 new InstructionInfo(InstructionType.goto_table,
315 new long[] { NwConstants.EGRESS_ACL_FILTER_TABLE }));
317 FlowEntity nextTblFlowEntity = MDSALUtil.buildFlowEntity(dpId, NwConstants.EGRESS_ACL_TABLE,
318 getTableMissFlowId(NwConstants.EGRESS_ACL_TABLE), 0, "Egress ACL Table allow all Flow",
319 0, 0, AclConstants.COOKIE_ACL_BASE, mkMatches, allowAllInstructions);
320 mdsalManager.installFlow(nextTblFlowEntity);
322 short dispatcherTableId = NwConstants.EGRESS_LPORT_DISPATCHER_TABLE;
324 List<ActionInfo> actionsInfos = new ArrayList<>();
325 List<InstructionInfo> instructions = new ArrayList<>();
326 actionsInfos.add(new ActionInfo(ActionType.nx_resubmit, new String[] {Short.toString(dispatcherTableId)}));
327 instructions.add(new InstructionInfo(InstructionType.apply_actions, actionsInfos));
329 nextTblFlowEntity = MDSALUtil.buildFlowEntity(dpId, NwConstants.EGRESS_ACL_FILTER_TABLE,
330 getTableMissFlowId(NwConstants.EGRESS_ACL_FILTER_TABLE), 0, "Egress ACL Filter Table allow all Flow",
331 0, 0, AclConstants.COOKIE_ACL_BASE, mkMatches, instructions);
332 mdsalManager.installFlow(nextTblFlowEntity);
334 LOG.debug("Added Transparent Egress ACL Table allow all Flows for dpn {}", dpId);
338 * Adds the ingress acl table miss flow.
340 * @param dpId the dp id
342 private void addStatelessIngressAclTableMissFlow(BigInteger dpId) {
343 List<MatchInfo> synMatches = new ArrayList<>();
344 synMatches.add(new MatchInfo(MatchFieldType.eth_type,
345 new long[] { NwConstants.ETHTYPE_IPV4 }));
346 synMatches.add(new MatchInfo(MatchFieldType.ip_proto,
347 new long[] { IPProtocols.TCP.intValue() }));
349 synMatches.add(new MatchInfo(MatchFieldType.tcp_flags, new long[] { AclConstants.TCP_FLAG_SYN }));
351 List<ActionInfo> dropActionsInfos = new ArrayList<>();
352 dropActionsInfos.add(new ActionInfo(ActionType.drop_action, new String[] {}));
353 List<InstructionInfo> synInstructions = new ArrayList<>();
354 synInstructions.add(new InstructionInfo(InstructionType.apply_actions, dropActionsInfos));
356 FlowEntity synFlowEntity = MDSALUtil.buildFlowEntity(dpId, NwConstants.EGRESS_ACL_TABLE,
357 "SYN-" + getTableMissFlowId(NwConstants.EGRESS_ACL_TABLE),
358 AclConstants.PROTO_MATCH_SYN_DROP_PRIORITY, "Ingress Syn ACL Table Block", 0, 0,
359 AclConstants.COOKIE_ACL_BASE, synMatches, synInstructions);
360 mdsalManager.installFlow(synFlowEntity);
362 synMatches = new ArrayList<>();
363 synMatches.add(new MatchInfo(MatchFieldType.eth_type,
364 new long[] { NwConstants.ETHTYPE_IPV4 }));
365 synMatches.add(new MatchInfo(MatchFieldType.ip_proto,
366 new long[] { IPProtocols.TCP.intValue() }));
367 synMatches.add(new MatchInfo(MatchFieldType.tcp_flags, new long[] { AclConstants.TCP_FLAG_SYN_ACK }));
369 List<InstructionInfo> allowAllInstructions = new ArrayList<>();
370 allowAllInstructions.add(
371 new InstructionInfo(InstructionType.goto_table,
372 new long[] { NwConstants.EGRESS_ACL_FILTER_TABLE }));
374 FlowEntity synAckFlowEntity = MDSALUtil.buildFlowEntity(dpId, NwConstants.EGRESS_ACL_TABLE,
375 "SYN-ACK-ALLOW-" + getTableMissFlowId(NwConstants.EGRESS_ACL_TABLE),
376 AclConstants.PROTO_MATCH_SYN_ACK_ALLOW_PRIORITY, "Ingress Syn Ack ACL Table Allow", 0, 0,
377 AclConstants.COOKIE_ACL_BASE, synMatches, allowAllInstructions);
378 mdsalManager.installFlow(synAckFlowEntity);
381 List<MatchInfo> mkMatches = new ArrayList<>();
382 FlowEntity flowEntity = MDSALUtil.buildFlowEntity(dpId, NwConstants.EGRESS_ACL_TABLE,
383 getTableMissFlowId(NwConstants.EGRESS_ACL_TABLE), 0, "Ingress Stateless ACL Table Miss Flow",
384 0, 0, AclConstants.COOKIE_ACL_BASE, mkMatches, allowAllInstructions);
385 mdsalManager.installFlow(flowEntity);
387 short dispatcherTableId = NwConstants.EGRESS_LPORT_DISPATCHER_TABLE;
389 List<ActionInfo> actionsInfos = new ArrayList<>();
390 List<InstructionInfo> instructions = new ArrayList<>();
391 actionsInfos.add(new ActionInfo(ActionType.nx_resubmit, new String[] {Short.toString(dispatcherTableId)}));
392 instructions.add(new InstructionInfo(InstructionType.apply_actions, actionsInfos));
394 FlowEntity nextTblFlowEntity = MDSALUtil.buildFlowEntity(dpId, NwConstants.EGRESS_ACL_FILTER_TABLE,
395 getTableMissFlowId(NwConstants.EGRESS_ACL_FILTER_TABLE), 0,
396 "Ingress Stateless Next ACL Table Miss Flow", 0, 0, AclConstants.COOKIE_ACL_BASE,
397 mkMatches, instructions);
398 mdsalManager.installFlow(nextTblFlowEntity);
400 LOG.debug("Added Stateless Ingress ACL Table Miss Flows for dpn {}.", dpId);
404 * Adds the stateless egress acl table miss flow.
406 * @param dpId the dp id
408 private void addStatelessEgressAclTableMissFlow(BigInteger dpId) {
409 List<InstructionInfo> allowAllInstructions = new ArrayList<>();
410 allowAllInstructions.add(
411 new InstructionInfo(InstructionType.goto_table, new long[] { NwConstants.INGRESS_ACL_FILTER_TABLE }));
413 List<MatchInfo> synMatches = new ArrayList<>();
414 synMatches.add(new MatchInfo(MatchFieldType.eth_type,
415 new long[] { NwConstants.ETHTYPE_IPV4 }));
416 synMatches.add(new MatchInfo(MatchFieldType.ip_proto,
417 new long[] { IPProtocols.TCP.intValue() }));
418 synMatches.add(new MatchInfo(MatchFieldType.tcp_flags, new long[] { AclConstants.TCP_FLAG_SYN }));
420 List<ActionInfo> synActionsInfos = new ArrayList<>();
421 synActionsInfos.add(new ActionInfo(ActionType.drop_action, new String[] {}));
422 List<InstructionInfo> synInstructions = new ArrayList<>();
423 synInstructions.add(new InstructionInfo(InstructionType.apply_actions, synActionsInfos));
425 FlowEntity synFlowEntity = MDSALUtil.buildFlowEntity(dpId, NwConstants.INGRESS_ACL_TABLE,
426 "SYN-" + getTableMissFlowId(NwConstants.INGRESS_ACL_TABLE),
427 AclConstants.PROTO_MATCH_SYN_DROP_PRIORITY, "Egress Syn ACL Table Block", 0, 0,
428 AclConstants.COOKIE_ACL_BASE, synMatches, synInstructions);
429 mdsalManager.installFlow(synFlowEntity);
431 synMatches = new ArrayList<>();
432 synMatches.add(new MatchInfo(MatchFieldType.eth_type,
433 new long[] { NwConstants.ETHTYPE_IPV4 }));
434 synMatches.add(new MatchInfo(MatchFieldType.ip_proto,
435 new long[] { IPProtocols.TCP.intValue() }));
436 synMatches.add(new MatchInfo(MatchFieldType.tcp_flags, new long[] { AclConstants.TCP_FLAG_SYN_ACK }));
438 FlowEntity synAckFlowEntity = MDSALUtil.buildFlowEntity(dpId, NwConstants.INGRESS_ACL_TABLE,
439 "SYN-ACK-ALLOW-" + getTableMissFlowId(NwConstants.INGRESS_ACL_TABLE),
440 AclConstants.PROTO_MATCH_SYN_ACK_ALLOW_PRIORITY, "Egress Syn Ack ACL Table Allow", 0, 0,
441 AclConstants.COOKIE_ACL_BASE, synMatches, allowAllInstructions);
442 mdsalManager.installFlow(synAckFlowEntity);
444 List<MatchInfo> mkMatches = new ArrayList<>();
445 FlowEntity flowEntity = MDSALUtil.buildFlowEntity(dpId, NwConstants.INGRESS_ACL_TABLE,
446 getTableMissFlowId(NwConstants.INGRESS_ACL_TABLE), 0, "Egress Stateless ACL Table Miss Flow", 0, 0,
447 AclConstants.COOKIE_ACL_BASE, mkMatches, allowAllInstructions);
448 mdsalManager.installFlow(flowEntity);
450 short dispatcherTableId = NwConstants.LPORT_DISPATCHER_TABLE;
452 List<ActionInfo> actionsInfos = new ArrayList<>();
453 List<InstructionInfo> dispatcherInstructions = new ArrayList<>();
454 actionsInfos.add(new ActionInfo(ActionType.nx_resubmit, new String[] {Short.toString(dispatcherTableId)}));
455 dispatcherInstructions.add(new InstructionInfo(InstructionType.apply_actions, actionsInfos));
457 FlowEntity nextTblFlowEntity = MDSALUtil.buildFlowEntity(dpId, NwConstants.INGRESS_ACL_FILTER_TABLE,
458 getTableMissFlowId(NwConstants.INGRESS_ACL_FILTER_TABLE), 0,
459 "Egress Stateless Next ACL Table Miss Flow", 0, 0, AclConstants.COOKIE_ACL_BASE, mkMatches,
460 dispatcherInstructions);
461 mdsalManager.installFlow(nextTblFlowEntity);
463 LOG.debug("Added Stateless Egress ACL Table Miss Flows for dpn {}", dpId);
467 * Adds the egress acl table miss flow.
469 * @param dpId the dp id
471 private void addEgressAclTableMissFlow(BigInteger dpId) {
472 List<MatchInfo> mkMatches = new ArrayList<>();
473 List<InstructionInfo> mkInstructions = new ArrayList<>();
474 List<ActionInfo> actionsInfos = new ArrayList<>();
475 actionsInfos.add(new ActionInfo(ActionType.drop_action, new String[] {}));
476 mkInstructions.add(new InstructionInfo(InstructionType.apply_actions, actionsInfos));
478 FlowEntity flowEntity = MDSALUtil.buildFlowEntity(dpId, NwConstants.INGRESS_ACL_TABLE,
479 getTableMissFlowId(NwConstants.INGRESS_ACL_TABLE), 0, "Egress ACL Table Miss Flow", 0, 0,
480 AclConstants.COOKIE_ACL_BASE, mkMatches, mkInstructions);
481 mdsalManager.installFlow(flowEntity);
483 FlowEntity nextTblFlowEntity = MDSALUtil.buildFlowEntity(dpId, NwConstants.INGRESS_ACL_FILTER_TABLE,
484 getTableMissFlowId(NwConstants.INGRESS_ACL_FILTER_TABLE), 0, "Egress ACL Table Miss Flow", 0, 0,
485 AclConstants.COOKIE_ACL_BASE, mkMatches, mkInstructions);
486 mdsalManager.installFlow(nextTblFlowEntity);
488 LOG.debug("Added Egress ACL Table Miss Flows for dpn {}", dpId);
491 private void addConntrackRules(BigInteger dpnId, short dispatcherTableId,short tableId, int write) {
492 programConntrackForwardRule(dpnId, AclConstants.CT_STATE_TRACKED_EXIST_PRIORITY,
493 "Tracked_Established", AclConstants.TRACKED_EST_CT_STATE, AclConstants.TRACKED_EST_CT_STATE_MASK,
494 dispatcherTableId, tableId, write );
495 programConntrackForwardRule(dpnId, AclConstants.CT_STATE_TRACKED_EXIST_PRIORITY,"Tracked_Related", AclConstants
496 .TRACKED_REL_CT_STATE, AclConstants.TRACKED_REL_CT_STATE_MASK, dispatcherTableId, tableId, write );
497 programConntrackDropRule(dpnId, AclConstants.CT_STATE_NEW_PRIORITY_DROP,"Tracked_New",
498 AclConstants.TRACKED_NEW_CT_STATE, AclConstants.TRACKED_NEW_CT_STATE_MASK, tableId, write );
499 programConntrackDropRule(dpnId, AclConstants.CT_STATE_NEW_PRIORITY_DROP, "Tracked_Invalid",
500 AclConstants.TRACKED_INV_CT_STATE, AclConstants.TRACKED_INV_CT_STATE_MASK, tableId, write );
505 * Adds the rule to forward the packets known packets.
507 * @param dpId the dpId
508 * @param lportTag the lport tag
509 * @param priority the priority of the flow
510 * @param flowId the flowId
511 * @param conntrackState the conntrack state of the packets thats should be
513 * @param conntrackMask the conntrack mask
514 * @param addOrRemove whether to add or remove the flow
516 private void programConntrackForwardRule(BigInteger dpId, Integer priority, String flowId,
517 int conntrackState, int conntrackMask, short dispatcherTableId, short tableId, int addOrRemove) {
518 List<MatchInfoBase> matches = new ArrayList<>();
519 matches.add(new NxMatchInfo(NxMatchFieldType.ct_state, new long[] {conntrackState, conntrackMask}));
521 List<InstructionInfo> instructions = getDispatcherTableResubmitInstructions(
522 new ArrayList<>(),dispatcherTableId);
524 flowId = "Fixed_Conntrk_Trk_" + dpId + "_" + flowId + dispatcherTableId;
525 syncFlow(dpId, tableId, flowId, priority, "ACL", 0, 0,
526 AclConstants.COOKIE_ACL_BASE, matches, instructions, addOrRemove);
530 * Adds the rule to drop the unknown/invalid packets .
532 * @param dpId the dpId
533 * @param lportTag the lport tag
534 * @param priority the priority of the flow
535 * @param flowId the flowId
536 * @param conntrackState the conntrack state of the packets thats should be
538 * @param conntrackMask the conntrack mask
539 * @param addOrRemove whether to add or remove the flow
541 private void programConntrackDropRule(BigInteger dpId, Integer priority, String flowId,
542 int conntrackState, int conntrackMask, short tableId, int addOrRemove) {
543 List<MatchInfoBase> matches = new ArrayList<>();
544 matches.add(new NxMatchInfo(NxMatchFieldType.ct_state, new long[] {conntrackState, conntrackMask}));
546 List<InstructionInfo> instructions = new ArrayList<>();
547 List<ActionInfo> actionsInfos = new ArrayList<>();
548 actionsInfos.add(new ActionInfo(ActionType.drop_action, new String[] {}));
549 instructions.add(new InstructionInfo(InstructionType.write_actions, actionsInfos));
550 flowId = "Fixed_Conntrk_NewDrop_" + dpId + "_" + flowId + tableId;
551 syncFlow(dpId, tableId, flowId, priority, "ACL", 0, 0,
552 AclConstants.COOKIE_ACL_BASE, matches, instructions, addOrRemove);
556 * Gets the dispatcher table resubmit instructions.
558 * @param actionsInfos the actions infos
559 * @return the instructions for dispatcher table resubmit
561 private List<InstructionInfo> getDispatcherTableResubmitInstructions(List<ActionInfo> actionsInfos,
562 short dispatcherTableId) {
563 List<InstructionInfo> instructions = new ArrayList<>();
564 actionsInfos.add(new ActionInfo(ActionType.nx_resubmit, new String[] {Short.toString(dispatcherTableId)}));
565 instructions.add(new InstructionInfo(InstructionType.apply_actions, actionsInfos));
570 * Writes/remove the flow to/from the datastore.
571 * @param dpId the dpId
572 * @param tableId the tableId
573 * @param flowId the flowId
574 * @param priority the priority
575 * @param flowName the flow name
576 * @param idleTimeOut the idle timeout
577 * @param hardTimeOut the hard timeout
578 * @param cookie the cookie
579 * @param matches the list of matches to be written
580 * @param instructions the list of instruction to be written.
581 * @param addOrRemove add or remove the entries.
583 protected void syncFlow(BigInteger dpId, short tableId, String flowId, int priority, String flowName,
584 int idleTimeOut, int hardTimeOut, BigInteger cookie, List<? extends MatchInfoBase> matches,
585 List<InstructionInfo> instructions, int addOrRemove) {
586 if (addOrRemove == NwConstants.DEL_FLOW) {
587 FlowEntity flowEntity = MDSALUtil.buildFlowEntity(dpId, tableId,flowId,
588 priority, flowName , idleTimeOut, hardTimeOut, cookie, matches, null);
589 LOG.trace("Removing Acl Flow DpnId {}, flowId {}", dpId, flowId);
590 mdsalManager.removeFlow(flowEntity);
592 FlowEntity flowEntity = MDSALUtil.buildFlowEntity(dpId, tableId, flowId,
593 priority, flowName, idleTimeOut, hardTimeOut, cookie, matches, instructions);
594 LOG.trace("Installing DpnId {}, flowId {}", dpId, flowId);
595 mdsalManager.installFlow(flowEntity);
600 * Gets the table miss flow id.
602 * @param tableId the table id
603 * @return the table miss flow id
605 private String getTableMissFlowId(short tableId) {
606 return String.valueOf(tableId);
610 protected AclNodeListener getDataTreeChangeListener() {
611 return AclNodeListener.this;