Bug 7031: Implement ping responder for router interfaces 34/45634/15
authorOlga <olga.schukin@hpe.com>
Sun, 4 Sep 2016 09:13:07 +0000 (12:13 +0300)
committerSam Hague <shague@redhat.com>
Tue, 25 Oct 2016 19:30:21 +0000 (19:30 +0000)
Trello task:
https://trello.com/c/z19VUYoU/151-ping-responder-for-router-interfaces-ipv4

Required for several tempest tests that ping the router interface.

This change depends on the following reviews:
[1] https://git.opendaylight.org/gerrit/45192
[2] https://git.opendaylight.org/gerrit/45632
[3] https://git.opendaylight.org/gerrit/46219

Change-Id: Iac9ad2d70fecba823630281142b632757c3a48c2
Signed-off-by: Olga <olga.schukin@hpe.com>
Signed-off-by: Olga Schukin <olga.schukin@hpe.com>
Author: Sam Hague <shague@redhat.com>
Signed-off-by: Sam Hague <shague@redhat.com>
vpnservice/fibmanager/fibmanager-api/src/main/java/org/opendaylight/netvirt/fibmanager/api/IFibManager.java
vpnservice/fibmanager/fibmanager-api/src/main/yang/odl-fib.yang
vpnservice/fibmanager/fibmanager-impl/src/main/java/org/opendaylight/netvirt/fibmanager/FibManagerImpl.java
vpnservice/fibmanager/fibmanager-impl/src/main/java/org/opendaylight/netvirt/fibmanager/VrfEntryListener.java
vpnservice/neutronvpn/neutronvpn-impl/src/main/java/org/opendaylight/netvirt/neutronvpn/NeutronPortChangeListener.java
vpnservice/neutronvpn/neutronvpn-impl/src/main/java/org/opendaylight/netvirt/neutronvpn/NeutronvpnManager.java
vpnservice/vpnmanager/vpnmanager-api/src/main/yang/l3vpn.yang
vpnservice/vpnmanager/vpnmanager-impl/src/main/java/org/opendaylight/netvirt/vpnmanager/VpnInterfaceManager.java

index 457b26ebae2a45ee39f98e79d2927d50591bbd72..f8c6b9d8e1b952f812c724e8005b2e86bb001c25 100644 (file)
@@ -11,7 +11,6 @@ package org.opendaylight.netvirt.fibmanager.api;
 import com.google.common.util.concurrent.FutureCallback;
 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
 import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
-
 import java.math.BigInteger;
 import java.util.List;
 
index 360a5c10fdc43a37bcebdfe89fe7b48701bcc539..ba4b56f9ebab596b91d7d7bc250b6584a3ef35f9 100644 (file)
@@ -43,6 +43,13 @@ module odl-fib {
             leaf elantag {type uint32;}
     }
 
+    augment "/odl-fib:fibEntries/odl-fib:vrfTables/odl-fib:vrfEntry" {
+        ext:augment-identifier "routerInterface";
+        leaf uuid {type string;}
+        leaf mac-address {type string;}
+        leaf ip-address {type string;}
+    }
+
     container fibEntries {
         config true;
         list vrfTables{
@@ -72,4 +79,4 @@ module odl-fib {
             leaf parent-vpn-rd { type string; }
          }
     }
-}
\ No newline at end of file
+}
index c16b2ace13f8fe972e3a2e8217c40cd40167890b..a1324f5f12cf5c919cadb67222ec8deec514e889 100644 (file)
@@ -22,6 +22,7 @@ import org.osgi.framework.BundleContext;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+
 public class FibManagerImpl implements IFibManager {
     private static final Logger LOG = LoggerFactory.getLogger(FibManagerImpl.class);
     private final NexthopManager nexthopManager;
@@ -156,4 +157,5 @@ public class FibManagerImpl implements IFibManager {
     public boolean isVPNConfigured() {
         return this.vpnmanager.isVPNConfigured();
     }
+
 }
index 234081684f8b6744a4fdbd2e441862baef399203..623fd5657f92ee27dca1e13afc33d180a4d897d1 100644 (file)
@@ -43,6 +43,7 @@ import org.opendaylight.genius.mdsalutil.MatchInfo;
 import org.opendaylight.genius.mdsalutil.MetaDataUtil;
 import org.opendaylight.genius.mdsalutil.NwConstants;
 import org.opendaylight.genius.mdsalutil.interfaces.IMdsalApiManager;
+import org.opendaylight.genius.mdsalutil.packet.IPProtocols;
 import org.opendaylight.genius.utils.ServiceIndex;
 import org.opendaylight.genius.utils.batching.ActionableResource;
 import org.opendaylight.genius.utils.batching.ActionableResourceImpl;
@@ -55,6 +56,7 @@ import org.opendaylight.netvirt.vpnmanager.api.IVpnManager;
 import org.opendaylight.netvirt.vpnmanager.api.intervpnlink.InterVpnLinkCache;
 import org.opendaylight.netvirt.vpnmanager.api.intervpnlink.InterVpnLinkDataComposite;
 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.interfaces.VpnInterface;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.MacAddress;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowId;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.Table;
@@ -77,6 +79,7 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.N
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.fibmanager.rev150330.FibEntries;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.fibmanager.rev150330.LabelRouteMap;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.fibmanager.rev150330.RouterInterface;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.fibmanager.rev150330.SubnetRoute;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.fibmanager.rev150330.fibentries.VrfTables;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.fibmanager.rev150330.fibentries.VrfTablesKey;
@@ -317,6 +320,10 @@ public class VrfEntryListener extends AsyncDataTreeChangeListenerBase<VrfEntry,
             }
             return;
         }
