Ipv6PktHandler implements AutoCloseable, PacketProcessingListener { @Override public void onPacketReceived(PacketReceived packetReceived) { int ethType; int v6NxtHdr; if (packetReceived == null) { LOG.debug("Received null packet. Returning without any processing"); return; } byte[] data = packetReceived.getPayload(); if (data.length <= 0) { LOG.debug("Received packet with invalid length {}", data.length); return; } try { ethType = BitBufferHelper.getInt(BitBufferHelper.getBits(data, Ipv6Constants.ETHTYPE_START, Ipv6Constants.TWO_BYTES)); if (ethType == NwConstants.ETHTYPE_IPV6) { v6NxtHdr = BitBufferHelper.getByte(BitBufferHelper.getBits(data, Ipv6Constants.IP_V6_HDR_START + Ipv6Constants.IP_V6_NEXT_HDR, Ipv6Constants.ONE_BYTE)); if (v6NxtHdr == IPProtocols.IPV6ICMP.intValue()) { int icmpv6Type = BitBufferHelper.getInt(BitBufferHelper.getBits(data, Ipv6Constants.ICMPV6_HDR_START, Ipv6Constants.ONE_BYTE)); if (isOfInterest(icmpv6Type)) { packetProcessor.execute(new PacketHandler(icmpv6Type, packetReceived)); } } else { LOG.debug("IPv6 Pdu received on port {} with next-header {} ", packetReceived.getIngress(), v6NxtHdr); } } else { return; } } catch (BufferException e) { LOG.warn("Failed to decode packet: {}", e.getMessage()); return; } } @Inject  Ipv6PktHandler(PacketProcessingService pktService, IfMgr ifMgr,Ipv6ServiceUtils ipv6ServiceUtils,
                          IpV6NAConfigHelper ipV6NAConfigHelper, IIpv6PacketListener ipv6PktListener); @Override void onPacketReceived(PacketReceived packetReceived); long getPacketProcessedCounter(); @Override @PreDestroy void close();  }
