VPNServiceChainHandler implements AutoCloseable { public void programScfToVpnPipeline(String vpnName, long scfTag, int servChainTag, long dpnId, int vpnPseudoLportTag, boolean isLastServiceChain, int addOrRemove) { LOG.info("L3VPN: Service Chaining programScfToVpnPipeline [Started]: Parameters Vpn Name: {} ", vpnName); String rd = VpnServiceChainUtils.getVpnRd(dataBroker, vpnName); if (rd == null || rd.isEmpty()) { LOG.warn("programScfToVpnPipeline: Could not find Router-distinguisher for VPN {}. No further actions", vpnName); return; } VpnInstanceOpDataEntry vpnInstance = getVpnInstance(rd); LOG.debug("programScfToVpnPipeline: rd={}, lportTag={} ", rd, vpnPseudoLportTag); if (vpnInstance != null) { if (addOrRemove == NwConstants.ADD_FLOW || addOrRemove == NwConstants.DEL_FLOW && isLastServiceChain) { Long vpnId = vpnInstance.getVpnId(); List<VpnToDpnList> vpnToDpnList = vpnInstance.getVpnToDpnList(); if (vpnToDpnList != null) { List<BigInteger> dpns = new ArrayList<>(); for (VpnToDpnList dpnInVpn : vpnToDpnList) { dpns.add(dpnInVpn.getDpnId()); } if (!dpns.contains(BigInteger.valueOf(dpnId))) { LOG.debug("Dpn {} is not included in the current VPN Footprint", dpnId); dpns.add(BigInteger.valueOf(dpnId)); } for (BigInteger dpn : dpns) { VpnServiceChainUtils.programLPortDispatcherFlowForScfToVpn(mdsalManager, vpnId, dpn, vpnPseudoLportTag, addOrRemove); } } else { LOG.debug("Could not find VpnToDpn list for VPN {} with rd {}", vpnName, rd); } } String intfName = VpnServiceChainUtils.buildVpnPseudoPortIfName(dpnId, scfTag, servChainTag, vpnPseudoLportTag); vpnFootprintService.updateVpnToDpnMapping(BigInteger.valueOf(dpnId), vpnName, rd, intfName, null, addOrRemove == NwConstants.ADD_FLOW); } LOG.info("L3VPN: Service Chaining programScfToVpnPipeline [End]"); } @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 testprogramScfToVpnPipelineNullRd() throws Exception { stubNoRdForVpnName(VPN_NAME); vpnsch.programScfToVpnPipeline(VPN_NAME, SCF_TAG, SERV_CHAIN_TAG, DPN_ID.longValue(), LPORT_TAG, false, NwConstants.ADD_FLOW); ArgumentCaptor<FlowEntity> argumentCaptor = ArgumentCaptor.forClass(FlowEntity.class); verify(mdsalMgr, times(0)).installFlow(argumentCaptor.capture()); List<FlowEntity> installedFlowsCaptured = argumentCaptor.getAllValues(); assert installedFlowsCaptured.isEmpty(); }
@Test public void testprogramScfToVpnPipelineNullVpnInstance() throws Exception { stubGetRouteDistinguisher(VPN_NAME, RD); stubNoVpnInstanceForRD(RD); vpnsch.programScfToVpnPipeline(VPN_NAME, SCF_TAG, SERV_CHAIN_TAG, DPN_ID.longValue(), LPORT_TAG, false, NwConstants.ADD_FLOW); ArgumentCaptor<FlowEntity> argumentCaptor = ArgumentCaptor.forClass(FlowEntity.class); verify(mdsalMgr, times(0)).installFlow(argumentCaptor.capture()); List<FlowEntity> installedFlowsCaptured = argumentCaptor.getAllValues(); assert installedFlowsCaptured.isEmpty(); }
@Test public void testprogramScfToVpnPipeline() throws Exception { stubGetRouteDistinguisher(VPN_NAME, RD); stubGetVpnInstance(RD, "1.2.3.4", "eth0"); 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("iface1")); vpnsch.programScfToVpnPipeline(VPN_NAME, SCF_TAG, SERV_CHAIN_TAG, DPN_ID.longValue(), LPORT_TAG, false, NwConstants.ADD_FLOW); ArgumentCaptor<Flow> argumentCaptor = ArgumentCaptor.forClass(Flow.class); verify(mdsalMgr, times(1)).installFlow((BigInteger)anyObject(), argumentCaptor.capture()); List<Flow> installedFlowsCaptured = argumentCaptor.getAllValues(); assert installedFlowsCaptured.size() == 1; Flow expectedLportDispatcherFlowEntity = VpnServiceChainUtils.buildLPortDispFromScfToL3VpnFlow(VPN_ID, DPN_ID, LPORT_TAG, NwConstants.ADD_FLOW); assert new FlowMatcher(expectedLportDispatcherFlowEntity).matches(installedFlowsCaptured.get(0)); String vpnPseudoPortIfaceName = VpnServiceChainUtils.buildVpnPseudoPortIfName(DPN_ID.longValue(), SCF_TAG, SERV_CHAIN_TAG, LPORT_TAG); verify(vpnFootprintService).updateVpnToDpnMapping(eq(DPN_ID), eq(VPN_NAME), eq(RD), eq(vpnPseudoPortIfaceName), eq(null), eq(Boolean.TRUE)); }