+        // ping responder for router interfaces
+        if (installRouterFibEntries(vrfEntry, vpnToDpnList, vpnId, NwConstants.ADD_FLOW)) {
+            return;
+        }
 
         if (RouteOrigin.value(vrfEntry.getOrigin()) == RouteOrigin.INTERVPN) {
             // When it is a leaked route, the LFIB and FIB goes a bit different.
@@ -1321,6 +1328,9 @@ public class VrfEntryListener extends AsyncDataTreeChangeListenerBase<VrfEntry,
             }
             return;
         }
+        if (installRouterFibEntries(vrfEntry, vpnToDpnList, vpnInstance.getVpnId(), NwConstants.DEL_FLOW)) {
+            return;
+        }
 
         final List<BigInteger> localDpnIdList = deleteLocalFibEntry(vpnInstance.getVpnId(),
                 vrfTableKey.getRouteDistinguisher(), vrfEntry);
@@ -1642,6 +1652,14 @@ public class VrfEntryListener extends AsyncDataTreeChangeListenerBase<VrfEntry,
                             installSubnetRouteInFib(dpnId, elanTag, rd, vpnId, vrfEntry, tx);
                             continue;
                         }
+                        RouterInterface routerInt = vrfEntry.getAugmentation(RouterInterface.class);
+                        if (routerInt != null) {
+                            LOG.trace( "Router augmented vrfentry found rd:{}, uuid:{}, ip:{}, mac:{}",
+                                    rd, routerInt.getUuid(), routerInt.getIpAddress(), routerInt.getMacAddress());
+                            installRouterFibEntry(vrfEntry, dpnId, vpnId, routerInt.getUuid(), routerInt.getIpAddress(),
+                                    new MacAddress(routerInt.getMacAddress()), NwConstants.ADD_FLOW);
+                            continue;
+                        }
                         if (RouteOrigin.value(vrfEntry.getOrigin()) == RouteOrigin.SELF_IMPORTED) { //Handle local flow creation for imports
                             LabelRouteInfo lri = getLabelRouteInfo(vrfEntry.getLabel());
                             if (lri != null && lri.getPrefix().equals(vrfEntry.getDestPrefix())
@@ -1823,6 +1841,15 @@ public class VrfEntryListener extends AsyncDataTreeChangeListenerBase<VrfEntry,
                                                 vrfEntry.getDestPrefix());
                                         continue;
                                     }
+                                    // ping responder for router interfaces
+                                    RouterInterface routerInt = vrfEntry.getAugmentation(RouterInterface.class);
+                                    if (routerInt != null) {
+                                        LOG.trace("Router augmented vrfentry found for rd:{}, uuid:{}, ip:{}, mac:{}",
+                                                rd, routerInt.getUuid(), routerInt.getIpAddress(), routerInt.getMacAddress());
+                                        installRouterFibEntry(vrfEntry, dpnId, vpnId, routerInt.getUuid(), routerInt.getIpAddress(),
+                                                new MacAddress(routerInt.getMacAddress()), NwConstants.DEL_FLOW);
+                                        continue;
+                                    }
                                     // Passing null as we don't know the dpn
                                     // to which prefix is attached at this point
                                     deleteRemoteRoute(null, dpnId, vpnId, vrfTable.get().getKey(), vrfEntry, tx);
