added arputil module 39/30539/12
authorsuneel verma <k.v.suneelu.verma@ericsson.com>
Thu, 3 Dec 2015 10:05:07 +0000 (15:35 +0530)
committersuneel verma <k.v.suneelu.verma@ericsson.com>
Tue, 8 Dec 2015 05:08:05 +0000 (10:38 +0530)
utility rpcs are added for sending arp request
arp response and finding mac address of ip

Change-Id: I08416fb2a4273bcb8c5e82f4ea6ffb6f4d6e47d8
Signed-off-by: suneel verma <k.v.suneelu.verma@ericsson.com>
21 files changed:
arputil/arputil-api/pom.xml [new file with mode: 0644]
arputil/arputil-api/src/main/yang/odl-arputil.yang [new file with mode: 0644]
arputil/arputil-impl/pom.xml [new file with mode: 0644]
arputil/arputil-impl/src/main/config/default-config.xml [new file with mode: 0644]
arputil/arputil-impl/src/main/java/org/opendaylight/vpnservice/arputil/internal/ArpPacketUtil.java [new file with mode: 0644]
arputil/arputil-impl/src/main/java/org/opendaylight/vpnservice/arputil/internal/ArpUtilImpl.java [new file with mode: 0644]
arputil/arputil-impl/src/main/java/org/opendaylight/vpnservice/arputil/internal/ArpUtilProvider.java [new file with mode: 0644]
arputil/arputil-impl/src/main/java/org/opendaylight/yang/gen/v1/urn/opendaylight/params/xml/ns/yang/arputil/impl/rev151126/ArputilImplModule.java [new file with mode: 0644]
arputil/arputil-impl/src/main/java/org/opendaylight/yang/gen/v1/urn/opendaylight/params/xml/ns/yang/arputil/impl/rev151126/ArputilImplModuleFactory.java [new file with mode: 0644]
arputil/arputil-impl/src/main/yang/arputil-impl.yang [new file with mode: 0644]
arputil/pom.xml [new file with mode: 0644]
commons/config-parent/pom.xml
features/pom.xml
features/src/main/features/features.xml
mdsalutil/mdsalutil-api/pom.xml
mdsalutil/mdsalutil-api/src/main/java/org/opendaylight/vpnservice/mdsalutil/MDSALUtil.java
mdsalutil/mdsalutil-api/src/main/java/org/opendaylight/vpnservice/mdsalutil/NWUtil.java [new file with mode: 0644]
mdsalutil/mdsalutil-api/src/main/java/org/opendaylight/vpnservice/mdsalutil/packet/ARP.java [new file with mode: 0644]
mdsalutil/mdsalutil-api/src/main/java/org/opendaylight/vpnservice/mdsalutil/packet/Ethernet.java [new file with mode: 0644]
mdsalutil/mdsalutil-impl/pom.xml
pom.xml

