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 org.opendaylight.controller.md.sal.binding.api.DataBroker;
15 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
16 import org.opendaylight.genius.datastoreutils.AsyncDataTreeChangeListenerBase;
17 import org.opendaylight.genius.mdsalutil.ActionInfo;
18 import org.opendaylight.genius.mdsalutil.ActionType;
19 import org.opendaylight.genius.mdsalutil.FlowEntity;
20 import org.opendaylight.genius.mdsalutil.InstructionInfo;
21 import org.opendaylight.genius.mdsalutil.InstructionType;
22 import org.opendaylight.genius.mdsalutil.MDSALUtil;
23 import org.opendaylight.genius.mdsalutil.MatchInfo;
24 import org.opendaylight.genius.mdsalutil.NwConstants;
25 import org.opendaylight.genius.mdsalutil.interfaces.IMdsalApiManager;
26 import org.opendaylight.netvirt.aclservice.utils.AclConstants;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey;
31 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
32 import org.slf4j.Logger;
33 import org.slf4j.LoggerFactory;
36 * Listener to handle flow capable node updates.
38 public class AclNodeListener extends AsyncDataTreeChangeListenerBase<FlowCapableNode, AclNodeListener>
39 implements AutoCloseable {
41 /** The Constant LOG. */
42 private static final Logger LOG = LoggerFactory.getLogger(AclNodeListener.class);
44 /** The mdsal manager. */
45 private final IMdsalApiManager mdsalManager;
47 /** The data broker. */
48 private final DataBroker dataBroker;
51 * Instantiates a new acl node listener.
53 * @param mdsalManager the mdsal manager
55 public AclNodeListener(final IMdsalApiManager mdsalManager, DataBroker dataBroker) {
56 super(FlowCapableNode.class, AclNodeListener.class);
58 this.mdsalManager = mdsalManager;
59 this.dataBroker = dataBroker;
63 registerListener(LogicalDatastoreType.OPERATIONAL, dataBroker);
70 * org.opendaylight.genius.datastoreutils.AsyncDataTreeChangeListenerBase#
74 protected InstanceIdentifier<FlowCapableNode> getWildCardPath() {
75 return InstanceIdentifier.create(Nodes.class).child(Node.class).augmentation(FlowCapableNode.class);
82 * org.opendaylight.genius.datastoreutils.AsyncDataTreeChangeListenerBase#
83 * remove(org.opendaylight.yangtools.yang.binding.InstanceIdentifier,
84 * org.opendaylight.yangtools.yang.binding.DataObject)
87 protected void remove(InstanceIdentifier<FlowCapableNode> key, FlowCapableNode dataObjectModification) {
96 * org.opendaylight.genius.datastoreutils.AsyncDataTreeChangeListenerBase#
97 * update(org.opendaylight.yangtools.yang.binding.InstanceIdentifier,
98 * org.opendaylight.yangtools.yang.binding.DataObject,
99 * org.opendaylight.yangtools.yang.binding.DataObject)
102 protected void update(InstanceIdentifier<FlowCapableNode> key, FlowCapableNode dataObjectModificationBefore,
103 FlowCapableNode dataObjectModificationAfter) {
112 * org.opendaylight.genius.datastoreutils.AsyncDataTreeChangeListenerBase#
113 * add(org.opendaylight.yangtools.yang.binding.InstanceIdentifier,
114 * org.opendaylight.yangtools.yang.binding.DataObject)
117 protected void add(InstanceIdentifier<FlowCapableNode> key, FlowCapableNode dataObjectModification) {
118 LOG.trace("FlowCapableNode Added: key: {}", key);
120 NodeKey nodeKey = key.firstKeyOf(Node.class);
121 BigInteger dpnId = MDSALUtil.getDpnIdFromNodeName(nodeKey.getId());
122 createTableMissEntries(dpnId);
126 * Creates the table miss entries.
128 * @param dpnId the dpn id
130 private void createTableMissEntries(BigInteger dpnId) {
131 addIngressAclTableMissFlow(dpnId);
132 addEgressAclTableMissFlow(dpnId);
136 * Adds the ingress acl table miss flow.
138 * @param dpId the dp id
140 private void addIngressAclTableMissFlow(BigInteger dpId) {
141 List<MatchInfo> mkMatches = new ArrayList<>();
142 List<InstructionInfo> mkInstructions = new ArrayList<>();
143 List<ActionInfo> actionsInfos = new ArrayList<>();
144 actionsInfos.add(new ActionInfo(ActionType.drop_action, new String[] {}));
145 mkInstructions.add(new InstructionInfo(InstructionType.apply_actions, actionsInfos));
147 FlowEntity flowEntity = MDSALUtil.buildFlowEntity(dpId, NwConstants.INGRESS_ACL_TABLE_ID,
148 getTableMissFlowId(NwConstants.INGRESS_ACL_TABLE_ID), 0, "Ingress ACL Table Miss Flow", 0, 0,
149 AclConstants.COOKIE_ACL_BASE, mkMatches, mkInstructions);
150 mdsalManager.installFlow(flowEntity);
152 FlowEntity nextTblFlowEntity = MDSALUtil.buildFlowEntity(dpId, NwConstants.INGRESS_ACL_NEXT_TABLE_ID,
153 getTableMissFlowId(NwConstants.INGRESS_ACL_NEXT_TABLE_ID), 0, "Ingress ACL Filter Table Miss Flow",
154 0, 0, AclConstants.COOKIE_ACL_BASE, mkMatches, mkInstructions);
155 mdsalManager.installFlow(nextTblFlowEntity);
157 LOG.debug("Added Ingress ACL Table Miss Flows for dpn {}", dpId);
161 * Adds the egress acl table miss flow.
163 * @param dpId the dp id
165 private void addEgressAclTableMissFlow(BigInteger dpId) {
166 List<MatchInfo> mkMatches = new ArrayList<>();
167 List<InstructionInfo> mkInstructions = new ArrayList<>();
168 List<ActionInfo> actionsInfos = new ArrayList<>();
169 actionsInfos.add(new ActionInfo(ActionType.drop_action, new String[] {}));
170 mkInstructions.add(new InstructionInfo(InstructionType.apply_actions, actionsInfos));
172 FlowEntity flowEntity = MDSALUtil.buildFlowEntity(dpId, NwConstants.EGRESS_ACL_TABLE_ID,
173 getTableMissFlowId(NwConstants.EGRESS_ACL_TABLE_ID), 0, "Egress ACL Table Miss Flow", 0, 0,
174 AclConstants.COOKIE_ACL_BASE, mkMatches, mkInstructions);
175 mdsalManager.installFlow(flowEntity);
177 FlowEntity nextTblFlowEntity = MDSALUtil.buildFlowEntity(dpId, NwConstants.EGRESS_ACL_NEXT_TABLE_ID,
178 getTableMissFlowId(NwConstants.EGRESS_ACL_NEXT_TABLE_ID), 0, "Egress ACL Table Miss Flow", 0, 0,
179 AclConstants.COOKIE_ACL_BASE, mkMatches, mkInstructions);
180 mdsalManager.installFlow(nextTblFlowEntity);
182 LOG.debug("Added Egress ACL Table Miss Flows for dpn {}", dpId);
186 * Gets the table miss flow id.
188 * @param tableId the table id
189 * @return the table miss flow id
191 private String getTableMissFlowId(short tableId) {
192 return String.valueOf(tableId);
199 * org.opendaylight.genius.datastoreutils.AsyncDataTreeChangeListenerBase#
200 * getDataTreeChangeListener()
203 protected AclNodeListener getDataTreeChangeListener() {
204 return AclNodeListener.this;