Thrift changes to support IPv6 calls over Quagga BGP stack
[netvirt.git] / vpnservice / vpnmanager / vpnmanager-impl / src / main / java / org / opendaylight / netvirt / vpnmanager / intervpnlink / InterVpnLinkUtil.java
index d80c3596fe06d869e7e4e34cd013d48acb193d8e..af8cf620b2f889e4d9b5b112c03d2cc9fb806e30 100755 (executable)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016 Ericsson India Global Services Pvt Ltd. and others. All rights reserved.
+ * Copyright (c) 2016, 2017 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,
@@ -10,11 +10,13 @@ package org.opendaylight.netvirt.vpnmanager.intervpnlink;
 import com.google.common.base.Optional;
 import com.google.common.base.Preconditions;
 import com.google.common.util.concurrent.ListenableFuture;
+
 import java.math.BigInteger;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
 import java.util.stream.Collectors;
+
 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
 import org.opendaylight.genius.mdsalutil.MDSALUtil;
@@ -25,6 +27,7 @@ import org.opendaylight.genius.mdsalutil.interfaces.IMdsalApiManager;
 import org.opendaylight.genius.mdsalutil.matches.MatchMetadata;
 import org.opendaylight.genius.utils.ServiceIndex;
 import org.opendaylight.netvirt.bgpmanager.api.IBgpManager;
+import org.opendaylight.netvirt.fibmanager.api.FibHelper;
 import org.opendaylight.netvirt.fibmanager.api.IFibManager;
 import org.opendaylight.netvirt.fibmanager.api.RouteOrigin;
 import org.opendaylight.netvirt.vpnmanager.VpnConstants;
@@ -33,14 +36,12 @@ import org.opendaylight.netvirt.vpnmanager.VpnUtil;
 import org.opendaylight.netvirt.vpnmanager.api.intervpnlink.InterVpnLinkCache;
 import org.opendaylight.netvirt.vpnmanager.api.intervpnlink.InterVpnLinkDataComposite;
 import org.opendaylight.netvirt.vpnmanager.utilities.InterfaceUtils;
-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.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.netvirt.fibmanager.rev150330.FibEntries;
 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;
 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.params.xml.ns.yang.netvirt.inter.vpn.link.rev160311.InterVpnLinkStates;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netvirt.inter.vpn.link.rev160311.InterVpnLinks;
@@ -130,19 +131,6 @@ public class InterVpnLinkUtil {
         vpnFootprintService.updateVpnToDpnMapping(dpnId, vpnName, ifaceName, false /* removal */);
     }
 
