Optimize iface search in transmitRouterAdvertisement
[netvirt.git] / vpnservice / ipv6service / impl / src / main / java / org / opendaylight / netvirt / ipv6service / Ipv6PktHandler.java
index a7c242df6c0d0f1eb1ed58911f64458b1fd71223..e74ea8b97d7da9834a0ae6bce2a82b47d4efba06 100644 (file)
@@ -20,23 +20,22 @@ import org.opendaylight.controller.liblldp.BitBufferHelper;
 import org.opendaylight.controller.liblldp.BufferException;
 import org.opendaylight.genius.mdsalutil.MetaDataUtil;
 import org.opendaylight.netvirt.ipv6service.utils.Ipv6Constants;
+import org.opendaylight.netvirt.ipv6service.utils.Ipv6Constants.Ipv6RtrAdvertType;
 import org.opendaylight.netvirt.ipv6service.utils.Ipv6ServiceUtils;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IetfInetUtil;
-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.inet.types.rev100924.Ipv6Address;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv6Prefix;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev100924.MacAddress;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv6Address;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.MacAddress;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Uuid;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorRef;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeRef;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.ipv6service.nd.packet.rev160620.EthernetHeader;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.ipv6service.nd.packet.rev160620.Ipv6Header;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.ipv6service.nd.packet.rev160620.RouterAdvertisementPacket;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.ipv6service.nd.packet.rev160620.RouterAdvertisementPacketBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.ipv6service.nd.packet.rev160620.NeighborAdvertisePacket;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.ipv6service.nd.packet.rev160620.NeighborAdvertisePacketBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.ipv6service.nd.packet.rev160620.NeighborSolicitationPacket;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.ipv6service.nd.packet.rev160620.NeighborSolicitationPacketBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.ipv6service.nd.packet.rev160620.RouterSolicitationPacket;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.ipv6service.nd.packet.rev160620.RouterSolicitationPacketBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.ipv6service.nd.packet.rev160620.router.advertisement.packet.PrefixList;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.ipv6service.nd.packet.rev160620.router.advertisement.packet.PrefixListBuilder;
 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;
