use of org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bmp.monitor.rev200120.RouterId in project netvirt by opendaylight.
the class NaptEventHandler method prepareAndSendPacketOut.
private void prepareAndSendPacketOut(NAPTEntryEvent naptEntryEvent, Long routerId) {
// Send Packetout - tcp or udp packets which got punted to controller.
BigInteger metadata = naptEntryEvent.getPacketReceived().getMatch().getMetadata().getMetadata();
byte[] inPayload = naptEntryEvent.getPacketReceived().getPayload();
Ethernet ethPkt = new Ethernet();
if (inPayload != null) {
try {
ethPkt.deserialize(inPayload, 0, inPayload.length * NetUtils.NUM_BITS_IN_A_BYTE);
} catch (PacketException e) {
LOG.error("prepareAndSendPacketOut : Failed to decode Packet", e);
return;
}
}
long portTag = MetaDataUtil.getLportFromMetadata(metadata).intValue();
LOG.debug("prepareAndSendPacketOut : portTag from incoming packet is {}", portTag);
String interfaceName = getInterfaceNameFromTag(portTag);
LOG.debug("prepareAndSendPacketOut : interfaceName fetched from portTag is {}", interfaceName);
org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface iface = null;
int vlanId = 0;
iface = interfaceManager.getInterfaceInfoFromConfigDataStore(interfaceName);
if (iface == null) {
LOG.error("prepareAndSendPacketOut : Unable to read interface {} from config DataStore", interfaceName);
return;
}
List<ActionInfo> actionInfos = new ArrayList<>();
IfL2vlan ifL2vlan = iface.getAugmentation(IfL2vlan.class);
if (ifL2vlan != null && ifL2vlan.getVlanId() != null) {
vlanId = ifL2vlan.getVlanId().getValue() == null ? 0 : ifL2vlan.getVlanId().getValue();
}
InterfaceInfo infInfo = interfaceManager.getInterfaceInfoFromOperationalDataStore(interfaceName);
if (infInfo == null) {
LOG.error("prepareAndSendPacketOut : error in getting interfaceInfo from Operation DS");
return;
}
byte[] pktOut = buildNaptPacketOut(ethPkt);
if (ethPkt.getEtherType() != (short) NwConstants.ETHTYPE_802_1Q) {
// VLAN Access port
LOG.debug("prepareAndSendPacketOut : vlanId is {}", vlanId);
if (vlanId != 0) {
// Push vlan
actionInfos.add(new ActionPushVlan(0));
actionInfos.add(new ActionSetFieldVlanVid(1, vlanId));
} else {
LOG.debug("prepareAndSendPacketOut : No vlanId {}, may be untagged", vlanId);
}
} else {
// VLAN Trunk Port
LOG.debug("prepareAndSendPacketOut : This is VLAN Trunk port case - need not do VLAN tagging again");
}
if (pktOut != null) {
String routerName = NatUtil.getRouterName(dataBroker, routerId);
long tunId = NatUtil.getTunnelIdForNonNaptToNaptFlow(dataBroker, elanManager, idManager, routerId, routerName);
sendNaptPacketOut(pktOut, infInfo, actionInfos, tunId);
} else {
LOG.warn("prepareAndSendPacketOut : Unable to send Packet Out");
}
}
use of org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bmp.monitor.rev200120.RouterId in project netvirt by opendaylight.
the class NaptEventHandler method buildAndInstallNatFlowsOptionalRpc.
private Future<RpcResult<AddFlowOutput>> buildAndInstallNatFlowsOptionalRpc(BigInteger dpnId, short tableId, long vpnId, long routerId, long bgpVpnId, SessionAddress actualSourceAddress, SessionAddress translatedSourceAddress, NAPTEntryEvent.Protocol protocol, String extGwMacAddress, boolean sendRpc) {
LOG.debug("buildAndInstallNatFlowsOptionalRpc : Build and install table={} flow on dpnId {} and routerId {}", tableId, dpnId, routerId);
// Build the flow for replacing the actual IP and port with the translated IP and port.
int idleTimeout = 0;
if (tableId == NwConstants.OUTBOUND_NAPT_TABLE) {
idleTimeout = NatConstants.DEFAULT_NAPT_IDLE_TIMEOUT;
}
long intranetVpnId;
if (bgpVpnId != NatConstants.INVALID_ID) {
intranetVpnId = bgpVpnId;
} else {
intranetVpnId = routerId;
}
LOG.debug("buildAndInstallNatFlowsOptionalRpc : Intranet VPN ID {} Router ID {}", intranetVpnId, routerId);
String translatedIp = translatedSourceAddress.getIpAddress();
int translatedPort = translatedSourceAddress.getPortNumber();
String actualIp = actualSourceAddress.getIpAddress();
int actualPort = actualSourceAddress.getPortNumber();
String switchFlowRef = NatUtil.getNaptFlowRef(dpnId, tableId, String.valueOf(routerId), actualIp, actualPort);
FlowEntity snatFlowEntity = new FlowEntityBuilder().setDpnId(dpnId).setTableId(tableId).setFlowId(switchFlowRef).setPriority(NatConstants.DEFAULT_NAPT_FLOW_PRIORITY).setFlowName(NatConstants.NAPT_FLOW_NAME).setIdleTimeOut(idleTimeout).setHardTimeOut(0).setCookie(NatUtil.getCookieNaptFlow(routerId)).setMatchInfoList(buildAndGetMatchInfo(actualIp, actualPort, tableId, protocol, intranetVpnId)).setInstructionInfoList(buildAndGetSetActionInstructionInfo(translatedIp, translatedPort, intranetVpnId, vpnId, tableId, protocol, extGwMacAddress)).setSendFlowRemFlag(true).build();
// Install flows using RPC to prevent race with future packet-out that depends on this flow
Future<RpcResult<AddFlowOutput>> addFlowResult = null;
if (sendRpc) {
Flow flow = snatFlowEntity.getFlowBuilder().build();
NodeRef nodeRef = getNodeRef(dpnId);
FlowRef flowRef = getFlowRef(dpnId, flow);
AddFlowInput addFlowInput = new AddFlowInputBuilder(flow).setFlowRef(flowRef).setNode(nodeRef).build();
long startTime = System.currentTimeMillis();
addFlowResult = salFlowServiceRpc.addFlow(addFlowInput);
LOG.debug("buildAndInstallNatFlowsOptionalRpc : Time elapsed for salFlowServiceRpc table {}: {}ms ", tableId, System.currentTimeMillis() - startTime);
// Keep flow installation through MDSAL as well to be able to handle switch failures
startTime = System.currentTimeMillis();
mdsalManager.installFlow(snatFlowEntity);
LOG.trace("buildAndInstallNatFlowsOptionalRpc : Time Elapsed while installing table-{} " + "flow on DPN:{} for snat packet({},{}): {}ms", tableId, dpnId, actualSourceAddress.getIpAddress(), actualSourceAddress.getPortNumber(), System.currentTimeMillis() - startTime);
} else {
long startTime = System.currentTimeMillis();
mdsalManager.syncInstallFlow(snatFlowEntity);
LOG.trace("buildAndInstallNatFlowsOptionalRpc : Time Elapsed while installing table-{} " + "flow on DPN:{} for snat packet({},{}): {}ms", tableId, dpnId, actualSourceAddress.getIpAddress(), actualSourceAddress.getPortNumber(), System.currentTimeMillis() - startTime);
}
LOG.trace("buildAndInstallNatFlowsOptionalRpc : Exited");
return addFlowResult;
}
use of org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bmp.monitor.rev200120.RouterId in project netvirt by opendaylight.
the class VpnFloatingIpHandler method onAddFloatingIp.
@Override
public void onAddFloatingIp(final BigInteger dpnId, final String routerUuid, final long routerId, final Uuid networkId, final String interfaceName, final InternalToExternalPortMap mapping, WriteTransaction writeFlowInvTx) {
String externalIp = mapping.getExternalIp();
String internalIp = mapping.getInternalIp();
Uuid floatingIpId = mapping.getExternalId();
Uuid subnetId = NatUtil.getFloatingIpPortSubnetIdFromFloatingIpId(dataBroker, floatingIpId);
String floatingIpPortMacAddress = NatUtil.getFloatingIpPortMacFromFloatingIpId(dataBroker, floatingIpId);
if (floatingIpPortMacAddress == null) {
LOG.error("onAddFloatingIp: Unable to retrieve floatingIp port MAC address from floatingIpId {} for " + "router {} to handle floatingIp {}", floatingIpId, routerUuid, externalIp);
return;
}
Optional<Subnets> externalSubnet = NatUtil.getOptionalExternalSubnets(dataBroker, subnetId);
final String vpnName = externalSubnet.isPresent() ? subnetId.getValue() : NatUtil.getAssociatedVPN(dataBroker, networkId);
final String subnetVpnName = externalSubnet.isPresent() ? subnetId.getValue() : null;
if (vpnName == null) {
LOG.error("onAddFloatingIp: No VPN is associated with ext nw {} to handle add floating ip {} configuration " + "for router {}", networkId, externalIp, routerId);
return;
}
String rd = NatUtil.getVpnRd(dataBroker, vpnName);
if (rd == null) {
LOG.error("onAddFloatingIp: Unable to retrieve external (internet) VPN RD from external VPN {} for " + "router {} to handle floatingIp {}", vpnName, routerId, externalIp);
return;
}
ProviderTypes provType = NatEvpnUtil.getExtNwProvTypeFromRouterName(dataBroker, routerUuid, networkId);
if (provType == null) {
return;
}
/*
* For external network of type GRE, it is required to use "Internet VPN VNI" for intra-DC
* communication, but we still require "MPLS labels" to reach SNAT/DNAT VMs from external
* entities via MPLSOverGRE.
*
* MPLSOverGRE based external networks, the ``opendaylight-vni-ranges`` pool will be
* used to carve out a unique VNI per Internet VPN (GRE-provider-type) to be used in the
* datapath for traffic forwarding for ``SNAT-to-DNAT`` and ``DNAT-to-DNAT`` cases within the
* DataCenter.
*/
if (NatUtil.isOpenStackVniSemanticsEnforcedForGreAndVxlan(elanService, provType)) {
NatOverVxlanUtil.validateAndCreateVxlanVniPool(dataBroker, nvpnManager, idManager, NatConstants.ODL_VNI_POOL_NAME);
}
String nextHopIp = NatUtil.getEndpointIpAddressForDPN(dataBroker, dpnId);
LOG.debug("onAddFloatingIp: Nexthop ip for prefix {} is {}", externalIp, nextHopIp);
if (provType == ProviderTypes.VXLAN) {
Uuid floatingIpInterface = NatEvpnUtil.getFloatingIpInterfaceIdFromFloatingIpId(dataBroker, floatingIpId);
evpnDnatFlowProgrammer.onAddFloatingIp(dpnId, routerUuid, routerId, vpnName, internalIp, externalIp, networkId, interfaceName, floatingIpInterface.getValue(), floatingIpPortMacAddress, rd, nextHopIp, writeFlowInvTx);
return;
}
/*
* MPLS label will be used to advertise prefixes and in "L3_LFIB_TABLE" (table 20) taking the packet
* to "INBOUND_NAPT_TABLE" (table 44) and "PDNAT_TABLE" (table 25).
*/
GenerateVpnLabelInput labelInput = new GenerateVpnLabelInputBuilder().setVpnName(vpnName).setIpPrefix(externalIp).build();
Future<RpcResult<GenerateVpnLabelOutput>> labelFuture = vpnService.generateVpnLabel(labelInput);
ListenableFuture<RpcResult<Void>> future = Futures.transformAsync(JdkFutureAdapters.listenInPoolThread(labelFuture), (AsyncFunction<RpcResult<GenerateVpnLabelOutput>, RpcResult<Void>>) result -> {
if (result.isSuccessful()) {
GenerateVpnLabelOutput output = result.getResult();
long label = output.getLabel();
LOG.debug("onAddFloatingIp : Generated label {} for prefix {}", label, externalIp);
FloatingIPListener.updateOperationalDS(dataBroker, routerUuid, interfaceName, label, internalIp, externalIp);
long l3vni = 0;
if (NatUtil.isOpenStackVniSemanticsEnforcedForGreAndVxlan(elanService, provType)) {
l3vni = NatOverVxlanUtil.getInternetVpnVni(idManager, vpnName, l3vni).longValue();
}
String fibExternalIp = NatUtil.validateAndAddNetworkMask(externalIp);
NatUtil.addPrefixToBGP(dataBroker, bgpManager, fibManager, vpnName, rd, subnetId, fibExternalIp, nextHopIp, networkId.getValue(), floatingIpPortMacAddress, label, l3vni, RouteOrigin.STATIC, dpnId);
List<Instruction> instructions = new ArrayList<>();
List<ActionInfo> actionsInfos = new ArrayList<>();
actionsInfos.add(new ActionNxResubmit(NwConstants.PDNAT_TABLE));
instructions.add(new InstructionApplyActions(actionsInfos).buildInstruction(0));
makeTunnelTableEntry(vpnName, dpnId, label, instructions, writeFlowInvTx, provType);
List<ActionInfo> actionInfoFib = new ArrayList<>();
List<Instruction> customInstructions = new ArrayList<>();
actionInfoFib.add(new ActionSetFieldEthernetDestination(new MacAddress(floatingIpPortMacAddress)));
customInstructions.add(new InstructionApplyActions(actionInfoFib).buildInstruction(0));
customInstructions.add(new InstructionGotoTable(NwConstants.PDNAT_TABLE).buildInstruction(1));
makeLFibTableEntry(dpnId, label, floatingIpPortMacAddress, NwConstants.PDNAT_TABLE, writeFlowInvTx);
CreateFibEntryInput input = new CreateFibEntryInputBuilder().setVpnName(vpnName).setSourceDpid(dpnId).setInstruction(customInstructions).setIpAddress(fibExternalIp).setServiceId(label).setIpAddressSource(CreateFibEntryInput.IpAddressSource.FloatingIP).setInstruction(customInstructions).build();
Future<RpcResult<Void>> future1 = fibService.createFibEntry(input);
LOG.debug("onAddFloatingIp : Add Floating Ip {} , found associated to fixed port {}", externalIp, interfaceName);
String networkVpnName = NatUtil.getAssociatedVPN(dataBroker, networkId);
txRunner.callWithNewWriteOnlyTransactionAndSubmit(tx -> {
vpnManager.addSubnetMacIntoVpnInstance(networkVpnName, subnetVpnName, floatingIpPortMacAddress, dpnId, tx);
vpnManager.addArpResponderFlowsToExternalNetworkIps(routerUuid, Collections.singleton(externalIp), floatingIpPortMacAddress, dpnId, networkId, tx);
});
return JdkFutureAdapters.listenInPoolThread(future1);
} else {
String errMsg = String.format("onAddFloatingIp : Could not retrieve the label for prefix %s " + "in VPN %s, %s", externalIp, vpnName, result.getErrors());
LOG.error(errMsg);
return Futures.immediateFailedFuture(new RuntimeException(errMsg));
}
}, MoreExecutors.directExecutor());
Futures.addCallback(future, new FutureCallback<RpcResult<Void>>() {
@Override
public void onFailure(@Nonnull Throwable error) {
LOG.error("onAddFloatingIp : Error in generate label or fib install process", error);
}
@Override
public void onSuccess(@Nonnull RpcResult<Void> result) {
if (result.isSuccessful()) {
LOG.info("onAddFloatingIp : Successfully installed custom FIB routes for prefix {}", externalIp);
} else {
LOG.error("onAddFloatingIp : Error in rpc call to create custom Fib entries for prefix {} " + "in DPN {}, {}", externalIp, dpnId, result.getErrors());
}
}
}, MoreExecutors.directExecutor());
// Handle GARP transmission
final IpAddress extrenalAddress = IpAddressBuilder.getDefaultInstance(externalIp);
sendGarpOnInterface(dpnId, networkId, extrenalAddress, floatingIpPortMacAddress);
}
use of org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bmp.monitor.rev200120.RouterId in project netvirt by opendaylight.
the class VxlanGreConntrackBasedSnatService method createOutboundTblEntryForVxlanGre.
protected void createOutboundTblEntryForVxlanGre(BigInteger dpnId, long routerId, Long extNetVpnId, List<ExternalIps> externalIps, int elanId, int addOrRemove) {
LOG.info("createOutboundTblEntryForVxlanGre: Install Outbound table flow on dpId {} for routerId {}", dpnId, routerId);
List<MatchInfoBase> matches = new ArrayList<>();
matches.add(MatchEthernetType.IPV4);
matches.add(new NxMatchCtState(TRACKED_NEW_CT_STATE, TRACKED_NEW_CT_MASK));
matches.add(new MatchMetadata(MetaDataUtil.getVpnIdMetadata(routerId), MetaDataUtil.METADATA_MASK_VRFID));
if (externalIps.isEmpty()) {
LOG.error("createOutboundTblEntryForVxlanGre: No externalIP present for routerId {}", routerId);
return;
}
// The logic now handle only one external IP per router, others if present will be ignored.
String externalIp = externalIps.get(0).getIpAddress();
List<ActionInfo> actionsInfos = new ArrayList<>();
if (addOrRemove == NwConstants.ADD_FLOW) {
ActionSetFieldMeta actionSetFieldMeta = new ActionSetFieldMeta(MetaDataUtil.getVpnIdMetadata(extNetVpnId));
actionsInfos.add(actionSetFieldMeta);
}
List<ActionNxConntrack.NxCtAction> ctActionsListCommit = new ArrayList<>();
int rangePresent = NxActionNatRangePresent.NXNATRANGEIPV4MIN.getIntValue();
int flags = NxActionNatFlags.NXNATFSRC.getIntValue();
ActionNxConntrack.NxCtAction nxCtActionCommit = new ActionNxConntrack.NxNat(0, flags, rangePresent, new IpPrefixOrAddress(externalIp.toCharArray()).getIpAddress(), null, 0, 0);
ctActionsListCommit.add(nxCtActionCommit);
int ctCommitFlag = 1;
ActionNxConntrack actionNxConntrackSubmit = new ActionNxConntrack(ctCommitFlag, 0, elanId, NwConstants.NAPT_PFIB_TABLE, ctActionsListCommit);
actionsInfos.add(actionNxConntrackSubmit);
List<InstructionInfo> instructions = new ArrayList<>();
instructions.add(new InstructionApplyActions(actionsInfos));
String flowRef = getFlowRef(dpnId, NwConstants.OUTBOUND_NAPT_TABLE, routerId);
syncFlow(dpnId, NwConstants.OUTBOUND_NAPT_TABLE, flowRef, NatConstants.SNAT_NEW_FLOW_PRIORITY, flowRef, NwConstants.COOKIE_SNAT_TABLE, matches, instructions, addOrRemove);
}
use of org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bmp.monitor.rev200120.RouterId in project netvirt by opendaylight.
the class NatRpcServiceImpl method constructNatInformation.
private List<RouterNat> constructNatInformation(Uuid routerUuid, long routerId) {
String neutronRouterName = NatUtil.getNeutronRouterNamebyUuid(dataBroker, routerUuid);
RouterNatBuilder natRouterBuilder = new RouterNatBuilder();
natRouterBuilder.setRouterUuid(routerUuid);
natRouterBuilder.setRouterName(neutronRouterName);
IpPortMapping ipPortMapping = NatUtil.getIportMapping(dataBroker, routerId);
if (ipPortMapping == null) {
LOG.warn("constructNatInformation : No SNAT IP Mapping found for router-uuid {}", routerUuid.getValue());
} else {
// Capturing SNAT information
List<SnatIpMapping> snatIpMapping = new ArrayList<SnatIpMapping>();
for (IntextIpProtocolType protocolType : ipPortMapping.getIntextIpProtocolType()) {
for (IpPortMap ipPortMap : protocolType.getIpPortMap()) {
String[] internalPortMap = ipPortMap.getIpPortInternal().split(NwConstants.MACADDR_SEP);
SnatIpMappingBuilder natIpMappingBuilder = new SnatIpMappingBuilder().setInternalIp(internalPortMap[0]).setInternalPort(internalPortMap[1]).setExternalIp(ipPortMap.getIpPortExternal().getIpAddress()).setExternalPort(ipPortMap.getIpPortExternal().getPortNum().toString()).setProtocol(protocolType.getProtocol().getName());
snatIpMapping.add(natIpMappingBuilder.build());
}
}
natRouterBuilder.setSnatIpMapping(snatIpMapping);
}
// Capturing DNAT information
List<DnatIpMapping> dnatIpMapping = new ArrayList<DnatIpMapping>();
List<Ports> fipPorts = NatUtil.getFloatingIpPortsForRouter(dataBroker, routerUuid);
if (fipPorts.isEmpty()) {
LOG.warn("constructNatInformation : No DNAT IP Mapping found for router-uuid {}", routerUuid.getValue());
} else {
for (Ports fipPort : fipPorts) {
List<InternalToExternalPortMap> ipMapping = fipPort.getInternalToExternalPortMap();
for (InternalToExternalPortMap fipMap : ipMapping) {
DnatIpMappingBuilder natIpMappingBuilder = new DnatIpMappingBuilder().setExternalIp(fipMap.getExternalIp()).setInternalIp(fipMap.getInternalIp());
dnatIpMapping.add(natIpMappingBuilder.build());
}
}
natRouterBuilder.setDnatIpMapping(dnatIpMapping);
}
List<RouterNat> natRouterList = new ArrayList<RouterNat>();
natRouterList.add(natRouterBuilder.build());
return natRouterList;
}
Aggregations