Moving TableIds into a single constants file
[vpnservice.git] / fibmanager / fibmanager-impl / src / main / java / org / opendaylight / vpnservice / fibmanager / FibManager.java
index ef2bec3acff24a147ec50d771e83ac85e7b49584..7adde2c47d7fb3d6dae78c6b9ba79bd96f774747 100644 (file)
@@ -18,6 +18,8 @@ import java.net.UnknownHostException;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.List;
+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.DataChangeListener;
@@ -48,17 +50,25 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.l3vpn.rev130911.prefix.to._
 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.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.params.xml.ns.yang.itm.rpcs.rev151217.ItmRpcService;
+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.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;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.fibmanager.rev150330.vrfentries.VrfEntry;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rev150331.TunnelTypeBase;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rev150331.TunnelTypeMplsOverGre;
+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.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rpcs.rev151003.GetTunnelTypeInputBuilder;
+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.yangtools.concepts.ListenerRegistration;
 import org.opendaylight.yangtools.yang.binding.DataObject;
 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;
 
@@ -72,17 +82,12 @@ public class FibManager extends AbstractDataChangeListener<VrfEntry> implements
   private NexthopManager nextHopManager;
   private ItmRpcService itmManager;
   private OdlInterfaceRpcService interfaceManager;
-
-  private static final short L3_FIB_TABLE = 21;
-  private static final short L3_LFIB_TABLE = 20;
-  private static final short L3_PROTOCOL_TABLE = 36;
-  private static final short L3_INTERFACE_TABLE = 80;
-  public static final short LPORT_DISPATCHER_TABLE = 30;
   private static final BigInteger COOKIE_VM_LFIB_TABLE = new BigInteger("8000002", 16);
   private static final BigInteger COOKIE_VM_FIB_TABLE =  new BigInteger("8000003", 16);
   private static final int DEFAULT_FIB_FLOW_PRIORITY = 10;
   private static final BigInteger METADATA_MASK_CLEAR = new BigInteger("000000FFFFFFFFFF", 16);
   private static final BigInteger CLEAR_METADATA = BigInteger.valueOf(0);
+  public static final BigInteger COOKIE_TUNNEL = new BigInteger("9000000", 16);
 
 
   private static final FutureCallback<Void> DEFAULT_CALLBACK =
@@ -201,9 +206,9 @@ public class FibManager extends AbstractDataChangeListener<VrfEntry> implements
     Preconditions.checkNotNull(vpnInstance.getVpnId(), "Vpn Instance with rd " + vpnInstance.getVrfId() + "has null vpnId!");
 
     Collection<VpnToDpnList> vpnToDpnList = vpnInstance.getVpnToDpnList();