-    /**
-     * Retrieves the InterVpnLink object searching by its name.
-     *
-     * @param broker dataBroker service reference
-     * @param vpnLinkName Name of the InterVpnLink
-     * @return the InterVpnLink or Optional.absent() if there is no InterVpnLink with the specified name
-     */
-    public static Optional<InterVpnLink> getInterVpnLinkByName(DataBroker broker, String vpnLinkName) {
-        InstanceIdentifier<InterVpnLink> interVpnLinksIid =
-            InstanceIdentifier.builder(InterVpnLinks.class)
-                .child(InterVpnLink.class, new InterVpnLinkKey(vpnLinkName)).build();
-        return VpnUtil.read(broker, LogicalDatastoreType.CONFIGURATION, interVpnLinksIid);
-    }
 
     /**
      * Updates inter-VPN link state.
@@ -160,9 +148,9 @@ public class InterVpnLinkUtil {
         if (optOldVpnLinkState.isPresent()) {
             InterVpnLinkState newVpnLinkState =
                 new InterVpnLinkStateBuilder(optOldVpnLinkState.get()).setState(state)
-                    .setFirstEndpointState(newFirstEndpointState)
-                    .setSecondEndpointState(newSecondEndpointState)
-                    .build();
+                            .setFirstEndpointState(newFirstEndpointState)
+                            .setSecondEndpointState(newSecondEndpointState)
+                            .build();
             VpnUtil.syncUpdate(broker, LogicalDatastoreType.CONFIGURATION,
                 InterVpnLinkUtil.getInterVpnLinkStateIid(vpnLinkName), newVpnLinkState);
             InterVpnLinkCache.addInterVpnLinkStateToCaches(newVpnLinkState);
@@ -187,21 +175,24 @@ public class InterVpnLinkUtil {
      *
      * @param broker dataBroker service reference
      * @param mdsalManager MDSAL API accessor
-     * @param interVpnLink Object that holds the needed information about both endpoints of the InterVpnLink.
+     * @param interVpnLinkName Name of the InterVpnLink.
      * @param dpnList The list of DPNs where this flow must be installed
      * @param vpnUuidOtherEndpoint UUID of the other endpoint of the InterVpnLink
      * @param lportTagOfOtherEndpoint Dataplane identifier of the other endpoint of the InterVpnLink
      * @return the list of Futures for each and every flow that has been installed
      */
     public static List<ListenableFuture<Void>> installLPortDispatcherTableFlow(DataBroker broker,
-        IMdsalApiManager mdsalManager, InterVpnLink interVpnLink, List<BigInteger> dpnList, Uuid vpnUuidOtherEndpoint,
-        Long lportTagOfOtherEndpoint) {
+                                                                               IMdsalApiManager mdsalManager,
+                                                                               String interVpnLinkName,
+                                                                               List<BigInteger> dpnList,
+                                                                               String vpnUuidOtherEndpoint,
+                                                                               Long lportTagOfOtherEndpoint) {
         List<ListenableFuture<Void>> result = new ArrayList<>();
-        long vpnId = VpnUtil.getVpnId(broker, vpnUuidOtherEndpoint.getValue());
+        long vpnId = VpnUtil.getVpnId(broker, vpnUuidOtherEndpoint);
         for (BigInteger dpnId : dpnList) {
             // insert into LPortDispatcher table
-            Flow lportDispatcherFlow = buildLPortDispatcherFlow(interVpnLink.getName(), vpnId,
-                lportTagOfOtherEndpoint.intValue());
+            Flow lportDispatcherFlow = buildLPortDispatcherFlow(interVpnLinkName, vpnId,
+                                                                lportTagOfOtherEndpoint.intValue());
             result.add(mdsalManager.installFlow(dpnId, lportDispatcherFlow));
         }
 
@@ -224,11 +215,11 @@ public class InterVpnLinkUtil {
                                 ServiceIndex.getIndex(NwConstants.L3VPN_SERVICE_NAME, NwConstants.L3VPN_SERVICE_INDEX)),
                         MetaDataUtil.getMetaDataMaskForLPortDispatcher()));
         String flowRef = getLportDispatcherFlowRef(interVpnLinkName, lportTag);
