Fix lisp route for public interfaces
[groupbasedpolicy.git] / renderers / vpp / src / main / java / org / opendaylight / groupbasedpolicy / renderer / vpp / lisp / flat / overlay / StaticRoutingHelper.java
index e04950cb0005332af27203f061e662a7e18a3bec..9a590352fdb3d3973e351a2870fe81f5c9c68a9d 100644 (file)
@@ -8,7 +8,10 @@
 package org.opendaylight.groupbasedpolicy.renderer.vpp.lisp.flat.overlay;
 
 import com.google.common.base.Preconditions;
-import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+
+import java.util.Collections;
+import java.util.List;
+
 import org.opendaylight.groupbasedpolicy.renderer.vpp.lisp.info.container.HostRelatedInfoContainer;
 import org.opendaylight.groupbasedpolicy.renderer.vpp.lisp.info.container.states.PortInterfaces;
 import org.opendaylight.groupbasedpolicy.renderer.vpp.lisp.info.container.states.PortRouteState;
@@ -26,6 +29,8 @@ import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ipv4.unicas
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ipv4.unicast.routing.rev170917.routing.routing.instance.routing.protocols.routing.protocol._static.routes.ipv4.RouteBuilder;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ipv4.unicast.routing.rev170917.routing.routing.instance.routing.protocols.routing.protocol._static.routes.ipv4.RouteKey;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ipv4.unicast.routing.rev170917.routing.routing.instance.routing.protocols.routing.protocol._static.routes.ipv4.route.next.hop.options.SimpleNextHopBuilder;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ipv4.unicast.routing.rev170917.routing.routing.instance.routing.protocols.routing.protocol._static.routes.ipv4.route.next.hop.options.TableLookupBuilder;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ipv4.unicast.routing.rev170917.routing.routing.instance.routing.protocols.routing.protocol._static.routes.ipv4.route.next.hop.options.table.lookup.TableLookupParamsBuilder;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.routing.rev140524.Static;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.routing.rev140524.routing.routing.instance.routing.protocols.RoutingProtocol;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.routing.rev140524.routing.routing.instance.routing.protocols.RoutingProtocolBuilder;
@@ -41,20 +46,13 @@ import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import java.util.Arrays;
-import java.util.List;
-
-/**
- * Created by Shakib Ahmed on 5/4/17.
- */
-public class StaticRoutingHelper {
+class StaticRoutingHelper {
     private static final Logger LOG = LoggerFactory.getLogger(StaticRoutingHelper.class);
 
     private HostRelatedInfoContainer hostRelatedInfoContainer = HostRelatedInfoContainer.getInstance();
 
-    public synchronized boolean addRoutingProtocolForVrf(InstanceIdentifier<Node> nodeIid,
-                                                         long vrfId,
-                                                         VrfHolder vrfHolderOfHost) {
+    synchronized boolean addRoutingProtocolForVrf(InstanceIdentifier<Node> nodeIid, long vrfId,
+        VrfHolder vrfHolderOfHost) {
         String routingProtocolName = getRoutingProtocolName(vrfId);
         RoutingProtocolBuilder builder = new RoutingProtocolBuilder();
         builder.setKey(new RoutingProtocolKey(routingProtocolName));
@@ -80,12 +78,8 @@ public class StaticRoutingHelper {
         return false;
     }
 
-    public synchronized boolean addSingleStaticRouteInRoutingProtocol(String hostName,
-                                                                      long portVrfId,
-                                                                      String portSubnetUuid,
-                                                                      Ipv4Address nextHopAddress,
-                                                                      Ipv4Prefix ipPrefix,
-                                                                      String outgoingInterface) {
+    synchronized boolean addSingleStaticRouteInRoutingProtocol(String hostName, long portVrfId, String portSubnetUuid,
+        Ipv4Address nextHopAddress, Ipv4Prefix ipPrefix, String outgoingInterface, VniReference secondaryVrf) {
         RouteBuilder builder = new RouteBuilder();
 
         VrfState hostVrfStateForPortVrf = hostRelatedInfoContainer
@@ -95,6 +89,11 @@ public class StaticRoutingHelper {
         PortInterfaces hostPortInterfaces = hostRelatedInfoContainer
                                                     .getPortInterfaceStateOfHost(hostName);
 
+        if (!hostPortInterfaces.isRoutingContextForInterfaceInitialized(outgoingInterface)) {
+            hostRelatedInfoContainer.getPortInterfaceStateOfHost(hostName).
+                initializeRoutingContextForInterface(outgoingInterface, portVrfId);
+        }
+
         Preconditions.checkNotNull(hostVrfStateForPortVrf, "Vrf has not been initialized yet");
 
         long routeId = hostVrfStateForPortVrf.getNextRouteId();
@@ -102,12 +101,16 @@ public class StaticRoutingHelper {
         builder.setId(routeId);
         builder.setDestinationPrefix(ipPrefix);
         builder.setKey(new RouteKey(builder.getId()));
-        builder.setNextHopOptions(new SimpleNextHopBuilder()
-                                        .setNextHop(nextHopAddress)
-                                        .setOutgoingInterface(outgoingInterface)
-                                        .build());
 
-        List<Route> routes = Arrays.asList(builder.build());
+        if (secondaryVrf != null) {
+            builder.setNextHopOptions(new TableLookupBuilder().setTableLookupParams(
+                new TableLookupParamsBuilder().setSecondaryVrf(secondaryVrf).build()).build());
+        } else {
+            builder.setNextHopOptions(
+                new SimpleNextHopBuilder().setNextHop(nextHopAddress).setOutgoingInterface(outgoingInterface).build());
+        }
+
+        List<Route> routes = Collections.singletonList(builder.build());
 
         Ipv4 ipv4Route = new Ipv4Builder().setRoute(routes).build();
 
@@ -118,12 +121,14 @@ public class StaticRoutingHelper {
                 .child(Ipv4.class);
 
         RoutingProtocolKey routingProtocolKey = new RoutingProtocolKey(hostVrfStateForPortVrf.getProtocolName());
-        boolean routingProtocol = GbpNetconfTransaction.netconfSyncedMerge(VppIidFactory.getNetconfNodeIid(new NodeId(hostName)), VppIidFactory
-                .getRoutingInstanceIid(routingProtocolKey),
-                new RoutingProtocolBuilder().setKey(routingProtocolKey).setType(Static.class).build(), GbpNetconfTransaction.RETRY_COUNT);
-
-        if (routingProtocol && GbpNetconfTransaction.netconfSyncedMerge(VppIidFactory.getNetconfNodeIid(new NodeId(hostName)), iid,
-                ipv4Route, GbpNetconfTransaction.RETRY_COUNT)) {
+        boolean routingProtocol =
+            GbpNetconfTransaction.netconfSyncedMerge(VppIidFactory.getNetconfNodeIid(new NodeId(hostName)),
+                VppIidFactory.getRoutingInstanceIid(routingProtocolKey),
+                new RoutingProtocolBuilder().setKey(routingProtocolKey).setType(Static.class).build(),
+                GbpNetconfTransaction.RETRY_COUNT);
+
+        if (routingProtocol && GbpNetconfTransaction.netconfSyncedMerge(
+            VppIidFactory.getNetconfNodeIid(new NodeId(hostName)), iid, ipv4Route, GbpNetconfTransaction.RETRY_COUNT)) {
             hostVrfStateForPortVrf.addNewPortIpInVrf(portSubnetUuid, nextHopAddress);
             hostPortInterfaces.addRouteToPortInterface(outgoingInterface, portSubnetUuid, nextHopAddress, routeId);
             return true;
@@ -132,10 +137,8 @@ public class StaticRoutingHelper {
         return false;
     }
 
-    public synchronized boolean deleteSingleStaticRouteFromRoutingProtocol(String hostName,
-                                                                           long vrfId,
-                                                                           String outgoingInterfaceName,
-                                                                           Long routeId) {
+    synchronized boolean deleteSingleStaticRouteFromRoutingProtocol(String hostName, long vrfId,
+        String outgoingInterfaceName, Long routeId) {
         VrfState vrfState = hostRelatedInfoContainer.getVrfStateOfHost(hostName).getVrfState(vrfId);
 
         Preconditions.checkNotNull(vrfState, "Vrf has not been initialized");
@@ -155,20 +158,21 @@ public class StaticRoutingHelper {
         return true;
     }
 
-    public synchronized boolean deleteAllRoutesThroughInterface(DataBroker vppDataBroker,
-                                                                String hostName,
-                                                                String outgoingInterfaceName) {
+    synchronized void deleteAllRoutesThroughInterface(String hostName, String outgoingInterfaceName) {
         PortRouteState portRouteState = hostRelatedInfoContainer
                                             .getPortInterfaceStateOfHost(hostName)
                                             .getPortRouteState(outgoingInterfaceName);
 
         long vrfId = hostRelatedInfoContainer.getPortInterfaceStateOfHost(hostName)
                 .getInterfaceVrfId(outgoingInterfaceName);
+        if(vrfId == -1) {
+            LOG.error("VrfID was not resolved when removing routes from interface. hostname: {}, interface: {}",
+                hostName, outgoingInterfaceName);
+            return;
+        }
 
         List<Ipv4Address> ipThroughInterface = portRouteState.getAllIps();
 
-        boolean allOk = true;
-
         for (Ipv4Address ip : ipThroughInterface) {
             long routeId = portRouteState.getRouteIdOfIp(ip);
             String subnetUuidOfIp = portRouteState.getSubnetUuidOfIp(ip);
@@ -183,11 +187,9 @@ public class StaticRoutingHelper {
                         .removePortIpFromVrf(subnetUuidOfIp, ip);
             }
         }
-
-        return allOk;
     }
 
-    public static String getRoutingProtocolName(long vrf) {
+    private static String getRoutingProtocolName(long vrf) {
         return Constants.ROUTING_PROTOCOL_NAME_PREFIX + vrf;
     }
 }