blob: 363df719a75d8f4b6f854d5391d68146b2c765a8 [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
Juraj Slobodac746a152018-07-09 02:36:37 +020012from scapy.layers.inet6 import IPv6, ICMPv6EchoRequest, ICMPv6EchoReply, \
13 ICMPv6ND_NS, ICMPv6ND_NA, ICMPv6NDOptDstLLAddr
Matus Fabianefcd1e92017-08-15 06:59:19 -070014from scapy.layers.inet6 import ICMPv6DestUnreach, IPerror6, IPv6ExtHdrFragment
Matus Fabian328dbc82017-06-19 04:28:04 -070015from scapy.layers.l2 import Ether, ARP, GRE
Matus Fabianeea28d72017-01-13 04:15:54 -080016from scapy.data import IP_PROTOS
Matus Fabianefcd1e92017-08-15 06:59:19 -070017from scapy.packet import bind_layers, Raw
18from scapy.all import fragment6
Klement Sekera9225dee2016-12-12 08:36:58 +010019from util import ppp
Matus Fabianeea28d72017-01-13 04:15:54 -080020from ipfix import IPFIX, Set, Template, Data, IPFIXDecoder
Martin Gálik977c1cb2017-03-30 23:21:51 -070021from time import sleep
Matus Fabian704018c2017-09-04 02:17:18 -070022from util import ip4_range
Ole Troan895b6e82017-10-20 13:28:20 +020023from util import mactobinary
Matus Fabiande886752016-12-07 03:38:19 -080024
25
Martin Gálikd7f75cd2017-03-27 06:02:47 -070026class MethodHolder(VppTestCase):
Matus Fabian2ba92e32017-08-21 07:05:03 -070027 """ NAT create capture and verify method holder """
Matus Fabiande886752016-12-07 03:38:19 -080028
Matus Fabiana6110b62018-06-13 05:39:07 -070029 def clear_nat44(self):
30 """
31 Clear NAT44 configuration.
32 """
33 if hasattr(self, 'pg7') and hasattr(self, 'pg8'):
34 # I found no elegant way to do this
35 self.vapi.ip_add_del_route(
36 dst_address=self.pg7.remote_ip4n,
37 dst_address_length=32,
38 next_hop_address=self.pg7.remote_ip4n,
39 next_hop_sw_if_index=self.pg7.sw_if_index,
40 is_add=0)
41 self.vapi.ip_add_del_route(
42 dst_address=self.pg8.remote_ip4n,
43 dst_address_length=32,
44 next_hop_address=self.pg8.remote_ip4n,
45 next_hop_sw_if_index=self.pg8.sw_if_index,
46 is_add=0)
47
48 for intf in [self.pg7, self.pg8]:
49 neighbors = self.vapi.ip_neighbor_dump(intf.sw_if_index)
50 for n in neighbors:
51 self.vapi.ip_neighbor_add_del(intf.sw_if_index,
52 n.mac_address,
53 n.ip_address,
54 is_add=0)
55
56 if self.pg7.has_ip4_config:
57 self.pg7.unconfig_ip4()
58
59 self.vapi.nat44_forwarding_enable_disable(0)
60
61 interfaces = self.vapi.nat44_interface_addr_dump()
62 for intf in interfaces:
63 self.vapi.nat44_add_interface_addr(intf.sw_if_index,
64 twice_nat=intf.twice_nat,
65 is_add=0)
66
67 self.vapi.nat_ipfix(enable=0, src_port=self.ipfix_src_port,
68 domain_id=self.ipfix_domain_id)
69 self.ipfix_src_port = 4739
70 self.ipfix_domain_id = 1
71
72 interfaces = self.vapi.nat44_interface_dump()
73 for intf in interfaces:
74 if intf.is_inside > 1:
75 self.vapi.nat44_interface_add_del_feature(intf.sw_if_index,
76 0,
77 is_add=0)
78 self.vapi.nat44_interface_add_del_feature(intf.sw_if_index,
79 intf.is_inside,
80 is_add=0)
81
82 interfaces = self.vapi.nat44_interface_output_feature_dump()
83 for intf in interfaces:
84 self.vapi.nat44_interface_add_del_output_feature(intf.sw_if_index,
85 intf.is_inside,
86 is_add=0)
87
88 static_mappings = self.vapi.nat44_static_mapping_dump()
89 for sm in static_mappings:
90 self.vapi.nat44_add_del_static_mapping(
91 sm.local_ip_address,
92 sm.external_ip_address,
93 local_port=sm.local_port,
94 external_port=sm.external_port,
95 addr_only=sm.addr_only,
96 vrf_id=sm.vrf_id,
97 protocol=sm.protocol,
98 twice_nat=sm.twice_nat,
99 self_twice_nat=sm.self_twice_nat,
100 out2in_only=sm.out2in_only,
101 tag=sm.tag,
102 external_sw_if_index=sm.external_sw_if_index,
103 is_add=0)
104
105 lb_static_mappings = self.vapi.nat44_lb_static_mapping_dump()
106 for lb_sm in lb_static_mappings:
107 self.vapi.nat44_add_del_lb_static_mapping(
108 lb_sm.external_addr,
109 lb_sm.external_port,
110 lb_sm.protocol,
111 vrf_id=lb_sm.vrf_id,
112 twice_nat=lb_sm.twice_nat,
113 self_twice_nat=lb_sm.self_twice_nat,
114 out2in_only=lb_sm.out2in_only,
115 tag=lb_sm.tag,
116 is_add=0,
117 local_num=0,
118 locals=[])
119
120 identity_mappings = self.vapi.nat44_identity_mapping_dump()
121 for id_m in identity_mappings:
122 self.vapi.nat44_add_del_identity_mapping(
123 addr_only=id_m.addr_only,
124 ip=id_m.ip_address,
125 port=id_m.port,
126 sw_if_index=id_m.sw_if_index,
127 vrf_id=id_m.vrf_id,
128 protocol=id_m.protocol,
129 is_add=0)
130
131 adresses = self.vapi.nat44_address_dump()
132 for addr in adresses:
133 self.vapi.nat44_add_del_address_range(addr.ip_address,
134 addr.ip_address,
135 twice_nat=addr.twice_nat,
136 is_add=0)
137
138 self.vapi.nat_set_reass()
139 self.vapi.nat_set_reass(is_ip6=1)
140
141 def nat44_add_static_mapping(self, local_ip, external_ip='0.0.0.0',
142 local_port=0, external_port=0, vrf_id=0,
143 is_add=1, external_sw_if_index=0xFFFFFFFF,
144 proto=0, twice_nat=0, self_twice_nat=0,
145 out2in_only=0, tag=""):
146 """
147 Add/delete NAT44 static mapping
148
149 :param local_ip: Local IP address
150 :param external_ip: External IP address
151 :param local_port: Local port number (Optional)
152 :param external_port: External port number (Optional)
153 :param vrf_id: VRF ID (Default 0)
154 :param is_add: 1 if add, 0 if delete (Default add)
155 :param external_sw_if_index: External interface instead of IP address
156 :param proto: IP protocol (Mandatory if port specified)
157 :param twice_nat: 1 if translate external host address and port
158 :param self_twice_nat: 1 if translate external host address and port
159 whenever external host address equals
160 local address of internal host
161 :param out2in_only: if 1 rule is matching only out2in direction
162 :param tag: Opaque string tag
163 """
164 addr_only = 1
165 if local_port and external_port:
166 addr_only = 0
167 l_ip = socket.inet_pton(socket.AF_INET, local_ip)
168 e_ip = socket.inet_pton(socket.AF_INET, external_ip)
169 self.vapi.nat44_add_del_static_mapping(
170 l_ip,
171 e_ip,
172 external_sw_if_index,
173 local_port,
174 external_port,
175 addr_only,
176 vrf_id,
177 proto,
178 twice_nat,
179 self_twice_nat,
180 out2in_only,
181 tag,
182 is_add)
183
184 def nat44_add_address(self, ip, is_add=1, vrf_id=0xFFFFFFFF, twice_nat=0):
185 """
186 Add/delete NAT44 address
187
188 :param ip: IP address
189 :param is_add: 1 if add, 0 if delete (Default add)
190 :param twice_nat: twice NAT address for extenal hosts
191 """
192 nat_addr = socket.inet_pton(socket.AF_INET, ip)
193 self.vapi.nat44_add_del_address_range(nat_addr, nat_addr, is_add,
194 vrf_id=vrf_id,
195 twice_nat=twice_nat)
196
Juraj Slobodacba69362017-12-19 02:09:32 +0100197 def create_stream_in(self, in_if, out_if, dst_ip=None, ttl=64):
Matus Fabiande886752016-12-07 03:38:19 -0800198 """
199 Create packet stream for inside network
200
201 :param in_if: Inside interface
202 :param out_if: Outside interface
Juraj Slobodacba69362017-12-19 02:09:32 +0100203 :param dst_ip: Destination address
Juraj Slobodab33f4132017-02-08 23:54:21 -0800204 :param ttl: TTL of generated packets
Matus Fabiande886752016-12-07 03:38:19 -0800205 """
Juraj Slobodacba69362017-12-19 02:09:32 +0100206 if dst_ip is None:
207 dst_ip = out_if.remote_ip4
208
Matus Fabiande886752016-12-07 03:38:19 -0800209 pkts = []
210 # TCP
211 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
Juraj Slobodacba69362017-12-19 02:09:32 +0100212 IP(src=in_if.remote_ip4, dst=dst_ip, ttl=ttl) /
Matus Fabian06596c52017-06-06 04:53:28 -0700213 TCP(sport=self.tcp_port_in, dport=20))
Matus Fabiande886752016-12-07 03:38:19 -0800214 pkts.append(p)
215
216 # UDP
217 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
Juraj Slobodacba69362017-12-19 02:09:32 +0100218 IP(src=in_if.remote_ip4, dst=dst_ip, ttl=ttl) /
Matus Fabian06596c52017-06-06 04:53:28 -0700219 UDP(sport=self.udp_port_in, dport=20))
Matus Fabiande886752016-12-07 03:38:19 -0800220 pkts.append(p)
221
222 # ICMP
223 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
Juraj Slobodacba69362017-12-19 02:09:32 +0100224 IP(src=in_if.remote_ip4, dst=dst_ip, ttl=ttl) /
Matus Fabiande886752016-12-07 03:38:19 -0800225 ICMP(id=self.icmp_id_in, type='echo-request'))
226 pkts.append(p)
227
228 return pkts
229
Matus Fabian428dc912017-06-21 06:15:18 -0700230 def compose_ip6(self, ip4, pref, plen):
231 """
232 Compose IPv4-embedded IPv6 addresses
233
234 :param ip4: IPv4 address
235 :param pref: IPv6 prefix
236 :param plen: IPv6 prefix length
237 :returns: IPv4-embedded IPv6 addresses
238 """
239 pref_n = list(socket.inet_pton(socket.AF_INET6, pref))
240 ip4_n = list(socket.inet_pton(socket.AF_INET, ip4))
241 if plen == 32:
242 pref_n[4] = ip4_n[0]
243 pref_n[5] = ip4_n[1]
244 pref_n[6] = ip4_n[2]
245 pref_n[7] = ip4_n[3]
246 elif plen == 40:
247 pref_n[5] = ip4_n[0]
248 pref_n[6] = ip4_n[1]
249 pref_n[7] = ip4_n[2]
250 pref_n[9] = ip4_n[3]
251 elif plen == 48:
252 pref_n[6] = ip4_n[0]
253 pref_n[7] = ip4_n[1]
254 pref_n[9] = ip4_n[2]
255 pref_n[10] = ip4_n[3]
256 elif plen == 56:
257 pref_n[7] = ip4_n[0]
258 pref_n[9] = ip4_n[1]
259 pref_n[10] = ip4_n[2]
260 pref_n[11] = ip4_n[3]
261 elif plen == 64:
262 pref_n[9] = ip4_n[0]
263 pref_n[10] = ip4_n[1]
264 pref_n[11] = ip4_n[2]
265 pref_n[12] = ip4_n[3]
266 elif plen == 96:
267 pref_n[12] = ip4_n[0]
268 pref_n[13] = ip4_n[1]
269 pref_n[14] = ip4_n[2]
270 pref_n[15] = ip4_n[3]
271 return socket.inet_ntop(socket.AF_INET6, ''.join(pref_n))
272
Juraj Slobodacba69362017-12-19 02:09:32 +0100273 def extract_ip4(self, ip6, plen):
274 """
275 Extract IPv4 address embedded in IPv6 addresses
276
277 :param ip6: IPv6 address
278 :param plen: IPv6 prefix length
279 :returns: extracted IPv4 address
280 """
281 ip6_n = list(socket.inet_pton(socket.AF_INET6, ip6))
282 ip4_n = [None] * 4
283 if plen == 32:
284 ip4_n[0] = ip6_n[4]
285 ip4_n[1] = ip6_n[5]
286 ip4_n[2] = ip6_n[6]
287 ip4_n[3] = ip6_n[7]
288 elif plen == 40:
289 ip4_n[0] = ip6_n[5]
290 ip4_n[1] = ip6_n[6]
291 ip4_n[2] = ip6_n[7]
292 ip4_n[3] = ip6_n[9]
293 elif plen == 48:
294 ip4_n[0] = ip6_n[6]
295 ip4_n[1] = ip6_n[7]
296 ip4_n[2] = ip6_n[9]
297 ip4_n[3] = ip6_n[10]
298 elif plen == 56:
299 ip4_n[0] = ip6_n[7]
300 ip4_n[1] = ip6_n[9]
301 ip4_n[2] = ip6_n[10]
302 ip4_n[3] = ip6_n[11]
303 elif plen == 64:
304 ip4_n[0] = ip6_n[9]
305 ip4_n[1] = ip6_n[10]
306 ip4_n[2] = ip6_n[11]
307 ip4_n[3] = ip6_n[12]
308 elif plen == 96:
309 ip4_n[0] = ip6_n[12]
310 ip4_n[1] = ip6_n[13]
311 ip4_n[2] = ip6_n[14]
312 ip4_n[3] = ip6_n[15]
313 return socket.inet_ntop(socket.AF_INET, ''.join(ip4_n))
314
Matus Fabian428dc912017-06-21 06:15:18 -0700315 def create_stream_in_ip6(self, in_if, out_if, hlim=64, pref=None, plen=0):
Matus Fabian06596c52017-06-06 04:53:28 -0700316 """
317 Create IPv6 packet stream for inside network
318
319 :param in_if: Inside interface
320 :param out_if: Outside interface
321 :param ttl: Hop Limit of generated packets
Matus Fabian428dc912017-06-21 06:15:18 -0700322 :param pref: NAT64 prefix
323 :param plen: NAT64 prefix length
Matus Fabian06596c52017-06-06 04:53:28 -0700324 """
325 pkts = []
Matus Fabian428dc912017-06-21 06:15:18 -0700326 if pref is None:
327 dst = ''.join(['64:ff9b::', out_if.remote_ip4])
328 else:
329 dst = self.compose_ip6(out_if.remote_ip4, pref, plen)
330
Matus Fabian06596c52017-06-06 04:53:28 -0700331 # TCP
332 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
333 IPv6(src=in_if.remote_ip6, dst=dst, hlim=hlim) /
334 TCP(sport=self.tcp_port_in, dport=20))
335 pkts.append(p)
336
337 # UDP
338 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
339 IPv6(src=in_if.remote_ip6, dst=dst, hlim=hlim) /
340 UDP(sport=self.udp_port_in, dport=20))
341 pkts.append(p)
342
343 # ICMP
344 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
345 IPv6(src=in_if.remote_ip6, dst=dst, hlim=hlim) /
346 ICMPv6EchoRequest(id=self.icmp_id_in))
347 pkts.append(p)
348
349 return pkts
350
Juraj Sloboda7b929792017-11-23 13:20:48 +0100351 def create_stream_out(self, out_if, dst_ip=None, ttl=64,
352 use_inside_ports=False):
Matus Fabiande886752016-12-07 03:38:19 -0800353 """
354 Create packet stream for outside network
355
356 :param out_if: Outside interface
Matus Fabian2ba92e32017-08-21 07:05:03 -0700357 :param dst_ip: Destination IP address (Default use global NAT address)
Juraj Slobodab33f4132017-02-08 23:54:21 -0800358 :param ttl: TTL of generated packets
Juraj Sloboda7b929792017-11-23 13:20:48 +0100359 :param use_inside_ports: Use inside NAT ports as destination ports
360 instead of outside ports
Matus Fabiande886752016-12-07 03:38:19 -0800361 """
362 if dst_ip is None:
Matus Fabian2ba92e32017-08-21 07:05:03 -0700363 dst_ip = self.nat_addr
Juraj Sloboda7b929792017-11-23 13:20:48 +0100364 if not use_inside_ports:
365 tcp_port = self.tcp_port_out
366 udp_port = self.udp_port_out
367 icmp_id = self.icmp_id_out
368 else:
369 tcp_port = self.tcp_port_in
370 udp_port = self.udp_port_in
371 icmp_id = self.icmp_id_in
Matus Fabiande886752016-12-07 03:38:19 -0800372 pkts = []
373 # TCP
374 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
Juraj Slobodab33f4132017-02-08 23:54:21 -0800375 IP(src=out_if.remote_ip4, dst=dst_ip, ttl=ttl) /
Juraj Sloboda7b929792017-11-23 13:20:48 +0100376 TCP(dport=tcp_port, sport=20))
Matus Fabiande886752016-12-07 03:38:19 -0800377 pkts.append(p)
378
379 # UDP
380 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
Juraj Slobodab33f4132017-02-08 23:54:21 -0800381 IP(src=out_if.remote_ip4, dst=dst_ip, ttl=ttl) /
Juraj Sloboda7b929792017-11-23 13:20:48 +0100382 UDP(dport=udp_port, sport=20))
Matus Fabiande886752016-12-07 03:38:19 -0800383 pkts.append(p)
384
385 # ICMP
386 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
Juraj Slobodab33f4132017-02-08 23:54:21 -0800387 IP(src=out_if.remote_ip4, dst=dst_ip, ttl=ttl) /
Juraj Sloboda7b929792017-11-23 13:20:48 +0100388 ICMP(id=icmp_id, type='echo-reply'))
Matus Fabiande886752016-12-07 03:38:19 -0800389 pkts.append(p)
390
391 return pkts
392
Juraj Slobodacba69362017-12-19 02:09:32 +0100393 def create_stream_out_ip6(self, out_if, src_ip, dst_ip, hl=64):
394 """
395 Create packet stream for outside network
396
397 :param out_if: Outside interface
398 :param dst_ip: Destination IP address (Default use global NAT address)
399 :param hl: HL of generated packets
400 """
401 pkts = []
402 # TCP
403 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
404 IPv6(src=src_ip, dst=dst_ip, hlim=hl) /
405 TCP(dport=self.tcp_port_out, sport=20))
406 pkts.append(p)
407
408 # UDP
409 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
410 IPv6(src=src_ip, dst=dst_ip, hlim=hl) /
411 UDP(dport=self.udp_port_out, sport=20))
412 pkts.append(p)
413
414 # ICMP
415 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
416 IPv6(src=src_ip, dst=dst_ip, hlim=hl) /
417 ICMPv6EchoReply(id=self.icmp_id_out))
418 pkts.append(p)
419
420 return pkts
421
Matus Fabiande886752016-12-07 03:38:19 -0800422 def verify_capture_out(self, capture, nat_ip=None, same_port=False,
Juraj Slobodacba69362017-12-19 02:09:32 +0100423 packet_num=3, dst_ip=None, is_ip6=False):
Matus Fabiande886752016-12-07 03:38:19 -0800424 """
425 Verify captured packets on outside network
426
427 :param capture: Captured packets
Matus Fabian2ba92e32017-08-21 07:05:03 -0700428 :param nat_ip: Translated IP address (Default use global NAT address)
Matus Fabiande886752016-12-07 03:38:19 -0800429 :param same_port: Sorce port number is not translated (Default False)
430 :param packet_num: Expected number of packets (Default 3)
Matus Fabian06596c52017-06-06 04:53:28 -0700431 :param dst_ip: Destination IP address (Default do not verify)
Juraj Slobodacba69362017-12-19 02:09:32 +0100432 :param is_ip6: If L3 protocol is IPv6 (Default False)
Matus Fabiande886752016-12-07 03:38:19 -0800433 """
Juraj Slobodacba69362017-12-19 02:09:32 +0100434 if is_ip6:
435 IP46 = IPv6
436 ICMP46 = ICMPv6EchoRequest
437 else:
438 IP46 = IP
439 ICMP46 = ICMP
Matus Fabiande886752016-12-07 03:38:19 -0800440 if nat_ip is None:
Matus Fabian2ba92e32017-08-21 07:05:03 -0700441 nat_ip = self.nat_addr
Matus Fabiande886752016-12-07 03:38:19 -0800442 self.assertEqual(packet_num, len(capture))
443 for packet in capture:
444 try:
Juraj Slobodacba69362017-12-19 02:09:32 +0100445 if not is_ip6:
Klement Sekerad81ae412018-05-16 10:52:54 +0200446 self.assert_packet_checksums_valid(packet)
Juraj Slobodacba69362017-12-19 02:09:32 +0100447 self.assertEqual(packet[IP46].src, nat_ip)
Matus Fabian06596c52017-06-06 04:53:28 -0700448 if dst_ip is not None:
Juraj Slobodacba69362017-12-19 02:09:32 +0100449 self.assertEqual(packet[IP46].dst, dst_ip)
Matus Fabiande886752016-12-07 03:38:19 -0800450 if packet.haslayer(TCP):
451 if same_port:
452 self.assertEqual(packet[TCP].sport, self.tcp_port_in)
453 else:
Klement Sekerada505f62017-01-04 12:58:53 +0100454 self.assertNotEqual(
455 packet[TCP].sport, self.tcp_port_in)
Matus Fabiande886752016-12-07 03:38:19 -0800456 self.tcp_port_out = packet[TCP].sport
Klement Sekerad81ae412018-05-16 10:52:54 +0200457 self.assert_packet_checksums_valid(packet)
Matus Fabiande886752016-12-07 03:38:19 -0800458 elif packet.haslayer(UDP):
459 if same_port:
460 self.assertEqual(packet[UDP].sport, self.udp_port_in)
461 else:
Klement Sekerada505f62017-01-04 12:58:53 +0100462 self.assertNotEqual(
463 packet[UDP].sport, self.udp_port_in)
Matus Fabiande886752016-12-07 03:38:19 -0800464 self.udp_port_out = packet[UDP].sport
465 else:
466 if same_port:
Juraj Slobodacba69362017-12-19 02:09:32 +0100467 self.assertEqual(packet[ICMP46].id, self.icmp_id_in)
Matus Fabiande886752016-12-07 03:38:19 -0800468 else:
Juraj Slobodacba69362017-12-19 02:09:32 +0100469 self.assertNotEqual(packet[ICMP46].id, self.icmp_id_in)
470 self.icmp_id_out = packet[ICMP46].id
Klement Sekerad81ae412018-05-16 10:52:54 +0200471 self.assert_packet_checksums_valid(packet)
Matus Fabiande886752016-12-07 03:38:19 -0800472 except:
Klement Sekera9225dee2016-12-12 08:36:58 +0100473 self.logger.error(ppp("Unexpected or invalid packet "
474 "(outside network):", packet))
Matus Fabiande886752016-12-07 03:38:19 -0800475 raise
476
Juraj Slobodacba69362017-12-19 02:09:32 +0100477 def verify_capture_out_ip6(self, capture, nat_ip, same_port=False,
478 packet_num=3, dst_ip=None):
479 """
480 Verify captured packets on outside network
481
482 :param capture: Captured packets
483 :param nat_ip: Translated IP address
484 :param same_port: Sorce port number is not translated (Default False)
485 :param packet_num: Expected number of packets (Default 3)
486 :param dst_ip: Destination IP address (Default do not verify)
487 """
488 return self.verify_capture_out(capture, nat_ip, same_port, packet_num,
489 dst_ip, True)
490
Matus Fabiande886752016-12-07 03:38:19 -0800491 def verify_capture_in(self, capture, in_if, packet_num=3):
492 """
493 Verify captured packets on inside network
494
495 :param capture: Captured packets
496 :param in_if: Inside interface
497 :param packet_num: Expected number of packets (Default 3)
498 """
499 self.assertEqual(packet_num, len(capture))
500 for packet in capture:
501 try:
Klement Sekerad81ae412018-05-16 10:52:54 +0200502 self.assert_packet_checksums_valid(packet)
Matus Fabiande886752016-12-07 03:38:19 -0800503 self.assertEqual(packet[IP].dst, in_if.remote_ip4)
504 if packet.haslayer(TCP):
505 self.assertEqual(packet[TCP].dport, self.tcp_port_in)
506 elif packet.haslayer(UDP):
507 self.assertEqual(packet[UDP].dport, self.udp_port_in)
508 else:
509 self.assertEqual(packet[ICMP].id, self.icmp_id_in)
510 except:
Klement Sekera9225dee2016-12-12 08:36:58 +0100511 self.logger.error(ppp("Unexpected or invalid packet "
512 "(inside network):", packet))
Matus Fabiande886752016-12-07 03:38:19 -0800513 raise
514
Matus Fabian06596c52017-06-06 04:53:28 -0700515 def verify_capture_in_ip6(self, capture, src_ip, dst_ip, packet_num=3):
516 """
517 Verify captured IPv6 packets on inside network
518
519 :param capture: Captured packets
520 :param src_ip: Source IP
521 :param dst_ip: Destination IP address
522 :param packet_num: Expected number of packets (Default 3)
523 """
524 self.assertEqual(packet_num, len(capture))
525 for packet in capture:
526 try:
527 self.assertEqual(packet[IPv6].src, src_ip)
528 self.assertEqual(packet[IPv6].dst, dst_ip)
Klement Sekerad81ae412018-05-16 10:52:54 +0200529 self.assert_packet_checksums_valid(packet)
Matus Fabian06596c52017-06-06 04:53:28 -0700530 if packet.haslayer(TCP):
531 self.assertEqual(packet[TCP].dport, self.tcp_port_in)
532 elif packet.haslayer(UDP):
533 self.assertEqual(packet[UDP].dport, self.udp_port_in)
534 else:
535 self.assertEqual(packet[ICMPv6EchoReply].id,
536 self.icmp_id_in)
537 except:
538 self.logger.error(ppp("Unexpected or invalid packet "
539 "(inside network):", packet))
540 raise
541
Matus Fabian675a69c2017-01-18 01:46:01 -0800542 def verify_capture_no_translation(self, capture, ingress_if, egress_if):
543 """
544 Verify captured packet that don't have to be translated
545
546 :param capture: Captured packets
547 :param ingress_if: Ingress interface
548 :param egress_if: Egress interface
549 """
550 for packet in capture:
551 try:
552 self.assertEqual(packet[IP].src, ingress_if.remote_ip4)
553 self.assertEqual(packet[IP].dst, egress_if.remote_ip4)
554 if packet.haslayer(TCP):
555 self.assertEqual(packet[TCP].sport, self.tcp_port_in)
556 elif packet.haslayer(UDP):
557 self.assertEqual(packet[UDP].sport, self.udp_port_in)
558 else:
559 self.assertEqual(packet[ICMP].id, self.icmp_id_in)
560 except:
561 self.logger.error(ppp("Unexpected or invalid packet "
562 "(inside network):", packet))
563 raise
564
Juraj Slobodab33f4132017-02-08 23:54:21 -0800565 def verify_capture_out_with_icmp_errors(self, capture, src_ip=None,
566 packet_num=3, icmp_type=11):
567 """
568 Verify captured packets with ICMP errors on outside network
569
570 :param capture: Captured packets
571 :param src_ip: Translated IP address or IP address of VPP
Matus Fabian2ba92e32017-08-21 07:05:03 -0700572 (Default use global NAT address)
Juraj Slobodab33f4132017-02-08 23:54:21 -0800573 :param packet_num: Expected number of packets (Default 3)
574 :param icmp_type: Type of error ICMP packet
575 we are expecting (Default 11)
576 """
577 if src_ip is None:
Matus Fabian2ba92e32017-08-21 07:05:03 -0700578 src_ip = self.nat_addr
Juraj Slobodab33f4132017-02-08 23:54:21 -0800579 self.assertEqual(packet_num, len(capture))
580 for packet in capture:
581 try:
582 self.assertEqual(packet[IP].src, src_ip)
583 self.assertTrue(packet.haslayer(ICMP))
584 icmp = packet[ICMP]
585 self.assertEqual(icmp.type, icmp_type)
586 self.assertTrue(icmp.haslayer(IPerror))
587 inner_ip = icmp[IPerror]
588 if inner_ip.haslayer(TCPerror):
589 self.assertEqual(inner_ip[TCPerror].dport,
590 self.tcp_port_out)
591 elif inner_ip.haslayer(UDPerror):
592 self.assertEqual(inner_ip[UDPerror].dport,
593 self.udp_port_out)
594 else:
595 self.assertEqual(inner_ip[ICMPerror].id, self.icmp_id_out)
596 except:
597 self.logger.error(ppp("Unexpected or invalid packet "
598 "(outside network):", packet))
599 raise
600
601 def verify_capture_in_with_icmp_errors(self, capture, in_if, packet_num=3,
602 icmp_type=11):
603 """
604 Verify captured packets with ICMP errors on inside network
605
606 :param capture: Captured packets
607 :param in_if: Inside interface
608 :param packet_num: Expected number of packets (Default 3)
609 :param icmp_type: Type of error ICMP packet
610 we are expecting (Default 11)
611 """
612 self.assertEqual(packet_num, len(capture))
613 for packet in capture:
614 try:
615 self.assertEqual(packet[IP].dst, in_if.remote_ip4)
616 self.assertTrue(packet.haslayer(ICMP))
617 icmp = packet[ICMP]
618 self.assertEqual(icmp.type, icmp_type)
619 self.assertTrue(icmp.haslayer(IPerror))
620 inner_ip = icmp[IPerror]
621 if inner_ip.haslayer(TCPerror):
622 self.assertEqual(inner_ip[TCPerror].sport,
623 self.tcp_port_in)
624 elif inner_ip.haslayer(UDPerror):
625 self.assertEqual(inner_ip[UDPerror].sport,
626 self.udp_port_in)
627 else:
628 self.assertEqual(inner_ip[ICMPerror].id, self.icmp_id_in)
629 except:
630 self.logger.error(ppp("Unexpected or invalid packet "
631 "(inside network):", packet))
632 raise
633
Matus Fabianefcd1e92017-08-15 06:59:19 -0700634 def create_stream_frag(self, src_if, dst, sport, dport, data):
635 """
636 Create fragmented packet stream
637
638 :param src_if: Source interface
639 :param dst: Destination IPv4 address
640 :param sport: Source TCP port
641 :param dport: Destination TCP port
642 :param data: Payload data
643 :returns: Fragmets
644 """
645 id = random.randint(0, 65535)
646 p = (IP(src=src_if.remote_ip4, dst=dst) /
647 TCP(sport=sport, dport=dport) /
648 Raw(data))
649 p = p.__class__(str(p))
650 chksum = p['TCP'].chksum
651 pkts = []
652 p = (Ether(src=src_if.remote_mac, dst=src_if.local_mac) /
653 IP(src=src_if.remote_ip4, dst=dst, flags="MF", frag=0, id=id) /
654 TCP(sport=sport, dport=dport, chksum=chksum) /
655 Raw(data[0:4]))
656 pkts.append(p)
657 p = (Ether(src=src_if.remote_mac, dst=src_if.local_mac) /
658 IP(src=src_if.remote_ip4, dst=dst, flags="MF", frag=3, id=id,
659 proto=IP_PROTOS.tcp) /
660 Raw(data[4:20]))
661 pkts.append(p)
662 p = (Ether(src=src_if.remote_mac, dst=src_if.local_mac) /
663 IP(src=src_if.remote_ip4, dst=dst, frag=5, proto=IP_PROTOS.tcp,
664 id=id) /
665 Raw(data[20:]))
666 pkts.append(p)
667 return pkts
668
669 def create_stream_frag_ip6(self, src_if, dst, sport, dport, data,
670 pref=None, plen=0, frag_size=128):
671 """
672 Create fragmented packet stream
673
674 :param src_if: Source interface
675 :param dst: Destination IPv4 address
676 :param sport: Source TCP port
677 :param dport: Destination TCP port
678 :param data: Payload data
679 :param pref: NAT64 prefix
680 :param plen: NAT64 prefix length
681 :param fragsize: size of fragments
682 :returns: Fragmets
683 """
684 if pref is None:
685 dst_ip6 = ''.join(['64:ff9b::', dst])
686 else:
687 dst_ip6 = self.compose_ip6(dst, pref, plen)
688
689 p = (Ether(dst=src_if.local_mac, src=src_if.remote_mac) /
690 IPv6(src=src_if.remote_ip6, dst=dst_ip6) /
691 IPv6ExtHdrFragment(id=random.randint(0, 65535)) /
692 TCP(sport=sport, dport=dport) /
693 Raw(data))
694
695 return fragment6(p, frag_size)
696
697 def reass_frags_and_verify(self, frags, src, dst):
698 """
699 Reassemble and verify fragmented packet
700
701 :param frags: Captured fragments
702 :param src: Source IPv4 address to verify
703 :param dst: Destination IPv4 address to verify
704
705 :returns: Reassembled IPv4 packet
706 """
707 buffer = StringIO.StringIO()
708 for p in frags:
709 self.assertEqual(p[IP].src, src)
710 self.assertEqual(p[IP].dst, dst)
Klement Sekerad81ae412018-05-16 10:52:54 +0200711 self.assert_ip_checksum_valid(p)
Matus Fabianefcd1e92017-08-15 06:59:19 -0700712 buffer.seek(p[IP].frag * 8)
713 buffer.write(p[IP].payload)
714 ip = frags[0].getlayer(IP)
715 ip = IP(src=frags[0][IP].src, dst=frags[0][IP].dst,
716 proto=frags[0][IP].proto)
717 if ip.proto == IP_PROTOS.tcp:
718 p = (ip / TCP(buffer.getvalue()))
Klement Sekerad81ae412018-05-16 10:52:54 +0200719 self.assert_tcp_checksum_valid(p)
Matus Fabianefcd1e92017-08-15 06:59:19 -0700720 elif ip.proto == IP_PROTOS.udp:
721 p = (ip / UDP(buffer.getvalue()))
722 return p
723
724 def reass_frags_and_verify_ip6(self, frags, src, dst):
725 """
726 Reassemble and verify fragmented packet
727
728 :param frags: Captured fragments
729 :param src: Source IPv6 address to verify
730 :param dst: Destination IPv6 address to verify
731
732 :returns: Reassembled IPv6 packet
733 """
734 buffer = StringIO.StringIO()
735 for p in frags:
736 self.assertEqual(p[IPv6].src, src)
737 self.assertEqual(p[IPv6].dst, dst)
738 buffer.seek(p[IPv6ExtHdrFragment].offset * 8)
739 buffer.write(p[IPv6ExtHdrFragment].payload)
740 ip = IPv6(src=frags[0][IPv6].src, dst=frags[0][IPv6].dst,
741 nh=frags[0][IPv6ExtHdrFragment].nh)
742 if ip.nh == IP_PROTOS.tcp:
743 p = (ip / TCP(buffer.getvalue()))
Matus Fabianefcd1e92017-08-15 06:59:19 -0700744 elif ip.nh == IP_PROTOS.udp:
745 p = (ip / UDP(buffer.getvalue()))
Klement Sekerad81ae412018-05-16 10:52:54 +0200746 self.assert_packet_checksums_valid(p)
Matus Fabianefcd1e92017-08-15 06:59:19 -0700747 return p
748
Matus Fabianebdf1902018-05-04 03:57:42 -0700749 def initiate_tcp_session(self, in_if, out_if):
750 """
751 Initiates TCP session
752
753 :param in_if: Inside interface
754 :param out_if: Outside interface
755 """
756 try:
757 # SYN packet in->out
758 p = (Ether(src=in_if.remote_mac, dst=in_if.local_mac) /
759 IP(src=in_if.remote_ip4, dst=out_if.remote_ip4) /
760 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
761 flags="S"))
762 in_if.add_stream(p)
763 self.pg_enable_capture(self.pg_interfaces)
764 self.pg_start()
765 capture = out_if.get_capture(1)
766 p = capture[0]
767 self.tcp_port_out = p[TCP].sport
768
769 # SYN + ACK packet out->in
770 p = (Ether(src=out_if.remote_mac, dst=out_if.local_mac) /
771 IP(src=out_if.remote_ip4, dst=self.nat_addr) /
772 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
773 flags="SA"))
774 out_if.add_stream(p)
775 self.pg_enable_capture(self.pg_interfaces)
776 self.pg_start()
777 in_if.get_capture(1)
778
779 # ACK packet in->out
780 p = (Ether(src=in_if.remote_mac, dst=in_if.local_mac) /
781 IP(src=in_if.remote_ip4, dst=out_if.remote_ip4) /
782 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
783 flags="A"))
784 in_if.add_stream(p)
785 self.pg_enable_capture(self.pg_interfaces)
786 self.pg_start()
787 out_if.get_capture(1)
788
789 except:
790 self.logger.error("TCP 3 way handshake failed")
791 raise
792
Matus Fabianeea28d72017-01-13 04:15:54 -0800793 def verify_ipfix_nat44_ses(self, data):
794 """
795 Verify IPFIX NAT44 session create/delete event
796
797 :param data: Decoded IPFIX data records
798 """
799 nat44_ses_create_num = 0
800 nat44_ses_delete_num = 0
801 self.assertEqual(6, len(data))
802 for record in data:
803 # natEvent
804 self.assertIn(ord(record[230]), [4, 5])
805 if ord(record[230]) == 4:
806 nat44_ses_create_num += 1
807 else:
808 nat44_ses_delete_num += 1
809 # sourceIPv4Address
810 self.assertEqual(self.pg0.remote_ip4n, record[8])
811 # postNATSourceIPv4Address
Matus Fabian2ba92e32017-08-21 07:05:03 -0700812 self.assertEqual(socket.inet_pton(socket.AF_INET, self.nat_addr),
Matus Fabianeea28d72017-01-13 04:15:54 -0800813 record[225])
814 # ingressVRFID
815 self.assertEqual(struct.pack("!I", 0), record[234])
816 # protocolIdentifier/sourceTransportPort/postNAPTSourceTransportPort
817 if IP_PROTOS.icmp == ord(record[4]):
818 self.assertEqual(struct.pack("!H", self.icmp_id_in), record[7])
819 self.assertEqual(struct.pack("!H", self.icmp_id_out),
820 record[227])
821 elif IP_PROTOS.tcp == ord(record[4]):
822 self.assertEqual(struct.pack("!H", self.tcp_port_in),
823 record[7])
824 self.assertEqual(struct.pack("!H", self.tcp_port_out),
825 record[227])
826 elif IP_PROTOS.udp == ord(record[4]):
827 self.assertEqual(struct.pack("!H", self.udp_port_in),
828 record[7])
829 self.assertEqual(struct.pack("!H", self.udp_port_out),
830 record[227])
831 else:
832 self.fail("Invalid protocol")
833 self.assertEqual(3, nat44_ses_create_num)
834 self.assertEqual(3, nat44_ses_delete_num)
835
836 def verify_ipfix_addr_exhausted(self, data):
837 """
838 Verify IPFIX NAT addresses event
839
840 :param data: Decoded IPFIX data records
841 """
842 self.assertEqual(1, len(data))
843 record = data[0]
844 # natEvent
845 self.assertEqual(ord(record[230]), 3)
846 # natPoolID
847 self.assertEqual(struct.pack("!I", 0), record[283])
848
Matus Fabiana431ad12018-01-04 04:03:14 -0800849 def verify_ipfix_max_sessions(self, data, limit):
850 """
851 Verify IPFIX maximum session entries exceeded event
852
853 :param data: Decoded IPFIX data records
854 :param limit: Number of maximum session entries that can be created.
855 """
856 self.assertEqual(1, len(data))
857 record = data[0]
858 # natEvent
859 self.assertEqual(ord(record[230]), 13)
860 # natQuotaExceededEvent
861 self.assertEqual(struct.pack("I", 1), record[466])
862 # maxSessionEntries
863 self.assertEqual(struct.pack("I", limit), record[471])
864
865 def verify_ipfix_max_bibs(self, data, limit):
866 """
867 Verify IPFIX maximum BIB entries exceeded event
868
869 :param data: Decoded IPFIX data records
870 :param limit: Number of maximum BIB entries that can be created.
871 """
872 self.assertEqual(1, len(data))
873 record = data[0]
874 # natEvent
875 self.assertEqual(ord(record[230]), 13)
876 # natQuotaExceededEvent
877 self.assertEqual(struct.pack("I", 2), record[466])
878 # maxBIBEntries
879 self.assertEqual(struct.pack("I", limit), record[472])
880
881 def verify_ipfix_max_fragments_ip6(self, data, limit, src_addr):
882 """
883 Verify IPFIX maximum IPv6 fragments pending reassembly exceeded event
884
885 :param data: Decoded IPFIX data records
886 :param limit: Number of maximum fragments pending reassembly
887 :param src_addr: IPv6 source address
888 """
889 self.assertEqual(1, len(data))
890 record = data[0]
891 # natEvent
892 self.assertEqual(ord(record[230]), 13)
893 # natQuotaExceededEvent
894 self.assertEqual(struct.pack("I", 5), record[466])
895 # maxFragmentsPendingReassembly
896 self.assertEqual(struct.pack("I", limit), record[475])
897 # sourceIPv6Address
898 self.assertEqual(src_addr, record[27])
899
900 def verify_ipfix_max_fragments_ip4(self, data, limit, src_addr):
901 """
902 Verify IPFIX maximum IPv4 fragments pending reassembly exceeded event
903
904 :param data: Decoded IPFIX data records
905 :param limit: Number of maximum fragments pending reassembly
906 :param src_addr: IPv4 source address
907 """
908 self.assertEqual(1, len(data))
909 record = data[0]
910 # natEvent
911 self.assertEqual(ord(record[230]), 13)
912 # natQuotaExceededEvent
913 self.assertEqual(struct.pack("I", 5), record[466])
914 # maxFragmentsPendingReassembly
915 self.assertEqual(struct.pack("I", limit), record[475])
916 # sourceIPv4Address
917 self.assertEqual(src_addr, record[8])
918
919 def verify_ipfix_bib(self, data, is_create, src_addr):
920 """
921 Verify IPFIX NAT64 BIB create and delete events
922
923 :param data: Decoded IPFIX data records
924 :param is_create: Create event if nonzero value otherwise delete event
925 :param src_addr: IPv6 source address
926 """
927 self.assertEqual(1, len(data))
928 record = data[0]
929 # natEvent
930 if is_create:
931 self.assertEqual(ord(record[230]), 10)
932 else:
933 self.assertEqual(ord(record[230]), 11)
934 # sourceIPv6Address
935 self.assertEqual(src_addr, record[27])
936 # postNATSourceIPv4Address
937 self.assertEqual(self.nat_addr_n, record[225])
938 # protocolIdentifier
939 self.assertEqual(IP_PROTOS.tcp, ord(record[4]))
940 # ingressVRFID
941 self.assertEqual(struct.pack("!I", 0), record[234])
942 # sourceTransportPort
943 self.assertEqual(struct.pack("!H", self.tcp_port_in), record[7])
944 # postNAPTSourceTransportPort
945 self.assertEqual(struct.pack("!H", self.tcp_port_out), record[227])
946
947 def verify_ipfix_nat64_ses(self, data, is_create, src_addr, dst_addr,
948 dst_port):
949 """
950 Verify IPFIX NAT64 session create and delete events
951
952 :param data: Decoded IPFIX data records
953 :param is_create: Create event if nonzero value otherwise delete event
954 :param src_addr: IPv6 source address
955 :param dst_addr: IPv4 destination address
956 :param dst_port: destination TCP port
957 """
958 self.assertEqual(1, len(data))
959 record = data[0]
960 # natEvent
961 if is_create:
962 self.assertEqual(ord(record[230]), 6)
963 else:
964 self.assertEqual(ord(record[230]), 7)
965 # sourceIPv6Address
966 self.assertEqual(src_addr, record[27])
967 # destinationIPv6Address
968 self.assertEqual(socket.inet_pton(socket.AF_INET6,
969 self.compose_ip6(dst_addr,
970 '64:ff9b::',
971 96)),
972 record[28])
973 # postNATSourceIPv4Address
974 self.assertEqual(self.nat_addr_n, record[225])
975 # postNATDestinationIPv4Address
976 self.assertEqual(socket.inet_pton(socket.AF_INET, dst_addr),
977 record[226])
978 # protocolIdentifier
979 self.assertEqual(IP_PROTOS.tcp, ord(record[4]))
980 # ingressVRFID
981 self.assertEqual(struct.pack("!I", 0), record[234])
982 # sourceTransportPort
983 self.assertEqual(struct.pack("!H", self.tcp_port_in), record[7])
984 # postNAPTSourceTransportPort
985 self.assertEqual(struct.pack("!H", self.tcp_port_out), record[227])
986 # destinationTransportPort
987 self.assertEqual(struct.pack("!H", dst_port), record[11])
988 # postNAPTDestinationTransportPort
989 self.assertEqual(struct.pack("!H", dst_port), record[228])
990
Martin Gálikd7f75cd2017-03-27 06:02:47 -0700991
Matus Fabian2ba92e32017-08-21 07:05:03 -0700992class TestNAT44(MethodHolder):
993 """ NAT44 Test Cases """
Martin Gálikd7f75cd2017-03-27 06:02:47 -0700994
995 @classmethod
996 def setUpClass(cls):
Matus Fabian2ba92e32017-08-21 07:05:03 -0700997 super(TestNAT44, cls).setUpClass()
Matus Fabian229c1aa2018-05-28 04:09:52 -0700998 cls.vapi.cli("set log class nat level debug")
Martin Gálikd7f75cd2017-03-27 06:02:47 -0700999
1000 try:
1001 cls.tcp_port_in = 6303
1002 cls.tcp_port_out = 6303
1003 cls.udp_port_in = 6304
1004 cls.udp_port_out = 6304
1005 cls.icmp_id_in = 6305
1006 cls.icmp_id_out = 6305
Matus Fabian2ba92e32017-08-21 07:05:03 -07001007 cls.nat_addr = '10.0.0.3'
Juraj Sloboda7b929792017-11-23 13:20:48 +01001008 cls.nat_addr_n = socket.inet_pton(socket.AF_INET, cls.nat_addr)
Matus Fabian6631e9c2017-05-24 01:52:20 -07001009 cls.ipfix_src_port = 4739
1010 cls.ipfix_domain_id = 1
Matus Fabianebdf1902018-05-04 03:57:42 -07001011 cls.tcp_external_port = 80
Martin Gálikd7f75cd2017-03-27 06:02:47 -07001012
Matus Fabian36ea2d62017-10-24 04:13:49 -07001013 cls.create_pg_interfaces(range(10))
Martin Gálikd7f75cd2017-03-27 06:02:47 -07001014 cls.interfaces = list(cls.pg_interfaces[0:4])
1015
1016 for i in cls.interfaces:
1017 i.admin_up()
1018 i.config_ip4()
1019 i.resolve_arp()
1020
Matus Fabian6fa74c62017-06-05 05:55:48 -07001021 cls.pg0.generate_remote_hosts(3)
Martin Gálikd7f75cd2017-03-27 06:02:47 -07001022 cls.pg0.configure_ipv4_neighbors()
1023
Juraj Sloboda1e5c07d2018-04-10 13:51:54 +02001024 cls.pg1.generate_remote_hosts(1)
1025 cls.pg1.configure_ipv4_neighbors()
1026
Martin Gálikd7f75cd2017-03-27 06:02:47 -07001027 cls.overlapping_interfaces = list(list(cls.pg_interfaces[4:7]))
Neale Ranns15002542017-09-10 04:39:11 -07001028 cls.vapi.ip_table_add_del(10, is_add=1)
1029 cls.vapi.ip_table_add_del(20, is_add=1)
Martin Gálikd7f75cd2017-03-27 06:02:47 -07001030
1031 cls.pg4._local_ip4 = "172.16.255.1"
1032 cls.pg4._local_ip4n = socket.inet_pton(socket.AF_INET, i.local_ip4)
1033 cls.pg4._remote_hosts[0]._ip4 = "172.16.255.2"
1034 cls.pg4.set_table_ip4(10)
Matus Fabian69126282017-08-14 23:39:58 -07001035 cls.pg5._local_ip4 = "172.17.255.3"
Martin Gálikd7f75cd2017-03-27 06:02:47 -07001036 cls.pg5._local_ip4n = socket.inet_pton(socket.AF_INET, i.local_ip4)
Matus Fabian69126282017-08-14 23:39:58 -07001037 cls.pg5._remote_hosts[0]._ip4 = "172.17.255.4"
Martin Gálikd7f75cd2017-03-27 06:02:47 -07001038 cls.pg5.set_table_ip4(10)
1039 cls.pg6._local_ip4 = "172.16.255.1"
1040 cls.pg6._local_ip4n = socket.inet_pton(socket.AF_INET, i.local_ip4)
1041 cls.pg6._remote_hosts[0]._ip4 = "172.16.255.2"
1042 cls.pg6.set_table_ip4(20)
1043 for i in cls.overlapping_interfaces:
1044 i.config_ip4()
1045 i.admin_up()
1046 i.resolve_arp()
1047
1048 cls.pg7.admin_up()
Martin Gálik406eb1d2017-05-04 04:35:04 -07001049 cls.pg8.admin_up()
Martin Gálikd7f75cd2017-03-27 06:02:47 -07001050
Matus Fabian36ea2d62017-10-24 04:13:49 -07001051 cls.pg9.generate_remote_hosts(2)
1052 cls.pg9.config_ip4()
1053 ip_addr_n = socket.inet_pton(socket.AF_INET, "10.0.0.1")
1054 cls.vapi.sw_interface_add_del_address(cls.pg9.sw_if_index,
1055 ip_addr_n,
1056 24)
1057 cls.pg9.admin_up()
1058 cls.pg9.resolve_arp()
1059 cls.pg9._remote_hosts[1]._ip4 = cls.pg9._remote_hosts[0]._ip4
1060 cls.pg4._remote_ip4 = cls.pg9._remote_hosts[0]._ip4 = "10.0.0.2"
1061 cls.pg9.resolve_arp()
1062
Martin Gálikd7f75cd2017-03-27 06:02:47 -07001063 except Exception:
Matus Fabian2ba92e32017-08-21 07:05:03 -07001064 super(TestNAT44, cls).tearDownClass()
Martin Gálikd7f75cd2017-03-27 06:02:47 -07001065 raise
1066
Matus Fabiande886752016-12-07 03:38:19 -08001067 def test_dynamic(self):
Matus Fabian2ba92e32017-08-21 07:05:03 -07001068 """ NAT44 dynamic translation test """
Matus Fabiande886752016-12-07 03:38:19 -08001069
Matus Fabian2ba92e32017-08-21 07:05:03 -07001070 self.nat44_add_address(self.nat_addr)
1071 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
1072 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
1073 is_inside=0)
Matus Fabiande886752016-12-07 03:38:19 -08001074
1075 # in2out
1076 pkts = self.create_stream_in(self.pg0, self.pg1)
1077 self.pg0.add_stream(pkts)
1078 self.pg_enable_capture(self.pg_interfaces)
1079 self.pg_start()
Klement Sekeradab231a2016-12-21 08:50:14 +01001080 capture = self.pg1.get_capture(len(pkts))
Matus Fabiande886752016-12-07 03:38:19 -08001081 self.verify_capture_out(capture)
1082
1083 # out2in
1084 pkts = self.create_stream_out(self.pg1)
1085 self.pg1.add_stream(pkts)
1086 self.pg_enable_capture(self.pg_interfaces)
1087 self.pg_start()
Klement Sekeradab231a2016-12-21 08:50:14 +01001088 capture = self.pg0.get_capture(len(pkts))
Matus Fabiande886752016-12-07 03:38:19 -08001089 self.verify_capture_in(capture, self.pg0)
1090
Juraj Slobodab33f4132017-02-08 23:54:21 -08001091 def test_dynamic_icmp_errors_in2out_ttl_1(self):
Matus Fabian2ba92e32017-08-21 07:05:03 -07001092 """ NAT44 handling of client packets with TTL=1 """
Juraj Slobodab33f4132017-02-08 23:54:21 -08001093
Matus Fabian2ba92e32017-08-21 07:05:03 -07001094 self.nat44_add_address(self.nat_addr)
1095 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
1096 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
1097 is_inside=0)
Juraj Slobodab33f4132017-02-08 23:54:21 -08001098
1099 # Client side - generate traffic
1100 pkts = self.create_stream_in(self.pg0, self.pg1, ttl=1)
1101 self.pg0.add_stream(pkts)
1102 self.pg_enable_capture(self.pg_interfaces)
1103 self.pg_start()
1104
1105 # Client side - verify ICMP type 11 packets
1106 capture = self.pg0.get_capture(len(pkts))
1107 self.verify_capture_in_with_icmp_errors(capture, self.pg0)
1108
1109 def test_dynamic_icmp_errors_out2in_ttl_1(self):
Matus Fabian2ba92e32017-08-21 07:05:03 -07001110 """ NAT44 handling of server packets with TTL=1 """
Juraj Slobodab33f4132017-02-08 23:54:21 -08001111
Matus Fabian2ba92e32017-08-21 07:05:03 -07001112 self.nat44_add_address(self.nat_addr)
1113 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
1114 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
1115 is_inside=0)
Juraj Slobodab33f4132017-02-08 23:54:21 -08001116
1117 # Client side - create sessions
1118 pkts = self.create_stream_in(self.pg0, self.pg1)
1119 self.pg0.add_stream(pkts)
1120 self.pg_enable_capture(self.pg_interfaces)
1121 self.pg_start()
1122
1123 # Server side - generate traffic
1124 capture = self.pg1.get_capture(len(pkts))
1125 self.verify_capture_out(capture)
1126 pkts = self.create_stream_out(self.pg1, ttl=1)
1127 self.pg1.add_stream(pkts)
1128 self.pg_enable_capture(self.pg_interfaces)
1129 self.pg_start()
1130
1131 # Server side - verify ICMP type 11 packets
1132 capture = self.pg1.get_capture(len(pkts))
1133 self.verify_capture_out_with_icmp_errors(capture,
1134 src_ip=self.pg1.local_ip4)
1135
1136 def test_dynamic_icmp_errors_in2out_ttl_2(self):
Matus Fabian2ba92e32017-08-21 07:05:03 -07001137 """ NAT44 handling of error responses to client packets with TTL=2 """
Juraj Slobodab33f4132017-02-08 23:54:21 -08001138
Matus Fabian2ba92e32017-08-21 07:05:03 -07001139 self.nat44_add_address(self.nat_addr)
1140 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
1141 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
1142 is_inside=0)
Juraj Slobodab33f4132017-02-08 23:54:21 -08001143
1144 # Client side - generate traffic
1145 pkts = self.create_stream_in(self.pg0, self.pg1, ttl=2)
1146 self.pg0.add_stream(pkts)
1147 self.pg_enable_capture(self.pg_interfaces)
1148 self.pg_start()
1149
1150 # Server side - simulate ICMP type 11 response
1151 capture = self.pg1.get_capture(len(pkts))
1152 pkts = [Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
Matus Fabian2ba92e32017-08-21 07:05:03 -07001153 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
Juraj Slobodab33f4132017-02-08 23:54:21 -08001154 ICMP(type=11) / packet[IP] for packet in capture]
1155 self.pg1.add_stream(pkts)
1156 self.pg_enable_capture(self.pg_interfaces)
1157 self.pg_start()
1158
1159 # Client side - verify ICMP type 11 packets
1160 capture = self.pg0.get_capture(len(pkts))
1161 self.verify_capture_in_with_icmp_errors(capture, self.pg0)
1162
1163 def test_dynamic_icmp_errors_out2in_ttl_2(self):
Matus Fabian2ba92e32017-08-21 07:05:03 -07001164 """ NAT44 handling of error responses to server packets with TTL=2 """
Juraj Slobodab33f4132017-02-08 23:54:21 -08001165
Matus Fabian2ba92e32017-08-21 07:05:03 -07001166 self.nat44_add_address(self.nat_addr)
1167 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
1168 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
1169 is_inside=0)
Juraj Slobodab33f4132017-02-08 23:54:21 -08001170
1171 # Client side - create sessions
1172 pkts = self.create_stream_in(self.pg0, self.pg1)
1173 self.pg0.add_stream(pkts)
1174 self.pg_enable_capture(self.pg_interfaces)
1175 self.pg_start()
1176
1177 # Server side - generate traffic
1178 capture = self.pg1.get_capture(len(pkts))
1179 self.verify_capture_out(capture)
1180 pkts = self.create_stream_out(self.pg1, ttl=2)
1181 self.pg1.add_stream(pkts)
1182 self.pg_enable_capture(self.pg_interfaces)
1183 self.pg_start()
1184
1185 # Client side - simulate ICMP type 11 response
1186 capture = self.pg0.get_capture(len(pkts))
1187 pkts = [Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
1188 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
1189 ICMP(type=11) / packet[IP] for packet in capture]
1190 self.pg0.add_stream(pkts)
1191 self.pg_enable_capture(self.pg_interfaces)
1192 self.pg_start()
1193
1194 # Server side - verify ICMP type 11 packets
1195 capture = self.pg1.get_capture(len(pkts))
1196 self.verify_capture_out_with_icmp_errors(capture)
1197
Juraj Sloboda665e4822017-02-16 17:17:19 -08001198 def test_ping_out_interface_from_outside(self):
Matus Fabian2ba92e32017-08-21 07:05:03 -07001199 """ Ping NAT44 out interface from outside network """
Juraj Sloboda665e4822017-02-16 17:17:19 -08001200
Matus Fabian2ba92e32017-08-21 07:05:03 -07001201 self.nat44_add_address(self.nat_addr)
1202 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
1203 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
1204 is_inside=0)
Juraj Sloboda665e4822017-02-16 17:17:19 -08001205
1206 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
1207 IP(src=self.pg1.remote_ip4, dst=self.pg1.local_ip4) /
1208 ICMP(id=self.icmp_id_out, type='echo-request'))
1209 pkts = [p]
1210 self.pg1.add_stream(pkts)
1211 self.pg_enable_capture(self.pg_interfaces)
1212 self.pg_start()
1213 capture = self.pg1.get_capture(len(pkts))
1214 self.assertEqual(1, len(capture))
1215 packet = capture[0]
1216 try:
1217 self.assertEqual(packet[IP].src, self.pg1.local_ip4)
1218 self.assertEqual(packet[IP].dst, self.pg1.remote_ip4)
1219 self.assertEqual(packet[ICMP].id, self.icmp_id_in)
1220 self.assertEqual(packet[ICMP].type, 0) # echo reply
1221 except:
1222 self.logger.error(ppp("Unexpected or invalid packet "
1223 "(outside network):", packet))
1224 raise
1225
Juraj Slobodad3677682017-04-14 03:24:45 +02001226 def test_ping_internal_host_from_outside(self):
1227 """ Ping internal host from outside network """
1228
Matus Fabian2ba92e32017-08-21 07:05:03 -07001229 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr)
1230 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
1231 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
1232 is_inside=0)
Juraj Slobodad3677682017-04-14 03:24:45 +02001233
1234 # out2in
1235 pkt = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
Matus Fabian2ba92e32017-08-21 07:05:03 -07001236 IP(src=self.pg1.remote_ip4, dst=self.nat_addr, ttl=64) /
Juraj Slobodad3677682017-04-14 03:24:45 +02001237 ICMP(id=self.icmp_id_out, type='echo-request'))
1238 self.pg1.add_stream(pkt)
1239 self.pg_enable_capture(self.pg_interfaces)
1240 self.pg_start()
1241 capture = self.pg0.get_capture(1)
1242 self.verify_capture_in(capture, self.pg0, packet_num=1)
1243 self.assert_equal(capture[0][IP].proto, IP_PROTOS.icmp)
1244
1245 # in2out
1246 pkt = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
1247 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4, ttl=64) /
1248 ICMP(id=self.icmp_id_in, type='echo-reply'))
1249 self.pg0.add_stream(pkt)
1250 self.pg_enable_capture(self.pg_interfaces)
1251 self.pg_start()
1252 capture = self.pg1.get_capture(1)
1253 self.verify_capture_out(capture, same_port=True, packet_num=1)
1254 self.assert_equal(capture[0][IP].proto, IP_PROTOS.icmp)
1255
Matus Fabianc79396e2018-07-23 00:05:22 -07001256 def test_forwarding(self):
Juraj Sloboda7b929792017-11-23 13:20:48 +01001257 """ NAT44 forwarding test """
1258
1259 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
1260 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
1261 is_inside=0)
1262 self.vapi.nat44_forwarding_enable_disable(1)
1263
1264 real_ip = self.pg0.remote_ip4n
1265 alias_ip = self.nat_addr_n
1266 self.vapi.nat44_add_del_static_mapping(local_ip=real_ip,
1267 external_ip=alias_ip)
1268
1269 try:
Matus Fabianc79396e2018-07-23 00:05:22 -07001270 # static mapping match
Juraj Sloboda7b929792017-11-23 13:20:48 +01001271
1272 pkts = self.create_stream_out(self.pg1)
1273 self.pg1.add_stream(pkts)
1274 self.pg_enable_capture(self.pg_interfaces)
1275 self.pg_start()
1276 capture = self.pg0.get_capture(len(pkts))
1277 self.verify_capture_in(capture, self.pg0)
1278
1279 pkts = self.create_stream_in(self.pg0, self.pg1)
1280 self.pg0.add_stream(pkts)
1281 self.pg_enable_capture(self.pg_interfaces)
1282 self.pg_start()
1283 capture = self.pg1.get_capture(len(pkts))
1284 self.verify_capture_out(capture, same_port=True)
1285
Matus Fabianc79396e2018-07-23 00:05:22 -07001286 # no static mapping match
Juraj Sloboda7b929792017-11-23 13:20:48 +01001287
1288 host0 = self.pg0.remote_hosts[0]
1289 self.pg0.remote_hosts[0] = self.pg0.remote_hosts[1]
1290 try:
1291 pkts = self.create_stream_out(self.pg1,
1292 dst_ip=self.pg0.remote_ip4,
1293 use_inside_ports=True)
1294 self.pg1.add_stream(pkts)
1295 self.pg_enable_capture(self.pg_interfaces)
1296 self.pg_start()
1297 capture = self.pg0.get_capture(len(pkts))
1298 self.verify_capture_in(capture, self.pg0)
1299
1300 pkts = self.create_stream_in(self.pg0, self.pg1)
1301 self.pg0.add_stream(pkts)
1302 self.pg_enable_capture(self.pg_interfaces)
1303 self.pg_start()
1304 capture = self.pg1.get_capture(len(pkts))
1305 self.verify_capture_out(capture, nat_ip=self.pg0.remote_ip4,
1306 same_port=True)
1307 finally:
1308 self.pg0.remote_hosts[0] = host0
1309
1310 finally:
1311 self.vapi.nat44_forwarding_enable_disable(0)
1312 self.vapi.nat44_add_del_static_mapping(local_ip=real_ip,
1313 external_ip=alias_ip,
1314 is_add=0)
1315
Matus Fabiande886752016-12-07 03:38:19 -08001316 def test_static_in(self):
Matus Fabian2ba92e32017-08-21 07:05:03 -07001317 """ 1:1 NAT initialized from inside network """
Matus Fabiande886752016-12-07 03:38:19 -08001318
1319 nat_ip = "10.0.0.10"
1320 self.tcp_port_out = 6303
1321 self.udp_port_out = 6304
1322 self.icmp_id_out = 6305
1323
Matus Fabian2ba92e32017-08-21 07:05:03 -07001324 self.nat44_add_static_mapping(self.pg0.remote_ip4, nat_ip)
1325 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
1326 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
1327 is_inside=0)
Matus Fabian5f224992018-01-25 21:59:16 -08001328 sm = self.vapi.nat44_static_mapping_dump()
1329 self.assertEqual(len(sm), 1)
1330 self.assertEqual((sm[0].tag).split('\0', 1)[0], '')
Matus Fabian9dba7812018-01-31 01:13:23 -08001331 self.assertEqual(sm[0].protocol, 0)
1332 self.assertEqual(sm[0].local_port, 0)
1333 self.assertEqual(sm[0].external_port, 0)
Matus Fabiande886752016-12-07 03:38:19 -08001334
1335 # in2out
1336 pkts = self.create_stream_in(self.pg0, self.pg1)
1337 self.pg0.add_stream(pkts)
1338 self.pg_enable_capture(self.pg_interfaces)
1339 self.pg_start()
Klement Sekeradab231a2016-12-21 08:50:14 +01001340 capture = self.pg1.get_capture(len(pkts))
Matus Fabiande886752016-12-07 03:38:19 -08001341 self.verify_capture_out(capture, nat_ip, True)
1342
1343 # out2in
1344 pkts = self.create_stream_out(self.pg1, nat_ip)
1345 self.pg1.add_stream(pkts)
1346 self.pg_enable_capture(self.pg_interfaces)
1347 self.pg_start()
Klement Sekeradab231a2016-12-21 08:50:14 +01001348 capture = self.pg0.get_capture(len(pkts))
Matus Fabiande886752016-12-07 03:38:19 -08001349 self.verify_capture_in(capture, self.pg0)
1350
1351 def test_static_out(self):
Matus Fabian2ba92e32017-08-21 07:05:03 -07001352 """ 1:1 NAT initialized from outside network """
Matus Fabiande886752016-12-07 03:38:19 -08001353
1354 nat_ip = "10.0.0.20"
1355 self.tcp_port_out = 6303
1356 self.udp_port_out = 6304
1357 self.icmp_id_out = 6305
Matus Fabian5f224992018-01-25 21:59:16 -08001358 tag = "testTAG"
Matus Fabiande886752016-12-07 03:38:19 -08001359
Matus Fabian5f224992018-01-25 21:59:16 -08001360 self.nat44_add_static_mapping(self.pg0.remote_ip4, nat_ip, tag=tag)
Matus Fabian2ba92e32017-08-21 07:05:03 -07001361 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
1362 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
1363 is_inside=0)
Matus Fabian5f224992018-01-25 21:59:16 -08001364 sm = self.vapi.nat44_static_mapping_dump()
1365 self.assertEqual(len(sm), 1)
1366 self.assertEqual((sm[0].tag).split('\0', 1)[0], tag)
Matus Fabiande886752016-12-07 03:38:19 -08001367
1368 # out2in
1369 pkts = self.create_stream_out(self.pg1, nat_ip)
1370 self.pg1.add_stream(pkts)
1371 self.pg_enable_capture(self.pg_interfaces)
1372 self.pg_start()
Klement Sekeradab231a2016-12-21 08:50:14 +01001373 capture = self.pg0.get_capture(len(pkts))
Matus Fabiande886752016-12-07 03:38:19 -08001374 self.verify_capture_in(capture, self.pg0)
1375
1376 # in2out
1377 pkts = self.create_stream_in(self.pg0, self.pg1)
1378 self.pg0.add_stream(pkts)
1379 self.pg_enable_capture(self.pg_interfaces)
1380 self.pg_start()
Klement Sekeradab231a2016-12-21 08:50:14 +01001381 capture = self.pg1.get_capture(len(pkts))
Matus Fabiande886752016-12-07 03:38:19 -08001382 self.verify_capture_out(capture, nat_ip, True)
1383
1384 def test_static_with_port_in(self):
Matus Fabian2ba92e32017-08-21 07:05:03 -07001385 """ 1:1 NAPT initialized from inside network """
Matus Fabiande886752016-12-07 03:38:19 -08001386
1387 self.tcp_port_out = 3606
1388 self.udp_port_out = 3607
1389 self.icmp_id_out = 3608
1390
Matus Fabian2ba92e32017-08-21 07:05:03 -07001391 self.nat44_add_address(self.nat_addr)
1392 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
1393 self.tcp_port_in, self.tcp_port_out,
1394 proto=IP_PROTOS.tcp)
1395 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
1396 self.udp_port_in, self.udp_port_out,
1397 proto=IP_PROTOS.udp)
1398 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
1399 self.icmp_id_in, self.icmp_id_out,
1400 proto=IP_PROTOS.icmp)
1401 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
1402 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
1403 is_inside=0)
Matus Fabiande886752016-12-07 03:38:19 -08001404
1405 # in2out
1406 pkts = self.create_stream_in(self.pg0, self.pg1)
1407 self.pg0.add_stream(pkts)
1408 self.pg_enable_capture(self.pg_interfaces)
1409 self.pg_start()
Klement Sekeradab231a2016-12-21 08:50:14 +01001410 capture = self.pg1.get_capture(len(pkts))
Matus Fabiande886752016-12-07 03:38:19 -08001411 self.verify_capture_out(capture)
1412
1413 # out2in
1414 pkts = self.create_stream_out(self.pg1)
1415 self.pg1.add_stream(pkts)
1416 self.pg_enable_capture(self.pg_interfaces)
1417 self.pg_start()
Klement Sekeradab231a2016-12-21 08:50:14 +01001418 capture = self.pg0.get_capture(len(pkts))
Matus Fabiande886752016-12-07 03:38:19 -08001419 self.verify_capture_in(capture, self.pg0)
1420
1421 def test_static_with_port_out(self):
Matus Fabian2ba92e32017-08-21 07:05:03 -07001422 """ 1:1 NAPT initialized from outside network """
Matus Fabiande886752016-12-07 03:38:19 -08001423
1424 self.tcp_port_out = 30606
1425 self.udp_port_out = 30607
1426 self.icmp_id_out = 30608
1427
Matus Fabian2ba92e32017-08-21 07:05:03 -07001428 self.nat44_add_address(self.nat_addr)
1429 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
1430 self.tcp_port_in, self.tcp_port_out,
1431 proto=IP_PROTOS.tcp)
1432 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
1433 self.udp_port_in, self.udp_port_out,
1434 proto=IP_PROTOS.udp)
1435 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
1436 self.icmp_id_in, self.icmp_id_out,
1437 proto=IP_PROTOS.icmp)
1438 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
1439 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
1440 is_inside=0)
Matus Fabiande886752016-12-07 03:38:19 -08001441
1442 # out2in
1443 pkts = self.create_stream_out(self.pg1)
1444 self.pg1.add_stream(pkts)
1445 self.pg_enable_capture(self.pg_interfaces)
1446 self.pg_start()
Klement Sekeradab231a2016-12-21 08:50:14 +01001447 capture = self.pg0.get_capture(len(pkts))
Matus Fabiande886752016-12-07 03:38:19 -08001448 self.verify_capture_in(capture, self.pg0)
1449
1450 # in2out
1451 pkts = self.create_stream_in(self.pg0, self.pg1)
1452 self.pg0.add_stream(pkts)
1453 self.pg_enable_capture(self.pg_interfaces)
1454 self.pg_start()
Klement Sekeradab231a2016-12-21 08:50:14 +01001455 capture = self.pg1.get_capture(len(pkts))
Matus Fabiande886752016-12-07 03:38:19 -08001456 self.verify_capture_out(capture)
1457
1458 def test_static_vrf_aware(self):
Matus Fabian2ba92e32017-08-21 07:05:03 -07001459 """ 1:1 NAT VRF awareness """
Matus Fabiande886752016-12-07 03:38:19 -08001460
1461 nat_ip1 = "10.0.0.30"
1462 nat_ip2 = "10.0.0.40"
1463 self.tcp_port_out = 6303
1464 self.udp_port_out = 6304
1465 self.icmp_id_out = 6305
1466
Matus Fabian2ba92e32017-08-21 07:05:03 -07001467 self.nat44_add_static_mapping(self.pg4.remote_ip4, nat_ip1,
1468 vrf_id=10)
1469 self.nat44_add_static_mapping(self.pg0.remote_ip4, nat_ip2,
1470 vrf_id=10)
1471 self.vapi.nat44_interface_add_del_feature(self.pg3.sw_if_index,
1472 is_inside=0)
1473 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
1474 self.vapi.nat44_interface_add_del_feature(self.pg4.sw_if_index)
Matus Fabiande886752016-12-07 03:38:19 -08001475
Matus Fabian2ba92e32017-08-21 07:05:03 -07001476 # inside interface VRF match NAT44 static mapping VRF
Matus Fabiande886752016-12-07 03:38:19 -08001477 pkts = self.create_stream_in(self.pg4, self.pg3)
1478 self.pg4.add_stream(pkts)
1479 self.pg_enable_capture(self.pg_interfaces)
1480 self.pg_start()
Klement Sekeradab231a2016-12-21 08:50:14 +01001481 capture = self.pg3.get_capture(len(pkts))
Matus Fabiande886752016-12-07 03:38:19 -08001482 self.verify_capture_out(capture, nat_ip1, True)
1483
Matus Fabian2ba92e32017-08-21 07:05:03 -07001484 # inside interface VRF don't match NAT44 static mapping VRF (packets
Matus Fabiande886752016-12-07 03:38:19 -08001485 # are dropped)
1486 pkts = self.create_stream_in(self.pg0, self.pg3)
1487 self.pg0.add_stream(pkts)
1488 self.pg_enable_capture(self.pg_interfaces)
1489 self.pg_start()
Klement Sekera9225dee2016-12-12 08:36:58 +01001490 self.pg3.assert_nothing_captured()
Matus Fabiande886752016-12-07 03:38:19 -08001491
Matus Fabianb793d092018-01-31 05:50:21 -08001492 def test_dynamic_to_static(self):
1493 """ Switch from dynamic translation to 1:1NAT """
1494 nat_ip = "10.0.0.10"
1495 self.tcp_port_out = 6303
1496 self.udp_port_out = 6304
1497 self.icmp_id_out = 6305
1498
1499 self.nat44_add_address(self.nat_addr)
1500 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
1501 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
1502 is_inside=0)
1503
1504 # dynamic
1505 pkts = self.create_stream_in(self.pg0, self.pg1)
1506 self.pg0.add_stream(pkts)
1507 self.pg_enable_capture(self.pg_interfaces)
1508 self.pg_start()
1509 capture = self.pg1.get_capture(len(pkts))
1510 self.verify_capture_out(capture)
1511
1512 # 1:1NAT
1513 self.nat44_add_static_mapping(self.pg0.remote_ip4, nat_ip)
1514 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n, 0)
1515 self.assertEqual(len(sessions), 0)
1516 pkts = self.create_stream_in(self.pg0, self.pg1)
1517 self.pg0.add_stream(pkts)
1518 self.pg_enable_capture(self.pg_interfaces)
1519 self.pg_start()
1520 capture = self.pg1.get_capture(len(pkts))
1521 self.verify_capture_out(capture, nat_ip, True)
1522
Matus Fabianab7a8052017-11-28 04:29:41 -08001523 def test_identity_nat(self):
1524 """ Identity NAT """
1525
1526 self.vapi.nat44_add_del_identity_mapping(ip=self.pg0.remote_ip4n)
1527 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
1528 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
1529 is_inside=0)
1530
1531 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
1532 IP(src=self.pg1.remote_ip4, dst=self.pg0.remote_ip4) /
1533 TCP(sport=12345, dport=56789))
1534 self.pg1.add_stream(p)
1535 self.pg_enable_capture(self.pg_interfaces)
1536 self.pg_start()
1537 capture = self.pg0.get_capture(1)
1538 p = capture[0]
1539 try:
1540 ip = p[IP]
1541 tcp = p[TCP]
1542 self.assertEqual(ip.dst, self.pg0.remote_ip4)
1543 self.assertEqual(ip.src, self.pg1.remote_ip4)
1544 self.assertEqual(tcp.dport, 56789)
1545 self.assertEqual(tcp.sport, 12345)
Klement Sekerad81ae412018-05-16 10:52:54 +02001546 self.assert_packet_checksums_valid(p)
Matus Fabianab7a8052017-11-28 04:29:41 -08001547 except:
1548 self.logger.error(ppp("Unexpected or invalid packet:", p))
1549 raise
1550
Matus Fabiande886752016-12-07 03:38:19 -08001551 def test_multiple_inside_interfaces(self):
Matus Fabian2ba92e32017-08-21 07:05:03 -07001552 """ NAT44 multiple non-overlapping address space inside interfaces """
Matus Fabiande886752016-12-07 03:38:19 -08001553
Matus Fabian2ba92e32017-08-21 07:05:03 -07001554 self.nat44_add_address(self.nat_addr)
1555 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
1556 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index)
1557 self.vapi.nat44_interface_add_del_feature(self.pg3.sw_if_index,
1558 is_inside=0)
Matus Fabiande886752016-12-07 03:38:19 -08001559
Matus Fabian2ba92e32017-08-21 07:05:03 -07001560 # between two NAT44 inside interfaces (no translation)
Matus Fabian675a69c2017-01-18 01:46:01 -08001561 pkts = self.create_stream_in(self.pg0, self.pg1)
1562 self.pg0.add_stream(pkts)
1563 self.pg_enable_capture(self.pg_interfaces)
1564 self.pg_start()
1565 capture = self.pg1.get_capture(len(pkts))
1566 self.verify_capture_no_translation(capture, self.pg0, self.pg1)
1567
Matus Fabian2ba92e32017-08-21 07:05:03 -07001568 # from NAT44 inside to interface without NAT44 feature (no translation)
Matus Fabian675a69c2017-01-18 01:46:01 -08001569 pkts = self.create_stream_in(self.pg0, self.pg2)
1570 self.pg0.add_stream(pkts)
1571 self.pg_enable_capture(self.pg_interfaces)
1572 self.pg_start()
1573 capture = self.pg2.get_capture(len(pkts))
1574 self.verify_capture_no_translation(capture, self.pg0, self.pg2)
1575
Matus Fabiande886752016-12-07 03:38:19 -08001576 # in2out 1st interface
1577 pkts = self.create_stream_in(self.pg0, self.pg3)
1578 self.pg0.add_stream(pkts)
1579 self.pg_enable_capture(self.pg_interfaces)
1580 self.pg_start()
Klement Sekeradab231a2016-12-21 08:50:14 +01001581 capture = self.pg3.get_capture(len(pkts))
Matus Fabiande886752016-12-07 03:38:19 -08001582 self.verify_capture_out(capture)
1583
1584 # out2in 1st interface
1585 pkts = self.create_stream_out(self.pg3)
1586 self.pg3.add_stream(pkts)
1587 self.pg_enable_capture(self.pg_interfaces)
1588 self.pg_start()
Klement Sekeradab231a2016-12-21 08:50:14 +01001589 capture = self.pg0.get_capture(len(pkts))
Matus Fabiande886752016-12-07 03:38:19 -08001590 self.verify_capture_in(capture, self.pg0)
1591
1592 # in2out 2nd interface
1593 pkts = self.create_stream_in(self.pg1, self.pg3)
1594 self.pg1.add_stream(pkts)
1595 self.pg_enable_capture(self.pg_interfaces)
1596 self.pg_start()
Klement Sekeradab231a2016-12-21 08:50:14 +01001597 capture = self.pg3.get_capture(len(pkts))
Matus Fabiande886752016-12-07 03:38:19 -08001598 self.verify_capture_out(capture)
1599
1600 # out2in 2nd interface
1601 pkts = self.create_stream_out(self.pg3)
1602 self.pg3.add_stream(pkts)
1603 self.pg_enable_capture(self.pg_interfaces)
1604 self.pg_start()
Klement Sekeradab231a2016-12-21 08:50:14 +01001605 capture = self.pg1.get_capture(len(pkts))
Matus Fabiande886752016-12-07 03:38:19 -08001606 self.verify_capture_in(capture, self.pg1)
1607
Matus Fabiande886752016-12-07 03:38:19 -08001608 def test_inside_overlapping_interfaces(self):
Matus Fabian2ba92e32017-08-21 07:05:03 -07001609 """ NAT44 multiple inside interfaces with overlapping address space """
Matus Fabiande886752016-12-07 03:38:19 -08001610
Matus Fabian675a69c2017-01-18 01:46:01 -08001611 static_nat_ip = "10.0.0.10"
Matus Fabian2ba92e32017-08-21 07:05:03 -07001612 self.nat44_add_address(self.nat_addr)
1613 self.vapi.nat44_interface_add_del_feature(self.pg3.sw_if_index,
1614 is_inside=0)
1615 self.vapi.nat44_interface_add_del_feature(self.pg4.sw_if_index)
1616 self.vapi.nat44_interface_add_del_feature(self.pg5.sw_if_index)
1617 self.vapi.nat44_interface_add_del_feature(self.pg6.sw_if_index)
1618 self.nat44_add_static_mapping(self.pg6.remote_ip4, static_nat_ip,
1619 vrf_id=20)
Matus Fabian675a69c2017-01-18 01:46:01 -08001620
Matus Fabian2ba92e32017-08-21 07:05:03 -07001621 # between NAT44 inside interfaces with same VRF (no translation)
Matus Fabian675a69c2017-01-18 01:46:01 -08001622 pkts = self.create_stream_in(self.pg4, self.pg5)
1623 self.pg4.add_stream(pkts)
1624 self.pg_enable_capture(self.pg_interfaces)
1625 self.pg_start()
1626 capture = self.pg5.get_capture(len(pkts))
1627 self.verify_capture_no_translation(capture, self.pg4, self.pg5)
1628
Matus Fabian2ba92e32017-08-21 07:05:03 -07001629 # between NAT44 inside interfaces with different VRF (hairpinning)
Matus Fabian675a69c2017-01-18 01:46:01 -08001630 p = (Ether(src=self.pg4.remote_mac, dst=self.pg4.local_mac) /
1631 IP(src=self.pg4.remote_ip4, dst=static_nat_ip) /
1632 TCP(sport=1234, dport=5678))
1633 self.pg4.add_stream(p)
1634 self.pg_enable_capture(self.pg_interfaces)
1635 self.pg_start()
1636 capture = self.pg6.get_capture(1)
1637 p = capture[0]
1638 try:
1639 ip = p[IP]
1640 tcp = p[TCP]
Matus Fabian2ba92e32017-08-21 07:05:03 -07001641 self.assertEqual(ip.src, self.nat_addr)
Matus Fabian675a69c2017-01-18 01:46:01 -08001642 self.assertEqual(ip.dst, self.pg6.remote_ip4)
1643 self.assertNotEqual(tcp.sport, 1234)
1644 self.assertEqual(tcp.dport, 5678)
1645 except:
1646 self.logger.error(ppp("Unexpected or invalid packet:", p))
1647 raise
Matus Fabiande886752016-12-07 03:38:19 -08001648
1649 # in2out 1st interface
1650 pkts = self.create_stream_in(self.pg4, self.pg3)
1651 self.pg4.add_stream(pkts)
1652 self.pg_enable_capture(self.pg_interfaces)
1653 self.pg_start()
Klement Sekeradab231a2016-12-21 08:50:14 +01001654 capture = self.pg3.get_capture(len(pkts))
Matus Fabiande886752016-12-07 03:38:19 -08001655 self.verify_capture_out(capture)
1656
1657 # out2in 1st interface
1658 pkts = self.create_stream_out(self.pg3)
1659 self.pg3.add_stream(pkts)
1660 self.pg_enable_capture(self.pg_interfaces)
1661 self.pg_start()
Klement Sekeradab231a2016-12-21 08:50:14 +01001662 capture = self.pg4.get_capture(len(pkts))
Matus Fabiande886752016-12-07 03:38:19 -08001663 self.verify_capture_in(capture, self.pg4)
1664
1665 # in2out 2nd interface
1666 pkts = self.create_stream_in(self.pg5, self.pg3)
1667 self.pg5.add_stream(pkts)
1668 self.pg_enable_capture(self.pg_interfaces)
1669 self.pg_start()
Klement Sekeradab231a2016-12-21 08:50:14 +01001670 capture = self.pg3.get_capture(len(pkts))
Matus Fabiande886752016-12-07 03:38:19 -08001671 self.verify_capture_out(capture)
1672
1673 # out2in 2nd interface
1674 pkts = self.create_stream_out(self.pg3)
1675 self.pg3.add_stream(pkts)
1676 self.pg_enable_capture(self.pg_interfaces)
1677 self.pg_start()
Klement Sekeradab231a2016-12-21 08:50:14 +01001678 capture = self.pg5.get_capture(len(pkts))
Matus Fabiande886752016-12-07 03:38:19 -08001679 self.verify_capture_in(capture, self.pg5)
1680
magalik23caa882017-02-08 23:25:45 -08001681 # pg5 session dump
Matus Fabian2ba92e32017-08-21 07:05:03 -07001682 addresses = self.vapi.nat44_address_dump()
magalik23caa882017-02-08 23:25:45 -08001683 self.assertEqual(len(addresses), 1)
Matus Fabian2ba92e32017-08-21 07:05:03 -07001684 sessions = self.vapi.nat44_user_session_dump(self.pg5.remote_ip4n, 10)
magalik23caa882017-02-08 23:25:45 -08001685 self.assertEqual(len(sessions), 3)
1686 for session in sessions:
1687 self.assertFalse(session.is_static)
1688 self.assertEqual(session.inside_ip_address[0:4],
1689 self.pg5.remote_ip4n)
1690 self.assertEqual(session.outside_ip_address,
1691 addresses[0].ip_address)
1692 self.assertEqual(sessions[0].protocol, IP_PROTOS.tcp)
1693 self.assertEqual(sessions[1].protocol, IP_PROTOS.udp)
1694 self.assertEqual(sessions[2].protocol, IP_PROTOS.icmp)
1695 self.assertEqual(sessions[0].inside_port, self.tcp_port_in)
1696 self.assertEqual(sessions[1].inside_port, self.udp_port_in)
1697 self.assertEqual(sessions[2].inside_port, self.icmp_id_in)
1698 self.assertEqual(sessions[0].outside_port, self.tcp_port_out)
1699 self.assertEqual(sessions[1].outside_port, self.udp_port_out)
1700 self.assertEqual(sessions[2].outside_port, self.icmp_id_out)
1701
Matus Fabiande886752016-12-07 03:38:19 -08001702 # in2out 3rd interface
1703 pkts = self.create_stream_in(self.pg6, self.pg3)
1704 self.pg6.add_stream(pkts)
1705 self.pg_enable_capture(self.pg_interfaces)
1706 self.pg_start()
Klement Sekeradab231a2016-12-21 08:50:14 +01001707 capture = self.pg3.get_capture(len(pkts))
Matus Fabian675a69c2017-01-18 01:46:01 -08001708 self.verify_capture_out(capture, static_nat_ip, True)
Matus Fabiande886752016-12-07 03:38:19 -08001709
1710 # out2in 3rd interface
Matus Fabian675a69c2017-01-18 01:46:01 -08001711 pkts = self.create_stream_out(self.pg3, static_nat_ip)
Matus Fabiande886752016-12-07 03:38:19 -08001712 self.pg3.add_stream(pkts)
1713 self.pg_enable_capture(self.pg_interfaces)
1714 self.pg_start()
Klement Sekeradab231a2016-12-21 08:50:14 +01001715 capture = self.pg6.get_capture(len(pkts))
Matus Fabiande886752016-12-07 03:38:19 -08001716 self.verify_capture_in(capture, self.pg6)
1717
magalik23caa882017-02-08 23:25:45 -08001718 # general user and session dump verifications
Matus Fabian2ba92e32017-08-21 07:05:03 -07001719 users = self.vapi.nat44_user_dump()
magalik23caa882017-02-08 23:25:45 -08001720 self.assertTrue(len(users) >= 3)
Matus Fabian2ba92e32017-08-21 07:05:03 -07001721 addresses = self.vapi.nat44_address_dump()
magalik23caa882017-02-08 23:25:45 -08001722 self.assertEqual(len(addresses), 1)
1723 for user in users:
Matus Fabian2ba92e32017-08-21 07:05:03 -07001724 sessions = self.vapi.nat44_user_session_dump(user.ip_address,
1725 user.vrf_id)
magalik23caa882017-02-08 23:25:45 -08001726 for session in sessions:
1727 self.assertEqual(user.ip_address, session.inside_ip_address)
1728 self.assertTrue(session.total_bytes > session.total_pkts > 0)
1729 self.assertTrue(session.protocol in
1730 [IP_PROTOS.tcp, IP_PROTOS.udp,
1731 IP_PROTOS.icmp])
Matus Fabian70a26ac2018-05-14 06:20:28 -07001732 self.assertFalse(session.ext_host_valid)
magalik23caa882017-02-08 23:25:45 -08001733
1734 # pg4 session dump
Matus Fabian2ba92e32017-08-21 07:05:03 -07001735 sessions = self.vapi.nat44_user_session_dump(self.pg4.remote_ip4n, 10)
magalik23caa882017-02-08 23:25:45 -08001736 self.assertTrue(len(sessions) >= 4)
1737 for session in sessions:
1738 self.assertFalse(session.is_static)
1739 self.assertEqual(session.inside_ip_address[0:4],
1740 self.pg4.remote_ip4n)
1741 self.assertEqual(session.outside_ip_address,
1742 addresses[0].ip_address)
1743
1744 # pg6 session dump
Matus Fabian2ba92e32017-08-21 07:05:03 -07001745 sessions = self.vapi.nat44_user_session_dump(self.pg6.remote_ip4n, 20)
magalik23caa882017-02-08 23:25:45 -08001746 self.assertTrue(len(sessions) >= 3)
1747 for session in sessions:
1748 self.assertTrue(session.is_static)
1749 self.assertEqual(session.inside_ip_address[0:4],
1750 self.pg6.remote_ip4n)
1751 self.assertEqual(map(ord, session.outside_ip_address[0:4]),
1752 map(int, static_nat_ip.split('.')))
1753 self.assertTrue(session.inside_port in
1754 [self.tcp_port_in, self.udp_port_in,
1755 self.icmp_id_in])
1756
Matus Fabianf78a70d2016-12-12 04:30:39 -08001757 def test_hairpinning(self):
Matus Fabian2ba92e32017-08-21 07:05:03 -07001758 """ NAT44 hairpinning - 1:1 NAPT """
Matus Fabianf78a70d2016-12-12 04:30:39 -08001759
1760 host = self.pg0.remote_hosts[0]
1761 server = self.pg0.remote_hosts[1]
1762 host_in_port = 1234
1763 host_out_port = 0
1764 server_in_port = 5678
1765 server_out_port = 8765
1766
Matus Fabian2ba92e32017-08-21 07:05:03 -07001767 self.nat44_add_address(self.nat_addr)
1768 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
1769 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
1770 is_inside=0)
Matus Fabianf78a70d2016-12-12 04:30:39 -08001771 # add static mapping for server
Matus Fabian2ba92e32017-08-21 07:05:03 -07001772 self.nat44_add_static_mapping(server.ip4, self.nat_addr,
1773 server_in_port, server_out_port,
1774 proto=IP_PROTOS.tcp)
Matus Fabianf78a70d2016-12-12 04:30:39 -08001775
1776 # send packet from host to server
1777 p = (Ether(src=host.mac, dst=self.pg0.local_mac) /
Matus Fabian2ba92e32017-08-21 07:05:03 -07001778 IP(src=host.ip4, dst=self.nat_addr) /
Matus Fabianf78a70d2016-12-12 04:30:39 -08001779 TCP(sport=host_in_port, dport=server_out_port))
1780 self.pg0.add_stream(p)
1781 self.pg_enable_capture(self.pg_interfaces)
1782 self.pg_start()
Klement Sekeradab231a2016-12-21 08:50:14 +01001783 capture = self.pg0.get_capture(1)
Matus Fabianf78a70d2016-12-12 04:30:39 -08001784 p = capture[0]
1785 try:
1786 ip = p[IP]
1787 tcp = p[TCP]
Matus Fabian2ba92e32017-08-21 07:05:03 -07001788 self.assertEqual(ip.src, self.nat_addr)
Matus Fabianf78a70d2016-12-12 04:30:39 -08001789 self.assertEqual(ip.dst, server.ip4)
1790 self.assertNotEqual(tcp.sport, host_in_port)
1791 self.assertEqual(tcp.dport, server_in_port)
Klement Sekerad81ae412018-05-16 10:52:54 +02001792 self.assert_packet_checksums_valid(p)
Matus Fabianf78a70d2016-12-12 04:30:39 -08001793 host_out_port = tcp.sport
1794 except:
Klement Sekera9225dee2016-12-12 08:36:58 +01001795 self.logger.error(ppp("Unexpected or invalid packet:", p))
Matus Fabianf78a70d2016-12-12 04:30:39 -08001796 raise
1797
1798 # send reply from server to host
1799 p = (Ether(src=server.mac, dst=self.pg0.local_mac) /
Matus Fabian2ba92e32017-08-21 07:05:03 -07001800 IP(src=server.ip4, dst=self.nat_addr) /
Matus Fabianf78a70d2016-12-12 04:30:39 -08001801 TCP(sport=server_in_port, dport=host_out_port))
1802 self.pg0.add_stream(p)
1803 self.pg_enable_capture(self.pg_interfaces)
1804 self.pg_start()
Klement Sekeradab231a2016-12-21 08:50:14 +01001805 capture = self.pg0.get_capture(1)
Matus Fabianf78a70d2016-12-12 04:30:39 -08001806 p = capture[0]
1807 try:
1808 ip = p[IP]
1809 tcp = p[TCP]
Matus Fabian2ba92e32017-08-21 07:05:03 -07001810 self.assertEqual(ip.src, self.nat_addr)
Matus Fabianf78a70d2016-12-12 04:30:39 -08001811 self.assertEqual(ip.dst, host.ip4)
1812 self.assertEqual(tcp.sport, server_out_port)
1813 self.assertEqual(tcp.dport, host_in_port)
Klement Sekerad81ae412018-05-16 10:52:54 +02001814 self.assert_packet_checksums_valid(p)
Matus Fabianf78a70d2016-12-12 04:30:39 -08001815 except:
Matus Fabiane82488f2018-01-18 03:38:45 -08001816 self.logger.error(ppp("Unexpected or invalid packet:", p))
Matus Fabianf78a70d2016-12-12 04:30:39 -08001817 raise
1818
Matus Fabian6fa74c62017-06-05 05:55:48 -07001819 def test_hairpinning2(self):
Matus Fabian2ba92e32017-08-21 07:05:03 -07001820 """ NAT44 hairpinning - 1:1 NAT"""
Matus Fabian6fa74c62017-06-05 05:55:48 -07001821
1822 server1_nat_ip = "10.0.0.10"
1823 server2_nat_ip = "10.0.0.11"
1824 host = self.pg0.remote_hosts[0]
1825 server1 = self.pg0.remote_hosts[1]
1826 server2 = self.pg0.remote_hosts[2]
1827 server_tcp_port = 22
1828 server_udp_port = 20
1829
Matus Fabian2ba92e32017-08-21 07:05:03 -07001830 self.nat44_add_address(self.nat_addr)
1831 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
1832 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
1833 is_inside=0)
Matus Fabian6fa74c62017-06-05 05:55:48 -07001834
1835 # add static mapping for servers
Matus Fabian2ba92e32017-08-21 07:05:03 -07001836 self.nat44_add_static_mapping(server1.ip4, server1_nat_ip)
1837 self.nat44_add_static_mapping(server2.ip4, server2_nat_ip)
Matus Fabian6fa74c62017-06-05 05:55:48 -07001838
1839 # host to server1
1840 pkts = []
1841 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
1842 IP(src=host.ip4, dst=server1_nat_ip) /
1843 TCP(sport=self.tcp_port_in, dport=server_tcp_port))
1844 pkts.append(p)
1845 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
1846 IP(src=host.ip4, dst=server1_nat_ip) /
1847 UDP(sport=self.udp_port_in, dport=server_udp_port))
1848 pkts.append(p)
1849 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
1850 IP(src=host.ip4, dst=server1_nat_ip) /
1851 ICMP(id=self.icmp_id_in, type='echo-request'))
1852 pkts.append(p)
1853 self.pg0.add_stream(pkts)
1854 self.pg_enable_capture(self.pg_interfaces)
1855 self.pg_start()
1856 capture = self.pg0.get_capture(len(pkts))
1857 for packet in capture:
1858 try:
Matus Fabian2ba92e32017-08-21 07:05:03 -07001859 self.assertEqual(packet[IP].src, self.nat_addr)
Matus Fabian6fa74c62017-06-05 05:55:48 -07001860 self.assertEqual(packet[IP].dst, server1.ip4)
1861 if packet.haslayer(TCP):
1862 self.assertNotEqual(packet[TCP].sport, self.tcp_port_in)
1863 self.assertEqual(packet[TCP].dport, server_tcp_port)
1864 self.tcp_port_out = packet[TCP].sport
Klement Sekerad81ae412018-05-16 10:52:54 +02001865 self.assert_packet_checksums_valid(packet)
Matus Fabian6fa74c62017-06-05 05:55:48 -07001866 elif packet.haslayer(UDP):
1867 self.assertNotEqual(packet[UDP].sport, self.udp_port_in)
1868 self.assertEqual(packet[UDP].dport, server_udp_port)
1869 self.udp_port_out = packet[UDP].sport
1870 else:
1871 self.assertNotEqual(packet[ICMP].id, self.icmp_id_in)
1872 self.icmp_id_out = packet[ICMP].id
1873 except:
1874 self.logger.error(ppp("Unexpected or invalid packet:", packet))
1875 raise
1876
1877 # server1 to host
1878 pkts = []
1879 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
Matus Fabian2ba92e32017-08-21 07:05:03 -07001880 IP(src=server1.ip4, dst=self.nat_addr) /
Matus Fabian6fa74c62017-06-05 05:55:48 -07001881 TCP(sport=server_tcp_port, dport=self.tcp_port_out))
1882 pkts.append(p)
1883 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
Matus Fabian2ba92e32017-08-21 07:05:03 -07001884 IP(src=server1.ip4, dst=self.nat_addr) /
Matus Fabian6fa74c62017-06-05 05:55:48 -07001885 UDP(sport=server_udp_port, dport=self.udp_port_out))
1886 pkts.append(p)
1887 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
Matus Fabian2ba92e32017-08-21 07:05:03 -07001888 IP(src=server1.ip4, dst=self.nat_addr) /
Matus Fabian6fa74c62017-06-05 05:55:48 -07001889 ICMP(id=self.icmp_id_out, type='echo-reply'))
1890 pkts.append(p)
1891 self.pg0.add_stream(pkts)
1892 self.pg_enable_capture(self.pg_interfaces)
1893 self.pg_start()
1894 capture = self.pg0.get_capture(len(pkts))
1895 for packet in capture:
1896 try:
1897 self.assertEqual(packet[IP].src, server1_nat_ip)
1898 self.assertEqual(packet[IP].dst, host.ip4)
1899 if packet.haslayer(TCP):
1900 self.assertEqual(packet[TCP].dport, self.tcp_port_in)
1901 self.assertEqual(packet[TCP].sport, server_tcp_port)
Klement Sekerad81ae412018-05-16 10:52:54 +02001902 self.assert_packet_checksums_valid(packet)
Matus Fabian6fa74c62017-06-05 05:55:48 -07001903 elif packet.haslayer(UDP):
1904 self.assertEqual(packet[UDP].dport, self.udp_port_in)
1905 self.assertEqual(packet[UDP].sport, server_udp_port)
1906 else:
1907 self.assertEqual(packet[ICMP].id, self.icmp_id_in)
1908 except:
1909 self.logger.error(ppp("Unexpected or invalid packet:", packet))
1910 raise
1911
1912 # server2 to server1
1913 pkts = []
1914 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
1915 IP(src=server2.ip4, dst=server1_nat_ip) /
1916 TCP(sport=self.tcp_port_in, dport=server_tcp_port))
1917 pkts.append(p)
1918 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
1919 IP(src=server2.ip4, dst=server1_nat_ip) /
1920 UDP(sport=self.udp_port_in, dport=server_udp_port))
1921 pkts.append(p)
1922 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
1923 IP(src=server2.ip4, dst=server1_nat_ip) /
1924 ICMP(id=self.icmp_id_in, type='echo-request'))
1925 pkts.append(p)
1926 self.pg0.add_stream(pkts)
1927 self.pg_enable_capture(self.pg_interfaces)
1928 self.pg_start()
1929 capture = self.pg0.get_capture(len(pkts))
1930 for packet in capture:
1931 try:
1932 self.assertEqual(packet[IP].src, server2_nat_ip)
1933 self.assertEqual(packet[IP].dst, server1.ip4)
1934 if packet.haslayer(TCP):
1935 self.assertEqual(packet[TCP].sport, self.tcp_port_in)
1936 self.assertEqual(packet[TCP].dport, server_tcp_port)
1937 self.tcp_port_out = packet[TCP].sport
Klement Sekerad81ae412018-05-16 10:52:54 +02001938 self.assert_packet_checksums_valid(packet)
Matus Fabian6fa74c62017-06-05 05:55:48 -07001939 elif packet.haslayer(UDP):
1940 self.assertEqual(packet[UDP].sport, self.udp_port_in)
1941 self.assertEqual(packet[UDP].dport, server_udp_port)
1942 self.udp_port_out = packet[UDP].sport
1943 else:
1944 self.assertEqual(packet[ICMP].id, self.icmp_id_in)
1945 self.icmp_id_out = packet[ICMP].id
1946 except:
1947 self.logger.error(ppp("Unexpected or invalid packet:", packet))
1948 raise
1949
1950 # server1 to server2
1951 pkts = []
1952 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
1953 IP(src=server1.ip4, dst=server2_nat_ip) /
1954 TCP(sport=server_tcp_port, dport=self.tcp_port_out))
1955 pkts.append(p)
1956 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
1957 IP(src=server1.ip4, dst=server2_nat_ip) /
1958 UDP(sport=server_udp_port, dport=self.udp_port_out))
1959 pkts.append(p)
1960 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
1961 IP(src=server1.ip4, dst=server2_nat_ip) /
1962 ICMP(id=self.icmp_id_out, type='echo-reply'))
1963 pkts.append(p)
1964 self.pg0.add_stream(pkts)
1965 self.pg_enable_capture(self.pg_interfaces)
1966 self.pg_start()
1967 capture = self.pg0.get_capture(len(pkts))
1968 for packet in capture:
1969 try:
1970 self.assertEqual(packet[IP].src, server1_nat_ip)
1971 self.assertEqual(packet[IP].dst, server2.ip4)
1972 if packet.haslayer(TCP):
1973 self.assertEqual(packet[TCP].dport, self.tcp_port_in)
1974 self.assertEqual(packet[TCP].sport, server_tcp_port)
Klement Sekerad81ae412018-05-16 10:52:54 +02001975 self.assert_packet_checksums_valid(packet)
Matus Fabian6fa74c62017-06-05 05:55:48 -07001976 elif packet.haslayer(UDP):
1977 self.assertEqual(packet[UDP].dport, self.udp_port_in)
1978 self.assertEqual(packet[UDP].sport, server_udp_port)
1979 else:
1980 self.assertEqual(packet[ICMP].id, self.icmp_id_in)
1981 except:
1982 self.logger.error(ppp("Unexpected or invalid packet:", packet))
1983 raise
1984
Matus Fabian9902fcd2016-12-21 23:58:46 -08001985 def test_max_translations_per_user(self):
1986 """ MAX translations per user - recycle the least recently used """
1987
Matus Fabian2ba92e32017-08-21 07:05:03 -07001988 self.nat44_add_address(self.nat_addr)
1989 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
1990 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
1991 is_inside=0)
Matus Fabian9902fcd2016-12-21 23:58:46 -08001992
1993 # get maximum number of translations per user
Matus Fabian2ba92e32017-08-21 07:05:03 -07001994 nat44_config = self.vapi.nat_show_config()
Matus Fabian9902fcd2016-12-21 23:58:46 -08001995
1996 # send more than maximum number of translations per user packets
Matus Fabian2ba92e32017-08-21 07:05:03 -07001997 pkts_num = nat44_config.max_translations_per_user + 5
Matus Fabian9902fcd2016-12-21 23:58:46 -08001998 pkts = []
1999 for port in range(0, pkts_num):
2000 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2001 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
2002 TCP(sport=1025 + port))
2003 pkts.append(p)
2004 self.pg0.add_stream(pkts)
2005 self.pg_enable_capture(self.pg_interfaces)
2006 self.pg_start()
2007
2008 # verify number of translated packet
Klement Sekeradab231a2016-12-21 08:50:14 +01002009 self.pg1.get_capture(pkts_num)
Matus Fabian9902fcd2016-12-21 23:58:46 -08002010
Matus Fabian132dc492018-05-09 04:51:03 -07002011 users = self.vapi.nat44_user_dump()
2012 for user in users:
2013 if user.ip_address == self.pg0.remote_ip4n:
2014 self.assertEqual(user.nsessions,
2015 nat44_config.max_translations_per_user)
2016 self.assertEqual(user.nstaticsessions, 0)
2017
2018 tcp_port = 22
2019 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
2020 tcp_port, tcp_port,
2021 proto=IP_PROTOS.tcp)
2022 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2023 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
2024 TCP(sport=tcp_port))
2025 self.pg0.add_stream(p)
2026 self.pg_enable_capture(self.pg_interfaces)
2027 self.pg_start()
2028 self.pg1.get_capture(1)
2029 users = self.vapi.nat44_user_dump()
2030 for user in users:
2031 if user.ip_address == self.pg0.remote_ip4n:
2032 self.assertEqual(user.nsessions,
2033 nat44_config.max_translations_per_user - 1)
2034 self.assertEqual(user.nstaticsessions, 1)
2035
Matus Fabian8bf68e82017-01-12 04:24:35 -08002036 def test_interface_addr(self):
Matus Fabian2ba92e32017-08-21 07:05:03 -07002037 """ Acquire NAT44 addresses from interface """
2038 self.vapi.nat44_add_interface_addr(self.pg7.sw_if_index)
Matus Fabian8bf68e82017-01-12 04:24:35 -08002039
2040 # no address in NAT pool
Matus Fabian2ba92e32017-08-21 07:05:03 -07002041 adresses = self.vapi.nat44_address_dump()
Matus Fabian8bf68e82017-01-12 04:24:35 -08002042 self.assertEqual(0, len(adresses))
2043
2044 # configure interface address and check NAT address pool
2045 self.pg7.config_ip4()
Matus Fabian2ba92e32017-08-21 07:05:03 -07002046 adresses = self.vapi.nat44_address_dump()
Matus Fabian8bf68e82017-01-12 04:24:35 -08002047 self.assertEqual(1, len(adresses))
Matus Fabian36532bd2017-01-23 23:42:28 -08002048 self.assertEqual(adresses[0].ip_address[0:4], self.pg7.local_ip4n)
Matus Fabian8bf68e82017-01-12 04:24:35 -08002049
2050 # remove interface address and check NAT address pool
2051 self.pg7.unconfig_ip4()
Matus Fabian2ba92e32017-08-21 07:05:03 -07002052 adresses = self.vapi.nat44_address_dump()
Matus Fabian8bf68e82017-01-12 04:24:35 -08002053 self.assertEqual(0, len(adresses))
2054
Matus Fabian36532bd2017-01-23 23:42:28 -08002055 def test_interface_addr_static_mapping(self):
2056 """ Static mapping with addresses from interface """
Matus Fabian5f224992018-01-25 21:59:16 -08002057 tag = "testTAG"
2058
Matus Fabian2ba92e32017-08-21 07:05:03 -07002059 self.vapi.nat44_add_interface_addr(self.pg7.sw_if_index)
2060 self.nat44_add_static_mapping(
2061 '1.2.3.4',
Matus Fabian5f224992018-01-25 21:59:16 -08002062 external_sw_if_index=self.pg7.sw_if_index,
2063 tag=tag)
Matus Fabian36532bd2017-01-23 23:42:28 -08002064
Matus Fabiane22e5462017-02-14 23:33:43 -08002065 # static mappings with external interface
Matus Fabian2ba92e32017-08-21 07:05:03 -07002066 static_mappings = self.vapi.nat44_static_mapping_dump()
Matus Fabiane22e5462017-02-14 23:33:43 -08002067 self.assertEqual(1, len(static_mappings))
2068 self.assertEqual(self.pg7.sw_if_index,
2069 static_mappings[0].external_sw_if_index)
Matus Fabian5f224992018-01-25 21:59:16 -08002070 self.assertEqual((static_mappings[0].tag).split('\0', 1)[0], tag)
Matus Fabian36532bd2017-01-23 23:42:28 -08002071
2072 # configure interface address and check static mappings
2073 self.pg7.config_ip4()
Matus Fabian2ba92e32017-08-21 07:05:03 -07002074 static_mappings = self.vapi.nat44_static_mapping_dump()
Matus Fabianea2600a2018-03-28 04:06:26 -07002075 self.assertEqual(2, len(static_mappings))
2076 resolved = False
2077 for sm in static_mappings:
2078 if sm.external_sw_if_index == 0xFFFFFFFF:
2079 self.assertEqual(sm.external_ip_address[0:4],
2080 self.pg7.local_ip4n)
2081 self.assertEqual((sm.tag).split('\0', 1)[0], tag)
2082 resolved = True
2083 self.assertTrue(resolved)
Matus Fabian36532bd2017-01-23 23:42:28 -08002084
2085 # remove interface address and check static mappings
2086 self.pg7.unconfig_ip4()
Matus Fabian2ba92e32017-08-21 07:05:03 -07002087 static_mappings = self.vapi.nat44_static_mapping_dump()
Matus Fabianea2600a2018-03-28 04:06:26 -07002088 self.assertEqual(1, len(static_mappings))
2089 self.assertEqual(self.pg7.sw_if_index,
2090 static_mappings[0].external_sw_if_index)
2091 self.assertEqual((static_mappings[0].tag).split('\0', 1)[0], tag)
2092
2093 # configure interface address again and check static mappings
2094 self.pg7.config_ip4()
2095 static_mappings = self.vapi.nat44_static_mapping_dump()
2096 self.assertEqual(2, len(static_mappings))
2097 resolved = False
2098 for sm in static_mappings:
2099 if sm.external_sw_if_index == 0xFFFFFFFF:
2100 self.assertEqual(sm.external_ip_address[0:4],
2101 self.pg7.local_ip4n)
2102 self.assertEqual((sm.tag).split('\0', 1)[0], tag)
2103 resolved = True
2104 self.assertTrue(resolved)
2105
2106 # remove static mapping
2107 self.nat44_add_static_mapping(
2108 '1.2.3.4',
2109 external_sw_if_index=self.pg7.sw_if_index,
2110 tag=tag,
2111 is_add=0)
2112 static_mappings = self.vapi.nat44_static_mapping_dump()
Matus Fabian36532bd2017-01-23 23:42:28 -08002113 self.assertEqual(0, len(static_mappings))
2114
Matus Fabianab7a8052017-11-28 04:29:41 -08002115 def test_interface_addr_identity_nat(self):
2116 """ Identity NAT with addresses from interface """
2117
2118 port = 53053
2119 self.vapi.nat44_add_interface_addr(self.pg7.sw_if_index)
2120 self.vapi.nat44_add_del_identity_mapping(
2121 sw_if_index=self.pg7.sw_if_index,
2122 port=port,
2123 protocol=IP_PROTOS.tcp,
2124 addr_only=0)
2125
2126 # identity mappings with external interface
2127 identity_mappings = self.vapi.nat44_identity_mapping_dump()
2128 self.assertEqual(1, len(identity_mappings))
2129 self.assertEqual(self.pg7.sw_if_index,
2130 identity_mappings[0].sw_if_index)
2131
2132 # configure interface address and check identity mappings
2133 self.pg7.config_ip4()
2134 identity_mappings = self.vapi.nat44_identity_mapping_dump()
Matus Fabianea2600a2018-03-28 04:06:26 -07002135 resolved = False
2136 self.assertEqual(2, len(identity_mappings))
2137 for sm in identity_mappings:
2138 if sm.sw_if_index == 0xFFFFFFFF:
2139 self.assertEqual(identity_mappings[0].ip_address,
2140 self.pg7.local_ip4n)
2141 self.assertEqual(port, identity_mappings[0].port)
2142 self.assertEqual(IP_PROTOS.tcp, identity_mappings[0].protocol)
2143 resolved = True
2144 self.assertTrue(resolved)
Matus Fabianab7a8052017-11-28 04:29:41 -08002145
2146 # remove interface address and check identity mappings
2147 self.pg7.unconfig_ip4()
2148 identity_mappings = self.vapi.nat44_identity_mapping_dump()
Matus Fabianea2600a2018-03-28 04:06:26 -07002149 self.assertEqual(1, len(identity_mappings))
2150 self.assertEqual(self.pg7.sw_if_index,
2151 identity_mappings[0].sw_if_index)
Matus Fabianab7a8052017-11-28 04:29:41 -08002152
Matus Fabianeea28d72017-01-13 04:15:54 -08002153 def test_ipfix_nat44_sess(self):
Matus Fabian2ba92e32017-08-21 07:05:03 -07002154 """ IPFIX logging NAT44 session created/delted """
Matus Fabian6631e9c2017-05-24 01:52:20 -07002155 self.ipfix_domain_id = 10
2156 self.ipfix_src_port = 20202
2157 colector_port = 30303
2158 bind_layers(UDP, IPFIX, dport=30303)
Matus Fabian2ba92e32017-08-21 07:05:03 -07002159 self.nat44_add_address(self.nat_addr)
2160 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
2161 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
2162 is_inside=0)
Matus Fabianeea28d72017-01-13 04:15:54 -08002163 self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4n,
2164 src_address=self.pg3.local_ip4n,
2165 path_mtu=512,
Matus Fabian6631e9c2017-05-24 01:52:20 -07002166 template_interval=10,
2167 collector_port=colector_port)
Matus Fabian2ba92e32017-08-21 07:05:03 -07002168 self.vapi.nat_ipfix(domain_id=self.ipfix_domain_id,
2169 src_port=self.ipfix_src_port)
Matus Fabianeea28d72017-01-13 04:15:54 -08002170
2171 pkts = self.create_stream_in(self.pg0, self.pg1)
2172 self.pg0.add_stream(pkts)
2173 self.pg_enable_capture(self.pg_interfaces)
2174 self.pg_start()
2175 capture = self.pg1.get_capture(len(pkts))
2176 self.verify_capture_out(capture)
Matus Fabian2ba92e32017-08-21 07:05:03 -07002177 self.nat44_add_address(self.nat_addr, is_add=0)
Matus Fabianeea28d72017-01-13 04:15:54 -08002178 self.vapi.cli("ipfix flush") # FIXME this should be an API call
Matus Fabiana431ad12018-01-04 04:03:14 -08002179 capture = self.pg3.get_capture(9)
Matus Fabianeea28d72017-01-13 04:15:54 -08002180 ipfix = IPFIXDecoder()
2181 # first load template
2182 for p in capture:
2183 self.assertTrue(p.haslayer(IPFIX))
Matus Fabian6631e9c2017-05-24 01:52:20 -07002184 self.assertEqual(p[IP].src, self.pg3.local_ip4)
2185 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
2186 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
2187 self.assertEqual(p[UDP].dport, colector_port)
2188 self.assertEqual(p[IPFIX].observationDomainID,
2189 self.ipfix_domain_id)
Matus Fabianeea28d72017-01-13 04:15:54 -08002190 if p.haslayer(Template):
2191 ipfix.add_template(p.getlayer(Template))
2192 # verify events in data set
2193 for p in capture:
2194 if p.haslayer(Data):
2195 data = ipfix.decode_data_set(p.getlayer(Set))
2196 self.verify_ipfix_nat44_ses(data)
2197
2198 def test_ipfix_addr_exhausted(self):
Matus Fabian2ba92e32017-08-21 07:05:03 -07002199 """ IPFIX logging NAT addresses exhausted """
2200 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
2201 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
2202 is_inside=0)
Matus Fabianeea28d72017-01-13 04:15:54 -08002203 self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4n,
2204 src_address=self.pg3.local_ip4n,
2205 path_mtu=512,
2206 template_interval=10)
Matus Fabian2ba92e32017-08-21 07:05:03 -07002207 self.vapi.nat_ipfix(domain_id=self.ipfix_domain_id,
2208 src_port=self.ipfix_src_port)
Matus Fabianeea28d72017-01-13 04:15:54 -08002209
2210 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
2211 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
2212 TCP(sport=3025))
2213 self.pg0.add_stream(p)
2214 self.pg_enable_capture(self.pg_interfaces)
2215 self.pg_start()
Matus Fabian229c1aa2018-05-28 04:09:52 -07002216 self.pg1.assert_nothing_captured()
2217 sleep(1)
Matus Fabianeea28d72017-01-13 04:15:54 -08002218 self.vapi.cli("ipfix flush") # FIXME this should be an API call
Matus Fabiana431ad12018-01-04 04:03:14 -08002219 capture = self.pg3.get_capture(9)
Matus Fabianeea28d72017-01-13 04:15:54 -08002220 ipfix = IPFIXDecoder()
2221 # first load template
2222 for p in capture:
2223 self.assertTrue(p.haslayer(IPFIX))
Matus Fabian6631e9c2017-05-24 01:52:20 -07002224 self.assertEqual(p[IP].src, self.pg3.local_ip4)
2225 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
2226 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
2227 self.assertEqual(p[UDP].dport, 4739)
2228 self.assertEqual(p[IPFIX].observationDomainID,
2229 self.ipfix_domain_id)
Matus Fabianeea28d72017-01-13 04:15:54 -08002230 if p.haslayer(Template):
2231 ipfix.add_template(p.getlayer(Template))
2232 # verify events in data set
2233 for p in capture:
2234 if p.haslayer(Data):
2235 data = ipfix.decode_data_set(p.getlayer(Set))
2236 self.verify_ipfix_addr_exhausted(data)
2237
Matus Fabiana431ad12018-01-04 04:03:14 -08002238 @unittest.skipUnless(running_extended_tests(), "part of extended tests")
2239 def test_ipfix_max_sessions(self):
2240 """ IPFIX logging maximum session entries exceeded """
2241 self.nat44_add_address(self.nat_addr)
2242 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
2243 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
2244 is_inside=0)
2245
2246 nat44_config = self.vapi.nat_show_config()
2247 max_sessions = 10 * nat44_config.translation_buckets
2248
2249 pkts = []
2250 for i in range(0, max_sessions):
2251 src = "10.10.%u.%u" % ((i & 0xFF00) >> 8, i & 0xFF)
2252 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2253 IP(src=src, dst=self.pg1.remote_ip4) /
2254 TCP(sport=1025))
2255 pkts.append(p)
2256 self.pg0.add_stream(pkts)
2257 self.pg_enable_capture(self.pg_interfaces)
2258 self.pg_start()
2259
2260 self.pg1.get_capture(max_sessions)
2261 self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4n,
2262 src_address=self.pg3.local_ip4n,
2263 path_mtu=512,
2264 template_interval=10)
2265 self.vapi.nat_ipfix(domain_id=self.ipfix_domain_id,
2266 src_port=self.ipfix_src_port)
2267
2268 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2269 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
2270 TCP(sport=1025))
2271 self.pg0.add_stream(p)
2272 self.pg_enable_capture(self.pg_interfaces)
2273 self.pg_start()
Matus Fabian229c1aa2018-05-28 04:09:52 -07002274 self.pg1.assert_nothing_captured()
2275 sleep(1)
Matus Fabiana431ad12018-01-04 04:03:14 -08002276 self.vapi.cli("ipfix flush") # FIXME this should be an API call
2277 capture = self.pg3.get_capture(9)
2278 ipfix = IPFIXDecoder()
2279 # first load template
2280 for p in capture:
2281 self.assertTrue(p.haslayer(IPFIX))
2282 self.assertEqual(p[IP].src, self.pg3.local_ip4)
2283 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
2284 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
2285 self.assertEqual(p[UDP].dport, 4739)
2286 self.assertEqual(p[IPFIX].observationDomainID,
2287 self.ipfix_domain_id)
2288 if p.haslayer(Template):
2289 ipfix.add_template(p.getlayer(Template))
2290 # verify events in data set
2291 for p in capture:
2292 if p.haslayer(Data):
2293 data = ipfix.decode_data_set(p.getlayer(Set))
2294 self.verify_ipfix_max_sessions(data, max_sessions)
2295
Matus Fabiane1ae29a2017-01-27 00:47:58 -08002296 def test_pool_addr_fib(self):
Matus Fabian2ba92e32017-08-21 07:05:03 -07002297 """ NAT44 add pool addresses to FIB """
Matus Fabiane1ae29a2017-01-27 00:47:58 -08002298 static_addr = '10.0.0.10'
Matus Fabian2ba92e32017-08-21 07:05:03 -07002299 self.nat44_add_address(self.nat_addr)
2300 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
2301 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
2302 is_inside=0)
2303 self.nat44_add_static_mapping(self.pg0.remote_ip4, static_addr)
Matus Fabiane1ae29a2017-01-27 00:47:58 -08002304
Matus Fabian2ba92e32017-08-21 07:05:03 -07002305 # NAT44 address
Matus Fabiane1ae29a2017-01-27 00:47:58 -08002306 p = (Ether(src=self.pg1.remote_mac, dst='ff:ff:ff:ff:ff:ff') /
Matus Fabian2ba92e32017-08-21 07:05:03 -07002307 ARP(op=ARP.who_has, pdst=self.nat_addr,
Matus Fabiane1ae29a2017-01-27 00:47:58 -08002308 psrc=self.pg1.remote_ip4, hwsrc=self.pg1.remote_mac))
2309 self.pg1.add_stream(p)
2310 self.pg_enable_capture(self.pg_interfaces)
2311 self.pg_start()
2312 capture = self.pg1.get_capture(1)
2313 self.assertTrue(capture[0].haslayer(ARP))
2314 self.assertTrue(capture[0][ARP].op, ARP.is_at)
2315
2316 # 1:1 NAT address
2317 p = (Ether(src=self.pg1.remote_mac, dst='ff:ff:ff:ff:ff:ff') /
2318 ARP(op=ARP.who_has, pdst=static_addr,
2319 psrc=self.pg1.remote_ip4, hwsrc=self.pg1.remote_mac))
2320 self.pg1.add_stream(p)
2321 self.pg_enable_capture(self.pg_interfaces)
2322 self.pg_start()
2323 capture = self.pg1.get_capture(1)
2324 self.assertTrue(capture[0].haslayer(ARP))
2325 self.assertTrue(capture[0][ARP].op, ARP.is_at)
2326
Matus Fabian2ba92e32017-08-21 07:05:03 -07002327 # send ARP to non-NAT44 interface
Matus Fabiane1ae29a2017-01-27 00:47:58 -08002328 p = (Ether(src=self.pg2.remote_mac, dst='ff:ff:ff:ff:ff:ff') /
Matus Fabian2ba92e32017-08-21 07:05:03 -07002329 ARP(op=ARP.who_has, pdst=self.nat_addr,
Matus Fabiane1ae29a2017-01-27 00:47:58 -08002330 psrc=self.pg2.remote_ip4, hwsrc=self.pg2.remote_mac))
2331 self.pg2.add_stream(p)
2332 self.pg_enable_capture(self.pg_interfaces)
2333 self.pg_start()
Matus Fabian229c1aa2018-05-28 04:09:52 -07002334 self.pg1.assert_nothing_captured()
Matus Fabiane1ae29a2017-01-27 00:47:58 -08002335
2336 # remove addresses and verify
Matus Fabian2ba92e32017-08-21 07:05:03 -07002337 self.nat44_add_address(self.nat_addr, is_add=0)
2338 self.nat44_add_static_mapping(self.pg0.remote_ip4, static_addr,
2339 is_add=0)
Matus Fabiane1ae29a2017-01-27 00:47:58 -08002340
2341 p = (Ether(src=self.pg1.remote_mac, dst='ff:ff:ff:ff:ff:ff') /
Matus Fabian2ba92e32017-08-21 07:05:03 -07002342 ARP(op=ARP.who_has, pdst=self.nat_addr,
Matus Fabiane1ae29a2017-01-27 00:47:58 -08002343 psrc=self.pg1.remote_ip4, hwsrc=self.pg1.remote_mac))
2344 self.pg1.add_stream(p)
2345 self.pg_enable_capture(self.pg_interfaces)
2346 self.pg_start()
Matus Fabian229c1aa2018-05-28 04:09:52 -07002347 self.pg1.assert_nothing_captured()
Matus Fabiane1ae29a2017-01-27 00:47:58 -08002348
2349 p = (Ether(src=self.pg1.remote_mac, dst='ff:ff:ff:ff:ff:ff') /
2350 ARP(op=ARP.who_has, pdst=static_addr,
2351 psrc=self.pg1.remote_ip4, hwsrc=self.pg1.remote_mac))
2352 self.pg1.add_stream(p)
2353 self.pg_enable_capture(self.pg_interfaces)
2354 self.pg_start()
Matus Fabian229c1aa2018-05-28 04:09:52 -07002355 self.pg1.assert_nothing_captured()
Matus Fabiane1ae29a2017-01-27 00:47:58 -08002356
Juraj Slobodaeab38d92017-03-06 19:55:21 -08002357 def test_vrf_mode(self):
Matus Fabian2ba92e32017-08-21 07:05:03 -07002358 """ NAT44 tenant VRF aware address pool mode """
Juraj Slobodaeab38d92017-03-06 19:55:21 -08002359
2360 vrf_id1 = 1
2361 vrf_id2 = 2
2362 nat_ip1 = "10.0.0.10"
2363 nat_ip2 = "10.0.0.11"
2364
2365 self.pg0.unconfig_ip4()
2366 self.pg1.unconfig_ip4()
Neale Ranns15002542017-09-10 04:39:11 -07002367 self.vapi.ip_table_add_del(vrf_id1, is_add=1)
2368 self.vapi.ip_table_add_del(vrf_id2, is_add=1)
Juraj Slobodaeab38d92017-03-06 19:55:21 -08002369 self.pg0.set_table_ip4(vrf_id1)
2370 self.pg1.set_table_ip4(vrf_id2)
2371 self.pg0.config_ip4()
2372 self.pg1.config_ip4()
Matus Fabian8008d7c2018-07-09 01:34:20 -07002373 self.pg0.resolve_arp()
2374 self.pg1.resolve_arp()
Juraj Slobodaeab38d92017-03-06 19:55:21 -08002375
Matus Fabian2ba92e32017-08-21 07:05:03 -07002376 self.nat44_add_address(nat_ip1, vrf_id=vrf_id1)
2377 self.nat44_add_address(nat_ip2, vrf_id=vrf_id2)
2378 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
2379 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index)
2380 self.vapi.nat44_interface_add_del_feature(self.pg2.sw_if_index,
2381 is_inside=0)
Juraj Slobodaeab38d92017-03-06 19:55:21 -08002382
Matus Fabian8008d7c2018-07-09 01:34:20 -07002383 try:
2384 # first VRF
2385 pkts = self.create_stream_in(self.pg0, self.pg2)
2386 self.pg0.add_stream(pkts)
2387 self.pg_enable_capture(self.pg_interfaces)
2388 self.pg_start()
2389 capture = self.pg2.get_capture(len(pkts))
2390 self.verify_capture_out(capture, nat_ip1)
Juraj Slobodaeab38d92017-03-06 19:55:21 -08002391
Matus Fabian8008d7c2018-07-09 01:34:20 -07002392 # second VRF
2393 pkts = self.create_stream_in(self.pg1, self.pg2)
2394 self.pg1.add_stream(pkts)
2395 self.pg_enable_capture(self.pg_interfaces)
2396 self.pg_start()
2397 capture = self.pg2.get_capture(len(pkts))
2398 self.verify_capture_out(capture, nat_ip2)
Juraj Slobodaeab38d92017-03-06 19:55:21 -08002399
Matus Fabian8008d7c2018-07-09 01:34:20 -07002400 finally:
2401 self.pg0.unconfig_ip4()
2402 self.pg1.unconfig_ip4()
2403 self.pg0.set_table_ip4(0)
2404 self.pg1.set_table_ip4(0)
2405 self.pg0.config_ip4()
2406 self.pg1.config_ip4()
2407 self.pg0.resolve_arp()
2408 self.pg1.resolve_arp()
2409 self.vapi.ip_table_add_del(vrf_id1, is_add=0)
2410 self.vapi.ip_table_add_del(vrf_id2, is_add=0)
Neale Ranns15002542017-09-10 04:39:11 -07002411
Juraj Slobodaeab38d92017-03-06 19:55:21 -08002412 def test_vrf_feature_independent(self):
Matus Fabian2ba92e32017-08-21 07:05:03 -07002413 """ NAT44 tenant VRF independent address pool mode """
Juraj Slobodaeab38d92017-03-06 19:55:21 -08002414
2415 nat_ip1 = "10.0.0.10"
2416 nat_ip2 = "10.0.0.11"
2417
Matus Fabian2ba92e32017-08-21 07:05:03 -07002418 self.nat44_add_address(nat_ip1)
Matus Fabian51e759f2017-12-07 23:22:51 -08002419 self.nat44_add_address(nat_ip2, vrf_id=99)
Matus Fabian2ba92e32017-08-21 07:05:03 -07002420 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
2421 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index)
2422 self.vapi.nat44_interface_add_del_feature(self.pg2.sw_if_index,
2423 is_inside=0)
Juraj Slobodaeab38d92017-03-06 19:55:21 -08002424
2425 # first VRF
2426 pkts = self.create_stream_in(self.pg0, self.pg2)
2427 self.pg0.add_stream(pkts)
2428 self.pg_enable_capture(self.pg_interfaces)
2429 self.pg_start()
2430 capture = self.pg2.get_capture(len(pkts))
2431 self.verify_capture_out(capture, nat_ip1)
2432
2433 # second VRF
2434 pkts = self.create_stream_in(self.pg1, self.pg2)
2435 self.pg1.add_stream(pkts)
2436 self.pg_enable_capture(self.pg_interfaces)
2437 self.pg_start()
2438 capture = self.pg2.get_capture(len(pkts))
2439 self.verify_capture_out(capture, nat_ip1)
2440
Martin Gálik406eb1d2017-05-04 04:35:04 -07002441 def test_dynamic_ipless_interfaces(self):
Matus Fabian2ba92e32017-08-21 07:05:03 -07002442 """ NAT44 interfaces without configured IP address """
Martin Gálik406eb1d2017-05-04 04:35:04 -07002443
2444 self.vapi.ip_neighbor_add_del(self.pg7.sw_if_index,
Ole Troan895b6e82017-10-20 13:28:20 +02002445 mactobinary(self.pg7.remote_mac),
Martin Gálik406eb1d2017-05-04 04:35:04 -07002446 self.pg7.remote_ip4n,
2447 is_static=1)
2448 self.vapi.ip_neighbor_add_del(self.pg8.sw_if_index,
Ole Troan895b6e82017-10-20 13:28:20 +02002449 mactobinary(self.pg8.remote_mac),
Martin Gálik406eb1d2017-05-04 04:35:04 -07002450 self.pg8.remote_ip4n,
2451 is_static=1)
2452
2453 self.vapi.ip_add_del_route(dst_address=self.pg7.remote_ip4n,
2454 dst_address_length=32,
2455 next_hop_address=self.pg7.remote_ip4n,
2456 next_hop_sw_if_index=self.pg7.sw_if_index)
2457 self.vapi.ip_add_del_route(dst_address=self.pg8.remote_ip4n,
2458 dst_address_length=32,
2459 next_hop_address=self.pg8.remote_ip4n,
2460 next_hop_sw_if_index=self.pg8.sw_if_index)
2461
Matus Fabian2ba92e32017-08-21 07:05:03 -07002462 self.nat44_add_address(self.nat_addr)
2463 self.vapi.nat44_interface_add_del_feature(self.pg7.sw_if_index)
2464 self.vapi.nat44_interface_add_del_feature(self.pg8.sw_if_index,
2465 is_inside=0)
Martin Gálik406eb1d2017-05-04 04:35:04 -07002466
2467 # in2out
2468 pkts = self.create_stream_in(self.pg7, self.pg8)
2469 self.pg7.add_stream(pkts)
2470 self.pg_enable_capture(self.pg_interfaces)
2471 self.pg_start()
2472 capture = self.pg8.get_capture(len(pkts))
2473 self.verify_capture_out(capture)
2474
2475 # out2in
Matus Fabian2ba92e32017-08-21 07:05:03 -07002476 pkts = self.create_stream_out(self.pg8, self.nat_addr)
Martin Gálik406eb1d2017-05-04 04:35:04 -07002477 self.pg8.add_stream(pkts)
2478 self.pg_enable_capture(self.pg_interfaces)
2479 self.pg_start()
2480 capture = self.pg7.get_capture(len(pkts))
2481 self.verify_capture_in(capture, self.pg7)
2482
2483 def test_static_ipless_interfaces(self):
Matus Fabian2ba92e32017-08-21 07:05:03 -07002484 """ NAT44 interfaces without configured IP address - 1:1 NAT """
Martin Gálik406eb1d2017-05-04 04:35:04 -07002485
2486 self.vapi.ip_neighbor_add_del(self.pg7.sw_if_index,
Ole Troan895b6e82017-10-20 13:28:20 +02002487 mactobinary(self.pg7.remote_mac),
Martin Gálik406eb1d2017-05-04 04:35:04 -07002488 self.pg7.remote_ip4n,
2489 is_static=1)
2490 self.vapi.ip_neighbor_add_del(self.pg8.sw_if_index,
Ole Troan895b6e82017-10-20 13:28:20 +02002491 mactobinary(self.pg8.remote_mac),
Martin Gálik406eb1d2017-05-04 04:35:04 -07002492 self.pg8.remote_ip4n,
2493 is_static=1)
2494
2495 self.vapi.ip_add_del_route(dst_address=self.pg7.remote_ip4n,
2496 dst_address_length=32,
2497 next_hop_address=self.pg7.remote_ip4n,
2498 next_hop_sw_if_index=self.pg7.sw_if_index)
2499 self.vapi.ip_add_del_route(dst_address=self.pg8.remote_ip4n,
2500 dst_address_length=32,
2501 next_hop_address=self.pg8.remote_ip4n,
2502 next_hop_sw_if_index=self.pg8.sw_if_index)
2503
Matus Fabian2ba92e32017-08-21 07:05:03 -07002504 self.nat44_add_static_mapping(self.pg7.remote_ip4, self.nat_addr)
2505 self.vapi.nat44_interface_add_del_feature(self.pg7.sw_if_index)
2506 self.vapi.nat44_interface_add_del_feature(self.pg8.sw_if_index,
2507 is_inside=0)
Martin Gálik406eb1d2017-05-04 04:35:04 -07002508
2509 # out2in
2510 pkts = self.create_stream_out(self.pg8)
2511 self.pg8.add_stream(pkts)
2512 self.pg_enable_capture(self.pg_interfaces)
2513 self.pg_start()
2514 capture = self.pg7.get_capture(len(pkts))
2515 self.verify_capture_in(capture, self.pg7)
2516
2517 # in2out
2518 pkts = self.create_stream_in(self.pg7, self.pg8)
2519 self.pg7.add_stream(pkts)
2520 self.pg_enable_capture(self.pg_interfaces)
2521 self.pg_start()
2522 capture = self.pg8.get_capture(len(pkts))
Matus Fabian2ba92e32017-08-21 07:05:03 -07002523 self.verify_capture_out(capture, self.nat_addr, True)
Martin Gálik406eb1d2017-05-04 04:35:04 -07002524
2525 def test_static_with_port_ipless_interfaces(self):
Matus Fabian2ba92e32017-08-21 07:05:03 -07002526 """ NAT44 interfaces without configured IP address - 1:1 NAPT """
Martin Gálik406eb1d2017-05-04 04:35:04 -07002527
2528 self.tcp_port_out = 30606
2529 self.udp_port_out = 30607
2530 self.icmp_id_out = 30608
2531
2532 self.vapi.ip_neighbor_add_del(self.pg7.sw_if_index,
Ole Troan895b6e82017-10-20 13:28:20 +02002533 mactobinary(self.pg7.remote_mac),
Martin Gálik406eb1d2017-05-04 04:35:04 -07002534 self.pg7.remote_ip4n,
2535 is_static=1)
2536 self.vapi.ip_neighbor_add_del(self.pg8.sw_if_index,
Ole Troan895b6e82017-10-20 13:28:20 +02002537 mactobinary(self.pg8.remote_mac),
Martin Gálik406eb1d2017-05-04 04:35:04 -07002538 self.pg8.remote_ip4n,
2539 is_static=1)
2540
2541 self.vapi.ip_add_del_route(dst_address=self.pg7.remote_ip4n,
2542 dst_address_length=32,
2543 next_hop_address=self.pg7.remote_ip4n,
2544 next_hop_sw_if_index=self.pg7.sw_if_index)
2545 self.vapi.ip_add_del_route(dst_address=self.pg8.remote_ip4n,
2546 dst_address_length=32,
2547 next_hop_address=self.pg8.remote_ip4n,
2548 next_hop_sw_if_index=self.pg8.sw_if_index)
2549
Matus Fabian2ba92e32017-08-21 07:05:03 -07002550 self.nat44_add_address(self.nat_addr)
2551 self.nat44_add_static_mapping(self.pg7.remote_ip4, self.nat_addr,
2552 self.tcp_port_in, self.tcp_port_out,
2553 proto=IP_PROTOS.tcp)
2554 self.nat44_add_static_mapping(self.pg7.remote_ip4, self.nat_addr,
2555 self.udp_port_in, self.udp_port_out,
2556 proto=IP_PROTOS.udp)
2557 self.nat44_add_static_mapping(self.pg7.remote_ip4, self.nat_addr,
2558 self.icmp_id_in, self.icmp_id_out,
2559 proto=IP_PROTOS.icmp)
2560 self.vapi.nat44_interface_add_del_feature(self.pg7.sw_if_index)
2561 self.vapi.nat44_interface_add_del_feature(self.pg8.sw_if_index,
2562 is_inside=0)
Martin Gálik406eb1d2017-05-04 04:35:04 -07002563
2564 # out2in
2565 pkts = self.create_stream_out(self.pg8)
2566 self.pg8.add_stream(pkts)
2567 self.pg_enable_capture(self.pg_interfaces)
2568 self.pg_start()
2569 capture = self.pg7.get_capture(len(pkts))
2570 self.verify_capture_in(capture, self.pg7)
2571
2572 # in2out
2573 pkts = self.create_stream_in(self.pg7, self.pg8)
2574 self.pg7.add_stream(pkts)
2575 self.pg_enable_capture(self.pg_interfaces)
2576 self.pg_start()
2577 capture = self.pg8.get_capture(len(pkts))
2578 self.verify_capture_out(capture)
2579
Matus Fabian328dbc82017-06-19 04:28:04 -07002580 def test_static_unknown_proto(self):
2581 """ 1:1 NAT translate packet with unknown protocol """
2582 nat_ip = "10.0.0.10"
Matus Fabian2ba92e32017-08-21 07:05:03 -07002583 self.nat44_add_static_mapping(self.pg0.remote_ip4, nat_ip)
2584 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
2585 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
2586 is_inside=0)
Matus Fabian328dbc82017-06-19 04:28:04 -07002587
2588 # in2out
2589 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2590 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
2591 GRE() /
Matus Fabian1e8db5f2017-06-20 01:45:49 -07002592 IP(src=self.pg2.remote_ip4, dst=self.pg3.remote_ip4) /
Matus Fabian328dbc82017-06-19 04:28:04 -07002593 TCP(sport=1234, dport=1234))
2594 self.pg0.add_stream(p)
2595 self.pg_enable_capture(self.pg_interfaces)
2596 self.pg_start()
2597 p = self.pg1.get_capture(1)
2598 packet = p[0]
2599 try:
2600 self.assertEqual(packet[IP].src, nat_ip)
2601 self.assertEqual(packet[IP].dst, self.pg1.remote_ip4)
2602 self.assertTrue(packet.haslayer(GRE))
Klement Sekerad81ae412018-05-16 10:52:54 +02002603 self.assert_packet_checksums_valid(packet)
Matus Fabian328dbc82017-06-19 04:28:04 -07002604 except:
2605 self.logger.error(ppp("Unexpected or invalid packet:", packet))
2606 raise
2607
2608 # out2in
2609 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
2610 IP(src=self.pg1.remote_ip4, dst=nat_ip) /
2611 GRE() /
Matus Fabian1e8db5f2017-06-20 01:45:49 -07002612 IP(src=self.pg3.remote_ip4, dst=self.pg2.remote_ip4) /
Matus Fabian328dbc82017-06-19 04:28:04 -07002613 TCP(sport=1234, dport=1234))
2614 self.pg1.add_stream(p)
2615 self.pg_enable_capture(self.pg_interfaces)
2616 self.pg_start()
2617 p = self.pg0.get_capture(1)
2618 packet = p[0]
2619 try:
2620 self.assertEqual(packet[IP].src, self.pg1.remote_ip4)
2621 self.assertEqual(packet[IP].dst, self.pg0.remote_ip4)
2622 self.assertTrue(packet.haslayer(GRE))
Klement Sekerad81ae412018-05-16 10:52:54 +02002623 self.assert_packet_checksums_valid(packet)
Matus Fabian328dbc82017-06-19 04:28:04 -07002624 except:
2625 self.logger.error(ppp("Unexpected or invalid packet:", packet))
2626 raise
2627
Matus Fabian7968e6c2017-07-06 05:37:49 -07002628 def test_hairpinning_static_unknown_proto(self):
Matus Fabian1e8db5f2017-06-20 01:45:49 -07002629 """ 1:1 NAT translate packet with unknown protocol - hairpinning """
2630
2631 host = self.pg0.remote_hosts[0]
2632 server = self.pg0.remote_hosts[1]
2633
2634 host_nat_ip = "10.0.0.10"
2635 server_nat_ip = "10.0.0.11"
2636
Matus Fabian2ba92e32017-08-21 07:05:03 -07002637 self.nat44_add_static_mapping(host.ip4, host_nat_ip)
2638 self.nat44_add_static_mapping(server.ip4, server_nat_ip)
2639 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
2640 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
2641 is_inside=0)
Matus Fabian1e8db5f2017-06-20 01:45:49 -07002642
2643 # host to server
2644 p = (Ether(dst=self.pg0.local_mac, src=host.mac) /
2645 IP(src=host.ip4, dst=server_nat_ip) /
2646 GRE() /
2647 IP(src=self.pg2.remote_ip4, dst=self.pg3.remote_ip4) /
2648 TCP(sport=1234, dport=1234))
2649 self.pg0.add_stream(p)
2650 self.pg_enable_capture(self.pg_interfaces)
2651 self.pg_start()
2652 p = self.pg0.get_capture(1)
2653 packet = p[0]
2654 try:
2655 self.assertEqual(packet[IP].src, host_nat_ip)
2656 self.assertEqual(packet[IP].dst, server.ip4)
2657 self.assertTrue(packet.haslayer(GRE))
Klement Sekerad81ae412018-05-16 10:52:54 +02002658 self.assert_packet_checksums_valid(packet)
Matus Fabian1e8db5f2017-06-20 01:45:49 -07002659 except:
2660 self.logger.error(ppp("Unexpected or invalid packet:", packet))
2661 raise
2662
2663 # server to host
2664 p = (Ether(dst=self.pg0.local_mac, src=server.mac) /
2665 IP(src=server.ip4, dst=host_nat_ip) /
2666 GRE() /
2667 IP(src=self.pg3.remote_ip4, dst=self.pg2.remote_ip4) /
2668 TCP(sport=1234, dport=1234))
2669 self.pg0.add_stream(p)
2670 self.pg_enable_capture(self.pg_interfaces)
2671 self.pg_start()
2672 p = self.pg0.get_capture(1)
2673 packet = p[0]
2674 try:
2675 self.assertEqual(packet[IP].src, server_nat_ip)
2676 self.assertEqual(packet[IP].dst, host.ip4)
2677 self.assertTrue(packet.haslayer(GRE))
Klement Sekerad81ae412018-05-16 10:52:54 +02002678 self.assert_packet_checksums_valid(packet)
Matus Fabian1e8db5f2017-06-20 01:45:49 -07002679 except:
2680 self.logger.error(ppp("Unexpected or invalid packet:", packet))
2681 raise
2682
Matus Fabian93d84c92017-07-19 08:06:01 -07002683 def test_output_feature(self):
Matus Fabian2ba92e32017-08-21 07:05:03 -07002684 """ NAT44 interface output feature (in2out postrouting) """
2685 self.nat44_add_address(self.nat_addr)
2686 self.vapi.nat44_interface_add_del_output_feature(self.pg0.sw_if_index)
Matus Fabianb2d2fc72017-09-10 22:17:47 -07002687 self.vapi.nat44_interface_add_del_output_feature(self.pg1.sw_if_index)
2688 self.vapi.nat44_interface_add_del_output_feature(self.pg3.sw_if_index,
Matus Fabian2ba92e32017-08-21 07:05:03 -07002689 is_inside=0)
Matus Fabian93d84c92017-07-19 08:06:01 -07002690
2691 # in2out
Matus Fabianb2d2fc72017-09-10 22:17:47 -07002692 pkts = self.create_stream_in(self.pg0, self.pg3)
Matus Fabian93d84c92017-07-19 08:06:01 -07002693 self.pg0.add_stream(pkts)
2694 self.pg_enable_capture(self.pg_interfaces)
2695 self.pg_start()
Matus Fabianb2d2fc72017-09-10 22:17:47 -07002696 capture = self.pg3.get_capture(len(pkts))
Matus Fabian93d84c92017-07-19 08:06:01 -07002697 self.verify_capture_out(capture)
2698
2699 # out2in
Matus Fabianb2d2fc72017-09-10 22:17:47 -07002700 pkts = self.create_stream_out(self.pg3)
2701 self.pg3.add_stream(pkts)
Matus Fabian93d84c92017-07-19 08:06:01 -07002702 self.pg_enable_capture(self.pg_interfaces)
2703 self.pg_start()
2704 capture = self.pg0.get_capture(len(pkts))
2705 self.verify_capture_in(capture, self.pg0)
2706
Matus Fabianb2d2fc72017-09-10 22:17:47 -07002707 # from non-NAT interface to NAT inside interface
2708 pkts = self.create_stream_in(self.pg2, self.pg0)
2709 self.pg2.add_stream(pkts)
2710 self.pg_enable_capture(self.pg_interfaces)
2711 self.pg_start()
2712 capture = self.pg0.get_capture(len(pkts))
2713 self.verify_capture_no_translation(capture, self.pg2, self.pg0)
2714
Matus Fabian93d84c92017-07-19 08:06:01 -07002715 def test_output_feature_vrf_aware(self):
Matus Fabian2ba92e32017-08-21 07:05:03 -07002716 """ NAT44 interface output feature VRF aware (in2out postrouting) """
Matus Fabian93d84c92017-07-19 08:06:01 -07002717 nat_ip_vrf10 = "10.0.0.10"
2718 nat_ip_vrf20 = "10.0.0.20"
2719
2720 self.vapi.ip_add_del_route(dst_address=self.pg3.remote_ip4n,
2721 dst_address_length=32,
2722 next_hop_address=self.pg3.remote_ip4n,
2723 next_hop_sw_if_index=self.pg3.sw_if_index,
2724 table_id=10)
2725 self.vapi.ip_add_del_route(dst_address=self.pg3.remote_ip4n,
2726 dst_address_length=32,
2727 next_hop_address=self.pg3.remote_ip4n,
2728 next_hop_sw_if_index=self.pg3.sw_if_index,
2729 table_id=20)
2730
Matus Fabian2ba92e32017-08-21 07:05:03 -07002731 self.nat44_add_address(nat_ip_vrf10, vrf_id=10)
2732 self.nat44_add_address(nat_ip_vrf20, vrf_id=20)
2733 self.vapi.nat44_interface_add_del_output_feature(self.pg4.sw_if_index)
2734 self.vapi.nat44_interface_add_del_output_feature(self.pg6.sw_if_index)
2735 self.vapi.nat44_interface_add_del_output_feature(self.pg3.sw_if_index,
2736 is_inside=0)
Matus Fabian93d84c92017-07-19 08:06:01 -07002737
2738 # in2out VRF 10
2739 pkts = self.create_stream_in(self.pg4, self.pg3)
2740 self.pg4.add_stream(pkts)
2741 self.pg_enable_capture(self.pg_interfaces)
2742 self.pg_start()
2743 capture = self.pg3.get_capture(len(pkts))
2744 self.verify_capture_out(capture, nat_ip=nat_ip_vrf10)
2745
2746 # out2in VRF 10
2747 pkts = self.create_stream_out(self.pg3, dst_ip=nat_ip_vrf10)
2748 self.pg3.add_stream(pkts)
2749 self.pg_enable_capture(self.pg_interfaces)
2750 self.pg_start()
2751 capture = self.pg4.get_capture(len(pkts))
2752 self.verify_capture_in(capture, self.pg4)
2753
2754 # in2out VRF 20
2755 pkts = self.create_stream_in(self.pg6, self.pg3)
2756 self.pg6.add_stream(pkts)
2757 self.pg_enable_capture(self.pg_interfaces)
2758 self.pg_start()
2759 capture = self.pg3.get_capture(len(pkts))
2760 self.verify_capture_out(capture, nat_ip=nat_ip_vrf20)
2761
2762 # out2in VRF 20
2763 pkts = self.create_stream_out(self.pg3, dst_ip=nat_ip_vrf20)
2764 self.pg3.add_stream(pkts)
2765 self.pg_enable_capture(self.pg_interfaces)
2766 self.pg_start()
2767 capture = self.pg6.get_capture(len(pkts))
2768 self.verify_capture_in(capture, self.pg6)
2769
Matus Fabian161c59c2017-07-21 03:46:03 -07002770 def test_output_feature_hairpinning(self):
Matus Fabian2ba92e32017-08-21 07:05:03 -07002771 """ NAT44 interface output feature hairpinning (in2out postrouting) """
Matus Fabian93d84c92017-07-19 08:06:01 -07002772 host = self.pg0.remote_hosts[0]
2773 server = self.pg0.remote_hosts[1]
2774 host_in_port = 1234
2775 host_out_port = 0
2776 server_in_port = 5678
2777 server_out_port = 8765
2778
Matus Fabian2ba92e32017-08-21 07:05:03 -07002779 self.nat44_add_address(self.nat_addr)
2780 self.vapi.nat44_interface_add_del_output_feature(self.pg0.sw_if_index)
2781 self.vapi.nat44_interface_add_del_output_feature(self.pg1.sw_if_index,
2782 is_inside=0)
Matus Fabian93d84c92017-07-19 08:06:01 -07002783
2784 # add static mapping for server
Matus Fabian2ba92e32017-08-21 07:05:03 -07002785 self.nat44_add_static_mapping(server.ip4, self.nat_addr,
2786 server_in_port, server_out_port,
2787 proto=IP_PROTOS.tcp)
Matus Fabian93d84c92017-07-19 08:06:01 -07002788
2789 # send packet from host to server
2790 p = (Ether(src=host.mac, dst=self.pg0.local_mac) /
Matus Fabian2ba92e32017-08-21 07:05:03 -07002791 IP(src=host.ip4, dst=self.nat_addr) /
Matus Fabian93d84c92017-07-19 08:06:01 -07002792 TCP(sport=host_in_port, dport=server_out_port))
2793 self.pg0.add_stream(p)
2794 self.pg_enable_capture(self.pg_interfaces)
2795 self.pg_start()
2796 capture = self.pg0.get_capture(1)
2797 p = capture[0]
2798 try:
2799 ip = p[IP]
2800 tcp = p[TCP]
Matus Fabian2ba92e32017-08-21 07:05:03 -07002801 self.assertEqual(ip.src, self.nat_addr)
Matus Fabian93d84c92017-07-19 08:06:01 -07002802 self.assertEqual(ip.dst, server.ip4)
2803 self.assertNotEqual(tcp.sport, host_in_port)
2804 self.assertEqual(tcp.dport, server_in_port)
Klement Sekerad81ae412018-05-16 10:52:54 +02002805 self.assert_packet_checksums_valid(p)
Matus Fabian93d84c92017-07-19 08:06:01 -07002806 host_out_port = tcp.sport
2807 except:
2808 self.logger.error(ppp("Unexpected or invalid packet:", p))
2809 raise
2810
2811 # send reply from server to host
2812 p = (Ether(src=server.mac, dst=self.pg0.local_mac) /
Matus Fabian2ba92e32017-08-21 07:05:03 -07002813 IP(src=server.ip4, dst=self.nat_addr) /
Matus Fabian93d84c92017-07-19 08:06:01 -07002814 TCP(sport=server_in_port, dport=host_out_port))
2815 self.pg0.add_stream(p)
2816 self.pg_enable_capture(self.pg_interfaces)
2817 self.pg_start()
2818 capture = self.pg0.get_capture(1)
2819 p = capture[0]
2820 try:
2821 ip = p[IP]
2822 tcp = p[TCP]
Matus Fabian2ba92e32017-08-21 07:05:03 -07002823 self.assertEqual(ip.src, self.nat_addr)
Matus Fabian93d84c92017-07-19 08:06:01 -07002824 self.assertEqual(ip.dst, host.ip4)
2825 self.assertEqual(tcp.sport, server_out_port)
2826 self.assertEqual(tcp.dport, host_in_port)
Klement Sekerad81ae412018-05-16 10:52:54 +02002827 self.assert_packet_checksums_valid(p)
Matus Fabian93d84c92017-07-19 08:06:01 -07002828 except:
Matus Fabiane82488f2018-01-18 03:38:45 -08002829 self.logger.error(ppp("Unexpected or invalid packet:", p))
Matus Fabian93d84c92017-07-19 08:06:01 -07002830 raise
2831
Matus Fabian36ea2d62017-10-24 04:13:49 -07002832 def test_one_armed_nat44(self):
2833 """ One armed NAT44 """
2834 remote_host = self.pg9.remote_hosts[0]
2835 local_host = self.pg9.remote_hosts[1]
2836 external_port = 0
2837
2838 self.nat44_add_address(self.nat_addr)
2839 self.vapi.nat44_interface_add_del_feature(self.pg9.sw_if_index)
2840 self.vapi.nat44_interface_add_del_feature(self.pg9.sw_if_index,
2841 is_inside=0)
2842
2843 # in2out
2844 p = (Ether(src=self.pg9.remote_mac, dst=self.pg9.local_mac) /
2845 IP(src=local_host.ip4, dst=remote_host.ip4) /
2846 TCP(sport=12345, dport=80))
2847 self.pg9.add_stream(p)
2848 self.pg_enable_capture(self.pg_interfaces)
2849 self.pg_start()
2850 capture = self.pg9.get_capture(1)
2851 p = capture[0]
2852 try:
2853 ip = p[IP]
2854 tcp = p[TCP]
2855 self.assertEqual(ip.src, self.nat_addr)
2856 self.assertEqual(ip.dst, remote_host.ip4)
2857 self.assertNotEqual(tcp.sport, 12345)
2858 external_port = tcp.sport
2859 self.assertEqual(tcp.dport, 80)
Klement Sekerad81ae412018-05-16 10:52:54 +02002860 self.assert_packet_checksums_valid(p)
Matus Fabian36ea2d62017-10-24 04:13:49 -07002861 except:
2862 self.logger.error(ppp("Unexpected or invalid packet:", p))
2863 raise
2864
2865 # out2in
2866 p = (Ether(src=self.pg9.remote_mac, dst=self.pg9.local_mac) /
2867 IP(src=remote_host.ip4, dst=self.nat_addr) /
2868 TCP(sport=80, dport=external_port))
2869 self.pg9.add_stream(p)
2870 self.pg_enable_capture(self.pg_interfaces)
2871 self.pg_start()
2872 capture = self.pg9.get_capture(1)
2873 p = capture[0]
2874 try:
2875 ip = p[IP]
2876 tcp = p[TCP]
2877 self.assertEqual(ip.src, remote_host.ip4)
2878 self.assertEqual(ip.dst, local_host.ip4)
2879 self.assertEqual(tcp.sport, 80)
2880 self.assertEqual(tcp.dport, 12345)
Klement Sekerad81ae412018-05-16 10:52:54 +02002881 self.assert_packet_checksums_valid(p)
Matus Fabian36ea2d62017-10-24 04:13:49 -07002882 except:
2883 self.logger.error(ppp("Unexpected or invalid packet:", p))
2884 raise
2885
Matus Fabian5ba86f72017-10-26 03:37:38 -07002886 def test_del_session(self):
2887 """ Delete NAT44 session """
2888 self.nat44_add_address(self.nat_addr)
2889 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
2890 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
2891 is_inside=0)
2892
2893 pkts = self.create_stream_in(self.pg0, self.pg1)
2894 self.pg0.add_stream(pkts)
2895 self.pg_enable_capture(self.pg_interfaces)
2896 self.pg_start()
Matus Fabian229c1aa2018-05-28 04:09:52 -07002897 self.pg1.get_capture(len(pkts))
Matus Fabian5ba86f72017-10-26 03:37:38 -07002898
2899 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n, 0)
2900 nsessions = len(sessions)
2901
2902 self.vapi.nat44_del_session(sessions[0].inside_ip_address,
2903 sessions[0].inside_port,
2904 sessions[0].protocol)
2905 self.vapi.nat44_del_session(sessions[1].outside_ip_address,
2906 sessions[1].outside_port,
2907 sessions[1].protocol,
2908 is_in=0)
2909
2910 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n, 0)
2911 self.assertEqual(nsessions - len(sessions), 2)
2912
Matus Fabianefcd1e92017-08-15 06:59:19 -07002913 def test_set_get_reass(self):
2914 """ NAT44 set/get virtual fragmentation reassembly """
2915 reas_cfg1 = self.vapi.nat_get_reass()
2916
2917 self.vapi.nat_set_reass(timeout=reas_cfg1.ip4_timeout + 5,
2918 max_reass=reas_cfg1.ip4_max_reass * 2,
2919 max_frag=reas_cfg1.ip4_max_frag * 2)
2920
2921 reas_cfg2 = self.vapi.nat_get_reass()
2922
2923 self.assertEqual(reas_cfg1.ip4_timeout + 5, reas_cfg2.ip4_timeout)
2924 self.assertEqual(reas_cfg1.ip4_max_reass * 2, reas_cfg2.ip4_max_reass)
2925 self.assertEqual(reas_cfg1.ip4_max_frag * 2, reas_cfg2.ip4_max_frag)
2926
2927 self.vapi.nat_set_reass(drop_frag=1)
2928 self.assertTrue(self.vapi.nat_get_reass().ip4_drop_frag)
2929
2930 def test_frag_in_order(self):
2931 """ NAT44 translate fragments arriving in order """
2932 self.nat44_add_address(self.nat_addr)
2933 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
2934 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
2935 is_inside=0)
2936
2937 data = "A" * 4 + "B" * 16 + "C" * 3
2938 self.tcp_port_in = random.randint(1025, 65535)
2939
2940 reass = self.vapi.nat_reass_dump()
2941 reass_n_start = len(reass)
2942
2943 # in2out
2944 pkts = self.create_stream_frag(self.pg0,
2945 self.pg1.remote_ip4,
2946 self.tcp_port_in,
2947 20,
2948 data)
2949 self.pg0.add_stream(pkts)
2950 self.pg_enable_capture(self.pg_interfaces)
2951 self.pg_start()
2952 frags = self.pg1.get_capture(len(pkts))
2953 p = self.reass_frags_and_verify(frags,
2954 self.nat_addr,
2955 self.pg1.remote_ip4)
2956 self.assertEqual(p[TCP].dport, 20)
2957 self.assertNotEqual(p[TCP].sport, self.tcp_port_in)
2958 self.tcp_port_out = p[TCP].sport
2959 self.assertEqual(data, p[Raw].load)
2960
2961 # out2in
2962 pkts = self.create_stream_frag(self.pg1,
2963 self.nat_addr,
2964 20,
2965 self.tcp_port_out,
2966 data)
2967 self.pg1.add_stream(pkts)
2968 self.pg_enable_capture(self.pg_interfaces)
2969 self.pg_start()
2970 frags = self.pg0.get_capture(len(pkts))
2971 p = self.reass_frags_and_verify(frags,
2972 self.pg1.remote_ip4,
2973 self.pg0.remote_ip4)
2974 self.assertEqual(p[TCP].sport, 20)
2975 self.assertEqual(p[TCP].dport, self.tcp_port_in)
2976 self.assertEqual(data, p[Raw].load)
2977
2978 reass = self.vapi.nat_reass_dump()
2979 reass_n_end = len(reass)
2980
2981 self.assertEqual(reass_n_end - reass_n_start, 2)
2982
2983 def test_reass_hairpinning(self):
2984 """ NAT44 fragments hairpinning """
Matus Fabianefcd1e92017-08-15 06:59:19 -07002985 server = self.pg0.remote_hosts[1]
2986 host_in_port = random.randint(1025, 65535)
Matus Fabianefcd1e92017-08-15 06:59:19 -07002987 server_in_port = random.randint(1025, 65535)
2988 server_out_port = random.randint(1025, 65535)
2989 data = "A" * 4 + "B" * 16 + "C" * 3
2990
2991 self.nat44_add_address(self.nat_addr)
2992 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
2993 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
2994 is_inside=0)
2995 # add static mapping for server
2996 self.nat44_add_static_mapping(server.ip4, self.nat_addr,
2997 server_in_port, server_out_port,
2998 proto=IP_PROTOS.tcp)
2999
3000 # send packet from host to server
3001 pkts = self.create_stream_frag(self.pg0,
3002 self.nat_addr,
3003 host_in_port,
3004 server_out_port,
3005 data)
3006 self.pg0.add_stream(pkts)
3007 self.pg_enable_capture(self.pg_interfaces)
3008 self.pg_start()
3009 frags = self.pg0.get_capture(len(pkts))
3010 p = self.reass_frags_and_verify(frags,
3011 self.nat_addr,
3012 server.ip4)
3013 self.assertNotEqual(p[TCP].sport, host_in_port)
3014 self.assertEqual(p[TCP].dport, server_in_port)
3015 self.assertEqual(data, p[Raw].load)
3016
3017 def test_frag_out_of_order(self):
3018 """ NAT44 translate fragments arriving out of order """
3019 self.nat44_add_address(self.nat_addr)
3020 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3021 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3022 is_inside=0)
3023
3024 data = "A" * 4 + "B" * 16 + "C" * 3
3025 random.randint(1025, 65535)
3026
3027 # in2out
3028 pkts = self.create_stream_frag(self.pg0,
3029 self.pg1.remote_ip4,
3030 self.tcp_port_in,
3031 20,
3032 data)
3033 pkts.reverse()
3034 self.pg0.add_stream(pkts)
3035 self.pg_enable_capture(self.pg_interfaces)
3036 self.pg_start()
3037 frags = self.pg1.get_capture(len(pkts))
3038 p = self.reass_frags_and_verify(frags,
3039 self.nat_addr,
3040 self.pg1.remote_ip4)
3041 self.assertEqual(p[TCP].dport, 20)
3042 self.assertNotEqual(p[TCP].sport, self.tcp_port_in)
3043 self.tcp_port_out = p[TCP].sport
3044 self.assertEqual(data, p[Raw].load)
3045
3046 # out2in
3047 pkts = self.create_stream_frag(self.pg1,
3048 self.nat_addr,
3049 20,
3050 self.tcp_port_out,
3051 data)
3052 pkts.reverse()
3053 self.pg1.add_stream(pkts)
3054 self.pg_enable_capture(self.pg_interfaces)
3055 self.pg_start()
3056 frags = self.pg0.get_capture(len(pkts))
3057 p = self.reass_frags_and_verify(frags,
3058 self.pg1.remote_ip4,
3059 self.pg0.remote_ip4)
3060 self.assertEqual(p[TCP].sport, 20)
3061 self.assertEqual(p[TCP].dport, self.tcp_port_in)
3062 self.assertEqual(data, p[Raw].load)
3063
Matus Fabian27697102017-11-09 01:43:47 -08003064 def test_port_restricted(self):
3065 """ Port restricted NAT44 (MAP-E CE) """
3066 self.nat44_add_address(self.nat_addr)
3067 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3068 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3069 is_inside=0)
Matus Fabian51e759f2017-12-07 23:22:51 -08003070 self.vapi.cli("nat addr-port-assignment-alg map-e psid 10 "
Matus Fabian27697102017-11-09 01:43:47 -08003071 "psid-offset 6 psid-len 6")
3072
3073 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
3074 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
3075 TCP(sport=4567, dport=22))
3076 self.pg0.add_stream(p)
3077 self.pg_enable_capture(self.pg_interfaces)
3078 self.pg_start()
3079 capture = self.pg1.get_capture(1)
3080 p = capture[0]
3081 try:
3082 ip = p[IP]
3083 tcp = p[TCP]
3084 self.assertEqual(ip.dst, self.pg1.remote_ip4)
3085 self.assertEqual(ip.src, self.nat_addr)
3086 self.assertEqual(tcp.dport, 22)
3087 self.assertNotEqual(tcp.sport, 4567)
3088 self.assertEqual((tcp.sport >> 6) & 63, 10)
Klement Sekerad81ae412018-05-16 10:52:54 +02003089 self.assert_packet_checksums_valid(p)
Matus Fabian27697102017-11-09 01:43:47 -08003090 except:
3091 self.logger.error(ppp("Unexpected or invalid packet:", p))
3092 raise
3093
Matus Fabiana6110b62018-06-13 05:39:07 -07003094 def test_ipfix_max_frags(self):
3095 """ IPFIX logging maximum fragments pending reassembly exceeded """
3096 self.nat44_add_address(self.nat_addr)
3097 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3098 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3099 is_inside=0)
3100 self.vapi.nat_set_reass(max_frag=0)
3101 self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4n,
3102 src_address=self.pg3.local_ip4n,
3103 path_mtu=512,
3104 template_interval=10)
3105 self.vapi.nat_ipfix(domain_id=self.ipfix_domain_id,
3106 src_port=self.ipfix_src_port)
3107
3108 data = "A" * 4 + "B" * 16 + "C" * 3
3109 self.tcp_port_in = random.randint(1025, 65535)
3110 pkts = self.create_stream_frag(self.pg0,
3111 self.pg1.remote_ip4,
3112 self.tcp_port_in,
3113 20,
3114 data)
3115 self.pg0.add_stream(pkts[-1])
3116 self.pg_enable_capture(self.pg_interfaces)
3117 self.pg_start()
3118 self.pg1.assert_nothing_captured()
3119 sleep(1)
3120 self.vapi.cli("ipfix flush") # FIXME this should be an API call
3121 capture = self.pg3.get_capture(9)
3122 ipfix = IPFIXDecoder()
3123 # first load template
3124 for p in capture:
3125 self.assertTrue(p.haslayer(IPFIX))
3126 self.assertEqual(p[IP].src, self.pg3.local_ip4)
3127 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
3128 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
3129 self.assertEqual(p[UDP].dport, 4739)
3130 self.assertEqual(p[IPFIX].observationDomainID,
3131 self.ipfix_domain_id)
3132 if p.haslayer(Template):
3133 ipfix.add_template(p.getlayer(Template))
3134 # verify events in data set
3135 for p in capture:
3136 if p.haslayer(Data):
3137 data = ipfix.decode_data_set(p.getlayer(Set))
3138 self.verify_ipfix_max_fragments_ip4(data, 0,
3139 self.pg0.remote_ip4n)
3140
Matus Fabian8008d7c2018-07-09 01:34:20 -07003141 def test_multiple_outside_vrf(self):
3142 """ Multiple outside VRF """
3143 vrf_id1 = 1
3144 vrf_id2 = 2
3145
3146 self.pg1.unconfig_ip4()
3147 self.pg2.unconfig_ip4()
3148 self.vapi.ip_table_add_del(vrf_id1, is_add=1)
3149 self.vapi.ip_table_add_del(vrf_id2, is_add=1)
3150 self.pg1.set_table_ip4(vrf_id1)
3151 self.pg2.set_table_ip4(vrf_id2)
3152 self.pg1.config_ip4()
3153 self.pg2.config_ip4()
3154 self.pg1.resolve_arp()
3155 self.pg2.resolve_arp()
3156
3157 self.nat44_add_address(self.nat_addr)
3158 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3159 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3160 is_inside=0)
3161 self.vapi.nat44_interface_add_del_feature(self.pg2.sw_if_index,
3162 is_inside=0)
3163
3164 try:
3165 # first VRF
3166 pkts = self.create_stream_in(self.pg0, self.pg1)
3167 self.pg0.add_stream(pkts)
3168 self.pg_enable_capture(self.pg_interfaces)
3169 self.pg_start()
3170 capture = self.pg1.get_capture(len(pkts))
3171 self.verify_capture_out(capture, self.nat_addr)
3172
3173 pkts = self.create_stream_out(self.pg1, self.nat_addr)
3174 self.pg1.add_stream(pkts)
3175 self.pg_enable_capture(self.pg_interfaces)
3176 self.pg_start()
3177 capture = self.pg0.get_capture(len(pkts))
3178 self.verify_capture_in(capture, self.pg0)
3179
3180 self.tcp_port_in = 60303
3181 self.udp_port_in = 60304
3182 self.icmp_id_in = 60305
3183
3184 # second VRF
3185 pkts = self.create_stream_in(self.pg0, self.pg2)
3186 self.pg0.add_stream(pkts)
3187 self.pg_enable_capture(self.pg_interfaces)
3188 self.pg_start()
3189 capture = self.pg2.get_capture(len(pkts))
3190 self.verify_capture_out(capture, self.nat_addr)
3191
3192 pkts = self.create_stream_out(self.pg2, self.nat_addr)
3193 self.pg2.add_stream(pkts)
3194 self.pg_enable_capture(self.pg_interfaces)
3195 self.pg_start()
3196 capture = self.pg0.get_capture(len(pkts))
3197 self.verify_capture_in(capture, self.pg0)
3198
3199 finally:
3200 self.pg1.unconfig_ip4()
3201 self.pg2.unconfig_ip4()
3202 self.pg1.set_table_ip4(0)
3203 self.pg2.set_table_ip4(0)
3204 self.pg1.config_ip4()
3205 self.pg2.config_ip4()
3206 self.pg1.resolve_arp()
3207 self.pg2.resolve_arp()
3208
Matus Fabiana6110b62018-06-13 05:39:07 -07003209 def tearDown(self):
3210 super(TestNAT44, self).tearDown()
3211 if not self.vpp_dead:
3212 self.logger.info(self.vapi.cli("show nat44 addresses"))
3213 self.logger.info(self.vapi.cli("show nat44 interfaces"))
3214 self.logger.info(self.vapi.cli("show nat44 static mappings"))
3215 self.logger.info(self.vapi.cli("show nat44 interface address"))
3216 self.logger.info(self.vapi.cli("show nat44 sessions detail"))
3217 self.logger.info(self.vapi.cli("show nat virtual-reassembly"))
3218 self.logger.info(self.vapi.cli("show nat44 hash tables detail"))
3219 self.vapi.cli("nat addr-port-assignment-alg default")
3220 self.clear_nat44()
3221 self.vapi.cli("clear logging")
3222
3223
3224class TestNAT44EndpointDependent(MethodHolder):
3225 """ Endpoint-Dependent mapping and filtering test cases """
3226
3227 @classmethod
3228 def setUpConstants(cls):
3229 super(TestNAT44EndpointDependent, cls).setUpConstants()
3230 cls.vpp_cmdline.extend(["nat", "{", "endpoint-dependent", "}"])
3231
3232 @classmethod
3233 def setUpClass(cls):
3234 super(TestNAT44EndpointDependent, cls).setUpClass()
3235 cls.vapi.cli("set log class nat level debug")
3236 try:
3237 cls.tcp_port_in = 6303
3238 cls.tcp_port_out = 6303
3239 cls.udp_port_in = 6304
3240 cls.udp_port_out = 6304
3241 cls.icmp_id_in = 6305
3242 cls.icmp_id_out = 6305
3243 cls.nat_addr = '10.0.0.3'
3244 cls.nat_addr_n = socket.inet_pton(socket.AF_INET, cls.nat_addr)
3245 cls.ipfix_src_port = 4739
3246 cls.ipfix_domain_id = 1
3247 cls.tcp_external_port = 80
3248
Matus Fabian8008d7c2018-07-09 01:34:20 -07003249 cls.create_pg_interfaces(range(7))
Matus Fabiana6110b62018-06-13 05:39:07 -07003250 cls.interfaces = list(cls.pg_interfaces[0:3])
3251
3252 for i in cls.interfaces:
3253 i.admin_up()
3254 i.config_ip4()
3255 i.resolve_arp()
3256
3257 cls.pg0.generate_remote_hosts(3)
3258 cls.pg0.configure_ipv4_neighbors()
3259
3260 cls.pg3.admin_up()
3261
3262 cls.pg4.generate_remote_hosts(2)
3263 cls.pg4.config_ip4()
3264 ip_addr_n = socket.inet_pton(socket.AF_INET, "10.0.0.1")
3265 cls.vapi.sw_interface_add_del_address(cls.pg4.sw_if_index,
3266 ip_addr_n,
3267 24)
3268 cls.pg4.admin_up()
3269 cls.pg4.resolve_arp()
3270 cls.pg4._remote_hosts[1]._ip4 = cls.pg4._remote_hosts[0]._ip4
3271 cls.pg4.resolve_arp()
3272
Matus Fabian8008d7c2018-07-09 01:34:20 -07003273 zero_ip4n = socket.inet_pton(socket.AF_INET, "0.0.0.0")
3274 cls.vapi.ip_table_add_del(1, is_add=1)
3275
3276 cls.pg5._local_ip4 = "10.1.1.1"
3277 cls.pg5._local_ip4n = socket.inet_pton(socket.AF_INET,
3278 cls.pg5.local_ip4)
3279 cls.pg5._remote_hosts[0]._ip4 = "10.1.1.2"
3280 cls.pg5._remote_hosts[0]._ip4n = socket.inet_pton(
3281 socket.AF_INET, cls.pg5.remote_ip4)
3282 cls.pg5.set_table_ip4(1)
3283 cls.pg5.config_ip4()
3284 cls.pg5.admin_up()
3285 cls.vapi.ip_add_del_route(dst_address=cls.pg5.remote_ip4n,
3286 dst_address_length=32,
3287 table_id=1,
3288 next_hop_sw_if_index=cls.pg5.sw_if_index,
3289 next_hop_address=zero_ip4n)
3290
3291 cls.pg6._local_ip4 = "10.1.2.1"
3292 cls.pg6._local_ip4n = socket.inet_pton(socket.AF_INET,
3293 cls.pg6.local_ip4)
3294 cls.pg6._remote_hosts[0]._ip4 = "10.1.2.2"
3295 cls.pg6._remote_hosts[0]._ip4n = socket.inet_pton(
3296 socket.AF_INET, cls.pg6.remote_ip4)
3297 cls.pg6.set_table_ip4(1)
3298 cls.pg6.config_ip4()
3299 cls.pg6.admin_up()
3300 cls.vapi.ip_add_del_route(dst_address=cls.pg6.remote_ip4n,
3301 dst_address_length=32,
3302 table_id=1,
3303 next_hop_sw_if_index=cls.pg6.sw_if_index,
3304 next_hop_address=zero_ip4n)
3305
3306 cls.vapi.ip_add_del_route(dst_address=cls.pg6.remote_ip4n,
3307 dst_address_length=16,
3308 next_hop_address=zero_ip4n,
3309 table_id=0,
3310 next_hop_table_id=1)
3311 cls.vapi.ip_add_del_route(dst_address=zero_ip4n,
3312 dst_address_length=0,
3313 next_hop_address=zero_ip4n,
3314 table_id=1,
3315 next_hop_table_id=0)
3316 cls.vapi.ip_add_del_route(dst_address=zero_ip4n,
3317 dst_address_length=0,
3318 table_id=0,
3319 next_hop_sw_if_index=cls.pg1.sw_if_index,
3320 next_hop_address=cls.pg1.local_ip4n)
3321
3322 cls.pg5.resolve_arp()
3323 cls.pg6.resolve_arp()
3324
Matus Fabiana6110b62018-06-13 05:39:07 -07003325 except Exception:
3326 super(TestNAT44EndpointDependent, cls).tearDownClass()
3327 raise
3328
3329 def test_dynamic(self):
3330 """ NAT44 dynamic translation test """
3331
3332 self.nat44_add_address(self.nat_addr)
3333 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3334 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3335 is_inside=0)
3336
3337 # in2out
3338 pkts = self.create_stream_in(self.pg0, self.pg1)
3339 self.pg0.add_stream(pkts)
3340 self.pg_enable_capture(self.pg_interfaces)
3341 self.pg_start()
3342 capture = self.pg1.get_capture(len(pkts))
3343 self.verify_capture_out(capture)
3344
3345 # out2in
3346 pkts = self.create_stream_out(self.pg1)
3347 self.pg1.add_stream(pkts)
3348 self.pg_enable_capture(self.pg_interfaces)
3349 self.pg_start()
3350 capture = self.pg0.get_capture(len(pkts))
3351 self.verify_capture_in(capture, self.pg0)
3352
3353 def test_forwarding(self):
3354 """ NAT44 forwarding test """
3355
3356 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3357 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3358 is_inside=0)
3359 self.vapi.nat44_forwarding_enable_disable(1)
3360
3361 real_ip = self.pg0.remote_ip4n
3362 alias_ip = self.nat_addr_n
3363 self.vapi.nat44_add_del_static_mapping(local_ip=real_ip,
3364 external_ip=alias_ip)
3365
3366 try:
3367 # in2out - static mapping match
3368
3369 pkts = self.create_stream_out(self.pg1)
3370 self.pg1.add_stream(pkts)
3371 self.pg_enable_capture(self.pg_interfaces)
3372 self.pg_start()
3373 capture = self.pg0.get_capture(len(pkts))
3374 self.verify_capture_in(capture, self.pg0)
3375
3376 pkts = self.create_stream_in(self.pg0, self.pg1)
3377 self.pg0.add_stream(pkts)
3378 self.pg_enable_capture(self.pg_interfaces)
3379 self.pg_start()
3380 capture = self.pg1.get_capture(len(pkts))
3381 self.verify_capture_out(capture, same_port=True)
3382
3383 # in2out - no static mapping match
3384
3385 host0 = self.pg0.remote_hosts[0]
3386 self.pg0.remote_hosts[0] = self.pg0.remote_hosts[1]
3387 try:
3388 pkts = self.create_stream_out(self.pg1,
3389 dst_ip=self.pg0.remote_ip4,
3390 use_inside_ports=True)
3391 self.pg1.add_stream(pkts)
3392 self.pg_enable_capture(self.pg_interfaces)
3393 self.pg_start()
3394 capture = self.pg0.get_capture(len(pkts))
3395 self.verify_capture_in(capture, self.pg0)
3396
3397 pkts = self.create_stream_in(self.pg0, self.pg1)
3398 self.pg0.add_stream(pkts)
3399 self.pg_enable_capture(self.pg_interfaces)
3400 self.pg_start()
3401 capture = self.pg1.get_capture(len(pkts))
3402 self.verify_capture_out(capture, nat_ip=self.pg0.remote_ip4,
3403 same_port=True)
3404 finally:
3405 self.pg0.remote_hosts[0] = host0
3406
3407 user = self.pg0.remote_hosts[1]
3408 sessions = self.vapi.nat44_user_session_dump(user.ip4n, 0)
3409 self.assertEqual(len(sessions), 3)
3410 self.assertTrue(sessions[0].ext_host_valid)
3411 self.vapi.nat44_del_session(
3412 sessions[0].inside_ip_address,
3413 sessions[0].inside_port,
3414 sessions[0].protocol,
3415 ext_host_address=sessions[0].ext_host_address,
3416 ext_host_port=sessions[0].ext_host_port)
3417 sessions = self.vapi.nat44_user_session_dump(user.ip4n, 0)
3418 self.assertEqual(len(sessions), 2)
3419
3420 finally:
3421 self.vapi.nat44_forwarding_enable_disable(0)
3422 self.vapi.nat44_add_del_static_mapping(local_ip=real_ip,
3423 external_ip=alias_ip,
3424 is_add=0)
3425
3426 def test_static_lb(self):
3427 """ NAT44 local service load balancing """
3428 external_addr_n = socket.inet_pton(socket.AF_INET, self.nat_addr)
3429 external_port = 80
3430 local_port = 8080
3431 server1 = self.pg0.remote_hosts[0]
3432 server2 = self.pg0.remote_hosts[1]
3433
3434 locals = [{'addr': server1.ip4n,
3435 'port': local_port,
3436 'probability': 70},
3437 {'addr': server2.ip4n,
3438 'port': local_port,
3439 'probability': 30}]
3440
3441 self.nat44_add_address(self.nat_addr)
3442 self.vapi.nat44_add_del_lb_static_mapping(external_addr_n,
3443 external_port,
3444 IP_PROTOS.tcp,
3445 local_num=len(locals),
3446 locals=locals)
3447 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3448 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3449 is_inside=0)
3450
3451 # from client to service
3452 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
3453 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
3454 TCP(sport=12345, dport=external_port))
3455 self.pg1.add_stream(p)
3456 self.pg_enable_capture(self.pg_interfaces)
3457 self.pg_start()
3458 capture = self.pg0.get_capture(1)
3459 p = capture[0]
3460 server = None
3461 try:
3462 ip = p[IP]
3463 tcp = p[TCP]
3464 self.assertIn(ip.dst, [server1.ip4, server2.ip4])
3465 if ip.dst == server1.ip4:
3466 server = server1
3467 else:
3468 server = server2
3469 self.assertEqual(tcp.dport, local_port)
3470 self.assert_packet_checksums_valid(p)
3471 except:
3472 self.logger.error(ppp("Unexpected or invalid packet:", p))
3473 raise
3474
3475 # from service back to client
3476 p = (Ether(src=server.mac, dst=self.pg0.local_mac) /
3477 IP(src=server.ip4, dst=self.pg1.remote_ip4) /
3478 TCP(sport=local_port, dport=12345))
3479 self.pg0.add_stream(p)
3480 self.pg_enable_capture(self.pg_interfaces)
3481 self.pg_start()
3482 capture = self.pg1.get_capture(1)
3483 p = capture[0]
3484 try:
3485 ip = p[IP]
3486 tcp = p[TCP]
3487 self.assertEqual(ip.src, self.nat_addr)
3488 self.assertEqual(tcp.sport, external_port)
3489 self.assert_packet_checksums_valid(p)
3490 except:
3491 self.logger.error(ppp("Unexpected or invalid packet:", p))
3492 raise
3493
3494 sessions = self.vapi.nat44_user_session_dump(server.ip4n, 0)
3495 self.assertEqual(len(sessions), 1)
3496 self.assertTrue(sessions[0].ext_host_valid)
3497 self.vapi.nat44_del_session(
3498 sessions[0].inside_ip_address,
3499 sessions[0].inside_port,
3500 sessions[0].protocol,
3501 ext_host_address=sessions[0].ext_host_address,
3502 ext_host_port=sessions[0].ext_host_port)
3503 sessions = self.vapi.nat44_user_session_dump(server.ip4n, 0)
3504 self.assertEqual(len(sessions), 0)
3505
3506 @unittest.skipUnless(running_extended_tests(), "part of extended tests")
3507 def test_static_lb_multi_clients(self):
3508 """ NAT44 local service load balancing - multiple clients"""
3509
3510 external_addr_n = socket.inet_pton(socket.AF_INET, self.nat_addr)
3511 external_port = 80
3512 local_port = 8080
3513 server1 = self.pg0.remote_hosts[0]
3514 server2 = self.pg0.remote_hosts[1]
3515
3516 locals = [{'addr': server1.ip4n,
3517 'port': local_port,
3518 'probability': 90},
3519 {'addr': server2.ip4n,
3520 'port': local_port,
3521 'probability': 10}]
3522
3523 self.nat44_add_address(self.nat_addr)
3524 self.vapi.nat44_add_del_lb_static_mapping(external_addr_n,
3525 external_port,
3526 IP_PROTOS.tcp,
3527 local_num=len(locals),
3528 locals=locals)
3529 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3530 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3531 is_inside=0)
3532
3533 server1_n = 0
3534 server2_n = 0
3535 clients = ip4_range(self.pg1.remote_ip4, 10, 50)
3536 pkts = []
3537 for client in clients:
3538 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
3539 IP(src=client, dst=self.nat_addr) /
3540 TCP(sport=12345, dport=external_port))
3541 pkts.append(p)
3542 self.pg1.add_stream(pkts)
3543 self.pg_enable_capture(self.pg_interfaces)
3544 self.pg_start()
3545 capture = self.pg0.get_capture(len(pkts))
3546 for p in capture:
3547 if p[IP].dst == server1.ip4:
3548 server1_n += 1
3549 else:
3550 server2_n += 1
3551 self.assertTrue(server1_n > server2_n)
3552
3553 def test_static_lb_2(self):
3554 """ NAT44 local service load balancing (asymmetrical rule) """
3555 external_addr_n = socket.inet_pton(socket.AF_INET, self.nat_addr)
3556 external_port = 80
3557 local_port = 8080
3558 server1 = self.pg0.remote_hosts[0]
3559 server2 = self.pg0.remote_hosts[1]
3560
3561 locals = [{'addr': server1.ip4n,
3562 'port': local_port,
3563 'probability': 70},
3564 {'addr': server2.ip4n,
3565 'port': local_port,
3566 'probability': 30}]
3567
3568 self.vapi.nat44_forwarding_enable_disable(1)
3569 self.vapi.nat44_add_del_lb_static_mapping(external_addr_n,
3570 external_port,
3571 IP_PROTOS.tcp,
3572 out2in_only=1,
3573 local_num=len(locals),
3574 locals=locals)
3575 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3576 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3577 is_inside=0)
3578
3579 # from client to service
3580 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
3581 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
3582 TCP(sport=12345, dport=external_port))
3583 self.pg1.add_stream(p)
3584 self.pg_enable_capture(self.pg_interfaces)
3585 self.pg_start()
3586 capture = self.pg0.get_capture(1)
3587 p = capture[0]
3588 server = None
3589 try:
3590 ip = p[IP]
3591 tcp = p[TCP]
3592 self.assertIn(ip.dst, [server1.ip4, server2.ip4])
3593 if ip.dst == server1.ip4:
3594 server = server1
3595 else:
3596 server = server2
3597 self.assertEqual(tcp.dport, local_port)
3598 self.assert_packet_checksums_valid(p)
3599 except:
3600 self.logger.error(ppp("Unexpected or invalid packet:", p))
3601 raise
3602
3603 # from service back to client
3604 p = (Ether(src=server.mac, dst=self.pg0.local_mac) /
3605 IP(src=server.ip4, dst=self.pg1.remote_ip4) /
3606 TCP(sport=local_port, dport=12345))
3607 self.pg0.add_stream(p)
3608 self.pg_enable_capture(self.pg_interfaces)
3609 self.pg_start()
3610 capture = self.pg1.get_capture(1)
3611 p = capture[0]
3612 try:
3613 ip = p[IP]
3614 tcp = p[TCP]
3615 self.assertEqual(ip.src, self.nat_addr)
3616 self.assertEqual(tcp.sport, external_port)
3617 self.assert_packet_checksums_valid(p)
3618 except:
3619 self.logger.error(ppp("Unexpected or invalid packet:", p))
3620 raise
3621
3622 # from client to server (no translation)
3623 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
3624 IP(src=self.pg1.remote_ip4, dst=server1.ip4) /
3625 TCP(sport=12346, dport=local_port))
3626 self.pg1.add_stream(p)
3627 self.pg_enable_capture(self.pg_interfaces)
3628 self.pg_start()
3629 capture = self.pg0.get_capture(1)
3630 p = capture[0]
3631 server = None
3632 try:
3633 ip = p[IP]
3634 tcp = p[TCP]
3635 self.assertEqual(ip.dst, server1.ip4)
3636 self.assertEqual(tcp.dport, local_port)
3637 self.assert_packet_checksums_valid(p)
3638 except:
3639 self.logger.error(ppp("Unexpected or invalid packet:", p))
3640 raise
3641
3642 # from service back to client (no translation)
3643 p = (Ether(src=server1.mac, dst=self.pg0.local_mac) /
3644 IP(src=server1.ip4, dst=self.pg1.remote_ip4) /
3645 TCP(sport=local_port, dport=12346))
3646 self.pg0.add_stream(p)
3647 self.pg_enable_capture(self.pg_interfaces)
3648 self.pg_start()
3649 capture = self.pg1.get_capture(1)
3650 p = capture[0]
3651 try:
3652 ip = p[IP]
3653 tcp = p[TCP]
3654 self.assertEqual(ip.src, server1.ip4)
3655 self.assertEqual(tcp.sport, local_port)
3656 self.assert_packet_checksums_valid(p)
3657 except:
3658 self.logger.error(ppp("Unexpected or invalid packet:", p))
3659 raise
3660
3661 def test_unknown_proto(self):
3662 """ NAT44 translate packet with unknown protocol """
3663 self.nat44_add_address(self.nat_addr)
3664 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3665 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3666 is_inside=0)
3667
3668 # in2out
3669 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
3670 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
3671 TCP(sport=self.tcp_port_in, dport=20))
3672 self.pg0.add_stream(p)
3673 self.pg_enable_capture(self.pg_interfaces)
3674 self.pg_start()
3675 p = self.pg1.get_capture(1)
3676
3677 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
3678 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
3679 GRE() /
3680 IP(src=self.pg2.remote_ip4, dst=self.pg2.remote_ip4) /
3681 TCP(sport=1234, dport=1234))
3682 self.pg0.add_stream(p)
3683 self.pg_enable_capture(self.pg_interfaces)
3684 self.pg_start()
3685 p = self.pg1.get_capture(1)
3686 packet = p[0]
3687 try:
3688 self.assertEqual(packet[IP].src, self.nat_addr)
3689 self.assertEqual(packet[IP].dst, self.pg1.remote_ip4)
3690 self.assertTrue(packet.haslayer(GRE))
3691 self.assert_packet_checksums_valid(packet)
3692 except:
3693 self.logger.error(ppp("Unexpected or invalid packet:", packet))
3694 raise
3695
3696 # out2in
3697 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
3698 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
3699 GRE() /
3700 IP(src=self.pg2.remote_ip4, dst=self.pg2.remote_ip4) /
3701 TCP(sport=1234, dport=1234))
3702 self.pg1.add_stream(p)
3703 self.pg_enable_capture(self.pg_interfaces)
3704 self.pg_start()
3705 p = self.pg0.get_capture(1)
3706 packet = p[0]
3707 try:
3708 self.assertEqual(packet[IP].src, self.pg1.remote_ip4)
3709 self.assertEqual(packet[IP].dst, self.pg0.remote_ip4)
3710 self.assertTrue(packet.haslayer(GRE))
3711 self.assert_packet_checksums_valid(packet)
3712 except:
3713 self.logger.error(ppp("Unexpected or invalid packet:", packet))
3714 raise
3715
3716 def test_hairpinning_unknown_proto(self):
3717 """ NAT44 translate packet with unknown protocol - hairpinning """
3718 host = self.pg0.remote_hosts[0]
3719 server = self.pg0.remote_hosts[1]
3720 host_in_port = 1234
3721 server_out_port = 8765
3722 server_nat_ip = "10.0.0.11"
3723
3724 self.nat44_add_address(self.nat_addr)
3725 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3726 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3727 is_inside=0)
3728
3729 # add static mapping for server
3730 self.nat44_add_static_mapping(server.ip4, server_nat_ip)
3731
3732 # host to server
3733 p = (Ether(src=host.mac, dst=self.pg0.local_mac) /
3734 IP(src=host.ip4, dst=server_nat_ip) /
3735 TCP(sport=host_in_port, dport=server_out_port))
3736 self.pg0.add_stream(p)
3737 self.pg_enable_capture(self.pg_interfaces)
3738 self.pg_start()
3739 self.pg0.get_capture(1)
3740
3741 p = (Ether(dst=self.pg0.local_mac, src=host.mac) /
3742 IP(src=host.ip4, dst=server_nat_ip) /
3743 GRE() /
3744 IP(src=self.pg2.remote_ip4, dst=self.pg2.remote_ip4) /
3745 TCP(sport=1234, dport=1234))
3746 self.pg0.add_stream(p)
3747 self.pg_enable_capture(self.pg_interfaces)
3748 self.pg_start()
3749 p = self.pg0.get_capture(1)
3750 packet = p[0]
3751 try:
3752 self.assertEqual(packet[IP].src, self.nat_addr)
3753 self.assertEqual(packet[IP].dst, server.ip4)
3754 self.assertTrue(packet.haslayer(GRE))
3755 self.assert_packet_checksums_valid(packet)
3756 except:
3757 self.logger.error(ppp("Unexpected or invalid packet:", packet))
3758 raise
3759
3760 # server to host
3761 p = (Ether(dst=self.pg0.local_mac, src=server.mac) /
3762 IP(src=server.ip4, dst=self.nat_addr) /
3763 GRE() /
3764 IP(src=self.pg2.remote_ip4, dst=self.pg2.remote_ip4) /
3765 TCP(sport=1234, dport=1234))
3766 self.pg0.add_stream(p)
3767 self.pg_enable_capture(self.pg_interfaces)
3768 self.pg_start()
3769 p = self.pg0.get_capture(1)
3770 packet = p[0]
3771 try:
3772 self.assertEqual(packet[IP].src, server_nat_ip)
3773 self.assertEqual(packet[IP].dst, host.ip4)
3774 self.assertTrue(packet.haslayer(GRE))
3775 self.assert_packet_checksums_valid(packet)
3776 except:
3777 self.logger.error(ppp("Unexpected or invalid packet:", packet))
3778 raise
3779
3780 def test_output_feature_and_service(self):
3781 """ NAT44 interface output feature and services """
3782 external_addr = '1.2.3.4'
3783 external_port = 80
3784 local_port = 8080
3785
3786 self.vapi.nat44_forwarding_enable_disable(1)
3787 self.nat44_add_address(self.nat_addr)
3788 self.vapi.nat44_add_del_identity_mapping(ip=self.pg1.remote_ip4n)
3789 self.nat44_add_static_mapping(self.pg0.remote_ip4, external_addr,
3790 local_port, external_port,
3791 proto=IP_PROTOS.tcp, out2in_only=1)
3792 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3793 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index,
3794 is_inside=0)
3795 self.vapi.nat44_interface_add_del_output_feature(self.pg1.sw_if_index,
3796 is_inside=0)
3797
3798 # from client to service
3799 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
3800 IP(src=self.pg1.remote_ip4, dst=external_addr) /
3801 TCP(sport=12345, dport=external_port))
3802 self.pg1.add_stream(p)
3803 self.pg_enable_capture(self.pg_interfaces)
3804 self.pg_start()
3805 capture = self.pg0.get_capture(1)
3806 p = capture[0]
3807 try:
3808 ip = p[IP]
3809 tcp = p[TCP]
3810 self.assertEqual(ip.dst, self.pg0.remote_ip4)
3811 self.assertEqual(tcp.dport, local_port)
3812 self.assert_packet_checksums_valid(p)
3813 except:
3814 self.logger.error(ppp("Unexpected or invalid packet:", p))
3815 raise
3816
3817 # from service back to client
3818 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
3819 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
3820 TCP(sport=local_port, dport=12345))
3821 self.pg0.add_stream(p)
3822 self.pg_enable_capture(self.pg_interfaces)
3823 self.pg_start()
3824 capture = self.pg1.get_capture(1)
3825 p = capture[0]
3826 try:
3827 ip = p[IP]
3828 tcp = p[TCP]
3829 self.assertEqual(ip.src, external_addr)
3830 self.assertEqual(tcp.sport, external_port)
3831 self.assert_packet_checksums_valid(p)
3832 except:
3833 self.logger.error(ppp("Unexpected or invalid packet:", p))
3834 raise
3835
3836 # from local network host to external network
3837 pkts = self.create_stream_in(self.pg0, self.pg1)
3838 self.pg0.add_stream(pkts)
3839 self.pg_enable_capture(self.pg_interfaces)
3840 self.pg_start()
3841 capture = self.pg1.get_capture(len(pkts))
3842 self.verify_capture_out(capture)
3843 pkts = self.create_stream_in(self.pg0, self.pg1)
3844 self.pg0.add_stream(pkts)
3845 self.pg_enable_capture(self.pg_interfaces)
3846 self.pg_start()
3847 capture = self.pg1.get_capture(len(pkts))
3848 self.verify_capture_out(capture)
3849
3850 # from external network back to local network host
3851 pkts = self.create_stream_out(self.pg1)
3852 self.pg1.add_stream(pkts)
3853 self.pg_enable_capture(self.pg_interfaces)
3854 self.pg_start()
3855 capture = self.pg0.get_capture(len(pkts))
3856 self.verify_capture_in(capture, self.pg0)
3857
3858 def test_output_feature_and_service2(self):
3859 """ NAT44 interface output feature and service host direct access """
3860 self.vapi.nat44_forwarding_enable_disable(1)
3861 self.nat44_add_address(self.nat_addr)
3862 self.vapi.nat44_interface_add_del_output_feature(self.pg1.sw_if_index,
3863 is_inside=0)
3864
3865 # session initiaded from service host - translate
3866 pkts = self.create_stream_in(self.pg0, self.pg1)
3867 self.pg0.add_stream(pkts)
3868 self.pg_enable_capture(self.pg_interfaces)
3869 self.pg_start()
3870 capture = self.pg1.get_capture(len(pkts))
3871 self.verify_capture_out(capture)
3872
3873 pkts = self.create_stream_out(self.pg1)
3874 self.pg1.add_stream(pkts)
3875 self.pg_enable_capture(self.pg_interfaces)
3876 self.pg_start()
3877 capture = self.pg0.get_capture(len(pkts))
3878 self.verify_capture_in(capture, self.pg0)
3879
3880 # session initiaded from remote host - do not translate
3881 self.tcp_port_in = 60303
3882 self.udp_port_in = 60304
3883 self.icmp_id_in = 60305
3884 pkts = self.create_stream_out(self.pg1,
3885 self.pg0.remote_ip4,
3886 use_inside_ports=True)
3887 self.pg1.add_stream(pkts)
3888 self.pg_enable_capture(self.pg_interfaces)
3889 self.pg_start()
3890 capture = self.pg0.get_capture(len(pkts))
3891 self.verify_capture_in(capture, self.pg0)
3892
3893 pkts = self.create_stream_in(self.pg0, self.pg1)
3894 self.pg0.add_stream(pkts)
3895 self.pg_enable_capture(self.pg_interfaces)
3896 self.pg_start()
3897 capture = self.pg1.get_capture(len(pkts))
3898 self.verify_capture_out(capture, nat_ip=self.pg0.remote_ip4,
3899 same_port=True)
3900
3901 def test_output_feature_and_service3(self):
3902 """ NAT44 interface output feature and DST NAT """
3903 external_addr = '1.2.3.4'
3904 external_port = 80
3905 local_port = 8080
3906
3907 self.vapi.nat44_forwarding_enable_disable(1)
3908 self.nat44_add_address(self.nat_addr)
3909 self.nat44_add_static_mapping(self.pg1.remote_ip4, external_addr,
3910 local_port, external_port,
3911 proto=IP_PROTOS.tcp, out2in_only=1)
3912 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3913 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index,
3914 is_inside=0)
3915 self.vapi.nat44_interface_add_del_output_feature(self.pg1.sw_if_index,
3916 is_inside=0)
3917
3918 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
3919 IP(src=self.pg0.remote_ip4, dst=external_addr) /
3920 TCP(sport=12345, dport=external_port))
3921 self.pg0.add_stream(p)
3922 self.pg_enable_capture(self.pg_interfaces)
3923 self.pg_start()
3924 capture = self.pg1.get_capture(1)
3925 p = capture[0]
3926 try:
3927 ip = p[IP]
3928 tcp = p[TCP]
3929 self.assertEqual(ip.src, self.pg0.remote_ip4)
3930 self.assertEqual(tcp.sport, 12345)
3931 self.assertEqual(ip.dst, self.pg1.remote_ip4)
3932 self.assertEqual(tcp.dport, local_port)
3933 self.assert_packet_checksums_valid(p)
3934 except:
3935 self.logger.error(ppp("Unexpected or invalid packet:", p))
3936 raise
3937
3938 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
3939 IP(src=self.pg1.remote_ip4, dst=self.pg0.remote_ip4) /
3940 TCP(sport=local_port, dport=12345))
3941 self.pg1.add_stream(p)
3942 self.pg_enable_capture(self.pg_interfaces)
3943 self.pg_start()
3944 capture = self.pg0.get_capture(1)
3945 p = capture[0]
3946 try:
3947 ip = p[IP]
3948 tcp = p[TCP]
3949 self.assertEqual(ip.src, external_addr)
3950 self.assertEqual(tcp.sport, external_port)
3951 self.assertEqual(ip.dst, self.pg0.remote_ip4)
3952 self.assertEqual(tcp.dport, 12345)
3953 self.assert_packet_checksums_valid(p)
3954 except:
3955 self.logger.error(ppp("Unexpected or invalid packet:", p))
3956 raise
3957
Juraj Sloboda1e5c07d2018-04-10 13:51:54 +02003958 def twice_nat_common(self, self_twice_nat=False, same_pg=False, lb=False,
3959 client_id=None):
Matus Fabianb932d262017-12-18 05:38:24 -08003960 twice_nat_addr = '10.0.1.3'
Juraj Sloboda1e5c07d2018-04-10 13:51:54 +02003961
Matus Fabianb932d262017-12-18 05:38:24 -08003962 port_in = 8080
Juraj Sloboda1e5c07d2018-04-10 13:51:54 +02003963 if lb:
3964 if not same_pg:
3965 port_in1 = port_in
3966 port_in2 = port_in
3967 else:
3968 port_in1 = port_in+1
3969 port_in2 = port_in+2
3970
Matus Fabianb932d262017-12-18 05:38:24 -08003971 port_out = 80
3972 eh_port_out = 4567
Juraj Sloboda1e5c07d2018-04-10 13:51:54 +02003973
3974 server1 = self.pg0.remote_hosts[0]
3975 server2 = self.pg0.remote_hosts[1]
3976 if lb and same_pg:
3977 server2 = server1
3978 if not lb:
3979 server = server1
3980
3981 pg0 = self.pg0
3982 if same_pg:
3983 pg1 = self.pg0
3984 else:
3985 pg1 = self.pg1
3986
3987 eh_translate = ((not self_twice_nat) or (not lb and same_pg) or
3988 client_id == 1)
3989
Matus Fabianb932d262017-12-18 05:38:24 -08003990 self.nat44_add_address(self.nat_addr)
3991 self.nat44_add_address(twice_nat_addr, twice_nat=1)
Juraj Sloboda1e5c07d2018-04-10 13:51:54 +02003992 if not lb:
3993 self.nat44_add_static_mapping(pg0.remote_ip4, self.nat_addr,
3994 port_in, port_out,
3995 proto=IP_PROTOS.tcp,
3996 twice_nat=int(not self_twice_nat),
3997 self_twice_nat=int(self_twice_nat))
3998 else:
3999 locals = [{'addr': server1.ip4n,
4000 'port': port_in1,
4001 'probability': 50},
4002 {'addr': server2.ip4n,
4003 'port': port_in2,
4004 'probability': 50}]
4005 out_addr_n = socket.inet_pton(socket.AF_INET, self.nat_addr)
4006 self.vapi.nat44_add_del_lb_static_mapping(out_addr_n,
4007 port_out,
4008 IP_PROTOS.tcp,
4009 twice_nat=int(
4010 not self_twice_nat),
4011 self_twice_nat=int(
4012 self_twice_nat),
4013 local_num=len(locals),
4014 locals=locals)
4015 self.vapi.nat44_interface_add_del_feature(pg0.sw_if_index)
4016 self.vapi.nat44_interface_add_del_feature(pg1.sw_if_index,
Matus Fabianb932d262017-12-18 05:38:24 -08004017 is_inside=0)
4018
Juraj Sloboda1e5c07d2018-04-10 13:51:54 +02004019 if same_pg:
4020 if not lb:
4021 client = server
4022 else:
4023 assert client_id is not None
4024 if client_id == 1:
4025 client = self.pg0.remote_hosts[0]
4026 elif client_id == 2:
4027 client = self.pg0.remote_hosts[1]
4028 else:
4029 client = pg1.remote_hosts[0]
4030 p = (Ether(src=pg1.remote_mac, dst=pg1.local_mac) /
4031 IP(src=client.ip4, dst=self.nat_addr) /
Matus Fabianb932d262017-12-18 05:38:24 -08004032 TCP(sport=eh_port_out, dport=port_out))
Juraj Sloboda1e5c07d2018-04-10 13:51:54 +02004033 pg1.add_stream(p)
Matus Fabianb932d262017-12-18 05:38:24 -08004034 self.pg_enable_capture(self.pg_interfaces)
4035 self.pg_start()
Juraj Sloboda1e5c07d2018-04-10 13:51:54 +02004036 capture = pg0.get_capture(1)
Matus Fabianb932d262017-12-18 05:38:24 -08004037 p = capture[0]
4038 try:
4039 ip = p[IP]
4040 tcp = p[TCP]
Juraj Sloboda1e5c07d2018-04-10 13:51:54 +02004041 if lb:
4042 if ip.dst == server1.ip4:
4043 server = server1
4044 port_in = port_in1
4045 else:
4046 server = server2
4047 port_in = port_in2
4048 self.assertEqual(ip.dst, server.ip4)
4049 if lb and same_pg:
4050 self.assertIn(tcp.dport, [port_in1, port_in2])
4051 else:
4052 self.assertEqual(tcp.dport, port_in)
4053 if eh_translate:
4054 self.assertEqual(ip.src, twice_nat_addr)
4055 self.assertNotEqual(tcp.sport, eh_port_out)
4056 else:
4057 self.assertEqual(ip.src, client.ip4)
4058 self.assertEqual(tcp.sport, eh_port_out)
4059 eh_addr_in = ip.src
Matus Fabianb932d262017-12-18 05:38:24 -08004060 eh_port_in = tcp.sport
Juraj Sloboda1e5c07d2018-04-10 13:51:54 +02004061 saved_port_in = tcp.dport
Klement Sekerad81ae412018-05-16 10:52:54 +02004062 self.assert_packet_checksums_valid(p)
Matus Fabianb932d262017-12-18 05:38:24 -08004063 except:
4064 self.logger.error(ppp("Unexpected or invalid packet:", p))
4065 raise
4066
Juraj Sloboda1e5c07d2018-04-10 13:51:54 +02004067 p = (Ether(src=server.mac, dst=pg0.local_mac) /
4068 IP(src=server.ip4, dst=eh_addr_in) /
4069 TCP(sport=saved_port_in, dport=eh_port_in))
4070 pg0.add_stream(p)
Matus Fabianb932d262017-12-18 05:38:24 -08004071 self.pg_enable_capture(self.pg_interfaces)
4072 self.pg_start()
Juraj Sloboda1e5c07d2018-04-10 13:51:54 +02004073 capture = pg1.get_capture(1)
Matus Fabianb932d262017-12-18 05:38:24 -08004074 p = capture[0]
4075 try:
4076 ip = p[IP]
4077 tcp = p[TCP]
Juraj Sloboda1e5c07d2018-04-10 13:51:54 +02004078 self.assertEqual(ip.dst, client.ip4)
Matus Fabianb932d262017-12-18 05:38:24 -08004079 self.assertEqual(ip.src, self.nat_addr)
4080 self.assertEqual(tcp.dport, eh_port_out)
4081 self.assertEqual(tcp.sport, port_out)
Klement Sekerad81ae412018-05-16 10:52:54 +02004082 self.assert_packet_checksums_valid(p)
Matus Fabianb932d262017-12-18 05:38:24 -08004083 except:
4084 self.logger.error(ppp("Unexpected or invalid packet:", p))
4085 raise
4086
Matus Fabian70a26ac2018-05-14 06:20:28 -07004087 if eh_translate:
4088 sessions = self.vapi.nat44_user_session_dump(server.ip4n, 0)
4089 self.assertEqual(len(sessions), 1)
4090 self.assertTrue(sessions[0].ext_host_valid)
4091 self.assertTrue(sessions[0].is_twicenat)
4092 self.vapi.nat44_del_session(
4093 sessions[0].inside_ip_address,
4094 sessions[0].inside_port,
4095 sessions[0].protocol,
4096 ext_host_address=sessions[0].ext_host_nat_address,
4097 ext_host_port=sessions[0].ext_host_nat_port)
4098 sessions = self.vapi.nat44_user_session_dump(server.ip4n, 0)
4099 self.assertEqual(len(sessions), 0)
4100
Juraj Sloboda1e5c07d2018-04-10 13:51:54 +02004101 def test_twice_nat(self):
4102 """ Twice NAT44 """
4103 self.twice_nat_common()
4104
4105 def test_self_twice_nat_positive(self):
4106 """ Self Twice NAT44 (positive test) """
4107 self.twice_nat_common(self_twice_nat=True, same_pg=True)
4108
4109 def test_self_twice_nat_negative(self):
4110 """ Self Twice NAT44 (negative test) """
4111 self.twice_nat_common(self_twice_nat=True)
4112
Matus Fabianb932d262017-12-18 05:38:24 -08004113 def test_twice_nat_lb(self):
4114 """ Twice NAT44 local service load balancing """
Juraj Sloboda1e5c07d2018-04-10 13:51:54 +02004115 self.twice_nat_common(lb=True)
Matus Fabianb932d262017-12-18 05:38:24 -08004116
Juraj Sloboda1e5c07d2018-04-10 13:51:54 +02004117 def test_self_twice_nat_lb_positive(self):
4118 """ Self Twice NAT44 local service load balancing (positive test) """
4119 self.twice_nat_common(lb=True, self_twice_nat=True, same_pg=True,
4120 client_id=1)
Matus Fabianb932d262017-12-18 05:38:24 -08004121
Juraj Sloboda1e5c07d2018-04-10 13:51:54 +02004122 def test_self_twice_nat_lb_negative(self):
4123 """ Self Twice NAT44 local service load balancing (negative test) """
4124 self.twice_nat_common(lb=True, self_twice_nat=True, same_pg=True,
4125 client_id=2)
Matus Fabianb932d262017-12-18 05:38:24 -08004126
4127 def test_twice_nat_interface_addr(self):
4128 """ Acquire twice NAT44 addresses from interface """
Matus Fabiana6110b62018-06-13 05:39:07 -07004129 self.vapi.nat44_add_interface_addr(self.pg3.sw_if_index, twice_nat=1)
Matus Fabianb932d262017-12-18 05:38:24 -08004130
4131 # no address in NAT pool
4132 adresses = self.vapi.nat44_address_dump()
4133 self.assertEqual(0, len(adresses))
4134
4135 # configure interface address and check NAT address pool
Matus Fabiana6110b62018-06-13 05:39:07 -07004136 self.pg3.config_ip4()
Matus Fabianb932d262017-12-18 05:38:24 -08004137 adresses = self.vapi.nat44_address_dump()
4138 self.assertEqual(1, len(adresses))
Matus Fabiana6110b62018-06-13 05:39:07 -07004139 self.assertEqual(adresses[0].ip_address[0:4], self.pg3.local_ip4n)
Matus Fabianb932d262017-12-18 05:38:24 -08004140 self.assertEqual(adresses[0].twice_nat, 1)
4141
4142 # remove interface address and check NAT address pool
Matus Fabiana6110b62018-06-13 05:39:07 -07004143 self.pg3.unconfig_ip4()
Matus Fabianb932d262017-12-18 05:38:24 -08004144 adresses = self.vapi.nat44_address_dump()
4145 self.assertEqual(0, len(adresses))
4146
Matus Fabianebdf1902018-05-04 03:57:42 -07004147 def test_tcp_session_close_in(self):
4148 """ Close TCP session from inside network """
Matus Fabian229c1aa2018-05-28 04:09:52 -07004149 self.tcp_port_out = 10505
Matus Fabianebdf1902018-05-04 03:57:42 -07004150 self.nat44_add_address(self.nat_addr)
Matus Fabian229c1aa2018-05-28 04:09:52 -07004151 self.nat44_add_static_mapping(self.pg0.remote_ip4,
4152 self.nat_addr,
4153 self.tcp_port_in,
4154 self.tcp_port_out,
4155 proto=IP_PROTOS.tcp,
4156 twice_nat=1)
Matus Fabianebdf1902018-05-04 03:57:42 -07004157 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
4158 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
4159 is_inside=0)
4160
4161 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n, 0)
4162 start_sessnum = len(sessions)
4163
4164 self.initiate_tcp_session(self.pg0, self.pg1)
4165
Matus Fabian229c1aa2018-05-28 04:09:52 -07004166 # FIN packet in -> out
4167 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
4168 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
4169 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
4170 flags="FA", seq=100, ack=300))
4171 self.pg0.add_stream(p)
4172 self.pg_enable_capture(self.pg_interfaces)
4173 self.pg_start()
4174 self.pg1.get_capture(1)
Matus Fabianebdf1902018-05-04 03:57:42 -07004175
Matus Fabian229c1aa2018-05-28 04:09:52 -07004176 pkts = []
Matus Fabianebdf1902018-05-04 03:57:42 -07004177
Matus Fabian229c1aa2018-05-28 04:09:52 -07004178 # ACK 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="A", seq=300, ack=101))
4183 pkts.append(p)
Matus Fabianebdf1902018-05-04 03:57:42 -07004184
Matus Fabian229c1aa2018-05-28 04:09:52 -07004185 # FIN packet out -> in
4186 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
4187 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
4188 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
4189 flags="FA", seq=300, ack=101))
4190 pkts.append(p)
Matus Fabianebdf1902018-05-04 03:57:42 -07004191
Matus Fabian229c1aa2018-05-28 04:09:52 -07004192 self.pg1.add_stream(pkts)
4193 self.pg_enable_capture(self.pg_interfaces)
4194 self.pg_start()
4195 self.pg0.get_capture(2)
Matus Fabianebdf1902018-05-04 03:57:42 -07004196
Matus Fabian229c1aa2018-05-28 04:09:52 -07004197 # ACK packet in -> out
4198 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
4199 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
4200 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
4201 flags="A", seq=101, ack=301))
4202 self.pg0.add_stream(p)
4203 self.pg_enable_capture(self.pg_interfaces)
4204 self.pg_start()
4205 self.pg1.get_capture(1)
Matus Fabianebdf1902018-05-04 03:57:42 -07004206
Matus Fabian229c1aa2018-05-28 04:09:52 -07004207 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n,
4208 0)
4209 self.assertEqual(len(sessions) - start_sessnum, 0)
Matus Fabianebdf1902018-05-04 03:57:42 -07004210
4211 def test_tcp_session_close_out(self):
4212 """ Close TCP session from outside network """
Matus Fabian229c1aa2018-05-28 04:09:52 -07004213 self.tcp_port_out = 10505
Matus Fabianebdf1902018-05-04 03:57:42 -07004214 self.nat44_add_address(self.nat_addr)
Matus Fabian229c1aa2018-05-28 04:09:52 -07004215 self.nat44_add_static_mapping(self.pg0.remote_ip4,
4216 self.nat_addr,
4217 self.tcp_port_in,
4218 self.tcp_port_out,
4219 proto=IP_PROTOS.tcp,
4220 twice_nat=1)
Matus Fabianebdf1902018-05-04 03:57:42 -07004221 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
4222 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
4223 is_inside=0)
4224
4225 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n, 0)
4226 start_sessnum = len(sessions)
4227
4228 self.initiate_tcp_session(self.pg0, self.pg1)
4229
Matus Fabian229c1aa2018-05-28 04:09:52 -07004230 # FIN packet out -> in
4231 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
4232 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
4233 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
4234 flags="FA", seq=100, ack=300))
4235 self.pg1.add_stream(p)
4236 self.pg_enable_capture(self.pg_interfaces)
4237 self.pg_start()
4238 self.pg0.get_capture(1)
Matus Fabianebdf1902018-05-04 03:57:42 -07004239
Matus Fabian229c1aa2018-05-28 04:09:52 -07004240 # FIN+ACK packet in -> out
4241 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
4242 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
4243 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
4244 flags="FA", seq=300, ack=101))
Matus Fabianebdf1902018-05-04 03:57:42 -07004245
Matus Fabian229c1aa2018-05-28 04:09:52 -07004246 self.pg0.add_stream(p)
4247 self.pg_enable_capture(self.pg_interfaces)
4248 self.pg_start()
4249 self.pg1.get_capture(1)
Matus Fabianebdf1902018-05-04 03:57:42 -07004250
Matus Fabian229c1aa2018-05-28 04:09:52 -07004251 # ACK packet out -> in
4252 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
4253 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
4254 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
4255 flags="A", seq=101, ack=301))
4256 self.pg1.add_stream(p)
4257 self.pg_enable_capture(self.pg_interfaces)
4258 self.pg_start()
4259 self.pg0.get_capture(1)
Matus Fabianebdf1902018-05-04 03:57:42 -07004260
Matus Fabian229c1aa2018-05-28 04:09:52 -07004261 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n,
4262 0)
4263 self.assertEqual(len(sessions) - start_sessnum, 0)
Matus Fabianebdf1902018-05-04 03:57:42 -07004264
4265 def test_tcp_session_close_simultaneous(self):
4266 """ Close TCP session from inside network """
Matus Fabian229c1aa2018-05-28 04:09:52 -07004267 self.tcp_port_out = 10505
Matus Fabianebdf1902018-05-04 03:57:42 -07004268 self.nat44_add_address(self.nat_addr)
Matus Fabian229c1aa2018-05-28 04:09:52 -07004269 self.nat44_add_static_mapping(self.pg0.remote_ip4,
4270 self.nat_addr,
4271 self.tcp_port_in,
4272 self.tcp_port_out,
4273 proto=IP_PROTOS.tcp,
4274 twice_nat=1)
Matus Fabianebdf1902018-05-04 03:57:42 -07004275 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
4276 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
4277 is_inside=0)
4278
4279 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n, 0)
4280 start_sessnum = len(sessions)
4281
4282 self.initiate_tcp_session(self.pg0, self.pg1)
4283
Matus Fabian229c1aa2018-05-28 04:09:52 -07004284 # FIN packet in -> out
4285 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
4286 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
4287 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
4288 flags="FA", seq=100, ack=300))
4289 self.pg0.add_stream(p)
4290 self.pg_enable_capture(self.pg_interfaces)
4291 self.pg_start()
4292 self.pg1.get_capture(1)
Matus Fabianebdf1902018-05-04 03:57:42 -07004293
Matus Fabian229c1aa2018-05-28 04:09:52 -07004294 # FIN packet out -> in
4295 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
4296 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
4297 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
4298 flags="FA", seq=300, ack=100))
4299 self.pg1.add_stream(p)
4300 self.pg_enable_capture(self.pg_interfaces)
4301 self.pg_start()
4302 self.pg0.get_capture(1)
Matus Fabianebdf1902018-05-04 03:57:42 -07004303
Matus Fabian229c1aa2018-05-28 04:09:52 -07004304 # ACK packet in -> out
4305 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
4306 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
4307 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
4308 flags="A", seq=101, ack=301))
4309 self.pg0.add_stream(p)
4310 self.pg_enable_capture(self.pg_interfaces)
4311 self.pg_start()
4312 self.pg1.get_capture(1)
Matus Fabianebdf1902018-05-04 03:57:42 -07004313
Matus Fabian229c1aa2018-05-28 04:09:52 -07004314 # ACK packet out -> in
4315 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
4316 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
4317 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
4318 flags="A", seq=301, ack=101))
4319 self.pg1.add_stream(p)
4320 self.pg_enable_capture(self.pg_interfaces)
4321 self.pg_start()
4322 self.pg0.get_capture(1)
Matus Fabianebdf1902018-05-04 03:57:42 -07004323
Matus Fabian229c1aa2018-05-28 04:09:52 -07004324 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n,
4325 0)
4326 self.assertEqual(len(sessions) - start_sessnum, 0)
Matus Fabianebdf1902018-05-04 03:57:42 -07004327
Matus Fabiana6110b62018-06-13 05:39:07 -07004328 def test_one_armed_nat44_static(self):
4329 """ One armed NAT44 and 1:1 NAPT asymmetrical rule """
4330 remote_host = self.pg4.remote_hosts[0]
4331 local_host = self.pg4.remote_hosts[1]
4332 external_port = 80
4333 local_port = 8080
4334 eh_port_in = 0
4335
4336 self.vapi.nat44_forwarding_enable_disable(1)
4337 self.nat44_add_address(self.nat_addr, twice_nat=1)
4338 self.nat44_add_static_mapping(local_host.ip4, self.nat_addr,
4339 local_port, external_port,
4340 proto=IP_PROTOS.tcp, out2in_only=1,
4341 twice_nat=1)
4342 self.vapi.nat44_interface_add_del_feature(self.pg4.sw_if_index)
4343 self.vapi.nat44_interface_add_del_feature(self.pg4.sw_if_index,
4344 is_inside=0)
4345
4346 # from client to service
4347 p = (Ether(src=self.pg4.remote_mac, dst=self.pg4.local_mac) /
4348 IP(src=remote_host.ip4, dst=self.nat_addr) /
4349 TCP(sport=12345, dport=external_port))
4350 self.pg4.add_stream(p)
4351 self.pg_enable_capture(self.pg_interfaces)
4352 self.pg_start()
4353 capture = self.pg4.get_capture(1)
4354 p = capture[0]
4355 try:
4356 ip = p[IP]
4357 tcp = p[TCP]
4358 self.assertEqual(ip.dst, local_host.ip4)
4359 self.assertEqual(ip.src, self.nat_addr)
4360 self.assertEqual(tcp.dport, local_port)
4361 self.assertNotEqual(tcp.sport, 12345)
4362 eh_port_in = tcp.sport
4363 self.assert_packet_checksums_valid(p)
4364 except:
4365 self.logger.error(ppp("Unexpected or invalid packet:", p))
4366 raise
4367
4368 # from service back to client
4369 p = (Ether(src=self.pg4.remote_mac, dst=self.pg4.local_mac) /
4370 IP(src=local_host.ip4, dst=self.nat_addr) /
4371 TCP(sport=local_port, dport=eh_port_in))
4372 self.pg4.add_stream(p)
4373 self.pg_enable_capture(self.pg_interfaces)
4374 self.pg_start()
4375 capture = self.pg4.get_capture(1)
4376 p = capture[0]
4377 try:
4378 ip = p[IP]
4379 tcp = p[TCP]
4380 self.assertEqual(ip.src, self.nat_addr)
4381 self.assertEqual(ip.dst, remote_host.ip4)
4382 self.assertEqual(tcp.sport, external_port)
4383 self.assertEqual(tcp.dport, 12345)
4384 self.assert_packet_checksums_valid(p)
4385 except:
4386 self.logger.error(ppp("Unexpected or invalid packet:", p))
4387 raise
4388
4389 def test_static_with_port_out2(self):
4390 """ 1:1 NAPT asymmetrical rule """
4391
4392 external_port = 80
4393 local_port = 8080
4394
4395 self.vapi.nat44_forwarding_enable_disable(1)
4396 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
4397 local_port, external_port,
4398 proto=IP_PROTOS.tcp, out2in_only=1)
4399 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
4400 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
4401 is_inside=0)
4402
4403 # from client to service
4404 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
4405 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
4406 TCP(sport=12345, dport=external_port))
4407 self.pg1.add_stream(p)
4408 self.pg_enable_capture(self.pg_interfaces)
4409 self.pg_start()
4410 capture = self.pg0.get_capture(1)
4411 p = capture[0]
4412 try:
4413 ip = p[IP]
4414 tcp = p[TCP]
4415 self.assertEqual(ip.dst, self.pg0.remote_ip4)
4416 self.assertEqual(tcp.dport, local_port)
4417 self.assert_packet_checksums_valid(p)
4418 except:
4419 self.logger.error(ppp("Unexpected or invalid packet:", p))
4420 raise
4421
4422 # ICMP error
4423 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
4424 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
4425 ICMP(type=11) / capture[0][IP])
4426 self.pg0.add_stream(p)
4427 self.pg_enable_capture(self.pg_interfaces)
4428 self.pg_start()
4429 capture = self.pg1.get_capture(1)
4430 p = capture[0]
4431 try:
4432 self.assertEqual(p[IP].src, self.nat_addr)
4433 inner = p[IPerror]
4434 self.assertEqual(inner.dst, self.nat_addr)
4435 self.assertEqual(inner[TCPerror].dport, external_port)
4436 except:
4437 self.logger.error(ppp("Unexpected or invalid packet:", p))
4438 raise
4439
4440 # from service back to client
4441 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
4442 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
4443 TCP(sport=local_port, dport=12345))
4444 self.pg0.add_stream(p)
4445 self.pg_enable_capture(self.pg_interfaces)
4446 self.pg_start()
4447 capture = self.pg1.get_capture(1)
4448 p = capture[0]
4449 try:
4450 ip = p[IP]
4451 tcp = p[TCP]
4452 self.assertEqual(ip.src, self.nat_addr)
4453 self.assertEqual(tcp.sport, external_port)
4454 self.assert_packet_checksums_valid(p)
4455 except:
4456 self.logger.error(ppp("Unexpected or invalid packet:", p))
4457 raise
4458
4459 # ICMP error
4460 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
4461 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
4462 ICMP(type=11) / capture[0][IP])
4463 self.pg1.add_stream(p)
4464 self.pg_enable_capture(self.pg_interfaces)
4465 self.pg_start()
4466 capture = self.pg0.get_capture(1)
4467 p = capture[0]
4468 try:
4469 self.assertEqual(p[IP].dst, self.pg0.remote_ip4)
4470 inner = p[IPerror]
4471 self.assertEqual(inner.src, self.pg0.remote_ip4)
4472 self.assertEqual(inner[TCPerror].sport, local_port)
4473 except:
4474 self.logger.error(ppp("Unexpected or invalid packet:", p))
4475 raise
4476
4477 # from client to server (no translation)
4478 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
4479 IP(src=self.pg1.remote_ip4, dst=self.pg0.remote_ip4) /
4480 TCP(sport=12346, dport=local_port))
4481 self.pg1.add_stream(p)
4482 self.pg_enable_capture(self.pg_interfaces)
4483 self.pg_start()
4484 capture = self.pg0.get_capture(1)
4485 p = capture[0]
4486 try:
4487 ip = p[IP]
4488 tcp = p[TCP]
4489 self.assertEqual(ip.dst, self.pg0.remote_ip4)
4490 self.assertEqual(tcp.dport, local_port)
4491 self.assert_packet_checksums_valid(p)
4492 except:
4493 self.logger.error(ppp("Unexpected or invalid packet:", p))
4494 raise
4495
4496 # from service back to client (no translation)
4497 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
4498 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
4499 TCP(sport=local_port, dport=12346))
4500 self.pg0.add_stream(p)
4501 self.pg_enable_capture(self.pg_interfaces)
4502 self.pg_start()
4503 capture = self.pg1.get_capture(1)
4504 p = capture[0]
4505 try:
4506 ip = p[IP]
4507 tcp = p[TCP]
4508 self.assertEqual(ip.src, self.pg0.remote_ip4)
4509 self.assertEqual(tcp.sport, local_port)
4510 self.assert_packet_checksums_valid(p)
4511 except:
4512 self.logger.error(ppp("Unexpected or invalid packet:", p))
4513 raise
4514
Matus Fabian235a47e2018-06-25 16:42:36 -07004515 def test_output_feature(self):
4516 """ NAT44 interface output feature (in2out postrouting) """
4517 self.vapi.nat44_forwarding_enable_disable(1)
4518 self.nat44_add_address(self.nat_addr)
4519 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index,
4520 is_inside=0)
4521 self.vapi.nat44_interface_add_del_output_feature(self.pg1.sw_if_index,
4522 is_inside=0)
4523
4524 # in2out
4525 pkts = self.create_stream_in(self.pg0, self.pg1)
4526 self.pg0.add_stream(pkts)
4527 self.pg_enable_capture(self.pg_interfaces)
4528 self.pg_start()
4529 capture = self.pg1.get_capture(len(pkts))
4530 self.verify_capture_out(capture)
4531
4532 # out2in
4533 pkts = self.create_stream_out(self.pg1)
4534 self.pg1.add_stream(pkts)
4535 self.pg_enable_capture(self.pg_interfaces)
4536 self.pg_start()
4537 capture = self.pg0.get_capture(len(pkts))
4538 self.verify_capture_in(capture, self.pg0)
4539
Matus Fabian8008d7c2018-07-09 01:34:20 -07004540 def test_multiple_vrf(self):
4541 """ Multiple VRF setup """
4542 external_addr = '1.2.3.4'
4543 external_port = 80
4544 local_port = 8080
4545 port = 0
4546
4547 self.vapi.nat44_forwarding_enable_disable(1)
4548 self.nat44_add_address(self.nat_addr)
4549 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
4550 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index,
4551 is_inside=0)
4552 self.vapi.nat44_interface_add_del_output_feature(self.pg1.sw_if_index,
4553 is_inside=0)
4554 self.vapi.nat44_interface_add_del_feature(self.pg5.sw_if_index)
4555 self.vapi.nat44_interface_add_del_feature(self.pg5.sw_if_index,
4556 is_inside=0)
4557 self.vapi.nat44_interface_add_del_feature(self.pg6.sw_if_index,
4558 is_inside=0)
4559 self.nat44_add_static_mapping(self.pg5.remote_ip4, external_addr,
4560 local_port, external_port, vrf_id=1,
4561 proto=IP_PROTOS.tcp, out2in_only=1)
4562 self.nat44_add_static_mapping(
4563 self.pg0.remote_ip4, external_sw_if_index=self.pg0.sw_if_index,
4564 local_port=local_port, vrf_id=0, external_port=external_port,
4565 proto=IP_PROTOS.tcp, out2in_only=1)
4566
4567 # from client to service (both VRF1)
4568 p = (Ether(src=self.pg6.remote_mac, dst=self.pg6.local_mac) /
4569 IP(src=self.pg6.remote_ip4, dst=external_addr) /
4570 TCP(sport=12345, dport=external_port))
4571 self.pg6.add_stream(p)
4572 self.pg_enable_capture(self.pg_interfaces)
4573 self.pg_start()
4574 capture = self.pg5.get_capture(1)
4575 p = capture[0]
4576 try:
4577 ip = p[IP]
4578 tcp = p[TCP]
4579 self.assertEqual(ip.dst, self.pg5.remote_ip4)
4580 self.assertEqual(tcp.dport, local_port)
4581 self.assert_packet_checksums_valid(p)
4582 except:
4583 self.logger.error(ppp("Unexpected or invalid packet:", p))
4584 raise
4585
4586 # from service back to client (both VRF1)
4587 p = (Ether(src=self.pg5.remote_mac, dst=self.pg5.local_mac) /
4588 IP(src=self.pg5.remote_ip4, dst=self.pg6.remote_ip4) /
4589 TCP(sport=local_port, dport=12345))
4590 self.pg5.add_stream(p)
4591 self.pg_enable_capture(self.pg_interfaces)
4592 self.pg_start()
4593 capture = self.pg6.get_capture(1)
4594 p = capture[0]
4595 try:
4596 ip = p[IP]
4597 tcp = p[TCP]
4598 self.assertEqual(ip.src, external_addr)
4599 self.assertEqual(tcp.sport, external_port)
4600 self.assert_packet_checksums_valid(p)
4601 except:
4602 self.logger.error(ppp("Unexpected or invalid packet:", p))
4603 raise
4604
4605 # dynamic NAT from VRF1 to VRF0 (output-feature)
4606 p = (Ether(src=self.pg5.remote_mac, dst=self.pg5.local_mac) /
4607 IP(src=self.pg5.remote_ip4, dst=self.pg1.remote_ip4) /
4608 TCP(sport=2345, dport=22))
4609 self.pg5.add_stream(p)
4610 self.pg_enable_capture(self.pg_interfaces)
4611 self.pg_start()
4612 capture = self.pg1.get_capture(1)
4613 p = capture[0]
4614 try:
4615 ip = p[IP]
4616 tcp = p[TCP]
4617 self.assertEqual(ip.src, self.nat_addr)
4618 self.assertNotEqual(tcp.sport, 2345)
4619 self.assert_packet_checksums_valid(p)
4620 port = tcp.sport
4621 except:
4622 self.logger.error(ppp("Unexpected or invalid packet:", p))
4623 raise
4624
4625 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
4626 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
4627 TCP(sport=22, dport=port))
4628 self.pg1.add_stream(p)
4629 self.pg_enable_capture(self.pg_interfaces)
4630 self.pg_start()
4631 capture = self.pg5.get_capture(1)
4632 p = capture[0]
4633 try:
4634 ip = p[IP]
4635 tcp = p[TCP]
4636 self.assertEqual(ip.dst, self.pg5.remote_ip4)
4637 self.assertEqual(tcp.dport, 2345)
4638 self.assert_packet_checksums_valid(p)
4639 except:
4640 self.logger.error(ppp("Unexpected or invalid packet:", p))
4641 raise
4642
4643 # from client VRF1 to service VRF0
4644 p = (Ether(src=self.pg6.remote_mac, dst=self.pg6.local_mac) /
4645 IP(src=self.pg6.remote_ip4, dst=self.pg0.local_ip4) /
4646 TCP(sport=12346, dport=external_port))
4647 self.pg6.add_stream(p)
4648 self.pg_enable_capture(self.pg_interfaces)
4649 self.pg_start()
4650 capture = self.pg0.get_capture(1)
4651 p = capture[0]
4652 try:
4653 ip = p[IP]
4654 tcp = p[TCP]
4655 self.assertEqual(ip.dst, self.pg0.remote_ip4)
4656 self.assertEqual(tcp.dport, local_port)
4657 self.assert_packet_checksums_valid(p)
4658 except:
4659 self.logger.error(ppp("Unexpected or invalid packet:", p))
4660 raise
4661
4662 # from service VRF0 back to client VRF1
4663 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
4664 IP(src=self.pg0.remote_ip4, dst=self.pg6.remote_ip4) /
4665 TCP(sport=local_port, dport=12346))
4666 self.pg0.add_stream(p)
4667 self.pg_enable_capture(self.pg_interfaces)
4668 self.pg_start()
4669 capture = self.pg6.get_capture(1)
4670 p = capture[0]
4671 try:
4672 ip = p[IP]
4673 tcp = p[TCP]
4674 self.assertEqual(ip.src, self.pg0.local_ip4)
4675 self.assertEqual(tcp.sport, external_port)
4676 self.assert_packet_checksums_valid(p)
4677 except:
4678 self.logger.error(ppp("Unexpected or invalid packet:", p))
4679 raise
4680
4681 # from client VRF0 to service VRF1
4682 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
4683 IP(src=self.pg0.remote_ip4, dst=external_addr) /
4684 TCP(sport=12347, dport=external_port))
4685 self.pg0.add_stream(p)
4686 self.pg_enable_capture(self.pg_interfaces)
4687 self.pg_start()
4688 capture = self.pg5.get_capture(1)
4689 p = capture[0]
4690 try:
4691 ip = p[IP]
4692 tcp = p[TCP]
4693 self.assertEqual(ip.dst, self.pg5.remote_ip4)
4694 self.assertEqual(tcp.dport, local_port)
4695 self.assert_packet_checksums_valid(p)
4696 except:
4697 self.logger.error(ppp("Unexpected or invalid packet:", p))
4698 raise
4699
4700 # from service VRF1 back to client VRF0
4701 p = (Ether(src=self.pg5.remote_mac, dst=self.pg5.local_mac) /
4702 IP(src=self.pg5.remote_ip4, dst=self.pg0.remote_ip4) /
4703 TCP(sport=local_port, dport=12347))
4704 self.pg5.add_stream(p)
4705 self.pg_enable_capture(self.pg_interfaces)
4706 self.pg_start()
4707 capture = self.pg0.get_capture(1)
4708 p = capture[0]
4709 try:
4710 ip = p[IP]
4711 tcp = p[TCP]
4712 self.assertEqual(ip.src, external_addr)
4713 self.assertEqual(tcp.sport, external_port)
4714 self.assert_packet_checksums_valid(p)
4715 except:
4716 self.logger.error(ppp("Unexpected or invalid packet:", p))
4717 raise
4718
4719 # from client to server (both VRF1, no translation)
4720 p = (Ether(src=self.pg6.remote_mac, dst=self.pg6.local_mac) /
4721 IP(src=self.pg6.remote_ip4, dst=self.pg5.remote_ip4) /
4722 TCP(sport=12348, dport=local_port))
4723 self.pg6.add_stream(p)
4724 self.pg_enable_capture(self.pg_interfaces)
4725 self.pg_start()
4726 capture = self.pg5.get_capture(1)
4727 p = capture[0]
4728 try:
4729 ip = p[IP]
4730 tcp = p[TCP]
4731 self.assertEqual(ip.dst, self.pg5.remote_ip4)
4732 self.assertEqual(tcp.dport, local_port)
4733 self.assert_packet_checksums_valid(p)
4734 except:
4735 self.logger.error(ppp("Unexpected or invalid packet:", p))
4736 raise
4737
4738 # from server back to client (both VRF1, no translation)
4739 p = (Ether(src=self.pg5.remote_mac, dst=self.pg5.local_mac) /
4740 IP(src=self.pg5.remote_ip4, dst=self.pg6.remote_ip4) /
4741 TCP(sport=local_port, dport=12348))
4742 self.pg5.add_stream(p)
4743 self.pg_enable_capture(self.pg_interfaces)
4744 self.pg_start()
4745 capture = self.pg6.get_capture(1)
4746 p = capture[0]
4747 try:
4748 ip = p[IP]
4749 tcp = p[TCP]
4750 self.assertEqual(ip.src, self.pg5.remote_ip4)
4751 self.assertEqual(tcp.sport, local_port)
4752 self.assert_packet_checksums_valid(p)
4753 except:
4754 self.logger.error(ppp("Unexpected or invalid packet:", p))
4755 raise
4756
4757 # from client VRF1 to server VRF0 (no translation)
4758 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
4759 IP(src=self.pg0.remote_ip4, dst=self.pg6.remote_ip4) /
4760 TCP(sport=local_port, dport=12349))
4761 self.pg0.add_stream(p)
4762 self.pg_enable_capture(self.pg_interfaces)
4763 self.pg_start()
4764 capture = self.pg6.get_capture(1)
4765 p = capture[0]
4766 try:
4767 ip = p[IP]
4768 tcp = p[TCP]
4769 self.assertEqual(ip.src, self.pg0.remote_ip4)
4770 self.assertEqual(tcp.sport, local_port)
4771 self.assert_packet_checksums_valid(p)
4772 except:
4773 self.logger.error(ppp("Unexpected or invalid packet:", p))
4774 raise
4775
4776 # from server VRF0 back to client VRF1 (no translation)
4777 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
4778 IP(src=self.pg0.remote_ip4, dst=self.pg6.remote_ip4) /
4779 TCP(sport=local_port, dport=12349))
4780 self.pg0.add_stream(p)
4781 self.pg_enable_capture(self.pg_interfaces)
4782 self.pg_start()
4783 capture = self.pg6.get_capture(1)
4784 p = capture[0]
4785 try:
4786 ip = p[IP]
4787 tcp = p[TCP]
4788 self.assertEqual(ip.src, self.pg0.remote_ip4)
4789 self.assertEqual(tcp.sport, local_port)
4790 self.assert_packet_checksums_valid(p)
4791 except:
4792 self.logger.error(ppp("Unexpected or invalid packet:", p))
4793 raise
4794
4795 # from client VRF0 to server VRF1 (no translation)
4796 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
4797 IP(src=self.pg0.remote_ip4, dst=self.pg5.remote_ip4) /
4798 TCP(sport=12344, dport=local_port))
4799 self.pg0.add_stream(p)
4800 self.pg_enable_capture(self.pg_interfaces)
4801 self.pg_start()
4802 capture = self.pg5.get_capture(1)
4803 p = capture[0]
4804 try:
4805 ip = p[IP]
4806 tcp = p[TCP]
4807 self.assertEqual(ip.dst, self.pg5.remote_ip4)
4808 self.assertEqual(tcp.dport, local_port)
4809 self.assert_packet_checksums_valid(p)
4810 except:
4811 self.logger.error(ppp("Unexpected or invalid packet:", p))
4812 raise
4813
4814 # from server VRF1 back to client VRF0 (no translation)
4815 p = (Ether(src=self.pg5.remote_mac, dst=self.pg5.local_mac) /
4816 IP(src=self.pg5.remote_ip4, dst=self.pg0.remote_ip4) /
4817 TCP(sport=local_port, dport=12344))
4818 self.pg5.add_stream(p)
4819 self.pg_enable_capture(self.pg_interfaces)
4820 self.pg_start()
4821 capture = self.pg0.get_capture(1)
4822 p = capture[0]
4823 try:
4824 ip = p[IP]
4825 tcp = p[TCP]
4826 self.assertEqual(ip.src, self.pg5.remote_ip4)
4827 self.assertEqual(tcp.sport, local_port)
4828 self.assert_packet_checksums_valid(p)
4829 except:
4830 self.logger.error(ppp("Unexpected or invalid packet:", p))
4831 raise
4832
Matus Fabiande886752016-12-07 03:38:19 -08004833 def tearDown(self):
Matus Fabiana6110b62018-06-13 05:39:07 -07004834 super(TestNAT44EndpointDependent, self).tearDown()
Matus Fabiande886752016-12-07 03:38:19 -08004835 if not self.vpp_dead:
Matus Fabian82119542018-01-25 01:13:22 -08004836 self.logger.info(self.vapi.cli("show nat44 addresses"))
4837 self.logger.info(self.vapi.cli("show nat44 interfaces"))
4838 self.logger.info(self.vapi.cli("show nat44 static mappings"))
4839 self.logger.info(self.vapi.cli("show nat44 interface address"))
4840 self.logger.info(self.vapi.cli("show nat44 sessions detail"))
Matus Fabian229c1aa2018-05-28 04:09:52 -07004841 self.logger.info(self.vapi.cli("show nat44 hash tables detail"))
Matus Fabian2ba92e32017-08-21 07:05:03 -07004842 self.clear_nat44()
Matus Fabian229c1aa2018-05-28 04:09:52 -07004843 self.vapi.cli("clear logging")
Matus Fabiande886752016-12-07 03:38:19 -08004844
Matus Fabianeea28d72017-01-13 04:15:54 -08004845
Juraj Slobodacba69362017-12-19 02:09:32 +01004846class TestNAT44Out2InDPO(MethodHolder):
4847 """ NAT44 Test Cases using out2in DPO """
4848
4849 @classmethod
4850 def setUpConstants(cls):
4851 super(TestNAT44Out2InDPO, cls).setUpConstants()
4852 cls.vpp_cmdline.extend(["nat", "{", "out2in dpo", "}"])
4853
4854 @classmethod
4855 def setUpClass(cls):
4856 super(TestNAT44Out2InDPO, cls).setUpClass()
Matus Fabian229c1aa2018-05-28 04:09:52 -07004857 cls.vapi.cli("set log class nat level debug")
Juraj Slobodacba69362017-12-19 02:09:32 +01004858
4859 try:
4860 cls.tcp_port_in = 6303
4861 cls.tcp_port_out = 6303
4862 cls.udp_port_in = 6304
4863 cls.udp_port_out = 6304
4864 cls.icmp_id_in = 6305
4865 cls.icmp_id_out = 6305
4866 cls.nat_addr = '10.0.0.3'
4867 cls.nat_addr_n = socket.inet_pton(socket.AF_INET, cls.nat_addr)
4868 cls.dst_ip4 = '192.168.70.1'
4869
4870 cls.create_pg_interfaces(range(2))
4871
4872 cls.pg0.admin_up()
4873 cls.pg0.config_ip4()
4874 cls.pg0.resolve_arp()
4875
4876 cls.pg1.admin_up()
4877 cls.pg1.config_ip6()
4878 cls.pg1.resolve_ndp()
4879
4880 cls.vapi.ip_add_del_route(is_ipv6=True, dst_address='\x00'*16,
4881 dst_address_length=0,
4882 next_hop_address=cls.pg1.remote_ip6n,
4883 next_hop_sw_if_index=cls.pg1.sw_if_index)
4884
4885 except Exception:
4886 super(TestNAT44Out2InDPO, cls).tearDownClass()
4887 raise
4888
4889 def configure_xlat(self):
4890 self.dst_ip6_pfx = '1:2:3::'
4891 self.dst_ip6_pfx_n = socket.inet_pton(socket.AF_INET6,
4892 self.dst_ip6_pfx)
4893 self.dst_ip6_pfx_len = 96
4894 self.src_ip6_pfx = '4:5:6::'
4895 self.src_ip6_pfx_n = socket.inet_pton(socket.AF_INET6,
4896 self.src_ip6_pfx)
4897 self.src_ip6_pfx_len = 96
4898 self.vapi.map_add_domain(self.dst_ip6_pfx_n, self.dst_ip6_pfx_len,
4899 self.src_ip6_pfx_n, self.src_ip6_pfx_len,
4900 '\x00\x00\x00\x00', 0, is_translation=1,
4901 is_rfc6052=1)
4902
4903 def test_464xlat_ce(self):
4904 """ Test 464XLAT CE with NAT44 """
4905
4906 self.configure_xlat()
4907
4908 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
4909 self.vapi.nat44_add_del_address_range(self.nat_addr_n, self.nat_addr_n)
4910
4911 out_src_ip6 = self.compose_ip6(self.dst_ip4, self.dst_ip6_pfx,
4912 self.dst_ip6_pfx_len)
4913 out_dst_ip6 = self.compose_ip6(self.nat_addr, self.src_ip6_pfx,
4914 self.src_ip6_pfx_len)
4915
4916 try:
4917 pkts = self.create_stream_in(self.pg0, self.pg1, self.dst_ip4)
4918 self.pg0.add_stream(pkts)
4919 self.pg_enable_capture(self.pg_interfaces)
4920 self.pg_start()
4921 capture = self.pg1.get_capture(len(pkts))
4922 self.verify_capture_out_ip6(capture, nat_ip=out_dst_ip6,
4923 dst_ip=out_src_ip6)
4924
4925 pkts = self.create_stream_out_ip6(self.pg1, out_src_ip6,
4926 out_dst_ip6)
4927 self.pg1.add_stream(pkts)
4928 self.pg_enable_capture(self.pg_interfaces)
4929 self.pg_start()
4930 capture = self.pg0.get_capture(len(pkts))
4931 self.verify_capture_in(capture, self.pg0)
4932 finally:
4933 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index,
4934 is_add=0)
4935 self.vapi.nat44_add_del_address_range(self.nat_addr_n,
4936 self.nat_addr_n, is_add=0)
4937
4938 def test_464xlat_ce_no_nat(self):
4939 """ Test 464XLAT CE without NAT44 """
4940
4941 self.configure_xlat()
4942
4943 out_src_ip6 = self.compose_ip6(self.dst_ip4, self.dst_ip6_pfx,
4944 self.dst_ip6_pfx_len)
4945 out_dst_ip6 = self.compose_ip6(self.pg0.remote_ip4, self.src_ip6_pfx,
4946 self.src_ip6_pfx_len)
4947
4948 pkts = self.create_stream_in(self.pg0, self.pg1, self.dst_ip4)
4949 self.pg0.add_stream(pkts)
4950 self.pg_enable_capture(self.pg_interfaces)
4951 self.pg_start()
4952 capture = self.pg1.get_capture(len(pkts))
4953 self.verify_capture_out_ip6(capture, dst_ip=out_src_ip6,
4954 nat_ip=out_dst_ip6, same_port=True)
4955
4956 pkts = self.create_stream_out_ip6(self.pg1, out_src_ip6, out_dst_ip6)
4957 self.pg1.add_stream(pkts)
4958 self.pg_enable_capture(self.pg_interfaces)
4959 self.pg_start()
4960 capture = self.pg0.get_capture(len(pkts))
4961 self.verify_capture_in(capture, self.pg0)
4962
4963
Martin Gálikd7f75cd2017-03-27 06:02:47 -07004964class TestDeterministicNAT(MethodHolder):
Matus Fabian066f0342017-02-10 03:48:01 -08004965 """ Deterministic NAT Test Cases """
4966
4967 @classmethod
4968 def setUpConstants(cls):
4969 super(TestDeterministicNAT, cls).setUpConstants()
Matus Fabian2ba92e32017-08-21 07:05:03 -07004970 cls.vpp_cmdline.extend(["nat", "{", "deterministic", "}"])
Matus Fabian066f0342017-02-10 03:48:01 -08004971
4972 @classmethod
4973 def setUpClass(cls):
4974 super(TestDeterministicNAT, cls).setUpClass()
Matus Fabian229c1aa2018-05-28 04:09:52 -07004975 cls.vapi.cli("set log class nat level debug")
Matus Fabian066f0342017-02-10 03:48:01 -08004976
4977 try:
Martin Gálik977c1cb2017-03-30 23:21:51 -07004978 cls.tcp_port_in = 6303
Martin Gálik9806eae2017-04-25 01:25:08 -07004979 cls.tcp_external_port = 6303
Martin Gálik977c1cb2017-03-30 23:21:51 -07004980 cls.udp_port_in = 6304
Martin Gálik9806eae2017-04-25 01:25:08 -07004981 cls.udp_external_port = 6304
Martin Gálik977c1cb2017-03-30 23:21:51 -07004982 cls.icmp_id_in = 6305
Matus Fabian2ba92e32017-08-21 07:05:03 -07004983 cls.nat_addr = '10.0.0.3'
Martin Gálik977c1cb2017-03-30 23:21:51 -07004984
Matus Fabian2f2db1c2017-04-18 05:29:59 -07004985 cls.create_pg_interfaces(range(3))
Matus Fabian066f0342017-02-10 03:48:01 -08004986 cls.interfaces = list(cls.pg_interfaces)
4987
4988 for i in cls.interfaces:
4989 i.admin_up()
4990 i.config_ip4()
4991 i.resolve_arp()
4992
Martin Gálik977c1cb2017-03-30 23:21:51 -07004993 cls.pg0.generate_remote_hosts(2)
4994 cls.pg0.configure_ipv4_neighbors()
4995
Matus Fabian066f0342017-02-10 03:48:01 -08004996 except Exception:
4997 super(TestDeterministicNAT, cls).tearDownClass()
4998 raise
4999
Martin Gálik977c1cb2017-03-30 23:21:51 -07005000 def create_stream_in(self, in_if, out_if, ttl=64):
5001 """
5002 Create packet stream for inside network
5003
5004 :param in_if: Inside interface
5005 :param out_if: Outside interface
5006 :param ttl: TTL of generated packets
5007 """
5008 pkts = []
5009 # TCP
5010 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
5011 IP(src=in_if.remote_ip4, dst=out_if.remote_ip4, ttl=ttl) /
Martin Gálik9806eae2017-04-25 01:25:08 -07005012 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port))
Martin Gálik977c1cb2017-03-30 23:21:51 -07005013 pkts.append(p)
5014
5015 # UDP
5016 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
5017 IP(src=in_if.remote_ip4, dst=out_if.remote_ip4, ttl=ttl) /
Martin Gálik9806eae2017-04-25 01:25:08 -07005018 UDP(sport=self.udp_port_in, dport=self.udp_external_port))
Martin Gálik977c1cb2017-03-30 23:21:51 -07005019 pkts.append(p)
5020
5021 # ICMP
5022 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
5023 IP(src=in_if.remote_ip4, dst=out_if.remote_ip4, ttl=ttl) /
5024 ICMP(id=self.icmp_id_in, type='echo-request'))
5025 pkts.append(p)
5026
5027 return pkts
5028
5029 def create_stream_out(self, out_if, dst_ip=None, ttl=64):
5030 """
5031 Create packet stream for outside network
5032
5033 :param out_if: Outside interface
Matus Fabian2ba92e32017-08-21 07:05:03 -07005034 :param dst_ip: Destination IP address (Default use global NAT address)
Martin Gálik977c1cb2017-03-30 23:21:51 -07005035 :param ttl: TTL of generated packets
5036 """
5037 if dst_ip is None:
Matus Fabian2ba92e32017-08-21 07:05:03 -07005038 dst_ip = self.nat_addr
Martin Gálik977c1cb2017-03-30 23:21:51 -07005039 pkts = []
5040 # TCP
5041 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
5042 IP(src=out_if.remote_ip4, dst=dst_ip, ttl=ttl) /
Martin Gálik9806eae2017-04-25 01:25:08 -07005043 TCP(dport=self.tcp_port_out, sport=self.tcp_external_port))
Martin Gálik977c1cb2017-03-30 23:21:51 -07005044 pkts.append(p)
5045
5046 # UDP
5047 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
5048 IP(src=out_if.remote_ip4, dst=dst_ip, ttl=ttl) /
Martin Gálik9806eae2017-04-25 01:25:08 -07005049 UDP(dport=self.udp_port_out, sport=self.udp_external_port))
Martin Gálik977c1cb2017-03-30 23:21:51 -07005050 pkts.append(p)
5051
5052 # ICMP
5053 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
5054 IP(src=out_if.remote_ip4, dst=dst_ip, ttl=ttl) /
5055 ICMP(id=self.icmp_external_id, type='echo-reply'))
5056 pkts.append(p)
5057
5058 return pkts
5059
5060 def verify_capture_out(self, capture, nat_ip=None, packet_num=3):
5061 """
5062 Verify captured packets on outside network
5063
5064 :param capture: Captured packets
Matus Fabian2ba92e32017-08-21 07:05:03 -07005065 :param nat_ip: Translated IP address (Default use global NAT address)
Martin Gálik977c1cb2017-03-30 23:21:51 -07005066 :param same_port: Sorce port number is not translated (Default False)
5067 :param packet_num: Expected number of packets (Default 3)
5068 """
5069 if nat_ip is None:
Matus Fabian2ba92e32017-08-21 07:05:03 -07005070 nat_ip = self.nat_addr
Martin Gálik977c1cb2017-03-30 23:21:51 -07005071 self.assertEqual(packet_num, len(capture))
5072 for packet in capture:
5073 try:
5074 self.assertEqual(packet[IP].src, nat_ip)
5075 if packet.haslayer(TCP):
Martin Gálik9806eae2017-04-25 01:25:08 -07005076 self.tcp_port_out = packet[TCP].sport
Martin Gálik977c1cb2017-03-30 23:21:51 -07005077 elif packet.haslayer(UDP):
Martin Gálik9806eae2017-04-25 01:25:08 -07005078 self.udp_port_out = packet[UDP].sport
Martin Gálik977c1cb2017-03-30 23:21:51 -07005079 else:
5080 self.icmp_external_id = packet[ICMP].id
5081 except:
5082 self.logger.error(ppp("Unexpected or invalid packet "
5083 "(outside network):", packet))
5084 raise
5085
Matus Fabian2f2db1c2017-04-18 05:29:59 -07005086 def verify_ipfix_max_entries_per_user(self, data):
5087 """
5088 Verify IPFIX maximum entries per user exceeded event
5089
5090 :param data: Decoded IPFIX data records
5091 """
5092 self.assertEqual(1, len(data))
5093 record = data[0]
5094 # natEvent
5095 self.assertEqual(ord(record[230]), 13)
5096 # natQuotaExceededEvent
5097 self.assertEqual('\x03\x00\x00\x00', record[466])
Matus Fabiana431ad12018-01-04 04:03:14 -08005098 # maxEntriesPerUser
5099 self.assertEqual('\xe8\x03\x00\x00', record[473])
Matus Fabian2f2db1c2017-04-18 05:29:59 -07005100 # sourceIPv4Address
5101 self.assertEqual(self.pg0.remote_ip4n, record[8])
5102
Matus Fabian066f0342017-02-10 03:48:01 -08005103 def test_deterministic_mode(self):
Matus Fabian2ba92e32017-08-21 07:05:03 -07005104 """ NAT plugin run deterministic mode """
Matus Fabian066f0342017-02-10 03:48:01 -08005105 in_addr = '172.16.255.0'
5106 out_addr = '172.17.255.50'
5107 in_addr_t = '172.16.255.20'
5108 in_addr_n = socket.inet_aton(in_addr)
5109 out_addr_n = socket.inet_aton(out_addr)
5110 in_addr_t_n = socket.inet_aton(in_addr_t)
5111 in_plen = 24
5112 out_plen = 32
5113
Matus Fabian2ba92e32017-08-21 07:05:03 -07005114 nat_config = self.vapi.nat_show_config()
5115 self.assertEqual(1, nat_config.deterministic)
Matus Fabian066f0342017-02-10 03:48:01 -08005116
Matus Fabian2ba92e32017-08-21 07:05:03 -07005117 self.vapi.nat_det_add_del_map(in_addr_n, in_plen, out_addr_n, out_plen)
Matus Fabian066f0342017-02-10 03:48:01 -08005118
Matus Fabian2ba92e32017-08-21 07:05:03 -07005119 rep1 = self.vapi.nat_det_forward(in_addr_t_n)
Matus Fabian066f0342017-02-10 03:48:01 -08005120 self.assertEqual(rep1.out_addr[:4], out_addr_n)
Matus Fabian2ba92e32017-08-21 07:05:03 -07005121 rep2 = self.vapi.nat_det_reverse(out_addr_n, rep1.out_port_hi)
Matus Fabian066f0342017-02-10 03:48:01 -08005122 self.assertEqual(rep2.in_addr[:4], in_addr_t_n)
5123
Matus Fabian2ba92e32017-08-21 07:05:03 -07005124 deterministic_mappings = self.vapi.nat_det_map_dump()
Martin17a75cb2017-03-08 05:53:20 -08005125 self.assertEqual(len(deterministic_mappings), 1)
5126 dsm = deterministic_mappings[0]
5127 self.assertEqual(in_addr_n, dsm.in_addr[:4])
5128 self.assertEqual(in_plen, dsm.in_plen)
5129 self.assertEqual(out_addr_n, dsm.out_addr[:4])
5130 self.assertEqual(out_plen, dsm.out_plen)
5131
Matus Fabian2ba92e32017-08-21 07:05:03 -07005132 self.clear_nat_det()
5133 deterministic_mappings = self.vapi.nat_det_map_dump()
Martinb616e9f2017-03-14 02:25:45 -07005134 self.assertEqual(len(deterministic_mappings), 0)
5135
Matus Fabian6a0946f2017-04-12 03:36:13 -07005136 def test_set_timeouts(self):
5137 """ Set deterministic NAT timeouts """
Matus Fabian2ba92e32017-08-21 07:05:03 -07005138 timeouts_before = self.vapi.nat_det_get_timeouts()
Matus Fabian6a0946f2017-04-12 03:36:13 -07005139
Matus Fabian2ba92e32017-08-21 07:05:03 -07005140 self.vapi.nat_det_set_timeouts(timeouts_before.udp + 10,
5141 timeouts_before.tcp_established + 10,
5142 timeouts_before.tcp_transitory + 10,
5143 timeouts_before.icmp + 10)
Matus Fabian6a0946f2017-04-12 03:36:13 -07005144
Matus Fabian2ba92e32017-08-21 07:05:03 -07005145 timeouts_after = self.vapi.nat_det_get_timeouts()
Matus Fabian6a0946f2017-04-12 03:36:13 -07005146
5147 self.assertNotEqual(timeouts_before.udp, timeouts_after.udp)
5148 self.assertNotEqual(timeouts_before.icmp, timeouts_after.icmp)
5149 self.assertNotEqual(timeouts_before.tcp_established,
5150 timeouts_after.tcp_established)
5151 self.assertNotEqual(timeouts_before.tcp_transitory,
5152 timeouts_after.tcp_transitory)
5153
Martin Gálik977c1cb2017-03-30 23:21:51 -07005154 def test_det_in(self):
Matus Fabian2ba92e32017-08-21 07:05:03 -07005155 """ Deterministic NAT translation test (TCP, UDP, ICMP) """
Martin Gálik977c1cb2017-03-30 23:21:51 -07005156
5157 nat_ip = "10.0.0.10"
Martin Gálik977c1cb2017-03-30 23:21:51 -07005158
Matus Fabian2ba92e32017-08-21 07:05:03 -07005159 self.vapi.nat_det_add_del_map(self.pg0.remote_ip4n,
5160 32,
5161 socket.inet_aton(nat_ip),
5162 32)
5163 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
5164 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
5165 is_inside=0)
Martin Gálik977c1cb2017-03-30 23:21:51 -07005166
5167 # in2out
5168 pkts = self.create_stream_in(self.pg0, self.pg1)
5169 self.pg0.add_stream(pkts)
5170 self.pg_enable_capture(self.pg_interfaces)
5171 self.pg_start()
5172 capture = self.pg1.get_capture(len(pkts))
5173 self.verify_capture_out(capture, nat_ip)
5174
5175 # out2in
5176 pkts = self.create_stream_out(self.pg1, nat_ip)
5177 self.pg1.add_stream(pkts)
5178 self.pg_enable_capture(self.pg_interfaces)
5179 self.pg_start()
5180 capture = self.pg0.get_capture(len(pkts))
5181 self.verify_capture_in(capture, self.pg0)
5182
Martin Gálik9806eae2017-04-25 01:25:08 -07005183 # session dump test
Matus Fabian2ba92e32017-08-21 07:05:03 -07005184 sessions = self.vapi.nat_det_session_dump(self.pg0.remote_ip4n)
Martin Gálik9806eae2017-04-25 01:25:08 -07005185 self.assertEqual(len(sessions), 3)
5186
5187 # TCP session
5188 s = sessions[0]
5189 self.assertEqual(s.ext_addr[:4], self.pg1.remote_ip4n)
5190 self.assertEqual(s.in_port, self.tcp_port_in)
5191 self.assertEqual(s.out_port, self.tcp_port_out)
5192 self.assertEqual(s.ext_port, self.tcp_external_port)
5193
5194 # UDP session
5195 s = sessions[1]
5196 self.assertEqual(s.ext_addr[:4], self.pg1.remote_ip4n)
5197 self.assertEqual(s.in_port, self.udp_port_in)
5198 self.assertEqual(s.out_port, self.udp_port_out)
5199 self.assertEqual(s.ext_port, self.udp_external_port)
5200
5201 # ICMP session
5202 s = sessions[2]
5203 self.assertEqual(s.ext_addr[:4], self.pg1.remote_ip4n)
5204 self.assertEqual(s.in_port, self.icmp_id_in)
5205 self.assertEqual(s.out_port, self.icmp_external_id)
5206
Martin Gálik977c1cb2017-03-30 23:21:51 -07005207 def test_multiple_users(self):
Matus Fabian2ba92e32017-08-21 07:05:03 -07005208 """ Deterministic NAT multiple users """
Martin Gálik977c1cb2017-03-30 23:21:51 -07005209
5210 nat_ip = "10.0.0.10"
5211 port_in = 80
Martin Gálik9806eae2017-04-25 01:25:08 -07005212 external_port = 6303
Martin Gálik977c1cb2017-03-30 23:21:51 -07005213
5214 host0 = self.pg0.remote_hosts[0]
5215 host1 = self.pg0.remote_hosts[1]
5216
Matus Fabian2ba92e32017-08-21 07:05:03 -07005217 self.vapi.nat_det_add_del_map(host0.ip4n,
5218 24,
5219 socket.inet_aton(nat_ip),
5220 32)
5221 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
5222 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
5223 is_inside=0)
Martin Gálik977c1cb2017-03-30 23:21:51 -07005224
5225 # host0 to out
5226 p = (Ether(src=host0.mac, dst=self.pg0.local_mac) /
5227 IP(src=host0.ip4, dst=self.pg1.remote_ip4) /
Martin Gálik9806eae2017-04-25 01:25:08 -07005228 TCP(sport=port_in, dport=external_port))
Martin Gálik977c1cb2017-03-30 23:21:51 -07005229 self.pg0.add_stream(p)
5230 self.pg_enable_capture(self.pg_interfaces)
5231 self.pg_start()
5232 capture = self.pg1.get_capture(1)
5233 p = capture[0]
5234 try:
5235 ip = p[IP]
5236 tcp = p[TCP]
5237 self.assertEqual(ip.src, nat_ip)
5238 self.assertEqual(ip.dst, self.pg1.remote_ip4)
Martin Gálik9806eae2017-04-25 01:25:08 -07005239 self.assertEqual(tcp.dport, external_port)
5240 port_out0 = tcp.sport
Martin Gálik977c1cb2017-03-30 23:21:51 -07005241 except:
5242 self.logger.error(ppp("Unexpected or invalid packet:", p))
5243 raise
5244
5245 # host1 to out
5246 p = (Ether(src=host1.mac, dst=self.pg0.local_mac) /
5247 IP(src=host1.ip4, dst=self.pg1.remote_ip4) /
Martin Gálik9806eae2017-04-25 01:25:08 -07005248 TCP(sport=port_in, dport=external_port))
Martin Gálik977c1cb2017-03-30 23:21:51 -07005249 self.pg0.add_stream(p)
5250 self.pg_enable_capture(self.pg_interfaces)
5251 self.pg_start()
5252 capture = self.pg1.get_capture(1)
5253 p = capture[0]
5254 try:
5255 ip = p[IP]
5256 tcp = p[TCP]
5257 self.assertEqual(ip.src, nat_ip)
5258 self.assertEqual(ip.dst, self.pg1.remote_ip4)
Martin Gálik9806eae2017-04-25 01:25:08 -07005259 self.assertEqual(tcp.dport, external_port)
5260 port_out1 = tcp.sport
Martin Gálik977c1cb2017-03-30 23:21:51 -07005261 except:
5262 self.logger.error(ppp("Unexpected or invalid packet:", p))
5263 raise
5264
Matus Fabian2ba92e32017-08-21 07:05:03 -07005265 dms = self.vapi.nat_det_map_dump()
Martin Gálik977c1cb2017-03-30 23:21:51 -07005266 self.assertEqual(1, len(dms))
5267 self.assertEqual(2, dms[0].ses_num)
5268
5269 # out to host0
5270 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5271 IP(src=self.pg1.remote_ip4, dst=nat_ip) /
Martin Gálik9806eae2017-04-25 01:25:08 -07005272 TCP(sport=external_port, dport=port_out0))
Martin Gálik977c1cb2017-03-30 23:21:51 -07005273 self.pg1.add_stream(p)
5274 self.pg_enable_capture(self.pg_interfaces)
5275 self.pg_start()
5276 capture = self.pg0.get_capture(1)
5277 p = capture[0]
5278 try:
5279 ip = p[IP]
5280 tcp = p[TCP]
5281 self.assertEqual(ip.src, self.pg1.remote_ip4)
5282 self.assertEqual(ip.dst, host0.ip4)
5283 self.assertEqual(tcp.dport, port_in)
Martin Gálik9806eae2017-04-25 01:25:08 -07005284 self.assertEqual(tcp.sport, external_port)
Martin Gálik977c1cb2017-03-30 23:21:51 -07005285 except:
5286 self.logger.error(ppp("Unexpected or invalid packet:", p))
5287 raise
5288
5289 # out to host1
5290 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5291 IP(src=self.pg1.remote_ip4, dst=nat_ip) /
Martin Gálik9806eae2017-04-25 01:25:08 -07005292 TCP(sport=external_port, dport=port_out1))
Martin Gálik977c1cb2017-03-30 23:21:51 -07005293 self.pg1.add_stream(p)
5294 self.pg_enable_capture(self.pg_interfaces)
5295 self.pg_start()
5296 capture = self.pg0.get_capture(1)
5297 p = capture[0]
5298 try:
5299 ip = p[IP]
5300 tcp = p[TCP]
5301 self.assertEqual(ip.src, self.pg1.remote_ip4)
5302 self.assertEqual(ip.dst, host1.ip4)
5303 self.assertEqual(tcp.dport, port_in)
Martin Gálik9806eae2017-04-25 01:25:08 -07005304 self.assertEqual(tcp.sport, external_port)
Martin Gálik977c1cb2017-03-30 23:21:51 -07005305 except:
5306 self.logger.error(ppp("Unexpected or invalid packet", p))
5307 raise
5308
Martin Gálik6bc8c642017-04-19 01:12:27 -07005309 # session close api test
Matus Fabian2ba92e32017-08-21 07:05:03 -07005310 self.vapi.nat_det_close_session_out(socket.inet_aton(nat_ip),
5311 port_out1,
Martin Gálik6bc8c642017-04-19 01:12:27 -07005312 self.pg1.remote_ip4n,
Martin Gálik9806eae2017-04-25 01:25:08 -07005313 external_port)
Matus Fabian2ba92e32017-08-21 07:05:03 -07005314 dms = self.vapi.nat_det_map_dump()
5315 self.assertEqual(dms[0].ses_num, 1)
5316
5317 self.vapi.nat_det_close_session_in(host0.ip4n,
5318 port_in,
5319 self.pg1.remote_ip4n,
5320 external_port)
5321 dms = self.vapi.nat_det_map_dump()
Martin Gálik6bc8c642017-04-19 01:12:27 -07005322 self.assertEqual(dms[0].ses_num, 0)
5323
Martin Gálik977c1cb2017-03-30 23:21:51 -07005324 def test_tcp_session_close_detection_in(self):
Matus Fabian2ba92e32017-08-21 07:05:03 -07005325 """ Deterministic NAT TCP session close from inside network """
5326 self.vapi.nat_det_add_del_map(self.pg0.remote_ip4n,
5327 32,
5328 socket.inet_aton(self.nat_addr),
5329 32)
5330 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
5331 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
5332 is_inside=0)
Martin Gálik977c1cb2017-03-30 23:21:51 -07005333
5334 self.initiate_tcp_session(self.pg0, self.pg1)
5335
5336 # close the session from inside
5337 try:
5338 # FIN packet in -> out
5339 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5340 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
Martin Gálik9806eae2017-04-25 01:25:08 -07005341 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
Martin Gálik977c1cb2017-03-30 23:21:51 -07005342 flags="F"))
5343 self.pg0.add_stream(p)
5344 self.pg_enable_capture(self.pg_interfaces)
5345 self.pg_start()
5346 self.pg1.get_capture(1)
5347
5348 pkts = []
5349
5350 # ACK packet out -> in
5351 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
Matus Fabian2ba92e32017-08-21 07:05:03 -07005352 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
Martin Gálik9806eae2017-04-25 01:25:08 -07005353 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
Martin Gálik977c1cb2017-03-30 23:21:51 -07005354 flags="A"))
5355 pkts.append(p)
5356
5357 # FIN packet out -> in
5358 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
Matus Fabian2ba92e32017-08-21 07:05:03 -07005359 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
Martin Gálik9806eae2017-04-25 01:25:08 -07005360 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
Martin Gálik977c1cb2017-03-30 23:21:51 -07005361 flags="F"))
5362 pkts.append(p)
5363
5364 self.pg1.add_stream(pkts)
5365 self.pg_enable_capture(self.pg_interfaces)
5366 self.pg_start()
5367 self.pg0.get_capture(2)
5368
5369 # ACK packet in -> out
5370 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5371 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
Martin Gálik9806eae2017-04-25 01:25:08 -07005372 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
Martin Gálik977c1cb2017-03-30 23:21:51 -07005373 flags="A"))
5374 self.pg0.add_stream(p)
5375 self.pg_enable_capture(self.pg_interfaces)
5376 self.pg_start()
5377 self.pg1.get_capture(1)
5378
Matus Fabian2ba92e32017-08-21 07:05:03 -07005379 # Check if deterministic NAT44 closed the session
5380 dms = self.vapi.nat_det_map_dump()
Martin Gálik977c1cb2017-03-30 23:21:51 -07005381 self.assertEqual(0, dms[0].ses_num)
5382 except:
5383 self.logger.error("TCP session termination failed")
5384 raise
5385
5386 def test_tcp_session_close_detection_out(self):
Matus Fabian2ba92e32017-08-21 07:05:03 -07005387 """ Deterministic NAT TCP session close from outside network """
5388 self.vapi.nat_det_add_del_map(self.pg0.remote_ip4n,
5389 32,
5390 socket.inet_aton(self.nat_addr),
5391 32)
5392 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
5393 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
5394 is_inside=0)
Martin Gálik977c1cb2017-03-30 23:21:51 -07005395
5396 self.initiate_tcp_session(self.pg0, self.pg1)
5397
5398 # close the session from outside
5399 try:
5400 # FIN packet out -> in
5401 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
Matus Fabian2ba92e32017-08-21 07:05:03 -07005402 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
Martin Gálik9806eae2017-04-25 01:25:08 -07005403 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
Martin Gálik977c1cb2017-03-30 23:21:51 -07005404 flags="F"))
5405 self.pg1.add_stream(p)
5406 self.pg_enable_capture(self.pg_interfaces)
5407 self.pg_start()
5408 self.pg0.get_capture(1)
5409
5410 pkts = []
5411
5412 # ACK packet in -> out
5413 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5414 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
Martin Gálik9806eae2017-04-25 01:25:08 -07005415 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
Martin Gálik977c1cb2017-03-30 23:21:51 -07005416 flags="A"))
5417 pkts.append(p)
5418
5419 # ACK packet in -> out
5420 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5421 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
Martin Gálik9806eae2017-04-25 01:25:08 -07005422 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
Martin Gálik977c1cb2017-03-30 23:21:51 -07005423 flags="F"))
5424 pkts.append(p)
5425
5426 self.pg0.add_stream(pkts)
5427 self.pg_enable_capture(self.pg_interfaces)
5428 self.pg_start()
5429 self.pg1.get_capture(2)
5430
5431 # ACK packet out -> in
5432 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
Matus Fabian2ba92e32017-08-21 07:05:03 -07005433 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
Martin Gálik9806eae2017-04-25 01:25:08 -07005434 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
Martin Gálik977c1cb2017-03-30 23:21:51 -07005435 flags="A"))
5436 self.pg1.add_stream(p)
5437 self.pg_enable_capture(self.pg_interfaces)
5438 self.pg_start()
5439 self.pg0.get_capture(1)
5440
Matus Fabian2ba92e32017-08-21 07:05:03 -07005441 # Check if deterministic NAT44 closed the session
5442 dms = self.vapi.nat_det_map_dump()
Martin Gálik977c1cb2017-03-30 23:21:51 -07005443 self.assertEqual(0, dms[0].ses_num)
5444 except:
5445 self.logger.error("TCP session termination failed")
5446 raise
5447
5448 @unittest.skipUnless(running_extended_tests(), "part of extended tests")
5449 def test_session_timeout(self):
Matus Fabian2ba92e32017-08-21 07:05:03 -07005450 """ Deterministic NAT session timeouts """
5451 self.vapi.nat_det_add_del_map(self.pg0.remote_ip4n,
5452 32,
5453 socket.inet_aton(self.nat_addr),
5454 32)
5455 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
5456 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
5457 is_inside=0)
Martin Gálik977c1cb2017-03-30 23:21:51 -07005458
5459 self.initiate_tcp_session(self.pg0, self.pg1)
Matus Fabian2ba92e32017-08-21 07:05:03 -07005460 self.vapi.nat_det_set_timeouts(5, 5, 5, 5)
Martin Gálik977c1cb2017-03-30 23:21:51 -07005461 pkts = self.create_stream_in(self.pg0, self.pg1)
5462 self.pg0.add_stream(pkts)
5463 self.pg_enable_capture(self.pg_interfaces)
5464 self.pg_start()
5465 capture = self.pg1.get_capture(len(pkts))
5466 sleep(15)
5467
Matus Fabian2ba92e32017-08-21 07:05:03 -07005468 dms = self.vapi.nat_det_map_dump()
Martin Gálik977c1cb2017-03-30 23:21:51 -07005469 self.assertEqual(0, dms[0].ses_num)
5470
Matus Fabian7c0aecc2017-07-03 01:21:38 -07005471 @unittest.skipUnless(running_extended_tests(), "part of extended tests")
Martin Gálik977c1cb2017-03-30 23:21:51 -07005472 def test_session_limit_per_user(self):
Matus Fabian2ba92e32017-08-21 07:05:03 -07005473 """ Deterministic NAT maximum sessions per user limit """
5474 self.vapi.nat_det_add_del_map(self.pg0.remote_ip4n,
5475 32,
5476 socket.inet_aton(self.nat_addr),
5477 32)
5478 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
5479 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
5480 is_inside=0)
Matus Fabian2f2db1c2017-04-18 05:29:59 -07005481 self.vapi.set_ipfix_exporter(collector_address=self.pg2.remote_ip4n,
5482 src_address=self.pg2.local_ip4n,
5483 path_mtu=512,
5484 template_interval=10)
Matus Fabian2ba92e32017-08-21 07:05:03 -07005485 self.vapi.nat_ipfix()
Martin Gálik977c1cb2017-03-30 23:21:51 -07005486
5487 pkts = []
5488 for port in range(1025, 2025):
5489 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5490 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5491 UDP(sport=port, dport=port))
5492 pkts.append(p)
5493
5494 self.pg0.add_stream(pkts)
5495 self.pg_enable_capture(self.pg_interfaces)
5496 self.pg_start()
5497 capture = self.pg1.get_capture(len(pkts))
5498
5499 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5500 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
Martin Gálikf7e655d2017-04-27 02:13:26 -07005501 UDP(sport=3001, dport=3002))
Martin Gálik977c1cb2017-03-30 23:21:51 -07005502 self.pg0.add_stream(p)
5503 self.pg_enable_capture(self.pg_interfaces)
5504 self.pg_start()
5505 capture = self.pg1.assert_nothing_captured()
5506
Martin Gálikf7e655d2017-04-27 02:13:26 -07005507 # verify ICMP error packet
5508 capture = self.pg0.get_capture(1)
5509 p = capture[0]
5510 self.assertTrue(p.haslayer(ICMP))
5511 icmp = p[ICMP]
5512 self.assertEqual(icmp.type, 3)
5513 self.assertEqual(icmp.code, 1)
5514 self.assertTrue(icmp.haslayer(IPerror))
5515 inner_ip = icmp[IPerror]
5516 self.assertEqual(inner_ip[UDPerror].sport, 3001)
5517 self.assertEqual(inner_ip[UDPerror].dport, 3002)
5518
Matus Fabian2ba92e32017-08-21 07:05:03 -07005519 dms = self.vapi.nat_det_map_dump()
Martin Gálik977c1cb2017-03-30 23:21:51 -07005520
5521 self.assertEqual(1000, dms[0].ses_num)
5522
Matus Fabian2f2db1c2017-04-18 05:29:59 -07005523 # verify IPFIX logging
5524 self.vapi.cli("ipfix flush") # FIXME this should be an API call
Matus Fabian7c0aecc2017-07-03 01:21:38 -07005525 sleep(1)
Matus Fabian2f2db1c2017-04-18 05:29:59 -07005526 capture = self.pg2.get_capture(2)
5527 ipfix = IPFIXDecoder()
5528 # first load template
5529 for p in capture:
5530 self.assertTrue(p.haslayer(IPFIX))
5531 if p.haslayer(Template):
5532 ipfix.add_template(p.getlayer(Template))
5533 # verify events in data set
5534 for p in capture:
5535 if p.haslayer(Data):
5536 data = ipfix.decode_data_set(p.getlayer(Set))
5537 self.verify_ipfix_max_entries_per_user(data)
5538
Matus Fabian2ba92e32017-08-21 07:05:03 -07005539 def clear_nat_det(self):
Martin17a75cb2017-03-08 05:53:20 -08005540 """
Matus Fabian2ba92e32017-08-21 07:05:03 -07005541 Clear deterministic NAT configuration.
Martin17a75cb2017-03-08 05:53:20 -08005542 """
Matus Fabian2ba92e32017-08-21 07:05:03 -07005543 self.vapi.nat_ipfix(enable=0)
5544 self.vapi.nat_det_set_timeouts()
5545 deterministic_mappings = self.vapi.nat_det_map_dump()
Martin17a75cb2017-03-08 05:53:20 -08005546 for dsm in deterministic_mappings:
Matus Fabian2ba92e32017-08-21 07:05:03 -07005547 self.vapi.nat_det_add_del_map(dsm.in_addr,
5548 dsm.in_plen,
5549 dsm.out_addr,
5550 dsm.out_plen,
5551 is_add=0)
Martin17a75cb2017-03-08 05:53:20 -08005552
Matus Fabian2ba92e32017-08-21 07:05:03 -07005553 interfaces = self.vapi.nat44_interface_dump()
Martin Gálik977c1cb2017-03-30 23:21:51 -07005554 for intf in interfaces:
Matus Fabian2ba92e32017-08-21 07:05:03 -07005555 self.vapi.nat44_interface_add_del_feature(intf.sw_if_index,
5556 intf.is_inside,
5557 is_add=0)
Martin Gálik977c1cb2017-03-30 23:21:51 -07005558
Matus Fabian066f0342017-02-10 03:48:01 -08005559 def tearDown(self):
5560 super(TestDeterministicNAT, self).tearDown()
5561 if not self.vpp_dead:
Matus Fabian82119542018-01-25 01:13:22 -08005562 self.logger.info(self.vapi.cli("show nat44 interfaces"))
5563 self.logger.info(
5564 self.vapi.cli("show nat44 deterministic mappings"))
5565 self.logger.info(
5566 self.vapi.cli("show nat44 deterministic timeouts"))
5567 self.logger.info(
5568 self.vapi.cli("show nat44 deterministic sessions"))
Matus Fabian2ba92e32017-08-21 07:05:03 -07005569 self.clear_nat_det()
Matus Fabian066f0342017-02-10 03:48:01 -08005570
Matus Fabian06596c52017-06-06 04:53:28 -07005571
5572class TestNAT64(MethodHolder):
5573 """ NAT64 Test Cases """
5574
5575 @classmethod
Matus Fabiana431ad12018-01-04 04:03:14 -08005576 def setUpConstants(cls):
5577 super(TestNAT64, cls).setUpConstants()
5578 cls.vpp_cmdline.extend(["nat", "{", "nat64 bib hash buckets 128",
5579 "nat64 st hash buckets 256", "}"])
5580
5581 @classmethod
Matus Fabian06596c52017-06-06 04:53:28 -07005582 def setUpClass(cls):
5583 super(TestNAT64, cls).setUpClass()
5584
5585 try:
5586 cls.tcp_port_in = 6303
5587 cls.tcp_port_out = 6303
5588 cls.udp_port_in = 6304
5589 cls.udp_port_out = 6304
5590 cls.icmp_id_in = 6305
5591 cls.icmp_id_out = 6305
5592 cls.nat_addr = '10.0.0.3'
5593 cls.nat_addr_n = socket.inet_pton(socket.AF_INET, cls.nat_addr)
Matus Fabian029f3d22017-06-15 02:28:50 -07005594 cls.vrf1_id = 10
5595 cls.vrf1_nat_addr = '10.0.10.3'
5596 cls.vrf1_nat_addr_n = socket.inet_pton(socket.AF_INET,
5597 cls.vrf1_nat_addr)
Matus Fabiana431ad12018-01-04 04:03:14 -08005598 cls.ipfix_src_port = 4739
5599 cls.ipfix_domain_id = 1
Matus Fabian06596c52017-06-06 04:53:28 -07005600
Juraj Slobodac746a152018-07-09 02:36:37 +02005601 cls.create_pg_interfaces(range(6))
Matus Fabian06596c52017-06-06 04:53:28 -07005602 cls.ip6_interfaces = list(cls.pg_interfaces[0:1])
Matus Fabian029f3d22017-06-15 02:28:50 -07005603 cls.ip6_interfaces.append(cls.pg_interfaces[2])
Matus Fabian06596c52017-06-06 04:53:28 -07005604 cls.ip4_interfaces = list(cls.pg_interfaces[1:2])
5605
Neale Ranns15002542017-09-10 04:39:11 -07005606 cls.vapi.ip_table_add_del(cls.vrf1_id, is_add=1, is_ipv6=1)
5607
Matus Fabian029f3d22017-06-15 02:28:50 -07005608 cls.pg_interfaces[2].set_table_ip6(cls.vrf1_id)
5609
5610 cls.pg0.generate_remote_hosts(2)
5611
Matus Fabian06596c52017-06-06 04:53:28 -07005612 for i in cls.ip6_interfaces:
5613 i.admin_up()
5614 i.config_ip6()
Matus Fabian029f3d22017-06-15 02:28:50 -07005615 i.configure_ipv6_neighbors()
Matus Fabian06596c52017-06-06 04:53:28 -07005616
5617 for i in cls.ip4_interfaces:
5618 i.admin_up()
5619 i.config_ip4()
5620 i.resolve_arp()
5621
Matus Fabian36ea2d62017-10-24 04:13:49 -07005622 cls.pg3.admin_up()
5623 cls.pg3.config_ip4()
5624 cls.pg3.resolve_arp()
5625 cls.pg3.config_ip6()
5626 cls.pg3.configure_ipv6_neighbors()
5627
Juraj Slobodac746a152018-07-09 02:36:37 +02005628 cls.pg5.admin_up()
5629 cls.pg5.config_ip6()
5630
Matus Fabian06596c52017-06-06 04:53:28 -07005631 except Exception:
5632 super(TestNAT64, cls).tearDownClass()
5633 raise
5634
Juraj Slobodac746a152018-07-09 02:36:37 +02005635 def test_nat64_inside_interface_handles_neighbor_advertisement(self):
5636 """ NAT64 inside interface handles Neighbor Advertisement """
5637
5638 self.vapi.nat64_add_del_interface(self.pg5.sw_if_index)
5639
5640 # Try to send ping
5641 ping = (Ether(dst=self.pg5.local_mac, src=self.pg5.remote_mac) /
5642 IPv6(src=self.pg5.remote_ip6, dst=self.pg5.local_ip6) /
5643 ICMPv6EchoRequest())
5644 pkts = [ping]
5645 self.pg5.add_stream(pkts)
5646 self.pg_enable_capture(self.pg_interfaces)
5647 self.pg_start()
5648
5649 # Wait for Neighbor Solicitation
5650 capture = self.pg5.get_capture(len(pkts))
5651 self.assertEqual(1, len(capture))
5652 packet = capture[0]
5653 try:
5654 self.assertEqual(packet[IPv6].src, self.pg5.local_ip6)
5655 self.assertTrue(packet.haslayer(ICMPv6ND_NS))
5656 tgt = packet[ICMPv6ND_NS].tgt
5657 except:
5658 self.logger.error(ppp("Unexpected or invalid packet:", packet))
5659 raise
5660
5661 # Send Neighbor Advertisement
5662 p = (Ether(dst=self.pg5.local_mac, src=self.pg5.remote_mac) /
5663 IPv6(src=self.pg5.remote_ip6, dst=self.pg5.local_ip6) /
5664 ICMPv6ND_NA(tgt=tgt) /
5665 ICMPv6NDOptDstLLAddr(lladdr=self.pg5.remote_mac))
5666 pkts = [p]
5667 self.pg5.add_stream(pkts)
5668 self.pg_enable_capture(self.pg_interfaces)
5669 self.pg_start()
5670
5671 # Try to send ping again
5672 pkts = [ping]
5673 self.pg5.add_stream(pkts)
5674 self.pg_enable_capture(self.pg_interfaces)
5675 self.pg_start()
5676
5677 # Wait for ping reply
5678 capture = self.pg5.get_capture(len(pkts))
5679 self.assertEqual(1, len(capture))
5680 packet = capture[0]
5681 try:
5682 self.assertEqual(packet[IPv6].src, self.pg5.local_ip6)
5683 self.assertEqual(packet[IPv6].dst, self.pg5.remote_ip6)
5684 self.assertTrue(packet.haslayer(ICMPv6EchoReply))
5685 except:
5686 self.logger.error(ppp("Unexpected or invalid packet:", packet))
5687 raise
5688
Matus Fabian06596c52017-06-06 04:53:28 -07005689 def test_pool(self):
5690 """ Add/delete address to NAT64 pool """
5691 nat_addr = socket.inet_pton(socket.AF_INET, '1.2.3.4')
5692
5693 self.vapi.nat64_add_del_pool_addr_range(nat_addr, nat_addr)
5694
5695 addresses = self.vapi.nat64_pool_addr_dump()
5696 self.assertEqual(len(addresses), 1)
5697 self.assertEqual(addresses[0].address, nat_addr)
5698
5699 self.vapi.nat64_add_del_pool_addr_range(nat_addr, nat_addr, is_add=0)
5700
5701 addresses = self.vapi.nat64_pool_addr_dump()
5702 self.assertEqual(len(addresses), 0)
5703
5704 def test_interface(self):
5705 """ Enable/disable NAT64 feature on the interface """
5706 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
5707 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
5708
5709 interfaces = self.vapi.nat64_interface_dump()
5710 self.assertEqual(len(interfaces), 2)
5711 pg0_found = False
5712 pg1_found = False
5713 for intf in interfaces:
5714 if intf.sw_if_index == self.pg0.sw_if_index:
5715 self.assertEqual(intf.is_inside, 1)
5716 pg0_found = True
5717 elif intf.sw_if_index == self.pg1.sw_if_index:
5718 self.assertEqual(intf.is_inside, 0)
5719 pg1_found = True
5720 self.assertTrue(pg0_found)
5721 self.assertTrue(pg1_found)
5722
5723 features = self.vapi.cli("show interface features pg0")
5724 self.assertNotEqual(features.find('nat64-in2out'), -1)
5725 features = self.vapi.cli("show interface features pg1")
5726 self.assertNotEqual(features.find('nat64-out2in'), -1)
5727
5728 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index, is_add=0)
5729 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_add=0)
5730
5731 interfaces = self.vapi.nat64_interface_dump()
5732 self.assertEqual(len(interfaces), 0)
5733
5734 def test_static_bib(self):
5735 """ Add/delete static BIB entry """
5736 in_addr = socket.inet_pton(socket.AF_INET6,
5737 '2001:db8:85a3::8a2e:370:7334')
5738 out_addr = socket.inet_pton(socket.AF_INET, '10.1.1.3')
5739 in_port = 1234
5740 out_port = 5678
5741 proto = IP_PROTOS.tcp
5742
5743 self.vapi.nat64_add_del_static_bib(in_addr,
5744 out_addr,
5745 in_port,
5746 out_port,
5747 proto)
5748 bib = self.vapi.nat64_bib_dump(IP_PROTOS.tcp)
5749 static_bib_num = 0
5750 for bibe in bib:
5751 if bibe.is_static:
5752 static_bib_num += 1
5753 self.assertEqual(bibe.i_addr, in_addr)
5754 self.assertEqual(bibe.o_addr, out_addr)
5755 self.assertEqual(bibe.i_port, in_port)
5756 self.assertEqual(bibe.o_port, out_port)
5757 self.assertEqual(static_bib_num, 1)
5758
5759 self.vapi.nat64_add_del_static_bib(in_addr,
5760 out_addr,
5761 in_port,
5762 out_port,
5763 proto,
5764 is_add=0)
5765 bib = self.vapi.nat64_bib_dump(IP_PROTOS.tcp)
5766 static_bib_num = 0
5767 for bibe in bib:
5768 if bibe.is_static:
5769 static_bib_num += 1
5770 self.assertEqual(static_bib_num, 0)
5771
5772 def test_set_timeouts(self):
5773 """ Set NAT64 timeouts """
5774 # verify default values
5775 timeouts = self.vapi.nat64_get_timeouts()
5776 self.assertEqual(timeouts.udp, 300)
5777 self.assertEqual(timeouts.icmp, 60)
5778 self.assertEqual(timeouts.tcp_trans, 240)
5779 self.assertEqual(timeouts.tcp_est, 7440)
5780 self.assertEqual(timeouts.tcp_incoming_syn, 6)
5781
5782 # set and verify custom values
5783 self.vapi.nat64_set_timeouts(udp=200, icmp=30, tcp_trans=250,
5784 tcp_est=7450, tcp_incoming_syn=10)
5785 timeouts = self.vapi.nat64_get_timeouts()
5786 self.assertEqual(timeouts.udp, 200)
5787 self.assertEqual(timeouts.icmp, 30)
5788 self.assertEqual(timeouts.tcp_trans, 250)
5789 self.assertEqual(timeouts.tcp_est, 7450)
5790 self.assertEqual(timeouts.tcp_incoming_syn, 10)
5791
5792 def test_dynamic(self):
5793 """ NAT64 dynamic translation test """
5794 self.tcp_port_in = 6303
5795 self.udp_port_in = 6304
5796 self.icmp_id_in = 6305
5797
5798 ses_num_start = self.nat64_get_ses_num()
5799
5800 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
5801 self.nat_addr_n)
5802 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
5803 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
5804
5805 # in2out
5806 pkts = self.create_stream_in_ip6(self.pg0, self.pg1)
5807 self.pg0.add_stream(pkts)
5808 self.pg_enable_capture(self.pg_interfaces)
5809 self.pg_start()
Matus Fabian029f3d22017-06-15 02:28:50 -07005810 capture = self.pg1.get_capture(len(pkts))
5811 self.verify_capture_out(capture, nat_ip=self.nat_addr,
Matus Fabian06596c52017-06-06 04:53:28 -07005812 dst_ip=self.pg1.remote_ip4)
5813
5814 # out2in
5815 pkts = self.create_stream_out(self.pg1, dst_ip=self.nat_addr)
5816 self.pg1.add_stream(pkts)
5817 self.pg_enable_capture(self.pg_interfaces)
5818 self.pg_start()
Matus Fabian029f3d22017-06-15 02:28:50 -07005819 capture = self.pg0.get_capture(len(pkts))
Matus Fabian06596c52017-06-06 04:53:28 -07005820 ip = IPv6(src=''.join(['64:ff9b::', self.pg1.remote_ip4]))
5821 self.verify_capture_in_ip6(capture, ip[IPv6].src, self.pg0.remote_ip6)
5822
5823 # in2out
5824 pkts = self.create_stream_in_ip6(self.pg0, self.pg1)
5825 self.pg0.add_stream(pkts)
5826 self.pg_enable_capture(self.pg_interfaces)
5827 self.pg_start()
Matus Fabian029f3d22017-06-15 02:28:50 -07005828 capture = self.pg1.get_capture(len(pkts))
5829 self.verify_capture_out(capture, nat_ip=self.nat_addr,
Matus Fabian06596c52017-06-06 04:53:28 -07005830 dst_ip=self.pg1.remote_ip4)
5831
5832 # out2in
5833 pkts = self.create_stream_out(self.pg1, dst_ip=self.nat_addr)
5834 self.pg1.add_stream(pkts)
5835 self.pg_enable_capture(self.pg_interfaces)
5836 self.pg_start()
Matus Fabian029f3d22017-06-15 02:28:50 -07005837 capture = self.pg0.get_capture(len(pkts))
Matus Fabian06596c52017-06-06 04:53:28 -07005838 self.verify_capture_in_ip6(capture, ip[IPv6].src, self.pg0.remote_ip6)
5839
5840 ses_num_end = self.nat64_get_ses_num()
5841
5842 self.assertEqual(ses_num_end - ses_num_start, 3)
5843
Matus Fabian029f3d22017-06-15 02:28:50 -07005844 # tenant with specific VRF
5845 self.vapi.nat64_add_del_pool_addr_range(self.vrf1_nat_addr_n,
5846 self.vrf1_nat_addr_n,
5847 vrf_id=self.vrf1_id)
5848 self.vapi.nat64_add_del_interface(self.pg2.sw_if_index)
5849
5850 pkts = self.create_stream_in_ip6(self.pg2, self.pg1)
5851 self.pg2.add_stream(pkts)
5852 self.pg_enable_capture(self.pg_interfaces)
5853 self.pg_start()
5854 capture = self.pg1.get_capture(len(pkts))
5855 self.verify_capture_out(capture, nat_ip=self.vrf1_nat_addr,
5856 dst_ip=self.pg1.remote_ip4)
5857
5858 pkts = self.create_stream_out(self.pg1, dst_ip=self.vrf1_nat_addr)
5859 self.pg1.add_stream(pkts)
5860 self.pg_enable_capture(self.pg_interfaces)
5861 self.pg_start()
5862 capture = self.pg2.get_capture(len(pkts))
5863 self.verify_capture_in_ip6(capture, ip[IPv6].src, self.pg2.remote_ip6)
5864
Matus Fabian06596c52017-06-06 04:53:28 -07005865 def test_static(self):
5866 """ NAT64 static translation test """
5867 self.tcp_port_in = 60303
5868 self.udp_port_in = 60304
5869 self.icmp_id_in = 60305
5870 self.tcp_port_out = 60303
5871 self.udp_port_out = 60304
5872 self.icmp_id_out = 60305
5873
5874 ses_num_start = self.nat64_get_ses_num()
5875
5876 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
5877 self.nat_addr_n)
5878 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
5879 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
5880
5881 self.vapi.nat64_add_del_static_bib(self.pg0.remote_ip6n,
5882 self.nat_addr_n,
5883 self.tcp_port_in,
5884 self.tcp_port_out,
5885 IP_PROTOS.tcp)
5886 self.vapi.nat64_add_del_static_bib(self.pg0.remote_ip6n,
5887 self.nat_addr_n,
5888 self.udp_port_in,
5889 self.udp_port_out,
5890 IP_PROTOS.udp)
5891 self.vapi.nat64_add_del_static_bib(self.pg0.remote_ip6n,
5892 self.nat_addr_n,
5893 self.icmp_id_in,
5894 self.icmp_id_out,
5895 IP_PROTOS.icmp)
5896
5897 # in2out
5898 pkts = self.create_stream_in_ip6(self.pg0, self.pg1)
5899 self.pg0.add_stream(pkts)
5900 self.pg_enable_capture(self.pg_interfaces)
5901 self.pg_start()
Matus Fabian029f3d22017-06-15 02:28:50 -07005902 capture = self.pg1.get_capture(len(pkts))
5903 self.verify_capture_out(capture, nat_ip=self.nat_addr,
Matus Fabian06596c52017-06-06 04:53:28 -07005904 dst_ip=self.pg1.remote_ip4, same_port=True)
5905
5906 # out2in
5907 pkts = self.create_stream_out(self.pg1, dst_ip=self.nat_addr)
5908 self.pg1.add_stream(pkts)
5909 self.pg_enable_capture(self.pg_interfaces)
5910 self.pg_start()
Matus Fabian029f3d22017-06-15 02:28:50 -07005911 capture = self.pg0.get_capture(len(pkts))
Matus Fabian06596c52017-06-06 04:53:28 -07005912 ip = IPv6(src=''.join(['64:ff9b::', self.pg1.remote_ip4]))
5913 self.verify_capture_in_ip6(capture, ip[IPv6].src, self.pg0.remote_ip6)
5914
5915 ses_num_end = self.nat64_get_ses_num()
5916
5917 self.assertEqual(ses_num_end - ses_num_start, 3)
5918
5919 @unittest.skipUnless(running_extended_tests(), "part of extended tests")
5920 def test_session_timeout(self):
5921 """ NAT64 session timeout """
5922 self.icmp_id_in = 1234
5923 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
5924 self.nat_addr_n)
5925 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
5926 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
5927 self.vapi.nat64_set_timeouts(icmp=5)
5928
5929 pkts = self.create_stream_in_ip6(self.pg0, self.pg1)
5930 self.pg0.add_stream(pkts)
5931 self.pg_enable_capture(self.pg_interfaces)
5932 self.pg_start()
Matus Fabian029f3d22017-06-15 02:28:50 -07005933 capture = self.pg1.get_capture(len(pkts))
Matus Fabian06596c52017-06-06 04:53:28 -07005934
5935 ses_num_before_timeout = self.nat64_get_ses_num()
5936
5937 sleep(15)
5938
5939 # ICMP session after timeout
5940 ses_num_after_timeout = self.nat64_get_ses_num()
5941 self.assertNotEqual(ses_num_before_timeout, ses_num_after_timeout)
5942
Matus Fabian732036d2017-06-08 05:24:28 -07005943 def test_icmp_error(self):
5944 """ NAT64 ICMP Error message translation """
5945 self.tcp_port_in = 6303
5946 self.udp_port_in = 6304
5947 self.icmp_id_in = 6305
5948
Matus Fabian732036d2017-06-08 05:24:28 -07005949 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
5950 self.nat_addr_n)
5951 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
5952 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
5953
5954 # send some packets to create sessions
5955 pkts = self.create_stream_in_ip6(self.pg0, self.pg1)
5956 self.pg0.add_stream(pkts)
5957 self.pg_enable_capture(self.pg_interfaces)
5958 self.pg_start()
5959 capture_ip4 = self.pg1.get_capture(len(pkts))
Matus Fabian029f3d22017-06-15 02:28:50 -07005960 self.verify_capture_out(capture_ip4,
Matus Fabian732036d2017-06-08 05:24:28 -07005961 nat_ip=self.nat_addr,
5962 dst_ip=self.pg1.remote_ip4)
5963
5964 pkts = self.create_stream_out(self.pg1, dst_ip=self.nat_addr)
5965 self.pg1.add_stream(pkts)
5966 self.pg_enable_capture(self.pg_interfaces)
5967 self.pg_start()
5968 capture_ip6 = self.pg0.get_capture(len(pkts))
5969 ip = IPv6(src=''.join(['64:ff9b::', self.pg1.remote_ip4]))
5970 self.verify_capture_in_ip6(capture_ip6, ip[IPv6].src,
5971 self.pg0.remote_ip6)
5972
5973 # in2out
5974 pkts = [Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
5975 IPv6(src=self.pg0.remote_ip6, dst=ip[IPv6].src) /
5976 ICMPv6DestUnreach(code=1) /
5977 packet[IPv6] for packet in capture_ip6]
5978 self.pg0.add_stream(pkts)
5979 self.pg_enable_capture(self.pg_interfaces)
5980 self.pg_start()
5981 capture = self.pg1.get_capture(len(pkts))
5982 for packet in capture:
5983 try:
5984 self.assertEqual(packet[IP].src, self.nat_addr)
5985 self.assertEqual(packet[IP].dst, self.pg1.remote_ip4)
5986 self.assertEqual(packet[ICMP].type, 3)
5987 self.assertEqual(packet[ICMP].code, 13)
5988 inner = packet[IPerror]
5989 self.assertEqual(inner.src, self.pg1.remote_ip4)
5990 self.assertEqual(inner.dst, self.nat_addr)
Klement Sekerad81ae412018-05-16 10:52:54 +02005991 self.assert_packet_checksums_valid(packet)
Matus Fabian732036d2017-06-08 05:24:28 -07005992 if inner.haslayer(TCPerror):
5993 self.assertEqual(inner[TCPerror].dport, self.tcp_port_out)
5994 elif inner.haslayer(UDPerror):
5995 self.assertEqual(inner[UDPerror].dport, self.udp_port_out)
5996 else:
5997 self.assertEqual(inner[ICMPerror].id, self.icmp_id_out)
5998 except:
5999 self.logger.error(ppp("Unexpected or invalid packet:", packet))
6000 raise
6001
6002 # out2in
6003 pkts = [Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
6004 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6005 ICMP(type=3, code=13) /
6006 packet[IP] for packet in capture_ip4]
6007 self.pg1.add_stream(pkts)
6008 self.pg_enable_capture(self.pg_interfaces)
6009 self.pg_start()
6010 capture = self.pg0.get_capture(len(pkts))
6011 for packet in capture:
6012 try:
6013 self.assertEqual(packet[IPv6].src, ip.src)
6014 self.assertEqual(packet[IPv6].dst, self.pg0.remote_ip6)
6015 icmp = packet[ICMPv6DestUnreach]
6016 self.assertEqual(icmp.code, 1)
6017 inner = icmp[IPerror6]
6018 self.assertEqual(inner.src, self.pg0.remote_ip6)
6019 self.assertEqual(inner.dst, ip.src)
Klement Sekerad81ae412018-05-16 10:52:54 +02006020 self.assert_icmpv6_checksum_valid(packet)
Matus Fabian732036d2017-06-08 05:24:28 -07006021 if inner.haslayer(TCPerror):
6022 self.assertEqual(inner[TCPerror].sport, self.tcp_port_in)
6023 elif inner.haslayer(UDPerror):
6024 self.assertEqual(inner[UDPerror].sport, self.udp_port_in)
6025 else:
6026 self.assertEqual(inner[ICMPv6EchoRequest].id,
6027 self.icmp_id_in)
6028 except:
6029 self.logger.error(ppp("Unexpected or invalid packet:", packet))
6030 raise
6031
Matus Fabian029f3d22017-06-15 02:28:50 -07006032 def test_hairpinning(self):
6033 """ NAT64 hairpinning """
6034
6035 client = self.pg0.remote_hosts[0]
6036 server = self.pg0.remote_hosts[1]
6037 server_tcp_in_port = 22
6038 server_tcp_out_port = 4022
6039 server_udp_in_port = 23
6040 server_udp_out_port = 4023
6041 client_tcp_in_port = 1234
6042 client_udp_in_port = 1235
6043 client_tcp_out_port = 0
6044 client_udp_out_port = 0
6045 ip = IPv6(src=''.join(['64:ff9b::', self.nat_addr]))
6046 nat_addr_ip6 = ip.src
6047
6048 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
6049 self.nat_addr_n)
6050 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
6051 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
6052
6053 self.vapi.nat64_add_del_static_bib(server.ip6n,
6054 self.nat_addr_n,
6055 server_tcp_in_port,
6056 server_tcp_out_port,
6057 IP_PROTOS.tcp)
6058 self.vapi.nat64_add_del_static_bib(server.ip6n,
6059 self.nat_addr_n,
6060 server_udp_in_port,
6061 server_udp_out_port,
6062 IP_PROTOS.udp)
6063
6064 # client to server
6065 pkts = []
6066 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
6067 IPv6(src=client.ip6, dst=nat_addr_ip6) /
6068 TCP(sport=client_tcp_in_port, dport=server_tcp_out_port))
6069 pkts.append(p)
6070 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
6071 IPv6(src=client.ip6, dst=nat_addr_ip6) /
6072 UDP(sport=client_udp_in_port, dport=server_udp_out_port))
6073 pkts.append(p)
6074 self.pg0.add_stream(pkts)
6075 self.pg_enable_capture(self.pg_interfaces)
6076 self.pg_start()
6077 capture = self.pg0.get_capture(len(pkts))
6078 for packet in capture:
6079 try:
6080 self.assertEqual(packet[IPv6].src, nat_addr_ip6)
6081 self.assertEqual(packet[IPv6].dst, server.ip6)
Klement Sekerad81ae412018-05-16 10:52:54 +02006082 self.assert_packet_checksums_valid(packet)
Matus Fabian029f3d22017-06-15 02:28:50 -07006083 if packet.haslayer(TCP):
6084 self.assertNotEqual(packet[TCP].sport, client_tcp_in_port)
6085 self.assertEqual(packet[TCP].dport, server_tcp_in_port)
Matus Fabian029f3d22017-06-15 02:28:50 -07006086 client_tcp_out_port = packet[TCP].sport
6087 else:
6088 self.assertNotEqual(packet[UDP].sport, client_udp_in_port)
6089 self.assertEqual(packet[UDP].dport, server_udp_in_port)
Matus Fabian029f3d22017-06-15 02:28:50 -07006090 client_udp_out_port = packet[UDP].sport
6091 except:
6092 self.logger.error(ppp("Unexpected or invalid packet:", packet))
6093 raise
6094
6095 # server to client
6096 pkts = []
6097 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
6098 IPv6(src=server.ip6, dst=nat_addr_ip6) /
6099 TCP(sport=server_tcp_in_port, dport=client_tcp_out_port))
6100 pkts.append(p)
6101 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
6102 IPv6(src=server.ip6, dst=nat_addr_ip6) /
6103 UDP(sport=server_udp_in_port, dport=client_udp_out_port))
6104 pkts.append(p)
6105 self.pg0.add_stream(pkts)
6106 self.pg_enable_capture(self.pg_interfaces)
6107 self.pg_start()
6108 capture = self.pg0.get_capture(len(pkts))
6109 for packet in capture:
6110 try:
6111 self.assertEqual(packet[IPv6].src, nat_addr_ip6)
6112 self.assertEqual(packet[IPv6].dst, client.ip6)
Klement Sekerad81ae412018-05-16 10:52:54 +02006113 self.assert_packet_checksums_valid(packet)
Matus Fabian029f3d22017-06-15 02:28:50 -07006114 if packet.haslayer(TCP):
6115 self.assertEqual(packet[TCP].sport, server_tcp_out_port)
6116 self.assertEqual(packet[TCP].dport, client_tcp_in_port)
Matus Fabian029f3d22017-06-15 02:28:50 -07006117 else:
6118 self.assertEqual(packet[UDP].sport, server_udp_out_port)
6119 self.assertEqual(packet[UDP].dport, client_udp_in_port)
Matus Fabian029f3d22017-06-15 02:28:50 -07006120 except:
6121 self.logger.error(ppp("Unexpected or invalid packet:", packet))
6122 raise
6123
6124 # ICMP error
6125 pkts = []
6126 pkts = [Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
6127 IPv6(src=client.ip6, dst=nat_addr_ip6) /
6128 ICMPv6DestUnreach(code=1) /
6129 packet[IPv6] for packet in capture]
6130 self.pg0.add_stream(pkts)
6131 self.pg_enable_capture(self.pg_interfaces)
6132 self.pg_start()
6133 capture = self.pg0.get_capture(len(pkts))
6134 for packet in capture:
6135 try:
6136 self.assertEqual(packet[IPv6].src, nat_addr_ip6)
6137 self.assertEqual(packet[IPv6].dst, server.ip6)
6138 icmp = packet[ICMPv6DestUnreach]
6139 self.assertEqual(icmp.code, 1)
6140 inner = icmp[IPerror6]
6141 self.assertEqual(inner.src, server.ip6)
6142 self.assertEqual(inner.dst, nat_addr_ip6)
Klement Sekerad81ae412018-05-16 10:52:54 +02006143 self.assert_packet_checksums_valid(packet)
Matus Fabian029f3d22017-06-15 02:28:50 -07006144 if inner.haslayer(TCPerror):
6145 self.assertEqual(inner[TCPerror].sport, server_tcp_in_port)
6146 self.assertEqual(inner[TCPerror].dport,
6147 client_tcp_out_port)
6148 else:
6149 self.assertEqual(inner[UDPerror].sport, server_udp_in_port)
6150 self.assertEqual(inner[UDPerror].dport,
6151 client_udp_out_port)
6152 except:
6153 self.logger.error(ppp("Unexpected or invalid packet:", packet))
6154 raise
6155
Matus Fabian428dc912017-06-21 06:15:18 -07006156 def test_prefix(self):
6157 """ NAT64 Network-Specific Prefix """
6158
6159 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
6160 self.nat_addr_n)
6161 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
6162 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
6163 self.vapi.nat64_add_del_pool_addr_range(self.vrf1_nat_addr_n,
6164 self.vrf1_nat_addr_n,
6165 vrf_id=self.vrf1_id)
6166 self.vapi.nat64_add_del_interface(self.pg2.sw_if_index)
6167
6168 # Add global prefix
6169 global_pref64 = "2001:db8::"
6170 global_pref64_n = socket.inet_pton(socket.AF_INET6, global_pref64)
6171 global_pref64_len = 32
6172 self.vapi.nat64_add_del_prefix(global_pref64_n, global_pref64_len)
6173
6174 prefix = self.vapi.nat64_prefix_dump()
6175 self.assertEqual(len(prefix), 1)
6176 self.assertEqual(prefix[0].prefix, global_pref64_n)
6177 self.assertEqual(prefix[0].prefix_len, global_pref64_len)
6178 self.assertEqual(prefix[0].vrf_id, 0)
6179
6180 # Add tenant specific prefix
6181 vrf1_pref64 = "2001:db8:122:300::"
6182 vrf1_pref64_n = socket.inet_pton(socket.AF_INET6, vrf1_pref64)
6183 vrf1_pref64_len = 56
6184 self.vapi.nat64_add_del_prefix(vrf1_pref64_n,
6185 vrf1_pref64_len,
6186 vrf_id=self.vrf1_id)
6187 prefix = self.vapi.nat64_prefix_dump()
6188 self.assertEqual(len(prefix), 2)
6189
6190 # Global prefix
6191 pkts = self.create_stream_in_ip6(self.pg0,
6192 self.pg1,
6193 pref=global_pref64,
6194 plen=global_pref64_len)
6195 self.pg0.add_stream(pkts)
6196 self.pg_enable_capture(self.pg_interfaces)
6197 self.pg_start()
6198 capture = self.pg1.get_capture(len(pkts))
6199 self.verify_capture_out(capture, nat_ip=self.nat_addr,
6200 dst_ip=self.pg1.remote_ip4)
6201
6202 pkts = self.create_stream_out(self.pg1, dst_ip=self.nat_addr)
6203 self.pg1.add_stream(pkts)
6204 self.pg_enable_capture(self.pg_interfaces)
6205 self.pg_start()
6206 capture = self.pg0.get_capture(len(pkts))
6207 dst_ip = self.compose_ip6(self.pg1.remote_ip4,
6208 global_pref64,
6209 global_pref64_len)
6210 self.verify_capture_in_ip6(capture, dst_ip, self.pg0.remote_ip6)
6211
6212 # Tenant specific prefix
6213 pkts = self.create_stream_in_ip6(self.pg2,
6214 self.pg1,
6215 pref=vrf1_pref64,
6216 plen=vrf1_pref64_len)
6217 self.pg2.add_stream(pkts)
6218 self.pg_enable_capture(self.pg_interfaces)
6219 self.pg_start()
6220 capture = self.pg1.get_capture(len(pkts))
6221 self.verify_capture_out(capture, nat_ip=self.vrf1_nat_addr,
6222 dst_ip=self.pg1.remote_ip4)
6223
6224 pkts = self.create_stream_out(self.pg1, dst_ip=self.vrf1_nat_addr)
6225 self.pg1.add_stream(pkts)
6226 self.pg_enable_capture(self.pg_interfaces)
6227 self.pg_start()
6228 capture = self.pg2.get_capture(len(pkts))
6229 dst_ip = self.compose_ip6(self.pg1.remote_ip4,
6230 vrf1_pref64,
6231 vrf1_pref64_len)
6232 self.verify_capture_in_ip6(capture, dst_ip, self.pg2.remote_ip6)
6233
Matus Fabianf8cd5812017-07-11 03:55:02 -07006234 def test_unknown_proto(self):
Matus Fabian7968e6c2017-07-06 05:37:49 -07006235 """ NAT64 translate packet with unknown protocol """
6236
6237 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
6238 self.nat_addr_n)
6239 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
6240 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
6241 remote_ip6 = self.compose_ip6(self.pg1.remote_ip4, '64:ff9b::', 96)
6242
6243 # in2out
6244 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
6245 IPv6(src=self.pg0.remote_ip6, dst=remote_ip6) /
6246 TCP(sport=self.tcp_port_in, dport=20))
6247 self.pg0.add_stream(p)
6248 self.pg_enable_capture(self.pg_interfaces)
6249 self.pg_start()
6250 p = self.pg1.get_capture(1)
6251
6252 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
Matus Fabianf8cd5812017-07-11 03:55:02 -07006253 IPv6(src=self.pg0.remote_ip6, dst=remote_ip6, nh=47) /
Matus Fabian7968e6c2017-07-06 05:37:49 -07006254 GRE() /
6255 IP(src=self.pg2.local_ip4, dst=self.pg2.remote_ip4) /
6256 TCP(sport=1234, dport=1234))
6257 self.pg0.add_stream(p)
6258 self.pg_enable_capture(self.pg_interfaces)
6259 self.pg_start()
6260 p = self.pg1.get_capture(1)
6261 packet = p[0]
6262 try:
6263 self.assertEqual(packet[IP].src, self.nat_addr)
6264 self.assertEqual(packet[IP].dst, self.pg1.remote_ip4)
6265 self.assertTrue(packet.haslayer(GRE))
Klement Sekerad81ae412018-05-16 10:52:54 +02006266 self.assert_packet_checksums_valid(packet)
Matus Fabian7968e6c2017-07-06 05:37:49 -07006267 except:
6268 self.logger.error(ppp("Unexpected or invalid packet:", packet))
6269 raise
6270
6271 # out2in
6272 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
6273 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6274 GRE() /
6275 IP(src=self.pg2.remote_ip4, dst=self.pg2.local_ip4) /
6276 TCP(sport=1234, dport=1234))
6277 self.pg1.add_stream(p)
6278 self.pg_enable_capture(self.pg_interfaces)
6279 self.pg_start()
6280 p = self.pg0.get_capture(1)
6281 packet = p[0]
6282 try:
6283 self.assertEqual(packet[IPv6].src, remote_ip6)
Matus Fabianf8cd5812017-07-11 03:55:02 -07006284 self.assertEqual(packet[IPv6].dst, self.pg0.remote_ip6)
6285 self.assertEqual(packet[IPv6].nh, 47)
Matus Fabian7968e6c2017-07-06 05:37:49 -07006286 except:
6287 self.logger.error(ppp("Unexpected or invalid packet:", packet))
6288 raise
6289
Matus Fabianf8cd5812017-07-11 03:55:02 -07006290 def test_hairpinning_unknown_proto(self):
Matus Fabian7968e6c2017-07-06 05:37:49 -07006291 """ NAT64 translate packet with unknown protocol - hairpinning """
6292
6293 client = self.pg0.remote_hosts[0]
6294 server = self.pg0.remote_hosts[1]
6295 server_tcp_in_port = 22
6296 server_tcp_out_port = 4022
6297 client_tcp_in_port = 1234
Matus Fabianf8cd5812017-07-11 03:55:02 -07006298 client_tcp_out_port = 1235
6299 server_nat_ip = "10.0.0.100"
6300 client_nat_ip = "10.0.0.110"
6301 server_nat_ip_n = socket.inet_pton(socket.AF_INET, server_nat_ip)
6302 client_nat_ip_n = socket.inet_pton(socket.AF_INET, client_nat_ip)
6303 server_nat_ip6 = self.compose_ip6(server_nat_ip, '64:ff9b::', 96)
6304 client_nat_ip6 = self.compose_ip6(client_nat_ip, '64:ff9b::', 96)
Matus Fabian7968e6c2017-07-06 05:37:49 -07006305
Matus Fabianf8cd5812017-07-11 03:55:02 -07006306 self.vapi.nat64_add_del_pool_addr_range(server_nat_ip_n,
6307 client_nat_ip_n)
Matus Fabian7968e6c2017-07-06 05:37:49 -07006308 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
6309 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
6310
6311 self.vapi.nat64_add_del_static_bib(server.ip6n,
Matus Fabianf8cd5812017-07-11 03:55:02 -07006312 server_nat_ip_n,
Matus Fabian7968e6c2017-07-06 05:37:49 -07006313 server_tcp_in_port,
6314 server_tcp_out_port,
6315 IP_PROTOS.tcp)
6316
Matus Fabianf8cd5812017-07-11 03:55:02 -07006317 self.vapi.nat64_add_del_static_bib(server.ip6n,
6318 server_nat_ip_n,
6319 0,
6320 0,
6321 IP_PROTOS.gre)
6322
6323 self.vapi.nat64_add_del_static_bib(client.ip6n,
6324 client_nat_ip_n,
6325 client_tcp_in_port,
6326 client_tcp_out_port,
6327 IP_PROTOS.tcp)
6328
Matus Fabian7968e6c2017-07-06 05:37:49 -07006329 # client to server
6330 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
Matus Fabianf8cd5812017-07-11 03:55:02 -07006331 IPv6(src=client.ip6, dst=server_nat_ip6) /
Matus Fabian7968e6c2017-07-06 05:37:49 -07006332 TCP(sport=client_tcp_in_port, dport=server_tcp_out_port))
6333 self.pg0.add_stream(p)
6334 self.pg_enable_capture(self.pg_interfaces)
6335 self.pg_start()
6336 p = self.pg0.get_capture(1)
6337
6338 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
Matus Fabianf8cd5812017-07-11 03:55:02 -07006339 IPv6(src=client.ip6, dst=server_nat_ip6, nh=IP_PROTOS.gre) /
Matus Fabian7968e6c2017-07-06 05:37:49 -07006340 GRE() /
6341 IP(src=self.pg2.local_ip4, dst=self.pg2.remote_ip4) /
6342 TCP(sport=1234, dport=1234))
6343 self.pg0.add_stream(p)
6344 self.pg_enable_capture(self.pg_interfaces)
6345 self.pg_start()
6346 p = self.pg0.get_capture(1)
6347 packet = p[0]
6348 try:
Matus Fabianf8cd5812017-07-11 03:55:02 -07006349 self.assertEqual(packet[IPv6].src, client_nat_ip6)
Matus Fabian7968e6c2017-07-06 05:37:49 -07006350 self.assertEqual(packet[IPv6].dst, server.ip6)
Matus Fabianf8cd5812017-07-11 03:55:02 -07006351 self.assertEqual(packet[IPv6].nh, IP_PROTOS.gre)
Matus Fabian7968e6c2017-07-06 05:37:49 -07006352 except:
6353 self.logger.error(ppp("Unexpected or invalid packet:", packet))
6354 raise
6355
6356 # server to client
6357 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
Matus Fabianf8cd5812017-07-11 03:55:02 -07006358 IPv6(src=server.ip6, dst=client_nat_ip6, nh=IP_PROTOS.gre) /
Matus Fabian7968e6c2017-07-06 05:37:49 -07006359 GRE() /
6360 IP(src=self.pg2.remote_ip4, dst=self.pg2.local_ip4) /
6361 TCP(sport=1234, dport=1234))
6362 self.pg0.add_stream(p)
6363 self.pg_enable_capture(self.pg_interfaces)
6364 self.pg_start()
6365 p = self.pg0.get_capture(1)
6366 packet = p[0]
6367 try:
Matus Fabianf8cd5812017-07-11 03:55:02 -07006368 self.assertEqual(packet[IPv6].src, server_nat_ip6)
Matus Fabian7968e6c2017-07-06 05:37:49 -07006369 self.assertEqual(packet[IPv6].dst, client.ip6)
Matus Fabianf8cd5812017-07-11 03:55:02 -07006370 self.assertEqual(packet[IPv6].nh, IP_PROTOS.gre)
Matus Fabian7968e6c2017-07-06 05:37:49 -07006371 except:
6372 self.logger.error(ppp("Unexpected or invalid packet:", packet))
6373 raise
6374
Matus Fabian36ea2d62017-10-24 04:13:49 -07006375 def test_one_armed_nat64(self):
6376 """ One armed NAT64 """
6377 external_port = 0
6378 remote_host_ip6 = self.compose_ip6(self.pg3.remote_ip4,
6379 '64:ff9b::',
6380 96)
6381
6382 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
6383 self.nat_addr_n)
6384 self.vapi.nat64_add_del_interface(self.pg3.sw_if_index)
6385 self.vapi.nat64_add_del_interface(self.pg3.sw_if_index, is_inside=0)
6386
6387 # in2out
6388 p = (Ether(src=self.pg3.remote_mac, dst=self.pg3.local_mac) /
6389 IPv6(src=self.pg3.remote_ip6, dst=remote_host_ip6) /
6390 TCP(sport=12345, dport=80))
6391 self.pg3.add_stream(p)
6392 self.pg_enable_capture(self.pg_interfaces)
6393 self.pg_start()
6394 capture = self.pg3.get_capture(1)
6395 p = capture[0]
6396 try:
6397 ip = p[IP]
6398 tcp = p[TCP]
6399 self.assertEqual(ip.src, self.nat_addr)
6400 self.assertEqual(ip.dst, self.pg3.remote_ip4)
6401 self.assertNotEqual(tcp.sport, 12345)
6402 external_port = tcp.sport
6403 self.assertEqual(tcp.dport, 80)
Klement Sekerad81ae412018-05-16 10:52:54 +02006404 self.assert_packet_checksums_valid(p)
Matus Fabian36ea2d62017-10-24 04:13:49 -07006405 except:
6406 self.logger.error(ppp("Unexpected or invalid packet:", p))
6407 raise
6408
6409 # out2in
6410 p = (Ether(src=self.pg3.remote_mac, dst=self.pg3.local_mac) /
6411 IP(src=self.pg3.remote_ip4, dst=self.nat_addr) /
6412 TCP(sport=80, dport=external_port))
6413 self.pg3.add_stream(p)
6414 self.pg_enable_capture(self.pg_interfaces)
6415 self.pg_start()
6416 capture = self.pg3.get_capture(1)
6417 p = capture[0]
6418 try:
6419 ip = p[IPv6]
6420 tcp = p[TCP]
6421 self.assertEqual(ip.src, remote_host_ip6)
6422 self.assertEqual(ip.dst, self.pg3.remote_ip6)
6423 self.assertEqual(tcp.sport, 80)
6424 self.assertEqual(tcp.dport, 12345)
Klement Sekerad81ae412018-05-16 10:52:54 +02006425 self.assert_packet_checksums_valid(p)
Matus Fabian36ea2d62017-10-24 04:13:49 -07006426 except:
6427 self.logger.error(ppp("Unexpected or invalid packet:", p))
6428 raise
6429
Matus Fabianefcd1e92017-08-15 06:59:19 -07006430 def test_frag_in_order(self):
6431 """ NAT64 translate fragments arriving in order """
6432 self.tcp_port_in = random.randint(1025, 65535)
6433
6434 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
6435 self.nat_addr_n)
6436 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
6437 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
6438
6439 reass = self.vapi.nat_reass_dump()
6440 reass_n_start = len(reass)
6441
6442 # in2out
6443 data = 'a' * 200
6444 pkts = self.create_stream_frag_ip6(self.pg0, self.pg1.remote_ip4,
6445 self.tcp_port_in, 20, data)
6446 self.pg0.add_stream(pkts)
6447 self.pg_enable_capture(self.pg_interfaces)
6448 self.pg_start()
6449 frags = self.pg1.get_capture(len(pkts))
6450 p = self.reass_frags_and_verify(frags,
6451 self.nat_addr,
6452 self.pg1.remote_ip4)
6453 self.assertEqual(p[TCP].dport, 20)
6454 self.assertNotEqual(p[TCP].sport, self.tcp_port_in)
6455 self.tcp_port_out = p[TCP].sport
6456 self.assertEqual(data, p[Raw].load)
6457
6458 # out2in
6459 data = "A" * 4 + "b" * 16 + "C" * 3
6460 pkts = self.create_stream_frag(self.pg1,
6461 self.nat_addr,
6462 20,
6463 self.tcp_port_out,
6464 data)
6465 self.pg1.add_stream(pkts)
6466 self.pg_enable_capture(self.pg_interfaces)
6467 self.pg_start()
6468 frags = self.pg0.get_capture(len(pkts))
6469 src = self.compose_ip6(self.pg1.remote_ip4, '64:ff9b::', 96)
6470 p = self.reass_frags_and_verify_ip6(frags, src, self.pg0.remote_ip6)
6471 self.assertEqual(p[TCP].sport, 20)
6472 self.assertEqual(p[TCP].dport, self.tcp_port_in)
6473 self.assertEqual(data, p[Raw].load)
6474
6475 reass = self.vapi.nat_reass_dump()
6476 reass_n_end = len(reass)
6477
6478 self.assertEqual(reass_n_end - reass_n_start, 2)
6479
6480 def test_reass_hairpinning(self):
6481 """ NAT64 fragments hairpinning """
6482 data = 'a' * 200
Matus Fabianefcd1e92017-08-15 06:59:19 -07006483 server = self.pg0.remote_hosts[1]
6484 server_in_port = random.randint(1025, 65535)
6485 server_out_port = random.randint(1025, 65535)
6486 client_in_port = random.randint(1025, 65535)
6487 ip = IPv6(src=''.join(['64:ff9b::', self.nat_addr]))
6488 nat_addr_ip6 = ip.src
6489
6490 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
6491 self.nat_addr_n)
6492 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
6493 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
6494
6495 # add static BIB entry for server
6496 self.vapi.nat64_add_del_static_bib(server.ip6n,
6497 self.nat_addr_n,
6498 server_in_port,
6499 server_out_port,
6500 IP_PROTOS.tcp)
6501
6502 # send packet from host to server
6503 pkts = self.create_stream_frag_ip6(self.pg0,
6504 self.nat_addr,
6505 client_in_port,
6506 server_out_port,
6507 data)
6508 self.pg0.add_stream(pkts)
6509 self.pg_enable_capture(self.pg_interfaces)
6510 self.pg_start()
6511 frags = self.pg0.get_capture(len(pkts))
6512 p = self.reass_frags_and_verify_ip6(frags, nat_addr_ip6, server.ip6)
6513 self.assertNotEqual(p[TCP].sport, client_in_port)
6514 self.assertEqual(p[TCP].dport, server_in_port)
6515 self.assertEqual(data, p[Raw].load)
6516
6517 def test_frag_out_of_order(self):
6518 """ NAT64 translate fragments arriving out of order """
6519 self.tcp_port_in = random.randint(1025, 65535)
6520
6521 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
6522 self.nat_addr_n)
6523 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
6524 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
6525
6526 # in2out
6527 data = 'a' * 200
6528 pkts = self.create_stream_frag_ip6(self.pg0, self.pg1.remote_ip4,
6529 self.tcp_port_in, 20, data)
6530 pkts.reverse()
6531 self.pg0.add_stream(pkts)
6532 self.pg_enable_capture(self.pg_interfaces)
6533 self.pg_start()
6534 frags = self.pg1.get_capture(len(pkts))
6535 p = self.reass_frags_and_verify(frags,
6536 self.nat_addr,
6537 self.pg1.remote_ip4)
6538 self.assertEqual(p[TCP].dport, 20)
6539 self.assertNotEqual(p[TCP].sport, self.tcp_port_in)
6540 self.tcp_port_out = p[TCP].sport
6541 self.assertEqual(data, p[Raw].load)
6542
6543 # out2in
6544 data = "A" * 4 + "B" * 16 + "C" * 3
6545 pkts = self.create_stream_frag(self.pg1,
6546 self.nat_addr,
6547 20,
6548 self.tcp_port_out,
6549 data)
6550 pkts.reverse()
6551 self.pg1.add_stream(pkts)
6552 self.pg_enable_capture(self.pg_interfaces)
6553 self.pg_start()
6554 frags = self.pg0.get_capture(len(pkts))
6555 src = self.compose_ip6(self.pg1.remote_ip4, '64:ff9b::', 96)
6556 p = self.reass_frags_and_verify_ip6(frags, src, self.pg0.remote_ip6)
6557 self.assertEqual(p[TCP].sport, 20)
6558 self.assertEqual(p[TCP].dport, self.tcp_port_in)
6559 self.assertEqual(data, p[Raw].load)
6560
Matus Fabian0938dcf2017-11-08 01:59:38 -08006561 def test_interface_addr(self):
6562 """ Acquire NAT64 pool addresses from interface """
6563 self.vapi.nat64_add_interface_addr(self.pg4.sw_if_index)
6564
6565 # no address in NAT64 pool
6566 adresses = self.vapi.nat44_address_dump()
6567 self.assertEqual(0, len(adresses))
6568
6569 # configure interface address and check NAT64 address pool
6570 self.pg4.config_ip4()
6571 addresses = self.vapi.nat64_pool_addr_dump()
6572 self.assertEqual(len(addresses), 1)
6573 self.assertEqual(addresses[0].address, self.pg4.local_ip4n)
6574
6575 # remove interface address and check NAT64 address pool
6576 self.pg4.unconfig_ip4()
6577 addresses = self.vapi.nat64_pool_addr_dump()
6578 self.assertEqual(0, len(adresses))
6579
Matus Fabiana431ad12018-01-04 04:03:14 -08006580 @unittest.skipUnless(running_extended_tests(), "part of extended tests")
6581 def test_ipfix_max_bibs_sessions(self):
6582 """ IPFIX logging maximum session and BIB entries exceeded """
6583 max_bibs = 1280
6584 max_sessions = 2560
6585 remote_host_ip6 = self.compose_ip6(self.pg1.remote_ip4,
6586 '64:ff9b::',
6587 96)
6588
6589 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
6590 self.nat_addr_n)
6591 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
6592 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
6593
6594 pkts = []
6595 src = ""
6596 for i in range(0, max_bibs):
6597 src = "fd01:aa::%x" % (i)
6598 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6599 IPv6(src=src, dst=remote_host_ip6) /
6600 TCP(sport=12345, dport=80))
6601 pkts.append(p)
6602 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6603 IPv6(src=src, dst=remote_host_ip6) /
6604 TCP(sport=12345, dport=22))
6605 pkts.append(p)
6606 self.pg0.add_stream(pkts)
6607 self.pg_enable_capture(self.pg_interfaces)
6608 self.pg_start()
6609 self.pg1.get_capture(max_sessions)
6610
6611 self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4n,
6612 src_address=self.pg3.local_ip4n,
6613 path_mtu=512,
6614 template_interval=10)
6615 self.vapi.nat_ipfix(domain_id=self.ipfix_domain_id,
6616 src_port=self.ipfix_src_port)
6617
6618 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6619 IPv6(src=src, dst=remote_host_ip6) /
6620 TCP(sport=12345, dport=25))
6621 self.pg0.add_stream(p)
6622 self.pg_enable_capture(self.pg_interfaces)
6623 self.pg_start()
Matus Fabian229c1aa2018-05-28 04:09:52 -07006624 self.pg1.assert_nothing_captured()
6625 sleep(1)
Matus Fabiana431ad12018-01-04 04:03:14 -08006626 self.vapi.cli("ipfix flush") # FIXME this should be an API call
6627 capture = self.pg3.get_capture(9)
6628 ipfix = IPFIXDecoder()
6629 # first load template
6630 for p in capture:
6631 self.assertTrue(p.haslayer(IPFIX))
6632 self.assertEqual(p[IP].src, self.pg3.local_ip4)
6633 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
6634 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
6635 self.assertEqual(p[UDP].dport, 4739)
6636 self.assertEqual(p[IPFIX].observationDomainID,
6637 self.ipfix_domain_id)
6638 if p.haslayer(Template):
6639 ipfix.add_template(p.getlayer(Template))
6640 # verify events in data set
6641 for p in capture:
6642 if p.haslayer(Data):
6643 data = ipfix.decode_data_set(p.getlayer(Set))
6644 self.verify_ipfix_max_sessions(data, max_sessions)
6645
6646 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6647 IPv6(src=self.pg0.remote_ip6, dst=remote_host_ip6) /
6648 TCP(sport=12345, dport=80))
6649 self.pg0.add_stream(p)
6650 self.pg_enable_capture(self.pg_interfaces)
6651 self.pg_start()
Matus Fabian229c1aa2018-05-28 04:09:52 -07006652 self.pg1.assert_nothing_captured()
6653 sleep(1)
Matus Fabiana431ad12018-01-04 04:03:14 -08006654 self.vapi.cli("ipfix flush") # FIXME this should be an API call
6655 capture = self.pg3.get_capture(1)
6656 # verify events in data set
6657 for p in capture:
6658 self.assertTrue(p.haslayer(IPFIX))
6659 self.assertEqual(p[IP].src, self.pg3.local_ip4)
6660 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
6661 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
6662 self.assertEqual(p[UDP].dport, 4739)
6663 self.assertEqual(p[IPFIX].observationDomainID,
6664 self.ipfix_domain_id)
6665 if p.haslayer(Data):
6666 data = ipfix.decode_data_set(p.getlayer(Set))
6667 self.verify_ipfix_max_bibs(data, max_bibs)
6668
6669 def test_ipfix_max_frags(self):
6670 """ IPFIX logging maximum fragments pending reassembly exceeded """
6671 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
6672 self.nat_addr_n)
6673 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
6674 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
6675 self.vapi.nat_set_reass(max_frag=0, is_ip6=1)
6676 self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4n,
6677 src_address=self.pg3.local_ip4n,
6678 path_mtu=512,
6679 template_interval=10)
6680 self.vapi.nat_ipfix(domain_id=self.ipfix_domain_id,
6681 src_port=self.ipfix_src_port)
6682
6683 data = 'a' * 200
6684 pkts = self.create_stream_frag_ip6(self.pg0, self.pg1.remote_ip4,
6685 self.tcp_port_in, 20, data)
6686 self.pg0.add_stream(pkts[-1])
6687 self.pg_enable_capture(self.pg_interfaces)
6688 self.pg_start()
Matus Fabian229c1aa2018-05-28 04:09:52 -07006689 self.pg1.assert_nothing_captured()
6690 sleep(1)
Matus Fabiana431ad12018-01-04 04:03:14 -08006691 self.vapi.cli("ipfix flush") # FIXME this should be an API call
6692 capture = self.pg3.get_capture(9)
6693 ipfix = IPFIXDecoder()
6694 # first load template
6695 for p in capture:
6696 self.assertTrue(p.haslayer(IPFIX))
6697 self.assertEqual(p[IP].src, self.pg3.local_ip4)
6698 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
6699 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
6700 self.assertEqual(p[UDP].dport, 4739)
6701 self.assertEqual(p[IPFIX].observationDomainID,
6702 self.ipfix_domain_id)
6703 if p.haslayer(Template):
6704 ipfix.add_template(p.getlayer(Template))
6705 # verify events in data set
6706 for p in capture:
6707 if p.haslayer(Data):
6708 data = ipfix.decode_data_set(p.getlayer(Set))
6709 self.verify_ipfix_max_fragments_ip6(data, 0,
6710 self.pg0.remote_ip6n)
6711
6712 def test_ipfix_bib_ses(self):
6713 """ IPFIX logging NAT64 BIB/session create and delete events """
6714 self.tcp_port_in = random.randint(1025, 65535)
6715 remote_host_ip6 = self.compose_ip6(self.pg1.remote_ip4,
6716 '64:ff9b::',
6717 96)
6718
6719 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
6720 self.nat_addr_n)
6721 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
6722 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
6723 self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4n,
6724 src_address=self.pg3.local_ip4n,
6725 path_mtu=512,
6726 template_interval=10)
6727 self.vapi.nat_ipfix(domain_id=self.ipfix_domain_id,
6728 src_port=self.ipfix_src_port)
6729
6730 # Create
6731 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6732 IPv6(src=self.pg0.remote_ip6, dst=remote_host_ip6) /
6733 TCP(sport=self.tcp_port_in, dport=25))
6734 self.pg0.add_stream(p)
6735 self.pg_enable_capture(self.pg_interfaces)
6736 self.pg_start()
6737 p = self.pg1.get_capture(1)
6738 self.tcp_port_out = p[0][TCP].sport
6739 self.vapi.cli("ipfix flush") # FIXME this should be an API call
6740 capture = self.pg3.get_capture(10)
6741 ipfix = IPFIXDecoder()
6742 # first load template
6743 for p in capture:
6744 self.assertTrue(p.haslayer(IPFIX))
6745 self.assertEqual(p[IP].src, self.pg3.local_ip4)
6746 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
6747 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
6748 self.assertEqual(p[UDP].dport, 4739)
6749 self.assertEqual(p[IPFIX].observationDomainID,
6750 self.ipfix_domain_id)
6751 if p.haslayer(Template):
6752 ipfix.add_template(p.getlayer(Template))
6753 # verify events in data set
6754 for p in capture:
6755 if p.haslayer(Data):
6756 data = ipfix.decode_data_set(p.getlayer(Set))
6757 if ord(data[0][230]) == 10:
6758 self.verify_ipfix_bib(data, 1, self.pg0.remote_ip6n)
6759 elif ord(data[0][230]) == 6:
6760 self.verify_ipfix_nat64_ses(data,
6761 1,
6762 self.pg0.remote_ip6n,
6763 self.pg1.remote_ip4,
6764 25)
6765 else:
6766 self.logger.error(ppp("Unexpected or invalid packet: ", p))
6767
6768 # Delete
6769 self.pg_enable_capture(self.pg_interfaces)
6770 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
6771 self.nat_addr_n,
6772 is_add=0)
6773 self.vapi.cli("ipfix flush") # FIXME this should be an API call
6774 capture = self.pg3.get_capture(2)
6775 # verify events in data set
6776 for p in capture:
6777 self.assertTrue(p.haslayer(IPFIX))
6778 self.assertEqual(p[IP].src, self.pg3.local_ip4)
6779 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
6780 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
6781 self.assertEqual(p[UDP].dport, 4739)
6782 self.assertEqual(p[IPFIX].observationDomainID,
6783 self.ipfix_domain_id)
6784 if p.haslayer(Data):
6785 data = ipfix.decode_data_set(p.getlayer(Set))
6786 if ord(data[0][230]) == 11:
6787 self.verify_ipfix_bib(data, 0, self.pg0.remote_ip6n)
6788 elif ord(data[0][230]) == 7:
6789 self.verify_ipfix_nat64_ses(data,
6790 0,
6791 self.pg0.remote_ip6n,
6792 self.pg1.remote_ip4,
6793 25)
6794 else:
6795 self.logger.error(ppp("Unexpected or invalid packet: ", p))
6796
Matus Fabian06596c52017-06-06 04:53:28 -07006797 def nat64_get_ses_num(self):
6798 """
6799 Return number of active NAT64 sessions.
6800 """
Matus Fabianab9a59c2017-08-16 05:37:36 -07006801 st = self.vapi.nat64_st_dump()
6802 return len(st)
Matus Fabian06596c52017-06-06 04:53:28 -07006803
6804 def clear_nat64(self):
6805 """
6806 Clear NAT64 configuration.
6807 """
Matus Fabiana431ad12018-01-04 04:03:14 -08006808 self.vapi.nat_ipfix(enable=0, src_port=self.ipfix_src_port,
6809 domain_id=self.ipfix_domain_id)
6810 self.ipfix_src_port = 4739
6811 self.ipfix_domain_id = 1
6812
Matus Fabian06596c52017-06-06 04:53:28 -07006813 self.vapi.nat64_set_timeouts()
6814
6815 interfaces = self.vapi.nat64_interface_dump()
6816 for intf in interfaces:
Matus Fabian36ea2d62017-10-24 04:13:49 -07006817 if intf.is_inside > 1:
6818 self.vapi.nat64_add_del_interface(intf.sw_if_index,
6819 0,
6820 is_add=0)
Matus Fabian06596c52017-06-06 04:53:28 -07006821 self.vapi.nat64_add_del_interface(intf.sw_if_index,
6822 intf.is_inside,
6823 is_add=0)
6824
Matus Fabiana431ad12018-01-04 04:03:14 -08006825 bib = self.vapi.nat64_bib_dump(255)
Matus Fabian06596c52017-06-06 04:53:28 -07006826 for bibe in bib:
6827 if bibe.is_static:
6828 self.vapi.nat64_add_del_static_bib(bibe.i_addr,
6829 bibe.o_addr,
6830 bibe.i_port,
6831 bibe.o_port,
6832 bibe.proto,
6833 bibe.vrf_id,
6834 is_add=0)
6835
6836 adresses = self.vapi.nat64_pool_addr_dump()
6837 for addr in adresses:
6838 self.vapi.nat64_add_del_pool_addr_range(addr.address,
6839 addr.address,
Matus Fabian029f3d22017-06-15 02:28:50 -07006840 vrf_id=addr.vrf_id,
Matus Fabian06596c52017-06-06 04:53:28 -07006841 is_add=0)
6842
Matus Fabian428dc912017-06-21 06:15:18 -07006843 prefixes = self.vapi.nat64_prefix_dump()
6844 for prefix in prefixes:
6845 self.vapi.nat64_add_del_prefix(prefix.prefix,
6846 prefix.prefix_len,
6847 vrf_id=prefix.vrf_id,
6848 is_add=0)
6849
Matus Fabian06596c52017-06-06 04:53:28 -07006850 def tearDown(self):
6851 super(TestNAT64, self).tearDown()
6852 if not self.vpp_dead:
6853 self.logger.info(self.vapi.cli("show nat64 pool"))
6854 self.logger.info(self.vapi.cli("show nat64 interfaces"))
Matus Fabian428dc912017-06-21 06:15:18 -07006855 self.logger.info(self.vapi.cli("show nat64 prefix"))
Matus Fabianab9a59c2017-08-16 05:37:36 -07006856 self.logger.info(self.vapi.cli("show nat64 bib all"))
6857 self.logger.info(self.vapi.cli("show nat64 session table all"))
Matus Fabianefcd1e92017-08-15 06:59:19 -07006858 self.logger.info(self.vapi.cli("show nat virtual-reassembly"))
Matus Fabian06596c52017-06-06 04:53:28 -07006859 self.clear_nat64()
6860
Matus Fabian8ebe6252017-11-06 05:04:53 -08006861
6862class TestDSlite(MethodHolder):
6863 """ DS-Lite Test Cases """
6864
6865 @classmethod
6866 def setUpClass(cls):
6867 super(TestDSlite, cls).setUpClass()
6868
6869 try:
6870 cls.nat_addr = '10.0.0.3'
6871 cls.nat_addr_n = socket.inet_pton(socket.AF_INET, cls.nat_addr)
6872
6873 cls.create_pg_interfaces(range(2))
6874 cls.pg0.admin_up()
6875 cls.pg0.config_ip4()
6876 cls.pg0.resolve_arp()
6877 cls.pg1.admin_up()
6878 cls.pg1.config_ip6()
6879 cls.pg1.generate_remote_hosts(2)
6880 cls.pg1.configure_ipv6_neighbors()
6881
6882 except Exception:
6883 super(TestDSlite, cls).tearDownClass()
6884 raise
6885
6886 def test_dslite(self):
6887 """ Test DS-Lite """
6888 self.vapi.dslite_add_del_pool_addr_range(self.nat_addr_n,
6889 self.nat_addr_n)
6890 aftr_ip4 = '192.0.0.1'
6891 aftr_ip4_n = socket.inet_pton(socket.AF_INET, aftr_ip4)
6892 aftr_ip6 = '2001:db8:85a3::8a2e:370:1'
6893 aftr_ip6_n = socket.inet_pton(socket.AF_INET6, aftr_ip6)
6894 self.vapi.dslite_set_aftr_addr(aftr_ip6_n, aftr_ip4_n)
6895
6896 # UDP
6897 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
6898 IPv6(dst=aftr_ip6, src=self.pg1.remote_hosts[0].ip6) /
6899 IP(dst=self.pg0.remote_ip4, src='192.168.1.1') /
6900 UDP(sport=20000, dport=10000))
6901 self.pg1.add_stream(p)
6902 self.pg_enable_capture(self.pg_interfaces)
6903 self.pg_start()
6904 capture = self.pg0.get_capture(1)
6905 capture = capture[0]
6906 self.assertFalse(capture.haslayer(IPv6))
6907 self.assertEqual(capture[IP].src, self.nat_addr)
6908 self.assertEqual(capture[IP].dst, self.pg0.remote_ip4)
6909 self.assertNotEqual(capture[UDP].sport, 20000)
6910 self.assertEqual(capture[UDP].dport, 10000)
Klement Sekerad81ae412018-05-16 10:52:54 +02006911 self.assert_packet_checksums_valid(capture)
Matus Fabian8ebe6252017-11-06 05:04:53 -08006912 out_port = capture[UDP].sport
6913
6914 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
6915 IP(dst=self.nat_addr, src=self.pg0.remote_ip4) /
6916 UDP(sport=10000, dport=out_port))
6917 self.pg0.add_stream(p)
6918 self.pg_enable_capture(self.pg_interfaces)
6919 self.pg_start()
6920 capture = self.pg1.get_capture(1)
6921 capture = capture[0]
6922 self.assertEqual(capture[IPv6].src, aftr_ip6)
6923 self.assertEqual(capture[IPv6].dst, self.pg1.remote_hosts[0].ip6)
6924 self.assertEqual(capture[IP].src, self.pg0.remote_ip4)
6925 self.assertEqual(capture[IP].dst, '192.168.1.1')
6926 self.assertEqual(capture[UDP].sport, 10000)
6927 self.assertEqual(capture[UDP].dport, 20000)
Klement Sekerad81ae412018-05-16 10:52:54 +02006928 self.assert_packet_checksums_valid(capture)
Matus Fabian8ebe6252017-11-06 05:04:53 -08006929
6930 # TCP
6931 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
6932 IPv6(dst=aftr_ip6, src=self.pg1.remote_hosts[1].ip6) /
6933 IP(dst=self.pg0.remote_ip4, src='192.168.1.1') /
6934 TCP(sport=20001, dport=10001))
6935 self.pg1.add_stream(p)
6936 self.pg_enable_capture(self.pg_interfaces)
6937 self.pg_start()
6938 capture = self.pg0.get_capture(1)
6939 capture = capture[0]
6940 self.assertFalse(capture.haslayer(IPv6))
6941 self.assertEqual(capture[IP].src, self.nat_addr)
6942 self.assertEqual(capture[IP].dst, self.pg0.remote_ip4)
6943 self.assertNotEqual(capture[TCP].sport, 20001)
6944 self.assertEqual(capture[TCP].dport, 10001)
Klement Sekerad81ae412018-05-16 10:52:54 +02006945 self.assert_packet_checksums_valid(capture)
Matus Fabian8ebe6252017-11-06 05:04:53 -08006946 out_port = capture[TCP].sport
6947
6948 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
6949 IP(dst=self.nat_addr, src=self.pg0.remote_ip4) /
6950 TCP(sport=10001, dport=out_port))
6951 self.pg0.add_stream(p)
6952 self.pg_enable_capture(self.pg_interfaces)
6953 self.pg_start()
6954 capture = self.pg1.get_capture(1)
6955 capture = capture[0]
6956 self.assertEqual(capture[IPv6].src, aftr_ip6)
6957 self.assertEqual(capture[IPv6].dst, self.pg1.remote_hosts[1].ip6)
6958 self.assertEqual(capture[IP].src, self.pg0.remote_ip4)
6959 self.assertEqual(capture[IP].dst, '192.168.1.1')
6960 self.assertEqual(capture[TCP].sport, 10001)
6961 self.assertEqual(capture[TCP].dport, 20001)
Klement Sekerad81ae412018-05-16 10:52:54 +02006962 self.assert_packet_checksums_valid(capture)
Matus Fabian8ebe6252017-11-06 05:04:53 -08006963
6964 # ICMP
6965 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
6966 IPv6(dst=aftr_ip6, src=self.pg1.remote_hosts[1].ip6) /
6967 IP(dst=self.pg0.remote_ip4, src='192.168.1.1') /
6968 ICMP(id=4000, type='echo-request'))
6969 self.pg1.add_stream(p)
6970 self.pg_enable_capture(self.pg_interfaces)
6971 self.pg_start()
6972 capture = self.pg0.get_capture(1)
6973 capture = capture[0]
6974 self.assertFalse(capture.haslayer(IPv6))
6975 self.assertEqual(capture[IP].src, self.nat_addr)
6976 self.assertEqual(capture[IP].dst, self.pg0.remote_ip4)
6977 self.assertNotEqual(capture[ICMP].id, 4000)
Klement Sekerad81ae412018-05-16 10:52:54 +02006978 self.assert_packet_checksums_valid(capture)
Matus Fabian8ebe6252017-11-06 05:04:53 -08006979 out_id = capture[ICMP].id
6980
6981 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
6982 IP(dst=self.nat_addr, src=self.pg0.remote_ip4) /
6983 ICMP(id=out_id, type='echo-reply'))
6984 self.pg0.add_stream(p)
6985 self.pg_enable_capture(self.pg_interfaces)
6986 self.pg_start()
6987 capture = self.pg1.get_capture(1)
6988 capture = capture[0]
6989 self.assertEqual(capture[IPv6].src, aftr_ip6)
6990 self.assertEqual(capture[IPv6].dst, self.pg1.remote_hosts[1].ip6)
6991 self.assertEqual(capture[IP].src, self.pg0.remote_ip4)
6992 self.assertEqual(capture[IP].dst, '192.168.1.1')
6993 self.assertEqual(capture[ICMP].id, 4000)
Klement Sekerad81ae412018-05-16 10:52:54 +02006994 self.assert_packet_checksums_valid(capture)
Matus Fabian8ebe6252017-11-06 05:04:53 -08006995
Matus Fabian331acc62017-12-08 03:38:51 -08006996 # ping DS-Lite AFTR tunnel endpoint address
6997 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
6998 IPv6(src=self.pg1.remote_hosts[1].ip6, dst=aftr_ip6) /
6999 ICMPv6EchoRequest())
7000 self.pg1.add_stream(p)
7001 self.pg_enable_capture(self.pg_interfaces)
7002 self.pg_start()
7003 capture = self.pg1.get_capture(1)
7004 self.assertEqual(1, len(capture))
7005 capture = capture[0]
7006 self.assertEqual(capture[IPv6].src, aftr_ip6)
7007 self.assertEqual(capture[IPv6].dst, self.pg1.remote_hosts[1].ip6)
7008 self.assertTrue(capture.haslayer(ICMPv6EchoReply))
7009
Matus Fabian8ebe6252017-11-06 05:04:53 -08007010 def tearDown(self):
7011 super(TestDSlite, self).tearDown()
7012 if not self.vpp_dead:
7013 self.logger.info(self.vapi.cli("show dslite pool"))
7014 self.logger.info(
7015 self.vapi.cli("show dslite aftr-tunnel-endpoint-address"))
7016 self.logger.info(self.vapi.cli("show dslite sessions"))
7017
Juraj Slobodac5c6a332018-01-09 16:08:32 +01007018
7019class TestDSliteCE(MethodHolder):
7020 """ DS-Lite CE Test Cases """
7021
7022 @classmethod
7023 def setUpConstants(cls):
7024 super(TestDSliteCE, cls).setUpConstants()
7025 cls.vpp_cmdline.extend(["nat", "{", "dslite ce", "}"])
7026
7027 @classmethod
7028 def setUpClass(cls):
7029 super(TestDSliteCE, cls).setUpClass()
7030
7031 try:
7032 cls.create_pg_interfaces(range(2))
7033 cls.pg0.admin_up()
7034 cls.pg0.config_ip4()
7035 cls.pg0.resolve_arp()
7036 cls.pg1.admin_up()
7037 cls.pg1.config_ip6()
7038 cls.pg1.generate_remote_hosts(1)
7039 cls.pg1.configure_ipv6_neighbors()
7040
7041 except Exception:
7042 super(TestDSliteCE, cls).tearDownClass()
7043 raise
7044
7045 def test_dslite_ce(self):
7046 """ Test DS-Lite CE """
7047
7048 b4_ip4 = '192.0.0.2'
7049 b4_ip4_n = socket.inet_pton(socket.AF_INET, b4_ip4)
7050 b4_ip6 = '2001:db8:62aa::375e:f4c1:1'
7051 b4_ip6_n = socket.inet_pton(socket.AF_INET6, b4_ip6)
7052 self.vapi.dslite_set_b4_addr(b4_ip6_n, b4_ip4_n)
7053
7054 aftr_ip4 = '192.0.0.1'
7055 aftr_ip4_n = socket.inet_pton(socket.AF_INET, aftr_ip4)
7056 aftr_ip6 = '2001:db8:85a3::8a2e:370:1'
7057 aftr_ip6_n = socket.inet_pton(socket.AF_INET6, aftr_ip6)
7058 self.vapi.dslite_set_aftr_addr(aftr_ip6_n, aftr_ip4_n)
7059
7060 self.vapi.ip_add_del_route(dst_address=aftr_ip6_n,
7061 dst_address_length=128,
7062 next_hop_address=self.pg1.remote_ip6n,
7063 next_hop_sw_if_index=self.pg1.sw_if_index,
7064 is_ipv6=1)
7065
7066 # UDP encapsulation
7067 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
7068 IP(dst=self.pg1.remote_ip4, src=self.pg0.remote_ip4) /
7069 UDP(sport=10000, dport=20000))
7070 self.pg0.add_stream(p)
7071 self.pg_enable_capture(self.pg_interfaces)
7072 self.pg_start()
7073 capture = self.pg1.get_capture(1)
7074 capture = capture[0]
7075 self.assertEqual(capture[IPv6].src, b4_ip6)
7076 self.assertEqual(capture[IPv6].dst, aftr_ip6)
7077 self.assertEqual(capture[IP].src, self.pg0.remote_ip4)
7078 self.assertEqual(capture[IP].dst, self.pg1.remote_ip4)
7079 self.assertEqual(capture[UDP].sport, 10000)
7080 self.assertEqual(capture[UDP].dport, 20000)
Klement Sekerad81ae412018-05-16 10:52:54 +02007081 self.assert_packet_checksums_valid(capture)
Juraj Slobodac5c6a332018-01-09 16:08:32 +01007082
7083 # UDP decapsulation
7084 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
7085 IPv6(dst=b4_ip6, src=aftr_ip6) /
7086 IP(dst=self.pg0.remote_ip4, src=self.pg1.remote_ip4) /
7087 UDP(sport=20000, dport=10000))
7088 self.pg1.add_stream(p)
7089 self.pg_enable_capture(self.pg_interfaces)
7090 self.pg_start()
7091 capture = self.pg0.get_capture(1)
7092 capture = capture[0]
7093 self.assertFalse(capture.haslayer(IPv6))
7094 self.assertEqual(capture[IP].src, self.pg1.remote_ip4)
7095 self.assertEqual(capture[IP].dst, self.pg0.remote_ip4)
7096 self.assertEqual(capture[UDP].sport, 20000)
7097 self.assertEqual(capture[UDP].dport, 10000)
Klement Sekerad81ae412018-05-16 10:52:54 +02007098 self.assert_packet_checksums_valid(capture)
Juraj Slobodac5c6a332018-01-09 16:08:32 +01007099
7100 # ping DS-Lite B4 tunnel endpoint address
7101 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
7102 IPv6(src=self.pg1.remote_hosts[0].ip6, dst=b4_ip6) /
7103 ICMPv6EchoRequest())
7104 self.pg1.add_stream(p)
7105 self.pg_enable_capture(self.pg_interfaces)
7106 self.pg_start()
7107 capture = self.pg1.get_capture(1)
7108 self.assertEqual(1, len(capture))
7109 capture = capture[0]
7110 self.assertEqual(capture[IPv6].src, b4_ip6)
7111 self.assertEqual(capture[IPv6].dst, self.pg1.remote_hosts[0].ip6)
7112 self.assertTrue(capture.haslayer(ICMPv6EchoReply))
7113
7114 def tearDown(self):
7115 super(TestDSliteCE, self).tearDown()
7116 if not self.vpp_dead:
7117 self.logger.info(
7118 self.vapi.cli("show dslite aftr-tunnel-endpoint-address"))
7119 self.logger.info(
7120 self.vapi.cli("show dslite b4-tunnel-endpoint-address"))
7121
Matus Fabianf2a23cc2018-01-22 03:41:53 -08007122
7123class TestNAT66(MethodHolder):
7124 """ NAT66 Test Cases """
7125
7126 @classmethod
7127 def setUpClass(cls):
7128 super(TestNAT66, cls).setUpClass()
7129
7130 try:
7131 cls.nat_addr = 'fd01:ff::2'
7132 cls.nat_addr_n = socket.inet_pton(socket.AF_INET6, cls.nat_addr)
7133
7134 cls.create_pg_interfaces(range(2))
7135 cls.interfaces = list(cls.pg_interfaces)
7136
7137 for i in cls.interfaces:
7138 i.admin_up()
7139 i.config_ip6()
7140 i.configure_ipv6_neighbors()
7141
7142 except Exception:
7143 super(TestNAT66, cls).tearDownClass()
7144 raise
7145
7146 def test_static(self):
7147 """ 1:1 NAT66 test """
7148 self.vapi.nat66_add_del_interface(self.pg0.sw_if_index)
7149 self.vapi.nat66_add_del_interface(self.pg1.sw_if_index, is_inside=0)
7150 self.vapi.nat66_add_del_static_mapping(self.pg0.remote_ip6n,
7151 self.nat_addr_n)
7152
7153 # in2out
7154 pkts = []
7155 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
7156 IPv6(src=self.pg0.remote_ip6, dst=self.pg1.remote_ip6) /
7157 TCP())
7158 pkts.append(p)
7159 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
7160 IPv6(src=self.pg0.remote_ip6, dst=self.pg1.remote_ip6) /
7161 UDP())
7162 pkts.append(p)
7163 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
7164 IPv6(src=self.pg0.remote_ip6, dst=self.pg1.remote_ip6) /
7165 ICMPv6EchoRequest())
7166 pkts.append(p)
7167 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
7168 IPv6(src=self.pg0.remote_ip6, dst=self.pg1.remote_ip6) /
7169 GRE() / IP() / TCP())
7170 pkts.append(p)
7171 self.pg0.add_stream(pkts)
7172 self.pg_enable_capture(self.pg_interfaces)
7173 self.pg_start()
7174 capture = self.pg1.get_capture(len(pkts))
7175 for packet in capture:
7176 try:
7177 self.assertEqual(packet[IPv6].src, self.nat_addr)
7178 self.assertEqual(packet[IPv6].dst, self.pg1.remote_ip6)
Klement Sekerad81ae412018-05-16 10:52:54 +02007179 self.assert_packet_checksums_valid(packet)
Matus Fabianf2a23cc2018-01-22 03:41:53 -08007180 except:
7181 self.logger.error(ppp("Unexpected or invalid packet:", packet))
7182 raise
7183
7184 # out2in
7185 pkts = []
7186 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
7187 IPv6(src=self.pg1.remote_ip6, dst=self.nat_addr) /
7188 TCP())
7189 pkts.append(p)
7190 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
7191 IPv6(src=self.pg1.remote_ip6, dst=self.nat_addr) /
7192 UDP())
7193 pkts.append(p)
7194 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
7195 IPv6(src=self.pg1.remote_ip6, dst=self.nat_addr) /
7196 ICMPv6EchoReply())
7197 pkts.append(p)
7198 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
7199 IPv6(src=self.pg1.remote_ip6, dst=self.nat_addr) /
7200 GRE() / IP() / TCP())
7201 pkts.append(p)
7202 self.pg1.add_stream(pkts)
7203 self.pg_enable_capture(self.pg_interfaces)
7204 self.pg_start()
7205 capture = self.pg0.get_capture(len(pkts))
7206 for packet in capture:
7207 try:
7208 self.assertEqual(packet[IPv6].src, self.pg1.remote_ip6)
7209 self.assertEqual(packet[IPv6].dst, self.pg0.remote_ip6)
Klement Sekerad81ae412018-05-16 10:52:54 +02007210 self.assert_packet_checksums_valid(packet)
Matus Fabianf2a23cc2018-01-22 03:41:53 -08007211 except:
7212 self.logger.error(ppp("Unexpected or invalid packet:", packet))
7213 raise
7214
7215 sm = self.vapi.nat66_static_mapping_dump()
7216 self.assertEqual(len(sm), 1)
7217 self.assertEqual(sm[0].total_pkts, 8)
7218
Juraj Sloboda9341e342018-04-13 12:00:46 +02007219 def test_check_no_translate(self):
7220 """ NAT66 translate only when egress interface is outside interface """
7221 self.vapi.nat66_add_del_interface(self.pg0.sw_if_index)
7222 self.vapi.nat66_add_del_interface(self.pg1.sw_if_index)
7223 self.vapi.nat66_add_del_static_mapping(self.pg0.remote_ip6n,
7224 self.nat_addr_n)
7225
7226 # in2out
7227 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
7228 IPv6(src=self.pg0.remote_ip6, dst=self.pg1.remote_ip6) /
7229 UDP())
7230 self.pg0.add_stream([p])
7231 self.pg_enable_capture(self.pg_interfaces)
7232 self.pg_start()
7233 capture = self.pg1.get_capture(1)
7234 packet = capture[0]
7235 try:
7236 self.assertEqual(packet[IPv6].src, self.pg0.remote_ip6)
7237 self.assertEqual(packet[IPv6].dst, self.pg1.remote_ip6)
7238 except:
7239 self.logger.error(ppp("Unexpected or invalid packet:", packet))
7240 raise
7241
Matus Fabianf2a23cc2018-01-22 03:41:53 -08007242 def clear_nat66(self):
7243 """
7244 Clear NAT66 configuration.
7245 """
7246 interfaces = self.vapi.nat66_interface_dump()
7247 for intf in interfaces:
7248 self.vapi.nat66_add_del_interface(intf.sw_if_index,
7249 intf.is_inside,
7250 is_add=0)
7251
7252 static_mappings = self.vapi.nat66_static_mapping_dump()
7253 for sm in static_mappings:
7254 self.vapi.nat66_add_del_static_mapping(sm.local_ip_address,
7255 sm.external_ip_address,
7256 sm.vrf_id,
7257 is_add=0)
7258
7259 def tearDown(self):
7260 super(TestNAT66, self).tearDown()
7261 if not self.vpp_dead:
7262 self.logger.info(self.vapi.cli("show nat66 interfaces"))
7263 self.logger.info(self.vapi.cli("show nat66 static mappings"))
7264 self.clear_nat66()
7265
Klement Sekerad81ae412018-05-16 10:52:54 +02007266
Matus Fabiande886752016-12-07 03:38:19 -08007267if __name__ == '__main__':
7268 unittest.main(testRunner=VppTestRunner)