@@ -2057,4 +2084,76 @@ public class VrfEntryListener extends AsyncDataTreeChangeListenerBase<VrfEntry,
                         child(VrfEntry.class, new VrfEntryKey(ipPrefix)).build();
         return vrfEntryId;
     }
+
+    protected Boolean installRouterFibEntries(final VrfEntry vrfEntry, final Collection<VpnToDpnList> vpnToDpnList,
+            long vpnId, int addOrRemove) {
+        RouterInterface routerInt = vrfEntry.getAugmentation(RouterInterface.class);
+        if (routerInt != null && vpnToDpnList != null) {
+            String routerId = routerInt.getUuid();
+            String macAddress = routerInt.getMacAddress();
+            String ipValue = routerInt.getIpAddress();
+            LOG.trace("createFibEntries - Router augmented vrfentry found for for router uuid:{}, ip:{}, mac:{}",
+                    routerId, ipValue, macAddress);
+            for (VpnToDpnList vpnDpn : vpnToDpnList) {
+                if (vpnDpn.getDpnState() == VpnToDpnList.DpnState.Active) {
+                    installRouterFibEntry(vrfEntry, vpnDpn.getDpnId(), vpnId, routerId, ipValue,
+                            new MacAddress(macAddress), addOrRemove);
+                }
+            }
+            return true;
+        }
+        return false;
+    }
+
+    public void installRouterFibEntry(final VrfEntry vrfEntry, BigInteger dpnId, long vpnId, String routerUuid,
+                                      String routerInternalIp, MacAddress routerMac, int addOrRemove) {
+        String[] subSplit = routerInternalIp.split("/");
+
+        String addRemoveStr = (addOrRemove == NwConstants.ADD_FLOW) ? "ADD_FLOW" : "DELETE_FLOW";
+        LOG.trace("{}: bulding Echo Flow entity for dpid:{}, router_ip:{}, vpnId:{}, subSplit:{} ", addRemoveStr,
+                dpnId, routerInternalIp, vpnId, subSplit[0]);
+
+        List<MatchInfo> matches = new ArrayList<>();
+
+        matches.add(new MatchInfo(MatchFieldType.ip_proto, new long[] { IPProtocols.ICMP.intValue() }));
+        matches.add(new MatchInfo(MatchFieldType.metadata,
+                new BigInteger[] { MetaDataUtil.getVpnIdMetadata(vpnId), MetaDataUtil.METADATA_MASK_VRFID }));
+        matches.add(new MatchInfo(MatchFieldType.icmp_v4, new long[] { (short) 8, (short) 0 }));
+        matches.add(new MatchInfo(MatchFieldType.eth_type, new long[] { NwConstants.ETHTYPE_IPV4 }));
+        matches.add(new MatchInfo(MatchFieldType.ipv4_destination, new String[] { subSplit[0], "32" }));
+
+        List<ActionInfo> actionsInfos = new ArrayList<>();
+
+        // Set Eth Src and Eth Dst
+        actionsInfos.add(new ActionInfo(ActionType.move_src_dst_eth, new String[] {}));
+        actionsInfos.add(new ActionInfo(ActionType.set_field_eth_src, new String[] { routerMac.getValue() }));
+
+        // Move Ip Src to Ip Dst
+        actionsInfos.add(new ActionInfo(ActionType.move_src_dst_ip, new String[] {}));
+        actionsInfos.add(new ActionInfo(ActionType.set_source_ip, new String[] { subSplit[0], "32" }));
+
+        // Set the ICMP type to 0 (echo reply)
+        actionsInfos.add(new ActionInfo(ActionType.set_icmp_type, new String[] { "0" }));
+
+        actionsInfos.add(new ActionInfo(ActionType.nx_load_in_port, new BigInteger[]{ BigInteger.ZERO }));
+
+        actionsInfos.add(new ActionInfo(ActionType.nx_resubmit,
+                new String[] { Short.toString(NwConstants.L3_FIB_TABLE) }));
+
+        List<InstructionInfo> instructions = new ArrayList<>();
+
+        instructions.add(new InstructionInfo(InstructionType.apply_actions, actionsInfos));
+
+        int priority = FibConstants.DEFAULT_FIB_FLOW_PRIORITY;
+        String flowRef = getFlowRef(dpnId, NwConstants.L3_FIB_TABLE, vrfEntry.getLabel(), priority);
+
+        FlowEntity flowEntity = MDSALUtil.buildFlowEntity(dpnId, NwConstants.L3_FIB_TABLE, flowRef, priority, flowRef,
+                0, 0, NwConstants.COOKIE_VM_FIB_TABLE, matches, instructions);
+
+        if (addOrRemove == NwConstants.ADD_FLOW) {
+            mdsalManager.installFlow(flowEntity);
+        } else {
+            mdsalManager.removeFlow(flowEntity);
+        }
+    }
 }
