+
+ protected Boolean isIpv4Address(String ipAddress) {
+ try {
+ InetAddress address = InetAddress.getByName(ipAddress);
+ if (address instanceof Inet4Address) {
+ return true;
+ }
+ } catch (UnknownHostException e) {
+ LOG.warn("Invalid ip address {}", ipAddress, e);
+ return false;
+ }
+ return false;
+ }
+
+ protected Boolean installRouterFibEntries(final VrfEntry vrfEntry, final Collection<VpnToDpnList> vpnToDpnList,
+ long vpnId, int addOrRemove) {
+ RouterInterface routerInt = vrfEntry.getAugmentation(RouterInterface.class);
+ if (routerInt != null && vpnToDpnList != null) {
+ String routerId = routerInt.getUuid();
+ String macAddress = routerInt.getMacAddress();
+ String ipValue = routerInt.getIpAddress();
+ LOG.trace("createFibEntries - Router augmented vrfentry found for for router uuid:{}, ip:{}, mac:{}",
+ routerId, ipValue, macAddress);
+ for (VpnToDpnList vpnDpn : vpnToDpnList) {
+ if (vpnDpn.getDpnState() == VpnToDpnList.DpnState.Active) {
+ installRouterFibEntry(vrfEntry, vpnDpn.getDpnId(), vpnId, routerId, ipValue,
+ new MacAddress(macAddress), addOrRemove);
+ }
+ }
+ return true;
+ }
+ return false;
+ }
+
+ public void installRouterFibEntry(final VrfEntry vrfEntry, BigInteger dpnId, long vpnId, String routerUuid,
+ String routerInternalIp, MacAddress routerMac, int addOrRemove) {
+ String[] subSplit = routerInternalIp.split("/");
+ if (!isIpv4Address(subSplit[0])) {
+ // Ping responder using OpenFlow rules is only supported for IPv4, hence skipping.
+ return;
+ }
+
+ String addRemoveStr = (addOrRemove == NwConstants.ADD_FLOW) ? "ADD_FLOW" : "DELETE_FLOW";
+ LOG.trace("{}: bulding Echo Flow entity for dpid:{}, router_ip:{}, vpnId:{}, subSplit:{} ", addRemoveStr,
+ dpnId, routerInternalIp, vpnId, subSplit[0]);
+
+ List<MatchInfo> matches = new ArrayList<>();
+
+ matches.add(MatchIpProtocol.ICMP);
+ matches.add(new MatchMetadata(MetaDataUtil.getVpnIdMetadata(vpnId), MetaDataUtil.METADATA_MASK_VRFID));
+ matches.add(new MatchIcmpv4((short) 8, (short) 0));
+ matches.add(MatchEthernetType.IPV4);
+ matches.add(new MatchIpv4Destination(subSplit[0], "32"));
+
+ List<ActionInfo> actionsInfos = new ArrayList<>();
+
+ // Set Eth Src and Eth Dst
+ actionsInfos.add(new ActionMoveSourceDestinationEth());
+ actionsInfos.add(new ActionSetFieldEthernetSource(routerMac));
+
+ // Move Ip Src to Ip Dst
+ actionsInfos.add(new ActionMoveSourceDestinationIp());
+ actionsInfos.add(new ActionSetSourceIp(subSplit[0], "32"));
+
+ // Set the ICMP type to 0 (echo reply)
+ actionsInfos.add(new ActionSetIcmpType((short) 0));
+
+ actionsInfos.add(new ActionNxLoadInPort(BigInteger.ZERO));
+
+ actionsInfos.add(new ActionNxResubmit(NwConstants.L3_FIB_TABLE));
+
+ List<InstructionInfo> instructions = new ArrayList<>();
+
+ instructions.add(new InstructionApplyActions(actionsInfos));
+
+ int priority = FibConstants.DEFAULT_FIB_FLOW_PRIORITY + FibConstants.DEFAULT_PREFIX_LENGTH;
+ String flowRef = getFlowRef(dpnId, NwConstants.L3_FIB_TABLE, vrfEntry.getLabel(), priority);
+
+ FlowEntity flowEntity = MDSALUtil.buildFlowEntity(dpnId, NwConstants.L3_FIB_TABLE, flowRef, priority, flowRef,
+ 0, 0, NwConstants.COOKIE_VM_FIB_TABLE, matches, instructions);
+
+ if (addOrRemove == NwConstants.ADD_FLOW) {
+ mdsalManager.installFlow(flowEntity);
+ } else {
+ mdsalManager.removeFlow(flowEntity);
+ }
+ }
+
+ public void removeInterVPNLinkRouteFlows(final String interVpnLinkName,
+ final boolean isVpnFirstEndPoint,
+ final VrfEntry vrfEntry)
+ {
+ Preconditions.checkArgument(vrfEntry.getNextHopAddressList() != null
+ && vrfEntry.getNextHopAddressList().size() == 1);
+ Optional<InterVpnLinkState> interVpnLinkState = FibUtil.getInterVpnLinkState(dataBroker, interVpnLinkName);
+
+ if ( !interVpnLinkState.isPresent()) {
+ LOG.warn("Could not find State for InterVpnLink {}", interVpnLinkName);
+ return;
+ }
+
+ List<BigInteger> targetDpns =
+ isVpnFirstEndPoint ? interVpnLinkState.get().getFirstEndpointState().getDpId()
+ : interVpnLinkState.get().getSecondEndpointState().getDpId();
+
+ String nextHop = vrfEntry.getNextHopAddressList().get(0);
+
+ // delete from FIB
+ //
+ String flowRef = getInterVpnFibFlowRef(interVpnLinkName, vrfEntry.getDestPrefix(), nextHop);
+ FlowKey flowKey = new FlowKey(new FlowId(flowRef));
+ Flow flow = new FlowBuilder().setKey(flowKey).setId(new FlowId(flowRef)).setTableId(NwConstants.L3_FIB_TABLE)
+ .setFlowName(flowRef).build();
+
+ LOG.trace("Removing flow in FIB table for interVpnLink {} key {}",
+ interVpnLinkName, flowRef);
+
+ for ( BigInteger dpId : targetDpns ) {
+ LOG.debug("Removing flow: VrfEntry=[prefix={} label={} nexthop={}] dpn {} for InterVpnLink {} in FIB",
+ vrfEntry.getDestPrefix(), vrfEntry.getLabel(), nextHop,
+ dpId, interVpnLinkName);
+
+ mdsalManager.removeFlow(dpId, flow);
+ }
+
+ // delete from LFIB
+ //
+ LOG.trace("Removing flow in FIB table for interVpnLink {}", interVpnLinkName);
+
+ WriteTransaction tx = dataBroker.newWriteOnlyTransaction();
+ for ( BigInteger dpId : targetDpns ) {
+ LOG.debug("Removing flow: VrfEntry=[prefix={} label={} nexthop={}] dpn {} for InterVpnLink {} in LFIB",
+ vrfEntry.getDestPrefix(), vrfEntry.getLabel(), nextHop,
+ dpId, interVpnLinkName);
+ makeLFibTableEntry(dpId, vrfEntry.getLabel(), null /* no instructions */,
+ LFIB_INTERVPN_PRIORITY, NwConstants.DEL_FLOW, tx);
+ }
+ tx.submit();
+ }