--- /dev/null
+<?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>
--- /dev/null
+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
--- /dev/null
+<?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>
--- /dev/null
+<?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&revision=2015-11-26</capability>
+ <capability>urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding?module=opendaylight-md-sal-binding&revision=2013-10-28</capability>
+ <capability>urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl?module=opendaylight-sal-binding-broker-impl&revision=2013-10-28</capability>
+ <capability>urn:opendaylight:params:xml:ns:yang:mdsalutil:api?module=odl-mdsalutil&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>
--- /dev/null
+/*
+ * 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
--- /dev/null
+/*
+ * 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;
+ }
+
+}
--- /dev/null
+/*
+ * 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");
+ }
+}
--- /dev/null
+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;
+ }
+
+}
--- /dev/null
+/*
+* 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 {
+
+}
--- /dev/null
+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;
+ }
+ }
+ }
+ }
+ }
+}
--- /dev/null
+<?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>
<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>
<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>
<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>
<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>
<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>
<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>
<dependencies>
<dependency>
- <groupId>org.opendaylight.yangtools</groupId>
+ <groupId>org.opendaylight.mdsal</groupId>
<artifactId>yang-binding</artifactId>
- <version>${yangtools.version}</version>
</dependency>
<dependency>
<groupId>org.opendaylight.yangtools</groupId>
<artifactId>yang-common</artifactId>
- <version>${yangtools.version}</version>
</dependency>
</dependencies>
<build>
<?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>
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;
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;
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;
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);
} catch (Exception e) {
throw new RuntimeException(e);
}
-
return result;
}
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();
+ }
+
}
--- /dev/null
+/*
+ * 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();
+ }
+}
--- /dev/null
+/*
+ * 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;
+ }
+}
--- /dev/null
+/*
+ * 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;
+ }
+
+}
<?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>
<module>mdsalutil</module>
<module>lockmanager</module>
<module>idmanager</module>
+ <module>arputil</module>
<module>vpnmanager</module>
<module>interfacemgr</module>
<module>nexthopmgr</module>
<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">
<modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>org.opendaylight.odlparent</groupId>
+ <artifactId>odlparent-lite</artifactId>
+ <version>1.6.0-SNAPSHOT</version>
+ <relativePath/>
+ </parent>
+
<groupId>org.opendaylight.vpnservice</groupId>
<artifactId>vpnservice-artifacts</artifactId>
<version>0.2.0-SNAPSHOT</version>