index fc6a9f183ffcd00b41d850e1eab331359b160f4a..31c9814f7efb4b3dfb88725a3f83048b266bd3d0 100644 (file)
@@ -296,8 +296,9 @@ public class NeutronPortChangeListener extends AsyncDataTreeChangeListenerBase<P
                         LOG.trace("NeutronPortChangeListener Add Subnet Gateway IP {} MAC {} Interface {} VPN {}",
                                 portIP.getIpAddress().getIpv4Address(),routerPort.getMacAddress(),
                                 routerPort.getUuid().getValue(), vpnId.getValue());
-                        NeutronvpnUtils.createVpnPortFixedIpToPort(dataBroker, vpnId.getValue(), ipValue, routerPort
-                                .getUuid().getValue(), routerPort.getMacAddress().getValue(), true, true, false);
+                        // ping responder for router interfaces
+                        nvpnManager.createVpnInterface(vpnId, routerId, routerPort, null);
+
                     } else {
                         LOG.info("Skip router port {} with the following address {}",
                                 routerPort.getUuid().getValue(), portIP.getIpAddress().getIpv6Address());
@@ -332,6 +333,8 @@ public class NeutronPortChangeListener extends AsyncDataTreeChangeListenerBase<P
                     nvpnNatManager.handleSubnetsForExternalRouter(routerId, dataBroker);
                     String ipValue = portIP.getIpAddress().getIpv4Address().getValue();
                     NeutronvpnUtils.removeVpnPortFixedIpToPort(dataBroker, vpnId.getValue(), ipValue);
+                    // ping responder for router interfaces
+                    nvpnManager.deleteVpnInterface(vpnId, routerId, routerPort, null);
                 } else {
                     LOG.info("Skip router port {} with the following address {}",
                             routerPort.getUuid().getValue(), portIP.getIpAddress().getIpv6Address());
index 112a0b784cb05b2aea3ec0055c9701a178f1e4a7..c9dd434830dcdfcfa5117a3443f8f76f2f0ad04e 100644 (file)
@@ -27,6 +27,7 @@ import org.opendaylight.genius.datastoreutils.DataStoreJobCoordinator;
 import org.opendaylight.genius.mdsalutil.MDSALUtil;
 import org.opendaylight.genius.mdsalutil.interfaces.IMdsalApiManager;
 import org.opendaylight.netvirt.elanmanager.api.IElanService;
+import org.opendaylight.netvirt.neutronvpn.api.utils.NeutronConstants;
 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.VpnInstances;
 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.VpnInterfaces;
 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.af.config.VpnTargets;
@@ -611,11 +612,16 @@ public class NeutronvpnManager implements NeutronvpnService, AutoCloseable, Even
         }
     }
 