@Test public void testOnPacketReceivedWithInvalidPacket() throws Exception { pktHandler.onPacketReceived(null); verify(pktProcessService, times(0)).transmitPacket(any(TransmitPacketInput.class)); byte[] pktArray = {}; PacketReceived packet = new PacketReceivedBuilder().setPayload(pktArray).build(); pktHandler.onPacketReceived(packet); verify(pktProcessService, times(0)).transmitPacket(any(TransmitPacketInput.class)); }
@Test public void testOnPacketReceivedWithInvalidParams() throws Exception { pktHandler.onPacketReceived(new PacketReceivedBuilder().setPayload(ipv6TestUtils.buildPacket( "33 33 FF F5 00 00", "00 01 02 03 04 05", "80 00", "6E 00 00 00", "00 18", "3A", "FF", "00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00", "FF 02 00 00 00 00 00 00 00 00 00 01 FF F5 00 00" )).build()); verify(pktProcessService, times(0)).transmitPacket(any(TransmitPacketInput.class)); pktHandler.onPacketReceived(new PacketReceivedBuilder().setPayload(ipv6TestUtils.buildPacket( "33 33 FF F5 00 00", "00 01 02 03 04 05", "86 DD", "6E 00 00 00", "00 18", "33", "FF", "00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00", "FF 02 00 00 00 00 00 00 00 00 00 01 FF F5 00 00" )).build()); verify(pktProcessService, times(0)).transmitPacket(any(TransmitPacketInput.class)); pktHandler.onPacketReceived(new PacketReceivedBuilder().setPayload(ipv6TestUtils.buildPacket( "33 33 FF F5 00 00", "00 01 02 03 04 05", "86 DD", "6E 00 00 00", "00 18", "3A", "FF", "00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00", "FF 02 00 00 00 00 00 00 00 00 00 01 FF F5 00 00", "85", "00", "67 3C", "00 00 00 00", "FE 80 00 00 00 00 00 00 C0 00 54 FF FE F5 00 00" )).build()); verify(pktProcessService, times(0)).transmitPacket(any(TransmitPacketInput.class)); }
@Test public void testonPacketReceivedNeighborSolicitationWithValidPayload() throws Exception { VirtualPort intf = Mockito.mock(VirtualPort.class); when(intf.getNetworkID()).thenReturn(new Uuid("eeec9dba-d831-4ad7-84b9-00d7f65f0555")); when(ifMgrInstance.getInterfaceNameFromTag(anyLong())).thenReturn("ddec9dba-d831-4ad7-84b9-00d7f65f052f"); when(ifMgrInstance.obtainV6Interface(any())).thenReturn(intf); VirtualPort routerIntf = Mockito.mock(VirtualPort.class); when(ifMgrInstance.getRouterV6InterfaceForNetwork(any())).thenReturn(routerIntf); List<Ipv6Address> ipv6AddrList = new ArrayList<>(); when(routerIntf.getMacAddress()).thenReturn("08:00:27:FE:8F:95"); Ipv6Address llAddr = Ipv6Util.getIpv6LinkLocalAddressFromMac(new MacAddress("08:00:27:FE:8F:95")); ipv6AddrList.add(llAddr); when(routerIntf.getIpv6Addresses()).thenReturn(ipv6AddrList); when(pktProcessService.transmitPacket(any())).thenReturn(Mockito.mock(ListenableFuture.class)); InstanceIdentifier<Node> ncId = InstanceIdentifier.builder(Nodes.class) .child(Node.class, new NodeKey(new NodeId("openflow:1"))).build(); NodeConnectorRef ncRef = new NodeConnectorRef(ncId); Uint64 mdata = Uint64.valueOf(0x1000000); Metadata metadata = new MetadataBuilder().setMetadata(mdata).build(); MatchBuilder matchbuilder = new MatchBuilder().setMetadata(metadata); pktHandler.onPacketReceived(new PacketReceivedBuilder().setPayload(ipv6TestUtils.buildPacket( "33 33 FF FE 8F 95", "08 00 27 D4 10 BB", "86 DD", "60 00 00 00", "00 20", "3A", "FF", "FE 80 00 00 00 00 00 00 0A 00 27 FF FE D4 10 BB", "FF 02 00 00 00 00 00 00 00 00 00 01 FF FE 8F 95", "87", "00", "A9 57", "00 00 00 00", "FE 80 00 00 00 00 00 00 0A 00 27 FF FE FE 8F 95", "01", "01", "08 00 27 D4 10 BB" )).setIngress(ncRef).setMatch(matchbuilder.build()).build()); waitForPacketProcessing(); verify(pktProcessService, times(1)).transmitPacket(any(TransmitPacketInput.class)); byte[] expectedPayload = ipv6TestUtils.buildPacket( "08 00 27 D4 10 BB", "08 00 27 FE 8F 95", "86 DD", "60 00 00 00", "00 20", "3A", "FF", "FE 80 00 00 00 00 00 00 0A 00 27 FF FE FE 8F 95", "FE 80 00 00 00 00 00 00 0A 00 27 FF FE D4 10 BB", "88", "00", "17 D6", "E0 00 00 00", "FE 80 00 00 00 00 00 00 0A 00 27 FF FE FE 8F 95", "02", "01", "08 00 27 FE 8F 95" ); verify(pktProcessService).transmitPacket(new TransmitPacketInputBuilder().setPayload(expectedPayload) .setNode(new NodeRef(ncId)).setEgress(ncRef).build()); }
@Test public void testonPacketReceivedRouterSolicitationWithSingleSubnet() throws Exception { VirtualPort intf = Mockito.mock(VirtualPort.class); when(intf.getDpId()).thenReturn(Uint64.valueOf(1)); when(intf.getIntfUUID()).thenReturn(Uuid.getDefaultInstance("ddec9dba-d831-4ad7-84b9-00d7f65f052f")); when(intf.getMacAddress()).thenReturn("fa:16:3e:4e:18:0c"); when(intf.getMtu()).thenReturn(1400); when(ifMgrInstance.getInterfaceNameFromTag(anyLong())).thenReturn("ddec9dba-d831-4ad7-84b9-00d7f65f052f"); List<Action> actions = new ArrayList<>(); actions.add(new ActionNxResubmit(NwConstants.EGRESS_LPORT_DISPATCHER_TABLE).buildAction()); when(ifMgrInstance.getEgressAction(any())).thenReturn(actions); when(ifMgrInstance.obtainV6Interface(any())).thenReturn(intf); when(ifMgrInstance.getRouterV6InterfaceForNetwork(any())).thenReturn(intf); when(pktProcessService.transmitPacket(any())).thenReturn(Mockito.mock(ListenableFuture.class)); IpAddress gwIpAddress = Mockito.mock(IpAddress.class); when(gwIpAddress.getIpv4Address()).thenReturn(null); when(gwIpAddress.getIpv6Address()).thenReturn(new Ipv6Address("2001:db8::1")); VirtualSubnet v6Subnet = VirtualSubnet.builder().gatewayIp(gwIpAddress) .subnetCidr(new IpPrefix(new Ipv6Prefix("2001:db8::/64"))) .ipv6AddressMode(Ipv6ServiceConstants.IPV6_SLAAC).ipv6RAMode(Ipv6ServiceConstants.IPV6_SLAAC).build(); VirtualRouter virtualRouter = VirtualRouter.builder().build(); v6Subnet.setRouter(virtualRouter); List<VirtualSubnet> subnetList = new ArrayList<>(); subnetList.add(v6Subnet); when(intf.getSubnets()).thenReturn(subnetList); Uint64 dpnId = Uint64.valueOf("1"); NodeConnectorRef ncRef = MDSALUtil.getDefaultNodeConnRef(dpnId); Uint64 mdata = Uint64.valueOf(0x1000000); Metadata metadata = new MetadataBuilder().setMetadata(mdata).build(); MatchBuilder matchbuilder = new MatchBuilder().setMetadata(metadata); pktHandler.onPacketReceived(new PacketReceivedBuilder().setPayload(ipv6TestUtils.buildPacket( "33 33 00 00 00 02", "FA 16 3E 69 2C F3", "86 DD", "60 00 00 00", "00 10", "3A", "FF", "FE 80 00 00 00 00 00 00 F8 16 3E FF FE 69 2C F3", "FF 02 00 00 00 00 00 00 00 00 00 00 00 00 00 02", "85", "00", "B4 47", "00 00 00 00", "01", "01", "FA 16 3E 69 2C F3" )).setIngress(ncRef).setMatch(matchbuilder.build()).build()); waitForPacketProcessing(); verify(pktProcessService, times(1)).transmitPacket(any(TransmitPacketInput.class)); byte[] expectedPayload = ipv6TestUtils.buildPacket( "FA 16 3E 69 2C F3", "FA 16 3E 4E 18 0C", "86 DD", "60 00 00 00", "00 40", "3A", "FF", "FE 80 00 00 00 00 00 00 F8 16 3E FF FE 4E 18 0C", "FE 80 00 00 00 00 00 00 F8 16 3E FF FE 69 2C F3", "86", "00", "11 2F", "40", "00", "11 94", "00 01 D4 C0", "00 00 00 00", "01", "01", "FA 16 3E 4E 18 0C", "05", "01", "00 00", "00 00 05 78", "03", "04", "40", "C0", "00 27 8D 00", "00 09 3A 80", "00 00 00 00", "20 01 0D B8 00 00 00 00 00 00 00 00 00 00 00 00" ); TransmitPacketInput transmitPacketInput = MDSALUtil.getPacketOut(actions, expectedPayload, dpnId); verify(pktProcessService).transmitPacket(transmitPacketInput); }
@Test public void testonPacketReceivedRouterSolicitationWithMultipleSubnets() throws Exception { VirtualPort intf = Mockito.mock(VirtualPort.class); when(intf.getDpId()).thenReturn(Uint64.valueOf(1)); when(intf.getMacAddress()).thenReturn("50:7B:9D:78:54:F3"); when(intf.getIntfUUID()).thenReturn(Uuid.getDefaultInstance("ddec9dba-d831-4ad7-84b9-00d7f65f052f")); when(ifMgrInstance.obtainV6Interface(any())).thenReturn(intf); when(ifMgrInstance.getInterfaceNameFromTag(anyLong())).thenReturn("ddec9dba-d831-4ad7-84b9-00d7f65f052f"); when(ifMgrInstance.getRouterV6InterfaceForNetwork(any())).thenReturn(intf); List<Action> actions = new ArrayList<>(); actions.add(new ActionNxResubmit(NwConstants.EGRESS_LPORT_DISPATCHER_TABLE).buildAction()); when(ifMgrInstance.getEgressAction(any())).thenReturn(actions); when(pktProcessService.transmitPacket(any())).thenReturn(Mockito.mock(ListenableFuture.class)); IpAddress gwIpAddress = Mockito.mock(IpAddress.class); when(gwIpAddress.getIpv4Address()).thenReturn(null); when(gwIpAddress.getIpv6Address()).thenReturn(new Ipv6Address("2001:db8:1111::1")); VirtualSubnet v6Subnet1 = VirtualSubnet.builder().gatewayIp(gwIpAddress) .subnetCidr(new IpPrefix(new Ipv6Prefix("2001:db8:1111::/64"))) .ipv6AddressMode(Ipv6ServiceConstants.IPV6_SLAAC).ipv6RAMode(Ipv6ServiceConstants.IPV6_SLAAC).build(); VirtualRouter virtualRouter = VirtualRouter.builder().build(); v6Subnet1.setRouter(virtualRouter); VirtualSubnet v6Subnet2 = VirtualSubnet.builder().gatewayIp(gwIpAddress) .subnetCidr(new IpPrefix(new Ipv6Prefix("2001:db8:2222::/64"))) .ipv6AddressMode(Ipv6ServiceConstants.IPV6_DHCPV6_STATELESS) .ipv6RAMode(Ipv6ServiceConstants.IPV6_DHCPV6_STATELESS).build(); v6Subnet2.setRouter(virtualRouter); VirtualSubnet v6Subnet3 = VirtualSubnet.builder().gatewayIp(gwIpAddress) .subnetCidr(new IpPrefix(new Ipv6Prefix("2001:db8:3333::/64"))) .ipv6AddressMode(Ipv6ServiceConstants.IPV6_DHCPV6_STATEFUL) .ipv6RAMode(Ipv6ServiceConstants.IPV6_DHCPV6_STATEFUL).build(); v6Subnet3.setRouter(virtualRouter); List<VirtualSubnet> subnetList = new ArrayList<>(); subnetList.add(v6Subnet1); subnetList.add(v6Subnet2); subnetList.add(v6Subnet3); when(intf.getSubnets()).thenReturn(subnetList); Uint64 dpnId = Uint64.valueOf("1"); NodeConnectorRef ncRef = MDSALUtil.getDefaultNodeConnRef(dpnId); Uint64 mdata = Uint64.valueOf(0x1000000); Metadata metadata = new MetadataBuilder().setMetadata(mdata).build(); MatchBuilder matchbuilder = new MatchBuilder().setMetadata(metadata); pktHandler.onPacketReceived(new PacketReceivedBuilder().setPayload(ipv6TestUtils.buildPacket( "33 33 00 00 00 02", "FA 16 3E 69 2C F3", "86 DD", "60 00 00 00", "00 10", "3A", "FF", "FE 80 00 00 00 00 00 00 F8 16 3E FF FE 69 2C F3", "FF 02 00 00 00 00 00 00 00 00 00 00 00 00 00 02", "85", "00", "B4 47", "00 00 00 00", "01", "01", "FA 16 3E 69 2C F3" )).setIngress(ncRef).setMatch(matchbuilder.build()).build()); waitForPacketProcessing(); verify(pktProcessService, times(1)).transmitPacket(any(TransmitPacketInput.class)); byte[] expectedPayload = ipv6TestUtils.buildPacket( "FA 16 3E 69 2C F3", "50 7B 9D 78 54 F3", "86 DD", "60 00 00 00", "00 78", "3A", "FF", "FE 80 00 00 00 00 00 00 52 7B 9D FF FE 78 54 F3", "FE 80 00 00 00 00 00 00 F8 16 3E FF FE 69 2C F3", "86", "00", "59 41", "40", "C0", "11 94", "00 01 D4 C0", "00 00 00 00", "01", "01", "50 7B 9D 78 54 F3", "03", "04", "40", "C0", "00 27 8D 00", "00 09 3A 80", "00 00 00 00", "20 01 0D B8 11 11 00 00 00 00 00 00 00 00 00 00", "03", "04", "40", "C0", "00 27 8D 00", "00 09 3A 80", "00 00 00 00", "20 01 0D B8 22 22 00 00 00 00 00 00 00 00 00 00", "03", "04", "40", "80", "00 27 8D 00", "00 09 3A 80", "00 00 00 00", "20 01 0D B8 33 33 00 00 00 00 00 00 00 00 00 00" ); TransmitPacketInput transmitPacketInput = MDSALUtil.getPacketOut(actions, expectedPayload, dpnId); verify(pktProcessService).transmitPacket(transmitPacketInput); }
@Test public void testonPacketReceivedNeighborAdvertisementWithValidPayload() throws Exception { VirtualPort intf = Mockito.mock(VirtualPort.class); when(intf.getNetworkID()).thenReturn(new Uuid("eeec9dba-d831-4ad7-84b9-00d7f65f0555")); when(ifMgrInstance.getInterfaceNameFromTag(anyLong())).thenReturn("ddec9dba-d831-4ad7-84b9-00d7f65f052f"); when(ifMgrInstance.obtainV6Interface(any())).thenReturn(intf); InstanceIdentifier<Node> ncId = InstanceIdentifier.builder(Nodes.class) .child(Node.class, new NodeKey(new NodeId("openflow:1"))).build(); NodeConnectorRef ncRef = new NodeConnectorRef(ncId); Uint64 mdata = Uint64.valueOf(0x1000000); Metadata metadata = new MetadataBuilder().setMetadata(mdata).build(); MatchBuilder matchbuilder = new MatchBuilder().setMetadata(metadata); byte[] data = ipv6TestUtils.buildPacket( "FA 16 3E F7 69 4E", "FA 16 3E A9 38 94", "86 DD", "60 00 00 00", "00 20", "3A", "FF", "20 01 0D B8 00 00 00 02 00 00 00 00 00 00 11 11", "10 01 0D B8 00 00 00 02 F8 16 3E FF FE F7 69 4E", "88", "00", "C9 9F", "00 00 00 00", "20 01 0D B8 00 00 00 02 00 00 00 00 00 00 11 11", "02", "01", "FA 16 3E A9 38 94" ); pktHandler.onPacketReceived(new PacketReceivedBuilder().setPayload(data).setIngress(ncRef) .setMatch(matchbuilder.build()).setTableId(new TableId((short) 45)).build()); waitForPacketProcessing(); NeighborAdvertisePacket naPdu = new Ipv6NaDecoder(data).decode(); NeighborAdvertisePacket naPacket = new NeighborAdvertisePacketBuilder(naPdu) .addAugmentation(PacketMetadata.class, new PacketMetadataBuilder().setOfTableId((long) 45) .setMetadata(mdata).setInterface("ddec9dba-d831-4ad7-84b9-00d7f65f052f").build()) .build(); verify(ipv6PktListener).onNaReceived(naPacket); }
@Test public void testonPacketReceivedNeighborAdvertisementWithInvalidPayload() throws Exception { VirtualPort intf = Mockito.mock(VirtualPort.class); when(intf.getNetworkID()).thenReturn(new Uuid("eeec9dba-d831-4ad7-84b9-00d7f65f0555")); when(ifMgrInstance.getInterfaceNameFromTag(anyLong())).thenReturn("ddec9dba-d831-4ad7-84b9-00d7f65f052f"); when(ifMgrInstance.obtainV6Interface(any())).thenReturn(intf); InstanceIdentifier<Node> ncId = InstanceIdentifier.builder(Nodes.class) .child(Node.class, new NodeKey(new NodeId("openflow:1"))).build(); NodeConnectorRef ncRef = new NodeConnectorRef(ncId); Uint64 mdata = Uint64.valueOf(0x1000000); Metadata metadata = new MetadataBuilder().setMetadata(mdata).build(); MatchBuilder matchbuilder = new MatchBuilder().setMetadata(metadata); pktHandler.onPacketReceived(new PacketReceivedBuilder().setPayload(ipv6TestUtils.buildPacket( "FA 16 3E F7 69 4E", "FA 16 3E A9 38 94", "86 DD", "60 00 00 00", "00 20", "3A", "FF", "20 01 0D B8 00 00 00 02 00 00 00 00 00 00 11 11", "10 01 0D B8 00 00 00 02 F8 16 3E FF FE F7 69 4E", "88", "00", "C9 9A", "00 00 00 00", "20 01 0D B8 00 00 00 02 00 00 00 00 00 00 11 11", "02", "01", "FA 16 3E A9 38 94" )).setIngress(ncRef).setMatch(matchbuilder.build()).setTableId(new TableId((short) 45)).build()); waitForPacketProcessing(); verify(ipv6PktListener, times(0)).onNaReceived(any(NeighborAdvertisePacket.class)); pktHandler.onPacketReceived(new PacketReceivedBuilder().setPayload(ipv6TestUtils.buildPacket( "FA 16 3E F7 69 4E", "FA 16 3E A9 38 94", "86 DD", "60 00 00 00", "00 20", "3A", "FF", "20 01 0D B8 00 00 00 02 00 00 00 00 00 00 11 11", "10 01 0D B8 00 00 00 02 F8 16 3E FF FE F7 69 4E", "87", "00", "C9 9F", "00 00 00 00", "20 01 0D B8 00 00 00 02 00 00 00 00 00 00 11 11", "02", "01", "FA 16 3E A9 38 94" )).setIngress(ncRef).setMatch(matchbuilder.build()).setTableId(new TableId((short) 45)).build()); waitForPacketProcessing(); verify(ipv6PktListener, times(0)).onNaReceived(any(NeighborAdvertisePacket.class)); }