Using Table Ids from NwConstants.java
[netvirt.git] / vpnservice / aclservice / impl / src / main / java / org / opendaylight / netvirt / aclservice / listeners / AclNodeListener.java
1 /*
2  * Copyright (c) 2016 Ericsson India Global Services Pvt Ltd. and others. All rights reserved.
3  *
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
7  */
8
9 package org.opendaylight.netvirt.aclservice.listeners;
10
11 import java.math.BigInteger;
12 import java.util.ArrayList;
13 import java.util.List;
14 import org.opendaylight.genius.datastoreutils.AsyncDataTreeChangeListenerBase;
15 import org.opendaylight.genius.mdsalutil.ActionInfo;
16 import org.opendaylight.genius.mdsalutil.ActionType;
17 import org.opendaylight.genius.mdsalutil.FlowEntity;
18 import org.opendaylight.genius.mdsalutil.InstructionInfo;
19 import org.opendaylight.genius.mdsalutil.InstructionType;
20 import org.opendaylight.genius.mdsalutil.MDSALUtil;
21 import org.opendaylight.genius.mdsalutil.MatchInfo;
22 import org.opendaylight.genius.mdsalutil.NwConstants;
23 import org.opendaylight.genius.mdsalutil.interfaces.IMdsalApiManager;
24 import org.opendaylight.netvirt.aclservice.utils.AclConstants;
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode;
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey;
29 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
30 import org.slf4j.Logger;
31 import org.slf4j.LoggerFactory;
32
33 /**
34  * Listener to handle flow capable node updates.
35  */
36 public class AclNodeListener extends AsyncDataTreeChangeListenerBase<FlowCapableNode, AclNodeListener>
37         implements AutoCloseable {
38
39     /** The Constant LOG. */
40     private static final Logger LOG = LoggerFactory.getLogger(AclNodeListener.class);
41
42     /** The mdsal manager. */
43     private IMdsalApiManager mdsalManager;
44
45     /**
46      * Instantiates a new acl node listener.
47      *
48      * @param mdsalManager the mdsal manager
49      */
50     public AclNodeListener(final IMdsalApiManager mdsalManager) {
51         super(FlowCapableNode.class, AclNodeListener.class);
52
53         this.mdsalManager = mdsalManager;
54     }
55
56     /*
57      * (non-Javadoc)
58      *
59      * @see
60      * org.opendaylight.genius.datastoreutils.AsyncDataTreeChangeListenerBase#
61      * getWildCardPath()
62      */
63     @Override
64     protected InstanceIdentifier<FlowCapableNode> getWildCardPath() {
65         return InstanceIdentifier.create(Nodes.class).child(Node.class).augmentation(FlowCapableNode.class);
66     }
67
68     /*
69      * (non-Javadoc)
70      *
71      * @see
72      * org.opendaylight.genius.datastoreutils.AsyncDataTreeChangeListenerBase#
73      * remove(org.opendaylight.yangtools.yang.binding.InstanceIdentifier,
74      * org.opendaylight.yangtools.yang.binding.DataObject)
75      */
76     @Override
77     protected void remove(InstanceIdentifier<FlowCapableNode> key, FlowCapableNode dataObjectModification) {
78         // do nothing
79
80     }
81
82     /*
83      * (non-Javadoc)
84      *
85      * @see
86      * org.opendaylight.genius.datastoreutils.AsyncDataTreeChangeListenerBase#
87      * update(org.opendaylight.yangtools.yang.binding.InstanceIdentifier,
88      * org.opendaylight.yangtools.yang.binding.DataObject,
89      * org.opendaylight.yangtools.yang.binding.DataObject)
90      */
91     @Override
92     protected void update(InstanceIdentifier<FlowCapableNode> key, FlowCapableNode dataObjectModificationBefore,
93             FlowCapableNode dataObjectModificationAfter) {
94         // do nothing
95
96     }
97
98     /*
99      * (non-Javadoc)
100      *
101      * @see
102      * org.opendaylight.genius.datastoreutils.AsyncDataTreeChangeListenerBase#
103      * add(org.opendaylight.yangtools.yang.binding.InstanceIdentifier,
104      * org.opendaylight.yangtools.yang.binding.DataObject)
105      */
106     @Override
107     protected void add(InstanceIdentifier<FlowCapableNode> key, FlowCapableNode dataObjectModification) {
108         LOG.trace("FlowCapableNode Added: key: {}", key);
109
110         NodeKey nodeKey = key.firstKeyOf(Node.class);
111         BigInteger dpnId = MDSALUtil.getDpnIdFromNodeName(nodeKey.getId());
112         createTableMissEntries(dpnId);
113     }
114
115     /**
116      * Creates the table miss entries.
117      *
118      * @param dpnId the dpn id
119      */
120     private void createTableMissEntries(BigInteger dpnId) {
121         addIngressAclTableMissFlow(dpnId);
122         addEgressAclTableMissFlow(dpnId);
123     }
124
125     /**
126      * Adds the ingress acl table miss flow.
127      *
128      * @param dpId the dp id
129      */
130     private void addIngressAclTableMissFlow(BigInteger dpId) {
131         List<MatchInfo> mkMatches = new ArrayList<>();
132         List<InstructionInfo> mkInstructions = new ArrayList<>();
133         List<ActionInfo> actionsInfos = new ArrayList<>();
134         actionsInfos.add(new ActionInfo(ActionType.drop_action, new String[] {}));
135         mkInstructions.add(new InstructionInfo(InstructionType.apply_actions, actionsInfos));
136
137         FlowEntity flowEntity = MDSALUtil.buildFlowEntity(dpId, NwConstants.INGRESS_ACL_TABLE_ID,
138                 getTableMissFlowId(NwConstants.INGRESS_ACL_TABLE_ID), 0, "Ingress ACL Table Miss Flow", 0, 0,
139                 AclConstants.COOKIE_ACL_BASE, mkMatches, mkInstructions);
140         mdsalManager.installFlow(flowEntity);
141
142         FlowEntity nextTblFlowEntity = MDSALUtil.buildFlowEntity(dpId, NwConstants.INGRESS_ACL_NEXT_TABLE_ID,
143                 getTableMissFlowId(NwConstants.INGRESS_ACL_NEXT_TABLE_ID), 0, "Ingress ACL Table Miss Flow", 0, 0,
144                 AclConstants.COOKIE_ACL_BASE, mkMatches, mkInstructions);
145         mdsalManager.installFlow(nextTblFlowEntity);
146
147         LOG.debug("Added Ingress ACL Table Miss Flows for dpn {}", dpId);
148     }
149
150     /**
151      * Adds the egress acl table miss flow.
152      *
153      * @param dpId the dp id
154      */
155     private void addEgressAclTableMissFlow(BigInteger dpId) {
156         List<MatchInfo> mkMatches = new ArrayList<>();
157         List<InstructionInfo> mkInstructions = new ArrayList<>();
158         List<ActionInfo> actionsInfos = new ArrayList<>();
159         actionsInfos.add(new ActionInfo(ActionType.drop_action, new String[] {}));
160         mkInstructions.add(new InstructionInfo(InstructionType.apply_actions, actionsInfos));
161
162         FlowEntity flowEntity = MDSALUtil.buildFlowEntity(dpId, NwConstants.EGRESS_ACL_TABLE_ID,
163                 getTableMissFlowId(NwConstants.EGRESS_ACL_TABLE_ID), 0, "Egress ACL Table Miss Flow", 0, 0,
164                 AclConstants.COOKIE_ACL_BASE, mkMatches, mkInstructions);
165         mdsalManager.installFlow(flowEntity);
166
167         FlowEntity nextTblFlowEntity = MDSALUtil.buildFlowEntity(dpId, NwConstants.EGRESS_ACL_NEXT_TABLE_ID,
168                 getTableMissFlowId(NwConstants.EGRESS_ACL_NEXT_TABLE_ID), 0, "Egress ACL Table Miss Flow", 0, 0,
169                 AclConstants.COOKIE_ACL_BASE, mkMatches, mkInstructions);
170         mdsalManager.installFlow(nextTblFlowEntity);
171
172         LOG.debug("Added Egress ACL Table Miss Flows for dpn {}", dpId);
173     }
174
175     /**
176      * Gets the table miss flow id.
177      *
178      * @param tableId the table id
179      * @return the table miss flow id
180      */
181     private String getTableMissFlowId(short tableId) {
182         return String.valueOf(tableId);
183     }
184
185     /*
186      * (non-Javadoc)
187      *
188      * @see
189      * org.opendaylight.genius.datastoreutils.AsyncDataTreeChangeListenerBase#
190      * getDataTreeChangeListener()
191      */
192     @Override
193     protected AclNodeListener getDataTreeChangeListener() {
194         return AclNodeListener.this;
195     }
196 }