added arputil module
[vpnservice.git] / arputil / arputil-impl / src / main / java / org / opendaylight / vpnservice / arputil / internal / ArpUtilImpl.java
1 /*
2  * Copyright (c) 2015 Ericsson India Global Services Pvt Ltd. and others.  All rights reserved.
3  *
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
7  */
8
9 package org.opendaylight.vpnservice.arputil.internal;
10
11 import static com.google.common.base.Preconditions.checkArgument;
12 import static com.google.common.base.Preconditions.checkNotNull;
13
14 import java.math.BigInteger;
15 import java.net.InetAddress;
16 import java.net.UnknownHostException;
17 import java.util.concurrent.ConcurrentHashMap;
18 import java.util.concurrent.ConcurrentMap;
19 import java.util.concurrent.ExecutorService;
20 import java.util.concurrent.Executors;
21 import java.util.concurrent.Future;
22
23 import org.opendaylight.controller.liblldp.NetUtils;
24 import org.opendaylight.controller.liblldp.Packet;
25 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
26 import org.opendaylight.controller.md.sal.binding.api.NotificationPublishService;
27 import org.opendaylight.controller.md.sal.binding.api.NotificationService;
28 import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;
29 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
30 import org.opendaylight.vpnservice.mdsalutil.MDSALUtil;
31 import org.opendaylight.vpnservice.mdsalutil.NWUtil;
32 import org.opendaylight.vpnservice.mdsalutil.interfaces.IMdsalApiManager;
33 import org.opendaylight.vpnservice.mdsalutil.packet.ARP;
34 import org.opendaylight.vpnservice.mdsalutil.packet.Ethernet;
35 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpAddress;
36 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.Interfaces;
37 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface;
38 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.InterfaceKey;
39 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.PhysAddress;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNodeConnector;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorRef;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeRef;
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes;
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnector;
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnectorKey;
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey;
50 import org.opendaylight.yang.gen.v1.urn.opendaylight.packet.service.rev130709.PacketInReason;
51 import org.opendaylight.yang.gen.v1.urn.opendaylight.packet.service.rev130709.PacketProcessingListener;
52 import org.opendaylight.yang.gen.v1.urn.opendaylight.packet.service.rev130709.PacketProcessingService;
53 import org.opendaylight.yang.gen.v1.urn.opendaylight.packet.service.rev130709.PacketReceived;
54 import org.opendaylight.yang.gen.v1.urn.opendaylight.packet.service.rev130709.SendToController;
55 import org.opendaylight.yang.gen.v1.urn.opendaylight.packet.service.rev130709.TransmitPacketInputBuilder;
56 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.arputil.rev151126.ArpRequestReceivedBuilder;
57 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.arputil.rev151126.ArpResponseReceivedBuilder;
58 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.arputil.rev151126.GetMacInput;
59 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.arputil.rev151126.GetMacOutput;
60 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.arputil.rev151126.GetMacOutputBuilder;
61 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.arputil.rev151126.MacChangedBuilder;
62 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.arputil.rev151126.OdlArputilService;
63 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.arputil.rev151126.SendArpRequestInput;
64 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.arputil.rev151126.SendArpRequestInputBuilder;
65 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.arputil.rev151126.SendArpResponseInput;
66 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.arputil.rev151126.interfaces.InterfaceAddress;
67 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rev150331.BaseIds;
68 import org.opendaylight.yangtools.concepts.ListenerRegistration;
69 import org.opendaylight.yangtools.yang.binding.DataObject;
70 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
71 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier.InstanceIdentifierBuilder;
72 import org.opendaylight.yangtools.yang.common.RpcError.ErrorType;
73 import org.opendaylight.yangtools.yang.common.RpcResult;
74 import org.opendaylight.yangtools.yang.common.RpcResultBuilder;
75 import org.slf4j.Logger;
76 import org.slf4j.LoggerFactory;
77
78 import com.google.common.base.Optional;
79 import com.google.common.util.concurrent.FutureCallback;
80 import com.google.common.util.concurrent.Futures;
81 import com.google.common.util.concurrent.JdkFutureAdapters;
82 import com.google.common.util.concurrent.SettableFuture;
83
84 public class ArpUtilImpl implements OdlArputilService,
85         PacketProcessingListener, AutoCloseable {
86
87     private static final String FAILED_TO_GET_SRC_IP_FOR_INTERFACE = "Failed to get src ip for %s";
88
89     private static final String FAILED_TO_GET_SRC_MAC_FOR_INTERFACE = "Failed to get src mac for interface %s iid %s ";
90
91     private static final String FAILED_TO_SEND_ARP_REQ_FOR_INTERFACE = "failed to send arp req for interface ";
92
93     private static final String UNKNOWN_IP_ADDRESS_SUPPLIED = "unknown ip address supplied";
94
95     private static final String NODE_CONNECTOR_NOT_FOUND_ERROR = "Node connector id not found for interface %s";
96
97     private static final String DPN_NOT_FOUND_ERROR = "dpn not found for interface %s ";
98
99     private static final short ARP_REQUEST_OP = (short) 1;
100
101     private static final short ARP_RESPONSE_OP = (short) 2;
102
103     private static final Logger LOGGER = LoggerFactory
104             .getLogger(ArpUtilImpl.class);
105
106     ExecutorService threadPool = Executors.newFixedThreadPool(1);
107
108     DataBroker dataBroker;
109     PacketProcessingService packetProcessingService;
110     NotificationPublishService notificationPublishService;
111     NotificationService notificationService;
112     IMdsalApiManager mdsalMgr;
113
114     ListenerRegistration<ArpUtilImpl> listenerRegistration;
115
116     ConcurrentMap<String, String> macsDB = new ConcurrentHashMap<>();
117     ConcurrentMap<String, SettableFuture<RpcResult<GetMacOutput>>> getMacFutures = new ConcurrentHashMap<>();
118
119     public ArpUtilImpl(DataBroker db,
120             PacketProcessingService packetProcessingService,
121             NotificationPublishService notificationPublishService,
122             NotificationService notificationService,
123             IMdsalApiManager mdsalApiManager) {
124
125         this.dataBroker = db;
126         this.packetProcessingService = packetProcessingService;
127         this.notificationPublishService = notificationPublishService;
128         this.mdsalMgr = mdsalApiManager;
129         this.notificationService = notificationService;
130
131         listenerRegistration = notificationService
132                 .registerNotificationListener(this);
133         LOGGER.info("ArpUtil Manager Initialized ");
134     }
135
136     @Override
137     public void close() throws Exception {
138         listenerRegistration.close();
139         LOGGER.trace("ArpUtil manager Closed");
140     }
141
142     String getIpAddressInString(IpAddress ipAddress)
143             throws UnknownHostException {
144         return InetAddress.getByName(ipAddress.getIpv4Address().getValue())
145                 .getHostAddress();
146     }
147
148     public Future<RpcResult<GetMacOutput>> getMac(GetMacInput input) {
149
150         try {
151             final String dstIpAddress = getIpAddressInString(input
152                     .getIpaddress());
153             if (LOGGER.isTraceEnabled()) {
154                 LOGGER.trace("getMac rpc invoked for ip " + dstIpAddress);
155             }
156             if (getMacFutures.get(dstIpAddress) != null) {
157                 if (LOGGER.isInfoEnabled()) {
158                     LOGGER.info("get mac already in progress for the ip "
159                             + dstIpAddress);
160                 }
161                 return getMacFutures.get(dstIpAddress);
162             }
163             SendArpRequestInputBuilder builder = new SendArpRequestInputBuilder()
164                     .setInterfaceAddress(input.getInterfaceAddress())
165                     .setIpaddress(input.getIpaddress());
166             Future<RpcResult<Void>> arpReqFt = sendArpRequest(builder.build());
167             final SettableFuture<RpcResult<GetMacOutput>> ft = SettableFuture
168                     .create();
169
170             Futures.addCallback(
171                     JdkFutureAdapters.listenInPoolThread(arpReqFt, threadPool),
172                     new FutureCallback<RpcResult<Void>>() {
173                         @Override
174                         public void onFailure(Throwable e) {
175                             RpcResultBuilder<GetMacOutput> resultBuilder = RpcResultBuilder
176                                     .<GetMacOutput> failed().withError(
177                                             ErrorType.APPLICATION,
178                                             e.getMessage(), e);
179                             ft.set(resultBuilder.build());
180                         }
181
182                         @Override
183                         public void onSuccess(RpcResult<Void> result) {
184                             LOGGER.trace("Successfully sent the arp pkt out for ip "
185                                     + dstIpAddress);
186                         }
187                     });
188
189             getMacFutures.put(dstIpAddress, ft);
190             return ft;
191         } catch (Exception e) {
192             LOGGER.trace("failed to handle getMac request for {} {}",
193                     input.getIpaddress(), e);
194             RpcResultBuilder<GetMacOutput> resultBuilder = RpcResultBuilder
195                     .<GetMacOutput> failed().withError(ErrorType.APPLICATION,
196                             e.getMessage(), e);
197             return Futures.immediateFuture(resultBuilder.build());
198         }
199     }
200
201     byte[] getIpAddressBytes(IpAddress ip) throws UnknownHostException {
202         return InetAddress.getByName(ip.getIpv4Address().getValue())
203                 .getAddress();
204     }
205
206     @Override
207     public Future<RpcResult<Void>> sendArpRequest(
208             SendArpRequestInput arpReqInput) {
209         if (LOGGER.isTraceEnabled()) {
210             LOGGER.trace("rpc sendArpRequest invoked for ip "
211                     + arpReqInput.getIpaddress());
212         }
213         BigInteger dpnId;
214         long groupId;
215         byte payload[];
216         String interfaceName = null;
217         byte srcIpBytes[];
218         byte[] dstIpBytes = null;
219
220         RpcResultBuilder<Void> failureBuilder = RpcResultBuilder
221                 .<Void> failed();
222         RpcResultBuilder<Void> successBuilder = RpcResultBuilder
223                 .<Void> success();
224
225         try {
226             dstIpBytes = getIpAddressBytes(arpReqInput.getIpaddress());
227         } catch (Exception e) {
228             failureBuilder.withError(ErrorType.APPLICATION,
229                     UNKNOWN_IP_ADDRESS_SUPPLIED);
230             return Futures.immediateFuture(failureBuilder.build());
231         }
232
233         int localErrorCount = 0;
234         for (InterfaceAddress interfaceAddress : arpReqInput
235                 .getInterfaceAddress()) {
236             try {
237                 interfaceName = interfaceAddress.getInterface();
238                 srcIpBytes = getIpAddressBytes(interfaceAddress.getIpAddress());
239
240                 NodeConnectorId id = getNodeConnectorFromDataStore(interfaceName);
241
242                 dpnId = BigInteger.valueOf(MDSALUtil.getDpnIdFromPortName(id));
243                 Long portid = MDSALUtil.getOfPortNumberFromPortName(id);
244                 checkArgument(null != dpnId && BigInteger.ZERO != dpnId,
245                         DPN_NOT_FOUND_ERROR, interfaceName);
246
247                 NodeConnectorRef ref = MDSALUtil.getNodeConnRef(dpnId,
248                         portid.toString());
249                 checkNotNull(ref, NODE_CONNECTOR_NOT_FOUND_ERROR, interfaceName);
250
251                 if (LOGGER.isTraceEnabled()) {
252                     LOGGER.trace(
253                             "sendArpRequest received dpnId {} out interface {}",
254                             dpnId, interfaceName);
255                 }
256                 byte srcMac[] = MDSALUtil.getMacAddressForNodeConnector(
257                         dataBroker,
258                         (InstanceIdentifier<NodeConnector>) ref.getValue());
259                 checkNotNull(srcMac, FAILED_TO_GET_SRC_MAC_FOR_INTERFACE,
260                         interfaceName, ref.getValue());
261                 checkNotNull(srcIpBytes, FAILED_TO_GET_SRC_IP_FOR_INTERFACE,
262                         interfaceName);
263
264                 payload = ArpPacketUtil.getPayload(ARP_REQUEST_OP, srcMac,
265                         srcIpBytes, ArpPacketUtil.EthernetDestination_Broadcast,
266                         dstIpBytes);
267
268                 sendPacketOut(dpnId, payload, ref);
269
270                 if (LOGGER.isTraceEnabled()) {
271                     LOGGER.trace("sent arp request for "
272                             + arpReqInput.getIpaddress());
273                 }
274             } catch (Exception e) {
275                 LOGGER.trace("failed to send arp req for {} on interface {}",
276                         arpReqInput.getIpaddress(), interfaceName);
277
278                 failureBuilder
279                         .withError(ErrorType.APPLICATION,
280                                 FAILED_TO_SEND_ARP_REQ_FOR_INTERFACE
281                                         + interfaceName, e);
282                 successBuilder
283                         .withError(ErrorType.APPLICATION,
284                                 FAILED_TO_SEND_ARP_REQ_FOR_INTERFACE
285                                         + interfaceName, e);
286                 localErrorCount++;
287             }
288         }
289         if (localErrorCount == arpReqInput.getInterfaceAddress().size()) {
290             // All the requests failed
291             return Futures.immediateFuture(failureBuilder.build());
292         }
293         return Futures.immediateFuture(successBuilder.build());
294     }
295
296     public Future<RpcResult<Void>> sendPacketOut(BigInteger dpnId,
297             byte[] payload, NodeConnectorRef ref) {
298
299         NodeConnectorRef nodeConnectorRef = MDSALUtil.getNodeConnRef(dpnId,
300                 "0xfffffffd");
301         return packetProcessingService
302                 .transmitPacket(new TransmitPacketInputBuilder()
303                         .setPayload(payload)
304                         .setNode(
305                                 new NodeRef(InstanceIdentifier
306                                         .builder(Nodes.class)
307                                         .child(Node.class,
308                                                 new NodeKey(new NodeId(
309                                                         "openflow:" + dpnId)))
310                                         .toInstance()))
311                         .setIngress(nodeConnectorRef).setEgress(ref).build());
312     }
313
314     @Override
315     public Future<RpcResult<Void>> sendArpResponse(SendArpResponseInput input) {
316         if (LOGGER.isTraceEnabled()) {
317             LOGGER.trace("sendArpResponse rpc invoked");
318         }
319         BigInteger dpnId;
320         long groupId;
321         byte payload[];
322
323         try {
324             String interfaceName = input.getInterface();
325             NodeConnectorId id = getNodeConnectorFromDataStore(interfaceName);
326
327             dpnId = BigInteger.valueOf(MDSALUtil.getDpnIdFromPortName(id));
328             Long portid = MDSALUtil.getOfPortNumberFromPortName(id);
329
330             NodeConnectorRef ref = MDSALUtil.getNodeConnRef(dpnId,
331                     portid.toString());
332             checkArgument(null != dpnId && BigInteger.ZERO != dpnId,
333                     DPN_NOT_FOUND_ERROR, interfaceName);
334             checkNotNull(ref, NODE_CONNECTOR_NOT_FOUND_ERROR, interfaceName);
335
336             if (LOGGER.isTraceEnabled()) {
337                 LOGGER.trace(
338                         "sendArpRequest received dpnId {} out interface {}",
339                         dpnId, interfaceName);
340             }
341
342             byte[] srcIpBytes = getIpAddressBytes(input.getSrcIpAddress());
343             byte[] dstIpBytes = getIpAddressBytes(input.getIpaddress());
344             byte srcMac[] = MDSALUtil.getMacAddressForNodeConnector(dataBroker,
345                     (InstanceIdentifier<NodeConnector>) ref.getValue());
346             byte[] dstMac = NWUtil.parseMacAddress(input.getMacaddress()
347                     .getValue());
348             checkNotNull(srcIpBytes, FAILED_TO_GET_SRC_IP_FOR_INTERFACE,
349                     interfaceName);
350             payload = ArpPacketUtil.getPayload(ARP_RESPONSE_OP, srcMac, srcIpBytes,
351                     dstMac, dstIpBytes);
352
353             sendPacketOut(dpnId, payload, ref);
354             if (LOGGER.isTraceEnabled()) {
355                 LOGGER.trace("sent the arp response for "
356                         + input.getSrcIpAddress());
357             }
358         } catch (Exception e) {
359             LOGGER.trace("failed to send arp response for {} {}",
360                     input.getSrcIpAddress(), e);
361             return RpcResultBuilder.<Void> failed()
362                     .withError(ErrorType.APPLICATION, e.getMessage(), e)
363                     .buildFuture();
364         }
365         RpcResultBuilder<Void> rpcResultBuilder = RpcResultBuilder.success();
366         return Futures.immediateFuture(rpcResultBuilder.build());
367     }
368
369     @Override
370     public void onPacketReceived(PacketReceived packetReceived) {
371         Class<? extends PacketInReason> pktInReason = packetReceived
372                 .getPacketInReason();
373         if (LOGGER.isTraceEnabled()) {
374             LOGGER.trace("Packet Received {}", packetReceived);
375         }
376
377         if (pktInReason == SendToController.class) {
378
379             try {
380                 int tableId = packetReceived.getTableId().getValue();
381
382                 byte[] data = packetReceived.getPayload();
383                 Ethernet ethernet = new Ethernet();
384
385                 ethernet.deserialize(data, 0, data.length
386                         * NetUtils.NumBitsInAByte);
387                 if (ethernet.getEtherType() != ARP_REQUEST_OP
388                         && ethernet.getEtherType() != ARP_REQUEST_OP) {
389                     return;
390                 }
391
392                 Packet pkt = ethernet.getPayload();
393                 ARP arp = (ARP) pkt;
394                 InetAddress srcInetAddr = InetAddress.getByAddress(arp
395                         .getSenderProtocolAddress());
396                 InetAddress dstInetAddr = InetAddress.getByAddress(arp
397                         .getTargetProtocolAddress());
398                 byte[] srcMac = ethernet.getSourceMACAddress();
399
400                 NodeConnectorRef ref = packetReceived.getIngress();
401
402                 String interfaceName = MDSALUtil.getInterfaceName(ref, dataBroker);
403
404                 checkAndFireMacChangedNotification(interfaceName, srcInetAddr,
405                         srcMac);
406
407                 macsDB.put(interfaceName + "-" + srcInetAddr.getHostAddress(),
408                         NWUtil.toStringMacAddress(srcMac));
409
410                 if (arp.getOpCode() == ARP_REQUEST_OP) {
411                     fireArpReqRecvdNotification(interfaceName, srcInetAddr,
412                             srcMac, dstInetAddr, tableId);
413                 } else {
414                     fireArpRespRecvdNotification(interfaceName, srcInetAddr,
415                             srcMac, tableId);
416                 }
417                 if (getMacFutures.get(srcInetAddr.getHostAddress()) != null) {
418                     threadPool.submit(new MacResponderTask(arp));
419                 }
420
421             } catch (Exception e) {
422                 LOGGER.trace("Failed to decode packet: {}", e);
423             }
424         }
425     }
426
427     class MacResponderTask implements Runnable {
428         ARP arp;
429
430         MacResponderTask(ARP arp) {
431             this.arp = arp;
432         }
433
434         @Override
435         public void run() {
436             InetAddress srcAddr;
437             GetMacOutputBuilder outputBuilder;
438             String srcMac;
439             SettableFuture<RpcResult<GetMacOutput>> future = null;
440             RpcResultBuilder<GetMacOutput> resultBuilder;
441             try {
442                 srcAddr = InetAddress.getByAddress(arp
443                         .getSenderProtocolAddress());
444                 srcMac = NWUtil.toStringMacAddress(arp
445                         .getSenderHardwareAddress());
446                 future = getMacFutures.remove(srcAddr.getHostAddress());
447                 if (future == null) {
448                     LOGGER.trace("There are no pending mac requests.");
449                     return;
450                 }
451                 outputBuilder = new GetMacOutputBuilder()
452                         .setMacaddress(new PhysAddress(srcMac));
453                 resultBuilder = RpcResultBuilder.success(outputBuilder.build());
454                 if (LOGGER.isTraceEnabled()) {
455                     LOGGER.trace("sent the mac response for ip {}",
456                             srcAddr.getHostAddress());
457                 }
458             } catch (Exception e) {
459                 LOGGER.trace("failed to send mac response {} ", e);
460                 resultBuilder = RpcResultBuilder.<GetMacOutput> failed()
461                         .withError(ErrorType.APPLICATION, e.getMessage(), e);
462             }
463             future.set(resultBuilder.build());
464         }
465     }
466
467     private void fireArpRespRecvdNotification(String interfaceName,
468             InetAddress inetAddr, byte[] macAddressBytes, int tableId)
469             throws InterruptedException {
470
471         IpAddress ip = new IpAddress(inetAddr.getHostAddress().toCharArray());
472         String macAddress = NWUtil.toStringMacAddress(macAddressBytes);
473         PhysAddress mac = new PhysAddress(macAddress);
474         ArpResponseReceivedBuilder builder = new ArpResponseReceivedBuilder();
475         builder.setInterface(interfaceName);
476         builder.setIpaddress(ip);
477         builder.setOfTableId((long) tableId);
478         builder.setMacaddress(mac);
479         notificationPublishService.putNotification(builder.build());
480     }
481
482     private void fireArpReqRecvdNotification(String interfaceName,
483             InetAddress srcInetAddr, byte[] srcMac, InetAddress dstInetAddr,
484             int tableId) throws InterruptedException {
485         String macAddress = NWUtil.toStringMacAddress(srcMac);
486         ArpRequestReceivedBuilder builder = new ArpRequestReceivedBuilder();
487         builder.setInterface(interfaceName);
488         builder.setOfTableId((long) tableId);
489         builder.setSrcIpaddress(new IpAddress(srcInetAddr.getHostAddress()
490                 .toCharArray()));
491         builder.setDstIpaddress(new IpAddress(dstInetAddr.getHostAddress()
492                 .toCharArray()));
493         builder.setSrcMac(new PhysAddress(macAddress));
494         notificationPublishService.putNotification(builder.build());
495     }
496
497     private void checkAndFireMacChangedNotification(String interfaceName,
498             InetAddress inetAddr, byte[] macAddressBytes)
499             throws InterruptedException {
500
501         IpAddress ip = new IpAddress(inetAddr.getHostAddress().toCharArray());
502         String macAddress = NWUtil.toStringMacAddress(macAddressBytes);
503         PhysAddress mac = new PhysAddress(macAddress);
504
505         if (!macAddress.equals(macsDB.get(interfaceName + "-"
506                 + inetAddr.getHostAddress()))) {
507             if (LOGGER.isTraceEnabled()) {
508                 LOGGER.trace("mac address changed for " + inetAddr);
509             }
510             MacChangedBuilder builder = new MacChangedBuilder();
511             builder.setInterface(interfaceName);
512             builder.setIpaddress(ip);
513             builder.setMacaddress(mac);
514             notificationPublishService.putNotification(builder.build());
515         }
516     }
517
518     private InstanceIdentifier<Interface> buildInterfaceId(String interfaceName) {
519         InstanceIdentifierBuilder<Interface> idBuilder = InstanceIdentifier
520                 .builder(Interfaces.class).child(Interface.class,
521                         new InterfaceKey(interfaceName));
522         InstanceIdentifier<Interface> id = idBuilder.build();
523         return id;
524     }
525
526
527     private NodeConnectorId getNodeConnectorFromDataStore(String interfaceName) {
528         InstanceIdentifier<Interface> id = buildInterfaceId(interfaceName);
529         Optional<Interface> interf = MDSALUtil.read(dataBroker,
530                 LogicalDatastoreType.CONFIGURATION,
531                 id);
532         if (interf.isPresent()) {
533             return interf.get().getAugmentation(BaseIds.class).getOfPortId();
534         }
535         return null;
536     }
537
538 }