-    protected void createVpnInterface(Uuid vpnId, Uuid routerId, Port port, WriteTransaction wrtConfigTxn) {
+    protected void createVpnInterface(Uuid vpnId, Uuid routerId, Port port,
+                                      WriteTransaction wrtConfigTxn) {
         String infName = port.getUuid().getValue();
         List<Adjacency> adjList = new ArrayList<>();
         List<FixedIps> ips = port.getFixedIps();
-
+        Boolean isRouterInterface = false;
+        if (port.getDeviceOwner() != null) {
+            isRouterInterface = port.getDeviceOwner().equals(NeutronConstants.DEVICE_OWNER_ROUTER_INF);
+        }
+        LOG.trace("createVpnInterface - isRouterInterface:{}", isRouterInterface);
         Router rtr = null;
         if (routerId != null) {
             rtr = NeutronvpnUtils.getNeutronRouter(dataBroker, routerId);
@@ -638,11 +644,11 @@ public class NeutronvpnManager implements NeutronvpnService, AutoCloseable, Even
             }
             String ipValue = ip.getIpAddress().getIpv4Address().getValue();
             NeutronvpnUtils.createVpnPortFixedIpToPort(dataBroker, vpnId.getValue(), ipValue, infName, port
-                            .getMacAddress().getValue(), false, true, false);
+                            .getMacAddress().getValue(), isRouterInterface, true, false);
         }
         // create vpn-interface on this neutron port
         Adjacencies adjs = new AdjacenciesBuilder().setAdjacency(adjList).build();
-        writeVpnInterfaceToDs(vpnId, infName, adjs, wrtConfigTxn);
+        writeVpnInterfaceToDs(vpnId, infName, adjs, isRouterInterface, wrtConfigTxn);
         if (routerId != null) {
             addToNeutronRouterInterfacesMap(routerId, infName);
         }
@@ -2149,11 +2155,11 @@ public class NeutronvpnManager implements NeutronvpnService, AutoCloseable, Even
     }
 
     private void createExternalVpnInterface(Uuid vpnId, String infName) {
-        writeVpnInterfaceToDs(vpnId, infName, null, null);
+        writeVpnInterfaceToDs(vpnId, infName, null, false /* not a router iface */, null);
     }
 
     private void writeVpnInterfaceToDs(Uuid vpnId, String infName, Adjacencies adjacencies,
-            WriteTransaction wrtConfigTxn) {
+            Boolean isRouterInterface, WriteTransaction wrtConfigTxn) {
         if (vpnId == null || infName == null) {
             LOG.debug("vpn id or interface is null");
             return;
@@ -2166,8 +2172,10 @@ public class NeutronvpnManager implements NeutronvpnService, AutoCloseable, Even
         }
 
         InstanceIdentifier<VpnInterface> vpnIfIdentifier = NeutronvpnUtils.buildVpnInterfaceIdentifier(infName);
-        VpnInterfaceBuilder vpnb = new VpnInterfaceBuilder().setKey(new VpnInterfaceKey(infName)).setName(infName)
-                .setVpnInstanceName(vpnId.getValue());
+        VpnInterfaceBuilder vpnb = new VpnInterfaceBuilder().setKey(new VpnInterfaceKey(infName))
+                .setName(infName)
+                .setVpnInstanceName(vpnId.getValue())
+                .setIsRouterInterface(isRouterInterface);
         if (adjacencies != null) {
             vpnb.addAugmentation(Adjacencies.class, adjacencies);
         }
index ffd8e00a2fac0ad3e0ce16f55be6ed946181611f..d5a0e0fd969b76a384943645f3414dc6e855b4ba 100644 (file)
@@ -790,6 +790,9 @@ module l3vpn {
       leaf scheduled-for-remove {
         type boolean;
       }
+      leaf is-router-interface {
+          type boolean;
+      }
     }
   }
 
index 717c11bb0d9a07a21f2801e8eae17abcf394e89a..541324577281d34bce23d6e2c7092d0803866ada 100644 (file)
@@ -96,6 +96,9 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.fibmanager.rev15033
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.fibmanager.rev150330.label.route.map.LabelRouteInfoKey;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.fibmanager.rev150330.vrfentries.VrfEntry;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.fibmanager.rev150330.vrfentries.VrfEntryBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.fibmanager.rev150330.vrfentries.VrfEntryKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.fibmanager.rev150330.RouterInterface;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.fibmanager.rev150330.RouterInterfaceBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.AddDpnEvent;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.AddDpnEventBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.Adjacencies;
@@ -231,6 +234,9 @@ public class VpnInterfaceManager extends AsyncDataTreeChangeListenerBase<VpnInte
                 LOG.error("Unable to retrieve dpnId from interface operational data store for interface {}. ", interfaceName, e);
                 return;
             }
