use of org.opendaylight.yangtools.yang.common.Uint32 in project netvirt by opendaylight.
the class NaptPacketInHandler method onPacketReceived.
@Override
// TODO Clean up the exception handling
@SuppressWarnings("checkstyle:IllegalCatch")
public void onPacketReceived(PacketReceived packetReceived) {
String internalIPAddress = "";
int portNumber = 0;
NAPTEntryEvent.Operation operation = NAPTEntryEvent.Operation.ADD;
NAPTEntryEvent.Protocol protocol;
Short tableId = packetReceived.getTableId().getValue().toJava();
LOG.trace("onPacketReceived : packet: {}, tableId {}", packetReceived, tableId);
if (tableId == NwConstants.OUTBOUND_NAPT_TABLE) {
LOG.debug("onPacketReceived : NAPTPacketInHandler Packet for Outbound NAPT Table");
byte[] inPayload = packetReceived.getPayload();
Ethernet ethPkt = new Ethernet();
if (inPayload != null) {
try {
ethPkt.deserialize(inPayload, 0, inPayload.length * Byte.SIZE);
} catch (Exception e) {
LOG.warn("onPacketReceived: Failed to decode Packet", e);
return;
}
if (ethPkt.getPayload() instanceof IPv4) {
IPv4 ipPkt = (IPv4) ethPkt.getPayload();
byte[] ipSrc = Ints.toByteArray(ipPkt.getSourceAddress());
internalIPAddress = NWUtil.toStringIpAddress(ipSrc);
LOG.trace("onPacketReceived : Retrieved internalIPAddress {}", internalIPAddress);
if (ipPkt.getPayload() instanceof TCP) {
TCP tcpPkt = (TCP) ipPkt.getPayload();
portNumber = tcpPkt.getSourcePort();
if (portNumber < 0) {
portNumber = 32767 + portNumber + 32767 + 2;
LOG.trace("onPacketReceived : Retrieved and extracted TCP portNumber {}", portNumber);
}
protocol = NAPTEntryEvent.Protocol.TCP;
LOG.trace("onPacketReceived : Retrieved TCP portNumber {}", portNumber);
} else if (ipPkt.getPayload() instanceof UDP) {
UDP udpPkt = (UDP) ipPkt.getPayload();
portNumber = udpPkt.getSourcePort();
if (portNumber < 0) {
portNumber = 32767 + portNumber + 32767 + 2;
LOG.trace("onPacketReceived : Retrieved and extracted UDP portNumber {}", portNumber);
}
protocol = NAPTEntryEvent.Protocol.UDP;
LOG.trace("onPacketReceived : Retrieved UDP portNumber {}", portNumber);
} else {
LOG.error("onPacketReceived : Incoming Packet is neither TCP or UDP packet");
return;
}
} else {
LOG.error("onPacketReceived : Incoming Packet is not IPv4 packet");
return;
}
if (internalIPAddress != null) {
Uint64 metadata = packetReceived.getMatch().getMetadata().getMetadata();
Uint32 routerId = Uint32.valueOf(MetaDataUtil.getNatRouterIdFromMetadata(metadata));
if (routerId.longValue() <= 0) {
LOG.error("onPacketReceived : Router ID is invalid");
return;
}
String sourceIPPortKey = routerId + NatConstants.COLON_SEPARATOR + internalIPAddress + NatConstants.COLON_SEPARATOR + portNumber;
NatPacketProcessingState state = INCOMING_PKT_MAP.get(sourceIPPortKey);
if (state == null) {
state = new NatPacketProcessingState(System.currentTimeMillis());
INCOMING_PKT_MAP.put(sourceIPPortKey, state);
LOG.trace("onPacketReceived : Processing new SNAT({}) Packet", sourceIPPortKey);
// send to Event Queue
NAPTEntryEvent naptEntryEvent = new NAPTEntryEvent(internalIPAddress, portNumber, routerId, operation, protocol, packetReceived, false, state);
LOG.info("onPacketReceived : First Packet IN Queue Size : {}", ((ThreadPoolExecutor) firstPacketExecutorService).getQueue().size());
firstPacketExecutorService.execute(() -> naptEventHandler.handleEvent(naptEntryEvent));
} else {
LOG.trace("onPacketReceived : SNAT({}) Packet already processed.", sourceIPPortKey);
NAPTEntryEvent naptEntryEvent = new NAPTEntryEvent(internalIPAddress, portNumber, routerId, operation, protocol, packetReceived, true, state);
LOG.debug("onPacketReceived : Retry Packet IN Queue Size : {}", ((ThreadPoolExecutor) retryPacketExecutorService).getQueue().size());
long firstPacketInTime = state.getFirstPacketInTime();
retryPacketExecutorService.execute(() -> {
if (System.currentTimeMillis() - firstPacketInTime > 4000) {
LOG.error("onPacketReceived : Flow not installed even after 4sec." + "Dropping SNAT ({}) Packet", sourceIPPortKey);
removeIncomingPacketMap(sourceIPPortKey);
return;
}
naptEventHandler.handleEvent(naptEntryEvent);
});
}
} else {
LOG.error("onPacketReceived : Retrived internalIPAddress is NULL");
}
}
} else {
LOG.trace("onPacketReceived : Packet is not from the Outbound NAPT table");
}
}
use of org.opendaylight.yangtools.yang.common.Uint32 in project netvirt by opendaylight.
the class NaptSwitchHA method installSnatGroupEntry.
// TODO Clean up the exception handling
@SuppressWarnings("checkstyle:IllegalCatch")
protected void installSnatGroupEntry(Uint64 dpnId, List<BucketInfo> bucketInfo, String routerName) {
GroupEntity groupEntity = null;
try {
Uint32 groupId = NatUtil.getUniqueId(idManager, NatConstants.SNAT_IDPOOL_NAME, NatUtil.getGroupIdKey(routerName));
if (groupId != NatConstants.INVALID_ID) {
LOG.debug("installSnatGroupEntry : install SnatMissEntry for groupId {} for dpnId {} for router {}", groupId, dpnId, routerName);
groupEntity = MDSALUtil.buildGroupEntity(dpnId, groupId.longValue(), routerName, GroupTypes.GroupAll, bucketInfo);
mdsalManager.syncInstallGroup(groupEntity);
LOG.debug("installSnatGroupEntry : installed the SNAT to NAPT GroupEntity:{}", groupEntity);
} else {
LOG.error("installSnatGroupEntry: Unable to obtain groupId for router:{}", routerName);
}
} catch (Exception ex) {
LOG.error("installSnatGroupEntry : Failed to install group for groupEntity {}", groupEntity, ex);
}
}
use of org.opendaylight.yangtools.yang.common.Uint32 in project netvirt by opendaylight.
the class NaptSwitchHA method isNaptSwitchDown.
// TODO Clean up the exception handling
@SuppressWarnings("checkstyle:IllegalCatch")
public boolean isNaptSwitchDown(Routers extRouter, Uint32 routerId, Uint64 dpnId, Uint64 naptSwitch, Uint32 routerVpnId, Collection<String> externalIpCache, boolean isClearBgpRts, TypedReadWriteTransaction<Configuration> confTx) throws ExecutionException, InterruptedException {
externalIpsCache = externalIpCache;
String routerName = extRouter.getRouterName();
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 = extRouter.getNetworkId();
String vpnName = getExtNetworkVpnName(routerName, networkId);
// elect a new NaptSwitch
naptSwitch = naptSwitchSelector.selectNewNAPTSwitch(routerName, Arrays.asList(naptSwitch));
if (natMode == NatMode.Conntrack) {
Routers extRouters = NatUtil.getRoutersFromConfigDS(dataBroker, routerName);
natServiceManager.notify(confTx, extRouters, null, dpnId, dpnId, SnatServiceManager.Action.CNT_ROUTER_ALL_SWITCH_DISBL);
if (extRouters.isEnableSnat()) {
natServiceManager.notify(confTx, extRouters, null, dpnId, dpnId, SnatServiceManager.Action.SNAT_ALL_SWITCH_DISBL);
}
natServiceManager.notify(confTx, extRouters, null, naptSwitch, naptSwitch, SnatServiceManager.Action.CNT_ROUTER_ALL_SWITCH_ENBL);
if (extRouters.isEnableSnat()) {
natServiceManager.notify(confTx, extRouters, null, naptSwitch, naptSwitch, SnatServiceManager.Action.SNAT_ALL_SWITCH_ENBL);
}
} else {
if (naptSwitch.equals(Uint64.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, 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 (!NatUtil.getSwitchStatus(dataBroker, 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.addFlow(confTx, flowEntity);
}
installSnatFlows(routerName, routerId, naptSwitch, routerVpnId, networkId, vpnName, confTx);
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
Uint32 groupId = NatUtil.getUniqueId(idManager, NatConstants.SNAT_IDPOOL_NAME, NatUtil.getGroupIdKey(routerName));
if (groupId != NatConstants.INVALID_ID) {
try {
LOG.info("isNaptSwitchDown : Removing NAPT Group in new naptSwitch {}", naptSwitch);
mdsalManager.removeGroup(confTx, naptSwitch, groupId.longValue());
} catch (Exception ex) {
LOG.error("isNaptSwitchDown : Failed to remove group in new naptSwitch {}", naptSwitch, ex);
}
} else {
LOG.error("NAT Service : Unable to obtain groupId for router:{}", routerName);
}
}
return true;
}
use of org.opendaylight.yangtools.yang.common.Uint32 in project netvirt by opendaylight.
the class ExternalRoutersListener method removeFlowsFromNonActiveSwitches.
public void removeFlowsFromNonActiveSwitches(Uint32 routerId, String routerName, Uint64 naptSwitchDpnId, TypedReadWriteTransaction<Configuration> removeFlowInvTx) throws ExecutionException, InterruptedException {
LOG.debug("removeFlowsFromNonActiveSwitches : Remove NAPT related flows from non active switches");
// Remove the flows from the other switches which points to the primary and secondary switches
// for the flows related the router ID.
List<Uint64> allSwitchList = naptSwitchSelector.getDpnsForVpn(routerName);
if (allSwitchList.isEmpty()) {
LOG.error("removeFlowsFromNonActiveSwitches : Unable to get the swithces for the router {}", routerName);
return;
}
for (Uint64 dpnId : allSwitchList) {
if (!naptSwitchDpnId.equals(dpnId)) {
LOG.info("removeFlowsFromNonActiveSwitches : Handle Ordinary switch");
// Remove the PSNAT entry which forwards the packet to Terminating Service table
String preSnatFlowRef = getFlowRefSnat(dpnId, NwConstants.PSNAT_TABLE, String.valueOf(routerName));
FlowEntity preSnatFlowEntity = NatUtil.buildFlowEntity(dpnId, NwConstants.PSNAT_TABLE, preSnatFlowRef);
LOG.info("removeFlowsFromNonActiveSwitches : Remove the flow in the {} for the non active switch " + "with the DPN ID {} and router ID {}", NwConstants.PSNAT_TABLE, dpnId, routerId);
mdsalManager.removeFlow(removeFlowInvTx, preSnatFlowEntity);
// Remove the group entry which forwards the traffic to the out port (VXLAN tunnel).
Uint32 groupId = NatUtil.getUniqueId(idManager, NatConstants.SNAT_IDPOOL_NAME, NatUtil.getGroupIdKey(routerName));
if (groupId != NatConstants.INVALID_ID) {
LOG.info("removeFlowsFromNonActiveSwitches : Remove the group {} for the non active switch with " + "the DPN ID {} and router ID {}", groupId, dpnId, routerId);
mdsalManager.removeGroup(removeFlowInvTx, dpnId, groupId.longValue());
} else {
LOG.error("removeFlowsFromNonActiveSwitches: Unable to obtained groupID for router:{}", routerName);
}
}
}
}
use of org.opendaylight.yangtools.yang.common.Uint32 in project netvirt by opendaylight.
the class ExternalRoutersListener method installNaptPfibEntriesForExternalSubnets.
protected void installNaptPfibEntriesForExternalSubnets(String routerName, Uint64 dpnId, @Nullable TypedWriteTransaction<Configuration> writeFlowInvTx) {
Collection<Uuid> externalSubnetIdsForRouter = NatUtil.getExternalSubnetIdsForRouter(dataBroker, routerName);
for (Uuid externalSubnetId : externalSubnetIdsForRouter) {
Uint32 subnetVpnId = NatUtil.getVpnId(dataBroker, externalSubnetId.getValue());
if (subnetVpnId != NatConstants.INVALID_ID) {
LOG.debug("installNaptPfibEntriesForExternalSubnets : called for dpnId {} " + "and vpnId {}", dpnId, subnetVpnId);
installNaptPfibEntry(dpnId, subnetVpnId, writeFlowInvTx);
}
}
}
Aggregations