WA to define local next hop ip 21/52821/1
authorKonsta Pozdeev <konsta.pozdeev@hpe.com>
Thu, 9 Feb 2017 11:31:40 +0000 (13:31 +0200)
committerKonsta Pozdeev <konsta.pozdeev@hpe.com>
Sun, 5 Mar 2017 09:40:13 +0000 (11:40 +0200)
Change-Id: I87c0296733445fe3f071321e4d3bb0c3e27814e7
Signed-off-by: Konsta Pozdeev <konsta.pozdeev@hpe.com>
netvirt/src/main/java/org/opendaylight/unimgr/mef/netvirt/IpvcListener.java
netvirt/src/main/java/org/opendaylight/unimgr/mef/netvirt/NetvirtUtils.java
netvirt/src/main/java/org/opendaylight/unimgr/mef/netvirt/NetvirtVpnUtils.java
netvirt/src/main/java/org/opendaylight/unimgr/mef/netvirt/UniQosManager.java
netvirt/src/main/resources/org/opendaylight/blueprint/netvirt-driver.xml

index 471021ebb3b68f050ba92ae9590704a5fd4876cb..1de28616900e08306afb91ac1c5974ebacf08c87 100644 (file)
@@ -8,6 +8,7 @@
 
 package org.opendaylight.unimgr.mef.netvirt;
 
+import java.math.BigInteger;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
@@ -18,6 +19,7 @@ import org.opendaylight.controller.md.sal.binding.api.DataTreeIdentifier;
 import org.opendaylight.controller.md.sal.binding.api.DataTreeModification;
 import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.ovsdb.utils.southbound.utils.SouthboundUtils;
 import org.opendaylight.unimgr.api.UnimgrDataTreeChangeListener;
 import org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.interfaces.rev150526.mef.interfaces.subnets.Subnet;
 import org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.interfaces.rev150526.mef.interfaces.subnets.SubnetBuilder;
@@ -33,11 +35,17 @@ import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpPrefix;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Prefix;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Uuid;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.meta.rev160406.BridgeRefInfo;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.meta.rev160406.bridge.ref.info.BridgeRefEntry;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.meta.rev160406.bridge.ref.info.BridgeRefEntryKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.OdlInterfaceRpcService;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.etree.rev160614.EtreeInterface.EtreeInterfaceType;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.op.data.VpnInstanceOpDataEntry;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.op.data.vpn.instance.op.data.entry.VpnToDpnList;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.op.data.vpn.instance.op.data.entry.vpn.to.dpn.list.VpnInterfaces;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.to.vpn.id.VpnInstance;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbBridgeAugmentation;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
 import org.opendaylight.yangtools.concepts.ListenerRegistration;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 import org.slf4j.Logger;
@@ -53,14 +61,23 @@ public class IpvcListener extends UnimgrDataTreeChangeListener<Ipvc> implements
     private ListenerRegistration<IpvcListener> ipvcListenerRegistration;
     @SuppressWarnings("unused")
     private final UniAwareListener uniAwareListener;
+    private OdlInterfaceRpcService odlInterfaceRpcService;
+    private final SouthboundUtils southBoundUtils;
+    private final org.opendaylight.ovsdb.utils.mdsal.utils.MdsalUtils mdsalUtils;
+    private static final String LOCAL_IP = "local_ip";
 
     public IpvcListener(final DataBroker dataBroker, final IUniPortManager uniPortManager,
-            final ISubnetManager subnetManager, final UniQosManager uniQosManager) {
+            final ISubnetManager subnetManager, final UniQosManager uniQosManager,
+            final OdlInterfaceRpcService odlInterfaceRpcService) {
         super(dataBroker);
         this.uniPortManager = uniPortManager;
         this.subnetManager = subnetManager;
         this.uniQosManager = uniQosManager;
         this.uniAwareListener = new UniAwareListener(dataBroker, this);
+        this.odlInterfaceRpcService = odlInterfaceRpcService;
+        this.mdsalUtils = new org.opendaylight.ovsdb.utils.mdsal.utils.MdsalUtils(dataBroker);
+        this.southBoundUtils = new SouthboundUtils(mdsalUtils);
+
         registerListener();
     }
 
