use of org.opendaylight.genius.mdsalutil.instructions.InstructionWriteMetadata in project netvirt by opendaylight.
the class ElanInterfaceManager method getInstructionsIntOrExtTunnelTable.
/**
* Builds the list of instructions to be installed in the INTERNAL_TUNNEL_TABLE (36) / EXTERNAL_TUNNEL_TABLE (38)
* which so far consists of writing the elanTag in metadata and send the packet to ELAN_DMAC_TABLE.
*
* @param elanTag
* elanTag to be written in metadata when flow is selected
* @return the instructions ready to be installed in a flow
*/
private List<InstructionInfo> getInstructionsIntOrExtTunnelTable(Long elanTag) {
List<InstructionInfo> mkInstructions = new ArrayList<>();
mkInstructions.add(new InstructionWriteMetadata(ElanHelper.getElanMetadataLabel(elanTag), ElanHelper.getElanMetadataMask()));
/* applicable for EXTERNAL_TUNNEL_TABLE only
* TODO: We should point to SMAC or DMAC depending on a configuration property to enable mac learning
*/
mkInstructions.add(new InstructionGotoTable(NwConstants.ELAN_DMAC_TABLE));
return mkInstructions;
}
use of org.opendaylight.genius.mdsalutil.instructions.InstructionWriteMetadata in project netvirt by opendaylight.
the class VpnManagerImpl method installArpResponderFlowsToExternalNetworkIp.
private void installArpResponderFlowsToExternalNetworkIp(String macAddress, BigInteger dpnId, String extInterfaceName, int lportTag, String fixedIp) {
// reset the split-horizon bit to allow traffic to be sent back to the
// provider port
List<Instruction> instructions = new ArrayList<>();
instructions.add(new InstructionWriteMetadata(BigInteger.ZERO, MetaDataUtil.METADATA_MASK_SH_FLAG).buildInstruction(1));
instructions.addAll(ArpResponderUtil.getExtInterfaceInstructions(interfaceManager, extInterfaceName, fixedIp, macAddress));
ArpReponderInputBuilder builder = new ArpReponderInputBuilder().setDpId(dpnId).setInterfaceName(extInterfaceName).setSpa(fixedIp).setSha(macAddress).setLportTag(lportTag);
builder.setInstructions(instructions);
elanService.addArpResponderFlow(builder.buildForInstallFlow());
}
use of org.opendaylight.genius.mdsalutil.instructions.InstructionWriteMetadata in project netvirt by opendaylight.
the class ExternalRoutersListener method buildOutboundFlowEntity.
protected FlowEntity buildOutboundFlowEntity(BigInteger dpId, long routerId) {
LOG.debug("buildOutboundFlowEntity : called for dpId {} and routerId{}", dpId, routerId);
List<MatchInfo> matches = new ArrayList<>();
matches.add(MatchEthernetType.IPV4);
matches.add(new MatchMetadata(MetaDataUtil.getVpnIdMetadata(routerId), MetaDataUtil.METADATA_MASK_VRFID));
List<InstructionInfo> instructions = new ArrayList<>();
List<ActionInfo> actionsInfos = new ArrayList<>();
actionsInfos.add(new ActionPuntToController());
instructions.add(new InstructionApplyActions(actionsInfos));
instructions.add(new InstructionWriteMetadata(MetaDataUtil.getVpnIdMetadata(routerId), MetaDataUtil.METADATA_MASK_VRFID));
String flowRef = getFlowRefOutbound(dpId, NwConstants.OUTBOUND_NAPT_TABLE, routerId);
BigInteger cookie = getCookieOutboundFlow(routerId);
FlowEntity flowEntity = MDSALUtil.buildFlowEntity(dpId, NwConstants.OUTBOUND_NAPT_TABLE, flowRef, 5, flowRef, 0, 0, cookie, matches, instructions);
LOG.debug("installOutboundMissEntry : returning flowEntity {}", flowEntity);
return flowEntity;
}
use of org.opendaylight.genius.mdsalutil.instructions.InstructionWriteMetadata in project netvirt by opendaylight.
the class ExternalRoutersListener method buildTsFlowEntityWithUpdatedVpnId.
private FlowEntity buildTsFlowEntityWithUpdatedVpnId(BigInteger dpId, String routerName, long routerIdLongVal, long changedVpnId, ProviderTypes extNwProvType) {
LOG.debug("buildTsFlowEntityWithUpdatedVpnId : called for switch {}, routerName {}, BGP VPN ID {}", dpId, routerName, changedVpnId);
List<MatchInfo> matches = new ArrayList<>();
matches.add(MatchEthernetType.IPV4);
BigInteger tunnelId = BigInteger.valueOf(changedVpnId);
if (NatUtil.isOpenStackVniSemanticsEnforcedForGreAndVxlan(elanManager, extNwProvType)) {
tunnelId = NatOverVxlanUtil.getRouterVni(idManager, routerName, changedVpnId);
}
matches.add(new MatchTunnelId(tunnelId));
List<InstructionInfo> instructions = new ArrayList<>();
instructions.add(new InstructionWriteMetadata(MetaDataUtil.getVpnIdMetadata(changedVpnId), MetaDataUtil.METADATA_MASK_VRFID));
instructions.add(new InstructionGotoTable(NwConstants.OUTBOUND_NAPT_TABLE));
BigInteger routerId = BigInteger.valueOf(routerIdLongVal);
String flowRef = getFlowRefTs(dpId, NwConstants.INTERNAL_TUNNEL_TABLE, routerId.longValue());
FlowEntity flowEntity = MDSALUtil.buildFlowEntity(dpId, NwConstants.INTERNAL_TUNNEL_TABLE, flowRef, NatConstants.DEFAULT_TS_FLOW_PRIORITY, flowRef, 0, 0, NwConstants.COOKIE_TS_TABLE, matches, instructions);
return flowEntity;
}
use of org.opendaylight.genius.mdsalutil.instructions.InstructionWriteMetadata in project netvirt by opendaylight.
the class NatTunnelInterfaceStateListener method hndlTepAddOnNaptSwitch.
private boolean hndlTepAddOnNaptSwitch(BigInteger srcDpnId, String tunnelType, String srcTepIp, String destTepIp, String tunnelName, long routerId, Optional<Routers> routerData, String nextHopIp, Uuid vpnName, ProviderTypes extNwProvType, WriteTransaction writeFlowInvTx) {
if (!routerData.isPresent()) {
LOG.warn("hndlTepAddOnNaptSwitch: routerData is not present");
return false;
}
Routers router = routerData.get();
String routerName = router.getRouterName();
LOG.debug("hndlTepAddOnNaptSwitch : SNAT -> Processing TEP add for the DPN {} having the router {} since " + "its THE NAPT switch for the TUNNEL TYPE {} b/w SRC IP {} and DST IP {} " + "and TUNNEL NAME {} ", srcDpnId, routerName, tunnelType, srcTepIp, destTepIp, tunnelName);
Uuid networkId = router.getNetworkId();
if (networkId == null) {
LOG.warn("hndlTepAddOnNaptSwitch : SNAT -> Ignoring TEP add since the router {} is not associated to the " + "external network", routerName);
return false;
}
LOG.debug("hndlTepAddOnNaptSwitch : SNAT -> Router {} is associated with Ext nw {}", routerId, networkId);
Long vpnId;
if (vpnName == null) {
LOG.debug("hndlTepAddOnNaptSwitch : SNAT -> Internal VPN associated to router {}", routerId);
vpnId = NatUtil.getNetworkVpnIdFromRouterId(dataBroker, routerId);
if (vpnId == NatConstants.INVALID_ID) {
LOG.error("hndlTepAddOnNaptSwitch : Invalid External VPN-ID returned for routerName {}", routerName);
return false;
}
LOG.debug("hndlTepAddOnNaptSwitch : SNAT -> Retrieved External VPN-ID {} for router {}", vpnId, routerId);
} else {
LOG.debug("hndlTepAddOnNaptSwitch : SNAT -> Private BGP VPN associated to router {}", routerId);
vpnId = NatUtil.getVpnId(dataBroker, vpnName.getValue());
if (vpnId == null || vpnId == NatConstants.INVALID_ID) {
LOG.error("hndlTepAddOnNaptSwitch : Invalid vpnId returned for routerName {}", routerName);
return false;
}
LOG.debug("hndlTepAddOnNaptSwitch : SNAT -> Retrieved vpnId {} for router {}", vpnId, routerId);
}
/*1) Withdraw the old route to the external IP from the BGP which was having the
next hop as the old TEP IP.
2) Advertise to the BGP about the new route to the external IP having the
new TEP IP as the next hop.
3) Populate a new FIB entry with the next hop IP as the new TEP IP using the
FIB manager.
*/
// Withdraw the old route to the external IP from the BGP which was having the
// next hop as the old TEP IP.
final String externalVpnName = NatUtil.getAssociatedVPN(dataBroker, networkId);
if (externalVpnName == null) {
LOG.error("hndlTepAddOnNaptSwitch : SNAT -> No VPN associated with ext nw {} in router {}", networkId, routerId);
return false;
}
Collection<String> externalIps = NatUtil.getExternalIpsForRouter(dataBroker, routerId);
LOG.debug("hndlTepAddOnNaptSwitch : Clearing the FIB entries but not the BGP routes");
for (String externalIp : externalIps) {
String rd = NatUtil.getVpnRd(dataBroker, externalVpnName);
LOG.debug("hndlTepAddOnNaptSwitch : Removing Fib entry rd {} prefix {}", rd, externalIp);
fibManager.removeFibEntry(rd, externalIp, null);
}
/*
Advertise to the BGP about the new route to the external IP having the
new TEP IP as the next hop.
Populate a new FIB entry with the next hop IP as the new TEP IP using the
FIB manager.
*/
String rd = NatUtil.getVpnRd(dataBroker, externalVpnName);
if (extNwProvType == null) {
return false;
}
String gwMacAddress = null;
long l3Vni = 0;
if (extNwProvType == ProviderTypes.VXLAN) {
// Get the External Gateway MAC Address which is Router gateway MAC address for SNAT
gwMacAddress = NatUtil.getExtGwMacAddFromRouterName(dataBroker, routerName);
if (gwMacAddress != null) {
LOG.debug("hndlTepAddOnNaptSwitch : External Gateway MAC address {} found for External Router ID {}", gwMacAddress, routerId);
} else {
LOG.error("hndlTepAddOnNaptSwitch : No External Gateway MAC address found for External Router ID {}", routerId);
return false;
}
// get l3Vni value for external VPN
l3Vni = NatEvpnUtil.getL3Vni(dataBroker, rd);
if (l3Vni == NatConstants.DEFAULT_L3VNI_VALUE) {
LOG.debug("hndlTepAddOnNaptSwitch : L3VNI value is not configured in Internet VPN {} and RD {} " + "Carve-out L3VNI value from OpenDaylight VXLAN VNI Pool and continue to installing " + "NAT flows", vpnName, rd);
l3Vni = NatOverVxlanUtil.getInternetVpnVni(idManager, externalVpnName, routerId).longValue();
}
}
for (final String externalIp : externalIps) {
long serviceId = 0;
String fibExternalIp = NatUtil.validateAndAddNetworkMask(externalIp);
if (extNwProvType == ProviderTypes.VXLAN) {
LOG.debug("hndlTepAddOnNaptSwitch : SNAT -> Advertise the route to the externalIp {} " + "having nextHopIp {}", externalIp, nextHopIp);
NatEvpnUtil.addRoutesForVxLanProvType(dataBroker, bgpManager, fibManager, externalVpnName, rd, externalIp, nextHopIp, l3Vni, tunnelName, gwMacAddress, writeFlowInvTx, RouteOrigin.STATIC, srcDpnId);
serviceId = l3Vni;
} else {
Long label = externalRouterListner.checkExternalIpLabel(routerId, externalIp);
if (label == null || label == NatConstants.INVALID_ID) {
LOG.error("hndlTepAddOnNaptSwitch : SNAT->Unable to advertise to the DC GW " + "since label is invalid");
return false;
}
LOG.debug("hndlTepAddOnNaptSwitch : SNAT -> Advertise the route to the externalIp {} " + "having nextHopIp {}", externalIp, nextHopIp);
long l3vni = 0;
if (NatUtil.isOpenStackVniSemanticsEnforcedForGreAndVxlan(elanManager, extNwProvType)) {
l3vni = NatOverVxlanUtil.getInternetVpnVni(idManager, externalVpnName, l3vni).longValue();
}
Uuid externalSubnetId = NatUtil.getExternalSubnetForRouterExternalIp(externalIp, router);
NatUtil.addPrefixToBGP(dataBroker, bgpManager, fibManager, externalVpnName, rd, externalSubnetId, fibExternalIp, nextHopIp, networkId.getValue(), null, /* mac-address */
label, l3vni, RouteOrigin.STATIC, srcDpnId);
serviceId = label;
}
LOG.debug("hndlTepAddOnNaptSwitch: SNAT -> Install custom FIB routes " + "(Table 21 -> Push MPLS label to Tunnel port");
List<Instruction> customInstructions = new ArrayList<>();
int customInstructionIndex = 0;
long externalSubnetVpnId = NatUtil.getExternalSubnetVpnIdForRouterExternalIp(dataBroker, externalIp, router);
if (externalSubnetVpnId != NatConstants.INVALID_ID) {
LOG.debug("hndlTepAddOnNaptSwitch : Will install custom FIB router with external subnet VPN ID {}", externalSubnetVpnId);
BigInteger subnetIdMetaData = MetaDataUtil.getVpnIdMetadata(externalSubnetVpnId);
customInstructions.add(new InstructionWriteMetadata(subnetIdMetaData, MetaDataUtil.METADATA_MASK_VRFID).buildInstruction(customInstructionIndex));
customInstructionIndex++;
}
customInstructions.add(new InstructionGotoTable(NwConstants.INBOUND_NAPT_TABLE).buildInstruction(customInstructionIndex));
CreateFibEntryInput input = new CreateFibEntryInputBuilder().setVpnName(externalVpnName).setSourceDpid(srcDpnId).setInstruction(customInstructions).setIpAddress(fibExternalIp).setServiceId(serviceId).setInstruction(customInstructions).build();
Future<RpcResult<Void>> future = fibRpcService.createFibEntry(input);
ListenableFuture<RpcResult<Void>> listenableFuture = JdkFutureAdapters.listenInPoolThread(future);
Futures.addCallback(listenableFuture, new FutureCallback<RpcResult<Void>>() {
@Override
public void onFailure(@Nonnull Throwable error) {
LOG.error("hndlTepAddOnNaptSwitch : SNAT->Error in generate label or fib install process", error);
}
@Override
public void onSuccess(@Nonnull RpcResult<Void> result) {
if (result.isSuccessful()) {
LOG.info("hndlTepAddOnNaptSwitch : SNAT -> Successfully installed custom FIB routes " + "for prefix {}", externalIp);
} else {
LOG.error("hndlTepAddOnNaptSwitch : SNAT -> Error in rpc call to create custom Fib entries " + "for prefix {} in DPN {}, {}", externalIp, srcDpnId, result.getErrors());
}
}
}, MoreExecutors.directExecutor());
}
return true;
}
Aggregations