diff --git a/arputil/arputil-api/pom.xml b/arputil/arputil-api/pom.xml
new file mode 100644 (file)
index 0000000..6c26ad3
--- /dev/null
@@ -0,0 +1,56 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <groupId>org.opendaylight.vpnservice</groupId>
+        <artifactId>config-parent</artifactId>
+        <version>0.2.0-SNAPSHOT</version>
+        <relativePath>../../commons/config-parent</relativePath>
+     </parent>
+    <modelVersion>4.0.0</modelVersion>
+    <groupId>org.opendaylight.vpnservice</groupId>
+    <artifactId>arputil-api</artifactId>
+    <version>${vpnservices.version}</version>
+    <packaging>bundle</packaging>
+
+    <dependencies>
+           <dependency>
+               <groupId>org.opendaylight.openflowplugin.model</groupId>
+               <artifactId>model-flow-base</artifactId>
+               <version>${openflowplugin.version}</version>
+           </dependency>
+        <dependency>
+               <groupId>org.opendaylight.openflowplugin.model</groupId>
+               <artifactId>model-flow-service</artifactId>
+               <version>${openflowplugin.version}</version>
+        </dependency>
+               <dependency>
+            <groupId>org.opendaylight.mdsal</groupId>
+            <artifactId>yang-binding</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.opendaylight.yangtools</groupId>
+            <artifactId>yang-common</artifactId>
+        </dependency>
+           <dependency>
+             <groupId>org.opendaylight.mdsal.model</groupId>
+             <artifactId>yang-ext</artifactId>
+           </dependency>
+           <dependency>
+             <groupId>org.opendaylight.mdsal.model</groupId>
+             <artifactId>ietf-inet-types</artifactId>
+           </dependency>
+           <dependency>
+             <groupId>org.opendaylight.mdsal.model</groupId>
+             <artifactId>ietf-yang-types</artifactId>
+           </dependency>
+           <dependency>
+             <groupId>org.opendaylight.mdsal.model</groupId>
+             <artifactId>ietf-interfaces</artifactId>
+           </dependency>
+           <dependency>
+             <groupId>org.opendaylight.mdsal.model</groupId>
+             <artifactId>iana-if-type-2014-05-08</artifactId>
+           </dependency>
+    </dependencies>
+</project>
diff --git a/arputil/arputil-api/src/main/yang/odl-arputil.yang b/arputil/arputil-api/src/main/yang/odl-arputil.yang
new file mode 100644 (file)
index 0000000..3f17695
--- /dev/null
@@ -0,0 +1,139 @@
+module odl-arputil {
+    yang-version 1;
+    namespace "urn:opendaylight:params:xml:ns:yang:arputil";
+    prefix "odl-arputil";
+
+    import ietf-interfaces {
+        prefix if;
+    }
+
+    import ietf-inet-types {
+        prefix inet;
+    }
+
+    import ietf-yang-types {
+        prefix yang;
+    }
+
+    import opendaylight-inventory {
+        prefix inv; revision-date 2013-08-19;
+    }
+
+    import config {
+        prefix config; revision-date 2013-04-05;
+    }
+
+    revision "2015-11-26" {
+        description "Arp Util module";
+    }
+
+
+    grouping interfaces {
+        list interface-address {
+           key interface;
+           leaf interface {
+                type leafref {
+                    path "/if:interfaces/if:interface/if:name";
+                }
+           }
+           leaf ip-address {
+                type inet:ip-address;
+           }
+        }
+    }
+
+
+    rpc get-mac {
+        input {
+            leaf ipaddress {
+                type inet:ip-address;
+            }
+            uses interfaces;
+        }
+        output {
+            leaf macaddress {
+                type yang:phys-address;
+            }
+        }
+    }
+
+    rpc send-arp-request {
+          input {
+              leaf ipaddress {
+                  type inet:ip-address;
+              }
+              uses interfaces;
+          }
+    }
+
+    rpc send-arp-response {
+          input {
+              leaf ipaddress {
+                  type inet:ip-address;
+              }
+              leaf macaddress {
+                  type yang:phys-address;
+              }
+              leaf interface {
+                  type leafref {
+                      path "/if:interfaces/if:interface/if:name";
+                  }
+              }
+              leaf src-ip-address {
+                  type inet:ip-address;
+              }
+          }
+    }
+
+
+    notification mac-changed {
+         leaf ipaddress {
+             type inet:ip-address;
+         }
+         leaf macaddress {
+             type yang:phys-address;
+         }
+         leaf interface {
+             type leafref {
+                path "/if:interfaces/if:interface/if:name";
+             }
+         }
+    }
+
+    notification arp-request-received {
+         leaf dst-ipaddress {
+             type inet:ip-address;
+         }
+         leaf src-ipaddress {
+             type inet:ip-address;
+         }
+         leaf src-mac {
+             type yang:phys-address;
+         }
+         leaf of-table-id {
+             type uint32;
+         }
+         leaf interface {
+             type leafref {
+                path "/if:interfaces/if:interface/if:name";
+            }
+         }
+    }
+
+    notification arp-response-received {
+         leaf ipaddress {
+             type inet:ip-address;
+         }
+         leaf macaddress {
+             type yang:phys-address;
+         }
+         leaf of-table-id {
+             type uint32;
+         }
+         leaf interface {
+             type leafref {
+                path "/if:interfaces/if:interface/if:name";
+            }
+         }
+    }
+}
\ No newline at end of file
diff --git a/arputil/arputil-impl/pom.xml b/arputil/arputil-impl/pom.xml
new file mode 100644 (file)
index 0000000..b5de1cc
--- /dev/null
@@ -0,0 +1,94 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <groupId>org.opendaylight.vpnservice</groupId>
+        <artifactId>config-parent</artifactId>
+        <version>0.2.0-SNAPSHOT</version>
+        <relativePath>../../commons/config-parent</relativePath>
+     </parent>
+    <modelVersion>4.0.0</modelVersion>
+    <groupId>org.opendaylight.vpnservice</groupId>
+    <artifactId>arputil-impl</artifactId>
+    <version>${vpnservices.version}</version>
+    <packaging>bundle</packaging>
+    <properties>
+    </properties>
+    <dependencies>
+        <dependency>
+          <groupId>${project.groupId}</groupId>
+          <artifactId>interfacemgr-api</artifactId>
+          <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.opendaylight.controller</groupId>
+            <artifactId>sal-binding-api</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.opendaylight.mdsal</groupId>
+            <artifactId>yang-binding</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.opendaylight.yangtools</groupId>
+            <artifactId>yang-common</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>${project.groupId}</groupId>
+            <artifactId>mdsalutil-api</artifactId>
+            <version>${vpnservices.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.opendaylight.mdsal.model</groupId>
+            <artifactId>yang-ext</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.opendaylight.controller</groupId>
+            <artifactId>liblldp</artifactId>
+            <version>${liblldp.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.opendaylight.mdsal.model</groupId>
+            <artifactId>ietf-inet-types</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>${project.groupId}</groupId>
+            <artifactId>arputil-api</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.opendaylight.mdsal.model</groupId>
+            <artifactId>ietf-yang-types</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.opendaylight.mdsal.model</groupId>
+            <artifactId>ietf-interfaces</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.opendaylight.mdsal.model</groupId>
+            <artifactId>iana-if-type-2014-05-08</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.opendaylight.openflowplugin.model</groupId>
+            <artifactId>model-flow-base</artifactId>
+            <version>${openflowplugin.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.opendaylight.openflowplugin.model</groupId>
+            <artifactId>model-flow-service</artifactId>
+            <version>${openflowplugin.version}</version>
+        </dependency>
+       <dependency>
+         <groupId>org.opendaylight.controller</groupId>
+         <artifactId>sal-binding-broker-impl</artifactId>
+         <scope>test</scope>
+       </dependency>
+       <dependency>
+         <groupId>org.opendaylight.controller</groupId>
+         <artifactId>sal-binding-broker-impl</artifactId>
+         <version>${mdsal.version}</version>
+         <scope>test</scope>
+         <type>test-jar</type>
+       </dependency>
+    </dependencies>
+
+</project>
diff --git a/arputil/arputil-impl/src/main/config/default-config.xml b/arputil/arputil-impl/src/main/config/default-config.xml
new file mode 100644 (file)
index 0000000..dcd772c
--- /dev/null
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+Copyright (c) 2015 Ericsson India Global Services Pvt Ltd. and others.  All rights reserved.
+
+This program and the accompanying materials are made available under the
+terms of the Eclipse Public License v1.0 which accompanies this distribution,
+and is available at http://www.eclipse.org/legal/epl-v10.html
+-->
+<snapshot>
+  <required-capabilities>
+      <capability>urn:opendaylight:params:xml:ns:yang:arputil:impl?module=arputil-impl&amp;revision=2015-11-26</capability>
+      <capability>urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding?module=opendaylight-md-sal-binding&amp;revision=2013-10-28</capability>
+      <capability>urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl?module=opendaylight-sal-binding-broker-impl&amp;revision=2013-10-28</capability>
+      <capability>urn:opendaylight:params:xml:ns:yang:mdsalutil:api?module=odl-mdsalutil&amp;revision=2015-04-10</capability>
+  </required-capabilities>
+  <configuration>
+
+    <data xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
+      <modules xmlns="urn:opendaylight:params:xml:ns:yang:controller:config">
+        <module>
+          <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:arputil:impl">prefix:arputil-impl</type>
+          <name>arputil-default</name>
+          <broker>
+            <type xmlns:binding="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding">binding:binding-broker-osgi-registry</type>
+            <name>binding-osgi-broker</name>
+          </broker>
+          <rpc-registry>
+            <type xmlns:binding="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding">binding:binding-rpc-registry</type>
+            <name>binding-rpc-broker</name>
+          </rpc-registry>
+          <mdsalutil>
+            <type xmlns:mdsalutil="urn:opendaylight:params:xml:ns:yang:mdsalutil:api">mdsalutil:odl-mdsalutil</type>
+            <name>mdsalutil-service</name>
+          </mdsalutil>
+          <notification-publish-service>
+            <type xmlns:bindingimpl="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl">bindingimpl:binding-new-notification-publish-service</type>
+            <name>binding-notification-publish-adapter</name>
+          </notification-publish-service>
+          <notification-service>
+            <type xmlns:bindingimpl="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl">bindingimpl:binding-new-notification-service</type>
+            <name>binding-notification-adapter</name>
+          </notification-service>
+        </module>
+      </modules>
+    </data>
+  </configuration>
+</snapshot>
diff --git a/arputil/arputil-impl/src/main/java/org/opendaylight/vpnservice/arputil/internal/ArpPacketUtil.java b/arputil/arputil-impl/src/main/java/org/opendaylight/vpnservice/arputil/internal/ArpPacketUtil.java
new file mode 100644 (file)
index 0000000..46af8e8
--- /dev/null
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2015 Ericsson India Global Services Pvt Ltd. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.vpnservice.arputil.internal;
+
+import org.opendaylight.controller.liblldp.EtherTypes;
+import org.opendaylight.controller.liblldp.PacketException;
+import org.opendaylight.vpnservice.mdsalutil.packet.ARP;
+import org.opendaylight.vpnservice.mdsalutil.packet.Ethernet;
+
+public class ArpPacketUtil {
+
+    public static byte[] EthernetDestination_Broadcast = new byte[] { (byte) 0xFF, (byte) 0xFF, (byte) 0xFF,
+            (byte) 0xFF, (byte) 0xFF, (byte) 0xFF };
+    public static byte[] MAC_Broadcast = new byte[] { (byte) 0, (byte) 0, (byte) 0, (byte) 0, (byte) 0, (byte) 0 };
+
+    public static byte[] getPayload(short opCode, byte[] senderMacAddress, byte[] senderIP, byte[] targetMacAddress,
+            byte[] targetIP) throws PacketException {
+        ARP arp = createARPPacket(opCode, senderMacAddress, senderIP, targetMacAddress, targetIP);
+        Ethernet ethernet = createEthernetPacket(senderMacAddress, targetMacAddress, arp);
+        return ethernet.serialize();
+    }
+
+    public static ARP createARPPacket(short opCode, byte[] senderMacAddress, byte[] senderIP, byte[] targetMacAddress,
+            byte[] targetIP) {
+        ARP arp = new ARP();
+        arp.setHardwareType(ARP.HW_TYPE_ETHERNET);
+        arp.setProtocolType(EtherTypes.IPv4.shortValue());
+        arp.setHardwareAddressLength((byte) 6);
+        arp.setProtocolAddressLength((byte) 4);
+        arp.setOpCode(opCode);
+        arp.setSenderHardwareAddress(senderMacAddress);
+        arp.setSenderProtocolAddress(senderIP);
+        arp.setTargetHardwareAddress(targetMacAddress);
+        arp.setTargetProtocolAddress(targetIP);
+        return arp;
+    }
+
+    public static Ethernet createEthernetPacket(byte[] sourceMAC, byte[] targetMAC, ARP arp)
+            throws PacketException {
+        Ethernet ethernet = new Ethernet();
+        ethernet.setSourceMACAddress(sourceMAC);
+        ethernet.setDestinationMACAddress(targetMAC);
+        ethernet.setEtherType(EtherTypes.ARP.shortValue());
+        ethernet.setPayload(arp);
+        return ethernet;
+    }
+}
\ No newline at end of file
diff --git a/arputil/arputil-impl/src/main/java/org/opendaylight/vpnservice/arputil/internal/ArpUtilImpl.java b/arputil/arputil-impl/src/main/java/org/opendaylight/vpnservice/arputil/internal/ArpUtilImpl.java
new file mode 100644 (file)
index 0000000..45f6824
--- /dev/null
@@ -0,0 +1,538 @@
+/*
+ * Copyright (c) 2015 Ericsson India Global Services Pvt Ltd. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.vpnservice.arputil.internal;
+
+import static com.google.common.base.Preconditions.checkArgument;
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import java.math.BigInteger;
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.Future;
+
+import org.opendaylight.controller.liblldp.NetUtils;
+import org.opendaylight.controller.liblldp.Packet;
+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.binding.api.ReadOnlyTransaction;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.vpnservice.mdsalutil.MDSALUtil;
+import org.opendaylight.vpnservice.mdsalutil.NWUtil;
+import org.opendaylight.vpnservice.mdsalutil.interfaces.IMdsalApiManager;
+import org.opendaylight.vpnservice.mdsalutil.packet.ARP;
+import org.opendaylight.vpnservice.mdsalutil.packet.Ethernet;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.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.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.flow.inventory.rev130819.FlowCapableNodeConnector;
+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;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnector;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnectorKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.packet.service.rev130709.PacketInReason;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.packet.service.rev130709.PacketProcessingListener;
+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.TransmitPacketInputBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.arputil.rev151126.ArpRequestReceivedBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.arputil.rev151126.ArpResponseReceivedBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.arputil.rev151126.GetMacInput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.arputil.rev151126.GetMacOutput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.arputil.rev151126.GetMacOutputBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.arputil.rev151126.MacChangedBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.arputil.rev151126.OdlArputilService;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.arputil.rev151126.SendArpRequestInput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.arputil.rev151126.SendArpRequestInputBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.arputil.rev151126.SendArpResponseInput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.arputil.rev151126.interfaces.InterfaceAddress;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rev150331.BaseIds;
+import org.opendaylight.yangtools.concepts.ListenerRegistration;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+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;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+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.SettableFuture;
+
+public class ArpUtilImpl implements OdlArputilService,
+        PacketProcessingListener, AutoCloseable {
+
+    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 Logger LOGGER = LoggerFactory
+            .getLogger(ArpUtilImpl.class);
+
+    ExecutorService threadPool = Executors.newFixedThreadPool(1);
+
+    DataBroker dataBroker;
+    PacketProcessingService packetProcessingService;
+    NotificationPublishService notificationPublishService;
+    NotificationService notificationService;
+    IMdsalApiManager mdsalMgr;
+
+    ListenerRegistration<ArpUtilImpl> listenerRegistration;
+
+    ConcurrentMap<String, String> macsDB = new ConcurrentHashMap<>();
+    ConcurrentMap<String, SettableFuture<RpcResult<GetMacOutput>>> getMacFutures = new ConcurrentHashMap<>();
+
+    public ArpUtilImpl(DataBroker db,
+            PacketProcessingService packetProcessingService,
+            NotificationPublishService notificationPublishService,
+            NotificationService notificationService,
+            IMdsalApiManager mdsalApiManager) {
+
+        this.dataBroker = db;
+        this.packetProcessingService = packetProcessingService;
+        this.notificationPublishService = notificationPublishService;
+        this.mdsalMgr = mdsalApiManager;
+        this.notificationService = notificationService;
+
+        listenerRegistration = notificationService
+                .registerNotificationListener(this);
+        LOGGER.info("ArpUtil Manager Initialized ");
+    }
+
+    @Override
+    public void close() throws Exception {
+        listenerRegistration.close();
+        LOGGER.trace("ArpUtil manager Closed");
+    }
+
+    String getIpAddressInString(IpAddress ipAddress)
+            throws UnknownHostException {
+        return InetAddress.getByName(ipAddress.getIpv4Address().getValue())
+                .getHostAddress();
+    }
+
+    public Future<RpcResult<GetMacOutput>> getMac(GetMacInput input) {
+
+        try {
+            final String dstIpAddress = getIpAddressInString(input
+                    .getIpaddress());
+            if (LOGGER.isTraceEnabled()) {
+                LOGGER.trace("getMac rpc invoked for ip " + dstIpAddress);
+            }
+            if (getMacFutures.get(dstIpAddress) != null) {
+                if (LOGGER.isInfoEnabled()) {
+                    LOGGER.info("get mac already in progress for the ip "
+                            + dstIpAddress);
+                }
+                return getMacFutures.get(dstIpAddress);
+            }
+            SendArpRequestInputBuilder builder = new SendArpRequestInputBuilder()
+                    .setInterfaceAddress(input.getInterfaceAddress())
+                    .setIpaddress(input.getIpaddress());
+            Future<RpcResult<Void>> arpReqFt = sendArpRequest(builder.build());
+            final SettableFuture<RpcResult<GetMacOutput>> ft = SettableFuture
+                    .create();
+
+            Futures.addCallback(
+                    JdkFutureAdapters.listenInPoolThread(arpReqFt, threadPool),
+                    new FutureCallback<RpcResult<Void>>() {
+                        @Override
+                        public void onFailure(Throwable e) {
+                            RpcResultBuilder<GetMacOutput> resultBuilder = RpcResultBuilder
+                                    .<GetMacOutput> failed().withError(
+                                            ErrorType.APPLICATION,
+                                            e.getMessage(), e);
+                            ft.set(resultBuilder.build());
+                        }
+
+                        @Override
+                        public void onSuccess(RpcResult<Void> result) {
+                            LOGGER.trace("Successfully sent the arp pkt out for ip "
+                                    + dstIpAddress);
+                        }
+                    });
+
+            getMacFutures.put(dstIpAddress, ft);
+            return ft;
+        } catch (Exception e) {
+            LOGGER.trace("failed to handle getMac request for {} {}",
+                    input.getIpaddress(), e);
+            RpcResultBuilder<GetMacOutput> resultBuilder = RpcResultBuilder
+                    .<GetMacOutput> failed().withError(ErrorType.APPLICATION,
+                            e.getMessage(), e);
+            return Futures.immediateFuture(resultBuilder.build());
+        }
+    }
+
+    byte[] getIpAddressBytes(IpAddress ip) throws UnknownHostException {
+        return InetAddress.getByName(ip.getIpv4Address().getValue())
+                .getAddress();
+    }
+
+    @Override
+    public Future<RpcResult<Void>> sendArpRequest(
+            SendArpRequestInput arpReqInput) {
+        if (LOGGER.isTraceEnabled()) {
+            LOGGER.trace("rpc sendArpRequest invoked for ip "
+                    + arpReqInput.getIpaddress());
+        }
+        BigInteger dpnId;
+        long groupId;
+        byte payload[];
+        String interfaceName = null;
+        byte srcIpBytes[];
+        byte[] dstIpBytes = null;
+
+        RpcResultBuilder<Void> failureBuilder = RpcResultBuilder
+                .<Void> failed();
+        RpcResultBuilder<Void> successBuilder = RpcResultBuilder
+                .<Void> success();
+
+        try {
+            dstIpBytes = getIpAddressBytes(arpReqInput.getIpaddress());
+        } catch (Exception e) {
+            failureBuilder.withError(ErrorType.APPLICATION,
+                    UNKNOWN_IP_ADDRESS_SUPPLIED);
+            return Futures.immediateFuture(failureBuilder.build());
+        }
+
+        int localErrorCount = 0;
+        for (InterfaceAddress interfaceAddress : arpReqInput
+                .getInterfaceAddress()) {
+            try {
+                interfaceName = interfaceAddress.getInterface();
+                srcIpBytes = getIpAddressBytes(interfaceAddress.getIpAddress());
+
+                NodeConnectorId id = getNodeConnectorFromDataStore(interfaceName);
+
+                dpnId = BigInteger.valueOf(MDSALUtil.getDpnIdFromPortName(id));
+                Long portid = MDSALUtil.getOfPortNumberFromPortName(id);
+                checkArgument(null != dpnId && BigInteger.ZERO != dpnId,
+                        DPN_NOT_FOUND_ERROR, interfaceName);
+
+                NodeConnectorRef ref = MDSALUtil.getNodeConnRef(dpnId,
+                        portid.toString());
+                checkNotNull(ref, NODE_CONNECTOR_NOT_FOUND_ERROR, interfaceName);
+
+                if (LOGGER.isTraceEnabled()) {
+                    LOGGER.trace(
+                            "sendArpRequest received dpnId {} out interface {}",
+                            dpnId, interfaceName);
+                }
+                byte srcMac[] = MDSALUtil.getMacAddressForNodeConnector(
+                        dataBroker,
+                        (InstanceIdentifier<NodeConnector>) ref.getValue());
+                checkNotNull(srcMac, FAILED_TO_GET_SRC_MAC_FOR_INTERFACE,
+                        interfaceName, ref.getValue());
+                checkNotNull(srcIpBytes, FAILED_TO_GET_SRC_IP_FOR_INTERFACE,
+                        interfaceName);
+
+                payload = ArpPacketUtil.getPayload(ARP_REQUEST_OP, srcMac,
+                        srcIpBytes, ArpPacketUtil.EthernetDestination_Broadcast,
+                        dstIpBytes);
+
+                sendPacketOut(dpnId, payload, ref);
+
+                if (LOGGER.isTraceEnabled()) {
+                    LOGGER.trace("sent arp request for "
+                            + arpReqInput.getIpaddress());
+                }
+            } catch (Exception e) {
+                LOGGER.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);
+                localErrorCount++;
+            }
+        }
+        if (localErrorCount == arpReqInput.getInterfaceAddress().size()) {
+            // All the requests failed
+            return Futures.immediateFuture(failureBuilder.build());
+        }
+        return Futures.immediateFuture(successBuilder.build());
+    }
+
+    public Future<RpcResult<Void>> 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()))
+                        .setIngress(nodeConnectorRef).setEgress(ref).build());
+    }
+
+    @Override
+    public Future<RpcResult<Void>> sendArpResponse(SendArpResponseInput input) {
+        if (LOGGER.isTraceEnabled()) {
+            LOGGER.trace("sendArpResponse rpc invoked");
+        }
+        BigInteger dpnId;
+        long groupId;
+        byte payload[];
+
+        try {
+            String interfaceName = input.getInterface();
+            NodeConnectorId id = getNodeConnectorFromDataStore(interfaceName);
+
+            dpnId = BigInteger.valueOf(MDSALUtil.getDpnIdFromPortName(id));
+            Long portid = MDSALUtil.getOfPortNumberFromPortName(id);
+
+            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);
+
+            if (LOGGER.isTraceEnabled()) {
+                LOGGER.trace(
+                        "sendArpRequest received dpnId {} out interface {}",
+                        dpnId, interfaceName);
+            }
+
+            byte[] srcIpBytes = getIpAddressBytes(input.getSrcIpAddress());
+            byte[] dstIpBytes = getIpAddressBytes(input.getIpaddress());
+            byte srcMac[] = MDSALUtil.getMacAddressForNodeConnector(dataBroker,
+                    (InstanceIdentifier<NodeConnector>) ref.getValue());
+            byte[] dstMac = NWUtil.parseMacAddress(input.getMacaddress()
+                    .getValue());
+            checkNotNull(srcIpBytes, FAILED_TO_GET_SRC_IP_FOR_INTERFACE,
+                    interfaceName);
+            payload = ArpPacketUtil.getPayload(ARP_RESPONSE_OP, srcMac, srcIpBytes,
+                    dstMac, dstIpBytes);
+
+            sendPacketOut(dpnId, payload, ref);
+            if (LOGGER.isTraceEnabled()) {
+                LOGGER.trace("sent the arp response for "
+                        + input.getSrcIpAddress());
+            }
+        } catch (Exception e) {
+            LOGGER.trace("failed to send arp response for {} {}",
+                    input.getSrcIpAddress(), e);
+            return RpcResultBuilder.<Void> failed()
+                    .withError(ErrorType.APPLICATION, e.getMessage(), e)
+                    .buildFuture();
+        }
+        RpcResultBuilder<Void> rpcResultBuilder = RpcResultBuilder.success();
+        return Futures.immediateFuture(rpcResultBuilder.build());
+    }
+
+    @Override
+    public void onPacketReceived(PacketReceived packetReceived) {
+        Class<? extends PacketInReason> pktInReason = packetReceived
+                .getPacketInReason();
+        if (LOGGER.isTraceEnabled()) {
+            LOGGER.trace("Packet Received {}", packetReceived);
+        }
+
+        if (pktInReason == SendToController.class) {
+
+            try {
+                int tableId = packetReceived.getTableId().getValue();
+
+                byte[] data = packetReceived.getPayload();
+                Ethernet ethernet = new Ethernet();
+
+                ethernet.deserialize(data, 0, data.length
+                        * NetUtils.NumBitsInAByte);
+                if (ethernet.getEtherType() != ARP_REQUEST_OP
+                        && ethernet.getEtherType() != ARP_REQUEST_OP) {
+                    return;
+                }
+
+                Packet pkt = ethernet.getPayload();
+                ARP arp = (ARP) pkt;
+                InetAddress srcInetAddr = InetAddress.getByAddress(arp
+                        .getSenderProtocolAddress());
+                InetAddress dstInetAddr = InetAddress.getByAddress(arp
+                        .getTargetProtocolAddress());
+                byte[] srcMac = ethernet.getSourceMACAddress();
+
+                NodeConnectorRef ref = packetReceived.getIngress();
+
+                String interfaceName = MDSALUtil.getInterfaceName(ref, dataBroker);
+
+                checkAndFireMacChangedNotification(interfaceName, srcInetAddr,
+                        srcMac);
+
+                macsDB.put(interfaceName + "-" + srcInetAddr.getHostAddress(),
+                        NWUtil.toStringMacAddress(srcMac));
+
+                if (arp.getOpCode() == ARP_REQUEST_OP) {
+                    fireArpReqRecvdNotification(interfaceName, srcInetAddr,
+                            srcMac, dstInetAddr, tableId);
+                } else {
+                    fireArpRespRecvdNotification(interfaceName, srcInetAddr,
+                            srcMac, tableId);
+                }
+                if (getMacFutures.get(srcInetAddr.getHostAddress()) != null) {
+                    threadPool.submit(new MacResponderTask(arp));
+                }
+
+            } catch (Exception e) {
+                LOGGER.trace("Failed to decode packet: {}", e);
+            }
+        }
+    }
+
+    class MacResponderTask implements Runnable {
+        ARP arp;
+
+        MacResponderTask(ARP arp) {
+            this.arp = arp;
+        }
+
+        @Override
+        public void run() {
+            InetAddress srcAddr;
+            GetMacOutputBuilder outputBuilder;
+            String srcMac;
+            SettableFuture<RpcResult<GetMacOutput>> future = null;
+            RpcResultBuilder<GetMacOutput> resultBuilder;
+            try {
+                srcAddr = InetAddress.getByAddress(arp
+                        .getSenderProtocolAddress());
+                srcMac = NWUtil.toStringMacAddress(arp
+                        .getSenderHardwareAddress());
+                future = getMacFutures.remove(srcAddr.getHostAddress());
+                if (future == null) {
+                    LOGGER.trace("There are no pending mac requests.");
+                    return;
+                }
+                outputBuilder = new GetMacOutputBuilder()
+                        .setMacaddress(new PhysAddress(srcMac));
+                resultBuilder = RpcResultBuilder.success(outputBuilder.build());
+                if (LOGGER.isTraceEnabled()) {
+                    LOGGER.trace("sent the mac response for ip {}",
+                            srcAddr.getHostAddress());
+                }
+            } catch (Exception e) {
+                LOGGER.trace("failed to send mac response {} ", e);
+                resultBuilder = RpcResultBuilder.<GetMacOutput> failed()
+                        .withError(ErrorType.APPLICATION, e.getMessage(), e);
+            }
+            future.set(resultBuilder.build());
+        }
+    }
+
+    private void fireArpRespRecvdNotification(String interfaceName,
+            InetAddress inetAddr, byte[] macAddressBytes, int tableId)
+            throws InterruptedException {
+
+        IpAddress ip = new IpAddress(inetAddr.getHostAddress().toCharArray());
+        String macAddress = NWUtil.toStringMacAddress(macAddressBytes);
+        PhysAddress mac = new PhysAddress(macAddress);
+        ArpResponseReceivedBuilder builder = new ArpResponseReceivedBuilder();
+        builder.setInterface(interfaceName);
+        builder.setIpaddress(ip);
+        builder.setOfTableId((long) tableId);
+        builder.setMacaddress(mac);
+        notificationPublishService.putNotification(builder.build());
+    }
+
+    private void fireArpReqRecvdNotification(String interfaceName,
+            InetAddress srcInetAddr, byte[] srcMac, InetAddress dstInetAddr,
+            int tableId) throws InterruptedException {
+        String macAddress = NWUtil.toStringMacAddress(srcMac);
+        ArpRequestReceivedBuilder builder = new ArpRequestReceivedBuilder();
+        builder.setInterface(interfaceName);
+        builder.setOfTableId((long) tableId);
+        builder.setSrcIpaddress(new IpAddress(srcInetAddr.getHostAddress()
+                .toCharArray()));
+        builder.setDstIpaddress(new IpAddress(dstInetAddr.getHostAddress()
+                .toCharArray()));
+        builder.setSrcMac(new PhysAddress(macAddress));
+        notificationPublishService.putNotification(builder.build());
+    }
+
+    private void checkAndFireMacChangedNotification(String interfaceName,
+            InetAddress inetAddr, byte[] macAddressBytes)
+            throws InterruptedException {
+
+        IpAddress ip = new IpAddress(inetAddr.getHostAddress().toCharArray());
+        String macAddress = NWUtil.toStringMacAddress(macAddressBytes);
+        PhysAddress mac = new PhysAddress(macAddress);
+
+        if (!macAddress.equals(macsDB.get(interfaceName + "-"
+                + inetAddr.getHostAddress()))) {
+            if (LOGGER.isTraceEnabled()) {
+                LOGGER.trace("mac address changed for " + inetAddr);
+            }
+            MacChangedBuilder builder = new MacChangedBuilder();
+            builder.setInterface(interfaceName);
+            builder.setIpaddress(ip);
+            builder.setMacaddress(mac);
+            notificationPublishService.putNotification(builder.build());
+        }
+    }
+
+    private InstanceIdentifier<Interface> buildInterfaceId(String interfaceName) {
+        InstanceIdentifierBuilder<Interface> idBuilder = InstanceIdentifier
+                .builder(Interfaces.class).child(Interface.class,
+                        new InterfaceKey(interfaceName));
+        InstanceIdentifier<Interface> id = idBuilder.build();
+        return id;
+    }
+
+
+    private NodeConnectorId getNodeConnectorFromDataStore(String interfaceName) {
+        InstanceIdentifier<Interface> id = buildInterfaceId(interfaceName);
+        Optional<Interface> interf = MDSALUtil.read(dataBroker,
+                LogicalDatastoreType.CONFIGURATION,
+                id);
+        if (interf.isPresent()) {
+            return interf.get().getAugmentation(BaseIds.class).getOfPortId();
+        }
+        return null;
+    }
+
+}
diff --git a/arputil/arputil-impl/src/main/java/org/opendaylight/vpnservice/arputil/internal/ArpUtilProvider.java b/arputil/arputil-impl/src/main/java/org/opendaylight/vpnservice/arputil/internal/ArpUtilProvider.java
new file mode 100644 (file)
index 0000000..d22f699
--- /dev/null
@@ -0,0 +1,81 @@
+/*
+ * Copyright (c) 2015 Ericsson India Global Services Pvt Ltd. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.vpnservice.arputil.internal;
+
+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.sal.binding.api.BindingAwareBroker;
+import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.ProviderContext;
+import org.opendaylight.controller.sal.binding.api.BindingAwareProvider;
+import org.opendaylight.controller.sal.binding.api.RpcProviderRegistry;
+import org.opendaylight.vpnservice.mdsalutil.interfaces.IMdsalApiManager;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.packet.service.rev130709.PacketProcessingService;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.arputil.rev151126.OdlArputilService;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class ArpUtilProvider implements BindingAwareProvider, AutoCloseable {
+
+    private static final Logger s_logger = LoggerFactory.getLogger(ArpUtilProvider.class);
+
+    RpcProviderRegistry         rpcProviderRegistry;
+
+    NotificationService         notificationService;
+
+    NotificationPublishService  notificationPublishService;
+
+    ArpUtilImpl                  arpManager;
+
+    IMdsalApiManager            mdsalApiManager;
+
+    BindingAwareBroker.RpcRegistration<OdlArputilService> rpcRegistration;
+
+    public ArpUtilProvider(RpcProviderRegistry rpcRegistry,
+            NotificationPublishService publishService,
+            NotificationService notificationService,
+            IMdsalApiManager iMdsalApiManager) {
+
+        this.rpcProviderRegistry        = rpcRegistry;
+        this.mdsalApiManager            = iMdsalApiManager;
+        this.notificationPublishService = publishService;
+        this.notificationService        = notificationService;
+    }
+
+    public ArpUtilProvider() {
+    }
+
+    @Override
+    public void onSessionInitiated(final ProviderContext session){
+
+        s_logger.info( " Session Initiated for Arp Provider") ;
+
+        try {
+            DataBroker dataBroker = session.getSALService(DataBroker.class);
+            PacketProcessingService packetProcessingService =
+                    session.getRpcService(PacketProcessingService.class);
+
+            arpManager = new ArpUtilImpl( dataBroker, packetProcessingService,
+                    notificationPublishService, notificationService,
+                     mdsalApiManager) ;
+
+            rpcRegistration = rpcProviderRegistry.
+                    addRpcImplementation(OdlArputilService.class, arpManager);
+            s_logger.info( " Session Initialized for Arp Provider") ;
+        }catch( Exception e) {
+            s_logger.error( "Error initializing Arp " , e );
+        }
+    }
+
+    @Override
+    public void close() throws Exception {
+        rpcRegistration.close();
+        arpManager.close();
+        s_logger.info("ArpManager Manager Closed");
+    }
+}
diff --git a/arputil/arputil-impl/src/main/java/org/opendaylight/yang/gen/v1/urn/opendaylight/params/xml/ns/yang/arputil/impl/rev151126/ArputilImplModule.java b/arputil/arputil-impl/src/main/java/org/opendaylight/yang/gen/v1/urn/opendaylight/params/xml/ns/yang/arputil/impl/rev151126/ArputilImplModule.java
new file mode 100644 (file)
index 0000000..83f9579
--- /dev/null
@@ -0,0 +1,30 @@
+package org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.arputil.impl.rev151126;
+
+import org.opendaylight.vpnservice.arputil.internal.ArpUtilProvider;
+
+public class ArputilImplModule extends org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.arputil.impl.rev151126.AbstractArputilImplModule {
+    public ArputilImplModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier, org.opendaylight.controller.config.api.DependencyResolver dependencyResolver) {
+        super(identifier, dependencyResolver);
+    }
+
+    public ArputilImplModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier, org.opendaylight.controller.config.api.DependencyResolver dependencyResolver, org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.arputil.impl.rev151126.ArputilImplModule oldModule, java.lang.AutoCloseable oldInstance) {
+        super(identifier, dependencyResolver, oldModule, oldInstance);
+    }
+
+    @Override
+    public void customValidation() {
+        // add custom validation form module attributes here.
+    }
+
+    @Override
+    public java.lang.AutoCloseable createInstance() {
+        ArpUtilProvider provider = new ArpUtilProvider(getRpcRegistryDependency(),
+                getNotificationPublishServiceDependency(),
+                getNotificationServiceDependency(),
+                getMdsalutilDependency()
+                );
+        getBrokerDependency().registerProvider(provider);
+        return provider;
+    }
+
+}
diff --git a/arputil/arputil-impl/src/main/java/org/opendaylight/yang/gen/v1/urn/opendaylight/params/xml/ns/yang/arputil/impl/rev151126/ArputilImplModuleFactory.java b/arputil/arputil-impl/src/main/java/org/opendaylight/yang/gen/v1/urn/opendaylight/params/xml/ns/yang/arputil/impl/rev151126/ArputilImplModuleFactory.java
new file mode 100644 (file)
index 0000000..af7a575
--- /dev/null
@@ -0,0 +1,13 @@
+/*
+* Generated file
+*
+* Generated from: yang module name: arputil-impl yang module local name: arputil-impl
+* Generated by: org.opendaylight.controller.config.yangjmxgenerator.plugin.JMXGenerator
+* Generated at: Mon Dec 07 21:19:46 IST 2015
+*
+* Do not modify this file unless it is present under src/main directory
+*/
+package org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.arputil.impl.rev151126;
+public class ArputilImplModuleFactory extends org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.arputil.impl.rev151126.AbstractArputilImplModuleFactory {
+
+}
diff --git a/arputil/arputil-impl/src/main/yang/arputil-impl.yang b/arputil/arputil-impl/src/main/yang/arputil-impl.yang
new file mode 100644 (file)
index 0000000..2107ff3
--- /dev/null
@@ -0,0 +1,70 @@
+module arputil-impl {
+    yang-version 1;
+    namespace "urn:opendaylight:params:xml:ns:yang:arputil:impl";
+    prefix "arputil-impl";
+
+    import config { prefix config; revision-date 2013-04-05; }
+    import opendaylight-md-sal-binding { prefix md-sal-binding; revision-date 2013-10-28;}
+    import opendaylight-sal-binding-broker-impl { prefix md-sal-binding-impl; revision-date 2013-10-28;}
+    import odl-mdsalutil { prefix odl-mdsal; revision-date 2015-04-10;}
+    import ietf-inet-types { prefix inet; }
+    import ietf-yang-types { prefix yang;}
+
+    description
+        "Service definition for mdsal project";
+
+    revision "2015-11-26" {
+        description
+            "Initial revision";
+    }
+
+    identity arputil-impl {
+       base config:module-type;
+    }
+
+    augment "/config:modules/config:module/config:configuration" {
+        case arputil-impl {
+            when "/config:modules/config:module/config:type = 'arputil-impl'";
+            container broker {
+                uses config:service-ref {
+                    refine type {
+                        mandatory true;
+                        config:required-identity md-sal-binding:binding-broker-osgi-registry;
+                    }
+                }
+            }
+            container rpc-registry {
+                 uses config:service-ref {
+                      refine type {
+                         mandatory true;
+                         config:required-identity md-sal-binding:binding-rpc-registry;
+                      }
+                 }
+            }
+            container mdsalutil {
+                uses config:service-ref {
+                    refine type {
+                        mandatory true;
+                        config:required-identity odl-mdsal:odl-mdsalutil;
+                    }
+                }
+            }
+            container notification-publish-service {
+                uses config:service-ref {
+                    refine type {
+                        mandatory true;
+                        config:required-identity md-sal-binding-impl:binding-new-notification-publish-service;
+                    }
+                }
+            }
+            container notification-service {
+                uses config:service-ref {
+                    refine type {
+                        mandatory true;
+                        config:required-identity md-sal-binding-impl:binding-new-notification-service;
+                    }
+                }
+            }
+        }
+    }
+}
diff --git a/arputil/pom.xml b/arputil/pom.xml
new file mode 100644 (file)
index 0000000..a65eb70
--- /dev/null
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+Copyright (c) 2015 Ericsson India Global Services Pvt Ltd. and others. All rights reserved.
+This program and the accompanying materials are made available under the
+terms of the Eclipse Public License v1.0 which accompanies this distribution,
+and is available at http://www.eclipse.org/legal/epl-v10.html INTERNAL
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+
+  <parent>
+    <groupId>org.opendaylight.odlparent</groupId>
+    <artifactId>odlparent</artifactId>
+    <version>1.6.0-SNAPSHOT</version>
+    <relativePath/>
+  </parent>
+
+  <groupId>org.opendaylight.vpnservice</groupId>
+  <artifactId>arputil-aggregator</artifactId>
+  <version>0.2.0-SNAPSHOT</version>
+  <name>arputil</name>
+  <packaging>pom</packaging>
+  <modelVersion>4.0.0</modelVersion>
+  <prerequisites>
+    <maven>3.1.1</maven>
+  </prerequisites>
+  <modules>
+    <module>arputil-api</module>
+    <module>arputil-impl</module>
+  </modules>
+  <!-- DO NOT install or deploy the repo root pom as it's only needed to initiate a build -->
+  <build>
+    <plugins>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-deploy-plugin</artifactId>
+        <configuration>
+          <skip>true</skip>
+        </configuration>
+      </plugin>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-install-plugin</artifactId>
+        <configuration>
+          <skip>true</skip>
+        </configuration>
+      </plugin>
+    </plugins>
+  </build>
+</project>
index 0a47ecfa6b53abb8d7bf1c55b5041822a873baa6..60c9534bce07697ef847a59a6eb5caaaa81a0f12 100644 (file)
@@ -30,6 +30,7 @@ and is available at http://www.eclipse.org/legal/epl-v10.html
     <model.bgp.version>2013.07.15.8-SNAPSHOT</model.bgp.version>
     <openflowplugin.version>0.2.0-SNAPSHOT</openflowplugin.version>
     <vpns.ovsdb.version>1.2.1-SNAPSHOT</vpns.ovsdb.version>
+    <liblldp.version>0.10.0-SNAPSHOT</liblldp.version>
   </properties>
 
   <dependencyManagement>
index 72b6f763b1ebb67b403cb6346c7f100593871de0..4fae2518ad0fcb45fc2d99c48ba4bc89d46bd3a4 100644 (file)
@@ -28,6 +28,7 @@ and is available at http://www.eclipse.org/legal/epl-v10.html INTERNAL
     <mdsal.model.version>0.8.0-SNAPSHOT</mdsal.model.version>
     <vpnservices.version>0.2.0-SNAPSHOT</vpnservices.version>
     <ovsdb.version>1.2.1-SNAPSHOT</ovsdb.version>
+    <arputil.version>${vpnservices.version}</arputil.version>
     <mdsalutil.version>${vpnservices.version}</mdsalutil.version>
     <vpnmanager.version>${vpnservices.version}</vpnmanager.version>
     <interfacemgr.version>${vpnservices.version}</interfacemgr.version>
@@ -116,11 +117,29 @@ and is available at http://www.eclipse.org/legal/epl-v10.html INTERNAL
       <version>${vpnmanager.version}</version>
       <classifier>config</classifier>
       <type>xml</type>
-    </dependency><dependency>
+    </dependency>
+    <dependency>
       <groupId>${project.groupId}</groupId>
       <artifactId>mdsalutil-impl</artifactId>
       <version>${mdsalutil.version}</version>
     </dependency>
+    <dependency>
+      <groupId>${project.groupId}</groupId>
+      <artifactId>arputil-api</artifactId>
+      <version>${arputil.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>${project.groupId}</groupId>
+      <artifactId>arputil-impl</artifactId>
+      <version>${arputil.version}</version>
+      <classifier>config</classifier>
+      <type>xml</type>
+    </dependency>
+     <dependency>
+      <groupId>${project.groupId}</groupId>
+      <artifactId>arputil-impl</artifactId>
+      <version>${arputil.version}</version>
+    </dependency>
     <dependency>
       <groupId>${project.groupId}</groupId>
       <artifactId>mdsalutil-impl</artifactId>
index 270db04df3cf65ff6c78c8213bf06a1cbc4af5de..c7167833f29062941586472f0e72be7ced6ef50d 100644 (file)
@@ -23,6 +23,7 @@ and is available at http://www.eclipse.org/legal/epl-v10.html
     <bundle>mvn:org.opendaylight.vpnservice/model-bgp/{{VERSION}}</bundle>
     <bundle>mvn:org.opendaylight.vpnservice/lockmanager-api/${lockmanager.version}</bundle>
     <bundle>mvn:org.opendaylight.vpnservice/idmanager-api/${idmanager.version}</bundle>
+    <bundle>mvn:org.opendaylight.vpnservice/arputil-api/${arputil.version}</bundle>
     <bundle>mvn:org.opendaylight.vpnservice/vpnmanager-api/${vpnmanager.version}</bundle>
     <bundle>mvn:org.opendaylight.vpnservice/nexthopmgr-api/${nexthopmgr.version}</bundle>
     <bundle>mvn:org.opendaylight.vpnservice/fibmanager-api/${fibmanager.version}</bundle>
@@ -39,6 +40,7 @@ and is available at http://www.eclipse.org/legal/epl-v10.html
     <bundle>mvn:org.opendaylight.vpnservice/bgpmanager-api/${vpnservices.version}</bundle>
     <bundle>mvn:org.opendaylight.vpnservice/bgpmanager-impl/${vpnservices.version}</bundle>
     <bundle>mvn:org.opendaylight.vpnservice/mdsalutil-api/${interfacemgr.version}</bundle>
+    <bundle>mvn:org.opendaylight.vpnservice/arputil-impl/${arputil.version}</bundle>
     <bundle>mvn:org.opendaylight.vpnservice/mdsalutil-impl/${interfacemgr.version}</bundle>
     <bundle>mvn:org.opendaylight.vpnservice/interfacemgr-api/${interfacemgr.version}</bundle>
     <bundle>mvn:org.opendaylight.vpnservice/interfacemgr-impl/${interfacemgr.version}</bundle>
@@ -55,6 +57,7 @@ and is available at http://www.eclipse.org/legal/epl-v10.html
     <configfile finalname="bgpmanager-impl-default-config.xml">mvn:org.opendaylight.vpnservice/bgpmanager-impl/${vpnservices.version}/xml/config</configfile>
     <configfile finalname="mdsalutil-impl-default-config.xml">mvn:org.opendaylight.vpnservice/mdsalutil-impl/${interfacemgr.version}/xml/config</configfile>
     <configfile finalname="interfacemgr-impl-default-config.xml">mvn:org.opendaylight.vpnservice/interfacemgr-impl/${interfacemgr.version}/xml/config</configfile>
+    <configfile finalname="arputil-impl-default-config.xml">mvn:org.opendaylight.vpnservice/arputil-impl/${arputil.version}/xml/config</configfile>
     <configfile finalname="vpnmanager-impl-default-config.xml">mvn:org.opendaylight.vpnservice/vpnmanager-impl/${vpnmanager.version}/xml/config</configfile>
     <configfile finalname="nexthopmgr-impl-default-config.xml">mvn:org.opendaylight.vpnservice/nexthopmgr-impl/${nexthopmgr.version}/xml/config</configfile>
     <configfile finalname="fibmanager-impl-default-config.xml">mvn:org.opendaylight.vpnservice/fibmanager-impl/${fibmanager.version}/xml/config</configfile>
index 61410f8c2e00c0c3a8ac67da0831e76840075eb4..424319fa3e83def673e440e1936a4b8c8fa24cf5 100644 (file)
@@ -1,14 +1,14 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
-    
+
     <parent>
         <groupId>org.opendaylight.vpnservice</groupId>
         <artifactId>config-parent</artifactId>
         <version>0.2.0-SNAPSHOT</version>
         <relativePath>../../commons/config-parent</relativePath>
      </parent>
-    
+
     <modelVersion>4.0.0</modelVersion>
     <groupId>org.opendaylight.vpnservice</groupId>
     <artifactId>mdsalutil-api</artifactId>
     <packaging>bundle</packaging>
 
     <dependencies>
-    <dependency>
-                <groupId>org.opendaylight.openflowplugin.model</groupId>
-                <artifactId>model-flow-base</artifactId>
-                <version>${openflowplugin.version}</version>
-            </dependency>
-            <dependency>
-                <groupId>org.opendaylight.openflowplugin.model</groupId>
-                <artifactId>model-flow-service</artifactId>
-                <version>${openflowplugin.version}</version>
+        <dependency>
+            <groupId>org.opendaylight.openflowplugin.model</groupId>
+            <artifactId>model-flow-base</artifactId>
+            <version>${openflowplugin.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.opendaylight.openflowplugin.model</groupId>
+            <artifactId>model-flow-service</artifactId>
+            <version>${openflowplugin.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.opendaylight.controller</groupId>
+            <artifactId>liblldp</artifactId>
+            <version>${liblldp.version}</version>
         </dependency>
-                      
     </dependencies>
 </project>
index 5ccaa576347f55f0a1952fa9c74d26c75f5fe63d..1d10a69aca89c0432ba754c4cd27936ac1c1ec45 100644 (file)
@@ -17,6 +17,10 @@ import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.ExecutionException;
 import java.util.concurrent.LinkedBlockingQueue;
 
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev100924.MacAddress;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.PopVlanActionCaseBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.pop.vlan.action._case.PopVlanActionBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.ActionBuilder;
@@ -62,6 +66,7 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.N
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey;
 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.yangtools.yang.binding.DataObject;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier.InstanceIdentifierBuilder;
 import org.opendaylight.yangtools.yang.binding.DataObject;
@@ -72,7 +77,8 @@ import org.opendaylight.controller.md.sal.binding.api.DataBroker;
 import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
-
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNodeConnector;
+import org.opendaylight.controller.liblldp.HexEncode;
 import com.google.common.base.Joiner;
 import com.google.common.base.Optional;
 import com.google.common.primitives.Bytes;
@@ -314,6 +320,12 @@ public class MDSALUtil {
         return getOfPortNumberFromPortName(nodeConnectorId.getValue());
     }
 
+    public static long getDpnIdFromPortName(NodeConnectorId nodeConnectorId) {
+        String ofPortName = nodeConnectorId.getValue();
+        return Long.parseLong(ofPortName.substring(ofPortName.indexOf(":")+1, 
+                ofPortName.lastIndexOf(":")));
+    }
+
     public static long getOfPortNumberFromPortName(String sMdsalPortName) {
         String sPortNumber = sMdsalPortName.substring(sMdsalPortName.lastIndexOf(":") + 1);
         return Long.parseLong(sPortNumber);
@@ -374,7 +386,6 @@ public class MDSALUtil {
         } catch (Exception e) {
             throw new RuntimeException(e);
         }
-
         return result;
     }
 
@@ -418,4 +429,52 @@ public class MDSALUtil {
             throw new RuntimeException(e.getMessage());
         }
     }
+
+    public static byte[] getMacAddressForNodeConnector(DataBroker broker,
+            InstanceIdentifier<NodeConnector> nodeConnectorId)  {
+        Optional<NodeConnector> optNc = MDSALDataStoreUtils.read(broker,
+                LogicalDatastoreType.OPERATIONAL, nodeConnectorId);
+        if(optNc.isPresent()) {
+            NodeConnector nc = optNc.get();
+            FlowCapableNodeConnector fcnc = nc.getAugmentation(FlowCapableNodeConnector.class);
+            MacAddress macAddress = fcnc.getHardwareAddress();
+            return HexEncode.bytesFromHexString(macAddress.getValue());
+        }
+        return null;
+    }
+
+    public static NodeId getNodeIdFromNodeConnectorId(NodeConnectorId ncId) {
+        return new NodeId(ncId.getValue().substring(0,
+                ncId.getValue().lastIndexOf(":")));
+    }
+
+    public static String getInterfaceName(NodeConnectorRef ref, DataBroker dataBroker) {
+        NodeConnectorId nodeConnectorId = getNodeConnectorId(dataBroker, ref);
+        NodeId nodeId = getNodeIdFromNodeConnectorId(nodeConnectorId);
+        InstanceIdentifier<NodeConnector> ncIdentifier = InstanceIdentifier
+                .builder(Nodes.class)
+                .child(Node.class, new NodeKey(nodeId))
+                .child(NodeConnector.class,
+                        new NodeConnectorKey(nodeConnectorId)).build();
+
+        Optional<NodeConnector> nodeConnectorOptional = read(
+                dataBroker,
+                LogicalDatastoreType.OPERATIONAL, ncIdentifier);
+        if (!nodeConnectorOptional.isPresent()) {
+            return null;
+        }
+        NodeConnector nc = nodeConnectorOptional.get();
+        FlowCapableNodeConnector fc = nc
+                .getAugmentation(FlowCapableNodeConnector.class);
+        return fc.getName();
+    }
+
+    public static NodeConnectorId getNodeConnectorId(DataBroker dataBroker,
+            NodeConnectorRef ref) {
+        Optional<NodeConnector> nc = (Optional<NodeConnector>) read(
+                dataBroker,
+                LogicalDatastoreType.CONFIGURATION, ref.getValue());
+        return nc.get().getId();
+    }
+
 }
diff --git a/mdsalutil/mdsalutil-api/src/main/java/org/opendaylight/vpnservice/mdsalutil/NWUtil.java b/mdsalutil/mdsalutil-api/src/main/java/org/opendaylight/vpnservice/mdsalutil/NWUtil.java
new file mode 100644 (file)
index 0000000..e2f3d63
--- /dev/null
@@ -0,0 +1,92 @@
+/*
+ * Copyright (c) 2015 Ericsson India Global Services Pvt Ltd. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.vpnservice.mdsalutil;
+
+import java.net.InetAddress;
+
+import com.google.common.primitives.UnsignedBytes;
+
+public class NWUtil {
+
+    public static  long convertInetAddressToLong(InetAddress address) {
+        byte[] ipAddressRaw = address.getAddress();
+        return (((ipAddressRaw[0] & 0xFF) << (3 * 8))
+                + ((ipAddressRaw[1] & 0xFF) << (2 * 8))
+                + ((ipAddressRaw[2] & 0xFF) << (1 * 8))
+                + (ipAddressRaw[3] & 0xFF))
+                & 0xffffffffL;
+    }
+
+    public static byte[] parseIpAddress(String ipAddress) {
+        byte cur;
+
+        String[] addressPart = ipAddress.split(".");
+        int size = addressPart.length;
+
+        byte[] part = new byte[size];
+        for (int i = 0; i < size; i++) {
+            cur = UnsignedBytes.parseUnsignedByte(addressPart[i], 16);
+            part[i] = cur;
+        }
+
+        return part;
+    }
+
+    public static byte[] parseMacAddress(String macAddress) {
+        byte cur;
+
+        String[] addressPart = macAddress.split(":");
+        int size = addressPart.length;
+
+        byte[] part = new byte[size];
+        for (int i = 0; i < size; i++) {
+            cur = UnsignedBytes.parseUnsignedByte(addressPart[i], 16);
+            part[i] = cur;
+        }
+
+        return part;
+    }
+
+    public static String toStringIpAddress(byte[] ipAddress)
+    {
+        if (ipAddress == null) {
+            return "";
+        }
+
+        StringBuilder sb = new StringBuilder(18);
+
+        for (int i = 0; i < ipAddress.length; i++) {
+            sb.append(UnsignedBytes.toString(ipAddress[i], 10));
+            sb.append(".");
+        }
+
+        sb.setLength(17);
+        return sb.toString();
+    }
+
+    public static String toStringMacAddress(byte[] macAddress)
+    {
+        if (macAddress == null) {
+            return "";
+        }
+
+        StringBuilder sb = new StringBuilder(18);
+
+        for (int i = 0; i < macAddress.length; i++) {
+            String tmp = UnsignedBytes.toString(macAddress[i], 16).toUpperCase();
+            if(tmp.length() == 1 || macAddress[i] == (byte)0) {
+                sb.append("0");
+            }
+            sb.append(tmp);
+            sb.append(":");
+        }
+
+        sb.setLength(17);
+        return sb.toString();
+    }
+}
diff --git a/mdsalutil/mdsalutil-api/src/main/java/org/opendaylight/vpnservice/mdsalutil/packet/ARP.java b/mdsalutil/mdsalutil-api/src/main/java/org/opendaylight/vpnservice/mdsalutil/packet/ARP.java
new file mode 100644 (file)
index 0000000..5f502d0
--- /dev/null
@@ -0,0 +1,200 @@
+/*
+ * Copyright (c) 2013, 2015 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.vpnservice.mdsalutil.packet;
+
+import java.util.HashMap;
+import java.util.LinkedHashMap;
+import java.util.Map;
+
+import org.apache.commons.lang3.tuple.ImmutablePair;
+import org.apache.commons.lang3.tuple.Pair;
+import org.opendaylight.controller.liblldp.BitBufferHelper;
+import org.opendaylight.controller.liblldp.Packet;
+
+/**
+ * Class that represents the ARP packet objects
+ * taken from opendaylight(helium) adsal bundle
+ *
+ */
+
+public class ARP extends Packet {
+    private static final String HWTYPE = "HardwareType";
+    private static final String PTYPE = "ProtocolType";
+    private static final String HWADDRLENGTH = "HardwareAddressLength";
+    private static final String PADDRLENGTH = "ProtocolAddressLength";
+    private static final String OPCODE = "OpCode";
+    private static final String SENDERHWADDR = "SenderHardwareAddress";
+    private static final String SENDERPADDR = "SenderProtocolAddress";
+    private static final String TARGETHWADDR = "TargetHardwareAddress";
+    private static final String TARGETPADDR = "TargetProtocolAddress";
+
+    public static short HW_TYPE_ETHERNET = (short) 0x1;
+    public static short REQUEST = (short) 0x1;
+    public static short REPLY = (short) 0x2;
+
+    public static short PROTO_TYPE_IP = 0x800;
+
+    private static Map<String, Pair<Integer, Integer>> fieldCoordinates = new LinkedHashMap<String, Pair<Integer, Integer>>() {
+        private static final long serialVersionUID = 1L;
+        {
+            put(HWTYPE, new ImmutablePair<Integer, Integer>(0, 16));
+            put(PTYPE, new ImmutablePair<Integer, Integer>(16, 16));
+            put(HWADDRLENGTH, new ImmutablePair<Integer, Integer>(32, 8));
+            put(PADDRLENGTH, new ImmutablePair<Integer, Integer>(40, 8));
+            put(OPCODE, new ImmutablePair<Integer, Integer>(48, 16));
+            put(SENDERHWADDR, new ImmutablePair<Integer, Integer>(64, 48));
+            put(SENDERPADDR, new ImmutablePair<Integer, Integer>(112, 32));
+            put(TARGETHWADDR, new ImmutablePair<Integer, Integer>(144, 48));
+            put(TARGETPADDR, new ImmutablePair<Integer, Integer>(192, 32));
+
+        }
+    };
+    private Map<String, byte[]> fieldValues;
+
+    /**
+     * Default constructor that creates and sets the HashMap
+     */
+    public ARP() {
+        super();
+        fieldValues = new HashMap<String, byte[]>();
+        hdrFieldCoordMap = fieldCoordinates;
+        hdrFieldsMap = fieldValues;
+    }
+
+    /**
+     * Constructor that sets the access level for the packet and
+     * creates and sets the HashMap
+     */
+    public ARP(boolean writeAccess) {
+        super(writeAccess);
+        fieldValues = new HashMap<String, byte[]>();
+        hdrFieldCoordMap = fieldCoordinates;
+        hdrFieldsMap = fieldValues;
+    }
+
+    public short getHardwareType() {
+        return (BitBufferHelper.getShort(fieldValues.get(HWTYPE)));
+
+    }
+
+    public short getProtocolType() {
+        return (BitBufferHelper.getShort(fieldValues.get(PTYPE)));
+    }
+
+    public byte getHardwareAddressLength() {
+        return (BitBufferHelper.getByte(fieldValues.get(HWADDRLENGTH)));
+    }
+
+    public byte getProtocolAddressLength() {
+        return (BitBufferHelper.getByte(fieldValues.get(PADDRLENGTH)));
+    }
+
+    public short getOpCode() {
+        return (BitBufferHelper.getShort(fieldValues.get(OPCODE)));
+    }
+
+    public byte[] getSenderHardwareAddress() {
+        return (fieldValues.get(SENDERHWADDR));
+    }
+
+    public byte[] getSenderProtocolAddress() {
+        return (fieldValues.get(SENDERPADDR));
+    }
+
+    public byte[] getTargetHardwareAddress() {
+        return (fieldValues.get(TARGETHWADDR));
+    }
+
+    public ARP setHardwareType(short hardwareType) {
+        byte[] hwType = BitBufferHelper.toByteArray(hardwareType);
+        fieldValues.put(HWTYPE, hwType);
+        return this;
+    }
+
+    public ARP setProtocolType(short protocolType) {
+        byte[] protType = BitBufferHelper.toByteArray(protocolType);
+        fieldValues.put(PTYPE, protType);
+        return this;
+    }
+
+    public ARP setHardwareAddressLength(byte hardwareAddressLength) {
+        byte[] hwAddressLength = BitBufferHelper
+                .toByteArray(hardwareAddressLength);
+        fieldValues.put(HWADDRLENGTH, hwAddressLength);
+        return this;
+    }
+
+    public ARP setProtocolAddressLength(byte protocolAddressLength) {
+        byte[] protocolAddrLength = BitBufferHelper
+                .toByteArray(protocolAddressLength);
+        fieldValues.put(PADDRLENGTH, protocolAddrLength);
+        return this;
+    }
+
+    public ARP setOpCode(short opCode) {
+        byte[] operationCode = BitBufferHelper.toByteArray(opCode);
+        fieldValues.put(OPCODE, operationCode);
+        return this;
+    }
+
+    public ARP setSenderHardwareAddress(byte[] senderHardwareAddress) {
+        fieldValues.put(SENDERHWADDR, senderHardwareAddress);
+        return this;
+    }
+
+    public ARP setTargetHardwareAddress(byte[] targetHardwareAddress) {
+        fieldValues.put(TARGETHWADDR, targetHardwareAddress);
+        return this;
+    }
+
+    public ARP setTargetProtocolAddress(byte[] targetProtocolAddress) {
+        fieldValues.put(TARGETPADDR, targetProtocolAddress);
+        return this;
+    }
+
+    public ARP setSenderProtocolAddress(byte[] senderIP) {
+        fieldValues.put(SENDERPADDR, senderIP);
+        return this;
+    }
+
+    public byte[] getTargetProtocolAddress() {
+        return fieldValues.get(TARGETPADDR);
+    }
+
+    @Override
+    public int hashCode() {
+        final int prime = 31;
+        int result = super.hashCode();
+        result = prime * result
+                + ((fieldValues == null) ? 0 : fieldValues.hashCode());
+        return result;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (!super.equals(obj)) {
+            return false;
+        }
+        if (getClass() != obj.getClass()) {
+            return false;
+        }
+        ARP other = (ARP) obj;
+        if (fieldValues == null) {
+            if (other.fieldValues != null) {
+                return false;
+            }
+        } else if (!fieldValues.equals(other.fieldValues)) {
+            return false;
+        }
+        return true;
+    }
+}
diff --git a/mdsalutil/mdsalutil-api/src/main/java/org/opendaylight/vpnservice/mdsalutil/packet/Ethernet.java b/mdsalutil/mdsalutil-api/src/main/java/org/opendaylight/vpnservice/mdsalutil/packet/Ethernet.java
new file mode 100644 (file)
index 0000000..5fce3de
--- /dev/null
@@ -0,0 +1,120 @@
+/*
+ * Copyright (c) 2013, 2015 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.vpnservice.mdsalutil.packet;
+
+import java.util.HashMap;
+import java.util.LinkedHashMap;
+import java.util.Map;
+
+import org.apache.commons.lang3.tuple.ImmutablePair;
+import org.apache.commons.lang3.tuple.Pair;
+import org.opendaylight.controller.liblldp.BitBufferHelper;
+import org.opendaylight.controller.liblldp.EtherTypes;
+import org.opendaylight.controller.liblldp.LLDP;
+import org.opendaylight.controller.liblldp.NetUtils;
+import org.opendaylight.controller.liblldp.Packet;
+
+/**
+ * Class that represents the Ethernet frame objects
+ * taken from opendaylight(helium) adsal bundle
+ */
+public class Ethernet extends Packet {
+    private static final String DMAC = "DestinationMACAddress";
+    private static final String SMAC = "SourceMACAddress";
+    private static final String ETHT = "EtherType";
+
+    // TODO: This has to be outside and it should be possible for osgi
+    // to add new coming packet classes
+    public static final Map<Short, Class<? extends Packet>> etherTypeClassMap;
+    static {
+        etherTypeClassMap = new HashMap<Short, Class<? extends Packet>>();
+        etherTypeClassMap.put(EtherTypes.ARP.shortValue(), ARP.class);
+        // TODO: Add support for more classes here
+        // etherTypeClassMap.put(EtherTypes.VLANTAGGED.shortValue(), IEEE8021Q.class);
+        // etherTypeClassMap.put(EtherTypes.OLDQINQ.shortValue(), IEEE8021Q.class);
+        // etherTypeClassMap.put(EtherTypes.QINQ.shortValue(), IEEE8021Q.class);
+        // etherTypeClassMap.put(EtherTypes.CISCOQINQ.shortValue(), IEEE8021Q.class);
+    }
+    private static Map<String, Pair<Integer, Integer>> fieldCoordinates = new LinkedHashMap<String, Pair<Integer, Integer>>() {
+        private static final long serialVersionUID = 1L;
+        {
+            put(DMAC, new ImmutablePair<Integer, Integer>(0, 48));
+            put(SMAC, new ImmutablePair<Integer, Integer>(48, 48));
+            put(ETHT, new ImmutablePair<Integer, Integer>(96, 16));
+        }
+    };
+    private final Map<String, byte[]> fieldValues;
+
+    /**
+     * Default constructor that creates and sets the HashMap
+     */
+    public Ethernet() {
+        super();
+        fieldValues = new HashMap<String, byte[]>();
+        hdrFieldCoordMap = fieldCoordinates;
+        hdrFieldsMap = fieldValues;
+    }
+
+    /**
+     * Constructor that sets the access level for the packet and
+     * creates and sets the HashMap
+     */
+    public Ethernet(boolean writeAccess) {
+        super(writeAccess);
+        fieldValues = new HashMap<String, byte[]>();
+        hdrFieldCoordMap = fieldCoordinates;
+        hdrFieldsMap = fieldValues;
+    }
+
+    @Override
+    public void setHeaderField(String headerField, byte[] readValue) {
+        if (headerField.equals(ETHT)) {
+            payloadClass = etherTypeClassMap.get(BitBufferHelper
+                    .getShort(readValue));
+        }
+        hdrFieldsMap.put(headerField, readValue);
+    }
+
+    public byte[] getDestinationMACAddress() {
+        return fieldValues.get(DMAC);
+    }
+
+    public byte[] getSourceMACAddress() {
+        return fieldValues.get(SMAC);
+    }
+
+    public short getEtherType() {
+        return BitBufferHelper.getShort(fieldValues.get(ETHT));
+    }
+
+    public boolean isBroadcast(){
+        return NetUtils.isBroadcastMACAddr(getDestinationMACAddress());
+    }
+
+    public boolean isMulticast(){
+        return NetUtils.isMulticastMACAddr(getDestinationMACAddress());
+    }
+
+    public Ethernet setDestinationMACAddress(byte[] destinationMACAddress) {
+        fieldValues.put(DMAC, destinationMACAddress);
+        return this;
+    }
+
+    public Ethernet setSourceMACAddress(byte[] sourceMACAddress) {
+        fieldValues.put(SMAC, sourceMACAddress);
+        return this;
+    }
+
+    public Ethernet setEtherType(short etherType) {
+        byte[] ethType = BitBufferHelper.toByteArray(etherType);
+        fieldValues.put(ETHT, ethType);
+        return this;
+    }
+
+}
index dcc08370c16732a6f4b8e4fd9c3df067f0087adf..0e9aeaf77962544266bbeaa495069221a597ead4 100644 (file)
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
-    
+
     <parent>
         <groupId>org.opendaylight.vpnservice</groupId>
         <artifactId>config-parent</artifactId>
     <artifactId>mdsalutil-impl</artifactId>
     <version>0.2.0-SNAPSHOT</version>    
     <packaging>bundle</packaging>
-    
-    <properties>
-        <xtend.version>2.4.3</xtend.version>
-    </properties>
+
     <dependencies>
         <dependency>
             <groupId>org.opendaylight.controller</groupId>
             <artifactId>model-flow-base</artifactId>
             <version>${openflowplugin.version}</version>
         </dependency>
+        <dependency>
+            <groupId>org.opendaylight.controller</groupId>
+            <artifactId>liblldp</artifactId>
+            <version>${liblldp.version}</version>
+        </dependency>
         <dependency>
             <groupId>org.opendaylight.openflowplugin.model</groupId>
             <artifactId>model-flow-service</artifactId>
diff --git a/pom.xml b/pom.xml
index d19242065c1a5e122a7f1acb99154d1df9787879..4e9b4dd3a4c8176a8151156f499e087569a061c1 100644 (file)
--- a/pom.xml
+++ b/pom.xml
@@ -22,6 +22,7 @@ and is available at http://www.eclipse.org/legal/epl-v10.html INTERNAL
     <module>mdsalutil</module>
     <module>lockmanager</module>
     <module>idmanager</module>
+    <module>arputil</module>
     <module>vpnmanager</module>
     <module>interfacemgr</module>
     <module>nexthopmgr</module>