+        } else if (vpnInterface.isIsRouterInterface()) {
+            createVpnInterfaceForRouter(vpnInterface, interfaceName);
+
         } else {
             LOG.error("Handling addition of VPN interface {} skipped as interfaceState is not available", interfaceName);
         }
@@ -1098,8 +1104,24 @@ public class VpnInterfaceManager extends AsyncDataTreeChangeListenerBase<VpnInte
                         }
                     });
 
-        }else{
-            LOG.warn("VPN interface {} was unavailable in operational data store to handle remove event", interfaceName);
+        } else if (vpnInterface.isIsRouterInterface()) {
+
+            List<Adjacency> adjsList = new ArrayList<>();
+            Adjacencies adjs = vpnInterface.getAugmentation(Adjacencies.class);
+            if (adjs != null) {
+                adjsList = adjs.getAdjacency();
+                for (Adjacency adj : adjsList) {
+                    if (adj.getMacAddress() != null && !adj.getMacAddress().isEmpty()) {
+                        String primaryInterfaceIp = adj.getIpAddress();
+                        String prefix = VpnUtil.getIpPrefix(primaryInterfaceIp);
+                        fibManager.removeFibEntry(dataBroker, vpnInterface.getVpnInstanceName(), prefix, null);
+                        return;
+                    }
+                }
+            }
+        } else {
+            LOG.warn("VPN interface {} was unavailable in operational data store to handle remove event",
+                    interfaceName);
         }
     }
 
@@ -1787,4 +1809,51 @@ public class VpnInterfaceManager extends AsyncDataTreeChangeListenerBase<VpnInte
             }
         }
     }
+
+    protected void createVpnInterfaceForRouter(VpnInterface vpnInterface, String interfaceName) {
+        if (vpnInterface == null) {
+            return;
+        }
+        String vpnName = vpnInterface.getVpnInstanceName();
+        String rd = getRouteDistinguisher(vpnName);
+        List<Adjacency> adjs = VpnUtil.getAdjacenciesForVpnInterfaceFromConfig(dataBroker, interfaceName);
+        if (adjs == null) {
+            LOG.info("VPN Interface {} of router addition failed as adjacencies for "
+                    + "this vpn interface could not be obtained", interfaceName);
+            return;
+        }
+        if (rd == null || rd.isEmpty()) {
+            rd = vpnName;
+        }
+        for (Adjacency adj : adjs) {
+            if (adj.getMacAddress() != null && !adj.getMacAddress().isEmpty()) {
+                String primaryInterfaceIp = adj.getIpAddress();
+                String macAddress = adj.getMacAddress();
+                String prefix = VpnUtil.getIpPrefix(primaryInterfaceIp);
+
+                long label = VpnUtil.getUniqueId(idManager, VpnConstants.VPN_IDPOOL_NAME,
+                        VpnUtil.getNextHopLabelKey((rd == null) ? vpnName : rd, prefix));
+
+                RouterInterface routerInt = new RouterInterfaceBuilder().setUuid(vpnName)
+                        .setMacAddress(macAddress).setIpAddress(primaryInterfaceIp).build();
+
+                VrfEntry vrfEntry = new VrfEntryBuilder().setKey(new VrfEntryKey(prefix)).setDestPrefix(prefix)
+                        .setNextHopAddressList(Arrays.asList(primaryInterfaceIp)).setLabel(label)
+                        .setOrigin(RouteOrigin.SELF_IMPORTED.getValue())
+                        .addAugmentation(RouterInterface.class, routerInt).build();
+
+                List<VrfEntry> vrfEntryList = Arrays.asList(vrfEntry);
+                InstanceIdentifierBuilder<VrfTables> idBuilder = InstanceIdentifier.builder(FibEntries.class)
+                        .child(VrfTables.class, new VrfTablesKey(rd));
+
+                InstanceIdentifier<VrfEntry> vrfEntryId = InstanceIdentifier.builder(FibEntries.class)
+                        .child(VrfTables.class, new VrfTablesKey(rd)).child(VrfEntry.class, new VrfEntryKey(prefix))
+                        .build();
+                VpnUtil.syncUpdate(dataBroker, LogicalDatastoreType.CONFIGURATION, vrfEntryId, vrfEntry);
+                return;
+            }
+        }
+        LOG.trace("VPN Interface {} of router addition failed as primary adjacency for"
+                + " this vpn interface could not be obtained", interfaceName);
+    }
 }