+    BigInteger localDpnId = createLocalFibEntry(vpnInstance.getVpnId(),
+              vrfTableKey.getRouteDistinguisher(), vrfEntry);
     if (vpnToDpnList != null) {
-      BigInteger localDpnId = createLocalFibEntry(vpnInstance.getVpnId(),
-                          vrfTableKey.getRouteDistinguisher(), vrfEntry);
       for (VpnToDpnList curDpn : vpnToDpnList) {
         if (!curDpn.getDpnId().equals(localDpnId)) {
           createRemoteFibEntry(localDpnId, curDpn.getDpnId(), vpnInstance.getVpnId(),
@@ -255,31 +260,39 @@ public class FibManager extends AbstractDataChangeListener<VrfEntry> implements
   }
 
   public void createTerminatingServiceActions( BigInteger destDpId, int label, List<ActionInfo> actionsInfos) {
-    // FIXME
-/*      List<MatchInfo> mkMatches = new ArrayList<MatchInfo>();
+      List<MatchInfo> mkMatches = new ArrayList<MatchInfo>();
 
       LOG.info("create terminatingServiceAction on DpnId = {} and serviceId = {} and actions = {}", destDpId , label,actionsInfos);
 
       // Matching metadata
-      mkMatches.add(new MatchInfo(MatchFieldType.tunnel_id, new BigInteger[] {
-                                  MetaDataUtil.getTunnelIdWithValidVniBitAndVniSet(label),
-                                  MetaDataUtil.METADA_MASK_TUNNEL_ID }));
+      // FIXME vxlan vni bit set is not working properly with OVS.need to revisit
+      mkMatches.add(new MatchInfo(MatchFieldType.tunnel_id, new BigInteger[] {BigInteger.valueOf(label)}));
 
       List<InstructionInfo> mkInstructions = new ArrayList<InstructionInfo>();
       mkInstructions.add(new InstructionInfo(InstructionType.write_actions, actionsInfos));
 
-      FlowEntity terminatingServiceTableFlowEntity = MDSALUtil.buildFlowEntity(destDpId,ITMConstants.TERMINATING_SERVICE_TABLE,
-                      getFlowRef(destDpId, ITMConstants.TERMINATING_SERVICE_TABLE,label), 5, String.format("%s:%d","TST Flow Entry ",label),
-                      0, 0, ITMConstants.COOKIE_ITM.add(BigInteger.valueOf(label)),mkMatches, mkInstructions);
+      FlowEntity terminatingServiceTableFlowEntity = MDSALUtil.buildFlowEntity(destDpId, NwConstants.INTERNAL_TUNNEL_TABLE,
+                      getFlowRef(destDpId, NwConstants.INTERNAL_TUNNEL_TABLE,label), 5, String.format("%s:%d","TST Flow Entry ",label),
+                      0, 0, COOKIE_TUNNEL.add(BigInteger.valueOf(label)),mkMatches, mkInstructions);
 
-      mdsalManager.installFlow(terminatingServiceTableFlowEntity);*/
+      mdsalManager.installFlow(terminatingServiceTableFlowEntity);
  }
 
   private void removeTunnelTableEntry(BigInteger dpId, long label) {
-      // FIXME
-      // itmManager.removeTerminatingServiceAction(dpId, (int)label);
-
-      // LOG.debug("Terminating service Entry for dpID {} : label : {} removed successfully {}",dpId, label);
+    FlowEntity flowEntity;
+    LOG.info("remove terminatingServiceActions called with DpnId = {} and label = {}", dpId , label);
+    List<MatchInfo> mkMatches = new ArrayList<MatchInfo>();
+    // Matching metadata
+    mkMatches.add(new MatchInfo(MatchFieldType.tunnel_id, new BigInteger[] {
+        MetaDataUtil.getTunnelIdWithValidVniBitAndVniSet((int)label),
+        MetaDataUtil.METADA_MASK_TUNNEL_ID }));
+    flowEntity = MDSALUtil.buildFlowEntity(dpId,
+                                           NwConstants.INTERNAL_TUNNEL_TABLE,
+                                           getFlowRef(dpId, NwConstants.INTERNAL_TUNNEL_TABLE, (int)label),
+                                           5, String.format("%s:%d","TST Flow Entry ",label), 0, 0,
+                                           COOKIE_TUNNEL.add(BigInteger.valueOf(label)), mkMatches, null);
+    mdsalManager.removeFlow(flowEntity);
+    LOG.debug("Terminating service Entry for dpID {} : label : {} removed successfully {}",dpId, label);
   }
 
   public BigInteger deleteLocalFibEntry(Long vpnId, String rd, VrfEntry vrfEntry) {
@@ -317,13 +330,61 @@ public class FibManager extends AbstractDataChangeListener<VrfEntry> implements
         read(LogicalDatastoreType.OPERATIONAL, getPrefixToInterfaceIdentifier(vpnId, ipPrefix));
     return  localNextHopInfoData.isPresent() ? localNextHopInfoData.get() : null;
   }
+  
+
+  private Class<? extends TunnelTypeBase> getTunnelType(String ifName) {
+        try {
+            Future<RpcResult<GetTunnelTypeOutput>> result = interfaceManager.getTunnelType(
+                         new GetTunnelTypeInputBuilder().setIntfName(ifName).build());
+          RpcResult<GetTunnelTypeOutput> rpcResult = result.get();
+          if(!rpcResult.isSuccessful()) {
+              LOG.warn("RPC Call to getTunnelInterfaceId returned with Errors {}", rpcResult.getErrors());
+          } else {
+              return rpcResult.getResult().getTunnelType();
+          }
+         
+      } catch (InterruptedException | ExecutionException e) {
+          LOG.warn("Exception when getting tunnel interface Id for tunnel type {}", e);
+      }
+  
+  return null;
 
+  }
   private void createRemoteFibEntry(final BigInteger localDpnId, final BigInteger remoteDpnId,
                                     final long vpnId, final VrfTablesKey vrfTableKey,
                                     final VrfEntry vrfEntry) {
     String rd = vrfTableKey.getRouteDistinguisher();
     LOG.debug("adding route " + vrfEntry.getDestPrefix() + " " + rd);
-
+    /********************************************/
+    String tunnelInterface = resolveAdjacency(localDpnId, remoteDpnId, vpnId, vrfEntry);
+    if(tunnelInterface == null) {
+      LOG.error("Could not get interface for nexthop: {} in vpn {}",
+                                   vrfEntry.getNextHopAddress(), rd);
+      LOG.warn("Failed to add Route: {} in vpn: {}",
+                             vrfEntry.getDestPrefix(), rd);
+      return;
+    }
+      List<ActionInfo> actionInfos = new ArrayList<>();
+       Class<? extends TunnelTypeBase> tunnel_type = getTunnelType(tunnelInterface);
+    if (tunnel_type.equals(TunnelTypeMplsOverGre.class)) {
+        LOG.debug("Push label action for prefix {}", vrfEntry.getDestPrefix());
+        actionInfos.add(new ActionInfo(ActionType.push_mpls, new String[] { null }));
+        actionInfos.add(new ActionInfo(ActionType.set_field_mpls_label, new String[] { Long.toString(vrfEntry.getLabel())}));
+    } else {
+        int label = vrfEntry.getLabel().intValue();
+        BigInteger tunnelId;
+        // FIXME vxlan vni bit set is not working properly with OVS.need to revisit
+        if(tunnel_type.equals(TunnelTypeVxlan.class)) {
+               tunnelId = BigInteger.valueOf(label);
+        } else {
+               tunnelId = BigInteger.valueOf(label);
+        }
+        LOG.debug("adding set tunnel id action for label {}", label);
+        actionInfos.add(new ActionInfo(ActionType.set_field_tunnel_id, new BigInteger[]{
+                tunnelId}));
+    }
+    actionInfos.addAll(nextHopManager.getEgressActionsForInterface(tunnelInterface));
+/*
     List<ActionInfo> actionInfos = resolveAdjacency(localDpnId, remoteDpnId, vpnId, vrfEntry);
     if(actionInfos == null) {
       LOG.error("Could not get nexthop group id for nexthop: {} in vpn {}",
@@ -349,8 +410,8 @@ public class FibManager extends AbstractDataChangeListener<VrfEntry> implements
                 MetaDataUtil.getTunnelIdWithValidVniBitAndVniSet(label),
                 MetaDataUtil.METADA_MASK_VALID_TUNNEL_ID_BIT_AND_TUNNEL_ID }));
     }
-
-    makeConnectedRoute(remoteDpnId, vpnId, vrfEntry, rd, actionInfos, NwConstants.ADD_FLOW);
+**/
+      makeConnectedRoute(remoteDpnId, vpnId, vrfEntry, rd, actionInfos, NwConstants.ADD_FLOW);
     LOG.debug(
         "Successfully added fib entry for " + vrfEntry.getDestPrefix() + " vpnId " + vpnId);
   }
@@ -364,9 +425,9 @@ public class FibManager extends AbstractDataChangeListener<VrfEntry> implements
     VpnInstanceOpDataEntry vpnInstance = getVpnInstance(vrfTableKey.getRouteDistinguisher());
     Preconditions.checkNotNull(vpnInstance, "Vpn Instance not available!");
     Collection<VpnToDpnList> vpnToDpnList = vpnInstance.getVpnToDpnList();
+    BigInteger localDpnId = deleteLocalFibEntry(vpnInstance.getVpnId(),
+              vrfTableKey.getRouteDistinguisher(), vrfEntry);
     if (vpnToDpnList != null) {
-      BigInteger localDpnId = deleteLocalFibEntry(vpnInstance.getVpnId(),
-                          vrfTableKey.getRouteDistinguisher(), vrfEntry);
       for (VpnToDpnList curDpn : vpnToDpnList) {
         if (!curDpn.getDpnId().equals(localDpnId)) {
           deleteRemoteRoute(localDpnId, curDpn.getDpnId(), vpnInstance.getVpnId(), vrfTableKey, vrfEntry);
@@ -381,8 +442,8 @@ public class FibManager extends AbstractDataChangeListener<VrfEntry> implements
                                 final VrfEntry vrfEntry) {
     LOG.debug("deleting route "+ vrfEntry.getDestPrefix() + " "+vpnId);
     String rd = vrfTableKey.getRouteDistinguisher();
-    List<ActionInfo> actionInfos = resolveAdjacency(localDpnId, remoteDpnId, vpnId, vrfEntry);
-    if(actionInfos == null) {
+    String egressInterface = resolveAdjacency(localDpnId, remoteDpnId, vpnId, vrfEntry);
+    if(egressInterface == null) {
       LOG.error("Could not get nexthop group id for nexthop: {} in vpn {}",
                 vrfEntry.getNextHopAddress(), rd);
       LOG.warn("Failed to delete Route: {} in vpn: {}",
@@ -432,12 +493,12 @@ public class FibManager extends AbstractDataChangeListener<VrfEntry> implements
       instructions.add(new InstructionInfo(InstructionType.write_actions, actionInfos));
     }
 
-    String flowRef = getFlowRef(dpId, L3_FIB_TABLE, rd, destPrefix);
+    String flowRef = getFlowRef(dpId, NwConstants.L3_FIB_TABLE, rd, destPrefix);
 
     FlowEntity flowEntity;
 
     int priority = DEFAULT_FIB_FLOW_PRIORITY + prefixLength;
-    flowEntity = MDSALUtil.buildFlowEntity(dpId, L3_FIB_TABLE, flowRef,
+    flowEntity = MDSALUtil.buildFlowEntity(dpId, NwConstants.L3_FIB_TABLE, flowRef,
                                            priority, flowRef, 0, 0,
                                            COOKIE_VM_FIB_TABLE, matches, instructions);
 
@@ -471,10 +532,10 @@ public class FibManager extends AbstractDataChangeListener<VrfEntry> implements
     instructions.add(new InstructionInfo(InstructionType.write_actions, actionsInfos));
 
     // Install the flow entry in L3_LFIB_TABLE
-    String flowRef = getFlowRef(dpId, L3_LFIB_TABLE, label, nextHop);
+    String flowRef = getFlowRef(dpId, NwConstants.L3_LFIB_TABLE, label, nextHop);
 
     FlowEntity flowEntity;
-    flowEntity = MDSALUtil.buildFlowEntity(dpId, L3_LFIB_TABLE, flowRef,
+    flowEntity = MDSALUtil.buildFlowEntity(dpId, NwConstants.L3_LFIB_TABLE, flowRef,
                                            DEFAULT_FIB_FLOW_PRIORITY, flowRef, 0, 0,
                                            COOKIE_VM_LFIB_TABLE, matches, instructions);
 
@@ -552,9 +613,9 @@ public class FibManager extends AbstractDataChangeListener<VrfEntry> implements
         .append(destPrefix.getHostAddress()).toString();
   }
 
-  protected List<ActionInfo> resolveAdjacency(final BigInteger localDpnId, final BigInteger remoteDpnId,
+  protected String resolveAdjacency(final BigInteger localDpnId, final BigInteger remoteDpnId,
                                               final long vpnId, final VrfEntry vrfEntry) {
-    List<ActionInfo> adjacency = null;
+    String adjacency = null;
     LOG.trace("resolveAdjacency called with localdpid{} remotedpid {}, vpnId{}, VrfEntry {}", localDpnId, remoteDpnId, vpnId, vrfEntry);;
     try {
       adjacency =
@@ -588,13 +649,13 @@ public class FibManager extends AbstractDataChangeListener<VrfEntry> implements
         final BigInteger COOKIE_TABLE_MISS = new BigInteger("1030000", 16);
         // Instruction to goto L3 InterfaceTable
         List<InstructionInfo> instructions = new ArrayList<InstructionInfo>();
-        instructions.add(new InstructionInfo(InstructionType.goto_table, new long[] { L3_INTERFACE_TABLE }));
+        instructions.add(new InstructionInfo(InstructionType.goto_table, new long[] { NwConstants.L3_INTERFACE_TABLE }));
         List<MatchInfo> matches = new ArrayList<MatchInfo>();
-        FlowEntity flowEntityLfib = MDSALUtil.buildFlowEntity(dpnId, L3_LFIB_TABLE,
-                getFlowRef(dpnId, L3_LFIB_TABLE, NwConstants.TABLE_MISS_FLOW),
+        FlowEntity flowEntityLfib = MDSALUtil.buildFlowEntity(dpnId, NwConstants.L3_LFIB_TABLE,
+                getFlowRef(dpnId, NwConstants.L3_LFIB_TABLE, NwConstants.TABLE_MISS_FLOW),
                 NwConstants.TABLE_MISS_PRIORITY, "Table Miss", 0, 0, COOKIE_TABLE_MISS, matches, instructions);
 
-        FlowEntity flowEntityFib = MDSALUtil.buildFlowEntity(dpnId,L3_FIB_TABLE, getFlowRef(dpnId, L3_FIB_TABLE, NwConstants.TABLE_MISS_FLOW),
+        FlowEntity flowEntityFib = MDSALUtil.buildFlowEntity(dpnId,NwConstants.L3_FIB_TABLE, getFlowRef(dpnId, NwConstants.L3_FIB_TABLE, NwConstants.TABLE_MISS_FLOW),
                 NwConstants.TABLE_MISS_PRIORITY, "FIB Table Miss Flow", 0, 0, COOKIE_VM_FIB_TABLE,
                 matches, instructions);
 
@@ -623,13 +684,13 @@ public class FibManager extends AbstractDataChangeListener<VrfEntry> implements
     final BigInteger COOKIE_PROTOCOL_TABLE = new BigInteger("1070000", 16);
     // Instruction to goto L3 InterfaceTable
     List<InstructionInfo> instructions = new ArrayList<>();
-    instructions.add(new InstructionInfo(InstructionType.goto_table, new long[] {L3_LFIB_TABLE}));
+    instructions.add(new InstructionInfo(InstructionType.goto_table, new long[] {NwConstants.L3_LFIB_TABLE}));
     List<MatchInfo> matches = new ArrayList<MatchInfo>();
     matches.add(new MatchInfo(MatchFieldType.eth_type,
                               new long[] { 0x8847L }));
-    FlowEntity flowEntityToLfib = MDSALUtil.buildFlowEntity(dpnId, L3_PROTOCOL_TABLE,
-                                                          getFlowRef(dpnId, L3_PROTOCOL_TABLE,
-                                                                     L3_LFIB_TABLE),
+    FlowEntity flowEntityToLfib = MDSALUtil.buildFlowEntity(dpnId, NwConstants.L3_PROTOCOL_TABLE,
+                                                          getFlowRef(dpnId, NwConstants.L3_PROTOCOL_TABLE,
+                                                                  NwConstants.L3_LFIB_TABLE),
                                                           DEFAULT_FIB_FLOW_PRIORITY,
                                                           "Protocol Table For LFIB",
                                                           0, 0,
@@ -673,10 +734,10 @@ public class FibManager extends AbstractDataChangeListener<VrfEntry> implements
     instructions.add(new InstructionInfo(InstructionType.clear_actions));
     // Instruction to goto L3 InterfaceTable
 
-    instructions.add(new InstructionInfo(InstructionType.goto_table, new long[] { LPORT_DISPATCHER_TABLE }));
+    instructions.add(new InstructionInfo(InstructionType.goto_table, new long[] { NwConstants.LPORT_DISPATCHER_TABLE }));
 
-    FlowEntity flowEntityL3Intf = MDSALUtil.buildFlowEntity(dpnId, L3_INTERFACE_TABLE,
-            getFlowRef(dpnId, L3_INTERFACE_TABLE, NwConstants.TABLE_MISS_FLOW),
+    FlowEntity flowEntityL3Intf = MDSALUtil.buildFlowEntity(dpnId, NwConstants.L3_INTERFACE_TABLE,
+            getFlowRef(dpnId, NwConstants.L3_INTERFACE_TABLE, NwConstants.TABLE_MISS_FLOW),
             NwConstants.TABLE_MISS_PRIORITY, "L3 Interface Table Miss", 0, 0, COOKIE_TABLE_MISS, matches, instructions);
     if (addOrRemove == NwConstants.ADD_FLOW) {
       LOG.info("Invoking MDSAL to install L3 interface Table Miss Entries");