-        Flow lportDispatcherFlow = MDSALUtil.buildFlowNew(NwConstants.LPORT_DISPATCHER_TABLE, flowRef,
-            VpnConstants.DEFAULT_LPORT_DISPATCHER_FLOW_PRIORITY, flowRef,
-            0, 0, VpnUtil.getCookieL3((int) vpnId), matches,
-            buildLportDispatcherTableInstructions(vpnId));
-        return lportDispatcherFlow;
+
+        return MDSALUtil.buildFlowNew(NwConstants.LPORT_DISPATCHER_TABLE, flowRef,
+                                      VpnConstants.DEFAULT_LPORT_DISPATCHER_FLOW_PRIORITY, flowRef,
+                                      0, 0, VpnUtil.getCookieL3((int) vpnId), matches,
+                                      buildLportDispatcherTableInstructions(vpnId));
     }
 
     /**
@@ -240,15 +231,11 @@ public class InterVpnLinkUtil {
      * @return the flow reference string
      */
     public static String getLportDispatcherFlowRef(String interVpnLinkName, Integer lportTag) {
-        return new StringBuffer()
-            .append(VpnConstants.FLOWID_PREFIX).append("INTERVPNLINK")
-            .append(NwConstants.FLOWID_SEPARATOR).append(interVpnLinkName)
-            .append(NwConstants.FLOWID_SEPARATOR).append(lportTag)
-            .append(NwConstants.FLOWID_SEPARATOR).append(ServiceIndex.getIndex(NwConstants.L3VPN_SERVICE_NAME,
-                NwConstants.L3VPN_SERVICE_INDEX))
-            .append(NwConstants.FLOWID_SEPARATOR)
-            .append(VpnConstants.DEFAULT_LPORT_DISPATCHER_FLOW_PRIORITY)
-            .toString();
+        return VpnConstants.FLOWID_PREFIX + "INTERVPNLINK" + NwConstants.FLOWID_SEPARATOR + interVpnLinkName
+             + NwConstants.FLOWID_SEPARATOR + lportTag
+             + NwConstants.FLOWID_SEPARATOR + ServiceIndex.getIndex(NwConstants.L3VPN_SERVICE_NAME,
+                                                                    NwConstants.L3VPN_SERVICE_INDEX)
+             + NwConstants.FLOWID_SEPARATOR + VpnConstants.DEFAULT_LPORT_DISPATCHER_FLOW_PRIORITY;
     }
 
 
@@ -291,62 +278,6 @@ public class InterVpnLinkUtil {
         return MDSALUtil.read(broker, LogicalDatastoreType.CONFIGURATION, getInterVpnLinkStateIid(interVpnLinkName));
     }
 
