X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=blobdiff_plain;f=arputil%2Farputil-impl%2Fsrc%2Fmain%2Fjava%2Forg%2Fopendaylight%2Fgenius%2Farputil%2Finternal%2FArpUtilImpl.java;h=2237d735b72f247d57648d695cd6a42a74475023;hb=35a126394b12b72f918b5f272e1d067a1745f5e6;hp=91d3e260c448eacc9882abeb9ce33726260ad17c;hpb=af28cdfdf051260b815bbd7ac1c76a5699ed6ec2;p=genius.git diff --git a/arputil/arputil-impl/src/main/java/org/opendaylight/genius/arputil/internal/ArpUtilImpl.java b/arputil/arputil-impl/src/main/java/org/opendaylight/genius/arputil/internal/ArpUtilImpl.java index 91d3e260c..2237d735b 100644 --- a/arputil/arputil-impl/src/main/java/org/opendaylight/genius/arputil/internal/ArpUtilImpl.java +++ b/arputil/arputil-impl/src/main/java/org/opendaylight/genius/arputil/internal/ArpUtilImpl.java @@ -10,13 +10,14 @@ package org.opendaylight.genius.arputil.internal; import static com.google.common.base.Preconditions.checkArgument; import static com.google.common.base.Preconditions.checkNotNull; +import static java.util.Collections.emptyList; -import com.google.common.base.Optional; import com.google.common.util.concurrent.FutureCallback; import com.google.common.util.concurrent.Futures; -import com.google.common.util.concurrent.JdkFutureAdapters; import com.google.common.util.concurrent.ListenableFuture; +import com.google.common.util.concurrent.MoreExecutors; import com.google.common.util.concurrent.SettableFuture; +import java.io.UnsupportedEncodingException; import java.math.BigInteger; import java.net.InetAddress; import java.net.UnknownHostException; @@ -26,29 +27,31 @@ import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; import java.util.concurrent.Future; +import javax.annotation.Nonnull; +import javax.annotation.Nullable; import javax.inject.Inject; import javax.inject.Singleton; -import org.opendaylight.controller.liblldp.HexEncode; -import org.opendaylight.controller.liblldp.NetUtils; -import org.opendaylight.controller.liblldp.Packet; -import org.opendaylight.controller.liblldp.PacketException; import org.opendaylight.controller.md.sal.binding.api.DataBroker; import org.opendaylight.controller.md.sal.binding.api.NotificationPublishService; import org.opendaylight.controller.md.sal.binding.api.NotificationService; -import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType; +import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException; +import org.opendaylight.genius.arputil.api.ArpConstants; import org.opendaylight.genius.mdsalutil.MDSALUtil; import org.opendaylight.genius.mdsalutil.MetaDataUtil; import org.opendaylight.genius.mdsalutil.NWUtil; import org.opendaylight.genius.mdsalutil.packet.ARP; import org.opendaylight.genius.mdsalutil.packet.Ethernet; import org.opendaylight.infrautils.inject.AbstractLifecycle; +import org.opendaylight.infrautils.metrics.Meter; +import org.opendaylight.infrautils.metrics.MetricProvider; +import org.opendaylight.infrautils.utils.concurrent.Executors; +import org.opendaylight.openflowplugin.libraries.liblldp.HexEncode; +import org.opendaylight.openflowplugin.libraries.liblldp.NetUtils; +import org.opendaylight.openflowplugin.libraries.liblldp.Packet; +import org.opendaylight.openflowplugin.libraries.liblldp.PacketException; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IetfInetUtil; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.Interfaces; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.InterfacesState; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.InterfaceKey; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.PhysAddress; import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.Action; import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.arputil.rev160406.ArpRequestReceivedBuilder; @@ -60,7 +63,9 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.arputil.rev160406.Ma import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.arputil.rev160406.OdlArputilService; import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.arputil.rev160406.SendArpRequestInput; import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.arputil.rev160406.SendArpRequestInputBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.arputil.rev160406.SendArpRequestOutput; import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.arputil.rev160406.SendArpResponseInput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.arputil.rev160406.SendArpResponseOutput; import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.arputil.rev160406.interfaces.InterfaceAddress; import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetEgressActionsForInterfaceInputBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetEgressActionsForInterfaceOutput; @@ -70,7 +75,6 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpc import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetPortFromInterfaceInputBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetPortFromInterfaceOutput; import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.OdlInterfaceRpcService; -import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId; import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorRef; import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId; import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeRef; @@ -84,10 +88,11 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.packet.service.rev130709.Pa import org.opendaylight.yang.gen.v1.urn.opendaylight.packet.service.rev130709.PacketProcessingService; import org.opendaylight.yang.gen.v1.urn.opendaylight.packet.service.rev130709.PacketReceived; import org.opendaylight.yang.gen.v1.urn.opendaylight.packet.service.rev130709.SendToController; +import org.opendaylight.yang.gen.v1.urn.opendaylight.packet.service.rev130709.TransmitPacketInput; import org.opendaylight.yang.gen.v1.urn.opendaylight.packet.service.rev130709.TransmitPacketInputBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.packet.service.rev130709.TransmitPacketOutput; import org.opendaylight.yangtools.concepts.ListenerRegistration; import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; -import org.opendaylight.yangtools.yang.binding.InstanceIdentifier.InstanceIdentifierBuilder; import org.opendaylight.yangtools.yang.common.RpcError.ErrorType; import org.opendaylight.yangtools.yang.common.RpcResult; import org.opendaylight.yangtools.yang.common.RpcResultBuilder; @@ -97,38 +102,47 @@ import org.slf4j.LoggerFactory; @Singleton public class ArpUtilImpl extends AbstractLifecycle implements OdlArputilService, PacketProcessingListener { private static final Logger LOG = LoggerFactory.getLogger(ArpUtilImpl.class); + private static final String MODULENAME = "odl.genius.arputil."; + private static final String OPENFLOW_PFX = "openflow:"; + private final DataBroker dataBroker; private final PacketProcessingService packetProcessingService; private final NotificationPublishService notificationPublishService; private final NotificationService notificationService; private final OdlInterfaceRpcService odlInterfaceRpcService; - private ListenerRegistration listenerRegistration; - - private static final String FAILED_TO_GET_SRC_IP_FOR_INTERFACE = "Failed to get src ip for %s"; - private static final String FAILED_TO_GET_SRC_MAC_FOR_INTERFACE = "Failed to get src mac for interface %s iid %s "; - private static final String FAILED_TO_SEND_ARP_REQ_FOR_INTERFACE = "failed to send arp req for interface "; - private static final String UNKNOWN_IP_ADDRESS_SUPPLIED = "unknown ip address supplied"; - private static final String NODE_CONNECTOR_NOT_FOUND_ERROR = "Node connector id not found for interface %s"; - private static final String DPN_NOT_FOUND_ERROR = "dpn not found for interface %s "; - private static final short ARP_REQUEST_OP = (short) 1; - private static final short ARP_RESPONSE_OP = (short) 2; - private static final short ETH_TYPE_ARP = 0x0806; - - private final ExecutorService threadPool = Executors.newFixedThreadPool(1); - + private final ExecutorService threadPool = Executors.newFixedThreadPool(1, "ArpUtil", LOG); private final ConcurrentMap macsDB = new ConcurrentHashMap<>(); private final ConcurrentMap>> macAddrs = new ConcurrentHashMap<>(); + private final Meter arpRespRecvd; + private final Meter arpRespRecvdNotification; + private final Meter arpRespRecvdNotificationRejected; + private final Meter arpReqRecvd; + private final Meter arpReqRecvdNotification; + private final Meter arpReqRecvdNotificationRejected; + + @Inject public ArpUtilImpl(final DataBroker dataBroker, final PacketProcessingService packetProcessingService, - final NotificationPublishService notificationPublishService, final NotificationService notificationService, - final OdlInterfaceRpcService odlInterfaceRpcService) { + final NotificationPublishService notificationPublishService, + final NotificationService notificationService, + final OdlInterfaceRpcService odlInterfaceRpcService, + final MetricProvider metricProvider) { this.dataBroker = dataBroker; this.packetProcessingService = packetProcessingService; this.notificationPublishService = notificationPublishService; this.notificationService = notificationService; this.odlInterfaceRpcService = odlInterfaceRpcService; + + arpRespRecvd = metricProvider.newMeter(this,MODULENAME + "arpResponseReceived"); + arpRespRecvdNotification = metricProvider.newMeter(this,MODULENAME + "arpResponseReceivedNotification"); + arpRespRecvdNotificationRejected = metricProvider.newMeter(this, + MODULENAME + "arpResponseReceivedNotificationRejected"); + arpReqRecvd = metricProvider.newMeter(this,MODULENAME + "arpRequestReceived"); + arpReqRecvdNotification = metricProvider.newMeter(this,MODULENAME + "arpRequestReceivedNotification"); + arpReqRecvdNotificationRejected = metricProvider.newMeter(this, + MODULENAME + "arpRequestReceivedNotificationRejected"); } @Override @@ -152,7 +166,7 @@ public class ArpUtilImpl extends AbstractLifecycle implements OdlArputilService, } @Override - public Future> getMac(GetMacInput input) { + public ListenableFuture> getMac(GetMacInput input) { try { final String dstIpAddress = getIpAddressInString(input.getIpaddress()); LOG.trace("getMac rpc invoked for ip {}", dstIpAddress); @@ -164,23 +178,22 @@ public class ArpUtilImpl extends AbstractLifecycle implements OdlArputilService, } SendArpRequestInputBuilder builder = new SendArpRequestInputBuilder() .setInterfaceAddress(input.getInterfaceAddress()).setIpaddress(input.getIpaddress()); - Future> arpReqFt = sendArpRequest(builder.build()); + ListenableFuture> arpReqFt = sendArpRequest(builder.build()); final SettableFuture> ft = SettableFuture.create(); - Futures.addCallback(JdkFutureAdapters.listenInPoolThread(arpReqFt, threadPool), - new FutureCallback>() { - @Override - public void onFailure(Throwable ex) { - RpcResultBuilder resultBuilder = RpcResultBuilder.failed() - .withError(ErrorType.APPLICATION, ex.getMessage(), ex); - ft.set(resultBuilder.build()); - } - - @Override - public void onSuccess(RpcResult result) { - LOG.trace("Successfully sent the arp pkt out for ip {}", dstIpAddress); - } - }); + Futures.addCallback(arpReqFt, new FutureCallback>() { + @Override + public void onFailure(Throwable ex) { + RpcResultBuilder resultBuilder = RpcResultBuilder.failed() + .withError(ErrorType.APPLICATION, ex.getMessage(), ex); + ft.set(resultBuilder.build()); + } + + @Override + public void onSuccess(RpcResult result) { + LOG.trace("Successfully sent the arp pkt out for ip {}", dstIpAddress); + } + }, MoreExecutors.directExecutor()); macAddrs.put(dstIpAddress, ft); return ft; @@ -197,42 +210,41 @@ public class ArpUtilImpl extends AbstractLifecycle implements OdlArputilService, } @Override - public Future> sendArpRequest(SendArpRequestInput arpReqInput) { + public ListenableFuture> sendArpRequest(SendArpRequestInput arpReqInput) { LOG.trace("rpc sendArpRequest invoked for ip {}", arpReqInput.getIpaddress()); BigInteger dpnId; byte[] payload; String interfaceName = null; byte[] srcIpBytes; - byte[] dstIpBytes = null; - byte[] srcMac = null; + byte[] dstIpBytes; + byte[] srcMac; - RpcResultBuilder failureBuilder = RpcResultBuilder.failed(); - RpcResultBuilder successBuilder = RpcResultBuilder.success(); + RpcResultBuilder failureBuilder = RpcResultBuilder.failed(); + RpcResultBuilder successBuilder = RpcResultBuilder.success(); try { dstIpBytes = getIpAddressBytes(arpReqInput.getIpaddress()); } catch (UnknownHostException e) { LOG.error("Cannot get IP address", e); - failureBuilder.withError(ErrorType.APPLICATION, UNKNOWN_IP_ADDRESS_SUPPLIED); + failureBuilder.withError(ErrorType.APPLICATION, ArpConstants.UNKNOWN_IP_ADDRESS_SUPPLIED); return Futures.immediateFuture(failureBuilder.build()); } int localErrorCount = 0; - for (InterfaceAddress interfaceAddress : arpReqInput.getInterfaceAddress()) { + for (InterfaceAddress interfaceAddress : nullToEmpty(arpReqInput.getInterfaceAddress())) { try { interfaceName = interfaceAddress.getInterface(); srcIpBytes = getIpAddressBytes(interfaceAddress.getIpAddress()); - NodeConnectorId id = getNodeConnectorFromInterfaceName(interfaceName); - GetPortFromInterfaceOutput portResult = getPortFromInterface(interfaceName); checkNotNull(portResult); dpnId = portResult.getDpid(); Long portid = portResult.getPortno(); - checkArgument(null != dpnId && BigInteger.ZERO != dpnId, DPN_NOT_FOUND_ERROR, interfaceName); + checkArgument(null != dpnId && !BigInteger.ZERO.equals(dpnId), + ArpConstants.DPN_NOT_FOUND_ERROR, interfaceName); NodeConnectorRef ref = MDSALUtil.getNodeConnRef(dpnId, portid.toString()); - checkNotNull(ref, NODE_CONNECTOR_NOT_FOUND_ERROR, interfaceName); + checkNotNull(ref, ArpConstants.NODE_CONNECTOR_NOT_FOUND_ERROR, interfaceName); LOG.trace("sendArpRequest received dpnId {} out interface {}", dpnId, interfaceName); if (interfaceAddress.getMacaddress() == null) { @@ -242,23 +254,24 @@ public class ArpUtilImpl extends AbstractLifecycle implements OdlArputilService, String macAddr = interfaceAddress.getMacaddress().getValue(); srcMac = HexEncode.bytesFromHexString(macAddr); } - checkNotNull(srcMac, FAILED_TO_GET_SRC_MAC_FOR_INTERFACE, interfaceName, ref.getValue()); - checkNotNull(srcIpBytes, FAILED_TO_GET_SRC_IP_FOR_INTERFACE, interfaceName); + checkNotNull(srcMac, ArpConstants.FAILED_TO_GET_SRC_MAC_FOR_INTERFACE, interfaceName, ref.getValue()); + checkNotNull(srcIpBytes, ArpConstants.FAILED_TO_GET_SRC_IP_FOR_INTERFACE, interfaceName); - payload = ArpPacketUtil.getPayload(ARP_REQUEST_OP, srcMac, srcIpBytes, + payload = ArpPacketUtil.getPayload(ArpConstants.ARP_REQUEST_OP, srcMac, srcIpBytes, ArpPacketUtil.ETHERNET_BROADCAST_DESTINATION, dstIpBytes); List actions = getEgressAction(interfaceName); sendPacketOutWithActions(dpnId, payload, ref, actions); LOG.trace("sent arp request for {}", arpReqInput.getIpaddress()); - } catch (UnknownHostException | PacketException | InterruptedException | ExecutionException e) { + } catch (UnknownHostException | PacketException | InterruptedException | ExecutionException + | ReadFailedException e) { LOG.trace("failed to send arp req for {} on interface {}", arpReqInput.getIpaddress(), interfaceName); - failureBuilder.withError(ErrorType.APPLICATION, FAILED_TO_SEND_ARP_REQ_FOR_INTERFACE + interfaceName, - e); - successBuilder.withError(ErrorType.APPLICATION, FAILED_TO_SEND_ARP_REQ_FOR_INTERFACE + interfaceName, - e); + failureBuilder.withError(ErrorType.APPLICATION, + ArpConstants.FAILED_TO_SEND_ARP_REQ_FOR_INTERFACE + interfaceName, e); + successBuilder.withError(ErrorType.APPLICATION, + ArpConstants.FAILED_TO_SEND_ARP_REQ_FOR_INTERFACE + interfaceName, e); localErrorCount++; } } @@ -269,23 +282,24 @@ public class ArpUtilImpl extends AbstractLifecycle implements OdlArputilService, return Futures.immediateFuture(successBuilder.build()); } - public Future> sendPacketOut(BigInteger dpnId, byte[] payload, NodeConnectorRef ref) { - + public ListenableFuture> sendPacketOut( + BigInteger dpnId, byte[] payload, NodeConnectorRef ref) { NodeConnectorRef nodeConnectorRef = MDSALUtil.getNodeConnRef(dpnId, "0xfffffffd"); return packetProcessingService.transmitPacket(new TransmitPacketInputBuilder().setPayload(payload) .setNode(new NodeRef(InstanceIdentifier.builder(Nodes.class) - .child(Node.class, new NodeKey(new NodeId("openflow:" + dpnId))).toInstance())) + .child(Node.class, new NodeKey(new NodeId(OPENFLOW_PFX + dpnId))).build())) .setIngress(nodeConnectorRef).setEgress(ref).build()); } - public Future> sendPacketOutWithActions(BigInteger dpnId, byte[] payload, NodeConnectorRef ref, - List actions) { - + private Future> sendPacketOutWithActions( + BigInteger dpnId, byte[] payload, NodeConnectorRef ref, List actions) { NodeConnectorRef nodeConnectorRef = MDSALUtil.getNodeConnRef(dpnId, "0xfffffffd"); - return packetProcessingService.transmitPacket(new TransmitPacketInputBuilder().setPayload(payload) + TransmitPacketInput transmitPacketInput = new TransmitPacketInputBuilder().setPayload(payload) .setNode(new NodeRef(InstanceIdentifier.builder(Nodes.class) - .child(Node.class, new NodeKey(new NodeId("openflow:" + dpnId))).toInstance())) - .setIngress(nodeConnectorRef).setEgress(ref).setAction(actions).build()); + .child(Node.class, new NodeKey(new NodeId(OPENFLOW_PFX + dpnId))).build())) + .setIngress(nodeConnectorRef).setEgress(ref).setAction(actions).build(); + LOG.trace("PacketOut message framed for transmitting {}", transmitPacketInput); + return packetProcessingService.transmitPacket(transmitPacketInput); } private List getEgressAction(String interfaceName) { @@ -315,7 +329,7 @@ public class ArpUtilImpl extends AbstractLifecycle implements OdlArputilService, } @Override - public Future> sendArpResponse(SendArpResponseInput input) { + public ListenableFuture> sendArpResponse(SendArpResponseInput input) { LOG.trace("sendArpResponse rpc invoked"); BigInteger dpnId; byte[] payload; @@ -328,22 +342,23 @@ public class ArpUtilImpl extends AbstractLifecycle implements OdlArputilService, dpnId = portResult.getDpid(); Long portid = portResult.getPortno(); NodeConnectorRef ref = MDSALUtil.getNodeConnRef(dpnId, portid.toString()); - checkArgument(null != dpnId && BigInteger.ZERO != dpnId, DPN_NOT_FOUND_ERROR, interfaceName); - checkNotNull(ref, NODE_CONNECTOR_NOT_FOUND_ERROR, interfaceName); + checkArgument(null != dpnId && !BigInteger.ZERO.equals(dpnId), + ArpConstants.DPN_NOT_FOUND_ERROR, interfaceName); + checkNotNull(ref, ArpConstants.NODE_CONNECTOR_NOT_FOUND_ERROR, interfaceName); LOG.trace("sendArpRequest received dpnId {} out interface {}", dpnId, interfaceName); byte[] srcIpBytes = getIpAddressBytes(input.getSrcIpaddress()); byte[] dstIpBytes = getIpAddressBytes(input.getDstIpaddress()); if (input.getSrcMacaddress() == null) { - srcMac = portResult.getPhyAddress().getBytes(); + srcMac = portResult.getPhyAddress().getBytes("UTF-8"); } else { String macAddr = input.getSrcMacaddress().getValue(); srcMac = HexEncode.bytesFromHexString(macAddr); } byte[] dstMac = NWUtil.parseMacAddress(input.getDstMacaddress().getValue()); - checkNotNull(srcIpBytes, FAILED_TO_GET_SRC_IP_FOR_INTERFACE, interfaceName); - payload = ArpPacketUtil.getPayload(ARP_RESPONSE_OP, srcMac, srcIpBytes, dstMac, dstIpBytes); + checkNotNull(srcIpBytes, ArpConstants.FAILED_TO_GET_SRC_IP_FOR_INTERFACE, interfaceName); + payload = ArpPacketUtil.getPayload(ArpConstants.ARP_RESPONSE_OP, srcMac, srcIpBytes, dstMac, dstIpBytes); List actions = getEgressAction(interfaceName); sendPacketOutWithActions(dpnId, payload, ref, actions); @@ -351,11 +366,13 @@ public class ArpUtilImpl extends AbstractLifecycle implements OdlArputilService, input.getSrcIpaddress().getIpv4Address().getValue(), HexEncode.bytesToHexStringFormat(srcMac), HexEncode.bytesToHexStringFormat(dstMac), input.getDstIpaddress().getIpv4Address().getValue(), dpnId); - } catch (UnknownHostException | PacketException | InterruptedException | ExecutionException e) { + } catch (UnknownHostException | PacketException | InterruptedException | UnsupportedEncodingException + | ExecutionException e) { LOG.error("failed to send arp response for {}: ", input.getSrcIpaddress(), e); - return RpcResultBuilder.failed().withError(ErrorType.APPLICATION, e.getMessage(), e).buildFuture(); + return RpcResultBuilder.failed() + .withError(ErrorType.APPLICATION, e.getMessage(), e).buildFuture(); } - RpcResultBuilder rpcResultBuilder = RpcResultBuilder.success(); + RpcResultBuilder rpcResultBuilder = RpcResultBuilder.success(); return Futures.immediateFuture(rpcResultBuilder.build()); } @@ -365,15 +382,15 @@ public class ArpUtilImpl extends AbstractLifecycle implements OdlArputilService, LOG.trace("Packet Received {}", packetReceived); if (pktInReason == SendToController.class) { - try { + BigInteger dpnId = extractDpnId(packetReceived); int tableId = packetReceived.getTableId().getValue(); byte[] data = packetReceived.getPayload(); Ethernet ethernet = new Ethernet(); - ethernet.deserialize(data, 0, data.length * NetUtils.NumBitsInAByte); - if (ethernet.getEtherType() != ETH_TYPE_ARP) { + ethernet.deserialize(data, 0, data.length * NetUtils.NUM_BITS_IN_A_BYTE); + if (ethernet.getEtherType() != ArpConstants.ETH_TYPE_ARP) { return; } @@ -381,31 +398,25 @@ public class ArpUtilImpl extends AbstractLifecycle implements OdlArputilService, ARP arp = (ARP) pkt; InetAddress srcInetAddr = InetAddress.getByAddress(arp.getSenderProtocolAddress()); InetAddress dstInetAddr = InetAddress.getByAddress(arp.getTargetProtocolAddress()); - InetAddress addr = srcInetAddr; - // For GARP learn target IP - if (srcInetAddr.getHostAddress().equalsIgnoreCase(dstInetAddr.getHostAddress())) { - addr = dstInetAddr; - } byte[] srcMac = ethernet.getSourceMACAddress(); - - NodeConnectorRef ref = packetReceived.getIngress(); + byte[] dstMac = ethernet.getDestinationMACAddress(); Metadata metadata = packetReceived.getMatch().getMetadata(); - String interfaceName = getInterfaceName(ref, metadata, dataBroker); + String interfaceName = getInterfaceName(metadata); checkAndFireMacChangedNotification(interfaceName, srcInetAddr, srcMac); macsDB.put(interfaceName + "-" + srcInetAddr.getHostAddress(), NWUtil.toStringMacAddress(srcMac)); - if (arp.getOpCode() == ARP_REQUEST_OP) { - fireArpReqRecvdNotification(interfaceName, srcInetAddr, srcMac, dstInetAddr, tableId, + if (arp.getOpCode() == ArpConstants.ARP_REQUEST_OP) { + fireArpReqRecvdNotification(interfaceName, srcInetAddr, srcMac, dstInetAddr, dpnId, tableId, metadata.getMetadata()); } else { - fireArpRespRecvdNotification(interfaceName, srcInetAddr, srcMac, tableId, metadata.getMetadata()); + fireArpRespRecvdNotification(interfaceName, srcInetAddr, srcMac, dpnId, tableId, + metadata.getMetadata(), dstInetAddr, dstMac); } if (macAddrs.get(srcInetAddr.getHostAddress()) != null) { - threadPool.submit(new MacResponderTask(arp)); + threadPool.execute(new MacResponderTask(arp)); } - } catch (PacketException | UnknownHostException | InterruptedException | ExecutionException e) { LOG.trace("Failed to decode packet", e); } @@ -427,7 +438,7 @@ public class ArpUtilImpl extends AbstractLifecycle implements OdlArputilService, return result; } - private String getInterfaceName(NodeConnectorRef ref, Metadata metadata, DataBroker dataBroker2) + private String getInterfaceName(Metadata metadata) throws InterruptedException, ExecutionException { LOG.debug("metadata received is {} ", metadata); @@ -443,8 +454,8 @@ public class ArpUtilImpl extends AbstractLifecycle implements OdlArputilService, return interfaceFromIfIndexOutput.getInterfaceName(); } - class MacResponderTask implements Runnable { - ARP arp; + private class MacResponderTask implements Runnable { + final ARP arp; MacResponderTask(ARP arp) { this.arp = arp; @@ -455,80 +466,84 @@ public class ArpUtilImpl extends AbstractLifecycle implements OdlArputilService, InetAddress srcAddr; GetMacOutputBuilder outputBuilder; String srcMac; - SettableFuture> future = null; - RpcResultBuilder resultBuilder; try { srcAddr = InetAddress.getByAddress(arp.getSenderProtocolAddress()); srcMac = NWUtil.toStringMacAddress(arp.getSenderHardwareAddress()); - future = macAddrs.remove(srcAddr.getHostAddress()); + SettableFuture> future = macAddrs.remove(srcAddr.getHostAddress()); if (future == null) { LOG.trace("There are no pending mac requests."); return; } outputBuilder = new GetMacOutputBuilder().setMacaddress(new PhysAddress(srcMac)); - resultBuilder = RpcResultBuilder.success(outputBuilder.build()); + future.set(RpcResultBuilder.success(outputBuilder.build()).build()); if (LOG.isTraceEnabled()) { LOG.trace("sent the mac response for ip {}", srcAddr.getHostAddress()); } } catch (UnknownHostException e) { LOG.error("failed to send mac response", e); - resultBuilder = RpcResultBuilder.failed().withError(ErrorType.APPLICATION, e.getMessage(), - e); } - future.set(resultBuilder.build()); } } - private void fireArpRespRecvdNotification(String interfaceName, InetAddress inetAddr, byte[] macAddressBytes, - int tableId, BigInteger metadata) throws InterruptedException { - ArpUtilCounters.arp_res_rcv.inc(); - - IpAddress ip = new IpAddress(inetAddr.getHostAddress().toCharArray()); - String macAddress = NWUtil.toStringMacAddress(macAddressBytes); - PhysAddress mac = new PhysAddress(macAddress); + private void fireArpRespRecvdNotification(String interfaceName, InetAddress srcInetAddr, byte[] srcMacAddressBytes, + BigInteger dpnId, int tableId, BigInteger metadata, InetAddress dstInetAddr, byte[] dstMacAddressBytes) + throws InterruptedException { + arpRespRecvd.mark(); + + IpAddress srcIp = IetfInetUtil.INSTANCE.ipAddressFor(srcInetAddr); + IpAddress dstIp = IetfInetUtil.INSTANCE.ipAddressFor(dstInetAddr); + String srcMacAddress = NWUtil.toStringMacAddress(srcMacAddressBytes); + PhysAddress srcMac = new PhysAddress(srcMacAddress); + String dstMacAddress = NWUtil.toStringMacAddress(dstMacAddressBytes); + PhysAddress dstMac = new PhysAddress(dstMacAddress); ArpResponseReceivedBuilder builder = new ArpResponseReceivedBuilder(); builder.setInterface(interfaceName); - builder.setIpaddress(ip); + builder.setSrcIpaddress(srcIp); + builder.setDpnId(dpnId); builder.setOfTableId((long) tableId); - builder.setMacaddress(mac); + builder.setSrcMac(srcMac); builder.setMetadata(metadata); + builder.setDstIpaddress(dstIp); + builder.setDstMac(dstMac); ListenableFuture offerNotification = notificationPublishService.offerNotification(builder.build()); if (offerNotification != null && offerNotification.equals(NotificationPublishService.REJECTED)) { - ArpUtilCounters.arp_res_rcv_notification_rejected.inc(); + arpRespRecvdNotificationRejected.mark(); + } else { - ArpUtilCounters.arp_res_rcv_notification.inc(); + arpRespRecvdNotification.mark(); } } private void fireArpReqRecvdNotification(String interfaceName, InetAddress srcInetAddr, byte[] srcMac, - InetAddress dstInetAddr, int tableId, BigInteger metadata) throws InterruptedException { - ArpUtilCounters.arp_req_rcv.inc(); + InetAddress dstInetAddr, BigInteger dpnId, int tableId, BigInteger metadata) throws InterruptedException { + arpReqRecvd.mark(); String macAddress = NWUtil.toStringMacAddress(srcMac); ArpRequestReceivedBuilder builder = new ArpRequestReceivedBuilder(); builder.setInterface(interfaceName); + builder.setDpnId(dpnId); builder.setOfTableId((long) tableId); - builder.setSrcIpaddress(new IpAddress(srcInetAddr.getHostAddress().toCharArray())); - builder.setDstIpaddress(new IpAddress(dstInetAddr.getHostAddress().toCharArray())); + builder.setSrcIpaddress(IetfInetUtil.INSTANCE.ipAddressFor(srcInetAddr)); + builder.setDstIpaddress(IetfInetUtil.INSTANCE.ipAddressFor(dstInetAddr)); builder.setSrcMac(new PhysAddress(macAddress)); builder.setMetadata(metadata); ListenableFuture offerNotification = notificationPublishService.offerNotification(builder.build()); if (offerNotification != null && offerNotification.equals(NotificationPublishService.REJECTED)) { - ArpUtilCounters.arp_req_rcv_notification_rejected.inc(); + arpReqRecvdNotificationRejected.mark(); } else { - ArpUtilCounters.arp_req_rcv_notification.inc(); + arpReqRecvdNotification.mark(); } } private void checkAndFireMacChangedNotification(String interfaceName, InetAddress inetAddr, byte[] macAddressBytes) throws InterruptedException { - IpAddress ip = new IpAddress(inetAddr.getHostAddress().toCharArray()); + IpAddress ip = IetfInetUtil.INSTANCE.ipAddressFor(inetAddr); String macAddress = NWUtil.toStringMacAddress(macAddressBytes); PhysAddress mac = new PhysAddress(macAddress); if (!macAddress.equals(macsDB.get(interfaceName + "-" + inetAddr.getHostAddress()))) { if (LOG.isTraceEnabled()) { - LOG.trace("mac address changed for " + inetAddr); + LOG.trace("mac address changed for {}", inetAddr); } MacChangedBuilder builder = new MacChangedBuilder(); builder.setInterface(interfaceName); @@ -538,35 +553,21 @@ public class ArpUtilImpl extends AbstractLifecycle implements OdlArputilService, } } - private InstanceIdentifier buildInterfaceId(String interfaceName) { - InstanceIdentifierBuilder idBuilder = InstanceIdentifier.builder(Interfaces.class) - .child(Interface.class, new InterfaceKey(interfaceName)); - return idBuilder.build(); - } + private BigInteger extractDpnId(PacketReceived packetReceived) { + NodeKey nodeKey = packetReceived.getIngress().getValue().firstKeyOf(Node.class); + String nodeKeyString = nodeKey.getId().getValue(); - private NodeConnectorId getNodeConnectorFromInterfaceName(String interfaceName) { - InstanceIdentifierBuilder idBuilder = InstanceIdentifier.builder(InterfacesState.class) - .child(org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508 - .interfaces.state.Interface.class, new org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf - .interfaces.rev140508.interfaces.state.InterfaceKey(interfaceName)); - - InstanceIdentifier ifStateId = idBuilder.build(); - - Optional ifStateOptional = MDSALUtil - .read(dataBroker, LogicalDatastoreType.OPERATIONAL, ifStateId); - - if (ifStateOptional.isPresent()) { - org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508 - .interfaces.state.Interface ifState = ifStateOptional - .get(); - List lowerLayerIf = ifState.getLowerLayerIf(); - if (!lowerLayerIf.isEmpty()) { - return new NodeConnectorId(lowerLayerIf.get(0)); - } + if (!nodeKeyString.startsWith(OPENFLOW_PFX)) { + LOG.warn("Could not extract DPN for packet-in, doesn't start with 'openflow:' {}", packetReceived); + return null; } - return null; + + return new BigInteger(nodeKeyString.substring(OPENFLOW_PFX.length())); + } + + // TODO Replace this with mdsal's DataObjectUtils.nullToEmpty when upgrading to mdsal 3.0.2 + @Nonnull + public static List nullToEmpty(final @Nullable List input) { + return input != null ? input : emptyList(); } }