#!/usr/bin/env python
-import unittest
import socket
+import unittest
+
+from parameterized import parameterized
+import scapy.compat
+import scapy.layers.inet6 as inet6
+from scapy.contrib.mpls import MPLS
+from scapy.layers.inet6 import IPv6, ICMPv6ND_NS, ICMPv6ND_RS, \
+ ICMPv6ND_RA, ICMPv6NDOptMTU, ICMPv6NDOptSrcLLAddr, ICMPv6NDOptPrefixInfo, \
+ ICMPv6ND_NA, ICMPv6NDOptDstLLAddr, ICMPv6DestUnreach, icmp6types, \
+ ICMPv6TimeExceeded, ICMPv6EchoRequest, ICMPv6EchoReply, IPv6ExtHdrHopByHop
+from scapy.layers.l2 import Ether, Dot1Q
+from scapy.packet import Raw
+from scapy.utils import inet_pton, inet_ntop
+from scapy.utils6 import in6_getnsma, in6_getnsmac, in6_ptop, in6_islladdr, \
+ in6_mactoifaceid
+from six import moves
from framework import VppTestCase, VppTestRunner
-from util import ppp, ip6_normalize
-from vpp_sub_interface import VppSubInterface, VppDot1QSubint
-from vpp_pg_interface import is_ipv6_misc
+from util import ppp, ip6_normalize, mk_ll_addr
+from vpp_ip import DpoProto
from vpp_ip_route import VppIpRoute, VppRoutePath, find_route, VppIpMRoute, \
VppMRoutePath, MRouteItfFlags, MRouteEntryFlags, VppMplsIpBind, \
- VppMplsRoute, DpoProto, VppMplsTable, VppIpTable
+ VppMplsRoute, VppMplsTable, VppIpTable, FibPathType
from vpp_neighbor import find_nbr, VppNeighbor
-
-from scapy.packet import Raw
-from scapy.layers.l2 import Ether, Dot1Q
-from scapy.layers.inet6 import IPv6, UDP, TCP, ICMPv6ND_NS, ICMPv6ND_RS, \
- ICMPv6ND_RA, ICMPv6NDOptSrcLLAddr, getmacbyip6, ICMPv6MRD_Solicitation, \
- ICMPv6NDOptMTU, ICMPv6NDOptSrcLLAddr, ICMPv6NDOptPrefixInfo, \
- ICMPv6ND_NA, ICMPv6NDOptDstLLAddr, ICMPv6DestUnreach, icmp6types, \
- ICMPv6TimeExceeded, ICMPv6EchoRequest, ICMPv6EchoReply
-from scapy.utils6 import in6_getnsma, in6_getnsmac, in6_ptop, in6_islladdr, \
- in6_mactoifaceid, in6_ismaddr
-from scapy.utils import inet_pton, inet_ntop
-from scapy.contrib.mpls import MPLS
-
+from vpp_pg_interface import is_ipv6_misc
+from vpp_sub_interface import VppSubInterface, VppDot1QSubint
+from ipaddress import IPv6Network, IPv4Network, IPv6Address
AF_INET6 = socket.AF_INET6
+try:
+ text_type = unicode
+except NameError:
+ text_type = str
-def mk_ll_addr(mac):
- euid = in6_mactoifaceid(mac)
- addr = "fe80::" + euid
- return addr
+NUM_PKTS = 67
class TestIPv6ND(VppTestCase):
in6_ptop(dst_ip))
# and come from the target address
- self.assertEqual(in6_ptop(rx[IPv6].src), in6_ptop(tgt_ip))
+ self.assertEqual(
+ in6_ptop(rx[IPv6].src), in6_ptop(tgt_ip))
# Dest link-layer options should have the router's MAC
dll = rx[ICMPv6NDOptDstLLAddr]
# the rx'd NS should be addressed to an mcast address
# derived from the target address
- self.assertEqual(in6_ptop(rx[IPv6].dst), in6_ptop(dst_ip))
+ self.assertEqual(
+ in6_ptop(rx[IPv6].dst), in6_ptop(dst_ip))
# expect the tgt IP in the NS header
ns = rx[ICMPv6ND_NS]
self.assertEqual(in6_ptop(ns.tgt), in6_ptop(tgt_ip))
# packet is from the router's local address
- self.assertEqual(in6_ptop(rx[IPv6].src), intf.local_ip6)
+ self.assertEqual(
+ in6_ptop(rx[IPv6].src), intf.local_ip6)
# Src link-layer options should have the router's MAC
sll = rx[ICMPv6NDOptSrcLLAddr]
def setUpClass(cls):
super(TestIPv6, cls).setUpClass()
+ @classmethod
+ def tearDownClass(cls):
+ super(TestIPv6, cls).tearDownClass()
+
def setUp(self):
"""
Perform test setup before test case.
i.config_ip6()
i.resolve_ndp()
- # config 2M FIB entries
- self.config_fib_entries(200)
-
def tearDown(self):
"""Run standard test teardown and log ``show ip6 neighbors``."""
for i in self.interfaces:
self.logger.info(self.vapi.cli("show ip6 neighbors"))
# info(self.vapi.cli("show ip6 fib")) # many entries
- def config_fib_entries(self, count):
- """For each interface add to the FIB table *count* routes to
- "fd02::1/128" destination with interface's local address as next-hop
- address.
-
- :param int count: Number of FIB entries.
-
- - *TODO:* check if the next-hop address shouldn't be remote address
- instead of local address.
- """
- n_int = len(self.interfaces)
- percent = 0
- counter = 0.0
- dest_addr = inet_pton(AF_INET6, "fd02::1")
- dest_addr_len = 128
- for i in self.interfaces:
- next_hop_address = i.local_ip6n
- for j in range(count / n_int):
- self.vapi.ip_add_del_route(
- dest_addr, dest_addr_len, next_hop_address, is_ipv6=1)
- counter += 1
- if counter / count * 100 > percent:
- self.logger.info("Configure %d FIB entries .. %d%% done" %
- (count, percent))
- percent += 1
-
def modify_packet(self, src_if, packet_size, pkt):
"""Add load, set destination IP and extend packet to required packet
size for defined interface.
dst_if = self.flows[src_if][dst_if_idx]
info = self.create_packet_info(src_if, dst_if)
payload = self.info_to_payload(info)
- p = pkt/Raw(payload)
+ p = pkt / Raw(payload)
p[IPv6].dst = dst_if.remote_ip6
info.data = p.copy()
if isinstance(src_if, VppSubInterface):
hdr_ext = 4 if isinstance(src_if, VppSubInterface) else 0
pkt_tmpl = (Ether(dst=src_if.local_mac, src=src_if.remote_mac) /
IPv6(src=src_if.remote_ip6) /
- UDP(sport=1234, dport=1234))
+ inet6.UDP(sport=1234, dport=1234))
pkts = [self.modify_packet(src_if, i, pkt_tmpl)
- for i in xrange(self.pg_if_packet_sizes[0],
- self.pg_if_packet_sizes[1], 10)]
+ for i in moves.range(self.pg_if_packet_sizes[0],
+ self.pg_if_packet_sizes[1], 10)]
pkts_b = [self.modify_packet(src_if, i, pkt_tmpl)
- for i in xrange(self.pg_if_packet_sizes[1] + hdr_ext,
- self.pg_if_packet_sizes[2] + hdr_ext, 50)]
+ for i in moves.range(self.pg_if_packet_sizes[1] + hdr_ext,
+ self.pg_if_packet_sizes[2] + hdr_ext,
+ 50)]
pkts.extend(pkts_b)
return pkts
self.assertTrue(Dot1Q not in packet)
try:
ip = packet[IPv6]
- udp = packet[UDP]
- payload_info = self.payload_to_info(str(packet[Raw]))
+ udp = packet[inet6.UDP]
+ payload_info = self.payload_to_info(packet[Raw])
packet_index = payload_info.index
self.assertEqual(payload_info.dst, dst_sw_if_index)
self.logger.debug(
self.assertEqual(packet_index, next_info.index)
saved_packet = next_info.data
# Check standard fields
- self.assertEqual(ip.src, saved_packet[IPv6].src)
- self.assertEqual(ip.dst, saved_packet[IPv6].dst)
- self.assertEqual(udp.sport, saved_packet[UDP].sport)
- self.assertEqual(udp.dport, saved_packet[UDP].dport)
+ self.assertEqual(
+ ip.src, saved_packet[IPv6].src)
+ self.assertEqual(
+ ip.dst, saved_packet[IPv6].dst)
+ self.assertEqual(
+ udp.sport, saved_packet[inet6.UDP].sport)
+ self.assertEqual(
+ udp.dport, saved_packet[inet6.UDP].dport)
except:
self.logger.error(ppp("Unexpected or invalid packet:", packet))
raise
"Interface %s: Packet expected from interface %s "
"didn't arrive" % (dst_if.name, i.name))
+ def test_next_header_anomaly(self):
+ """ IPv6 next header anomaly test
+
+ Test scenario:
+ - ipv6 next header field = Fragment Header (44)
+ - next header is ICMPv6 Echo Request
+ - wait for reassembly
+ """
+ pkt = (Ether(src=self.pg0.local_mac, dst=self.pg0.remote_mac) /
+ IPv6(src=self.pg0.remote_ip6, dst=self.pg0.local_ip6, nh=44) /
+ ICMPv6EchoRequest())
+
+ self.pg0.add_stream(pkt)
+ self.pg_start()
+
+ # wait for reassembly
+ self.sleep(10)
+
def test_fib(self):
""" IPv6 FIB test
p = (Ether(dst=in6_getnsmac(nsma)) /
IPv6(dst=d, src="2002::2") /
ICMPv6ND_NS(tgt=self.pg0.local_ip6) /
- ICMPv6NDOptSrcLLAddr(lladdr=self.pg0.remote_mac))
+ ICMPv6NDOptSrcLLAddr(
+ lladdr=self.pg0.remote_mac))
pkts = [p]
self.send_and_assert_no_replies(
p = (Ether(dst=in6_getnsmac(nsma)) /
IPv6(dst=d, src=self.pg0.remote_ip6) /
ICMPv6ND_NS(tgt=self.pg0.local_ip6) /
- ICMPv6NDOptSrcLLAddr(lladdr=self.pg0.remote_mac))
+ ICMPv6NDOptSrcLLAddr(
+ lladdr=self.pg0.remote_mac))
pkts = [p]
self.send_and_assert_no_replies(
p = (Ether(dst=in6_getnsmac(nsma)) /
IPv6(dst=d, src=self.pg0.remote_ip6) /
ICMPv6ND_NS(tgt="fd::ffff") /
- ICMPv6NDOptSrcLLAddr(lladdr=self.pg0.remote_mac))
+ ICMPv6NDOptSrcLLAddr(
+ lladdr=self.pg0.remote_mac))
pkts = [p]
self.send_and_assert_no_replies(self.pg0, pkts,
self.pg0.sw_if_index,
self.pg0.remote_hosts[2].mac,
self.pg0.remote_hosts[2].ip6,
- af=AF_INET6,
is_no_fib_entry=1)
nd_entry.add_vpp_config()
#
self.assertTrue(find_nbr(self,
self.pg0.sw_if_index,
- self.pg0._remote_hosts[2].ip6,
- inet=AF_INET6))
+ self.pg0._remote_hosts[2].ip6))
self.assertFalse(find_route(self,
self.pg0._remote_hosts[2].ip6,
- 128,
- inet=AF_INET6))
+ 128))
#
# send an NS from a link local address to the interface's global
# address
#
p = (Ether(dst=in6_getnsmac(nsma), src=self.pg0.remote_mac) /
- IPv6(dst=d, src=self.pg0._remote_hosts[2].ip6_ll) /
+ IPv6(
+ dst=d, src=self.pg0._remote_hosts[2].ip6_ll) /
ICMPv6ND_NS(tgt=self.pg0.local_ip6) /
- ICMPv6NDOptSrcLLAddr(lladdr=self.pg0.remote_mac))
+ ICMPv6NDOptSrcLLAddr(
+ lladdr=self.pg0.remote_mac))
self.send_and_expect_na(self.pg0, p,
"NS from link-local",
#
self.assertTrue(find_nbr(self,
self.pg0.sw_if_index,
- self.pg0._remote_hosts[2].ip6_ll,
- inet=AF_INET6))
+ self.pg0._remote_hosts[2].ip6_ll))
self.assertFalse(find_route(self,
self.pg0._remote_hosts[2].ip6_ll,
- 128,
- inet=AF_INET6))
+ 128))
#
# An NS to the router's own Link-local
#
p = (Ether(dst=in6_getnsmac(nsma), src=self.pg0.remote_mac) /
- IPv6(dst=d, src=self.pg0._remote_hosts[3].ip6_ll) /
+ IPv6(
+ dst=d, src=self.pg0._remote_hosts[3].ip6_ll) /
ICMPv6ND_NS(tgt=self.pg0.local_ip6_ll) /
- ICMPv6NDOptSrcLLAddr(lladdr=self.pg0.remote_mac))
+ ICMPv6NDOptSrcLLAddr(
+ lladdr=self.pg0.remote_mac))
self.send_and_expect_na(self.pg0, p,
"NS to/from link-local",
#
self.assertTrue(find_nbr(self,
self.pg0.sw_if_index,
- self.pg0._remote_hosts[3].ip6_ll,
- inet=AF_INET6))
+ self.pg0._remote_hosts[3].ip6_ll))
self.assertFalse(find_route(self,
self.pg0._remote_hosts[3].ip6_ll,
- 128,
- inet=AF_INET6))
+ 128))
def test_ns_duplicates(self):
""" ND Duplicates"""
ns_pg1 = VppNeighbor(self,
self.pg1.sw_if_index,
self.pg1.remote_hosts[1].mac,
- self.pg1.remote_hosts[1].ip6,
- af=AF_INET6)
+ self.pg1.remote_hosts[1].ip6)
ns_pg1.add_vpp_config()
ns_pg2 = VppNeighbor(self,
self.pg2.sw_if_index,
self.pg2.remote_mac,
- self.pg1.remote_hosts[1].ip6,
- af=AF_INET6)
+ self.pg1.remote_hosts[1].ip6)
ns_pg2.add_vpp_config()
#
src=self.pg0.remote_mac) /
IPv6(src=self.pg0.remote_ip6,
dst=self.pg1.remote_hosts[1].ip6) /
- UDP(sport=1234, dport=1234) /
+ inet6.UDP(sport=1234, dport=1234) /
Raw())
self.pg0.add_stream(p)
#
# remove the duplicate on pg1
- # packet stream shoud generate NSs out of pg1
+ # packet stream should generate NSs out of pg1
#
ns_pg1.remove_vpp_config()
if not pi_opt:
# the RA should not contain prefix information
- self.assertFalse(ra.haslayer(ICMPv6NDOptPrefixInfo))
+ self.assertFalse(ra.haslayer(
+ ICMPv6NDOptPrefixInfo))
else:
raos = rx.getlayer(ICMPv6NDOptPrefixInfo, 1)
# decipher how to decode. this 1st layer of option always returns
# nested classes, so a direct obj1=obj2 comparison always fails.
# however, the getlayer(.., 2) does give one instnace.
- # so we cheat here and construct a new opt instnace for comparison
- rd = ICMPv6NDOptPrefixInfo(prefixlen=raos.prefixlen,
- prefix=raos.prefix,
- L=raos.L,
- A=raos.A)
+ # so we cheat here and construct a new opt instance for comparison
+ rd = ICMPv6NDOptPrefixInfo(
+ prefixlen=raos.prefixlen,
+ prefix=raos.prefix,
+ L=raos.L,
+ A=raos.A)
if type(pi_opt) is list:
for ii in range(len(pi_opt)):
self.assertEqual(pi_opt[ii], rd)
- rd = rx.getlayer(ICMPv6NDOptPrefixInfo, ii+2)
+ rd = rx.getlayer(
+ ICMPv6NDOptPrefixInfo, ii + 2)
else:
self.assertEqual(pi_opt, raos)
# - expect an RA in return
#
p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
- IPv6(dst=self.pg0.local_ip6, src=self.pg0.remote_ip6) /
+ IPv6(
+ dst=self.pg0.local_ip6, src=self.pg0.remote_ip6) /
ICMPv6ND_RS())
pkts = [p]
self.send_and_expect_ra(self.pg0, pkts, "Genuine RS")
self.send_and_assert_no_replies(self.pg0, pkts, "RA rate limited")
#
- # When we reconfiure the IPv6 RA config, we reset the RA rate limiting,
+ # When we reconfigure the IPv6 RA config,
+ # we reset the RA rate limiting,
# so we need to do this before each test below so as not to drop
# packets for rate limiting reasons. Test this works here.
#
#
self.pg0.ip6_ra_config(send_unicast=1)
p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
- IPv6(dst=self.pg0.local_ip6, src="2002::ffff") /
+ IPv6(dst=self.pg0.local_ip6,
+ src="2002::ffff") /
ICMPv6ND_RS())
pkts = [p]
self.send_and_assert_no_replies(self.pg0, pkts,
#
# Configure The RA to announce the links prefix
#
- self.pg0.ip6_ra_prefix(self.pg0.local_ip6n,
+ self.pg0.ip6_ra_prefix(self.pg0.local_ip6,
self.pg0.local_ip6_prefix_len)
#
# RAs should now contain the prefix information option
#
- opt = ICMPv6NDOptPrefixInfo(prefixlen=self.pg0.local_ip6_prefix_len,
- prefix=self.pg0.local_ip6,
- L=1,
- A=1)
+ opt = ICMPv6NDOptPrefixInfo(
+ prefixlen=self.pg0.local_ip6_prefix_len,
+ prefix=self.pg0.local_ip6,
+ L=1,
+ A=1)
self.pg0.ip6_ra_config(send_unicast=1)
ll = mk_ll_addr(self.pg0.remote_mac)
# Change the prefix info to not off-link
# L-flag is clear
#
- self.pg0.ip6_ra_prefix(self.pg0.local_ip6n,
+ self.pg0.ip6_ra_prefix(self.pg0.local_ip6,
self.pg0.local_ip6_prefix_len,
off_link=1)
- opt = ICMPv6NDOptPrefixInfo(prefixlen=self.pg0.local_ip6_prefix_len,
- prefix=self.pg0.local_ip6,
- L=0,
- A=1)
+ opt = ICMPv6NDOptPrefixInfo(
+ prefixlen=self.pg0.local_ip6_prefix_len,
+ prefix=self.pg0.local_ip6,
+ L=0,
+ A=1)
self.pg0.ip6_ra_config(send_unicast=1)
self.send_and_expect_ra(self.pg0, p,
# Change the prefix info to not off-link, no-autoconfig
# L and A flag are clear in the advert
#
- self.pg0.ip6_ra_prefix(self.pg0.local_ip6n,
+ self.pg0.ip6_ra_prefix(self.pg0.local_ip6,
self.pg0.local_ip6_prefix_len,
off_link=1,
no_autoconfig=1)
- opt = ICMPv6NDOptPrefixInfo(prefixlen=self.pg0.local_ip6_prefix_len,
- prefix=self.pg0.local_ip6,
- L=0,
- A=0)
+ opt = ICMPv6NDOptPrefixInfo(
+ prefixlen=self.pg0.local_ip6_prefix_len,
+ prefix=self.pg0.local_ip6,
+ L=0,
+ A=0)
self.pg0.ip6_ra_config(send_unicast=1)
self.send_and_expect_ra(self.pg0, p,
# Change the flag settings back to the defaults
# L and A flag are set in the advert
#
- self.pg0.ip6_ra_prefix(self.pg0.local_ip6n,
+ self.pg0.ip6_ra_prefix(self.pg0.local_ip6,
self.pg0.local_ip6_prefix_len)
- opt = ICMPv6NDOptPrefixInfo(prefixlen=self.pg0.local_ip6_prefix_len,
- prefix=self.pg0.local_ip6,
- L=1,
- A=1)
+ opt = ICMPv6NDOptPrefixInfo(
+ prefixlen=self.pg0.local_ip6_prefix_len,
+ prefix=self.pg0.local_ip6,
+ L=1,
+ A=1)
self.pg0.ip6_ra_config(send_unicast=1)
self.send_and_expect_ra(self.pg0, p,
# Change the prefix info to not off-link, no-autoconfig
# L and A flag are clear in the advert
#
- self.pg0.ip6_ra_prefix(self.pg0.local_ip6n,
+ self.pg0.ip6_ra_prefix(self.pg0.local_ip6,
self.pg0.local_ip6_prefix_len,
off_link=1,
no_autoconfig=1)
- opt = ICMPv6NDOptPrefixInfo(prefixlen=self.pg0.local_ip6_prefix_len,
- prefix=self.pg0.local_ip6,
- L=0,
- A=0)
+ opt = ICMPv6NDOptPrefixInfo(
+ prefixlen=self.pg0.local_ip6_prefix_len,
+ prefix=self.pg0.local_ip6,
+ L=0,
+ A=0)
self.pg0.ip6_ra_config(send_unicast=1)
self.send_and_expect_ra(self.pg0, p,
opt=opt)
#
- # Use the reset to defults option to revert to defaults
+ # Use the reset to defaults option to revert to defaults
# L and A flag are clear in the advert
#
- self.pg0.ip6_ra_prefix(self.pg0.local_ip6n,
+ self.pg0.ip6_ra_prefix(self.pg0.local_ip6,
self.pg0.local_ip6_prefix_len,
use_default=1)
- opt = ICMPv6NDOptPrefixInfo(prefixlen=self.pg0.local_ip6_prefix_len,
- prefix=self.pg0.local_ip6,
- L=1,
- A=1)
+ opt = ICMPv6NDOptPrefixInfo(
+ prefixlen=self.pg0.local_ip6_prefix_len,
+ prefix=self.pg0.local_ip6,
+ L=1,
+ A=1)
self.pg0.ip6_ra_config(send_unicast=1)
self.send_and_expect_ra(self.pg0, p,
#
# Advertise Another prefix. With no L-flag/A-flag
#
- self.pg0.ip6_ra_prefix(self.pg1.local_ip6n,
+ self.pg0.ip6_ra_prefix(self.pg1.local_ip6,
self.pg1.local_ip6_prefix_len,
off_link=1,
no_autoconfig=1)
- opt = [ICMPv6NDOptPrefixInfo(prefixlen=self.pg0.local_ip6_prefix_len,
- prefix=self.pg0.local_ip6,
- L=1,
- A=1),
- ICMPv6NDOptPrefixInfo(prefixlen=self.pg1.local_ip6_prefix_len,
- prefix=self.pg1.local_ip6,
- L=0,
- A=0)]
+ opt = [ICMPv6NDOptPrefixInfo(
+ prefixlen=self.pg0.local_ip6_prefix_len,
+ prefix=self.pg0.local_ip6,
+ L=1,
+ A=1),
+ ICMPv6NDOptPrefixInfo(
+ prefixlen=self.pg1.local_ip6_prefix_len,
+ prefix=self.pg1.local_ip6,
+ L=0,
+ A=0)]
self.pg0.ip6_ra_config(send_unicast=1)
ll = mk_ll_addr(self.pg0.remote_mac)
opt=opt)
#
- # Remove the first refix-info - expect the second is still in the
+ # Remove the first prefix-info - expect the second is still in the
# advert
#
- self.pg0.ip6_ra_prefix(self.pg0.local_ip6n,
+ self.pg0.ip6_ra_prefix(self.pg0.local_ip6,
self.pg0.local_ip6_prefix_len,
is_no=1)
- opt = ICMPv6NDOptPrefixInfo(prefixlen=self.pg1.local_ip6_prefix_len,
- prefix=self.pg1.local_ip6,
- L=0,
- A=0)
+ opt = ICMPv6NDOptPrefixInfo(
+ prefixlen=self.pg1.local_ip6_prefix_len,
+ prefix=self.pg1.local_ip6,
+ L=0,
+ A=0)
self.pg0.ip6_ra_config(send_unicast=1)
self.send_and_expect_ra(self.pg0, p,
opt=opt)
#
- # Remove the second prefix-info - expect no prefix-info i nthe adverts
+ # Remove the second prefix-info - expect no prefix-info in the adverts
#
- self.pg0.ip6_ra_prefix(self.pg1.local_ip6n,
+ self.pg0.ip6_ra_prefix(self.pg1.local_ip6,
self.pg1.local_ip6_prefix_len,
is_no=1)
class TestICMPv6Echo(VppTestCase):
""" ICMPv6 Echo Test Case """
+ @classmethod
+ def setUpClass(cls):
+ super(TestICMPv6Echo, cls).setUpClass()
+
+ @classmethod
+ def tearDownClass(cls):
+ super(TestICMPv6Echo, cls).tearDownClass()
+
def setUp(self):
super(TestICMPv6Echo, self).setUp()
icmpv6_id = 0xb
icmpv6_seq = 5
- icmpv6_data = '\x0a' * 18
+ icmpv6_data = b'\x0a' * 18
p_echo_request = (Ether(src=self.pg0.remote_mac,
dst=self.pg0.local_mac) /
IPv6(src=self.pg0.remote_ip6,
dst=self.pg0.local_ip6) /
- ICMPv6EchoRequest(id=icmpv6_id, seq=icmpv6_seq,
- data=icmpv6_data))
+ ICMPv6EchoRequest(
+ id=icmpv6_id,
+ seq=icmpv6_seq,
+ data=icmpv6_data))
self.pg0.add_stream(p_echo_request)
self.pg_enable_capture(self.pg_interfaces)
self.assertEqual(ipv6.src, self.pg0.local_ip6)
self.assertEqual(ipv6.dst, self.pg0.remote_ip6)
- self.assertEqual(icmp6types[icmpv6.type], "Echo Reply")
+ self.assertEqual(
+ icmp6types[icmpv6.type], "Echo Reply")
self.assertEqual(icmpv6.id, icmpv6_id)
self.assertEqual(icmpv6.seq, icmpv6_seq)
self.assertEqual(icmpv6.data, icmpv6_data)
def setUpClass(cls):
super(TestIPv6RD, cls).setUpClass()
+ @classmethod
+ def tearDownClass(cls):
+ super(TestIPv6RD, cls).tearDownClass()
+
def setUp(self):
super(TestIPv6RD, self).setUp()
rx_list = self.pg1.get_capture(count, timeout=3)
self.assertEqual(len(rx_list), count)
for packet in rx_list:
- self.assertTrue(packet.haslayer(IPv6))
- self.assertTrue(packet[IPv6].haslayer(ICMPv6ND_RS))
+ self.assertEqual(packet.haslayer(IPv6), 1)
+ self.assertEqual(packet[IPv6].haslayer(
+ ICMPv6ND_RS), 1)
dst = ip6_normalize(packet[IPv6].dst)
dst2 = ip6_normalize("ff02::2")
self.assert_equal(dst, dst2)
src = ip6_normalize(packet[IPv6].src)
src2 = ip6_normalize(self.pg1.local_ip6_ll)
self.assert_equal(src, src2)
- self.assertTrue(packet[ICMPv6ND_RS].haslayer(ICMPv6NDOptSrcLLAddr))
- self.assert_equal(packet[ICMPv6NDOptSrcLLAddr].lladdr,
- self.pg1.local_mac)
+ self.assertTrue(
+ bool(packet[ICMPv6ND_RS].haslayer(
+ ICMPv6NDOptSrcLLAddr)))
+ self.assert_equal(
+ packet[ICMPv6NDOptSrcLLAddr].lladdr,
+ self.pg1.local_mac)
def verify_prefix_info(self, reported_prefix, prefix_option):
- prefix = socket.inet_pton(socket.AF_INET6,
- prefix_option.getfieldval("prefix"))
- self.assert_equal(reported_prefix.dst_address, prefix)
- self.assert_equal(reported_prefix.dst_address_length,
- prefix_option.getfieldval("prefixlen"))
+ prefix = IPv6Network(
+ text_type(prefix_option.getfieldval("prefix") +
+ "/" +
+ text_type(prefix_option.getfieldval("prefixlen"))),
+ strict=False)
+ self.assert_equal(reported_prefix.prefix.network_address,
+ prefix.network_address)
L = prefix_option.getfieldval("L")
A = prefix_option.getfieldval("A")
option_flags = (L << 7) | (A << 6)
def setUpClass(cls):
super(TestIPv6RDControlPlane, cls).setUpClass()
+ @classmethod
+ def tearDownClass(cls):
+ super(TestIPv6RDControlPlane, cls).tearDownClass()
+
def setUp(self):
super(TestIPv6RDControlPlane, self).setUp()
def get_default_routes(fib):
list = []
for entry in fib:
- if entry.address_length == 0:
- for path in entry.path:
+ if entry.route.prefix.prefixlen == 0:
+ for path in entry.route.paths:
if path.sw_if_index != 0xFFFFFFFF:
defaut_route = {}
defaut_route['sw_if_index'] = path.sw_if_index
- defaut_route['next_hop'] = path.next_hop
+ defaut_route['next_hop'] = path.nh.address.ip6
list.append(defaut_route)
return list
def get_interface_addresses(fib, pg):
list = []
for entry in fib:
- if entry.address_length == 128:
- path = entry.path[0]
+ if entry.route.prefix.prefixlen == 128:
+ path = entry.route.paths[0]
if path.sw_if_index == pg.sw_if_index:
- list.append(entry.address)
+ list.append(str(entry.route.prefix.network_address))
return list
def test_all(self):
""" Test handling of SLAAC addresses and default routes """
- fib = self.vapi.ip6_fib_dump()
+ fib = self.vapi.ip_route_dump(0, True)
default_routes = self.get_default_routes(fib)
initial_addresses = set(self.get_interface_addresses(fib, self.pg0))
self.assertEqual(default_routes, [])
- router_address = self.pg0.remote_ip6n_ll
+ router_address = IPv6Address(text_type(self.pg0.remote_ip6_ll))
self.vapi.ip6_nd_address_autoconfig(self.pg0.sw_if_index, 1, 1)
self.sleep(0.1)
# send RA
- packet = (self.create_ra_packet(self.pg0) / ICMPv6NDOptPrefixInfo(
+ packet = (self.create_ra_packet(
+ self.pg0) / ICMPv6NDOptPrefixInfo(
prefix="1::",
prefixlen=64,
validlifetime=2,
self.sleep(0.1)
- fib = self.vapi.ip6_fib_dump()
+ fib = self.vapi.ip_route_dump(0, True)
# check FIB for new address
addresses = set(self.get_interface_addresses(fib, self.pg0))
new_addresses = addresses.difference(initial_addresses)
self.assertEqual(len(new_addresses), 1)
- prefix = list(new_addresses)[0][:8] + '\0\0\0\0\0\0\0\0'
- self.assertEqual(inet_ntop(AF_INET6, prefix), '1::')
+ prefix = IPv6Network(text_type("%s/%d" % (list(new_addresses)[0], 20)),
+ strict=False)
+ self.assertEqual(prefix, IPv6Network(text_type('1::/20')))
# check FIB for new default route
default_routes = self.get_default_routes(fib)
self.sleep(0.1)
# check that default route is deleted
- fib = self.vapi.ip6_fib_dump()
+ fib = self.vapi.ip_route_dump(0, True)
default_routes = self.get_default_routes(fib)
self.assertEqual(len(default_routes), 0)
self.sleep(0.1)
# check FIB for new default route
- fib = self.vapi.ip6_fib_dump()
+ fib = self.vapi.ip_route_dump(0, True)
default_routes = self.get_default_routes(fib)
self.assertEqual(len(default_routes), 1)
dr = default_routes[0]
self.sleep(0.1)
# check that default route still exists
- fib = self.vapi.ip6_fib_dump()
+ fib = self.vapi.ip_route_dump(0, True)
default_routes = self.get_default_routes(fib)
self.assertEqual(len(default_routes), 1)
dr = default_routes[0]
self.sleep(1)
# check that default route is deleted
- fib = self.vapi.ip6_fib_dump()
+ fib = self.vapi.ip_route_dump(0, True)
default_routes = self.get_default_routes(fib)
self.assertEqual(len(default_routes), 0)
# check FIB still contains the SLAAC address
addresses = set(self.get_interface_addresses(fib, self.pg0))
new_addresses = addresses.difference(initial_addresses)
+
self.assertEqual(len(new_addresses), 1)
- prefix = list(new_addresses)[0][:8] + '\0\0\0\0\0\0\0\0'
- self.assertEqual(inet_ntop(AF_INET6, prefix), '1::')
+ prefix = IPv6Network(text_type("%s/%d" % (list(new_addresses)[0], 20)),
+ strict=False)
+ self.assertEqual(prefix, IPv6Network(text_type('1::/20')))
self.sleep(1)
# check that SLAAC address is deleted
- fib = self.vapi.ip6_fib_dump()
+ fib = self.vapi.ip_route_dump(0, True)
addresses = set(self.get_interface_addresses(fib, self.pg0))
new_addresses = addresses.difference(initial_addresses)
self.assertEqual(len(new_addresses), 0)
class IPv6NDProxyTest(TestIPv6ND):
""" IPv6 ND ProxyTest Case """
+ @classmethod
+ def setUpClass(cls):
+ super(IPv6NDProxyTest, cls).setUpClass()
+
+ @classmethod
+ def tearDownClass(cls):
+ super(IPv6NDProxyTest, cls).tearDownClass()
+
def setUp(self):
super(IPv6NDProxyTest, self).setUp()
# on the link that has the prefix configured
#
ns_pg1 = (Ether(dst=in6_getnsmac(nsma), src=self.pg1.remote_mac) /
- IPv6(dst=d, src=self.pg0._remote_hosts[2].ip6) /
+ IPv6(dst=d,
+ src=self.pg0._remote_hosts[2].ip6) /
ICMPv6ND_NS(tgt=self.pg0.local_ip6) /
- ICMPv6NDOptSrcLLAddr(lladdr=self.pg0._remote_hosts[2].mac))
+ ICMPv6NDOptSrcLLAddr(
+ lladdr=self.pg0._remote_hosts[2].mac))
self.send_and_assert_no_replies(self.pg1, ns_pg1, "Off link NS")
#
# Add proxy support for the host
#
- self.vapi.ip6_nd_proxy(
- inet_pton(AF_INET6, self.pg0._remote_hosts[2].ip6),
- self.pg1.sw_if_index)
+ self.vapi.ip6nd_proxy_add_del(
+ ip=inet_pton(AF_INET6, self.pg0._remote_hosts[2].ip6),
+ sw_if_index=self.pg1.sw_if_index)
#
# try that NS again. this time we expect an NA back
#
self.assertTrue(find_nbr(self,
self.pg1.sw_if_index,
- self.pg0._remote_hosts[2].ip6,
- inet=AF_INET6))
+ self.pg0._remote_hosts[2].ip6))
#
# ... and we can route traffic to it
t = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
IPv6(dst=self.pg0._remote_hosts[2].ip6,
src=self.pg0.remote_ip6) /
- UDP(sport=10000, dport=20000) /
+ inet6.UDP(sport=10000, dport=20000) /
Raw('\xa5' * 100))
self.pg0.add_stream(t)
self.assertEqual(rx[Ether].dst, self.pg0._remote_hosts[2].mac)
self.assertEqual(rx[Ether].src, self.pg1.local_mac)
- self.assertEqual(rx[IPv6].src, t[IPv6].src)
- self.assertEqual(rx[IPv6].dst, t[IPv6].dst)
+ self.assertEqual(rx[IPv6].src,
+ t[IPv6].src)
+ self.assertEqual(rx[IPv6].dst,
+ t[IPv6].dst)
#
# Test we proxy for the host on the main interface
#
ns_pg0 = (Ether(dst=in6_getnsmac(nsma), src=self.pg0.remote_mac) /
IPv6(dst=d, src=self.pg0.remote_ip6) /
- ICMPv6ND_NS(tgt=self.pg0._remote_hosts[2].ip6) /
- ICMPv6NDOptSrcLLAddr(lladdr=self.pg0.remote_mac))
+ ICMPv6ND_NS(
+ tgt=self.pg0._remote_hosts[2].ip6) /
+ ICMPv6NDOptSrcLLAddr(
+ lladdr=self.pg0.remote_mac))
self.send_and_expect_na(self.pg0, ns_pg0,
"NS to proxy entry on main",
# Setup and resolve proxy for another host on another interface
#
ns_pg2 = (Ether(dst=in6_getnsmac(nsma), src=self.pg2.remote_mac) /
- IPv6(dst=d, src=self.pg0._remote_hosts[3].ip6) /
+ IPv6(dst=d,
+ src=self.pg0._remote_hosts[3].ip6) /
ICMPv6ND_NS(tgt=self.pg0.local_ip6) /
- ICMPv6NDOptSrcLLAddr(lladdr=self.pg0._remote_hosts[2].mac))
+ ICMPv6NDOptSrcLLAddr(
+ lladdr=self.pg0._remote_hosts[2].mac))
- self.vapi.ip6_nd_proxy(
- inet_pton(AF_INET6, self.pg0._remote_hosts[3].ip6),
- self.pg2.sw_if_index)
+ self.vapi.ip6nd_proxy_add_del(
+ ip=inet_pton(AF_INET6, self.pg0._remote_hosts[3].ip6),
+ sw_if_index=self.pg2.sw_if_index)
self.send_and_expect_na(self.pg2, ns_pg2,
"NS to proxy entry other interface",
self.assertTrue(find_nbr(self,
self.pg2.sw_if_index,
- self.pg0._remote_hosts[3].ip6,
- inet=AF_INET6))
+ self.pg0._remote_hosts[3].ip6))
#
# hosts can communicate. pg2->pg1
src=self.pg0.remote_hosts[3].mac) /
IPv6(dst=self.pg0._remote_hosts[2].ip6,
src=self.pg0._remote_hosts[3].ip6) /
- UDP(sport=10000, dport=20000) /
+ inet6.UDP(sport=10000, dport=20000) /
Raw('\xa5' * 100))
self.pg2.add_stream(t2)
self.assertEqual(rx[Ether].dst, self.pg0._remote_hosts[2].mac)
self.assertEqual(rx[Ether].src, self.pg1.local_mac)
- self.assertEqual(rx[IPv6].src, t2[IPv6].src)
- self.assertEqual(rx[IPv6].dst, t2[IPv6].dst)
+ self.assertEqual(rx[IPv6].src,
+ t2[IPv6].src)
+ self.assertEqual(rx[IPv6].dst,
+ t2[IPv6].dst)
#
# remove the proxy configs
#
- self.vapi.ip6_nd_proxy(
- inet_pton(AF_INET6, self.pg0._remote_hosts[2].ip6),
- self.pg1.sw_if_index,
- is_del=1)
- self.vapi.ip6_nd_proxy(
- inet_pton(AF_INET6, self.pg0._remote_hosts[3].ip6),
- self.pg2.sw_if_index,
- is_del=1)
+ self.vapi.ip6nd_proxy_add_del(
+ ip=inet_pton(AF_INET6, self.pg0._remote_hosts[2].ip6),
+ sw_if_index=self.pg1.sw_if_index, is_del=1)
+ self.vapi.ip6nd_proxy_add_del(
+ ip=inet_pton(AF_INET6, self.pg0._remote_hosts[3].ip6),
+ sw_if_index=self.pg2.sw_if_index, is_del=1)
self.assertFalse(find_nbr(self,
self.pg2.sw_if_index,
- self.pg0._remote_hosts[3].ip6,
- inet=AF_INET6))
+ self.pg0._remote_hosts[3].ip6))
self.assertFalse(find_nbr(self,
self.pg1.sw_if_index,
- self.pg0._remote_hosts[2].ip6,
- inet=AF_INET6))
+ self.pg0._remote_hosts[2].ip6))
#
# no longer proxy-ing...
class TestIPNull(VppTestCase):
""" IPv6 routes via NULL """
+ @classmethod
+ def setUpClass(cls):
+ super(TestIPNull, cls).setUpClass()
+
+ @classmethod
+ def tearDownClass(cls):
+ super(TestIPNull, cls).tearDownClass()
+
def setUp(self):
super(TestIPNull, self).setUp()
p = (Ether(src=self.pg0.remote_mac,
dst=self.pg0.local_mac) /
IPv6(src=self.pg0.remote_ip6, dst="2001::1") /
- UDP(sport=1234, dport=1234) /
+ inet6.UDP(sport=1234, dport=1234) /
Raw('\xa5' * 100))
#
# A route via IP NULL that will reply with ICMP unreachables
#
- ip_unreach = VppIpRoute(self, "2001::", 64, [], is_unreach=1, is_ip6=1)
+ ip_unreach = VppIpRoute(
+ self, "2001::", 64,
+ [VppRoutePath("::", 0xffffffff,
+ type=FibPathType.FIB_PATH_TYPE_ICMP_UNREACH)])
ip_unreach.add_vpp_config()
self.pg0.add_stream(p)
#
# A route via IP NULL that will reply with ICMP prohibited
#
- ip_prohibit = VppIpRoute(self, "2001::1", 128, [],
- is_prohibit=1, is_ip6=1)
+ ip_prohibit = VppIpRoute(
+ self, "2001::1", 128,
+ [VppRoutePath("::", 0xffffffff,
+ type=FibPathType.FIB_PATH_TYPE_ICMP_PROHIBIT)])
ip_prohibit.add_vpp_config()
self.pg0.add_stream(p)
class TestIPDisabled(VppTestCase):
""" IPv6 disabled """
+ @classmethod
+ def setUpClass(cls):
+ super(TestIPDisabled, cls).setUpClass()
+
+ @classmethod
+ def tearDownClass(cls):
+ super(TestIPDisabled, cls).tearDownClass()
+
def setUp(self):
super(TestIPDisabled, self).setUp()
# create 2 pg interfaces
self.create_pg_interfaces(range(2))
- # PG0 is IP enalbed
+ # PG0 is IP enabled
self.pg0.admin_up()
self.pg0.config_ip6()
self.pg0.resolve_ndp()
[VppMRoutePath(self.pg1.sw_if_index,
MRouteItfFlags.MFIB_ITF_FLAG_ACCEPT),
VppMRoutePath(self.pg0.sw_if_index,
- MRouteItfFlags.MFIB_ITF_FLAG_FORWARD)],
- is_ip6=1)
+ MRouteItfFlags.MFIB_ITF_FLAG_FORWARD)])
route_ff_01.add_vpp_config()
pu = (Ether(src=self.pg1.remote_mac,
dst=self.pg1.local_mac) /
IPv6(src="2001::1", dst=self.pg0.remote_ip6) /
- UDP(sport=1234, dport=1234) /
+ inet6.UDP(sport=1234, dport=1234) /
Raw('\xa5' * 100))
pm = (Ether(src=self.pg1.remote_mac,
dst=self.pg1.local_mac) /
IPv6(src="2001::1", dst="ffef::1") /
- UDP(sport=1234, dport=1234) /
+ inet6.UDP(sport=1234, dport=1234) /
Raw('\xa5' * 100))
#
class TestIP6LoadBalance(VppTestCase):
""" IPv6 Load-Balancing """
+ @classmethod
+ def setUpClass(cls):
+ super(TestIP6LoadBalance, cls).setUpClass()
+
+ @classmethod
+ def tearDownClass(cls):
+ super(TestIP6LoadBalance, cls).tearDownClass()
+
def setUp(self):
super(TestIP6LoadBalance, self).setUp()
i.disable_mpls()
super(TestIP6LoadBalance, self).tearDown()
- def send_and_expect_load_balancing(self, input, pkts, outputs):
+ def pg_send(self, input, pkts):
self.vapi.cli("clear trace")
input.add_stream(pkts)
self.pg_enable_capture(self.pg_interfaces)
self.pg_start()
+
+ def send_and_expect_load_balancing(self, input, pkts, outputs):
+ self.pg_send(input, pkts)
for oo in outputs:
rx = oo._get_capture(1)
self.assertNotEqual(0, len(rx))
def send_and_expect_one_itf(self, input, pkts, itf):
- self.vapi.cli("clear trace")
- input.add_stream(pkts)
- self.pg_enable_capture(self.pg_interfaces)
- self.pg_start()
+ self.pg_send(input, pkts)
rx = itf.get_capture(len(pkts))
def test_ip6_load_balance(self):
src_ip_pkts = []
src_mpls_pkts = []
- for ii in range(65):
- port_ip_hdr = (IPv6(dst="3000::1", src="3000:1::1") /
- UDP(sport=1234, dport=1234 + ii) /
- Raw('\xa5' * 100))
+ for ii in range(NUM_PKTS):
+ port_ip_hdr = (
+ IPv6(dst="3000::1", src="3000:1::1") /
+ inet6.UDP(sport=1234, dport=1234 + ii) /
+ Raw('\xa5' * 100))
port_ip_pkts.append((Ether(src=self.pg0.remote_mac,
dst=self.pg0.local_mac) /
port_ip_hdr))
MPLS(label=14, ttl=2) /
MPLS(label=999, ttl=2) /
port_ip_hdr))
- src_ip_hdr = (IPv6(dst="3000::1", src="3000:1::%d" % ii) /
- UDP(sport=1234, dport=1234) /
- Raw('\xa5' * 100))
+ src_ip_hdr = (
+ IPv6(dst="3000::1", src="3000:1::%d" % ii) /
+ inet6.UDP(sport=1234, dport=1234) /
+ Raw('\xa5' * 100))
src_ip_pkts.append((Ether(src=self.pg0.remote_mac,
dst=self.pg0.local_mac) /
src_ip_hdr))
src_ip_hdr))
#
- # A route for the IP pacekts
+ # A route for the IP packets
#
route_3000_1 = VppIpRoute(self, "3000::1", 128,
[VppRoutePath(self.pg1.remote_ip6,
- self.pg1.sw_if_index,
- proto=DpoProto.DPO_PROTO_IP6),
+ self.pg1.sw_if_index),
VppRoutePath(self.pg2.remote_ip6,
- self.pg2.sw_if_index,
- proto=DpoProto.DPO_PROTO_IP6)],
- is_ip6=1)
+ self.pg2.sw_if_index)])
route_3000_1.add_vpp_config()
#
route_67 = VppMplsRoute(self, 67, 0,
[VppRoutePath(self.pg1.remote_ip6,
self.pg1.sw_if_index,
- labels=[67],
- proto=DpoProto.DPO_PROTO_IP6),
+ labels=[67]),
VppRoutePath(self.pg2.remote_ip6,
self.pg2.sw_if_index,
- labels=[67],
- proto=DpoProto.DPO_PROTO_IP6)])
+ labels=[67])])
route_67.add_vpp_config()
#
# src,dst
# We are not going to ensure equal amounts of packets across each link,
# since the hash algorithm is statistical and therefore this can never
- # be guaranteed. But wuth 64 different packets we do expect some
+ # be guaranteed. But with 64 different packets we do expect some
# balancing. So instead just ensure there is traffic on each link.
#
self.send_and_expect_load_balancing(self.pg0, port_ip_pkts,
#
# The packets with Entropy label in should not load-balance,
- # since the Entorpy value is fixed.
+ # since the Entropy value is fixed.
#
self.send_and_expect_one_itf(self.pg0, port_ent_pkts, self.pg1)
# - now only the stream with differing source address will
# load-balance
#
- self.vapi.set_ip_flow_hash(0, is_ip6=1, src=1, dst=1, sport=0, dport=0)
+ self.vapi.set_ip_flow_hash(vrf_id=0, src=1, dst=1, sport=0, dport=0,
+ is_ipv6=1)
self.send_and_expect_load_balancing(self.pg0, src_ip_pkts,
[self.pg1, self.pg2])
#
# change the flow hash config back to defaults
#
- self.vapi.set_ip_flow_hash(0, is_ip6=1, src=1, dst=1, sport=1, dport=1)
+ self.vapi.set_ip_flow_hash(vrf_id=0, src=1, dst=1, sport=1, dport=1,
+ is_ipv6=1)
#
# Recursive prefixes
for ii in range(257):
port_pkts.append((Ether(src=self.pg0.remote_mac,
dst=self.pg0.local_mac) /
- IPv6(dst="4000::1", src="4000:1::1") /
- UDP(sport=1234, dport=1234 + ii) /
+ IPv6(dst="4000::1",
+ src="4000:1::1") /
+ inet6.UDP(sport=1234,
+ dport=1234 + ii) /
Raw('\xa5' * 100)))
src_pkts.append((Ether(src=self.pg0.remote_mac,
dst=self.pg0.local_mac) /
- IPv6(dst="4000::1", src="4000:1::%d" % ii) /
- UDP(sport=1234, dport=1234) /
+ IPv6(dst="4000::1",
+ src="4000:1::%d" % ii) /
+ inet6.UDP(sport=1234, dport=1234) /
Raw('\xa5' * 100)))
route_3000_2 = VppIpRoute(self, "3000::2", 128,
[VppRoutePath(self.pg3.remote_ip6,
- self.pg3.sw_if_index,
- proto=DpoProto.DPO_PROTO_IP6),
+ self.pg3.sw_if_index),
VppRoutePath(self.pg4.remote_ip6,
- self.pg4.sw_if_index,
- proto=DpoProto.DPO_PROTO_IP6)],
- is_ip6=1)
+ self.pg4.sw_if_index)])
route_3000_2.add_vpp_config()
route_4000_1 = VppIpRoute(self, "4000::1", 128,
[VppRoutePath("3000::1",
- 0xffffffff,
- proto=DpoProto.DPO_PROTO_IP6),
+ 0xffffffff),
VppRoutePath("3000::2",
- 0xffffffff,
- proto=DpoProto.DPO_PROTO_IP6)],
- is_ip6=1)
+ 0xffffffff)])
route_4000_1.add_vpp_config()
#
for ii in range(257):
port_pkts.append((Ether(src=self.pg0.remote_mac,
dst=self.pg0.local_mac) /
- IPv6(dst="6000::1", src="6000:1::1") /
- UDP(sport=1234, dport=1234 + ii) /
+ IPv6(dst="6000::1",
+ src="6000:1::1") /
+ inet6.UDP(sport=1234,
+ dport=1234 + ii) /
Raw('\xa5' * 100)))
route_5000_2 = VppIpRoute(self, "5000::2", 128,
[VppRoutePath(self.pg3.remote_ip6,
- self.pg3.sw_if_index,
- proto=DpoProto.DPO_PROTO_IP6)],
- is_ip6=1)
+ self.pg3.sw_if_index)])
route_5000_2.add_vpp_config()
route_6000_1 = VppIpRoute(self, "6000::1", 128,
[VppRoutePath("5000::2",
- 0xffffffff,
- proto=DpoProto.DPO_PROTO_IP6)],
- is_ip6=1)
+ 0xffffffff)])
route_6000_1.add_vpp_config()
#
class TestIP6Punt(VppTestCase):
""" IPv6 Punt Police/Redirect """
+ @classmethod
+ def setUpClass(cls):
+ super(TestIP6Punt, cls).setUpClass()
+
+ @classmethod
+ def tearDownClass(cls):
+ super(TestIP6Punt, cls).tearDownClass()
+
def setUp(self):
super(TestIP6Punt, self).setUp()
- self.create_pg_interfaces(range(2))
+ self.create_pg_interfaces(range(4))
for i in self.pg_interfaces:
i.admin_up()
p = (Ether(src=self.pg0.remote_mac,
dst=self.pg0.local_mac) /
- IPv6(src=self.pg0.remote_ip6, dst=self.pg0.local_ip6) /
- TCP(sport=1234, dport=1234) /
+ IPv6(src=self.pg0.remote_ip6,
+ dst=self.pg0.local_ip6) /
+ inet6.TCP(sport=1234, dport=1234) /
Raw('\xa5' * 100))
pkts = p * 1025
#
# Configure a punt redirect via pg1.
#
- nh_addr = inet_pton(AF_INET6,
- self.pg1.remote_ip6)
+ nh_addr = self.pg1.remote_ip6
self.vapi.ip_punt_redirect(self.pg0.sw_if_index,
self.pg1.sw_if_index,
- nh_addr,
- is_ip6=1)
+ nh_addr)
self.send_and_expect(self.pg0, pkts, self.pg1)
#
# add a policer
#
- policer = self.vapi.policer_add_del("ip6-punt", 400, 0, 10, 0,
+ policer = self.vapi.policer_add_del(b"ip6-punt", 400, 0, 10, 0,
rate_type=1)
self.vapi.ip_punt_police(policer.policer_index, is_ip6=1)
self.pg_start()
#
- # the number of packet recieved should be greater than 0,
+ # the number of packet received should be greater than 0,
# but not equal to the number sent, since some were policed
#
rx = self.pg1._get_capture(1)
- self.assertTrue(len(rx) > 0)
- self.assertTrue(len(rx) < len(pkts))
+ self.assertGreater(len(rx), 0)
+ self.assertLess(len(rx), len(pkts))
#
- # remove the poilcer. back to full rx
+ # remove the policer. back to full rx
#
self.vapi.ip_punt_police(policer.policer_index, is_add=0, is_ip6=1)
- self.vapi.policer_add_del("ip6-punt", 400, 0, 10, 0,
+ self.vapi.policer_add_del(b"ip6-punt", 400, 0, 10, 0,
rate_type=1, is_add=0)
self.send_and_expect(self.pg0, pkts, self.pg1)
self.vapi.ip_punt_redirect(self.pg0.sw_if_index,
self.pg1.sw_if_index,
nh_addr,
- is_add=0,
- is_ip6=1)
+ is_add=0)
self.send_and_assert_no_replies(self.pg0, pkts,
"IP no punt config")
#
self.vapi.ip_punt_redirect(0xffffffff,
self.pg1.sw_if_index,
- nh_addr,
- is_ip6=1)
+ nh_addr)
self.send_and_expect(self.pg0, pkts, self.pg1)
self.vapi.ip_punt_redirect(0xffffffff,
self.pg1.sw_if_index,
nh_addr,
- is_add=0,
- is_ip6=1)
+ is_add=0)
+
+ def test_ip_punt_dump(self):
+ """ IP6 punt redirect dump"""
+
+ #
+ # Configure a punt redirects
+ #
+ nh_addr = self.pg3.remote_ip6
+ self.vapi.ip_punt_redirect(self.pg0.sw_if_index,
+ self.pg3.sw_if_index,
+ nh_addr)
+ self.vapi.ip_punt_redirect(self.pg1.sw_if_index,
+ self.pg3.sw_if_index,
+ nh_addr)
+ self.vapi.ip_punt_redirect(self.pg2.sw_if_index,
+ self.pg3.sw_if_index,
+ '0::0')
+
+ #
+ # Dump pg0 punt redirects
+ #
+ punts = self.vapi.ip_punt_redirect_dump(self.pg0.sw_if_index,
+ is_ipv6=1)
+ for p in punts:
+ self.assertEqual(p.punt.rx_sw_if_index, self.pg0.sw_if_index)
+
+ #
+ # Dump punt redirects for all interfaces
+ #
+ punts = self.vapi.ip_punt_redirect_dump(0xffffffff, is_ipv6=1)
+ self.assertEqual(len(punts), 3)
+ for p in punts:
+ self.assertEqual(p.punt.tx_sw_if_index, self.pg3.sw_if_index)
+ self.assertNotEqual(punts[1].punt.nh, self.pg3.remote_ip6)
+ self.assertEqual(str(punts[2].punt.nh), '::')
class TestIPDeag(VppTestCase):
""" IPv6 Deaggregate Routes """
+ @classmethod
+ def setUpClass(cls):
+ super(TestIPDeag, cls).setUpClass()
+
+ @classmethod
+ def tearDownClass(cls):
+ super(TestIPDeag, cls).tearDownClass()
+
def setUp(self):
super(TestIPDeag, self).setUp()
route_to_dst = VppIpRoute(self, "1::1", 128,
[VppRoutePath("::",
0xffffffff,
- nh_table_id=1,
- proto=DpoProto.DPO_PROTO_IP6)],
- is_ip6=1)
- route_to_src = VppIpRoute(self, "1::2", 128,
- [VppRoutePath("::",
- 0xffffffff,
- nh_table_id=2,
- is_source_lookup=1,
- proto=DpoProto.DPO_PROTO_IP6)],
- is_ip6=1)
+ nh_table_id=1)])
+ route_to_src = VppIpRoute(
+ self, "1::2", 128,
+ [VppRoutePath("::",
+ 0xffffffff,
+ nh_table_id=2,
+ type=FibPathType.FIB_PATH_TYPE_SOURCE_LOOKUP)])
+
route_to_dst.add_vpp_config()
route_to_src.add_vpp_config()
p_dst = (Ether(src=self.pg0.remote_mac,
dst=self.pg0.local_mac) /
IPv6(src="5::5", dst="1::1") /
- TCP(sport=1234, dport=1234) /
+ inet6.TCP(sport=1234, dport=1234) /
Raw('\xa5' * 100))
p_src = (Ether(src=self.pg0.remote_mac,
dst=self.pg0.local_mac) /
IPv6(src="2::2", dst="1::2") /
- TCP(sport=1234, dport=1234) /
+ inet6.TCP(sport=1234, dport=1234) /
Raw('\xa5' * 100))
pkts_dst = p_dst * 257
pkts_src = p_src * 257
#
route_in_dst = VppIpRoute(self, "1::1", 128,
[VppRoutePath(self.pg1.remote_ip6,
- self.pg1.sw_if_index,
- proto=DpoProto.DPO_PROTO_IP6)],
- is_ip6=1,
+ self.pg1.sw_if_index)],
table_id=1)
route_in_dst.add_vpp_config()
#
route_in_src = VppIpRoute(self, "2::2", 128,
[VppRoutePath(self.pg2.remote_ip6,
- self.pg2.sw_if_index,
- proto=DpoProto.DPO_PROTO_IP6)],
- is_ip6=1,
+ self.pg2.sw_if_index)],
table_id=2)
route_in_src.add_vpp_config()
self.send_and_expect(self.pg0, pkts_src, self.pg2)
#
route_loop = VppIpRoute(self, "3::3", 128,
[VppRoutePath("::",
- 0xffffffff,
- proto=DpoProto.DPO_PROTO_IP6)],
- is_ip6=1)
+ 0xffffffff)])
route_loop.add_vpp_config()
p_l = (Ether(src=self.pg0.remote_mac,
dst=self.pg0.local_mac) /
IPv6(src="3::4", dst="3::3") /
- TCP(sport=1234, dport=1234) /
+ inet6.TCP(sport=1234, dport=1234) /
Raw('\xa5' * 100))
self.send_and_assert_no_replies(self.pg0, p_l * 257,
class TestIP6Input(VppTestCase):
- """ IPv6 Input Exceptions """
+ """ IPv6 Input Exception Test Cases """
+
+ @classmethod
+ def setUpClass(cls):
+ super(TestIP6Input, cls).setUpClass()
+
+ @classmethod
+ def tearDownClass(cls):
+ super(TestIP6Input, cls).tearDownClass()
def setUp(self):
super(TestIP6Input, self).setUp()
i.unconfig_ip6()
i.admin_down()
- def test_ip_input(self):
- """ IP6 Input Exceptions """
-
+ def test_ip_input_icmp_reply(self):
+ """ IP6 Input Exception - Return ICMP (3,0) """
#
- # bad version - this is dropped
+ # hop limit - ICMP replies
#
p_version = (Ether(src=self.pg0.remote_mac,
dst=self.pg0.local_mac) /
IPv6(src=self.pg0.remote_ip6,
dst=self.pg1.remote_ip6,
- version=3) /
- UDP(sport=1234, dport=1234) /
+ hlim=1) /
+ inet6.UDP(sport=1234, dport=1234) /
Raw('\xa5' * 100))
- self.send_and_assert_no_replies(self.pg0, p_version * 65,
- "funky version")
+ rx = self.send_and_expect(self.pg0, p_version * NUM_PKTS, self.pg0)
+ rx = rx[0]
+ icmp = rx[ICMPv6TimeExceeded]
+
+ # 0: "hop limit exceeded in transit",
+ self.assertEqual((icmp.type, icmp.code), (3, 0))
+
+ icmpv6_data = '\x0a' * 18
+ all_0s = "::"
+ all_1s = "FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF"
+
+ @parameterized.expand([
+ # Name, src, dst, l4proto, msg, timeout
+ ("src='iface', dst='iface'", None, None,
+ inet6.UDP(sport=1234, dport=1234), "funky version", None),
+ ("src='All 0's', dst='iface'", all_0s, None,
+ ICMPv6EchoRequest(id=0xb, seq=5, data=icmpv6_data), None, 0.1),
+ ("src='iface', dst='All 0's'", None, all_0s,
+ ICMPv6EchoRequest(id=0xb, seq=5, data=icmpv6_data), None, 0.1),
+ ("src='All 1's', dst='iface'", all_1s, None,
+ ICMPv6EchoRequest(id=0xb, seq=5, data=icmpv6_data), None, 0.1),
+ ("src='iface', dst='All 1's'", None, all_1s,
+ ICMPv6EchoRequest(id=0xb, seq=5, data=icmpv6_data), None, 0.1),
+ ("src='All 1's', dst='All 1's'", all_1s, all_1s,
+ ICMPv6EchoRequest(id=0xb, seq=5, data=icmpv6_data), None, 0.1),
+
+ ])
+ def test_ip_input_no_replies(self, name, src, dst, l4, msg, timeout):
+
+ self._testMethodDoc = 'IPv6 Input Exception - %s' % name
- #
- # hop limit - IMCP replies
- #
p_version = (Ether(src=self.pg0.remote_mac,
dst=self.pg0.local_mac) /
- IPv6(src=self.pg0.remote_ip6,
- dst=self.pg1.remote_ip6,
- hlim=1) /
- UDP(sport=1234, dport=1234) /
+ IPv6(src=src or self.pg0.remote_ip6,
+ dst=dst or self.pg1.remote_ip6,
+ version=3) /
+ l4 /
Raw('\xa5' * 100))
- rx = self.send_and_expect(self.pg0, p_version * 65, self.pg0)
- rx = rx[0]
- icmp = rx[ICMPv6TimeExceeded]
- self.assertEqual(icmp.type, 3)
- # 0: "hop limit exceeded in transit",
- self.assertEqual(icmp.code, 0)
+ self.send_and_assert_no_replies(self.pg0, p_version * NUM_PKTS,
+ remark=msg or "",
+ timeout=timeout)
+
+ def test_hop_by_hop(self):
+ """ Hop-by-hop header test """
+ p = (Ether(src=self.pg0.remote_mac,
+ dst=self.pg0.local_mac) /
+ IPv6(src=self.pg0.remote_ip6, dst=self.pg0.local_ip6) /
+ IPv6ExtHdrHopByHop() /
+ inet6.UDP(sport=1234, dport=1234) /
+ Raw('\xa5' * 100))
+
+ self.pg0.add_stream(p)
+ self.pg_enable_capture(self.pg_interfaces)
+ self.pg_start()
if __name__ == '__main__':
unittest.main(testRunner=VppTestRunner)