/* * Copyright (c) 2016 Ericsson India Global Services Pvt Ltd. and others. All rights reserved. * * This program and the accompanying materials are made available under the * terms of the Eclipse Public License v1.0 which accompanies this distribution, * and is available at http://www.eclipse.org/legal/epl-v10.html */ package org.opendaylight.netvirt.aclservice.listeners; import java.math.BigInteger; import java.util.ArrayList; import java.util.List; import org.opendaylight.genius.datastoreutils.AsyncDataTreeChangeListenerBase; import org.opendaylight.genius.mdsalutil.ActionInfo; import org.opendaylight.genius.mdsalutil.ActionType; import org.opendaylight.genius.mdsalutil.FlowEntity; import org.opendaylight.genius.mdsalutil.InstructionInfo; import org.opendaylight.genius.mdsalutil.InstructionType; import org.opendaylight.genius.mdsalutil.MDSALUtil; import org.opendaylight.genius.mdsalutil.MatchInfo; import org.opendaylight.genius.mdsalutil.NwConstants; import org.opendaylight.genius.mdsalutil.interfaces.IMdsalApiManager; import org.opendaylight.netvirt.aclservice.utils.AclConstants; import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode; import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes; import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node; import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey; import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * Listener to handle flow capable node updates. */ public class AclNodeListener extends AsyncDataTreeChangeListenerBase implements AutoCloseable { /** The Constant LOG. */ private static final Logger LOG = LoggerFactory.getLogger(AclNodeListener.class); /** The mdsal manager. */ private IMdsalApiManager mdsalManager; /** * Instantiates a new acl node listener. * * @param mdsalManager the mdsal manager */ public AclNodeListener(final IMdsalApiManager mdsalManager) { super(FlowCapableNode.class, AclNodeListener.class); this.mdsalManager = mdsalManager; } /* * (non-Javadoc) * * @see * org.opendaylight.genius.datastoreutils.AsyncDataTreeChangeListenerBase# * getWildCardPath() */ @Override protected InstanceIdentifier getWildCardPath() { return InstanceIdentifier.create(Nodes.class).child(Node.class).augmentation(FlowCapableNode.class); } /* * (non-Javadoc) * * @see * org.opendaylight.genius.datastoreutils.AsyncDataTreeChangeListenerBase# * remove(org.opendaylight.yangtools.yang.binding.InstanceIdentifier, * org.opendaylight.yangtools.yang.binding.DataObject) */ @Override protected void remove(InstanceIdentifier key, FlowCapableNode dataObjectModification) { // do nothing } /* * (non-Javadoc) * * @see * org.opendaylight.genius.datastoreutils.AsyncDataTreeChangeListenerBase# * update(org.opendaylight.yangtools.yang.binding.InstanceIdentifier, * org.opendaylight.yangtools.yang.binding.DataObject, * org.opendaylight.yangtools.yang.binding.DataObject) */ @Override protected void update(InstanceIdentifier key, FlowCapableNode dataObjectModificationBefore, FlowCapableNode dataObjectModificationAfter) { // do nothing } /* * (non-Javadoc) * * @see * org.opendaylight.genius.datastoreutils.AsyncDataTreeChangeListenerBase# * add(org.opendaylight.yangtools.yang.binding.InstanceIdentifier, * org.opendaylight.yangtools.yang.binding.DataObject) */ @Override protected void add(InstanceIdentifier key, FlowCapableNode dataObjectModification) { LOG.trace("FlowCapableNode Added: key: {}", key); NodeKey nodeKey = key.firstKeyOf(Node.class); BigInteger dpnId = MDSALUtil.getDpnIdFromNodeName(nodeKey.getId()); createTableMissEntries(dpnId); } /** * Creates the table miss entries. * * @param dpnId the dpn id */ private void createTableMissEntries(BigInteger dpnId) { addIngressAclTableMissFlow(dpnId); addEgressAclTableMissFlow(dpnId); } /** * Adds the ingress acl table miss flow. * * @param dpId the dp id */ private void addIngressAclTableMissFlow(BigInteger dpId) { List mkMatches = new ArrayList<>(); List mkInstructions = new ArrayList<>(); List actionsInfos = new ArrayList<>(); actionsInfos.add(new ActionInfo(ActionType.drop_action, new String[] {})); mkInstructions.add(new InstructionInfo(InstructionType.apply_actions, actionsInfos)); FlowEntity flowEntity = MDSALUtil.buildFlowEntity(dpId, NwConstants.INGRESS_ACL_TABLE_ID, getTableMissFlowId(NwConstants.INGRESS_ACL_TABLE_ID), 0, "Ingress ACL Table Miss Flow", 0, 0, AclConstants.COOKIE_ACL_BASE, mkMatches, mkInstructions); mdsalManager.installFlow(flowEntity); FlowEntity nextTblFlowEntity = MDSALUtil.buildFlowEntity(dpId, NwConstants.INGRESS_ACL_NEXT_TABLE_ID, getTableMissFlowId(NwConstants.INGRESS_ACL_NEXT_TABLE_ID), 0, "Ingress ACL Table Miss Flow", 0, 0, AclConstants.COOKIE_ACL_BASE, mkMatches, mkInstructions); mdsalManager.installFlow(nextTblFlowEntity); LOG.debug("Added Ingress ACL Table Miss Flows for dpn {}", dpId); } /** * Adds the egress acl table miss flow. * * @param dpId the dp id */ private void addEgressAclTableMissFlow(BigInteger dpId) { List mkMatches = new ArrayList<>(); List mkInstructions = new ArrayList<>(); List actionsInfos = new ArrayList<>(); actionsInfos.add(new ActionInfo(ActionType.drop_action, new String[] {})); mkInstructions.add(new InstructionInfo(InstructionType.apply_actions, actionsInfos)); FlowEntity flowEntity = MDSALUtil.buildFlowEntity(dpId, NwConstants.EGRESS_ACL_TABLE_ID, getTableMissFlowId(NwConstants.EGRESS_ACL_TABLE_ID), 0, "Egress ACL Table Miss Flow", 0, 0, AclConstants.COOKIE_ACL_BASE, mkMatches, mkInstructions); mdsalManager.installFlow(flowEntity); FlowEntity nextTblFlowEntity = MDSALUtil.buildFlowEntity(dpId, NwConstants.EGRESS_ACL_NEXT_TABLE_ID, getTableMissFlowId(NwConstants.EGRESS_ACL_NEXT_TABLE_ID), 0, "Egress ACL Table Miss Flow", 0, 0, AclConstants.COOKIE_ACL_BASE, mkMatches, mkInstructions); mdsalManager.installFlow(nextTblFlowEntity); LOG.debug("Added Egress ACL Table Miss Flows for dpn {}", dpId); } /** * Gets the table miss flow id. * * @param tableId the table id * @return the table miss flow id */ private String getTableMissFlowId(short tableId) { return String.valueOf(tableId); } /* * (non-Javadoc) * * @see * org.opendaylight.genius.datastoreutils.AsyncDataTreeChangeListenerBase# * getDataTreeChangeListener() */ @Override protected AclNodeListener getDataTreeChangeListener() { return AclNodeListener.this; } }