@@ -49,23 +48,17 @@ import org.slf4j.LoggerFactory;
 public class Ipv6PktHandler implements AutoCloseable, PacketProcessingListener {
     private static final Logger LOG = LoggerFactory.getLogger(Ipv6PktHandler.class);
     private long pktProccessedCounter = 0;
-    private PacketProcessingService pktService;
-    private IfMgr ifMgr;
-    private Ipv6ServiceUtils ipv6Utils;
+    private final PacketProcessingService pktService;
+    private final IfMgr ifMgr;
+    private final Ipv6ServiceUtils ipv6Utils;
     private final ExecutorService packetProcessor = Executors.newCachedThreadPool();
 
-    public Ipv6PktHandler() {
+    public Ipv6PktHandler(PacketProcessingService pktService) {
+        this.pktService = pktService;
+        ifMgr = IfMgr.getIfMgrInstance();
         this.ipv6Utils = Ipv6ServiceUtils.getInstance();
     }
 
-    public void setPacketProcessingService(PacketProcessingService packetService) {
-        this.pktService = packetService;
-    }
-
-    public void setIfMgrInstance(IfMgr instance) {
-        this.ifMgr = instance;
-    }
-
     @Override
     public void onPacketReceived(PacketReceived packetReceived) {
         int     ethType;
@@ -84,13 +77,14 @@ public class Ipv6PktHandler implements AutoCloseable, PacketProcessingListener {
         try {
             ethType = BitBufferHelper.getInt(BitBufferHelper.getBits(data, Ipv6Constants.ETHTYPE_START,
                     Ipv6Constants.TWO_BYTES));
-            if (ethType == Ipv6Constants.IPv6_ETHTYPE) {
+            if (ethType == Ipv6Constants.IP_V6_ETHTYPE) {
                 v6NxtHdr = BitBufferHelper.getByte(BitBufferHelper.getBits(data,
-                        (Ipv6Constants.IPv6_HDR_START + Ipv6Constants.IPv6_NEXT_HDR), Ipv6Constants.ONE_BYTE));
-                if (v6NxtHdr == Ipv6Constants.ICMPv6_TYPE) {
+                        (Ipv6Constants.IP_V6_HDR_START + Ipv6Constants.IP_V6_NEXT_HDR), Ipv6Constants.ONE_BYTE));
+                if (v6NxtHdr == Ipv6Constants.ICMP_V6_TYPE) {
                     int icmpv6Type = BitBufferHelper.getInt(BitBufferHelper.getBits(data,
                             Ipv6Constants.ICMPV6_HDR_START, Ipv6Constants.ONE_BYTE));
-                    if ((icmpv6Type == Ipv6Constants.ICMPv6_RS_CODE) || (icmpv6Type == Ipv6Constants.ICMPv6_NS_CODE)) {
+                    if ((icmpv6Type == Ipv6Constants.ICMP_V6_RS_CODE)
+                            || (icmpv6Type == Ipv6Constants.ICMP_V6_NS_CODE)) {
                         packetProcessor.submit(new PacketHandler(icmpv6Type, packetReceived));
                     }
                 } else {
@@ -121,22 +115,22 @@ public class Ipv6PktHandler implements AutoCloseable, PacketProcessingListener {
 
         @Override
         public void run() {
-            if (type == Ipv6Constants.ICMPv6_NS_CODE) {
+            if (type == Ipv6Constants.ICMP_V6_NS_CODE) {
                 LOG.info("Received Neighbor Solicitation request");
-            } else if (type == Ipv6Constants.ICMPv6_RS_CODE) {
+                processNeighborSolicitationRequest();
+            } else if (type == Ipv6Constants.ICMP_V6_RS_CODE) {
                 LOG.info("Received Router Solicitation request");
                 processRouterSolicitationRequest();
             }
         }
 
-        private void processRouterSolicitationRequest() {
+        private void processNeighborSolicitationRequest() {
             byte[] data = packet.getPayload();
-            List<String> prefixList;
-            RouterSolicitationPacket rsPdu = deserializeRSPacket(data);
-            Ipv6Header ipv6Header = (Ipv6Header) rsPdu;
-            if (ipv6Utils.validateChecksum(data, ipv6Header, rsPdu.getIcmp6Chksum()) == false) {
+            NeighborSolicitationPacket nsPdu = deserializeNSPacket(data);
+            Ipv6Header ipv6Header = (Ipv6Header) nsPdu;
+            if (ipv6Utils.validateChecksum(data, ipv6Header, nsPdu.getIcmp6Chksum()) == false) {
                 pktProccessedCounter++;
-                LOG.warn("Received RS packet with invalid checksum on {}. Ignoring the packet.",
+                LOG.warn("Received Neighbor Solicitation with invalid checksum on {}. Ignoring the packet.",
                         packet.getIngress());
                 return;
             }
@@ -154,25 +148,180 @@ public class Ipv6PktHandler implements AutoCloseable, PacketProcessingListener {
             VirtualPort routerPort = ifMgr.getRouterV6InterfaceForNetwork(port.getNetworkID());
             if (routerPort == null) {
                 pktProccessedCounter++;
-                LOG.warn("Port {} is not associated to a Router, skipping.", routerPort);
+                LOG.warn("Port {} is not associated to a Router, skipping NS request.", routerPort);
+                return;
+            }
+
+            if (!routerPort.getIpv6Addresses().contains(nsPdu.getTargetIpAddress())) {
+                pktProccessedCounter++;
+                LOG.warn("No Router interface with address {} on the network {}, skipping NS request.",
+                        nsPdu.getTargetIpAddress(), port.getNetworkID());
                 return;
             }
 
-            RouterAdvertisementPacketBuilder raPacket = new RouterAdvertisementPacketBuilder();
-            updateRAResponse(rsPdu, raPacket, rsPdu.getSourceMac(), routerPort);
-            // Serialize the response packet
-            byte[] txPayload = fillRouterAdvertisementPacket(raPacket.build());
+            //formulate the NA response
+            NeighborAdvertisePacketBuilder naPacket = new NeighborAdvertisePacketBuilder();
+            updateNAResponse(nsPdu, routerPort, naPacket);
+            // serialize the response packet
+            byte[] txPayload = fillNeighborAdvertisementPacket(naPacket.build());
             InstanceIdentifier<Node> outNode = packet.getIngress().getValue().firstIdentifierOf(Node.class);
             TransmitPacketInput input = new TransmitPacketInputBuilder().setPayload(txPayload)
                     .setNode(new NodeRef(outNode))
                     .setEgress(packet.getIngress()).build();
+            // Tx the packet out of the controller.
             if (pktService != null) {
-                LOG.debug("Transmitting the Router Advt packet out {}", packet.getIngress());
+                LOG.debug("Transmitting the Neighbor Advt packet out on {}", packet.getIngress());
                 pktService.transmitPacket(input);
                 pktProccessedCounter++;
             }
         }
 
+        private NeighborSolicitationPacket deserializeNSPacket(byte[] data) {
+            NeighborSolicitationPacketBuilder nsPdu = new NeighborSolicitationPacketBuilder();
+            int bitOffset = 0;
+
+            try {
+                nsPdu.setDestinationMac(new MacAddress(
+                        ipv6Utils.bytesToHexString(BitBufferHelper.getBits(data, bitOffset, 48))));
+                bitOffset = bitOffset + 48;
+                nsPdu.setSourceMac(new MacAddress(
+                        ipv6Utils.bytesToHexString(BitBufferHelper.getBits(data, bitOffset, 48))));
+                bitOffset = bitOffset + 48;
+                nsPdu.setEthertype(BitBufferHelper.getInt(BitBufferHelper.getBits(data, bitOffset, 16)));
+
+                bitOffset = Ipv6Constants.IP_V6_HDR_START;
+                nsPdu.setVersion(BitBufferHelper.getShort(BitBufferHelper.getBits(data, bitOffset, 4)));
+                bitOffset = bitOffset + 4;
+                nsPdu.setFlowLabel(BitBufferHelper.getLong(BitBufferHelper.getBits(data, bitOffset, 28)));
+                bitOffset = bitOffset + 28;
+                nsPdu.setIpv6Length(BitBufferHelper.getInt(BitBufferHelper.getBits(data, bitOffset, 16)));
+                bitOffset = bitOffset + 16;
+                nsPdu.setNextHeader(BitBufferHelper.getShort(BitBufferHelper.getBits(data, bitOffset, 8)));
+                bitOffset = bitOffset + 8;
+                nsPdu.setHopLimit(BitBufferHelper.getShort(BitBufferHelper.getBits(data, bitOffset, 8)));
+                bitOffset = bitOffset + 8;
+                nsPdu.setSourceIpv6(Ipv6Address.getDefaultInstance(
+                        InetAddress.getByAddress(BitBufferHelper.getBits(data, bitOffset, 128)).getHostAddress()));
+                bitOffset = bitOffset + 128;
+                nsPdu.setDestinationIpv6(Ipv6Address.getDefaultInstance(
+                        InetAddress.getByAddress(BitBufferHelper.getBits(data, bitOffset, 128)).getHostAddress()));
+                bitOffset = bitOffset + 128;
+
+                nsPdu.setIcmp6Type(BitBufferHelper.getShort(BitBufferHelper.getBits(data, bitOffset, 8)));
+                bitOffset = bitOffset + 8;
+                nsPdu.setIcmp6Code(BitBufferHelper.getShort(BitBufferHelper.getBits(data, bitOffset, 8)));
+                bitOffset = bitOffset + 8;
+                nsPdu.setIcmp6Chksum(BitBufferHelper.getInt(BitBufferHelper.getBits(data, bitOffset, 16)));
+                bitOffset = bitOffset + 16;
+                nsPdu.setReserved(Long.valueOf(0));
+                bitOffset = bitOffset + 32;
+                nsPdu.setTargetIpAddress(Ipv6Address.getDefaultInstance(
+                        InetAddress.getByAddress(BitBufferHelper.getBits(data, bitOffset, 128)).getHostAddress()));
+            } catch (BufferException | UnknownHostException  e) {
+                LOG.warn("Exception obtained when deserializing NS packet", e.toString());
+            }
+            return nsPdu.build();
+        }
+
+        private void updateNAResponse(NeighborSolicitationPacket pdu,
+                                      VirtualPort port, NeighborAdvertisePacketBuilder naPacket) {
+            long flag = 0;
+            if (!pdu.getSourceIpv6().equals(ipv6Utils.UNSPECIFIED_ADDR)) {
+                naPacket.setDestinationIpv6(pdu.getSourceIpv6());
+                flag = 0xE0; // Set Router, Solicited and Override Flag.
+            } else {
+                naPacket.setDestinationIpv6(ipv6Utils.ALL_NODES_MCAST_ADDR);
+                flag = 0xA0; // Set Router and Override Flag.
+            }
+            naPacket.setDestinationMac(pdu.getSourceMac());
+            naPacket.setEthertype(pdu.getEthertype());
+            naPacket.setSourceIpv6(pdu.getTargetIpAddress());
+            naPacket.setSourceMac(new MacAddress(port.getMacAddress()));
+            naPacket.setHopLimit(Ipv6Constants.ICMP_V6_MAX_HOP_LIMIT);
+            naPacket.setIcmp6Type(Ipv6Constants.ICMP_V6_NA_CODE);
+            naPacket.setIcmp6Code(pdu.getIcmp6Code());
+            flag = flag << 24;
+            naPacket.setFlags(flag);
+            naPacket.setFlowLabel(pdu.getFlowLabel());
+            naPacket.setIpv6Length(32);
+            naPacket.setNextHeader(pdu.getNextHeader());
+            naPacket.setOptionType((short)2);
+            naPacket.setTargetAddrLength((short)1);
+            naPacket.setTargetAddress(pdu.getTargetIpAddress());
+            naPacket.setTargetLlAddress(new MacAddress(port.getMacAddress()));
+            naPacket.setVersion(pdu.getVersion());
+            naPacket.setIcmp6Chksum(0);
+            return;
+        }
+
+        private byte[] icmp6NAPayloadtoByte(NeighborAdvertisePacket pdu) {
+            byte[] data = new byte[36];
+            Arrays.fill(data, (byte)0);
+
+            ByteBuffer buf = ByteBuffer.wrap(data);
+            buf.put((byte)pdu.getIcmp6Type().shortValue());
+            buf.put((byte)pdu.getIcmp6Code().shortValue());
+            buf.putShort((short)pdu.getIcmp6Chksum().intValue());
+            buf.putInt((int)pdu.getFlags().longValue());
+            try {
+                byte[] address = null;
+                address = InetAddress.getByName(pdu.getTargetAddress().getValue()).getAddress();
+                buf.put(address);
+            } catch (UnknownHostException e) {
+                LOG.error("Serializing NA target address failed", e);
+            }
+            buf.put((byte)pdu.getOptionType().shortValue());
+            buf.put((byte)pdu.getTargetAddrLength().shortValue());
+            buf.put(ipv6Utils.bytesFromHexString(pdu.getTargetLlAddress().getValue().toString()));
+            return data;
+        }
+
+        private byte[] fillNeighborAdvertisementPacket(NeighborAdvertisePacket pdu) {
+            ByteBuffer buf = ByteBuffer.allocate(Ipv6Constants.ICMPV6_OFFSET + pdu.getIpv6Length());
+
+            buf.put(ipv6Utils.convertEthernetHeaderToByte((EthernetHeader)pdu), 0, 14);
+            buf.put(ipv6Utils.convertIpv6HeaderToByte((Ipv6Header)pdu), 0, 40);
+            buf.put(icmp6NAPayloadtoByte(pdu), 0, pdu.getIpv6Length());
+            int checksum = ipv6Utils.calcIcmpv6Checksum(buf.array(), (Ipv6Header) pdu);
+            buf.putShort((Ipv6Constants.ICMPV6_OFFSET + 2), (short)checksum);
+            return (buf.array());
+        }
+
+        private void processRouterSolicitationRequest() {
+            byte[] data = packet.getPayload();
+            RouterSolicitationPacket rsPdu = deserializeRSPacket(data);
+            Ipv6Header ipv6Header = (Ipv6Header) rsPdu;
+            if (ipv6Utils.validateChecksum(data, ipv6Header, rsPdu.getIcmp6Chksum()) == false) {
+                pktProccessedCounter++;
+                LOG.warn("Received RS packet with invalid checksum on {}. Ignoring the packet.",
+                        packet.getIngress());
+                return;
+            }
+
+            BigInteger metadata = packet.getMatch().getMetadata().getMetadata();
+            long portTag = MetaDataUtil.getLportFromMetadata(metadata).intValue();
+            String interfaceName = ifMgr.getInterfaceNameFromTag(portTag);
+            VirtualPort port = ifMgr.obtainV6Interface(new Uuid(interfaceName));
+            if (port == null) {
+                pktProccessedCounter++;
+                LOG.info("Port {} not found, skipping.", port);
+                return;
+            }
+
+            VirtualPort routerPort = ifMgr.getRouterV6InterfaceForNetwork(port.getNetworkID());
+            if (routerPort == null) {
+                pktProccessedCounter++;
+                LOG.warn("Port {} is not associated to a Router, skipping.", routerPort);
+                return;
+            }
+            Ipv6RouterAdvt ipv6RouterAdvert = new Ipv6RouterAdvt();
+            List<NodeConnectorRef> ncRefList = new ArrayList<>();
+            ncRefList.add(packet.getIngress());
+            ipv6RouterAdvert.transmitRtrAdvertisement(Ipv6RtrAdvertType.SOLICITED_ADVERTISEMENT,
+                                                      routerPort, ncRefList, rsPdu);
+            pktProccessedCounter = pktProccessedCounter + 1;
+        }
+
         private RouterSolicitationPacket deserializeRSPacket(byte[] data) {
             RouterSolicitationPacketBuilder rsPdu = new RouterSolicitationPacketBuilder();
             int bitOffset = 0;
@@ -186,7 +335,7 @@ public class Ipv6PktHandler implements AutoCloseable, PacketProcessingListener {
                 bitOffset = bitOffset + 48;
                 rsPdu.setEthertype(BitBufferHelper.getInt(BitBufferHelper.getBits(data, bitOffset, 16)));
 
-                bitOffset = Ipv6Constants.IPv6_HDR_START;
+                bitOffset = Ipv6Constants.IP_V6_HDR_START;
                 rsPdu.setVersion(BitBufferHelper.getShort(BitBufferHelper.getBits(data, bitOffset, 4)));
                 bitOffset = bitOffset + 4;
                 rsPdu.setFlowLabel(BitBufferHelper.getLong(BitBufferHelper.getBits(data, bitOffset, 28)));
@@ -229,145 +378,6 @@ public class Ipv6PktHandler implements AutoCloseable, PacketProcessingListener {
             }
             return rsPdu.build();
         }
-
-        private void updateRAResponse(RouterSolicitationPacket pdu,
-                                      RouterAdvertisementPacketBuilder raPacket,
-                                      MacAddress vmMac, VirtualPort routerPort) {
-            short icmpv6RaFlags = 0;
-            String gatewayMac = null;
-            IpAddress gatewayIp;
-            List<String> autoConfigPrefixList = new ArrayList<String>();
-            List<String> statefulConfigPrefixList = new ArrayList<String>();
-
-            for (VirtualSubnet subnet : routerPort.getSubnets()) {
-                gatewayIp = subnet.getGatewayIp();
-                // Skip if its a v4 subnet.
-                if (gatewayIp.getIpv4Address() != null) {
-                    continue;
-                }
-
-                if (!subnet.getIpv6RAMode().isEmpty()) {
-                    if (Ipv6Constants.IPV6_AUTO_ADDRESS_SUBNETS.contains(subnet.getIpv6RAMode())) {
-                        autoConfigPrefixList.add(String.valueOf(subnet.getSubnetCidr().getValue()));
-                    }
-
-                    if (subnet.getIpv6RAMode().equalsIgnoreCase(Ipv6Constants.IPV6_DHCPV6_STATEFUL)) {
-                        statefulConfigPrefixList.add(String.valueOf(subnet.getSubnetCidr().getValue()));
-                    }
-                }
-
-                if (subnet.getIpv6RAMode().equalsIgnoreCase(Ipv6Constants.IPV6_DHCPV6_STATELESS)) {
-                    icmpv6RaFlags = (short) (icmpv6RaFlags | (1 << 6)); // Other Configuration.
-                } else if (subnet.getIpv6RAMode().equalsIgnoreCase(Ipv6Constants.IPV6_DHCPV6_STATEFUL)) {
-                    icmpv6RaFlags = (short) (icmpv6RaFlags | (1 << 7)); // Managed Address Conf.
-                }
-            }
-
-            gatewayMac = routerPort.getMacAddress();
-
-            MacAddress sourceMac = MacAddress.getDefaultInstance(gatewayMac);
-            raPacket.setSourceMac(sourceMac);
-            raPacket.setDestinationMac(vmMac);
-            raPacket.setEthertype(pdu.getEthertype());
-
-            raPacket.setVersion(pdu.getVersion());
-            raPacket.setFlowLabel(pdu.getFlowLabel());
-            int prefixListLength = autoConfigPrefixList.size() + statefulConfigPrefixList.size();
-            raPacket.setIpv6Length(Ipv6Constants.ICMPV6_RA_LENGTH_WO_OPTIONS
-                    + Ipv6Constants.ICMPV6_OPTION_SOURCE_LLA_LENGTH
-                    + prefixListLength * Ipv6Constants.ICMPV6_OPTION_PREFIX_LENGTH);
-            raPacket.setNextHeader(pdu.getNextHeader());
-            raPacket.setHopLimit(Ipv6Constants.ICMPv6_MAX_HOP_LIMIT);
-            raPacket.setSourceIpv6(ipv6Utils.getIpv6LinkLocalAddressFromMac(sourceMac));
-            raPacket.setDestinationIpv6(pdu.getSourceIpv6());
-
-            raPacket.setIcmp6Type(Ipv6Constants.ICMPv6_RA_CODE);
-            raPacket.setIcmp6Code((short)0);
-            raPacket.setIcmp6Chksum(0);
-
-            raPacket.setCurHopLimit((short) Ipv6Constants.IPV6_DEFAULT_HOP_LIMIT);
-            raPacket.setFlags((short) icmpv6RaFlags);
-            raPacket.setRouterLifetime(Ipv6Constants.IPV6_ROUTER_LIFETIME);
-            raPacket.setReachableTime((long) 0);
-            raPacket.setRetransTime((long) 0);
-
-            raPacket.setOptionSourceAddr((short)1);
-            raPacket.setSourceAddrLength((short)1);
-            raPacket.setSourceLlAddress(MacAddress.getDefaultInstance(gatewayMac));
-
-            List<PrefixList> prefixList = new ArrayList<PrefixList>();
-            PrefixListBuilder prefix = new PrefixListBuilder();
-            prefix.setOptionType((short)3);
-            prefix.setOptionLength((short)4);
-            // Note: EUI-64 auto-configuration requires 64 bits.
-            prefix.setPrefixLength((short)64);
-            prefix.setValidLifetime((long) Ipv6Constants.IPV6_RA_VALID_LIFETIME);
-            prefix.setPreferredLifetime((long) Ipv6Constants.IPV6_RA_PREFERRED_LIFETIME);
-            prefix.setReserved((long) 0);
-
-            short autoConfPrefixFlags = 0;
-            autoConfPrefixFlags = (short) (autoConfPrefixFlags | (1 << 7)); // On-link flag
-            autoConfPrefixFlags = (short) (autoConfPrefixFlags | (1 << 6)); // Autonomous address-configuration flag.
-            for (String v6Prefix : autoConfigPrefixList) {
-                prefix.setFlags((short)autoConfPrefixFlags);
-                prefix.setPrefix(new Ipv6Prefix(v6Prefix));
-                prefixList.add(prefix.build());
-            }
-
-            short statefulPrefixFlags = 0;
-            statefulPrefixFlags = (short) (statefulPrefixFlags | (1 << 7)); // On-link flag
-            for (String v6Prefix : statefulConfigPrefixList) {
-                prefix.setFlags((short)statefulPrefixFlags);
-                prefix.setPrefix(new Ipv6Prefix(v6Prefix));
-                prefixList.add(prefix.build());
-            }
-
-            raPacket.setPrefixList((List<PrefixList>) prefixList);
-
-            return;
-        }
-
-        private byte[] fillRouterAdvertisementPacket(RouterAdvertisementPacket pdu) {
-            ByteBuffer buf = ByteBuffer.allocate(Ipv6Constants.ICMPV6_OFFSET + pdu.getIpv6Length());
-
-            buf.put(ipv6Utils.convertEthernetHeaderToByte((EthernetHeader)pdu), 0, 14);
-            buf.put(ipv6Utils.convertIpv6HeaderToByte((Ipv6Header)pdu), 0, 40);
-            buf.put(icmp6RAPayloadtoByte(pdu), 0, pdu.getIpv6Length());
-            int checksum = ipv6Utils.calcIcmpv6Checksum(buf.array(), (Ipv6Header) pdu);
-            buf.putShort((Ipv6Constants.ICMPV6_OFFSET + 2), (short)checksum);
-            return (buf.array());
-        }
-
-        private byte[] icmp6RAPayloadtoByte(RouterAdvertisementPacket pdu) {
-            byte[] data = new byte[pdu.getIpv6Length()];
-            Arrays.fill(data, (byte)0);
-
-            ByteBuffer buf = ByteBuffer.wrap(data);
-            buf.put((byte)pdu.getIcmp6Type().shortValue());
-            buf.put((byte)pdu.getIcmp6Code().shortValue());
-            buf.putShort((short)pdu.getIcmp6Chksum().intValue());
-            buf.put((byte)pdu.getCurHopLimit().shortValue());
-            buf.put((byte)pdu.getFlags().shortValue());
-            buf.putShort((short)pdu.getRouterLifetime().intValue());
-            buf.putInt((int)pdu.getReachableTime().longValue());
-            buf.putInt((int)pdu.getRetransTime().longValue());
-            buf.put((byte)pdu.getOptionSourceAddr().shortValue());
-            buf.put((byte)pdu.getSourceAddrLength().shortValue());
-            buf.put(ipv6Utils.bytesFromHexString(pdu.getSourceLlAddress().getValue().toString()));
-
-            for (PrefixList prefix : pdu.getPrefixList()) {
-                buf.put((byte)prefix.getOptionType().shortValue());
-                buf.put((byte)prefix.getOptionLength().shortValue());
-                buf.put((byte)prefix.getPrefixLength().shortValue());
-                buf.put((byte)prefix.getFlags().shortValue());
-                buf.putInt((int)prefix.getValidLifetime().longValue());
-                buf.putInt((int)prefix.getPreferredLifetime().longValue());
-                buf.putInt((int)prefix.getReserved().longValue());
-                buf.put(IetfInetUtil.INSTANCE.ipv6PrefixToBytes(new Ipv6Prefix(prefix.getPrefix())),0,16);
-            }
-            return data;
-        }
-
     }
 
     @Override