6 from framework import VppTestCase, VppTestRunner
7 from vpp_ip import DpoProto
8 from vpp_ip_route import VppIpRoute, VppRoutePath
9 from util import fragment_rfc791, fragment_rfc8200
12 from scapy.layers.l2 import Ether
13 from scapy.packet import Raw
14 from scapy.layers.inet import IP, UDP, ICMP, TCP
15 from scapy.layers.inet6 import IPv6, ICMPv6TimeExceeded, IPv6ExtHdrFragment
16 from scapy.layers.inet6 import ICMPv6EchoRequest, ICMPv6EchoReply
19 class TestMAPBR(VppTestCase):
20 """ MAP-T Test Cases """
24 super(TestMAPBR, cls).setUpClass()
27 def tearDownClass(cls):
28 super(TestMAPBR, cls).tearDownClass()
31 super(TestMAPBR, self).setUp()
34 # Create 2 pg interfaces.
38 self.create_pg_interfaces(range(2))
42 self.pg1.generate_remote_hosts(20)
43 self.pg1.configure_ipv4_neighbors()
44 self.pg0.resolve_arp()
48 self.pg1.generate_remote_hosts(20)
49 self.pg1.configure_ipv6_neighbors()
52 # BR configuration parameters used for all test.
54 self.ip4_prefix = '198.18.0.0/24'
55 self.ip6_prefix = '2001:db8:f0::/48'
56 self.ip6_src = '2001:db8:ffff:ff00::/64'
63 self.ipv4_internet_address = self.pg0.remote_ip4
64 self.ipv4_map_address = "198.18.0.12"
65 self.ipv4_udp_or_tcp_internet_port = 65000
66 self.ipv4_udp_or_tcp_map_port = 16606
68 self.ipv6_cpe_address = "2001:db8:f0:c30:0:c612:c:3" # 198.18.0.12
69 self.ipv6_spoof_address = "2001:db8:f0:c30:0:c612:1c:3" # 198.18.0.28
70 self.ipv6_spoof_prefix = "2001:db8:f0:c30:0:a00:c:3" # 10.0.0.12
71 self.ipv6_spoof_psid = "2001:db8:f0:c30:0:c612:c:4" # 4
72 self.ipv6_spoof_subnet = "2001:db8:f1:c30:0:c612:c:3" # f1
74 self.ipv6_udp_or_tcp_internet_port = 65000
75 self.ipv6_udp_or_tcp_map_port = 16606
76 self.ipv6_udp_or_tcp_spoof_port = 16862
78 self.ipv6_map_address = (
79 "2001:db8:ffff:ff00:ac:1001:200:0") # 176.16.1.2
80 self.ipv6_map_same_rule_diff_addr = (
81 "2001:db8:ffff:ff00:c6:1200:10:0") # 198.18.0.16
83 self.map_br_prefix = "2001:db8:f0::"
84 self.map_br_prefix_len = 48
88 # Add an IPv6 route to the MAP-BR.
90 map_route = VppIpRoute(self,
92 self.map_br_prefix_len,
93 [VppRoutePath(self.pg1.remote_ip6,
94 self.pg1.sw_if_index)])
95 map_route.add_vpp_config()
97 ip4_map_route = VppIpRoute(self,
100 [VppRoutePath(self.pg1.remote_ip4,
101 self.pg1.sw_if_index)])
102 ip4_map_route.add_vpp_config()
105 # Add a MAP BR domain that maps from pg0 to pg1.
107 self.vapi.map_add_domain(ip4_prefix=self.ip4_prefix,
108 ip6_prefix=self.ip6_prefix,
109 ip6_src=self.ip6_src,
110 ea_bits_len=self.ea_bits_len,
111 psid_offset=self.psid_offset,
112 psid_length=self.psid_length,
119 self.vapi.map_param_set_fragmentation(inner=1, ignore_df=0)
120 self.vapi.map_param_set_fragmentation(inner=0, ignore_df=0)
121 self.vapi.map_param_set_icmp(ip4_err_relay_src=self.pg0.local_ip4)
122 self.vapi.map_param_set_traffic_class(copy=1)
125 # Enable MAP-T on interfaces.
127 self.vapi.map_if_enable_disable(is_enable=1,
128 sw_if_index=self.pg0.sw_if_index,
131 self.vapi.map_if_enable_disable(is_enable=1,
132 sw_if_index=self.pg1.sw_if_index,
135 self.vapi.map_if_enable_disable(is_enable=1,
136 sw_if_index=self.pg1.sw_if_index,
140 super(TestMAPBR, self).tearDown()
141 for i in self.pg_interfaces:
147 # Spoofed IPv4 Source Address v6 -> v4 direction
148 # Send a packet with a wrong IPv4 address embedded in bits 72-103.
149 # The BR should either drop the packet, or rewrite the spoofed
150 # source IPv4 as the actual source IPv4 address.
151 # The BR really should drop the packet.
154 def test_map_t_spoof_ipv4_src_addr_ip6_to_ip4(self):
155 """ MAP-T spoof ipv4 src addr IPv6 -> IPv4 """
157 eth = Ether(src=self.pg1.remote_mac,
158 dst=self.pg1.local_mac)
159 ip = IPv6(src=self.ipv6_spoof_address,
160 dst=self.ipv6_map_address)
161 udp = UDP(sport=self.ipv6_udp_or_tcp_map_port,
162 dport=self.ipv6_udp_or_tcp_internet_port)
164 tx_pkt = eth / ip / udp / payload
166 self.pg_send(self.pg1, tx_pkt * 1)
168 self.pg0.get_capture(0, timeout=1)
169 self.pg0.assert_nothing_captured("Should drop IPv4 spoof address")
172 # Spoofed IPv4 Source Prefix v6 -> v4 direction
173 # Send a packet with a wrong IPv4 prefix embedded in bits 72-103.
174 # The BR should either drop the packet, or rewrite the source IPv4
175 # to the prefix that matches the source IPv4 address.
178 def test_map_t_spoof_ipv4_src_prefix_ip6_to_ip4(self):
179 """ MAP-T spoof ipv4 src prefix IPv6 -> IPv4 """
181 eth = Ether(src=self.pg1.remote_mac,
182 dst=self.pg1.local_mac)
183 ip = IPv6(src=self.ipv6_spoof_prefix,
184 dst=self.ipv6_map_address)
185 udp = UDP(sport=self.ipv6_udp_or_tcp_map_port,
186 dport=self.ipv6_udp_or_tcp_internet_port)
188 tx_pkt = eth / ip / udp / payload
190 self.pg_send(self.pg1, tx_pkt * 1)
192 self.pg0.get_capture(0, timeout=1)
193 self.pg0.assert_nothing_captured("Should drop IPv4 spoof prefix")
196 # Spoofed IPv6 PSID v6 -> v4 direction
197 # Send a packet with a wrong IPv6 port PSID
198 # The BR should drop the packet.
201 def test_map_t_spoof_psid_ip6_to_ip4(self):
202 """ MAP-T spoof psid IPv6 -> IPv4 """
204 eth = Ether(src=self.pg1.remote_mac,
205 dst=self.pg1.local_mac)
206 ip = IPv6(src=self.ipv6_spoof_psid,
207 dst=self.ipv6_map_address)
208 udp = UDP(sport=self.ipv6_udp_or_tcp_map_port,
209 dport=self.ipv6_udp_or_tcp_internet_port)
211 tx_pkt = eth / ip / udp / payload
213 self.pg_send(self.pg1, tx_pkt * 1)
215 self.pg0.get_capture(0, timeout=1)
216 self.pg0.assert_nothing_captured("Should drop IPv6 spoof PSID")
219 # Spoofed IPv6 subnet field v6 -> v4 direction
220 # Send a packet with a wrong IPv6 subnet as "2001:db8:f1"
221 # The BR should drop the packet.
224 def test_map_t_spoof_subnet_ip6_to_ip4(self):
225 """ MAP-T spoof subnet IPv6 -> IPv4 """
227 eth = Ether(src=self.pg1.remote_mac,
228 dst=self.pg1.local_mac)
229 ip = IPv6(src=self.ipv6_spoof_subnet,
230 dst=self.ipv6_map_address)
231 udp = UDP(sport=self.ipv6_udp_or_tcp_map_port,
232 dport=self.ipv6_udp_or_tcp_internet_port)
234 tx_pkt = eth / ip / udp / payload
236 self.pg_send(self.pg1, tx_pkt * 1)
238 self.pg0.get_capture(0, timeout=1)
239 self.pg0.assert_nothing_captured("Should drop IPv6 spoof subnet")
242 # Spoofed IPv6 port PSID v6 -> v4 direction
243 # Send a packet with a wrong IPv6 port PSID
244 # The BR should drop the packet.
247 def test_map_t_spoof_port_psid_ip6_to_ip4(self):
248 """ MAP-T spoof port psid IPv6 -> IPv4 """
250 eth = Ether(src=self.pg1.remote_mac,
251 dst=self.pg1.local_mac)
252 ip = IPv6(src=self.ipv6_cpe_address,
253 dst=self.ipv6_map_address)
254 udp = UDP(sport=self.ipv6_udp_or_tcp_spoof_port,
255 dport=self.ipv6_udp_or_tcp_internet_port)
257 tx_pkt = eth / ip / udp / payload
259 self.pg_send(self.pg1, tx_pkt * 1)
261 self.pg0.get_capture(0, timeout=1)
262 self.pg0.assert_nothing_captured("Should drop IPv6 spoof port PSID")
264 if __name__ == '__main__':
265 unittest.main(testRunner=VppTestRunner)