+ public BigInteger createLocalFibEntry(Long vpnId, String rd, VrfEntry vrfEntry) {
+ BigInteger localDpnId = BigInteger.ZERO;
+ Prefixes localNextHopInfo = getPrefixToInterface(vpnId, vrfEntry.getDestPrefix());
+ String localNextHopIP = vrfEntry.getDestPrefix();
+
+ if(localNextHopInfo == null) {
+ //Is this fib route an extra route? If yes, get the nexthop which would be an adjacency in the vpn
+ Extraroute extra_route = getVpnToExtraroute(rd, vrfEntry.getDestPrefix());
+ if (extra_route != null) {
+ localNextHopInfo = getPrefixToInterface(vpnId, extra_route.getNexthopIp() + "/32");
+ localNextHopIP = extra_route.getNexthopIp() + "/32";
+ }
+ }
+
+ if(localNextHopInfo != null) {
+ localDpnId = localNextHopInfo.getDpnId();
+ long groupId = nextHopManager.createLocalNextHop(vpnId, localDpnId, localNextHopInfo.getVpnInterfaceName(), localNextHopIP);
+ 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, 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);
+ }
+
+ 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[] {BigInteger.valueOf(label)}));
+ 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) {
+ BigInteger localDpnId = BigInteger.ZERO;
+ boolean isExtraRoute = false;
+ VpnNexthop localNextHopInfo = nextHopManager.getVpnNexthop(vpnId, vrfEntry.getDestPrefix());
+ String localNextHopIP = vrfEntry.getDestPrefix();
+
+ if(localNextHopInfo == null) {
+ //Is this fib route an extra route? If yes, get the nexthop which would be an adjacency in the vpn
+ Extraroute extra_route = getVpnToExtraroute(rd, vrfEntry.getDestPrefix());
+ if (extra_route != null) {
+ localNextHopInfo = nextHopManager.getVpnNexthop(vpnId, extra_route.getNexthopIp() + "/32");
+ localNextHopIP = extra_route.getNexthopIp() + "/32";
+ isExtraRoute = true;
+ }
+ }
+
+
+ if(localNextHopInfo != null) {
+ localDpnId = localNextHopInfo.getDpnId();
+ Prefixes prefix = getPrefixToInterface(vpnId, isExtraRoute ? localNextHopIP : vrfEntry.getDestPrefix());
+ 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, localNextHopIP);
+ }
+ 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 =
+ FibUtil.read(broker, LogicalDatastoreType.OPERATIONAL, getPrefixToInterfaceIdentifier(vpnId, ipPrefix));
+ return localNextHopInfoData.isPresent() ? localNextHopInfoData.get() : null;
+ }
+
+ private InstanceIdentifier<Extraroute> getVpnToExtrarouteIdentifier(String vrfId, String ipPrefix) {
+ return InstanceIdentifier.builder(VpnToExtraroute.class)
+ .child(Vpn.class, new VpnKey(vrfId)).child(Extraroute.class,
+ new ExtrarouteKey(ipPrefix)).build();
+ }
+
+ private Extraroute getVpnToExtraroute(String rd, String ipPrefix) {
+ Optional<Extraroute> extraRouteInfo =
+ FibUtil.read(broker, LogicalDatastoreType.OPERATIONAL, getVpnToExtrarouteIdentifier(rd, ipPrefix));
+ return extraRouteInfo.isPresent() ? extraRouteInfo.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) {