VPNServiceChainHandler implements AutoCloseable { public void programVpnToScfPipeline(String vpnName, short tableId, long scfTag, int lportTag, int addOrRemove) { LOG.info("programVpnToScfPipeline ({}) : Parameters VpnName:{} tableId:{} scftag:{} lportTag:{}", addOrRemove == NwConstants.ADD_FLOW ? "Creation" : "Removal", vpnName, tableId, scfTag, lportTag); String rd = VpnServiceChainUtils.getVpnRd(dataBroker, vpnName); LOG.debug("Router distinguisher (rd):{}", rd); if (rd == null || rd.isEmpty()) { LOG.warn("programVpnToScfPipeline: Could not find Router-distinguisher for VPN {}. No further actions", vpnName); return; } VpnInstanceOpDataEntry vpnInstance = getVpnInstance(rd); if (vpnInstance == null) { LOG.warn("Could not find a suitable VpnInstance for Route-Distinguisher={}", rd); return; } Collection<VpnToDpnList> vpnToDpnList = vpnInstance.getVpnToDpnList(); List<VrfEntry> vrfEntries = VpnServiceChainUtils.getAllVrfEntries(dataBroker, rd); if (vrfEntries != null) { if (addOrRemove == NwConstants.ADD_FLOW) { AddVpnPseudoPortDataJob updateVpnToPseudoPortTask = new AddVpnPseudoPortDataJob(dataBroker, rd, lportTag, tableId, (int) scfTag); jobCoordinator.enqueueJob(updateVpnToPseudoPortTask.getDsJobCoordinatorKey(), updateVpnToPseudoPortTask); } else { RemoveVpnPseudoPortDataJob removeVpnPseudoPortDataTask = new RemoveVpnPseudoPortDataJob(dataBroker, rd); jobCoordinator.enqueueJob(removeVpnPseudoPortDataTask.getDsJobCoordinatorKey(), removeVpnPseudoPortDataTask); } for (VpnToDpnList dpnInVpn : vpnToDpnList) { BigInteger dpnId = dpnInVpn.getDpnId(); programVpnToScfPipelineOnDpn(dpnId, vrfEntries, tableId, (int) scfTag, lportTag, addOrRemove); if (dpnInVpn.getVpnInterfaces() != null) { long vpnId = vpnInstance.getVpnId(); Flow flow = VpnServiceChainUtils.buildLPortDispFromScfToL3VpnFlow(vpnId, dpnId, lportTag, NwConstants.ADD_FLOW); if (addOrRemove == NwConstants.ADD_FLOW) { mdsalManager.installFlow(dpnId, flow); } else { mdsalManager.removeFlow(dpnId, flow); } dpnInVpn.getVpnInterfaces().forEach(vpnIf -> { if (addOrRemove == NwConstants.ADD_FLOW) { bindScfOnVpnInterface(vpnIf.getInterfaceName(), (int) scfTag); } else { unbindScfOnVpnInterface(vpnIf.getInterfaceName()); } }); } } } } @Inject  VPNServiceChainHandler(final DataBroker db, final IMdsalApiManager mdsalManager,
                                  final IVpnFootprintService vpnFootprintService, final IInterfaceManager ifaceMgr,
                                  final JobCoordinator jobCoordinator); @PostConstruct void init(); @Override @PreDestroy void close(); void programVpnToScfPipeline(String vpnName, short tableId, long scfTag, int lportTag, int addOrRemove); void programVpnToScfPipelineOnDpn(BigInteger dpnId, List<VrfEntry> vpnVrfEntries, short tableIdToGoTo,
                                             int scfTag, int lportTag, int addOrRemove); void programScfToVpnPipeline(String vpnName, long scfTag, int servChainTag, long dpnId,
                                        int vpnPseudoLportTag, boolean isLastServiceChain, int addOrRemove); void removeVpnPseudoPortFlows(String vpnInstanceName, int vpnPseudoLportTag); void bindScfOnVpnInterface(String ifName, int scfTag); void unbindScfOnVpnInterface(String ifName); Optional<VpnToPseudoPortData> getScfInfoForVpn(String vpnName);  }
