Merge "Added support for VPN Intent" into stable/beryllium
authorVishal Thapar <vishal.thapar@ericsson.com>
Fri, 22 Jan 2016 14:38:25 +0000 (14:38 +0000)
committerGerrit Code Review <gerrit@opendaylight.org>
Fri, 22 Jan 2016 14:38:25 +0000 (14:38 +0000)
51 files changed:
alivenessmonitor/alivenessmonitor-api/src/main/yang/aliveness-monitor.yang
elanmanager/elanmanager-impl/src/main/java/org/opendaylight/vpnservice/elan/internal/ElanInterfaceManager.java
elanmanager/elanmanager-impl/src/main/java/org/opendaylight/vpnservice/elan/utils/ElanUtils.java
fibmanager/fibmanager-api/src/main/yang/odl-fib.yang
fibmanager/fibmanager-impl/src/main/java/org/opendaylight/vpnservice/fibmanager/FibManager.java
fibmanager/fibmanager-impl/src/main/java/org/opendaylight/vpnservice/fibmanager/FibUtil.java [new file with mode: 0644]
fibmanager/fibmanager-impl/src/main/java/org/opendaylight/vpnservice/fibmanager/NexthopManager.java
fibmanager/fibmanager-impl/src/test/java/org/opendaylight/vpnservice/fibmanager/test/FibManagerTest.java
interfacemgr/interfacemgr-api/src/main/java/org/opendaylight/vpnservice/interfacemgr/globals/LogicalGroupInterfaceInfo.java
interfacemgr/interfacemgr-api/src/main/yang/odl-interface-meta.yang
interfacemgr/interfacemgr-api/src/main/yang/odl-interface.yang
interfacemgr/interfacemgr-impl/pom.xml
interfacemgr/interfacemgr-impl/src/main/config/default-config.xml
interfacemgr/interfacemgr-impl/src/main/java/org/opendaylight/vpnservice/interfacemgr/IfmUtil.java
interfacemgr/interfacemgr-impl/src/main/java/org/opendaylight/vpnservice/interfacemgr/InterfacemgrProvider.java
interfacemgr/interfacemgr-impl/src/main/java/org/opendaylight/vpnservice/interfacemgr/commons/AlivenessMonitorUtils.java [new file with mode: 0644]
interfacemgr/interfacemgr-impl/src/main/java/org/opendaylight/vpnservice/interfacemgr/commons/InterfaceManagerCommonUtils.java
interfacemgr/interfacemgr-impl/src/main/java/org/opendaylight/vpnservice/interfacemgr/listeners/AlivenessMonitorListener.java [new file with mode: 0644]
interfacemgr/interfacemgr-impl/src/main/java/org/opendaylight/vpnservice/interfacemgr/listeners/InterfaceConfigListener.java
interfacemgr/interfacemgr-impl/src/main/java/org/opendaylight/vpnservice/interfacemgr/listeners/InterfaceInventoryStateListener.java
interfacemgr/interfacemgr-impl/src/main/java/org/opendaylight/vpnservice/interfacemgr/listeners/VlanMemberConfigListener.java
interfacemgr/interfacemgr-impl/src/main/java/org/opendaylight/vpnservice/interfacemgr/renderer/ovs/confighelpers/OvsInterfaceConfigAddHelper.java
interfacemgr/interfacemgr-impl/src/main/java/org/opendaylight/vpnservice/interfacemgr/renderer/ovs/confighelpers/OvsInterfaceConfigRemoveHelper.java
interfacemgr/interfacemgr-impl/src/main/java/org/opendaylight/vpnservice/interfacemgr/renderer/ovs/confighelpers/OvsInterfaceConfigUpdateHelper.java
interfacemgr/interfacemgr-impl/src/main/java/org/opendaylight/vpnservice/interfacemgr/renderer/ovs/confighelpers/OvsVlanMemberConfigUpdateHelper.java
interfacemgr/interfacemgr-impl/src/main/java/org/opendaylight/vpnservice/interfacemgr/renderer/ovs/statehelpers/OvsInterfaceStateAddHelper.java
interfacemgr/interfacemgr-impl/src/main/java/org/opendaylight/vpnservice/interfacemgr/renderer/ovs/statehelpers/OvsInterfaceStateRemoveHelper.java
interfacemgr/interfacemgr-impl/src/main/java/org/opendaylight/vpnservice/interfacemgr/renderer/ovs/statehelpers/OvsInterfaceStateUpdateHelper.java
interfacemgr/interfacemgr-impl/src/main/java/org/opendaylight/yang/gen/v1/urn/opendaylight/params/xml/ns/yang/interfacemgr/impl/rev150325/InterfacemgrImplModule.java
interfacemgr/interfacemgr-impl/src/main/yang/interfacemgr-impl.yang
interfacemgr/interfacemgr-impl/src/test/java/org/opendaylight/vpnservice/interfacemgr/test/StateInterfaceTest.java
interfacemgr/interfacemgr-impl/src/test/java/org/opendaylight/vpnservice/interfacemgr/test/TunnelInterfaceConfigurationTest.java
interfacemgr/interfacemgr-impl/src/test/java/org/opendaylight/vpnservice/interfacemgr/test/VlanInterfaceConfigurationTest.java
mdsalutil/mdsalutil-api/src/main/java/org/opendaylight/vpnservice/mdsalutil/ActionType.java
mdsalutil/mdsalutil-api/src/main/java/org/opendaylight/vpnservice/mdsalutil/MatchFieldType.java
mdsalutil/mdsalutil-api/src/main/java/org/opendaylight/vpnservice/mdsalutil/interfaces/IMdsalApiManager.java
mdsalutil/mdsalutil-impl/src/main/java/org/opendaylight/vpnservice/mdsalutil/internal/MDSALUtilProvider.java
model-bgp/src/main/yang/bgp.yang
model-bgp/src/main/yang/ebgp.yang
neutronvpn/neutronvpn-impl/src/main/java/org/opendaylight/vpnservice/neutronvpn/NeutronRouterChangeListener.java
neutronvpn/neutronvpn-impl/src/main/java/org/opendaylight/vpnservice/neutronvpn/NeutronvpnManager.java
neutronvpn/neutronvpn-impl/src/main/java/org/opendaylight/vpnservice/neutronvpn/NeutronvpnUtils.java
vpnmanager/vpnmanager-api/src/main/yang/odl-l3vpn.yang
vpnmanager/vpnmanager-impl/src/main/java/org/opendaylight/vpnservice/InterfaceStateChangeListener.java
vpnmanager/vpnmanager-impl/src/main/java/org/opendaylight/vpnservice/VpnConstants.java
vpnmanager/vpnmanager-impl/src/main/java/org/opendaylight/vpnservice/VpnInterfaceManager.java
vpnmanager/vpnmanager-impl/src/main/java/org/opendaylight/vpnservice/VpnManager.java
vpnmanager/vpnmanager-impl/src/main/java/org/opendaylight/vpnservice/VpnNotifyTask.java [new file with mode: 0644]
vpnmanager/vpnmanager-impl/src/main/java/org/opendaylight/vpnservice/VpnUtil.java
vpnmanager/vpnmanager-impl/src/main/java/org/opendaylight/vpnservice/VpnserviceProvider.java
vpnmanager/vpnmanager-impl/src/main/java/org/opendaylight/vpnservice/utilities/InterfaceUtils.java

index a9828107fc4971d4e3ddc1933eff78b7f2d210e6..134288f6542e598977e164edf30d248c4c28f71e 100644 (file)
@@ -4,6 +4,7 @@ module aliveness-monitor {
 
     import ietf-inet-types {
         prefix inet;
+        revision-date "2010-09-24";
     }
 
     revision "2015-06-29" {
index b933578d701e89efc5b3454c179252de2c811fed..329eed0e440eb9484c3f05a55f35eb1a84ce1d12 100644 (file)
@@ -15,27 +15,11 @@ import org.opendaylight.controller.md.sal.binding.api.DataChangeListener;
 import org.opendaylight.controller.md.sal.common.api.data.AsyncDataBroker.DataChangeScope;
 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
 import org.opendaylight.vpnservice.elan.utils.ElanConstants;
-import org.opendaylight.vpnservice.elan.utils.ElanConstants;
 import org.opendaylight.vpnservice.elan.utils.ElanUtils;
 import org.opendaylight.vpnservice.interfacemgr.globals.InterfaceInfo;
 import org.opendaylight.vpnservice.interfacemgr.globals.InterfaceInfo.InterfaceType;
 import org.opendaylight.vpnservice.interfacemgr.interfaces.IInterfaceManager;
 import org.opendaylight.vpnservice.itm.api.IITMProvider;
-import org.opendaylight.vpnservice.itm.globals.ITMConstants;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.OutputActionCase;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.PushVlanActionCase;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.SetFieldCase;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.Action;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.Match;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.*;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.general.rev140714.ExtensionKey;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.general.rev140714.GeneralAugMatchNodesNodeTableFlow;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.general.rev140714.GeneralAugMatchNodesNodeTableFlowBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.general.rev140714.general.extension.grouping.ExtensionBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.general.rev140714.general.extension.list.grouping.ExtensionList;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.general.rev140714.general.extension.list.grouping.ExtensionListBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.match.rev140714.*;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.match.rev140714.nxm.nx.reg.grouping.NxmNxRegBuilder;
 
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.servicebinding.rev151015.service.bindings.services.info.BoundServices;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.Instruction;
@@ -70,8 +54,6 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rpc
 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rpcs.rev151003.OdlInterfaceRpcService;
 import org.opendaylight.yangtools.concepts.ListenerRegistration;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.MatchBuilder;
-import org.opendaylight.yangtools.yang.common.RpcResult;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -79,8 +61,6 @@ import java.math.BigInteger;
 import java.util.*;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.ConcurrentLinkedQueue;
-import java.util.concurrent.ExecutionException;
-import java.util.concurrent.Future;
 
 
 public class ElanInterfaceManager extends AbstractDataChangeListener<ElanInterface> implements AutoCloseable {
@@ -443,8 +423,7 @@ public class ElanInterfaceManager extends AbstractDataChangeListener<ElanInterfa
             // LocalBroadcast Group creation with elan-Interfaces
             setupLocalBroadcastGroups(elanInfo, interfaceInfo);
 
-            //Remote-broadcast group & Terminating Service , UnknownDMAC Table.
-            //setupRemoteBroadcastGroups(elanInfo, interfaceInfo);
+            //Terminating Service , UnknownDMAC Table.
             setupTerminateServiceTable(elanInfo, interfaceInfo);
             setupUnknownDMacTable(elanInfo, interfaceInfo);
             setupFilterEqualsTable(elanInfo, interfaceInfo);
@@ -457,13 +436,9 @@ public class ElanInterfaceManager extends AbstractDataChangeListener<ElanInterfa
     }
 
     public void setupFilterEqualsTable(ElanInstance elanInfo, InterfaceInfo interfaceInfo) {
-        long elanTag = elanInfo.getElanTag();
-        long ifTag = interfaceInfo.getInterfaceTag();
-        List<MatchInfo> mkMatches = new ArrayList<MatchInfo>();
-        MatchBuilder mb = new MatchBuilder();
-        addNxRegMatch(mb, RegMatch.of(NxmNxReg1.class, ifTag));
+        int ifTag = interfaceInfo.getInterfaceTag();
         FlowEntity flowEntity = MDSALUtil.buildFlowEntity(interfaceInfo.getDpId(), ElanConstants.ELAN_FILTER_EQUALS_TABLE, getFlowRef(ElanConstants.ELAN_FILTER_EQUALS_TABLE, ifTag),
-                9, elanInfo.getElanInstanceName(), 0, 0, ElanConstants.COOKIE_ELAN_FILTER_EQUALS.add(BigInteger.valueOf(ifTag)), getMatchesForFilterEqualsReg1LPortTag(ifTag),
+                9, elanInfo.getElanInstanceName(), 0, 0, ElanConstants.COOKIE_ELAN_FILTER_EQUALS.add(BigInteger.valueOf(ifTag)), getTunnelIdMatchForFilterEqualsLPortTag(ifTag),
                 getInstructionsInPortForOutGroup(interfaceInfo.getInterfaceName()));
 
         mdsalManager.installFlow(flowEntity);
@@ -475,45 +450,6 @@ public class ElanInterfaceManager extends AbstractDataChangeListener<ElanInterfa
         mdsalManager.installFlow(flowEntity1);
     }
 
-
-    protected List<ActionInfo> getEgressActionsForInterface(String ifName) {
-        List<ActionInfo> listActionInfo = new ArrayList<ActionInfo>();
-        try {
-            Future<RpcResult<GetEgressActionsForInterfaceOutput>> result =
-                    interfaceManagerRpcService.getEgressActionsForInterface(
-                            new GetEgressActionsForInterfaceInputBuilder().setIntfName(ifName).build());
-            RpcResult<GetEgressActionsForInterfaceOutput> rpcResult = result.get();
-            System.out.println("Data is populated");
-            if(!rpcResult.isSuccessful()) {
-                logger.warn("RPC Call to Get egress actions for interface {} returned with Errors {}", ifName, rpcResult.getErrors());
-            } else {
-                List<org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.Action> actions =
-                        rpcResult.getResult().getAction();
-                for (Action action : actions) {
-                    org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.Action actionClass = action.getAction();
-                    if (actionClass instanceof OutputActionCase) {
-                        System.out.println("Data ");
-                        listActionInfo.add(new ActionInfo(ActionType.output,
-                                new String[] {((OutputActionCase)actionClass).getOutputAction()
-                                        .getOutputNodeConnector().getValue()}));
-                    } else if (actionClass instanceof PushVlanActionCase) {
-                        listActionInfo.add(new ActionInfo(ActionType.push_vlan, new String[] {}));
-                    } else if (actionClass instanceof SetFieldCase) {
-                        if (((SetFieldCase)actionClass).getSetField().getVlanMatch() != null) {
-                            int vlanVid = ((SetFieldCase)actionClass).getSetField().getVlanMatch().getVlanId().getVlanId().getValue();
-                            listActionInfo.add(new ActionInfo(ActionType.set_field_vlan_vid,
-                                    new String[] { Long.toString(vlanVid) }));
-                        }
-                    }
-                }
-            }
-        } catch (InterruptedException | ExecutionException e) {
-            logger.warn("Exception when egress actions for interface {}", ifName, e);
-        }
-        return listActionInfo;
-    }
-
-
     private List<BucketInfo> getRemoteBCGroupBucketInfos(ElanInstance elanInfo,
             InterfaceInfo interfaceInfo) {
         BigInteger dpnId = interfaceInfo.getDpId();
@@ -540,8 +476,8 @@ public class ElanInterfaceManager extends AbstractDataChangeListener<ElanInterfa
         return listBucketInfo;
     }
 
-    public ActionInfo getReg1ActionInfo(int interfaceTag) {
-         return new ActionInfo(ActionType.set_field_reg, new String[] {String.valueOf(interfaceTag)});
+    public ActionInfo getTunnelIdActionInfo(int interfaceTag) {
+         return new ActionInfo(ActionType.set_field_tunnel_id, new BigInteger[]{BigInteger.valueOf(interfaceTag)});
     }
 
     private void setRemoteBCGrouponOtherDpns(ElanInstance elanInfo,
@@ -726,14 +662,6 @@ public class ElanInterfaceManager extends AbstractDataChangeListener<ElanInterfa
         mdsalManager.syncRemoveGroup(groupEntity);
     }
 
-    public void setupRemoteBroadcastGroups(ElanInstance elanInfo, InterfaceInfo interfaceInfo) {
-        List<BucketInfo> listBucketInfo = getRemoteBCGroupBucketInfos(elanInfo, interfaceInfo);
-        BigInteger dpnId = interfaceInfo.getDpId();
-        long groupId = ElanUtils.getElanRemoteBCGID(elanInfo.getElanTag());
-        GroupEntity groupEntity = MDSALUtil.buildGroupEntity(dpnId, groupId, elanInfo.getElanInstanceName(), GroupTypes.GroupAll, listBucketInfo);
-        mdsalManager.syncInstallGroup(groupEntity, ElanConstants.DELAY_TIME_IN_MILLISECOND);
-    }
-
     public void removeRemoteBroadcastGroup(ElanInstance elanInfo, InterfaceInfo interfaceInfo) {
         List<BucketInfo> listBucketInfo = getRemoteBCGroupBucketInfos(elanInfo, interfaceInfo);
         BigInteger dpnId = interfaceInfo.getDpId();
@@ -850,7 +778,7 @@ public class ElanInterfaceManager extends AbstractDataChangeListener<ElanInterfa
 
     private List<ActionInfo> getInterfacePortActionInfos(InterfaceInfo interfaceInfo) {
         List<ActionInfo> listActionInfo = new ArrayList<ActionInfo>();
-        listActionInfo.add(getReg1ActionInfo(interfaceInfo.getInterfaceTag()));
+        listActionInfo.add(getTunnelIdActionInfo(interfaceInfo.getInterfaceTag()));
         listActionInfo.add(new ActionInfo(ActionType.nx_resubmit, new String[]{}));
         return listActionInfo;
     }
@@ -1028,95 +956,33 @@ public class ElanInterfaceManager extends AbstractDataChangeListener<ElanInterfa
         }
     }
 
-    private List<MatchInfo> getMatchesForFilterEqualsLPortTag(Long LportTag) {
+    private List<MatchInfo> getMatchesForFilterEqualsLPortTag(int LportTag) {
         List<MatchInfo> mkMatches = new ArrayList<MatchInfo>();
         // Matching metadata
         mkMatches.add(new MatchInfo(MatchFieldType.metadata, new BigInteger[] {
-                ElanUtils.getElanMetadataLabel(LportTag),
-                MetaDataUtil.METADATA_MASK_SERVICE }));
-        mkMatches.add(new MatchInfo(MatchFieldType.reg1, new long[] {LportTag.longValue()}));
+                MetaDataUtil.getLportTagMetaData(LportTag),
+                MetaDataUtil.METADATA_MASK_LPORT_TAG }));
+        mkMatches.add(new MatchInfo(MatchFieldType.tunnel_id, new BigInteger[] {BigInteger.valueOf(LportTag)}));
         return mkMatches;
     }
 
 
