+ public BigInteger createLocalFibEntry(Long vpnId, String rd, VrfEntry vrfEntry) {
+ BigInteger localDpnId = BigInteger.ZERO;
+ Prefixes localNextHopInfo = getPrefixToInterface(vpnId, vrfEntry.getDestPrefix());
+ boolean staticRoute = false;
+
+ //If the vrf entry is a static/extra route, the nexthop of the entry would be a adjacency in the vpn
+ if(localNextHopInfo == null) {
+ localNextHopInfo = getPrefixToInterface(vpnId, vrfEntry.getNextHopAddress() + "/32");
+ staticRoute = true;
+ }
+
+ if(localNextHopInfo != null) {
+ localDpnId = localNextHopInfo.getDpnId();
+ long groupId = nextHopManager.createLocalNextHop(vpnId, localDpnId, localNextHopInfo.getVpnInterfaceName(),
+ (staticRoute == true) ? vrfEntry.getNextHopAddress() + "/32" : vrfEntry.getDestPrefix());
+ List<ActionInfo> actionInfos = new ArrayList<ActionInfo>();
+
+ actionInfos.add(new ActionInfo(ActionType.group, new String[] { String.valueOf(groupId)}));
+
+ makeConnectedRoute(localDpnId, vpnId, vrfEntry, rd, actionInfos, NwConstants.ADD_FLOW);
+ makeLFibTableEntry(localDpnId, vrfEntry.getLabel(), groupId, vrfEntry.getNextHopAddress(), NwConstants.ADD_FLOW);
+
+ LOG.debug("Installing tunnel table entry on dpn {} for interface {} with label {}",
+ localDpnId, localNextHopInfo.getVpnInterfaceName(), vrfEntry.getLabel());
+ makeTunnelTableEntry(localDpnId, vrfEntry.getLabel(), groupId);
+
+ }
+ return localDpnId;
+ }
+
+ private void makeTunnelTableEntry(BigInteger dpId, long label, long groupId/*String egressInterfaceName*/) {
+ List<ActionInfo> actionsInfos = new ArrayList<ActionInfo>();
+ actionsInfos.add(new ActionInfo(ActionType.group, new String[] { String.valueOf(groupId) }));
+
+
+ createTerminatingServiceActions(dpId, (int)label, actionsInfos);
+
+ LOG.debug("Terminating service Entry for dpID {} : label : {} egress : {} installed successfully {}",
+ dpId, label, groupId);
+ }
+
+ public void createTerminatingServiceActions( BigInteger destDpId, int label, List<ActionInfo> actionsInfos) {
+ List<MatchInfo> mkMatches = new ArrayList<MatchInfo>();
+
+ LOG.info("create terminatingServiceAction on DpnId = {} and serviceId = {} and actions = {}", destDpId , label,actionsInfos);
+
+ // Matching metadata
+ // 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, INTERNAL_TUNNEL_TABLE,
+ getFlowRef(destDpId, 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);
+ }
+
+ private void removeTunnelTableEntry(BigInteger dpId, long 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,
+ INTERNAL_TUNNEL_TABLE,
+ getFlowRef(dpId, 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) {
+ BigInteger localDpnId = BigInteger.ZERO;
+ VpnNexthop localNextHopInfo = nextHopManager.getVpnNexthop(vpnId, vrfEntry.getDestPrefix());
+ boolean staticRoute = false;
+
+ //If the vrf entry is a static/extra route, the nexthop of the entry would be a adjacency in the vpn
+ if(localNextHopInfo == null) {
+ localNextHopInfo = nextHopManager.getVpnNexthop(vpnId, vrfEntry.getNextHopAddress() + "/32");
+ staticRoute = true;
+ }
+
+ if(localNextHopInfo != null) {
+ localDpnId = localNextHopInfo.getDpnId();
+ if (getPrefixToInterface(vpnId, (staticRoute == true) ? vrfEntry.getNextHopAddress() + "/32" : vrfEntry.getDestPrefix()) == null) {
+ makeConnectedRoute(localDpnId, vpnId, vrfEntry, rd, null /* invalid */,
+ NwConstants.DEL_FLOW);
+ makeLFibTableEntry(localDpnId, vrfEntry.getLabel(), 0 /* invalid */,
+ vrfEntry.getNextHopAddress(), NwConstants.DEL_FLOW);
+ removeTunnelTableEntry(localDpnId, vrfEntry.getLabel());
+ deleteLocalAdjacency(localDpnId, vpnId, (staticRoute == true) ? vrfEntry.getNextHopAddress() + "/32" : vrfEntry.getDestPrefix());
+ }
+ }
+ return localDpnId;
+ }
+
+ private InstanceIdentifier<Prefixes> getPrefixToInterfaceIdentifier(Long vpnId, String ipPrefix) {
+ return InstanceIdentifier.builder(PrefixToInterface.class)
+ .child(VpnIds.class, new VpnIdsKey(vpnId)).child(Prefixes.class, new PrefixesKey(ipPrefix)).build();
+ }
+
+ private Prefixes getPrefixToInterface(Long vpnId, String ipPrefix) {
+ Optional<Prefixes> localNextHopInfoData =
+ 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) {