use of org.opendaylight.genius.mdsalutil.ActionInfo in project netvirt by opendaylight.
the class NexthopManager method createLocalNextHop.
public long createLocalNextHop(long vpnId, BigInteger dpnId, String ifName, String ipNextHopAddress, String ipPrefixAddress, String gwMacAddress, String jobKey) {
String vpnName = fibUtil.getVpnNameFromId(vpnId);
if (vpnName == null) {
return 0;
}
String macAddress = fibUtil.getMacAddressFromPrefix(ifName, vpnName, ipPrefixAddress);
String ipAddress = macAddress != null ? ipPrefixAddress : ipNextHopAddress;
long groupId = createNextHopPointer(getNextHopKey(vpnId, ipAddress));
if (groupId == 0) {
LOG.error("Unable to allocate groupId for vpnId {} , prefix {} IntfName {}, nextHopAddr {}", vpnId, ipAddress, ifName, ipNextHopAddress);
return groupId;
}
String nextHopLockStr = vpnId + ipAddress;
jobCoordinator.enqueueJob(jobKey, () -> {
synchronized (nextHopLockStr.intern()) {
VpnNexthop nexthop = getVpnNexthop(vpnId, ipAddress);
LOG.trace("nexthop: {} retrieved for vpnId {}, prefix {}, ifName {} on dpn {}", nexthop, vpnId, ipAddress, ifName, dpnId);
if (nexthop == null) {
String encMacAddress = macAddress == null ? fibUtil.getMacAddressFromPrefix(ifName, vpnName, ipAddress) : macAddress;
List<BucketInfo> listBucketInfo = new ArrayList<>();
List<ActionInfo> listActionInfo = new ArrayList<>();
int actionKey = 0;
// MAC re-write
if (encMacAddress != null) {
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(encMacAddress)));
// listActionInfo.add(0, new ActionPopMpls());
} else {
// FIXME: Log message here.
LOG.debug("mac address for new local nexthop is null");
}
listActionInfo.addAll(getEgressActionsForInterface(ifName, actionKey));
BucketInfo bucket = new BucketInfo(listActionInfo);
listBucketInfo.add(bucket);
GroupEntity groupEntity = MDSALUtil.buildGroupEntity(dpnId, groupId, ipAddress, GroupTypes.GroupAll, listBucketInfo);
LOG.trace("Install LNH Group: id {}, mac address {}, interface {} for prefix {}", groupId, encMacAddress, ifName, ipAddress);
// Try to install group directly on the DPN bypassing the FRM, in order to avoid waiting for the
// group to get installed before programming the flows
installGroupOnDpn(groupId, dpnId, ipAddress, listBucketInfo, getNextHopKey(vpnId, ipAddress), GroupTypes.GroupAll);
// install Group
mdsalApiManager.syncInstallGroup(groupEntity);
// update MD-SAL DS
addVpnNexthopToDS(dpnId, vpnId, ipAddress, groupId);
} else {
// nexthop exists already; a new flow is going to point to
// it, increment the flowrefCount by 1
int flowrefCnt = nexthop.getFlowrefCount() + 1;
VpnNexthop nh = new VpnNexthopBuilder().setKey(new VpnNexthopKey(ipAddress)).setFlowrefCount(flowrefCnt).build();
LOG.trace("Updating vpnnextHop {} for refCount {} to Operational DS", nh, flowrefCnt);
MDSALUtil.syncUpdate(dataBroker, LogicalDatastoreType.OPERATIONAL, getVpnNextHopIdentifier(vpnId, ipAddress), nh);
}
}
return Collections.emptyList();
});
return groupId;
}
use of org.opendaylight.genius.mdsalutil.ActionInfo in project netvirt by opendaylight.
the class VrfEntryListener method installSubnetBroadcastAddrDropRule.
private void installSubnetBroadcastAddrDropRule(final BigInteger dpnId, final String rd, final long vpnId, final VrfEntry vrfEntry, int addOrRemove, WriteTransaction tx) {
List<MatchInfo> matches = new ArrayList<>();
LOG.debug("SUBNETROUTE: installSubnetBroadcastAddrDropRule: destPrefix {} rd {} vpnId {} dpnId {}", vrfEntry.getDestPrefix(), rd, vpnId, dpnId);
String[] ipAddress = vrfEntry.getDestPrefix().split("/");
String subnetBroadcastAddr = FibUtil.getBroadcastAddressFromCidr(vrfEntry.getDestPrefix());
final int prefixLength = ipAddress.length == 1 ? 0 : Integer.parseInt(ipAddress[1]);
InetAddress destPrefix;
try {
destPrefix = InetAddress.getByName(subnetBroadcastAddr);
} catch (UnknownHostException e) {
LOG.error("Failed to get destPrefix for prefix {} rd {} VpnId {} DPN {}", vrfEntry.getDestPrefix(), rd, vpnId, dpnId, e);
return;
}
// Match on VpnId and SubnetBroadCast IP address
matches.add(new MatchMetadata(MetaDataUtil.getVpnIdMetadata(vpnId), MetaDataUtil.METADATA_MASK_VRFID));
matches.add(MatchEthernetType.IPV4);
if (prefixLength != 0) {
matches.add(new MatchIpv4Destination(subnetBroadcastAddr, Integer.toString(IPV4_ADDR_PREFIX_LENGTH)));
}
// Action is to drop the packet
List<InstructionInfo> dropInstructions = new ArrayList<>();
List<ActionInfo> actionsInfos = new ArrayList<>();
actionsInfos.add(new ActionDrop());
dropInstructions.add(new InstructionApplyActions(actionsInfos));
int priority = DEFAULT_FIB_FLOW_PRIORITY + IPV4_ADDR_PREFIX_LENGTH;
String flowRef = FibUtil.getFlowRef(dpnId, NwConstants.L3_SUBNET_ROUTE_TABLE, rd, priority, destPrefix);
FlowEntity flowEntity = MDSALUtil.buildFlowEntity(dpnId, NwConstants.L3_SUBNET_ROUTE_TABLE, flowRef, priority, flowRef, 0, 0, COOKIE_TABLE_MISS, matches, dropInstructions);
Flow flow = flowEntity.getFlowBuilder().build();
String flowId = flowEntity.getFlowId();
FlowKey flowKey = new FlowKey(new FlowId(flowId));
Node nodeDpn = FibUtil.buildDpnNode(dpnId);
InstanceIdentifier<Flow> flowInstanceId = InstanceIdentifier.builder(Nodes.class).child(Node.class, nodeDpn.getKey()).augmentation(FlowCapableNode.class).child(Table.class, new TableKey(flow.getTableId())).child(Flow.class, flowKey).build();
if (addOrRemove == NwConstants.ADD_FLOW) {
tx.put(LogicalDatastoreType.CONFIGURATION, flowInstanceId, flow, true);
} else {
tx.delete(LogicalDatastoreType.CONFIGURATION, flowInstanceId);
}
}
use of org.opendaylight.genius.mdsalutil.ActionInfo in project netvirt by opendaylight.
the class VrfEntryListener method createRemoteFibEntry.
private void createRemoteFibEntry(final BigInteger remoteDpnId, final long vpnId, String rd, final VrfEntry vrfEntry, WriteTransaction tx) {
Boolean wrTxPresent = true;
if (tx == null) {
wrTxPresent = false;
tx = dataBroker.newWriteOnlyTransaction();
}
String vpnName = fibUtil.getVpnNameFromId(vpnId);
LOG.debug("createremotefibentry: adding route {} for rd {} on remoteDpnId {}", vrfEntry.getDestPrefix(), rd, remoteDpnId);
List<AdjacencyResult> adjacencyResults = baseVrfEntryHandler.resolveAdjacency(remoteDpnId, vpnId, vrfEntry, rd);
if (adjacencyResults.isEmpty()) {
LOG.error("Could not get interface for route-paths: {} in vpn {} on DPN {}", vrfEntry.getRoutePaths(), rd, remoteDpnId);
LOG.error("Failed to add Route: {} in vpn: {}", vrfEntry.getDestPrefix(), rd);
return;
}
List<String> usedRds = VpnExtraRouteHelper.getUsedRds(dataBroker, vpnId, vrfEntry.getDestPrefix());
List<Routes> vpnExtraRoutes = VpnExtraRouteHelper.getAllVpnExtraRoutes(dataBroker, vpnName, usedRds, vrfEntry.getDestPrefix());
// multiple VMs
if (!vpnExtraRoutes.isEmpty() && (vpnExtraRoutes.size() > 1 || vpnExtraRoutes.get(0).getNexthopIpList().size() > 1)) {
List<InstructionInfo> instructions = new ArrayList<>();
// Obtain the local routes for this particular dpn.
java.util.Optional<Routes> routes = vpnExtraRoutes.stream().filter(route -> {
Prefixes prefixToInterface = fibUtil.getPrefixToInterface(vpnId, fibUtil.getIpPrefix(route.getNexthopIpList().get(0)));
if (prefixToInterface == null) {
return false;
}
return remoteDpnId.equals(prefixToInterface.getDpnId());
}).findFirst();
long groupId = nextHopManager.createNextHopGroups(vpnId, rd, remoteDpnId, vrfEntry, routes.isPresent() ? routes.get() : null, vpnExtraRoutes);
if (groupId == FibConstants.INVALID_GROUP_ID) {
LOG.error("Unable to create Group for local prefix {} on rd {} on Node {}", vrfEntry.getDestPrefix(), rd, remoteDpnId.toString());
return;
}
List<ActionInfo> actionInfos = Collections.singletonList(new ActionGroup(groupId));
instructions.add(new InstructionApplyActions(actionInfos));
baseVrfEntryHandler.makeConnectedRoute(remoteDpnId, vpnId, vrfEntry, rd, instructions, NwConstants.ADD_FLOW, tx, null);
} else {
baseVrfEntryHandler.programRemoteFib(remoteDpnId, vpnId, vrfEntry, tx, rd, adjacencyResults, null);
}
if (!wrTxPresent) {
tx.submit();
}
LOG.debug("Successfully added FIB entry for prefix {} in vpnId {}", vrfEntry.getDestPrefix(), vpnId);
}
use of org.opendaylight.genius.mdsalutil.ActionInfo in project netvirt by opendaylight.
the class BaseVrfEntryHandler method installPingResponderFlowEntry.
public void installPingResponderFlowEntry(BigInteger dpnId, long vpnId, String routerInternalIp, MacAddress routerMac, long label, int addOrRemove) {
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(routerInternalIp, "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(routerInternalIp, "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 = FibUtil.getFlowRef(dpnId, NwConstants.L3_FIB_TABLE, label, 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.syncInstallFlow(flowEntity);
} else {
mdsalManager.syncRemoveFlow(flowEntity);
}
}
use of org.opendaylight.genius.mdsalutil.ActionInfo in project netvirt by opendaylight.
the class BgpRouteVrfEntryHandler method programRemoteFibForBgpRoutes.
public void programRemoteFibForBgpRoutes(final BigInteger remoteDpnId, final long vpnId, final VrfEntry vrfEntry, WriteTransaction tx, String rd, List<NexthopManager.AdjacencyResult> adjacencyResults, List<SubTransaction> subTxns) {
Preconditions.checkArgument(vrfEntry.getRoutePaths().size() <= 2);
if (adjacencyResults.size() == 1) {
programRemoteFib(remoteDpnId, vpnId, vrfEntry, tx, rd, adjacencyResults, subTxns);
return;
}
// ECMP Use case, point to LB group. Move the mpls label accordingly.
List<String> tunnelList = adjacencyResults.stream().map(adjacencyResult -> adjacencyResult.getNextHopIp()).sorted().collect(toList());
String lbGroupKey = FibUtil.getGreLbGroupKey(tunnelList);
long groupId = nexthopManager.createNextHopPointer(lbGroupKey);
int index = 0;
List<ActionInfo> actionInfos = new ArrayList<>();
for (NexthopManager.AdjacencyResult adjResult : adjacencyResults) {
String nextHopIp = adjResult.getNextHopIp();
java.util.Optional<Long> optionalLabel = FibUtil.getLabelForNextHop(vrfEntry, nextHopIp);
if (!optionalLabel.isPresent()) {
LOG.warn("NextHopIp {} not found in vrfEntry {}", nextHopIp, vrfEntry);
continue;
}
long label = optionalLabel.get();
actionInfos.add(new ActionRegLoad(index, FibConstants.NXM_REG_MAPPING.get(index++), 0, 31, label));
}
List<InstructionInfo> instructions = new ArrayList<>();
actionInfos.add(new ActionGroup(index, groupId));
instructions.add(new InstructionApplyActions(actionInfos));
makeConnectedRoute(remoteDpnId, vpnId, vrfEntry, rd, instructions, NwConstants.ADD_FLOW, tx, subTxns);
}
Aggregations