@@ -405,7 +422,9 @@ public class IpvcListener extends UnimgrDataTreeChangeListener<Ipvc> implements
             IpUni ipUni, String interfaceName, String elanName, WriteTransaction tx) {
 
         Log.info("Adding vpn interface: " + interfaceName);
-        NetvirtVpnUtils.createUpdateVpnInterface(vpnName, interfaceName, ipUni.getIpAddress(),
+        BigInteger dpId = NetvirtUtils.getDpnForInterface(odlInterfaceRpcService, interfaceName);
+        IpAddress nextHop = getNodeIP(dpId);
+        NetvirtVpnUtils.createUpdateVpnInterface(vpnName, interfaceName, nextHop, ipUni.getIpAddress(),
                 uni.getMacAddress().getValue(), true, null, elanName, tx);
         Log.info("Finished working on vpn instance {} interface () ", vpnName, interfaceName);
     }
@@ -531,4 +550,36 @@ public class IpvcListener extends UnimgrDataTreeChangeListener<Ipvc> implements
         uniToUpdate.forEach(u -> uniQosManager.updateUni(u.getUniId(), u.getIngressBwProfile()));
         updateQos(uniToUpdate);
     }
+
+    private IpAddress getNodeIP(BigInteger dpId) {
+        Node node = getPortsNode(dpId);
+        String localIp = southBoundUtils.getOpenvswitchOtherConfig(node, LOCAL_IP);
+        if (localIp == null) {
+            throw new UnsupportedOperationException(
+                    "missing local_ip key in ovsdb:openvswitch-other-configs in operational"
+                    + " network-topology for node: " + node.getNodeId().getValue());
+        }
+
+        return new IpAddress(localIp.toCharArray());
+    }
+
+    @SuppressWarnings("unchecked")
+    private Node getPortsNode(BigInteger dpnId) {
+        InstanceIdentifier<BridgeRefEntry> bridgeRefInfoPath = InstanceIdentifier.create(BridgeRefInfo.class)
+                .child(BridgeRefEntry.class, new BridgeRefEntryKey(dpnId));
+        BridgeRefEntry bridgeRefEntry = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, bridgeRefInfoPath);
+        if (bridgeRefEntry == null) {
+            throw new UnsupportedOperationException("no bridge ref entry found for dpnId: " + dpnId);
+        }
+
+        InstanceIdentifier<Node> nodeId = ((InstanceIdentifier<OvsdbBridgeAugmentation>) bridgeRefEntry
+                .getBridgeReference().getValue()).firstIdentifierOf(Node.class);
+        Node node = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, nodeId);
+
+        if (node == null) {
+            throw new UnsupportedOperationException("missing node for dpnId: " + dpnId);
+        }
+        return node;
+
+    }
 }
index 3f2fd7a16e98e34f5ba9898e8670c51521eb1193..9202a91014044350a7f80cf21cee16fd676b0c0d 100644 (file)
@@ -8,6 +8,10 @@
 
 package org.opendaylight.unimgr.mef.netvirt;
 
+import java.math.BigInteger;
+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.WriteTransaction;
 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
@@ -22,6 +26,10 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev
 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.ParentRefsBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.SplitHorizon;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.SplitHorizonBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetDpidFromInterfaceInput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetDpidFromInterfaceInputBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetDpidFromInterfaceOutput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.OdlInterfaceRpcService;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.l2.types.rev130827.VlanId;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.etree.rev160614.EtreeInstance;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.etree.rev160614.EtreeInstanceBuilder;
@@ -39,6 +47,7 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.SegmentTypeVxlan;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier.InstanceIdentifierBuilder;
+import org.opendaylight.yangtools.yang.common.RpcResult;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -255,6 +264,24 @@ public class NetvirtUtils {
                 einterfaceBuilder.build());
     }
 
