2 * Copyright (c) 2016 Ericsson India Global Services Pvt Ltd. and others. All rights reserved.
4 * This program and the accompanying materials are made available under the
5 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6 * and is available at http://www.eclipse.org/legal/epl-v10.html
9 package org.opendaylight.genius.arputil.internal;
11 import com.google.common.base.Optional;
12 import com.google.common.util.concurrent.FutureCallback;
13 import com.google.common.util.concurrent.Futures;
14 import com.google.common.util.concurrent.JdkFutureAdapters;
15 import com.google.common.util.concurrent.SettableFuture;
17 import org.opendaylight.controller.liblldp.HexEncode;
18 import org.opendaylight.controller.liblldp.NetUtils;
19 import org.opendaylight.controller.liblldp.Packet;
20 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
21 import org.opendaylight.controller.md.sal.binding.api.NotificationPublishService;
22 import org.opendaylight.controller.md.sal.binding.api.NotificationService;
23 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
24 import org.opendaylight.controller.sal.binding.api.RpcProviderRegistry;
25 import org.opendaylight.genius.mdsalutil.MDSALUtil;
26 import org.opendaylight.genius.mdsalutil.MetaDataUtil;
27 import org.opendaylight.genius.mdsalutil.NWUtil;
28 import org.opendaylight.genius.mdsalutil.interfaces.IMdsalApiManager;
29 import org.opendaylight.genius.mdsalutil.packet.ARP;
30 import org.opendaylight.genius.mdsalutil.packet.Ethernet;
31 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
32 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.Interfaces;
33 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.InterfacesState;
34 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface;
35 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.InterfaceKey;
36 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.PhysAddress;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.Action;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.arputil.rev160406.ArpRequestReceivedBuilder;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.arputil.rev160406.ArpResponseReceivedBuilder;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.arputil.rev160406.GetMacInput;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.arputil.rev160406.GetMacOutput;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.arputil.rev160406.GetMacOutputBuilder;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.arputil.rev160406.MacChangedBuilder;
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.arputil.rev160406.OdlArputilService;
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.arputil.rev160406.SendArpRequestInput;
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.arputil.rev160406.SendArpRequestInputBuilder;
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.arputil.rev160406.SendArpResponseInput;
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.arputil.rev160406.interfaces.InterfaceAddress;
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetEgressActionsForInterfaceInputBuilder;
50 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetEgressActionsForInterfaceOutput;
51 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetPortFromInterfaceInputBuilder;
52 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetInterfaceFromIfIndexInput;
53 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetInterfaceFromIfIndexOutput;
54 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetInterfaceFromIfIndexInputBuilder;
55 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetPortFromInterfaceOutput;
56 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.OdlInterfaceRpcService;
57 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId;
58 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorRef;
59 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes;
60 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeRef;
61 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
62 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnector;
63 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
64 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey;
65 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.Metadata;
66 import org.opendaylight.yang.gen.v1.urn.opendaylight.packet.service.rev130709.PacketInReason;
67 import org.opendaylight.yang.gen.v1.urn.opendaylight.packet.service.rev130709.PacketProcessingListener;
68 import org.opendaylight.yang.gen.v1.urn.opendaylight.packet.service.rev130709.PacketProcessingService;
69 import org.opendaylight.yang.gen.v1.urn.opendaylight.packet.service.rev130709.PacketReceived;
70 import org.opendaylight.yang.gen.v1.urn.opendaylight.packet.service.rev130709.SendToController;
71 import org.opendaylight.yang.gen.v1.urn.opendaylight.packet.service.rev130709.TransmitPacketInputBuilder;
72 import org.opendaylight.yangtools.concepts.ListenerRegistration;
73 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
74 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier.InstanceIdentifierBuilder;
75 import org.opendaylight.yangtools.yang.common.RpcError.ErrorType;
76 import org.opendaylight.yangtools.yang.common.RpcResult;
77 import org.opendaylight.yangtools.yang.common.RpcResultBuilder;
78 import org.slf4j.Logger;
79 import org.slf4j.LoggerFactory;
81 import java.math.BigInteger;
82 import java.net.InetAddress;
83 import java.net.UnknownHostException;
84 import java.util.ArrayList;
85 import java.util.List;
86 import java.util.concurrent.ConcurrentHashMap;
87 import java.util.concurrent.ConcurrentMap;
88 import java.util.concurrent.ExecutionException;
89 import java.util.concurrent.ExecutorService;
90 import java.util.concurrent.Executors;
91 import java.util.concurrent.Future;
93 import static com.google.common.base.Preconditions.checkArgument;
94 import static com.google.common.base.Preconditions.checkNotNull;
96 public class ArpUtilImpl implements OdlArputilService,
97 PacketProcessingListener, AutoCloseable {
99 private static final String FAILED_TO_GET_SRC_IP_FOR_INTERFACE = "Failed to get src ip for %s";
101 private static final String FAILED_TO_GET_SRC_MAC_FOR_INTERFACE = "Failed to get src mac for interface %s iid %s ";
103 private static final String FAILED_TO_SEND_ARP_REQ_FOR_INTERFACE = "failed to send arp req for interface ";
105 private static final String UNKNOWN_IP_ADDRESS_SUPPLIED = "unknown ip address supplied";
107 private static final String NODE_CONNECTOR_NOT_FOUND_ERROR = "Node connector id not found for interface %s";
109 private static final String DPN_NOT_FOUND_ERROR = "dpn not found for interface %s ";
111 private static final short ARP_REQUEST_OP = (short) 1;
113 private static final short ARP_RESPONSE_OP = (short) 2;
115 private static final short ETH_TYPE_ARP = 0x0806;
117 private static final Logger LOGGER = LoggerFactory
118 .getLogger(ArpUtilImpl.class);
120 static OdlInterfaceRpcService intfRpc;
122 ExecutorService threadPool = Executors.newFixedThreadPool(1);
124 DataBroker dataBroker;
125 PacketProcessingService packetProcessingService;
126 NotificationPublishService notificationPublishService;
127 NotificationService notificationService;
128 IMdsalApiManager mdsalMgr;
130 RpcProviderRegistry rpc;
131 ListenerRegistration<ArpUtilImpl> listenerRegistration;
133 ConcurrentMap<String, String> macsDB = new ConcurrentHashMap<>();
134 ConcurrentMap<String, SettableFuture<RpcResult<GetMacOutput>>> getMacFutures = new ConcurrentHashMap<>();
136 public ArpUtilImpl(DataBroker db,
137 PacketProcessingService packetProcessingService,
138 NotificationPublishService notificationPublishService,
139 NotificationService notificationService,
140 IMdsalApiManager mdsalApiManager,
141 RpcProviderRegistry rpc) {
143 this.dataBroker = db;
144 this.packetProcessingService = packetProcessingService;
145 this.notificationPublishService = notificationPublishService;
146 this.mdsalMgr = mdsalApiManager;
147 this.notificationService = notificationService;
149 listenerRegistration = notificationService
150 .registerNotificationListener(this);
151 LOGGER.info("ArpUtil Manager Initialized ");
154 OdlInterfaceRpcService getInterfaceRpcService() {
155 if (intfRpc == null ) {
156 intfRpc = rpc.getRpcService(OdlInterfaceRpcService.class);
162 public void close() throws Exception {
163 listenerRegistration.close();
164 LOGGER.trace("ArpUtil manager Closed");
167 String getIpAddressInString(IpAddress ipAddress)
168 throws UnknownHostException {
169 return InetAddress.getByName(ipAddress.getIpv4Address().getValue()).getHostAddress();
173 public Future<RpcResult<GetMacOutput>> getMac(GetMacInput input) {
176 final String dstIpAddress = getIpAddressInString(input.getIpaddress());
177 if (LOGGER.isTraceEnabled()) {
178 LOGGER.trace("getMac rpc invoked for ip " + dstIpAddress);
180 if (getMacFutures.get(dstIpAddress) != null) {
181 if (LOGGER.isInfoEnabled()) {
182 LOGGER.info("get mac already in progress for the ip "
185 return getMacFutures.get(dstIpAddress);
187 SendArpRequestInputBuilder builder = new SendArpRequestInputBuilder()
188 .setInterfaceAddress(input.getInterfaceAddress())
189 .setIpaddress(input.getIpaddress());
190 Future<RpcResult<Void>> arpReqFt = sendArpRequest(builder.build());
191 final SettableFuture<RpcResult<GetMacOutput>> ft = SettableFuture
195 JdkFutureAdapters.listenInPoolThread(arpReqFt, threadPool),
196 new FutureCallback<RpcResult<Void>>() {
198 public void onFailure(Throwable e) {
199 RpcResultBuilder<GetMacOutput> resultBuilder = RpcResultBuilder
200 .<GetMacOutput> failed().withError(
201 ErrorType.APPLICATION,
203 ft.set(resultBuilder.build());
207 public void onSuccess(RpcResult<Void> result) {
208 LOGGER.trace("Successfully sent the arp pkt out for ip "
213 getMacFutures.put(dstIpAddress, ft);
215 } catch (Exception e) {
216 LOGGER.trace("failed to handle getMac request for {} {}",
217 input.getIpaddress(), e);
218 RpcResultBuilder<GetMacOutput> resultBuilder = RpcResultBuilder
219 .<GetMacOutput> failed().withError(ErrorType.APPLICATION,
221 return Futures.immediateFuture(resultBuilder.build());
225 byte[] getIpAddressBytes(IpAddress ip) throws UnknownHostException {
226 return InetAddress.getByName(ip.getIpv4Address().getValue())
231 public Future<RpcResult<Void>> sendArpRequest(
232 SendArpRequestInput arpReqInput) {
233 if (LOGGER.isTraceEnabled()) {
234 LOGGER.trace("rpc sendArpRequest invoked for ip "
235 + arpReqInput.getIpaddress());
240 String interfaceName = null;
242 byte[] dstIpBytes = null;
243 byte[] srcMac = null;
245 RpcResultBuilder<Void> failureBuilder = RpcResultBuilder
247 RpcResultBuilder<Void> successBuilder = RpcResultBuilder
251 dstIpBytes = getIpAddressBytes(arpReqInput.getIpaddress());
252 } catch (Exception e) {
253 failureBuilder.withError(ErrorType.APPLICATION,
254 UNKNOWN_IP_ADDRESS_SUPPLIED);
255 return Futures.immediateFuture(failureBuilder.build());
258 int localErrorCount = 0;
259 for (InterfaceAddress interfaceAddress : arpReqInput
260 .getInterfaceAddress()) {
262 interfaceName = interfaceAddress.getInterface();
263 srcIpBytes = getIpAddressBytes(interfaceAddress.getIpAddress());
265 NodeConnectorId id = getNodeConnectorFromInterfaceName(interfaceName);
267 GetPortFromInterfaceOutput portResult = getPortFromInterface(interfaceName);
268 checkNotNull(portResult);
269 dpnId = portResult.getDpid();
270 Long portid = portResult.getPortno();
271 checkArgument(null != dpnId && BigInteger.ZERO != dpnId,
272 DPN_NOT_FOUND_ERROR, interfaceName);
274 NodeConnectorRef ref = MDSALUtil.getNodeConnRef(dpnId,
276 checkNotNull(ref, NODE_CONNECTOR_NOT_FOUND_ERROR, interfaceName);
278 if (LOGGER.isTraceEnabled()) {
280 "sendArpRequest received dpnId {} out interface {}",
281 dpnId, interfaceName);
283 if (interfaceAddress.getMacaddress() == null) {
284 srcMac = MDSALUtil.getMacAddressForNodeConnector(
286 (InstanceIdentifier<NodeConnector>) ref.getValue());
288 String macAddr = interfaceAddress.getMacaddress().getValue();
289 srcMac = HexEncode.bytesFromHexString(macAddr);
292 checkNotNull(srcMac, FAILED_TO_GET_SRC_MAC_FOR_INTERFACE,
293 interfaceName, ref.getValue());
294 checkNotNull(srcIpBytes, FAILED_TO_GET_SRC_IP_FOR_INTERFACE,
297 payload = ArpPacketUtil.getPayload(ARP_REQUEST_OP, srcMac,
298 srcIpBytes, ArpPacketUtil.EthernetDestination_Broadcast,
301 List<Action> actions = getEgressAction(interfaceName);
302 sendPacketOutWithActions(dpnId, payload, ref, actions);
304 if (LOGGER.isTraceEnabled()) {
305 LOGGER.trace("sent arp request for "
306 + arpReqInput.getIpaddress());
308 } catch (Throwable e) {
309 LOGGER.trace("failed to send arp req for {} on interface {}",
310 arpReqInput.getIpaddress(), interfaceName);
313 .withError(ErrorType.APPLICATION,
314 FAILED_TO_SEND_ARP_REQ_FOR_INTERFACE
317 .withError(ErrorType.APPLICATION,
318 FAILED_TO_SEND_ARP_REQ_FOR_INTERFACE
323 if (localErrorCount == arpReqInput.getInterfaceAddress().size()) {
324 // All the requests failed
325 return Futures.immediateFuture(failureBuilder.build());
327 return Futures.immediateFuture(successBuilder.build());
330 public Future<RpcResult<Void>> sendPacketOut(BigInteger dpnId,
331 byte[] payload, NodeConnectorRef ref) {
333 NodeConnectorRef nodeConnectorRef = MDSALUtil.getNodeConnRef(dpnId,
335 return packetProcessingService
336 .transmitPacket(new TransmitPacketInputBuilder()
339 new NodeRef(InstanceIdentifier
340 .builder(Nodes.class)
342 new NodeKey(new NodeId(
343 "openflow:" + dpnId)))
345 .setIngress(nodeConnectorRef).setEgress(ref).build());
348 public Future<RpcResult<Void>> sendPacketOutWithActions(BigInteger dpnId,
349 byte[] payload, NodeConnectorRef ref, List<Action> actions) {
351 NodeConnectorRef nodeConnectorRef = MDSALUtil.getNodeConnRef(dpnId,
353 return packetProcessingService
354 .transmitPacket(new TransmitPacketInputBuilder()
357 new NodeRef(InstanceIdentifier
358 .builder(Nodes.class)
360 new NodeKey(new NodeId(
361 "openflow:" + dpnId)))
363 .setIngress(nodeConnectorRef).setEgress(ref)
364 .setAction(actions).build());
367 private List<Action> getEgressAction(String interfaceName) {
368 List<Action> actions = new ArrayList<Action>();
370 GetEgressActionsForInterfaceInputBuilder egressAction = new GetEgressActionsForInterfaceInputBuilder().setIntfName(interfaceName);
371 OdlInterfaceRpcService intfRpc = getInterfaceRpcService();
372 if (intfRpc == null) {
373 LOGGER.error("Unable to obtain interfaceMgrRpc service, ignoring egress actions for interfaceName {}", interfaceName);
376 Future<RpcResult<GetEgressActionsForInterfaceOutput>> result =
377 intfRpc.getEgressActionsForInterface(egressAction.build());
378 RpcResult<GetEgressActionsForInterfaceOutput> rpcResult = result.get();
379 if (!rpcResult.isSuccessful()) {
380 LOGGER.warn("RPC Call to Get egress actions for interface {} returned with Errors {}", interfaceName, rpcResult.getErrors());
382 actions = rpcResult.getResult().getAction();
384 } catch (InterruptedException | ExecutionException e) {
385 LOGGER.error("Exception when egress actions for interface {}", interfaceName, e);
386 } catch ( Exception e) {
387 LOGGER.error("Exception when egress actions for interface {}", interfaceName, e);
393 public Future<RpcResult<Void>> sendArpResponse(SendArpResponseInput input) {
394 if (LOGGER.isTraceEnabled()) {
395 LOGGER.trace("sendArpResponse rpc invoked");
400 //byte srcMac[] = new byte[] { (byte) 0, (byte) 0, (byte) 0, (byte) 0, (byte) 0, (byte) 0 };
405 String interfaceName = input.getInterface();
406 GetPortFromInterfaceOutput portResult = getPortFromInterface(interfaceName);
407 checkNotNull(portResult);
408 dpnId = portResult.getDpid();
409 Long portid = portResult.getPortno();
410 NodeConnectorRef ref = MDSALUtil.getNodeConnRef(dpnId,
412 checkArgument(null != dpnId && BigInteger.ZERO != dpnId,
413 DPN_NOT_FOUND_ERROR, interfaceName);
414 checkNotNull(ref, NODE_CONNECTOR_NOT_FOUND_ERROR, interfaceName);
416 if (LOGGER.isTraceEnabled()) {
418 "sendArpRequest received dpnId {} out interface {}",
419 dpnId, interfaceName);
422 byte[] srcIpBytes = getIpAddressBytes(input.getSrcIpaddress());
423 byte[] dstIpBytes = getIpAddressBytes(input.getDstIpaddress());
424 if(input.getSrcMacaddress() == null) {
425 srcMac = MDSALUtil.getMacAddressForNodeConnector(dataBroker,
426 (InstanceIdentifier<NodeConnector>) ref.getValue());
428 String macAddr = input.getSrcMacaddress().getValue();
429 srcMac = HexEncode.bytesFromHexString(macAddr);
431 byte[] dstMac = NWUtil.parseMacAddress(input.getDstMacaddress()
433 checkNotNull(srcIpBytes, FAILED_TO_GET_SRC_IP_FOR_INTERFACE,
435 payload = ArpPacketUtil.getPayload(ARP_RESPONSE_OP, srcMac, srcIpBytes,
438 List<Action> actions = getEgressAction(interfaceName);
439 sendPacketOutWithActions(dpnId, payload, ref, actions);
440 if (LOGGER.isTraceEnabled()) {
441 LOGGER.trace("sent the arp response for "
442 + input.getSrcIpaddress());
444 } catch (Throwable e) {
445 LOGGER.error("failed to send arp response for {} {}",
446 input.getSrcIpaddress(), e);
447 return RpcResultBuilder.<Void> failed()
448 .withError(ErrorType.APPLICATION, e.getMessage(), e)
451 RpcResultBuilder<Void> rpcResultBuilder = RpcResultBuilder.success();
452 return Futures.immediateFuture(rpcResultBuilder.build());
456 public void onPacketReceived(PacketReceived packetReceived) {
457 Class<? extends PacketInReason> pktInReason = packetReceived
458 .getPacketInReason();
459 if (LOGGER.isTraceEnabled()) {
460 LOGGER.trace("Packet Received {}", packetReceived);
463 if (pktInReason == SendToController.class) {
466 int tableId = packetReceived.getTableId().getValue();
468 byte[] data = packetReceived.getPayload();
469 Ethernet ethernet = new Ethernet();
471 ethernet.deserialize(data, 0, data.length
472 * NetUtils.NumBitsInAByte);
473 if (ethernet.getEtherType() != ETH_TYPE_ARP) {
477 Packet pkt = ethernet.getPayload();
479 InetAddress srcInetAddr = InetAddress.getByAddress(arp
480 .getSenderProtocolAddress());
481 InetAddress dstInetAddr = InetAddress.getByAddress(arp
482 .getTargetProtocolAddress());
483 InetAddress addr = srcInetAddr;
484 //For GARP learn target IP
485 if (srcInetAddr.getHostAddress().equalsIgnoreCase(dstInetAddr.getHostAddress()))
487 byte[] srcMac = ethernet.getSourceMACAddress();
489 NodeConnectorRef ref = packetReceived.getIngress();
491 Metadata metadata = packetReceived.getMatch().getMetadata();
493 String interfaceName = getInterfaceName(ref,metadata, dataBroker);
494 //Long vpnId = MetaDataUtil.getVpnIdFromMetadata(metadata.getMetadata());
496 checkAndFireMacChangedNotification(interfaceName, srcInetAddr,
498 macsDB.put(interfaceName + "-" + srcInetAddr.getHostAddress(),
499 NWUtil.toStringMacAddress(srcMac));
500 if (arp.getOpCode() == ARP_REQUEST_OP) {
501 fireArpReqRecvdNotification(interfaceName, srcInetAddr,
502 srcMac, dstInetAddr, tableId, metadata.getMetadata());
504 fireArpRespRecvdNotification(interfaceName, srcInetAddr,
505 srcMac, tableId, metadata.getMetadata());
507 if (getMacFutures.get(srcInetAddr.getHostAddress()) != null) {
508 threadPool.submit(new MacResponderTask(arp));
511 } catch (Throwable e) {
512 LOGGER.trace("Failed to decode packet: {}", e);
517 GetPortFromInterfaceOutput getPortFromInterface(String interfaceName) throws Throwable {
518 GetPortFromInterfaceInputBuilder getPortFromInterfaceInputBuilder = new GetPortFromInterfaceInputBuilder();
519 getPortFromInterfaceInputBuilder.setIntfName(interfaceName);
520 OdlInterfaceRpcService intfRpc = getInterfaceRpcService();
521 if (intfRpc == null) {
522 LOGGER.error("Failed to get OF port for interface {}. Unable to obtain OdlInterfaceRpcService",
527 Future<RpcResult<GetPortFromInterfaceOutput>> portFromInterface = intfRpc.getPortFromInterface(getPortFromInterfaceInputBuilder.build());
528 GetPortFromInterfaceOutput result = portFromInterface.get().getResult();
529 LOGGER.trace("getPortFromInterface rpc result is {} ", result);
530 if (result != null) {
531 LOGGER.trace("getPortFromInterface rpc result is {} {} ", result.getDpid(), result.getPortno());
536 private String getInterfaceName(NodeConnectorRef ref, Metadata metadata, DataBroker dataBroker2) throws Throwable {
537 LOGGER.debug("metadata received is {} ", metadata);
539 GetInterfaceFromIfIndexInputBuilder ifIndexInputBuilder = new GetInterfaceFromIfIndexInputBuilder();
540 BigInteger lportTag = MetaDataUtil.getLportFromMetadata(metadata.getMetadata());
542 ifIndexInputBuilder.setIfIndex(lportTag.intValue());
543 GetInterfaceFromIfIndexInput input = ifIndexInputBuilder.build();
544 OdlInterfaceRpcService intfRpc = getInterfaceRpcService();
546 Future<RpcResult<GetInterfaceFromIfIndexOutput>> interfaceFromIfIndex = intfRpc.getInterfaceFromIfIndex(input);
547 GetInterfaceFromIfIndexOutput interfaceFromIfIndexOutput = interfaceFromIfIndex.get().getResult();
548 return interfaceFromIfIndexOutput.getInterfaceName();
551 class MacResponderTask implements Runnable {
554 MacResponderTask(ARP arp) {
561 GetMacOutputBuilder outputBuilder;
563 SettableFuture<RpcResult<GetMacOutput>> future = null;
564 RpcResultBuilder<GetMacOutput> resultBuilder;
566 srcAddr = InetAddress.getByAddress(arp
567 .getSenderProtocolAddress());
568 srcMac = NWUtil.toStringMacAddress(arp
569 .getSenderHardwareAddress());
570 future = getMacFutures.remove(srcAddr.getHostAddress());
571 if (future == null) {
572 LOGGER.trace("There are no pending mac requests.");
575 outputBuilder = new GetMacOutputBuilder()
576 .setMacaddress(new PhysAddress(srcMac));
577 resultBuilder = RpcResultBuilder.success(outputBuilder.build());
578 if (LOGGER.isTraceEnabled()) {
579 LOGGER.trace("sent the mac response for ip {}",
580 srcAddr.getHostAddress());
582 } catch (Exception e) {
583 LOGGER.trace("failed to send mac response {} ", e);
584 resultBuilder = RpcResultBuilder.<GetMacOutput> failed()
585 .withError(ErrorType.APPLICATION, e.getMessage(), e);
587 future.set(resultBuilder.build());
591 private void fireArpRespRecvdNotification(String interfaceName,
592 InetAddress inetAddr, byte[] macAddressBytes, int tableId, BigInteger metadata)
593 throws InterruptedException {
595 IpAddress ip = new IpAddress(inetAddr.getHostAddress().toCharArray());
596 String macAddress = NWUtil.toStringMacAddress(macAddressBytes);
597 PhysAddress mac = new PhysAddress(macAddress);
598 ArpResponseReceivedBuilder builder = new ArpResponseReceivedBuilder();
599 builder.setInterface(interfaceName);
600 builder.setIpaddress(ip);
601 builder.setOfTableId((long) tableId);
602 builder.setMacaddress(mac);
603 builder.setMetadata(metadata);
604 notificationPublishService.putNotification(builder.build());
607 private void fireArpReqRecvdNotification(String interfaceName,
608 InetAddress srcInetAddr, byte[] srcMac, InetAddress dstInetAddr,
609 int tableId, BigInteger metadata) throws InterruptedException {
610 String macAddress = NWUtil.toStringMacAddress(srcMac);
611 ArpRequestReceivedBuilder builder = new ArpRequestReceivedBuilder();
612 builder.setInterface(interfaceName);
613 builder.setOfTableId((long) tableId);
614 builder.setSrcIpaddress(new IpAddress(srcInetAddr.getHostAddress()
616 builder.setDstIpaddress(new IpAddress(dstInetAddr.getHostAddress()
618 builder.setSrcMac(new PhysAddress(macAddress));
619 builder.setMetadata(metadata);
620 notificationPublishService.putNotification(builder.build());
623 private void checkAndFireMacChangedNotification(String interfaceName,
624 InetAddress inetAddr, byte[] macAddressBytes)
625 throws InterruptedException {
627 IpAddress ip = new IpAddress(inetAddr.getHostAddress().toCharArray());
628 String macAddress = NWUtil.toStringMacAddress(macAddressBytes);
629 PhysAddress mac = new PhysAddress(macAddress);
631 if (!macAddress.equals(macsDB.get(interfaceName + "-"
632 + inetAddr.getHostAddress()))) {
633 if (LOGGER.isTraceEnabled()) {
634 LOGGER.trace("mac address changed for " + inetAddr);
636 MacChangedBuilder builder = new MacChangedBuilder();
637 builder.setInterface(interfaceName);
638 builder.setIpaddress(ip);
639 builder.setMacaddress(mac);
640 notificationPublishService.putNotification(builder.build());
644 private InstanceIdentifier<Interface> buildInterfaceId(String interfaceName) {
645 InstanceIdentifierBuilder<Interface> idBuilder = InstanceIdentifier
646 .builder(Interfaces.class).child(Interface.class,
647 new InterfaceKey(interfaceName));
648 InstanceIdentifier<Interface> id = idBuilder.build();
652 private NodeConnectorId getNodeConnectorFromInterfaceName(String interfaceName) {
653 InstanceIdentifierBuilder<org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface> idBuilder =
654 InstanceIdentifier.builder(InterfacesState.class)
655 .child(org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface.class,
656 new org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.InterfaceKey(interfaceName));
657 InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface> ifStateId = idBuilder.build();
659 Optional<org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface> ifStateOptional = MDSALUtil.read(dataBroker,
660 LogicalDatastoreType.OPERATIONAL,
663 if (ifStateOptional.isPresent()) {
664 org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface ifState = ifStateOptional.get();
665 List<String> lowerLayerIf = ifState.getLowerLayerIf();
666 if (!lowerLayerIf.isEmpty()) {
667 return new NodeConnectorId(lowerLayerIf.get(0));