use of org.opendaylight.yang.gen.v1.urn.opendaylight.table.types.rev131026.TunnelId in project netvirt by opendaylight.
the class NaptSwitchHA method removeSnatFlowsInOldNaptSwitch.
/* This method checks the switch that gone down is a NaptSwitch for a router.
If it is a NaptSwitch
1) selects new NAPT switch
2) installs nat flows in new NAPT switch
table 21(FIB)->26(PSNAT)->group(resubmit/napttunnel)->36(Terminating)->46(outbound)->47(resubmit)->21
3) modify the group and miss entry flow in other vSwitches pointing to newNaptSwitch
4) Remove nat flows in oldNaptSwitch
*/
/*public void handleNaptSwitchDown(BigInteger dpnId){
LOG.debug("handleNaptSwitchDown method is called with dpnId {}",dpnId);
BigInteger naptSwitch;
try {
NaptSwitches naptSwitches = NatUtil.getNaptSwitch(dataBroker);
if (naptSwitches == null || naptSwitches.getRouterToNaptSwitch() == null
|| naptSwitches.getRouterToNaptSwitch().isEmpty()) {
LOG.debug("NaptSwitchDown: NaptSwitch is not allocated for none of the routers");
return;
}
for (RouterToNaptSwitch routerToNaptSwitch : naptSwitches.getRouterToNaptSwitch()) {
String routerName = routerToNaptSwitch.getRouterName();
naptSwitch = routerToNaptSwitch.getPrimarySwitchId();
boolean naptStatus = isNaptSwitchDown(routerName,dpnId,naptSwitch);
if (!naptStatus) {
LOG.debug("NaptSwitchDown: Switch with DpnId {} is not naptSwitch for router {}",
dpnId, routerName);
} else {
removeSnatFlowsInOldNaptSwitch(routerName,naptSwitch);
return;
}
}
} catch (Exception ex) {
LOG.error("Exception in handleNaptSwitchDown method {}",ex);
}
}*/
protected void removeSnatFlowsInOldNaptSwitch(String routerName, Long routerId, BigInteger naptSwitch, Map<String, Long> externalIpmap, WriteTransaction removeFlowInvTx) {
// remove SNAT flows in old NAPT SWITCH
Uuid networkId = NatUtil.getNetworkIdFromRouterName(dataBroker, routerName);
String vpnName = getExtNetworkVpnName(routerName, networkId);
if (vpnName == null) {
LOG.error("removeSnatFlowsInOldNaptSwitch : Vpn is not associated to externalN/w of router {}", routerName);
return;
}
ProviderTypes extNwProvType = NatEvpnUtil.getExtNwProvTypeFromRouterName(dataBroker, routerName, networkId);
if (extNwProvType == null) {
LOG.error("removeSnatFlowsInOldNaptSwitch : Unable to retrieve the External Network Provider Type " + "for Router {}", routerName);
return;
}
if (extNwProvType == ProviderTypes.VXLAN) {
evpnNaptSwitchHA.evpnRemoveSnatFlowsInOldNaptSwitch(routerName, routerId, vpnName, naptSwitch, removeFlowInvTx);
} else {
// Remove the Terminating Service table entry which forwards the packet to Outbound NAPT Table
long tunnelId = NatUtil.getTunnelIdForNonNaptToNaptFlow(dataBroker, elanManager, idManager, routerId, routerName);
String tsFlowRef = externalRouterListener.getFlowRefTs(naptSwitch, NwConstants.INTERNAL_TUNNEL_TABLE, tunnelId);
FlowEntity tsNatFlowEntity = NatUtil.buildFlowEntity(naptSwitch, NwConstants.INTERNAL_TUNNEL_TABLE, tsFlowRef);
LOG.info("removeSnatFlowsInOldNaptSwitch : Remove the flow in table {} for the old napt switch " + "with the DPN ID {} and router ID {}", NwConstants.INTERNAL_TUNNEL_TABLE, naptSwitch, routerId);
mdsalManager.removeFlowToTx(tsNatFlowEntity, removeFlowInvTx);
}
if (NatUtil.isOpenStackVniSemanticsEnforcedForGreAndVxlan(elanManager, extNwProvType)) {
// Remove the flow table 25->44 If there is no FIP Match on table 25 (PDNAT_TABLE)
NatUtil.removePreDnatToSnatTableEntry(mdsalManager, naptSwitch, removeFlowInvTx);
}
// Remove the Outbound flow entry which forwards the packet to Outbound NAPT Table
String outboundNatFlowRef = externalRouterListener.getFlowRefOutbound(naptSwitch, NwConstants.OUTBOUND_NAPT_TABLE, routerId);
FlowEntity outboundNatFlowEntity = NatUtil.buildFlowEntity(naptSwitch, NwConstants.OUTBOUND_NAPT_TABLE, outboundNatFlowRef);
LOG.info("Remove the flow in table {} for the old napt switch with the DPN ID {} and router ID {}", NwConstants.OUTBOUND_NAPT_TABLE, naptSwitch, routerId);
mdsalManager.removeFlowToTx(outboundNatFlowEntity, removeFlowInvTx);
// Remove the NAPT PFIB TABLE (47->21) which forwards the incoming packet to FIB Table matching on the
// External Subnet Vpn Id.
Collection<Uuid> externalSubnetIdsForRouter = NatUtil.getExternalSubnetIdsForRouter(dataBroker, routerName);
for (Uuid externalSubnetId : externalSubnetIdsForRouter) {
long subnetVpnId = NatUtil.getVpnId(dataBroker, externalSubnetId.getValue());
if (subnetVpnId != -1) {
String natPfibSubnetFlowRef = externalRouterListener.getFlowRefTs(naptSwitch, NwConstants.NAPT_PFIB_TABLE, subnetVpnId);
FlowEntity natPfibFlowEntity = NatUtil.buildFlowEntity(naptSwitch, NwConstants.NAPT_PFIB_TABLE, natPfibSubnetFlowRef);
mdsalManager.removeFlowToTx(natPfibFlowEntity, removeFlowInvTx);
LOG.debug("removeSnatFlowsInOldNaptSwitch : Removed the flow in table {} with external subnet " + "Vpn Id {} as metadata on Napt Switch {}", NwConstants.NAPT_PFIB_TABLE, subnetVpnId, naptSwitch);
}
}
// Remove the NAPT_PFIB_TABLE(47) flow entry forwards the packet to Fib Table for inbound traffic
// matching on the router ID.
String naptPFibflowRef = externalRouterListener.getFlowRefTs(naptSwitch, NwConstants.NAPT_PFIB_TABLE, routerId);
FlowEntity naptPFibFlowEntity = NatUtil.buildFlowEntity(naptSwitch, NwConstants.NAPT_PFIB_TABLE, naptPFibflowRef);
LOG.info("removeSnatFlowsInOldNaptSwitch : Remove the flow in table {} for the old napt switch " + "with the DPN ID {} and router ID {}", NwConstants.NAPT_PFIB_TABLE, naptSwitch, routerId);
mdsalManager.removeFlowToTx(naptPFibFlowEntity, removeFlowInvTx);
// Remove the NAPT_PFIB_TABLE(47) flow entry forwards the packet to Fib Table for outbound traffic
// matching on the vpn ID.
boolean switchSharedByRouters = false;
Uuid extNetworkId = NatUtil.getNetworkIdFromRouterName(dataBroker, routerName);
if (extNetworkId != null) {
List<String> routerNamesAssociated = getRouterIdsForExtNetwork(extNetworkId);
for (String routerNameAssociated : routerNamesAssociated) {
if (!routerNameAssociated.equals(routerName)) {
Long routerIdAssociated = NatUtil.getVpnId(dataBroker, routerNameAssociated);
BigInteger naptDpn = NatUtil.getPrimaryNaptfromRouterName(dataBroker, routerNameAssociated);
if (naptDpn != null && naptDpn.equals(naptSwitch)) {
LOG.debug("removeSnatFlowsInOldNaptSwitch : Napt switch {} is also acting as primary " + "for router {}", naptSwitch, routerIdAssociated);
switchSharedByRouters = true;
break;
}
}
}
if (!switchSharedByRouters) {
Long vpnId = getVpnIdForRouter(routerId, extNetworkId);
if (vpnId != NatConstants.INVALID_ID) {
String naptFibflowRef = externalRouterListener.getFlowRefTs(naptSwitch, NwConstants.NAPT_PFIB_TABLE, vpnId);
FlowEntity naptFibFlowEntity = NatUtil.buildFlowEntity(naptSwitch, NwConstants.NAPT_PFIB_TABLE, naptFibflowRef);
LOG.info("removeSnatFlowsInOldNaptSwitch : Remove the flow in table {} for the old napt switch" + " with the DPN ID {} and vpnId {}", NwConstants.NAPT_PFIB_TABLE, naptSwitch, vpnId);
mdsalManager.removeFlowToTx(naptFibFlowEntity, removeFlowInvTx);
} else {
LOG.error("removeSnatFlowsInOldNaptSwitch : Invalid vpnId retrieved for routerId {}", routerId);
return;
}
}
}
// Remove Fib entries,tables 20->44 ,36-> 44
String gwMacAddress = NatUtil.getExtGwMacAddFromRouterName(dataBroker, routerName);
if (externalIpmap != null && !externalIpmap.isEmpty()) {
for (Entry<String, Long> entry : externalIpmap.entrySet()) {
String externalIp = entry.getKey();
Long label = entry.getValue();
externalRouterListener.delFibTsAndReverseTraffic(naptSwitch, routerId, externalIp, vpnName, extNetworkId, label, gwMacAddress, true, removeFlowInvTx);
LOG.debug("removeSnatFlowsInOldNaptSwitch : Successfully removed fib entries in old naptswitch {} " + "for router {} and externalIps {} label {}", naptSwitch, routerId, externalIp, label);
}
} else {
List<String> externalIps = NatUtil.getExternalIpsForRouter(dataBroker, routerName);
if (networkId != null) {
externalRouterListener.clearFibTsAndReverseTraffic(naptSwitch, routerId, networkId, externalIps, null, gwMacAddress, removeFlowInvTx);
LOG.debug("removeSnatFlowsInOldNaptSwitch : Successfully removed fib entries in old naptswitch {} for " + "router {} with networkId {} and externalIps {}", naptSwitch, routerId, networkId, externalIps);
} else {
LOG.debug("removeSnatFlowsInOldNaptSwitch : External network not associated to router {}", routerId);
}
externalRouterListener.removeNaptFibExternalOutputFlows(routerId, naptSwitch, extNetworkId, externalIps, removeFlowInvTx);
}
// For the router ID get the internal IP , internal port and the corresponding external IP and external Port.
IpPortMapping ipPortMapping = NatUtil.getIportMapping(dataBroker, routerId);
if (ipPortMapping == null || ipPortMapping.getIntextIpProtocolType() == null || ipPortMapping.getIntextIpProtocolType().isEmpty()) {
LOG.warn("removeSnatFlowsInOldNaptSwitch : No Internal Ip Port mapping associated to router {}, " + "no flows need to be removed in oldNaptSwitch {}", routerId, naptSwitch);
return;
}
BigInteger cookieSnatFlow = NatUtil.getCookieNaptFlow(routerId);
List<IntextIpProtocolType> intextIpProtocolTypes = ipPortMapping.getIntextIpProtocolType();
for (IntextIpProtocolType intextIpProtocolType : intextIpProtocolTypes) {
if (intextIpProtocolType.getIpPortMap() == null || intextIpProtocolType.getIpPortMap().isEmpty()) {
LOG.debug("removeSnatFlowsInOldNaptSwitch : No {} session associated to router {}," + "no flows need to be removed in oldNaptSwitch {}", intextIpProtocolType.getProtocol(), routerId, naptSwitch);
break;
}
List<IpPortMap> ipPortMaps = intextIpProtocolType.getIpPortMap();
for (IpPortMap ipPortMap : ipPortMaps) {
String ipPortInternal = ipPortMap.getIpPortInternal();
String[] ipPortParts = ipPortInternal.split(":");
if (ipPortParts.length != 2) {
LOG.error("removeSnatFlowsInOldNaptSwitch : Unable to retrieve the Internal IP and port");
continue;
}
String internalIp = ipPortParts[0];
String internalPort = ipPortParts[1];
// Build and remove flow in outbound NAPT table
String switchFlowRef = NatUtil.getNaptFlowRef(naptSwitch, NwConstants.OUTBOUND_NAPT_TABLE, String.valueOf(routerId), internalIp, Integer.parseInt(internalPort));
FlowEntity outboundNaptFlowEntity = NatUtil.buildFlowEntity(naptSwitch, NwConstants.OUTBOUND_NAPT_TABLE, cookieSnatFlow, switchFlowRef);
LOG.info("removeSnatFlowsInOldNaptSwitch : Remove the flow in table {} for old napt switch " + "with the DPN ID {} and router ID {}", NwConstants.OUTBOUND_NAPT_TABLE, naptSwitch, routerId);
mdsalManager.removeFlowToTx(outboundNaptFlowEntity, removeFlowInvTx);
IpPortExternal ipPortExternal = ipPortMap.getIpPortExternal();
if (ipPortExternal == null) {
LOG.debug("removeSnatFlowsInOldNaptSwitch : External Ipport mapping not found for internalIp {} " + "with port {} for router {}", internalIp, internalPort, routerId);
continue;
}
String externalIp = ipPortExternal.getIpAddress();
int externalPort = ipPortExternal.getPortNum();
// Build and remove flow in inbound NAPT table
switchFlowRef = NatUtil.getNaptFlowRef(naptSwitch, NwConstants.INBOUND_NAPT_TABLE, String.valueOf(routerId), externalIp, externalPort);
FlowEntity inboundNaptFlowEntity = NatUtil.buildFlowEntity(naptSwitch, NwConstants.INBOUND_NAPT_TABLE, cookieSnatFlow, switchFlowRef);
LOG.info("removeSnatFlowsInOldNaptSwitch : Remove the flow in table {} for old napt switch with the " + "DPN ID {} and router ID {}", NwConstants.INBOUND_NAPT_TABLE, naptSwitch, routerId);
mdsalManager.removeFlowToTx(inboundNaptFlowEntity, removeFlowInvTx);
}
}
}
use of org.opendaylight.yang.gen.v1.urn.opendaylight.table.types.rev131026.TunnelId in project netvirt by opendaylight.
the class BaseVrfEntryHandler method addTunnelInterfaceActions.
protected void addTunnelInterfaceActions(AdjacencyResult adjacencyResult, long vpnId, VrfEntry vrfEntry, List<ActionInfo> actionInfos, String rd) {
Class<? extends TunnelTypeBase> tunnelType = VpnExtraRouteHelper.getTunnelType(nextHopManager.getInterfaceManager(), adjacencyResult.getInterfaceName());
if (tunnelType == null) {
LOG.debug("Tunnel type not found for vrfEntry {}", vrfEntry);
return;
}
// TODO - For now have added routePath into adjacencyResult so that we know for which
// routePath this result is built for. If this is not possible construct a map which does
// the same.
String nextHopIp = adjacencyResult.getNextHopIp();
java.util.Optional<Long> optionalLabel = FibUtil.getLabelForNextHop(vrfEntry, nextHopIp);
if (!optionalLabel.isPresent()) {
LOG.warn("NextHopIp {} not found in vrfEntry {}", nextHopIp, vrfEntry);
return;
}
long label = optionalLabel.get();
BigInteger tunnelId = null;
Prefixes prefixInfo = null;
// revisit
if (tunnelType.equals(TunnelTypeVxlan.class)) {
prefixInfo = fibUtil.getPrefixToInterface(vpnId, vrfEntry.getDestPrefix());
// For extra route, the prefixInfo is fetched from the primary adjacency
if (prefixInfo == null) {
prefixInfo = fibUtil.getPrefixToInterface(vpnId, adjacencyResult.getPrefix());
}
// Internet VPN VNI will be used as tun_id for NAT use-cases
if (Prefixes.PrefixCue.Nat.equals(prefixInfo.getPrefixCue())) {
if (vrfEntry.getL3vni() != null && vrfEntry.getL3vni() != 0) {
tunnelId = BigInteger.valueOf(vrfEntry.getL3vni());
}
} else {
if (fibUtil.enforceVxlanDatapathSemanticsforInternalRouterVpn(prefixInfo.getSubnetId(), vpnId, rd)) {
java.util.Optional<Long> optionalVni = fibUtil.getVniForVxlanNetwork(prefixInfo.getSubnetId());
if (!optionalVni.isPresent()) {
LOG.error("VNI not found for nexthop {} vrfEntry {} with subnetId {}", nextHopIp, vrfEntry, prefixInfo.getSubnetId());
return;
}
tunnelId = BigInteger.valueOf(optionalVni.get());
} else {
tunnelId = BigInteger.valueOf(label);
}
}
} else {
tunnelId = BigInteger.valueOf(label);
}
LOG.debug("adding set tunnel id action for label {}", label);
actionInfos.add(new ActionSetFieldTunnelId(tunnelId));
addRewriteDstMacAction(vpnId, vrfEntry, prefixInfo, actionInfos);
}
use of org.opendaylight.yang.gen.v1.urn.opendaylight.table.types.rev131026.TunnelId in project netvirt by opendaylight.
the class EvpnVrfEntryHandler method createRemoteFibEntry.
private void createRemoteFibEntry(final BigInteger remoteDpnId, final long vpnId, final VrfTablesKey vrfTableKey, final VrfEntry vrfEntry, boolean isNatPrefix, WriteTransaction tx) {
String rd = vrfTableKey.getRouteDistinguisher();
List<SubTransaction> subTxns = new ArrayList<>();
LOG.debug("createremotefibentry: adding route {} for rd {} with transaction {}", vrfEntry.getDestPrefix(), rd, tx);
List<NexthopManager.AdjacencyResult> tunnelInterfaceList = resolveAdjacency(remoteDpnId, vpnId, vrfEntry, rd);
if (tunnelInterfaceList.isEmpty()) {
LOG.error("Could not get interface for route-paths: {} in vpn {}", vrfEntry.getRoutePaths(), rd);
LOG.warn("Failed to add Route: {} in vpn: {}", vrfEntry.getDestPrefix(), rd);
return;
}
for (NexthopManager.AdjacencyResult adjacencyResult : tunnelInterfaceList) {
List<ActionInfo> actionInfos = new ArrayList<>();
BigInteger tunnelId;
String prefix = adjacencyResult.getPrefix();
Prefixes prefixInfo = getFibUtil().getPrefixToInterface(vpnId, prefix);
String interfaceName = prefixInfo.getVpnInterfaceName();
if (vrfEntry.getOrigin().equals(RouteOrigin.BGP.getValue()) || isNatPrefix) {
tunnelId = BigInteger.valueOf(vrfEntry.getL3vni());
} else if (elanManager.isOpenStackVniSemanticsEnforced()) {
tunnelId = BigInteger.valueOf(getFibUtil().getVniForVxlanNetwork(prefixInfo.getSubnetId()).get());
} else {
Interface interfaceState = getFibUtil().getInterfaceStateFromOperDS(interfaceName);
tunnelId = BigInteger.valueOf(interfaceState.getIfIndex());
}
LOG.debug("adding set tunnel id action for label {}", tunnelId);
String macAddress = null;
String vpnName = getFibUtil().getVpnNameFromId(vpnId);
if (vpnName == null) {
LOG.debug("Failed to get VPN name for vpnId {}", vpnId);
return;
}
if (interfaceName != null) {
macAddress = getFibUtil().getMacAddressFromPrefix(interfaceName, vpnName, prefix);
actionInfos.add(new ActionSetFieldEthernetDestination(new MacAddress(macAddress)));
}
actionInfos.add(new ActionSetFieldTunnelId(tunnelId));
List<ActionInfo> egressActions = nexthopManager.getEgressActionsForInterface(adjacencyResult.getInterfaceName(), actionInfos.size());
if (egressActions.isEmpty()) {
LOG.error("Failed to retrieve egress action for prefix {} route-paths {} interface {}." + " Aborting remote FIB entry creation..", vrfEntry.getDestPrefix(), vrfEntry.getRoutePaths(), adjacencyResult.getInterfaceName());
return;
}
actionInfos.addAll(egressActions);
List<InstructionInfo> instructions = new ArrayList<>();
instructions.add(new InstructionApplyActions(actionInfos));
makeConnectedRoute(remoteDpnId, vpnId, vrfEntry, rd, instructions, NwConstants.ADD_FLOW, tx, subTxns);
}
LOG.debug("Successfully added FIB entry for prefix {} in rd {}", vrfEntry.getDestPrefix(), rd);
}
use of org.opendaylight.yang.gen.v1.urn.opendaylight.table.types.rev131026.TunnelId in project netvirt by opendaylight.
the class DhcpPktHandler method getEgressAction.
private List<Action> getEgressAction(String interfaceName, BigInteger tunnelId) {
List<Action> actions = null;
try {
GetEgressActionsForInterfaceInputBuilder egressAction = new GetEgressActionsForInterfaceInputBuilder().setIntfName(interfaceName);
if (tunnelId != null) {
egressAction.setTunnelKey(tunnelId.longValue());
}
Future<RpcResult<GetEgressActionsForInterfaceOutput>> result = interfaceManagerRpc.getEgressActionsForInterface(egressAction.build());
RpcResult<GetEgressActionsForInterfaceOutput> rpcResult = result.get();
if (!rpcResult.isSuccessful()) {
LOG.warn("RPC Call to Get egress actions for interface {} returned with Errors {}", interfaceName, rpcResult.getErrors());
} else {
actions = rpcResult.getResult().getAction();
}
} catch (InterruptedException | ExecutionException e) {
LOG.warn("Exception when egress actions for interface {}", interfaceName, e);
}
return actions;
}
use of org.opendaylight.yang.gen.v1.urn.opendaylight.table.types.rev131026.TunnelId in project netvirt by opendaylight.
the class DhcpPktHandler method onPacketReceived.
// TODO: Handle this in a separate thread
@Override
public void onPacketReceived(PacketReceived packet) {
if (!config.isControllerDhcpEnabled()) {
return;
}
Class<? extends PacketInReason> pktInReason = packet.getPacketInReason();
short tableId = packet.getTableId().getValue();
if ((tableId == NwConstants.DHCP_TABLE || tableId == NwConstants.DHCP_TABLE_EXTERNAL_TUNNEL) && isPktInReasonSendtoCtrl(pktInReason)) {
byte[] inPayload = packet.getPayload();
Ethernet ethPkt = new Ethernet();
try {
ethPkt.deserialize(inPayload, 0, inPayload.length * NetUtils.NUM_BITS_IN_A_BYTE);
} catch (PacketException e) {
LOG.warn("Failed to decode DHCP Packet.", e);
LOG.trace("Received packet {}", packet);
return;
}
DHCP pktIn;
pktIn = getDhcpPktIn(ethPkt);
if (pktIn != null) {
LOG.trace("DHCPPkt received: {}", pktIn);
LOG.trace("Received Packet: {}", packet);
BigInteger metadata = packet.getMatch().getMetadata().getMetadata();
long portTag = MetaDataUtil.getLportFromMetadata(metadata).intValue();
String macAddress = DHCPUtils.byteArrayToString(ethPkt.getSourceMACAddress());
BigInteger tunnelId = packet.getMatch().getTunnel() == null ? null : packet.getMatch().getTunnel().getTunnelId();
String interfaceName = getInterfaceNameFromTag(portTag);
InterfaceInfo interfaceInfo = interfaceManager.getInterfaceInfoFromOperationalDataStore(interfaceName);
if (interfaceInfo == null) {
LOG.error("Failed to get interface info for interface name {}", interfaceName);
return;
}
Port port;
if (tunnelId != null) {
port = dhcpExternalTunnelManager.readVniMacToPortCache(tunnelId, macAddress);
} else {
port = getNeutronPort(interfaceName);
}
Subnet subnet = getNeutronSubnet(port);
String serverMacAddress = interfaceInfo.getMacAddress();
String serverIp = null;
if (subnet != null) {
java.util.Optional<SubnetToDhcpPort> dhcpPortData = DhcpServiceUtils.getSubnetDhcpPortData(broker, subnet.getUuid().getValue());
/* If enable_dhcp_service flag was enabled and an ODL network DHCP Port data was made available use
* the ports Fixed IP as server IP for DHCP communication.
*/
if (dhcpPortData.isPresent()) {
serverIp = dhcpPortData.get().getPortFixedip();
serverMacAddress = dhcpPortData.get().getPortMacaddress();
} else {
// DHCP Neutron Port not found for this network
LOG.error("Neutron DHCP port is not available for the Subnet {} and port {}.", subnet.getUuid(), port.getUuid());
return;
}
}
DHCP replyPkt = handleDhcpPacket(pktIn, interfaceName, macAddress, port, subnet, serverIp);
if (replyPkt == null) {
LOG.warn("Unable to construct reply packet for interface name {}", interfaceName);
return;
}
byte[] pktOut = getDhcpPacketOut(replyPkt, ethPkt, serverMacAddress);
sendPacketOut(pktOut, interfaceInfo.getDpId(), interfaceName, tunnelId);
}
}
}
Aggregations