-    /**
-     * Checks if the specified InterVpnLink is currently Active.
-     *
-     * @param broker dataBroker service reference
-     * @param interVpnLinkName The name of the InterVpnLink
-     * @return true if the InterVpnLink is Active
-     */
-    public static boolean isInterVpnLinkActive(DataBroker broker, String interVpnLinkName) {
-        Optional<InterVpnLinkState> optIVpnLinkState = getInterVpnLinkState(broker, interVpnLinkName);
-        if (!optIVpnLinkState.isPresent()) {
-            return false;
-        }
-        InterVpnLinkState interVpnLinkState = optIVpnLinkState.get();
-        return interVpnLinkState.getState() == InterVpnLinkState.State.Active;
-    }
-
-    /**
-     * Retrieves an InterVpnLink by searching by one of its endpoint's IP.
-     *
-     * @param broker dataBroker service reference
-     * @param endpointIp IP to serch for.
-     * @return the InterVpnLink or null if no InterVpnLink can be found
-     */
-    public static Optional<InterVpnLink> getInterVpnLinkByEndpointIp(DataBroker broker, String endpointIp) {
-        List<InterVpnLink> allInterVpnLinks = InterVpnLinkUtil.getAllInterVpnLinks(broker);
-        for (InterVpnLink interVpnLink : allInterVpnLinks) {
-            if (interVpnLink.getFirstEndpoint().getIpAddress().getValue().equals(endpointIp)
-                || interVpnLink.getSecondEndpoint().getIpAddress().getValue().equals(endpointIp)) {
-                return Optional.of(interVpnLink);
-            }
-        }
-        return Optional.absent();
-    }
-
-
-    /**
-     * Retrieves the InterVpnLink that has one of its 2 endpoints installed in
-     * the specified DpnId.
-     *
-     * @param broker dataBroker service reference
-     * @param dpnId Id of the DPN
-     * @return The InterVpnLink object if found, Optional.absent() otherwise
-     */
-    public static Optional<InterVpnLink> getInterVpnLinkByDpnId(DataBroker broker, BigInteger dpnId) {
-        List<InterVpnLink> allInterVpnLinks = InterVpnLinkUtil.getAllInterVpnLinks(broker);
-        for (InterVpnLink interVpnLink : allInterVpnLinks) {
-            Optional<InterVpnLinkState> optInterVpnLinkState = getInterVpnLinkState(broker, interVpnLink.getName());
-            if (optInterVpnLinkState.isPresent()
-                && (optInterVpnLinkState.get().getFirstEndpointState().getDpId().contains(dpnId)
-                        || optInterVpnLinkState.get().getSecondEndpointState().getDpId().contains(dpnId))) {
-                return Optional.fromNullable(interVpnLink);
-            }
-        }
-        return Optional.absent();
-    }
-
     /**
      * Retrieves all configured InterVpnLinks.
      *
@@ -363,51 +294,6 @@ public class InterVpnLinkUtil {
             : new ArrayList<>();
     }
 
-    /**
-     * Retrieves the list of DPNs where the endpoint of a VPN in an InterVPNLink was instantiated.
-     *
-     * @param broker dataBroker service reference
-     * @param vpnLinkName the name of the InterVpnLink
-     * @param vpnUuid UUID of the VPN whose endpoint to be checked
-     * @return the list of DPN Ids
-     */
-    public static List<BigInteger> getVpnLinkEndpointDPNs(DataBroker broker, String vpnLinkName, String vpnUuid) {
-        Optional<InterVpnLinkState> interVpnLinkState = getInterVpnLinkState(broker, vpnLinkName);
-        if (interVpnLinkState.isPresent()) {
-            if (interVpnLinkState.get().getFirstEndpointState().getVpnUuid().getValue().equals(vpnUuid)) {
-                return interVpnLinkState.get().getFirstEndpointState().getDpId();
-            } else {
-                return interVpnLinkState.get().getSecondEndpointState().getDpId();
-            }
-        } else {
-            LOG.trace("Could not find InterVpnLinkState for interVpnLink {}", vpnLinkName);
-            return new ArrayList<>();
-        }
-    }
-
-    /**
-     * Retrieves the list of DPNs where the endpoint of a VPN in an InterVPNLink was instantiated.
-     *
-     * @param broker dataBroker service reference
-     * @param endpointIp Ip of the endpoint specified in the InterVpnLink
-     * @return the list of DPN Ids
-     */
-    public static List<BigInteger> getVpnLinkEndpointDPNsByIp(DataBroker broker, String endpointIp) {
-        Optional<InterVpnLink> optIVpnLink = getInterVpnLinkByEndpointIp(broker, endpointIp);
-        if (optIVpnLink.isPresent()) {
-            InterVpnLink interVpnLink = optIVpnLink.get();
-            boolean isFirstEndpoint = interVpnLink.getFirstEndpoint().getIpAddress().getValue().equals(endpointIp);
-            return isFirstEndpoint ? getVpnLinkEndpointDPNs(broker, interVpnLink.getName(),
-                interVpnLink.getFirstEndpoint().getVpnUuid().getValue())
-                : getVpnLinkEndpointDPNs(broker, interVpnLink.getName(),
-                interVpnLink.getSecondEndpoint().getVpnUuid().getValue());
-        } else {
-            LOG.trace("Could not find an InterVpnLink with endpoint IpAddr={}", endpointIp);
-            return new ArrayList<>();
-        }
-    }
-
-
     /**
      * Leaks a route from one VPN to another. By default, the origin for this leaked route is INTERVPN.
      *
@@ -460,10 +346,8 @@ public class InterVpnLinkUtil {
         String endpointIp = destinationIs1stEndpoint ? interVpnLink.getSecondEndpoint().getIpAddress().getValue()
             : interVpnLink.getFirstEndpoint().getIpAddress().getValue();
 
-        VrfEntry newVrfEntry = new VrfEntryBuilder().setKey(new VrfEntryKey(prefix)).setDestPrefix(prefix)
-            .setLabel(label).setNextHopAddressList(Collections.singletonList(endpointIp))
-            .setOrigin(RouteOrigin.INTERVPN.getValue())
-            .build();
+        VrfEntry newVrfEntry = FibHelper.getVrfEntryBuilder(prefix, label, endpointIp, RouteOrigin.INTERVPN,
+                null /* parentVpnRd */).build();
 
         String dstVpnRd = VpnUtil.getVpnRd(broker, dstVpnUuid);
         InstanceIdentifier<VrfEntry> newVrfEntryIid =