+    public static BigInteger getDpnForInterface(OdlInterfaceRpcService interfaceManagerRpcService, String ifName) {
+        BigInteger nodeId = BigInteger.ZERO;
+        try {
+            GetDpidFromInterfaceInput dpIdInput = new GetDpidFromInterfaceInputBuilder().setIntfName(ifName).build();
+            Future<RpcResult<GetDpidFromInterfaceOutput>> dpIdOutput = interfaceManagerRpcService
+                    .getDpidFromInterface(dpIdInput);
+            RpcResult<GetDpidFromInterfaceOutput> dpIdResult = dpIdOutput.get();
+            if (dpIdResult.isSuccessful()) {
+                nodeId = dpIdResult.getResult().getDpid();
+            } else {
+                logger.error("Could not retrieve DPN Id for interface {}", ifName);
+            }
+        } catch (NullPointerException | InterruptedException | ExecutionException e) {
+            logger.error("Exception when getting dpn for interface {}", ifName, e);
+        }
+        return nodeId;
+    }
+
     public static void safeSleep() {
         try {
             Thread.yield();
index dcfaa7ec13a50331881640c70721d61fccd2c2ca..eac08a6b04bbc02269f50a574ce7ade0d878090e 100644 (file)
@@ -141,13 +141,15 @@ public class NetvirtVpnUtils {
         MdsalUtils.commitTransaction(tx);
     }
 
-    public static void createUpdateVpnInterface(String vpnName, String interfaceName, IpPrefix ifPrefix,
+    public static void createUpdateVpnInterface(String vpnName, String interfaceName, IpAddress primaryNextHop,
+            IpPrefix ifPrefix,
             String macAddress, boolean primary, IpPrefix gwIpAddress, String directSubnetId, WriteTransaction tx) {
         synchronized (interfaceName.intern()) {
             String ipAddress = null;
             String nextHopIp = null;
             if (primary) {
                 ipAddress = getAddressFromSubnet(ipPrefixToString(ifPrefix));
+                nextHopIp = ipAddressToString(primaryNextHop);
             } else {
                 ipAddress = ipPrefixToString(ifPrefix);
                 nextHopIp = getIpAddressFromPrefix(ipPrefixToString(gwIpAddress));
index 19751bb1a43374f47ab303313bbf2231ee77200a..102502656b6aeac904765b0e68fae8fb7eef2154 100644 (file)
@@ -263,7 +263,7 @@ public class UniQosManager extends UnimgrDataTreeChangeListener<BwpFlow> {
         if (uniToDpn.containsKey(uniId)) {
             dpId = uniToDpn.get(uniId);
         } else {
-            dpId = getDpnForInterface(odlInterfaceRpcService, logicalPortId);
+            dpId = NetvirtUtils.getDpnForInterface(odlInterfaceRpcService, logicalPortId);
             uniToDpn.put(uniId, dpId);
         }
         if (dpId.equals(BigInteger.ZERO)) {
@@ -317,23 +317,6 @@ public class UniQosManager extends UnimgrDataTreeChangeListener<BwpFlow> {
         return null;
     }
 
-    private static BigInteger getDpnForInterface(OdlInterfaceRpcService interfaceManagerRpcService, String ifName) {
-        BigInteger nodeId = BigInteger.ZERO;
-        try {
-            GetDpidFromInterfaceInput dpIdInput = new GetDpidFromInterfaceInputBuilder().setIntfName(ifName).build();
-            Future<RpcResult<GetDpidFromInterfaceOutput>> dpIdOutput = interfaceManagerRpcService
-                    .getDpidFromInterface(dpIdInput);
-            RpcResult<GetDpidFromInterfaceOutput> dpIdResult = dpIdOutput.get();
-            if (dpIdResult.isSuccessful()) {
-                nodeId = dpIdResult.getResult().getDpid();
-            } else {
-                Log.error("Could not retrieve DPN Id for interface {}", ifName);
-            }
-        } catch (NullPointerException | InterruptedException | ExecutionException e) {
-            Log.error("Exception when getting dpn for interface {}", ifName, e);
-        }
-        return nodeId;
-    }
 
     private static String getPhysicalPortForUni(DataBroker dataBroker, String uniId) {
         String nodeId = null;
index 51c330b0e351902165fb140b3959b25bfc7275b2..33c627bbe388b9cbfa50973fa9f5e396df26947d 100644 (file)
@@ -37,6 +37,7 @@
                <argument ref="uniPortManager" />
                <argument ref="subnetListener" />
                <argument ref="uniQosManager" />
+               <argument ref="odlInterfaceRpcService" />               
        </bean>
 
        <bean id="subnetListener" class="org.opendaylight.unimgr.mef.netvirt.SubnetListener">