import org.opendaylight.genius.mdsalutil.actions.ActionPushVlan;
import org.opendaylight.genius.mdsalutil.actions.ActionRegLoad;
import org.opendaylight.genius.mdsalutil.actions.ActionSetFieldEthernetDestination;
+import org.opendaylight.genius.mdsalutil.actions.ActionSetFieldEthernetSource;
import org.opendaylight.genius.mdsalutil.actions.ActionSetFieldVlanVid;
import org.opendaylight.genius.mdsalutil.interfaces.IMdsalApiManager;
import org.opendaylight.netvirt.elanmanager.api.IElanService;
private final ItmRpcService itmManager;
private final IdManagerService idManager;
private final IElanService elanService;
- private static final short LPORT_INGRESS_TABLE = 0;
- private static final short LFIB_TABLE = 20;
- private static final short FIB_TABLE = 21;
- private static final short DEFAULT_FLOW_PRIORITY = 10;
private static final String NEXTHOP_ID_POOL_NAME = "nextHopPointerPool";
private static final long FIXED_DELAY_IN_MILLISECONDS = 4000;
private L3VPNTransportTypes configuredTransportTypeL3VPN = L3VPNTransportTypes.Invalid;
}
}
- protected List<ActionInfo> getEgressActionsForInterface(String ifName) {
- List<ActionInfo> listActionInfo = new ArrayList<>();
+ protected List<ActionInfo> getEgressActionsForInterface(final String ifName, int actionKey) {
+ List<ActionInfo> listActionInfo = new ArrayList<ActionInfo>();
try {
Future<RpcResult<GetEgressActionsForInterfaceOutput>> result =
interfaceManager.getEgressActionsForInterface(
List<org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.Action> actions =
rpcResult.getResult().getAction();
for (Action action : actions) {
+ actionKey = action.getKey().getOrder() + (actionKey++);
org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.Action
actionClass = action.getAction();
if (actionClass instanceof OutputActionCase) {
- listActionInfo.add(new ActionOutput(
+ listActionInfo.add(new ActionOutput(actionKey,
((OutputActionCase) actionClass).getOutputAction().getOutputNodeConnector()));
} else if (actionClass instanceof PushVlanActionCase) {
- listActionInfo.add(new ActionPushVlan());
+ listActionInfo.add(new ActionPushVlan(actionKey));
} else if (actionClass instanceof SetFieldCase) {
if (((SetFieldCase) actionClass).getSetField().getVlanMatch() != null) {
int vlanVid = ((SetFieldCase) actionClass).getSetField().getVlanMatch()
.getVlanId().getVlanId().getValue();
- listActionInfo.add(new ActionSetFieldVlanVid(vlanVid));
+ listActionInfo.add(new ActionSetFieldVlanVid(actionKey, vlanVid));
}
} else if (actionClass instanceof NxActionResubmitRpcAddGroupCase) {
Short tableId = ((NxActionResubmitRpcAddGroupCase) actionClass).getNxResubmit().getTable();
- listActionInfo.add(new ActionNxResubmit(action.getKey().getOrder() + 1, tableId));
+ listActionInfo.add(new ActionNxResubmit(actionKey, tableId));
} else if (actionClass instanceof NxActionRegLoadNodesNodeTableFlowApplyActionsCase) {
NxRegLoad nxRegLoad =
((NxActionRegLoadNodesNodeTableFlowApplyActionsCase) actionClass).getNxRegLoad();
- listActionInfo.add(new ActionRegLoad(action.getKey().getOrder() + 1, NxmNxReg6.class,
+ listActionInfo.add(new ActionRegLoad(actionKey, NxmNxReg6.class,
nxRegLoad.getDst().getStart(), nxRegLoad.getDst().getEnd(),
nxRegLoad.getValue().longValue()));
}
return null;
}
- public long createLocalNextHop(long vpnId, BigInteger dpnId,
- String ifName, String ipNextHopAddress, String ipPrefixAddress) {
+ public long createLocalNextHop(long vpnId, BigInteger dpnId, String ifName,
+ String ipNextHopAddress, String ipPrefixAddress, String gwMacAddress) {
String macAddress = FibUtil.getMacAddressFromPrefix(dataBroker, ifName, ipPrefixAddress);
String ipAddress = (macAddress != null) ? ipPrefixAddress : ipNextHopAddress;
}
List<BucketInfo> listBucketInfo = new ArrayList<>();
List<ActionInfo> listActionInfo = new ArrayList<>();
+ int actionKey = 0;
// MAC re-write
if (macAddress != null) {
- int actionKey = listActionInfo.size();
- listActionInfo.add(new ActionSetFieldEthernetDestination(actionKey, new MacAddress(macAddress)));
- //listActionInfo.add(0, new ActionPopMpls());
+ if (gwMacAddress != null) {
+ LOG.trace("The Local NextHop Group Source Mac {} for VpnInterface {} on VPN {}",
+ gwMacAddress, ifName, vpnId);
+ listActionInfo.add(
+ new ActionSetFieldEthernetSource(actionKey++, new MacAddress(gwMacAddress)));
+ }
+ listActionInfo.add(new ActionSetFieldEthernetDestination(actionKey++, new MacAddress(macAddress)));
+ // listActionInfo.add(0, new ActionPopMpls());
} else {
//FIXME: Log message here.
LOG.debug("mac address for new local nexthop is null");
}
- listActionInfo.addAll(getEgressActionsForInterface(ifName));
+ listActionInfo.addAll(getEgressActionsForInterface(ifName, actionKey));
BucketInfo bucket = new BucketInfo(listActionInfo);
listBucketInfo.add(bucket);
}
List<VpnInstanceOpDataEntry> vpnsToImportRoute = getVpnsImportingMyRoute(vpnName);
-
+ Optional<String> gwMac = Optional.absent();
LOG.trace("NextHops for interface {} are {}", interfaceName, nextHops);
for (Adjacency nextHop : nextHops) {
String prefix = VpnUtil.getIpPrefix(nextHop.getIpAddress());
final Uuid subnetId = nextHop.getSubnetId();
setupGwMacIfRequired(dpnId, vpnName, interfaceName, vpnId, subnetId,
writeInvTxn, NwConstants.ADD_FLOW);
- addArpResponderFlow(dpnId, lportTag, vpnName, vpnId, interfaceName, subnetId, writeInvTxn);
+ final Optional<String> gatewayIp = VpnUtil.getVpnSubnetGatewayIp(dataBroker, subnetId);
+ gwMac = getGatewayMacAddressForInterface(vpnName, interfaceName, gatewayIp.get());
+ addArpResponderFlow(dpnId, lportTag, vpnName, vpnId, interfaceName, subnetId,
+ gwMac.get(), gatewayIp.get(), writeInvTxn);
} else {
//Extra route adjacency
LOG.trace("Adding prefix {} and nextHopList {} as extra-route for vpn", nextHop.getIpAddress(),
if (rd != null) {
addToLabelMapper(label, dpnId, nextHop.getIpAddress(), nhList, vpnId,
interfaceName, null, false, rd, writeOperTxn);
- addPrefixToBGP(rd, nextHop.getIpAddress(), nhList, label, RouteOrigin.LOCAL, writeConfigTxn);
+ addPrefixToBGP(rd, nextHop.getIpAddress(), nhList, label, gwMac.isPresent() ? gwMac.get() : null,
+ RouteOrigin.LOCAL, writeConfigTxn);
//TODO: ERT - check for VPNs importing my route
for (VpnInstanceOpDataEntry vpn : vpnsToImportRoute) {
String vpnRd = vpn.getVrfId();
LOG.debug("Exporting route with rd {} prefix {} nexthop {} label {} to VPN {}", vpnRd,
nextHop.getIpAddress(), nextHopIp, label, vpn);
fibManager.addOrUpdateFibEntry(dataBroker, vpnRd, nextHop.getIpAddress(), nhList, (int) label,
- RouteOrigin.SELF_IMPORTED, writeConfigTxn);
+ gwMac.isPresent() ? gwMac.get() : null, RouteOrigin.SELF_IMPORTED, writeConfigTxn);
}
}
} else {
// ### add FIB route directly
fibManager.addOrUpdateFibEntry(dataBroker, vpnName, nextHop.getIpAddress(),
(nextHopIp == null ? Collections.emptyList() : Collections.singletonList(nextHopIp)),
- (int) label, RouteOrigin.LOCAL, writeConfigTxn);
+ (int) label, gwMac.isPresent() ? gwMac.get() : null, RouteOrigin.LOCAL, writeConfigTxn);
}
}
}
LOG.info("Updating label mapper : label {} dpn {} prefix {} nexthoplist {} vpnid {} rd {}", label,
srcDpnId, prefix, nhList, vpnId, rd);
updateLabelMapper(label, nhList);
-
+ Optional<String> gwMacAddr = getGatewayMacAddressForInterface(vpnInterface.getVpnInstanceName(),
+ vpnInterface.getName(),prefix);
// Update the VRF entry with nextHop
- fibManager.updateFibEntry(dataBroker, rd, prefix, nhList, null);
+ fibManager.updateFibEntry(dataBroker, rd, prefix, nhList,
+ gwMacAddr.isPresent() ? gwMacAddr.get() : null, null);
//Get the list of VPN's importing this route(prefix) .
// Then update the VRF entry with nhList
if (vpnRd != null) {
LOG.debug("Exporting route with rd {} prefix {} nhList {} label {} to VPN {}", vpnRd,
prefix, nhList, label, vpn);
- fibManager.updateFibEntry(dataBroker, vpnRd, prefix, nhList, null);
+ fibManager.updateFibEntry(dataBroker, vpnRd, prefix, nhList,
+ gwMacAddr.isPresent() ? gwMacAddr.get() : null, null);
}
}
// Advertise the prefix to BGP only for external vpn
// If nextHopList is already cleaned , no need to modify again
if ((nextHopList != null) & (!nextHopList.isEmpty())) {
isNextHopRemoveReqd = true;
+
value.add(new AdjacencyBuilder(adj).setNextHopIpList(nhList).build());
Adjacencies aug = VpnUtil.getVpnInterfaceAugmentation(value);
LOG.info("Updating label mapper : label {} dpn {} prefix {} nexthoplist {} vpnid {} rd {}", label,
srcDpnId, prefix, nhList, vpnId, rd);
updateLabelMapper(label, nhList);
-
+ Optional<String> gwMacAddr = getGatewayMacAddressForInterface(vpnInterface.getVpnInstanceName(),
+ vpnInterface.getName(),prefix);
// Update the VRF entry with emtpy nextHop
- fibManager.updateFibEntry(dataBroker, rd, prefix, new ArrayList<>() /* empty */, null);
+ fibManager.updateFibEntry(dataBroker, rd, prefix, new ArrayList<>()/* empty */,
+ gwMacAddr.isPresent() ? gwMacAddr.get() : null, null);
//Get the list of VPN's importing this route(prefix) .
// Then update the VRF entry with nhList
if (vpnRd != null) {
LOG.debug("Exporting route with rd {} prefix {} nhList {} label {} to VPN {}", vpnRd,
prefix, nhList, label, vpn);
- fibManager.updateFibEntry(dataBroker, vpnRd, prefix, nhList, null);
+ fibManager.updateFibEntry(dataBroker, vpnRd, prefix, nhList,
+ gwMacAddr.isPresent() ? gwMacAddr.get() : null, null);
}
}
String prefix = vrfEntry.getDestPrefix();
long label = vrfEntry.getLabel();
List<String> nextHops = vrfEntry.getNextHopAddressList();
+ String gwMac = vrfEntry.getGatewayMacAddress();
SubnetRoute route = vrfEntry.getAugmentation(SubnetRoute.class);
for (String nh : nextHops) {
if (route != null) {
vpnRd, prefix, nh, label, vpn.getVpnInstanceName());
importSubnetRouteForNewVpn(vpnRd, prefix, nh, (int) label, route, writeConfigTxn);
} else {
- LOG.info("Importing fib entry rd {} prefix {} nexthop {} label {} to vpn {}", vpnRd,
- prefix, nh, label, vpn.getVpnInstanceName());
+ LOG.info("Importing fib entry rd {} prefix {} nexthop {} label {} gwmac {} "
+ + "to vpn {}", vpnRd, prefix, nh, label, gwMac, vpn.getVpnInstanceName());
fibManager.addOrUpdateFibEntry(dataBroker, vpnRd, prefix, Collections.singletonList(nh),
- (int) label,
- RouteOrigin.SELF_IMPORTED, writeConfigTxn);
+ (int) label, gwMac, RouteOrigin.SELF_IMPORTED, writeConfigTxn);
}
}
} catch (Exception e) {
// TODO Clean up the exception handling
@SuppressWarnings("checkstyle:IllegalCatch")
- private void addPrefixToBGP(String rd, String prefix, List<String> nextHopList, long label, RouteOrigin origin,
- WriteTransaction writeConfigTxn) {
+ private void addPrefixToBGP(String rd, String prefix, List<String> nextHopList, long label, String gwMacAddress,
+ RouteOrigin origin, WriteTransaction writeConfigTxn) {
try {
- LOG.info("ADD: Adding Fib entry rd {} prefix {} nextHop {} label {}", rd, prefix, nextHopList, label);
- fibManager.addOrUpdateFibEntry(dataBroker, rd, prefix, nextHopList, (int)label, origin, writeConfigTxn);
- LOG.info("ADD: Added Fib entry rd {} prefix {} nextHop {} label {}", rd, prefix, nextHopList, label);
+ LOG.info("ADD: Adding Fib entry rd {} prefix {} nextHop {} label {} gwMac {}",
+ rd, prefix, nextHopList, label, gwMacAddress);
+ fibManager.addOrUpdateFibEntry(dataBroker, rd, prefix, nextHopList, (int)label,
+ gwMacAddress, origin, writeConfigTxn);
+ LOG.info("ADD: Added Fib entry rd {} prefix {} nextHop {} label {} gwMac {}",
+ rd, prefix, nextHopList, label, gwMacAddress);
// Advertize the prefix to BGP only if nexthop ip is available
if (nextHopList != null && !nextHopList.isEmpty()) {
bgpManager.advertisePrefix(rd, prefix, nextHopList, (int)label);
}
}
- private void addArpResponderFlow(final BigInteger dpId, final int lportTag, final String vpnName,
- final long vpnId, final String ifName, final Uuid subnetId,
- final WriteTransaction writeInvTxn) {
+ private void addArpResponderFlow(final BigInteger dpId, final int lportTag, final String vpnName,
+ final long vpnId, final String ifName, final Uuid subnetId,
+ final String subnetGwMac, final String gwIp, final WriteTransaction writeInvTxn) {
LOG.trace("Creating the ARP Responder flow for VPN Interface {}",ifName);
- final Optional<String> gatewayIp = VpnUtil.getVpnSubnetGatewayIp(dataBroker, subnetId);
- if (gatewayIp.isPresent()) {
- String gwIp = gatewayIp.get();
- LOG.trace("VPN Interface Adjacency Subnet Gateway IP {}", gwIp);
- VpnPortipToPort gwPort = VpnUtil.getNeutronPortFromVpnPortFixedIp(dataBroker, vpnName, gwIp);
- //Check if a router gateway interface is available for the subnet gw is so then use Router interface
- // else use connected interface
- final String subNetGwMac = (gwPort != null && gwPort.isSubnetIp())
- ? gwPort.getMacAddress() : InterfaceUtils.getMacAddressForInterface(dataBroker, ifName).get();
- LOG.debug("VPN Interface Subnet Gateway MAC for {} interface to be used for ARPResponder is {}",
- (gwPort != null && gwPort.isSubnetIp()) ? "Router" : "Connected", subNetGwMac);
- final String flowId = ArpResponderUtil.getFlowID(lportTag, gwIp);
- List<Action> actions = ArpResponderUtil.getActions(ifaceMgrRpcService, ifName, gwIp, subNetGwMac);
- ArpResponderUtil.installFlow(mdsalManager, writeInvTxn, dpId, flowId, flowId,
- NwConstants.DEFAULT_ARP_FLOW_PRIORITY, ArpResponderUtil.generateCookie(lportTag, gwIp),
- ArpResponderUtil.getMatchCriteria(lportTag, vpnId, gwIp),
- Collections.singletonList(MDSALUtil.buildApplyActionsInstruction(actions)));
- LOG.trace("Installed the ARP Responder flow for VPN Interface {}", ifName);
- }
+ final String flowId = ArpResponderUtil.getFlowID(lportTag, gwIp);
+ List<Action> actions = ArpResponderUtil.getActions(ifaceMgrRpcService, ifName, gwIp, subnetGwMac);
+ ArpResponderUtil.installFlow(mdsalManager, writeInvTxn, dpId, flowId, flowId,
+ NwConstants.DEFAULT_ARP_FLOW_PRIORITY, ArpResponderUtil.generateCookie(lportTag, gwIp),
+ ArpResponderUtil.getMatchCriteria(lportTag, vpnId, gwIp),
+ Collections.singletonList(MDSALUtil.buildApplyActionsInstruction(actions)));
+ LOG.trace("Installed the ARP Responder flow for VPN Interface {}", ifName);
+ }
+
+ private Optional<String> getGatewayMacAddressForInterface(String vpnName, String ifName, String ipAddress) {
+ Optional<String> routerGwMac = Optional.absent();
+ VpnPortipToPort gwPort = VpnUtil.getNeutronPortFromVpnPortFixedIp(dataBroker, vpnName, ipAddress);
+ //Check if a router gateway interface is available for the subnet gw is so then use Router interface
+ // else use connected interface
+ routerGwMac = Optional.of((gwPort != null && gwPort.isSubnetIp())
+ ? gwPort.getMacAddress() : InterfaceUtils.getMacAddressForInterface(dataBroker, ifName).get());
+ return routerGwMac;
}
private void removeArpResponderFlow(final BigInteger dpId, final int lportTag, final Uuid subnetUuid,
newLabel);
} else {
if (rd != null) {
- addPrefixToBGP(rd, destination, nextHopIpList, label, origin, writeConfigTxn);
+ addPrefixToBGP(rd, destination, nextHopIpList, label, null, origin, writeConfigTxn);
} else {
// ### add FIB route directly
- fibManager.addOrUpdateFibEntry(dataBroker, routerID, destination, nextHopIpList, label, origin,
- writeConfigTxn);
+ fibManager.addOrUpdateFibEntry(dataBroker, routerID, destination, nextHopIpList, label,
+ null /*gatewayMacAddress*/, origin, writeConfigTxn);
}
}
if (!writeOperTxnPresent) {