blob: 8012350b6c63220ec2e5543436946ddda7cc6d67 [file] [log] [blame]
Matus Fabiande886752016-12-07 03:38:19 -08001#!/usr/bin/env python
2
3import socket
4import unittest
Matus Fabianeea28d72017-01-13 04:15:54 -08005import struct
Matus Fabianefcd1e92017-08-15 06:59:19 -07006import StringIO
7import random
Matus Fabiande886752016-12-07 03:38:19 -08008
Martin Gálik977c1cb2017-03-30 23:21:51 -07009from framework import VppTestCase, VppTestRunner, running_extended_tests
Matus Fabiande886752016-12-07 03:38:19 -080010from scapy.layers.inet import IP, TCP, UDP, ICMP
Juraj Slobodab33f4132017-02-08 23:54:21 -080011from scapy.layers.inet import IPerror, TCPerror, UDPerror, ICMPerror
Matus Fabian06596c52017-06-06 04:53:28 -070012from scapy.layers.inet6 import IPv6, ICMPv6EchoRequest, ICMPv6EchoReply
Matus Fabianefcd1e92017-08-15 06:59:19 -070013from scapy.layers.inet6 import ICMPv6DestUnreach, IPerror6, IPv6ExtHdrFragment
Matus Fabian328dbc82017-06-19 04:28:04 -070014from scapy.layers.l2 import Ether, ARP, GRE
Matus Fabianeea28d72017-01-13 04:15:54 -080015from scapy.data import IP_PROTOS
Matus Fabianefcd1e92017-08-15 06:59:19 -070016from scapy.packet import bind_layers, Raw
17from scapy.all import fragment6
Klement Sekera9225dee2016-12-12 08:36:58 +010018from util import ppp
Matus Fabianeea28d72017-01-13 04:15:54 -080019from ipfix import IPFIX, Set, Template, Data, IPFIXDecoder
Martin Gálik977c1cb2017-03-30 23:21:51 -070020from time import sleep
Matus Fabian704018c2017-09-04 02:17:18 -070021from util import ip4_range
Ole Troan895b6e82017-10-20 13:28:20 +020022from util import mactobinary
Matus Fabiande886752016-12-07 03:38:19 -080023
24
Martin Gálikd7f75cd2017-03-27 06:02:47 -070025class MethodHolder(VppTestCase):
Matus Fabian2ba92e32017-08-21 07:05:03 -070026 """ NAT create capture and verify method holder """
Matus Fabiande886752016-12-07 03:38:19 -080027
Matus Fabiana6110b62018-06-13 05:39:07 -070028 def clear_nat44(self):
29 """
30 Clear NAT44 configuration.
31 """
32 if hasattr(self, 'pg7') and hasattr(self, 'pg8'):
33 # I found no elegant way to do this
34 self.vapi.ip_add_del_route(
35 dst_address=self.pg7.remote_ip4n,
36 dst_address_length=32,
37 next_hop_address=self.pg7.remote_ip4n,
38 next_hop_sw_if_index=self.pg7.sw_if_index,
39 is_add=0)
40 self.vapi.ip_add_del_route(
41 dst_address=self.pg8.remote_ip4n,
42 dst_address_length=32,
43 next_hop_address=self.pg8.remote_ip4n,
44 next_hop_sw_if_index=self.pg8.sw_if_index,
45 is_add=0)
46
47 for intf in [self.pg7, self.pg8]:
48 neighbors = self.vapi.ip_neighbor_dump(intf.sw_if_index)
49 for n in neighbors:
50 self.vapi.ip_neighbor_add_del(intf.sw_if_index,
51 n.mac_address,
52 n.ip_address,
53 is_add=0)
54
55 if self.pg7.has_ip4_config:
56 self.pg7.unconfig_ip4()
57
58 self.vapi.nat44_forwarding_enable_disable(0)
59
60 interfaces = self.vapi.nat44_interface_addr_dump()
61 for intf in interfaces:
62 self.vapi.nat44_add_interface_addr(intf.sw_if_index,
63 twice_nat=intf.twice_nat,
64 is_add=0)
65
66 self.vapi.nat_ipfix(enable=0, src_port=self.ipfix_src_port,
67 domain_id=self.ipfix_domain_id)
68 self.ipfix_src_port = 4739
69 self.ipfix_domain_id = 1
70
71 interfaces = self.vapi.nat44_interface_dump()
72 for intf in interfaces:
73 if intf.is_inside > 1:
74 self.vapi.nat44_interface_add_del_feature(intf.sw_if_index,
75 0,
76 is_add=0)
77 self.vapi.nat44_interface_add_del_feature(intf.sw_if_index,
78 intf.is_inside,
79 is_add=0)
80
81 interfaces = self.vapi.nat44_interface_output_feature_dump()
82 for intf in interfaces:
83 self.vapi.nat44_interface_add_del_output_feature(intf.sw_if_index,
84 intf.is_inside,
85 is_add=0)
86
87 static_mappings = self.vapi.nat44_static_mapping_dump()
88 for sm in static_mappings:
89 self.vapi.nat44_add_del_static_mapping(
90 sm.local_ip_address,
91 sm.external_ip_address,
92 local_port=sm.local_port,
93 external_port=sm.external_port,
94 addr_only=sm.addr_only,
95 vrf_id=sm.vrf_id,
96 protocol=sm.protocol,
97 twice_nat=sm.twice_nat,
98 self_twice_nat=sm.self_twice_nat,
99 out2in_only=sm.out2in_only,
100 tag=sm.tag,
101 external_sw_if_index=sm.external_sw_if_index,
102 is_add=0)
103
104 lb_static_mappings = self.vapi.nat44_lb_static_mapping_dump()
105 for lb_sm in lb_static_mappings:
106 self.vapi.nat44_add_del_lb_static_mapping(
107 lb_sm.external_addr,
108 lb_sm.external_port,
109 lb_sm.protocol,
110 vrf_id=lb_sm.vrf_id,
111 twice_nat=lb_sm.twice_nat,
112 self_twice_nat=lb_sm.self_twice_nat,
113 out2in_only=lb_sm.out2in_only,
114 tag=lb_sm.tag,
115 is_add=0,
116 local_num=0,
117 locals=[])
118
119 identity_mappings = self.vapi.nat44_identity_mapping_dump()
120 for id_m in identity_mappings:
121 self.vapi.nat44_add_del_identity_mapping(
122 addr_only=id_m.addr_only,
123 ip=id_m.ip_address,
124 port=id_m.port,
125 sw_if_index=id_m.sw_if_index,
126 vrf_id=id_m.vrf_id,
127 protocol=id_m.protocol,
128 is_add=0)
129
130 adresses = self.vapi.nat44_address_dump()
131 for addr in adresses:
132 self.vapi.nat44_add_del_address_range(addr.ip_address,
133 addr.ip_address,
134 twice_nat=addr.twice_nat,
135 is_add=0)
136
137 self.vapi.nat_set_reass()
138 self.vapi.nat_set_reass(is_ip6=1)
139
140 def nat44_add_static_mapping(self, local_ip, external_ip='0.0.0.0',
141 local_port=0, external_port=0, vrf_id=0,
142 is_add=1, external_sw_if_index=0xFFFFFFFF,
143 proto=0, twice_nat=0, self_twice_nat=0,
144 out2in_only=0, tag=""):
145 """
146 Add/delete NAT44 static mapping
147
148 :param local_ip: Local IP address
149 :param external_ip: External IP address
150 :param local_port: Local port number (Optional)
151 :param external_port: External port number (Optional)
152 :param vrf_id: VRF ID (Default 0)
153 :param is_add: 1 if add, 0 if delete (Default add)
154 :param external_sw_if_index: External interface instead of IP address
155 :param proto: IP protocol (Mandatory if port specified)
156 :param twice_nat: 1 if translate external host address and port
157 :param self_twice_nat: 1 if translate external host address and port
158 whenever external host address equals
159 local address of internal host
160 :param out2in_only: if 1 rule is matching only out2in direction
161 :param tag: Opaque string tag
162 """
163 addr_only = 1
164 if local_port and external_port:
165 addr_only = 0
166 l_ip = socket.inet_pton(socket.AF_INET, local_ip)
167 e_ip = socket.inet_pton(socket.AF_INET, external_ip)
168 self.vapi.nat44_add_del_static_mapping(
169 l_ip,
170 e_ip,
171 external_sw_if_index,
172 local_port,
173 external_port,
174 addr_only,
175 vrf_id,
176 proto,
177 twice_nat,
178 self_twice_nat,
179 out2in_only,
180 tag,
181 is_add)
182
183 def nat44_add_address(self, ip, is_add=1, vrf_id=0xFFFFFFFF, twice_nat=0):
184 """
185 Add/delete NAT44 address
186
187 :param ip: IP address
188 :param is_add: 1 if add, 0 if delete (Default add)
189 :param twice_nat: twice NAT address for extenal hosts
190 """
191 nat_addr = socket.inet_pton(socket.AF_INET, ip)
192 self.vapi.nat44_add_del_address_range(nat_addr, nat_addr, is_add,
193 vrf_id=vrf_id,
194 twice_nat=twice_nat)
195
Juraj Slobodacba69362017-12-19 02:09:32 +0100196 def create_stream_in(self, in_if, out_if, dst_ip=None, ttl=64):
Matus Fabiande886752016-12-07 03:38:19 -0800197 """
198 Create packet stream for inside network
199
200 :param in_if: Inside interface
201 :param out_if: Outside interface
Juraj Slobodacba69362017-12-19 02:09:32 +0100202 :param dst_ip: Destination address
Juraj Slobodab33f4132017-02-08 23:54:21 -0800203 :param ttl: TTL of generated packets
Matus Fabiande886752016-12-07 03:38:19 -0800204 """
Juraj Slobodacba69362017-12-19 02:09:32 +0100205 if dst_ip is None:
206 dst_ip = out_if.remote_ip4
207
Matus Fabiande886752016-12-07 03:38:19 -0800208 pkts = []
209 # TCP
210 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
Juraj Slobodacba69362017-12-19 02:09:32 +0100211 IP(src=in_if.remote_ip4, dst=dst_ip, ttl=ttl) /
Matus Fabian06596c52017-06-06 04:53:28 -0700212 TCP(sport=self.tcp_port_in, dport=20))
Matus Fabiande886752016-12-07 03:38:19 -0800213 pkts.append(p)
214
215 # UDP
216 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
Juraj Slobodacba69362017-12-19 02:09:32 +0100217 IP(src=in_if.remote_ip4, dst=dst_ip, ttl=ttl) /
Matus Fabian06596c52017-06-06 04:53:28 -0700218 UDP(sport=self.udp_port_in, dport=20))
Matus Fabiande886752016-12-07 03:38:19 -0800219 pkts.append(p)
220
221 # ICMP
222 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
Juraj Slobodacba69362017-12-19 02:09:32 +0100223 IP(src=in_if.remote_ip4, dst=dst_ip, ttl=ttl) /
Matus Fabiande886752016-12-07 03:38:19 -0800224 ICMP(id=self.icmp_id_in, type='echo-request'))
225 pkts.append(p)
226
227 return pkts
228
Matus Fabian428dc912017-06-21 06:15:18 -0700229 def compose_ip6(self, ip4, pref, plen):
230 """
231 Compose IPv4-embedded IPv6 addresses
232
233 :param ip4: IPv4 address
234 :param pref: IPv6 prefix
235 :param plen: IPv6 prefix length
236 :returns: IPv4-embedded IPv6 addresses
237 """
238 pref_n = list(socket.inet_pton(socket.AF_INET6, pref))
239 ip4_n = list(socket.inet_pton(socket.AF_INET, ip4))
240 if plen == 32:
241 pref_n[4] = ip4_n[0]
242 pref_n[5] = ip4_n[1]
243 pref_n[6] = ip4_n[2]
244 pref_n[7] = ip4_n[3]
245 elif plen == 40:
246 pref_n[5] = ip4_n[0]
247 pref_n[6] = ip4_n[1]
248 pref_n[7] = ip4_n[2]
249 pref_n[9] = ip4_n[3]
250 elif plen == 48:
251 pref_n[6] = ip4_n[0]
252 pref_n[7] = ip4_n[1]
253 pref_n[9] = ip4_n[2]
254 pref_n[10] = ip4_n[3]
255 elif plen == 56:
256 pref_n[7] = ip4_n[0]
257 pref_n[9] = ip4_n[1]
258 pref_n[10] = ip4_n[2]
259 pref_n[11] = ip4_n[3]
260 elif plen == 64:
261 pref_n[9] = ip4_n[0]
262 pref_n[10] = ip4_n[1]
263 pref_n[11] = ip4_n[2]
264 pref_n[12] = ip4_n[3]
265 elif plen == 96:
266 pref_n[12] = ip4_n[0]
267 pref_n[13] = ip4_n[1]
268 pref_n[14] = ip4_n[2]
269 pref_n[15] = ip4_n[3]
270 return socket.inet_ntop(socket.AF_INET6, ''.join(pref_n))
271
Juraj Slobodacba69362017-12-19 02:09:32 +0100272 def extract_ip4(self, ip6, plen):
273 """
274 Extract IPv4 address embedded in IPv6 addresses
275
276 :param ip6: IPv6 address
277 :param plen: IPv6 prefix length
278 :returns: extracted IPv4 address
279 """
280 ip6_n = list(socket.inet_pton(socket.AF_INET6, ip6))
281 ip4_n = [None] * 4
282 if plen == 32:
283 ip4_n[0] = ip6_n[4]
284 ip4_n[1] = ip6_n[5]
285 ip4_n[2] = ip6_n[6]
286 ip4_n[3] = ip6_n[7]
287 elif plen == 40:
288 ip4_n[0] = ip6_n[5]
289 ip4_n[1] = ip6_n[6]
290 ip4_n[2] = ip6_n[7]
291 ip4_n[3] = ip6_n[9]
292 elif plen == 48:
293 ip4_n[0] = ip6_n[6]
294 ip4_n[1] = ip6_n[7]
295 ip4_n[2] = ip6_n[9]
296 ip4_n[3] = ip6_n[10]
297 elif plen == 56:
298 ip4_n[0] = ip6_n[7]
299 ip4_n[1] = ip6_n[9]
300 ip4_n[2] = ip6_n[10]
301 ip4_n[3] = ip6_n[11]
302 elif plen == 64:
303 ip4_n[0] = ip6_n[9]
304 ip4_n[1] = ip6_n[10]
305 ip4_n[2] = ip6_n[11]
306 ip4_n[3] = ip6_n[12]
307 elif plen == 96:
308 ip4_n[0] = ip6_n[12]
309 ip4_n[1] = ip6_n[13]
310 ip4_n[2] = ip6_n[14]
311 ip4_n[3] = ip6_n[15]
312 return socket.inet_ntop(socket.AF_INET, ''.join(ip4_n))
313
Matus Fabian428dc912017-06-21 06:15:18 -0700314 def create_stream_in_ip6(self, in_if, out_if, hlim=64, pref=None, plen=0):
Matus Fabian06596c52017-06-06 04:53:28 -0700315 """
316 Create IPv6 packet stream for inside network
317
318 :param in_if: Inside interface
319 :param out_if: Outside interface
320 :param ttl: Hop Limit of generated packets
Matus Fabian428dc912017-06-21 06:15:18 -0700321 :param pref: NAT64 prefix
322 :param plen: NAT64 prefix length
Matus Fabian06596c52017-06-06 04:53:28 -0700323 """
324 pkts = []
Matus Fabian428dc912017-06-21 06:15:18 -0700325 if pref is None:
326 dst = ''.join(['64:ff9b::', out_if.remote_ip4])
327 else:
328 dst = self.compose_ip6(out_if.remote_ip4, pref, plen)
329
Matus Fabian06596c52017-06-06 04:53:28 -0700330 # TCP
331 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
332 IPv6(src=in_if.remote_ip6, dst=dst, hlim=hlim) /
333 TCP(sport=self.tcp_port_in, dport=20))
334 pkts.append(p)
335
336 # UDP
337 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
338 IPv6(src=in_if.remote_ip6, dst=dst, hlim=hlim) /
339 UDP(sport=self.udp_port_in, dport=20))
340 pkts.append(p)
341
342 # ICMP
343 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
344 IPv6(src=in_if.remote_ip6, dst=dst, hlim=hlim) /
345 ICMPv6EchoRequest(id=self.icmp_id_in))
346 pkts.append(p)
347
348 return pkts
349
Juraj Sloboda7b929792017-11-23 13:20:48 +0100350 def create_stream_out(self, out_if, dst_ip=None, ttl=64,
351 use_inside_ports=False):
Matus Fabiande886752016-12-07 03:38:19 -0800352 """
353 Create packet stream for outside network
354
355 :param out_if: Outside interface
Matus Fabian2ba92e32017-08-21 07:05:03 -0700356 :param dst_ip: Destination IP address (Default use global NAT address)
Juraj Slobodab33f4132017-02-08 23:54:21 -0800357 :param ttl: TTL of generated packets
Juraj Sloboda7b929792017-11-23 13:20:48 +0100358 :param use_inside_ports: Use inside NAT ports as destination ports
359 instead of outside ports
Matus Fabiande886752016-12-07 03:38:19 -0800360 """
361 if dst_ip is None:
Matus Fabian2ba92e32017-08-21 07:05:03 -0700362 dst_ip = self.nat_addr
Juraj Sloboda7b929792017-11-23 13:20:48 +0100363 if not use_inside_ports:
364 tcp_port = self.tcp_port_out
365 udp_port = self.udp_port_out
366 icmp_id = self.icmp_id_out
367 else:
368 tcp_port = self.tcp_port_in
369 udp_port = self.udp_port_in
370 icmp_id = self.icmp_id_in
Matus Fabiande886752016-12-07 03:38:19 -0800371 pkts = []
372 # TCP
373 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
Juraj Slobodab33f4132017-02-08 23:54:21 -0800374 IP(src=out_if.remote_ip4, dst=dst_ip, ttl=ttl) /
Juraj Sloboda7b929792017-11-23 13:20:48 +0100375 TCP(dport=tcp_port, sport=20))
Matus Fabiande886752016-12-07 03:38:19 -0800376 pkts.append(p)
377
378 # UDP
379 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
Juraj Slobodab33f4132017-02-08 23:54:21 -0800380 IP(src=out_if.remote_ip4, dst=dst_ip, ttl=ttl) /
Juraj Sloboda7b929792017-11-23 13:20:48 +0100381 UDP(dport=udp_port, sport=20))
Matus Fabiande886752016-12-07 03:38:19 -0800382 pkts.append(p)
383
384 # ICMP
385 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
Juraj Slobodab33f4132017-02-08 23:54:21 -0800386 IP(src=out_if.remote_ip4, dst=dst_ip, ttl=ttl) /
Juraj Sloboda7b929792017-11-23 13:20:48 +0100387 ICMP(id=icmp_id, type='echo-reply'))
Matus Fabiande886752016-12-07 03:38:19 -0800388 pkts.append(p)
389
390 return pkts
391
Juraj Slobodacba69362017-12-19 02:09:32 +0100392 def create_stream_out_ip6(self, out_if, src_ip, dst_ip, hl=64):
393 """
394 Create packet stream for outside network
395
396 :param out_if: Outside interface
397 :param dst_ip: Destination IP address (Default use global NAT address)
398 :param hl: HL of generated packets
399 """
400 pkts = []
401 # TCP
402 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
403 IPv6(src=src_ip, dst=dst_ip, hlim=hl) /
404 TCP(dport=self.tcp_port_out, sport=20))
405 pkts.append(p)
406
407 # UDP
408 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
409 IPv6(src=src_ip, dst=dst_ip, hlim=hl) /
410 UDP(dport=self.udp_port_out, sport=20))
411 pkts.append(p)
412
413 # ICMP
414 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
415 IPv6(src=src_ip, dst=dst_ip, hlim=hl) /
416 ICMPv6EchoReply(id=self.icmp_id_out))
417 pkts.append(p)
418
419 return pkts
420
Matus Fabiande886752016-12-07 03:38:19 -0800421 def verify_capture_out(self, capture, nat_ip=None, same_port=False,
Juraj Slobodacba69362017-12-19 02:09:32 +0100422 packet_num=3, dst_ip=None, is_ip6=False):
Matus Fabiande886752016-12-07 03:38:19 -0800423 """
424 Verify captured packets on outside network
425
426 :param capture: Captured packets
Matus Fabian2ba92e32017-08-21 07:05:03 -0700427 :param nat_ip: Translated IP address (Default use global NAT address)
Matus Fabiande886752016-12-07 03:38:19 -0800428 :param same_port: Sorce port number is not translated (Default False)
429 :param packet_num: Expected number of packets (Default 3)
Matus Fabian06596c52017-06-06 04:53:28 -0700430 :param dst_ip: Destination IP address (Default do not verify)
Juraj Slobodacba69362017-12-19 02:09:32 +0100431 :param is_ip6: If L3 protocol is IPv6 (Default False)
Matus Fabiande886752016-12-07 03:38:19 -0800432 """
Juraj Slobodacba69362017-12-19 02:09:32 +0100433 if is_ip6:
434 IP46 = IPv6
435 ICMP46 = ICMPv6EchoRequest
436 else:
437 IP46 = IP
438 ICMP46 = ICMP
Matus Fabiande886752016-12-07 03:38:19 -0800439 if nat_ip is None:
Matus Fabian2ba92e32017-08-21 07:05:03 -0700440 nat_ip = self.nat_addr
Matus Fabiande886752016-12-07 03:38:19 -0800441 self.assertEqual(packet_num, len(capture))
442 for packet in capture:
443 try:
Juraj Slobodacba69362017-12-19 02:09:32 +0100444 if not is_ip6:
Klement Sekerad81ae412018-05-16 10:52:54 +0200445 self.assert_packet_checksums_valid(packet)
Juraj Slobodacba69362017-12-19 02:09:32 +0100446 self.assertEqual(packet[IP46].src, nat_ip)
Matus Fabian06596c52017-06-06 04:53:28 -0700447 if dst_ip is not None:
Juraj Slobodacba69362017-12-19 02:09:32 +0100448 self.assertEqual(packet[IP46].dst, dst_ip)
Matus Fabiande886752016-12-07 03:38:19 -0800449 if packet.haslayer(TCP):
450 if same_port:
451 self.assertEqual(packet[TCP].sport, self.tcp_port_in)
452 else:
Klement Sekerada505f62017-01-04 12:58:53 +0100453 self.assertNotEqual(
454 packet[TCP].sport, self.tcp_port_in)
Matus Fabiande886752016-12-07 03:38:19 -0800455 self.tcp_port_out = packet[TCP].sport
Klement Sekerad81ae412018-05-16 10:52:54 +0200456 self.assert_packet_checksums_valid(packet)
Matus Fabiande886752016-12-07 03:38:19 -0800457 elif packet.haslayer(UDP):
458 if same_port:
459 self.assertEqual(packet[UDP].sport, self.udp_port_in)
460 else:
Klement Sekerada505f62017-01-04 12:58:53 +0100461 self.assertNotEqual(
462 packet[UDP].sport, self.udp_port_in)
Matus Fabiande886752016-12-07 03:38:19 -0800463 self.udp_port_out = packet[UDP].sport
464 else:
465 if same_port:
Juraj Slobodacba69362017-12-19 02:09:32 +0100466 self.assertEqual(packet[ICMP46].id, self.icmp_id_in)
Matus Fabiande886752016-12-07 03:38:19 -0800467 else:
Juraj Slobodacba69362017-12-19 02:09:32 +0100468 self.assertNotEqual(packet[ICMP46].id, self.icmp_id_in)
469 self.icmp_id_out = packet[ICMP46].id
Klement Sekerad81ae412018-05-16 10:52:54 +0200470 self.assert_packet_checksums_valid(packet)
Matus Fabiande886752016-12-07 03:38:19 -0800471 except:
Klement Sekera9225dee2016-12-12 08:36:58 +0100472 self.logger.error(ppp("Unexpected or invalid packet "
473 "(outside network):", packet))
Matus Fabiande886752016-12-07 03:38:19 -0800474 raise
475
Juraj Slobodacba69362017-12-19 02:09:32 +0100476 def verify_capture_out_ip6(self, capture, nat_ip, same_port=False,
477 packet_num=3, dst_ip=None):
478 """
479 Verify captured packets on outside network
480
481 :param capture: Captured packets
482 :param nat_ip: Translated IP address
483 :param same_port: Sorce port number is not translated (Default False)
484 :param packet_num: Expected number of packets (Default 3)
485 :param dst_ip: Destination IP address (Default do not verify)
486 """
487 return self.verify_capture_out(capture, nat_ip, same_port, packet_num,
488 dst_ip, True)
489
Matus Fabiande886752016-12-07 03:38:19 -0800490 def verify_capture_in(self, capture, in_if, packet_num=3):
491 """
492 Verify captured packets on inside network
493
494 :param capture: Captured packets
495 :param in_if: Inside interface
496 :param packet_num: Expected number of packets (Default 3)
497 """
498 self.assertEqual(packet_num, len(capture))
499 for packet in capture:
500 try:
Klement Sekerad81ae412018-05-16 10:52:54 +0200501 self.assert_packet_checksums_valid(packet)
Matus Fabiande886752016-12-07 03:38:19 -0800502 self.assertEqual(packet[IP].dst, in_if.remote_ip4)
503 if packet.haslayer(TCP):
504 self.assertEqual(packet[TCP].dport, self.tcp_port_in)
505 elif packet.haslayer(UDP):
506 self.assertEqual(packet[UDP].dport, self.udp_port_in)
507 else:
508 self.assertEqual(packet[ICMP].id, self.icmp_id_in)
509 except:
Klement Sekera9225dee2016-12-12 08:36:58 +0100510 self.logger.error(ppp("Unexpected or invalid packet "
511 "(inside network):", packet))
Matus Fabiande886752016-12-07 03:38:19 -0800512 raise
513
Matus Fabian06596c52017-06-06 04:53:28 -0700514 def verify_capture_in_ip6(self, capture, src_ip, dst_ip, packet_num=3):
515 """
516 Verify captured IPv6 packets on inside network
517
518 :param capture: Captured packets
519 :param src_ip: Source IP
520 :param dst_ip: Destination IP address
521 :param packet_num: Expected number of packets (Default 3)
522 """
523 self.assertEqual(packet_num, len(capture))
524 for packet in capture:
525 try:
526 self.assertEqual(packet[IPv6].src, src_ip)
527 self.assertEqual(packet[IPv6].dst, dst_ip)
Klement Sekerad81ae412018-05-16 10:52:54 +0200528 self.assert_packet_checksums_valid(packet)
Matus Fabian06596c52017-06-06 04:53:28 -0700529 if packet.haslayer(TCP):
530 self.assertEqual(packet[TCP].dport, self.tcp_port_in)
531 elif packet.haslayer(UDP):
532 self.assertEqual(packet[UDP].dport, self.udp_port_in)
533 else:
534 self.assertEqual(packet[ICMPv6EchoReply].id,
535 self.icmp_id_in)
536 except:
537 self.logger.error(ppp("Unexpected or invalid packet "
538 "(inside network):", packet))
539 raise
540
Matus Fabian675a69c2017-01-18 01:46:01 -0800541 def verify_capture_no_translation(self, capture, ingress_if, egress_if):
542 """
543 Verify captured packet that don't have to be translated
544
545 :param capture: Captured packets
546 :param ingress_if: Ingress interface
547 :param egress_if: Egress interface
548 """
549 for packet in capture:
550 try:
551 self.assertEqual(packet[IP].src, ingress_if.remote_ip4)
552 self.assertEqual(packet[IP].dst, egress_if.remote_ip4)
553 if packet.haslayer(TCP):
554 self.assertEqual(packet[TCP].sport, self.tcp_port_in)
555 elif packet.haslayer(UDP):
556 self.assertEqual(packet[UDP].sport, self.udp_port_in)
557 else:
558 self.assertEqual(packet[ICMP].id, self.icmp_id_in)
559 except:
560 self.logger.error(ppp("Unexpected or invalid packet "
561 "(inside network):", packet))
562 raise
563
Juraj Slobodab33f4132017-02-08 23:54:21 -0800564 def verify_capture_out_with_icmp_errors(self, capture, src_ip=None,
565 packet_num=3, icmp_type=11):
566 """
567 Verify captured packets with ICMP errors on outside network
568
569 :param capture: Captured packets
570 :param src_ip: Translated IP address or IP address of VPP
Matus Fabian2ba92e32017-08-21 07:05:03 -0700571 (Default use global NAT address)
Juraj Slobodab33f4132017-02-08 23:54:21 -0800572 :param packet_num: Expected number of packets (Default 3)
573 :param icmp_type: Type of error ICMP packet
574 we are expecting (Default 11)
575 """
576 if src_ip is None:
Matus Fabian2ba92e32017-08-21 07:05:03 -0700577 src_ip = self.nat_addr
Juraj Slobodab33f4132017-02-08 23:54:21 -0800578 self.assertEqual(packet_num, len(capture))
579 for packet in capture:
580 try:
581 self.assertEqual(packet[IP].src, src_ip)
582 self.assertTrue(packet.haslayer(ICMP))
583 icmp = packet[ICMP]
584 self.assertEqual(icmp.type, icmp_type)
585 self.assertTrue(icmp.haslayer(IPerror))
586 inner_ip = icmp[IPerror]
587 if inner_ip.haslayer(TCPerror):
588 self.assertEqual(inner_ip[TCPerror].dport,
589 self.tcp_port_out)
590 elif inner_ip.haslayer(UDPerror):
591 self.assertEqual(inner_ip[UDPerror].dport,
592 self.udp_port_out)
593 else:
594 self.assertEqual(inner_ip[ICMPerror].id, self.icmp_id_out)
595 except:
596 self.logger.error(ppp("Unexpected or invalid packet "
597 "(outside network):", packet))
598 raise
599
600 def verify_capture_in_with_icmp_errors(self, capture, in_if, packet_num=3,
601 icmp_type=11):
602 """
603 Verify captured packets with ICMP errors on inside network
604
605 :param capture: Captured packets
606 :param in_if: Inside interface
607 :param packet_num: Expected number of packets (Default 3)
608 :param icmp_type: Type of error ICMP packet
609 we are expecting (Default 11)
610 """
611 self.assertEqual(packet_num, len(capture))
612 for packet in capture:
613 try:
614 self.assertEqual(packet[IP].dst, in_if.remote_ip4)
615 self.assertTrue(packet.haslayer(ICMP))
616 icmp = packet[ICMP]
617 self.assertEqual(icmp.type, icmp_type)
618 self.assertTrue(icmp.haslayer(IPerror))
619 inner_ip = icmp[IPerror]
620 if inner_ip.haslayer(TCPerror):
621 self.assertEqual(inner_ip[TCPerror].sport,
622 self.tcp_port_in)
623 elif inner_ip.haslayer(UDPerror):
624 self.assertEqual(inner_ip[UDPerror].sport,
625 self.udp_port_in)
626 else:
627 self.assertEqual(inner_ip[ICMPerror].id, self.icmp_id_in)
628 except:
629 self.logger.error(ppp("Unexpected or invalid packet "
630 "(inside network):", packet))
631 raise
632
Matus Fabianefcd1e92017-08-15 06:59:19 -0700633 def create_stream_frag(self, src_if, dst, sport, dport, data):
634 """
635 Create fragmented packet stream
636
637 :param src_if: Source interface
638 :param dst: Destination IPv4 address
639 :param sport: Source TCP port
640 :param dport: Destination TCP port
641 :param data: Payload data
642 :returns: Fragmets
643 """
644 id = random.randint(0, 65535)
645 p = (IP(src=src_if.remote_ip4, dst=dst) /
646 TCP(sport=sport, dport=dport) /
647 Raw(data))
648 p = p.__class__(str(p))
649 chksum = p['TCP'].chksum
650 pkts = []
651 p = (Ether(src=src_if.remote_mac, dst=src_if.local_mac) /
652 IP(src=src_if.remote_ip4, dst=dst, flags="MF", frag=0, id=id) /
653 TCP(sport=sport, dport=dport, chksum=chksum) /
654 Raw(data[0:4]))
655 pkts.append(p)
656 p = (Ether(src=src_if.remote_mac, dst=src_if.local_mac) /
657 IP(src=src_if.remote_ip4, dst=dst, flags="MF", frag=3, id=id,
658 proto=IP_PROTOS.tcp) /
659 Raw(data[4:20]))
660 pkts.append(p)
661 p = (Ether(src=src_if.remote_mac, dst=src_if.local_mac) /
662 IP(src=src_if.remote_ip4, dst=dst, frag=5, proto=IP_PROTOS.tcp,
663 id=id) /
664 Raw(data[20:]))
665 pkts.append(p)
666 return pkts
667
668 def create_stream_frag_ip6(self, src_if, dst, sport, dport, data,
669 pref=None, plen=0, frag_size=128):
670 """
671 Create fragmented packet stream
672
673 :param src_if: Source interface
674 :param dst: Destination IPv4 address
675 :param sport: Source TCP port
676 :param dport: Destination TCP port
677 :param data: Payload data
678 :param pref: NAT64 prefix
679 :param plen: NAT64 prefix length
680 :param fragsize: size of fragments
681 :returns: Fragmets
682 """
683 if pref is None:
684 dst_ip6 = ''.join(['64:ff9b::', dst])
685 else:
686 dst_ip6 = self.compose_ip6(dst, pref, plen)
687
688 p = (Ether(dst=src_if.local_mac, src=src_if.remote_mac) /
689 IPv6(src=src_if.remote_ip6, dst=dst_ip6) /
690 IPv6ExtHdrFragment(id=random.randint(0, 65535)) /
691 TCP(sport=sport, dport=dport) /
692 Raw(data))
693
694 return fragment6(p, frag_size)
695
696 def reass_frags_and_verify(self, frags, src, dst):
697 """
698 Reassemble and verify fragmented packet
699
700 :param frags: Captured fragments
701 :param src: Source IPv4 address to verify
702 :param dst: Destination IPv4 address to verify
703
704 :returns: Reassembled IPv4 packet
705 """
706 buffer = StringIO.StringIO()
707 for p in frags:
708 self.assertEqual(p[IP].src, src)
709 self.assertEqual(p[IP].dst, dst)
Klement Sekerad81ae412018-05-16 10:52:54 +0200710 self.assert_ip_checksum_valid(p)
Matus Fabianefcd1e92017-08-15 06:59:19 -0700711 buffer.seek(p[IP].frag * 8)
712 buffer.write(p[IP].payload)
713 ip = frags[0].getlayer(IP)
714 ip = IP(src=frags[0][IP].src, dst=frags[0][IP].dst,
715 proto=frags[0][IP].proto)
716 if ip.proto == IP_PROTOS.tcp:
717 p = (ip / TCP(buffer.getvalue()))
Klement Sekerad81ae412018-05-16 10:52:54 +0200718 self.assert_tcp_checksum_valid(p)
Matus Fabianefcd1e92017-08-15 06:59:19 -0700719 elif ip.proto == IP_PROTOS.udp:
720 p = (ip / UDP(buffer.getvalue()))
721 return p
722
723 def reass_frags_and_verify_ip6(self, frags, src, dst):
724 """
725 Reassemble and verify fragmented packet
726
727 :param frags: Captured fragments
728 :param src: Source IPv6 address to verify
729 :param dst: Destination IPv6 address to verify
730
731 :returns: Reassembled IPv6 packet
732 """
733 buffer = StringIO.StringIO()
734 for p in frags:
735 self.assertEqual(p[IPv6].src, src)
736 self.assertEqual(p[IPv6].dst, dst)
737 buffer.seek(p[IPv6ExtHdrFragment].offset * 8)
738 buffer.write(p[IPv6ExtHdrFragment].payload)
739 ip = IPv6(src=frags[0][IPv6].src, dst=frags[0][IPv6].dst,
740 nh=frags[0][IPv6ExtHdrFragment].nh)
741 if ip.nh == IP_PROTOS.tcp:
742 p = (ip / TCP(buffer.getvalue()))
Matus Fabianefcd1e92017-08-15 06:59:19 -0700743 elif ip.nh == IP_PROTOS.udp:
744 p = (ip / UDP(buffer.getvalue()))
Klement Sekerad81ae412018-05-16 10:52:54 +0200745 self.assert_packet_checksums_valid(p)
Matus Fabianefcd1e92017-08-15 06:59:19 -0700746 return p
747
Matus Fabianebdf1902018-05-04 03:57:42 -0700748 def initiate_tcp_session(self, in_if, out_if):
749 """
750 Initiates TCP session
751
752 :param in_if: Inside interface
753 :param out_if: Outside interface
754 """
755 try:
756 # SYN packet in->out
757 p = (Ether(src=in_if.remote_mac, dst=in_if.local_mac) /
758 IP(src=in_if.remote_ip4, dst=out_if.remote_ip4) /
759 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
760 flags="S"))
761 in_if.add_stream(p)
762 self.pg_enable_capture(self.pg_interfaces)
763 self.pg_start()
764 capture = out_if.get_capture(1)
765 p = capture[0]
766 self.tcp_port_out = p[TCP].sport
767
768 # SYN + ACK packet out->in
769 p = (Ether(src=out_if.remote_mac, dst=out_if.local_mac) /
770 IP(src=out_if.remote_ip4, dst=self.nat_addr) /
771 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
772 flags="SA"))
773 out_if.add_stream(p)
774 self.pg_enable_capture(self.pg_interfaces)
775 self.pg_start()
776 in_if.get_capture(1)
777
778 # ACK packet in->out
779 p = (Ether(src=in_if.remote_mac, dst=in_if.local_mac) /
780 IP(src=in_if.remote_ip4, dst=out_if.remote_ip4) /
781 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
782 flags="A"))
783 in_if.add_stream(p)
784 self.pg_enable_capture(self.pg_interfaces)
785 self.pg_start()
786 out_if.get_capture(1)
787
788 except:
789 self.logger.error("TCP 3 way handshake failed")
790 raise
791
Matus Fabianeea28d72017-01-13 04:15:54 -0800792 def verify_ipfix_nat44_ses(self, data):
793 """
794 Verify IPFIX NAT44 session create/delete event
795
796 :param data: Decoded IPFIX data records
797 """
798 nat44_ses_create_num = 0
799 nat44_ses_delete_num = 0
800 self.assertEqual(6, len(data))
801 for record in data:
802 # natEvent
803 self.assertIn(ord(record[230]), [4, 5])
804 if ord(record[230]) == 4:
805 nat44_ses_create_num += 1
806 else:
807 nat44_ses_delete_num += 1
808 # sourceIPv4Address
809 self.assertEqual(self.pg0.remote_ip4n, record[8])
810 # postNATSourceIPv4Address
Matus Fabian2ba92e32017-08-21 07:05:03 -0700811 self.assertEqual(socket.inet_pton(socket.AF_INET, self.nat_addr),
Matus Fabianeea28d72017-01-13 04:15:54 -0800812 record[225])
813 # ingressVRFID
814 self.assertEqual(struct.pack("!I", 0), record[234])
815 # protocolIdentifier/sourceTransportPort/postNAPTSourceTransportPort
816 if IP_PROTOS.icmp == ord(record[4]):
817 self.assertEqual(struct.pack("!H", self.icmp_id_in), record[7])
818 self.assertEqual(struct.pack("!H", self.icmp_id_out),
819 record[227])
820 elif IP_PROTOS.tcp == ord(record[4]):
821 self.assertEqual(struct.pack("!H", self.tcp_port_in),
822 record[7])
823 self.assertEqual(struct.pack("!H", self.tcp_port_out),
824 record[227])
825 elif IP_PROTOS.udp == ord(record[4]):
826 self.assertEqual(struct.pack("!H", self.udp_port_in),
827 record[7])
828 self.assertEqual(struct.pack("!H", self.udp_port_out),
829 record[227])
830 else:
831 self.fail("Invalid protocol")
832 self.assertEqual(3, nat44_ses_create_num)
833 self.assertEqual(3, nat44_ses_delete_num)
834
835 def verify_ipfix_addr_exhausted(self, data):
836 """
837 Verify IPFIX NAT addresses event
838
839 :param data: Decoded IPFIX data records
840 """
841 self.assertEqual(1, len(data))
842 record = data[0]
843 # natEvent
844 self.assertEqual(ord(record[230]), 3)
845 # natPoolID
846 self.assertEqual(struct.pack("!I", 0), record[283])
847
Matus Fabiana431ad12018-01-04 04:03:14 -0800848 def verify_ipfix_max_sessions(self, data, limit):
849 """
850 Verify IPFIX maximum session entries exceeded event
851
852 :param data: Decoded IPFIX data records
853 :param limit: Number of maximum session entries that can be created.
854 """
855 self.assertEqual(1, len(data))
856 record = data[0]
857 # natEvent
858 self.assertEqual(ord(record[230]), 13)
859 # natQuotaExceededEvent
860 self.assertEqual(struct.pack("I", 1), record[466])
861 # maxSessionEntries
862 self.assertEqual(struct.pack("I", limit), record[471])
863
864 def verify_ipfix_max_bibs(self, data, limit):
865 """
866 Verify IPFIX maximum BIB entries exceeded event
867
868 :param data: Decoded IPFIX data records
869 :param limit: Number of maximum BIB entries that can be created.
870 """
871 self.assertEqual(1, len(data))
872 record = data[0]
873 # natEvent
874 self.assertEqual(ord(record[230]), 13)
875 # natQuotaExceededEvent
876 self.assertEqual(struct.pack("I", 2), record[466])
877 # maxBIBEntries
878 self.assertEqual(struct.pack("I", limit), record[472])
879
880 def verify_ipfix_max_fragments_ip6(self, data, limit, src_addr):
881 """
882 Verify IPFIX maximum IPv6 fragments pending reassembly exceeded event
883
884 :param data: Decoded IPFIX data records
885 :param limit: Number of maximum fragments pending reassembly
886 :param src_addr: IPv6 source address
887 """
888 self.assertEqual(1, len(data))
889 record = data[0]
890 # natEvent
891 self.assertEqual(ord(record[230]), 13)
892 # natQuotaExceededEvent
893 self.assertEqual(struct.pack("I", 5), record[466])
894 # maxFragmentsPendingReassembly
895 self.assertEqual(struct.pack("I", limit), record[475])
896 # sourceIPv6Address
897 self.assertEqual(src_addr, record[27])
898
899 def verify_ipfix_max_fragments_ip4(self, data, limit, src_addr):
900 """
901 Verify IPFIX maximum IPv4 fragments pending reassembly exceeded event
902
903 :param data: Decoded IPFIX data records
904 :param limit: Number of maximum fragments pending reassembly
905 :param src_addr: IPv4 source address
906 """
907 self.assertEqual(1, len(data))
908 record = data[0]
909 # natEvent
910 self.assertEqual(ord(record[230]), 13)
911 # natQuotaExceededEvent
912 self.assertEqual(struct.pack("I", 5), record[466])
913 # maxFragmentsPendingReassembly
914 self.assertEqual(struct.pack("I", limit), record[475])
915 # sourceIPv4Address
916 self.assertEqual(src_addr, record[8])
917
918 def verify_ipfix_bib(self, data, is_create, src_addr):
919 """
920 Verify IPFIX NAT64 BIB create and delete events
921
922 :param data: Decoded IPFIX data records
923 :param is_create: Create event if nonzero value otherwise delete event
924 :param src_addr: IPv6 source address
925 """
926 self.assertEqual(1, len(data))
927 record = data[0]
928 # natEvent
929 if is_create:
930 self.assertEqual(ord(record[230]), 10)
931 else:
932 self.assertEqual(ord(record[230]), 11)
933 # sourceIPv6Address
934 self.assertEqual(src_addr, record[27])
935 # postNATSourceIPv4Address
936 self.assertEqual(self.nat_addr_n, record[225])
937 # protocolIdentifier
938 self.assertEqual(IP_PROTOS.tcp, ord(record[4]))
939 # ingressVRFID
940 self.assertEqual(struct.pack("!I", 0), record[234])
941 # sourceTransportPort
942 self.assertEqual(struct.pack("!H", self.tcp_port_in), record[7])
943 # postNAPTSourceTransportPort
944 self.assertEqual(struct.pack("!H", self.tcp_port_out), record[227])
945
946 def verify_ipfix_nat64_ses(self, data, is_create, src_addr, dst_addr,
947 dst_port):
948 """
949 Verify IPFIX NAT64 session create and delete events
950
951 :param data: Decoded IPFIX data records
952 :param is_create: Create event if nonzero value otherwise delete event
953 :param src_addr: IPv6 source address
954 :param dst_addr: IPv4 destination address
955 :param dst_port: destination TCP port
956 """
957 self.assertEqual(1, len(data))
958 record = data[0]
959 # natEvent
960 if is_create:
961 self.assertEqual(ord(record[230]), 6)
962 else:
963 self.assertEqual(ord(record[230]), 7)
964 # sourceIPv6Address
965 self.assertEqual(src_addr, record[27])
966 # destinationIPv6Address
967 self.assertEqual(socket.inet_pton(socket.AF_INET6,
968 self.compose_ip6(dst_addr,
969 '64:ff9b::',
970 96)),
971 record[28])
972 # postNATSourceIPv4Address
973 self.assertEqual(self.nat_addr_n, record[225])
974 # postNATDestinationIPv4Address
975 self.assertEqual(socket.inet_pton(socket.AF_INET, dst_addr),
976 record[226])
977 # protocolIdentifier
978 self.assertEqual(IP_PROTOS.tcp, ord(record[4]))
979 # ingressVRFID
980 self.assertEqual(struct.pack("!I", 0), record[234])
981 # sourceTransportPort
982 self.assertEqual(struct.pack("!H", self.tcp_port_in), record[7])
983 # postNAPTSourceTransportPort
984 self.assertEqual(struct.pack("!H", self.tcp_port_out), record[227])
985 # destinationTransportPort
986 self.assertEqual(struct.pack("!H", dst_port), record[11])
987 # postNAPTDestinationTransportPort
988 self.assertEqual(struct.pack("!H", dst_port), record[228])
989
Martin Gálikd7f75cd2017-03-27 06:02:47 -0700990
Matus Fabian2ba92e32017-08-21 07:05:03 -0700991class TestNAT44(MethodHolder):
992 """ NAT44 Test Cases """
Martin Gálikd7f75cd2017-03-27 06:02:47 -0700993
994 @classmethod
995 def setUpClass(cls):
Matus Fabian2ba92e32017-08-21 07:05:03 -0700996 super(TestNAT44, cls).setUpClass()
Matus Fabian229c1aa2018-05-28 04:09:52 -0700997 cls.vapi.cli("set log class nat level debug")
Martin Gálikd7f75cd2017-03-27 06:02:47 -0700998
999 try:
1000 cls.tcp_port_in = 6303
1001 cls.tcp_port_out = 6303
1002 cls.udp_port_in = 6304
1003 cls.udp_port_out = 6304
1004 cls.icmp_id_in = 6305
1005 cls.icmp_id_out = 6305
Matus Fabian2ba92e32017-08-21 07:05:03 -07001006 cls.nat_addr = '10.0.0.3'
Juraj Sloboda7b929792017-11-23 13:20:48 +01001007 cls.nat_addr_n = socket.inet_pton(socket.AF_INET, cls.nat_addr)
Matus Fabian6631e9c2017-05-24 01:52:20 -07001008 cls.ipfix_src_port = 4739
1009 cls.ipfix_domain_id = 1
Matus Fabianebdf1902018-05-04 03:57:42 -07001010 cls.tcp_external_port = 80
Martin Gálikd7f75cd2017-03-27 06:02:47 -07001011
Matus Fabian36ea2d62017-10-24 04:13:49 -07001012 cls.create_pg_interfaces(range(10))
Martin Gálikd7f75cd2017-03-27 06:02:47 -07001013 cls.interfaces = list(cls.pg_interfaces[0:4])
1014
1015 for i in cls.interfaces:
1016 i.admin_up()
1017 i.config_ip4()
1018 i.resolve_arp()
1019
Matus Fabian6fa74c62017-06-05 05:55:48 -07001020 cls.pg0.generate_remote_hosts(3)
Martin Gálikd7f75cd2017-03-27 06:02:47 -07001021 cls.pg0.configure_ipv4_neighbors()
1022
Juraj Sloboda1e5c07d2018-04-10 13:51:54 +02001023 cls.pg1.generate_remote_hosts(1)
1024 cls.pg1.configure_ipv4_neighbors()
1025
Martin Gálikd7f75cd2017-03-27 06:02:47 -07001026 cls.overlapping_interfaces = list(list(cls.pg_interfaces[4:7]))
Neale Ranns15002542017-09-10 04:39:11 -07001027 cls.vapi.ip_table_add_del(10, is_add=1)
1028 cls.vapi.ip_table_add_del(20, is_add=1)
Martin Gálikd7f75cd2017-03-27 06:02:47 -07001029
1030 cls.pg4._local_ip4 = "172.16.255.1"
1031 cls.pg4._local_ip4n = socket.inet_pton(socket.AF_INET, i.local_ip4)
1032 cls.pg4._remote_hosts[0]._ip4 = "172.16.255.2"
1033 cls.pg4.set_table_ip4(10)
Matus Fabian69126282017-08-14 23:39:58 -07001034 cls.pg5._local_ip4 = "172.17.255.3"
Martin Gálikd7f75cd2017-03-27 06:02:47 -07001035 cls.pg5._local_ip4n = socket.inet_pton(socket.AF_INET, i.local_ip4)
Matus Fabian69126282017-08-14 23:39:58 -07001036 cls.pg5._remote_hosts[0]._ip4 = "172.17.255.4"
Martin Gálikd7f75cd2017-03-27 06:02:47 -07001037 cls.pg5.set_table_ip4(10)
1038 cls.pg6._local_ip4 = "172.16.255.1"
1039 cls.pg6._local_ip4n = socket.inet_pton(socket.AF_INET, i.local_ip4)
1040 cls.pg6._remote_hosts[0]._ip4 = "172.16.255.2"
1041 cls.pg6.set_table_ip4(20)
1042 for i in cls.overlapping_interfaces:
1043 i.config_ip4()
1044 i.admin_up()
1045 i.resolve_arp()
1046
1047 cls.pg7.admin_up()
Martin Gálik406eb1d2017-05-04 04:35:04 -07001048 cls.pg8.admin_up()
Martin Gálikd7f75cd2017-03-27 06:02:47 -07001049
Matus Fabian36ea2d62017-10-24 04:13:49 -07001050 cls.pg9.generate_remote_hosts(2)
1051 cls.pg9.config_ip4()
1052 ip_addr_n = socket.inet_pton(socket.AF_INET, "10.0.0.1")
1053 cls.vapi.sw_interface_add_del_address(cls.pg9.sw_if_index,
1054 ip_addr_n,
1055 24)
1056 cls.pg9.admin_up()
1057 cls.pg9.resolve_arp()
1058 cls.pg9._remote_hosts[1]._ip4 = cls.pg9._remote_hosts[0]._ip4
1059 cls.pg4._remote_ip4 = cls.pg9._remote_hosts[0]._ip4 = "10.0.0.2"
1060 cls.pg9.resolve_arp()
1061
Martin Gálikd7f75cd2017-03-27 06:02:47 -07001062 except Exception:
Matus Fabian2ba92e32017-08-21 07:05:03 -07001063 super(TestNAT44, cls).tearDownClass()
Martin Gálikd7f75cd2017-03-27 06:02:47 -07001064 raise
1065
Matus Fabiande886752016-12-07 03:38:19 -08001066 def test_dynamic(self):
Matus Fabian2ba92e32017-08-21 07:05:03 -07001067 """ NAT44 dynamic translation test """
Matus Fabiande886752016-12-07 03:38:19 -08001068
Matus Fabian2ba92e32017-08-21 07:05:03 -07001069 self.nat44_add_address(self.nat_addr)
1070 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
1071 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
1072 is_inside=0)
Matus Fabiande886752016-12-07 03:38:19 -08001073
1074 # in2out
1075 pkts = self.create_stream_in(self.pg0, self.pg1)
1076 self.pg0.add_stream(pkts)
1077 self.pg_enable_capture(self.pg_interfaces)
1078 self.pg_start()
Klement Sekeradab231a2016-12-21 08:50:14 +01001079 capture = self.pg1.get_capture(len(pkts))
Matus Fabiande886752016-12-07 03:38:19 -08001080 self.verify_capture_out(capture)
1081
1082 # out2in
1083 pkts = self.create_stream_out(self.pg1)
1084 self.pg1.add_stream(pkts)
1085 self.pg_enable_capture(self.pg_interfaces)
1086 self.pg_start()
Klement Sekeradab231a2016-12-21 08:50:14 +01001087 capture = self.pg0.get_capture(len(pkts))
Matus Fabiande886752016-12-07 03:38:19 -08001088 self.verify_capture_in(capture, self.pg0)
1089
Juraj Slobodab33f4132017-02-08 23:54:21 -08001090 def test_dynamic_icmp_errors_in2out_ttl_1(self):
Matus Fabian2ba92e32017-08-21 07:05:03 -07001091 """ NAT44 handling of client packets with TTL=1 """
Juraj Slobodab33f4132017-02-08 23:54:21 -08001092
Matus Fabian2ba92e32017-08-21 07:05:03 -07001093 self.nat44_add_address(self.nat_addr)
1094 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
1095 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
1096 is_inside=0)
Juraj Slobodab33f4132017-02-08 23:54:21 -08001097
1098 # Client side - generate traffic
1099 pkts = self.create_stream_in(self.pg0, self.pg1, ttl=1)
1100 self.pg0.add_stream(pkts)
1101 self.pg_enable_capture(self.pg_interfaces)
1102 self.pg_start()
1103
1104 # Client side - verify ICMP type 11 packets
1105 capture = self.pg0.get_capture(len(pkts))
1106 self.verify_capture_in_with_icmp_errors(capture, self.pg0)
1107
1108 def test_dynamic_icmp_errors_out2in_ttl_1(self):
Matus Fabian2ba92e32017-08-21 07:05:03 -07001109 """ NAT44 handling of server packets with TTL=1 """
Juraj Slobodab33f4132017-02-08 23:54:21 -08001110
Matus Fabian2ba92e32017-08-21 07:05:03 -07001111 self.nat44_add_address(self.nat_addr)
1112 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
1113 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
1114 is_inside=0)
Juraj Slobodab33f4132017-02-08 23:54:21 -08001115
1116 # Client side - create sessions
1117 pkts = self.create_stream_in(self.pg0, self.pg1)
1118 self.pg0.add_stream(pkts)
1119 self.pg_enable_capture(self.pg_interfaces)
1120 self.pg_start()
1121
1122 # Server side - generate traffic
1123 capture = self.pg1.get_capture(len(pkts))
1124 self.verify_capture_out(capture)
1125 pkts = self.create_stream_out(self.pg1, ttl=1)
1126 self.pg1.add_stream(pkts)
1127 self.pg_enable_capture(self.pg_interfaces)
1128 self.pg_start()
1129
1130 # Server side - verify ICMP type 11 packets
1131 capture = self.pg1.get_capture(len(pkts))
1132 self.verify_capture_out_with_icmp_errors(capture,
1133 src_ip=self.pg1.local_ip4)
1134
1135 def test_dynamic_icmp_errors_in2out_ttl_2(self):
Matus Fabian2ba92e32017-08-21 07:05:03 -07001136 """ NAT44 handling of error responses to client packets with TTL=2 """
Juraj Slobodab33f4132017-02-08 23:54:21 -08001137
Matus Fabian2ba92e32017-08-21 07:05:03 -07001138 self.nat44_add_address(self.nat_addr)
1139 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
1140 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
1141 is_inside=0)
Juraj Slobodab33f4132017-02-08 23:54:21 -08001142
1143 # Client side - generate traffic
1144 pkts = self.create_stream_in(self.pg0, self.pg1, ttl=2)
1145 self.pg0.add_stream(pkts)
1146 self.pg_enable_capture(self.pg_interfaces)
1147 self.pg_start()
1148
1149 # Server side - simulate ICMP type 11 response
1150 capture = self.pg1.get_capture(len(pkts))
1151 pkts = [Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
Matus Fabian2ba92e32017-08-21 07:05:03 -07001152 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
Juraj Slobodab33f4132017-02-08 23:54:21 -08001153 ICMP(type=11) / packet[IP] for packet in capture]
1154 self.pg1.add_stream(pkts)
1155 self.pg_enable_capture(self.pg_interfaces)
1156 self.pg_start()
1157
1158 # Client side - verify ICMP type 11 packets
1159 capture = self.pg0.get_capture(len(pkts))
1160 self.verify_capture_in_with_icmp_errors(capture, self.pg0)
1161
1162 def test_dynamic_icmp_errors_out2in_ttl_2(self):
Matus Fabian2ba92e32017-08-21 07:05:03 -07001163 """ NAT44 handling of error responses to server packets with TTL=2 """
Juraj Slobodab33f4132017-02-08 23:54:21 -08001164
Matus Fabian2ba92e32017-08-21 07:05:03 -07001165 self.nat44_add_address(self.nat_addr)
1166 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
1167 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
1168 is_inside=0)
Juraj Slobodab33f4132017-02-08 23:54:21 -08001169
1170 # Client side - create sessions
1171 pkts = self.create_stream_in(self.pg0, self.pg1)
1172 self.pg0.add_stream(pkts)
1173 self.pg_enable_capture(self.pg_interfaces)
1174 self.pg_start()
1175
1176 # Server side - generate traffic
1177 capture = self.pg1.get_capture(len(pkts))
1178 self.verify_capture_out(capture)
1179 pkts = self.create_stream_out(self.pg1, ttl=2)
1180 self.pg1.add_stream(pkts)
1181 self.pg_enable_capture(self.pg_interfaces)
1182 self.pg_start()
1183
1184 # Client side - simulate ICMP type 11 response
1185 capture = self.pg0.get_capture(len(pkts))
1186 pkts = [Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
1187 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
1188 ICMP(type=11) / packet[IP] for packet in capture]
1189 self.pg0.add_stream(pkts)
1190 self.pg_enable_capture(self.pg_interfaces)
1191 self.pg_start()
1192
1193 # Server side - verify ICMP type 11 packets
1194 capture = self.pg1.get_capture(len(pkts))
1195 self.verify_capture_out_with_icmp_errors(capture)
1196
Juraj Sloboda665e4822017-02-16 17:17:19 -08001197 def test_ping_out_interface_from_outside(self):
Matus Fabian2ba92e32017-08-21 07:05:03 -07001198 """ Ping NAT44 out interface from outside network """
Juraj Sloboda665e4822017-02-16 17:17:19 -08001199
Matus Fabian2ba92e32017-08-21 07:05:03 -07001200 self.nat44_add_address(self.nat_addr)
1201 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
1202 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
1203 is_inside=0)
Juraj Sloboda665e4822017-02-16 17:17:19 -08001204
1205 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
1206 IP(src=self.pg1.remote_ip4, dst=self.pg1.local_ip4) /
1207 ICMP(id=self.icmp_id_out, type='echo-request'))
1208 pkts = [p]
1209 self.pg1.add_stream(pkts)
1210 self.pg_enable_capture(self.pg_interfaces)
1211 self.pg_start()
1212 capture = self.pg1.get_capture(len(pkts))
1213 self.assertEqual(1, len(capture))
1214 packet = capture[0]
1215 try:
1216 self.assertEqual(packet[IP].src, self.pg1.local_ip4)
1217 self.assertEqual(packet[IP].dst, self.pg1.remote_ip4)
1218 self.assertEqual(packet[ICMP].id, self.icmp_id_in)
1219 self.assertEqual(packet[ICMP].type, 0) # echo reply
1220 except:
1221 self.logger.error(ppp("Unexpected or invalid packet "
1222 "(outside network):", packet))
1223 raise
1224
Juraj Slobodad3677682017-04-14 03:24:45 +02001225 def test_ping_internal_host_from_outside(self):
1226 """ Ping internal host from outside network """
1227
Matus Fabian2ba92e32017-08-21 07:05:03 -07001228 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr)
1229 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
1230 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
1231 is_inside=0)
Juraj Slobodad3677682017-04-14 03:24:45 +02001232
1233 # out2in
1234 pkt = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
Matus Fabian2ba92e32017-08-21 07:05:03 -07001235 IP(src=self.pg1.remote_ip4, dst=self.nat_addr, ttl=64) /
Juraj Slobodad3677682017-04-14 03:24:45 +02001236 ICMP(id=self.icmp_id_out, type='echo-request'))
1237 self.pg1.add_stream(pkt)
1238 self.pg_enable_capture(self.pg_interfaces)
1239 self.pg_start()
1240 capture = self.pg0.get_capture(1)
1241 self.verify_capture_in(capture, self.pg0, packet_num=1)
1242 self.assert_equal(capture[0][IP].proto, IP_PROTOS.icmp)
1243
1244 # in2out
1245 pkt = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
1246 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4, ttl=64) /
1247 ICMP(id=self.icmp_id_in, type='echo-reply'))
1248 self.pg0.add_stream(pkt)
1249 self.pg_enable_capture(self.pg_interfaces)
1250 self.pg_start()
1251 capture = self.pg1.get_capture(1)
1252 self.verify_capture_out(capture, same_port=True, packet_num=1)
1253 self.assert_equal(capture[0][IP].proto, IP_PROTOS.icmp)
1254
Matus Fabiana6110b62018-06-13 05:39:07 -07001255 def _test_forwarding(self):
Juraj Sloboda7b929792017-11-23 13:20:48 +01001256 """ NAT44 forwarding test """
1257
1258 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
1259 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
1260 is_inside=0)
1261 self.vapi.nat44_forwarding_enable_disable(1)
1262
1263 real_ip = self.pg0.remote_ip4n
1264 alias_ip = self.nat_addr_n
1265 self.vapi.nat44_add_del_static_mapping(local_ip=real_ip,
1266 external_ip=alias_ip)
1267
1268 try:
1269 # in2out - static mapping match
1270
1271 pkts = self.create_stream_out(self.pg1)
1272 self.pg1.add_stream(pkts)
1273 self.pg_enable_capture(self.pg_interfaces)
1274 self.pg_start()
1275 capture = self.pg0.get_capture(len(pkts))
1276 self.verify_capture_in(capture, self.pg0)
1277
1278 pkts = self.create_stream_in(self.pg0, self.pg1)
1279 self.pg0.add_stream(pkts)
1280 self.pg_enable_capture(self.pg_interfaces)
1281 self.pg_start()
1282 capture = self.pg1.get_capture(len(pkts))
1283 self.verify_capture_out(capture, same_port=True)
1284
1285 # in2out - no static mapping match
1286
1287 host0 = self.pg0.remote_hosts[0]
1288 self.pg0.remote_hosts[0] = self.pg0.remote_hosts[1]
1289 try:
1290 pkts = self.create_stream_out(self.pg1,
1291 dst_ip=self.pg0.remote_ip4,
1292 use_inside_ports=True)
1293 self.pg1.add_stream(pkts)
1294 self.pg_enable_capture(self.pg_interfaces)
1295 self.pg_start()
1296 capture = self.pg0.get_capture(len(pkts))
1297 self.verify_capture_in(capture, self.pg0)
1298
1299 pkts = self.create_stream_in(self.pg0, self.pg1)
1300 self.pg0.add_stream(pkts)
1301 self.pg_enable_capture(self.pg_interfaces)
1302 self.pg_start()
1303 capture = self.pg1.get_capture(len(pkts))
1304 self.verify_capture_out(capture, nat_ip=self.pg0.remote_ip4,
1305 same_port=True)
1306 finally:
1307 self.pg0.remote_hosts[0] = host0
1308
Matus Fabian70a26ac2018-05-14 06:20:28 -07001309 user = self.pg0.remote_hosts[1]
1310 sessions = self.vapi.nat44_user_session_dump(user.ip4n, 0)
1311 self.assertEqual(len(sessions), 3)
1312 self.assertTrue(sessions[0].ext_host_valid)
1313 self.vapi.nat44_del_session(
1314 sessions[0].inside_ip_address,
1315 sessions[0].inside_port,
1316 sessions[0].protocol,
1317 ext_host_address=sessions[0].ext_host_address,
1318 ext_host_port=sessions[0].ext_host_port)
1319 sessions = self.vapi.nat44_user_session_dump(user.ip4n, 0)
1320 self.assertEqual(len(sessions), 2)
1321
Juraj Sloboda7b929792017-11-23 13:20:48 +01001322 finally:
1323 self.vapi.nat44_forwarding_enable_disable(0)
1324 self.vapi.nat44_add_del_static_mapping(local_ip=real_ip,
1325 external_ip=alias_ip,
1326 is_add=0)
1327
Matus Fabiande886752016-12-07 03:38:19 -08001328 def test_static_in(self):
Matus Fabian2ba92e32017-08-21 07:05:03 -07001329 """ 1:1 NAT initialized from inside network """
Matus Fabiande886752016-12-07 03:38:19 -08001330
1331 nat_ip = "10.0.0.10"
1332 self.tcp_port_out = 6303
1333 self.udp_port_out = 6304
1334 self.icmp_id_out = 6305
1335
Matus Fabian2ba92e32017-08-21 07:05:03 -07001336 self.nat44_add_static_mapping(self.pg0.remote_ip4, nat_ip)
1337 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
1338 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
1339 is_inside=0)
Matus Fabian5f224992018-01-25 21:59:16 -08001340 sm = self.vapi.nat44_static_mapping_dump()
1341 self.assertEqual(len(sm), 1)
1342 self.assertEqual((sm[0].tag).split('\0', 1)[0], '')
Matus Fabian9dba7812018-01-31 01:13:23 -08001343 self.assertEqual(sm[0].protocol, 0)
1344 self.assertEqual(sm[0].local_port, 0)
1345 self.assertEqual(sm[0].external_port, 0)
Matus Fabiande886752016-12-07 03:38:19 -08001346
1347 # in2out
1348 pkts = self.create_stream_in(self.pg0, self.pg1)
1349 self.pg0.add_stream(pkts)
1350 self.pg_enable_capture(self.pg_interfaces)
1351 self.pg_start()
Klement Sekeradab231a2016-12-21 08:50:14 +01001352 capture = self.pg1.get_capture(len(pkts))
Matus Fabiande886752016-12-07 03:38:19 -08001353 self.verify_capture_out(capture, nat_ip, True)
1354
1355 # out2in
1356 pkts = self.create_stream_out(self.pg1, nat_ip)
1357 self.pg1.add_stream(pkts)
1358 self.pg_enable_capture(self.pg_interfaces)
1359 self.pg_start()
Klement Sekeradab231a2016-12-21 08:50:14 +01001360 capture = self.pg0.get_capture(len(pkts))
Matus Fabiande886752016-12-07 03:38:19 -08001361 self.verify_capture_in(capture, self.pg0)
1362
1363 def test_static_out(self):
Matus Fabian2ba92e32017-08-21 07:05:03 -07001364 """ 1:1 NAT initialized from outside network """
Matus Fabiande886752016-12-07 03:38:19 -08001365
1366 nat_ip = "10.0.0.20"
1367 self.tcp_port_out = 6303
1368 self.udp_port_out = 6304
1369 self.icmp_id_out = 6305
Matus Fabian5f224992018-01-25 21:59:16 -08001370 tag = "testTAG"
Matus Fabiande886752016-12-07 03:38:19 -08001371
Matus Fabian5f224992018-01-25 21:59:16 -08001372 self.nat44_add_static_mapping(self.pg0.remote_ip4, nat_ip, tag=tag)
Matus Fabian2ba92e32017-08-21 07:05:03 -07001373 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
1374 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
1375 is_inside=0)
Matus Fabian5f224992018-01-25 21:59:16 -08001376 sm = self.vapi.nat44_static_mapping_dump()
1377 self.assertEqual(len(sm), 1)
1378 self.assertEqual((sm[0].tag).split('\0', 1)[0], tag)
Matus Fabiande886752016-12-07 03:38:19 -08001379
1380 # out2in
1381 pkts = self.create_stream_out(self.pg1, nat_ip)
1382 self.pg1.add_stream(pkts)
1383 self.pg_enable_capture(self.pg_interfaces)
1384 self.pg_start()
Klement Sekeradab231a2016-12-21 08:50:14 +01001385 capture = self.pg0.get_capture(len(pkts))
Matus Fabiande886752016-12-07 03:38:19 -08001386 self.verify_capture_in(capture, self.pg0)
1387
1388 # in2out
1389 pkts = self.create_stream_in(self.pg0, self.pg1)
1390 self.pg0.add_stream(pkts)
1391 self.pg_enable_capture(self.pg_interfaces)
1392 self.pg_start()
Klement Sekeradab231a2016-12-21 08:50:14 +01001393 capture = self.pg1.get_capture(len(pkts))
Matus Fabiande886752016-12-07 03:38:19 -08001394 self.verify_capture_out(capture, nat_ip, True)
1395
1396 def test_static_with_port_in(self):
Matus Fabian2ba92e32017-08-21 07:05:03 -07001397 """ 1:1 NAPT initialized from inside network """
Matus Fabiande886752016-12-07 03:38:19 -08001398
1399 self.tcp_port_out = 3606
1400 self.udp_port_out = 3607
1401 self.icmp_id_out = 3608
1402
Matus Fabian2ba92e32017-08-21 07:05:03 -07001403 self.nat44_add_address(self.nat_addr)
1404 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
1405 self.tcp_port_in, self.tcp_port_out,
1406 proto=IP_PROTOS.tcp)
1407 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
1408 self.udp_port_in, self.udp_port_out,
1409 proto=IP_PROTOS.udp)
1410 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
1411 self.icmp_id_in, self.icmp_id_out,
1412 proto=IP_PROTOS.icmp)
1413 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
1414 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
1415 is_inside=0)
Matus Fabiande886752016-12-07 03:38:19 -08001416
1417 # in2out
1418 pkts = self.create_stream_in(self.pg0, self.pg1)
1419 self.pg0.add_stream(pkts)
1420 self.pg_enable_capture(self.pg_interfaces)
1421 self.pg_start()
Klement Sekeradab231a2016-12-21 08:50:14 +01001422 capture = self.pg1.get_capture(len(pkts))
Matus Fabiande886752016-12-07 03:38:19 -08001423 self.verify_capture_out(capture)
1424
1425 # out2in
1426 pkts = self.create_stream_out(self.pg1)
1427 self.pg1.add_stream(pkts)
1428 self.pg_enable_capture(self.pg_interfaces)
1429 self.pg_start()
Klement Sekeradab231a2016-12-21 08:50:14 +01001430 capture = self.pg0.get_capture(len(pkts))
Matus Fabiande886752016-12-07 03:38:19 -08001431 self.verify_capture_in(capture, self.pg0)
1432
1433 def test_static_with_port_out(self):
Matus Fabian2ba92e32017-08-21 07:05:03 -07001434 """ 1:1 NAPT initialized from outside network """
Matus Fabiande886752016-12-07 03:38:19 -08001435
1436 self.tcp_port_out = 30606
1437 self.udp_port_out = 30607
1438 self.icmp_id_out = 30608
1439
Matus Fabian2ba92e32017-08-21 07:05:03 -07001440 self.nat44_add_address(self.nat_addr)
1441 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
1442 self.tcp_port_in, self.tcp_port_out,
1443 proto=IP_PROTOS.tcp)
1444 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
1445 self.udp_port_in, self.udp_port_out,
1446 proto=IP_PROTOS.udp)
1447 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
1448 self.icmp_id_in, self.icmp_id_out,
1449 proto=IP_PROTOS.icmp)
1450 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
1451 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
1452 is_inside=0)
Matus Fabiande886752016-12-07 03:38:19 -08001453
1454 # out2in
1455 pkts = self.create_stream_out(self.pg1)
1456 self.pg1.add_stream(pkts)
1457 self.pg_enable_capture(self.pg_interfaces)
1458 self.pg_start()
Klement Sekeradab231a2016-12-21 08:50:14 +01001459 capture = self.pg0.get_capture(len(pkts))
Matus Fabiande886752016-12-07 03:38:19 -08001460 self.verify_capture_in(capture, self.pg0)
1461
1462 # in2out
1463 pkts = self.create_stream_in(self.pg0, self.pg1)
1464 self.pg0.add_stream(pkts)
1465 self.pg_enable_capture(self.pg_interfaces)
1466 self.pg_start()
Klement Sekeradab231a2016-12-21 08:50:14 +01001467 capture = self.pg1.get_capture(len(pkts))
Matus Fabiande886752016-12-07 03:38:19 -08001468 self.verify_capture_out(capture)
1469
1470 def test_static_vrf_aware(self):
Matus Fabian2ba92e32017-08-21 07:05:03 -07001471 """ 1:1 NAT VRF awareness """
Matus Fabiande886752016-12-07 03:38:19 -08001472
1473 nat_ip1 = "10.0.0.30"
1474 nat_ip2 = "10.0.0.40"
1475 self.tcp_port_out = 6303
1476 self.udp_port_out = 6304
1477 self.icmp_id_out = 6305
1478
Matus Fabian2ba92e32017-08-21 07:05:03 -07001479 self.nat44_add_static_mapping(self.pg4.remote_ip4, nat_ip1,
1480 vrf_id=10)
1481 self.nat44_add_static_mapping(self.pg0.remote_ip4, nat_ip2,
1482 vrf_id=10)
1483 self.vapi.nat44_interface_add_del_feature(self.pg3.sw_if_index,
1484 is_inside=0)
1485 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
1486 self.vapi.nat44_interface_add_del_feature(self.pg4.sw_if_index)
Matus Fabiande886752016-12-07 03:38:19 -08001487
Matus Fabian2ba92e32017-08-21 07:05:03 -07001488 # inside interface VRF match NAT44 static mapping VRF
Matus Fabiande886752016-12-07 03:38:19 -08001489 pkts = self.create_stream_in(self.pg4, self.pg3)
1490 self.pg4.add_stream(pkts)
1491 self.pg_enable_capture(self.pg_interfaces)
1492 self.pg_start()
Klement Sekeradab231a2016-12-21 08:50:14 +01001493 capture = self.pg3.get_capture(len(pkts))
Matus Fabiande886752016-12-07 03:38:19 -08001494 self.verify_capture_out(capture, nat_ip1, True)
1495
Matus Fabian2ba92e32017-08-21 07:05:03 -07001496 # inside interface VRF don't match NAT44 static mapping VRF (packets
Matus Fabiande886752016-12-07 03:38:19 -08001497 # are dropped)
1498 pkts = self.create_stream_in(self.pg0, self.pg3)
1499 self.pg0.add_stream(pkts)
1500 self.pg_enable_capture(self.pg_interfaces)
1501 self.pg_start()
Klement Sekera9225dee2016-12-12 08:36:58 +01001502 self.pg3.assert_nothing_captured()
Matus Fabiande886752016-12-07 03:38:19 -08001503
Matus Fabianb793d092018-01-31 05:50:21 -08001504 def test_dynamic_to_static(self):
1505 """ Switch from dynamic translation to 1:1NAT """
1506 nat_ip = "10.0.0.10"
1507 self.tcp_port_out = 6303
1508 self.udp_port_out = 6304
1509 self.icmp_id_out = 6305
1510
1511 self.nat44_add_address(self.nat_addr)
1512 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
1513 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
1514 is_inside=0)
1515
1516 # dynamic
1517 pkts = self.create_stream_in(self.pg0, self.pg1)
1518 self.pg0.add_stream(pkts)
1519 self.pg_enable_capture(self.pg_interfaces)
1520 self.pg_start()
1521 capture = self.pg1.get_capture(len(pkts))
1522 self.verify_capture_out(capture)
1523
1524 # 1:1NAT
1525 self.nat44_add_static_mapping(self.pg0.remote_ip4, nat_ip)
1526 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n, 0)
1527 self.assertEqual(len(sessions), 0)
1528 pkts = self.create_stream_in(self.pg0, self.pg1)
1529 self.pg0.add_stream(pkts)
1530 self.pg_enable_capture(self.pg_interfaces)
1531 self.pg_start()
1532 capture = self.pg1.get_capture(len(pkts))
1533 self.verify_capture_out(capture, nat_ip, True)
1534
Matus Fabianab7a8052017-11-28 04:29:41 -08001535 def test_identity_nat(self):
1536 """ Identity NAT """
1537
1538 self.vapi.nat44_add_del_identity_mapping(ip=self.pg0.remote_ip4n)
1539 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
1540 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
1541 is_inside=0)
1542
1543 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
1544 IP(src=self.pg1.remote_ip4, dst=self.pg0.remote_ip4) /
1545 TCP(sport=12345, dport=56789))
1546 self.pg1.add_stream(p)
1547 self.pg_enable_capture(self.pg_interfaces)
1548 self.pg_start()
1549 capture = self.pg0.get_capture(1)
1550 p = capture[0]
1551 try:
1552 ip = p[IP]
1553 tcp = p[TCP]
1554 self.assertEqual(ip.dst, self.pg0.remote_ip4)
1555 self.assertEqual(ip.src, self.pg1.remote_ip4)
1556 self.assertEqual(tcp.dport, 56789)
1557 self.assertEqual(tcp.sport, 12345)
Klement Sekerad81ae412018-05-16 10:52:54 +02001558 self.assert_packet_checksums_valid(p)
Matus Fabianab7a8052017-11-28 04:29:41 -08001559 except:
1560 self.logger.error(ppp("Unexpected or invalid packet:", p))
1561 raise
1562
Matus Fabiande886752016-12-07 03:38:19 -08001563 def test_multiple_inside_interfaces(self):
Matus Fabian2ba92e32017-08-21 07:05:03 -07001564 """ NAT44 multiple non-overlapping address space inside interfaces """
Matus Fabiande886752016-12-07 03:38:19 -08001565
Matus Fabian2ba92e32017-08-21 07:05:03 -07001566 self.nat44_add_address(self.nat_addr)
1567 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
1568 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index)
1569 self.vapi.nat44_interface_add_del_feature(self.pg3.sw_if_index,
1570 is_inside=0)
Matus Fabiande886752016-12-07 03:38:19 -08001571
Matus Fabian2ba92e32017-08-21 07:05:03 -07001572 # between two NAT44 inside interfaces (no translation)
Matus Fabian675a69c2017-01-18 01:46:01 -08001573 pkts = self.create_stream_in(self.pg0, self.pg1)
1574 self.pg0.add_stream(pkts)
1575 self.pg_enable_capture(self.pg_interfaces)
1576 self.pg_start()
1577 capture = self.pg1.get_capture(len(pkts))
1578 self.verify_capture_no_translation(capture, self.pg0, self.pg1)
1579
Matus Fabian2ba92e32017-08-21 07:05:03 -07001580 # from NAT44 inside to interface without NAT44 feature (no translation)
Matus Fabian675a69c2017-01-18 01:46:01 -08001581 pkts = self.create_stream_in(self.pg0, self.pg2)
1582 self.pg0.add_stream(pkts)
1583 self.pg_enable_capture(self.pg_interfaces)
1584 self.pg_start()
1585 capture = self.pg2.get_capture(len(pkts))
1586 self.verify_capture_no_translation(capture, self.pg0, self.pg2)
1587
Matus Fabiande886752016-12-07 03:38:19 -08001588 # in2out 1st interface
1589 pkts = self.create_stream_in(self.pg0, self.pg3)
1590 self.pg0.add_stream(pkts)
1591 self.pg_enable_capture(self.pg_interfaces)
1592 self.pg_start()
Klement Sekeradab231a2016-12-21 08:50:14 +01001593 capture = self.pg3.get_capture(len(pkts))
Matus Fabiande886752016-12-07 03:38:19 -08001594 self.verify_capture_out(capture)
1595
1596 # out2in 1st interface
1597 pkts = self.create_stream_out(self.pg3)
1598 self.pg3.add_stream(pkts)
1599 self.pg_enable_capture(self.pg_interfaces)
1600 self.pg_start()
Klement Sekeradab231a2016-12-21 08:50:14 +01001601 capture = self.pg0.get_capture(len(pkts))
Matus Fabiande886752016-12-07 03:38:19 -08001602 self.verify_capture_in(capture, self.pg0)
1603
1604 # in2out 2nd interface
1605 pkts = self.create_stream_in(self.pg1, self.pg3)
1606 self.pg1.add_stream(pkts)
1607 self.pg_enable_capture(self.pg_interfaces)
1608 self.pg_start()
Klement Sekeradab231a2016-12-21 08:50:14 +01001609 capture = self.pg3.get_capture(len(pkts))
Matus Fabiande886752016-12-07 03:38:19 -08001610 self.verify_capture_out(capture)
1611
1612 # out2in 2nd interface
1613 pkts = self.create_stream_out(self.pg3)
1614 self.pg3.add_stream(pkts)
1615 self.pg_enable_capture(self.pg_interfaces)
1616 self.pg_start()
Klement Sekeradab231a2016-12-21 08:50:14 +01001617 capture = self.pg1.get_capture(len(pkts))
Matus Fabiande886752016-12-07 03:38:19 -08001618 self.verify_capture_in(capture, self.pg1)
1619
Matus Fabiande886752016-12-07 03:38:19 -08001620 def test_inside_overlapping_interfaces(self):
Matus Fabian2ba92e32017-08-21 07:05:03 -07001621 """ NAT44 multiple inside interfaces with overlapping address space """
Matus Fabiande886752016-12-07 03:38:19 -08001622
Matus Fabian675a69c2017-01-18 01:46:01 -08001623 static_nat_ip = "10.0.0.10"
Matus Fabian2ba92e32017-08-21 07:05:03 -07001624 self.nat44_add_address(self.nat_addr)
1625 self.vapi.nat44_interface_add_del_feature(self.pg3.sw_if_index,
1626 is_inside=0)
1627 self.vapi.nat44_interface_add_del_feature(self.pg4.sw_if_index)
1628 self.vapi.nat44_interface_add_del_feature(self.pg5.sw_if_index)
1629 self.vapi.nat44_interface_add_del_feature(self.pg6.sw_if_index)
1630 self.nat44_add_static_mapping(self.pg6.remote_ip4, static_nat_ip,
1631 vrf_id=20)
Matus Fabian675a69c2017-01-18 01:46:01 -08001632
Matus Fabian2ba92e32017-08-21 07:05:03 -07001633 # between NAT44 inside interfaces with same VRF (no translation)
Matus Fabian675a69c2017-01-18 01:46:01 -08001634 pkts = self.create_stream_in(self.pg4, self.pg5)
1635 self.pg4.add_stream(pkts)
1636 self.pg_enable_capture(self.pg_interfaces)
1637 self.pg_start()
1638 capture = self.pg5.get_capture(len(pkts))
1639 self.verify_capture_no_translation(capture, self.pg4, self.pg5)
1640
Matus Fabian2ba92e32017-08-21 07:05:03 -07001641 # between NAT44 inside interfaces with different VRF (hairpinning)
Matus Fabian675a69c2017-01-18 01:46:01 -08001642 p = (Ether(src=self.pg4.remote_mac, dst=self.pg4.local_mac) /
1643 IP(src=self.pg4.remote_ip4, dst=static_nat_ip) /
1644 TCP(sport=1234, dport=5678))
1645 self.pg4.add_stream(p)
1646 self.pg_enable_capture(self.pg_interfaces)
1647 self.pg_start()
1648 capture = self.pg6.get_capture(1)
1649 p = capture[0]
1650 try:
1651 ip = p[IP]
1652 tcp = p[TCP]
Matus Fabian2ba92e32017-08-21 07:05:03 -07001653 self.assertEqual(ip.src, self.nat_addr)
Matus Fabian675a69c2017-01-18 01:46:01 -08001654 self.assertEqual(ip.dst, self.pg6.remote_ip4)
1655 self.assertNotEqual(tcp.sport, 1234)
1656 self.assertEqual(tcp.dport, 5678)
1657 except:
1658 self.logger.error(ppp("Unexpected or invalid packet:", p))
1659 raise
Matus Fabiande886752016-12-07 03:38:19 -08001660
1661 # in2out 1st interface
1662 pkts = self.create_stream_in(self.pg4, self.pg3)
1663 self.pg4.add_stream(pkts)
1664 self.pg_enable_capture(self.pg_interfaces)
1665 self.pg_start()
Klement Sekeradab231a2016-12-21 08:50:14 +01001666 capture = self.pg3.get_capture(len(pkts))
Matus Fabiande886752016-12-07 03:38:19 -08001667 self.verify_capture_out(capture)
1668
1669 # out2in 1st interface
1670 pkts = self.create_stream_out(self.pg3)
1671 self.pg3.add_stream(pkts)
1672 self.pg_enable_capture(self.pg_interfaces)
1673 self.pg_start()
Klement Sekeradab231a2016-12-21 08:50:14 +01001674 capture = self.pg4.get_capture(len(pkts))
Matus Fabiande886752016-12-07 03:38:19 -08001675 self.verify_capture_in(capture, self.pg4)
1676
1677 # in2out 2nd interface
1678 pkts = self.create_stream_in(self.pg5, self.pg3)
1679 self.pg5.add_stream(pkts)
1680 self.pg_enable_capture(self.pg_interfaces)
1681 self.pg_start()
Klement Sekeradab231a2016-12-21 08:50:14 +01001682 capture = self.pg3.get_capture(len(pkts))
Matus Fabiande886752016-12-07 03:38:19 -08001683 self.verify_capture_out(capture)
1684
1685 # out2in 2nd interface
1686 pkts = self.create_stream_out(self.pg3)
1687 self.pg3.add_stream(pkts)
1688 self.pg_enable_capture(self.pg_interfaces)
1689 self.pg_start()
Klement Sekeradab231a2016-12-21 08:50:14 +01001690 capture = self.pg5.get_capture(len(pkts))
Matus Fabiande886752016-12-07 03:38:19 -08001691 self.verify_capture_in(capture, self.pg5)
1692
magalik23caa882017-02-08 23:25:45 -08001693 # pg5 session dump
Matus Fabian2ba92e32017-08-21 07:05:03 -07001694 addresses = self.vapi.nat44_address_dump()
magalik23caa882017-02-08 23:25:45 -08001695 self.assertEqual(len(addresses), 1)
Matus Fabian2ba92e32017-08-21 07:05:03 -07001696 sessions = self.vapi.nat44_user_session_dump(self.pg5.remote_ip4n, 10)
magalik23caa882017-02-08 23:25:45 -08001697 self.assertEqual(len(sessions), 3)
1698 for session in sessions:
1699 self.assertFalse(session.is_static)
1700 self.assertEqual(session.inside_ip_address[0:4],
1701 self.pg5.remote_ip4n)
1702 self.assertEqual(session.outside_ip_address,
1703 addresses[0].ip_address)
1704 self.assertEqual(sessions[0].protocol, IP_PROTOS.tcp)
1705 self.assertEqual(sessions[1].protocol, IP_PROTOS.udp)
1706 self.assertEqual(sessions[2].protocol, IP_PROTOS.icmp)
1707 self.assertEqual(sessions[0].inside_port, self.tcp_port_in)
1708 self.assertEqual(sessions[1].inside_port, self.udp_port_in)
1709 self.assertEqual(sessions[2].inside_port, self.icmp_id_in)
1710 self.assertEqual(sessions[0].outside_port, self.tcp_port_out)
1711 self.assertEqual(sessions[1].outside_port, self.udp_port_out)
1712 self.assertEqual(sessions[2].outside_port, self.icmp_id_out)
1713
Matus Fabiande886752016-12-07 03:38:19 -08001714 # in2out 3rd interface
1715 pkts = self.create_stream_in(self.pg6, self.pg3)
1716 self.pg6.add_stream(pkts)
1717 self.pg_enable_capture(self.pg_interfaces)
1718 self.pg_start()
Klement Sekeradab231a2016-12-21 08:50:14 +01001719 capture = self.pg3.get_capture(len(pkts))
Matus Fabian675a69c2017-01-18 01:46:01 -08001720 self.verify_capture_out(capture, static_nat_ip, True)
Matus Fabiande886752016-12-07 03:38:19 -08001721
1722 # out2in 3rd interface
Matus Fabian675a69c2017-01-18 01:46:01 -08001723 pkts = self.create_stream_out(self.pg3, static_nat_ip)
Matus Fabiande886752016-12-07 03:38:19 -08001724 self.pg3.add_stream(pkts)
1725 self.pg_enable_capture(self.pg_interfaces)
1726 self.pg_start()
Klement Sekeradab231a2016-12-21 08:50:14 +01001727 capture = self.pg6.get_capture(len(pkts))
Matus Fabiande886752016-12-07 03:38:19 -08001728 self.verify_capture_in(capture, self.pg6)
1729
magalik23caa882017-02-08 23:25:45 -08001730 # general user and session dump verifications
Matus Fabian2ba92e32017-08-21 07:05:03 -07001731 users = self.vapi.nat44_user_dump()
magalik23caa882017-02-08 23:25:45 -08001732 self.assertTrue(len(users) >= 3)
Matus Fabian2ba92e32017-08-21 07:05:03 -07001733 addresses = self.vapi.nat44_address_dump()
magalik23caa882017-02-08 23:25:45 -08001734 self.assertEqual(len(addresses), 1)
1735 for user in users:
Matus Fabian2ba92e32017-08-21 07:05:03 -07001736 sessions = self.vapi.nat44_user_session_dump(user.ip_address,
1737 user.vrf_id)
magalik23caa882017-02-08 23:25:45 -08001738 for session in sessions:
1739 self.assertEqual(user.ip_address, session.inside_ip_address)
1740 self.assertTrue(session.total_bytes > session.total_pkts > 0)
1741 self.assertTrue(session.protocol in
1742 [IP_PROTOS.tcp, IP_PROTOS.udp,
1743 IP_PROTOS.icmp])
Matus Fabian70a26ac2018-05-14 06:20:28 -07001744 self.assertFalse(session.ext_host_valid)
magalik23caa882017-02-08 23:25:45 -08001745
1746 # pg4 session dump
Matus Fabian2ba92e32017-08-21 07:05:03 -07001747 sessions = self.vapi.nat44_user_session_dump(self.pg4.remote_ip4n, 10)
magalik23caa882017-02-08 23:25:45 -08001748 self.assertTrue(len(sessions) >= 4)
1749 for session in sessions:
1750 self.assertFalse(session.is_static)
1751 self.assertEqual(session.inside_ip_address[0:4],
1752 self.pg4.remote_ip4n)
1753 self.assertEqual(session.outside_ip_address,
1754 addresses[0].ip_address)
1755
1756 # pg6 session dump
Matus Fabian2ba92e32017-08-21 07:05:03 -07001757 sessions = self.vapi.nat44_user_session_dump(self.pg6.remote_ip4n, 20)
magalik23caa882017-02-08 23:25:45 -08001758 self.assertTrue(len(sessions) >= 3)
1759 for session in sessions:
1760 self.assertTrue(session.is_static)
1761 self.assertEqual(session.inside_ip_address[0:4],
1762 self.pg6.remote_ip4n)
1763 self.assertEqual(map(ord, session.outside_ip_address[0:4]),
1764 map(int, static_nat_ip.split('.')))
1765 self.assertTrue(session.inside_port in
1766 [self.tcp_port_in, self.udp_port_in,
1767 self.icmp_id_in])
1768
Matus Fabianf78a70d2016-12-12 04:30:39 -08001769 def test_hairpinning(self):
Matus Fabian2ba92e32017-08-21 07:05:03 -07001770 """ NAT44 hairpinning - 1:1 NAPT """
Matus Fabianf78a70d2016-12-12 04:30:39 -08001771
1772 host = self.pg0.remote_hosts[0]
1773 server = self.pg0.remote_hosts[1]
1774 host_in_port = 1234
1775 host_out_port = 0
1776 server_in_port = 5678
1777 server_out_port = 8765
1778
Matus Fabian2ba92e32017-08-21 07:05:03 -07001779 self.nat44_add_address(self.nat_addr)
1780 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
1781 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
1782 is_inside=0)
Matus Fabianf78a70d2016-12-12 04:30:39 -08001783 # add static mapping for server
Matus Fabian2ba92e32017-08-21 07:05:03 -07001784 self.nat44_add_static_mapping(server.ip4, self.nat_addr,
1785 server_in_port, server_out_port,
1786 proto=IP_PROTOS.tcp)
Matus Fabianf78a70d2016-12-12 04:30:39 -08001787
1788 # send packet from host to server
1789 p = (Ether(src=host.mac, dst=self.pg0.local_mac) /
Matus Fabian2ba92e32017-08-21 07:05:03 -07001790 IP(src=host.ip4, dst=self.nat_addr) /
Matus Fabianf78a70d2016-12-12 04:30:39 -08001791 TCP(sport=host_in_port, dport=server_out_port))
1792 self.pg0.add_stream(p)
1793 self.pg_enable_capture(self.pg_interfaces)
1794 self.pg_start()
Klement Sekeradab231a2016-12-21 08:50:14 +01001795 capture = self.pg0.get_capture(1)
Matus Fabianf78a70d2016-12-12 04:30:39 -08001796 p = capture[0]
1797 try:
1798 ip = p[IP]
1799 tcp = p[TCP]
Matus Fabian2ba92e32017-08-21 07:05:03 -07001800 self.assertEqual(ip.src, self.nat_addr)
Matus Fabianf78a70d2016-12-12 04:30:39 -08001801 self.assertEqual(ip.dst, server.ip4)
1802 self.assertNotEqual(tcp.sport, host_in_port)
1803 self.assertEqual(tcp.dport, server_in_port)
Klement Sekerad81ae412018-05-16 10:52:54 +02001804 self.assert_packet_checksums_valid(p)
Matus Fabianf78a70d2016-12-12 04:30:39 -08001805 host_out_port = tcp.sport
1806 except:
Klement Sekera9225dee2016-12-12 08:36:58 +01001807 self.logger.error(ppp("Unexpected or invalid packet:", p))
Matus Fabianf78a70d2016-12-12 04:30:39 -08001808 raise
1809
1810 # send reply from server to host
1811 p = (Ether(src=server.mac, dst=self.pg0.local_mac) /
Matus Fabian2ba92e32017-08-21 07:05:03 -07001812 IP(src=server.ip4, dst=self.nat_addr) /
Matus Fabianf78a70d2016-12-12 04:30:39 -08001813 TCP(sport=server_in_port, dport=host_out_port))
1814 self.pg0.add_stream(p)
1815 self.pg_enable_capture(self.pg_interfaces)
1816 self.pg_start()
Klement Sekeradab231a2016-12-21 08:50:14 +01001817 capture = self.pg0.get_capture(1)
Matus Fabianf78a70d2016-12-12 04:30:39 -08001818 p = capture[0]
1819 try:
1820 ip = p[IP]
1821 tcp = p[TCP]
Matus Fabian2ba92e32017-08-21 07:05:03 -07001822 self.assertEqual(ip.src, self.nat_addr)
Matus Fabianf78a70d2016-12-12 04:30:39 -08001823 self.assertEqual(ip.dst, host.ip4)
1824 self.assertEqual(tcp.sport, server_out_port)
1825 self.assertEqual(tcp.dport, host_in_port)
Klement Sekerad81ae412018-05-16 10:52:54 +02001826 self.assert_packet_checksums_valid(p)
Matus Fabianf78a70d2016-12-12 04:30:39 -08001827 except:
Matus Fabiane82488f2018-01-18 03:38:45 -08001828 self.logger.error(ppp("Unexpected or invalid packet:", p))
Matus Fabianf78a70d2016-12-12 04:30:39 -08001829 raise
1830
Matus Fabian6fa74c62017-06-05 05:55:48 -07001831 def test_hairpinning2(self):
Matus Fabian2ba92e32017-08-21 07:05:03 -07001832 """ NAT44 hairpinning - 1:1 NAT"""
Matus Fabian6fa74c62017-06-05 05:55:48 -07001833
1834 server1_nat_ip = "10.0.0.10"
1835 server2_nat_ip = "10.0.0.11"
1836 host = self.pg0.remote_hosts[0]
1837 server1 = self.pg0.remote_hosts[1]
1838 server2 = self.pg0.remote_hosts[2]
1839 server_tcp_port = 22
1840 server_udp_port = 20
1841
Matus Fabian2ba92e32017-08-21 07:05:03 -07001842 self.nat44_add_address(self.nat_addr)
1843 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
1844 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
1845 is_inside=0)
Matus Fabian6fa74c62017-06-05 05:55:48 -07001846
1847 # add static mapping for servers
Matus Fabian2ba92e32017-08-21 07:05:03 -07001848 self.nat44_add_static_mapping(server1.ip4, server1_nat_ip)
1849 self.nat44_add_static_mapping(server2.ip4, server2_nat_ip)
Matus Fabian6fa74c62017-06-05 05:55:48 -07001850
1851 # host to server1
1852 pkts = []
1853 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
1854 IP(src=host.ip4, dst=server1_nat_ip) /
1855 TCP(sport=self.tcp_port_in, dport=server_tcp_port))
1856 pkts.append(p)
1857 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
1858 IP(src=host.ip4, dst=server1_nat_ip) /
1859 UDP(sport=self.udp_port_in, dport=server_udp_port))
1860 pkts.append(p)
1861 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
1862 IP(src=host.ip4, dst=server1_nat_ip) /
1863 ICMP(id=self.icmp_id_in, type='echo-request'))
1864 pkts.append(p)
1865 self.pg0.add_stream(pkts)
1866 self.pg_enable_capture(self.pg_interfaces)
1867 self.pg_start()
1868 capture = self.pg0.get_capture(len(pkts))
1869 for packet in capture:
1870 try:
Matus Fabian2ba92e32017-08-21 07:05:03 -07001871 self.assertEqual(packet[IP].src, self.nat_addr)
Matus Fabian6fa74c62017-06-05 05:55:48 -07001872 self.assertEqual(packet[IP].dst, server1.ip4)
1873 if packet.haslayer(TCP):
1874 self.assertNotEqual(packet[TCP].sport, self.tcp_port_in)
1875 self.assertEqual(packet[TCP].dport, server_tcp_port)
1876 self.tcp_port_out = packet[TCP].sport
Klement Sekerad81ae412018-05-16 10:52:54 +02001877 self.assert_packet_checksums_valid(packet)
Matus Fabian6fa74c62017-06-05 05:55:48 -07001878 elif packet.haslayer(UDP):
1879 self.assertNotEqual(packet[UDP].sport, self.udp_port_in)
1880 self.assertEqual(packet[UDP].dport, server_udp_port)
1881 self.udp_port_out = packet[UDP].sport
1882 else:
1883 self.assertNotEqual(packet[ICMP].id, self.icmp_id_in)
1884 self.icmp_id_out = packet[ICMP].id
1885 except:
1886 self.logger.error(ppp("Unexpected or invalid packet:", packet))
1887 raise
1888
1889 # server1 to host
1890 pkts = []
1891 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
Matus Fabian2ba92e32017-08-21 07:05:03 -07001892 IP(src=server1.ip4, dst=self.nat_addr) /
Matus Fabian6fa74c62017-06-05 05:55:48 -07001893 TCP(sport=server_tcp_port, dport=self.tcp_port_out))
1894 pkts.append(p)
1895 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
Matus Fabian2ba92e32017-08-21 07:05:03 -07001896 IP(src=server1.ip4, dst=self.nat_addr) /
Matus Fabian6fa74c62017-06-05 05:55:48 -07001897 UDP(sport=server_udp_port, dport=self.udp_port_out))
1898 pkts.append(p)
1899 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
Matus Fabian2ba92e32017-08-21 07:05:03 -07001900 IP(src=server1.ip4, dst=self.nat_addr) /
Matus Fabian6fa74c62017-06-05 05:55:48 -07001901 ICMP(id=self.icmp_id_out, type='echo-reply'))
1902 pkts.append(p)
1903 self.pg0.add_stream(pkts)
1904 self.pg_enable_capture(self.pg_interfaces)
1905 self.pg_start()
1906 capture = self.pg0.get_capture(len(pkts))
1907 for packet in capture:
1908 try:
1909 self.assertEqual(packet[IP].src, server1_nat_ip)
1910 self.assertEqual(packet[IP].dst, host.ip4)
1911 if packet.haslayer(TCP):
1912 self.assertEqual(packet[TCP].dport, self.tcp_port_in)
1913 self.assertEqual(packet[TCP].sport, server_tcp_port)
Klement Sekerad81ae412018-05-16 10:52:54 +02001914 self.assert_packet_checksums_valid(packet)
Matus Fabian6fa74c62017-06-05 05:55:48 -07001915 elif packet.haslayer(UDP):
1916 self.assertEqual(packet[UDP].dport, self.udp_port_in)
1917 self.assertEqual(packet[UDP].sport, server_udp_port)
1918 else:
1919 self.assertEqual(packet[ICMP].id, self.icmp_id_in)
1920 except:
1921 self.logger.error(ppp("Unexpected or invalid packet:", packet))
1922 raise
1923
1924 # server2 to server1
1925 pkts = []
1926 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
1927 IP(src=server2.ip4, dst=server1_nat_ip) /
1928 TCP(sport=self.tcp_port_in, dport=server_tcp_port))
1929 pkts.append(p)
1930 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
1931 IP(src=server2.ip4, dst=server1_nat_ip) /
1932 UDP(sport=self.udp_port_in, dport=server_udp_port))
1933 pkts.append(p)
1934 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
1935 IP(src=server2.ip4, dst=server1_nat_ip) /
1936 ICMP(id=self.icmp_id_in, type='echo-request'))
1937 pkts.append(p)
1938 self.pg0.add_stream(pkts)
1939 self.pg_enable_capture(self.pg_interfaces)
1940 self.pg_start()
1941 capture = self.pg0.get_capture(len(pkts))
1942 for packet in capture:
1943 try:
1944 self.assertEqual(packet[IP].src, server2_nat_ip)
1945 self.assertEqual(packet[IP].dst, server1.ip4)
1946 if packet.haslayer(TCP):
1947 self.assertEqual(packet[TCP].sport, self.tcp_port_in)
1948 self.assertEqual(packet[TCP].dport, server_tcp_port)
1949 self.tcp_port_out = packet[TCP].sport
Klement Sekerad81ae412018-05-16 10:52:54 +02001950 self.assert_packet_checksums_valid(packet)
Matus Fabian6fa74c62017-06-05 05:55:48 -07001951 elif packet.haslayer(UDP):
1952 self.assertEqual(packet[UDP].sport, self.udp_port_in)
1953 self.assertEqual(packet[UDP].dport, server_udp_port)
1954 self.udp_port_out = packet[UDP].sport
1955 else:
1956 self.assertEqual(packet[ICMP].id, self.icmp_id_in)
1957 self.icmp_id_out = packet[ICMP].id
1958 except:
1959 self.logger.error(ppp("Unexpected or invalid packet:", packet))
1960 raise
1961
1962 # server1 to server2
1963 pkts = []
1964 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
1965 IP(src=server1.ip4, dst=server2_nat_ip) /
1966 TCP(sport=server_tcp_port, dport=self.tcp_port_out))
1967 pkts.append(p)
1968 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
1969 IP(src=server1.ip4, dst=server2_nat_ip) /
1970 UDP(sport=server_udp_port, dport=self.udp_port_out))
1971 pkts.append(p)
1972 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
1973 IP(src=server1.ip4, dst=server2_nat_ip) /
1974 ICMP(id=self.icmp_id_out, type='echo-reply'))
1975 pkts.append(p)
1976 self.pg0.add_stream(pkts)
1977 self.pg_enable_capture(self.pg_interfaces)
1978 self.pg_start()
1979 capture = self.pg0.get_capture(len(pkts))
1980 for packet in capture:
1981 try:
1982 self.assertEqual(packet[IP].src, server1_nat_ip)
1983 self.assertEqual(packet[IP].dst, server2.ip4)
1984 if packet.haslayer(TCP):
1985 self.assertEqual(packet[TCP].dport, self.tcp_port_in)
1986 self.assertEqual(packet[TCP].sport, server_tcp_port)
Klement Sekerad81ae412018-05-16 10:52:54 +02001987 self.assert_packet_checksums_valid(packet)
Matus Fabian6fa74c62017-06-05 05:55:48 -07001988 elif packet.haslayer(UDP):
1989 self.assertEqual(packet[UDP].dport, self.udp_port_in)
1990 self.assertEqual(packet[UDP].sport, server_udp_port)
1991 else:
1992 self.assertEqual(packet[ICMP].id, self.icmp_id_in)
1993 except:
1994 self.logger.error(ppp("Unexpected or invalid packet:", packet))
1995 raise
1996
Matus Fabian9902fcd2016-12-21 23:58:46 -08001997 def test_max_translations_per_user(self):
1998 """ MAX translations per user - recycle the least recently used """
1999
Matus Fabian2ba92e32017-08-21 07:05:03 -07002000 self.nat44_add_address(self.nat_addr)
2001 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
2002 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
2003 is_inside=0)
Matus Fabian9902fcd2016-12-21 23:58:46 -08002004
2005 # get maximum number of translations per user
Matus Fabian2ba92e32017-08-21 07:05:03 -07002006 nat44_config = self.vapi.nat_show_config()
Matus Fabian9902fcd2016-12-21 23:58:46 -08002007
2008 # send more than maximum number of translations per user packets
Matus Fabian2ba92e32017-08-21 07:05:03 -07002009 pkts_num = nat44_config.max_translations_per_user + 5
Matus Fabian9902fcd2016-12-21 23:58:46 -08002010 pkts = []
2011 for port in range(0, pkts_num):
2012 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2013 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
2014 TCP(sport=1025 + port))
2015 pkts.append(p)
2016 self.pg0.add_stream(pkts)
2017 self.pg_enable_capture(self.pg_interfaces)
2018 self.pg_start()
2019
2020 # verify number of translated packet
Klement Sekeradab231a2016-12-21 08:50:14 +01002021 self.pg1.get_capture(pkts_num)
Matus Fabian9902fcd2016-12-21 23:58:46 -08002022
Matus Fabian132dc492018-05-09 04:51:03 -07002023 users = self.vapi.nat44_user_dump()
2024 for user in users:
2025 if user.ip_address == self.pg0.remote_ip4n:
2026 self.assertEqual(user.nsessions,
2027 nat44_config.max_translations_per_user)
2028 self.assertEqual(user.nstaticsessions, 0)
2029
2030 tcp_port = 22
2031 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
2032 tcp_port, tcp_port,
2033 proto=IP_PROTOS.tcp)
2034 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2035 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
2036 TCP(sport=tcp_port))
2037 self.pg0.add_stream(p)
2038 self.pg_enable_capture(self.pg_interfaces)
2039 self.pg_start()
2040 self.pg1.get_capture(1)
2041 users = self.vapi.nat44_user_dump()
2042 for user in users:
2043 if user.ip_address == self.pg0.remote_ip4n:
2044 self.assertEqual(user.nsessions,
2045 nat44_config.max_translations_per_user - 1)
2046 self.assertEqual(user.nstaticsessions, 1)
2047
Matus Fabian8bf68e82017-01-12 04:24:35 -08002048 def test_interface_addr(self):
Matus Fabian2ba92e32017-08-21 07:05:03 -07002049 """ Acquire NAT44 addresses from interface """
2050 self.vapi.nat44_add_interface_addr(self.pg7.sw_if_index)
Matus Fabian8bf68e82017-01-12 04:24:35 -08002051
2052 # no address in NAT pool
Matus Fabian2ba92e32017-08-21 07:05:03 -07002053 adresses = self.vapi.nat44_address_dump()
Matus Fabian8bf68e82017-01-12 04:24:35 -08002054 self.assertEqual(0, len(adresses))
2055
2056 # configure interface address and check NAT address pool
2057 self.pg7.config_ip4()
Matus Fabian2ba92e32017-08-21 07:05:03 -07002058 adresses = self.vapi.nat44_address_dump()
Matus Fabian8bf68e82017-01-12 04:24:35 -08002059 self.assertEqual(1, len(adresses))
Matus Fabian36532bd2017-01-23 23:42:28 -08002060 self.assertEqual(adresses[0].ip_address[0:4], self.pg7.local_ip4n)
Matus Fabian8bf68e82017-01-12 04:24:35 -08002061
2062 # remove interface address and check NAT address pool
2063 self.pg7.unconfig_ip4()
Matus Fabian2ba92e32017-08-21 07:05:03 -07002064 adresses = self.vapi.nat44_address_dump()
Matus Fabian8bf68e82017-01-12 04:24:35 -08002065 self.assertEqual(0, len(adresses))
2066
Matus Fabian36532bd2017-01-23 23:42:28 -08002067 def test_interface_addr_static_mapping(self):
2068 """ Static mapping with addresses from interface """
Matus Fabian5f224992018-01-25 21:59:16 -08002069 tag = "testTAG"
2070
Matus Fabian2ba92e32017-08-21 07:05:03 -07002071 self.vapi.nat44_add_interface_addr(self.pg7.sw_if_index)
2072 self.nat44_add_static_mapping(
2073 '1.2.3.4',
Matus Fabian5f224992018-01-25 21:59:16 -08002074 external_sw_if_index=self.pg7.sw_if_index,
2075 tag=tag)
Matus Fabian36532bd2017-01-23 23:42:28 -08002076
Matus Fabiane22e5462017-02-14 23:33:43 -08002077 # static mappings with external interface
Matus Fabian2ba92e32017-08-21 07:05:03 -07002078 static_mappings = self.vapi.nat44_static_mapping_dump()
Matus Fabiane22e5462017-02-14 23:33:43 -08002079 self.assertEqual(1, len(static_mappings))
2080 self.assertEqual(self.pg7.sw_if_index,
2081 static_mappings[0].external_sw_if_index)
Matus Fabian5f224992018-01-25 21:59:16 -08002082 self.assertEqual((static_mappings[0].tag).split('\0', 1)[0], tag)
Matus Fabian36532bd2017-01-23 23:42:28 -08002083
2084 # configure interface address and check static mappings
2085 self.pg7.config_ip4()
Matus Fabian2ba92e32017-08-21 07:05:03 -07002086 static_mappings = self.vapi.nat44_static_mapping_dump()
Matus Fabianea2600a2018-03-28 04:06:26 -07002087 self.assertEqual(2, len(static_mappings))
2088 resolved = False
2089 for sm in static_mappings:
2090 if sm.external_sw_if_index == 0xFFFFFFFF:
2091 self.assertEqual(sm.external_ip_address[0:4],
2092 self.pg7.local_ip4n)
2093 self.assertEqual((sm.tag).split('\0', 1)[0], tag)
2094 resolved = True
2095 self.assertTrue(resolved)
Matus Fabian36532bd2017-01-23 23:42:28 -08002096
2097 # remove interface address and check static mappings
2098 self.pg7.unconfig_ip4()
Matus Fabian2ba92e32017-08-21 07:05:03 -07002099 static_mappings = self.vapi.nat44_static_mapping_dump()
Matus Fabianea2600a2018-03-28 04:06:26 -07002100 self.assertEqual(1, len(static_mappings))
2101 self.assertEqual(self.pg7.sw_if_index,
2102 static_mappings[0].external_sw_if_index)
2103 self.assertEqual((static_mappings[0].tag).split('\0', 1)[0], tag)
2104
2105 # configure interface address again and check static mappings
2106 self.pg7.config_ip4()
2107 static_mappings = self.vapi.nat44_static_mapping_dump()
2108 self.assertEqual(2, len(static_mappings))
2109 resolved = False
2110 for sm in static_mappings:
2111 if sm.external_sw_if_index == 0xFFFFFFFF:
2112 self.assertEqual(sm.external_ip_address[0:4],
2113 self.pg7.local_ip4n)
2114 self.assertEqual((sm.tag).split('\0', 1)[0], tag)
2115 resolved = True
2116 self.assertTrue(resolved)
2117
2118 # remove static mapping
2119 self.nat44_add_static_mapping(
2120 '1.2.3.4',
2121 external_sw_if_index=self.pg7.sw_if_index,
2122 tag=tag,
2123 is_add=0)
2124 static_mappings = self.vapi.nat44_static_mapping_dump()
Matus Fabian36532bd2017-01-23 23:42:28 -08002125 self.assertEqual(0, len(static_mappings))
2126
Matus Fabianab7a8052017-11-28 04:29:41 -08002127 def test_interface_addr_identity_nat(self):
2128 """ Identity NAT with addresses from interface """
2129
2130 port = 53053
2131 self.vapi.nat44_add_interface_addr(self.pg7.sw_if_index)
2132 self.vapi.nat44_add_del_identity_mapping(
2133 sw_if_index=self.pg7.sw_if_index,
2134 port=port,
2135 protocol=IP_PROTOS.tcp,
2136 addr_only=0)
2137
2138 # identity mappings with external interface
2139 identity_mappings = self.vapi.nat44_identity_mapping_dump()
2140 self.assertEqual(1, len(identity_mappings))
2141 self.assertEqual(self.pg7.sw_if_index,
2142 identity_mappings[0].sw_if_index)
2143
2144 # configure interface address and check identity mappings
2145 self.pg7.config_ip4()
2146 identity_mappings = self.vapi.nat44_identity_mapping_dump()
Matus Fabianea2600a2018-03-28 04:06:26 -07002147 resolved = False
2148 self.assertEqual(2, len(identity_mappings))
2149 for sm in identity_mappings:
2150 if sm.sw_if_index == 0xFFFFFFFF:
2151 self.assertEqual(identity_mappings[0].ip_address,
2152 self.pg7.local_ip4n)
2153 self.assertEqual(port, identity_mappings[0].port)
2154 self.assertEqual(IP_PROTOS.tcp, identity_mappings[0].protocol)
2155 resolved = True
2156 self.assertTrue(resolved)
Matus Fabianab7a8052017-11-28 04:29:41 -08002157
2158 # remove interface address and check identity mappings
2159 self.pg7.unconfig_ip4()
2160 identity_mappings = self.vapi.nat44_identity_mapping_dump()
Matus Fabianea2600a2018-03-28 04:06:26 -07002161 self.assertEqual(1, len(identity_mappings))
2162 self.assertEqual(self.pg7.sw_if_index,
2163 identity_mappings[0].sw_if_index)
Matus Fabianab7a8052017-11-28 04:29:41 -08002164
Matus Fabianeea28d72017-01-13 04:15:54 -08002165 def test_ipfix_nat44_sess(self):
Matus Fabian2ba92e32017-08-21 07:05:03 -07002166 """ IPFIX logging NAT44 session created/delted """
Matus Fabian6631e9c2017-05-24 01:52:20 -07002167 self.ipfix_domain_id = 10
2168 self.ipfix_src_port = 20202
2169 colector_port = 30303
2170 bind_layers(UDP, IPFIX, dport=30303)
Matus Fabian2ba92e32017-08-21 07:05:03 -07002171 self.nat44_add_address(self.nat_addr)
2172 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
2173 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
2174 is_inside=0)
Matus Fabianeea28d72017-01-13 04:15:54 -08002175 self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4n,
2176 src_address=self.pg3.local_ip4n,
2177 path_mtu=512,
Matus Fabian6631e9c2017-05-24 01:52:20 -07002178 template_interval=10,
2179 collector_port=colector_port)
Matus Fabian2ba92e32017-08-21 07:05:03 -07002180 self.vapi.nat_ipfix(domain_id=self.ipfix_domain_id,
2181 src_port=self.ipfix_src_port)
Matus Fabianeea28d72017-01-13 04:15:54 -08002182
2183 pkts = self.create_stream_in(self.pg0, self.pg1)
2184 self.pg0.add_stream(pkts)
2185 self.pg_enable_capture(self.pg_interfaces)
2186 self.pg_start()
2187 capture = self.pg1.get_capture(len(pkts))
2188 self.verify_capture_out(capture)
Matus Fabian2ba92e32017-08-21 07:05:03 -07002189 self.nat44_add_address(self.nat_addr, is_add=0)
Matus Fabianeea28d72017-01-13 04:15:54 -08002190 self.vapi.cli("ipfix flush") # FIXME this should be an API call
Matus Fabiana431ad12018-01-04 04:03:14 -08002191 capture = self.pg3.get_capture(9)
Matus Fabianeea28d72017-01-13 04:15:54 -08002192 ipfix = IPFIXDecoder()
2193 # first load template
2194 for p in capture:
2195 self.assertTrue(p.haslayer(IPFIX))
Matus Fabian6631e9c2017-05-24 01:52:20 -07002196 self.assertEqual(p[IP].src, self.pg3.local_ip4)
2197 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
2198 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
2199 self.assertEqual(p[UDP].dport, colector_port)
2200 self.assertEqual(p[IPFIX].observationDomainID,
2201 self.ipfix_domain_id)
Matus Fabianeea28d72017-01-13 04:15:54 -08002202 if p.haslayer(Template):
2203 ipfix.add_template(p.getlayer(Template))
2204 # verify events in data set
2205 for p in capture:
2206 if p.haslayer(Data):
2207 data = ipfix.decode_data_set(p.getlayer(Set))
2208 self.verify_ipfix_nat44_ses(data)
2209
2210 def test_ipfix_addr_exhausted(self):
Matus Fabian2ba92e32017-08-21 07:05:03 -07002211 """ IPFIX logging NAT addresses exhausted """
2212 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
2213 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
2214 is_inside=0)
Matus Fabianeea28d72017-01-13 04:15:54 -08002215 self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4n,
2216 src_address=self.pg3.local_ip4n,
2217 path_mtu=512,
2218 template_interval=10)
Matus Fabian2ba92e32017-08-21 07:05:03 -07002219 self.vapi.nat_ipfix(domain_id=self.ipfix_domain_id,
2220 src_port=self.ipfix_src_port)
Matus Fabianeea28d72017-01-13 04:15:54 -08002221
2222 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
2223 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
2224 TCP(sport=3025))
2225 self.pg0.add_stream(p)
2226 self.pg_enable_capture(self.pg_interfaces)
2227 self.pg_start()
Matus Fabian229c1aa2018-05-28 04:09:52 -07002228 self.pg1.assert_nothing_captured()
2229 sleep(1)
Matus Fabianeea28d72017-01-13 04:15:54 -08002230 self.vapi.cli("ipfix flush") # FIXME this should be an API call
Matus Fabiana431ad12018-01-04 04:03:14 -08002231 capture = self.pg3.get_capture(9)
Matus Fabianeea28d72017-01-13 04:15:54 -08002232 ipfix = IPFIXDecoder()
2233 # first load template
2234 for p in capture:
2235 self.assertTrue(p.haslayer(IPFIX))
Matus Fabian6631e9c2017-05-24 01:52:20 -07002236 self.assertEqual(p[IP].src, self.pg3.local_ip4)
2237 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
2238 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
2239 self.assertEqual(p[UDP].dport, 4739)
2240 self.assertEqual(p[IPFIX].observationDomainID,
2241 self.ipfix_domain_id)
Matus Fabianeea28d72017-01-13 04:15:54 -08002242 if p.haslayer(Template):
2243 ipfix.add_template(p.getlayer(Template))
2244 # verify events in data set
2245 for p in capture:
2246 if p.haslayer(Data):
2247 data = ipfix.decode_data_set(p.getlayer(Set))
2248 self.verify_ipfix_addr_exhausted(data)
2249
Matus Fabiana431ad12018-01-04 04:03:14 -08002250 @unittest.skipUnless(running_extended_tests(), "part of extended tests")
2251 def test_ipfix_max_sessions(self):
2252 """ IPFIX logging maximum session entries exceeded """
2253 self.nat44_add_address(self.nat_addr)
2254 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
2255 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
2256 is_inside=0)
2257
2258 nat44_config = self.vapi.nat_show_config()
2259 max_sessions = 10 * nat44_config.translation_buckets
2260
2261 pkts = []
2262 for i in range(0, max_sessions):
2263 src = "10.10.%u.%u" % ((i & 0xFF00) >> 8, i & 0xFF)
2264 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2265 IP(src=src, dst=self.pg1.remote_ip4) /
2266 TCP(sport=1025))
2267 pkts.append(p)
2268 self.pg0.add_stream(pkts)
2269 self.pg_enable_capture(self.pg_interfaces)
2270 self.pg_start()
2271
2272 self.pg1.get_capture(max_sessions)
2273 self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4n,
2274 src_address=self.pg3.local_ip4n,
2275 path_mtu=512,
2276 template_interval=10)
2277 self.vapi.nat_ipfix(domain_id=self.ipfix_domain_id,
2278 src_port=self.ipfix_src_port)
2279
2280 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2281 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
2282 TCP(sport=1025))
2283 self.pg0.add_stream(p)
2284 self.pg_enable_capture(self.pg_interfaces)
2285 self.pg_start()
Matus Fabian229c1aa2018-05-28 04:09:52 -07002286 self.pg1.assert_nothing_captured()
2287 sleep(1)
Matus Fabiana431ad12018-01-04 04:03:14 -08002288 self.vapi.cli("ipfix flush") # FIXME this should be an API call
2289 capture = self.pg3.get_capture(9)
2290 ipfix = IPFIXDecoder()
2291 # first load template
2292 for p in capture:
2293 self.assertTrue(p.haslayer(IPFIX))
2294 self.assertEqual(p[IP].src, self.pg3.local_ip4)
2295 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
2296 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
2297 self.assertEqual(p[UDP].dport, 4739)
2298 self.assertEqual(p[IPFIX].observationDomainID,
2299 self.ipfix_domain_id)
2300 if p.haslayer(Template):
2301 ipfix.add_template(p.getlayer(Template))
2302 # verify events in data set
2303 for p in capture:
2304 if p.haslayer(Data):
2305 data = ipfix.decode_data_set(p.getlayer(Set))
2306 self.verify_ipfix_max_sessions(data, max_sessions)
2307
Matus Fabiane1ae29a2017-01-27 00:47:58 -08002308 def test_pool_addr_fib(self):
Matus Fabian2ba92e32017-08-21 07:05:03 -07002309 """ NAT44 add pool addresses to FIB """
Matus Fabiane1ae29a2017-01-27 00:47:58 -08002310 static_addr = '10.0.0.10'
Matus Fabian2ba92e32017-08-21 07:05:03 -07002311 self.nat44_add_address(self.nat_addr)
2312 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
2313 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
2314 is_inside=0)
2315 self.nat44_add_static_mapping(self.pg0.remote_ip4, static_addr)
Matus Fabiane1ae29a2017-01-27 00:47:58 -08002316
Matus Fabian2ba92e32017-08-21 07:05:03 -07002317 # NAT44 address
Matus Fabiane1ae29a2017-01-27 00:47:58 -08002318 p = (Ether(src=self.pg1.remote_mac, dst='ff:ff:ff:ff:ff:ff') /
Matus Fabian2ba92e32017-08-21 07:05:03 -07002319 ARP(op=ARP.who_has, pdst=self.nat_addr,
Matus Fabiane1ae29a2017-01-27 00:47:58 -08002320 psrc=self.pg1.remote_ip4, hwsrc=self.pg1.remote_mac))
2321 self.pg1.add_stream(p)
2322 self.pg_enable_capture(self.pg_interfaces)
2323 self.pg_start()
2324 capture = self.pg1.get_capture(1)
2325 self.assertTrue(capture[0].haslayer(ARP))
2326 self.assertTrue(capture[0][ARP].op, ARP.is_at)
2327
2328 # 1:1 NAT address
2329 p = (Ether(src=self.pg1.remote_mac, dst='ff:ff:ff:ff:ff:ff') /
2330 ARP(op=ARP.who_has, pdst=static_addr,
2331 psrc=self.pg1.remote_ip4, hwsrc=self.pg1.remote_mac))
2332 self.pg1.add_stream(p)
2333 self.pg_enable_capture(self.pg_interfaces)
2334 self.pg_start()
2335 capture = self.pg1.get_capture(1)
2336 self.assertTrue(capture[0].haslayer(ARP))
2337 self.assertTrue(capture[0][ARP].op, ARP.is_at)
2338
Matus Fabian2ba92e32017-08-21 07:05:03 -07002339 # send ARP to non-NAT44 interface
Matus Fabiane1ae29a2017-01-27 00:47:58 -08002340 p = (Ether(src=self.pg2.remote_mac, dst='ff:ff:ff:ff:ff:ff') /
Matus Fabian2ba92e32017-08-21 07:05:03 -07002341 ARP(op=ARP.who_has, pdst=self.nat_addr,
Matus Fabiane1ae29a2017-01-27 00:47:58 -08002342 psrc=self.pg2.remote_ip4, hwsrc=self.pg2.remote_mac))
2343 self.pg2.add_stream(p)
2344 self.pg_enable_capture(self.pg_interfaces)
2345 self.pg_start()
Matus Fabian229c1aa2018-05-28 04:09:52 -07002346 self.pg1.assert_nothing_captured()
Matus Fabiane1ae29a2017-01-27 00:47:58 -08002347
2348 # remove addresses and verify
Matus Fabian2ba92e32017-08-21 07:05:03 -07002349 self.nat44_add_address(self.nat_addr, is_add=0)
2350 self.nat44_add_static_mapping(self.pg0.remote_ip4, static_addr,
2351 is_add=0)
Matus Fabiane1ae29a2017-01-27 00:47:58 -08002352
2353 p = (Ether(src=self.pg1.remote_mac, dst='ff:ff:ff:ff:ff:ff') /
Matus Fabian2ba92e32017-08-21 07:05:03 -07002354 ARP(op=ARP.who_has, pdst=self.nat_addr,
Matus Fabiane1ae29a2017-01-27 00:47:58 -08002355 psrc=self.pg1.remote_ip4, hwsrc=self.pg1.remote_mac))
2356 self.pg1.add_stream(p)
2357 self.pg_enable_capture(self.pg_interfaces)
2358 self.pg_start()
Matus Fabian229c1aa2018-05-28 04:09:52 -07002359 self.pg1.assert_nothing_captured()
Matus Fabiane1ae29a2017-01-27 00:47:58 -08002360
2361 p = (Ether(src=self.pg1.remote_mac, dst='ff:ff:ff:ff:ff:ff') /
2362 ARP(op=ARP.who_has, pdst=static_addr,
2363 psrc=self.pg1.remote_ip4, hwsrc=self.pg1.remote_mac))
2364 self.pg1.add_stream(p)
2365 self.pg_enable_capture(self.pg_interfaces)
2366 self.pg_start()
Matus Fabian229c1aa2018-05-28 04:09:52 -07002367 self.pg1.assert_nothing_captured()
Matus Fabiane1ae29a2017-01-27 00:47:58 -08002368
Juraj Slobodaeab38d92017-03-06 19:55:21 -08002369 def test_vrf_mode(self):
Matus Fabian2ba92e32017-08-21 07:05:03 -07002370 """ NAT44 tenant VRF aware address pool mode """
Juraj Slobodaeab38d92017-03-06 19:55:21 -08002371
2372 vrf_id1 = 1
2373 vrf_id2 = 2
2374 nat_ip1 = "10.0.0.10"
2375 nat_ip2 = "10.0.0.11"
2376
2377 self.pg0.unconfig_ip4()
2378 self.pg1.unconfig_ip4()
Neale Ranns15002542017-09-10 04:39:11 -07002379 self.vapi.ip_table_add_del(vrf_id1, is_add=1)
2380 self.vapi.ip_table_add_del(vrf_id2, is_add=1)
Juraj Slobodaeab38d92017-03-06 19:55:21 -08002381 self.pg0.set_table_ip4(vrf_id1)
2382 self.pg1.set_table_ip4(vrf_id2)
2383 self.pg0.config_ip4()
2384 self.pg1.config_ip4()
2385
Matus Fabian2ba92e32017-08-21 07:05:03 -07002386 self.nat44_add_address(nat_ip1, vrf_id=vrf_id1)
2387 self.nat44_add_address(nat_ip2, vrf_id=vrf_id2)
2388 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
2389 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index)
2390 self.vapi.nat44_interface_add_del_feature(self.pg2.sw_if_index,
2391 is_inside=0)
Juraj Slobodaeab38d92017-03-06 19:55:21 -08002392
2393 # first VRF
2394 pkts = self.create_stream_in(self.pg0, self.pg2)
2395 self.pg0.add_stream(pkts)
2396 self.pg_enable_capture(self.pg_interfaces)
2397 self.pg_start()
2398 capture = self.pg2.get_capture(len(pkts))
2399 self.verify_capture_out(capture, nat_ip1)
2400
2401 # second VRF
2402 pkts = self.create_stream_in(self.pg1, self.pg2)
2403 self.pg1.add_stream(pkts)
2404 self.pg_enable_capture(self.pg_interfaces)
2405 self.pg_start()
2406 capture = self.pg2.get_capture(len(pkts))
2407 self.verify_capture_out(capture, nat_ip2)
2408
Neale Ranns15002542017-09-10 04:39:11 -07002409 self.pg0.unconfig_ip4()
2410 self.pg1.unconfig_ip4()
2411 self.pg0.set_table_ip4(0)
2412 self.pg1.set_table_ip4(0)
2413 self.vapi.ip_table_add_del(vrf_id1, is_add=0)
2414 self.vapi.ip_table_add_del(vrf_id2, is_add=0)
2415
Juraj Slobodaeab38d92017-03-06 19:55:21 -08002416 def test_vrf_feature_independent(self):
Matus Fabian2ba92e32017-08-21 07:05:03 -07002417 """ NAT44 tenant VRF independent address pool mode """
Juraj Slobodaeab38d92017-03-06 19:55:21 -08002418
2419 nat_ip1 = "10.0.0.10"
2420 nat_ip2 = "10.0.0.11"
2421
Matus Fabian2ba92e32017-08-21 07:05:03 -07002422 self.nat44_add_address(nat_ip1)
Matus Fabian51e759f2017-12-07 23:22:51 -08002423 self.nat44_add_address(nat_ip2, vrf_id=99)
Matus Fabian2ba92e32017-08-21 07:05:03 -07002424 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
2425 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index)
2426 self.vapi.nat44_interface_add_del_feature(self.pg2.sw_if_index,
2427 is_inside=0)
Juraj Slobodaeab38d92017-03-06 19:55:21 -08002428
2429 # first VRF
2430 pkts = self.create_stream_in(self.pg0, self.pg2)
2431 self.pg0.add_stream(pkts)
2432 self.pg_enable_capture(self.pg_interfaces)
2433 self.pg_start()
2434 capture = self.pg2.get_capture(len(pkts))
2435 self.verify_capture_out(capture, nat_ip1)
2436
2437 # second VRF
2438 pkts = self.create_stream_in(self.pg1, self.pg2)
2439 self.pg1.add_stream(pkts)
2440 self.pg_enable_capture(self.pg_interfaces)
2441 self.pg_start()
2442 capture = self.pg2.get_capture(len(pkts))
2443 self.verify_capture_out(capture, nat_ip1)
2444
Martin Gálik406eb1d2017-05-04 04:35:04 -07002445 def test_dynamic_ipless_interfaces(self):
Matus Fabian2ba92e32017-08-21 07:05:03 -07002446 """ NAT44 interfaces without configured IP address """
Martin Gálik406eb1d2017-05-04 04:35:04 -07002447
2448 self.vapi.ip_neighbor_add_del(self.pg7.sw_if_index,
Ole Troan895b6e82017-10-20 13:28:20 +02002449 mactobinary(self.pg7.remote_mac),
Martin Gálik406eb1d2017-05-04 04:35:04 -07002450 self.pg7.remote_ip4n,
2451 is_static=1)
2452 self.vapi.ip_neighbor_add_del(self.pg8.sw_if_index,
Ole Troan895b6e82017-10-20 13:28:20 +02002453 mactobinary(self.pg8.remote_mac),
Martin Gálik406eb1d2017-05-04 04:35:04 -07002454 self.pg8.remote_ip4n,
2455 is_static=1)
2456
2457 self.vapi.ip_add_del_route(dst_address=self.pg7.remote_ip4n,
2458 dst_address_length=32,
2459 next_hop_address=self.pg7.remote_ip4n,
2460 next_hop_sw_if_index=self.pg7.sw_if_index)
2461 self.vapi.ip_add_del_route(dst_address=self.pg8.remote_ip4n,
2462 dst_address_length=32,
2463 next_hop_address=self.pg8.remote_ip4n,
2464 next_hop_sw_if_index=self.pg8.sw_if_index)
2465
Matus Fabian2ba92e32017-08-21 07:05:03 -07002466 self.nat44_add_address(self.nat_addr)
2467 self.vapi.nat44_interface_add_del_feature(self.pg7.sw_if_index)
2468 self.vapi.nat44_interface_add_del_feature(self.pg8.sw_if_index,
2469 is_inside=0)
Martin Gálik406eb1d2017-05-04 04:35:04 -07002470
2471 # in2out
2472 pkts = self.create_stream_in(self.pg7, self.pg8)
2473 self.pg7.add_stream(pkts)
2474 self.pg_enable_capture(self.pg_interfaces)
2475 self.pg_start()
2476 capture = self.pg8.get_capture(len(pkts))
2477 self.verify_capture_out(capture)
2478
2479 # out2in
Matus Fabian2ba92e32017-08-21 07:05:03 -07002480 pkts = self.create_stream_out(self.pg8, self.nat_addr)
Martin Gálik406eb1d2017-05-04 04:35:04 -07002481 self.pg8.add_stream(pkts)
2482 self.pg_enable_capture(self.pg_interfaces)
2483 self.pg_start()
2484 capture = self.pg7.get_capture(len(pkts))
2485 self.verify_capture_in(capture, self.pg7)
2486
2487 def test_static_ipless_interfaces(self):
Matus Fabian2ba92e32017-08-21 07:05:03 -07002488 """ NAT44 interfaces without configured IP address - 1:1 NAT """
Martin Gálik406eb1d2017-05-04 04:35:04 -07002489
2490 self.vapi.ip_neighbor_add_del(self.pg7.sw_if_index,
Ole Troan895b6e82017-10-20 13:28:20 +02002491 mactobinary(self.pg7.remote_mac),
Martin Gálik406eb1d2017-05-04 04:35:04 -07002492 self.pg7.remote_ip4n,
2493 is_static=1)
2494 self.vapi.ip_neighbor_add_del(self.pg8.sw_if_index,
Ole Troan895b6e82017-10-20 13:28:20 +02002495 mactobinary(self.pg8.remote_mac),
Martin Gálik406eb1d2017-05-04 04:35:04 -07002496 self.pg8.remote_ip4n,
2497 is_static=1)
2498
2499 self.vapi.ip_add_del_route(dst_address=self.pg7.remote_ip4n,
2500 dst_address_length=32,
2501 next_hop_address=self.pg7.remote_ip4n,
2502 next_hop_sw_if_index=self.pg7.sw_if_index)
2503 self.vapi.ip_add_del_route(dst_address=self.pg8.remote_ip4n,
2504 dst_address_length=32,
2505 next_hop_address=self.pg8.remote_ip4n,
2506 next_hop_sw_if_index=self.pg8.sw_if_index)
2507
Matus Fabian2ba92e32017-08-21 07:05:03 -07002508 self.nat44_add_static_mapping(self.pg7.remote_ip4, self.nat_addr)
2509 self.vapi.nat44_interface_add_del_feature(self.pg7.sw_if_index)
2510 self.vapi.nat44_interface_add_del_feature(self.pg8.sw_if_index,
2511 is_inside=0)
Martin Gálik406eb1d2017-05-04 04:35:04 -07002512
2513 # out2in
2514 pkts = self.create_stream_out(self.pg8)
2515 self.pg8.add_stream(pkts)
2516 self.pg_enable_capture(self.pg_interfaces)
2517 self.pg_start()
2518 capture = self.pg7.get_capture(len(pkts))
2519 self.verify_capture_in(capture, self.pg7)
2520
2521 # in2out
2522 pkts = self.create_stream_in(self.pg7, self.pg8)
2523 self.pg7.add_stream(pkts)
2524 self.pg_enable_capture(self.pg_interfaces)
2525 self.pg_start()
2526 capture = self.pg8.get_capture(len(pkts))
Matus Fabian2ba92e32017-08-21 07:05:03 -07002527 self.verify_capture_out(capture, self.nat_addr, True)
Martin Gálik406eb1d2017-05-04 04:35:04 -07002528
2529 def test_static_with_port_ipless_interfaces(self):
Matus Fabian2ba92e32017-08-21 07:05:03 -07002530 """ NAT44 interfaces without configured IP address - 1:1 NAPT """
Martin Gálik406eb1d2017-05-04 04:35:04 -07002531
2532 self.tcp_port_out = 30606
2533 self.udp_port_out = 30607
2534 self.icmp_id_out = 30608
2535
2536 self.vapi.ip_neighbor_add_del(self.pg7.sw_if_index,
Ole Troan895b6e82017-10-20 13:28:20 +02002537 mactobinary(self.pg7.remote_mac),
Martin Gálik406eb1d2017-05-04 04:35:04 -07002538 self.pg7.remote_ip4n,
2539 is_static=1)
2540 self.vapi.ip_neighbor_add_del(self.pg8.sw_if_index,
Ole Troan895b6e82017-10-20 13:28:20 +02002541 mactobinary(self.pg8.remote_mac),
Martin Gálik406eb1d2017-05-04 04:35:04 -07002542 self.pg8.remote_ip4n,
2543 is_static=1)
2544
2545 self.vapi.ip_add_del_route(dst_address=self.pg7.remote_ip4n,
2546 dst_address_length=32,
2547 next_hop_address=self.pg7.remote_ip4n,
2548 next_hop_sw_if_index=self.pg7.sw_if_index)
2549 self.vapi.ip_add_del_route(dst_address=self.pg8.remote_ip4n,
2550 dst_address_length=32,
2551 next_hop_address=self.pg8.remote_ip4n,
2552 next_hop_sw_if_index=self.pg8.sw_if_index)
2553
Matus Fabian2ba92e32017-08-21 07:05:03 -07002554 self.nat44_add_address(self.nat_addr)
2555 self.nat44_add_static_mapping(self.pg7.remote_ip4, self.nat_addr,
2556 self.tcp_port_in, self.tcp_port_out,
2557 proto=IP_PROTOS.tcp)
2558 self.nat44_add_static_mapping(self.pg7.remote_ip4, self.nat_addr,
2559 self.udp_port_in, self.udp_port_out,
2560 proto=IP_PROTOS.udp)
2561 self.nat44_add_static_mapping(self.pg7.remote_ip4, self.nat_addr,
2562 self.icmp_id_in, self.icmp_id_out,
2563 proto=IP_PROTOS.icmp)
2564 self.vapi.nat44_interface_add_del_feature(self.pg7.sw_if_index)
2565 self.vapi.nat44_interface_add_del_feature(self.pg8.sw_if_index,
2566 is_inside=0)
Martin Gálik406eb1d2017-05-04 04:35:04 -07002567
2568 # out2in
2569 pkts = self.create_stream_out(self.pg8)
2570 self.pg8.add_stream(pkts)
2571 self.pg_enable_capture(self.pg_interfaces)
2572 self.pg_start()
2573 capture = self.pg7.get_capture(len(pkts))
2574 self.verify_capture_in(capture, self.pg7)
2575
2576 # in2out
2577 pkts = self.create_stream_in(self.pg7, self.pg8)
2578 self.pg7.add_stream(pkts)
2579 self.pg_enable_capture(self.pg_interfaces)
2580 self.pg_start()
2581 capture = self.pg8.get_capture(len(pkts))
2582 self.verify_capture_out(capture)
2583
Matus Fabian328dbc82017-06-19 04:28:04 -07002584 def test_static_unknown_proto(self):
2585 """ 1:1 NAT translate packet with unknown protocol """
2586 nat_ip = "10.0.0.10"
Matus Fabian2ba92e32017-08-21 07:05:03 -07002587 self.nat44_add_static_mapping(self.pg0.remote_ip4, nat_ip)
2588 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
2589 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
2590 is_inside=0)
Matus Fabian328dbc82017-06-19 04:28:04 -07002591
2592 # in2out
2593 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2594 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
2595 GRE() /
Matus Fabian1e8db5f2017-06-20 01:45:49 -07002596 IP(src=self.pg2.remote_ip4, dst=self.pg3.remote_ip4) /
Matus Fabian328dbc82017-06-19 04:28:04 -07002597 TCP(sport=1234, dport=1234))
2598 self.pg0.add_stream(p)
2599 self.pg_enable_capture(self.pg_interfaces)
2600 self.pg_start()
2601 p = self.pg1.get_capture(1)
2602 packet = p[0]
2603 try:
2604 self.assertEqual(packet[IP].src, nat_ip)
2605 self.assertEqual(packet[IP].dst, self.pg1.remote_ip4)
2606 self.assertTrue(packet.haslayer(GRE))
Klement Sekerad81ae412018-05-16 10:52:54 +02002607 self.assert_packet_checksums_valid(packet)
Matus Fabian328dbc82017-06-19 04:28:04 -07002608 except:
2609 self.logger.error(ppp("Unexpected or invalid packet:", packet))
2610 raise
2611
2612 # out2in
2613 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
2614 IP(src=self.pg1.remote_ip4, dst=nat_ip) /
2615 GRE() /
Matus Fabian1e8db5f2017-06-20 01:45:49 -07002616 IP(src=self.pg3.remote_ip4, dst=self.pg2.remote_ip4) /
Matus Fabian328dbc82017-06-19 04:28:04 -07002617 TCP(sport=1234, dport=1234))
2618 self.pg1.add_stream(p)
2619 self.pg_enable_capture(self.pg_interfaces)
2620 self.pg_start()
2621 p = self.pg0.get_capture(1)
2622 packet = p[0]
2623 try:
2624 self.assertEqual(packet[IP].src, self.pg1.remote_ip4)
2625 self.assertEqual(packet[IP].dst, self.pg0.remote_ip4)
2626 self.assertTrue(packet.haslayer(GRE))
Klement Sekerad81ae412018-05-16 10:52:54 +02002627 self.assert_packet_checksums_valid(packet)
Matus Fabian328dbc82017-06-19 04:28:04 -07002628 except:
2629 self.logger.error(ppp("Unexpected or invalid packet:", packet))
2630 raise
2631
Matus Fabian7968e6c2017-07-06 05:37:49 -07002632 def test_hairpinning_static_unknown_proto(self):
Matus Fabian1e8db5f2017-06-20 01:45:49 -07002633 """ 1:1 NAT translate packet with unknown protocol - hairpinning """
2634
2635 host = self.pg0.remote_hosts[0]
2636 server = self.pg0.remote_hosts[1]
2637
2638 host_nat_ip = "10.0.0.10"
2639 server_nat_ip = "10.0.0.11"
2640
Matus Fabian2ba92e32017-08-21 07:05:03 -07002641 self.nat44_add_static_mapping(host.ip4, host_nat_ip)
2642 self.nat44_add_static_mapping(server.ip4, server_nat_ip)
2643 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
2644 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
2645 is_inside=0)
Matus Fabian1e8db5f2017-06-20 01:45:49 -07002646
2647 # host to server
2648 p = (Ether(dst=self.pg0.local_mac, src=host.mac) /
2649 IP(src=host.ip4, dst=server_nat_ip) /
2650 GRE() /
2651 IP(src=self.pg2.remote_ip4, dst=self.pg3.remote_ip4) /
2652 TCP(sport=1234, dport=1234))
2653 self.pg0.add_stream(p)
2654 self.pg_enable_capture(self.pg_interfaces)
2655 self.pg_start()
2656 p = self.pg0.get_capture(1)
2657 packet = p[0]
2658 try:
2659 self.assertEqual(packet[IP].src, host_nat_ip)
2660 self.assertEqual(packet[IP].dst, server.ip4)
2661 self.assertTrue(packet.haslayer(GRE))
Klement Sekerad81ae412018-05-16 10:52:54 +02002662 self.assert_packet_checksums_valid(packet)
Matus Fabian1e8db5f2017-06-20 01:45:49 -07002663 except:
2664 self.logger.error(ppp("Unexpected or invalid packet:", packet))
2665 raise
2666
2667 # server to host
2668 p = (Ether(dst=self.pg0.local_mac, src=server.mac) /
2669 IP(src=server.ip4, dst=host_nat_ip) /
2670 GRE() /
2671 IP(src=self.pg3.remote_ip4, dst=self.pg2.remote_ip4) /
2672 TCP(sport=1234, dport=1234))
2673 self.pg0.add_stream(p)
2674 self.pg_enable_capture(self.pg_interfaces)
2675 self.pg_start()
2676 p = self.pg0.get_capture(1)
2677 packet = p[0]
2678 try:
2679 self.assertEqual(packet[IP].src, server_nat_ip)
2680 self.assertEqual(packet[IP].dst, host.ip4)
2681 self.assertTrue(packet.haslayer(GRE))
Klement Sekerad81ae412018-05-16 10:52:54 +02002682 self.assert_packet_checksums_valid(packet)
Matus Fabian1e8db5f2017-06-20 01:45:49 -07002683 except:
2684 self.logger.error(ppp("Unexpected or invalid packet:", packet))
2685 raise
2686
Matus Fabian93d84c92017-07-19 08:06:01 -07002687 def test_output_feature(self):
Matus Fabian2ba92e32017-08-21 07:05:03 -07002688 """ NAT44 interface output feature (in2out postrouting) """
2689 self.nat44_add_address(self.nat_addr)
2690 self.vapi.nat44_interface_add_del_output_feature(self.pg0.sw_if_index)
Matus Fabianb2d2fc72017-09-10 22:17:47 -07002691 self.vapi.nat44_interface_add_del_output_feature(self.pg1.sw_if_index)
2692 self.vapi.nat44_interface_add_del_output_feature(self.pg3.sw_if_index,
Matus Fabian2ba92e32017-08-21 07:05:03 -07002693 is_inside=0)
Matus Fabian93d84c92017-07-19 08:06:01 -07002694
2695 # in2out
Matus Fabianb2d2fc72017-09-10 22:17:47 -07002696 pkts = self.create_stream_in(self.pg0, self.pg3)
Matus Fabian93d84c92017-07-19 08:06:01 -07002697 self.pg0.add_stream(pkts)
2698 self.pg_enable_capture(self.pg_interfaces)
2699 self.pg_start()
Matus Fabianb2d2fc72017-09-10 22:17:47 -07002700 capture = self.pg3.get_capture(len(pkts))
Matus Fabian93d84c92017-07-19 08:06:01 -07002701 self.verify_capture_out(capture)
2702
2703 # out2in
Matus Fabianb2d2fc72017-09-10 22:17:47 -07002704 pkts = self.create_stream_out(self.pg3)
2705 self.pg3.add_stream(pkts)
Matus Fabian93d84c92017-07-19 08:06:01 -07002706 self.pg_enable_capture(self.pg_interfaces)
2707 self.pg_start()
2708 capture = self.pg0.get_capture(len(pkts))
2709 self.verify_capture_in(capture, self.pg0)
2710
Matus Fabianb2d2fc72017-09-10 22:17:47 -07002711 # from non-NAT interface to NAT inside interface
2712 pkts = self.create_stream_in(self.pg2, self.pg0)
2713 self.pg2.add_stream(pkts)
2714 self.pg_enable_capture(self.pg_interfaces)
2715 self.pg_start()
2716 capture = self.pg0.get_capture(len(pkts))
2717 self.verify_capture_no_translation(capture, self.pg2, self.pg0)
2718
Matus Fabian93d84c92017-07-19 08:06:01 -07002719 def test_output_feature_vrf_aware(self):
Matus Fabian2ba92e32017-08-21 07:05:03 -07002720 """ NAT44 interface output feature VRF aware (in2out postrouting) """
Matus Fabian93d84c92017-07-19 08:06:01 -07002721 nat_ip_vrf10 = "10.0.0.10"
2722 nat_ip_vrf20 = "10.0.0.20"
2723
2724 self.vapi.ip_add_del_route(dst_address=self.pg3.remote_ip4n,
2725 dst_address_length=32,
2726 next_hop_address=self.pg3.remote_ip4n,
2727 next_hop_sw_if_index=self.pg3.sw_if_index,
2728 table_id=10)
2729 self.vapi.ip_add_del_route(dst_address=self.pg3.remote_ip4n,
2730 dst_address_length=32,
2731 next_hop_address=self.pg3.remote_ip4n,
2732 next_hop_sw_if_index=self.pg3.sw_if_index,
2733 table_id=20)
2734
Matus Fabian2ba92e32017-08-21 07:05:03 -07002735 self.nat44_add_address(nat_ip_vrf10, vrf_id=10)
2736 self.nat44_add_address(nat_ip_vrf20, vrf_id=20)
2737 self.vapi.nat44_interface_add_del_output_feature(self.pg4.sw_if_index)
2738 self.vapi.nat44_interface_add_del_output_feature(self.pg6.sw_if_index)
2739 self.vapi.nat44_interface_add_del_output_feature(self.pg3.sw_if_index,
2740 is_inside=0)
Matus Fabian93d84c92017-07-19 08:06:01 -07002741
2742 # in2out VRF 10
2743 pkts = self.create_stream_in(self.pg4, self.pg3)
2744 self.pg4.add_stream(pkts)
2745 self.pg_enable_capture(self.pg_interfaces)
2746 self.pg_start()
2747 capture = self.pg3.get_capture(len(pkts))
2748 self.verify_capture_out(capture, nat_ip=nat_ip_vrf10)
2749
2750 # out2in VRF 10
2751 pkts = self.create_stream_out(self.pg3, dst_ip=nat_ip_vrf10)
2752 self.pg3.add_stream(pkts)
2753 self.pg_enable_capture(self.pg_interfaces)
2754 self.pg_start()
2755 capture = self.pg4.get_capture(len(pkts))
2756 self.verify_capture_in(capture, self.pg4)
2757
2758 # in2out VRF 20
2759 pkts = self.create_stream_in(self.pg6, self.pg3)
2760 self.pg6.add_stream(pkts)
2761 self.pg_enable_capture(self.pg_interfaces)
2762 self.pg_start()
2763 capture = self.pg3.get_capture(len(pkts))
2764 self.verify_capture_out(capture, nat_ip=nat_ip_vrf20)
2765
2766 # out2in VRF 20
2767 pkts = self.create_stream_out(self.pg3, dst_ip=nat_ip_vrf20)
2768 self.pg3.add_stream(pkts)
2769 self.pg_enable_capture(self.pg_interfaces)
2770 self.pg_start()
2771 capture = self.pg6.get_capture(len(pkts))
2772 self.verify_capture_in(capture, self.pg6)
2773
Matus Fabian161c59c2017-07-21 03:46:03 -07002774 def test_output_feature_hairpinning(self):
Matus Fabian2ba92e32017-08-21 07:05:03 -07002775 """ NAT44 interface output feature hairpinning (in2out postrouting) """
Matus Fabian93d84c92017-07-19 08:06:01 -07002776 host = self.pg0.remote_hosts[0]
2777 server = self.pg0.remote_hosts[1]
2778 host_in_port = 1234
2779 host_out_port = 0
2780 server_in_port = 5678
2781 server_out_port = 8765
2782
Matus Fabian2ba92e32017-08-21 07:05:03 -07002783 self.nat44_add_address(self.nat_addr)
2784 self.vapi.nat44_interface_add_del_output_feature(self.pg0.sw_if_index)
2785 self.vapi.nat44_interface_add_del_output_feature(self.pg1.sw_if_index,
2786 is_inside=0)
Matus Fabian93d84c92017-07-19 08:06:01 -07002787
2788 # add static mapping for server
Matus Fabian2ba92e32017-08-21 07:05:03 -07002789 self.nat44_add_static_mapping(server.ip4, self.nat_addr,
2790 server_in_port, server_out_port,
2791 proto=IP_PROTOS.tcp)
Matus Fabian93d84c92017-07-19 08:06:01 -07002792
2793 # send packet from host to server
2794 p = (Ether(src=host.mac, dst=self.pg0.local_mac) /
Matus Fabian2ba92e32017-08-21 07:05:03 -07002795 IP(src=host.ip4, dst=self.nat_addr) /
Matus Fabian93d84c92017-07-19 08:06:01 -07002796 TCP(sport=host_in_port, dport=server_out_port))
2797 self.pg0.add_stream(p)
2798 self.pg_enable_capture(self.pg_interfaces)
2799 self.pg_start()
2800 capture = self.pg0.get_capture(1)
2801 p = capture[0]
2802 try:
2803 ip = p[IP]
2804 tcp = p[TCP]
Matus Fabian2ba92e32017-08-21 07:05:03 -07002805 self.assertEqual(ip.src, self.nat_addr)
Matus Fabian93d84c92017-07-19 08:06:01 -07002806 self.assertEqual(ip.dst, server.ip4)
2807 self.assertNotEqual(tcp.sport, host_in_port)
2808 self.assertEqual(tcp.dport, server_in_port)
Klement Sekerad81ae412018-05-16 10:52:54 +02002809 self.assert_packet_checksums_valid(p)
Matus Fabian93d84c92017-07-19 08:06:01 -07002810 host_out_port = tcp.sport
2811 except:
2812 self.logger.error(ppp("Unexpected or invalid packet:", p))
2813 raise
2814
2815 # send reply from server to host
2816 p = (Ether(src=server.mac, dst=self.pg0.local_mac) /
Matus Fabian2ba92e32017-08-21 07:05:03 -07002817 IP(src=server.ip4, dst=self.nat_addr) /
Matus Fabian93d84c92017-07-19 08:06:01 -07002818 TCP(sport=server_in_port, dport=host_out_port))
2819 self.pg0.add_stream(p)
2820 self.pg_enable_capture(self.pg_interfaces)
2821 self.pg_start()
2822 capture = self.pg0.get_capture(1)
2823 p = capture[0]
2824 try:
2825 ip = p[IP]
2826 tcp = p[TCP]
Matus Fabian2ba92e32017-08-21 07:05:03 -07002827 self.assertEqual(ip.src, self.nat_addr)
Matus Fabian93d84c92017-07-19 08:06:01 -07002828 self.assertEqual(ip.dst, host.ip4)
2829 self.assertEqual(tcp.sport, server_out_port)
2830 self.assertEqual(tcp.dport, host_in_port)
Klement Sekerad81ae412018-05-16 10:52:54 +02002831 self.assert_packet_checksums_valid(p)
Matus Fabian93d84c92017-07-19 08:06:01 -07002832 except:
Matus Fabiane82488f2018-01-18 03:38:45 -08002833 self.logger.error(ppp("Unexpected or invalid packet:", p))
Matus Fabian93d84c92017-07-19 08:06:01 -07002834 raise
2835
Matus Fabian36ea2d62017-10-24 04:13:49 -07002836 def test_one_armed_nat44(self):
2837 """ One armed NAT44 """
2838 remote_host = self.pg9.remote_hosts[0]
2839 local_host = self.pg9.remote_hosts[1]
2840 external_port = 0
2841
2842 self.nat44_add_address(self.nat_addr)
2843 self.vapi.nat44_interface_add_del_feature(self.pg9.sw_if_index)
2844 self.vapi.nat44_interface_add_del_feature(self.pg9.sw_if_index,
2845 is_inside=0)
2846
2847 # in2out
2848 p = (Ether(src=self.pg9.remote_mac, dst=self.pg9.local_mac) /
2849 IP(src=local_host.ip4, dst=remote_host.ip4) /
2850 TCP(sport=12345, dport=80))
2851 self.pg9.add_stream(p)
2852 self.pg_enable_capture(self.pg_interfaces)
2853 self.pg_start()
2854 capture = self.pg9.get_capture(1)
2855 p = capture[0]
2856 try:
2857 ip = p[IP]
2858 tcp = p[TCP]
2859 self.assertEqual(ip.src, self.nat_addr)
2860 self.assertEqual(ip.dst, remote_host.ip4)
2861 self.assertNotEqual(tcp.sport, 12345)
2862 external_port = tcp.sport
2863 self.assertEqual(tcp.dport, 80)
Klement Sekerad81ae412018-05-16 10:52:54 +02002864 self.assert_packet_checksums_valid(p)
Matus Fabian36ea2d62017-10-24 04:13:49 -07002865 except:
2866 self.logger.error(ppp("Unexpected or invalid packet:", p))
2867 raise
2868
2869 # out2in
2870 p = (Ether(src=self.pg9.remote_mac, dst=self.pg9.local_mac) /
2871 IP(src=remote_host.ip4, dst=self.nat_addr) /
2872 TCP(sport=80, dport=external_port))
2873 self.pg9.add_stream(p)
2874 self.pg_enable_capture(self.pg_interfaces)
2875 self.pg_start()
2876 capture = self.pg9.get_capture(1)
2877 p = capture[0]
2878 try:
2879 ip = p[IP]
2880 tcp = p[TCP]
2881 self.assertEqual(ip.src, remote_host.ip4)
2882 self.assertEqual(ip.dst, local_host.ip4)
2883 self.assertEqual(tcp.sport, 80)
2884 self.assertEqual(tcp.dport, 12345)
Klement Sekerad81ae412018-05-16 10:52:54 +02002885 self.assert_packet_checksums_valid(p)
Matus Fabian36ea2d62017-10-24 04:13:49 -07002886 except:
2887 self.logger.error(ppp("Unexpected or invalid packet:", p))
2888 raise
2889
Matus Fabian5ba86f72017-10-26 03:37:38 -07002890 def test_del_session(self):
2891 """ Delete NAT44 session """
2892 self.nat44_add_address(self.nat_addr)
2893 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
2894 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
2895 is_inside=0)
2896
2897 pkts = self.create_stream_in(self.pg0, self.pg1)
2898 self.pg0.add_stream(pkts)
2899 self.pg_enable_capture(self.pg_interfaces)
2900 self.pg_start()
Matus Fabian229c1aa2018-05-28 04:09:52 -07002901 self.pg1.get_capture(len(pkts))
Matus Fabian5ba86f72017-10-26 03:37:38 -07002902
2903 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n, 0)
2904 nsessions = len(sessions)
2905
2906 self.vapi.nat44_del_session(sessions[0].inside_ip_address,
2907 sessions[0].inside_port,
2908 sessions[0].protocol)
2909 self.vapi.nat44_del_session(sessions[1].outside_ip_address,
2910 sessions[1].outside_port,
2911 sessions[1].protocol,
2912 is_in=0)
2913
2914 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n, 0)
2915 self.assertEqual(nsessions - len(sessions), 2)
2916
Matus Fabianefcd1e92017-08-15 06:59:19 -07002917 def test_set_get_reass(self):
2918 """ NAT44 set/get virtual fragmentation reassembly """
2919 reas_cfg1 = self.vapi.nat_get_reass()
2920
2921 self.vapi.nat_set_reass(timeout=reas_cfg1.ip4_timeout + 5,
2922 max_reass=reas_cfg1.ip4_max_reass * 2,
2923 max_frag=reas_cfg1.ip4_max_frag * 2)
2924
2925 reas_cfg2 = self.vapi.nat_get_reass()
2926
2927 self.assertEqual(reas_cfg1.ip4_timeout + 5, reas_cfg2.ip4_timeout)
2928 self.assertEqual(reas_cfg1.ip4_max_reass * 2, reas_cfg2.ip4_max_reass)
2929 self.assertEqual(reas_cfg1.ip4_max_frag * 2, reas_cfg2.ip4_max_frag)
2930
2931 self.vapi.nat_set_reass(drop_frag=1)
2932 self.assertTrue(self.vapi.nat_get_reass().ip4_drop_frag)
2933
2934 def test_frag_in_order(self):
2935 """ NAT44 translate fragments arriving in order """
2936 self.nat44_add_address(self.nat_addr)
2937 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
2938 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
2939 is_inside=0)
2940
2941 data = "A" * 4 + "B" * 16 + "C" * 3
2942 self.tcp_port_in = random.randint(1025, 65535)
2943
2944 reass = self.vapi.nat_reass_dump()
2945 reass_n_start = len(reass)
2946
2947 # in2out
2948 pkts = self.create_stream_frag(self.pg0,
2949 self.pg1.remote_ip4,
2950 self.tcp_port_in,
2951 20,
2952 data)
2953 self.pg0.add_stream(pkts)
2954 self.pg_enable_capture(self.pg_interfaces)
2955 self.pg_start()
2956 frags = self.pg1.get_capture(len(pkts))
2957 p = self.reass_frags_and_verify(frags,
2958 self.nat_addr,
2959 self.pg1.remote_ip4)
2960 self.assertEqual(p[TCP].dport, 20)
2961 self.assertNotEqual(p[TCP].sport, self.tcp_port_in)
2962 self.tcp_port_out = p[TCP].sport
2963 self.assertEqual(data, p[Raw].load)
2964
2965 # out2in
2966 pkts = self.create_stream_frag(self.pg1,
2967 self.nat_addr,
2968 20,
2969 self.tcp_port_out,
2970 data)
2971 self.pg1.add_stream(pkts)
2972 self.pg_enable_capture(self.pg_interfaces)
2973 self.pg_start()
2974 frags = self.pg0.get_capture(len(pkts))
2975 p = self.reass_frags_and_verify(frags,
2976 self.pg1.remote_ip4,
2977 self.pg0.remote_ip4)
2978 self.assertEqual(p[TCP].sport, 20)
2979 self.assertEqual(p[TCP].dport, self.tcp_port_in)
2980 self.assertEqual(data, p[Raw].load)
2981
2982 reass = self.vapi.nat_reass_dump()
2983 reass_n_end = len(reass)
2984
2985 self.assertEqual(reass_n_end - reass_n_start, 2)
2986
2987 def test_reass_hairpinning(self):
2988 """ NAT44 fragments hairpinning """
Matus Fabianefcd1e92017-08-15 06:59:19 -07002989 server = self.pg0.remote_hosts[1]
2990 host_in_port = random.randint(1025, 65535)
Matus Fabianefcd1e92017-08-15 06:59:19 -07002991 server_in_port = random.randint(1025, 65535)
2992 server_out_port = random.randint(1025, 65535)
2993 data = "A" * 4 + "B" * 16 + "C" * 3
2994
2995 self.nat44_add_address(self.nat_addr)
2996 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
2997 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
2998 is_inside=0)
2999 # add static mapping for server
3000 self.nat44_add_static_mapping(server.ip4, self.nat_addr,
3001 server_in_port, server_out_port,
3002 proto=IP_PROTOS.tcp)
3003
3004 # send packet from host to server
3005 pkts = self.create_stream_frag(self.pg0,
3006 self.nat_addr,
3007 host_in_port,
3008 server_out_port,
3009 data)
3010 self.pg0.add_stream(pkts)
3011 self.pg_enable_capture(self.pg_interfaces)
3012 self.pg_start()
3013 frags = self.pg0.get_capture(len(pkts))
3014 p = self.reass_frags_and_verify(frags,
3015 self.nat_addr,
3016 server.ip4)
3017 self.assertNotEqual(p[TCP].sport, host_in_port)
3018 self.assertEqual(p[TCP].dport, server_in_port)
3019 self.assertEqual(data, p[Raw].load)
3020
3021 def test_frag_out_of_order(self):
3022 """ NAT44 translate fragments arriving out of order """
3023 self.nat44_add_address(self.nat_addr)
3024 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3025 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3026 is_inside=0)
3027
3028 data = "A" * 4 + "B" * 16 + "C" * 3
3029 random.randint(1025, 65535)
3030
3031 # in2out
3032 pkts = self.create_stream_frag(self.pg0,
3033 self.pg1.remote_ip4,
3034 self.tcp_port_in,
3035 20,
3036 data)
3037 pkts.reverse()
3038 self.pg0.add_stream(pkts)
3039 self.pg_enable_capture(self.pg_interfaces)
3040 self.pg_start()
3041 frags = self.pg1.get_capture(len(pkts))
3042 p = self.reass_frags_and_verify(frags,
3043 self.nat_addr,
3044 self.pg1.remote_ip4)
3045 self.assertEqual(p[TCP].dport, 20)
3046 self.assertNotEqual(p[TCP].sport, self.tcp_port_in)
3047 self.tcp_port_out = p[TCP].sport
3048 self.assertEqual(data, p[Raw].load)
3049
3050 # out2in
3051 pkts = self.create_stream_frag(self.pg1,
3052 self.nat_addr,
3053 20,
3054 self.tcp_port_out,
3055 data)
3056 pkts.reverse()
3057 self.pg1.add_stream(pkts)
3058 self.pg_enable_capture(self.pg_interfaces)
3059 self.pg_start()
3060 frags = self.pg0.get_capture(len(pkts))
3061 p = self.reass_frags_and_verify(frags,
3062 self.pg1.remote_ip4,
3063 self.pg0.remote_ip4)
3064 self.assertEqual(p[TCP].sport, 20)
3065 self.assertEqual(p[TCP].dport, self.tcp_port_in)
3066 self.assertEqual(data, p[Raw].load)
3067
Matus Fabian27697102017-11-09 01:43:47 -08003068 def test_port_restricted(self):
3069 """ Port restricted NAT44 (MAP-E CE) """
3070 self.nat44_add_address(self.nat_addr)
3071 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3072 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3073 is_inside=0)
Matus Fabian51e759f2017-12-07 23:22:51 -08003074 self.vapi.cli("nat addr-port-assignment-alg map-e psid 10 "
Matus Fabian27697102017-11-09 01:43:47 -08003075 "psid-offset 6 psid-len 6")
3076
3077 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
3078 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
3079 TCP(sport=4567, dport=22))
3080 self.pg0.add_stream(p)
3081 self.pg_enable_capture(self.pg_interfaces)
3082 self.pg_start()
3083 capture = self.pg1.get_capture(1)
3084 p = capture[0]
3085 try:
3086 ip = p[IP]
3087 tcp = p[TCP]
3088 self.assertEqual(ip.dst, self.pg1.remote_ip4)
3089 self.assertEqual(ip.src, self.nat_addr)
3090 self.assertEqual(tcp.dport, 22)
3091 self.assertNotEqual(tcp.sport, 4567)
3092 self.assertEqual((tcp.sport >> 6) & 63, 10)
Klement Sekerad81ae412018-05-16 10:52:54 +02003093 self.assert_packet_checksums_valid(p)
Matus Fabian27697102017-11-09 01:43:47 -08003094 except:
3095 self.logger.error(ppp("Unexpected or invalid packet:", p))
3096 raise
3097
Matus Fabiana6110b62018-06-13 05:39:07 -07003098 def test_ipfix_max_frags(self):
3099 """ IPFIX logging maximum fragments pending reassembly exceeded """
3100 self.nat44_add_address(self.nat_addr)
3101 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3102 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3103 is_inside=0)
3104 self.vapi.nat_set_reass(max_frag=0)
3105 self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4n,
3106 src_address=self.pg3.local_ip4n,
3107 path_mtu=512,
3108 template_interval=10)
3109 self.vapi.nat_ipfix(domain_id=self.ipfix_domain_id,
3110 src_port=self.ipfix_src_port)
3111
3112 data = "A" * 4 + "B" * 16 + "C" * 3
3113 self.tcp_port_in = random.randint(1025, 65535)
3114 pkts = self.create_stream_frag(self.pg0,
3115 self.pg1.remote_ip4,
3116 self.tcp_port_in,
3117 20,
3118 data)
3119 self.pg0.add_stream(pkts[-1])
3120 self.pg_enable_capture(self.pg_interfaces)
3121 self.pg_start()
3122 self.pg1.assert_nothing_captured()
3123 sleep(1)
3124 self.vapi.cli("ipfix flush") # FIXME this should be an API call
3125 capture = self.pg3.get_capture(9)
3126 ipfix = IPFIXDecoder()
3127 # first load template
3128 for p in capture:
3129 self.assertTrue(p.haslayer(IPFIX))
3130 self.assertEqual(p[IP].src, self.pg3.local_ip4)
3131 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
3132 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
3133 self.assertEqual(p[UDP].dport, 4739)
3134 self.assertEqual(p[IPFIX].observationDomainID,
3135 self.ipfix_domain_id)
3136 if p.haslayer(Template):
3137 ipfix.add_template(p.getlayer(Template))
3138 # verify events in data set
3139 for p in capture:
3140 if p.haslayer(Data):
3141 data = ipfix.decode_data_set(p.getlayer(Set))
3142 self.verify_ipfix_max_fragments_ip4(data, 0,
3143 self.pg0.remote_ip4n)
3144
3145 def tearDown(self):
3146 super(TestNAT44, self).tearDown()
3147 if not self.vpp_dead:
3148 self.logger.info(self.vapi.cli("show nat44 addresses"))
3149 self.logger.info(self.vapi.cli("show nat44 interfaces"))
3150 self.logger.info(self.vapi.cli("show nat44 static mappings"))
3151 self.logger.info(self.vapi.cli("show nat44 interface address"))
3152 self.logger.info(self.vapi.cli("show nat44 sessions detail"))
3153 self.logger.info(self.vapi.cli("show nat virtual-reassembly"))
3154 self.logger.info(self.vapi.cli("show nat44 hash tables detail"))
3155 self.vapi.cli("nat addr-port-assignment-alg default")
3156 self.clear_nat44()
3157 self.vapi.cli("clear logging")
3158
3159
3160class TestNAT44EndpointDependent(MethodHolder):
3161 """ Endpoint-Dependent mapping and filtering test cases """
3162
3163 @classmethod
3164 def setUpConstants(cls):
3165 super(TestNAT44EndpointDependent, cls).setUpConstants()
3166 cls.vpp_cmdline.extend(["nat", "{", "endpoint-dependent", "}"])
3167
3168 @classmethod
3169 def setUpClass(cls):
3170 super(TestNAT44EndpointDependent, cls).setUpClass()
3171 cls.vapi.cli("set log class nat level debug")
3172 try:
3173 cls.tcp_port_in = 6303
3174 cls.tcp_port_out = 6303
3175 cls.udp_port_in = 6304
3176 cls.udp_port_out = 6304
3177 cls.icmp_id_in = 6305
3178 cls.icmp_id_out = 6305
3179 cls.nat_addr = '10.0.0.3'
3180 cls.nat_addr_n = socket.inet_pton(socket.AF_INET, cls.nat_addr)
3181 cls.ipfix_src_port = 4739
3182 cls.ipfix_domain_id = 1
3183 cls.tcp_external_port = 80
3184
3185 cls.create_pg_interfaces(range(5))
3186 cls.interfaces = list(cls.pg_interfaces[0:3])
3187
3188 for i in cls.interfaces:
3189 i.admin_up()
3190 i.config_ip4()
3191 i.resolve_arp()
3192
3193 cls.pg0.generate_remote_hosts(3)
3194 cls.pg0.configure_ipv4_neighbors()
3195
3196 cls.pg3.admin_up()
3197
3198 cls.pg4.generate_remote_hosts(2)
3199 cls.pg4.config_ip4()
3200 ip_addr_n = socket.inet_pton(socket.AF_INET, "10.0.0.1")
3201 cls.vapi.sw_interface_add_del_address(cls.pg4.sw_if_index,
3202 ip_addr_n,
3203 24)
3204 cls.pg4.admin_up()
3205 cls.pg4.resolve_arp()
3206 cls.pg4._remote_hosts[1]._ip4 = cls.pg4._remote_hosts[0]._ip4
3207 cls.pg4.resolve_arp()
3208
3209 except Exception:
3210 super(TestNAT44EndpointDependent, cls).tearDownClass()
3211 raise
3212
3213 def test_dynamic(self):
3214 """ NAT44 dynamic translation test """
3215
3216 self.nat44_add_address(self.nat_addr)
3217 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3218 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3219 is_inside=0)
3220
3221 # in2out
3222 pkts = self.create_stream_in(self.pg0, self.pg1)
3223 self.pg0.add_stream(pkts)
3224 self.pg_enable_capture(self.pg_interfaces)
3225 self.pg_start()
3226 capture = self.pg1.get_capture(len(pkts))
3227 self.verify_capture_out(capture)
3228
3229 # out2in
3230 pkts = self.create_stream_out(self.pg1)
3231 self.pg1.add_stream(pkts)
3232 self.pg_enable_capture(self.pg_interfaces)
3233 self.pg_start()
3234 capture = self.pg0.get_capture(len(pkts))
3235 self.verify_capture_in(capture, self.pg0)
3236
3237 def test_forwarding(self):
3238 """ NAT44 forwarding test """
3239
3240 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3241 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3242 is_inside=0)
3243 self.vapi.nat44_forwarding_enable_disable(1)
3244
3245 real_ip = self.pg0.remote_ip4n
3246 alias_ip = self.nat_addr_n
3247 self.vapi.nat44_add_del_static_mapping(local_ip=real_ip,
3248 external_ip=alias_ip)
3249
3250 try:
3251 # in2out - static mapping match
3252
3253 pkts = self.create_stream_out(self.pg1)
3254 self.pg1.add_stream(pkts)
3255 self.pg_enable_capture(self.pg_interfaces)
3256 self.pg_start()
3257 capture = self.pg0.get_capture(len(pkts))
3258 self.verify_capture_in(capture, self.pg0)
3259
3260 pkts = self.create_stream_in(self.pg0, self.pg1)
3261 self.pg0.add_stream(pkts)
3262 self.pg_enable_capture(self.pg_interfaces)
3263 self.pg_start()
3264 capture = self.pg1.get_capture(len(pkts))
3265 self.verify_capture_out(capture, same_port=True)
3266
3267 # in2out - no static mapping match
3268
3269 host0 = self.pg0.remote_hosts[0]
3270 self.pg0.remote_hosts[0] = self.pg0.remote_hosts[1]
3271 try:
3272 pkts = self.create_stream_out(self.pg1,
3273 dst_ip=self.pg0.remote_ip4,
3274 use_inside_ports=True)
3275 self.pg1.add_stream(pkts)
3276 self.pg_enable_capture(self.pg_interfaces)
3277 self.pg_start()
3278 capture = self.pg0.get_capture(len(pkts))
3279 self.verify_capture_in(capture, self.pg0)
3280
3281 pkts = self.create_stream_in(self.pg0, self.pg1)
3282 self.pg0.add_stream(pkts)
3283 self.pg_enable_capture(self.pg_interfaces)
3284 self.pg_start()
3285 capture = self.pg1.get_capture(len(pkts))
3286 self.verify_capture_out(capture, nat_ip=self.pg0.remote_ip4,
3287 same_port=True)
3288 finally:
3289 self.pg0.remote_hosts[0] = host0
3290
3291 user = self.pg0.remote_hosts[1]
3292 sessions = self.vapi.nat44_user_session_dump(user.ip4n, 0)
3293 self.assertEqual(len(sessions), 3)
3294 self.assertTrue(sessions[0].ext_host_valid)
3295 self.vapi.nat44_del_session(
3296 sessions[0].inside_ip_address,
3297 sessions[0].inside_port,
3298 sessions[0].protocol,
3299 ext_host_address=sessions[0].ext_host_address,
3300 ext_host_port=sessions[0].ext_host_port)
3301 sessions = self.vapi.nat44_user_session_dump(user.ip4n, 0)
3302 self.assertEqual(len(sessions), 2)
3303
3304 finally:
3305 self.vapi.nat44_forwarding_enable_disable(0)
3306 self.vapi.nat44_add_del_static_mapping(local_ip=real_ip,
3307 external_ip=alias_ip,
3308 is_add=0)
3309
3310 def test_static_lb(self):
3311 """ NAT44 local service load balancing """
3312 external_addr_n = socket.inet_pton(socket.AF_INET, self.nat_addr)
3313 external_port = 80
3314 local_port = 8080
3315 server1 = self.pg0.remote_hosts[0]
3316 server2 = self.pg0.remote_hosts[1]
3317
3318 locals = [{'addr': server1.ip4n,
3319 'port': local_port,
3320 'probability': 70},
3321 {'addr': server2.ip4n,
3322 'port': local_port,
3323 'probability': 30}]
3324
3325 self.nat44_add_address(self.nat_addr)
3326 self.vapi.nat44_add_del_lb_static_mapping(external_addr_n,
3327 external_port,
3328 IP_PROTOS.tcp,
3329 local_num=len(locals),
3330 locals=locals)
3331 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3332 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3333 is_inside=0)
3334
3335 # from client to service
3336 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
3337 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
3338 TCP(sport=12345, dport=external_port))
3339 self.pg1.add_stream(p)
3340 self.pg_enable_capture(self.pg_interfaces)
3341 self.pg_start()
3342 capture = self.pg0.get_capture(1)
3343 p = capture[0]
3344 server = None
3345 try:
3346 ip = p[IP]
3347 tcp = p[TCP]
3348 self.assertIn(ip.dst, [server1.ip4, server2.ip4])
3349 if ip.dst == server1.ip4:
3350 server = server1
3351 else:
3352 server = server2
3353 self.assertEqual(tcp.dport, local_port)
3354 self.assert_packet_checksums_valid(p)
3355 except:
3356 self.logger.error(ppp("Unexpected or invalid packet:", p))
3357 raise
3358
3359 # from service back to client
3360 p = (Ether(src=server.mac, dst=self.pg0.local_mac) /
3361 IP(src=server.ip4, dst=self.pg1.remote_ip4) /
3362 TCP(sport=local_port, dport=12345))
3363 self.pg0.add_stream(p)
3364 self.pg_enable_capture(self.pg_interfaces)
3365 self.pg_start()
3366 capture = self.pg1.get_capture(1)
3367 p = capture[0]
3368 try:
3369 ip = p[IP]
3370 tcp = p[TCP]
3371 self.assertEqual(ip.src, self.nat_addr)
3372 self.assertEqual(tcp.sport, external_port)
3373 self.assert_packet_checksums_valid(p)
3374 except:
3375 self.logger.error(ppp("Unexpected or invalid packet:", p))
3376 raise
3377
3378 sessions = self.vapi.nat44_user_session_dump(server.ip4n, 0)
3379 self.assertEqual(len(sessions), 1)
3380 self.assertTrue(sessions[0].ext_host_valid)
3381 self.vapi.nat44_del_session(
3382 sessions[0].inside_ip_address,
3383 sessions[0].inside_port,
3384 sessions[0].protocol,
3385 ext_host_address=sessions[0].ext_host_address,
3386 ext_host_port=sessions[0].ext_host_port)
3387 sessions = self.vapi.nat44_user_session_dump(server.ip4n, 0)
3388 self.assertEqual(len(sessions), 0)
3389
3390 @unittest.skipUnless(running_extended_tests(), "part of extended tests")
3391 def test_static_lb_multi_clients(self):
3392 """ NAT44 local service load balancing - multiple clients"""
3393
3394 external_addr_n = socket.inet_pton(socket.AF_INET, self.nat_addr)
3395 external_port = 80
3396 local_port = 8080
3397 server1 = self.pg0.remote_hosts[0]
3398 server2 = self.pg0.remote_hosts[1]
3399
3400 locals = [{'addr': server1.ip4n,
3401 'port': local_port,
3402 'probability': 90},
3403 {'addr': server2.ip4n,
3404 'port': local_port,
3405 'probability': 10}]
3406
3407 self.nat44_add_address(self.nat_addr)
3408 self.vapi.nat44_add_del_lb_static_mapping(external_addr_n,
3409 external_port,
3410 IP_PROTOS.tcp,
3411 local_num=len(locals),
3412 locals=locals)
3413 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3414 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3415 is_inside=0)
3416
3417 server1_n = 0
3418 server2_n = 0
3419 clients = ip4_range(self.pg1.remote_ip4, 10, 50)
3420 pkts = []
3421 for client in clients:
3422 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
3423 IP(src=client, dst=self.nat_addr) /
3424 TCP(sport=12345, dport=external_port))
3425 pkts.append(p)
3426 self.pg1.add_stream(pkts)
3427 self.pg_enable_capture(self.pg_interfaces)
3428 self.pg_start()
3429 capture = self.pg0.get_capture(len(pkts))
3430 for p in capture:
3431 if p[IP].dst == server1.ip4:
3432 server1_n += 1
3433 else:
3434 server2_n += 1
3435 self.assertTrue(server1_n > server2_n)
3436
3437 def test_static_lb_2(self):
3438 """ NAT44 local service load balancing (asymmetrical rule) """
3439 external_addr_n = socket.inet_pton(socket.AF_INET, self.nat_addr)
3440 external_port = 80
3441 local_port = 8080
3442 server1 = self.pg0.remote_hosts[0]
3443 server2 = self.pg0.remote_hosts[1]
3444
3445 locals = [{'addr': server1.ip4n,
3446 'port': local_port,
3447 'probability': 70},
3448 {'addr': server2.ip4n,
3449 'port': local_port,
3450 'probability': 30}]
3451
3452 self.vapi.nat44_forwarding_enable_disable(1)
3453 self.vapi.nat44_add_del_lb_static_mapping(external_addr_n,
3454 external_port,
3455 IP_PROTOS.tcp,
3456 out2in_only=1,
3457 local_num=len(locals),
3458 locals=locals)
3459 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3460 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3461 is_inside=0)
3462
3463 # from client to service
3464 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
3465 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
3466 TCP(sport=12345, dport=external_port))
3467 self.pg1.add_stream(p)
3468 self.pg_enable_capture(self.pg_interfaces)
3469 self.pg_start()
3470 capture = self.pg0.get_capture(1)
3471 p = capture[0]
3472 server = None
3473 try:
3474 ip = p[IP]
3475 tcp = p[TCP]
3476 self.assertIn(ip.dst, [server1.ip4, server2.ip4])
3477 if ip.dst == server1.ip4:
3478 server = server1
3479 else:
3480 server = server2
3481 self.assertEqual(tcp.dport, local_port)
3482 self.assert_packet_checksums_valid(p)
3483 except:
3484 self.logger.error(ppp("Unexpected or invalid packet:", p))
3485 raise
3486
3487 # from service back to client
3488 p = (Ether(src=server.mac, dst=self.pg0.local_mac) /
3489 IP(src=server.ip4, dst=self.pg1.remote_ip4) /
3490 TCP(sport=local_port, dport=12345))
3491 self.pg0.add_stream(p)
3492 self.pg_enable_capture(self.pg_interfaces)
3493 self.pg_start()
3494 capture = self.pg1.get_capture(1)
3495 p = capture[0]
3496 try:
3497 ip = p[IP]
3498 tcp = p[TCP]
3499 self.assertEqual(ip.src, self.nat_addr)
3500 self.assertEqual(tcp.sport, external_port)
3501 self.assert_packet_checksums_valid(p)
3502 except:
3503 self.logger.error(ppp("Unexpected or invalid packet:", p))
3504 raise
3505
3506 # from client to server (no translation)
3507 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
3508 IP(src=self.pg1.remote_ip4, dst=server1.ip4) /
3509 TCP(sport=12346, dport=local_port))
3510 self.pg1.add_stream(p)
3511 self.pg_enable_capture(self.pg_interfaces)
3512 self.pg_start()
3513 capture = self.pg0.get_capture(1)
3514 p = capture[0]
3515 server = None
3516 try:
3517 ip = p[IP]
3518 tcp = p[TCP]
3519 self.assertEqual(ip.dst, server1.ip4)
3520 self.assertEqual(tcp.dport, local_port)
3521 self.assert_packet_checksums_valid(p)
3522 except:
3523 self.logger.error(ppp("Unexpected or invalid packet:", p))
3524 raise
3525
3526 # from service back to client (no translation)
3527 p = (Ether(src=server1.mac, dst=self.pg0.local_mac) /
3528 IP(src=server1.ip4, dst=self.pg1.remote_ip4) /
3529 TCP(sport=local_port, dport=12346))
3530 self.pg0.add_stream(p)
3531 self.pg_enable_capture(self.pg_interfaces)
3532 self.pg_start()
3533 capture = self.pg1.get_capture(1)
3534 p = capture[0]
3535 try:
3536 ip = p[IP]
3537 tcp = p[TCP]
3538 self.assertEqual(ip.src, server1.ip4)
3539 self.assertEqual(tcp.sport, local_port)
3540 self.assert_packet_checksums_valid(p)
3541 except:
3542 self.logger.error(ppp("Unexpected or invalid packet:", p))
3543 raise
3544
3545 def test_unknown_proto(self):
3546 """ NAT44 translate packet with unknown protocol """
3547 self.nat44_add_address(self.nat_addr)
3548 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3549 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3550 is_inside=0)
3551
3552 # in2out
3553 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
3554 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
3555 TCP(sport=self.tcp_port_in, dport=20))
3556 self.pg0.add_stream(p)
3557 self.pg_enable_capture(self.pg_interfaces)
3558 self.pg_start()
3559 p = self.pg1.get_capture(1)
3560
3561 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
3562 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
3563 GRE() /
3564 IP(src=self.pg2.remote_ip4, dst=self.pg2.remote_ip4) /
3565 TCP(sport=1234, dport=1234))
3566 self.pg0.add_stream(p)
3567 self.pg_enable_capture(self.pg_interfaces)
3568 self.pg_start()
3569 p = self.pg1.get_capture(1)
3570 packet = p[0]
3571 try:
3572 self.assertEqual(packet[IP].src, self.nat_addr)
3573 self.assertEqual(packet[IP].dst, self.pg1.remote_ip4)
3574 self.assertTrue(packet.haslayer(GRE))
3575 self.assert_packet_checksums_valid(packet)
3576 except:
3577 self.logger.error(ppp("Unexpected or invalid packet:", packet))
3578 raise
3579
3580 # out2in
3581 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
3582 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
3583 GRE() /
3584 IP(src=self.pg2.remote_ip4, dst=self.pg2.remote_ip4) /
3585 TCP(sport=1234, dport=1234))
3586 self.pg1.add_stream(p)
3587 self.pg_enable_capture(self.pg_interfaces)
3588 self.pg_start()
3589 p = self.pg0.get_capture(1)
3590 packet = p[0]
3591 try:
3592 self.assertEqual(packet[IP].src, self.pg1.remote_ip4)
3593 self.assertEqual(packet[IP].dst, self.pg0.remote_ip4)
3594 self.assertTrue(packet.haslayer(GRE))
3595 self.assert_packet_checksums_valid(packet)
3596 except:
3597 self.logger.error(ppp("Unexpected or invalid packet:", packet))
3598 raise
3599
3600 def test_hairpinning_unknown_proto(self):
3601 """ NAT44 translate packet with unknown protocol - hairpinning """
3602 host = self.pg0.remote_hosts[0]
3603 server = self.pg0.remote_hosts[1]
3604 host_in_port = 1234
3605 server_out_port = 8765
3606 server_nat_ip = "10.0.0.11"
3607
3608 self.nat44_add_address(self.nat_addr)
3609 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3610 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3611 is_inside=0)
3612
3613 # add static mapping for server
3614 self.nat44_add_static_mapping(server.ip4, server_nat_ip)
3615
3616 # host to server
3617 p = (Ether(src=host.mac, dst=self.pg0.local_mac) /
3618 IP(src=host.ip4, dst=server_nat_ip) /
3619 TCP(sport=host_in_port, dport=server_out_port))
3620 self.pg0.add_stream(p)
3621 self.pg_enable_capture(self.pg_interfaces)
3622 self.pg_start()
3623 self.pg0.get_capture(1)
3624
3625 p = (Ether(dst=self.pg0.local_mac, src=host.mac) /
3626 IP(src=host.ip4, dst=server_nat_ip) /
3627 GRE() /
3628 IP(src=self.pg2.remote_ip4, dst=self.pg2.remote_ip4) /
3629 TCP(sport=1234, dport=1234))
3630 self.pg0.add_stream(p)
3631 self.pg_enable_capture(self.pg_interfaces)
3632 self.pg_start()
3633 p = self.pg0.get_capture(1)
3634 packet = p[0]
3635 try:
3636 self.assertEqual(packet[IP].src, self.nat_addr)
3637 self.assertEqual(packet[IP].dst, server.ip4)
3638 self.assertTrue(packet.haslayer(GRE))
3639 self.assert_packet_checksums_valid(packet)
3640 except:
3641 self.logger.error(ppp("Unexpected or invalid packet:", packet))
3642 raise
3643
3644 # server to host
3645 p = (Ether(dst=self.pg0.local_mac, src=server.mac) /
3646 IP(src=server.ip4, dst=self.nat_addr) /
3647 GRE() /
3648 IP(src=self.pg2.remote_ip4, dst=self.pg2.remote_ip4) /
3649 TCP(sport=1234, dport=1234))
3650 self.pg0.add_stream(p)
3651 self.pg_enable_capture(self.pg_interfaces)
3652 self.pg_start()
3653 p = self.pg0.get_capture(1)
3654 packet = p[0]
3655 try:
3656 self.assertEqual(packet[IP].src, server_nat_ip)
3657 self.assertEqual(packet[IP].dst, host.ip4)
3658 self.assertTrue(packet.haslayer(GRE))
3659 self.assert_packet_checksums_valid(packet)
3660 except:
3661 self.logger.error(ppp("Unexpected or invalid packet:", packet))
3662 raise
3663
3664 def test_output_feature_and_service(self):
3665 """ NAT44 interface output feature and services """
3666 external_addr = '1.2.3.4'
3667 external_port = 80
3668 local_port = 8080
3669
3670 self.vapi.nat44_forwarding_enable_disable(1)
3671 self.nat44_add_address(self.nat_addr)
3672 self.vapi.nat44_add_del_identity_mapping(ip=self.pg1.remote_ip4n)
3673 self.nat44_add_static_mapping(self.pg0.remote_ip4, external_addr,
3674 local_port, external_port,
3675 proto=IP_PROTOS.tcp, out2in_only=1)
3676 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3677 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index,
3678 is_inside=0)
3679 self.vapi.nat44_interface_add_del_output_feature(self.pg1.sw_if_index,
3680 is_inside=0)
3681
3682 # from client to service
3683 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
3684 IP(src=self.pg1.remote_ip4, dst=external_addr) /
3685 TCP(sport=12345, dport=external_port))
3686 self.pg1.add_stream(p)
3687 self.pg_enable_capture(self.pg_interfaces)
3688 self.pg_start()
3689 capture = self.pg0.get_capture(1)
3690 p = capture[0]
3691 try:
3692 ip = p[IP]
3693 tcp = p[TCP]
3694 self.assertEqual(ip.dst, self.pg0.remote_ip4)
3695 self.assertEqual(tcp.dport, local_port)
3696 self.assert_packet_checksums_valid(p)
3697 except:
3698 self.logger.error(ppp("Unexpected or invalid packet:", p))
3699 raise
3700
3701 # from service back to client
3702 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
3703 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
3704 TCP(sport=local_port, dport=12345))
3705 self.pg0.add_stream(p)
3706 self.pg_enable_capture(self.pg_interfaces)
3707 self.pg_start()
3708 capture = self.pg1.get_capture(1)
3709 p = capture[0]
3710 try:
3711 ip = p[IP]
3712 tcp = p[TCP]
3713 self.assertEqual(ip.src, external_addr)
3714 self.assertEqual(tcp.sport, external_port)
3715 self.assert_packet_checksums_valid(p)
3716 except:
3717 self.logger.error(ppp("Unexpected or invalid packet:", p))
3718 raise
3719
3720 # from local network host to external network
3721 pkts = self.create_stream_in(self.pg0, self.pg1)
3722 self.pg0.add_stream(pkts)
3723 self.pg_enable_capture(self.pg_interfaces)
3724 self.pg_start()
3725 capture = self.pg1.get_capture(len(pkts))
3726 self.verify_capture_out(capture)
3727 pkts = self.create_stream_in(self.pg0, self.pg1)
3728 self.pg0.add_stream(pkts)
3729 self.pg_enable_capture(self.pg_interfaces)
3730 self.pg_start()
3731 capture = self.pg1.get_capture(len(pkts))
3732 self.verify_capture_out(capture)
3733
3734 # from external network back to local network host
3735 pkts = self.create_stream_out(self.pg1)
3736 self.pg1.add_stream(pkts)
3737 self.pg_enable_capture(self.pg_interfaces)
3738 self.pg_start()
3739 capture = self.pg0.get_capture(len(pkts))
3740 self.verify_capture_in(capture, self.pg0)
3741
3742 def test_output_feature_and_service2(self):
3743 """ NAT44 interface output feature and service host direct access """
3744 self.vapi.nat44_forwarding_enable_disable(1)
3745 self.nat44_add_address(self.nat_addr)
3746 self.vapi.nat44_interface_add_del_output_feature(self.pg1.sw_if_index,
3747 is_inside=0)
3748
3749 # session initiaded from service host - translate
3750 pkts = self.create_stream_in(self.pg0, self.pg1)
3751 self.pg0.add_stream(pkts)
3752 self.pg_enable_capture(self.pg_interfaces)
3753 self.pg_start()
3754 capture = self.pg1.get_capture(len(pkts))
3755 self.verify_capture_out(capture)
3756
3757 pkts = self.create_stream_out(self.pg1)
3758 self.pg1.add_stream(pkts)
3759 self.pg_enable_capture(self.pg_interfaces)
3760 self.pg_start()
3761 capture = self.pg0.get_capture(len(pkts))
3762 self.verify_capture_in(capture, self.pg0)
3763
3764 # session initiaded from remote host - do not translate
3765 self.tcp_port_in = 60303
3766 self.udp_port_in = 60304
3767 self.icmp_id_in = 60305
3768 pkts = self.create_stream_out(self.pg1,
3769 self.pg0.remote_ip4,
3770 use_inside_ports=True)
3771 self.pg1.add_stream(pkts)
3772 self.pg_enable_capture(self.pg_interfaces)
3773 self.pg_start()
3774 capture = self.pg0.get_capture(len(pkts))
3775 self.verify_capture_in(capture, self.pg0)
3776
3777 pkts = self.create_stream_in(self.pg0, self.pg1)
3778 self.pg0.add_stream(pkts)
3779 self.pg_enable_capture(self.pg_interfaces)
3780 self.pg_start()
3781 capture = self.pg1.get_capture(len(pkts))
3782 self.verify_capture_out(capture, nat_ip=self.pg0.remote_ip4,
3783 same_port=True)
3784
3785 def test_output_feature_and_service3(self):
3786 """ NAT44 interface output feature and DST NAT """
3787 external_addr = '1.2.3.4'
3788 external_port = 80
3789 local_port = 8080
3790
3791 self.vapi.nat44_forwarding_enable_disable(1)
3792 self.nat44_add_address(self.nat_addr)
3793 self.nat44_add_static_mapping(self.pg1.remote_ip4, external_addr,
3794 local_port, external_port,
3795 proto=IP_PROTOS.tcp, out2in_only=1)
3796 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3797 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index,
3798 is_inside=0)
3799 self.vapi.nat44_interface_add_del_output_feature(self.pg1.sw_if_index,
3800 is_inside=0)
3801
3802 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
3803 IP(src=self.pg0.remote_ip4, dst=external_addr) /
3804 TCP(sport=12345, dport=external_port))
3805 self.pg0.add_stream(p)
3806 self.pg_enable_capture(self.pg_interfaces)
3807 self.pg_start()
3808 capture = self.pg1.get_capture(1)
3809 p = capture[0]
3810 try:
3811 ip = p[IP]
3812 tcp = p[TCP]
3813 self.assertEqual(ip.src, self.pg0.remote_ip4)
3814 self.assertEqual(tcp.sport, 12345)
3815 self.assertEqual(ip.dst, self.pg1.remote_ip4)
3816 self.assertEqual(tcp.dport, local_port)
3817 self.assert_packet_checksums_valid(p)
3818 except:
3819 self.logger.error(ppp("Unexpected or invalid packet:", p))
3820 raise
3821
3822 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
3823 IP(src=self.pg1.remote_ip4, dst=self.pg0.remote_ip4) /
3824 TCP(sport=local_port, dport=12345))
3825 self.pg1.add_stream(p)
3826 self.pg_enable_capture(self.pg_interfaces)
3827 self.pg_start()
3828 capture = self.pg0.get_capture(1)
3829 p = capture[0]
3830 try:
3831 ip = p[IP]
3832 tcp = p[TCP]
3833 self.assertEqual(ip.src, external_addr)
3834 self.assertEqual(tcp.sport, external_port)
3835 self.assertEqual(ip.dst, self.pg0.remote_ip4)
3836 self.assertEqual(tcp.dport, 12345)
3837 self.assert_packet_checksums_valid(p)
3838 except:
3839 self.logger.error(ppp("Unexpected or invalid packet:", p))
3840 raise
3841
Juraj Sloboda1e5c07d2018-04-10 13:51:54 +02003842 def twice_nat_common(self, self_twice_nat=False, same_pg=False, lb=False,
3843 client_id=None):
Matus Fabianb932d262017-12-18 05:38:24 -08003844 twice_nat_addr = '10.0.1.3'
Juraj Sloboda1e5c07d2018-04-10 13:51:54 +02003845
Matus Fabianb932d262017-12-18 05:38:24 -08003846 port_in = 8080
Juraj Sloboda1e5c07d2018-04-10 13:51:54 +02003847 if lb:
3848 if not same_pg:
3849 port_in1 = port_in
3850 port_in2 = port_in
3851 else:
3852 port_in1 = port_in+1
3853 port_in2 = port_in+2
3854
Matus Fabianb932d262017-12-18 05:38:24 -08003855 port_out = 80
3856 eh_port_out = 4567
Juraj Sloboda1e5c07d2018-04-10 13:51:54 +02003857
3858 server1 = self.pg0.remote_hosts[0]
3859 server2 = self.pg0.remote_hosts[1]
3860 if lb and same_pg:
3861 server2 = server1
3862 if not lb:
3863 server = server1
3864
3865 pg0 = self.pg0
3866 if same_pg:
3867 pg1 = self.pg0
3868 else:
3869 pg1 = self.pg1
3870
3871 eh_translate = ((not self_twice_nat) or (not lb and same_pg) or
3872 client_id == 1)
3873
Matus Fabianb932d262017-12-18 05:38:24 -08003874 self.nat44_add_address(self.nat_addr)
3875 self.nat44_add_address(twice_nat_addr, twice_nat=1)
Juraj Sloboda1e5c07d2018-04-10 13:51:54 +02003876 if not lb:
3877 self.nat44_add_static_mapping(pg0.remote_ip4, self.nat_addr,
3878 port_in, port_out,
3879 proto=IP_PROTOS.tcp,
3880 twice_nat=int(not self_twice_nat),
3881 self_twice_nat=int(self_twice_nat))
3882 else:
3883 locals = [{'addr': server1.ip4n,
3884 'port': port_in1,
3885 'probability': 50},
3886 {'addr': server2.ip4n,
3887 'port': port_in2,
3888 'probability': 50}]
3889 out_addr_n = socket.inet_pton(socket.AF_INET, self.nat_addr)
3890 self.vapi.nat44_add_del_lb_static_mapping(out_addr_n,
3891 port_out,
3892 IP_PROTOS.tcp,
3893 twice_nat=int(
3894 not self_twice_nat),
3895 self_twice_nat=int(
3896 self_twice_nat),
3897 local_num=len(locals),
3898 locals=locals)
3899 self.vapi.nat44_interface_add_del_feature(pg0.sw_if_index)
3900 self.vapi.nat44_interface_add_del_feature(pg1.sw_if_index,
Matus Fabianb932d262017-12-18 05:38:24 -08003901 is_inside=0)
3902
Juraj Sloboda1e5c07d2018-04-10 13:51:54 +02003903 if same_pg:
3904 if not lb:
3905 client = server
3906 else:
3907 assert client_id is not None
3908 if client_id == 1:
3909 client = self.pg0.remote_hosts[0]
3910 elif client_id == 2:
3911 client = self.pg0.remote_hosts[1]
3912 else:
3913 client = pg1.remote_hosts[0]
3914 p = (Ether(src=pg1.remote_mac, dst=pg1.local_mac) /
3915 IP(src=client.ip4, dst=self.nat_addr) /
Matus Fabianb932d262017-12-18 05:38:24 -08003916 TCP(sport=eh_port_out, dport=port_out))
Juraj Sloboda1e5c07d2018-04-10 13:51:54 +02003917 pg1.add_stream(p)
Matus Fabianb932d262017-12-18 05:38:24 -08003918 self.pg_enable_capture(self.pg_interfaces)
3919 self.pg_start()
Juraj Sloboda1e5c07d2018-04-10 13:51:54 +02003920 capture = pg0.get_capture(1)
Matus Fabianb932d262017-12-18 05:38:24 -08003921 p = capture[0]
3922 try:
3923 ip = p[IP]
3924 tcp = p[TCP]
Juraj Sloboda1e5c07d2018-04-10 13:51:54 +02003925 if lb:
3926 if ip.dst == server1.ip4:
3927 server = server1
3928 port_in = port_in1
3929 else:
3930 server = server2
3931 port_in = port_in2
3932 self.assertEqual(ip.dst, server.ip4)
3933 if lb and same_pg:
3934 self.assertIn(tcp.dport, [port_in1, port_in2])
3935 else:
3936 self.assertEqual(tcp.dport, port_in)
3937 if eh_translate:
3938 self.assertEqual(ip.src, twice_nat_addr)
3939 self.assertNotEqual(tcp.sport, eh_port_out)
3940 else:
3941 self.assertEqual(ip.src, client.ip4)
3942 self.assertEqual(tcp.sport, eh_port_out)
3943 eh_addr_in = ip.src
Matus Fabianb932d262017-12-18 05:38:24 -08003944 eh_port_in = tcp.sport
Juraj Sloboda1e5c07d2018-04-10 13:51:54 +02003945 saved_port_in = tcp.dport
Klement Sekerad81ae412018-05-16 10:52:54 +02003946 self.assert_packet_checksums_valid(p)
Matus Fabianb932d262017-12-18 05:38:24 -08003947 except:
3948 self.logger.error(ppp("Unexpected or invalid packet:", p))
3949 raise
3950
Juraj Sloboda1e5c07d2018-04-10 13:51:54 +02003951 p = (Ether(src=server.mac, dst=pg0.local_mac) /
3952 IP(src=server.ip4, dst=eh_addr_in) /
3953 TCP(sport=saved_port_in, dport=eh_port_in))
3954 pg0.add_stream(p)
Matus Fabianb932d262017-12-18 05:38:24 -08003955 self.pg_enable_capture(self.pg_interfaces)
3956 self.pg_start()
Juraj Sloboda1e5c07d2018-04-10 13:51:54 +02003957 capture = pg1.get_capture(1)
Matus Fabianb932d262017-12-18 05:38:24 -08003958 p = capture[0]
3959 try:
3960 ip = p[IP]
3961 tcp = p[TCP]
Juraj Sloboda1e5c07d2018-04-10 13:51:54 +02003962 self.assertEqual(ip.dst, client.ip4)
Matus Fabianb932d262017-12-18 05:38:24 -08003963 self.assertEqual(ip.src, self.nat_addr)
3964 self.assertEqual(tcp.dport, eh_port_out)
3965 self.assertEqual(tcp.sport, port_out)
Klement Sekerad81ae412018-05-16 10:52:54 +02003966 self.assert_packet_checksums_valid(p)
Matus Fabianb932d262017-12-18 05:38:24 -08003967 except:
3968 self.logger.error(ppp("Unexpected or invalid packet:", p))
3969 raise
3970
Matus Fabian70a26ac2018-05-14 06:20:28 -07003971 if eh_translate:
3972 sessions = self.vapi.nat44_user_session_dump(server.ip4n, 0)
3973 self.assertEqual(len(sessions), 1)
3974 self.assertTrue(sessions[0].ext_host_valid)
3975 self.assertTrue(sessions[0].is_twicenat)
3976 self.vapi.nat44_del_session(
3977 sessions[0].inside_ip_address,
3978 sessions[0].inside_port,
3979 sessions[0].protocol,
3980 ext_host_address=sessions[0].ext_host_nat_address,
3981 ext_host_port=sessions[0].ext_host_nat_port)
3982 sessions = self.vapi.nat44_user_session_dump(server.ip4n, 0)
3983 self.assertEqual(len(sessions), 0)
3984
Juraj Sloboda1e5c07d2018-04-10 13:51:54 +02003985 def test_twice_nat(self):
3986 """ Twice NAT44 """
3987 self.twice_nat_common()
3988
3989 def test_self_twice_nat_positive(self):
3990 """ Self Twice NAT44 (positive test) """
3991 self.twice_nat_common(self_twice_nat=True, same_pg=True)
3992
3993 def test_self_twice_nat_negative(self):
3994 """ Self Twice NAT44 (negative test) """
3995 self.twice_nat_common(self_twice_nat=True)
3996
Matus Fabianb932d262017-12-18 05:38:24 -08003997 def test_twice_nat_lb(self):
3998 """ Twice NAT44 local service load balancing """
Juraj Sloboda1e5c07d2018-04-10 13:51:54 +02003999 self.twice_nat_common(lb=True)
Matus Fabianb932d262017-12-18 05:38:24 -08004000
Juraj Sloboda1e5c07d2018-04-10 13:51:54 +02004001 def test_self_twice_nat_lb_positive(self):
4002 """ Self Twice NAT44 local service load balancing (positive test) """
4003 self.twice_nat_common(lb=True, self_twice_nat=True, same_pg=True,
4004 client_id=1)
Matus Fabianb932d262017-12-18 05:38:24 -08004005
Juraj Sloboda1e5c07d2018-04-10 13:51:54 +02004006 def test_self_twice_nat_lb_negative(self):
4007 """ Self Twice NAT44 local service load balancing (negative test) """
4008 self.twice_nat_common(lb=True, self_twice_nat=True, same_pg=True,
4009 client_id=2)
Matus Fabianb932d262017-12-18 05:38:24 -08004010
4011 def test_twice_nat_interface_addr(self):
4012 """ Acquire twice NAT44 addresses from interface """
Matus Fabiana6110b62018-06-13 05:39:07 -07004013 self.vapi.nat44_add_interface_addr(self.pg3.sw_if_index, twice_nat=1)
Matus Fabianb932d262017-12-18 05:38:24 -08004014
4015 # no address in NAT pool
4016 adresses = self.vapi.nat44_address_dump()
4017 self.assertEqual(0, len(adresses))
4018
4019 # configure interface address and check NAT address pool
Matus Fabiana6110b62018-06-13 05:39:07 -07004020 self.pg3.config_ip4()
Matus Fabianb932d262017-12-18 05:38:24 -08004021 adresses = self.vapi.nat44_address_dump()
4022 self.assertEqual(1, len(adresses))
Matus Fabiana6110b62018-06-13 05:39:07 -07004023 self.assertEqual(adresses[0].ip_address[0:4], self.pg3.local_ip4n)
Matus Fabianb932d262017-12-18 05:38:24 -08004024 self.assertEqual(adresses[0].twice_nat, 1)
4025
4026 # remove interface address and check NAT address pool
Matus Fabiana6110b62018-06-13 05:39:07 -07004027 self.pg3.unconfig_ip4()
Matus Fabianb932d262017-12-18 05:38:24 -08004028 adresses = self.vapi.nat44_address_dump()
4029 self.assertEqual(0, len(adresses))
4030
Matus Fabianebdf1902018-05-04 03:57:42 -07004031 def test_tcp_session_close_in(self):
4032 """ Close TCP session from inside network """
Matus Fabian229c1aa2018-05-28 04:09:52 -07004033 self.tcp_port_out = 10505
Matus Fabianebdf1902018-05-04 03:57:42 -07004034 self.nat44_add_address(self.nat_addr)
Matus Fabian229c1aa2018-05-28 04:09:52 -07004035 self.nat44_add_static_mapping(self.pg0.remote_ip4,
4036 self.nat_addr,
4037 self.tcp_port_in,
4038 self.tcp_port_out,
4039 proto=IP_PROTOS.tcp,
4040 twice_nat=1)
Matus Fabianebdf1902018-05-04 03:57:42 -07004041 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
4042 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
4043 is_inside=0)
4044
4045 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n, 0)
4046 start_sessnum = len(sessions)
4047
4048 self.initiate_tcp_session(self.pg0, self.pg1)
4049
Matus Fabian229c1aa2018-05-28 04:09:52 -07004050 # FIN packet in -> out
4051 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
4052 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
4053 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
4054 flags="FA", seq=100, ack=300))
4055 self.pg0.add_stream(p)
4056 self.pg_enable_capture(self.pg_interfaces)
4057 self.pg_start()
4058 self.pg1.get_capture(1)
Matus Fabianebdf1902018-05-04 03:57:42 -07004059
Matus Fabian229c1aa2018-05-28 04:09:52 -07004060 pkts = []
Matus Fabianebdf1902018-05-04 03:57:42 -07004061
Matus Fabian229c1aa2018-05-28 04:09:52 -07004062 # ACK packet out -> in
4063 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
4064 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
4065 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
4066 flags="A", seq=300, ack=101))
4067 pkts.append(p)
Matus Fabianebdf1902018-05-04 03:57:42 -07004068
Matus Fabian229c1aa2018-05-28 04:09:52 -07004069 # FIN packet out -> in
4070 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
4071 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
4072 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
4073 flags="FA", seq=300, ack=101))
4074 pkts.append(p)
Matus Fabianebdf1902018-05-04 03:57:42 -07004075
Matus Fabian229c1aa2018-05-28 04:09:52 -07004076 self.pg1.add_stream(pkts)
4077 self.pg_enable_capture(self.pg_interfaces)
4078 self.pg_start()
4079 self.pg0.get_capture(2)
Matus Fabianebdf1902018-05-04 03:57:42 -07004080
Matus Fabian229c1aa2018-05-28 04:09:52 -07004081 # ACK packet in -> out
4082 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
4083 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
4084 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
4085 flags="A", seq=101, ack=301))
4086 self.pg0.add_stream(p)
4087 self.pg_enable_capture(self.pg_interfaces)
4088 self.pg_start()
4089 self.pg1.get_capture(1)
Matus Fabianebdf1902018-05-04 03:57:42 -07004090
Matus Fabian229c1aa2018-05-28 04:09:52 -07004091 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n,
4092 0)
4093 self.assertEqual(len(sessions) - start_sessnum, 0)
Matus Fabianebdf1902018-05-04 03:57:42 -07004094
4095 def test_tcp_session_close_out(self):
4096 """ Close TCP session from outside network """
Matus Fabian229c1aa2018-05-28 04:09:52 -07004097 self.tcp_port_out = 10505
Matus Fabianebdf1902018-05-04 03:57:42 -07004098 self.nat44_add_address(self.nat_addr)
Matus Fabian229c1aa2018-05-28 04:09:52 -07004099 self.nat44_add_static_mapping(self.pg0.remote_ip4,
4100 self.nat_addr,
4101 self.tcp_port_in,
4102 self.tcp_port_out,
4103 proto=IP_PROTOS.tcp,
4104 twice_nat=1)
Matus Fabianebdf1902018-05-04 03:57:42 -07004105 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
4106 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
4107 is_inside=0)
4108
4109 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n, 0)
4110 start_sessnum = len(sessions)
4111
4112 self.initiate_tcp_session(self.pg0, self.pg1)
4113
Matus Fabian229c1aa2018-05-28 04:09:52 -07004114 # FIN packet out -> in
4115 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
4116 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
4117 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
4118 flags="FA", seq=100, ack=300))
4119 self.pg1.add_stream(p)
4120 self.pg_enable_capture(self.pg_interfaces)
4121 self.pg_start()
4122 self.pg0.get_capture(1)
Matus Fabianebdf1902018-05-04 03:57:42 -07004123
Matus Fabian229c1aa2018-05-28 04:09:52 -07004124 # FIN+ACK packet in -> out
4125 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
4126 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
4127 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
4128 flags="FA", seq=300, ack=101))
Matus Fabianebdf1902018-05-04 03:57:42 -07004129
Matus Fabian229c1aa2018-05-28 04:09:52 -07004130 self.pg0.add_stream(p)
4131 self.pg_enable_capture(self.pg_interfaces)
4132 self.pg_start()
4133 self.pg1.get_capture(1)
Matus Fabianebdf1902018-05-04 03:57:42 -07004134
Matus Fabian229c1aa2018-05-28 04:09:52 -07004135 # ACK packet out -> in
4136 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
4137 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
4138 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
4139 flags="A", seq=101, ack=301))
4140 self.pg1.add_stream(p)
4141 self.pg_enable_capture(self.pg_interfaces)
4142 self.pg_start()
4143 self.pg0.get_capture(1)
Matus Fabianebdf1902018-05-04 03:57:42 -07004144
Matus Fabian229c1aa2018-05-28 04:09:52 -07004145 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n,
4146 0)
4147 self.assertEqual(len(sessions) - start_sessnum, 0)
Matus Fabianebdf1902018-05-04 03:57:42 -07004148
4149 def test_tcp_session_close_simultaneous(self):
4150 """ Close TCP session from inside network """
Matus Fabian229c1aa2018-05-28 04:09:52 -07004151 self.tcp_port_out = 10505
Matus Fabianebdf1902018-05-04 03:57:42 -07004152 self.nat44_add_address(self.nat_addr)
Matus Fabian229c1aa2018-05-28 04:09:52 -07004153 self.nat44_add_static_mapping(self.pg0.remote_ip4,
4154 self.nat_addr,
4155 self.tcp_port_in,
4156 self.tcp_port_out,
4157 proto=IP_PROTOS.tcp,
4158 twice_nat=1)
Matus Fabianebdf1902018-05-04 03:57:42 -07004159 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
4160 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
4161 is_inside=0)
4162
4163 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n, 0)
4164 start_sessnum = len(sessions)
4165
4166 self.initiate_tcp_session(self.pg0, self.pg1)
4167
Matus Fabian229c1aa2018-05-28 04:09:52 -07004168 # FIN packet in -> out
4169 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
4170 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
4171 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
4172 flags="FA", seq=100, ack=300))
4173 self.pg0.add_stream(p)
4174 self.pg_enable_capture(self.pg_interfaces)
4175 self.pg_start()
4176 self.pg1.get_capture(1)
Matus Fabianebdf1902018-05-04 03:57:42 -07004177
Matus Fabian229c1aa2018-05-28 04:09:52 -07004178 # FIN packet out -> in
4179 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
4180 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
4181 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
4182 flags="FA", seq=300, ack=100))
4183 self.pg1.add_stream(p)
4184 self.pg_enable_capture(self.pg_interfaces)
4185 self.pg_start()
4186 self.pg0.get_capture(1)
Matus Fabianebdf1902018-05-04 03:57:42 -07004187
Matus Fabian229c1aa2018-05-28 04:09:52 -07004188 # ACK packet in -> out
4189 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
4190 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
4191 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
4192 flags="A", seq=101, ack=301))
4193 self.pg0.add_stream(p)
4194 self.pg_enable_capture(self.pg_interfaces)
4195 self.pg_start()
4196 self.pg1.get_capture(1)
Matus Fabianebdf1902018-05-04 03:57:42 -07004197
Matus Fabian229c1aa2018-05-28 04:09:52 -07004198 # ACK packet out -> in
4199 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
4200 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
4201 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
4202 flags="A", seq=301, ack=101))
4203 self.pg1.add_stream(p)
4204 self.pg_enable_capture(self.pg_interfaces)
4205 self.pg_start()
4206 self.pg0.get_capture(1)
Matus Fabianebdf1902018-05-04 03:57:42 -07004207
Matus Fabian229c1aa2018-05-28 04:09:52 -07004208 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n,
4209 0)
4210 self.assertEqual(len(sessions) - start_sessnum, 0)
Matus Fabianebdf1902018-05-04 03:57:42 -07004211
Matus Fabiana6110b62018-06-13 05:39:07 -07004212 def test_one_armed_nat44_static(self):
4213 """ One armed NAT44 and 1:1 NAPT asymmetrical rule """
4214 remote_host = self.pg4.remote_hosts[0]
4215 local_host = self.pg4.remote_hosts[1]
4216 external_port = 80
4217 local_port = 8080
4218 eh_port_in = 0
4219
4220 self.vapi.nat44_forwarding_enable_disable(1)
4221 self.nat44_add_address(self.nat_addr, twice_nat=1)
4222 self.nat44_add_static_mapping(local_host.ip4, self.nat_addr,
4223 local_port, external_port,
4224 proto=IP_PROTOS.tcp, out2in_only=1,
4225 twice_nat=1)
4226 self.vapi.nat44_interface_add_del_feature(self.pg4.sw_if_index)
4227 self.vapi.nat44_interface_add_del_feature(self.pg4.sw_if_index,
4228 is_inside=0)
4229
4230 # from client to service
4231 p = (Ether(src=self.pg4.remote_mac, dst=self.pg4.local_mac) /
4232 IP(src=remote_host.ip4, dst=self.nat_addr) /
4233 TCP(sport=12345, dport=external_port))
4234 self.pg4.add_stream(p)
4235 self.pg_enable_capture(self.pg_interfaces)
4236 self.pg_start()
4237 capture = self.pg4.get_capture(1)
4238 p = capture[0]
4239 try:
4240 ip = p[IP]
4241 tcp = p[TCP]
4242 self.assertEqual(ip.dst, local_host.ip4)
4243 self.assertEqual(ip.src, self.nat_addr)
4244 self.assertEqual(tcp.dport, local_port)
4245 self.assertNotEqual(tcp.sport, 12345)
4246 eh_port_in = tcp.sport
4247 self.assert_packet_checksums_valid(p)
4248 except:
4249 self.logger.error(ppp("Unexpected or invalid packet:", p))
4250 raise
4251
4252 # from service back to client
4253 p = (Ether(src=self.pg4.remote_mac, dst=self.pg4.local_mac) /
4254 IP(src=local_host.ip4, dst=self.nat_addr) /
4255 TCP(sport=local_port, dport=eh_port_in))
4256 self.pg4.add_stream(p)
4257 self.pg_enable_capture(self.pg_interfaces)
4258 self.pg_start()
4259 capture = self.pg4.get_capture(1)
4260 p = capture[0]
4261 try:
4262 ip = p[IP]
4263 tcp = p[TCP]
4264 self.assertEqual(ip.src, self.nat_addr)
4265 self.assertEqual(ip.dst, remote_host.ip4)
4266 self.assertEqual(tcp.sport, external_port)
4267 self.assertEqual(tcp.dport, 12345)
4268 self.assert_packet_checksums_valid(p)
4269 except:
4270 self.logger.error(ppp("Unexpected or invalid packet:", p))
4271 raise
4272
4273 def test_static_with_port_out2(self):
4274 """ 1:1 NAPT asymmetrical rule """
4275
4276 external_port = 80
4277 local_port = 8080
4278
4279 self.vapi.nat44_forwarding_enable_disable(1)
4280 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
4281 local_port, external_port,
4282 proto=IP_PROTOS.tcp, out2in_only=1)
4283 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
4284 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
4285 is_inside=0)
4286
4287 # from client to service
4288 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
4289 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
4290 TCP(sport=12345, dport=external_port))
4291 self.pg1.add_stream(p)
4292 self.pg_enable_capture(self.pg_interfaces)
4293 self.pg_start()
4294 capture = self.pg0.get_capture(1)
4295 p = capture[0]
4296 try:
4297 ip = p[IP]
4298 tcp = p[TCP]
4299 self.assertEqual(ip.dst, self.pg0.remote_ip4)
4300 self.assertEqual(tcp.dport, local_port)
4301 self.assert_packet_checksums_valid(p)
4302 except:
4303 self.logger.error(ppp("Unexpected or invalid packet:", p))
4304 raise
4305
4306 # ICMP error
4307 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
4308 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
4309 ICMP(type=11) / capture[0][IP])
4310 self.pg0.add_stream(p)
4311 self.pg_enable_capture(self.pg_interfaces)
4312 self.pg_start()
4313 capture = self.pg1.get_capture(1)
4314 p = capture[0]
4315 try:
4316 self.assertEqual(p[IP].src, self.nat_addr)
4317 inner = p[IPerror]
4318 self.assertEqual(inner.dst, self.nat_addr)
4319 self.assertEqual(inner[TCPerror].dport, external_port)
4320 except:
4321 self.logger.error(ppp("Unexpected or invalid packet:", p))
4322 raise
4323
4324 # from service back to client
4325 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
4326 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
4327 TCP(sport=local_port, dport=12345))
4328 self.pg0.add_stream(p)
4329 self.pg_enable_capture(self.pg_interfaces)
4330 self.pg_start()
4331 capture = self.pg1.get_capture(1)
4332 p = capture[0]
4333 try:
4334 ip = p[IP]
4335 tcp = p[TCP]
4336 self.assertEqual(ip.src, self.nat_addr)
4337 self.assertEqual(tcp.sport, external_port)
4338 self.assert_packet_checksums_valid(p)
4339 except:
4340 self.logger.error(ppp("Unexpected or invalid packet:", p))
4341 raise
4342
4343 # ICMP error
4344 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
4345 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
4346 ICMP(type=11) / capture[0][IP])
4347 self.pg1.add_stream(p)
4348 self.pg_enable_capture(self.pg_interfaces)
4349 self.pg_start()
4350 capture = self.pg0.get_capture(1)
4351 p = capture[0]
4352 try:
4353 self.assertEqual(p[IP].dst, self.pg0.remote_ip4)
4354 inner = p[IPerror]
4355 self.assertEqual(inner.src, self.pg0.remote_ip4)
4356 self.assertEqual(inner[TCPerror].sport, local_port)
4357 except:
4358 self.logger.error(ppp("Unexpected or invalid packet:", p))
4359 raise
4360
4361 # from client to server (no translation)
4362 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
4363 IP(src=self.pg1.remote_ip4, dst=self.pg0.remote_ip4) /
4364 TCP(sport=12346, dport=local_port))
4365 self.pg1.add_stream(p)
4366 self.pg_enable_capture(self.pg_interfaces)
4367 self.pg_start()
4368 capture = self.pg0.get_capture(1)
4369 p = capture[0]
4370 try:
4371 ip = p[IP]
4372 tcp = p[TCP]
4373 self.assertEqual(ip.dst, self.pg0.remote_ip4)
4374 self.assertEqual(tcp.dport, local_port)
4375 self.assert_packet_checksums_valid(p)
4376 except:
4377 self.logger.error(ppp("Unexpected or invalid packet:", p))
4378 raise
4379
4380 # from service back to client (no translation)
4381 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
4382 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
4383 TCP(sport=local_port, dport=12346))
4384 self.pg0.add_stream(p)
4385 self.pg_enable_capture(self.pg_interfaces)
4386 self.pg_start()
4387 capture = self.pg1.get_capture(1)
4388 p = capture[0]
4389 try:
4390 ip = p[IP]
4391 tcp = p[TCP]
4392 self.assertEqual(ip.src, self.pg0.remote_ip4)
4393 self.assertEqual(tcp.sport, local_port)
4394 self.assert_packet_checksums_valid(p)
4395 except:
4396 self.logger.error(ppp("Unexpected or invalid packet:", p))
4397 raise
4398
Matus Fabiande886752016-12-07 03:38:19 -08004399 def tearDown(self):
Matus Fabiana6110b62018-06-13 05:39:07 -07004400 super(TestNAT44EndpointDependent, self).tearDown()
Matus Fabiande886752016-12-07 03:38:19 -08004401 if not self.vpp_dead:
Matus Fabian82119542018-01-25 01:13:22 -08004402 self.logger.info(self.vapi.cli("show nat44 addresses"))
4403 self.logger.info(self.vapi.cli("show nat44 interfaces"))
4404 self.logger.info(self.vapi.cli("show nat44 static mappings"))
4405 self.logger.info(self.vapi.cli("show nat44 interface address"))
4406 self.logger.info(self.vapi.cli("show nat44 sessions detail"))
Matus Fabian229c1aa2018-05-28 04:09:52 -07004407 self.logger.info(self.vapi.cli("show nat44 hash tables detail"))
Matus Fabian2ba92e32017-08-21 07:05:03 -07004408 self.clear_nat44()
Matus Fabian229c1aa2018-05-28 04:09:52 -07004409 self.vapi.cli("clear logging")
Matus Fabiande886752016-12-07 03:38:19 -08004410
Matus Fabianeea28d72017-01-13 04:15:54 -08004411
Juraj Slobodacba69362017-12-19 02:09:32 +01004412class TestNAT44Out2InDPO(MethodHolder):
4413 """ NAT44 Test Cases using out2in DPO """
4414
4415 @classmethod
4416 def setUpConstants(cls):
4417 super(TestNAT44Out2InDPO, cls).setUpConstants()
4418 cls.vpp_cmdline.extend(["nat", "{", "out2in dpo", "}"])
4419
4420 @classmethod
4421 def setUpClass(cls):
4422 super(TestNAT44Out2InDPO, cls).setUpClass()
Matus Fabian229c1aa2018-05-28 04:09:52 -07004423 cls.vapi.cli("set log class nat level debug")
Juraj Slobodacba69362017-12-19 02:09:32 +01004424
4425 try:
4426 cls.tcp_port_in = 6303
4427 cls.tcp_port_out = 6303
4428 cls.udp_port_in = 6304
4429 cls.udp_port_out = 6304
4430 cls.icmp_id_in = 6305
4431 cls.icmp_id_out = 6305
4432 cls.nat_addr = '10.0.0.3'
4433 cls.nat_addr_n = socket.inet_pton(socket.AF_INET, cls.nat_addr)
4434 cls.dst_ip4 = '192.168.70.1'
4435
4436 cls.create_pg_interfaces(range(2))
4437
4438 cls.pg0.admin_up()
4439 cls.pg0.config_ip4()
4440 cls.pg0.resolve_arp()
4441
4442 cls.pg1.admin_up()
4443 cls.pg1.config_ip6()
4444 cls.pg1.resolve_ndp()
4445
4446 cls.vapi.ip_add_del_route(is_ipv6=True, dst_address='\x00'*16,
4447 dst_address_length=0,
4448 next_hop_address=cls.pg1.remote_ip6n,
4449 next_hop_sw_if_index=cls.pg1.sw_if_index)
4450
4451 except Exception:
4452 super(TestNAT44Out2InDPO, cls).tearDownClass()
4453 raise
4454
4455 def configure_xlat(self):
4456 self.dst_ip6_pfx = '1:2:3::'
4457 self.dst_ip6_pfx_n = socket.inet_pton(socket.AF_INET6,
4458 self.dst_ip6_pfx)
4459 self.dst_ip6_pfx_len = 96
4460 self.src_ip6_pfx = '4:5:6::'
4461 self.src_ip6_pfx_n = socket.inet_pton(socket.AF_INET6,
4462 self.src_ip6_pfx)
4463 self.src_ip6_pfx_len = 96
4464 self.vapi.map_add_domain(self.dst_ip6_pfx_n, self.dst_ip6_pfx_len,
4465 self.src_ip6_pfx_n, self.src_ip6_pfx_len,
4466 '\x00\x00\x00\x00', 0, is_translation=1,
4467 is_rfc6052=1)
4468
4469 def test_464xlat_ce(self):
4470 """ Test 464XLAT CE with NAT44 """
4471
4472 self.configure_xlat()
4473
4474 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
4475 self.vapi.nat44_add_del_address_range(self.nat_addr_n, self.nat_addr_n)
4476
4477 out_src_ip6 = self.compose_ip6(self.dst_ip4, self.dst_ip6_pfx,
4478 self.dst_ip6_pfx_len)
4479 out_dst_ip6 = self.compose_ip6(self.nat_addr, self.src_ip6_pfx,
4480 self.src_ip6_pfx_len)
4481
4482 try:
4483 pkts = self.create_stream_in(self.pg0, self.pg1, self.dst_ip4)
4484 self.pg0.add_stream(pkts)
4485 self.pg_enable_capture(self.pg_interfaces)
4486 self.pg_start()
4487 capture = self.pg1.get_capture(len(pkts))
4488 self.verify_capture_out_ip6(capture, nat_ip=out_dst_ip6,
4489 dst_ip=out_src_ip6)
4490
4491 pkts = self.create_stream_out_ip6(self.pg1, out_src_ip6,
4492 out_dst_ip6)
4493 self.pg1.add_stream(pkts)
4494 self.pg_enable_capture(self.pg_interfaces)
4495 self.pg_start()
4496 capture = self.pg0.get_capture(len(pkts))
4497 self.verify_capture_in(capture, self.pg0)
4498 finally:
4499 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index,
4500 is_add=0)
4501 self.vapi.nat44_add_del_address_range(self.nat_addr_n,
4502 self.nat_addr_n, is_add=0)
4503
4504 def test_464xlat_ce_no_nat(self):
4505 """ Test 464XLAT CE without NAT44 """
4506
4507 self.configure_xlat()
4508
4509 out_src_ip6 = self.compose_ip6(self.dst_ip4, self.dst_ip6_pfx,
4510 self.dst_ip6_pfx_len)
4511 out_dst_ip6 = self.compose_ip6(self.pg0.remote_ip4, self.src_ip6_pfx,
4512 self.src_ip6_pfx_len)
4513
4514 pkts = self.create_stream_in(self.pg0, self.pg1, self.dst_ip4)
4515 self.pg0.add_stream(pkts)
4516 self.pg_enable_capture(self.pg_interfaces)
4517 self.pg_start()
4518 capture = self.pg1.get_capture(len(pkts))
4519 self.verify_capture_out_ip6(capture, dst_ip=out_src_ip6,
4520 nat_ip=out_dst_ip6, same_port=True)
4521
4522 pkts = self.create_stream_out_ip6(self.pg1, out_src_ip6, out_dst_ip6)
4523 self.pg1.add_stream(pkts)
4524 self.pg_enable_capture(self.pg_interfaces)
4525 self.pg_start()
4526 capture = self.pg0.get_capture(len(pkts))
4527 self.verify_capture_in(capture, self.pg0)
4528
4529
Martin Gálikd7f75cd2017-03-27 06:02:47 -07004530class TestDeterministicNAT(MethodHolder):
Matus Fabian066f0342017-02-10 03:48:01 -08004531 """ Deterministic NAT Test Cases """
4532
4533 @classmethod
4534 def setUpConstants(cls):
4535 super(TestDeterministicNAT, cls).setUpConstants()
Matus Fabian2ba92e32017-08-21 07:05:03 -07004536 cls.vpp_cmdline.extend(["nat", "{", "deterministic", "}"])
Matus Fabian066f0342017-02-10 03:48:01 -08004537
4538 @classmethod
4539 def setUpClass(cls):
4540 super(TestDeterministicNAT, cls).setUpClass()
Matus Fabian229c1aa2018-05-28 04:09:52 -07004541 cls.vapi.cli("set log class nat level debug")
Matus Fabian066f0342017-02-10 03:48:01 -08004542
4543 try:
Martin Gálik977c1cb2017-03-30 23:21:51 -07004544 cls.tcp_port_in = 6303
Martin Gálik9806eae2017-04-25 01:25:08 -07004545 cls.tcp_external_port = 6303
Martin Gálik977c1cb2017-03-30 23:21:51 -07004546 cls.udp_port_in = 6304
Martin Gálik9806eae2017-04-25 01:25:08 -07004547 cls.udp_external_port = 6304
Martin Gálik977c1cb2017-03-30 23:21:51 -07004548 cls.icmp_id_in = 6305
Matus Fabian2ba92e32017-08-21 07:05:03 -07004549 cls.nat_addr = '10.0.0.3'
Martin Gálik977c1cb2017-03-30 23:21:51 -07004550
Matus Fabian2f2db1c2017-04-18 05:29:59 -07004551 cls.create_pg_interfaces(range(3))
Matus Fabian066f0342017-02-10 03:48:01 -08004552 cls.interfaces = list(cls.pg_interfaces)
4553
4554 for i in cls.interfaces:
4555 i.admin_up()
4556 i.config_ip4()
4557 i.resolve_arp()
4558
Martin Gálik977c1cb2017-03-30 23:21:51 -07004559 cls.pg0.generate_remote_hosts(2)
4560 cls.pg0.configure_ipv4_neighbors()
4561
Matus Fabian066f0342017-02-10 03:48:01 -08004562 except Exception:
4563 super(TestDeterministicNAT, cls).tearDownClass()
4564 raise
4565
Martin Gálik977c1cb2017-03-30 23:21:51 -07004566 def create_stream_in(self, in_if, out_if, ttl=64):
4567 """
4568 Create packet stream for inside network
4569
4570 :param in_if: Inside interface
4571 :param out_if: Outside interface
4572 :param ttl: TTL of generated packets
4573 """
4574 pkts = []
4575 # TCP
4576 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
4577 IP(src=in_if.remote_ip4, dst=out_if.remote_ip4, ttl=ttl) /
Martin Gálik9806eae2017-04-25 01:25:08 -07004578 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port))
Martin Gálik977c1cb2017-03-30 23:21:51 -07004579 pkts.append(p)
4580
4581 # UDP
4582 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
4583 IP(src=in_if.remote_ip4, dst=out_if.remote_ip4, ttl=ttl) /
Martin Gálik9806eae2017-04-25 01:25:08 -07004584 UDP(sport=self.udp_port_in, dport=self.udp_external_port))
Martin Gálik977c1cb2017-03-30 23:21:51 -07004585 pkts.append(p)
4586
4587 # ICMP
4588 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
4589 IP(src=in_if.remote_ip4, dst=out_if.remote_ip4, ttl=ttl) /
4590 ICMP(id=self.icmp_id_in, type='echo-request'))
4591 pkts.append(p)
4592
4593 return pkts
4594
4595 def create_stream_out(self, out_if, dst_ip=None, ttl=64):
4596 """
4597 Create packet stream for outside network
4598
4599 :param out_if: Outside interface
Matus Fabian2ba92e32017-08-21 07:05:03 -07004600 :param dst_ip: Destination IP address (Default use global NAT address)
Martin Gálik977c1cb2017-03-30 23:21:51 -07004601 :param ttl: TTL of generated packets
4602 """
4603 if dst_ip is None:
Matus Fabian2ba92e32017-08-21 07:05:03 -07004604 dst_ip = self.nat_addr
Martin Gálik977c1cb2017-03-30 23:21:51 -07004605 pkts = []
4606 # TCP
4607 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
4608 IP(src=out_if.remote_ip4, dst=dst_ip, ttl=ttl) /
Martin Gálik9806eae2017-04-25 01:25:08 -07004609 TCP(dport=self.tcp_port_out, sport=self.tcp_external_port))
Martin Gálik977c1cb2017-03-30 23:21:51 -07004610 pkts.append(p)
4611
4612 # UDP
4613 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
4614 IP(src=out_if.remote_ip4, dst=dst_ip, ttl=ttl) /
Martin Gálik9806eae2017-04-25 01:25:08 -07004615 UDP(dport=self.udp_port_out, sport=self.udp_external_port))
Martin Gálik977c1cb2017-03-30 23:21:51 -07004616 pkts.append(p)
4617
4618 # ICMP
4619 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
4620 IP(src=out_if.remote_ip4, dst=dst_ip, ttl=ttl) /
4621 ICMP(id=self.icmp_external_id, type='echo-reply'))
4622 pkts.append(p)
4623
4624 return pkts
4625
4626 def verify_capture_out(self, capture, nat_ip=None, packet_num=3):
4627 """
4628 Verify captured packets on outside network
4629
4630 :param capture: Captured packets
Matus Fabian2ba92e32017-08-21 07:05:03 -07004631 :param nat_ip: Translated IP address (Default use global NAT address)
Martin Gálik977c1cb2017-03-30 23:21:51 -07004632 :param same_port: Sorce port number is not translated (Default False)
4633 :param packet_num: Expected number of packets (Default 3)
4634 """
4635 if nat_ip is None:
Matus Fabian2ba92e32017-08-21 07:05:03 -07004636 nat_ip = self.nat_addr
Martin Gálik977c1cb2017-03-30 23:21:51 -07004637 self.assertEqual(packet_num, len(capture))
4638 for packet in capture:
4639 try:
4640 self.assertEqual(packet[IP].src, nat_ip)
4641 if packet.haslayer(TCP):
Martin Gálik9806eae2017-04-25 01:25:08 -07004642 self.tcp_port_out = packet[TCP].sport
Martin Gálik977c1cb2017-03-30 23:21:51 -07004643 elif packet.haslayer(UDP):
Martin Gálik9806eae2017-04-25 01:25:08 -07004644 self.udp_port_out = packet[UDP].sport
Martin Gálik977c1cb2017-03-30 23:21:51 -07004645 else:
4646 self.icmp_external_id = packet[ICMP].id
4647 except:
4648 self.logger.error(ppp("Unexpected or invalid packet "
4649 "(outside network):", packet))
4650 raise
4651
Matus Fabian2f2db1c2017-04-18 05:29:59 -07004652 def verify_ipfix_max_entries_per_user(self, data):
4653 """
4654 Verify IPFIX maximum entries per user exceeded event
4655
4656 :param data: Decoded IPFIX data records
4657 """
4658 self.assertEqual(1, len(data))
4659 record = data[0]
4660 # natEvent
4661 self.assertEqual(ord(record[230]), 13)
4662 # natQuotaExceededEvent
4663 self.assertEqual('\x03\x00\x00\x00', record[466])
Matus Fabiana431ad12018-01-04 04:03:14 -08004664 # maxEntriesPerUser
4665 self.assertEqual('\xe8\x03\x00\x00', record[473])
Matus Fabian2f2db1c2017-04-18 05:29:59 -07004666 # sourceIPv4Address
4667 self.assertEqual(self.pg0.remote_ip4n, record[8])
4668
Matus Fabian066f0342017-02-10 03:48:01 -08004669 def test_deterministic_mode(self):
Matus Fabian2ba92e32017-08-21 07:05:03 -07004670 """ NAT plugin run deterministic mode """
Matus Fabian066f0342017-02-10 03:48:01 -08004671 in_addr = '172.16.255.0'
4672 out_addr = '172.17.255.50'
4673 in_addr_t = '172.16.255.20'
4674 in_addr_n = socket.inet_aton(in_addr)
4675 out_addr_n = socket.inet_aton(out_addr)
4676 in_addr_t_n = socket.inet_aton(in_addr_t)
4677 in_plen = 24
4678 out_plen = 32
4679
Matus Fabian2ba92e32017-08-21 07:05:03 -07004680 nat_config = self.vapi.nat_show_config()
4681 self.assertEqual(1, nat_config.deterministic)
Matus Fabian066f0342017-02-10 03:48:01 -08004682
Matus Fabian2ba92e32017-08-21 07:05:03 -07004683 self.vapi.nat_det_add_del_map(in_addr_n, in_plen, out_addr_n, out_plen)
Matus Fabian066f0342017-02-10 03:48:01 -08004684
Matus Fabian2ba92e32017-08-21 07:05:03 -07004685 rep1 = self.vapi.nat_det_forward(in_addr_t_n)
Matus Fabian066f0342017-02-10 03:48:01 -08004686 self.assertEqual(rep1.out_addr[:4], out_addr_n)
Matus Fabian2ba92e32017-08-21 07:05:03 -07004687 rep2 = self.vapi.nat_det_reverse(out_addr_n, rep1.out_port_hi)
Matus Fabian066f0342017-02-10 03:48:01 -08004688 self.assertEqual(rep2.in_addr[:4], in_addr_t_n)
4689
Matus Fabian2ba92e32017-08-21 07:05:03 -07004690 deterministic_mappings = self.vapi.nat_det_map_dump()
Martin17a75cb2017-03-08 05:53:20 -08004691 self.assertEqual(len(deterministic_mappings), 1)
4692 dsm = deterministic_mappings[0]
4693 self.assertEqual(in_addr_n, dsm.in_addr[:4])
4694 self.assertEqual(in_plen, dsm.in_plen)
4695 self.assertEqual(out_addr_n, dsm.out_addr[:4])
4696 self.assertEqual(out_plen, dsm.out_plen)
4697
Matus Fabian2ba92e32017-08-21 07:05:03 -07004698 self.clear_nat_det()
4699 deterministic_mappings = self.vapi.nat_det_map_dump()
Martinb616e9f2017-03-14 02:25:45 -07004700 self.assertEqual(len(deterministic_mappings), 0)
4701
Matus Fabian6a0946f2017-04-12 03:36:13 -07004702 def test_set_timeouts(self):
4703 """ Set deterministic NAT timeouts """
Matus Fabian2ba92e32017-08-21 07:05:03 -07004704 timeouts_before = self.vapi.nat_det_get_timeouts()
Matus Fabian6a0946f2017-04-12 03:36:13 -07004705
Matus Fabian2ba92e32017-08-21 07:05:03 -07004706 self.vapi.nat_det_set_timeouts(timeouts_before.udp + 10,
4707 timeouts_before.tcp_established + 10,
4708 timeouts_before.tcp_transitory + 10,
4709 timeouts_before.icmp + 10)
Matus Fabian6a0946f2017-04-12 03:36:13 -07004710
Matus Fabian2ba92e32017-08-21 07:05:03 -07004711 timeouts_after = self.vapi.nat_det_get_timeouts()
Matus Fabian6a0946f2017-04-12 03:36:13 -07004712
4713 self.assertNotEqual(timeouts_before.udp, timeouts_after.udp)
4714 self.assertNotEqual(timeouts_before.icmp, timeouts_after.icmp)
4715 self.assertNotEqual(timeouts_before.tcp_established,
4716 timeouts_after.tcp_established)
4717 self.assertNotEqual(timeouts_before.tcp_transitory,
4718 timeouts_after.tcp_transitory)
4719
Martin Gálik977c1cb2017-03-30 23:21:51 -07004720 def test_det_in(self):
Matus Fabian2ba92e32017-08-21 07:05:03 -07004721 """ Deterministic NAT translation test (TCP, UDP, ICMP) """
Martin Gálik977c1cb2017-03-30 23:21:51 -07004722
4723 nat_ip = "10.0.0.10"
Martin Gálik977c1cb2017-03-30 23:21:51 -07004724
Matus Fabian2ba92e32017-08-21 07:05:03 -07004725 self.vapi.nat_det_add_del_map(self.pg0.remote_ip4n,
4726 32,
4727 socket.inet_aton(nat_ip),
4728 32)
4729 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
4730 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
4731 is_inside=0)
Martin Gálik977c1cb2017-03-30 23:21:51 -07004732
4733 # in2out
4734 pkts = self.create_stream_in(self.pg0, self.pg1)
4735 self.pg0.add_stream(pkts)
4736 self.pg_enable_capture(self.pg_interfaces)
4737 self.pg_start()
4738 capture = self.pg1.get_capture(len(pkts))
4739 self.verify_capture_out(capture, nat_ip)
4740
4741 # out2in
4742 pkts = self.create_stream_out(self.pg1, nat_ip)
4743 self.pg1.add_stream(pkts)
4744 self.pg_enable_capture(self.pg_interfaces)
4745 self.pg_start()
4746 capture = self.pg0.get_capture(len(pkts))
4747 self.verify_capture_in(capture, self.pg0)
4748
Martin Gálik9806eae2017-04-25 01:25:08 -07004749 # session dump test
Matus Fabian2ba92e32017-08-21 07:05:03 -07004750 sessions = self.vapi.nat_det_session_dump(self.pg0.remote_ip4n)
Martin Gálik9806eae2017-04-25 01:25:08 -07004751 self.assertEqual(len(sessions), 3)
4752
4753 # TCP session
4754 s = sessions[0]
4755 self.assertEqual(s.ext_addr[:4], self.pg1.remote_ip4n)
4756 self.assertEqual(s.in_port, self.tcp_port_in)
4757 self.assertEqual(s.out_port, self.tcp_port_out)
4758 self.assertEqual(s.ext_port, self.tcp_external_port)
4759
4760 # UDP session
4761 s = sessions[1]
4762 self.assertEqual(s.ext_addr[:4], self.pg1.remote_ip4n)
4763 self.assertEqual(s.in_port, self.udp_port_in)
4764 self.assertEqual(s.out_port, self.udp_port_out)
4765 self.assertEqual(s.ext_port, self.udp_external_port)
4766
4767 # ICMP session
4768 s = sessions[2]
4769 self.assertEqual(s.ext_addr[:4], self.pg1.remote_ip4n)
4770 self.assertEqual(s.in_port, self.icmp_id_in)
4771 self.assertEqual(s.out_port, self.icmp_external_id)
4772
Martin Gálik977c1cb2017-03-30 23:21:51 -07004773 def test_multiple_users(self):
Matus Fabian2ba92e32017-08-21 07:05:03 -07004774 """ Deterministic NAT multiple users """
Martin Gálik977c1cb2017-03-30 23:21:51 -07004775
4776 nat_ip = "10.0.0.10"
4777 port_in = 80
Martin Gálik9806eae2017-04-25 01:25:08 -07004778 external_port = 6303
Martin Gálik977c1cb2017-03-30 23:21:51 -07004779
4780 host0 = self.pg0.remote_hosts[0]
4781 host1 = self.pg0.remote_hosts[1]
4782
Matus Fabian2ba92e32017-08-21 07:05:03 -07004783 self.vapi.nat_det_add_del_map(host0.ip4n,
4784 24,
4785 socket.inet_aton(nat_ip),
4786 32)
4787 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
4788 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
4789 is_inside=0)
Martin Gálik977c1cb2017-03-30 23:21:51 -07004790
4791 # host0 to out
4792 p = (Ether(src=host0.mac, dst=self.pg0.local_mac) /
4793 IP(src=host0.ip4, dst=self.pg1.remote_ip4) /
Martin Gálik9806eae2017-04-25 01:25:08 -07004794 TCP(sport=port_in, dport=external_port))
Martin Gálik977c1cb2017-03-30 23:21:51 -07004795 self.pg0.add_stream(p)
4796 self.pg_enable_capture(self.pg_interfaces)
4797 self.pg_start()
4798 capture = self.pg1.get_capture(1)
4799 p = capture[0]
4800 try:
4801 ip = p[IP]
4802 tcp = p[TCP]
4803 self.assertEqual(ip.src, nat_ip)
4804 self.assertEqual(ip.dst, self.pg1.remote_ip4)
Martin Gálik9806eae2017-04-25 01:25:08 -07004805 self.assertEqual(tcp.dport, external_port)
4806 port_out0 = tcp.sport
Martin Gálik977c1cb2017-03-30 23:21:51 -07004807 except:
4808 self.logger.error(ppp("Unexpected or invalid packet:", p))
4809 raise
4810
4811 # host1 to out
4812 p = (Ether(src=host1.mac, dst=self.pg0.local_mac) /
4813 IP(src=host1.ip4, dst=self.pg1.remote_ip4) /
Martin Gálik9806eae2017-04-25 01:25:08 -07004814 TCP(sport=port_in, dport=external_port))
Martin Gálik977c1cb2017-03-30 23:21:51 -07004815 self.pg0.add_stream(p)
4816 self.pg_enable_capture(self.pg_interfaces)
4817 self.pg_start()
4818 capture = self.pg1.get_capture(1)
4819 p = capture[0]
4820 try:
4821 ip = p[IP]
4822 tcp = p[TCP]
4823 self.assertEqual(ip.src, nat_ip)
4824 self.assertEqual(ip.dst, self.pg1.remote_ip4)
Martin Gálik9806eae2017-04-25 01:25:08 -07004825 self.assertEqual(tcp.dport, external_port)
4826 port_out1 = tcp.sport
Martin Gálik977c1cb2017-03-30 23:21:51 -07004827 except:
4828 self.logger.error(ppp("Unexpected or invalid packet:", p))
4829 raise
4830
Matus Fabian2ba92e32017-08-21 07:05:03 -07004831 dms = self.vapi.nat_det_map_dump()
Martin Gálik977c1cb2017-03-30 23:21:51 -07004832 self.assertEqual(1, len(dms))
4833 self.assertEqual(2, dms[0].ses_num)
4834
4835 # out to host0
4836 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
4837 IP(src=self.pg1.remote_ip4, dst=nat_ip) /
Martin Gálik9806eae2017-04-25 01:25:08 -07004838 TCP(sport=external_port, dport=port_out0))
Martin Gálik977c1cb2017-03-30 23:21:51 -07004839 self.pg1.add_stream(p)
4840 self.pg_enable_capture(self.pg_interfaces)
4841 self.pg_start()
4842 capture = self.pg0.get_capture(1)
4843 p = capture[0]
4844 try:
4845 ip = p[IP]
4846 tcp = p[TCP]
4847 self.assertEqual(ip.src, self.pg1.remote_ip4)
4848 self.assertEqual(ip.dst, host0.ip4)
4849 self.assertEqual(tcp.dport, port_in)
Martin Gálik9806eae2017-04-25 01:25:08 -07004850 self.assertEqual(tcp.sport, external_port)
Martin Gálik977c1cb2017-03-30 23:21:51 -07004851 except:
4852 self.logger.error(ppp("Unexpected or invalid packet:", p))
4853 raise
4854
4855 # out to host1
4856 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
4857 IP(src=self.pg1.remote_ip4, dst=nat_ip) /
Martin Gálik9806eae2017-04-25 01:25:08 -07004858 TCP(sport=external_port, dport=port_out1))
Martin Gálik977c1cb2017-03-30 23:21:51 -07004859 self.pg1.add_stream(p)
4860 self.pg_enable_capture(self.pg_interfaces)
4861 self.pg_start()
4862 capture = self.pg0.get_capture(1)
4863 p = capture[0]
4864 try:
4865 ip = p[IP]
4866 tcp = p[TCP]
4867 self.assertEqual(ip.src, self.pg1.remote_ip4)
4868 self.assertEqual(ip.dst, host1.ip4)
4869 self.assertEqual(tcp.dport, port_in)
Martin Gálik9806eae2017-04-25 01:25:08 -07004870 self.assertEqual(tcp.sport, external_port)
Martin Gálik977c1cb2017-03-30 23:21:51 -07004871 except:
4872 self.logger.error(ppp("Unexpected or invalid packet", p))
4873 raise
4874
Martin Gálik6bc8c642017-04-19 01:12:27 -07004875 # session close api test
Matus Fabian2ba92e32017-08-21 07:05:03 -07004876 self.vapi.nat_det_close_session_out(socket.inet_aton(nat_ip),
4877 port_out1,
Martin Gálik6bc8c642017-04-19 01:12:27 -07004878 self.pg1.remote_ip4n,
Martin Gálik9806eae2017-04-25 01:25:08 -07004879 external_port)
Matus Fabian2ba92e32017-08-21 07:05:03 -07004880 dms = self.vapi.nat_det_map_dump()
4881 self.assertEqual(dms[0].ses_num, 1)
4882
4883 self.vapi.nat_det_close_session_in(host0.ip4n,
4884 port_in,
4885 self.pg1.remote_ip4n,
4886 external_port)
4887 dms = self.vapi.nat_det_map_dump()
Martin Gálik6bc8c642017-04-19 01:12:27 -07004888 self.assertEqual(dms[0].ses_num, 0)
4889
Martin Gálik977c1cb2017-03-30 23:21:51 -07004890 def test_tcp_session_close_detection_in(self):
Matus Fabian2ba92e32017-08-21 07:05:03 -07004891 """ Deterministic NAT TCP session close from inside network """
4892 self.vapi.nat_det_add_del_map(self.pg0.remote_ip4n,
4893 32,
4894 socket.inet_aton(self.nat_addr),
4895 32)
4896 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
4897 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
4898 is_inside=0)
Martin Gálik977c1cb2017-03-30 23:21:51 -07004899
4900 self.initiate_tcp_session(self.pg0, self.pg1)
4901
4902 # close the session from inside
4903 try:
4904 # FIN packet in -> out
4905 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
4906 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
Martin Gálik9806eae2017-04-25 01:25:08 -07004907 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
Martin Gálik977c1cb2017-03-30 23:21:51 -07004908 flags="F"))
4909 self.pg0.add_stream(p)
4910 self.pg_enable_capture(self.pg_interfaces)
4911 self.pg_start()
4912 self.pg1.get_capture(1)
4913
4914 pkts = []
4915
4916 # ACK packet out -> in
4917 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
Matus Fabian2ba92e32017-08-21 07:05:03 -07004918 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
Martin Gálik9806eae2017-04-25 01:25:08 -07004919 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
Martin Gálik977c1cb2017-03-30 23:21:51 -07004920 flags="A"))
4921 pkts.append(p)
4922
4923 # FIN packet out -> in
4924 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
Matus Fabian2ba92e32017-08-21 07:05:03 -07004925 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
Martin Gálik9806eae2017-04-25 01:25:08 -07004926 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
Martin Gálik977c1cb2017-03-30 23:21:51 -07004927 flags="F"))
4928 pkts.append(p)
4929
4930 self.pg1.add_stream(pkts)
4931 self.pg_enable_capture(self.pg_interfaces)
4932 self.pg_start()
4933 self.pg0.get_capture(2)
4934
4935 # ACK packet in -> out
4936 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
4937 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
Martin Gálik9806eae2017-04-25 01:25:08 -07004938 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
Martin Gálik977c1cb2017-03-30 23:21:51 -07004939 flags="A"))
4940 self.pg0.add_stream(p)
4941 self.pg_enable_capture(self.pg_interfaces)
4942 self.pg_start()
4943 self.pg1.get_capture(1)
4944
Matus Fabian2ba92e32017-08-21 07:05:03 -07004945 # Check if deterministic NAT44 closed the session
4946 dms = self.vapi.nat_det_map_dump()
Martin Gálik977c1cb2017-03-30 23:21:51 -07004947 self.assertEqual(0, dms[0].ses_num)
4948 except:
4949 self.logger.error("TCP session termination failed")
4950 raise
4951
4952 def test_tcp_session_close_detection_out(self):
Matus Fabian2ba92e32017-08-21 07:05:03 -07004953 """ Deterministic NAT TCP session close from outside network """
4954 self.vapi.nat_det_add_del_map(self.pg0.remote_ip4n,
4955 32,
4956 socket.inet_aton(self.nat_addr),
4957 32)
4958 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
4959 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
4960 is_inside=0)
Martin Gálik977c1cb2017-03-30 23:21:51 -07004961
4962 self.initiate_tcp_session(self.pg0, self.pg1)
4963
4964 # close the session from outside
4965 try:
4966 # FIN packet out -> in
4967 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
Matus Fabian2ba92e32017-08-21 07:05:03 -07004968 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
Martin Gálik9806eae2017-04-25 01:25:08 -07004969 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
Martin Gálik977c1cb2017-03-30 23:21:51 -07004970 flags="F"))
4971 self.pg1.add_stream(p)
4972 self.pg_enable_capture(self.pg_interfaces)
4973 self.pg_start()
4974 self.pg0.get_capture(1)
4975
4976 pkts = []
4977
4978 # ACK packet in -> out
4979 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
4980 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
Martin Gálik9806eae2017-04-25 01:25:08 -07004981 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
Martin Gálik977c1cb2017-03-30 23:21:51 -07004982 flags="A"))
4983 pkts.append(p)
4984
4985 # ACK packet in -> out
4986 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
4987 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
Martin Gálik9806eae2017-04-25 01:25:08 -07004988 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
Martin Gálik977c1cb2017-03-30 23:21:51 -07004989 flags="F"))
4990 pkts.append(p)
4991
4992 self.pg0.add_stream(pkts)
4993 self.pg_enable_capture(self.pg_interfaces)
4994 self.pg_start()
4995 self.pg1.get_capture(2)
4996
4997 # ACK packet out -> in
4998 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
Matus Fabian2ba92e32017-08-21 07:05:03 -07004999 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
Martin Gálik9806eae2017-04-25 01:25:08 -07005000 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
Martin Gálik977c1cb2017-03-30 23:21:51 -07005001 flags="A"))
5002 self.pg1.add_stream(p)
5003 self.pg_enable_capture(self.pg_interfaces)
5004 self.pg_start()
5005 self.pg0.get_capture(1)
5006
Matus Fabian2ba92e32017-08-21 07:05:03 -07005007 # Check if deterministic NAT44 closed the session
5008 dms = self.vapi.nat_det_map_dump()
Martin Gálik977c1cb2017-03-30 23:21:51 -07005009 self.assertEqual(0, dms[0].ses_num)
5010 except:
5011 self.logger.error("TCP session termination failed")
5012 raise
5013
5014 @unittest.skipUnless(running_extended_tests(), "part of extended tests")
5015 def test_session_timeout(self):
Matus Fabian2ba92e32017-08-21 07:05:03 -07005016 """ Deterministic NAT session timeouts """
5017 self.vapi.nat_det_add_del_map(self.pg0.remote_ip4n,
5018 32,
5019 socket.inet_aton(self.nat_addr),
5020 32)
5021 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
5022 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
5023 is_inside=0)
Martin Gálik977c1cb2017-03-30 23:21:51 -07005024
5025 self.initiate_tcp_session(self.pg0, self.pg1)
Matus Fabian2ba92e32017-08-21 07:05:03 -07005026 self.vapi.nat_det_set_timeouts(5, 5, 5, 5)
Martin Gálik977c1cb2017-03-30 23:21:51 -07005027 pkts = self.create_stream_in(self.pg0, self.pg1)
5028 self.pg0.add_stream(pkts)
5029 self.pg_enable_capture(self.pg_interfaces)
5030 self.pg_start()
5031 capture = self.pg1.get_capture(len(pkts))
5032 sleep(15)
5033
Matus Fabian2ba92e32017-08-21 07:05:03 -07005034 dms = self.vapi.nat_det_map_dump()
Martin Gálik977c1cb2017-03-30 23:21:51 -07005035 self.assertEqual(0, dms[0].ses_num)
5036
Matus Fabian7c0aecc2017-07-03 01:21:38 -07005037 @unittest.skipUnless(running_extended_tests(), "part of extended tests")
Martin Gálik977c1cb2017-03-30 23:21:51 -07005038 def test_session_limit_per_user(self):
Matus Fabian2ba92e32017-08-21 07:05:03 -07005039 """ Deterministic NAT maximum sessions per user limit """
5040 self.vapi.nat_det_add_del_map(self.pg0.remote_ip4n,
5041 32,
5042 socket.inet_aton(self.nat_addr),
5043 32)
5044 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
5045 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
5046 is_inside=0)
Matus Fabian2f2db1c2017-04-18 05:29:59 -07005047 self.vapi.set_ipfix_exporter(collector_address=self.pg2.remote_ip4n,
5048 src_address=self.pg2.local_ip4n,
5049 path_mtu=512,
5050 template_interval=10)
Matus Fabian2ba92e32017-08-21 07:05:03 -07005051 self.vapi.nat_ipfix()
Martin Gálik977c1cb2017-03-30 23:21:51 -07005052
5053 pkts = []
5054 for port in range(1025, 2025):
5055 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5056 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5057 UDP(sport=port, dport=port))
5058 pkts.append(p)
5059
5060 self.pg0.add_stream(pkts)
5061 self.pg_enable_capture(self.pg_interfaces)
5062 self.pg_start()
5063 capture = self.pg1.get_capture(len(pkts))
5064
5065 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5066 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
Martin Gálikf7e655d2017-04-27 02:13:26 -07005067 UDP(sport=3001, dport=3002))
Martin Gálik977c1cb2017-03-30 23:21:51 -07005068 self.pg0.add_stream(p)
5069 self.pg_enable_capture(self.pg_interfaces)
5070 self.pg_start()
5071 capture = self.pg1.assert_nothing_captured()
5072
Martin Gálikf7e655d2017-04-27 02:13:26 -07005073 # verify ICMP error packet
5074 capture = self.pg0.get_capture(1)
5075 p = capture[0]
5076 self.assertTrue(p.haslayer(ICMP))
5077 icmp = p[ICMP]
5078 self.assertEqual(icmp.type, 3)
5079 self.assertEqual(icmp.code, 1)
5080 self.assertTrue(icmp.haslayer(IPerror))
5081 inner_ip = icmp[IPerror]
5082 self.assertEqual(inner_ip[UDPerror].sport, 3001)
5083 self.assertEqual(inner_ip[UDPerror].dport, 3002)
5084
Matus Fabian2ba92e32017-08-21 07:05:03 -07005085 dms = self.vapi.nat_det_map_dump()
Martin Gálik977c1cb2017-03-30 23:21:51 -07005086
5087 self.assertEqual(1000, dms[0].ses_num)
5088
Matus Fabian2f2db1c2017-04-18 05:29:59 -07005089 # verify IPFIX logging
5090 self.vapi.cli("ipfix flush") # FIXME this should be an API call
Matus Fabian7c0aecc2017-07-03 01:21:38 -07005091 sleep(1)
Matus Fabian2f2db1c2017-04-18 05:29:59 -07005092 capture = self.pg2.get_capture(2)
5093 ipfix = IPFIXDecoder()
5094 # first load template
5095 for p in capture:
5096 self.assertTrue(p.haslayer(IPFIX))
5097 if p.haslayer(Template):
5098 ipfix.add_template(p.getlayer(Template))
5099 # verify events in data set
5100 for p in capture:
5101 if p.haslayer(Data):
5102 data = ipfix.decode_data_set(p.getlayer(Set))
5103 self.verify_ipfix_max_entries_per_user(data)
5104
Matus Fabian2ba92e32017-08-21 07:05:03 -07005105 def clear_nat_det(self):
Martin17a75cb2017-03-08 05:53:20 -08005106 """
Matus Fabian2ba92e32017-08-21 07:05:03 -07005107 Clear deterministic NAT configuration.
Martin17a75cb2017-03-08 05:53:20 -08005108 """
Matus Fabian2ba92e32017-08-21 07:05:03 -07005109 self.vapi.nat_ipfix(enable=0)
5110 self.vapi.nat_det_set_timeouts()
5111 deterministic_mappings = self.vapi.nat_det_map_dump()
Martin17a75cb2017-03-08 05:53:20 -08005112 for dsm in deterministic_mappings:
Matus Fabian2ba92e32017-08-21 07:05:03 -07005113 self.vapi.nat_det_add_del_map(dsm.in_addr,
5114 dsm.in_plen,
5115 dsm.out_addr,
5116 dsm.out_plen,
5117 is_add=0)
Martin17a75cb2017-03-08 05:53:20 -08005118
Matus Fabian2ba92e32017-08-21 07:05:03 -07005119 interfaces = self.vapi.nat44_interface_dump()
Martin Gálik977c1cb2017-03-30 23:21:51 -07005120 for intf in interfaces:
Matus Fabian2ba92e32017-08-21 07:05:03 -07005121 self.vapi.nat44_interface_add_del_feature(intf.sw_if_index,
5122 intf.is_inside,
5123 is_add=0)
Martin Gálik977c1cb2017-03-30 23:21:51 -07005124
Matus Fabian066f0342017-02-10 03:48:01 -08005125 def tearDown(self):
5126 super(TestDeterministicNAT, self).tearDown()
5127 if not self.vpp_dead:
Matus Fabian82119542018-01-25 01:13:22 -08005128 self.logger.info(self.vapi.cli("show nat44 interfaces"))
5129 self.logger.info(
5130 self.vapi.cli("show nat44 deterministic mappings"))
5131 self.logger.info(
5132 self.vapi.cli("show nat44 deterministic timeouts"))
5133 self.logger.info(
5134 self.vapi.cli("show nat44 deterministic sessions"))
Matus Fabian2ba92e32017-08-21 07:05:03 -07005135 self.clear_nat_det()
Matus Fabian066f0342017-02-10 03:48:01 -08005136
Matus Fabian06596c52017-06-06 04:53:28 -07005137
5138class TestNAT64(MethodHolder):
5139 """ NAT64 Test Cases """
5140
5141 @classmethod
Matus Fabiana431ad12018-01-04 04:03:14 -08005142 def setUpConstants(cls):
5143 super(TestNAT64, cls).setUpConstants()
5144 cls.vpp_cmdline.extend(["nat", "{", "nat64 bib hash buckets 128",
5145 "nat64 st hash buckets 256", "}"])
5146
5147 @classmethod
Matus Fabian06596c52017-06-06 04:53:28 -07005148 def setUpClass(cls):
5149 super(TestNAT64, cls).setUpClass()
5150
5151 try:
5152 cls.tcp_port_in = 6303
5153 cls.tcp_port_out = 6303
5154 cls.udp_port_in = 6304
5155 cls.udp_port_out = 6304
5156 cls.icmp_id_in = 6305
5157 cls.icmp_id_out = 6305
5158 cls.nat_addr = '10.0.0.3'
5159 cls.nat_addr_n = socket.inet_pton(socket.AF_INET, cls.nat_addr)
Matus Fabian029f3d22017-06-15 02:28:50 -07005160 cls.vrf1_id = 10
5161 cls.vrf1_nat_addr = '10.0.10.3'
5162 cls.vrf1_nat_addr_n = socket.inet_pton(socket.AF_INET,
5163 cls.vrf1_nat_addr)
Matus Fabiana431ad12018-01-04 04:03:14 -08005164 cls.ipfix_src_port = 4739
5165 cls.ipfix_domain_id = 1
Matus Fabian06596c52017-06-06 04:53:28 -07005166
Matus Fabian0938dcf2017-11-08 01:59:38 -08005167 cls.create_pg_interfaces(range(5))
Matus Fabian06596c52017-06-06 04:53:28 -07005168 cls.ip6_interfaces = list(cls.pg_interfaces[0:1])
Matus Fabian029f3d22017-06-15 02:28:50 -07005169 cls.ip6_interfaces.append(cls.pg_interfaces[2])
Matus Fabian06596c52017-06-06 04:53:28 -07005170 cls.ip4_interfaces = list(cls.pg_interfaces[1:2])
5171
Neale Ranns15002542017-09-10 04:39:11 -07005172 cls.vapi.ip_table_add_del(cls.vrf1_id, is_add=1, is_ipv6=1)
5173
Matus Fabian029f3d22017-06-15 02:28:50 -07005174 cls.pg_interfaces[2].set_table_ip6(cls.vrf1_id)
5175
5176 cls.pg0.generate_remote_hosts(2)
5177
Matus Fabian06596c52017-06-06 04:53:28 -07005178 for i in cls.ip6_interfaces:
5179 i.admin_up()
5180 i.config_ip6()
Matus Fabian029f3d22017-06-15 02:28:50 -07005181 i.configure_ipv6_neighbors()
Matus Fabian06596c52017-06-06 04:53:28 -07005182
5183 for i in cls.ip4_interfaces:
5184 i.admin_up()
5185 i.config_ip4()
5186 i.resolve_arp()
5187
Matus Fabian36ea2d62017-10-24 04:13:49 -07005188 cls.pg3.admin_up()
5189 cls.pg3.config_ip4()
5190 cls.pg3.resolve_arp()
5191 cls.pg3.config_ip6()
5192 cls.pg3.configure_ipv6_neighbors()
5193
Matus Fabian06596c52017-06-06 04:53:28 -07005194 except Exception:
5195 super(TestNAT64, cls).tearDownClass()
5196 raise
5197
5198 def test_pool(self):
5199 """ Add/delete address to NAT64 pool """
5200 nat_addr = socket.inet_pton(socket.AF_INET, '1.2.3.4')
5201
5202 self.vapi.nat64_add_del_pool_addr_range(nat_addr, nat_addr)
5203
5204 addresses = self.vapi.nat64_pool_addr_dump()
5205 self.assertEqual(len(addresses), 1)
5206 self.assertEqual(addresses[0].address, nat_addr)
5207
5208 self.vapi.nat64_add_del_pool_addr_range(nat_addr, nat_addr, is_add=0)
5209
5210 addresses = self.vapi.nat64_pool_addr_dump()
5211 self.assertEqual(len(addresses), 0)
5212
5213 def test_interface(self):
5214 """ Enable/disable NAT64 feature on the interface """
5215 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
5216 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
5217
5218 interfaces = self.vapi.nat64_interface_dump()
5219 self.assertEqual(len(interfaces), 2)
5220 pg0_found = False
5221 pg1_found = False
5222 for intf in interfaces:
5223 if intf.sw_if_index == self.pg0.sw_if_index:
5224 self.assertEqual(intf.is_inside, 1)
5225 pg0_found = True
5226 elif intf.sw_if_index == self.pg1.sw_if_index:
5227 self.assertEqual(intf.is_inside, 0)
5228 pg1_found = True
5229 self.assertTrue(pg0_found)
5230 self.assertTrue(pg1_found)
5231
5232 features = self.vapi.cli("show interface features pg0")
5233 self.assertNotEqual(features.find('nat64-in2out'), -1)
5234 features = self.vapi.cli("show interface features pg1")
5235 self.assertNotEqual(features.find('nat64-out2in'), -1)
5236
5237 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index, is_add=0)
5238 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_add=0)
5239
5240 interfaces = self.vapi.nat64_interface_dump()
5241 self.assertEqual(len(interfaces), 0)
5242
5243 def test_static_bib(self):
5244 """ Add/delete static BIB entry """
5245 in_addr = socket.inet_pton(socket.AF_INET6,
5246 '2001:db8:85a3::8a2e:370:7334')
5247 out_addr = socket.inet_pton(socket.AF_INET, '10.1.1.3')
5248 in_port = 1234
5249 out_port = 5678
5250 proto = IP_PROTOS.tcp
5251
5252 self.vapi.nat64_add_del_static_bib(in_addr,
5253 out_addr,
5254 in_port,
5255 out_port,
5256 proto)
5257 bib = self.vapi.nat64_bib_dump(IP_PROTOS.tcp)
5258 static_bib_num = 0
5259 for bibe in bib:
5260 if bibe.is_static:
5261 static_bib_num += 1
5262 self.assertEqual(bibe.i_addr, in_addr)
5263 self.assertEqual(bibe.o_addr, out_addr)
5264 self.assertEqual(bibe.i_port, in_port)
5265 self.assertEqual(bibe.o_port, out_port)
5266 self.assertEqual(static_bib_num, 1)
5267
5268 self.vapi.nat64_add_del_static_bib(in_addr,
5269 out_addr,
5270 in_port,
5271 out_port,
5272 proto,
5273 is_add=0)
5274 bib = self.vapi.nat64_bib_dump(IP_PROTOS.tcp)
5275 static_bib_num = 0
5276 for bibe in bib:
5277 if bibe.is_static:
5278 static_bib_num += 1
5279 self.assertEqual(static_bib_num, 0)
5280
5281 def test_set_timeouts(self):
5282 """ Set NAT64 timeouts """
5283 # verify default values
5284 timeouts = self.vapi.nat64_get_timeouts()
5285 self.assertEqual(timeouts.udp, 300)
5286 self.assertEqual(timeouts.icmp, 60)
5287 self.assertEqual(timeouts.tcp_trans, 240)
5288 self.assertEqual(timeouts.tcp_est, 7440)
5289 self.assertEqual(timeouts.tcp_incoming_syn, 6)
5290
5291 # set and verify custom values
5292 self.vapi.nat64_set_timeouts(udp=200, icmp=30, tcp_trans=250,
5293 tcp_est=7450, tcp_incoming_syn=10)
5294 timeouts = self.vapi.nat64_get_timeouts()
5295 self.assertEqual(timeouts.udp, 200)
5296 self.assertEqual(timeouts.icmp, 30)
5297 self.assertEqual(timeouts.tcp_trans, 250)
5298 self.assertEqual(timeouts.tcp_est, 7450)
5299 self.assertEqual(timeouts.tcp_incoming_syn, 10)
5300
5301 def test_dynamic(self):
5302 """ NAT64 dynamic translation test """
5303 self.tcp_port_in = 6303
5304 self.udp_port_in = 6304
5305 self.icmp_id_in = 6305
5306
5307 ses_num_start = self.nat64_get_ses_num()
5308
5309 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
5310 self.nat_addr_n)
5311 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
5312 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
5313
5314 # in2out
5315 pkts = self.create_stream_in_ip6(self.pg0, self.pg1)
5316 self.pg0.add_stream(pkts)
5317 self.pg_enable_capture(self.pg_interfaces)
5318 self.pg_start()
Matus Fabian029f3d22017-06-15 02:28:50 -07005319 capture = self.pg1.get_capture(len(pkts))
5320 self.verify_capture_out(capture, nat_ip=self.nat_addr,
Matus Fabian06596c52017-06-06 04:53:28 -07005321 dst_ip=self.pg1.remote_ip4)
5322
5323 # out2in
5324 pkts = self.create_stream_out(self.pg1, dst_ip=self.nat_addr)
5325 self.pg1.add_stream(pkts)
5326 self.pg_enable_capture(self.pg_interfaces)
5327 self.pg_start()
Matus Fabian029f3d22017-06-15 02:28:50 -07005328 capture = self.pg0.get_capture(len(pkts))
Matus Fabian06596c52017-06-06 04:53:28 -07005329 ip = IPv6(src=''.join(['64:ff9b::', self.pg1.remote_ip4]))
5330 self.verify_capture_in_ip6(capture, ip[IPv6].src, self.pg0.remote_ip6)
5331
5332 # in2out
5333 pkts = self.create_stream_in_ip6(self.pg0, self.pg1)
5334 self.pg0.add_stream(pkts)
5335 self.pg_enable_capture(self.pg_interfaces)
5336 self.pg_start()
Matus Fabian029f3d22017-06-15 02:28:50 -07005337 capture = self.pg1.get_capture(len(pkts))
5338 self.verify_capture_out(capture, nat_ip=self.nat_addr,
Matus Fabian06596c52017-06-06 04:53:28 -07005339 dst_ip=self.pg1.remote_ip4)
5340
5341 # out2in
5342 pkts = self.create_stream_out(self.pg1, dst_ip=self.nat_addr)
5343 self.pg1.add_stream(pkts)
5344 self.pg_enable_capture(self.pg_interfaces)
5345 self.pg_start()
Matus Fabian029f3d22017-06-15 02:28:50 -07005346 capture = self.pg0.get_capture(len(pkts))
Matus Fabian06596c52017-06-06 04:53:28 -07005347 self.verify_capture_in_ip6(capture, ip[IPv6].src, self.pg0.remote_ip6)
5348
5349 ses_num_end = self.nat64_get_ses_num()
5350
5351 self.assertEqual(ses_num_end - ses_num_start, 3)
5352
Matus Fabian029f3d22017-06-15 02:28:50 -07005353 # tenant with specific VRF
5354 self.vapi.nat64_add_del_pool_addr_range(self.vrf1_nat_addr_n,
5355 self.vrf1_nat_addr_n,
5356 vrf_id=self.vrf1_id)
5357 self.vapi.nat64_add_del_interface(self.pg2.sw_if_index)
5358
5359 pkts = self.create_stream_in_ip6(self.pg2, self.pg1)
5360 self.pg2.add_stream(pkts)
5361 self.pg_enable_capture(self.pg_interfaces)
5362 self.pg_start()
5363 capture = self.pg1.get_capture(len(pkts))
5364 self.verify_capture_out(capture, nat_ip=self.vrf1_nat_addr,
5365 dst_ip=self.pg1.remote_ip4)
5366
5367 pkts = self.create_stream_out(self.pg1, dst_ip=self.vrf1_nat_addr)
5368 self.pg1.add_stream(pkts)
5369 self.pg_enable_capture(self.pg_interfaces)
5370 self.pg_start()
5371 capture = self.pg2.get_capture(len(pkts))
5372 self.verify_capture_in_ip6(capture, ip[IPv6].src, self.pg2.remote_ip6)
5373
Matus Fabian06596c52017-06-06 04:53:28 -07005374 def test_static(self):
5375 """ NAT64 static translation test """
5376 self.tcp_port_in = 60303
5377 self.udp_port_in = 60304
5378 self.icmp_id_in = 60305
5379 self.tcp_port_out = 60303
5380 self.udp_port_out = 60304
5381 self.icmp_id_out = 60305
5382
5383 ses_num_start = self.nat64_get_ses_num()
5384
5385 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
5386 self.nat_addr_n)
5387 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
5388 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
5389
5390 self.vapi.nat64_add_del_static_bib(self.pg0.remote_ip6n,
5391 self.nat_addr_n,
5392 self.tcp_port_in,
5393 self.tcp_port_out,
5394 IP_PROTOS.tcp)
5395 self.vapi.nat64_add_del_static_bib(self.pg0.remote_ip6n,
5396 self.nat_addr_n,
5397 self.udp_port_in,
5398 self.udp_port_out,
5399 IP_PROTOS.udp)
5400 self.vapi.nat64_add_del_static_bib(self.pg0.remote_ip6n,
5401 self.nat_addr_n,
5402 self.icmp_id_in,
5403 self.icmp_id_out,
5404 IP_PROTOS.icmp)
5405
5406 # in2out
5407 pkts = self.create_stream_in_ip6(self.pg0, self.pg1)
5408 self.pg0.add_stream(pkts)
5409 self.pg_enable_capture(self.pg_interfaces)
5410 self.pg_start()
Matus Fabian029f3d22017-06-15 02:28:50 -07005411 capture = self.pg1.get_capture(len(pkts))
5412 self.verify_capture_out(capture, nat_ip=self.nat_addr,
Matus Fabian06596c52017-06-06 04:53:28 -07005413 dst_ip=self.pg1.remote_ip4, same_port=True)
5414
5415 # out2in
5416 pkts = self.create_stream_out(self.pg1, dst_ip=self.nat_addr)
5417 self.pg1.add_stream(pkts)
5418 self.pg_enable_capture(self.pg_interfaces)
5419 self.pg_start()
Matus Fabian029f3d22017-06-15 02:28:50 -07005420 capture = self.pg0.get_capture(len(pkts))
Matus Fabian06596c52017-06-06 04:53:28 -07005421 ip = IPv6(src=''.join(['64:ff9b::', self.pg1.remote_ip4]))
5422 self.verify_capture_in_ip6(capture, ip[IPv6].src, self.pg0.remote_ip6)
5423
5424 ses_num_end = self.nat64_get_ses_num()
5425
5426 self.assertEqual(ses_num_end - ses_num_start, 3)
5427
5428 @unittest.skipUnless(running_extended_tests(), "part of extended tests")
5429 def test_session_timeout(self):
5430 """ NAT64 session timeout """
5431 self.icmp_id_in = 1234
5432 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
5433 self.nat_addr_n)
5434 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
5435 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
5436 self.vapi.nat64_set_timeouts(icmp=5)
5437
5438 pkts = self.create_stream_in_ip6(self.pg0, self.pg1)
5439 self.pg0.add_stream(pkts)
5440 self.pg_enable_capture(self.pg_interfaces)
5441 self.pg_start()
Matus Fabian029f3d22017-06-15 02:28:50 -07005442 capture = self.pg1.get_capture(len(pkts))
Matus Fabian06596c52017-06-06 04:53:28 -07005443
5444 ses_num_before_timeout = self.nat64_get_ses_num()
5445
5446 sleep(15)
5447
5448 # ICMP session after timeout
5449 ses_num_after_timeout = self.nat64_get_ses_num()
5450 self.assertNotEqual(ses_num_before_timeout, ses_num_after_timeout)
5451
Matus Fabian732036d2017-06-08 05:24:28 -07005452 def test_icmp_error(self):
5453 """ NAT64 ICMP Error message translation """
5454 self.tcp_port_in = 6303
5455 self.udp_port_in = 6304
5456 self.icmp_id_in = 6305
5457
Matus Fabian732036d2017-06-08 05:24:28 -07005458 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
5459 self.nat_addr_n)
5460 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
5461 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
5462
5463 # send some packets to create sessions
5464 pkts = self.create_stream_in_ip6(self.pg0, self.pg1)
5465 self.pg0.add_stream(pkts)
5466 self.pg_enable_capture(self.pg_interfaces)
5467 self.pg_start()
5468 capture_ip4 = self.pg1.get_capture(len(pkts))
Matus Fabian029f3d22017-06-15 02:28:50 -07005469 self.verify_capture_out(capture_ip4,
Matus Fabian732036d2017-06-08 05:24:28 -07005470 nat_ip=self.nat_addr,
5471 dst_ip=self.pg1.remote_ip4)
5472
5473 pkts = self.create_stream_out(self.pg1, dst_ip=self.nat_addr)
5474 self.pg1.add_stream(pkts)
5475 self.pg_enable_capture(self.pg_interfaces)
5476 self.pg_start()
5477 capture_ip6 = self.pg0.get_capture(len(pkts))
5478 ip = IPv6(src=''.join(['64:ff9b::', self.pg1.remote_ip4]))
5479 self.verify_capture_in_ip6(capture_ip6, ip[IPv6].src,
5480 self.pg0.remote_ip6)
5481
5482 # in2out
5483 pkts = [Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
5484 IPv6(src=self.pg0.remote_ip6, dst=ip[IPv6].src) /
5485 ICMPv6DestUnreach(code=1) /
5486 packet[IPv6] for packet in capture_ip6]
5487 self.pg0.add_stream(pkts)
5488 self.pg_enable_capture(self.pg_interfaces)
5489 self.pg_start()
5490 capture = self.pg1.get_capture(len(pkts))
5491 for packet in capture:
5492 try:
5493 self.assertEqual(packet[IP].src, self.nat_addr)
5494 self.assertEqual(packet[IP].dst, self.pg1.remote_ip4)
5495 self.assertEqual(packet[ICMP].type, 3)
5496 self.assertEqual(packet[ICMP].code, 13)
5497 inner = packet[IPerror]
5498 self.assertEqual(inner.src, self.pg1.remote_ip4)
5499 self.assertEqual(inner.dst, self.nat_addr)
Klement Sekerad81ae412018-05-16 10:52:54 +02005500 self.assert_packet_checksums_valid(packet)
Matus Fabian732036d2017-06-08 05:24:28 -07005501 if inner.haslayer(TCPerror):
5502 self.assertEqual(inner[TCPerror].dport, self.tcp_port_out)
5503 elif inner.haslayer(UDPerror):
5504 self.assertEqual(inner[UDPerror].dport, self.udp_port_out)
5505 else:
5506 self.assertEqual(inner[ICMPerror].id, self.icmp_id_out)
5507 except:
5508 self.logger.error(ppp("Unexpected or invalid packet:", packet))
5509 raise
5510
5511 # out2in
5512 pkts = [Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
5513 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5514 ICMP(type=3, code=13) /
5515 packet[IP] for packet in capture_ip4]
5516 self.pg1.add_stream(pkts)
5517 self.pg_enable_capture(self.pg_interfaces)
5518 self.pg_start()
5519 capture = self.pg0.get_capture(len(pkts))
5520 for packet in capture:
5521 try:
5522 self.assertEqual(packet[IPv6].src, ip.src)
5523 self.assertEqual(packet[IPv6].dst, self.pg0.remote_ip6)
5524 icmp = packet[ICMPv6DestUnreach]
5525 self.assertEqual(icmp.code, 1)
5526 inner = icmp[IPerror6]
5527 self.assertEqual(inner.src, self.pg0.remote_ip6)
5528 self.assertEqual(inner.dst, ip.src)
Klement Sekerad81ae412018-05-16 10:52:54 +02005529 self.assert_icmpv6_checksum_valid(packet)
Matus Fabian732036d2017-06-08 05:24:28 -07005530 if inner.haslayer(TCPerror):
5531 self.assertEqual(inner[TCPerror].sport, self.tcp_port_in)
5532 elif inner.haslayer(UDPerror):
5533 self.assertEqual(inner[UDPerror].sport, self.udp_port_in)
5534 else:
5535 self.assertEqual(inner[ICMPv6EchoRequest].id,
5536 self.icmp_id_in)
5537 except:
5538 self.logger.error(ppp("Unexpected or invalid packet:", packet))
5539 raise
5540
Matus Fabian029f3d22017-06-15 02:28:50 -07005541 def test_hairpinning(self):
5542 """ NAT64 hairpinning """
5543
5544 client = self.pg0.remote_hosts[0]
5545 server = self.pg0.remote_hosts[1]
5546 server_tcp_in_port = 22
5547 server_tcp_out_port = 4022
5548 server_udp_in_port = 23
5549 server_udp_out_port = 4023
5550 client_tcp_in_port = 1234
5551 client_udp_in_port = 1235
5552 client_tcp_out_port = 0
5553 client_udp_out_port = 0
5554 ip = IPv6(src=''.join(['64:ff9b::', self.nat_addr]))
5555 nat_addr_ip6 = ip.src
5556
5557 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
5558 self.nat_addr_n)
5559 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
5560 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
5561
5562 self.vapi.nat64_add_del_static_bib(server.ip6n,
5563 self.nat_addr_n,
5564 server_tcp_in_port,
5565 server_tcp_out_port,
5566 IP_PROTOS.tcp)
5567 self.vapi.nat64_add_del_static_bib(server.ip6n,
5568 self.nat_addr_n,
5569 server_udp_in_port,
5570 server_udp_out_port,
5571 IP_PROTOS.udp)
5572
5573 # client to server
5574 pkts = []
5575 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
5576 IPv6(src=client.ip6, dst=nat_addr_ip6) /
5577 TCP(sport=client_tcp_in_port, dport=server_tcp_out_port))
5578 pkts.append(p)
5579 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
5580 IPv6(src=client.ip6, dst=nat_addr_ip6) /
5581 UDP(sport=client_udp_in_port, dport=server_udp_out_port))
5582 pkts.append(p)
5583 self.pg0.add_stream(pkts)
5584 self.pg_enable_capture(self.pg_interfaces)
5585 self.pg_start()
5586 capture = self.pg0.get_capture(len(pkts))
5587 for packet in capture:
5588 try:
5589 self.assertEqual(packet[IPv6].src, nat_addr_ip6)
5590 self.assertEqual(packet[IPv6].dst, server.ip6)
Klement Sekerad81ae412018-05-16 10:52:54 +02005591 self.assert_packet_checksums_valid(packet)
Matus Fabian029f3d22017-06-15 02:28:50 -07005592 if packet.haslayer(TCP):
5593 self.assertNotEqual(packet[TCP].sport, client_tcp_in_port)
5594 self.assertEqual(packet[TCP].dport, server_tcp_in_port)
Matus Fabian029f3d22017-06-15 02:28:50 -07005595 client_tcp_out_port = packet[TCP].sport
5596 else:
5597 self.assertNotEqual(packet[UDP].sport, client_udp_in_port)
5598 self.assertEqual(packet[UDP].dport, server_udp_in_port)
Matus Fabian029f3d22017-06-15 02:28:50 -07005599 client_udp_out_port = packet[UDP].sport
5600 except:
5601 self.logger.error(ppp("Unexpected or invalid packet:", packet))
5602 raise
5603
5604 # server to client
5605 pkts = []
5606 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
5607 IPv6(src=server.ip6, dst=nat_addr_ip6) /
5608 TCP(sport=server_tcp_in_port, dport=client_tcp_out_port))
5609 pkts.append(p)
5610 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
5611 IPv6(src=server.ip6, dst=nat_addr_ip6) /
5612 UDP(sport=server_udp_in_port, dport=client_udp_out_port))
5613 pkts.append(p)
5614 self.pg0.add_stream(pkts)
5615 self.pg_enable_capture(self.pg_interfaces)
5616 self.pg_start()
5617 capture = self.pg0.get_capture(len(pkts))
5618 for packet in capture:
5619 try:
5620 self.assertEqual(packet[IPv6].src, nat_addr_ip6)
5621 self.assertEqual(packet[IPv6].dst, client.ip6)
Klement Sekerad81ae412018-05-16 10:52:54 +02005622 self.assert_packet_checksums_valid(packet)
Matus Fabian029f3d22017-06-15 02:28:50 -07005623 if packet.haslayer(TCP):
5624 self.assertEqual(packet[TCP].sport, server_tcp_out_port)
5625 self.assertEqual(packet[TCP].dport, client_tcp_in_port)
Matus Fabian029f3d22017-06-15 02:28:50 -07005626 else:
5627 self.assertEqual(packet[UDP].sport, server_udp_out_port)
5628 self.assertEqual(packet[UDP].dport, client_udp_in_port)
Matus Fabian029f3d22017-06-15 02:28:50 -07005629 except:
5630 self.logger.error(ppp("Unexpected or invalid packet:", packet))
5631 raise
5632
5633 # ICMP error
5634 pkts = []
5635 pkts = [Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
5636 IPv6(src=client.ip6, dst=nat_addr_ip6) /
5637 ICMPv6DestUnreach(code=1) /
5638 packet[IPv6] for packet in capture]
5639 self.pg0.add_stream(pkts)
5640 self.pg_enable_capture(self.pg_interfaces)
5641 self.pg_start()
5642 capture = self.pg0.get_capture(len(pkts))
5643 for packet in capture:
5644 try:
5645 self.assertEqual(packet[IPv6].src, nat_addr_ip6)
5646 self.assertEqual(packet[IPv6].dst, server.ip6)
5647 icmp = packet[ICMPv6DestUnreach]
5648 self.assertEqual(icmp.code, 1)
5649 inner = icmp[IPerror6]
5650 self.assertEqual(inner.src, server.ip6)
5651 self.assertEqual(inner.dst, nat_addr_ip6)
Klement Sekerad81ae412018-05-16 10:52:54 +02005652 self.assert_packet_checksums_valid(packet)
Matus Fabian029f3d22017-06-15 02:28:50 -07005653 if inner.haslayer(TCPerror):
5654 self.assertEqual(inner[TCPerror].sport, server_tcp_in_port)
5655 self.assertEqual(inner[TCPerror].dport,
5656 client_tcp_out_port)
5657 else:
5658 self.assertEqual(inner[UDPerror].sport, server_udp_in_port)
5659 self.assertEqual(inner[UDPerror].dport,
5660 client_udp_out_port)
5661 except:
5662 self.logger.error(ppp("Unexpected or invalid packet:", packet))
5663 raise
5664
Matus Fabian428dc912017-06-21 06:15:18 -07005665 def test_prefix(self):
5666 """ NAT64 Network-Specific Prefix """
5667
5668 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
5669 self.nat_addr_n)
5670 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
5671 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
5672 self.vapi.nat64_add_del_pool_addr_range(self.vrf1_nat_addr_n,
5673 self.vrf1_nat_addr_n,
5674 vrf_id=self.vrf1_id)
5675 self.vapi.nat64_add_del_interface(self.pg2.sw_if_index)
5676
5677 # Add global prefix
5678 global_pref64 = "2001:db8::"
5679 global_pref64_n = socket.inet_pton(socket.AF_INET6, global_pref64)
5680 global_pref64_len = 32
5681 self.vapi.nat64_add_del_prefix(global_pref64_n, global_pref64_len)
5682
5683 prefix = self.vapi.nat64_prefix_dump()
5684 self.assertEqual(len(prefix), 1)
5685 self.assertEqual(prefix[0].prefix, global_pref64_n)
5686 self.assertEqual(prefix[0].prefix_len, global_pref64_len)
5687 self.assertEqual(prefix[0].vrf_id, 0)
5688
5689 # Add tenant specific prefix
5690 vrf1_pref64 = "2001:db8:122:300::"
5691 vrf1_pref64_n = socket.inet_pton(socket.AF_INET6, vrf1_pref64)
5692 vrf1_pref64_len = 56
5693 self.vapi.nat64_add_del_prefix(vrf1_pref64_n,
5694 vrf1_pref64_len,
5695 vrf_id=self.vrf1_id)
5696 prefix = self.vapi.nat64_prefix_dump()
5697 self.assertEqual(len(prefix), 2)
5698
5699 # Global prefix
5700 pkts = self.create_stream_in_ip6(self.pg0,
5701 self.pg1,
5702 pref=global_pref64,
5703 plen=global_pref64_len)
5704 self.pg0.add_stream(pkts)
5705 self.pg_enable_capture(self.pg_interfaces)
5706 self.pg_start()
5707 capture = self.pg1.get_capture(len(pkts))
5708 self.verify_capture_out(capture, nat_ip=self.nat_addr,
5709 dst_ip=self.pg1.remote_ip4)
5710
5711 pkts = self.create_stream_out(self.pg1, dst_ip=self.nat_addr)
5712 self.pg1.add_stream(pkts)
5713 self.pg_enable_capture(self.pg_interfaces)
5714 self.pg_start()
5715 capture = self.pg0.get_capture(len(pkts))
5716 dst_ip = self.compose_ip6(self.pg1.remote_ip4,
5717 global_pref64,
5718 global_pref64_len)
5719 self.verify_capture_in_ip6(capture, dst_ip, self.pg0.remote_ip6)
5720
5721 # Tenant specific prefix
5722 pkts = self.create_stream_in_ip6(self.pg2,
5723 self.pg1,
5724 pref=vrf1_pref64,
5725 plen=vrf1_pref64_len)
5726 self.pg2.add_stream(pkts)
5727 self.pg_enable_capture(self.pg_interfaces)
5728 self.pg_start()
5729 capture = self.pg1.get_capture(len(pkts))
5730 self.verify_capture_out(capture, nat_ip=self.vrf1_nat_addr,
5731 dst_ip=self.pg1.remote_ip4)
5732
5733 pkts = self.create_stream_out(self.pg1, dst_ip=self.vrf1_nat_addr)
5734 self.pg1.add_stream(pkts)
5735 self.pg_enable_capture(self.pg_interfaces)
5736 self.pg_start()
5737 capture = self.pg2.get_capture(len(pkts))
5738 dst_ip = self.compose_ip6(self.pg1.remote_ip4,
5739 vrf1_pref64,
5740 vrf1_pref64_len)
5741 self.verify_capture_in_ip6(capture, dst_ip, self.pg2.remote_ip6)
5742
Matus Fabianf8cd5812017-07-11 03:55:02 -07005743 def test_unknown_proto(self):
Matus Fabian7968e6c2017-07-06 05:37:49 -07005744 """ NAT64 translate packet with unknown protocol """
5745
5746 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
5747 self.nat_addr_n)
5748 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
5749 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
5750 remote_ip6 = self.compose_ip6(self.pg1.remote_ip4, '64:ff9b::', 96)
5751
5752 # in2out
5753 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
5754 IPv6(src=self.pg0.remote_ip6, dst=remote_ip6) /
5755 TCP(sport=self.tcp_port_in, dport=20))
5756 self.pg0.add_stream(p)
5757 self.pg_enable_capture(self.pg_interfaces)
5758 self.pg_start()
5759 p = self.pg1.get_capture(1)
5760
5761 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
Matus Fabianf8cd5812017-07-11 03:55:02 -07005762 IPv6(src=self.pg0.remote_ip6, dst=remote_ip6, nh=47) /
Matus Fabian7968e6c2017-07-06 05:37:49 -07005763 GRE() /
5764 IP(src=self.pg2.local_ip4, dst=self.pg2.remote_ip4) /
5765 TCP(sport=1234, dport=1234))
5766 self.pg0.add_stream(p)
5767 self.pg_enable_capture(self.pg_interfaces)
5768 self.pg_start()
5769 p = self.pg1.get_capture(1)
5770 packet = p[0]
5771 try:
5772 self.assertEqual(packet[IP].src, self.nat_addr)
5773 self.assertEqual(packet[IP].dst, self.pg1.remote_ip4)
5774 self.assertTrue(packet.haslayer(GRE))
Klement Sekerad81ae412018-05-16 10:52:54 +02005775 self.assert_packet_checksums_valid(packet)
Matus Fabian7968e6c2017-07-06 05:37:49 -07005776 except:
5777 self.logger.error(ppp("Unexpected or invalid packet:", packet))
5778 raise
5779
5780 # out2in
5781 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
5782 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5783 GRE() /
5784 IP(src=self.pg2.remote_ip4, dst=self.pg2.local_ip4) /
5785 TCP(sport=1234, dport=1234))
5786 self.pg1.add_stream(p)
5787 self.pg_enable_capture(self.pg_interfaces)
5788 self.pg_start()
5789 p = self.pg0.get_capture(1)
5790 packet = p[0]
5791 try:
5792 self.assertEqual(packet[IPv6].src, remote_ip6)
Matus Fabianf8cd5812017-07-11 03:55:02 -07005793 self.assertEqual(packet[IPv6].dst, self.pg0.remote_ip6)
5794 self.assertEqual(packet[IPv6].nh, 47)
Matus Fabian7968e6c2017-07-06 05:37:49 -07005795 except:
5796 self.logger.error(ppp("Unexpected or invalid packet:", packet))
5797 raise
5798
Matus Fabianf8cd5812017-07-11 03:55:02 -07005799 def test_hairpinning_unknown_proto(self):
Matus Fabian7968e6c2017-07-06 05:37:49 -07005800 """ NAT64 translate packet with unknown protocol - hairpinning """
5801
5802 client = self.pg0.remote_hosts[0]
5803 server = self.pg0.remote_hosts[1]
5804 server_tcp_in_port = 22
5805 server_tcp_out_port = 4022
5806 client_tcp_in_port = 1234
Matus Fabianf8cd5812017-07-11 03:55:02 -07005807 client_tcp_out_port = 1235
5808 server_nat_ip = "10.0.0.100"
5809 client_nat_ip = "10.0.0.110"
5810 server_nat_ip_n = socket.inet_pton(socket.AF_INET, server_nat_ip)
5811 client_nat_ip_n = socket.inet_pton(socket.AF_INET, client_nat_ip)
5812 server_nat_ip6 = self.compose_ip6(server_nat_ip, '64:ff9b::', 96)
5813 client_nat_ip6 = self.compose_ip6(client_nat_ip, '64:ff9b::', 96)
Matus Fabian7968e6c2017-07-06 05:37:49 -07005814
Matus Fabianf8cd5812017-07-11 03:55:02 -07005815 self.vapi.nat64_add_del_pool_addr_range(server_nat_ip_n,
5816 client_nat_ip_n)
Matus Fabian7968e6c2017-07-06 05:37:49 -07005817 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
5818 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
5819
5820 self.vapi.nat64_add_del_static_bib(server.ip6n,
Matus Fabianf8cd5812017-07-11 03:55:02 -07005821 server_nat_ip_n,
Matus Fabian7968e6c2017-07-06 05:37:49 -07005822 server_tcp_in_port,
5823 server_tcp_out_port,
5824 IP_PROTOS.tcp)
5825
Matus Fabianf8cd5812017-07-11 03:55:02 -07005826 self.vapi.nat64_add_del_static_bib(server.ip6n,
5827 server_nat_ip_n,
5828 0,
5829 0,
5830 IP_PROTOS.gre)
5831
5832 self.vapi.nat64_add_del_static_bib(client.ip6n,
5833 client_nat_ip_n,
5834 client_tcp_in_port,
5835 client_tcp_out_port,
5836 IP_PROTOS.tcp)
5837
Matus Fabian7968e6c2017-07-06 05:37:49 -07005838 # client to server
5839 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
Matus Fabianf8cd5812017-07-11 03:55:02 -07005840 IPv6(src=client.ip6, dst=server_nat_ip6) /
Matus Fabian7968e6c2017-07-06 05:37:49 -07005841 TCP(sport=client_tcp_in_port, dport=server_tcp_out_port))
5842 self.pg0.add_stream(p)
5843 self.pg_enable_capture(self.pg_interfaces)
5844 self.pg_start()
5845 p = self.pg0.get_capture(1)
5846
5847 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
Matus Fabianf8cd5812017-07-11 03:55:02 -07005848 IPv6(src=client.ip6, dst=server_nat_ip6, nh=IP_PROTOS.gre) /
Matus Fabian7968e6c2017-07-06 05:37:49 -07005849 GRE() /
5850 IP(src=self.pg2.local_ip4, dst=self.pg2.remote_ip4) /
5851 TCP(sport=1234, dport=1234))
5852 self.pg0.add_stream(p)
5853 self.pg_enable_capture(self.pg_interfaces)
5854 self.pg_start()
5855 p = self.pg0.get_capture(1)
5856 packet = p[0]
5857 try:
Matus Fabianf8cd5812017-07-11 03:55:02 -07005858 self.assertEqual(packet[IPv6].src, client_nat_ip6)
Matus Fabian7968e6c2017-07-06 05:37:49 -07005859 self.assertEqual(packet[IPv6].dst, server.ip6)
Matus Fabianf8cd5812017-07-11 03:55:02 -07005860 self.assertEqual(packet[IPv6].nh, IP_PROTOS.gre)
Matus Fabian7968e6c2017-07-06 05:37:49 -07005861 except:
5862 self.logger.error(ppp("Unexpected or invalid packet:", packet))
5863 raise
5864
5865 # server to client
5866 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
Matus Fabianf8cd5812017-07-11 03:55:02 -07005867 IPv6(src=server.ip6, dst=client_nat_ip6, nh=IP_PROTOS.gre) /
Matus Fabian7968e6c2017-07-06 05:37:49 -07005868 GRE() /
5869 IP(src=self.pg2.remote_ip4, dst=self.pg2.local_ip4) /
5870 TCP(sport=1234, dport=1234))
5871 self.pg0.add_stream(p)
5872 self.pg_enable_capture(self.pg_interfaces)
5873 self.pg_start()
5874 p = self.pg0.get_capture(1)
5875 packet = p[0]
5876 try:
Matus Fabianf8cd5812017-07-11 03:55:02 -07005877 self.assertEqual(packet[IPv6].src, server_nat_ip6)
Matus Fabian7968e6c2017-07-06 05:37:49 -07005878 self.assertEqual(packet[IPv6].dst, client.ip6)
Matus Fabianf8cd5812017-07-11 03:55:02 -07005879 self.assertEqual(packet[IPv6].nh, IP_PROTOS.gre)
Matus Fabian7968e6c2017-07-06 05:37:49 -07005880 except:
5881 self.logger.error(ppp("Unexpected or invalid packet:", packet))
5882 raise
5883
Matus Fabian36ea2d62017-10-24 04:13:49 -07005884 def test_one_armed_nat64(self):
5885 """ One armed NAT64 """
5886 external_port = 0
5887 remote_host_ip6 = self.compose_ip6(self.pg3.remote_ip4,
5888 '64:ff9b::',
5889 96)
5890
5891 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
5892 self.nat_addr_n)
5893 self.vapi.nat64_add_del_interface(self.pg3.sw_if_index)
5894 self.vapi.nat64_add_del_interface(self.pg3.sw_if_index, is_inside=0)
5895
5896 # in2out
5897 p = (Ether(src=self.pg3.remote_mac, dst=self.pg3.local_mac) /
5898 IPv6(src=self.pg3.remote_ip6, dst=remote_host_ip6) /
5899 TCP(sport=12345, dport=80))
5900 self.pg3.add_stream(p)
5901 self.pg_enable_capture(self.pg_interfaces)
5902 self.pg_start()
5903 capture = self.pg3.get_capture(1)
5904 p = capture[0]
5905 try:
5906 ip = p[IP]
5907 tcp = p[TCP]
5908 self.assertEqual(ip.src, self.nat_addr)
5909 self.assertEqual(ip.dst, self.pg3.remote_ip4)
5910 self.assertNotEqual(tcp.sport, 12345)
5911 external_port = tcp.sport
5912 self.assertEqual(tcp.dport, 80)
Klement Sekerad81ae412018-05-16 10:52:54 +02005913 self.assert_packet_checksums_valid(p)
Matus Fabian36ea2d62017-10-24 04:13:49 -07005914 except:
5915 self.logger.error(ppp("Unexpected or invalid packet:", p))
5916 raise
5917
5918 # out2in
5919 p = (Ether(src=self.pg3.remote_mac, dst=self.pg3.local_mac) /
5920 IP(src=self.pg3.remote_ip4, dst=self.nat_addr) /
5921 TCP(sport=80, dport=external_port))
5922 self.pg3.add_stream(p)
5923 self.pg_enable_capture(self.pg_interfaces)
5924 self.pg_start()
5925 capture = self.pg3.get_capture(1)
5926 p = capture[0]
5927 try:
5928 ip = p[IPv6]
5929 tcp = p[TCP]
5930 self.assertEqual(ip.src, remote_host_ip6)
5931 self.assertEqual(ip.dst, self.pg3.remote_ip6)
5932 self.assertEqual(tcp.sport, 80)
5933 self.assertEqual(tcp.dport, 12345)
Klement Sekerad81ae412018-05-16 10:52:54 +02005934 self.assert_packet_checksums_valid(p)
Matus Fabian36ea2d62017-10-24 04:13:49 -07005935 except:
5936 self.logger.error(ppp("Unexpected or invalid packet:", p))
5937 raise
5938
Matus Fabianefcd1e92017-08-15 06:59:19 -07005939 def test_frag_in_order(self):
5940 """ NAT64 translate fragments arriving in order """
5941 self.tcp_port_in = random.randint(1025, 65535)
5942
5943 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
5944 self.nat_addr_n)
5945 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
5946 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
5947
5948 reass = self.vapi.nat_reass_dump()
5949 reass_n_start = len(reass)
5950
5951 # in2out
5952 data = 'a' * 200
5953 pkts = self.create_stream_frag_ip6(self.pg0, self.pg1.remote_ip4,
5954 self.tcp_port_in, 20, data)
5955 self.pg0.add_stream(pkts)
5956 self.pg_enable_capture(self.pg_interfaces)
5957 self.pg_start()
5958 frags = self.pg1.get_capture(len(pkts))
5959 p = self.reass_frags_and_verify(frags,
5960 self.nat_addr,
5961 self.pg1.remote_ip4)
5962 self.assertEqual(p[TCP].dport, 20)
5963 self.assertNotEqual(p[TCP].sport, self.tcp_port_in)
5964 self.tcp_port_out = p[TCP].sport
5965 self.assertEqual(data, p[Raw].load)
5966
5967 # out2in
5968 data = "A" * 4 + "b" * 16 + "C" * 3
5969 pkts = self.create_stream_frag(self.pg1,
5970 self.nat_addr,
5971 20,
5972 self.tcp_port_out,
5973 data)
5974 self.pg1.add_stream(pkts)
5975 self.pg_enable_capture(self.pg_interfaces)
5976 self.pg_start()
5977 frags = self.pg0.get_capture(len(pkts))
5978 src = self.compose_ip6(self.pg1.remote_ip4, '64:ff9b::', 96)
5979 p = self.reass_frags_and_verify_ip6(frags, src, self.pg0.remote_ip6)
5980 self.assertEqual(p[TCP].sport, 20)
5981 self.assertEqual(p[TCP].dport, self.tcp_port_in)
5982 self.assertEqual(data, p[Raw].load)
5983
5984 reass = self.vapi.nat_reass_dump()
5985 reass_n_end = len(reass)
5986
5987 self.assertEqual(reass_n_end - reass_n_start, 2)
5988
5989 def test_reass_hairpinning(self):
5990 """ NAT64 fragments hairpinning """
5991 data = 'a' * 200
Matus Fabianefcd1e92017-08-15 06:59:19 -07005992 server = self.pg0.remote_hosts[1]
5993 server_in_port = random.randint(1025, 65535)
5994 server_out_port = random.randint(1025, 65535)
5995 client_in_port = random.randint(1025, 65535)
5996 ip = IPv6(src=''.join(['64:ff9b::', self.nat_addr]))
5997 nat_addr_ip6 = ip.src
5998
5999 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
6000 self.nat_addr_n)
6001 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
6002 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
6003
6004 # add static BIB entry for server
6005 self.vapi.nat64_add_del_static_bib(server.ip6n,
6006 self.nat_addr_n,
6007 server_in_port,
6008 server_out_port,
6009 IP_PROTOS.tcp)
6010
6011 # send packet from host to server
6012 pkts = self.create_stream_frag_ip6(self.pg0,
6013 self.nat_addr,
6014 client_in_port,
6015 server_out_port,
6016 data)
6017 self.pg0.add_stream(pkts)
6018 self.pg_enable_capture(self.pg_interfaces)
6019 self.pg_start()
6020 frags = self.pg0.get_capture(len(pkts))
6021 p = self.reass_frags_and_verify_ip6(frags, nat_addr_ip6, server.ip6)
6022 self.assertNotEqual(p[TCP].sport, client_in_port)
6023 self.assertEqual(p[TCP].dport, server_in_port)
6024 self.assertEqual(data, p[Raw].load)
6025
6026 def test_frag_out_of_order(self):
6027 """ NAT64 translate fragments arriving out of order """
6028 self.tcp_port_in = random.randint(1025, 65535)
6029
6030 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
6031 self.nat_addr_n)
6032 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
6033 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
6034
6035 # in2out
6036 data = 'a' * 200
6037 pkts = self.create_stream_frag_ip6(self.pg0, self.pg1.remote_ip4,
6038 self.tcp_port_in, 20, data)
6039 pkts.reverse()
6040 self.pg0.add_stream(pkts)
6041 self.pg_enable_capture(self.pg_interfaces)
6042 self.pg_start()
6043 frags = self.pg1.get_capture(len(pkts))
6044 p = self.reass_frags_and_verify(frags,
6045 self.nat_addr,
6046 self.pg1.remote_ip4)
6047 self.assertEqual(p[TCP].dport, 20)
6048 self.assertNotEqual(p[TCP].sport, self.tcp_port_in)
6049 self.tcp_port_out = p[TCP].sport
6050 self.assertEqual(data, p[Raw].load)
6051
6052 # out2in
6053 data = "A" * 4 + "B" * 16 + "C" * 3
6054 pkts = self.create_stream_frag(self.pg1,
6055 self.nat_addr,
6056 20,
6057 self.tcp_port_out,
6058 data)
6059 pkts.reverse()
6060 self.pg1.add_stream(pkts)
6061 self.pg_enable_capture(self.pg_interfaces)
6062 self.pg_start()
6063 frags = self.pg0.get_capture(len(pkts))
6064 src = self.compose_ip6(self.pg1.remote_ip4, '64:ff9b::', 96)
6065 p = self.reass_frags_and_verify_ip6(frags, src, self.pg0.remote_ip6)
6066 self.assertEqual(p[TCP].sport, 20)
6067 self.assertEqual(p[TCP].dport, self.tcp_port_in)
6068 self.assertEqual(data, p[Raw].load)
6069
Matus Fabian0938dcf2017-11-08 01:59:38 -08006070 def test_interface_addr(self):
6071 """ Acquire NAT64 pool addresses from interface """
6072 self.vapi.nat64_add_interface_addr(self.pg4.sw_if_index)
6073
6074 # no address in NAT64 pool
6075 adresses = self.vapi.nat44_address_dump()
6076 self.assertEqual(0, len(adresses))
6077
6078 # configure interface address and check NAT64 address pool
6079 self.pg4.config_ip4()
6080 addresses = self.vapi.nat64_pool_addr_dump()
6081 self.assertEqual(len(addresses), 1)
6082 self.assertEqual(addresses[0].address, self.pg4.local_ip4n)
6083
6084 # remove interface address and check NAT64 address pool
6085 self.pg4.unconfig_ip4()
6086 addresses = self.vapi.nat64_pool_addr_dump()
6087 self.assertEqual(0, len(adresses))
6088
Matus Fabiana431ad12018-01-04 04:03:14 -08006089 @unittest.skipUnless(running_extended_tests(), "part of extended tests")
6090 def test_ipfix_max_bibs_sessions(self):
6091 """ IPFIX logging maximum session and BIB entries exceeded """
6092 max_bibs = 1280
6093 max_sessions = 2560
6094 remote_host_ip6 = self.compose_ip6(self.pg1.remote_ip4,
6095 '64:ff9b::',
6096 96)
6097
6098 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
6099 self.nat_addr_n)
6100 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
6101 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
6102
6103 pkts = []
6104 src = ""
6105 for i in range(0, max_bibs):
6106 src = "fd01:aa::%x" % (i)
6107 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6108 IPv6(src=src, dst=remote_host_ip6) /
6109 TCP(sport=12345, dport=80))
6110 pkts.append(p)
6111 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6112 IPv6(src=src, dst=remote_host_ip6) /
6113 TCP(sport=12345, dport=22))
6114 pkts.append(p)
6115 self.pg0.add_stream(pkts)
6116 self.pg_enable_capture(self.pg_interfaces)
6117 self.pg_start()
6118 self.pg1.get_capture(max_sessions)
6119
6120 self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4n,
6121 src_address=self.pg3.local_ip4n,
6122 path_mtu=512,
6123 template_interval=10)
6124 self.vapi.nat_ipfix(domain_id=self.ipfix_domain_id,
6125 src_port=self.ipfix_src_port)
6126
6127 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6128 IPv6(src=src, dst=remote_host_ip6) /
6129 TCP(sport=12345, dport=25))
6130 self.pg0.add_stream(p)
6131 self.pg_enable_capture(self.pg_interfaces)
6132 self.pg_start()
Matus Fabian229c1aa2018-05-28 04:09:52 -07006133 self.pg1.assert_nothing_captured()
6134 sleep(1)
Matus Fabiana431ad12018-01-04 04:03:14 -08006135 self.vapi.cli("ipfix flush") # FIXME this should be an API call
6136 capture = self.pg3.get_capture(9)
6137 ipfix = IPFIXDecoder()
6138 # first load template
6139 for p in capture:
6140 self.assertTrue(p.haslayer(IPFIX))
6141 self.assertEqual(p[IP].src, self.pg3.local_ip4)
6142 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
6143 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
6144 self.assertEqual(p[UDP].dport, 4739)
6145 self.assertEqual(p[IPFIX].observationDomainID,
6146 self.ipfix_domain_id)
6147 if p.haslayer(Template):
6148 ipfix.add_template(p.getlayer(Template))
6149 # verify events in data set
6150 for p in capture:
6151 if p.haslayer(Data):
6152 data = ipfix.decode_data_set(p.getlayer(Set))
6153 self.verify_ipfix_max_sessions(data, max_sessions)
6154
6155 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6156 IPv6(src=self.pg0.remote_ip6, dst=remote_host_ip6) /
6157 TCP(sport=12345, dport=80))
6158 self.pg0.add_stream(p)
6159 self.pg_enable_capture(self.pg_interfaces)
6160 self.pg_start()
Matus Fabian229c1aa2018-05-28 04:09:52 -07006161 self.pg1.assert_nothing_captured()
6162 sleep(1)
Matus Fabiana431ad12018-01-04 04:03:14 -08006163 self.vapi.cli("ipfix flush") # FIXME this should be an API call
6164 capture = self.pg3.get_capture(1)
6165 # verify events in data set
6166 for p in capture:
6167 self.assertTrue(p.haslayer(IPFIX))
6168 self.assertEqual(p[IP].src, self.pg3.local_ip4)
6169 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
6170 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
6171 self.assertEqual(p[UDP].dport, 4739)
6172 self.assertEqual(p[IPFIX].observationDomainID,
6173 self.ipfix_domain_id)
6174 if p.haslayer(Data):
6175 data = ipfix.decode_data_set(p.getlayer(Set))
6176 self.verify_ipfix_max_bibs(data, max_bibs)
6177
6178 def test_ipfix_max_frags(self):
6179 """ IPFIX logging maximum fragments pending reassembly exceeded """
6180 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
6181 self.nat_addr_n)
6182 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
6183 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
6184 self.vapi.nat_set_reass(max_frag=0, is_ip6=1)
6185 self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4n,
6186 src_address=self.pg3.local_ip4n,
6187 path_mtu=512,
6188 template_interval=10)
6189 self.vapi.nat_ipfix(domain_id=self.ipfix_domain_id,
6190 src_port=self.ipfix_src_port)
6191
6192 data = 'a' * 200
6193 pkts = self.create_stream_frag_ip6(self.pg0, self.pg1.remote_ip4,
6194 self.tcp_port_in, 20, data)
6195 self.pg0.add_stream(pkts[-1])
6196 self.pg_enable_capture(self.pg_interfaces)
6197 self.pg_start()
Matus Fabian229c1aa2018-05-28 04:09:52 -07006198 self.pg1.assert_nothing_captured()
6199 sleep(1)
Matus Fabiana431ad12018-01-04 04:03:14 -08006200 self.vapi.cli("ipfix flush") # FIXME this should be an API call
6201 capture = self.pg3.get_capture(9)
6202 ipfix = IPFIXDecoder()
6203 # first load template
6204 for p in capture:
6205 self.assertTrue(p.haslayer(IPFIX))
6206 self.assertEqual(p[IP].src, self.pg3.local_ip4)
6207 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
6208 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
6209 self.assertEqual(p[UDP].dport, 4739)
6210 self.assertEqual(p[IPFIX].observationDomainID,
6211 self.ipfix_domain_id)
6212 if p.haslayer(Template):
6213 ipfix.add_template(p.getlayer(Template))
6214 # verify events in data set
6215 for p in capture:
6216 if p.haslayer(Data):
6217 data = ipfix.decode_data_set(p.getlayer(Set))
6218 self.verify_ipfix_max_fragments_ip6(data, 0,
6219 self.pg0.remote_ip6n)
6220
6221 def test_ipfix_bib_ses(self):
6222 """ IPFIX logging NAT64 BIB/session create and delete events """
6223 self.tcp_port_in = random.randint(1025, 65535)
6224 remote_host_ip6 = self.compose_ip6(self.pg1.remote_ip4,
6225 '64:ff9b::',
6226 96)
6227
6228 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
6229 self.nat_addr_n)
6230 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
6231 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
6232 self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4n,
6233 src_address=self.pg3.local_ip4n,
6234 path_mtu=512,
6235 template_interval=10)
6236 self.vapi.nat_ipfix(domain_id=self.ipfix_domain_id,
6237 src_port=self.ipfix_src_port)
6238
6239 # Create
6240 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6241 IPv6(src=self.pg0.remote_ip6, dst=remote_host_ip6) /
6242 TCP(sport=self.tcp_port_in, dport=25))
6243 self.pg0.add_stream(p)
6244 self.pg_enable_capture(self.pg_interfaces)
6245 self.pg_start()
6246 p = self.pg1.get_capture(1)
6247 self.tcp_port_out = p[0][TCP].sport
6248 self.vapi.cli("ipfix flush") # FIXME this should be an API call
6249 capture = self.pg3.get_capture(10)
6250 ipfix = IPFIXDecoder()
6251 # first load template
6252 for p in capture:
6253 self.assertTrue(p.haslayer(IPFIX))
6254 self.assertEqual(p[IP].src, self.pg3.local_ip4)
6255 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
6256 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
6257 self.assertEqual(p[UDP].dport, 4739)
6258 self.assertEqual(p[IPFIX].observationDomainID,
6259 self.ipfix_domain_id)
6260 if p.haslayer(Template):
6261 ipfix.add_template(p.getlayer(Template))
6262 # verify events in data set
6263 for p in capture:
6264 if p.haslayer(Data):
6265 data = ipfix.decode_data_set(p.getlayer(Set))
6266 if ord(data[0][230]) == 10:
6267 self.verify_ipfix_bib(data, 1, self.pg0.remote_ip6n)
6268 elif ord(data[0][230]) == 6:
6269 self.verify_ipfix_nat64_ses(data,
6270 1,
6271 self.pg0.remote_ip6n,
6272 self.pg1.remote_ip4,
6273 25)
6274 else:
6275 self.logger.error(ppp("Unexpected or invalid packet: ", p))
6276
6277 # Delete
6278 self.pg_enable_capture(self.pg_interfaces)
6279 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
6280 self.nat_addr_n,
6281 is_add=0)
6282 self.vapi.cli("ipfix flush") # FIXME this should be an API call
6283 capture = self.pg3.get_capture(2)
6284 # verify events in data set
6285 for p in capture:
6286 self.assertTrue(p.haslayer(IPFIX))
6287 self.assertEqual(p[IP].src, self.pg3.local_ip4)
6288 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
6289 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
6290 self.assertEqual(p[UDP].dport, 4739)
6291 self.assertEqual(p[IPFIX].observationDomainID,
6292 self.ipfix_domain_id)
6293 if p.haslayer(Data):
6294 data = ipfix.decode_data_set(p.getlayer(Set))
6295 if ord(data[0][230]) == 11:
6296 self.verify_ipfix_bib(data, 0, self.pg0.remote_ip6n)
6297 elif ord(data[0][230]) == 7:
6298 self.verify_ipfix_nat64_ses(data,
6299 0,
6300 self.pg0.remote_ip6n,
6301 self.pg1.remote_ip4,
6302 25)
6303 else:
6304 self.logger.error(ppp("Unexpected or invalid packet: ", p))
6305
Matus Fabian06596c52017-06-06 04:53:28 -07006306 def nat64_get_ses_num(self):
6307 """
6308 Return number of active NAT64 sessions.
6309 """
Matus Fabianab9a59c2017-08-16 05:37:36 -07006310 st = self.vapi.nat64_st_dump()
6311 return len(st)
Matus Fabian06596c52017-06-06 04:53:28 -07006312
6313 def clear_nat64(self):
6314 """
6315 Clear NAT64 configuration.
6316 """
Matus Fabiana431ad12018-01-04 04:03:14 -08006317 self.vapi.nat_ipfix(enable=0, src_port=self.ipfix_src_port,
6318 domain_id=self.ipfix_domain_id)
6319 self.ipfix_src_port = 4739
6320 self.ipfix_domain_id = 1
6321
Matus Fabian06596c52017-06-06 04:53:28 -07006322 self.vapi.nat64_set_timeouts()
6323
6324 interfaces = self.vapi.nat64_interface_dump()
6325 for intf in interfaces:
Matus Fabian36ea2d62017-10-24 04:13:49 -07006326 if intf.is_inside > 1:
6327 self.vapi.nat64_add_del_interface(intf.sw_if_index,
6328 0,
6329 is_add=0)
Matus Fabian06596c52017-06-06 04:53:28 -07006330 self.vapi.nat64_add_del_interface(intf.sw_if_index,
6331 intf.is_inside,
6332 is_add=0)
6333
Matus Fabiana431ad12018-01-04 04:03:14 -08006334 bib = self.vapi.nat64_bib_dump(255)
Matus Fabian06596c52017-06-06 04:53:28 -07006335 for bibe in bib:
6336 if bibe.is_static:
6337 self.vapi.nat64_add_del_static_bib(bibe.i_addr,
6338 bibe.o_addr,
6339 bibe.i_port,
6340 bibe.o_port,
6341 bibe.proto,
6342 bibe.vrf_id,
6343 is_add=0)
6344
6345 adresses = self.vapi.nat64_pool_addr_dump()
6346 for addr in adresses:
6347 self.vapi.nat64_add_del_pool_addr_range(addr.address,
6348 addr.address,
Matus Fabian029f3d22017-06-15 02:28:50 -07006349 vrf_id=addr.vrf_id,
Matus Fabian06596c52017-06-06 04:53:28 -07006350 is_add=0)
6351
Matus Fabian428dc912017-06-21 06:15:18 -07006352 prefixes = self.vapi.nat64_prefix_dump()
6353 for prefix in prefixes:
6354 self.vapi.nat64_add_del_prefix(prefix.prefix,
6355 prefix.prefix_len,
6356 vrf_id=prefix.vrf_id,
6357 is_add=0)
6358
Matus Fabian06596c52017-06-06 04:53:28 -07006359 def tearDown(self):
6360 super(TestNAT64, self).tearDown()
6361 if not self.vpp_dead:
6362 self.logger.info(self.vapi.cli("show nat64 pool"))
6363 self.logger.info(self.vapi.cli("show nat64 interfaces"))
Matus Fabian428dc912017-06-21 06:15:18 -07006364 self.logger.info(self.vapi.cli("show nat64 prefix"))
Matus Fabianab9a59c2017-08-16 05:37:36 -07006365 self.logger.info(self.vapi.cli("show nat64 bib all"))
6366 self.logger.info(self.vapi.cli("show nat64 session table all"))
Matus Fabianefcd1e92017-08-15 06:59:19 -07006367 self.logger.info(self.vapi.cli("show nat virtual-reassembly"))
Matus Fabian06596c52017-06-06 04:53:28 -07006368 self.clear_nat64()
6369
Matus Fabian8ebe6252017-11-06 05:04:53 -08006370
6371class TestDSlite(MethodHolder):
6372 """ DS-Lite Test Cases """
6373
6374 @classmethod
6375 def setUpClass(cls):
6376 super(TestDSlite, cls).setUpClass()
6377
6378 try:
6379 cls.nat_addr = '10.0.0.3'
6380 cls.nat_addr_n = socket.inet_pton(socket.AF_INET, cls.nat_addr)
6381
6382 cls.create_pg_interfaces(range(2))
6383 cls.pg0.admin_up()
6384 cls.pg0.config_ip4()
6385 cls.pg0.resolve_arp()
6386 cls.pg1.admin_up()
6387 cls.pg1.config_ip6()
6388 cls.pg1.generate_remote_hosts(2)
6389 cls.pg1.configure_ipv6_neighbors()
6390
6391 except Exception:
6392 super(TestDSlite, cls).tearDownClass()
6393 raise
6394
6395 def test_dslite(self):
6396 """ Test DS-Lite """
6397 self.vapi.dslite_add_del_pool_addr_range(self.nat_addr_n,
6398 self.nat_addr_n)
6399 aftr_ip4 = '192.0.0.1'
6400 aftr_ip4_n = socket.inet_pton(socket.AF_INET, aftr_ip4)
6401 aftr_ip6 = '2001:db8:85a3::8a2e:370:1'
6402 aftr_ip6_n = socket.inet_pton(socket.AF_INET6, aftr_ip6)
6403 self.vapi.dslite_set_aftr_addr(aftr_ip6_n, aftr_ip4_n)
6404
6405 # UDP
6406 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
6407 IPv6(dst=aftr_ip6, src=self.pg1.remote_hosts[0].ip6) /
6408 IP(dst=self.pg0.remote_ip4, src='192.168.1.1') /
6409 UDP(sport=20000, dport=10000))
6410 self.pg1.add_stream(p)
6411 self.pg_enable_capture(self.pg_interfaces)
6412 self.pg_start()
6413 capture = self.pg0.get_capture(1)
6414 capture = capture[0]
6415 self.assertFalse(capture.haslayer(IPv6))
6416 self.assertEqual(capture[IP].src, self.nat_addr)
6417 self.assertEqual(capture[IP].dst, self.pg0.remote_ip4)
6418 self.assertNotEqual(capture[UDP].sport, 20000)
6419 self.assertEqual(capture[UDP].dport, 10000)
Klement Sekerad81ae412018-05-16 10:52:54 +02006420 self.assert_packet_checksums_valid(capture)
Matus Fabian8ebe6252017-11-06 05:04:53 -08006421 out_port = capture[UDP].sport
6422
6423 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
6424 IP(dst=self.nat_addr, src=self.pg0.remote_ip4) /
6425 UDP(sport=10000, dport=out_port))
6426 self.pg0.add_stream(p)
6427 self.pg_enable_capture(self.pg_interfaces)
6428 self.pg_start()
6429 capture = self.pg1.get_capture(1)
6430 capture = capture[0]
6431 self.assertEqual(capture[IPv6].src, aftr_ip6)
6432 self.assertEqual(capture[IPv6].dst, self.pg1.remote_hosts[0].ip6)
6433 self.assertEqual(capture[IP].src, self.pg0.remote_ip4)
6434 self.assertEqual(capture[IP].dst, '192.168.1.1')
6435 self.assertEqual(capture[UDP].sport, 10000)
6436 self.assertEqual(capture[UDP].dport, 20000)
Klement Sekerad81ae412018-05-16 10:52:54 +02006437 self.assert_packet_checksums_valid(capture)
Matus Fabian8ebe6252017-11-06 05:04:53 -08006438
6439 # TCP
6440 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
6441 IPv6(dst=aftr_ip6, src=self.pg1.remote_hosts[1].ip6) /
6442 IP(dst=self.pg0.remote_ip4, src='192.168.1.1') /
6443 TCP(sport=20001, dport=10001))
6444 self.pg1.add_stream(p)
6445 self.pg_enable_capture(self.pg_interfaces)
6446 self.pg_start()
6447 capture = self.pg0.get_capture(1)
6448 capture = capture[0]
6449 self.assertFalse(capture.haslayer(IPv6))
6450 self.assertEqual(capture[IP].src, self.nat_addr)
6451 self.assertEqual(capture[IP].dst, self.pg0.remote_ip4)
6452 self.assertNotEqual(capture[TCP].sport, 20001)
6453 self.assertEqual(capture[TCP].dport, 10001)
Klement Sekerad81ae412018-05-16 10:52:54 +02006454 self.assert_packet_checksums_valid(capture)
Matus Fabian8ebe6252017-11-06 05:04:53 -08006455 out_port = capture[TCP].sport
6456
6457 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
6458 IP(dst=self.nat_addr, src=self.pg0.remote_ip4) /
6459 TCP(sport=10001, dport=out_port))
6460 self.pg0.add_stream(p)
6461 self.pg_enable_capture(self.pg_interfaces)
6462 self.pg_start()
6463 capture = self.pg1.get_capture(1)
6464 capture = capture[0]
6465 self.assertEqual(capture[IPv6].src, aftr_ip6)
6466 self.assertEqual(capture[IPv6].dst, self.pg1.remote_hosts[1].ip6)
6467 self.assertEqual(capture[IP].src, self.pg0.remote_ip4)
6468 self.assertEqual(capture[IP].dst, '192.168.1.1')
6469 self.assertEqual(capture[TCP].sport, 10001)
6470 self.assertEqual(capture[TCP].dport, 20001)
Klement Sekerad81ae412018-05-16 10:52:54 +02006471 self.assert_packet_checksums_valid(capture)
Matus Fabian8ebe6252017-11-06 05:04:53 -08006472
6473 # ICMP
6474 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
6475 IPv6(dst=aftr_ip6, src=self.pg1.remote_hosts[1].ip6) /
6476 IP(dst=self.pg0.remote_ip4, src='192.168.1.1') /
6477 ICMP(id=4000, type='echo-request'))
6478 self.pg1.add_stream(p)
6479 self.pg_enable_capture(self.pg_interfaces)
6480 self.pg_start()
6481 capture = self.pg0.get_capture(1)
6482 capture = capture[0]
6483 self.assertFalse(capture.haslayer(IPv6))
6484 self.assertEqual(capture[IP].src, self.nat_addr)
6485 self.assertEqual(capture[IP].dst, self.pg0.remote_ip4)
6486 self.assertNotEqual(capture[ICMP].id, 4000)
Klement Sekerad81ae412018-05-16 10:52:54 +02006487 self.assert_packet_checksums_valid(capture)
Matus Fabian8ebe6252017-11-06 05:04:53 -08006488 out_id = capture[ICMP].id
6489
6490 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
6491 IP(dst=self.nat_addr, src=self.pg0.remote_ip4) /
6492 ICMP(id=out_id, type='echo-reply'))
6493 self.pg0.add_stream(p)
6494 self.pg_enable_capture(self.pg_interfaces)
6495 self.pg_start()
6496 capture = self.pg1.get_capture(1)
6497 capture = capture[0]
6498 self.assertEqual(capture[IPv6].src, aftr_ip6)
6499 self.assertEqual(capture[IPv6].dst, self.pg1.remote_hosts[1].ip6)
6500 self.assertEqual(capture[IP].src, self.pg0.remote_ip4)
6501 self.assertEqual(capture[IP].dst, '192.168.1.1')
6502 self.assertEqual(capture[ICMP].id, 4000)
Klement Sekerad81ae412018-05-16 10:52:54 +02006503 self.assert_packet_checksums_valid(capture)
Matus Fabian8ebe6252017-11-06 05:04:53 -08006504
Matus Fabian331acc62017-12-08 03:38:51 -08006505 # ping DS-Lite AFTR tunnel endpoint address
6506 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
6507 IPv6(src=self.pg1.remote_hosts[1].ip6, dst=aftr_ip6) /
6508 ICMPv6EchoRequest())
6509 self.pg1.add_stream(p)
6510 self.pg_enable_capture(self.pg_interfaces)
6511 self.pg_start()
6512 capture = self.pg1.get_capture(1)
6513 self.assertEqual(1, len(capture))
6514 capture = capture[0]
6515 self.assertEqual(capture[IPv6].src, aftr_ip6)
6516 self.assertEqual(capture[IPv6].dst, self.pg1.remote_hosts[1].ip6)
6517 self.assertTrue(capture.haslayer(ICMPv6EchoReply))
6518
Matus Fabian8ebe6252017-11-06 05:04:53 -08006519 def tearDown(self):
6520 super(TestDSlite, self).tearDown()
6521 if not self.vpp_dead:
6522 self.logger.info(self.vapi.cli("show dslite pool"))
6523 self.logger.info(
6524 self.vapi.cli("show dslite aftr-tunnel-endpoint-address"))
6525 self.logger.info(self.vapi.cli("show dslite sessions"))
6526
Juraj Slobodac5c6a332018-01-09 16:08:32 +01006527
6528class TestDSliteCE(MethodHolder):
6529 """ DS-Lite CE Test Cases """
6530
6531 @classmethod
6532 def setUpConstants(cls):
6533 super(TestDSliteCE, cls).setUpConstants()
6534 cls.vpp_cmdline.extend(["nat", "{", "dslite ce", "}"])
6535
6536 @classmethod
6537 def setUpClass(cls):
6538 super(TestDSliteCE, cls).setUpClass()
6539
6540 try:
6541 cls.create_pg_interfaces(range(2))
6542 cls.pg0.admin_up()
6543 cls.pg0.config_ip4()
6544 cls.pg0.resolve_arp()
6545 cls.pg1.admin_up()
6546 cls.pg1.config_ip6()
6547 cls.pg1.generate_remote_hosts(1)
6548 cls.pg1.configure_ipv6_neighbors()
6549
6550 except Exception:
6551 super(TestDSliteCE, cls).tearDownClass()
6552 raise
6553
6554 def test_dslite_ce(self):
6555 """ Test DS-Lite CE """
6556
6557 b4_ip4 = '192.0.0.2'
6558 b4_ip4_n = socket.inet_pton(socket.AF_INET, b4_ip4)
6559 b4_ip6 = '2001:db8:62aa::375e:f4c1:1'
6560 b4_ip6_n = socket.inet_pton(socket.AF_INET6, b4_ip6)
6561 self.vapi.dslite_set_b4_addr(b4_ip6_n, b4_ip4_n)
6562
6563 aftr_ip4 = '192.0.0.1'
6564 aftr_ip4_n = socket.inet_pton(socket.AF_INET, aftr_ip4)
6565 aftr_ip6 = '2001:db8:85a3::8a2e:370:1'
6566 aftr_ip6_n = socket.inet_pton(socket.AF_INET6, aftr_ip6)
6567 self.vapi.dslite_set_aftr_addr(aftr_ip6_n, aftr_ip4_n)
6568
6569 self.vapi.ip_add_del_route(dst_address=aftr_ip6_n,
6570 dst_address_length=128,
6571 next_hop_address=self.pg1.remote_ip6n,
6572 next_hop_sw_if_index=self.pg1.sw_if_index,
6573 is_ipv6=1)
6574
6575 # UDP encapsulation
6576 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
6577 IP(dst=self.pg1.remote_ip4, src=self.pg0.remote_ip4) /
6578 UDP(sport=10000, dport=20000))
6579 self.pg0.add_stream(p)
6580 self.pg_enable_capture(self.pg_interfaces)
6581 self.pg_start()
6582 capture = self.pg1.get_capture(1)
6583 capture = capture[0]
6584 self.assertEqual(capture[IPv6].src, b4_ip6)
6585 self.assertEqual(capture[IPv6].dst, aftr_ip6)
6586 self.assertEqual(capture[IP].src, self.pg0.remote_ip4)
6587 self.assertEqual(capture[IP].dst, self.pg1.remote_ip4)
6588 self.assertEqual(capture[UDP].sport, 10000)
6589 self.assertEqual(capture[UDP].dport, 20000)
Klement Sekerad81ae412018-05-16 10:52:54 +02006590 self.assert_packet_checksums_valid(capture)
Juraj Slobodac5c6a332018-01-09 16:08:32 +01006591
6592 # UDP decapsulation
6593 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
6594 IPv6(dst=b4_ip6, src=aftr_ip6) /
6595 IP(dst=self.pg0.remote_ip4, src=self.pg1.remote_ip4) /
6596 UDP(sport=20000, dport=10000))
6597 self.pg1.add_stream(p)
6598 self.pg_enable_capture(self.pg_interfaces)
6599 self.pg_start()
6600 capture = self.pg0.get_capture(1)
6601 capture = capture[0]
6602 self.assertFalse(capture.haslayer(IPv6))
6603 self.assertEqual(capture[IP].src, self.pg1.remote_ip4)
6604 self.assertEqual(capture[IP].dst, self.pg0.remote_ip4)
6605 self.assertEqual(capture[UDP].sport, 20000)
6606 self.assertEqual(capture[UDP].dport, 10000)
Klement Sekerad81ae412018-05-16 10:52:54 +02006607 self.assert_packet_checksums_valid(capture)
Juraj Slobodac5c6a332018-01-09 16:08:32 +01006608
6609 # ping DS-Lite B4 tunnel endpoint address
6610 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
6611 IPv6(src=self.pg1.remote_hosts[0].ip6, dst=b4_ip6) /
6612 ICMPv6EchoRequest())
6613 self.pg1.add_stream(p)
6614 self.pg_enable_capture(self.pg_interfaces)
6615 self.pg_start()
6616 capture = self.pg1.get_capture(1)
6617 self.assertEqual(1, len(capture))
6618 capture = capture[0]
6619 self.assertEqual(capture[IPv6].src, b4_ip6)
6620 self.assertEqual(capture[IPv6].dst, self.pg1.remote_hosts[0].ip6)
6621 self.assertTrue(capture.haslayer(ICMPv6EchoReply))
6622
6623 def tearDown(self):
6624 super(TestDSliteCE, self).tearDown()
6625 if not self.vpp_dead:
6626 self.logger.info(
6627 self.vapi.cli("show dslite aftr-tunnel-endpoint-address"))
6628 self.logger.info(
6629 self.vapi.cli("show dslite b4-tunnel-endpoint-address"))
6630
Matus Fabianf2a23cc2018-01-22 03:41:53 -08006631
6632class TestNAT66(MethodHolder):
6633 """ NAT66 Test Cases """
6634
6635 @classmethod
6636 def setUpClass(cls):
6637 super(TestNAT66, cls).setUpClass()
6638
6639 try:
6640 cls.nat_addr = 'fd01:ff::2'
6641 cls.nat_addr_n = socket.inet_pton(socket.AF_INET6, cls.nat_addr)
6642
6643 cls.create_pg_interfaces(range(2))
6644 cls.interfaces = list(cls.pg_interfaces)
6645
6646 for i in cls.interfaces:
6647 i.admin_up()
6648 i.config_ip6()
6649 i.configure_ipv6_neighbors()
6650
6651 except Exception:
6652 super(TestNAT66, cls).tearDownClass()
6653 raise
6654
6655 def test_static(self):
6656 """ 1:1 NAT66 test """
6657 self.vapi.nat66_add_del_interface(self.pg0.sw_if_index)
6658 self.vapi.nat66_add_del_interface(self.pg1.sw_if_index, is_inside=0)
6659 self.vapi.nat66_add_del_static_mapping(self.pg0.remote_ip6n,
6660 self.nat_addr_n)
6661
6662 # in2out
6663 pkts = []
6664 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
6665 IPv6(src=self.pg0.remote_ip6, dst=self.pg1.remote_ip6) /
6666 TCP())
6667 pkts.append(p)
6668 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
6669 IPv6(src=self.pg0.remote_ip6, dst=self.pg1.remote_ip6) /
6670 UDP())
6671 pkts.append(p)
6672 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
6673 IPv6(src=self.pg0.remote_ip6, dst=self.pg1.remote_ip6) /
6674 ICMPv6EchoRequest())
6675 pkts.append(p)
6676 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
6677 IPv6(src=self.pg0.remote_ip6, dst=self.pg1.remote_ip6) /
6678 GRE() / IP() / TCP())
6679 pkts.append(p)
6680 self.pg0.add_stream(pkts)
6681 self.pg_enable_capture(self.pg_interfaces)
6682 self.pg_start()
6683 capture = self.pg1.get_capture(len(pkts))
6684 for packet in capture:
6685 try:
6686 self.assertEqual(packet[IPv6].src, self.nat_addr)
6687 self.assertEqual(packet[IPv6].dst, self.pg1.remote_ip6)
Klement Sekerad81ae412018-05-16 10:52:54 +02006688 self.assert_packet_checksums_valid(packet)
Matus Fabianf2a23cc2018-01-22 03:41:53 -08006689 except:
6690 self.logger.error(ppp("Unexpected or invalid packet:", packet))
6691 raise
6692
6693 # out2in
6694 pkts = []
6695 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
6696 IPv6(src=self.pg1.remote_ip6, dst=self.nat_addr) /
6697 TCP())
6698 pkts.append(p)
6699 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
6700 IPv6(src=self.pg1.remote_ip6, dst=self.nat_addr) /
6701 UDP())
6702 pkts.append(p)
6703 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
6704 IPv6(src=self.pg1.remote_ip6, dst=self.nat_addr) /
6705 ICMPv6EchoReply())
6706 pkts.append(p)
6707 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
6708 IPv6(src=self.pg1.remote_ip6, dst=self.nat_addr) /
6709 GRE() / IP() / TCP())
6710 pkts.append(p)
6711 self.pg1.add_stream(pkts)
6712 self.pg_enable_capture(self.pg_interfaces)
6713 self.pg_start()
6714 capture = self.pg0.get_capture(len(pkts))
6715 for packet in capture:
6716 try:
6717 self.assertEqual(packet[IPv6].src, self.pg1.remote_ip6)
6718 self.assertEqual(packet[IPv6].dst, self.pg0.remote_ip6)
Klement Sekerad81ae412018-05-16 10:52:54 +02006719 self.assert_packet_checksums_valid(packet)
Matus Fabianf2a23cc2018-01-22 03:41:53 -08006720 except:
6721 self.logger.error(ppp("Unexpected or invalid packet:", packet))
6722 raise
6723
6724 sm = self.vapi.nat66_static_mapping_dump()
6725 self.assertEqual(len(sm), 1)
6726 self.assertEqual(sm[0].total_pkts, 8)
6727
Juraj Sloboda9341e342018-04-13 12:00:46 +02006728 def test_check_no_translate(self):
6729 """ NAT66 translate only when egress interface is outside interface """
6730 self.vapi.nat66_add_del_interface(self.pg0.sw_if_index)
6731 self.vapi.nat66_add_del_interface(self.pg1.sw_if_index)
6732 self.vapi.nat66_add_del_static_mapping(self.pg0.remote_ip6n,
6733 self.nat_addr_n)
6734
6735 # in2out
6736 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
6737 IPv6(src=self.pg0.remote_ip6, dst=self.pg1.remote_ip6) /
6738 UDP())
6739 self.pg0.add_stream([p])
6740 self.pg_enable_capture(self.pg_interfaces)
6741 self.pg_start()
6742 capture = self.pg1.get_capture(1)
6743 packet = capture[0]
6744 try:
6745 self.assertEqual(packet[IPv6].src, self.pg0.remote_ip6)
6746 self.assertEqual(packet[IPv6].dst, self.pg1.remote_ip6)
6747 except:
6748 self.logger.error(ppp("Unexpected or invalid packet:", packet))
6749 raise
6750
Matus Fabianf2a23cc2018-01-22 03:41:53 -08006751 def clear_nat66(self):
6752 """
6753 Clear NAT66 configuration.
6754 """
6755 interfaces = self.vapi.nat66_interface_dump()
6756 for intf in interfaces:
6757 self.vapi.nat66_add_del_interface(intf.sw_if_index,
6758 intf.is_inside,
6759 is_add=0)
6760
6761 static_mappings = self.vapi.nat66_static_mapping_dump()
6762 for sm in static_mappings:
6763 self.vapi.nat66_add_del_static_mapping(sm.local_ip_address,
6764 sm.external_ip_address,
6765 sm.vrf_id,
6766 is_add=0)
6767
6768 def tearDown(self):
6769 super(TestNAT66, self).tearDown()
6770 if not self.vpp_dead:
6771 self.logger.info(self.vapi.cli("show nat66 interfaces"))
6772 self.logger.info(self.vapi.cli("show nat66 static mappings"))
6773 self.clear_nat66()
6774
Klement Sekerad81ae412018-05-16 10:52:54 +02006775
Matus Fabiande886752016-12-07 03:38:19 -08006776if __name__ == '__main__':
6777 unittest.main(testRunner=VppTestRunner)