@@ -488,7 +372,9 @@ public class InterVpnLinkUtil {
             try {
                 LOG.debug("Advertising route in VPN={} [prefix={} label={}  nexthops={}] to DC-GW",
                     dstVpnRd, newVrfEntry.getDestPrefix(), label.intValue(), nexthops);
-                bgpManager.advertisePrefix(dstVpnRd, newVrfEntry.getDestPrefix(), nexthops, label.intValue());
+                bgpManager.advertisePrefix(dstVpnRd, null /*macAddress*/, newVrfEntry.getDestPrefix(), nexthops,
+                        VrfEntry.EncapType.Mplsgre, label.intValue(), 0 /*l3vni*/, 0 /*l2vni*/,
+                        null /*gatewayMacAddress*/);
             } catch (Exception exc) {
                 LOG.error("Could not advertise prefix {} with label {} to VPN rd={}",
                     newVrfEntry.getDestPrefix(), label.intValue(), dstVpnRd);
@@ -501,7 +387,7 @@ public class InterVpnLinkUtil {
 
     public static void handleStaticRoute(InterVpnLinkDataComposite interVpnLink, String vpnName,
         String destination, String nexthop, int label,
-        DataBroker dataBroker, IFibManager fibManager, IBgpManager bgpManager) {
+        DataBroker dataBroker, IFibManager fibManager, IBgpManager bgpManager) throws Exception {
 
         LOG.debug("handleStaticRoute [vpnLink={} srcVpn={} destination={} nextHop={} label={}]",
             interVpnLink.getInterVpnLinkName(), vpnName, destination, nexthop, label);
@@ -513,8 +399,9 @@ public class InterVpnLinkUtil {
         }
         LOG.debug("Writing FibEntry to DS:  vpnRd={}, prefix={}, label={}, nexthop={} (interVpnLink)",
             vpnRd, destination, label, nexthop);
-        fibManager.addOrUpdateFibEntry(dataBroker, vpnRd, destination, Collections.singletonList(nexthop), label,
-            RouteOrigin.STATIC, null);
+        fibManager.addOrUpdateFibEntry(dataBroker, vpnRd, null /*macAddress*/, destination,
+                Collections.singletonList(nexthop), VrfEntry.EncapType.Mplsgre, label,
+                0 /*l3vni*/, null /*gatewayMacAddress*/, null /*parentVpnRd*/, RouteOrigin.STATIC, null /*writeTxn*/);
 
         // Now advertise to BGP. The nexthop that must be advertised to BGP are the IPs of the DPN where the
         // VPN's endpoint have been instantiated
@@ -522,12 +409,11 @@ public class InterVpnLinkUtil {
         List<BigInteger> endpointDpns = interVpnLink.getEndpointDpnsByVpnName(vpnName);
         List<String> nexthopList =
             endpointDpns.stream().map(dpnId -> InterfaceUtils.getEndpointIpAddressForDPN(dataBroker, dpnId))
-                .collect(Collectors.toList());
+                        .collect(Collectors.toList());
         LOG.debug("advertising IVpnLink route to BGP:  vpnRd={}, prefix={}, label={}, nexthops={}",
             vpnRd, destination, label, nexthopList);
-        bgpManager.advertisePrefix(vpnRd, destination, nexthopList, label);
-
-        // TODO: Leak if static-routes-leaking flag is active
-
+        bgpManager.advertisePrefix(vpnRd, null /*macAddress*/, destination, nexthopList,
+                VrfEntry.EncapType.Mplsgre, label, 0 /*l3vni*/, 0 /*l2vni*/,
+                null /*gatewayMacAddress*/);
     }
 }