@Test public void testProgramVpnToScfWithVpnIfacesAlreadyBound() throws Exception { String ifaceName = "eth0"; stubGetRouteDistinguisher(VPN_NAME, RD); stubGetVpnInstance(RD, "1.2.3.4", ifaceName); VrfEntry vrfEntry = FibHelper.getVrfEntryBuilder("11.12.13.14", 2000L, DC_GW_IP, RouteOrigin.STATIC, null) .build(); stubGetVrfEntries(RD, Collections.singletonList(vrfEntry)); stubReadVpnToDpnList(RD, DPN_ID, Collections.singletonList(ifaceName)); stubScfIsBoundOnIface(SCF_TAG, ifaceName); short tableId = 10; vpnsch.programVpnToScfPipeline(VPN_NAME, tableId, SCF_TAG, LPORT_TAG, NwConstants.ADD_FLOW); ArgumentCaptor<FlowEntity> argumentCaptor = ArgumentCaptor.forClass(FlowEntity.class); verify(mdsalMgr, times(2)).installFlow(argumentCaptor.capture()); List<FlowEntity> installedFlowsCaptured = argumentCaptor.getAllValues(); assert installedFlowsCaptured.size() == 2; RoutePaths routePath = vrfEntry.getRoutePaths().get(0); FlowEntity expectedLFibFlowEntity = VpnServiceChainUtils.buildLFibVpnPseudoPortFlow(DPN_ID, routePath.getLabel(), getEtherTypeFromIpPrefix(vrfEntry.getDestPrefix()), routePath.getNexthopAddress(), LPORT_TAG); assert new FlowEntityMatcher(expectedLFibFlowEntity).matches(installedFlowsCaptured.get(0)); FlowEntity expectedLPortDispatcher = VpnServiceChainUtils.buildLportFlowDispForVpnToScf(DPN_ID, LPORT_TAG, SCF_TAG, tableId); assert new FlowEntityMatcher(expectedLPortDispatcher).matches(installedFlowsCaptured.get(1)); }
@Test public void testProgramVpnToScfWithIfacesNotBound() throws Exception { String ifaceName = "eth0"; stubGetRouteDistinguisher(VPN_NAME, RD); stubGetVpnInstance(RD, "1.2.3.4", ifaceName); VrfEntry vrfEntry = FibHelper.getVrfEntryBuilder("11.12.13.14", 2000L, DC_GW_IP, RouteOrigin.STATIC, null) .build(); stubGetVrfEntries(RD, Collections.singletonList(vrfEntry)); stubReadVpnToDpnList(RD, DPN_ID, Collections.singletonList(ifaceName)); stubScfIsNotBoundOnIface(SCF_TAG, ifaceName); short tableId = 10; vpnsch.programVpnToScfPipeline(VPN_NAME, tableId, SCF_TAG, LPORT_TAG, NwConstants.ADD_FLOW); ArgumentCaptor<FlowEntity> argumentCaptor = ArgumentCaptor.forClass(FlowEntity.class); verify(ifaceMgr).bindService(eq(ifaceName), eq(ServiceModeIngress.class), anyObject()); verify(mdsalMgr, times(2)).installFlow(argumentCaptor.capture()); List<FlowEntity> installedFlowsCaptured = argumentCaptor.getAllValues(); assert installedFlowsCaptured.size() == 2; RoutePaths routePath = vrfEntry.getRoutePaths().get(0); FlowEntity expectedLFibFlowEntity = VpnServiceChainUtils.buildLFibVpnPseudoPortFlow(DPN_ID, routePath.getLabel(), getEtherTypeFromIpPrefix(vrfEntry.getDestPrefix()), routePath.getNexthopAddress(), LPORT_TAG); assert new FlowEntityMatcher(expectedLFibFlowEntity).matches(installedFlowsCaptured.get(0)); FlowEntity expectedLPortDispatcher = VpnServiceChainUtils.buildLportFlowDispForVpnToScf(DPN_ID, LPORT_TAG, SCF_TAG, tableId); assert new FlowEntityMatcher(expectedLPortDispatcher).matches(installedFlowsCaptured.get(1)); }