-    private List<MatchInfo> getMatchesForFilterEqualsReg1LPortTag(Long LportTag) {
+    private List<MatchInfo> getTunnelIdMatchForFilterEqualsLPortTag(int LportTag) {
         List<MatchInfo> mkMatches = new ArrayList<MatchInfo>();
         // Matching metadata
-        mkMatches.add(new MatchInfo(MatchFieldType.reg1, new long[] {
-                (LportTag.longValue())}));
+        mkMatches.add(new MatchInfo(MatchFieldType.tunnel_id, new BigInteger[] {
+                BigInteger.valueOf(LportTag)}));
         return mkMatches;
 
 
     }
 
-    public static class RegMatch {
-
-        final Class<? extends NxmNxReg> reg;
-        final Long value;
-
-        public RegMatch(Class<? extends NxmNxReg> reg, Long value) {
-            super();
-            this.reg = reg;
-            this.value = value;
-        }
-
-        public static RegMatch of(Class<? extends NxmNxReg> reg, Long value) {
-            return new RegMatch(reg, value);
-        }
-    }
-
-    public static void addNxRegMatch(MatchBuilder match, RegMatch... matches) {
-        ArrayList<ExtensionList> extensions = new ArrayList<>();
-        for (RegMatch rm : matches) {
-            Class<? extends ExtensionKey> key;
-            if (NxmNxReg0.class.equals(rm.reg)) {
-                key = NxmNxReg0Key.class;
-            } else if (NxmNxReg1.class.equals(rm.reg)) {
-                key = NxmNxReg1Key.class;
-            } else if (NxmNxReg2.class.equals(rm.reg)) {
-                key = NxmNxReg2Key.class;
-            } else if (NxmNxReg3.class.equals(rm.reg)) {
-                key = NxmNxReg3Key.class;
-            } else if (NxmNxReg4.class.equals(rm.reg)) {
-                key = NxmNxReg4Key.class;
-            } else if (NxmNxReg5.class.equals(rm.reg)) {
-                key = NxmNxReg5Key.class;
-            } else if (NxmNxReg6.class.equals(rm.reg)) {
-                key = NxmNxReg6Key.class;
-            } else {
-                key = NxmNxReg7Key.class;
-            }
-            NxAugMatchNodesNodeTableFlow am = new NxAugMatchNodesNodeTableFlowBuilder().setNxmNxReg(
-                    new NxmNxRegBuilder().setReg(rm.reg).setValue(rm.value).build()).build();
-            extensions.add(new ExtensionListBuilder().setExtensionKey(key)
-                    .setExtension(new ExtensionBuilder().addAugmentation(NxAugMatchNodesNodeTableFlow.class, am).build())
-                    .build());
-        }
-        GeneralAugMatchNodesNodeTableFlow m = new GeneralAugMatchNodesNodeTableFlowBuilder().setExtensionList(
-                extensions).build();
-        match.addAugmentation(GeneralAugMatchNodesNodeTableFlow.class, m);
-
-    }
-
-
-    private List<InstructionInfo> getInstructionsInPortForOutGroup(
-            long GroupId) {
-        List<InstructionInfo> mkInstructions = new ArrayList<InstructionInfo>();
-        List <ActionInfo> actionsInfos = new ArrayList <ActionInfo> ();
-        actionsInfos.add(new ActionInfo(ActionType.nx_resubmit, new String[]{ "123"}));
-        actionsInfos.add(new ActionInfo(ActionType.group, new String[]{Long.toString(GroupId)}));
-        mkInstructions.add(new InstructionInfo(InstructionType.write_actions, actionsInfos));
-        return mkInstructions;
-    }
-
     private List<InstructionInfo> getInstructionsInPortForOutGroup(
             String ifName) {
         List<InstructionInfo> mkInstructions = new ArrayList<InstructionInfo>();
         List <ActionInfo> actionsInfos = new ArrayList <ActionInfo> ();
-        //TODO: modify in-port action
-        //actionsInfos.add(new ActionInfo(ActionType.set_source_port_field, new String[]{ "255"}));
-        actionsInfos.addAll(getEgressActionsForInterface(ifName));
-        mkInstructions.add(new InstructionInfo(InstructionType.write_actions, actionsInfos));
+        actionsInfos.addAll(ElanUtils.getEgressActionsForInterface(ifName));
+        mkInstructions.add(new InstructionInfo(InstructionType.apply_actions, actionsInfos));
         return mkInstructions;
     }
 
index 0ffbf63932382bd8213d118d2eee9cf5d07c3edf..823da3e16672f3cb7680ba07344830059c3839e3 100644 (file)
@@ -28,22 +28,11 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.acti
 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.PushVlanActionCase;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.SetFieldCase;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.Action;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.MatchBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.Instruction;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
 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.yang.gen.v1.urn.opendaylight.vpnservice._interface.service.rev150602._interface.service.info.ServiceInfo;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.*;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.general.rev140714.ExtensionKey;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.general.rev140714.GeneralAugMatchNodesNodeTableFlow;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.general.rev140714.GeneralAugMatchNodesNodeTableFlowBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.general.rev140714.general.extension.grouping.ExtensionBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.general.rev140714.general.extension.list.grouping.ExtensionList;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.general.rev140714.general.extension.list.grouping.ExtensionListBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.match.rev140714.*;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.match.rev140714.nxm.nx.reg.grouping.NxmNxRegBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.rev150602.*;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.rev150602.elan._interface.forwarding.entries.ElanInterfaceMac;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.rev150602.elan._interface.forwarding.entries.ElanInterfaceMacKey;
@@ -68,9 +57,6 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.rev150602.e
 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.rev150602.forwarding.entries.MacEntry;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.rev150602.forwarding.entries.MacEntryKey;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.idmanager.rev150403.*;
-//import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rev150331.IfIndexesInterfaceMap;
-//import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rev150331._if.indexes._interface.map.IfIndexInterface;
-//import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rev150331._if.indexes._interface.map.IfIndexInterfaceKey;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rpcs.rev151003.GetEgressActionsForInterfaceInputBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rpcs.rev151003.GetEgressActionsForInterfaceOutput;
 import org.opendaylight.yangtools.yang.binding.DataObject;
@@ -199,54 +185,6 @@ public class ElanUtils {
         return null;
     }
 
-    public static class RegMatch {
-
-        final Class<? extends NxmNxReg> reg;
-        final Long value;
-
-        public RegMatch(Class<? extends NxmNxReg> reg, Long value) {
-            super();
-            this.reg = reg;
-            this.value = value;
-        }
-
-        public static RegMatch of(Class<? extends NxmNxReg> reg, Long value) {
-            return new RegMatch(reg, value);
-        }
-    }
-
-    public static void addNxRegMatch(MatchBuilder match, RegMatch... matches) {
-        ArrayList<ExtensionList> extensions = new ArrayList<>();
-        for (RegMatch rm : matches) {
-            Class<? extends ExtensionKey> key;
-            if (NxmNxReg0.class.equals(rm.reg)) {
-                key = NxmNxReg0Key.class;
-            } else if (NxmNxReg1.class.equals(rm.reg)) {
-                key = NxmNxReg1Key.class;
-            } else if (NxmNxReg2.class.equals(rm.reg)) {
-                key = NxmNxReg2Key.class;
-            } else if (NxmNxReg3.class.equals(rm.reg)) {
-                key = NxmNxReg3Key.class;
-            } else if (NxmNxReg4.class.equals(rm.reg)) {
-                key = NxmNxReg4Key.class;
-            } else if (NxmNxReg5.class.equals(rm.reg)) {
-                key = NxmNxReg5Key.class;
-            } else if (NxmNxReg6.class.equals(rm.reg)) {
-                key = NxmNxReg6Key.class;
-            } else {
-                key = NxmNxReg7Key.class;
-            }
-            NxAugMatchNodesNodeTableFlow am = new NxAugMatchNodesNodeTableFlowBuilder().setNxmNxReg(
-                    new NxmNxRegBuilder().setReg(rm.reg).setValue(rm.value).build()).build();
-            extensions.add(new ExtensionListBuilder().setExtensionKey(key)
-                    .setExtension(new ExtensionBuilder().addAugmentation(NxAugMatchNodesNodeTableFlow.class, am).build())
-                    .build());
-        }
-        GeneralAugMatchNodesNodeTableFlow m = new GeneralAugMatchNodesNodeTableFlowBuilder().setExtensionList(
-                extensions).build();
-        match.addAugmentation(GeneralAugMatchNodesNodeTableFlow.class, m);
-    }
-
     public static InstanceIdentifier<ElanInterface> getElanInterfaceConfigurationDataPathId(String interfaceName) {
         return InstanceIdentifier.builder(ElanInterfaces.class).child(ElanInterface.class,
                 new ElanInterfaceKey(interfaceName)).build();
@@ -519,7 +457,6 @@ public class ElanUtils {
                     elanServiceProvider.getInterfaceManagerRpcService().getEgressActionsForInterface(
                             new GetEgressActionsForInterfaceInputBuilder().setIntfName(ifName).build());
             RpcResult<GetEgressActionsForInterfaceOutput> rpcResult = result.get();
-            System.out.println("Data is populated");
             if(!rpcResult.isSuccessful()) {
                 logger.warn("RPC Call to Get egress actions for interface {} returned with Errors {}", ifName, rpcResult.getErrors());
             } else {
@@ -528,7 +465,6 @@ public class ElanUtils {
                 for (Action action : actions) {
                     org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.Action actionClass = action.getAction();
                     if (actionClass instanceof OutputActionCase) {
-                        System.out.println("Data ");
                         listActionInfo.add(new ActionInfo(ActionType.output,
                                 new String[] {((OutputActionCase)actionClass).getOutputAction()
                                         .getOutputNodeConnector().getValue()}));
index bea6c951615dc786d4fe01ebd202407b43d63dad..046855e323edba431836914bbdf25bdf85a1872b 100644 (file)
@@ -32,7 +32,7 @@ module odl-fib {
     }
 
     container fibEntries {
-        config false;
+        config true;
         list vrfTables{
             key "routeDistinguisher";
             leaf routeDistinguisher {type string;}
index 0135f1d10b2f3e7231add2b840497a7de0205b67..80500315315a38b9a18cd35d8a9d87daeb78c56e 100644 (file)
@@ -43,6 +43,7 @@ import org.opendaylight.vpnservice.mdsalutil.NwConstants;
 import org.opendaylight.vpnservice.mdsalutil.interfaces.IMdsalApiManager;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.l3vpn.rev130911.PrefixToInterface;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.l3vpn.rev130911.VpnInstanceOpData;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.l3vpn.rev130911.VpnToExtraroute;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.l3vpn.rev130911.prefix.to._interface.VpnIds;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.l3vpn.rev130911.prefix.to._interface.VpnIdsKey;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.l3vpn.rev130911.prefix.to._interface.vpn.ids.Prefixes;
@@ -52,6 +53,11 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.l3vpn.rev130911.vpn.instanc
 import org.opendaylight.yang.gen.v1.urn.opendaylight.l3vpn.rev130911.vpn.instance.op.data.vpn.instance.op.data.entry.VpnToDpnList;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.overlay.rev150105.TunnelTypeVxlan;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.itm.rpcs.rev151217.ItmRpcService;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.l3vpn.rev130911.vpn.to.extraroute.Vpn;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.l3vpn.rev130911.vpn.to.extraroute.VpnKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.l3vpn.rev130911.vpn.to.extraroute.vpn.Extraroute;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.l3vpn.rev130911.vpn.to.extraroute.vpn.ExtrarouteBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.l3vpn.rev130911.vpn.to.extraroute.vpn.ExtrarouteKey;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.fibmanager.rev150330.FibEntries;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.fibmanager.rev150330.fibentries.VrfTables;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.fibmanager.rev150330.fibentries.VrfTablesKey;
@@ -64,6 +70,9 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rpc
 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rpcs.rev151003.GetTunnelTypeOutput;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rpcs.rev151003.OdlInterfaceRpcService;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.l3nexthop.rev150409.l3nexthop.vpnnexthops.VpnNexthop;
+import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.interfaces.VpnInterface;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.l3vpn.rev130911.Adjacencies;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.l3vpn.rev130911.adjacency.list.Adjacency;
 import org.opendaylight.yangtools.concepts.ListenerRegistration;
 import org.opendaylight.yangtools.yang.binding.DataObject;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
@@ -90,17 +99,6 @@ public class FibManager extends AbstractDataChangeListener<VrfEntry> implements
   public static final BigInteger COOKIE_TUNNEL = new BigInteger("9000000", 16);
 
 
-  private static final FutureCallback<Void> DEFAULT_CALLBACK =
-      new FutureCallback<Void>() {
-        public void onSuccess(Void result) {
-          LOG.debug("Success in Datastore write operation");
-        }
-
-        public void onFailure(Throwable error) {
-          LOG.error("Error in Datastore write operation", error);
-        };
-      };
-
   public FibManager(final DataBroker db) {
     super(VrfEntry.class);
     broker = db;
@@ -142,7 +140,7 @@ public class FibManager extends AbstractDataChangeListener<VrfEntry> implements
 
   private void registerListener(final DataBroker db) {
     try {
-      listenerRegistration = db.registerDataChangeListener(LogicalDatastoreType.OPERATIONAL,
+      listenerRegistration = db.registerDataChangeListener(LogicalDatastoreType.CONFIGURATION,
                                                            getWildCardPath(), FibManager.this, DataChangeScope.SUBTREE);
     } catch (final Exception e) {
       LOG.error("FibManager DataChange listener registration fail!", e);
@@ -150,31 +148,11 @@ public class FibManager extends AbstractDataChangeListener<VrfEntry> implements
     }
   }
 
-  private <T extends DataObject> Optional<T> read(LogicalDatastoreType datastoreType,
-                                                  InstanceIdentifier<T> path) {
-
-    ReadOnlyTransaction tx = broker.newReadOnlyTransaction();
-
-    Optional<T> result = Optional.absent();
-    try {
-      result = tx.read(datastoreType, path).get();
-    } catch (Exception e) {
-      throw new RuntimeException(e);
-    }
-
-    return result;
-  }
 
   private InstanceIdentifier<VrfEntry> getWildCardPath() {
     return InstanceIdentifier.create(FibEntries.class).child(VrfTables.class).child(VrfEntry.class);
   }
 
-  private <T extends DataObject> void asyncWrite(LogicalDatastoreType datastoreType,
-                                                 InstanceIdentifier<T> path, T data, FutureCallback<Void> callback) {
-    WriteTransaction tx = broker.newWriteOnlyTransaction();
-    tx.put(datastoreType, path, data, true);
-    Futures.addCallback(tx.submit(), callback);
-  }
 
   @Override
   protected void add(final InstanceIdentifier<VrfEntry> identifier,
@@ -221,18 +199,20 @@ public class FibManager extends AbstractDataChangeListener<VrfEntry> implements
   public BigInteger createLocalFibEntry(Long vpnId, String rd, VrfEntry vrfEntry) {
     BigInteger localDpnId = BigInteger.ZERO;
     Prefixes localNextHopInfo = getPrefixToInterface(vpnId, vrfEntry.getDestPrefix());
-    boolean staticRoute = false;
+    String localNextHopIP = vrfEntry.getDestPrefix();
 
-    //If the vrf entry is a static/extra route, the nexthop of the entry would be a adjacency in the vpn
     if(localNextHopInfo == null) {
-      localNextHopInfo = getPrefixToInterface(vpnId, vrfEntry.getNextHopAddress() + "/32");
-      staticRoute = true;
+        //Is this fib route an extra route? If yes, get the nexthop which would be an adjacency in the vpn
+        Extraroute extra_route = getVpnToExtraroute(rd, vrfEntry.getDestPrefix());
+        if (extra_route != null) {
+            localNextHopInfo = getPrefixToInterface(vpnId, extra_route.getNexthopIp() + "/32");
+            localNextHopIP = extra_route.getNexthopIp() + "/32";
+        }
     }
 
     if(localNextHopInfo != null) {
       localDpnId = localNextHopInfo.getDpnId();
-      long groupId = nextHopManager.createLocalNextHop(vpnId, localDpnId, localNextHopInfo.getVpnInterfaceName(),
-                                                        (staticRoute == true) ? vrfEntry.getNextHopAddress() + "/32" : vrfEntry.getDestPrefix());
+      long groupId = nextHopManager.createLocalNextHop(vpnId, localDpnId, localNextHopInfo.getVpnInterfaceName(), localNextHopIP);
       List<ActionInfo> actionInfos = new ArrayList<ActionInfo>();
 
       actionInfos.add(new ActionInfo(ActionType.group, new String[] { String.valueOf(groupId)}));
@@ -296,23 +276,28 @@ public class FibManager extends AbstractDataChangeListener<VrfEntry> implements
   public BigInteger deleteLocalFibEntry(Long vpnId, String rd, VrfEntry vrfEntry) {
     BigInteger localDpnId = BigInteger.ZERO;
     VpnNexthop localNextHopInfo = nextHopManager.getVpnNexthop(vpnId, vrfEntry.getDestPrefix());
-    boolean staticRoute = false;
+    String localNextHopIP = vrfEntry.getDestPrefix();
 
-    //If the vrf entry is a static/extra route, the nexthop of the entry would be a adjacency in the vpn
     if(localNextHopInfo == null) {
-      localNextHopInfo = nextHopManager.getVpnNexthop(vpnId, vrfEntry.getNextHopAddress() + "/32");
-      staticRoute = true;
+        //Is this fib route an extra route? If yes, get the nexthop which would be an adjacency in the vpn
+        Extraroute extra_route = getVpnToExtraroute(rd, vrfEntry.getDestPrefix());
+        if (extra_route != null) {
+            localNextHopInfo = nextHopManager.getVpnNexthop(vpnId, extra_route.getNexthopIp());
+            localNextHopIP = extra_route.getNexthopIp() + "/32";
+        }
     }
 
+
     if(localNextHopInfo != null) {
       localDpnId = localNextHopInfo.getDpnId();
-      if (getPrefixToInterface(vpnId, (staticRoute == true) ? vrfEntry.getNextHopAddress() + "/32" : vrfEntry.getDestPrefix()) == null) {
+      //if (getPrefixToInterface(vpnId, (staticRoute == true) ? extra_route.getNextHopAddress() + "/32" : vrfEntry.getDestPrefix()) == null)
+      {
         makeConnectedRoute(localDpnId, vpnId, vrfEntry, rd, null /* invalid */,
                            NwConstants.DEL_FLOW);
         makeLFibTableEntry(localDpnId, vrfEntry.getLabel(), 0 /* invalid */,
                            vrfEntry.getNextHopAddress(), NwConstants.DEL_FLOW);
         removeTunnelTableEntry(localDpnId, vrfEntry.getLabel());
-        deleteLocalAdjacency(localDpnId, vpnId, (staticRoute == true) ? vrfEntry.getNextHopAddress() + "/32" : vrfEntry.getDestPrefix());
+        deleteLocalAdjacency(localDpnId, vpnId, localNextHopIP);
       }
     }
     return localDpnId;
@@ -325,10 +310,22 @@ public class FibManager extends AbstractDataChangeListener<VrfEntry> implements
 
   private Prefixes getPrefixToInterface(Long vpnId, String ipPrefix) {
     Optional<Prefixes> localNextHopInfoData =
-        read(LogicalDatastoreType.OPERATIONAL, getPrefixToInterfaceIdentifier(vpnId, ipPrefix));
+        FibUtil.read(broker, LogicalDatastoreType.OPERATIONAL, getPrefixToInterfaceIdentifier(vpnId, ipPrefix));
     return  localNextHopInfoData.isPresent() ? localNextHopInfoData.get() : null;
   }
-  
+
+    private InstanceIdentifier<Extraroute> getVpnToExtrarouteIdentifier(String vrfId, String ipPrefix) {
+        return InstanceIdentifier.builder(VpnToExtraroute.class)
+                .child(Vpn.class, new VpnKey(vrfId)).child(Extraroute.class,
+                        new ExtrarouteKey(ipPrefix)).build();
+    }
+
+    private Extraroute getVpnToExtraroute(String rd, String ipPrefix) {
+        Optional<Extraroute> extraRouteInfo =
+                FibUtil.read(broker, LogicalDatastoreType.OPERATIONAL, getVpnToExtrarouteIdentifier(rd, ipPrefix));
+        return  extraRouteInfo.isPresent() ? extraRouteInfo.get() : null;
+
+    }
 
   private Class<? extends TunnelTypeBase> getTunnelType(String ifName) {
         try {
@@ -354,7 +351,7 @@ public class FibManager extends AbstractDataChangeListener<VrfEntry> implements
     String rd = vrfTableKey.getRouteDistinguisher();
     LOG.debug("adding route " + vrfEntry.getDestPrefix() + " " + rd);
     /********************************************/
-    String tunnelInterface = resolveAdjacency(localDpnId, remoteDpnId, vpnId, vrfEntry);
+    String tunnelInterface = resolveAdjacency(localDpnId, remoteDpnId, vpnId, vrfEntry, rd);
     if(tunnelInterface == null) {
       LOG.error("Could not get interface for nexthop: {} in vpn {}",
                                    vrfEntry.getNextHopAddress(), rd);
@@ -414,6 +411,67 @@ public class FibManager extends AbstractDataChangeListener<VrfEntry> implements
         "Successfully added fib entry for " + vrfEntry.getDestPrefix() + " vpnId " + vpnId);
   }
 
+    private void delIntfFromDpnToVpnList(long vpnId, BigInteger dpnId, String intfName, String rd) {
+        InstanceIdentifier<VpnToDpnList> id = FibUtil.getVpnToDpnListIdentifier(rd, dpnId);
+        Optional<VpnToDpnList> dpnInVpn = FibUtil.read(broker, LogicalDatastoreType.OPERATIONAL, id);
+        if (dpnInVpn.isPresent()) {
+            List<org.opendaylight.yang.gen.v1.urn.opendaylight.l3vpn.rev130911.vpn.instance.op.data
+                    .vpn.instance.op.data.entry.vpn.to.dpn.list.VpnInterfaces> vpnInterfaces = dpnInVpn.get().getVpnInterfaces();
+            org.opendaylight.yang.gen.v1.urn.opendaylight.l3vpn.rev130911.vpn.instance.op.data.vpn.instance.op.data.entry.vpn.to.dpn.list.VpnInterfaces
+                    currVpnInterface = new org.opendaylight.yang.gen.v1.urn.opendaylight.l3vpn.rev130911.vpn.instance.op.data.vpn.instance.op.data.entry.vpn.to.dpn.list.VpnInterfacesBuilder().setInterfaceName(intfName).build();
+
+            if (vpnInterfaces.remove(currVpnInterface)) {
+                if (vpnInterfaces.isEmpty()) {
+                    //FibUtil.delete(broker, LogicalDatastoreType.OPERATIONAL, id);
+                    cleanUpDpnForVpn(dpnId, vpnId, rd);
+                } else {
+                    FibUtil.delete(broker, LogicalDatastoreType.OPERATIONAL, id.child(
+                            org.opendaylight.yang.gen.v1.urn.opendaylight.l3vpn.rev130911.vpn.instance.op.data
+                                    .vpn.instance.op.data.entry.vpn.to.dpn.list.VpnInterfaces.class,
+                            new org.opendaylight.yang.gen.v1.urn.opendaylight.l3vpn.rev130911.vpn.instance.op.data.vpn.instance.op.data.entry.vpn.to.dpn.list.VpnInterfacesKey(intfName)));
+                }
+            }
+        }
+    }
+
+  private void cleanUpOpDataForFib(Long vpnId, String rd, final VrfEntry vrfEntry) {
+    /* Get interface info from prefix to interface mapping;
+        Use the interface info to get the corresponding vpn interface op DS entry,
+        remove the adjacency corresponding to this fib entry.
+        If adjacency removed is the last adjacency, clean up the following:
+         - vpn interface from dpntovpn list, dpn if last vpn interface on dpn
+         - prefix to interface entry
+         - vpn interface op DS
+     */
+      Prefixes prefixInfo = getPrefixToInterface(vpnId, vrfEntry.getDestPrefix());
+      boolean extra_route = false;
+      if (prefixInfo == null) {
+          prefixInfo = getPrefixToInterface(vpnId, vrfEntry.getNextHopAddress() + "/32");
+          extra_route = true;
+      }
+      if (prefixInfo == null)
+          return; //Don't have any info for this prefix (shouldn't happen); need to return
+      String ifName = prefixInfo.getVpnInterfaceName();
+      Optional<Adjacencies> optAdjacencies = FibUtil.read(broker, LogicalDatastoreType.OPERATIONAL, FibUtil.getAdjListPath(ifName));
+      int numAdj = 0;
+      if (optAdjacencies.isPresent()) {
+          numAdj = optAdjacencies.get().getAdjacency().size();
+      }
+      //remove adjacency corr to prefix
+      FibUtil.delete(broker, LogicalDatastoreType.OPERATIONAL, FibUtil.getAdjacencyIdentifier(ifName, vrfEntry.getDestPrefix()));
+
+      if((numAdj - 1) == 0) { //there are no adjacencies left for this vpn interface, clean up
+        //clean up the vpn interface from DpnToVpn list
+          delIntfFromDpnToVpnList(vpnId, prefixInfo.getDpnId(), ifName, rd);
+          FibUtil.delete(broker, LogicalDatastoreType.OPERATIONAL,
+                  FibUtil.getPrefixToInterfaceIdentifier(
+                          vpnId,
+                          (extra_route) ? vrfEntry.getNextHopAddress() + "/32" : vrfEntry.getDestPrefix()));
+          FibUtil.delete(broker, LogicalDatastoreType.OPERATIONAL,
+                  FibUtil.getVpnInterfaceIdentifier(ifName));
+      }
+  }
+
   private void deleteFibEntries(final InstanceIdentifier<VrfEntry> identifier,
                                 final VrfEntry vrfEntry) {
     final VrfTablesKey vrfTableKey = identifier.firstKeyOf(VrfTables.class, VrfTablesKey.class);
@@ -431,8 +489,10 @@ public class FibManager extends AbstractDataChangeListener<VrfEntry> implements
           deleteRemoteRoute(localDpnId, curDpn.getDpnId(), vpnInstance.getVpnId(), vrfTableKey, vrfEntry);
         }
       }
-
     }
+    //The flow/group entry has been deleted from config DS; need to clean up associated operational
+    //DS entries in VPN Op DS, VpnInstanceOpData and PrefixToInterface to complete deletion
+    cleanUpOpDataForFib(vpnInstance.getVpnId(), vrfTableKey.getRouteDistinguisher(), vrfEntry);
   }
 
   public void deleteRemoteRoute(final BigInteger localDpnId, final BigInteger remoteDpnId,
@@ -440,7 +500,7 @@ public class FibManager extends AbstractDataChangeListener<VrfEntry> implements
                                 final VrfEntry vrfEntry) {
     LOG.debug("deleting route "+ vrfEntry.getDestPrefix() + " "+vpnId);
     String rd = vrfTableKey.getRouteDistinguisher();
-    String egressInterface = resolveAdjacency(localDpnId, remoteDpnId, vpnId, vrfEntry);
+    String egressInterface = resolveAdjacency(localDpnId, remoteDpnId, vpnId, vrfEntry, rd);
     if(egressInterface == null) {
       LOG.error("Could not get nexthop group id for nexthop: {} in vpn {}",
                 vrfEntry.getNextHopAddress(), rd);
@@ -506,13 +566,9 @@ public class FibManager extends AbstractDataChangeListener<VrfEntry> implements
       * for or for notification that operational DS write for flows is done. We do not turn on the stats writing for flows,
       * so that notification never comes, so we do not need that wait. Sending the lowest value of wait "1 ms" since 0 wait means
       * wait indefinitely. */
-      // FIXME: sync calls.
-      //mdsalManager.syncInstallFlow(flowEntity, 1);
-      mdsalManager.installFlow(flowEntity);
+      mdsalManager.syncInstallFlow(flowEntity, 1);
     } else {
-      // FIXME: sync calls.
-      // mdsalManager.syncRemoveFlow(flowEntity, 1);
-      mdsalManager.removeFlow(flowEntity);
+      mdsalManager.syncRemoveFlow(flowEntity, 1);
     }
   }
 
@@ -544,13 +600,9 @@ public class FibManager extends AbstractDataChangeListener<VrfEntry> implements
       * so that notification never comes, so we do not need that wait. Sending the lowest value of wait "1 ms" since 0 wait means
       * wait indefinitely. */
 
-      // FIXME:
-      // mdsalManager.syncInstallFlow(flowEntity, 1);
-      mdsalManager.installFlow(flowEntity);
+      mdsalManager.syncInstallFlow(flowEntity, 1);
     } else {
-      // FIXME:
-      // mdsalManager.syncRemoveFlow(flowEntity, 1);
-      mdsalManager.removeFlow(flowEntity);
+      mdsalManager.syncRemoveFlow(flowEntity, 1);
     }
     LOG.debug("LFIB Entry for dpID {} : label : {} group {} modified successfully {}",dpId, label, groupId );
   }
@@ -567,7 +619,7 @@ public class FibManager extends AbstractDataChangeListener<VrfEntry> implements
   public void populateFibOnNewDpn(BigInteger dpnId, long vpnId, String rd) {
     LOG.trace("New dpn {} for vpn {} : populateFibOnNewDpn", dpnId, rd);
     InstanceIdentifier<VrfTables> id = buildVrfId(rd);
-    Optional<VrfTables> vrfTable = read(LogicalDatastoreType.OPERATIONAL, id);
+    Optional<VrfTables> vrfTable = FibUtil.read(broker, LogicalDatastoreType.CONFIGURATION, id);
     if(vrfTable.isPresent()) {
       for(VrfEntry vrfEntry : vrfTable.get().getVrfEntry()) {
         // Passing null as we don't know the dpn
@@ -580,7 +632,7 @@ public class FibManager extends AbstractDataChangeListener<VrfEntry> implements
   public void cleanUpDpnForVpn(BigInteger dpnId, long vpnId, String rd) {
     LOG.trace("Remove dpn {} for vpn {} : cleanUpDpnForVpn", dpnId, rd);
     InstanceIdentifier<VrfTables> id = buildVrfId(rd);
-    Optional<VrfTables> vrfTable = read(LogicalDatastoreType.OPERATIONAL, id);
+    Optional<VrfTables> vrfTable = FibUtil.read(broker, LogicalDatastoreType.CONFIGURATION, id);
     if(vrfTable.isPresent()) {
       for(VrfEntry vrfEntry : vrfTable.get().getVrfEntry()) {
         // Passing null as we don't know the dpn
@@ -612,14 +664,20 @@ public class FibManager extends AbstractDataChangeListener<VrfEntry> implements
   }
 
   protected String resolveAdjacency(final BigInteger localDpnId, final BigInteger remoteDpnId,
-                                              final long vpnId, final VrfEntry vrfEntry) {
+                                              final long vpnId, final VrfEntry vrfEntry, String rd) {
     String adjacency = null;
-    LOG.trace("resolveAdjacency called with localdpid{} remotedpid {}, vpnId{}, VrfEntry {}", localDpnId, remoteDpnId, vpnId, vrfEntry);;
+    boolean staticRoute = false;
+    LOG.trace("resolveAdjacency called with localdpid{} remotedpid {}, vpnId{}, VrfEntry {}", localDpnId, remoteDpnId, vpnId, vrfEntry);
     try {
-      adjacency =
+        Extraroute extra_route = getVpnToExtraroute(rd, vrfEntry.getDestPrefix());
+        if(extra_route != null) {
+            staticRoute = true;
+        }
+
+        adjacency =
           nextHopManager.getRemoteNextHopPointer(localDpnId, remoteDpnId, vpnId,
                                                  vrfEntry.getDestPrefix(),
-                                                 vrfEntry.getNextHopAddress());
+                  (staticRoute == true) ? extra_route.getNexthopIp() : vrfEntry.getNextHopAddress());
     } catch (NullPointerException e) {
       LOG.trace("", e);
     }
@@ -629,7 +687,7 @@ public class FibManager extends AbstractDataChangeListener<VrfEntry> implements
   protected VpnInstanceOpDataEntry getVpnInstance(String rd) {
     InstanceIdentifier<VpnInstanceOpDataEntry> id = InstanceIdentifier.create(VpnInstanceOpData.class).child(
         VpnInstanceOpDataEntry.class, new VpnInstanceOpDataEntryKey(rd));
-    Optional<VpnInstanceOpDataEntry> vpnInstanceOpData = read(LogicalDatastoreType.OPERATIONAL, id);
+    Optional<VpnInstanceOpDataEntry> vpnInstanceOpData = FibUtil.read(broker, LogicalDatastoreType.OPERATIONAL, id);
     if(vpnInstanceOpData.isPresent()) {
       return vpnInstanceOpData.get();
     }
@@ -707,7 +765,7 @@ public class FibManager extends AbstractDataChangeListener<VrfEntry> implements
     result.add(String.format("   %-7s  %-20s  %-20s  %-7s", "RD", "Prefix", "Nexthop", "Label"));
     result.add("-------------------------------------------------------------------");
     InstanceIdentifier<FibEntries> id = InstanceIdentifier.create(FibEntries.class);
-    Optional<FibEntries> fibEntries = read(LogicalDatastoreType.OPERATIONAL, id);
+    Optional<FibEntries> fibEntries = FibUtil.read(broker, LogicalDatastoreType.CONFIGURATION, id);
     if (fibEntries.isPresent()) {
       List<VrfTables> vrfTables = fibEntries.get().getVrfTables();
       for (VrfTables vrfTable : vrfTables) {
diff --git a/fibmanager/fibmanager-impl/src/main/java/org/opendaylight/vpnservice/fibmanager/FibUtil.java b/fibmanager/fibmanager-impl/src/main/java/org/opendaylight/vpnservice/fibmanager/FibUtil.java
new file mode 100644 (file)
index 0000000..273d648
--- /dev/null
@@ -0,0 +1,108 @@
+/*
+ * 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.vpnservice.fibmanager;
+
+import com.google.common.base.Optional;
+import com.google.common.util.concurrent.FutureCallback;
+import com.google.common.util.concurrent.Futures;
+
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;
+import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.interfaces.VpnInterface;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.l3vpn.rev130911.Adjacencies;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.l3vpn.rev130911.adjacency.list.Adjacency;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.l3vpn.rev130911.prefix.to._interface.vpn.ids.Prefixes;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.l3vpn.rev130911.vpn.instance.op.data.vpn.instance.op.data.entry.VpnToDpnList;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.math.BigInteger;
+
+public class FibUtil {
+    private static final Logger LOG = LoggerFactory.getLogger(FibUtil.class);
+    static <T extends DataObject> Optional<T> read(DataBroker broker, LogicalDatastoreType datastoreType,
+                                                   InstanceIdentifier<T> path) {
+
+        ReadOnlyTransaction tx = broker.newReadOnlyTransaction();
+
+        Optional<T> result = Optional.absent();
+        try {
+            result = tx.read(datastoreType, path).get();
+        } catch (Exception e) {
+            throw new RuntimeException(e);
+        }
+
+        return result;
+    }
+
+    static <T extends DataObject> void asyncWrite(DataBroker broker, LogicalDatastoreType datastoreType,
+                                                  InstanceIdentifier<T> path, T data, FutureCallback<Void> callback) {
+        WriteTransaction tx = broker.newWriteOnlyTransaction();
+        tx.merge(datastoreType, path, data, true);
+        Futures.addCallback(tx.submit(), callback);
+    }
+
+    static <T extends DataObject> void syncWrite(DataBroker broker, LogicalDatastoreType datastoreType,
+                                                 InstanceIdentifier<T> path, T data, FutureCallback<Void> callback) {
+        WriteTransaction tx = broker.newWriteOnlyTransaction();
+        tx.merge(datastoreType, path, data, true);
+        tx.submit();
+    }
+
+    static <T extends DataObject> void delete(DataBroker broker, LogicalDatastoreType datastoreType, InstanceIdentifier<T> path) {
+        WriteTransaction tx = broker.newWriteOnlyTransaction();
+        tx.delete(datastoreType, path);
+        Futures.addCallback(tx.submit(), DEFAULT_CALLBACK);
+    }
+
+    static InstanceIdentifier<Adjacency> getAdjacencyIdentifier(String vpnInterfaceName, String ipAddress) {
+        return InstanceIdentifier.builder(org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.VpnInterfaces.class)
+                .child(org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.interfaces.VpnInterface.class, new org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.interfaces.VpnInterfaceKey(vpnInterfaceName)).augmentation(
+                        org.opendaylight.yang.gen.v1.urn.opendaylight.l3vpn.rev130911.Adjacencies.class).child(org.opendaylight.yang.gen.v1.urn.opendaylight.l3vpn.rev130911.adjacency.list.Adjacency.class, new org.opendaylight.yang.gen.v1.urn.opendaylight.l3vpn.rev130911.adjacency.list.AdjacencyKey(ipAddress)).build();
+    }
+
+    static InstanceIdentifier<Adjacencies> getAdjListPath(String vpnInterfaceName) {
+        return InstanceIdentifier.builder(org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.VpnInterfaces.class)
+                .child(org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.interfaces.VpnInterface.class, new org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.interfaces.VpnInterfaceKey(vpnInterfaceName)).augmentation(
+                        org.opendaylight.yang.gen.v1.urn.opendaylight.l3vpn.rev130911.Adjacencies.class).build();
+    }
+
+    static InstanceIdentifier<Prefixes> getPrefixToInterfaceIdentifier(long vpnId, String ipPrefix) {
+        return InstanceIdentifier.builder(org.opendaylight.yang.gen.v1.urn.opendaylight.l3vpn.rev130911.PrefixToInterface.class)
+                .child(org.opendaylight.yang.gen.v1.urn.opendaylight.l3vpn.rev130911.prefix.to._interface.VpnIds.class, new org.opendaylight.yang.gen.v1.urn.opendaylight.l3vpn.rev130911.prefix.to._interface.VpnIdsKey(vpnId)).child(org.opendaylight.yang.gen.v1.urn.opendaylight.l3vpn.rev130911.prefix.to._interface.vpn.ids.Prefixes.class,
+                        new org.opendaylight.yang.gen.v1.urn.opendaylight.l3vpn.rev130911.prefix.to._interface.vpn.ids.PrefixesKey(ipPrefix)).build();
+    }
+
+    static InstanceIdentifier<VpnInterface> getVpnInterfaceIdentifier(String vpnInterfaceName) {
+        return InstanceIdentifier.builder(org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.VpnInterfaces.class)
+                .child(org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.interfaces.VpnInterface.class, new org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.interfaces.VpnInterfaceKey(vpnInterfaceName)).build();
+    }
+
+    static InstanceIdentifier<VpnToDpnList> getVpnToDpnListIdentifier(String rd, BigInteger dpnId) {
+        return InstanceIdentifier.builder(org.opendaylight.yang.gen.v1.urn.opendaylight.l3vpn.rev130911.VpnInstanceOpData.class)
+                .child(org.opendaylight.yang.gen.v1.urn.opendaylight.l3vpn.rev130911.vpn.instance.op.data.VpnInstanceOpDataEntry.class, new org.opendaylight.yang.gen.v1.urn.opendaylight.l3vpn.rev130911.vpn.instance.op.data.VpnInstanceOpDataEntryKey(rd))
+                .child(org.opendaylight.yang.gen.v1.urn.opendaylight.l3vpn.rev130911.vpn.instance.op.data.vpn.instance.op.data.entry.VpnToDpnList.class, new org.opendaylight.yang.gen.v1.urn.opendaylight.l3vpn.rev130911.vpn.instance.op.data.vpn.instance.op.data.entry.VpnToDpnListKey(dpnId)).build();
+    }
+
+    static final FutureCallback<Void> DEFAULT_CALLBACK =
+            new FutureCallback<Void>() {
+                public void onSuccess(Void result) {
+                    LOG.debug("Success in Datastore operation");
+                }
+
+                public void onFailure(Throwable error) {
+                    LOG.error("Error in Datastore operation", error);
+                };
+            };
+
+}
index 83c6feb93a176d51d3c757b9496ab8ea9632e893..a3cd7c4eea9af109c9fde30e87a205b3441bbad3 100644 (file)
@@ -83,6 +83,7 @@ public class NexthopManager implements AutoCloseable {
     private static final short FIB_TABLE = 21;
     private static final short DEFAULT_FLOW_PRIORITY = 10;
     private static final String NEXTHOP_ID_POOL_NAME = "nextHopPointerPool";
+    private static final long FIXED_DELAY_IN_MILLISECONDS = 4000;
 
     private static final FutureCallback<Void> DEFAULT_CALLBACK =
         new FutureCallback<Void>() {
@@ -285,8 +286,7 @@ public class NexthopManager implements AutoCloseable {
                 addVpnNexthopToDS(dpnId, vpnId, ipAddress, groupId);
 
                 // install Group
-                // FIXME: mdsalManager.syncInstallGroup(groupEntity);
-                mdsalManager.installGroup(groupEntity);
+                mdsalManager.syncInstallGroup(groupEntity, FIXED_DELAY_IN_MILLISECONDS);
 
             } else {
                 //nexthop exists already; a new flow is going to point to it, increment the flowrefCount by 1
@@ -362,11 +362,13 @@ public class NexthopManager implements AutoCloseable {
                   localDpnId, remoteDpnId, vpnId, prefixIp, nextHopIp);
 
         LOG.trace("getRemoteNextHopPointer: Calling ITM with localDpnId {} ", localDpnId);
-        try{
-            // here use the config for tunnel type param
-            tunnelIfName = getTunnelInterfaceName(remoteDpnId, IpAddressBuilder.getDefaultInstance(nextHopIp));
-        }catch(Exception ex){
-            LOG.error("Error while retrieving nexthop pointer for DC Gateway : ", ex.getMessage());
+        if (nextHopIp != null && !nextHopIp.isEmpty()) {
+            try{
+                // here use the config for tunnel type param
+                tunnelIfName = getTunnelInterfaceName(remoteDpnId, IpAddressBuilder.getDefaultInstance(nextHopIp));
+            }catch(Exception ex){
+            LOG.error("Error while retrieving nexthop pointer for nexthop {} : ", nextHopIp, ex.getMessage());
+            }
         }
         return tunnelIfName;
     }
@@ -401,8 +403,7 @@ public class NexthopManager implements AutoCloseable {
                     GroupEntity groupEntity = MDSALUtil.buildGroupEntity(
                             dpnId, nh.getEgressPointer(), ipAddress, GroupTypes.GroupIndirect, null);
                     // remove Group ...
-                    // FIXME: mdsalManager.syncRemoveGroup(groupEntity);
-                    mdsalManager.removeGroup(groupEntity);
+                    mdsalManager.syncRemoveGroup(groupEntity);
                     //update MD-SAL DS
                     removeVpnNexthopFromDS(vpnId, ipAddress);
                     //release groupId
@@ -463,4 +464,10 @@ public class NexthopManager implements AutoCloseable {
             .child(VpnInterface.class, new VpnInterfaceKey(vpnInterfaceName)).augmentation(
                 Adjacencies.class).child(Adjacency.class, new AdjacencyKey(ipAddress)).build();
     }
+
+    InstanceIdentifier<Adjacencies> getAdjListPath(String vpnInterfaceName) {
+        return InstanceIdentifier.builder(VpnInterfaces.class)
+                .child(VpnInterface.class, new VpnInterfaceKey(vpnInterfaceName)).augmentation(
+                        Adjacencies.class).build();
+    }
 }
index f68a5f5f145c31baf80397af0555906eef2fca62..89841010dd808e0e5c56ed614e4257738f51a102 100644 (file)
@@ -77,6 +77,7 @@ public class FibManagerTest {
   private static final int label = 10;
   BigInteger Dpn;
   private static final long vpnId = 101L;
+  private static final long vpnIntfCnt = 2;
 
   private void SetupMocks() {
     Dpn = BigInteger.valueOf(100000L);
@@ -115,6 +116,9 @@ public class FibManagerTest {
             return testRd;
           }
 
+          @Override
+          public Long getVpnInterfaceCount() { return vpnIntfCnt; }
+
           @Override
           public List<VpnToDpnList> getVpnToDpnList() {
             List <VpnToDpnList> vpnToDpnLists =  new ArrayList<>();
index c8206d080262ef5df2c346175de5825d00369a0f..72f820fc7ff32cdc024899b6bec73f1a68a681c6 100644 (file)
@@ -8,12 +8,8 @@
 package org.opendaylight.vpnservice.interfacemgr.globals;
 
 import java.math.BigInteger;
-import java.net.InetAddress;
-import java.util.*;
-
-import org.opendaylight.vpnservice.mdsalutil.ActionInfo;
-import org.opendaylight.vpnservice.mdsalutil.InstructionInfo;
-import org.opendaylight.vpnservice.mdsalutil.MatchInfo;
+import java.util.List;
+import java.util.ArrayList;
 
 public class LogicalGroupInterfaceInfo extends InterfaceInfo {
 
@@ -49,5 +45,3 @@ public class LogicalGroupInterfaceInfo extends InterfaceInfo {
 
 }
 
-/*--------------------------------*/
-
index ef6aa20aeef774d4325f6e6dfc5078a47bb4e9c1..8654cc8f12c9851ee17f4f639cbabb90d17b07e6 100644 (file)
@@ -73,5 +73,31 @@ module odl-interface-meta {
                    type string;
                }
            }
+   }
+
+   container interface-monitor-id-map {
+       config false;
+       list interface-monitor-id {
+           key interface-name;
+           leaf interface-name {
+               type string;
+           }
+           leaf-list monitor-id {
+               type uint32;
+           }
+       }
+   }
+
+   container monitor-id-interface-map {
+       config false;
+       list monitor-id-interface {
+           key monitor-id;
+           leaf monitor-id {
+               type uint32;
+           }
+           leaf interface-name {
+               type string;
+           }
        }
+   }
 }
\ No newline at end of file
index db04860f8f96f568d3d9a0a0d8fd1b21382c2edc..29994dafdc8937b8f29842a81f3e1f3595ae018b 100644 (file)
@@ -188,6 +188,16 @@ module odl-interface {
             type inet:ip-address;
             description "gateway IP address";
         }
+
+        leaf monitor-enabled {
+            type boolean;
+            default false;
+        }
+
+        leaf monitor-interval {
+             type uint32;
+              default 10000;
+        }
     }
 
     augment "/if:interfaces/if:interface" {
@@ -216,6 +226,7 @@ module odl-interface {
             description "gateway IP address";
         }
     }
+
     /* MPLS logical port */
     augment "/if:interfaces/if:interface" {
         ext:augment-identifier "if-mpls";
index 2045f87d03ba53aa47d8ff2380c6b4e252631070..0b726d415779ce0b68e9a81394c1dc587b41c850 100644 (file)
@@ -55,10 +55,19 @@ and is available at http://www.eclipse.org/legal/epl-v10.html
       <artifactId>idmanager-impl</artifactId>
       <version>${vpnservices.version}</version>
     </dependency>
+    <dependency>
+      <groupId>org.opendaylight.vpnservice</groupId>
+      <artifactId>alivenessmonitor-api</artifactId>
+      <version>${vpnservices.version}</version>
+    </dependency>
     <dependency>
       <groupId>org.opendaylight.ovsdb</groupId>
       <artifactId>southbound-api</artifactId>
       <version>${vpns.ovsdb.version}</version>
     </dependency>
+    <dependency>
+      <groupId>org.opendaylight.controller</groupId>
+      <artifactId>sal-binding-broker-impl</artifactId>
+    </dependency>
   </dependencies>
 </project>
index a7b9952a34d51d38ace63cf50fe1afb295ec68da..8eff6555a333c3c72e0cbae36d451a47a03461c2 100644 (file)
@@ -13,6 +13,7 @@ and is available at http://www.eclipse.org/legal/epl-v10.html
       <capability>urn:opendaylight:params:xml:ns:yang:interfacemgr:impl?module=interfacemgr-impl&amp;revision=2015-03-25</capability>
       <capability>urn:opendaylight:params:xml:ns:yang:mdsalutil:api?module=odl-mdsalutil&amp;revision=2015-04-10</capability>
       <capability>urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding?module=opendaylight-md-sal-binding&amp;revision=2013-10-28</capability>
+      <capability>urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl?module=opendaylight-sal-binding-broker-impl&amp;revision=2013-10-28</capability>
   </required-capabilities>
   <configuration>
 
@@ -29,6 +30,10 @@ and is available at http://www.eclipse.org/legal/epl-v10.html
             <type xmlns:mdsalutil="urn:opendaylight:params:xml:ns:yang:mdsalutil:api">mdsalutil:odl-mdsalutil</type>
             <name>mdsalutil-service</name>
           </mdsalutil>
+          <notification-service>
+            <type xmlns:bindingimpl="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl">bindingimpl:binding-new-notification-service</type>
+            <name>binding-notification-adapter</name>
+          </notification-service>
           <rpc-registry>
             <type xmlns:binding="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding">binding:binding-rpc-registry</type>
             <name>binding-rpc-broker</name>
index adebb5fa07010351bc0468af30fdd7de3a93e17f..eacf25cab94ba7fa55c8046a33c3670c2b6d1038 100644 (file)
@@ -21,6 +21,7 @@ import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
 import org.opendaylight.vpnservice.interfacemgr.globals.InterfaceInfo;
 import org.opendaylight.vpnservice.interfacemgr.globals.VlanInterfaceInfo;
 import org.opendaylight.vpnservice.interfacemgr.servicebindings.flowbased.utilities.FlowBasedServicesUtils;
+import org.opendaylight.vpnservice.mdsalutil.MDSALUtil;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.iana._if.type.rev140508.L2vlan;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.iana._if.type.rev140508.Tunnel;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.Interfaces;
@@ -36,6 +37,8 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.overlay.
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.overlay.rev150105.TunnelTypeGre;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.overlay.rev150105.TunnelTypeVxlan;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.DatapathId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.alivenessmonitor.rev150629.*;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.alivenessmonitor.rev150629.monitor.profile.create.input.ProfileBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.idmanager.rev150403.AllocateIdInput;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.idmanager.rev150403.AllocateIdInputBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.idmanager.rev150403.AllocateIdOutput;
@@ -45,6 +48,14 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.idmanager.rev150
 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.idmanager.rev150403.ReleaseIdInputBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.idmanager.rev150403.id.pools.IdPool;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.idmanager.rev150403.id.pools.IdPoolKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007.InterfaceMonitorIdMap;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007.MonitorIdInterfaceMap;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007._interface.monitor.id.map.InterfaceMonitorId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007._interface.monitor.id.map.InterfaceMonitorIdBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007._interface.monitor.id.map.InterfaceMonitorIdKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007.monitor.id._interface.map.MonitorIdInterface;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007.monitor.id._interface.map.MonitorIdInterfaceBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007.monitor.id._interface.map.MonitorIdInterfaceKey;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rev150331.IfL2vlan.L2vlanMode;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rev150331.IfTunnel;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rev150331.IfL2vlan;
@@ -273,7 +284,4 @@ public class IfmUtil {
         }
         return vlanInterfaceInfo;
     }
-
-
-
 }
index f1a9c84963399a5f4974a42c3dd7ad6f75c591d7..15a2866d0cc4818d97dcb1da7a0e6db62f08ff07 100644 (file)
@@ -13,6 +13,8 @@ import java.util.concurrent.ExecutionException;
 import java.util.concurrent.Future;
 
 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.md.sal.binding.api.NotificationPublishService;
+import org.opendaylight.controller.md.sal.binding.api.NotificationService;
 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
 import org.opendaylight.controller.sal.binding.api.BindingAwareBroker;
 import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.ProviderContext;
@@ -36,9 +38,11 @@ import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.InterfaceKey;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface.OperStatus;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.alivenessmonitor.rev150629.AlivenessMonitorListener;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.idmanager.rev150403.CreateIdPoolInput;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.idmanager.rev150403.CreateIdPoolInputBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.idmanager.rev150403.IdManagerService;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.alivenessmonitor.rev150629.AlivenessMonitorService;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rpcs.rev151003.GetDpidFromInterfaceInput;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rpcs.rev151003.GetDpidFromInterfaceInputBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rpcs.rev151003.GetDpidFromInterfaceOutput;
@@ -59,6 +63,8 @@ public class InterfacemgrProvider implements BindingAwareProvider, AutoCloseable
 
     private RpcProviderRegistry rpcProviderRegistry;
     private IdManagerService idManager;
+    private NotificationService notificationService;
+    private AlivenessMonitorService alivenessManager;
     private IMdsalApiManager mdsalManager;
     private InterfaceConfigListener interfaceConfigListener;
     private InterfaceTopologyStateListener topologyStateListener;
@@ -66,6 +72,7 @@ public class InterfacemgrProvider implements BindingAwareProvider, AutoCloseable
     private FlowBasedServicesInterfaceStateListener flowBasedServicesInterfaceStateListener;
     private FlowBasedServicesConfigListener flowBasedServicesConfigListener;
     private VlanMemberConfigListener vlanMemberConfigListener;
+    private org.opendaylight.vpnservice.interfacemgr.listeners.AlivenessMonitorListener alivenessMonitorListener;
     private DataBroker dataBroker;
     private InterfaceManagerRpcService interfaceManagerRpcService;
     private BindingAwareBroker.RpcRegistration<OdlInterfaceRpcService> rpcRegistration;
@@ -78,6 +85,10 @@ public class InterfacemgrProvider implements BindingAwareProvider, AutoCloseable
         this.mdsalManager = mdsalManager;
     }
 
+    public void setNotificationService(NotificationService notificationService) {
+        this.notificationService = notificationService;
+    }
+
     @Override
     public void onSessionInitiated(ProviderContext session) {
         LOG.info("InterfacemgrProvider Session Initiated");
@@ -86,14 +97,15 @@ public class InterfacemgrProvider implements BindingAwareProvider, AutoCloseable
             idManager = rpcProviderRegistry.getRpcService(IdManagerService.class);
             createIdPool();
 
+            alivenessManager = rpcProviderRegistry.getRpcService(AlivenessMonitorService.class);
             interfaceManagerRpcService = new InterfaceManagerRpcService(dataBroker, mdsalManager);
             rpcRegistration = getRpcProviderRegistry().addRpcImplementation(
                     OdlInterfaceRpcService.class, interfaceManagerRpcService);
 
-            interfaceConfigListener = new InterfaceConfigListener(dataBroker, idManager);
+            interfaceConfigListener = new InterfaceConfigListener(dataBroker, idManager,alivenessManager);
             interfaceConfigListener.registerListener(LogicalDatastoreType.CONFIGURATION, dataBroker);
 
-            interfaceInventoryStateListener = new InterfaceInventoryStateListener(dataBroker, idManager, mdsalManager);
+            interfaceInventoryStateListener = new InterfaceInventoryStateListener(dataBroker, idManager, mdsalManager, alivenessManager);
             interfaceInventoryStateListener.registerListener(LogicalDatastoreType.OPERATIONAL, dataBroker);
 
             topologyStateListener = new InterfaceTopologyStateListener(dataBroker);
@@ -107,8 +119,10 @@ public class InterfacemgrProvider implements BindingAwareProvider, AutoCloseable
             flowBasedServicesInterfaceStateListener.registerListener(LogicalDatastoreType.OPERATIONAL, dataBroker);
 
             vlanMemberConfigListener =
-                               new VlanMemberConfigListener(dataBroker, idManager);
+                               new VlanMemberConfigListener(dataBroker, idManager, alivenessManager);
             vlanMemberConfigListener.registerListener(LogicalDatastoreType.CONFIGURATION, dataBroker);
+            alivenessMonitorListener = new org.opendaylight.vpnservice.interfacemgr.listeners.AlivenessMonitorListener(dataBroker);
+            notificationService.registerNotificationListener(alivenessMonitorListener);
         } catch (Exception e) {
             LOG.error("Error initializing services", e);
         }
@@ -198,7 +212,7 @@ public class InterfacemgrProvider implements BindingAwareProvider, AutoCloseable
         }
 
         if(interfaceType == InterfaceInfo.InterfaceType.VLAN_INTERFACE){
-               interfaceInfo = IfmUtil.getVlanInterfaceInfo(interfaceName, intf, dpId);
+            interfaceInfo = IfmUtil.getVlanInterfaceInfo(interfaceName, intf, dpId);
         } else if (interfaceType == InterfaceInfo.InterfaceType.VXLAN_TRUNK_INTERFACE || interfaceType == InterfaceInfo.InterfaceType.GRE_TRUNK_INTERFACE) {/*
             trunkInterfaceInfo trunkInterfaceInfo = (TrunkInterfaceInfo) ConfigIfmUtil.getTrunkInterfaceInfo(ifName, ConfigIfmUtil.getInterfaceByIfName(dataBroker, ifName));
             String higherLayerIf = inf.getHigherLayerIf().get(0);
@@ -229,21 +243,21 @@ public class InterfacemgrProvider implements BindingAwareProvider, AutoCloseable
     }
 
     @Override
-       public InterfaceInfo getInterfaceInfoFromOperationalDataStore(String interfaceName, InterfaceInfo.InterfaceType interfaceType) {
-               InterfaceInfo interfaceInfo = new InterfaceInfo(interfaceName);
-               org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface ifState = InterfaceManagerCommonUtils
-                               .getInterfaceStateFromOperDS(interfaceName, dataBroker);
-               if (ifState == null) {
-                       LOG.error("Interface {} is not present", interfaceName);
-                       return null;
-               }
+    public InterfaceInfo getInterfaceInfoFromOperationalDataStore(String interfaceName, InterfaceInfo.InterfaceType interfaceType) {
+        InterfaceInfo interfaceInfo = new InterfaceInfo(interfaceName);
+        org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface ifState = InterfaceManagerCommonUtils
+                .getInterfaceStateFromOperDS(interfaceName, dataBroker);
+        if (ifState == null) {
+            LOG.error("Interface {} is not present", interfaceName);
+            return null;
+        }
         Integer lportTag = ifState.getIfIndex();
-               Interface intf = InterfaceManagerCommonUtils.getInterfaceFromConfigDS(new InterfaceKey(interfaceName), dataBroker);
-               NodeConnectorId ncId = IfmUtil.getNodeConnectorIdFromInterface(intf, dataBroker);
-               if (ncId != null) {
-                       interfaceInfo.setDpId(new BigInteger(IfmUtil.getDpnFromNodeConnectorId(ncId)));
-                       interfaceInfo.setPortNo(Integer.parseInt(IfmUtil.getPortNoFromNodeConnectorId(ncId)));
-               }
+        Interface intf = InterfaceManagerCommonUtils.getInterfaceFromConfigDS(new InterfaceKey(interfaceName), dataBroker);
+        NodeConnectorId ncId = IfmUtil.getNodeConnectorIdFromInterface(intf, dataBroker);
+        if (ncId != null) {
+            interfaceInfo.setDpId(new BigInteger(IfmUtil.getDpnFromNodeConnectorId(ncId)));
+            interfaceInfo.setPortNo(Integer.parseInt(IfmUtil.getPortNoFromNodeConnectorId(ncId)));
+        }
         interfaceInfo.setAdminState((intf.isEnabled() == true) ? InterfaceAdminState.ENABLED : InterfaceAdminState.DISABLED);
         interfaceInfo.setInterfaceName(interfaceName);
         interfaceInfo.setInterfaceTag(lportTag);
@@ -253,7 +267,7 @@ public class InterfacemgrProvider implements BindingAwareProvider, AutoCloseable
 
 
         return interfaceInfo;
-               }
+    }
 
     @Override
     public BigInteger getDpnForInterface(String ifName) {
diff --git a/interfacemgr/interfacemgr-impl/src/main/java/org/opendaylight/vpnservice/interfacemgr/commons/AlivenessMonitorUtils.java b/interfacemgr/interfacemgr-impl/src/main/java/org/opendaylight/vpnservice/interfacemgr/commons/AlivenessMonitorUtils.java
new file mode 100644 (file)
index 0000000..598a4bc
--- /dev/null
@@ -0,0 +1,272 @@
+/*
+ * Copyright (c) 2015 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.vpnservice.interfacemgr.commons;
+
+import com.google.common.base.Optional;
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.vpnservice.interfacemgr.IfmConstants;
+import org.opendaylight.vpnservice.interfacemgr.IfmUtil;
+import org.opendaylight.vpnservice.mdsalutil.MDSALUtil;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpAddressBuilder;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.InterfaceKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.alivenessmonitor.rev150629.*;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.alivenessmonitor.rev150629.endpoint.endpoint.type.IpAddress;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.alivenessmonitor.rev150629.monitor.params.SourceBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.alivenessmonitor.rev150629.monitor.profile.create.input.ProfileBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.alivenessmonitor.rev150629.monitor.start.input.ConfigBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.idmanager.rev150403.IdManagerService;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007.*;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007._if.indexes._interface.map.IfIndexInterface;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007._if.indexes._interface.map.IfIndexInterfaceBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007._if.indexes._interface.map.IfIndexInterfaceKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007._interface.child.info.InterfaceParentEntry;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007._interface.child.info.InterfaceParentEntryKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007._interface.child.info._interface.parent.entry.InterfaceChildEntry;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007._interface.child.info._interface.parent.entry.InterfaceChildEntryKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007._interface.monitor.id.map.InterfaceMonitorId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007._interface.monitor.id.map.InterfaceMonitorIdBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007._interface.monitor.id.map.InterfaceMonitorIdKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007.bridge._interface.info.BridgeEntry;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007.bridge._interface.info.BridgeEntryKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007.bridge._interface.info.bridge.entry.BridgeInterfaceEntry;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007.bridge._interface.info.bridge.entry.BridgeInterfaceEntryBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007.bridge._interface.info.bridge.entry.BridgeInterfaceEntryKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007.bridge.ref.info.BridgeRefEntry;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007.bridge.ref.info.BridgeRefEntryKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007.monitor.id._interface.map.MonitorIdInterface;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007.monitor.id._interface.map.MonitorIdInterfaceBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007.monitor.id._interface.map.MonitorIdInterfaceKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rev150331.IfTunnel;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rev150331.TunnelTypeVxlan;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.common.RpcResult;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.Future;
+
+public class AlivenessMonitorUtils {
+
+    private static final Logger LOG = LoggerFactory.getLogger(AlivenessMonitorUtils.class);
+    private static final int FAILURE_THRESHOLD = 4;
+    private static final int MONITORING_INTERVAL = 10;
+    private static final int MONITORING_WINDOW = 4;
+
+    public static void startLLDPMonitoring(AlivenessMonitorService alivenessMonitorService, DataBroker dataBroker,
+                                            Interface trunkInterface) {
+        //LLDP monitoring for the trunk interface
+        /*String trunkInterfaceName = trunkInterface.getName();
+        IfTunnel ifTunnel = trunkInterface.getAugmentation(IfTunnel.class);
+        if(ifTunnel.getTunnelInterfaceType().isAssignableFrom(TunnelTypeVxlan.class)) {
+            MonitorStartInput lldpMonitorInput = new MonitorStartInputBuilder().setConfig(new ConfigBuilder()
+                    .setSource(new SourceBuilder().setEndpointType(getInterfaceForMonitoring(trunkInterfaceName,
+                            ifTunnel.getTunnelSource())).build())
+                    .setMode(MonitoringMode.OneOne)
+                    .setProfileId(allocateProfile(alivenessMonitorService, FAILURE_THRESHOLD, MONITORING_INTERVAL, MONITORING_WINDOW,
+                            EtherTypes.Lldp)).build()).build();
+            try {
+                Future<RpcResult<MonitorStartOutput>> result = alivenessMonitorService.monitorStart(lldpMonitorInput);
+                RpcResult<MonitorStartOutput> rpcResult = result.get();
+                long monitorId;
+                if (rpcResult.isSuccessful()) {
+                    monitorId = rpcResult.getResult().getMonitorId();
+                    createOrUpdateInterfaceMonitorIdMap(dataBroker, trunkInterfaceName, monitorId);
+                    createOrUpdateMonitorIdInterfaceMap(dataBroker, trunkInterfaceName, monitorId);
+                    LOG.trace("Started LLDP monitoring with id {}", monitorId);
+                } else {
+                    LOG.warn("RPC Call to start monitoring returned with Errors {}", rpcResult.getErrors());
+                }
+            } catch (InterruptedException | ExecutionException e) {
+                LOG.warn("Exception when starting monitoring", e);
+            }
+        }*/
+    }
+
+    public static void stopLLDPMonitoring(AlivenessMonitorService alivenessMonitorService, DataBroker dataBroker,
+                                          Interface trunkInterface) {
+        /*IfTunnel ifTunnel = trunkInterface.getAugmentation(IfTunnel.class);
+        if(!ifTunnel.getTunnelInterfaceType().isAssignableFrom(TunnelTypeVxlan.class)){
+            return;
+        }
+        List<Long> monitorIds = getMonitorIdForInterface(dataBroker, trunkInterface.getName());
+        if (monitorIds == null) {
+            LOG.error("Monitor Id doesn't exist for Interface {}", trunkInterface);
+            return;
+        }
+        for (Long monitorId : monitorIds) {
+            String interfaceName = getInterfaceFromMonitorId(dataBroker, monitorId);
+            if (interfaceName != null) {
+                MonitorStopInput input = new MonitorStopInputBuilder().setMonitorId(monitorId).build();
+                alivenessMonitorService.monitorStop(input);
+                removeMonitorIdInterfaceMap(dataBroker, monitorId);
+                removeMonitorIdFromInterfaceMonitorIdMap(dataBroker, interfaceName, monitorId);
+                return;
+            }
+        }*/
+    }
+
+    public static String getInterfaceFromMonitorId(DataBroker broker, Long monitorId) {
+        InstanceIdentifier<MonitorIdInterface> id = InstanceIdentifier.builder(MonitorIdInterfaceMap.class).child(MonitorIdInterface.class, new MonitorIdInterfaceKey(monitorId)).build();
+        Optional<MonitorIdInterface> interfaceMonitorIdMap = IfmUtil.read(LogicalDatastoreType.OPERATIONAL, id, broker);
+        if(interfaceMonitorIdMap.isPresent()) {
+            return interfaceMonitorIdMap.get().getInterfaceName();
+        }
+        return null;
+    }
+
+    private static void removeMonitorIdInterfaceMap(DataBroker broker, long monitorId) {
+        InstanceIdentifier<MonitorIdInterface> id = InstanceIdentifier.builder(MonitorIdInterfaceMap.class).child(MonitorIdInterface.class, new MonitorIdInterfaceKey(monitorId)).build();
+        Optional<MonitorIdInterface> monitorIdInterfaceMap = IfmUtil.read(LogicalDatastoreType.OPERATIONAL, id, broker);
+        if(monitorIdInterfaceMap.isPresent()) {
+            MDSALUtil.syncDelete(broker, LogicalDatastoreType.OPERATIONAL, id);
+        }
+    }
+
+    private static void removeMonitorIdFromInterfaceMonitorIdMap(DataBroker broker, String infName, long monitorId) {
+        InstanceIdentifier<InterfaceMonitorId> id = InstanceIdentifier.builder(InterfaceMonitorIdMap.class).child(InterfaceMonitorId.class, new InterfaceMonitorIdKey(infName)).build();
+        Optional<InterfaceMonitorId> interfaceMonitorIdMap = IfmUtil.read(LogicalDatastoreType.OPERATIONAL, id, broker);
+        if(interfaceMonitorIdMap.isPresent()) {
+            InterfaceMonitorId interfaceMonitorIdInstance = interfaceMonitorIdMap.get();
+            List<Long> existingMonitorIds = interfaceMonitorIdInstance.getMonitorId();
+            if (existingMonitorIds != null && existingMonitorIds.contains(monitorId)) {
+                existingMonitorIds.remove(monitorId);
+                InterfaceMonitorIdBuilder interfaceMonitorIdBuilder = new InterfaceMonitorIdBuilder();
+                interfaceMonitorIdInstance = interfaceMonitorIdBuilder.setKey(new InterfaceMonitorIdKey(infName)).setMonitorId(existingMonitorIds).build();
+                MDSALUtil.syncWrite(broker, LogicalDatastoreType.OPERATIONAL, id, interfaceMonitorIdInstance);
+            }
+        }
+    }
+
+    private static org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.alivenessmonitor.rev150629.endpoint.endpoint.type.Interface getInterfaceForMonitoring(String interfaceName, org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpAddress ipAddress) {
+        return new org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.alivenessmonitor.rev150629.endpoint.
+                endpoint.type.InterfaceBuilder().setInterfaceIp(ipAddress).setInterfaceName(interfaceName).build();
+    }
+
+    protected void handleTunnelMonitorEnabledUpdates(AlivenessMonitorService alivenessMonitorService, DataBroker dataBroker,
+                                                     List<String> interfaceNames, boolean origMonitorEnabled, boolean updatedMonitorEnabled) {
+        for (String interfaceName : interfaceNames) {
+            org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface tunnelInterface =
+                    InterfaceManagerCommonUtils.getInterfaceFromConfigDS(new InterfaceKey(interfaceName), dataBroker);
+            IfTunnel ifTunnel = tunnelInterface.getAugmentation(IfTunnel.class);
+            InterfaceManagerCommonUtils.updateTunnelMonitorDetailsInConfigDS(dataBroker, interfaceName, updatedMonitorEnabled, 3);
+            // Check if monitoring is started already
+            if (getMonitorIdForInterface(dataBroker, interfaceName) != null) {
+                // Get updated Interface details from Config DS
+                if(ifTunnel.getTunnelInterfaceType().isAssignableFrom(TunnelTypeVxlan.class)) {
+                    if (updatedMonitorEnabled) {
+                        startLLDPMonitoring(alivenessMonitorService, dataBroker, tunnelInterface);
+                    } else {
+                        stopLLDPMonitoring(alivenessMonitorService, dataBroker, tunnelInterface);
+                    }
+                }
+            }
+        }
+    }
+
+    protected void handleTunnelMonitorIntervalUpdates(AlivenessMonitorService alivenessMonitorService, DataBroker dataBroker,
+                                                      List<String> interfaceNames, long origMonitorInterval, long updatedMonitorInterval) {
+        for (String interfaceName : interfaceNames) {
+            org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface tunnelInterface =
+                    InterfaceManagerCommonUtils.getInterfaceFromConfigDS(new InterfaceKey(interfaceName), dataBroker);
+            IfTunnel ifTunnel = tunnelInterface.getAugmentation(IfTunnel.class);
+            InterfaceManagerCommonUtils.updateTunnelMonitorDetailsInConfigDS(dataBroker, interfaceName, ifTunnel.isMonitorEnabled(), updatedMonitorInterval);
+            // Restart LLDP monitoring only if it's started already
+            List<Long> monitorIds = getMonitorIdForInterface(dataBroker, interfaceName);
+            if (monitorIds != null && monitorIds.size() > 1) {
+                // Get updated Interface details from Config DS
+                if(ifTunnel.getTunnelInterfaceType().isAssignableFrom(TunnelTypeVxlan.class)) {
+                    stopLLDPMonitoring(alivenessMonitorService, dataBroker, tunnelInterface);
+                    startLLDPMonitoring(alivenessMonitorService, dataBroker,tunnelInterface);
+                }
+            }
+        }
+        // Delete old profile from Aliveness Manager
+        if (origMonitorInterval > 0) {
+            long profileId = allocateProfile(alivenessMonitorService, 4, origMonitorInterval, 4, EtherTypes.Lldp);
+            MonitorProfileDeleteInput  profileDeleteInput = new MonitorProfileDeleteInputBuilder().setProfileId(profileId).build();
+            alivenessMonitorService.monitorProfileDelete(profileDeleteInput);
+        }
+    }
+
+
+    public static void createOrUpdateInterfaceMonitorIdMap(DataBroker broker, String infName, long monitorId) {
+        InterfaceMonitorId interfaceMonitorIdInstance;
+        List<Long> existingMonitorIds;
+        InterfaceMonitorIdBuilder interfaceMonitorIdBuilder = new InterfaceMonitorIdBuilder();
+        InstanceIdentifier<InterfaceMonitorId> id = InstanceIdentifier.builder(InterfaceMonitorIdMap.class).child(InterfaceMonitorId.class, new InterfaceMonitorIdKey(infName)).build();
+        Optional<InterfaceMonitorId> interfaceMonitorIdMap = IfmUtil.read(LogicalDatastoreType.OPERATIONAL, id, broker);
+        if (interfaceMonitorIdMap.isPresent()) {
+            interfaceMonitorIdInstance = interfaceMonitorIdMap.get();
+            existingMonitorIds = interfaceMonitorIdInstance.getMonitorId();
+            if (existingMonitorIds == null) {
+                existingMonitorIds = new ArrayList<>();
+            }
+            if (!existingMonitorIds.contains(monitorId)) {
+                existingMonitorIds.add(monitorId);
+                interfaceMonitorIdInstance = interfaceMonitorIdBuilder.setKey(new InterfaceMonitorIdKey(infName)).setMonitorId(existingMonitorIds).build();
+                MDSALUtil.syncUpdate(broker, LogicalDatastoreType.OPERATIONAL, id, interfaceMonitorIdInstance);
+            }
+        } else {
+            existingMonitorIds = new ArrayList<>();
+            existingMonitorIds.add(monitorId);
+            interfaceMonitorIdInstance = interfaceMonitorIdBuilder.setMonitorId(existingMonitorIds).setKey(new InterfaceMonitorIdKey(infName)).setInterfaceName(infName).build();
+            MDSALUtil.syncWrite(broker, LogicalDatastoreType.OPERATIONAL, id, interfaceMonitorIdInstance);
+        }
+    }
+
+    public static void createOrUpdateMonitorIdInterfaceMap(DataBroker broker,String infName,  long monitorId) {
+        MonitorIdInterface monitorIdInterfaceInstance;
+        String existinginterfaceName;
+        MonitorIdInterfaceBuilder monitorIdInterfaceBuilder = new MonitorIdInterfaceBuilder();
+        InstanceIdentifier<MonitorIdInterface> id = InstanceIdentifier.builder(MonitorIdInterfaceMap.class).child(MonitorIdInterface.class, new MonitorIdInterfaceKey(monitorId)).build();
+        Optional<MonitorIdInterface> monitorIdInterfaceMap = IfmUtil.read(LogicalDatastoreType.OPERATIONAL, id, broker);
+        if(monitorIdInterfaceMap.isPresent()) {
+            monitorIdInterfaceInstance = monitorIdInterfaceMap.get();
+            existinginterfaceName = monitorIdInterfaceInstance.getInterfaceName();
+            if(!existinginterfaceName.equals(infName)) {
+                monitorIdInterfaceInstance = monitorIdInterfaceBuilder.setKey(new MonitorIdInterfaceKey(monitorId)).setInterfaceName(infName).build();
+                MDSALUtil.syncUpdate(broker, LogicalDatastoreType.OPERATIONAL, id, monitorIdInterfaceInstance);
+            }
+        } else {
+            monitorIdInterfaceInstance = monitorIdInterfaceBuilder.setMonitorId(monitorId).setKey(new MonitorIdInterfaceKey(monitorId)).setInterfaceName(infName).build();
+            MDSALUtil.syncWrite(broker, LogicalDatastoreType.OPERATIONAL, id, monitorIdInterfaceInstance);
+        }
+    }
+
+    public static List<Long> getMonitorIdForInterface(DataBroker broker, String infName) {
+        InstanceIdentifier<InterfaceMonitorId> id = InstanceIdentifier.builder(InterfaceMonitorIdMap.class).child(InterfaceMonitorId.class, new InterfaceMonitorIdKey(infName)).build();
+        Optional<InterfaceMonitorId> interfaceMonitorIdMap = IfmUtil.read(LogicalDatastoreType.OPERATIONAL, id, broker);
+        if(interfaceMonitorIdMap.isPresent()) {
+            return interfaceMonitorIdMap.get().getMonitorId();
+        }
+        return null;
+    }
+
+    public static long allocateProfile(AlivenessMonitorService alivenessMonitor, long failureThreshold, long interval, long window, EtherTypes etherType ) {
+        MonitorProfileCreateInput input = new MonitorProfileCreateInputBuilder().setProfile(new ProfileBuilder().setFailureThreshold(failureThreshold)
+                .setMonitorInterval(interval).setMonitorWindow(window).setProtocolType(etherType).build()).build();
+        try {
+            Future<RpcResult<MonitorProfileCreateOutput>> result = alivenessMonitor.monitorProfileCreate(input);
+            RpcResult<MonitorProfileCreateOutput> rpcResult = result.get();
+            if(rpcResult.isSuccessful()) {
+                return rpcResult.getResult().getProfileId();
+            } else {
+                LOG.warn("RPC Call to Get Profile Id Id returned with Errors {}", rpcResult.getErrors());
+            }
+        } catch (InterruptedException | ExecutionException e) {
+            LOG.warn("Exception when allocating profile Id",e);
+        }
+        return 0;
+    }
+}
\ No newline at end of file
index c3fafa07790a41890fa879ad4ffde6a524744432..0d134849438229e3bbe07d1bf28195b03b8d51af 100644 (file)
@@ -22,6 +22,7 @@ import org.opendaylight.vpnservice.mdsalutil.interfaces.IMdsalApiManager;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.Interfaces;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.InterfaceKey;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.InterfaceBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes;
@@ -29,8 +30,7 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.No
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnectorKey;
 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.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rev150331.IfTunnel;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rev150331.TunnelTypeMplsOverGre;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rev150331.*;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 import org.opendaylight.yangtools.yang.common.RpcResult;
 import org.slf4j.Logger;
@@ -110,4 +110,24 @@ public class InterfaceManagerCommonUtils {
     public static String getTunnelInterfaceFlowRef(BigInteger dpnId, short tableId, String ifName) {
         return new StringBuilder().append(dpnId).append(tableId).append(ifName).toString();
     }
+
+    public static void setOpStateForInterface(DataBroker broker, String interfaceName, org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface.OperStatus opStatus) {
+        InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface> interfaceId = IfmUtil.buildStateInterfaceId(interfaceName);
+        InterfaceBuilder ifaceBuilder = new InterfaceBuilder().setKey(new org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.InterfaceKey(interfaceName));
+        org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface interfaceData = ifaceBuilder.setOperStatus(opStatus).build();
+        MDSALUtil.syncUpdate(broker, LogicalDatastoreType.OPERATIONAL, interfaceId, interfaceData);
+    }
+
+    public static void updateTunnelMonitorDetailsInConfigDS(DataBroker broker, String interfaceName, boolean monitorEnabled, long monitorInterval) {
+        InstanceIdentifier<Interface> id = IfmUtil.buildId(interfaceName);
+        org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.InterfaceBuilder ifaceBuilder = new org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.InterfaceBuilder();
+        ifaceBuilder.setKey(new InterfaceKey(interfaceName));
+        IfTunnelBuilder ifTunnelBuilder = new IfTunnelBuilder();
+        ifTunnelBuilder.setMonitorEnabled(monitorEnabled);
+        ifTunnelBuilder.setMonitorInterval(monitorInterval);
+        ifaceBuilder.addAugmentation(IfTunnel.class, ifTunnelBuilder.build());
+
+        LOG.trace("Updating trunk interface {} in Config DS", interfaceName);
+        MDSALUtil.syncUpdate(broker, LogicalDatastoreType.OPERATIONAL, id, ifaceBuilder.build());
+    }
 }
\ No newline at end of file
diff --git a/interfacemgr/interfacemgr-impl/src/main/java/org/opendaylight/vpnservice/interfacemgr/listeners/AlivenessMonitorListener.java b/interfacemgr/interfacemgr-impl/src/main/java/org/opendaylight/vpnservice/interfacemgr/listeners/AlivenessMonitorListener.java
new file mode 100644 (file)
index 0000000..9f8b84c
--- /dev/null
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 2015 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.vpnservice.interfacemgr.listeners;
+
+import com.google.common.util.concurrent.ListenableFuture;
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.vpnservice.datastoreutils.AsyncDataTreeChangeListenerBase;
+import org.opendaylight.vpnservice.datastoreutils.DataStoreJobCoordinator;
+import org.opendaylight.vpnservice.interfacemgr.IfmUtil;
+import org.opendaylight.vpnservice.interfacemgr.commons.AlivenessMonitorUtils;
+import org.opendaylight.vpnservice.interfacemgr.commons.InterfaceManagerCommonUtils;
+import org.opendaylight.vpnservice.interfacemgr.globals.InterfaceInfo;
+import org.opendaylight.vpnservice.interfacemgr.renderer.ovs.confighelpers.OvsInterfaceConfigAddHelper;
+import org.opendaylight.vpnservice.interfacemgr.renderer.ovs.confighelpers.OvsInterfaceConfigRemoveHelper;
+import org.opendaylight.vpnservice.interfacemgr.renderer.ovs.confighelpers.OvsInterfaceConfigUpdateHelper;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.Interfaces;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.InterfaceKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.alivenessmonitor.rev150629.AlivenessMonitorService;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.alivenessmonitor.rev150629.LivenessState;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.alivenessmonitor.rev150629.MonitorEvent;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.idmanager.rev150403.IdManagerService;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rev150331.IfTunnel;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rev150331.ParentRefs;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rev150331.TunnelTypeGre;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rev150331.TunnelTypeVxlan;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.List;
+import java.util.concurrent.Callable;
+
+/**
+ * This class listens for interface creation/removal/update in Configuration DS.
+ * This is used to handle interfaces for base of-ports.
+ */
+public class AlivenessMonitorListener implements org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.alivenessmonitor.rev150629.AlivenessMonitorListener {
+    private static final Logger LOG = LoggerFactory.getLogger(AlivenessMonitorListener.class);
+    private DataBroker dataBroker;
+
+    public AlivenessMonitorListener(final DataBroker dataBroker) {
+        this.dataBroker = dataBroker;
+    }
+
+    @Override
+    public void onMonitorEvent(MonitorEvent notification) {
+        Long monitorId = notification.getEventData().getMonitorId();
+        String trunkInterfaceName = AlivenessMonitorUtils.getInterfaceFromMonitorId(dataBroker, monitorId);
+        if (trunkInterfaceName == null) {
+            LOG.debug("Either monitoring for interface - {} not started by Interfacemgr or it is not LLDP monitoring", trunkInterfaceName);
+            return;
+        }
+        LivenessState livenessState = notification.getEventData().getMonitorState();
+        Interface interfaceInfo = InterfaceManagerCommonUtils.getInterfaceFromConfigDS(new InterfaceKey(trunkInterfaceName),
+                dataBroker);
+        IfTunnel tunnelInfo = interfaceInfo.getAugmentation(IfTunnel.class);
+        // Not handling monitoring event if it is GRE Trunk Interface.
+        if (tunnelInfo.getTunnelInterfaceType().isAssignableFrom(TunnelTypeGre.class)) {
+            return;
+        }
+        org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface.OperStatus opState =
+                livenessState == LivenessState.Up ? org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface.OperStatus.Up :
+                        org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface.OperStatus.Down;
+        InterfaceManagerCommonUtils.setOpStateForInterface(dataBroker, trunkInterfaceName, opState);
+    }
+
+}
\ No newline at end of file
index 6e911667b56576ba0c7027419cfd9bcd4d2e0898..a519f3a0efcc1214657a04a9c5f9be20ca453469 100644 (file)
@@ -18,6 +18,7 @@ import org.opendaylight.vpnservice.interfacemgr.renderer.ovs.confighelpers.OvsIn
 import org.opendaylight.vpnservice.interfacemgr.renderer.ovs.confighelpers.OvsInterfaceConfigUpdateHelper;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.Interfaces;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.alivenessmonitor.rev150629.AlivenessMonitorService;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.idmanager.rev150403.IdManagerService;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rev150331.ParentRefs;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
@@ -35,11 +36,13 @@ public class InterfaceConfigListener extends AsyncDataTreeChangeListenerBase<Int
     private static final Logger LOG = LoggerFactory.getLogger(InterfaceConfigListener.class);
     private DataBroker dataBroker;
     private IdManagerService idManager;
+    private AlivenessMonitorService alivenessMonitorService;
 
-    public InterfaceConfigListener(final DataBroker dataBroker, final IdManagerService idManager) {
+    public InterfaceConfigListener(final DataBroker dataBroker, final IdManagerService idManager, final AlivenessMonitorService alivenessMonitorService) {
         super(Interface.class, InterfaceConfigListener.class);
         this.dataBroker = dataBroker;
         this.idManager = idManager;
+        this.alivenessMonitorService = alivenessMonitorService;
     }
 
     @Override
@@ -132,7 +135,8 @@ public class InterfaceConfigListener extends AsyncDataTreeChangeListenerBase<Int
         public List<ListenableFuture<Void>> call() throws Exception {
             // If another renderer(for eg : CSS) needs to be supported, check can be performed here
             // to call the respective helpers.
-            return OvsInterfaceConfigAddHelper.addConfiguration(dataBroker, parentRefs, interfaceNew, idManager);
+            return OvsInterfaceConfigAddHelper.addConfiguration(dataBroker, parentRefs, interfaceNew,
+                    idManager);
         }
 
         @Override
@@ -166,7 +170,8 @@ public class InterfaceConfigListener extends AsyncDataTreeChangeListenerBase<Int
         public List<ListenableFuture<Void>> call() throws Exception {
             // If another renderer(for eg : CSS) needs to be supported, check can be performed here
             // to call the respective helpers.
-            return OvsInterfaceConfigUpdateHelper.updateConfiguration(dataBroker, idManager, interfaceNew, interfaceOld);
+            return OvsInterfaceConfigUpdateHelper.updateConfiguration(dataBroker, alivenessMonitorService, idManager,
+                    interfaceNew, interfaceOld);
         }
 
         @Override
@@ -201,7 +206,8 @@ public class InterfaceConfigListener extends AsyncDataTreeChangeListenerBase<Int
         public List<ListenableFuture<Void>> call() throws Exception {
             // If another renderer(for eg : CSS) needs to be supported, check can be performed here
             // to call the respective helpers.
-            return OvsInterfaceConfigRemoveHelper.removeConfiguration(dataBroker, interfaceOld, idManager, parentRefs);
+            return OvsInterfaceConfigRemoveHelper.removeConfiguration(dataBroker, alivenessMonitorService,
+                    interfaceOld, idManager, parentRefs);
         }
 
         @Override
index e99e2912029973c97fb7cc80e15c9638efa98414..d2e56baf4480f2d9eba7487bff33448cc7f6f2de 100644 (file)
@@ -23,6 +23,7 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeCon
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnector;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.alivenessmonitor.rev150629.AlivenessMonitorService;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.idmanager.rev150403.IdManagerService;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 import org.slf4j.Logger;
@@ -44,12 +45,15 @@ public class InterfaceInventoryStateListener extends AsyncDataChangeListenerBase
     private DataBroker dataBroker;
     private IdManagerService idManager;
     private IMdsalApiManager mdsalApiManager;
+    private AlivenessMonitorService alivenessMonitorService;
 
-    public InterfaceInventoryStateListener(final DataBroker dataBroker, final IdManagerService idManager, final IMdsalApiManager mdsalApiManager) {
+    public InterfaceInventoryStateListener(final DataBroker dataBroker, final IdManagerService idManager,
+                                           final IMdsalApiManager mdsalApiManager, final AlivenessMonitorService alivenessMonitorService) {
         super(FlowCapableNodeConnector.class, InterfaceInventoryStateListener.class);
         this.dataBroker = dataBroker;
         this.idManager = idManager;
         this.mdsalApiManager = mdsalApiManager;
+        this.alivenessMonitorService = alivenessMonitorService;
     }
 
     @Override
@@ -73,11 +77,10 @@ public class InterfaceInventoryStateListener extends AsyncDataChangeListenerBase
                           FlowCapableNodeConnector flowCapableNodeConnectorOld) {
         LOG.debug("Received NodeConnector Remove Event: {}, {}", key, flowCapableNodeConnectorOld);
         String portName = flowCapableNodeConnectorOld.getName();
-        NodeConnectorId nodeConnectorId = InstanceIdentifier.keyOf(key.firstIdentifierOf(NodeConnector.class)).getId();
         DataStoreJobCoordinator coordinator = DataStoreJobCoordinator.getInstance();
 
-        InterfaceStateRemoveWorker interfaceStateRemoveWorker = new InterfaceStateRemoveWorker(idManager, key,
-                flowCapableNodeConnectorOld, portName);
+        InterfaceStateRemoveWorker interfaceStateRemoveWorker = new InterfaceStateRemoveWorker(idManager,
+                key, flowCapableNodeConnectorOld, portName);
         coordinator.enqueueJob(portName, interfaceStateRemoveWorker);
     }
 
@@ -124,7 +127,7 @@ public class InterfaceInventoryStateListener extends AsyncDataChangeListenerBase
         public Object call() throws Exception {
             // If another renderer(for eg : CSS) needs to be supported, check can be performed here
             // to call the respective helpers.
-             return OvsInterfaceStateAddHelper.addState(dataBroker, idManager, mdsalApiManager, nodeConnectorId,
+             return OvsInterfaceStateAddHelper.addState(dataBroker, idManager, mdsalApiManager, alivenessMonitorService, nodeConnectorId,
                      portName, fcNodeConnectorNew);
         }
 
@@ -159,7 +162,7 @@ public class InterfaceInventoryStateListener extends AsyncDataChangeListenerBase
         public Object call() throws Exception {
             // If another renderer(for eg : CSS) needs to be supported, check can be performed here
             // to call the respective helpers.
-            return OvsInterfaceStateUpdateHelper.updateState(key, dataBroker, portName,
+            return OvsInterfaceStateUpdateHelper.updateState(key, alivenessMonitorService, dataBroker, portName,
                     fcNodeConnectorNew, fcNodeConnectorOld);
         }
 
@@ -194,7 +197,8 @@ public class InterfaceInventoryStateListener extends AsyncDataChangeListenerBase
         public Object call() throws Exception {
             // If another renderer(for eg : CSS) needs to be supported, check can be performed here
             // to call the respective helpers.
-            return OvsInterfaceStateRemoveHelper.removeState(idManager, mdsalApiManager, key, dataBroker, portName, fcNodeConnectorOld);
+            return OvsInterfaceStateRemoveHelper.removeState(idManager, mdsalApiManager, alivenessMonitorService,
+                    key, dataBroker, portName, fcNodeConnectorOld);
         }
 
         @Override
index eb43d689abe927007580d8263a530d92686d44dc..ca4342dbfab3bfed95ac56e30e5288198477e35b 100644 (file)
@@ -17,6 +17,7 @@ import org.opendaylight.vpnservice.interfacemgr.renderer.ovs.confighelpers.OvsVl
 import org.opendaylight.vpnservice.interfacemgr.renderer.ovs.confighelpers.OvsVlanMemberConfigUpdateHelper;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.Interfaces;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.alivenessmonitor.rev150629.AlivenessMonitorService;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.idmanager.rev150403.IdManagerService;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rev150331.IfL2vlan;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rev150331.ParentRefs;
@@ -31,11 +32,14 @@ public class VlanMemberConfigListener extends AsyncDataTreeChangeListenerBase<In
     private static final Logger LOG = LoggerFactory.getLogger(VlanMemberConfigListener.class);
     private DataBroker dataBroker;
     private IdManagerService idManager;
+    private AlivenessMonitorService alivenessMonitorService;
 
-    public VlanMemberConfigListener(final DataBroker dataBroker, final IdManagerService idManager) {
+    public VlanMemberConfigListener(final DataBroker dataBroker, final IdManagerService idManager,
+                                    final AlivenessMonitorService alivenessMonitorService) {
         super(Interface.class, VlanMemberConfigListener.class);
         this.dataBroker = dataBroker;
         this.idManager = idManager;
+        this.alivenessMonitorService = alivenessMonitorService;
     }
 
     @Override
@@ -179,8 +183,8 @@ public class VlanMemberConfigListener extends AsyncDataTreeChangeListenerBase<In
         public List<ListenableFuture<Void>> call() throws Exception {
             // If another renderer(for eg : CSS) needs to be supported, check can be performed here
             // to call the respective helpers.
-            return OvsVlanMemberConfigUpdateHelper.updateConfiguration(dataBroker, parentRefsNew, interfaceOld,
-                    ifL2vlanNew, interfaceNew, idManager);
+            return OvsVlanMemberConfigUpdateHelper.updateConfiguration(dataBroker, alivenessMonitorService,
+                    parentRefsNew, interfaceOld, ifL2vlanNew, interfaceNew, idManager);
         }
     }
 
index 70fca216c73d681aaf45ccbf55ffbca43826cd06..07d67bdaf3052950018f5f8bbffa36f6c9148750 100644 (file)
@@ -9,15 +9,19 @@ package org.opendaylight.vpnservice.interfacemgr.renderer.ovs.confighelpers;
 
 import com.google.common.base.Optional;
 import com.google.common.util.concurrent.ListenableFuture;
+import org.eclipse.xtend.lib.annotations.Data;
 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
 import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
 import org.opendaylight.idmanager.IdManager;
 import org.opendaylight.vpnservice.interfacemgr.IfmConstants;
 import org.opendaylight.vpnservice.interfacemgr.IfmUtil;
+import org.opendaylight.vpnservice.interfacemgr.commons.AlivenessMonitorUtils;
 import org.opendaylight.vpnservice.interfacemgr.commons.InterfaceManagerCommonUtils;
 import org.opendaylight.vpnservice.interfacemgr.commons.InterfaceMetaUtils;
+import org.opendaylight.vpnservice.interfacemgr.globals.InterfaceInfo;
 import org.opendaylight.vpnservice.interfacemgr.renderer.ovs.utilities.SouthboundUtils;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpAddressBuilder;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.InterfaceKey;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface.OperStatus;
@@ -26,6 +30,9 @@ import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.PhysAddress;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbBridgeAugmentation;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.alivenessmonitor.rev150629.*;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.alivenessmonitor.rev150629.monitor.params.SourceBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.alivenessmonitor.rev150629.monitor.start.input.ConfigBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.idmanager.rev150403.IdManagerService;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007._interface.child.info.InterfaceParentEntry;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007._interface.child.info.InterfaceParentEntryKey;
@@ -36,18 +43,19 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.met
 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007.bridge._interface.info.bridge.entry.BridgeInterfaceEntryKey;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007.bridge.ref.info.BridgeRefEntry;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007.bridge.ref.info.BridgeRefEntryKey;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rev150331.IfL2vlan;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rev150331.IfTunnel;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rev150331.ParentRefs;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rev150331.*;
 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPoint;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.common.RpcResult;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 import java.math.BigInteger;
 import java.util.ArrayList;
 import java.util.List;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.Future;
 
 public class OvsInterfaceConfigAddHelper {
     private static final Logger LOG = LoggerFactory.getLogger(OvsInterfaceConfigAddHelper.class);
index 03f9c0600c40783e0b728da5a6b1c9d4df1b03f5..3956a43c1193ff8418040ba16c7c89e880a5a5ab 100644 (file)
@@ -13,6 +13,7 @@ import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
 import org.opendaylight.idmanager.IdManager;
 import org.opendaylight.vpnservice.interfacemgr.IfmUtil;
+import org.opendaylight.vpnservice.interfacemgr.commons.AlivenessMonitorUtils;
 import org.opendaylight.vpnservice.interfacemgr.commons.InterfaceManagerCommonUtils;
 import org.opendaylight.vpnservice.interfacemgr.commons.InterfaceMetaUtils;
 import org.opendaylight.vpnservice.interfacemgr.renderer.ovs.utilities.SouthboundUtils;
@@ -23,6 +24,9 @@ import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNodeConnector;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnector;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.alivenessmonitor.rev150629.AlivenessMonitorService;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.alivenessmonitor.rev150629.MonitorStopInput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.alivenessmonitor.rev150629.MonitorStopInputBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.idmanager.rev150403.IdManagerService;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007._interface.child.info.InterfaceParentEntry;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007._interface.child.info.InterfaceParentEntryKey;
@@ -49,18 +53,21 @@ import java.util.List;
 public class OvsInterfaceConfigRemoveHelper {
     private static final Logger LOG = LoggerFactory.getLogger(OvsInterfaceConfigRemoveHelper.class);
 
-    public static List<ListenableFuture<Void>> removeConfiguration(DataBroker dataBroker, Interface interfaceOld,
+    public static List<ListenableFuture<Void>> removeConfiguration(DataBroker dataBroker, AlivenessMonitorService alivenessMonitorService,
+                                                                   Interface interfaceOld,
                                                                    IdManagerService idManager, ParentRefs parentRefs) {
         List<ListenableFuture<Void>> futures = new ArrayList<>();
         WriteTransaction t = dataBroker.newWriteOnlyTransaction();
 
         IfTunnel ifTunnel = interfaceOld.getAugmentation(IfTunnel.class);
         if (ifTunnel != null) {
-            removeTunnelConfiguration(parentRefs, dataBroker, interfaceOld, idManager, t);
+            removeTunnelConfiguration(alivenessMonitorService, parentRefs, dataBroker, interfaceOld, idManager, t);
+            futures.add(t.submit());
+            AlivenessMonitorUtils.stopLLDPMonitoring(alivenessMonitorService, dataBroker, interfaceOld);
         }else {
             removeVlanConfiguration(dataBroker, interfaceOld, t);
+            futures.add(t.submit());
         }
-        futures.add(t.submit());
         return futures;
     }
 
@@ -123,7 +130,8 @@ public class OvsInterfaceConfigRemoveHelper {
         }
     }
 
-    private static void removeTunnelConfiguration(ParentRefs parentRefs, DataBroker dataBroker, Interface interfaceOld,
+    private static void removeTunnelConfiguration(AlivenessMonitorService alivenessMonitorService, ParentRefs parentRefs,
+                                                  DataBroker dataBroker, Interface interfaceOld,
                                                   IdManagerService idManager, WriteTransaction t) {
 
         BigInteger dpId = null;
index 0770bd5b1648f49fb88b9a3ac3aeb5b720dcbfe0..f6a76d339bb40db597d2c02618c13dc048f7c587 100644 (file)
@@ -13,8 +13,10 @@ import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
 import org.opendaylight.idmanager.IdManager;
 import org.opendaylight.vpnservice.interfacemgr.IfmUtil;
+import org.opendaylight.vpnservice.interfacemgr.commons.AlivenessMonitorUtils;
 import org.opendaylight.vpnservice.interfacemgr.commons.InterfaceManagerCommonUtils;
 import org.opendaylight.vpnservice.interfacemgr.commons.InterfaceMetaUtils;
+import org.opendaylight.vpnservice.interfacemgr.globals.InterfaceInfo;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.InterfaceKey;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface.OperStatus;
@@ -22,6 +24,10 @@ import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNodeConnector;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnector;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.alivenessmonitor.rev150629.AlivenessMonitorListener;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.alivenessmonitor.rev150629.AlivenessMonitorService;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.alivenessmonitor.rev150629.LivenessState;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.alivenessmonitor.rev150629.MonitorEvent;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.idmanager.rev150403.IdManagerService;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007._interface.child.info.InterfaceParentEntry;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007._interface.child.info.InterfaceParentEntryKey;
@@ -29,6 +35,7 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.met
 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rev150331.IfL2vlan;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rev150331.IfTunnel;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rev150331.ParentRefs;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rev150331.TunnelTypeVxlan;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -36,15 +43,16 @@ import org.slf4j.LoggerFactory;
 import java.util.ArrayList;
 import java.util.List;
 
-public class OvsInterfaceConfigUpdateHelper {
+public class OvsInterfaceConfigUpdateHelper{
     private static final Logger LOG = LoggerFactory.getLogger(OvsInterfaceConfigUpdateHelper.class);
 
-    public static List<ListenableFuture<Void>> updateConfiguration(DataBroker dataBroker,  IdManagerService idManager,
+    public static List<ListenableFuture<Void>> updateConfiguration(DataBroker dataBroker,  AlivenessMonitorService alivenessMonitorService,
+                                                                   IdManagerService idManager,
                                                                    Interface interfaceNew, Interface interfaceOld) {
         List<ListenableFuture<Void>> futures = new ArrayList<>();
 
         if(portAttributesModified(interfaceOld, interfaceNew)) {
-            futures.addAll(OvsInterfaceConfigRemoveHelper.removeConfiguration(dataBroker, interfaceOld, idManager,
+            futures.addAll(OvsInterfaceConfigRemoveHelper.removeConfiguration(dataBroker, alivenessMonitorService, interfaceOld, idManager,
                     interfaceOld.getAugmentation(ParentRefs.class)));
             futures.addAll(OvsInterfaceConfigAddHelper.addConfiguration(dataBroker,
                     interfaceNew.getAugmentation(ParentRefs.class), interfaceNew, idManager));
@@ -86,6 +94,10 @@ public class OvsInterfaceConfigUpdateHelper {
             IfL2vlan ifL2vlan = interfaceNew.getAugmentation(IfL2vlan.class);
             if (ifL2vlan == null || ifL2vlan.getL2vlanMode() != IfL2vlan.L2vlanMode.Trunk) {
                 futures.add(t.submit());
+                // stop tunnel monitoring if admin state is disabled for a vxlan trunk interface
+                if(!interfaceNew.isEnabled()){
+                    AlivenessMonitorUtils.stopLLDPMonitoring(alivenessMonitorService, dataBroker, interfaceNew);
+                }
                 return futures;
             }
 
@@ -159,4 +171,5 @@ public class OvsInterfaceConfigUpdateHelper {
 
         return false;
     }
+
 }
\ No newline at end of file
index 703322653f8ce402513d3579819d7b23bc40cd90..9111839dd22d2d735a02f79f8fbd5030118a1284 100644 (file)
@@ -18,6 +18,7 @@ import org.opendaylight.vpnservice.interfacemgr.commons.InterfaceMetaUtils;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface.OperStatus;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.InterfaceBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.alivenessmonitor.rev150629.AlivenessMonitorService;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.idmanager.rev150403.IdManagerService;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007._interface.child.info.InterfaceParentEntryKey;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007._interface.child.info._interface.parent.entry.InterfaceChildEntry;
@@ -33,7 +34,7 @@ import java.util.List;
 
 public class OvsVlanMemberConfigUpdateHelper {
     private static final Logger LOG = LoggerFactory.getLogger(OvsVlanMemberConfigUpdateHelper.class);
-    public static List<ListenableFuture<Void>> updateConfiguration(DataBroker dataBroker, ParentRefs parentRefsNew,
+    public static List<ListenableFuture<Void>> updateConfiguration(DataBroker dataBroker, AlivenessMonitorService alivenessMonitorService, ParentRefs parentRefsNew,
                                                                    Interface interfaceOld, IfL2vlan ifL2vlanNew,
                                                                    Interface interfaceNew, IdManagerService idManager) {
         List<ListenableFuture<Void>> futures = new ArrayList<>();
index 8a3faba162bb00794f34101978649b2078fcac50..e23fb3f64a543d60dfe1f5b7bcb54268cd072410 100644 (file)
@@ -15,6 +15,7 @@ import org.opendaylight.idmanager.IdManager;
 import org.opendaylight.vpnservice.VpnConstants;
 import org.opendaylight.vpnservice.interfacemgr.IfmConstants;
 import org.opendaylight.vpnservice.interfacemgr.IfmUtil;
+import org.opendaylight.vpnservice.interfacemgr.commons.AlivenessMonitorUtils;
 import org.opendaylight.vpnservice.interfacemgr.commons.InterfaceManagerCommonUtils;
 import org.opendaylight.vpnservice.interfacemgr.commons.InterfaceMetaUtils;
 import org.opendaylight.vpnservice.interfacemgr.servicebindings.flowbased.utilities.FlowBasedServicesUtils;
@@ -28,6 +29,7 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.Fl
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.Flow;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.Instruction;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.alivenessmonitor.rev150629.AlivenessMonitorService;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.idmanager.rev150403.IdManagerService;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007._interface.child.info.InterfaceParentEntry;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007._interface.child.info.InterfaceParentEntryKey;
@@ -54,7 +56,8 @@ import java.util.List;
 public class OvsInterfaceStateAddHelper {
     private static final Logger LOG = LoggerFactory.getLogger(OvsInterfaceStateAddHelper.class);
 
-    public static List<ListenableFuture<Void>> addState(DataBroker dataBroker, IdManagerService idManager, IMdsalApiManager mdsalApiManager,
+    public static List<ListenableFuture<Void>> addState(DataBroker dataBroker, IdManagerService idManager,
+                                                        IMdsalApiManager mdsalApiManager,AlivenessMonitorService alivenessMonitorService,
                                                         NodeConnectorId nodeConnectorId, String portName, FlowCapableNodeConnector fcNodeConnectorNew) {
         LOG.debug("Adding Interface State to Oper DS for port: {}", portName);
         List<ListenableFuture<Void>> futures = new ArrayList<>();
@@ -103,6 +106,7 @@ public class OvsInterfaceStateAddHelper {
             InterfaceManagerCommonUtils.makeTunnelIngressFlow(futures, mdsalApiManager, tunnel,dpId, portNo, iface,
                     NwConstants.ADD_FLOW);
             futures.add(transaction.submit());
+            AlivenessMonitorUtils.startLLDPMonitoring(alivenessMonitorService, dataBroker, iface);
             return futures;
         }
 
index 2aa85d2675e39037ea11347926485c4564510f6f..88af8f816baab55a01b1493aba82fb53dda93906 100644 (file)
@@ -12,6 +12,7 @@ import org.opendaylight.controller.md.sal.binding.api.DataBroker;
 import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
 import org.opendaylight.vpnservice.interfacemgr.IfmUtil;
+import org.opendaylight.vpnservice.interfacemgr.commons.AlivenessMonitorUtils;
 import org.opendaylight.vpnservice.interfacemgr.commons.InterfaceManagerCommonUtils;
 import org.opendaylight.vpnservice.interfacemgr.commons.InterfaceMetaUtils;
 import org.opendaylight.vpnservice.mdsalutil.MDSALUtil;
@@ -24,6 +25,7 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeCon
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnector;
 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.yang.gen.v1.urn.opendaylight.vpnservice.alivenessmonitor.rev150629.AlivenessMonitorService;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.idmanager.rev150403.IdManagerService;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007._interface.child.info.InterfaceParentEntry;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007._interface.child.info.InterfaceParentEntryKey;
@@ -41,6 +43,7 @@ public class OvsInterfaceStateRemoveHelper {
     private static final Logger LOG = LoggerFactory.getLogger(OvsInterfaceStateRemoveHelper.class);
 
     public static List<ListenableFuture<Void>> removeState(IdManagerService idManager, IMdsalApiManager mdsalApiManager,
+                                                           AlivenessMonitorService alivenessMonitorService,
                                                            InstanceIdentifier<FlowCapableNodeConnector> key,
                                                            DataBroker dataBroker, String portName, FlowCapableNodeConnector fcNodeConnectorOld) {
         LOG.debug("Removing interface-state for port: {}", portName);
@@ -66,7 +69,7 @@ public class OvsInterfaceStateRemoveHelper {
             return futures;
         }
 
-        // If this interface is a tunnel interface, remove the tunnel ingress flow
+        // If this interface is a tunnel interface, remove the tunnel ingress flow and stop lldp monitoring
         IfTunnel tunnel = iface.getAugmentation(IfTunnel.class);
         if(tunnel != null){
             NodeConnectorId nodeConnectorId = InstanceIdentifier.keyOf(key.firstIdentifierOf(NodeConnector.class)).getId();
@@ -74,6 +77,8 @@ public class OvsInterfaceStateRemoveHelper {
             long portNo = Long.valueOf(IfmUtil.getPortNoFromNodeConnectorId(nodeConnectorId));
             InterfaceManagerCommonUtils.makeTunnelIngressFlow(futures, mdsalApiManager, tunnel, dpId, portNo, iface,
                     NwConstants.DEL_FLOW);
+            futures.add(transaction.submit());
+            AlivenessMonitorUtils.stopLLDPMonitoring(alivenessMonitorService, dataBroker, iface);
             return futures;
         }
 
index 02a3a2ace4b75378a70845e77260d25515e67e9a..9b99aee56065aaa9aa7ad88c69bcb4cb59b0a172 100644 (file)
@@ -12,6 +12,7 @@ import org.opendaylight.controller.md.sal.binding.api.DataBroker;
 import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
 import org.opendaylight.vpnservice.interfacemgr.IfmUtil;
+import org.opendaylight.vpnservice.interfacemgr.commons.AlivenessMonitorUtils;
 import org.opendaylight.vpnservice.interfacemgr.commons.InterfaceManagerCommonUtils;
 import org.opendaylight.vpnservice.interfacemgr.commons.InterfaceMetaUtils;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.InterfaceKey;
@@ -20,6 +21,7 @@ import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev100924.MacAddress;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.PhysAddress;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNodeConnector;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.alivenessmonitor.rev150629.AlivenessMonitorService;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007._interface.child.info.InterfaceParentEntry;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007._interface.child.info.InterfaceParentEntryKey;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007._interface.child.info._interface.parent.entry.InterfaceChildEntry;
@@ -34,6 +36,7 @@ public class OvsInterfaceStateUpdateHelper {
     private static final Logger LOG = LoggerFactory.getLogger(OvsInterfaceStateUpdateHelper.class);
 
     public static List<ListenableFuture<Void>> updateState(InstanceIdentifier<FlowCapableNodeConnector> key,
+                                                           AlivenessMonitorService alivenessMonitorService,
                                                            DataBroker dataBroker, String portName,
                                                            FlowCapableNodeConnector flowCapableNodeConnectorNew,
                                                            FlowCapableNodeConnector flowCapableNodeConnectorOld) {
@@ -73,13 +76,12 @@ public class OvsInterfaceStateUpdateHelper {
 
         InstanceIdentifier<Interface> ifStateId = IfmUtil.buildStateInterfaceId(portName);
         InterfaceBuilder ifaceBuilder = new InterfaceBuilder();
-
+        org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface iface = null;
         boolean modified = false;
         if (opstateModified) {
             LOG.debug("Opstate Modified for Port: {}", portName);
             InterfaceKey interfaceKey = new InterfaceKey(portName);
-            org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface iface =
-                    InterfaceManagerCommonUtils.getInterfaceFromConfigDS(interfaceKey, dataBroker);
+             iface = InterfaceManagerCommonUtils.getInterfaceFromConfigDS(interfaceKey, dataBroker);
 
             // If interface config admin state is disabled, set operstate of the Interface State entity to Down.
             if (iface != null && !iface.isEnabled()) {
@@ -116,6 +118,11 @@ public class OvsInterfaceStateUpdateHelper {
                     InterfaceMetaUtils.getInterfaceParentEntryFromConfigDS(interfaceParentEntryKey, dataBroker);
             if (interfaceParentEntry == null) {
                 futures.add(t.submit());
+                // start/stop monitoring based on opState
+                if(operStatusNew == Interface.OperStatus.Down )
+                    AlivenessMonitorUtils.stopLLDPMonitoring(alivenessMonitorService, dataBroker, iface);
+                else
+                    AlivenessMonitorUtils.startLLDPMonitoring(alivenessMonitorService,dataBroker, iface);
                 return futures;
             }
 
index 14ab2e60ccd4fa79b4a7602c8508875dfaea6c79..2eae05ca3ef17e02fdabdd1d6427ef31c05003f8 100644 (file)
@@ -28,6 +28,7 @@ public class InterfacemgrImplModule extends org.opendaylight.yang.gen.v1.urn.ope
     public java.lang.AutoCloseable createInstance() {
         InterfacemgrProvider provider = new InterfacemgrProvider();
         provider.setRpcProviderRegistry(getRpcRegistryDependency());
+        provider.setNotificationService(getNotificationServiceDependency());
         provider.setMdsalManager(getMdsalutilDependency());
         getBrokerDependency().registerProvider(provider);
         return provider;
index 471880160cc72aa4cd3879537e89706857909c87..18227c5913c077885459eb6985ec3d3c5ab1e37b 100644 (file)
@@ -4,6 +4,7 @@ module interfacemgr-impl {
     prefix "interfacemgr-impl";
 
     import config { prefix config; revision-date 2013-04-05; }
+    import opendaylight-sal-binding-broker-impl { prefix md-sal-binding-impl; revision-date 2013-10-28;}
     import opendaylight-md-sal-binding { prefix md-sal-binding; revision-date 2013-10-28;}
     import odl-interface {prefix odlif; revision-date 2015-03-31;}
     import odl-mdsalutil { prefix odl-mdsal; revision-date 2015-04-10;}
@@ -49,6 +50,14 @@ module interfacemgr-impl {
                     }
                 }
             }
+            container notification-service {
+                 uses config:service-ref {
+                     refine type {
+                         mandatory true;
+                         config:required-identity md-sal-binding-impl:binding-new-notification-service;
+                     }
+                 }
+            }
         }
     }
 }
index 489031c4de4bdb0f515370b894a8766c72f9f6f6..4b626cf648f45fe356e7f2bc6494588839514947 100644 (file)
@@ -39,6 +39,7 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.Fl
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.port.rev130925.flow.capable.port.StateBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnector;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.alivenessmonitor.rev150629.AlivenessMonitorService;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.idmanager.rev150403.*;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007.IfIndexesInterfaceMap;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007._if.indexes._interface.map.IfIndexInterface;
@@ -85,6 +86,7 @@ public class StateInterfaceTest {
     @Mock ListenerRegistration<DataChangeListener> dataChangeListenerRegistration;
     @Mock ReadOnlyTransaction mockReadTx;
     @Mock WriteTransaction mockWriteTx;
+    @Mock AlivenessMonitorService alivenessMonitorService;
 
     OvsInterfaceStateAddHelper addHelper;
     OvsInterfaceStateRemoveHelper removeHelper;
@@ -147,7 +149,8 @@ public class StateInterfaceTest {
                 .setIdKey(InterfaceManagerTestUtil.interfaceName).build();
         doReturn(idOutputOptional).when(idManager).allocateId(getIdInput);
 
-        addHelper.addState(dataBroker, idManager, mdsalManager, nodeConnectorId, InterfaceManagerTestUtil.interfaceName, fcNodeConnectorNew);
+        addHelper.addState(dataBroker, idManager, mdsalManager, alivenessMonitorService,
+                nodeConnectorId, InterfaceManagerTestUtil.interfaceName, fcNodeConnectorNew);
 
         //Add some verifications
         verify(mockWriteTx).put(LogicalDatastoreType.OPERATIONAL, interfaceStateIdentifier,
@@ -171,7 +174,7 @@ public class StateInterfaceTest {
 
         doReturn(Futures.immediateFuture(RpcResultBuilder.<Void>success().build())).when(idManager).releaseId(getIdInput);
 
-        removeHelper.removeState(idManager, mdsalManager, fcNodeConnectorId, dataBroker, InterfaceManagerTestUtil.interfaceName, fcNodeConnectorNew);
+        removeHelper.removeState(idManager, mdsalManager, alivenessMonitorService, fcNodeConnectorId, dataBroker, InterfaceManagerTestUtil.interfaceName, fcNodeConnectorNew);
 
         verify(mockWriteTx).delete(LogicalDatastoreType.OPERATIONAL, interfaceStateIdentifier);
         verify(mockWriteTx).delete(LogicalDatastoreType.OPERATIONAL, ifIndexId);
@@ -205,7 +208,7 @@ public class StateInterfaceTest {
         fcNodeConnectorOldupdate.setState(b2.build());
         fcNodeConnectorNewupdate.setState(b3.build());
 
-        updateHelper.updateState(fcNodeConnectorId, dataBroker, InterfaceManagerTestUtil.interfaceName, fcNodeConnectorNewupdate.build(), fcNodeConnectorOldupdate.build());
+        updateHelper.updateState(fcNodeConnectorId, alivenessMonitorService, dataBroker, InterfaceManagerTestUtil.interfaceName, fcNodeConnectorNewupdate.build(), fcNodeConnectorOldupdate.build());
 
         verify(mockWriteTx).merge(LogicalDatastoreType.OPERATIONAL,interfaceStateIdentifier,stateInterface);
     }
index fc57cdd73e4cd1c6378da3069a8d63699c826418..966976ec9dcbcd1dd3f5eb0d85d699cd6fb8ef03 100644 (file)
@@ -34,6 +34,7 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.No
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.InterfaceTypeGre;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbBridgeAugmentation;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbBridgeRef;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.alivenessmonitor.rev150629.AlivenessMonitorService;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.idmanager.rev150403.IdManagerService;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007.bridge._interface.info.BridgeEntry;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007.bridge._interface.info.BridgeEntryKey;
@@ -85,6 +86,7 @@ public class TunnelInterfaceConfigurationTest {
 
     @Mock DataBroker dataBroker;
     @Mock IdManagerService idManager;
+    @Mock AlivenessMonitorService alivenessMonitorService;
     @Mock ListenerRegistration<DataChangeListener> dataChangeListenerRegistration;
     @Mock ReadOnlyTransaction mockReadTx;
     @Mock WriteTransaction mockWriteTx;
@@ -198,7 +200,7 @@ public class TunnelInterfaceConfigurationTest {
         ifaceBuilder.setKey(IfmUtil.getStateInterfaceKeyFromName(tunnelInterfaceEnabled.getName()));
         stateInterface = ifaceBuilder.build();
 
-        removeHelper.removeConfiguration(dataBroker, tunnelInterfaceEnabled, idManager, parentRefs);
+        removeHelper.removeConfiguration(dataBroker, alivenessMonitorService, tunnelInterfaceEnabled, idManager, parentRefs);
 
         //Add some verifications
         verify(mockWriteTx).delete(LogicalDatastoreType.CONFIGURATION, bridgeEntryIid);
@@ -213,7 +215,7 @@ public class TunnelInterfaceConfigurationTest {
         doReturn(Futures.immediateCheckedFuture(expectedStateInterface)).when(mockReadTx).read(
                 LogicalDatastoreType.OPERATIONAL, interfaceStateIdentifier);
 
-        updateHelper.updateConfiguration(dataBroker,idManager,tunnelInterfaceDisabled,tunnelInterfaceEnabled);
+        updateHelper.updateConfiguration(dataBroker, alivenessMonitorService, idManager,tunnelInterfaceDisabled,tunnelInterfaceEnabled);
 
         //verify whether operational data store is updated with the new oper state.
         InterfaceBuilder ifaceBuilder = new InterfaceBuilder();
@@ -234,7 +236,7 @@ public class TunnelInterfaceConfigurationTest {
         doReturn(Futures.immediateCheckedFuture(expectedStateInterface)).when(mockReadTx).read(
                 LogicalDatastoreType.OPERATIONAL, interfaceStateIdentifier);
 
-        updateHelper.updateConfiguration(dataBroker,idManager,tunnelInterfaceEnabled,tunnelInterfaceDisabled);
+        updateHelper.updateConfiguration(dataBroker, alivenessMonitorService, idManager,tunnelInterfaceEnabled,tunnelInterfaceDisabled);
 
         //verify whether operational data store is updated with the new oper state.
         InterfaceBuilder ifaceBuilder = new InterfaceBuilder();
index 4b7adb0f5bd69e251119bba4abef7042d65d2b8d..29c7c35f703b207f52cf1d14c2ec22a6993251b8 100644 (file)
@@ -38,6 +38,7 @@ import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface.OperStatus;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnector;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.alivenessmonitor.rev150629.AlivenessMonitorService;
 import org.opendaylight.yangtools.concepts.ListenerRegistration;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 
@@ -46,6 +47,8 @@ public class VlanInterfaceConfigurationTest {
 
     @Mock
     DataBroker dataBroker;
+    @Mock
+    AlivenessMonitorService alivenessMonitorService;
     @Mock IdManager idManager;
     @Mock ListenerRegistration<DataChangeListener> dataChangeListenerRegistration;
     @Mock ReadOnlyTransaction mockReadTx;
@@ -164,7 +167,7 @@ public class VlanInterfaceConfigurationTest {
         ifaceBuilder.setKey(IfmUtil.getStateInterfaceKeyFromName(vlanInterfaceEnabled.getName()));
         stateInterface = ifaceBuilder.build();
 
-        removeHelper.removeConfiguration(dataBroker, vlanInterfaceEnabled, idManager, null);
+        removeHelper.removeConfiguration(dataBroker,alivenessMonitorService, vlanInterfaceEnabled, idManager, null);
 
         //verification
         verify(mockWriteTx).merge(LogicalDatastoreType.OPERATIONAL, interfaceStateIdentifier, stateInterface);
index 19ec9da2a72db07bb29cc839f047bb49fbc0bda1..07e0e00dcb9cb4b0b18b5ae7b4fe69e3beb17ea6 100755 (executable)
@@ -29,14 +29,11 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.acti
 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.push.mpls.action._case.PushMplsActionBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.push.pbb.action._case.PushPbbActionBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.push.vlan.action._case.PushVlanActionBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.set.field._case.SetField;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.set.field._case.SetFieldBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.Action;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.ActionBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.ActionKey;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.OutputPortValues;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.ApplyActionsCaseBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.apply.actions._case.ApplyActions;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.l2.types.rev130827.VlanId;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.ethernet.match.fields.EthernetDestinationBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.EthernetMatchBuilder;
@@ -47,36 +44,16 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026
 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.vlan.match.fields.VlanIdBuilder;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Prefix;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.PortNumber;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Uri;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev100924.MacAddress;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.ethernet.match.fields.EthernetDestinationBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.ethernet.match.fields.EthernetSourceBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.ethernet.match.fields.EthernetTypeBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.EthernetMatchBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.IpMatchBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.VlanMatchBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._3.match.Ipv4Match;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._3.match.Ipv4MatchBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._4.match.UdpMatchBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.vlan.match.fields.VlanIdBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.DropActionCaseBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.drop.action._case.DropAction;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.drop.action._case.DropActionBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev150203.action.grouping.action.choice.set.field._case.SetFieldActionBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.action.rev140421.OfjNxActionOutputRegGrouping;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.action.rev140421.action.container.action.choice.ActionOutputRegBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.NxmNxReg1;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.add.group.input.buckets.bucket.action.action.NxActionOutputRegRpcAddGroupCase;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.add.group.input.buckets.bucket.action.action.NxActionOutputRegRpcAddGroupCaseBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.add.group.input.buckets.bucket.action.action.NxActionResubmitRpcAddGroupCaseBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nodes.node.group.buckets.bucket.action.action.NxActionOutputRegNodesNodeGroupBucketsBucketActionsCase;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nodes.node.group.buckets.bucket.action.action.NxActionOutputRegNodesNodeGroupBucketsBucketActionsCaseBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nodes.node.group.buckets.bucket.action.action.NxActionRegLoadNodesNodeGroupBucketsBucketActionsCaseBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nodes.node.table.flow.instructions.instruction.instruction.apply.actions._case.apply.actions.action.action.NxActionOutputRegNodesNodeTableFlowApplyActionsCaseBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nx.action.output.reg.grouping.NxOutputReg;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nx.action.output.reg.grouping.NxOutputRegBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nx.action.resubmit.grouping.NxResubmitBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.src.choice.grouping.src.choice.SrcNxRegCaseBuilder;
+
 public enum ActionType {
     group {
         @Override
@@ -391,26 +368,6 @@ public enum ActionType {
             return ab.build();
         }
     },
-    set_field_reg {
-
-        @Override
-        public Action buildAction(ActionInfo actionInfo) {
-            ActionBuilder ab = new ActionBuilder();
-            String[] actionValues = actionInfo.getActionValues();
-            NxOutputReg r = new NxOutputRegBuilder().setSrc(
-                    new org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nx.action.output.reg.grouping.nx.output.reg.SrcBuilder().setSrcChoice(
-                            new SrcNxRegCaseBuilder().setNxReg(NxmNxReg1.class).build())
-                            .setOfsNbits(Integer.valueOf(Integer.parseInt(actionValues[0])))
-                            .build())
-                    .setMaxLen(Integer.valueOf(0xffff))
-                    .build();
-            ab.setAction(new NxActionOutputRegNodesNodeGroupBucketsBucketActionsCaseBuilder().setNxOutputReg(r).build());
-            ab.setKey(new ActionKey(actionInfo.getActionKey()));
-            return ab.build();
-        }
-    },
-
-
 
     nx_resubmit {
 
index e514e3eb1e2796cabf0d8319cafb29949f37eac7..7e4cfa290a0f8ebce907ede79a2480d75ef22f2f 100755 (executable)
@@ -8,8 +8,6 @@
 package org.opendaylight.vpnservice.mdsalutil;
 
 import java.math.BigInteger;
-import java.util.ArrayList;
-import java.util.List;
 import java.util.Map;
 
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Prefix;
@@ -33,16 +31,6 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026
 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._4.match.UdpMatchBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.protocol.match.fields.PbbBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.vlan.match.fields.VlanIdBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.NxmNxReg1;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.general.rev140714.GeneralAugMatchNodesNodeTableFlow;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.general.rev140714.GeneralAugMatchNodesNodeTableFlowBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.general.rev140714.general.extension.grouping.ExtensionBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.general.rev140714.general.extension.list.grouping.ExtensionList;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.general.rev140714.general.extension.list.grouping.ExtensionListBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.match.rev140714.NxAugMatchNodesNodeTableFlow;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.match.rev140714.NxAugMatchNodesNodeTableFlowBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.match.rev140714.NxmNxReg1Key;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.match.rev140714.nxm.nx.reg.grouping.NxmNxRegBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.table.types.rev131026.ArpOp;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.table.types.rev131026.ArpSpa;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.table.types.rev131026.ArpTpa;
@@ -57,14 +45,11 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.table.types.rev131026.Match
 import org.opendaylight.yang.gen.v1.urn.opendaylight.table.types.rev131026.Metadata;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.table.types.rev131026.MplsLabel;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.table.types.rev131026.PbbIsid;
-//import org.opendaylight.yang.gen.v1.urn.opendaylight.table.types.rev131026.SalOpenflowBasicClass;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.table.types.rev131026.TcpDst;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.table.types.rev131026.TcpSrc;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.table.types.rev131026.UdpDst;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.table.types.rev131026.UdpSrc;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.table.types.rev131026.VlanVid;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.table.types.rev131026.set.field.match.SetFieldMatch;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.table.types.rev131026.set.field.match.SetFieldMatchBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.TunnelBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.table.types.rev131026.TunnelId;
 
@@ -588,39 +573,6 @@ public enum MatchFieldType {
 
     },
 
-    reg1 {
-        @Override
-        protected Class<? extends MatchField> getMatchType() {
-            return MatchField.class;
-        }
-
-        @Override
-        public void createInnerMatchBuilder(MatchInfo matchInfo, Map<Class<?>, Object> mapMatchBuilder) {
-            NxmNxRegBuilder regdataBuilder = (NxmNxRegBuilder) mapMatchBuilder.get(NxmNxRegBuilder.class);
-             if (regdataBuilder == null) {
-                regdataBuilder = new NxmNxRegBuilder();
-                mapMatchBuilder.put(NxmNxRegBuilder.class, regdataBuilder);
-            }
-            long[] metadataValues = matchInfo.getMatchValues();
-            regdataBuilder.setValue(metadataValues[0]).build();
-            ArrayList<ExtensionList> extensions = new ArrayList<>();
-            NxAugMatchNodesNodeTableFlow am =  new NxAugMatchNodesNodeTableFlowBuilder().setNxmNxReg(new NxmNxRegBuilder().setReg(NxmNxReg1.class).setValue(metadataValues[0]).build()).build();
-            extensions.add(new ExtensionListBuilder().setExtensionKey(NxmNxReg1Key.class).setExtension(new ExtensionBuilder().addAugmentation(NxAugMatchNodesNodeTableFlow.class, am).build()).build());
-            GeneralAugMatchNodesNodeTableFlow m = new GeneralAugMatchNodesNodeTableFlowBuilder().setExtensionList(extensions).build();
-        }
-
-        @Override
-        public void setMatch(MatchBuilder matchBuilderInOut, MatchInfo matchInfo, Map<Class<?>, Object> mapMatchBuilder) {
-            List<ExtensionList> extensions = new ArrayList<>();
-            long[] matchvalues = matchInfo.getMatchValues();
-            NxAugMatchNodesNodeTableFlow am = new NxAugMatchNodesNodeTableFlowBuilder().setNxmNxReg(new NxmNxRegBuilder().setReg(NxmNxReg1.class).setValue(matchvalues[0]).build()).build();
-            extensions.add(new ExtensionListBuilder().setExtensionKey(NxmNxReg1Key.class).setExtension(new ExtensionBuilder().addAugmentation(NxAugMatchNodesNodeTableFlow.class, am).build()).build());
-            GeneralAugMatchNodesNodeTableFlow m = new GeneralAugMatchNodesNodeTableFlowBuilder().setExtensionList(extensions).build();
-            matchBuilderInOut.addAugmentation(GeneralAugMatchNodesNodeTableFlow.class, m);
-
-        }
-    },
-
     vlan_vid {
         @Override
         protected Class<? extends MatchField> getMatchType() {
index 3535c435e9c0297c2fde7e5fe7006efecfc88739..250a247175274b6ae31a6d788f4a3f65fa4f11ec 100644 (file)
@@ -11,12 +11,10 @@ import java.math.BigInteger;
 import java.util.List;
 
 import com.google.common.util.concurrent.CheckedFuture;
-import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
 import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
 import org.opendaylight.vpnservice.mdsalutil.ActionInfo;
 import org.opendaylight.vpnservice.mdsalutil.FlowEntity;
 import org.opendaylight.vpnservice.mdsalutil.GroupEntity;
-import org.opendaylight.vpnservice.mdsalutil.*;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.Flow;
 
 public interface IMdsalApiManager {
@@ -53,6 +51,7 @@ public interface IMdsalApiManager {
      * @param delayTime
      */
     public void syncRemoveFlow(FlowEntity flowEntity, long delayTime);
+    public void syncInstallFlow(FlowEntity flowEntity, long delayTime);
 
     /**
      * API to install the Group on Data Plane Node synchronously. It internally waits for
index c617cfcda7feb7b1fc7318e11261e9acfe34be63..cacb6344bd1ca8bcff135f8f20a9d3e9addb3d11 100644 (file)
@@ -130,6 +130,11 @@ public class MDSALUtilProvider implements BindingAwareConsumer, IMdsalApiManager
         mdSalMgr.syncSetUpFlow(flowEntity,  delayTime, true);
     }
 
+    @Override
+    public void syncInstallFlow(FlowEntity flowEntity, long delayTime) {
+        mdSalMgr.syncSetUpFlow(flowEntity, delayTime, false);
+    }
+
     @Override
     public void syncInstallGroup(GroupEntity groupEntity, long delayTime) {
         mdSalMgr.syncSetUpGroup(groupEntity, delayTime, false);
index cced35d54575ba854650c04c87dc2bba51809a1a..dcae6c67445083d05c7c84248ef12f2df376665a 100644 (file)
@@ -5,6 +5,7 @@ module bgp {
 
   import ietf-inet-types {
     prefix inet;
+    revision-date "2010-09-24";
   }
   import ietf-yang-types {
     prefix yang;
index 4611809073dfd5de7220b6addc8059df3c39fb8b..54020fc988b69f7d8109f36374210e6cf6e0a581 100644 (file)
@@ -8,7 +8,7 @@ module ebgp {
   prefix "ericsson-bgp";
 
   // import some basic inet types
-  import ietf-inet-types { prefix inet; }
+  import ietf-inet-types { prefix inet; revision-date "2010-09-24"; }
 
   // meta
   organization
@@ -83,7 +83,6 @@ module ebgp {
     container ebgp-multihop {
       leaf nhops {
         type uint32;
-        mandatory "true";
       }
       leaf peer-ip {
         type leafref {
index 826f9f839b52a35c0082c336f631031fe79ff456..4cd576e2ac9355f95cde2d4153c3f2b962bd646b 100644 (file)
@@ -18,7 +18,6 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.l3.rev150712.router
 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.l3.rev150712.routers.attributes.routers.Router;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.l3.rev150712.routers.attributes.routers.router.Interfaces;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.rev150712.Neutron;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.neutronvpn.rev150602.vpnmaps.VpnMap;
 import org.opendaylight.yangtools.concepts.ListenerRegistration;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 import org.slf4j.Logger;
@@ -83,21 +82,16 @@ public class NeutronRouterChangeListener extends AbstractDataChangeListener<Rout
         if (LOG.isTraceEnabled()) {
             LOG.trace("Removing router : key: " + identifier + ", value=" + input);
         }
-        // check if this router has internal-VPN
         Uuid routerId = input.getUuid();
-        VpnMap vpnmap = NeutronvpnUtils.getVpnMap(broker, routerId);
-        if (vpnmap != null) {
-            // if yes, remove corresponding internal vpn
-            LOG.trace("removing internal-vpn for router {}", routerId);
-            nvpnManager.removeL3Vpn(routerId);
-        } else {
-            // if not, it is associated with some VPN
-            // remove VPN-router association
-            Uuid vpnId = NeutronvpnUtils.getVpnForRouter(broker, routerId);
-            LOG.trace("dissociating router {} from vpn {}", routerId, vpnId);
-            nvpnManager.dissociateRouterFromVpn(vpnId, routerId);
+        // fetch subnets associated to router
+        List<Interfaces> routerInterfaces = input.getInterfaces();
+        List<Uuid> routerSubnetIds = new ArrayList<Uuid>();
+        if (routerInterfaces != null) {
+            for (Interfaces rtrIf : routerInterfaces) {
+                routerSubnetIds.add(rtrIf.getSubnetId());
+            }
         }
-
+        nvpnManager.handleNeutronRouterDeleted(routerId, routerSubnetIds);
     }
 
     @Override
@@ -107,7 +101,11 @@ public class NeutronRouterChangeListener extends AbstractDataChangeListener<Rout
                     update);
         }
         Uuid routerId = update.getUuid();
-        Uuid vpnId = NeutronvpnUtils.getVpnForRouter(broker, routerId);
+        Uuid vpnId = NeutronvpnUtils.getVpnForRouter(broker, routerId, true);
+        // internal vpn always present in case external vpn not found
+        if (vpnId == null) {
+            vpnId = routerId;
+        }
         List<Interfaces> oldInterfaces = (original.getInterfaces() != null) ? original.getInterfaces() : new
                 ArrayList<Interfaces>();
         List<Interfaces> newInterfaces = (update.getInterfaces() != null) ? update.getInterfaces() : new
index a94101d0fb0328d15fb59cb7794d6eb09319c486..e7399566f514e9b6b0ce04880bf7854c76f548d3 100644 (file)
@@ -369,10 +369,9 @@ public class NeutronvpnManager implements NeutronvpnService, AutoCloseable {
             return;
         }
         String portname = NeutronvpnUtils.uuidToTapPortName(port.getUuid());
-        String name = new StringBuilder(portname).append(":0").toString();
         List<Adjacency> adjList = new ArrayList<Adjacency>();
         InstanceIdentifier<VpnInterface> vpnIfIdentifier = InstanceIdentifier.builder(VpnInterfaces.class).
-                child(VpnInterface.class, new VpnInterfaceKey(name)).build();
+                child(VpnInterface.class, new VpnInterfaceKey(portname)).build();
         // find router associated to vpn
         Uuid routerId = NeutronvpnUtils.getRouterforVpn(broker, vpnId);
         Router rtr = null;
@@ -392,7 +391,7 @@ public class NeutronvpnManager implements NeutronvpnService, AutoCloseable {
             // create extra route adjacency
             if (rtr != null && rtr.getRoutes() != null) {
                 List<String> routeList = rtr.getRoutes();
-                List<Adjacency> erAdjList = addAdjacencyforExtraRoute(routeList, false, name);
+                List<Adjacency> erAdjList = addAdjacencyforExtraRoute(routeList, false, portname);
                 if (erAdjList != null) {
                     adjList.addAll(erAdjList);
                 }
@@ -400,18 +399,18 @@ public class NeutronvpnManager implements NeutronvpnService, AutoCloseable {
         }
         // create vpn-interface on this neutron port
         Adjacencies adjs = new AdjacenciesBuilder().setAdjacency(adjList).build();
-        VpnInterfaceBuilder vpnb = new VpnInterfaceBuilder().setKey(new VpnInterfaceKey(name)).
-                setName(name).setVpnInstanceName(vpnId.getValue()).addAugmentation(Adjacencies.class, adjs);
+        VpnInterfaceBuilder vpnb = new VpnInterfaceBuilder().setKey(new VpnInterfaceKey(portname)).
+                setName(portname).setVpnInstanceName(vpnId.getValue()).addAugmentation(Adjacencies.class, adjs);
         VpnInterface vpnIf = vpnb.build();
 
-        NeutronvpnUtils.lockVpnInterface(lockManager, name);
+        NeutronvpnUtils.lockVpnInterface(lockManager, portname);
         try {
             logger.debug("Creating vpn interface {}", vpnIf);
             MDSALUtil.syncWrite(broker, LogicalDatastoreType.CONFIGURATION, vpnIfIdentifier, vpnIf);
         } catch (Exception ex) {
-            logger.error("Creation of vpninterface {} failed due to {}", name, ex);
+            logger.error("Creation of vpninterface {} failed due to {}", portname, ex);
         } finally {
-            NeutronvpnUtils.unlockVpnInterface(lockManager, name);
+            NeutronvpnUtils.unlockVpnInterface(lockManager, portname);
         }
     }
 
@@ -419,18 +418,17 @@ public class NeutronvpnManager implements NeutronvpnService, AutoCloseable {
 
         if (port != null) {
             String pname = NeutronvpnUtils.uuidToTapPortName(port.getUuid());
-            String name = new StringBuilder(pname).append(":0").toString();
             InstanceIdentifier<VpnInterface> vpnIfIdentifier = InstanceIdentifier.builder(VpnInterfaces.class).
-                    child(VpnInterface.class, new VpnInterfaceKey(name)).build();
+                    child(VpnInterface.class, new VpnInterfaceKey(pname)).build();
 
-            NeutronvpnUtils.lockVpnInterface(lockManager, name);
+            NeutronvpnUtils.lockVpnInterface(lockManager, pname);
             try {
-                logger.debug("Deleting vpn interface {}", name);
+                logger.debug("Deleting vpn interface {}", pname);
                 MDSALUtil.syncDelete(broker, LogicalDatastoreType.CONFIGURATION, vpnIfIdentifier);
             } catch (Exception ex) {
-                logger.error("Deletion of vpninterface {} failed due to {}", name, ex);
+                logger.error("Deletion of vpninterface {} failed due to {}", pname, ex);
             } finally {
-                NeutronvpnUtils.unlockVpnInterface(lockManager, name);
+                NeutronvpnUtils.unlockVpnInterface(lockManager, pname);
             }
         }
     }
@@ -689,30 +687,29 @@ public class NeutronvpnManager implements NeutronvpnService, AutoCloseable {
                     String destination = parts[1];
 
                     String tapPortName = NeutronvpnUtils.getNeutronPortNamefromPortFixedIp(broker, nextHop);
-                    String ifname = new StringBuilder(tapPortName).append(":0").toString();
                     logger.trace("Adding extra route with nexthop {}, destination {}, ifName {}", nextHop,
-                            destination, ifname);
+                            destination, tapPortName);
                     Adjacency erAdj = new AdjacencyBuilder().setIpAddress(destination).setNextHopIp(nextHop).setKey
                             (new AdjacencyKey(destination)).build();
                     if (rtrUp == false) {
-                        if (ifname.equals(vpnifname)) {
+                        if (tapPortName.equals(vpnifname)) {
                             adjList.add(erAdj);
                         }
                         continue;
                     }
                     InstanceIdentifier<VpnInterface> vpnIfIdentifier = InstanceIdentifier.builder(VpnInterfaces.class).
-                            child(VpnInterface.class, new VpnInterfaceKey(ifname)).build();
+                            child(VpnInterface.class, new VpnInterfaceKey(tapPortName)).build();
                     Optional<VpnInterface> optionalVpnInterface = NeutronvpnUtils.read(broker, LogicalDatastoreType
                             .CONFIGURATION, vpnIfIdentifier);
                     if (optionalVpnInterface.isPresent()) {
                         Adjacencies erAdjs = new AdjacenciesBuilder().setAdjacency(Arrays.asList(erAdj)).build();
-                        VpnInterface vpnIf = new VpnInterfaceBuilder().setKey(new VpnInterfaceKey(ifname))
+                        VpnInterface vpnIf = new VpnInterfaceBuilder().setKey(new VpnInterfaceKey(tapPortName))
                                 .addAugmentation(Adjacencies.class, erAdjs).build();
                         MDSALUtil.syncUpdate(broker, LogicalDatastoreType.CONFIGURATION, vpnIfIdentifier, vpnIf);
                         logger.trace("extra route {} added successfully", route);
                     } else {
                         logger.error("VM adjacency for interface {} not present ; cannot add extra route adjacency",
-                                ifname);
+                                tapPortName);
                     }
                 } else {
                     logger.error("Incorrect input received for extra route. {}", parts);
@@ -735,11 +732,10 @@ public class NeutronvpnManager implements NeutronvpnService, AutoCloseable {
                     String destination = parts[1];
 
                     String tapPortName = NeutronvpnUtils.getNeutronPortNamefromPortFixedIp(broker, nextHop);
-                    String ifname = new StringBuilder(tapPortName).append(":0").toString();
                     logger.trace("Removing extra route with nexthop {}, destination {}, ifName {}", nextHop,
-                            destination, ifname);
+                            destination, tapPortName);
                     InstanceIdentifier<Adjacency> adjacencyIdentifier = InstanceIdentifier.builder(VpnInterfaces.class).
-                            child(VpnInterface.class, new VpnInterfaceKey(ifname)).augmentation(Adjacencies.class)
+                            child(VpnInterface.class, new VpnInterfaceKey(tapPortName)).augmentation(Adjacencies.class)
                             .child(Adjacency.class, new AdjacencyKey(destination)).build();
                     MDSALUtil.syncDelete(broker, LogicalDatastoreType.CONFIGURATION, adjacencyIdentifier);
                     logger.trace("extra route {} deleted successfully", route);
@@ -758,7 +754,7 @@ public class NeutronvpnManager implements NeutronvpnService, AutoCloseable {
     }
 
     protected void removeL3Vpn(Uuid id) {
-        // read VPN networks
+        // read VPNMaps
         VpnMap vpnMap = NeutronvpnUtils.getVpnMap(broker, id);
         Uuid router = vpnMap.getRouterId();
         // dissociate router
@@ -800,39 +796,40 @@ public class NeutronvpnManager implements NeutronvpnService, AutoCloseable {
         }
     }
 
-    protected void associateRouterToVpn(Uuid vpn, Uuid router) {
+    protected void associateRouterToVpn(Uuid vpnId, Uuid routerId) {
 
-        // remove existing Router-VPN
-        if (!vpn.equals(router)) {
-            removeL3Vpn(router);
-        }
-        updateVpnMaps(vpn, null, router, null, null);
+        List<Uuid> routerSubnets = NeutronvpnUtils.getNeutronRouterSubnetIds(broker, routerId);
 
-        List<Uuid> routerSubnets = NeutronvpnUtils.getNeutronRouterSubnetIds(broker, router);
-        logger.debug("Adding subnets...");
+        if (!vpnId.equals(routerId)) {
+            logger.debug("Removing subnets from internal vpn {}", routerId.getValue());
+            if (routerSubnets != null) {
+                for (Uuid subnet : routerSubnets) {
+                    removeSubnetFromVpn(routerId, subnet);
+                }
+            }
+        }
+        logger.debug("Adding subnets to vpn {}", vpnId.getValue());
         for (Uuid subnet : routerSubnets) {
-            addSubnetToVpn(vpn, subnet);
+            addSubnetToVpn(vpnId, subnet);
         }
+
+        updateVpnMaps(vpnId, null, routerId, null, null);
     }
 
-    protected void dissociateRouterFromVpn(Uuid vpn, Uuid router) {
-        clearFromVpnMaps(vpn, router, null);
+    protected void dissociateRouterFromVpn(Uuid vpnId, Uuid routerId) {
 
-        // fetching sn from SubnetmapDS for internal VPN because sn already deleted from RouterIf DS on router deletion
-        List<Uuid> routerSubnets = (vpn.equals(router)) ? getSubnetsforVpn(vpn) :
-                NeutronvpnUtils.getNeutronRouterSubnetIds(broker, router);
+        // remove existing external vpn interfaces
+        List<Uuid> routerSubnets = NeutronvpnUtils.getNeutronRouterSubnetIds(broker, routerId);
 
-        logger.debug("dissociateRouter vpn {} router {} Removing subnets...", vpn.getValue(), router.getValue());
         if (routerSubnets != null) {
             for (Uuid subnet : routerSubnets) {
-                removeSubnetFromVpn(vpn, subnet);
+                logger.debug("Removing subnets from external vpn {}", vpnId.getValue());
+                removeSubnetFromVpn(vpnId, subnet);
+                logger.debug("Adding subnets to internal vpn {}", routerId.getValue());
+                addSubnetToVpn(routerId, subnet);
             }
         }
-        // create Router-VPN for this router
-        if (!vpn.equals(router)) {
-            logger.debug("Re-creating vpn-router...");
-            createL3Vpn(router, null, null, null, null, null, router, null);
-        }
+        clearFromVpnMaps(vpnId, routerId, null);
     }
 
     protected List<String> associateNetworksToVpn(Uuid vpn, List<Uuid> networks) {
@@ -1056,6 +1053,28 @@ public class NeutronvpnManager implements NeutronvpnService, AutoCloseable {
         return result;
     }
 
+    protected void handleNeutronRouterDeleted(Uuid routerId, List<Uuid> routerSubnetIds) {
+        // check if the router is associated to some VPN
+        Uuid vpnId = NeutronvpnUtils.getVpnForRouter(broker, routerId, true);
+        if (vpnId != null) {
+            // remove existing external vpn interfaces
+            for (Uuid subnetId : routerSubnetIds) {
+                removeSubnetFromVpn(vpnId, subnetId);
+            }
+            clearFromVpnMaps(vpnId, routerId, null);
+        } else {
+            // remove existing internal vpn interfaces
+            for (Uuid subnetId : routerSubnetIds) {
+                removeSubnetFromVpn(routerId, subnetId);
+            }
+        }
+        // delete entire vpnMaps node for internal VPN
+        deleteVpnMapsNode(routerId);
+
+        // delete vpn-instance for internal VPN
+        deleteVpnInstance(routerId);
+    }
+
     protected Subnet getNeutronSubnet(Uuid subnetId) {
         InstanceIdentifier<Subnet> inst = InstanceIdentifier.create(Neutron.class).
                 child(Subnets.class).child(Subnet.class, new SubnetKey(subnetId));
index 042b0ea19f28dd22f0e400f892d715692b59c79b..a74a34b62a65303df327f79c57c79bd82a3b2635 100644 (file)
@@ -25,6 +25,9 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.networks.rev150712.
 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.networks.rev150712.networks.attributes.networks.NetworkKey;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.ports.attributes.ports.Port;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.rev150712.Neutron;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.subnets.rev150712.subnets.attributes.Subnets;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.subnets.rev150712.subnets.attributes.subnets.Subnet;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.subnets.rev150712.subnets.attributes.subnets.SubnetKey;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.lockmanager.rev150819.LockManagerService;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.lockmanager.rev150819.TimeUnits;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.lockmanager.rev150819.TryLockInput;
@@ -104,16 +107,26 @@ public class NeutronvpnUtils {
         return null;
     }
 
-    protected static Uuid getVpnForRouter(DataBroker broker, Uuid router) {
+    // true for external vpn, false for internal vpn
+    protected static Uuid getVpnForRouter(DataBroker broker, Uuid routerId, Boolean externalVpn) {
         InstanceIdentifier<VpnMaps> vpnMapsIdentifier = InstanceIdentifier.builder(VpnMaps.class).build();
-        Optional<VpnMaps> optionalVpnMaps = read(broker, LogicalDatastoreType.CONFIGURATION, vpnMapsIdentifier);
+        Optional<VpnMaps> optionalVpnMaps = read(broker, LogicalDatastoreType.CONFIGURATION,
+                vpnMapsIdentifier);
         if (optionalVpnMaps.isPresent()) {
             VpnMaps vpnNets = optionalVpnMaps.get();
             List<VpnMap> allMaps = vpnNets.getVpnMap();
-            if (router != null) {
+            if (routerId != null) {
                 for (VpnMap vpnMap : allMaps) {
-                    if (router.equals(vpnMap.getRouterId())) {
-                        return vpnMap.getVpnId();
+                    if (routerId.equals(vpnMap.getRouterId())) {
+                        if (externalVpn == true) {
+                            if (!routerId.equals(vpnMap.getVpnId())) {
+                                return vpnMap.getVpnId();
+                            }
+                        } else {
+                            if (routerId.equals(vpnMap.getVpnId())) {
+                                return vpnMap.getVpnId();
+                            }
+                        }
                     }
                 }
             }
@@ -201,20 +214,20 @@ public class NeutronvpnUtils {
     protected static List<Uuid> getNeutronRouterSubnetIds(DataBroker broker, Uuid routerId) {
         logger.info("getNeutronRouterSubnetIds for {}", routerId.getValue());
 
-        List<Uuid> subnetNames = new ArrayList<Uuid>();
+        List<Uuid> subnetIdList = new ArrayList<Uuid>();
         Router router = getNeutronRouter(broker, routerId);
         if (router != null) {
             List<org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.l3.rev150712.routers.attributes.routers.router
-                    .Interfaces> ifs = router.getInterfaces();
-            if (!ifs.isEmpty()) {
+                    .Interfaces> interfacesList = router.getInterfaces();
+            if (!interfacesList.isEmpty()) {
                 for (org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.l3.rev150712.routers.attributes.routers
-                        .router.Interfaces iff : ifs) {
-                    subnetNames.add(iff.getSubnetId());
+                        .router.Interfaces interfaces : interfacesList) {
+                    subnetIdList.add(interfaces.getSubnetId());
                 }
             }
         }
         logger.info("returning from getNeutronRouterSubnetIds for {}", routerId.getValue());
-        return subnetNames;
+        return subnetIdList;
     }
 
     protected static String uuidToTapPortName(Uuid id) {
@@ -261,17 +274,10 @@ public class NeutronvpnUtils {
         try {
             Uuid subnetUUID = port.getFixedIps().get(0).getSubnetId();
 
-            org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.subnets.rev150712.subnets.attributes.subnets
-                    .SubnetKey subnetkey = new org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.subnets
-                    .rev150712.subnets.attributes.subnets.SubnetKey(subnetUUID);
-            InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.subnets.rev150712.subnets
-                    .attributes.subnets.Subnet> subnetidentifier = InstanceIdentifier.create(Neutron.class).child(org
-                    .opendaylight.yang.gen.v1.urn.opendaylight.neutron.subnets.rev150712.subnets.attributes.Subnets
-                    .class).child(org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.subnets.rev150712.subnets
-                    .attributes.subnets.Subnet.class, subnetkey);
-            Optional<org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.subnets.rev150712.subnets.attributes
-                    .subnets.Subnet> subnet = read(broker, LogicalDatastoreType.CONFIGURATION, subnetidentifier);
-
+            SubnetKey subnetkey = new SubnetKey(subnetUUID);
+            InstanceIdentifier<Subnet> subnetidentifier = InstanceIdentifier.create(Neutron.class).child(Subnets
+                    .class).child(Subnet.class, subnetkey);
+            Optional<Subnet> subnet = read(broker, LogicalDatastoreType.CONFIGURATION,subnetidentifier);
             if (subnet.isPresent()) {
                 cidr = subnet.get().getCidr();
                 // Extract the prefix length from cidr
index f097eaeea7e23290b2f7aa2afaf467893a438e8c..4beb21ec9eb1b94d90bf637942dfae750f50c8d0 100644 (file)
@@ -49,6 +49,27 @@ module odl-l3vpn {
         }
     }
 
+    container vpn-to-extraroute {
+        config false;
+        list vpn {
+           key vrf-id;
+           leaf vrf-id {
+              description
+                 "The vrf-id command configures a route distinguisher (RD)
+                  for the IPv4 or IPv6 address family of a VPN instance or
+                  vpn instance name for internal vpn case.";
+              type string;
+           }
+           list extraroute {
+              key prefix;
+              leaf prefix {type string;}
+                     leaf nexthop-ip {
+                         type string;
+                     }
+           }
+        }
+    }
+
     /* Data models to adhere to restart requirements */
     container vpn-instance-to-vpn-id {
        list vpn-instance {
@@ -82,6 +103,7 @@ module odl-l3vpn {
               type string;
            }
 
+           leaf vpn-interface-count { type uint32; }
            uses vpn-route-list;
            list vpn-to-dpn-list {
                key dpnId;
index 599f70380f12b18ab36c76ea206378bed0b5ed61..206f884a3c6dcfb56bbd25669cd6e9c9bb33d7f2 100644 (file)
@@ -76,14 +76,14 @@ public class InterfaceStateChangeListener extends AbstractDataChangeListener<Int
         LOG.info("Received port UP event for interface {} ", interfaceName);
         org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface
             configInterface = InterfaceUtils.getInterface(broker, interfaceName);
+        BigInteger dpnId = InterfaceUtils.getDpIdFromInterface(intrf);
         if (configInterface != null && configInterface.getType().equals(Tunnel.class)) {
-          BigInteger dpnId = InterfaceUtils.getDpnForInterface(interfaceManager, interfaceName);
           if(intrf.getOperStatus().equals(Interface.OperStatus.Up)) {
             //advertise all prefixes in all vpns for this dpn to bgp
             vpnInterfaceManager.updatePrefixesForDPN(dpnId, VpnInterfaceManager.UpdateRouteAction.ADVERTISE_ROUTE);
           }
         } else {
-          vpnInterfaceManager.processVpnInterfaceUp(interfaceName, intrf.getIfIndex());
+          vpnInterfaceManager.processVpnInterfaceUp(dpnId, interfaceName, intrf.getIfIndex());
         }
       } catch (Exception e) {
         LOG.error("Exception caught in Interface Operational State Up event", e);
@@ -103,20 +103,15 @@ public class InterfaceStateChangeListener extends AbstractDataChangeListener<Int
         LOG.info("Received port DOWN event for interface {} ", interfaceName);
         org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface
             intf = InterfaceUtils.getInterface(broker, interfaceName);
+        BigInteger dpId = InterfaceUtils.getDpIdFromInterface(intrf);
         if (intf != null && intf.getType().equals(Tunnel.class)) {
-          // Get the dpId from del reference itself. Because interfaceManager.getDpnForInterface returns
-          // NPE because entry is already deleted in operational data store
-          BigInteger dpId = getDpIdFromInterface(intrf);
-          if (dpId == null) {
-            return;
-          }
           if(intrf.getOperStatus().equals(Interface.OperStatus.Down)) {
             //withdraw all prefixes in all vpns for this dpn from bgp
             vpnInterfaceManager.updatePrefixesForDPN(dpId, VpnInterfaceManager.UpdateRouteAction.WITHDRAW_ROUTE);
           }
         } else {
           if (VpnUtil.isVpnInterfaceConfigured(broker, interfaceName)) {
-            vpnInterfaceManager.processVpnInterfaceDown(interfaceName, intrf.getIfIndex(), true);
+            vpnInterfaceManager.processVpnInterfaceDown(dpId, interfaceName, intrf.getIfIndex(), true);
           }
         }
       } catch (Exception e) {
@@ -132,7 +127,7 @@ public class InterfaceStateChangeListener extends AbstractDataChangeListener<Int
       org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface
           intf = InterfaceUtils.getInterface(broker, interfaceName);
       if (intf != null && intf.getType().equals(Tunnel.class)) {
-        BigInteger dpnId = InterfaceUtils.getDpnForInterface(interfaceManager, interfaceName);
+        BigInteger dpnId = InterfaceUtils.getDpIdFromInterface(update);
         if(update.getOperStatus().equals(Interface.OperStatus.Up)) {
           //advertise all prefixes in all vpns for this dpn to bgp
           vpnInterfaceManager.updatePrefixesForDPN(dpnId, VpnInterfaceManager.UpdateRouteAction.ADVERTISE_ROUTE);
@@ -144,12 +139,4 @@ public class InterfaceStateChangeListener extends AbstractDataChangeListener<Int
 
     }
 
-  public BigInteger getDpIdFromInterface(org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface infState) {
-    org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface ifState =
-        InterfaceUtils.getInterfaceStateFromOperDS(broker, infState.getName());
-    String lowerLayerIf = ifState.getLowerLayerIf().get(0);
-    NodeConnectorId nodeConnectorId = new NodeConnectorId(lowerLayerIf);
-    return new BigInteger(InterfaceUtils.getDpnFromNodeConnectorId(nodeConnectorId));
-  }
-
 }
index 75b076395e4895c9ecd99419cd61879bfd62f727..862a6c49c24a83f3d301f445ce0e7ad246b43f16 100644 (file)
@@ -21,4 +21,5 @@ public class VpnConstants {
     public static final BigInteger COOKIE_VM_INGRESS_TABLE = new BigInteger("8000001", 16);
     public static final BigInteger COOKIE_L3_BASE = new BigInteger("8000000", 16);
     public static final String FLOWID_PREFIX = "L3.";
+    public static final long WAIT_TIME_IN_MILLISECONDS = 5000;
 }
index 525d30bd0cd1d3e970c139ffbefa99062218e71d..d4dd28813275770c4469305e425fc7ca74e2377a 100644 (file)
@@ -18,6 +18,7 @@ import org.opendaylight.vpnservice.mdsalutil.*;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpAddress;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.PhysAddress;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.l3vpn.rev130911.adjacency.list.AdjacencyKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.l3vpn.rev130911.vpn.instance.op.data.VpnInstanceOpDataEntry;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.l3vpn.rev130911.vpn.instance.op.data.vpn.instance.op.data.entry.VpnToDpnList;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.l3vpn.rev130911.vpn.instance.op.data.vpn.instance.op.data.entry.VpnToDpnListBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.l3vpn.rev130911.vpn.instance.op.data.vpn.instance.op.data.entry.vpn.to.dpn.list.VpnInterfacesBuilder;
@@ -41,7 +42,7 @@ import java.util.Collection;
 import java.util.Iterator;
 import java.util.List;
 import java.util.ArrayList;
-import java.util.concurrent.Future;
+import java.util.concurrent.*;
 
 import com.google.common.base.Optional;
 
@@ -73,7 +74,9 @@ import org.slf4j.LoggerFactory;
 
 public class VpnInterfaceManager extends AbstractDataChangeListener<VpnInterface> implements AutoCloseable {
     private static final Logger LOG = LoggerFactory.getLogger(VpnInterfaceManager.class);
-    private ListenerRegistration<DataChangeListener> listenerRegistration;
+    private ListenerRegistration<DataChangeListener> listenerRegistration, opListenerRegistration;
+    private ConcurrentMap<String, Runnable> vpnIntfMap = new ConcurrentHashMap<String, Runnable>();
+    private ExecutorService executorService = Executors.newSingleThreadExecutor();
     private final DataBroker broker;
     private final IBgpManager bgpManager;
     private IFibManager fibManager;
@@ -83,6 +86,7 @@ public class VpnInterfaceManager extends AbstractDataChangeListener<VpnInterface
     private IdManagerService idManager;
     private OdlArputilService arpManager;
     private InterfaceStateChangeListener interfaceListener;
+    private VpnInterfaceOpListener vpnInterfaceOpListener;
     private ArpNotificationHandler arpNotificationHandler;
     protected enum UpdateRouteAction {
         ADVERTISE_ROUTE, WITHDRAW_ROUTE
@@ -98,6 +102,7 @@ public class VpnInterfaceManager extends AbstractDataChangeListener<VpnInterface
         broker = db;
         this.bgpManager = bgpManager;
         interfaceListener = new InterfaceStateChangeListener(db, this);
+        vpnInterfaceOpListener = new VpnInterfaceOpListener();
         arpNotificationHandler = new ArpNotificationHandler(this, broker);
         notificationService.registerNotificationListener(arpNotificationHandler);
         registerListener(db);
@@ -133,10 +138,12 @@ public class VpnInterfaceManager extends AbstractDataChangeListener<VpnInterface
         if (listenerRegistration != null) {
             try {
                 listenerRegistration.close();
+                opListenerRegistration.close();
             } catch (final Exception e) {
                 LOG.error("Error when cleaning up DataChangeListener.", e);
             }
             listenerRegistration = null;
+            opListenerRegistration = null;
         }
         LOG.info("VPN Interface Manager Closed");
     }
@@ -145,6 +152,8 @@ public class VpnInterfaceManager extends AbstractDataChangeListener<VpnInterface
         try {
             listenerRegistration = db.registerDataChangeListener(LogicalDatastoreType.CONFIGURATION,
                     getWildCardPath(), VpnInterfaceManager.this, DataChangeScope.SUBTREE);
+            opListenerRegistration = db.registerDataChangeListener(LogicalDatastoreType.OPERATIONAL,
+                                                                   getWildCardPath(), vpnInterfaceOpListener, DataChangeScope.SUBTREE);
         } catch (final Exception e) {
             LOG.error("VPN Service DataChange listener registration fail!", e);
             throw new IllegalStateException("VPN Service registration Listener failed.", e);
@@ -159,13 +168,13 @@ public class VpnInterfaceManager extends AbstractDataChangeListener<VpnInterface
     @Override
     protected void add(final InstanceIdentifier<VpnInterface> identifier,
             final VpnInterface vpnInterface) {
-        LOG.trace("key: {} , value: {}", identifier, vpnInterface );
+        LOG.trace("VPN Interface key: {} , value: {}", identifier, vpnInterface );
         addInterface(identifier, vpnInterface);
     }
 
     private void addInterface(final InstanceIdentifier<VpnInterface> identifier,
                               final VpnInterface vpnInterface) {
-        LOG.trace("Add event - key: {}, value: {}" ,identifier, vpnInterface );
+        LOG.trace("VPN Interface add event - key: {}, value: {}" ,identifier, vpnInterface );
         final VpnInterfaceKey key = identifier.firstKeyOf(VpnInterface.class, VpnInterfaceKey.class);
         String interfaceName = key.getName();
 
@@ -173,11 +182,13 @@ public class VpnInterfaceManager extends AbstractDataChangeListener<VpnInterface
             InterfaceUtils.getInterfaceStateFromOperDS(broker, interfaceName);
         if (interfaceState != null) {
             // Interface state is up
-            processVpnInterfaceUp(interfaceName, interfaceState.getIfIndex());
+            processVpnInterfaceUp(InterfaceUtils.getDpIdFromInterface(interfaceState), interfaceName, interfaceState.getIfIndex());
+        } else {
+            LOG.trace("VPN interfaces are not yet operational.");
         }
     }
 
-    protected synchronized void processVpnInterfaceUp(String interfaceName, int lPortTag) {
+    protected void processVpnInterfaceUp(BigInteger dpId, String interfaceName, int lPortTag) {
 
         VpnInterface vpnInterface = VpnUtil.getConfiguredVpnInterface(broker, interfaceName);
         if(vpnInterface == null) {
@@ -186,9 +197,21 @@ public class VpnInterfaceManager extends AbstractDataChangeListener<VpnInterface
         }
         String vpnName = vpnInterface.getVpnInstanceName();
         LOG.info("Binding vpn service to interface {} ", interfaceName);
-        bindService(vpnName, interfaceName, lPortTag);
-        updateDpnDbs(vpnName, interfaceName, true);
-        processVpnInterfaceAdjacencies(VpnUtil.getVpnInterfaceIdentifier(vpnInterface.getName()), vpnInterface);
+        long vpnId = VpnUtil.getVpnId(broker, vpnName);
+        if (vpnId == VpnConstants.INVALID_ID) {
+            LOG.trace("VpnInstance to VPNId mapping is not yet available, bailing out now.");
+            return;
+        }
+        if (VpnUtil.getOperationalVpnInterface(broker, vpnInterface.getName()) != null) {
+            LOG.trace("VPN Interface already provisioned , bailing out from here.");
+            return;
+        }
+        synchronized (interfaceName.intern()) {
+
+            bindService(dpId, vpnName, interfaceName, lPortTag);
+            updateDpnDbs(vpnName, interfaceName, true);
+            processVpnInterfaceAdjacencies(VpnUtil.getVpnInterfaceIdentifier(vpnInterface.getName()), vpnInterface);
+        }
 
     }
 
@@ -204,7 +227,7 @@ public class VpnInterfaceManager extends AbstractDataChangeListener<VpnInterface
 
     }
 
-    private void bindService(String vpnInstanceName, String vpnInterfaceName, int lPortTag) {
+    private void bindService(BigInteger dpId, String vpnInstanceName, String vpnInterfaceName, int lPortTag) {
         int priority = VpnConstants.DEFAULT_FLOW_PRIORITY;
         long vpnId = VpnUtil.getVpnId(broker, vpnInstanceName);
 
@@ -221,7 +244,8 @@ public class VpnInterfaceManager extends AbstractDataChangeListener<VpnInterface
                                             VpnConstants.COOKIE_VM_INGRESS_TABLE, instructions);
         VpnUtil.syncWrite(broker, LogicalDatastoreType.CONFIGURATION,
                           InterfaceUtils.buildServiceId(vpnInterfaceName, VpnConstants.L3VPN_SERVICE_IDENTIFIER), serviceInfo);
-        makeArpFlow(VpnConstants.L3VPN_SERVICE_IDENTIFIER, lPortTag, vpnInterfaceName, vpnId, ArpReplyOrRequest.REQUEST, NwConstants.ADD_FLOW);
+        makeArpFlow(dpId, VpnConstants.L3VPN_SERVICE_IDENTIFIER, lPortTag, vpnInterfaceName,
+                    vpnId, ArpReplyOrRequest.REQUEST, NwConstants.ADD_FLOW);
 
     }
 
@@ -284,7 +308,8 @@ public class VpnInterfaceManager extends AbstractDataChangeListener<VpnInterface
         }
     }
 
-    private void makeArpFlow(short sIndex, int lPortTag, String vpnInterfaceName, long vpnId, ArpReplyOrRequest replyOrRequest, int addOrRemoveFlow){
+    private void makeArpFlow(BigInteger dpId,short sIndex, int lPortTag, String vpnInterfaceName,
+                             long vpnId, ArpReplyOrRequest replyOrRequest, int addOrRemoveFlow){
         List<MatchInfo> matches = new ArrayList<MatchInfo>();
         BigInteger metadata = MetaDataUtil.getMetaDataForLPortDispatcher(lPortTag, ++sIndex, BigInteger.valueOf(vpnId));
         BigInteger metadataMask = MetaDataUtil.getMetaDataMaskForLPortDispatcher(MetaDataUtil.METADATA_MASK_SERVICE_INDEX,
@@ -304,7 +329,6 @@ public class VpnInterfaceManager extends AbstractDataChangeListener<VpnInterface
         instructions.add(new InstructionInfo(InstructionType.write_actions, actionsInfos));
 
         // Install the flow entry in L3_INTERFACE_TABLE
-        BigInteger dpId = InterfaceUtils.getDpnForInterface(interfaceManager, vpnInterfaceName);
         String flowRef = VpnUtil.getFlowRef(dpId, NwConstants.L3_INTERFACE_TABLE,
                     NwConstants.ETHTYPE_ARP, lPortTag, replyOrRequest.getArpOperation());
         FlowEntity flowEntity;
@@ -350,7 +374,7 @@ public class VpnInterfaceManager extends AbstractDataChangeListener<VpnInterface
         } else {
             VpnUtil.syncUpdate(broker, LogicalDatastoreType.OPERATIONAL,
                                     VpnUtil.getVpnInstanceOpDataIdentifier(rd),
-                                    VpnUtil.getVpnInstanceOpData(rd, vpnId));
+                                    VpnUtil.getVpnInstanceOpDataBuilder(rd, vpnId));
             VpnToDpnListBuilder vpnToDpnList = new VpnToDpnListBuilder().setDpnId(dpnId);
             List<org.opendaylight.yang.gen.v1.urn.opendaylight.l3vpn.rev130911.vpn.instance.op.data
                 .vpn.instance.op.data.entry.vpn.to.dpn.list.VpnInterfaces> vpnInterfaces =  new ArrayList<>();
@@ -423,13 +447,13 @@ public class VpnInterfaceManager extends AbstractDataChangeListener<VpnInterface
             InterfaceUtils.getInterfaceStateFromOperDS(broker, interfaceName);
 
         if (existingVpnInterface.isPresent() && interfaceState != null) {
-            processVpnInterfaceDown(interfaceName, interfaceState.getIfIndex(), false);
+            processVpnInterfaceDown(InterfaceUtils.getDpIdFromInterface(interfaceState), interfaceName, interfaceState.getIfIndex(), false);
         } else {
             LOG.warn("VPN interface {} was unavailable in operational data store to handle remove event", interfaceName);
         }
     }
 
-    protected synchronized void processVpnInterfaceDown(String interfaceName, int lPortTag, boolean isInterfaceStateDown) {
+    protected void processVpnInterfaceDown(BigInteger dpId, String interfaceName, int lPortTag, boolean isInterfaceStateDown) {
         VpnInterface vpnInterface = VpnUtil.getOperationalVpnInterface(broker, interfaceName);
         if(vpnInterface == null) {
             LOG.info("Unable to process delete/down for interface {} as it is not available in operational data store", interfaceName);
@@ -438,11 +462,24 @@ public class VpnInterfaceManager extends AbstractDataChangeListener<VpnInterface
         String vpnName = vpnInterface.getVpnInstanceName();
         InstanceIdentifier<VpnInterface> identifier = VpnUtil.getVpnInterfaceIdentifier(interfaceName);
 
-        removeAdjacenciesFromVpn(identifier, vpnInterface);
-        LOG.info("Unbinding vpn service from interface {} ", interfaceName);
-        unbindService(vpnName, interfaceName, lPortTag, isInterfaceStateDown);
-        updateDpnDbs(vpnName, interfaceName, false);
-        VpnUtil.delete(broker, LogicalDatastoreType.OPERATIONAL, identifier, VpnUtil.DEFAULT_CALLBACK);
+        synchronized (interfaceName.intern()) {
+            removeAdjacenciesFromVpn(identifier, vpnInterface);
+            LOG.info("Unbinding vpn service from interface {} ", interfaceName);
+            unbindService(dpId, vpnName, interfaceName, lPortTag, isInterfaceStateDown);
+
+            //wait till DCN for removal of vpn interface in operational DS arrives
+            Runnable notifyTask = new VpnNotifyTask();
+            synchronized (interfaceName.intern()) {
+                vpnIntfMap.put(interfaceName, notifyTask);
+                synchronized (notifyTask) {
+                    try {
+                        notifyTask.wait(VpnConstants.WAIT_TIME_IN_MILLISECONDS);
+                    } catch (InterruptedException e) {
+                    }
+                }
+            }
+
+        }
     }
 
     private void removeAdjacenciesFromVpn(final InstanceIdentifier<VpnInterface> identifier, VpnInterface intf) {
@@ -459,11 +496,11 @@ public class VpnInterfaceManager extends AbstractDataChangeListener<VpnInterface
                 for (Adjacency nextHop : nextHops) {
                     VpnUtil.releaseId(idManager, VpnConstants.VPN_IDPOOL_NAME,
                                       VpnUtil.getNextHopLabelKey(rd, nextHop.getIpAddress()));
-                    VpnUtil.delete(broker, LogicalDatastoreType.OPERATIONAL,
+                    /*VpnUtil.delete(broker, LogicalDatastoreType.OPERATIONAL,
                                    VpnUtil.getPrefixToInterfaceIdentifier(
                                        VpnUtil.getVpnId(broker, intf.getVpnInstanceName()),
                                        nextHop.getIpAddress()),
-                                   VpnUtil.DEFAULT_CALLBACK);
+                                   VpnUtil.DEFAULT_CALLBACK);*/
                     if (rd.equals(intf.getVpnInstanceName())) {
                         //this is an internal vpn - the rd is assigned to the vpn instance name;
                         //remove from FIB directly
@@ -477,7 +514,8 @@ public class VpnInterfaceManager extends AbstractDataChangeListener<VpnInterface
     }
 
 
-    private void unbindService(String vpnInstanceName, String vpnInterfaceName, int lPortTag, boolean isInterfaceStateDown) {
+    private void unbindService(BigInteger dpId, String vpnInstanceName, String vpnInterfaceName,
+                               int lPortTag, boolean isInterfaceStateDown) {
         if (!isInterfaceStateDown) {
             VpnUtil.delete(broker, LogicalDatastoreType.CONFIGURATION,
                            InterfaceUtils.buildServiceId(vpnInterfaceName,
@@ -485,7 +523,7 @@ public class VpnInterfaceManager extends AbstractDataChangeListener<VpnInterface
                            VpnUtil.DEFAULT_CALLBACK);
         }
         long vpnId = VpnUtil.getVpnId(broker, vpnInstanceName);
-        makeArpFlow(VpnConstants.L3VPN_SERVICE_IDENTIFIER, lPortTag, vpnInterfaceName,
+        makeArpFlow(dpId, VpnConstants.L3VPN_SERVICE_IDENTIFIER, lPortTag, vpnInterfaceName,
                     vpnId, ArpReplyOrRequest.REQUEST, NwConstants.DEL_FLOW);
     }
 
@@ -622,7 +660,7 @@ public class VpnInterfaceManager extends AbstractDataChangeListener<VpnInterface
         VrfTables vrfTableNew = new VrfTablesBuilder().setRouteDistinguisher(rd).
                     setVrfEntry(vrfEntryList).build();
 
-        VpnUtil.syncUpdate(broker, LogicalDatastoreType.OPERATIONAL, vrfTableId, vrfTableNew);
+        VpnUtil.syncUpdate(broker, LogicalDatastoreType.CONFIGURATION, vrfTableId, vrfTableNew);
     }
 
     public synchronized void removeFibEntryFromDS(String rd, String prefix) {
@@ -632,7 +670,7 @@ public class VpnInterfaceManager extends AbstractDataChangeListener<VpnInterface
         InstanceIdentifierBuilder<VrfEntry> idBuilder =
             InstanceIdentifier.builder(FibEntries.class).child(VrfTables.class, new VrfTablesKey(rd)).child(VrfEntry.class, new VrfEntryKey(prefix));
         InstanceIdentifier<VrfEntry> vrfEntryId = idBuilder.build();
-        VpnUtil.delete(broker, LogicalDatastoreType.OPERATIONAL, vrfEntryId, VpnUtil.DEFAULT_CALLBACK);
+        VpnUtil.delete(broker, LogicalDatastoreType.CONFIGURATION, vrfEntryId, VpnUtil.DEFAULT_CALLBACK);
 
     }
 
@@ -643,7 +681,7 @@ public class VpnInterfaceManager extends AbstractDataChangeListener<VpnInterface
                 InstanceIdentifier.builder(FibEntries.class).child(VrfTables.class, new VrfTablesKey(rd));
         InstanceIdentifier<VrfTables> vrfTableId = idBuilder.build();
 
-        VpnUtil.delete(broker, LogicalDatastoreType.OPERATIONAL, vrfTableId, VpnUtil.DEFAULT_CALLBACK);
+        VpnUtil.delete(broker, LogicalDatastoreType.CONFIGURATION, vrfTableId, VpnUtil.DEFAULT_CALLBACK);
 
     }
 
@@ -676,7 +714,7 @@ public class VpnInterfaceManager extends AbstractDataChangeListener<VpnInterface
             VpnInterface newVpnIntf = VpnUtil.getVpnInterface(currVpnIntf.getName(), currVpnIntf.getVpnInstanceName(), aug);
 
             VpnUtil.syncUpdate(broker, LogicalDatastoreType.OPERATIONAL, identifier, newVpnIntf);
-            addExtraRoute(adj.getIpAddress(), adj.getNextHopIp(), rd, currVpnIntf.getVpnInstanceName(), (int) label);
+            addExtraRoute(adj.getIpAddress(), adj.getNextHopIp(), rd, currVpnIntf.getVpnInstanceName(), (int) label, currVpnIntf.getName());
 
         }
 
@@ -720,7 +758,25 @@ public class VpnInterfaceManager extends AbstractDataChangeListener<VpnInterface
 
     }
 
-    protected void addExtraRoute(String destination, String nextHop, String rd, String routerID, int label) {
+    protected void addExtraRoute(String destination, String nextHop, String rd, String routerID, int label, String intfName) {
+
+        //add extra route to vpn mapping; advertise with nexthop as tunnel ip
+        VpnUtil.syncUpdate(
+            broker,
+            LogicalDatastoreType.OPERATIONAL,
+            VpnUtil.getVpnToExtrarouteIdentifier(
+                (rd != null) ? rd : routerID, destination),
+            VpnUtil.getVpnToExtraroute(destination, nextHop));
+
+        if(intfName != null && !intfName.isEmpty()) {
+            BigInteger dpnId = InterfaceUtils.getDpnForInterface(interfaceManager, intfName);
+            String nextHopIp = InterfaceUtils.getEndpointIpAddressForDPN(broker, dpnId);
+            if (nextHopIp == null && !nextHopIp.isEmpty()) {
+                LOG.error("NextHop for interface {} is null. Failed adding extra route for prefix {}", intfName, destination);
+                return;
+            }
+            nextHop = nextHopIp;
+        }
         if (rd != null) {
             addPrefixToBGP(rd, destination, nextHop, label);
         } else {
@@ -738,6 +794,73 @@ public class VpnInterfaceManager extends AbstractDataChangeListener<VpnInterface
         }
     }
 
+    class VpnInterfaceOpListener extends org.opendaylight.vpnservice.mdsalutil.AbstractDataChangeListener<VpnInterface> {
+
+        public VpnInterfaceOpListener() {
+            super(VpnInterface.class);
+        }
+
+        @Override
+        protected void remove(InstanceIdentifier<VpnInterface> identifier, VpnInterface del) {
+            final VpnInterfaceKey key = identifier.firstKeyOf(VpnInterface.class, VpnInterfaceKey.class);
+            String interfaceName = key.getName();
+
+            //increment the vpn interface count in Vpn Instance Op Data
+            Long ifCnt = 0L;
+            String rd = getRouteDistinguisher(del.getVpnInstanceName());
+            if(rd.isEmpty()) rd = del.getVpnInstanceName();
+            VpnInstanceOpDataEntry vpnInstOp = VpnUtil.getVpnInstanceOpData(broker, rd);
+            if(vpnInstOp != null && vpnInstOp.getVpnInterfaceCount() != null) {
+                ifCnt = vpnInstOp.getVpnInterfaceCount();
+            }
+
+            LOG.trace("VpnInterfaceOpListener remove: interface name {} rd {} interface count in Vpn Op Instance {}", interfaceName, rd, ifCnt);
+
+            VpnUtil.asyncUpdate(broker, LogicalDatastoreType.OPERATIONAL,
+                    VpnUtil.getVpnInstanceOpDataIdentifier(rd),
+                    VpnUtil.updateIntfCntInVpnInstOpData(ifCnt - 1, rd), VpnUtil.DEFAULT_CALLBACK);
+
+            //TODO: Clean up the DPN List in Vpn Instance Op if ifCnt is zero
+
+            notifyTaskIfRequired(interfaceName);
+        }
+
+        private void notifyTaskIfRequired(String intfName) {
+            Runnable notifyTask = vpnIntfMap.remove(intfName);
+            if (notifyTask == null) {
+                return;
+            }
+            executorService.execute(notifyTask);
+        }
+
+        @Override
+        protected void update(InstanceIdentifier<VpnInterface> identifier, VpnInterface original, VpnInterface update) {
+        }
+
+        @Override
+        protected void add(InstanceIdentifier<VpnInterface> identifier, VpnInterface add) {
+            final VpnInterfaceKey key = identifier.firstKeyOf(VpnInterface.class, VpnInterfaceKey.class);
+            String interfaceName = key.getName();
+
+            //increment the vpn interface count in Vpn Instance Op Data
+            Long ifCnt = 0L;
+            String rd = getRouteDistinguisher(add.getVpnInstanceName());
+            if(rd.isEmpty()) rd = add.getVpnInstanceName();
+            VpnInstanceOpDataEntry vpnInstOp = VpnUtil.getVpnInstanceOpData(broker, rd);
+            if(vpnInstOp != null &&  vpnInstOp.getVpnInterfaceCount() != null) {
+                ifCnt = vpnInstOp.getVpnInterfaceCount();
+            }
+
+            LOG.trace("VpnInterfaceOpListener add: interface name {} rd {} interface count in Vpn Op Instance {}", interfaceName, rd, ifCnt);
+
+            VpnUtil.asyncUpdate(broker, LogicalDatastoreType.OPERATIONAL,
+                    VpnUtil.getVpnInstanceOpDataIdentifier(rd),
+                    VpnUtil.updateIntfCntInVpnInstOpData(ifCnt + 1, rd), VpnUtil.DEFAULT_CALLBACK);
+
+
+        }
+    }
+
     protected void updatePrefixesForDPN(BigInteger dpnId, UpdateRouteAction action) {
 
         InstanceIdentifierBuilder<VpnInstances> idBuilder = InstanceIdentifier.builder(VpnInstances.class);
index 5567d3e6206a47e3c47d2a65f283ff2ddc62ed3d..1a454018d0a3f912570d99da250693f6f9a03c19 100644 (file)
@@ -10,12 +10,15 @@ package org.opendaylight.vpnservice;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.List;
+import java.util.concurrent.*;
 
+import com.google.common.util.concurrent.CheckedFuture;
 import org.opendaylight.bgpmanager.api.IBgpManager;
 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
 import org.opendaylight.controller.md.sal.binding.api.DataChangeListener;
 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
 import org.opendaylight.controller.md.sal.common.api.data.AsyncDataBroker.DataChangeScope;
+import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.af.config.vpntargets.VpnTarget;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.l3vpn.rev130911.VpnInstanceToVpnId;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.l3vpn.rev130911.VpnInstanceToVpnIdBuilder;
@@ -51,12 +54,15 @@ import com.google.common.util.concurrent.Futures;
 
 public class VpnManager extends AbstractDataChangeListener<VpnInstance> implements AutoCloseable {
     private static final Logger LOG = LoggerFactory.getLogger(VpnManager.class);
-    private ListenerRegistration<DataChangeListener> listenerRegistration, fibListenerRegistration;
+    private ListenerRegistration<DataChangeListener> listenerRegistration, fibListenerRegistration, opListenerRegistration;
+    private ConcurrentMap<String, Runnable> vpnOpMap = new ConcurrentHashMap<String, Runnable>();
+    private ExecutorService executorService = Executors.newSingleThreadExecutor();
     private final DataBroker broker;
     private final IBgpManager bgpManager;
     private IdManagerService idManager;
     private VpnInterfaceManager vpnInterfaceManager;
     private final FibEntriesListener fibListener;
+    private final VpnInstanceOpListener vpnInstOpListener;
 
     private static final FutureCallback<Void> DEFAULT_CALLBACK =
             new FutureCallback<Void>() {
@@ -80,6 +86,7 @@ public class VpnManager extends AbstractDataChangeListener<VpnInstance> implemen
         broker = db;
         this.bgpManager = bgpManager;
         this.fibListener = new FibEntriesListener();
+        this.vpnInstOpListener = new VpnInstanceOpListener();
         registerListener(db);
     }
 
@@ -89,6 +96,9 @@ public class VpnManager extends AbstractDataChangeListener<VpnInstance> implemen
                     getWildCardPath(), VpnManager.this, DataChangeScope.SUBTREE);
             fibListenerRegistration = db.registerDataChangeListener(LogicalDatastoreType.OPERATIONAL,
                     getFibEntryListenerPath(), fibListener, DataChangeScope.BASE);
+            opListenerRegistration = db.registerDataChangeListener(LogicalDatastoreType.CONFIGURATION,
+                    getVpnInstanceOpListenerPath(), vpnInstOpListener, DataChangeScope.SUBTREE);
+
         } catch (final Exception e) {
             LOG.error("VPN Service DataChange listener registration fail !", e);
             throw new IllegalStateException("VPN Service registration Listener failed.", e);
@@ -103,6 +113,21 @@ public class VpnManager extends AbstractDataChangeListener<VpnInstance> implemen
         this.vpnInterfaceManager = vpnInterfaceManager;
     }
 
+    private void waitForOpDataRemoval(String id) {
+        //wait till DCN for removal of all DPNs in VPN arrivaes
+        Runnable notifyTask = new VpnNotifyTask();
+        synchronized (id.intern()) {
+            vpnOpMap.put(id, notifyTask);
+            synchronized (notifyTask) {
+                try {
+                    notifyTask.wait(VpnConstants.WAIT_TIME_IN_MILLISECONDS);
+                } catch (InterruptedException e) {
+                }
+            }
+        }
+
+    }
+
     @Override
     protected void remove(InstanceIdentifier<VpnInstance> identifier, VpnInstance del) {
         LOG.trace("Remove VPN event - Key: {}, value: {}", identifier, del);
@@ -131,13 +156,15 @@ public class VpnManager extends AbstractDataChangeListener<VpnInstance> implemen
 
         if (rd !=null) {
 
-            delete(LogicalDatastoreType.OPERATIONAL, VpnUtil.getVpnInstanceOpDataIdentifier(rd));
             try {
                 bgpManager.deleteVrf(rd);
-            } catch(Exception e) {
+            } catch (Exception e) {
                 LOG.error("Exception when removing VRF from BGP", e);
             }
+            waitForOpDataRemoval(rd);
+            delete(LogicalDatastoreType.OPERATIONAL, VpnUtil.getVpnInstanceOpDataIdentifier(rd));
         } else {
+            waitForOpDataRemoval(vpnName);
             delete(LogicalDatastoreType.OPERATIONAL, VpnUtil.getVpnInstanceOpDataIdentifier(vpnName));
         }
     }
@@ -151,30 +178,30 @@ public class VpnManager extends AbstractDataChangeListener<VpnInstance> implemen
     @Override
     protected void add(InstanceIdentifier<VpnInstance> identifier,
             VpnInstance value) {
-        LOG.trace("key: {}, value: {}", identifier, value);
+        LOG.trace("VPN Instance key: {}, value: {}", identifier, value);
         VpnAfConfig config = value.getIpv4Family();
         String rd = config.getRouteDistinguisher();
 
         long vpnId = VpnUtil.getUniqueId(idManager, VpnConstants.VPN_IDPOOL_NAME, value.getVpnInstanceName());
-
+        LOG.trace("VPN instance to ID generated.");
         org.opendaylight.yang.gen.v1.urn.opendaylight.l3vpn.rev130911.vpn.instance.to.vpn.id.VpnInstance
             vpnInstanceToVpnId = VpnUtil.getVpnInstanceToVpnId(value.getVpnInstanceName(), vpnId,
                                                                     (rd != null) ? rd : value.getVpnInstanceName());
 
-        asyncWrite(LogicalDatastoreType.CONFIGURATION,
+        syncWrite(LogicalDatastoreType.CONFIGURATION,
                    VpnUtil.getVpnInstanceToVpnIdIdentifier(value.getVpnInstanceName()),
                    vpnInstanceToVpnId, DEFAULT_CALLBACK);
 
 
         if(rd == null) {
-            asyncWrite(LogicalDatastoreType.OPERATIONAL,
+            syncWrite(LogicalDatastoreType.OPERATIONAL,
                     VpnUtil.getVpnInstanceOpDataIdentifier(value.getVpnInstanceName()),
-                    VpnUtil.getVpnInstanceOpData(value.getVpnInstanceName(), vpnId), DEFAULT_CALLBACK);
+                    VpnUtil.getVpnInstanceOpDataBuilder(value.getVpnInstanceName(), vpnId), DEFAULT_CALLBACK);
 
         } else {
-            asyncWrite(LogicalDatastoreType.OPERATIONAL,
+            syncWrite(LogicalDatastoreType.OPERATIONAL,
                        VpnUtil.getVpnInstanceOpDataIdentifier(rd),
-                       VpnUtil.getVpnInstanceOpData(rd, vpnId), DEFAULT_CALLBACK);
+                       VpnUtil.getVpnInstanceOpDataBuilder(rd, vpnId), DEFAULT_CALLBACK);
 
             List<VpnTarget> vpnTargetList = config.getVpnTargets().getVpnTarget();
 
@@ -200,6 +227,22 @@ public class VpnManager extends AbstractDataChangeListener<VpnInstance> implemen
                 LOG.error("Exception when adding VRF to BGP", e);
             }
         }
+        //Try to add up vpn Interfaces if already in Operational Datastore
+        LOG.trace("Trying to add the vpn interfaces  -1.");
+        InstanceIdentifier<VpnInterfaces> vpnInterfacesId = InstanceIdentifier.builder(VpnInterfaces.class).build();
+        Optional<VpnInterfaces> optionalVpnInterfaces = read(LogicalDatastoreType.CONFIGURATION, vpnInterfacesId);
+
+        if(optionalVpnInterfaces.isPresent()) {
+            List<VpnInterface> vpnInterfaces = optionalVpnInterfaces.get().getVpnInterface();
+            for(VpnInterface vpnInterface : vpnInterfaces) {
+                if(vpnInterface.getVpnInstanceName().equals(value.getVpnInstanceName())) {
+                    LOG.debug("VpnInterface {} will be added from VPN {}", vpnInterface.getName(), value.getVpnInstanceName());
+                    vpnInterfaceManager.add(
+                                VpnUtil.getVpnInterfaceIdentifier(vpnInterface.getName()), vpnInterface);
+
+                }
+            }
+        }
     }
 
     private InstanceIdentifier<?> getWildCardPath() {
@@ -211,6 +254,11 @@ public class VpnManager extends AbstractDataChangeListener<VpnInstance> implemen
                 .child(VrfEntry.class);
     }
 
+    private InstanceIdentifier<?> getVpnInstanceOpListenerPath() {
+        return InstanceIdentifier.create(VpnInstanceOpData.class).child(VpnInstanceOpDataEntry.class);
+
+    }
+
     @Override
     public void close() throws Exception {
         if (listenerRegistration != null) {
@@ -229,6 +277,15 @@ public class VpnManager extends AbstractDataChangeListener<VpnInstance> implemen
             }
             fibListenerRegistration = null;
         }
+        if (opListenerRegistration != null) {
+            try {
+                opListenerRegistration.close();
+            } catch (final Exception e) {
+                LOG.error("Error when cleaning up VPN Instance Operational entries DataChangeListener.", e);
+            }
+            opListenerRegistration = null;
+        }
+
         LOG.trace("VPN Manager Closed");
     }
 
@@ -254,6 +311,19 @@ public class VpnManager extends AbstractDataChangeListener<VpnInstance> implemen
         Futures.addCallback(tx.submit(), callback);
     }
 
+    private <T extends DataObject> void syncWrite(LogicalDatastoreType datastoreType,
+                                                   InstanceIdentifier<T> path, T data, FutureCallback<Void> callback) {
+        WriteTransaction tx = broker.newWriteOnlyTransaction();
+        tx.put(datastoreType, path, data, true);
+        CheckedFuture<Void, TransactionCommitFailedException> futures = tx.submit();
+        try {
+            futures.get();
+        } catch (InterruptedException | ExecutionException e) {
+            LOG.error("Error writing VPN instance to ID info to datastore (path, data) : ({}, {})", path, data);
+            throw new RuntimeException(e.getMessage());
+        }
+    }
+
     protected VpnInstanceOpDataEntry getVpnInstanceOpData(String rd) {
         InstanceIdentifier<VpnInstanceOpDataEntry> id = VpnUtil.getVpnInstanceOpDataIdentifier(rd);
         Optional<VpnInstanceOpDataEntry> vpnInstanceOpData = read(LogicalDatastoreType.OPERATIONAL, id);
@@ -327,4 +397,42 @@ public class VpnManager extends AbstractDataChangeListener<VpnInstance> implemen
             }
         }
     }
+
+    class VpnInstanceOpListener extends org.opendaylight.vpnservice.mdsalutil.AbstractDataChangeListener<VpnInstanceOpDataEntry> {
+
+        public VpnInstanceOpListener() {
+            super(VpnInstanceOpDataEntry.class);
+        }
+
+        @Override
+        protected void remove(InstanceIdentifier<VpnInstanceOpDataEntry> identifier, VpnInstanceOpDataEntry del) {
+
+        }
+
+        @Override
+        protected void update(InstanceIdentifier<VpnInstanceOpDataEntry> identifier, VpnInstanceOpDataEntry original, VpnInstanceOpDataEntry update) {
+            final VpnInstanceOpDataEntryKey key = identifier.firstKeyOf(VpnInstanceOpDataEntry.class, VpnInstanceOpDataEntryKey.class);
+            String vpnName = key.getVrfId();
+
+            LOG.trace("VpnInstanceOpListener update: vpn name {} interface count in Old VpnOp Instance {} in New VpnOp Instance {}" ,
+                            vpnName, original.getVpnInterfaceCount(), update.getVpnInterfaceCount() );
+
+            //if((original.getVpnToDpnList().size() != update.getVpnToDpnList().size()) && (update.getVpnToDpnList().size() == 0)) {
+            if((original.getVpnInterfaceCount() != update.getVpnInterfaceCount()) && (update.getVpnInterfaceCount() == 0)) {
+                notifyTaskIfRequired(vpnName);
+            }
+        }
+
+        private void notifyTaskIfRequired(String vpnName) {
+            Runnable notifyTask = vpnOpMap.remove(vpnName);
+            if (notifyTask == null) {
+                return;
+            }
+            executorService.execute(notifyTask);
+        }
+
+        @Override
+        protected void add(InstanceIdentifier<VpnInstanceOpDataEntry> identifier, VpnInstanceOpDataEntry add) {
+        }
+    }
 }
diff --git a/vpnmanager/vpnmanager-impl/src/main/java/org/opendaylight/vpnservice/VpnNotifyTask.java b/vpnmanager/vpnmanager-impl/src/main/java/org/opendaylight/vpnservice/VpnNotifyTask.java
new file mode 100644 (file)
index 0000000..0611e34
--- /dev/null
@@ -0,0 +1,25 @@
+/*
+ * 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.vpnservice;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+class VpnNotifyTask implements Runnable{
+    private static final Logger logger = LoggerFactory.getLogger(VpnNotifyTask.class);
+
+    @Override
+    public void run() {
+        logger.debug("Notify Task is running for the task {}", this);
+        synchronized (this) {
+            notifyAll();
+        }
+    }
+
+}
index 29ad638fa14ff79a3f8be1611ab740516db6ae54..10d69f961627900d630cd67991a9532e2e4c2914 100644 (file)
@@ -34,9 +34,7 @@ import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev14081
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.Interfaces;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.InterfaceKey;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.l3vpn.rev130911.PrefixToInterface;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.l3vpn.rev130911.VpnInstanceOpData;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.l3vpn.rev130911.VpnInstanceToVpnId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.l3vpn.rev130911.*;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.l3vpn.rev130911.adjacency.list.Adjacency;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.l3vpn.rev130911.Adjacencies;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.l3vpn.rev130911.AdjacenciesBuilder;
@@ -50,6 +48,11 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.l3vpn.rev130911.vpn.instanc
 import org.opendaylight.yang.gen.v1.urn.opendaylight.l3vpn.rev130911.vpn.instance.op.data.VpnInstanceOpDataEntryKey;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.l3vpn.rev130911.vpn.instance.op.data.vpn.instance.op.data.entry.VpnToDpnList;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.l3vpn.rev130911.vpn.instance.op.data.vpn.instance.op.data.entry.VpnToDpnListKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.l3vpn.rev130911.vpn.to.extraroute.Vpn;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.l3vpn.rev130911.vpn.to.extraroute.VpnKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.l3vpn.rev130911.vpn.to.extraroute.vpn.Extraroute;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.l3vpn.rev130911.vpn.to.extraroute.vpn.ExtrarouteBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.l3vpn.rev130911.vpn.to.extraroute.vpn.ExtrarouteKey;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.idmanager.rev150403.IdPools;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.idmanager.rev150403.id.pools.IdPool;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.idmanager.rev150403.id.pools.IdPoolKey;
@@ -97,6 +100,16 @@ public class VpnUtil {
             vpnInterfaceName).setIpAddress(ipPrefix).build();
     }
 
+    static InstanceIdentifier<Extraroute> getVpnToExtrarouteIdentifier(String vrfId, String ipPrefix) {
+        return InstanceIdentifier.builder(VpnToExtraroute.class)
+                .child(Vpn.class, new VpnKey(vrfId)).child(Extraroute.class,
+                 new ExtrarouteKey(ipPrefix)).build();
+    }
+
+    static Extraroute getVpnToExtraroute(String ipPrefix, String nextHop) {
+        return new ExtrarouteBuilder().setPrefix(ipPrefix).setNexthopIp(nextHop).build();
+    }
+
     static Adjacencies
     getVpnInterfaceAugmentation(List<Adjacency> nextHops) {
         return new AdjacenciesBuilder().setAdjacency(nextHops).build();
@@ -219,10 +232,23 @@ public class VpnUtil {
             .child(VpnInstanceOpDataEntry.class, new VpnInstanceOpDataEntryKey(rd)).build();
     }
 
-    static VpnInstanceOpDataEntry getVpnInstanceOpData(String rd, long vpnId) {
+    static VpnInstanceOpDataEntry getVpnInstanceOpDataBuilder(String rd, long vpnId) {
         return new VpnInstanceOpDataEntryBuilder().setVrfId(rd).setVpnId(vpnId).build();
     }
 
+    static VpnInstanceOpDataEntry updateIntfCntInVpnInstOpData(Long count, String vrfId) {
+        return new VpnInstanceOpDataEntryBuilder().setVpnInterfaceCount(count).setVrfId(vrfId).build();
+    }
+
+    static VpnInstanceOpDataEntry getVpnInstanceOpData(DataBroker broker, String rd) {
+        InstanceIdentifier<VpnInstanceOpDataEntry> id = VpnUtil.getVpnInstanceOpDataIdentifier(rd);
+        Optional<VpnInstanceOpDataEntry> vpnInstanceOpData = read(broker, LogicalDatastoreType.OPERATIONAL, id);
+        if(vpnInstanceOpData.isPresent()) {
+            return vpnInstanceOpData.get();
+        }
+        return null;
+    }
+
     static VpnInterface getConfiguredVpnInterface(DataBroker broker, String interfaceName) {
         InstanceIdentifier<VpnInterface> interfaceId = getVpnInterfaceIdentifier(interfaceName);
         Optional<VpnInterface> configuredVpnInterface = read(broker, LogicalDatastoreType.CONFIGURATION, interfaceId);
index 3dd6644554d671afff0f5336afe80d608b56f0d7..ce72eb6ac19489d155d874d14c16d2de680bb280 100644 (file)
@@ -130,7 +130,7 @@ public class VpnserviceProvider implements BindingAwareProvider, IVpnManager,
     @Override
     public void addExtraRoute(String destination, String nextHop, String rd, String routerID, int label) {
         LOG.info("Adding extra route with destination {} and nexthop {}", destination, nextHop);
-        vpnInterfaceManager.addExtraRoute(destination, nextHop, rd, routerID, label);
+        vpnInterfaceManager.addExtraRoute(destination, nextHop, rd, routerID, label, null);
     }
 
     @Override
index bd0f22a35ccc89b300363e2421e298c2cda63e44..36ffe3d20e6c0a792c0e5bc4a69983a5def0a8d2 100644 (file)
@@ -144,4 +144,11 @@ public class InterfaceUtils {
     String[] split = portId.getValue().split(OF_URI_SEPARATOR);
     return split[1];
   }
+
+  public static BigInteger getDpIdFromInterface(org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface ifState) {
+    String lowerLayerIf = ifState.getLowerLayerIf().get(0);
+    NodeConnectorId nodeConnectorId = new NodeConnectorId(lowerLayerIf);
+    return new BigInteger(getDpnFromNodeConnectorId(nodeConnectorId));
+  }
+
 }