use of org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.Bgp in project netvirt by opendaylight.
the class NaptFlowRemovedEventHandler method onFlowRemoved.
@Override
public void onFlowRemoved(FlowRemoved flowRemoved) {
/*
If the removed flow is from the OUTBOUND NAPT table :
1) Get the ActionInfo of the flow.
2) From the ActionInfo of the flow get the internal IP address, port and the protocol.
3) Get the Metadata matching info of the flow.
4) From the Metadata matching info of the flow get router ID.
5) Querry the container intext-ip-port-map using the router ID
and the internal IP address, port to get the external IP address, port
6) Instantiate an NaptEntry event and populate the external IP address, port and the router ID.
7) Place the NaptEntry event to the queue.
*/
short tableId = flowRemoved.getTableId();
RemovedFlowReason removedReasonFlag = flowRemoved.getReason();
if (tableId == NwConstants.OUTBOUND_NAPT_TABLE && RemovedFlowReason.OFPRRIDLETIMEOUT.equals(removedReasonFlag)) {
LOG.info("onFlowRemoved : triggered for table-{} entry", tableId);
// Get the internal internal IP address and the port number from the IPv4 match.
Ipv4Prefix internalIpv4Address = null;
Layer3Match layer3Match = flowRemoved.getMatch().getLayer3Match();
if (layer3Match instanceof Ipv4Match) {
Ipv4Match internalIpv4Match = (Ipv4Match) layer3Match;
internalIpv4Address = internalIpv4Match.getIpv4Source();
}
if (internalIpv4Address == null) {
LOG.error("onFlowRemoved : Matching internal IP is null while retrieving the " + "value from the Outbound NAPT flow");
return;
}
// Get the internal IP as a string
String internalIpv4AddressAsString = internalIpv4Address.getValue();
String[] internalIpv4AddressParts = internalIpv4AddressAsString.split("/");
String internalIpv4HostAddress = null;
if (internalIpv4AddressParts.length >= 1) {
internalIpv4HostAddress = internalIpv4AddressParts[0];
}
// Get the protocol from the layer4 match
NAPTEntryEvent.Protocol protocol = null;
Integer internalPortNumber = null;
Layer4Match layer4Match = flowRemoved.getMatch().getLayer4Match();
if (layer4Match instanceof TcpMatch) {
TcpMatchFields tcpMatchFields = (TcpMatchFields) layer4Match;
internalPortNumber = tcpMatchFields.getTcpSourcePort().getValue();
protocol = NAPTEntryEvent.Protocol.TCP;
} else if (layer4Match instanceof UdpMatch) {
UdpMatchFields udpMatchFields = (UdpMatchFields) layer4Match;
internalPortNumber = udpMatchFields.getUdpSourcePort().getValue();
protocol = NAPTEntryEvent.Protocol.UDP;
}
if (protocol == null) {
LOG.error("onFlowRemoved : Matching protocol is null while retrieving the value " + "from the Outbound NAPT flow");
return;
}
// Get the router ID from the metadata.
Long routerId;
BigInteger metadata = flowRemoved.getMatch().getMetadata().getMetadata();
if (MetaDataUtil.getNatRouterIdFromMetadata(metadata) != 0) {
routerId = MetaDataUtil.getNatRouterIdFromMetadata(metadata);
} else {
LOG.error("onFlowRemoved : Null exception while retrieving routerId");
return;
}
final String internalIpPortKey = routerId + NatConstants.COLON_SEPARATOR + internalIpv4HostAddress + NatConstants.COLON_SEPARATOR + internalPortNumber;
// Get the external IP address and the port from the model
IpPortExternal ipPortExternal = NatUtil.getExternalIpPortMap(dataBroker, routerId, internalIpv4HostAddress, internalPortNumber.toString(), protocol);
if (ipPortExternal == null) {
LOG.error("onFlowRemoved : IpPortExternal not found, BGP vpn might be " + "associated with router");
// router must be associated with BGP vpn ID
long bgpVpnId = routerId;
LOG.debug("onFlowRemoved : BGP VPN ID {}", bgpVpnId);
String vpnName = NatUtil.getRouterName(dataBroker, bgpVpnId);
String routerName = NatUtil.getRouterIdfromVpnInstance(dataBroker, vpnName);
if (routerName == null) {
LOG.error("onFlowRemoved : Unable to find router for VpnName {}", vpnName);
return;
}
routerId = NatUtil.getVpnId(dataBroker, routerName);
LOG.debug("onFlowRemoved : Router ID {}", routerId);
ipPortExternal = NatUtil.getExternalIpPortMap(dataBroker, routerId, internalIpv4HostAddress, internalPortNumber.toString(), protocol);
if (ipPortExternal == null) {
LOG.error("onFlowRemoved : IpPortExternal is null while queried from the " + "model for routerId {}", routerId);
return;
}
}
String externalIpAddress = ipPortExternal.getIpAddress();
int externalPortNumber = ipPortExternal.getPortNum();
// Create an NAPT event and place it in the queue.
NAPTEntryEvent naptEntryEvent = new NAPTEntryEvent(externalIpAddress, externalPortNumber, routerId, NAPTEntryEvent.Operation.DELETE, protocol, null, false, null);
naptEventdispatcher.addFlowRemovedNaptEvent(naptEntryEvent);
// Get the DPN ID from the Node
InstanceIdentifier<Node> nodeRef = flowRemoved.getNode().getValue().firstIdentifierOf(Node.class);
String dpn = nodeRef.firstKeyOf(Node.class).getId().getValue();
BigInteger dpnId = getDpnId(dpn);
String switchFlowRef = NatUtil.getNaptFlowRef(dpnId, tableId, String.valueOf(routerId), internalIpv4HostAddress, internalPortNumber);
// Inform the MDSAL manager to inform about the flow removal.
LOG.debug("onFlowRemoved : DPN ID {}, Metadata {}, SwitchFlowRef {}, " + "internalIpv4HostAddress{}", dpnId, routerId, switchFlowRef, internalIpv4AddressAsString);
FlowEntity snatFlowEntity = NatUtil.buildFlowEntity(dpnId, tableId, switchFlowRef);
long startTime = System.currentTimeMillis();
mdsalManager.removeFlow(snatFlowEntity);
LOG.debug("onFlowRemoved : Elapsed time fo deleting table-{} flow for snat ({}) session:{}ms", tableId, internalIpPortKey, (System.currentTimeMillis() - startTime));
// Remove the SourceIP:Port key from the Napt packet handler map.
naptPacketInHandler.removeIncomingPacketMap(internalIpPortKey);
// Remove the mapping of internal fixed ip/port to external ip/port from the datastore.
SessionAddress internalSessionAddress = new SessionAddress(internalIpv4HostAddress, internalPortNumber);
naptManager.releaseIpExtPortMapping(routerId, internalSessionAddress, protocol);
LOG.info("onFlowRemoved : exit");
} else {
LOG.debug("onFlowRemoved : Received flow removed notification due to flowdelete from switch for flowref");
}
}
use of org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.Bgp in project netvirt by opendaylight.
the class NaptSwitchHA method isNaptSwitchDown.
// TODO Clean up the exception handling
@SuppressWarnings("checkstyle:IllegalCatch")
public boolean isNaptSwitchDown(String routerName, Long routerId, BigInteger dpnId, BigInteger naptSwitch, Long routerVpnId, Collection<String> externalIpCache, boolean isClearBgpRts, WriteTransaction writeFlowInvTx) {
externalIpsCache = externalIpCache;
if (!naptSwitch.equals(dpnId)) {
LOG.debug("isNaptSwitchDown : DpnId {} is not a naptSwitch {} for Router {}", dpnId, naptSwitch, routerName);
return false;
}
LOG.debug("NaptSwitch {} is down for Router {}", naptSwitch, routerName);
if (routerId == NatConstants.INVALID_ID) {
LOG.error("isNaptSwitchDown : Invalid routerId returned for routerName {}", routerName);
return true;
}
Uuid networkId = NatUtil.getNetworkIdFromRouterName(dataBroker, routerName);
String vpnName = getExtNetworkVpnName(routerName, networkId);
// elect a new NaptSwitch
naptSwitch = naptSwitchSelector.selectNewNAPTSwitch(routerName);
if (natMode == NatMode.Conntrack) {
Routers extRouters = NatUtil.getRoutersFromConfigDS(dataBroker, routerName);
natServiceManager.notify(extRouters, dpnId, dpnId, SnatServiceManager.Action.SNAT_ALL_SWITCH_DISBL);
natServiceManager.notify(extRouters, naptSwitch, naptSwitch, SnatServiceManager.Action.SNAT_ALL_SWITCH_ENBL);
} else {
if (naptSwitch.equals(BigInteger.ZERO)) {
LOG.warn("isNaptSwitchDown : No napt switch is elected since all the switches for router {}" + " are down. SNAT IS NOT SUPPORTED FOR ROUTER {}", routerName, routerName);
boolean naptUpdatedStatus = updateNaptSwitch(routerName, naptSwitch);
if (!naptUpdatedStatus) {
LOG.debug("isNaptSwitchDown : Failed to update naptSwitch {} for router {} in ds", naptSwitch, routerName);
}
// clearBgpRoutes
if (externalIpsCache != null) {
if (vpnName != null) {
// if (externalIps != null) {
if (isClearBgpRts) {
LOG.debug("isNaptSwitchDown : Clearing both FIB entries and the BGP routes");
for (String externalIp : externalIpsCache) {
externalRouterListener.clearBgpRoutes(externalIp, vpnName);
}
} else {
LOG.debug("isNaptSwitchDown : Clearing the FIB entries but not the BGP routes");
String rd = NatUtil.getVpnRd(dataBroker, vpnName);
for (String externalIp : externalIpsCache) {
LOG.debug("isNaptSwitchDown : Removing Fib entry rd {} prefix {}", rd, externalIp);
fibManager.removeFibEntry(rd, externalIp, null);
}
}
} else {
LOG.debug("isNaptSwitchDown : vpn is not associated to extn/w for router {}", routerName);
}
} else {
LOG.debug("isNaptSwitchDown : No ExternalIps found for subnets under router {}, " + "no bgp routes need to be cleared", routerName);
}
return true;
}
// checking elected switch health status
if (!getSwitchStatus(naptSwitch)) {
LOG.error("isNaptSwitchDown : Newly elected Napt switch {} for router {} is down", naptSwitch, routerName);
return true;
}
LOG.debug("isNaptSwitchDown : New NaptSwitch {} is up for Router {} and can proceed for flow installation", naptSwitch, routerName);
// update napt model for new napt switch
boolean naptUpdated = updateNaptSwitch(routerName, naptSwitch);
if (naptUpdated) {
// update group of ordinary switch point to naptSwitch tunnel port
updateNaptSwitchBucketStatus(routerName, routerId, naptSwitch);
} else {
LOG.error("isNaptSwitchDown : Failed to update naptSwitch model for newNaptSwitch {} for router {}", naptSwitch, routerName);
}
// update table26 forward packets to table46(outbound napt table)
FlowEntity flowEntity = buildSnatFlowEntityForNaptSwitch(naptSwitch, routerName, routerVpnId, NatConstants.ADD_FLOW);
if (flowEntity == null) {
LOG.error("isNaptSwitchDown : Failed to populate flowentity for router {} in naptSwitch {}", routerName, naptSwitch);
} else {
LOG.debug("isNaptSwitchDown : Successfully installed flow in naptSwitch {} for router {}", naptSwitch, routerName);
mdsalManager.addFlowToTx(flowEntity, writeFlowInvTx);
}
installSnatFlows(routerName, routerId, naptSwitch, routerVpnId, writeFlowInvTx);
boolean flowInstalledStatus = handleNatFlowsInNewNaptSwitch(routerName, routerId, dpnId, naptSwitch, routerVpnId, networkId);
if (flowInstalledStatus) {
LOG.debug("isNaptSwitchDown :Installed all active session flows in newNaptSwitch {} for routerName {}", naptSwitch, routerName);
} else {
LOG.error("isNaptSwitchDown : Failed to install flows in newNaptSwitch {} for routerId {}", naptSwitch, routerId);
}
// remove group in new naptswitch, coz this switch acted previously as ordinary switch
long groupId = NatUtil.createGroupId(NatUtil.getGroupIdKey(routerName), idManager);
GroupEntity groupEntity = null;
try {
groupEntity = MDSALUtil.buildGroupEntity(naptSwitch, groupId, routerName, GroupTypes.GroupAll, Collections.emptyList());
LOG.info("isNaptSwitchDown : Removing NAPT Group in new naptSwitch {}", naptSwitch);
mdsalManager.removeGroup(groupEntity);
} catch (Exception ex) {
LOG.error("isNaptSwitchDown : Failed to remove group in new naptSwitch {}", groupEntity, ex);
}
}
return true;
}
use of org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.Bgp in project netvirt by opendaylight.
the class BgpRouteVrfEntryHandler method createFibEntries.
/*
Please note that the following createFibEntries will be invoked only for BGP Imported Routes.
The invocation of the following method is via create() callback from the MDSAL Batching Infrastructure
provided by ResourceBatchingManager
*/
private void createFibEntries(WriteTransaction writeTx, final InstanceIdentifier<VrfEntry> vrfEntryIid, final VrfEntry vrfEntry, List<SubTransaction> subTxns) {
final VrfTablesKey vrfTableKey = vrfEntryIid.firstKeyOf(VrfTables.class);
final VpnInstanceOpDataEntry vpnInstance = getFibUtil().getVpnInstance(vrfTableKey.getRouteDistinguisher());
Preconditions.checkNotNull(vpnInstance, "Vpn Instance not available " + vrfTableKey.getRouteDistinguisher());
Preconditions.checkNotNull(vpnInstance.getVpnId(), "Vpn Instance with rd " + vpnInstance.getVrfId() + " has null vpnId!");
final Collection<VpnToDpnList> vpnToDpnList = vpnInstance.getVpnToDpnList();
if (vpnToDpnList != null) {
for (VpnToDpnList vpnDpn : vpnToDpnList) {
if (vpnDpn.getDpnState() == VpnToDpnList.DpnState.Active) {
createRemoteFibEntry(vpnDpn.getDpnId(), vpnInstance.getVpnId(), vrfTableKey.getRouteDistinguisher(), vrfEntry, writeTx, subTxns);
}
}
}
}
use of org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.Bgp in project netvirt by opendaylight.
the class IVpnLinkServiceImpl method leakExtraRoutesToVpnEndpoint.
/*
* Checks if there are static routes in Vpn1 whose nexthop is Vpn2's endpoint.
* Those routes must be leaked to Vpn1.
*
* @param vpnLink
* @param vpn1Uuid
* @param vpn2Uuid
*/
private void leakExtraRoutesToVpnEndpoint(InterVpnLinkDataComposite vpnLink, String vpn1Uuid, String vpn2Uuid) {
String vpn1Rd = VpnUtil.getVpnRd(dataBroker, vpn1Uuid);
String vpn2Endpoint = vpnLink.getOtherEndpointIpAddr(vpn2Uuid);
List<VrfEntry> allVpnVrfEntries = VpnUtil.getAllVrfEntries(dataBroker, vpn1Rd);
for (VrfEntry vrfEntry : allVpnVrfEntries) {
vrfEntry.getRoutePaths().stream().filter(routePath -> routePath.getNexthopAddress().equals(vpn2Endpoint)).forEach(routePath -> {
// Vpn1 has a route pointing to Vpn2's endpoint. Forcing the leaking of the route will update
// the BGP accordingly
long label = VpnUtil.getUniqueId(idManager, VpnConstants.VPN_IDPOOL_NAME, VpnUtil.getNextHopLabelKey(vpn1Rd, vrfEntry.getDestPrefix()));
if (label == VpnConstants.INVALID_LABEL) {
LOG.error("Unable to fetch label from Id Manager. Bailing out of leaking extra routes for " + "InterVpnLink {} rd {} prefix {}", vpnLink.getInterVpnLinkName(), vpn1Rd, vrfEntry.getDestPrefix());
} else {
leakRoute(vpnLink, vpn2Uuid, vpn1Uuid, vrfEntry.getDestPrefix(), label, RouteOrigin.value(vrfEntry.getOrigin()));
}
});
}
}
use of org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.Bgp in project netvirt by opendaylight.
the class IVpnLinkServiceImpl method handleStaticRoute.
/*
* Takes care of an static route to see if flows related to interVpnLink
* must be installed in tables 20 and 17
*
* @param vpnId Vpn to which the route belongs
* @param route Route to handle. Will only be considered if its nexthop is the VPN's endpoint IpAddress
* at the other side of the InterVpnLink
* @param iVpnLink
*/
@SuppressWarnings("checkstyle:IllegalCatch")
private void handleStaticRoute(String vpnId, Routes route, InterVpnLinkDataComposite ivpnLink) {
IpAddress nhIpAddr = route.getNexthop();
String routeNextHop = nhIpAddr.getIpv4Address() != null ? nhIpAddr.getIpv4Address().getValue() : nhIpAddr.getIpv6Address().getValue();
String destination = String.valueOf(route.getDestination().getValue());
// is nexthop the other endpoint's IP
String otherEndpoint = ivpnLink.getOtherEndpoint(vpnId);
if (!routeNextHop.equals(otherEndpoint)) {
LOG.debug("VPN {}: Route to {} nexthop={} points to an InterVpnLink endpoint, but its not " + "the other endpoint. Other endpoint is {}", vpnId, destination, routeNextHop, otherEndpoint);
return;
}
// Lets work: 1) write Fibentry, 2) advertise to BGP and 3) check if it must be leaked
String vpnRd = VpnUtil.getVpnRd(dataBroker, vpnId);
if (vpnRd == null) {
LOG.warn("Could not find Route-Distinguisher for VpnName {}", vpnId);
return;
}
int label = VpnUtil.getUniqueId(idManager, VpnConstants.VPN_IDPOOL_NAME, VpnUtil.getNextHopLabelKey(vpnId, destination));
try {
InterVpnLinkUtil.handleStaticRoute(ivpnLink, vpnId, destination, routeNextHop, label, dataBroker, fibManager, bgpManager);
} catch (Exception e) {
LOG.error("Exception while advertising prefix for intervpn link, {}", e);
}
}
Aggregations