blob: 973666a3f9eb044996592abc9ee9fdc9b4d8560d [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 Fabiana6110b62018-06-13 05:39:07 -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:
1270 # in2out - static mapping match
1271
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
1286 # in2out - no static mapping match
1287
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
Matus Fabian70a26ac2018-05-14 06:20:28 -07001310 user = self.pg0.remote_hosts[1]
1311 sessions = self.vapi.nat44_user_session_dump(user.ip4n, 0)
1312 self.assertEqual(len(sessions), 3)
1313 self.assertTrue(sessions[0].ext_host_valid)
1314 self.vapi.nat44_del_session(
1315 sessions[0].inside_ip_address,
1316 sessions[0].inside_port,
1317 sessions[0].protocol,
1318 ext_host_address=sessions[0].ext_host_address,
1319 ext_host_port=sessions[0].ext_host_port)
1320 sessions = self.vapi.nat44_user_session_dump(user.ip4n, 0)
1321 self.assertEqual(len(sessions), 2)
1322
Juraj Sloboda7b929792017-11-23 13:20:48 +01001323 finally:
1324 self.vapi.nat44_forwarding_enable_disable(0)
1325 self.vapi.nat44_add_del_static_mapping(local_ip=real_ip,
1326 external_ip=alias_ip,
1327 is_add=0)
1328
Matus Fabiande886752016-12-07 03:38:19 -08001329 def test_static_in(self):
Matus Fabian2ba92e32017-08-21 07:05:03 -07001330 """ 1:1 NAT initialized from inside network """
Matus Fabiande886752016-12-07 03:38:19 -08001331
1332 nat_ip = "10.0.0.10"
1333 self.tcp_port_out = 6303
1334 self.udp_port_out = 6304
1335 self.icmp_id_out = 6305
1336
Matus Fabian2ba92e32017-08-21 07:05:03 -07001337 self.nat44_add_static_mapping(self.pg0.remote_ip4, nat_ip)
1338 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
1339 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
1340 is_inside=0)
Matus Fabian5f224992018-01-25 21:59:16 -08001341 sm = self.vapi.nat44_static_mapping_dump()
1342 self.assertEqual(len(sm), 1)
1343 self.assertEqual((sm[0].tag).split('\0', 1)[0], '')
Matus Fabian9dba7812018-01-31 01:13:23 -08001344 self.assertEqual(sm[0].protocol, 0)
1345 self.assertEqual(sm[0].local_port, 0)
1346 self.assertEqual(sm[0].external_port, 0)
Matus Fabiande886752016-12-07 03:38:19 -08001347
1348 # in2out
1349 pkts = self.create_stream_in(self.pg0, self.pg1)
1350 self.pg0.add_stream(pkts)
1351 self.pg_enable_capture(self.pg_interfaces)
1352 self.pg_start()
Klement Sekeradab231a2016-12-21 08:50:14 +01001353 capture = self.pg1.get_capture(len(pkts))
Matus Fabiande886752016-12-07 03:38:19 -08001354 self.verify_capture_out(capture, nat_ip, True)
1355
1356 # out2in
1357 pkts = self.create_stream_out(self.pg1, nat_ip)
1358 self.pg1.add_stream(pkts)
1359 self.pg_enable_capture(self.pg_interfaces)
1360 self.pg_start()
Klement Sekeradab231a2016-12-21 08:50:14 +01001361 capture = self.pg0.get_capture(len(pkts))
Matus Fabiande886752016-12-07 03:38:19 -08001362 self.verify_capture_in(capture, self.pg0)
1363
1364 def test_static_out(self):
Matus Fabian2ba92e32017-08-21 07:05:03 -07001365 """ 1:1 NAT initialized from outside network """
Matus Fabiande886752016-12-07 03:38:19 -08001366
1367 nat_ip = "10.0.0.20"
1368 self.tcp_port_out = 6303
1369 self.udp_port_out = 6304
1370 self.icmp_id_out = 6305
Matus Fabian5f224992018-01-25 21:59:16 -08001371 tag = "testTAG"
Matus Fabiande886752016-12-07 03:38:19 -08001372
Matus Fabian5f224992018-01-25 21:59:16 -08001373 self.nat44_add_static_mapping(self.pg0.remote_ip4, nat_ip, tag=tag)
Matus Fabian2ba92e32017-08-21 07:05:03 -07001374 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
1375 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
1376 is_inside=0)
Matus Fabian5f224992018-01-25 21:59:16 -08001377 sm = self.vapi.nat44_static_mapping_dump()
1378 self.assertEqual(len(sm), 1)
1379 self.assertEqual((sm[0].tag).split('\0', 1)[0], tag)
Matus Fabiande886752016-12-07 03:38:19 -08001380
1381 # out2in
1382 pkts = self.create_stream_out(self.pg1, nat_ip)
1383 self.pg1.add_stream(pkts)
1384 self.pg_enable_capture(self.pg_interfaces)
1385 self.pg_start()
Klement Sekeradab231a2016-12-21 08:50:14 +01001386 capture = self.pg0.get_capture(len(pkts))
Matus Fabiande886752016-12-07 03:38:19 -08001387 self.verify_capture_in(capture, self.pg0)
1388
1389 # in2out
1390 pkts = self.create_stream_in(self.pg0, self.pg1)
1391 self.pg0.add_stream(pkts)
1392 self.pg_enable_capture(self.pg_interfaces)
1393 self.pg_start()
Klement Sekeradab231a2016-12-21 08:50:14 +01001394 capture = self.pg1.get_capture(len(pkts))
Matus Fabiande886752016-12-07 03:38:19 -08001395 self.verify_capture_out(capture, nat_ip, True)
1396
1397 def test_static_with_port_in(self):
Matus Fabian2ba92e32017-08-21 07:05:03 -07001398 """ 1:1 NAPT initialized from inside network """
Matus Fabiande886752016-12-07 03:38:19 -08001399
1400 self.tcp_port_out = 3606
1401 self.udp_port_out = 3607
1402 self.icmp_id_out = 3608
1403
Matus Fabian2ba92e32017-08-21 07:05:03 -07001404 self.nat44_add_address(self.nat_addr)
1405 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
1406 self.tcp_port_in, self.tcp_port_out,
1407 proto=IP_PROTOS.tcp)
1408 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
1409 self.udp_port_in, self.udp_port_out,
1410 proto=IP_PROTOS.udp)
1411 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
1412 self.icmp_id_in, self.icmp_id_out,
1413 proto=IP_PROTOS.icmp)
1414 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
1415 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
1416 is_inside=0)
Matus Fabiande886752016-12-07 03:38:19 -08001417
1418 # in2out
1419 pkts = self.create_stream_in(self.pg0, self.pg1)
1420 self.pg0.add_stream(pkts)
1421 self.pg_enable_capture(self.pg_interfaces)
1422 self.pg_start()
Klement Sekeradab231a2016-12-21 08:50:14 +01001423 capture = self.pg1.get_capture(len(pkts))
Matus Fabiande886752016-12-07 03:38:19 -08001424 self.verify_capture_out(capture)
1425
1426 # out2in
1427 pkts = self.create_stream_out(self.pg1)
1428 self.pg1.add_stream(pkts)
1429 self.pg_enable_capture(self.pg_interfaces)
1430 self.pg_start()
Klement Sekeradab231a2016-12-21 08:50:14 +01001431 capture = self.pg0.get_capture(len(pkts))
Matus Fabiande886752016-12-07 03:38:19 -08001432 self.verify_capture_in(capture, self.pg0)
1433
1434 def test_static_with_port_out(self):
Matus Fabian2ba92e32017-08-21 07:05:03 -07001435 """ 1:1 NAPT initialized from outside network """
Matus Fabiande886752016-12-07 03:38:19 -08001436
1437 self.tcp_port_out = 30606
1438 self.udp_port_out = 30607
1439 self.icmp_id_out = 30608
1440
Matus Fabian2ba92e32017-08-21 07:05:03 -07001441 self.nat44_add_address(self.nat_addr)
1442 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
1443 self.tcp_port_in, self.tcp_port_out,
1444 proto=IP_PROTOS.tcp)
1445 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
1446 self.udp_port_in, self.udp_port_out,
1447 proto=IP_PROTOS.udp)
1448 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
1449 self.icmp_id_in, self.icmp_id_out,
1450 proto=IP_PROTOS.icmp)
1451 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
1452 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
1453 is_inside=0)
Matus Fabiande886752016-12-07 03:38:19 -08001454
1455 # out2in
1456 pkts = self.create_stream_out(self.pg1)
1457 self.pg1.add_stream(pkts)
1458 self.pg_enable_capture(self.pg_interfaces)
1459 self.pg_start()
Klement Sekeradab231a2016-12-21 08:50:14 +01001460 capture = self.pg0.get_capture(len(pkts))
Matus Fabiande886752016-12-07 03:38:19 -08001461 self.verify_capture_in(capture, self.pg0)
1462
1463 # in2out
1464 pkts = self.create_stream_in(self.pg0, self.pg1)
1465 self.pg0.add_stream(pkts)
1466 self.pg_enable_capture(self.pg_interfaces)
1467 self.pg_start()
Klement Sekeradab231a2016-12-21 08:50:14 +01001468 capture = self.pg1.get_capture(len(pkts))
Matus Fabiande886752016-12-07 03:38:19 -08001469 self.verify_capture_out(capture)
1470
1471 def test_static_vrf_aware(self):
Matus Fabian2ba92e32017-08-21 07:05:03 -07001472 """ 1:1 NAT VRF awareness """
Matus Fabiande886752016-12-07 03:38:19 -08001473
1474 nat_ip1 = "10.0.0.30"
1475 nat_ip2 = "10.0.0.40"
1476 self.tcp_port_out = 6303
1477 self.udp_port_out = 6304
1478 self.icmp_id_out = 6305
1479
Matus Fabian2ba92e32017-08-21 07:05:03 -07001480 self.nat44_add_static_mapping(self.pg4.remote_ip4, nat_ip1,
1481 vrf_id=10)
1482 self.nat44_add_static_mapping(self.pg0.remote_ip4, nat_ip2,
1483 vrf_id=10)
1484 self.vapi.nat44_interface_add_del_feature(self.pg3.sw_if_index,
1485 is_inside=0)
1486 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
1487 self.vapi.nat44_interface_add_del_feature(self.pg4.sw_if_index)
Matus Fabiande886752016-12-07 03:38:19 -08001488
Matus Fabian2ba92e32017-08-21 07:05:03 -07001489 # inside interface VRF match NAT44 static mapping VRF
Matus Fabiande886752016-12-07 03:38:19 -08001490 pkts = self.create_stream_in(self.pg4, self.pg3)
1491 self.pg4.add_stream(pkts)
1492 self.pg_enable_capture(self.pg_interfaces)
1493 self.pg_start()
Klement Sekeradab231a2016-12-21 08:50:14 +01001494 capture = self.pg3.get_capture(len(pkts))
Matus Fabiande886752016-12-07 03:38:19 -08001495 self.verify_capture_out(capture, nat_ip1, True)
1496
Matus Fabian2ba92e32017-08-21 07:05:03 -07001497 # inside interface VRF don't match NAT44 static mapping VRF (packets
Matus Fabiande886752016-12-07 03:38:19 -08001498 # are dropped)
1499 pkts = self.create_stream_in(self.pg0, self.pg3)
1500 self.pg0.add_stream(pkts)
1501 self.pg_enable_capture(self.pg_interfaces)
1502 self.pg_start()
Klement Sekera9225dee2016-12-12 08:36:58 +01001503 self.pg3.assert_nothing_captured()
Matus Fabiande886752016-12-07 03:38:19 -08001504
Matus Fabianb793d092018-01-31 05:50:21 -08001505 def test_dynamic_to_static(self):
1506 """ Switch from dynamic translation to 1:1NAT """
1507 nat_ip = "10.0.0.10"
1508 self.tcp_port_out = 6303
1509 self.udp_port_out = 6304
1510 self.icmp_id_out = 6305
1511
1512 self.nat44_add_address(self.nat_addr)
1513 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
1514 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
1515 is_inside=0)
1516
1517 # dynamic
1518 pkts = self.create_stream_in(self.pg0, self.pg1)
1519 self.pg0.add_stream(pkts)
1520 self.pg_enable_capture(self.pg_interfaces)
1521 self.pg_start()
1522 capture = self.pg1.get_capture(len(pkts))
1523 self.verify_capture_out(capture)
1524
1525 # 1:1NAT
1526 self.nat44_add_static_mapping(self.pg0.remote_ip4, nat_ip)
1527 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n, 0)
1528 self.assertEqual(len(sessions), 0)
1529 pkts = self.create_stream_in(self.pg0, self.pg1)
1530 self.pg0.add_stream(pkts)
1531 self.pg_enable_capture(self.pg_interfaces)
1532 self.pg_start()
1533 capture = self.pg1.get_capture(len(pkts))
1534 self.verify_capture_out(capture, nat_ip, True)
1535
Matus Fabianab7a8052017-11-28 04:29:41 -08001536 def test_identity_nat(self):
1537 """ Identity NAT """
1538
1539 self.vapi.nat44_add_del_identity_mapping(ip=self.pg0.remote_ip4n)
1540 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
1541 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
1542 is_inside=0)
1543
1544 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
1545 IP(src=self.pg1.remote_ip4, dst=self.pg0.remote_ip4) /
1546 TCP(sport=12345, dport=56789))
1547 self.pg1.add_stream(p)
1548 self.pg_enable_capture(self.pg_interfaces)
1549 self.pg_start()
1550 capture = self.pg0.get_capture(1)
1551 p = capture[0]
1552 try:
1553 ip = p[IP]
1554 tcp = p[TCP]
1555 self.assertEqual(ip.dst, self.pg0.remote_ip4)
1556 self.assertEqual(ip.src, self.pg1.remote_ip4)
1557 self.assertEqual(tcp.dport, 56789)
1558 self.assertEqual(tcp.sport, 12345)
Klement Sekerad81ae412018-05-16 10:52:54 +02001559 self.assert_packet_checksums_valid(p)
Matus Fabianab7a8052017-11-28 04:29:41 -08001560 except:
1561 self.logger.error(ppp("Unexpected or invalid packet:", p))
1562 raise
1563
Matus Fabiande886752016-12-07 03:38:19 -08001564 def test_multiple_inside_interfaces(self):
Matus Fabian2ba92e32017-08-21 07:05:03 -07001565 """ NAT44 multiple non-overlapping address space inside interfaces """
Matus Fabiande886752016-12-07 03:38:19 -08001566
Matus Fabian2ba92e32017-08-21 07:05:03 -07001567 self.nat44_add_address(self.nat_addr)
1568 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
1569 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index)
1570 self.vapi.nat44_interface_add_del_feature(self.pg3.sw_if_index,
1571 is_inside=0)
Matus Fabiande886752016-12-07 03:38:19 -08001572
Matus Fabian2ba92e32017-08-21 07:05:03 -07001573 # between two NAT44 inside interfaces (no translation)
Matus Fabian675a69c2017-01-18 01:46:01 -08001574 pkts = self.create_stream_in(self.pg0, self.pg1)
1575 self.pg0.add_stream(pkts)
1576 self.pg_enable_capture(self.pg_interfaces)
1577 self.pg_start()
1578 capture = self.pg1.get_capture(len(pkts))
1579 self.verify_capture_no_translation(capture, self.pg0, self.pg1)
1580
Matus Fabian2ba92e32017-08-21 07:05:03 -07001581 # from NAT44 inside to interface without NAT44 feature (no translation)
Matus Fabian675a69c2017-01-18 01:46:01 -08001582 pkts = self.create_stream_in(self.pg0, self.pg2)
1583 self.pg0.add_stream(pkts)
1584 self.pg_enable_capture(self.pg_interfaces)
1585 self.pg_start()
1586 capture = self.pg2.get_capture(len(pkts))
1587 self.verify_capture_no_translation(capture, self.pg0, self.pg2)
1588
Matus Fabiande886752016-12-07 03:38:19 -08001589 # in2out 1st interface
1590 pkts = self.create_stream_in(self.pg0, self.pg3)
1591 self.pg0.add_stream(pkts)
1592 self.pg_enable_capture(self.pg_interfaces)
1593 self.pg_start()
Klement Sekeradab231a2016-12-21 08:50:14 +01001594 capture = self.pg3.get_capture(len(pkts))
Matus Fabiande886752016-12-07 03:38:19 -08001595 self.verify_capture_out(capture)
1596
1597 # out2in 1st interface
1598 pkts = self.create_stream_out(self.pg3)
1599 self.pg3.add_stream(pkts)
1600 self.pg_enable_capture(self.pg_interfaces)
1601 self.pg_start()
Klement Sekeradab231a2016-12-21 08:50:14 +01001602 capture = self.pg0.get_capture(len(pkts))
Matus Fabiande886752016-12-07 03:38:19 -08001603 self.verify_capture_in(capture, self.pg0)
1604
1605 # in2out 2nd interface
1606 pkts = self.create_stream_in(self.pg1, self.pg3)
1607 self.pg1.add_stream(pkts)
1608 self.pg_enable_capture(self.pg_interfaces)
1609 self.pg_start()
Klement Sekeradab231a2016-12-21 08:50:14 +01001610 capture = self.pg3.get_capture(len(pkts))
Matus Fabiande886752016-12-07 03:38:19 -08001611 self.verify_capture_out(capture)
1612
1613 # out2in 2nd interface
1614 pkts = self.create_stream_out(self.pg3)
1615 self.pg3.add_stream(pkts)
1616 self.pg_enable_capture(self.pg_interfaces)
1617 self.pg_start()
Klement Sekeradab231a2016-12-21 08:50:14 +01001618 capture = self.pg1.get_capture(len(pkts))
Matus Fabiande886752016-12-07 03:38:19 -08001619 self.verify_capture_in(capture, self.pg1)
1620
Matus Fabiande886752016-12-07 03:38:19 -08001621 def test_inside_overlapping_interfaces(self):
Matus Fabian2ba92e32017-08-21 07:05:03 -07001622 """ NAT44 multiple inside interfaces with overlapping address space """
Matus Fabiande886752016-12-07 03:38:19 -08001623
Matus Fabian675a69c2017-01-18 01:46:01 -08001624 static_nat_ip = "10.0.0.10"
Matus Fabian2ba92e32017-08-21 07:05:03 -07001625 self.nat44_add_address(self.nat_addr)
1626 self.vapi.nat44_interface_add_del_feature(self.pg3.sw_if_index,
1627 is_inside=0)
1628 self.vapi.nat44_interface_add_del_feature(self.pg4.sw_if_index)
1629 self.vapi.nat44_interface_add_del_feature(self.pg5.sw_if_index)
1630 self.vapi.nat44_interface_add_del_feature(self.pg6.sw_if_index)
1631 self.nat44_add_static_mapping(self.pg6.remote_ip4, static_nat_ip,
1632 vrf_id=20)
Matus Fabian675a69c2017-01-18 01:46:01 -08001633
Matus Fabian2ba92e32017-08-21 07:05:03 -07001634 # between NAT44 inside interfaces with same VRF (no translation)
Matus Fabian675a69c2017-01-18 01:46:01 -08001635 pkts = self.create_stream_in(self.pg4, self.pg5)
1636 self.pg4.add_stream(pkts)
1637 self.pg_enable_capture(self.pg_interfaces)
1638 self.pg_start()
1639 capture = self.pg5.get_capture(len(pkts))
1640 self.verify_capture_no_translation(capture, self.pg4, self.pg5)
1641
Matus Fabian2ba92e32017-08-21 07:05:03 -07001642 # between NAT44 inside interfaces with different VRF (hairpinning)
Matus Fabian675a69c2017-01-18 01:46:01 -08001643 p = (Ether(src=self.pg4.remote_mac, dst=self.pg4.local_mac) /
1644 IP(src=self.pg4.remote_ip4, dst=static_nat_ip) /
1645 TCP(sport=1234, dport=5678))
1646 self.pg4.add_stream(p)
1647 self.pg_enable_capture(self.pg_interfaces)
1648 self.pg_start()
1649 capture = self.pg6.get_capture(1)
1650 p = capture[0]
1651 try:
1652 ip = p[IP]
1653 tcp = p[TCP]
Matus Fabian2ba92e32017-08-21 07:05:03 -07001654 self.assertEqual(ip.src, self.nat_addr)
Matus Fabian675a69c2017-01-18 01:46:01 -08001655 self.assertEqual(ip.dst, self.pg6.remote_ip4)
1656 self.assertNotEqual(tcp.sport, 1234)
1657 self.assertEqual(tcp.dport, 5678)
1658 except:
1659 self.logger.error(ppp("Unexpected or invalid packet:", p))
1660 raise
Matus Fabiande886752016-12-07 03:38:19 -08001661
1662 # in2out 1st interface
1663 pkts = self.create_stream_in(self.pg4, self.pg3)
1664 self.pg4.add_stream(pkts)
1665 self.pg_enable_capture(self.pg_interfaces)
1666 self.pg_start()
Klement Sekeradab231a2016-12-21 08:50:14 +01001667 capture = self.pg3.get_capture(len(pkts))
Matus Fabiande886752016-12-07 03:38:19 -08001668 self.verify_capture_out(capture)
1669
1670 # out2in 1st interface
1671 pkts = self.create_stream_out(self.pg3)
1672 self.pg3.add_stream(pkts)
1673 self.pg_enable_capture(self.pg_interfaces)
1674 self.pg_start()
Klement Sekeradab231a2016-12-21 08:50:14 +01001675 capture = self.pg4.get_capture(len(pkts))
Matus Fabiande886752016-12-07 03:38:19 -08001676 self.verify_capture_in(capture, self.pg4)
1677
1678 # in2out 2nd interface
1679 pkts = self.create_stream_in(self.pg5, self.pg3)
1680 self.pg5.add_stream(pkts)
1681 self.pg_enable_capture(self.pg_interfaces)
1682 self.pg_start()
Klement Sekeradab231a2016-12-21 08:50:14 +01001683 capture = self.pg3.get_capture(len(pkts))
Matus Fabiande886752016-12-07 03:38:19 -08001684 self.verify_capture_out(capture)
1685
1686 # out2in 2nd interface
1687 pkts = self.create_stream_out(self.pg3)
1688 self.pg3.add_stream(pkts)
1689 self.pg_enable_capture(self.pg_interfaces)
1690 self.pg_start()
Klement Sekeradab231a2016-12-21 08:50:14 +01001691 capture = self.pg5.get_capture(len(pkts))
Matus Fabiande886752016-12-07 03:38:19 -08001692 self.verify_capture_in(capture, self.pg5)
1693
magalik23caa882017-02-08 23:25:45 -08001694 # pg5 session dump
Matus Fabian2ba92e32017-08-21 07:05:03 -07001695 addresses = self.vapi.nat44_address_dump()
magalik23caa882017-02-08 23:25:45 -08001696 self.assertEqual(len(addresses), 1)
Matus Fabian2ba92e32017-08-21 07:05:03 -07001697 sessions = self.vapi.nat44_user_session_dump(self.pg5.remote_ip4n, 10)
magalik23caa882017-02-08 23:25:45 -08001698 self.assertEqual(len(sessions), 3)
1699 for session in sessions:
1700 self.assertFalse(session.is_static)
1701 self.assertEqual(session.inside_ip_address[0:4],
1702 self.pg5.remote_ip4n)
1703 self.assertEqual(session.outside_ip_address,
1704 addresses[0].ip_address)
1705 self.assertEqual(sessions[0].protocol, IP_PROTOS.tcp)
1706 self.assertEqual(sessions[1].protocol, IP_PROTOS.udp)
1707 self.assertEqual(sessions[2].protocol, IP_PROTOS.icmp)
1708 self.assertEqual(sessions[0].inside_port, self.tcp_port_in)
1709 self.assertEqual(sessions[1].inside_port, self.udp_port_in)
1710 self.assertEqual(sessions[2].inside_port, self.icmp_id_in)
1711 self.assertEqual(sessions[0].outside_port, self.tcp_port_out)
1712 self.assertEqual(sessions[1].outside_port, self.udp_port_out)
1713 self.assertEqual(sessions[2].outside_port, self.icmp_id_out)
1714
Matus Fabiande886752016-12-07 03:38:19 -08001715 # in2out 3rd interface
1716 pkts = self.create_stream_in(self.pg6, self.pg3)
1717 self.pg6.add_stream(pkts)
1718 self.pg_enable_capture(self.pg_interfaces)
1719 self.pg_start()
Klement Sekeradab231a2016-12-21 08:50:14 +01001720 capture = self.pg3.get_capture(len(pkts))
Matus Fabian675a69c2017-01-18 01:46:01 -08001721 self.verify_capture_out(capture, static_nat_ip, True)
Matus Fabiande886752016-12-07 03:38:19 -08001722
1723 # out2in 3rd interface
Matus Fabian675a69c2017-01-18 01:46:01 -08001724 pkts = self.create_stream_out(self.pg3, static_nat_ip)
Matus Fabiande886752016-12-07 03:38:19 -08001725 self.pg3.add_stream(pkts)
1726 self.pg_enable_capture(self.pg_interfaces)
1727 self.pg_start()
Klement Sekeradab231a2016-12-21 08:50:14 +01001728 capture = self.pg6.get_capture(len(pkts))
Matus Fabiande886752016-12-07 03:38:19 -08001729 self.verify_capture_in(capture, self.pg6)
1730
magalik23caa882017-02-08 23:25:45 -08001731 # general user and session dump verifications
Matus Fabian2ba92e32017-08-21 07:05:03 -07001732 users = self.vapi.nat44_user_dump()
magalik23caa882017-02-08 23:25:45 -08001733 self.assertTrue(len(users) >= 3)
Matus Fabian2ba92e32017-08-21 07:05:03 -07001734 addresses = self.vapi.nat44_address_dump()
magalik23caa882017-02-08 23:25:45 -08001735 self.assertEqual(len(addresses), 1)
1736 for user in users:
Matus Fabian2ba92e32017-08-21 07:05:03 -07001737 sessions = self.vapi.nat44_user_session_dump(user.ip_address,
1738 user.vrf_id)
magalik23caa882017-02-08 23:25:45 -08001739 for session in sessions:
1740 self.assertEqual(user.ip_address, session.inside_ip_address)
1741 self.assertTrue(session.total_bytes > session.total_pkts > 0)
1742 self.assertTrue(session.protocol in
1743 [IP_PROTOS.tcp, IP_PROTOS.udp,
1744 IP_PROTOS.icmp])
Matus Fabian70a26ac2018-05-14 06:20:28 -07001745 self.assertFalse(session.ext_host_valid)
magalik23caa882017-02-08 23:25:45 -08001746
1747 # pg4 session dump
Matus Fabian2ba92e32017-08-21 07:05:03 -07001748 sessions = self.vapi.nat44_user_session_dump(self.pg4.remote_ip4n, 10)
magalik23caa882017-02-08 23:25:45 -08001749 self.assertTrue(len(sessions) >= 4)
1750 for session in sessions:
1751 self.assertFalse(session.is_static)
1752 self.assertEqual(session.inside_ip_address[0:4],
1753 self.pg4.remote_ip4n)
1754 self.assertEqual(session.outside_ip_address,
1755 addresses[0].ip_address)
1756
1757 # pg6 session dump
Matus Fabian2ba92e32017-08-21 07:05:03 -07001758 sessions = self.vapi.nat44_user_session_dump(self.pg6.remote_ip4n, 20)
magalik23caa882017-02-08 23:25:45 -08001759 self.assertTrue(len(sessions) >= 3)
1760 for session in sessions:
1761 self.assertTrue(session.is_static)
1762 self.assertEqual(session.inside_ip_address[0:4],
1763 self.pg6.remote_ip4n)
1764 self.assertEqual(map(ord, session.outside_ip_address[0:4]),
1765 map(int, static_nat_ip.split('.')))
1766 self.assertTrue(session.inside_port in
1767 [self.tcp_port_in, self.udp_port_in,
1768 self.icmp_id_in])
1769
Matus Fabianf78a70d2016-12-12 04:30:39 -08001770 def test_hairpinning(self):
Matus Fabian2ba92e32017-08-21 07:05:03 -07001771 """ NAT44 hairpinning - 1:1 NAPT """
Matus Fabianf78a70d2016-12-12 04:30:39 -08001772
1773 host = self.pg0.remote_hosts[0]
1774 server = self.pg0.remote_hosts[1]
1775 host_in_port = 1234
1776 host_out_port = 0
1777 server_in_port = 5678
1778 server_out_port = 8765
1779
Matus Fabian2ba92e32017-08-21 07:05:03 -07001780 self.nat44_add_address(self.nat_addr)
1781 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
1782 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
1783 is_inside=0)
Matus Fabianf78a70d2016-12-12 04:30:39 -08001784 # add static mapping for server
Matus Fabian2ba92e32017-08-21 07:05:03 -07001785 self.nat44_add_static_mapping(server.ip4, self.nat_addr,
1786 server_in_port, server_out_port,
1787 proto=IP_PROTOS.tcp)
Matus Fabianf78a70d2016-12-12 04:30:39 -08001788
1789 # send packet from host to server
1790 p = (Ether(src=host.mac, dst=self.pg0.local_mac) /
Matus Fabian2ba92e32017-08-21 07:05:03 -07001791 IP(src=host.ip4, dst=self.nat_addr) /
Matus Fabianf78a70d2016-12-12 04:30:39 -08001792 TCP(sport=host_in_port, dport=server_out_port))
1793 self.pg0.add_stream(p)
1794 self.pg_enable_capture(self.pg_interfaces)
1795 self.pg_start()
Klement Sekeradab231a2016-12-21 08:50:14 +01001796 capture = self.pg0.get_capture(1)
Matus Fabianf78a70d2016-12-12 04:30:39 -08001797 p = capture[0]
1798 try:
1799 ip = p[IP]
1800 tcp = p[TCP]
Matus Fabian2ba92e32017-08-21 07:05:03 -07001801 self.assertEqual(ip.src, self.nat_addr)
Matus Fabianf78a70d2016-12-12 04:30:39 -08001802 self.assertEqual(ip.dst, server.ip4)
1803 self.assertNotEqual(tcp.sport, host_in_port)
1804 self.assertEqual(tcp.dport, server_in_port)
Klement Sekerad81ae412018-05-16 10:52:54 +02001805 self.assert_packet_checksums_valid(p)
Matus Fabianf78a70d2016-12-12 04:30:39 -08001806 host_out_port = tcp.sport
1807 except:
Klement Sekera9225dee2016-12-12 08:36:58 +01001808 self.logger.error(ppp("Unexpected or invalid packet:", p))
Matus Fabianf78a70d2016-12-12 04:30:39 -08001809 raise
1810
1811 # send reply from server to host
1812 p = (Ether(src=server.mac, dst=self.pg0.local_mac) /
Matus Fabian2ba92e32017-08-21 07:05:03 -07001813 IP(src=server.ip4, dst=self.nat_addr) /
Matus Fabianf78a70d2016-12-12 04:30:39 -08001814 TCP(sport=server_in_port, dport=host_out_port))
1815 self.pg0.add_stream(p)
1816 self.pg_enable_capture(self.pg_interfaces)
1817 self.pg_start()
Klement Sekeradab231a2016-12-21 08:50:14 +01001818 capture = self.pg0.get_capture(1)
Matus Fabianf78a70d2016-12-12 04:30:39 -08001819 p = capture[0]
1820 try:
1821 ip = p[IP]
1822 tcp = p[TCP]
Matus Fabian2ba92e32017-08-21 07:05:03 -07001823 self.assertEqual(ip.src, self.nat_addr)
Matus Fabianf78a70d2016-12-12 04:30:39 -08001824 self.assertEqual(ip.dst, host.ip4)
1825 self.assertEqual(tcp.sport, server_out_port)
1826 self.assertEqual(tcp.dport, host_in_port)
Klement Sekerad81ae412018-05-16 10:52:54 +02001827 self.assert_packet_checksums_valid(p)
Matus Fabianf78a70d2016-12-12 04:30:39 -08001828 except:
Matus Fabiane82488f2018-01-18 03:38:45 -08001829 self.logger.error(ppp("Unexpected or invalid packet:", p))
Matus Fabianf78a70d2016-12-12 04:30:39 -08001830 raise
1831
Matus Fabian6fa74c62017-06-05 05:55:48 -07001832 def test_hairpinning2(self):
Matus Fabian2ba92e32017-08-21 07:05:03 -07001833 """ NAT44 hairpinning - 1:1 NAT"""
Matus Fabian6fa74c62017-06-05 05:55:48 -07001834
1835 server1_nat_ip = "10.0.0.10"
1836 server2_nat_ip = "10.0.0.11"
1837 host = self.pg0.remote_hosts[0]
1838 server1 = self.pg0.remote_hosts[1]
1839 server2 = self.pg0.remote_hosts[2]
1840 server_tcp_port = 22
1841 server_udp_port = 20
1842
Matus Fabian2ba92e32017-08-21 07:05:03 -07001843 self.nat44_add_address(self.nat_addr)
1844 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
1845 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
1846 is_inside=0)
Matus Fabian6fa74c62017-06-05 05:55:48 -07001847
1848 # add static mapping for servers
Matus Fabian2ba92e32017-08-21 07:05:03 -07001849 self.nat44_add_static_mapping(server1.ip4, server1_nat_ip)
1850 self.nat44_add_static_mapping(server2.ip4, server2_nat_ip)
Matus Fabian6fa74c62017-06-05 05:55:48 -07001851
1852 # host to server1
1853 pkts = []
1854 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
1855 IP(src=host.ip4, dst=server1_nat_ip) /
1856 TCP(sport=self.tcp_port_in, dport=server_tcp_port))
1857 pkts.append(p)
1858 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
1859 IP(src=host.ip4, dst=server1_nat_ip) /
1860 UDP(sport=self.udp_port_in, dport=server_udp_port))
1861 pkts.append(p)
1862 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
1863 IP(src=host.ip4, dst=server1_nat_ip) /
1864 ICMP(id=self.icmp_id_in, type='echo-request'))
1865 pkts.append(p)
1866 self.pg0.add_stream(pkts)
1867 self.pg_enable_capture(self.pg_interfaces)
1868 self.pg_start()
1869 capture = self.pg0.get_capture(len(pkts))
1870 for packet in capture:
1871 try:
Matus Fabian2ba92e32017-08-21 07:05:03 -07001872 self.assertEqual(packet[IP].src, self.nat_addr)
Matus Fabian6fa74c62017-06-05 05:55:48 -07001873 self.assertEqual(packet[IP].dst, server1.ip4)
1874 if packet.haslayer(TCP):
1875 self.assertNotEqual(packet[TCP].sport, self.tcp_port_in)
1876 self.assertEqual(packet[TCP].dport, server_tcp_port)
1877 self.tcp_port_out = packet[TCP].sport
Klement Sekerad81ae412018-05-16 10:52:54 +02001878 self.assert_packet_checksums_valid(packet)
Matus Fabian6fa74c62017-06-05 05:55:48 -07001879 elif packet.haslayer(UDP):
1880 self.assertNotEqual(packet[UDP].sport, self.udp_port_in)
1881 self.assertEqual(packet[UDP].dport, server_udp_port)
1882 self.udp_port_out = packet[UDP].sport
1883 else:
1884 self.assertNotEqual(packet[ICMP].id, self.icmp_id_in)
1885 self.icmp_id_out = packet[ICMP].id
1886 except:
1887 self.logger.error(ppp("Unexpected or invalid packet:", packet))
1888 raise
1889
1890 # server1 to host
1891 pkts = []
1892 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
Matus Fabian2ba92e32017-08-21 07:05:03 -07001893 IP(src=server1.ip4, dst=self.nat_addr) /
Matus Fabian6fa74c62017-06-05 05:55:48 -07001894 TCP(sport=server_tcp_port, dport=self.tcp_port_out))
1895 pkts.append(p)
1896 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
Matus Fabian2ba92e32017-08-21 07:05:03 -07001897 IP(src=server1.ip4, dst=self.nat_addr) /
Matus Fabian6fa74c62017-06-05 05:55:48 -07001898 UDP(sport=server_udp_port, dport=self.udp_port_out))
1899 pkts.append(p)
1900 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
Matus Fabian2ba92e32017-08-21 07:05:03 -07001901 IP(src=server1.ip4, dst=self.nat_addr) /
Matus Fabian6fa74c62017-06-05 05:55:48 -07001902 ICMP(id=self.icmp_id_out, type='echo-reply'))
1903 pkts.append(p)
1904 self.pg0.add_stream(pkts)
1905 self.pg_enable_capture(self.pg_interfaces)
1906 self.pg_start()
1907 capture = self.pg0.get_capture(len(pkts))
1908 for packet in capture:
1909 try:
1910 self.assertEqual(packet[IP].src, server1_nat_ip)
1911 self.assertEqual(packet[IP].dst, host.ip4)
1912 if packet.haslayer(TCP):
1913 self.assertEqual(packet[TCP].dport, self.tcp_port_in)
1914 self.assertEqual(packet[TCP].sport, server_tcp_port)
Klement Sekerad81ae412018-05-16 10:52:54 +02001915 self.assert_packet_checksums_valid(packet)
Matus Fabian6fa74c62017-06-05 05:55:48 -07001916 elif packet.haslayer(UDP):
1917 self.assertEqual(packet[UDP].dport, self.udp_port_in)
1918 self.assertEqual(packet[UDP].sport, server_udp_port)
1919 else:
1920 self.assertEqual(packet[ICMP].id, self.icmp_id_in)
1921 except:
1922 self.logger.error(ppp("Unexpected or invalid packet:", packet))
1923 raise
1924
1925 # server2 to server1
1926 pkts = []
1927 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
1928 IP(src=server2.ip4, dst=server1_nat_ip) /
1929 TCP(sport=self.tcp_port_in, dport=server_tcp_port))
1930 pkts.append(p)
1931 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
1932 IP(src=server2.ip4, dst=server1_nat_ip) /
1933 UDP(sport=self.udp_port_in, dport=server_udp_port))
1934 pkts.append(p)
1935 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
1936 IP(src=server2.ip4, dst=server1_nat_ip) /
1937 ICMP(id=self.icmp_id_in, type='echo-request'))
1938 pkts.append(p)
1939 self.pg0.add_stream(pkts)
1940 self.pg_enable_capture(self.pg_interfaces)
1941 self.pg_start()
1942 capture = self.pg0.get_capture(len(pkts))
1943 for packet in capture:
1944 try:
1945 self.assertEqual(packet[IP].src, server2_nat_ip)
1946 self.assertEqual(packet[IP].dst, server1.ip4)
1947 if packet.haslayer(TCP):
1948 self.assertEqual(packet[TCP].sport, self.tcp_port_in)
1949 self.assertEqual(packet[TCP].dport, server_tcp_port)
1950 self.tcp_port_out = packet[TCP].sport
Klement Sekerad81ae412018-05-16 10:52:54 +02001951 self.assert_packet_checksums_valid(packet)
Matus Fabian6fa74c62017-06-05 05:55:48 -07001952 elif packet.haslayer(UDP):
1953 self.assertEqual(packet[UDP].sport, self.udp_port_in)
1954 self.assertEqual(packet[UDP].dport, server_udp_port)
1955 self.udp_port_out = packet[UDP].sport
1956 else:
1957 self.assertEqual(packet[ICMP].id, self.icmp_id_in)
1958 self.icmp_id_out = packet[ICMP].id
1959 except:
1960 self.logger.error(ppp("Unexpected or invalid packet:", packet))
1961 raise
1962
1963 # server1 to server2
1964 pkts = []
1965 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
1966 IP(src=server1.ip4, dst=server2_nat_ip) /
1967 TCP(sport=server_tcp_port, dport=self.tcp_port_out))
1968 pkts.append(p)
1969 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
1970 IP(src=server1.ip4, dst=server2_nat_ip) /
1971 UDP(sport=server_udp_port, dport=self.udp_port_out))
1972 pkts.append(p)
1973 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
1974 IP(src=server1.ip4, dst=server2_nat_ip) /
1975 ICMP(id=self.icmp_id_out, type='echo-reply'))
1976 pkts.append(p)
1977 self.pg0.add_stream(pkts)
1978 self.pg_enable_capture(self.pg_interfaces)
1979 self.pg_start()
1980 capture = self.pg0.get_capture(len(pkts))
1981 for packet in capture:
1982 try:
1983 self.assertEqual(packet[IP].src, server1_nat_ip)
1984 self.assertEqual(packet[IP].dst, server2.ip4)
1985 if packet.haslayer(TCP):
1986 self.assertEqual(packet[TCP].dport, self.tcp_port_in)
1987 self.assertEqual(packet[TCP].sport, server_tcp_port)
Klement Sekerad81ae412018-05-16 10:52:54 +02001988 self.assert_packet_checksums_valid(packet)
Matus Fabian6fa74c62017-06-05 05:55:48 -07001989 elif packet.haslayer(UDP):
1990 self.assertEqual(packet[UDP].dport, self.udp_port_in)
1991 self.assertEqual(packet[UDP].sport, server_udp_port)
1992 else:
1993 self.assertEqual(packet[ICMP].id, self.icmp_id_in)
1994 except:
1995 self.logger.error(ppp("Unexpected or invalid packet:", packet))
1996 raise
1997
Matus Fabian9902fcd2016-12-21 23:58:46 -08001998 def test_max_translations_per_user(self):
1999 """ MAX translations per user - recycle the least recently used """
2000
Matus Fabian2ba92e32017-08-21 07:05:03 -07002001 self.nat44_add_address(self.nat_addr)
2002 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
2003 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
2004 is_inside=0)
Matus Fabian9902fcd2016-12-21 23:58:46 -08002005
2006 # get maximum number of translations per user
Matus Fabian2ba92e32017-08-21 07:05:03 -07002007 nat44_config = self.vapi.nat_show_config()
Matus Fabian9902fcd2016-12-21 23:58:46 -08002008
2009 # send more than maximum number of translations per user packets
Matus Fabian2ba92e32017-08-21 07:05:03 -07002010 pkts_num = nat44_config.max_translations_per_user + 5
Matus Fabian9902fcd2016-12-21 23:58:46 -08002011 pkts = []
2012 for port in range(0, pkts_num):
2013 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2014 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
2015 TCP(sport=1025 + port))
2016 pkts.append(p)
2017 self.pg0.add_stream(pkts)
2018 self.pg_enable_capture(self.pg_interfaces)
2019 self.pg_start()
2020
2021 # verify number of translated packet
Klement Sekeradab231a2016-12-21 08:50:14 +01002022 self.pg1.get_capture(pkts_num)
Matus Fabian9902fcd2016-12-21 23:58:46 -08002023
Matus Fabian132dc492018-05-09 04:51:03 -07002024 users = self.vapi.nat44_user_dump()
2025 for user in users:
2026 if user.ip_address == self.pg0.remote_ip4n:
2027 self.assertEqual(user.nsessions,
2028 nat44_config.max_translations_per_user)
2029 self.assertEqual(user.nstaticsessions, 0)
2030
2031 tcp_port = 22
2032 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
2033 tcp_port, tcp_port,
2034 proto=IP_PROTOS.tcp)
2035 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2036 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
2037 TCP(sport=tcp_port))
2038 self.pg0.add_stream(p)
2039 self.pg_enable_capture(self.pg_interfaces)
2040 self.pg_start()
2041 self.pg1.get_capture(1)
2042 users = self.vapi.nat44_user_dump()
2043 for user in users:
2044 if user.ip_address == self.pg0.remote_ip4n:
2045 self.assertEqual(user.nsessions,
2046 nat44_config.max_translations_per_user - 1)
2047 self.assertEqual(user.nstaticsessions, 1)
2048
Matus Fabian8bf68e82017-01-12 04:24:35 -08002049 def test_interface_addr(self):
Matus Fabian2ba92e32017-08-21 07:05:03 -07002050 """ Acquire NAT44 addresses from interface """
2051 self.vapi.nat44_add_interface_addr(self.pg7.sw_if_index)
Matus Fabian8bf68e82017-01-12 04:24:35 -08002052
2053 # no address in NAT pool
Matus Fabian2ba92e32017-08-21 07:05:03 -07002054 adresses = self.vapi.nat44_address_dump()
Matus Fabian8bf68e82017-01-12 04:24:35 -08002055 self.assertEqual(0, len(adresses))
2056
2057 # configure interface address and check NAT address pool
2058 self.pg7.config_ip4()
Matus Fabian2ba92e32017-08-21 07:05:03 -07002059 adresses = self.vapi.nat44_address_dump()
Matus Fabian8bf68e82017-01-12 04:24:35 -08002060 self.assertEqual(1, len(adresses))
Matus Fabian36532bd2017-01-23 23:42:28 -08002061 self.assertEqual(adresses[0].ip_address[0:4], self.pg7.local_ip4n)
Matus Fabian8bf68e82017-01-12 04:24:35 -08002062
2063 # remove interface address and check NAT address pool
2064 self.pg7.unconfig_ip4()
Matus Fabian2ba92e32017-08-21 07:05:03 -07002065 adresses = self.vapi.nat44_address_dump()
Matus Fabian8bf68e82017-01-12 04:24:35 -08002066 self.assertEqual(0, len(adresses))
2067
Matus Fabian36532bd2017-01-23 23:42:28 -08002068 def test_interface_addr_static_mapping(self):
2069 """ Static mapping with addresses from interface """
Matus Fabian5f224992018-01-25 21:59:16 -08002070 tag = "testTAG"
2071
Matus Fabian2ba92e32017-08-21 07:05:03 -07002072 self.vapi.nat44_add_interface_addr(self.pg7.sw_if_index)
2073 self.nat44_add_static_mapping(
2074 '1.2.3.4',
Matus Fabian5f224992018-01-25 21:59:16 -08002075 external_sw_if_index=self.pg7.sw_if_index,
2076 tag=tag)
Matus Fabian36532bd2017-01-23 23:42:28 -08002077
Matus Fabiane22e5462017-02-14 23:33:43 -08002078 # static mappings with external interface
Matus Fabian2ba92e32017-08-21 07:05:03 -07002079 static_mappings = self.vapi.nat44_static_mapping_dump()
Matus Fabiane22e5462017-02-14 23:33:43 -08002080 self.assertEqual(1, len(static_mappings))
2081 self.assertEqual(self.pg7.sw_if_index,
2082 static_mappings[0].external_sw_if_index)
Matus Fabian5f224992018-01-25 21:59:16 -08002083 self.assertEqual((static_mappings[0].tag).split('\0', 1)[0], tag)
Matus Fabian36532bd2017-01-23 23:42:28 -08002084
2085 # configure interface address and check static mappings
2086 self.pg7.config_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(2, len(static_mappings))
2089 resolved = False
2090 for sm in static_mappings:
2091 if sm.external_sw_if_index == 0xFFFFFFFF:
2092 self.assertEqual(sm.external_ip_address[0:4],
2093 self.pg7.local_ip4n)
2094 self.assertEqual((sm.tag).split('\0', 1)[0], tag)
2095 resolved = True
2096 self.assertTrue(resolved)
Matus Fabian36532bd2017-01-23 23:42:28 -08002097
2098 # remove interface address and check static mappings
2099 self.pg7.unconfig_ip4()
Matus Fabian2ba92e32017-08-21 07:05:03 -07002100 static_mappings = self.vapi.nat44_static_mapping_dump()
Matus Fabianea2600a2018-03-28 04:06:26 -07002101 self.assertEqual(1, len(static_mappings))
2102 self.assertEqual(self.pg7.sw_if_index,
2103 static_mappings[0].external_sw_if_index)
2104 self.assertEqual((static_mappings[0].tag).split('\0', 1)[0], tag)
2105
2106 # configure interface address again and check static mappings
2107 self.pg7.config_ip4()
2108 static_mappings = self.vapi.nat44_static_mapping_dump()
2109 self.assertEqual(2, len(static_mappings))
2110 resolved = False
2111 for sm in static_mappings:
2112 if sm.external_sw_if_index == 0xFFFFFFFF:
2113 self.assertEqual(sm.external_ip_address[0:4],
2114 self.pg7.local_ip4n)
2115 self.assertEqual((sm.tag).split('\0', 1)[0], tag)
2116 resolved = True
2117 self.assertTrue(resolved)
2118
2119 # remove static mapping
2120 self.nat44_add_static_mapping(
2121 '1.2.3.4',
2122 external_sw_if_index=self.pg7.sw_if_index,
2123 tag=tag,
2124 is_add=0)
2125 static_mappings = self.vapi.nat44_static_mapping_dump()
Matus Fabian36532bd2017-01-23 23:42:28 -08002126 self.assertEqual(0, len(static_mappings))
2127
Matus Fabianab7a8052017-11-28 04:29:41 -08002128 def test_interface_addr_identity_nat(self):
2129 """ Identity NAT with addresses from interface """
2130
2131 port = 53053
2132 self.vapi.nat44_add_interface_addr(self.pg7.sw_if_index)
2133 self.vapi.nat44_add_del_identity_mapping(
2134 sw_if_index=self.pg7.sw_if_index,
2135 port=port,
2136 protocol=IP_PROTOS.tcp,
2137 addr_only=0)
2138
2139 # identity mappings with external interface
2140 identity_mappings = self.vapi.nat44_identity_mapping_dump()
2141 self.assertEqual(1, len(identity_mappings))
2142 self.assertEqual(self.pg7.sw_if_index,
2143 identity_mappings[0].sw_if_index)
2144
2145 # configure interface address and check identity mappings
2146 self.pg7.config_ip4()
2147 identity_mappings = self.vapi.nat44_identity_mapping_dump()
Matus Fabianea2600a2018-03-28 04:06:26 -07002148 resolved = False
2149 self.assertEqual(2, len(identity_mappings))
2150 for sm in identity_mappings:
2151 if sm.sw_if_index == 0xFFFFFFFF:
2152 self.assertEqual(identity_mappings[0].ip_address,
2153 self.pg7.local_ip4n)
2154 self.assertEqual(port, identity_mappings[0].port)
2155 self.assertEqual(IP_PROTOS.tcp, identity_mappings[0].protocol)
2156 resolved = True
2157 self.assertTrue(resolved)
Matus Fabianab7a8052017-11-28 04:29:41 -08002158
2159 # remove interface address and check identity mappings
2160 self.pg7.unconfig_ip4()
2161 identity_mappings = self.vapi.nat44_identity_mapping_dump()
Matus Fabianea2600a2018-03-28 04:06:26 -07002162 self.assertEqual(1, len(identity_mappings))
2163 self.assertEqual(self.pg7.sw_if_index,
2164 identity_mappings[0].sw_if_index)
Matus Fabianab7a8052017-11-28 04:29:41 -08002165
Matus Fabianeea28d72017-01-13 04:15:54 -08002166 def test_ipfix_nat44_sess(self):
Matus Fabian2ba92e32017-08-21 07:05:03 -07002167 """ IPFIX logging NAT44 session created/delted """
Matus Fabian6631e9c2017-05-24 01:52:20 -07002168 self.ipfix_domain_id = 10
2169 self.ipfix_src_port = 20202
2170 colector_port = 30303
2171 bind_layers(UDP, IPFIX, dport=30303)
Matus Fabian2ba92e32017-08-21 07:05:03 -07002172 self.nat44_add_address(self.nat_addr)
2173 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
2174 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
2175 is_inside=0)
Matus Fabianeea28d72017-01-13 04:15:54 -08002176 self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4n,
2177 src_address=self.pg3.local_ip4n,
2178 path_mtu=512,
Matus Fabian6631e9c2017-05-24 01:52:20 -07002179 template_interval=10,
2180 collector_port=colector_port)
Matus Fabian2ba92e32017-08-21 07:05:03 -07002181 self.vapi.nat_ipfix(domain_id=self.ipfix_domain_id,
2182 src_port=self.ipfix_src_port)
Matus Fabianeea28d72017-01-13 04:15:54 -08002183
2184 pkts = self.create_stream_in(self.pg0, self.pg1)
2185 self.pg0.add_stream(pkts)
2186 self.pg_enable_capture(self.pg_interfaces)
2187 self.pg_start()
2188 capture = self.pg1.get_capture(len(pkts))
2189 self.verify_capture_out(capture)
Matus Fabian2ba92e32017-08-21 07:05:03 -07002190 self.nat44_add_address(self.nat_addr, is_add=0)
Matus Fabianeea28d72017-01-13 04:15:54 -08002191 self.vapi.cli("ipfix flush") # FIXME this should be an API call
Matus Fabiana431ad12018-01-04 04:03:14 -08002192 capture = self.pg3.get_capture(9)
Matus Fabianeea28d72017-01-13 04:15:54 -08002193 ipfix = IPFIXDecoder()
2194 # first load template
2195 for p in capture:
2196 self.assertTrue(p.haslayer(IPFIX))
Matus Fabian6631e9c2017-05-24 01:52:20 -07002197 self.assertEqual(p[IP].src, self.pg3.local_ip4)
2198 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
2199 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
2200 self.assertEqual(p[UDP].dport, colector_port)
2201 self.assertEqual(p[IPFIX].observationDomainID,
2202 self.ipfix_domain_id)
Matus Fabianeea28d72017-01-13 04:15:54 -08002203 if p.haslayer(Template):
2204 ipfix.add_template(p.getlayer(Template))
2205 # verify events in data set
2206 for p in capture:
2207 if p.haslayer(Data):
2208 data = ipfix.decode_data_set(p.getlayer(Set))
2209 self.verify_ipfix_nat44_ses(data)
2210
2211 def test_ipfix_addr_exhausted(self):
Matus Fabian2ba92e32017-08-21 07:05:03 -07002212 """ IPFIX logging NAT addresses exhausted """
2213 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
2214 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
2215 is_inside=0)
Matus Fabianeea28d72017-01-13 04:15:54 -08002216 self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4n,
2217 src_address=self.pg3.local_ip4n,
2218 path_mtu=512,
2219 template_interval=10)
Matus Fabian2ba92e32017-08-21 07:05:03 -07002220 self.vapi.nat_ipfix(domain_id=self.ipfix_domain_id,
2221 src_port=self.ipfix_src_port)
Matus Fabianeea28d72017-01-13 04:15:54 -08002222
2223 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
2224 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
2225 TCP(sport=3025))
2226 self.pg0.add_stream(p)
2227 self.pg_enable_capture(self.pg_interfaces)
2228 self.pg_start()
Matus Fabian229c1aa2018-05-28 04:09:52 -07002229 self.pg1.assert_nothing_captured()
2230 sleep(1)
Matus Fabianeea28d72017-01-13 04:15:54 -08002231 self.vapi.cli("ipfix flush") # FIXME this should be an API call
Matus Fabiana431ad12018-01-04 04:03:14 -08002232 capture = self.pg3.get_capture(9)
Matus Fabianeea28d72017-01-13 04:15:54 -08002233 ipfix = IPFIXDecoder()
2234 # first load template
2235 for p in capture:
2236 self.assertTrue(p.haslayer(IPFIX))
Matus Fabian6631e9c2017-05-24 01:52:20 -07002237 self.assertEqual(p[IP].src, self.pg3.local_ip4)
2238 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
2239 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
2240 self.assertEqual(p[UDP].dport, 4739)
2241 self.assertEqual(p[IPFIX].observationDomainID,
2242 self.ipfix_domain_id)
Matus Fabianeea28d72017-01-13 04:15:54 -08002243 if p.haslayer(Template):
2244 ipfix.add_template(p.getlayer(Template))
2245 # verify events in data set
2246 for p in capture:
2247 if p.haslayer(Data):
2248 data = ipfix.decode_data_set(p.getlayer(Set))
2249 self.verify_ipfix_addr_exhausted(data)
2250
Matus Fabiana431ad12018-01-04 04:03:14 -08002251 @unittest.skipUnless(running_extended_tests(), "part of extended tests")
2252 def test_ipfix_max_sessions(self):
2253 """ IPFIX logging maximum session entries exceeded """
2254 self.nat44_add_address(self.nat_addr)
2255 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
2256 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
2257 is_inside=0)
2258
2259 nat44_config = self.vapi.nat_show_config()
2260 max_sessions = 10 * nat44_config.translation_buckets
2261
2262 pkts = []
2263 for i in range(0, max_sessions):
2264 src = "10.10.%u.%u" % ((i & 0xFF00) >> 8, i & 0xFF)
2265 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2266 IP(src=src, dst=self.pg1.remote_ip4) /
2267 TCP(sport=1025))
2268 pkts.append(p)
2269 self.pg0.add_stream(pkts)
2270 self.pg_enable_capture(self.pg_interfaces)
2271 self.pg_start()
2272
2273 self.pg1.get_capture(max_sessions)
2274 self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4n,
2275 src_address=self.pg3.local_ip4n,
2276 path_mtu=512,
2277 template_interval=10)
2278 self.vapi.nat_ipfix(domain_id=self.ipfix_domain_id,
2279 src_port=self.ipfix_src_port)
2280
2281 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2282 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
2283 TCP(sport=1025))
2284 self.pg0.add_stream(p)
2285 self.pg_enable_capture(self.pg_interfaces)
2286 self.pg_start()
Matus Fabian229c1aa2018-05-28 04:09:52 -07002287 self.pg1.assert_nothing_captured()
2288 sleep(1)
Matus Fabiana431ad12018-01-04 04:03:14 -08002289 self.vapi.cli("ipfix flush") # FIXME this should be an API call
2290 capture = self.pg3.get_capture(9)
2291 ipfix = IPFIXDecoder()
2292 # first load template
2293 for p in capture:
2294 self.assertTrue(p.haslayer(IPFIX))
2295 self.assertEqual(p[IP].src, self.pg3.local_ip4)
2296 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
2297 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
2298 self.assertEqual(p[UDP].dport, 4739)
2299 self.assertEqual(p[IPFIX].observationDomainID,
2300 self.ipfix_domain_id)
2301 if p.haslayer(Template):
2302 ipfix.add_template(p.getlayer(Template))
2303 # verify events in data set
2304 for p in capture:
2305 if p.haslayer(Data):
2306 data = ipfix.decode_data_set(p.getlayer(Set))
2307 self.verify_ipfix_max_sessions(data, max_sessions)
2308
Matus Fabiane1ae29a2017-01-27 00:47:58 -08002309 def test_pool_addr_fib(self):
Matus Fabian2ba92e32017-08-21 07:05:03 -07002310 """ NAT44 add pool addresses to FIB """
Matus Fabiane1ae29a2017-01-27 00:47:58 -08002311 static_addr = '10.0.0.10'
Matus Fabian2ba92e32017-08-21 07:05:03 -07002312 self.nat44_add_address(self.nat_addr)
2313 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
2314 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
2315 is_inside=0)
2316 self.nat44_add_static_mapping(self.pg0.remote_ip4, static_addr)
Matus Fabiane1ae29a2017-01-27 00:47:58 -08002317
Matus Fabian2ba92e32017-08-21 07:05:03 -07002318 # NAT44 address
Matus Fabiane1ae29a2017-01-27 00:47:58 -08002319 p = (Ether(src=self.pg1.remote_mac, dst='ff:ff:ff:ff:ff:ff') /
Matus Fabian2ba92e32017-08-21 07:05:03 -07002320 ARP(op=ARP.who_has, pdst=self.nat_addr,
Matus Fabiane1ae29a2017-01-27 00:47:58 -08002321 psrc=self.pg1.remote_ip4, hwsrc=self.pg1.remote_mac))
2322 self.pg1.add_stream(p)
2323 self.pg_enable_capture(self.pg_interfaces)
2324 self.pg_start()
2325 capture = self.pg1.get_capture(1)
2326 self.assertTrue(capture[0].haslayer(ARP))
2327 self.assertTrue(capture[0][ARP].op, ARP.is_at)
2328
2329 # 1:1 NAT address
2330 p = (Ether(src=self.pg1.remote_mac, dst='ff:ff:ff:ff:ff:ff') /
2331 ARP(op=ARP.who_has, pdst=static_addr,
2332 psrc=self.pg1.remote_ip4, hwsrc=self.pg1.remote_mac))
2333 self.pg1.add_stream(p)
2334 self.pg_enable_capture(self.pg_interfaces)
2335 self.pg_start()
2336 capture = self.pg1.get_capture(1)
2337 self.assertTrue(capture[0].haslayer(ARP))
2338 self.assertTrue(capture[0][ARP].op, ARP.is_at)
2339
Matus Fabian2ba92e32017-08-21 07:05:03 -07002340 # send ARP to non-NAT44 interface
Matus Fabiane1ae29a2017-01-27 00:47:58 -08002341 p = (Ether(src=self.pg2.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.pg2.remote_ip4, hwsrc=self.pg2.remote_mac))
2344 self.pg2.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 # remove addresses and verify
Matus Fabian2ba92e32017-08-21 07:05:03 -07002350 self.nat44_add_address(self.nat_addr, is_add=0)
2351 self.nat44_add_static_mapping(self.pg0.remote_ip4, static_addr,
2352 is_add=0)
Matus Fabiane1ae29a2017-01-27 00:47:58 -08002353
2354 p = (Ether(src=self.pg1.remote_mac, dst='ff:ff:ff:ff:ff:ff') /
Matus Fabian2ba92e32017-08-21 07:05:03 -07002355 ARP(op=ARP.who_has, pdst=self.nat_addr,
Matus Fabiane1ae29a2017-01-27 00:47:58 -08002356 psrc=self.pg1.remote_ip4, hwsrc=self.pg1.remote_mac))
2357 self.pg1.add_stream(p)
2358 self.pg_enable_capture(self.pg_interfaces)
2359 self.pg_start()
Matus Fabian229c1aa2018-05-28 04:09:52 -07002360 self.pg1.assert_nothing_captured()
Matus Fabiane1ae29a2017-01-27 00:47:58 -08002361
2362 p = (Ether(src=self.pg1.remote_mac, dst='ff:ff:ff:ff:ff:ff') /
2363 ARP(op=ARP.who_has, pdst=static_addr,
2364 psrc=self.pg1.remote_ip4, hwsrc=self.pg1.remote_mac))
2365 self.pg1.add_stream(p)
2366 self.pg_enable_capture(self.pg_interfaces)
2367 self.pg_start()
Matus Fabian229c1aa2018-05-28 04:09:52 -07002368 self.pg1.assert_nothing_captured()
Matus Fabiane1ae29a2017-01-27 00:47:58 -08002369
Juraj Slobodaeab38d92017-03-06 19:55:21 -08002370 def test_vrf_mode(self):
Matus Fabian2ba92e32017-08-21 07:05:03 -07002371 """ NAT44 tenant VRF aware address pool mode """
Juraj Slobodaeab38d92017-03-06 19:55:21 -08002372
2373 vrf_id1 = 1
2374 vrf_id2 = 2
2375 nat_ip1 = "10.0.0.10"
2376 nat_ip2 = "10.0.0.11"
2377
2378 self.pg0.unconfig_ip4()
2379 self.pg1.unconfig_ip4()
Neale Ranns15002542017-09-10 04:39:11 -07002380 self.vapi.ip_table_add_del(vrf_id1, is_add=1)
2381 self.vapi.ip_table_add_del(vrf_id2, is_add=1)
Juraj Slobodaeab38d92017-03-06 19:55:21 -08002382 self.pg0.set_table_ip4(vrf_id1)
2383 self.pg1.set_table_ip4(vrf_id2)
2384 self.pg0.config_ip4()
2385 self.pg1.config_ip4()
Matus Fabian8008d7c2018-07-09 01:34:20 -07002386 self.pg0.resolve_arp()
2387 self.pg1.resolve_arp()
Juraj Slobodaeab38d92017-03-06 19:55:21 -08002388
Matus Fabian2ba92e32017-08-21 07:05:03 -07002389 self.nat44_add_address(nat_ip1, vrf_id=vrf_id1)
2390 self.nat44_add_address(nat_ip2, vrf_id=vrf_id2)
2391 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
2392 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index)
2393 self.vapi.nat44_interface_add_del_feature(self.pg2.sw_if_index,
2394 is_inside=0)
Juraj Slobodaeab38d92017-03-06 19:55:21 -08002395
Matus Fabian8008d7c2018-07-09 01:34:20 -07002396 try:
2397 # first VRF
2398 pkts = self.create_stream_in(self.pg0, self.pg2)
2399 self.pg0.add_stream(pkts)
2400 self.pg_enable_capture(self.pg_interfaces)
2401 self.pg_start()
2402 capture = self.pg2.get_capture(len(pkts))
2403 self.verify_capture_out(capture, nat_ip1)
Juraj Slobodaeab38d92017-03-06 19:55:21 -08002404
Matus Fabian8008d7c2018-07-09 01:34:20 -07002405 # second VRF
2406 pkts = self.create_stream_in(self.pg1, self.pg2)
2407 self.pg1.add_stream(pkts)
2408 self.pg_enable_capture(self.pg_interfaces)
2409 self.pg_start()
2410 capture = self.pg2.get_capture(len(pkts))
2411 self.verify_capture_out(capture, nat_ip2)
Juraj Slobodaeab38d92017-03-06 19:55:21 -08002412
Matus Fabian8008d7c2018-07-09 01:34:20 -07002413 finally:
2414 self.pg0.unconfig_ip4()
2415 self.pg1.unconfig_ip4()
2416 self.pg0.set_table_ip4(0)
2417 self.pg1.set_table_ip4(0)
2418 self.pg0.config_ip4()
2419 self.pg1.config_ip4()
2420 self.pg0.resolve_arp()
2421 self.pg1.resolve_arp()
2422 self.vapi.ip_table_add_del(vrf_id1, is_add=0)
2423 self.vapi.ip_table_add_del(vrf_id2, is_add=0)
Neale Ranns15002542017-09-10 04:39:11 -07002424
Juraj Slobodaeab38d92017-03-06 19:55:21 -08002425 def test_vrf_feature_independent(self):
Matus Fabian2ba92e32017-08-21 07:05:03 -07002426 """ NAT44 tenant VRF independent address pool mode """
Juraj Slobodaeab38d92017-03-06 19:55:21 -08002427
2428 nat_ip1 = "10.0.0.10"
2429 nat_ip2 = "10.0.0.11"
2430
Matus Fabian2ba92e32017-08-21 07:05:03 -07002431 self.nat44_add_address(nat_ip1)
Matus Fabian51e759f2017-12-07 23:22:51 -08002432 self.nat44_add_address(nat_ip2, vrf_id=99)
Matus Fabian2ba92e32017-08-21 07:05:03 -07002433 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
2434 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index)
2435 self.vapi.nat44_interface_add_del_feature(self.pg2.sw_if_index,
2436 is_inside=0)
Juraj Slobodaeab38d92017-03-06 19:55:21 -08002437
2438 # first VRF
2439 pkts = self.create_stream_in(self.pg0, self.pg2)
2440 self.pg0.add_stream(pkts)
2441 self.pg_enable_capture(self.pg_interfaces)
2442 self.pg_start()
2443 capture = self.pg2.get_capture(len(pkts))
2444 self.verify_capture_out(capture, nat_ip1)
2445
2446 # second VRF
2447 pkts = self.create_stream_in(self.pg1, self.pg2)
2448 self.pg1.add_stream(pkts)
2449 self.pg_enable_capture(self.pg_interfaces)
2450 self.pg_start()
2451 capture = self.pg2.get_capture(len(pkts))
2452 self.verify_capture_out(capture, nat_ip1)
2453
Martin Gálik406eb1d2017-05-04 04:35:04 -07002454 def test_dynamic_ipless_interfaces(self):
Matus Fabian2ba92e32017-08-21 07:05:03 -07002455 """ NAT44 interfaces without configured IP address """
Martin Gálik406eb1d2017-05-04 04:35:04 -07002456
2457 self.vapi.ip_neighbor_add_del(self.pg7.sw_if_index,
Ole Troan895b6e82017-10-20 13:28:20 +02002458 mactobinary(self.pg7.remote_mac),
Martin Gálik406eb1d2017-05-04 04:35:04 -07002459 self.pg7.remote_ip4n,
2460 is_static=1)
2461 self.vapi.ip_neighbor_add_del(self.pg8.sw_if_index,
Ole Troan895b6e82017-10-20 13:28:20 +02002462 mactobinary(self.pg8.remote_mac),
Martin Gálik406eb1d2017-05-04 04:35:04 -07002463 self.pg8.remote_ip4n,
2464 is_static=1)
2465
2466 self.vapi.ip_add_del_route(dst_address=self.pg7.remote_ip4n,
2467 dst_address_length=32,
2468 next_hop_address=self.pg7.remote_ip4n,
2469 next_hop_sw_if_index=self.pg7.sw_if_index)
2470 self.vapi.ip_add_del_route(dst_address=self.pg8.remote_ip4n,
2471 dst_address_length=32,
2472 next_hop_address=self.pg8.remote_ip4n,
2473 next_hop_sw_if_index=self.pg8.sw_if_index)
2474
Matus Fabian2ba92e32017-08-21 07:05:03 -07002475 self.nat44_add_address(self.nat_addr)
2476 self.vapi.nat44_interface_add_del_feature(self.pg7.sw_if_index)
2477 self.vapi.nat44_interface_add_del_feature(self.pg8.sw_if_index,
2478 is_inside=0)
Martin Gálik406eb1d2017-05-04 04:35:04 -07002479
2480 # in2out
2481 pkts = self.create_stream_in(self.pg7, self.pg8)
2482 self.pg7.add_stream(pkts)
2483 self.pg_enable_capture(self.pg_interfaces)
2484 self.pg_start()
2485 capture = self.pg8.get_capture(len(pkts))
2486 self.verify_capture_out(capture)
2487
2488 # out2in
Matus Fabian2ba92e32017-08-21 07:05:03 -07002489 pkts = self.create_stream_out(self.pg8, self.nat_addr)
Martin Gálik406eb1d2017-05-04 04:35:04 -07002490 self.pg8.add_stream(pkts)
2491 self.pg_enable_capture(self.pg_interfaces)
2492 self.pg_start()
2493 capture = self.pg7.get_capture(len(pkts))
2494 self.verify_capture_in(capture, self.pg7)
2495
2496 def test_static_ipless_interfaces(self):
Matus Fabian2ba92e32017-08-21 07:05:03 -07002497 """ NAT44 interfaces without configured IP address - 1:1 NAT """
Martin Gálik406eb1d2017-05-04 04:35:04 -07002498
2499 self.vapi.ip_neighbor_add_del(self.pg7.sw_if_index,
Ole Troan895b6e82017-10-20 13:28:20 +02002500 mactobinary(self.pg7.remote_mac),
Martin Gálik406eb1d2017-05-04 04:35:04 -07002501 self.pg7.remote_ip4n,
2502 is_static=1)
2503 self.vapi.ip_neighbor_add_del(self.pg8.sw_if_index,
Ole Troan895b6e82017-10-20 13:28:20 +02002504 mactobinary(self.pg8.remote_mac),
Martin Gálik406eb1d2017-05-04 04:35:04 -07002505 self.pg8.remote_ip4n,
2506 is_static=1)
2507
2508 self.vapi.ip_add_del_route(dst_address=self.pg7.remote_ip4n,
2509 dst_address_length=32,
2510 next_hop_address=self.pg7.remote_ip4n,
2511 next_hop_sw_if_index=self.pg7.sw_if_index)
2512 self.vapi.ip_add_del_route(dst_address=self.pg8.remote_ip4n,
2513 dst_address_length=32,
2514 next_hop_address=self.pg8.remote_ip4n,
2515 next_hop_sw_if_index=self.pg8.sw_if_index)
2516
Matus Fabian2ba92e32017-08-21 07:05:03 -07002517 self.nat44_add_static_mapping(self.pg7.remote_ip4, self.nat_addr)
2518 self.vapi.nat44_interface_add_del_feature(self.pg7.sw_if_index)
2519 self.vapi.nat44_interface_add_del_feature(self.pg8.sw_if_index,
2520 is_inside=0)
Martin Gálik406eb1d2017-05-04 04:35:04 -07002521
2522 # out2in
2523 pkts = self.create_stream_out(self.pg8)
2524 self.pg8.add_stream(pkts)
2525 self.pg_enable_capture(self.pg_interfaces)
2526 self.pg_start()
2527 capture = self.pg7.get_capture(len(pkts))
2528 self.verify_capture_in(capture, self.pg7)
2529
2530 # in2out
2531 pkts = self.create_stream_in(self.pg7, self.pg8)
2532 self.pg7.add_stream(pkts)
2533 self.pg_enable_capture(self.pg_interfaces)
2534 self.pg_start()
2535 capture = self.pg8.get_capture(len(pkts))
Matus Fabian2ba92e32017-08-21 07:05:03 -07002536 self.verify_capture_out(capture, self.nat_addr, True)
Martin Gálik406eb1d2017-05-04 04:35:04 -07002537
2538 def test_static_with_port_ipless_interfaces(self):
Matus Fabian2ba92e32017-08-21 07:05:03 -07002539 """ NAT44 interfaces without configured IP address - 1:1 NAPT """
Martin Gálik406eb1d2017-05-04 04:35:04 -07002540
2541 self.tcp_port_out = 30606
2542 self.udp_port_out = 30607
2543 self.icmp_id_out = 30608
2544
2545 self.vapi.ip_neighbor_add_del(self.pg7.sw_if_index,
Ole Troan895b6e82017-10-20 13:28:20 +02002546 mactobinary(self.pg7.remote_mac),
Martin Gálik406eb1d2017-05-04 04:35:04 -07002547 self.pg7.remote_ip4n,
2548 is_static=1)
2549 self.vapi.ip_neighbor_add_del(self.pg8.sw_if_index,
Ole Troan895b6e82017-10-20 13:28:20 +02002550 mactobinary(self.pg8.remote_mac),
Martin Gálik406eb1d2017-05-04 04:35:04 -07002551 self.pg8.remote_ip4n,
2552 is_static=1)
2553
2554 self.vapi.ip_add_del_route(dst_address=self.pg7.remote_ip4n,
2555 dst_address_length=32,
2556 next_hop_address=self.pg7.remote_ip4n,
2557 next_hop_sw_if_index=self.pg7.sw_if_index)
2558 self.vapi.ip_add_del_route(dst_address=self.pg8.remote_ip4n,
2559 dst_address_length=32,
2560 next_hop_address=self.pg8.remote_ip4n,
2561 next_hop_sw_if_index=self.pg8.sw_if_index)
2562
Matus Fabian2ba92e32017-08-21 07:05:03 -07002563 self.nat44_add_address(self.nat_addr)
2564 self.nat44_add_static_mapping(self.pg7.remote_ip4, self.nat_addr,
2565 self.tcp_port_in, self.tcp_port_out,
2566 proto=IP_PROTOS.tcp)
2567 self.nat44_add_static_mapping(self.pg7.remote_ip4, self.nat_addr,
2568 self.udp_port_in, self.udp_port_out,
2569 proto=IP_PROTOS.udp)
2570 self.nat44_add_static_mapping(self.pg7.remote_ip4, self.nat_addr,
2571 self.icmp_id_in, self.icmp_id_out,
2572 proto=IP_PROTOS.icmp)
2573 self.vapi.nat44_interface_add_del_feature(self.pg7.sw_if_index)
2574 self.vapi.nat44_interface_add_del_feature(self.pg8.sw_if_index,
2575 is_inside=0)
Martin Gálik406eb1d2017-05-04 04:35:04 -07002576
2577 # out2in
2578 pkts = self.create_stream_out(self.pg8)
2579 self.pg8.add_stream(pkts)
2580 self.pg_enable_capture(self.pg_interfaces)
2581 self.pg_start()
2582 capture = self.pg7.get_capture(len(pkts))
2583 self.verify_capture_in(capture, self.pg7)
2584
2585 # in2out
2586 pkts = self.create_stream_in(self.pg7, self.pg8)
2587 self.pg7.add_stream(pkts)
2588 self.pg_enable_capture(self.pg_interfaces)
2589 self.pg_start()
2590 capture = self.pg8.get_capture(len(pkts))
2591 self.verify_capture_out(capture)
2592
Matus Fabian328dbc82017-06-19 04:28:04 -07002593 def test_static_unknown_proto(self):
2594 """ 1:1 NAT translate packet with unknown protocol """
2595 nat_ip = "10.0.0.10"
Matus Fabian2ba92e32017-08-21 07:05:03 -07002596 self.nat44_add_static_mapping(self.pg0.remote_ip4, nat_ip)
2597 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
2598 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
2599 is_inside=0)
Matus Fabian328dbc82017-06-19 04:28:04 -07002600
2601 # in2out
2602 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2603 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
2604 GRE() /
Matus Fabian1e8db5f2017-06-20 01:45:49 -07002605 IP(src=self.pg2.remote_ip4, dst=self.pg3.remote_ip4) /
Matus Fabian328dbc82017-06-19 04:28:04 -07002606 TCP(sport=1234, dport=1234))
2607 self.pg0.add_stream(p)
2608 self.pg_enable_capture(self.pg_interfaces)
2609 self.pg_start()
2610 p = self.pg1.get_capture(1)
2611 packet = p[0]
2612 try:
2613 self.assertEqual(packet[IP].src, nat_ip)
2614 self.assertEqual(packet[IP].dst, self.pg1.remote_ip4)
2615 self.assertTrue(packet.haslayer(GRE))
Klement Sekerad81ae412018-05-16 10:52:54 +02002616 self.assert_packet_checksums_valid(packet)
Matus Fabian328dbc82017-06-19 04:28:04 -07002617 except:
2618 self.logger.error(ppp("Unexpected or invalid packet:", packet))
2619 raise
2620
2621 # out2in
2622 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
2623 IP(src=self.pg1.remote_ip4, dst=nat_ip) /
2624 GRE() /
Matus Fabian1e8db5f2017-06-20 01:45:49 -07002625 IP(src=self.pg3.remote_ip4, dst=self.pg2.remote_ip4) /
Matus Fabian328dbc82017-06-19 04:28:04 -07002626 TCP(sport=1234, dport=1234))
2627 self.pg1.add_stream(p)
2628 self.pg_enable_capture(self.pg_interfaces)
2629 self.pg_start()
2630 p = self.pg0.get_capture(1)
2631 packet = p[0]
2632 try:
2633 self.assertEqual(packet[IP].src, self.pg1.remote_ip4)
2634 self.assertEqual(packet[IP].dst, self.pg0.remote_ip4)
2635 self.assertTrue(packet.haslayer(GRE))
Klement Sekerad81ae412018-05-16 10:52:54 +02002636 self.assert_packet_checksums_valid(packet)
Matus Fabian328dbc82017-06-19 04:28:04 -07002637 except:
2638 self.logger.error(ppp("Unexpected or invalid packet:", packet))
2639 raise
2640
Matus Fabian7968e6c2017-07-06 05:37:49 -07002641 def test_hairpinning_static_unknown_proto(self):
Matus Fabian1e8db5f2017-06-20 01:45:49 -07002642 """ 1:1 NAT translate packet with unknown protocol - hairpinning """
2643
2644 host = self.pg0.remote_hosts[0]
2645 server = self.pg0.remote_hosts[1]
2646
2647 host_nat_ip = "10.0.0.10"
2648 server_nat_ip = "10.0.0.11"
2649
Matus Fabian2ba92e32017-08-21 07:05:03 -07002650 self.nat44_add_static_mapping(host.ip4, host_nat_ip)
2651 self.nat44_add_static_mapping(server.ip4, server_nat_ip)
2652 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
2653 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
2654 is_inside=0)
Matus Fabian1e8db5f2017-06-20 01:45:49 -07002655
2656 # host to server
2657 p = (Ether(dst=self.pg0.local_mac, src=host.mac) /
2658 IP(src=host.ip4, dst=server_nat_ip) /
2659 GRE() /
2660 IP(src=self.pg2.remote_ip4, dst=self.pg3.remote_ip4) /
2661 TCP(sport=1234, dport=1234))
2662 self.pg0.add_stream(p)
2663 self.pg_enable_capture(self.pg_interfaces)
2664 self.pg_start()
2665 p = self.pg0.get_capture(1)
2666 packet = p[0]
2667 try:
2668 self.assertEqual(packet[IP].src, host_nat_ip)
2669 self.assertEqual(packet[IP].dst, server.ip4)
2670 self.assertTrue(packet.haslayer(GRE))
Klement Sekerad81ae412018-05-16 10:52:54 +02002671 self.assert_packet_checksums_valid(packet)
Matus Fabian1e8db5f2017-06-20 01:45:49 -07002672 except:
2673 self.logger.error(ppp("Unexpected or invalid packet:", packet))
2674 raise
2675
2676 # server to host
2677 p = (Ether(dst=self.pg0.local_mac, src=server.mac) /
2678 IP(src=server.ip4, dst=host_nat_ip) /
2679 GRE() /
2680 IP(src=self.pg3.remote_ip4, dst=self.pg2.remote_ip4) /
2681 TCP(sport=1234, dport=1234))
2682 self.pg0.add_stream(p)
2683 self.pg_enable_capture(self.pg_interfaces)
2684 self.pg_start()
2685 p = self.pg0.get_capture(1)
2686 packet = p[0]
2687 try:
2688 self.assertEqual(packet[IP].src, server_nat_ip)
2689 self.assertEqual(packet[IP].dst, host.ip4)
2690 self.assertTrue(packet.haslayer(GRE))
Klement Sekerad81ae412018-05-16 10:52:54 +02002691 self.assert_packet_checksums_valid(packet)
Matus Fabian1e8db5f2017-06-20 01:45:49 -07002692 except:
2693 self.logger.error(ppp("Unexpected or invalid packet:", packet))
2694 raise
2695
Matus Fabian93d84c92017-07-19 08:06:01 -07002696 def test_output_feature(self):
Matus Fabian2ba92e32017-08-21 07:05:03 -07002697 """ NAT44 interface output feature (in2out postrouting) """
2698 self.nat44_add_address(self.nat_addr)
2699 self.vapi.nat44_interface_add_del_output_feature(self.pg0.sw_if_index)
Matus Fabianb2d2fc72017-09-10 22:17:47 -07002700 self.vapi.nat44_interface_add_del_output_feature(self.pg1.sw_if_index)
2701 self.vapi.nat44_interface_add_del_output_feature(self.pg3.sw_if_index,
Matus Fabian2ba92e32017-08-21 07:05:03 -07002702 is_inside=0)
Matus Fabian93d84c92017-07-19 08:06:01 -07002703
2704 # in2out
Matus Fabianb2d2fc72017-09-10 22:17:47 -07002705 pkts = self.create_stream_in(self.pg0, self.pg3)
Matus Fabian93d84c92017-07-19 08:06:01 -07002706 self.pg0.add_stream(pkts)
2707 self.pg_enable_capture(self.pg_interfaces)
2708 self.pg_start()
Matus Fabianb2d2fc72017-09-10 22:17:47 -07002709 capture = self.pg3.get_capture(len(pkts))
Matus Fabian93d84c92017-07-19 08:06:01 -07002710 self.verify_capture_out(capture)
2711
2712 # out2in
Matus Fabianb2d2fc72017-09-10 22:17:47 -07002713 pkts = self.create_stream_out(self.pg3)
2714 self.pg3.add_stream(pkts)
Matus Fabian93d84c92017-07-19 08:06:01 -07002715 self.pg_enable_capture(self.pg_interfaces)
2716 self.pg_start()
2717 capture = self.pg0.get_capture(len(pkts))
2718 self.verify_capture_in(capture, self.pg0)
2719
Matus Fabianb2d2fc72017-09-10 22:17:47 -07002720 # from non-NAT interface to NAT inside interface
2721 pkts = self.create_stream_in(self.pg2, self.pg0)
2722 self.pg2.add_stream(pkts)
2723 self.pg_enable_capture(self.pg_interfaces)
2724 self.pg_start()
2725 capture = self.pg0.get_capture(len(pkts))
2726 self.verify_capture_no_translation(capture, self.pg2, self.pg0)
2727
Matus Fabian93d84c92017-07-19 08:06:01 -07002728 def test_output_feature_vrf_aware(self):
Matus Fabian2ba92e32017-08-21 07:05:03 -07002729 """ NAT44 interface output feature VRF aware (in2out postrouting) """
Matus Fabian93d84c92017-07-19 08:06:01 -07002730 nat_ip_vrf10 = "10.0.0.10"
2731 nat_ip_vrf20 = "10.0.0.20"
2732
2733 self.vapi.ip_add_del_route(dst_address=self.pg3.remote_ip4n,
2734 dst_address_length=32,
2735 next_hop_address=self.pg3.remote_ip4n,
2736 next_hop_sw_if_index=self.pg3.sw_if_index,
2737 table_id=10)
2738 self.vapi.ip_add_del_route(dst_address=self.pg3.remote_ip4n,
2739 dst_address_length=32,
2740 next_hop_address=self.pg3.remote_ip4n,
2741 next_hop_sw_if_index=self.pg3.sw_if_index,
2742 table_id=20)
2743
Matus Fabian2ba92e32017-08-21 07:05:03 -07002744 self.nat44_add_address(nat_ip_vrf10, vrf_id=10)
2745 self.nat44_add_address(nat_ip_vrf20, vrf_id=20)
2746 self.vapi.nat44_interface_add_del_output_feature(self.pg4.sw_if_index)
2747 self.vapi.nat44_interface_add_del_output_feature(self.pg6.sw_if_index)
2748 self.vapi.nat44_interface_add_del_output_feature(self.pg3.sw_if_index,
2749 is_inside=0)
Matus Fabian93d84c92017-07-19 08:06:01 -07002750
2751 # in2out VRF 10
2752 pkts = self.create_stream_in(self.pg4, self.pg3)
2753 self.pg4.add_stream(pkts)
2754 self.pg_enable_capture(self.pg_interfaces)
2755 self.pg_start()
2756 capture = self.pg3.get_capture(len(pkts))
2757 self.verify_capture_out(capture, nat_ip=nat_ip_vrf10)
2758
2759 # out2in VRF 10
2760 pkts = self.create_stream_out(self.pg3, dst_ip=nat_ip_vrf10)
2761 self.pg3.add_stream(pkts)
2762 self.pg_enable_capture(self.pg_interfaces)
2763 self.pg_start()
2764 capture = self.pg4.get_capture(len(pkts))
2765 self.verify_capture_in(capture, self.pg4)
2766
2767 # in2out VRF 20
2768 pkts = self.create_stream_in(self.pg6, self.pg3)
2769 self.pg6.add_stream(pkts)
2770 self.pg_enable_capture(self.pg_interfaces)
2771 self.pg_start()
2772 capture = self.pg3.get_capture(len(pkts))
2773 self.verify_capture_out(capture, nat_ip=nat_ip_vrf20)
2774
2775 # out2in VRF 20
2776 pkts = self.create_stream_out(self.pg3, dst_ip=nat_ip_vrf20)
2777 self.pg3.add_stream(pkts)
2778 self.pg_enable_capture(self.pg_interfaces)
2779 self.pg_start()
2780 capture = self.pg6.get_capture(len(pkts))
2781 self.verify_capture_in(capture, self.pg6)
2782
Matus Fabian161c59c2017-07-21 03:46:03 -07002783 def test_output_feature_hairpinning(self):
Matus Fabian2ba92e32017-08-21 07:05:03 -07002784 """ NAT44 interface output feature hairpinning (in2out postrouting) """
Matus Fabian93d84c92017-07-19 08:06:01 -07002785 host = self.pg0.remote_hosts[0]
2786 server = self.pg0.remote_hosts[1]
2787 host_in_port = 1234
2788 host_out_port = 0
2789 server_in_port = 5678
2790 server_out_port = 8765
2791
Matus Fabian2ba92e32017-08-21 07:05:03 -07002792 self.nat44_add_address(self.nat_addr)
2793 self.vapi.nat44_interface_add_del_output_feature(self.pg0.sw_if_index)
2794 self.vapi.nat44_interface_add_del_output_feature(self.pg1.sw_if_index,
2795 is_inside=0)
Matus Fabian93d84c92017-07-19 08:06:01 -07002796
2797 # add static mapping for server
Matus Fabian2ba92e32017-08-21 07:05:03 -07002798 self.nat44_add_static_mapping(server.ip4, self.nat_addr,
2799 server_in_port, server_out_port,
2800 proto=IP_PROTOS.tcp)
Matus Fabian93d84c92017-07-19 08:06:01 -07002801
2802 # send packet from host to server
2803 p = (Ether(src=host.mac, dst=self.pg0.local_mac) /
Matus Fabian2ba92e32017-08-21 07:05:03 -07002804 IP(src=host.ip4, dst=self.nat_addr) /
Matus Fabian93d84c92017-07-19 08:06:01 -07002805 TCP(sport=host_in_port, dport=server_out_port))
2806 self.pg0.add_stream(p)
2807 self.pg_enable_capture(self.pg_interfaces)
2808 self.pg_start()
2809 capture = self.pg0.get_capture(1)
2810 p = capture[0]
2811 try:
2812 ip = p[IP]
2813 tcp = p[TCP]
Matus Fabian2ba92e32017-08-21 07:05:03 -07002814 self.assertEqual(ip.src, self.nat_addr)
Matus Fabian93d84c92017-07-19 08:06:01 -07002815 self.assertEqual(ip.dst, server.ip4)
2816 self.assertNotEqual(tcp.sport, host_in_port)
2817 self.assertEqual(tcp.dport, server_in_port)
Klement Sekerad81ae412018-05-16 10:52:54 +02002818 self.assert_packet_checksums_valid(p)
Matus Fabian93d84c92017-07-19 08:06:01 -07002819 host_out_port = tcp.sport
2820 except:
2821 self.logger.error(ppp("Unexpected or invalid packet:", p))
2822 raise
2823
2824 # send reply from server to host
2825 p = (Ether(src=server.mac, dst=self.pg0.local_mac) /
Matus Fabian2ba92e32017-08-21 07:05:03 -07002826 IP(src=server.ip4, dst=self.nat_addr) /
Matus Fabian93d84c92017-07-19 08:06:01 -07002827 TCP(sport=server_in_port, dport=host_out_port))
2828 self.pg0.add_stream(p)
2829 self.pg_enable_capture(self.pg_interfaces)
2830 self.pg_start()
2831 capture = self.pg0.get_capture(1)
2832 p = capture[0]
2833 try:
2834 ip = p[IP]
2835 tcp = p[TCP]
Matus Fabian2ba92e32017-08-21 07:05:03 -07002836 self.assertEqual(ip.src, self.nat_addr)
Matus Fabian93d84c92017-07-19 08:06:01 -07002837 self.assertEqual(ip.dst, host.ip4)
2838 self.assertEqual(tcp.sport, server_out_port)
2839 self.assertEqual(tcp.dport, host_in_port)
Klement Sekerad81ae412018-05-16 10:52:54 +02002840 self.assert_packet_checksums_valid(p)
Matus Fabian93d84c92017-07-19 08:06:01 -07002841 except:
Matus Fabiane82488f2018-01-18 03:38:45 -08002842 self.logger.error(ppp("Unexpected or invalid packet:", p))
Matus Fabian93d84c92017-07-19 08:06:01 -07002843 raise
2844
Matus Fabian36ea2d62017-10-24 04:13:49 -07002845 def test_one_armed_nat44(self):
2846 """ One armed NAT44 """
2847 remote_host = self.pg9.remote_hosts[0]
2848 local_host = self.pg9.remote_hosts[1]
2849 external_port = 0
2850
2851 self.nat44_add_address(self.nat_addr)
2852 self.vapi.nat44_interface_add_del_feature(self.pg9.sw_if_index)
2853 self.vapi.nat44_interface_add_del_feature(self.pg9.sw_if_index,
2854 is_inside=0)
2855
2856 # in2out
2857 p = (Ether(src=self.pg9.remote_mac, dst=self.pg9.local_mac) /
2858 IP(src=local_host.ip4, dst=remote_host.ip4) /
2859 TCP(sport=12345, dport=80))
2860 self.pg9.add_stream(p)
2861 self.pg_enable_capture(self.pg_interfaces)
2862 self.pg_start()
2863 capture = self.pg9.get_capture(1)
2864 p = capture[0]
2865 try:
2866 ip = p[IP]
2867 tcp = p[TCP]
2868 self.assertEqual(ip.src, self.nat_addr)
2869 self.assertEqual(ip.dst, remote_host.ip4)
2870 self.assertNotEqual(tcp.sport, 12345)
2871 external_port = tcp.sport
2872 self.assertEqual(tcp.dport, 80)
Klement Sekerad81ae412018-05-16 10:52:54 +02002873 self.assert_packet_checksums_valid(p)
Matus Fabian36ea2d62017-10-24 04:13:49 -07002874 except:
2875 self.logger.error(ppp("Unexpected or invalid packet:", p))
2876 raise
2877
2878 # out2in
2879 p = (Ether(src=self.pg9.remote_mac, dst=self.pg9.local_mac) /
2880 IP(src=remote_host.ip4, dst=self.nat_addr) /
2881 TCP(sport=80, dport=external_port))
2882 self.pg9.add_stream(p)
2883 self.pg_enable_capture(self.pg_interfaces)
2884 self.pg_start()
2885 capture = self.pg9.get_capture(1)
2886 p = capture[0]
2887 try:
2888 ip = p[IP]
2889 tcp = p[TCP]
2890 self.assertEqual(ip.src, remote_host.ip4)
2891 self.assertEqual(ip.dst, local_host.ip4)
2892 self.assertEqual(tcp.sport, 80)
2893 self.assertEqual(tcp.dport, 12345)
Klement Sekerad81ae412018-05-16 10:52:54 +02002894 self.assert_packet_checksums_valid(p)
Matus Fabian36ea2d62017-10-24 04:13:49 -07002895 except:
2896 self.logger.error(ppp("Unexpected or invalid packet:", p))
2897 raise
2898
Matus Fabian5ba86f72017-10-26 03:37:38 -07002899 def test_del_session(self):
2900 """ Delete NAT44 session """
2901 self.nat44_add_address(self.nat_addr)
2902 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
2903 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
2904 is_inside=0)
2905
2906 pkts = self.create_stream_in(self.pg0, self.pg1)
2907 self.pg0.add_stream(pkts)
2908 self.pg_enable_capture(self.pg_interfaces)
2909 self.pg_start()
Matus Fabian229c1aa2018-05-28 04:09:52 -07002910 self.pg1.get_capture(len(pkts))
Matus Fabian5ba86f72017-10-26 03:37:38 -07002911
2912 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n, 0)
2913 nsessions = len(sessions)
2914
2915 self.vapi.nat44_del_session(sessions[0].inside_ip_address,
2916 sessions[0].inside_port,
2917 sessions[0].protocol)
2918 self.vapi.nat44_del_session(sessions[1].outside_ip_address,
2919 sessions[1].outside_port,
2920 sessions[1].protocol,
2921 is_in=0)
2922
2923 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n, 0)
2924 self.assertEqual(nsessions - len(sessions), 2)
2925
Matus Fabianefcd1e92017-08-15 06:59:19 -07002926 def test_set_get_reass(self):
2927 """ NAT44 set/get virtual fragmentation reassembly """
2928 reas_cfg1 = self.vapi.nat_get_reass()
2929
2930 self.vapi.nat_set_reass(timeout=reas_cfg1.ip4_timeout + 5,
2931 max_reass=reas_cfg1.ip4_max_reass * 2,
2932 max_frag=reas_cfg1.ip4_max_frag * 2)
2933
2934 reas_cfg2 = self.vapi.nat_get_reass()
2935
2936 self.assertEqual(reas_cfg1.ip4_timeout + 5, reas_cfg2.ip4_timeout)
2937 self.assertEqual(reas_cfg1.ip4_max_reass * 2, reas_cfg2.ip4_max_reass)
2938 self.assertEqual(reas_cfg1.ip4_max_frag * 2, reas_cfg2.ip4_max_frag)
2939
2940 self.vapi.nat_set_reass(drop_frag=1)
2941 self.assertTrue(self.vapi.nat_get_reass().ip4_drop_frag)
2942
2943 def test_frag_in_order(self):
2944 """ NAT44 translate fragments arriving in order """
2945 self.nat44_add_address(self.nat_addr)
2946 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
2947 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
2948 is_inside=0)
2949
2950 data = "A" * 4 + "B" * 16 + "C" * 3
2951 self.tcp_port_in = random.randint(1025, 65535)
2952
2953 reass = self.vapi.nat_reass_dump()
2954 reass_n_start = len(reass)
2955
2956 # in2out
2957 pkts = self.create_stream_frag(self.pg0,
2958 self.pg1.remote_ip4,
2959 self.tcp_port_in,
2960 20,
2961 data)
2962 self.pg0.add_stream(pkts)
2963 self.pg_enable_capture(self.pg_interfaces)
2964 self.pg_start()
2965 frags = self.pg1.get_capture(len(pkts))
2966 p = self.reass_frags_and_verify(frags,
2967 self.nat_addr,
2968 self.pg1.remote_ip4)
2969 self.assertEqual(p[TCP].dport, 20)
2970 self.assertNotEqual(p[TCP].sport, self.tcp_port_in)
2971 self.tcp_port_out = p[TCP].sport
2972 self.assertEqual(data, p[Raw].load)
2973
2974 # out2in
2975 pkts = self.create_stream_frag(self.pg1,
2976 self.nat_addr,
2977 20,
2978 self.tcp_port_out,
2979 data)
2980 self.pg1.add_stream(pkts)
2981 self.pg_enable_capture(self.pg_interfaces)
2982 self.pg_start()
2983 frags = self.pg0.get_capture(len(pkts))
2984 p = self.reass_frags_and_verify(frags,
2985 self.pg1.remote_ip4,
2986 self.pg0.remote_ip4)
2987 self.assertEqual(p[TCP].sport, 20)
2988 self.assertEqual(p[TCP].dport, self.tcp_port_in)
2989 self.assertEqual(data, p[Raw].load)
2990
2991 reass = self.vapi.nat_reass_dump()
2992 reass_n_end = len(reass)
2993
2994 self.assertEqual(reass_n_end - reass_n_start, 2)
2995
2996 def test_reass_hairpinning(self):
2997 """ NAT44 fragments hairpinning """
Matus Fabianefcd1e92017-08-15 06:59:19 -07002998 server = self.pg0.remote_hosts[1]
2999 host_in_port = random.randint(1025, 65535)
Matus Fabianefcd1e92017-08-15 06:59:19 -07003000 server_in_port = random.randint(1025, 65535)
3001 server_out_port = random.randint(1025, 65535)
3002 data = "A" * 4 + "B" * 16 + "C" * 3
3003
3004 self.nat44_add_address(self.nat_addr)
3005 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3006 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3007 is_inside=0)
3008 # add static mapping for server
3009 self.nat44_add_static_mapping(server.ip4, self.nat_addr,
3010 server_in_port, server_out_port,
3011 proto=IP_PROTOS.tcp)
3012
3013 # send packet from host to server
3014 pkts = self.create_stream_frag(self.pg0,
3015 self.nat_addr,
3016 host_in_port,
3017 server_out_port,
3018 data)
3019 self.pg0.add_stream(pkts)
3020 self.pg_enable_capture(self.pg_interfaces)
3021 self.pg_start()
3022 frags = self.pg0.get_capture(len(pkts))
3023 p = self.reass_frags_and_verify(frags,
3024 self.nat_addr,
3025 server.ip4)
3026 self.assertNotEqual(p[TCP].sport, host_in_port)
3027 self.assertEqual(p[TCP].dport, server_in_port)
3028 self.assertEqual(data, p[Raw].load)
3029
3030 def test_frag_out_of_order(self):
3031 """ NAT44 translate fragments arriving out of order """
3032 self.nat44_add_address(self.nat_addr)
3033 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3034 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3035 is_inside=0)
3036
3037 data = "A" * 4 + "B" * 16 + "C" * 3
3038 random.randint(1025, 65535)
3039
3040 # in2out
3041 pkts = self.create_stream_frag(self.pg0,
3042 self.pg1.remote_ip4,
3043 self.tcp_port_in,
3044 20,
3045 data)
3046 pkts.reverse()
3047 self.pg0.add_stream(pkts)
3048 self.pg_enable_capture(self.pg_interfaces)
3049 self.pg_start()
3050 frags = self.pg1.get_capture(len(pkts))
3051 p = self.reass_frags_and_verify(frags,
3052 self.nat_addr,
3053 self.pg1.remote_ip4)
3054 self.assertEqual(p[TCP].dport, 20)
3055 self.assertNotEqual(p[TCP].sport, self.tcp_port_in)
3056 self.tcp_port_out = p[TCP].sport
3057 self.assertEqual(data, p[Raw].load)
3058
3059 # out2in
3060 pkts = self.create_stream_frag(self.pg1,
3061 self.nat_addr,
3062 20,
3063 self.tcp_port_out,
3064 data)
3065 pkts.reverse()
3066 self.pg1.add_stream(pkts)
3067 self.pg_enable_capture(self.pg_interfaces)
3068 self.pg_start()
3069 frags = self.pg0.get_capture(len(pkts))
3070 p = self.reass_frags_and_verify(frags,
3071 self.pg1.remote_ip4,
3072 self.pg0.remote_ip4)
3073 self.assertEqual(p[TCP].sport, 20)
3074 self.assertEqual(p[TCP].dport, self.tcp_port_in)
3075 self.assertEqual(data, p[Raw].load)
3076
Matus Fabian27697102017-11-09 01:43:47 -08003077 def test_port_restricted(self):
3078 """ Port restricted NAT44 (MAP-E CE) """
3079 self.nat44_add_address(self.nat_addr)
3080 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3081 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3082 is_inside=0)
Matus Fabian51e759f2017-12-07 23:22:51 -08003083 self.vapi.cli("nat addr-port-assignment-alg map-e psid 10 "
Matus Fabian27697102017-11-09 01:43:47 -08003084 "psid-offset 6 psid-len 6")
3085
3086 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
3087 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
3088 TCP(sport=4567, dport=22))
3089 self.pg0.add_stream(p)
3090 self.pg_enable_capture(self.pg_interfaces)
3091 self.pg_start()
3092 capture = self.pg1.get_capture(1)
3093 p = capture[0]
3094 try:
3095 ip = p[IP]
3096 tcp = p[TCP]
3097 self.assertEqual(ip.dst, self.pg1.remote_ip4)
3098 self.assertEqual(ip.src, self.nat_addr)
3099 self.assertEqual(tcp.dport, 22)
3100 self.assertNotEqual(tcp.sport, 4567)
3101 self.assertEqual((tcp.sport >> 6) & 63, 10)
Klement Sekerad81ae412018-05-16 10:52:54 +02003102 self.assert_packet_checksums_valid(p)
Matus Fabian27697102017-11-09 01:43:47 -08003103 except:
3104 self.logger.error(ppp("Unexpected or invalid packet:", p))
3105 raise
3106
Matus Fabiana6110b62018-06-13 05:39:07 -07003107 def test_ipfix_max_frags(self):
3108 """ IPFIX logging maximum fragments pending reassembly exceeded """
3109 self.nat44_add_address(self.nat_addr)
3110 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3111 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3112 is_inside=0)
3113 self.vapi.nat_set_reass(max_frag=0)
3114 self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4n,
3115 src_address=self.pg3.local_ip4n,
3116 path_mtu=512,
3117 template_interval=10)
3118 self.vapi.nat_ipfix(domain_id=self.ipfix_domain_id,
3119 src_port=self.ipfix_src_port)
3120
3121 data = "A" * 4 + "B" * 16 + "C" * 3
3122 self.tcp_port_in = random.randint(1025, 65535)
3123 pkts = self.create_stream_frag(self.pg0,
3124 self.pg1.remote_ip4,
3125 self.tcp_port_in,
3126 20,
3127 data)
3128 self.pg0.add_stream(pkts[-1])
3129 self.pg_enable_capture(self.pg_interfaces)
3130 self.pg_start()
3131 self.pg1.assert_nothing_captured()
3132 sleep(1)
3133 self.vapi.cli("ipfix flush") # FIXME this should be an API call
3134 capture = self.pg3.get_capture(9)
3135 ipfix = IPFIXDecoder()
3136 # first load template
3137 for p in capture:
3138 self.assertTrue(p.haslayer(IPFIX))
3139 self.assertEqual(p[IP].src, self.pg3.local_ip4)
3140 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
3141 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
3142 self.assertEqual(p[UDP].dport, 4739)
3143 self.assertEqual(p[IPFIX].observationDomainID,
3144 self.ipfix_domain_id)
3145 if p.haslayer(Template):
3146 ipfix.add_template(p.getlayer(Template))
3147 # verify events in data set
3148 for p in capture:
3149 if p.haslayer(Data):
3150 data = ipfix.decode_data_set(p.getlayer(Set))
3151 self.verify_ipfix_max_fragments_ip4(data, 0,
3152 self.pg0.remote_ip4n)
3153
Matus Fabian8008d7c2018-07-09 01:34:20 -07003154 def test_multiple_outside_vrf(self):
3155 """ Multiple outside VRF """
3156 vrf_id1 = 1
3157 vrf_id2 = 2
3158
3159 self.pg1.unconfig_ip4()
3160 self.pg2.unconfig_ip4()
3161 self.vapi.ip_table_add_del(vrf_id1, is_add=1)
3162 self.vapi.ip_table_add_del(vrf_id2, is_add=1)
3163 self.pg1.set_table_ip4(vrf_id1)
3164 self.pg2.set_table_ip4(vrf_id2)
3165 self.pg1.config_ip4()
3166 self.pg2.config_ip4()
3167 self.pg1.resolve_arp()
3168 self.pg2.resolve_arp()
3169
3170 self.nat44_add_address(self.nat_addr)
3171 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3172 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3173 is_inside=0)
3174 self.vapi.nat44_interface_add_del_feature(self.pg2.sw_if_index,
3175 is_inside=0)
3176
3177 try:
3178 # first VRF
3179 pkts = self.create_stream_in(self.pg0, self.pg1)
3180 self.pg0.add_stream(pkts)
3181 self.pg_enable_capture(self.pg_interfaces)
3182 self.pg_start()
3183 capture = self.pg1.get_capture(len(pkts))
3184 self.verify_capture_out(capture, self.nat_addr)
3185
3186 pkts = self.create_stream_out(self.pg1, self.nat_addr)
3187 self.pg1.add_stream(pkts)
3188 self.pg_enable_capture(self.pg_interfaces)
3189 self.pg_start()
3190 capture = self.pg0.get_capture(len(pkts))
3191 self.verify_capture_in(capture, self.pg0)
3192
3193 self.tcp_port_in = 60303
3194 self.udp_port_in = 60304
3195 self.icmp_id_in = 60305
3196
3197 # second VRF
3198 pkts = self.create_stream_in(self.pg0, self.pg2)
3199 self.pg0.add_stream(pkts)
3200 self.pg_enable_capture(self.pg_interfaces)
3201 self.pg_start()
3202 capture = self.pg2.get_capture(len(pkts))
3203 self.verify_capture_out(capture, self.nat_addr)
3204
3205 pkts = self.create_stream_out(self.pg2, self.nat_addr)
3206 self.pg2.add_stream(pkts)
3207 self.pg_enable_capture(self.pg_interfaces)
3208 self.pg_start()
3209 capture = self.pg0.get_capture(len(pkts))
3210 self.verify_capture_in(capture, self.pg0)
3211
3212 finally:
3213 self.pg1.unconfig_ip4()
3214 self.pg2.unconfig_ip4()
3215 self.pg1.set_table_ip4(0)
3216 self.pg2.set_table_ip4(0)
3217 self.pg1.config_ip4()
3218 self.pg2.config_ip4()
3219 self.pg1.resolve_arp()
3220 self.pg2.resolve_arp()
3221
Matus Fabiana6110b62018-06-13 05:39:07 -07003222 def tearDown(self):
3223 super(TestNAT44, self).tearDown()
3224 if not self.vpp_dead:
3225 self.logger.info(self.vapi.cli("show nat44 addresses"))
3226 self.logger.info(self.vapi.cli("show nat44 interfaces"))
3227 self.logger.info(self.vapi.cli("show nat44 static mappings"))
3228 self.logger.info(self.vapi.cli("show nat44 interface address"))
3229 self.logger.info(self.vapi.cli("show nat44 sessions detail"))
3230 self.logger.info(self.vapi.cli("show nat virtual-reassembly"))
3231 self.logger.info(self.vapi.cli("show nat44 hash tables detail"))
3232 self.vapi.cli("nat addr-port-assignment-alg default")
3233 self.clear_nat44()
3234 self.vapi.cli("clear logging")
3235
3236
3237class TestNAT44EndpointDependent(MethodHolder):
3238 """ Endpoint-Dependent mapping and filtering test cases """
3239
3240 @classmethod
3241 def setUpConstants(cls):
3242 super(TestNAT44EndpointDependent, cls).setUpConstants()
3243 cls.vpp_cmdline.extend(["nat", "{", "endpoint-dependent", "}"])
3244
3245 @classmethod
3246 def setUpClass(cls):
3247 super(TestNAT44EndpointDependent, cls).setUpClass()
3248 cls.vapi.cli("set log class nat level debug")
3249 try:
3250 cls.tcp_port_in = 6303
3251 cls.tcp_port_out = 6303
3252 cls.udp_port_in = 6304
3253 cls.udp_port_out = 6304
3254 cls.icmp_id_in = 6305
3255 cls.icmp_id_out = 6305
3256 cls.nat_addr = '10.0.0.3'
3257 cls.nat_addr_n = socket.inet_pton(socket.AF_INET, cls.nat_addr)
3258 cls.ipfix_src_port = 4739
3259 cls.ipfix_domain_id = 1
3260 cls.tcp_external_port = 80
3261
Matus Fabian8008d7c2018-07-09 01:34:20 -07003262 cls.create_pg_interfaces(range(7))
Matus Fabiana6110b62018-06-13 05:39:07 -07003263 cls.interfaces = list(cls.pg_interfaces[0:3])
3264
3265 for i in cls.interfaces:
3266 i.admin_up()
3267 i.config_ip4()
3268 i.resolve_arp()
3269
3270 cls.pg0.generate_remote_hosts(3)
3271 cls.pg0.configure_ipv4_neighbors()
3272
3273 cls.pg3.admin_up()
3274
3275 cls.pg4.generate_remote_hosts(2)
3276 cls.pg4.config_ip4()
3277 ip_addr_n = socket.inet_pton(socket.AF_INET, "10.0.0.1")
3278 cls.vapi.sw_interface_add_del_address(cls.pg4.sw_if_index,
3279 ip_addr_n,
3280 24)
3281 cls.pg4.admin_up()
3282 cls.pg4.resolve_arp()
3283 cls.pg4._remote_hosts[1]._ip4 = cls.pg4._remote_hosts[0]._ip4
3284 cls.pg4.resolve_arp()
3285
Matus Fabian8008d7c2018-07-09 01:34:20 -07003286 zero_ip4n = socket.inet_pton(socket.AF_INET, "0.0.0.0")
3287 cls.vapi.ip_table_add_del(1, is_add=1)
3288
3289 cls.pg5._local_ip4 = "10.1.1.1"
3290 cls.pg5._local_ip4n = socket.inet_pton(socket.AF_INET,
3291 cls.pg5.local_ip4)
3292 cls.pg5._remote_hosts[0]._ip4 = "10.1.1.2"
3293 cls.pg5._remote_hosts[0]._ip4n = socket.inet_pton(
3294 socket.AF_INET, cls.pg5.remote_ip4)
3295 cls.pg5.set_table_ip4(1)
3296 cls.pg5.config_ip4()
3297 cls.pg5.admin_up()
3298 cls.vapi.ip_add_del_route(dst_address=cls.pg5.remote_ip4n,
3299 dst_address_length=32,
3300 table_id=1,
3301 next_hop_sw_if_index=cls.pg5.sw_if_index,
3302 next_hop_address=zero_ip4n)
3303
3304 cls.pg6._local_ip4 = "10.1.2.1"
3305 cls.pg6._local_ip4n = socket.inet_pton(socket.AF_INET,
3306 cls.pg6.local_ip4)
3307 cls.pg6._remote_hosts[0]._ip4 = "10.1.2.2"
3308 cls.pg6._remote_hosts[0]._ip4n = socket.inet_pton(
3309 socket.AF_INET, cls.pg6.remote_ip4)
3310 cls.pg6.set_table_ip4(1)
3311 cls.pg6.config_ip4()
3312 cls.pg6.admin_up()
3313 cls.vapi.ip_add_del_route(dst_address=cls.pg6.remote_ip4n,
3314 dst_address_length=32,
3315 table_id=1,
3316 next_hop_sw_if_index=cls.pg6.sw_if_index,
3317 next_hop_address=zero_ip4n)
3318
3319 cls.vapi.ip_add_del_route(dst_address=cls.pg6.remote_ip4n,
3320 dst_address_length=16,
3321 next_hop_address=zero_ip4n,
3322 table_id=0,
3323 next_hop_table_id=1)
3324 cls.vapi.ip_add_del_route(dst_address=zero_ip4n,
3325 dst_address_length=0,
3326 next_hop_address=zero_ip4n,
3327 table_id=1,
3328 next_hop_table_id=0)
3329 cls.vapi.ip_add_del_route(dst_address=zero_ip4n,
3330 dst_address_length=0,
3331 table_id=0,
3332 next_hop_sw_if_index=cls.pg1.sw_if_index,
3333 next_hop_address=cls.pg1.local_ip4n)
3334
3335 cls.pg5.resolve_arp()
3336 cls.pg6.resolve_arp()
3337
Matus Fabiana6110b62018-06-13 05:39:07 -07003338 except Exception:
3339 super(TestNAT44EndpointDependent, cls).tearDownClass()
3340 raise
3341
3342 def test_dynamic(self):
3343 """ NAT44 dynamic translation test """
3344
3345 self.nat44_add_address(self.nat_addr)
3346 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3347 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3348 is_inside=0)
3349
3350 # in2out
3351 pkts = self.create_stream_in(self.pg0, self.pg1)
3352 self.pg0.add_stream(pkts)
3353 self.pg_enable_capture(self.pg_interfaces)
3354 self.pg_start()
3355 capture = self.pg1.get_capture(len(pkts))
3356 self.verify_capture_out(capture)
3357
3358 # out2in
3359 pkts = self.create_stream_out(self.pg1)
3360 self.pg1.add_stream(pkts)
3361 self.pg_enable_capture(self.pg_interfaces)
3362 self.pg_start()
3363 capture = self.pg0.get_capture(len(pkts))
3364 self.verify_capture_in(capture, self.pg0)
3365
3366 def test_forwarding(self):
3367 """ NAT44 forwarding test """
3368
3369 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3370 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3371 is_inside=0)
3372 self.vapi.nat44_forwarding_enable_disable(1)
3373
3374 real_ip = self.pg0.remote_ip4n
3375 alias_ip = self.nat_addr_n
3376 self.vapi.nat44_add_del_static_mapping(local_ip=real_ip,
3377 external_ip=alias_ip)
3378
3379 try:
3380 # in2out - static mapping match
3381
3382 pkts = self.create_stream_out(self.pg1)
3383 self.pg1.add_stream(pkts)
3384 self.pg_enable_capture(self.pg_interfaces)
3385 self.pg_start()
3386 capture = self.pg0.get_capture(len(pkts))
3387 self.verify_capture_in(capture, self.pg0)
3388
3389 pkts = self.create_stream_in(self.pg0, self.pg1)
3390 self.pg0.add_stream(pkts)
3391 self.pg_enable_capture(self.pg_interfaces)
3392 self.pg_start()
3393 capture = self.pg1.get_capture(len(pkts))
3394 self.verify_capture_out(capture, same_port=True)
3395
3396 # in2out - no static mapping match
3397
3398 host0 = self.pg0.remote_hosts[0]
3399 self.pg0.remote_hosts[0] = self.pg0.remote_hosts[1]
3400 try:
3401 pkts = self.create_stream_out(self.pg1,
3402 dst_ip=self.pg0.remote_ip4,
3403 use_inside_ports=True)
3404 self.pg1.add_stream(pkts)
3405 self.pg_enable_capture(self.pg_interfaces)
3406 self.pg_start()
3407 capture = self.pg0.get_capture(len(pkts))
3408 self.verify_capture_in(capture, self.pg0)
3409
3410 pkts = self.create_stream_in(self.pg0, self.pg1)
3411 self.pg0.add_stream(pkts)
3412 self.pg_enable_capture(self.pg_interfaces)
3413 self.pg_start()
3414 capture = self.pg1.get_capture(len(pkts))
3415 self.verify_capture_out(capture, nat_ip=self.pg0.remote_ip4,
3416 same_port=True)
3417 finally:
3418 self.pg0.remote_hosts[0] = host0
3419
3420 user = self.pg0.remote_hosts[1]
3421 sessions = self.vapi.nat44_user_session_dump(user.ip4n, 0)
3422 self.assertEqual(len(sessions), 3)
3423 self.assertTrue(sessions[0].ext_host_valid)
3424 self.vapi.nat44_del_session(
3425 sessions[0].inside_ip_address,
3426 sessions[0].inside_port,
3427 sessions[0].protocol,
3428 ext_host_address=sessions[0].ext_host_address,
3429 ext_host_port=sessions[0].ext_host_port)
3430 sessions = self.vapi.nat44_user_session_dump(user.ip4n, 0)
3431 self.assertEqual(len(sessions), 2)
3432
3433 finally:
3434 self.vapi.nat44_forwarding_enable_disable(0)
3435 self.vapi.nat44_add_del_static_mapping(local_ip=real_ip,
3436 external_ip=alias_ip,
3437 is_add=0)
3438
3439 def test_static_lb(self):
3440 """ NAT44 local service load balancing """
3441 external_addr_n = socket.inet_pton(socket.AF_INET, self.nat_addr)
3442 external_port = 80
3443 local_port = 8080
3444 server1 = self.pg0.remote_hosts[0]
3445 server2 = self.pg0.remote_hosts[1]
3446
3447 locals = [{'addr': server1.ip4n,
3448 'port': local_port,
3449 'probability': 70},
3450 {'addr': server2.ip4n,
3451 'port': local_port,
3452 'probability': 30}]
3453
3454 self.nat44_add_address(self.nat_addr)
3455 self.vapi.nat44_add_del_lb_static_mapping(external_addr_n,
3456 external_port,
3457 IP_PROTOS.tcp,
3458 local_num=len(locals),
3459 locals=locals)
3460 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3461 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3462 is_inside=0)
3463
3464 # from client to service
3465 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
3466 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
3467 TCP(sport=12345, dport=external_port))
3468 self.pg1.add_stream(p)
3469 self.pg_enable_capture(self.pg_interfaces)
3470 self.pg_start()
3471 capture = self.pg0.get_capture(1)
3472 p = capture[0]
3473 server = None
3474 try:
3475 ip = p[IP]
3476 tcp = p[TCP]
3477 self.assertIn(ip.dst, [server1.ip4, server2.ip4])
3478 if ip.dst == server1.ip4:
3479 server = server1
3480 else:
3481 server = server2
3482 self.assertEqual(tcp.dport, local_port)
3483 self.assert_packet_checksums_valid(p)
3484 except:
3485 self.logger.error(ppp("Unexpected or invalid packet:", p))
3486 raise
3487
3488 # from service back to client
3489 p = (Ether(src=server.mac, dst=self.pg0.local_mac) /
3490 IP(src=server.ip4, dst=self.pg1.remote_ip4) /
3491 TCP(sport=local_port, dport=12345))
3492 self.pg0.add_stream(p)
3493 self.pg_enable_capture(self.pg_interfaces)
3494 self.pg_start()
3495 capture = self.pg1.get_capture(1)
3496 p = capture[0]
3497 try:
3498 ip = p[IP]
3499 tcp = p[TCP]
3500 self.assertEqual(ip.src, self.nat_addr)
3501 self.assertEqual(tcp.sport, external_port)
3502 self.assert_packet_checksums_valid(p)
3503 except:
3504 self.logger.error(ppp("Unexpected or invalid packet:", p))
3505 raise
3506
3507 sessions = self.vapi.nat44_user_session_dump(server.ip4n, 0)
3508 self.assertEqual(len(sessions), 1)
3509 self.assertTrue(sessions[0].ext_host_valid)
3510 self.vapi.nat44_del_session(
3511 sessions[0].inside_ip_address,
3512 sessions[0].inside_port,
3513 sessions[0].protocol,
3514 ext_host_address=sessions[0].ext_host_address,
3515 ext_host_port=sessions[0].ext_host_port)
3516 sessions = self.vapi.nat44_user_session_dump(server.ip4n, 0)
3517 self.assertEqual(len(sessions), 0)
3518
3519 @unittest.skipUnless(running_extended_tests(), "part of extended tests")
3520 def test_static_lb_multi_clients(self):
3521 """ NAT44 local service load balancing - multiple clients"""
3522
3523 external_addr_n = socket.inet_pton(socket.AF_INET, self.nat_addr)
3524 external_port = 80
3525 local_port = 8080
3526 server1 = self.pg0.remote_hosts[0]
3527 server2 = self.pg0.remote_hosts[1]
3528
3529 locals = [{'addr': server1.ip4n,
3530 'port': local_port,
3531 'probability': 90},
3532 {'addr': server2.ip4n,
3533 'port': local_port,
3534 'probability': 10}]
3535
3536 self.nat44_add_address(self.nat_addr)
3537 self.vapi.nat44_add_del_lb_static_mapping(external_addr_n,
3538 external_port,
3539 IP_PROTOS.tcp,
3540 local_num=len(locals),
3541 locals=locals)
3542 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3543 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3544 is_inside=0)
3545
3546 server1_n = 0
3547 server2_n = 0
3548 clients = ip4_range(self.pg1.remote_ip4, 10, 50)
3549 pkts = []
3550 for client in clients:
3551 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
3552 IP(src=client, dst=self.nat_addr) /
3553 TCP(sport=12345, dport=external_port))
3554 pkts.append(p)
3555 self.pg1.add_stream(pkts)
3556 self.pg_enable_capture(self.pg_interfaces)
3557 self.pg_start()
3558 capture = self.pg0.get_capture(len(pkts))
3559 for p in capture:
3560 if p[IP].dst == server1.ip4:
3561 server1_n += 1
3562 else:
3563 server2_n += 1
3564 self.assertTrue(server1_n > server2_n)
3565
3566 def test_static_lb_2(self):
3567 """ NAT44 local service load balancing (asymmetrical rule) """
3568 external_addr_n = socket.inet_pton(socket.AF_INET, self.nat_addr)
3569 external_port = 80
3570 local_port = 8080
3571 server1 = self.pg0.remote_hosts[0]
3572 server2 = self.pg0.remote_hosts[1]
3573
3574 locals = [{'addr': server1.ip4n,
3575 'port': local_port,
3576 'probability': 70},
3577 {'addr': server2.ip4n,
3578 'port': local_port,
3579 'probability': 30}]
3580
3581 self.vapi.nat44_forwarding_enable_disable(1)
3582 self.vapi.nat44_add_del_lb_static_mapping(external_addr_n,
3583 external_port,
3584 IP_PROTOS.tcp,
3585 out2in_only=1,
3586 local_num=len(locals),
3587 locals=locals)
3588 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3589 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3590 is_inside=0)
3591
3592 # from client to service
3593 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
3594 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
3595 TCP(sport=12345, dport=external_port))
3596 self.pg1.add_stream(p)
3597 self.pg_enable_capture(self.pg_interfaces)
3598 self.pg_start()
3599 capture = self.pg0.get_capture(1)
3600 p = capture[0]
3601 server = None
3602 try:
3603 ip = p[IP]
3604 tcp = p[TCP]
3605 self.assertIn(ip.dst, [server1.ip4, server2.ip4])
3606 if ip.dst == server1.ip4:
3607 server = server1
3608 else:
3609 server = server2
3610 self.assertEqual(tcp.dport, local_port)
3611 self.assert_packet_checksums_valid(p)
3612 except:
3613 self.logger.error(ppp("Unexpected or invalid packet:", p))
3614 raise
3615
3616 # from service back to client
3617 p = (Ether(src=server.mac, dst=self.pg0.local_mac) /
3618 IP(src=server.ip4, dst=self.pg1.remote_ip4) /
3619 TCP(sport=local_port, dport=12345))
3620 self.pg0.add_stream(p)
3621 self.pg_enable_capture(self.pg_interfaces)
3622 self.pg_start()
3623 capture = self.pg1.get_capture(1)
3624 p = capture[0]
3625 try:
3626 ip = p[IP]
3627 tcp = p[TCP]
3628 self.assertEqual(ip.src, self.nat_addr)
3629 self.assertEqual(tcp.sport, external_port)
3630 self.assert_packet_checksums_valid(p)
3631 except:
3632 self.logger.error(ppp("Unexpected or invalid packet:", p))
3633 raise
3634
3635 # from client to server (no translation)
3636 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
3637 IP(src=self.pg1.remote_ip4, dst=server1.ip4) /
3638 TCP(sport=12346, dport=local_port))
3639 self.pg1.add_stream(p)
3640 self.pg_enable_capture(self.pg_interfaces)
3641 self.pg_start()
3642 capture = self.pg0.get_capture(1)
3643 p = capture[0]
3644 server = None
3645 try:
3646 ip = p[IP]
3647 tcp = p[TCP]
3648 self.assertEqual(ip.dst, server1.ip4)
3649 self.assertEqual(tcp.dport, local_port)
3650 self.assert_packet_checksums_valid(p)
3651 except:
3652 self.logger.error(ppp("Unexpected or invalid packet:", p))
3653 raise
3654
3655 # from service back to client (no translation)
3656 p = (Ether(src=server1.mac, dst=self.pg0.local_mac) /
3657 IP(src=server1.ip4, dst=self.pg1.remote_ip4) /
3658 TCP(sport=local_port, dport=12346))
3659 self.pg0.add_stream(p)
3660 self.pg_enable_capture(self.pg_interfaces)
3661 self.pg_start()
3662 capture = self.pg1.get_capture(1)
3663 p = capture[0]
3664 try:
3665 ip = p[IP]
3666 tcp = p[TCP]
3667 self.assertEqual(ip.src, server1.ip4)
3668 self.assertEqual(tcp.sport, local_port)
3669 self.assert_packet_checksums_valid(p)
3670 except:
3671 self.logger.error(ppp("Unexpected or invalid packet:", p))
3672 raise
3673
3674 def test_unknown_proto(self):
3675 """ NAT44 translate packet with unknown protocol """
3676 self.nat44_add_address(self.nat_addr)
3677 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3678 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3679 is_inside=0)
3680
3681 # in2out
3682 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
3683 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
3684 TCP(sport=self.tcp_port_in, dport=20))
3685 self.pg0.add_stream(p)
3686 self.pg_enable_capture(self.pg_interfaces)
3687 self.pg_start()
3688 p = self.pg1.get_capture(1)
3689
3690 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
3691 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
3692 GRE() /
3693 IP(src=self.pg2.remote_ip4, dst=self.pg2.remote_ip4) /
3694 TCP(sport=1234, dport=1234))
3695 self.pg0.add_stream(p)
3696 self.pg_enable_capture(self.pg_interfaces)
3697 self.pg_start()
3698 p = self.pg1.get_capture(1)
3699 packet = p[0]
3700 try:
3701 self.assertEqual(packet[IP].src, self.nat_addr)
3702 self.assertEqual(packet[IP].dst, self.pg1.remote_ip4)
3703 self.assertTrue(packet.haslayer(GRE))
3704 self.assert_packet_checksums_valid(packet)
3705 except:
3706 self.logger.error(ppp("Unexpected or invalid packet:", packet))
3707 raise
3708
3709 # out2in
3710 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
3711 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
3712 GRE() /
3713 IP(src=self.pg2.remote_ip4, dst=self.pg2.remote_ip4) /
3714 TCP(sport=1234, dport=1234))
3715 self.pg1.add_stream(p)
3716 self.pg_enable_capture(self.pg_interfaces)
3717 self.pg_start()
3718 p = self.pg0.get_capture(1)
3719 packet = p[0]
3720 try:
3721 self.assertEqual(packet[IP].src, self.pg1.remote_ip4)
3722 self.assertEqual(packet[IP].dst, self.pg0.remote_ip4)
3723 self.assertTrue(packet.haslayer(GRE))
3724 self.assert_packet_checksums_valid(packet)
3725 except:
3726 self.logger.error(ppp("Unexpected or invalid packet:", packet))
3727 raise
3728
3729 def test_hairpinning_unknown_proto(self):
3730 """ NAT44 translate packet with unknown protocol - hairpinning """
3731 host = self.pg0.remote_hosts[0]
3732 server = self.pg0.remote_hosts[1]
3733 host_in_port = 1234
3734 server_out_port = 8765
3735 server_nat_ip = "10.0.0.11"
3736
3737 self.nat44_add_address(self.nat_addr)
3738 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3739 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3740 is_inside=0)
3741
3742 # add static mapping for server
3743 self.nat44_add_static_mapping(server.ip4, server_nat_ip)
3744
3745 # host to server
3746 p = (Ether(src=host.mac, dst=self.pg0.local_mac) /
3747 IP(src=host.ip4, dst=server_nat_ip) /
3748 TCP(sport=host_in_port, dport=server_out_port))
3749 self.pg0.add_stream(p)
3750 self.pg_enable_capture(self.pg_interfaces)
3751 self.pg_start()
3752 self.pg0.get_capture(1)
3753
3754 p = (Ether(dst=self.pg0.local_mac, src=host.mac) /
3755 IP(src=host.ip4, dst=server_nat_ip) /
3756 GRE() /
3757 IP(src=self.pg2.remote_ip4, dst=self.pg2.remote_ip4) /
3758 TCP(sport=1234, dport=1234))
3759 self.pg0.add_stream(p)
3760 self.pg_enable_capture(self.pg_interfaces)
3761 self.pg_start()
3762 p = self.pg0.get_capture(1)
3763 packet = p[0]
3764 try:
3765 self.assertEqual(packet[IP].src, self.nat_addr)
3766 self.assertEqual(packet[IP].dst, server.ip4)
3767 self.assertTrue(packet.haslayer(GRE))
3768 self.assert_packet_checksums_valid(packet)
3769 except:
3770 self.logger.error(ppp("Unexpected or invalid packet:", packet))
3771 raise
3772
3773 # server to host
3774 p = (Ether(dst=self.pg0.local_mac, src=server.mac) /
3775 IP(src=server.ip4, dst=self.nat_addr) /
3776 GRE() /
3777 IP(src=self.pg2.remote_ip4, dst=self.pg2.remote_ip4) /
3778 TCP(sport=1234, dport=1234))
3779 self.pg0.add_stream(p)
3780 self.pg_enable_capture(self.pg_interfaces)
3781 self.pg_start()
3782 p = self.pg0.get_capture(1)
3783 packet = p[0]
3784 try:
3785 self.assertEqual(packet[IP].src, server_nat_ip)
3786 self.assertEqual(packet[IP].dst, host.ip4)
3787 self.assertTrue(packet.haslayer(GRE))
3788 self.assert_packet_checksums_valid(packet)
3789 except:
3790 self.logger.error(ppp("Unexpected or invalid packet:", packet))
3791 raise
3792
3793 def test_output_feature_and_service(self):
3794 """ NAT44 interface output feature and services """
3795 external_addr = '1.2.3.4'
3796 external_port = 80
3797 local_port = 8080
3798
3799 self.vapi.nat44_forwarding_enable_disable(1)
3800 self.nat44_add_address(self.nat_addr)
3801 self.vapi.nat44_add_del_identity_mapping(ip=self.pg1.remote_ip4n)
3802 self.nat44_add_static_mapping(self.pg0.remote_ip4, external_addr,
3803 local_port, external_port,
3804 proto=IP_PROTOS.tcp, out2in_only=1)
3805 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3806 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index,
3807 is_inside=0)
3808 self.vapi.nat44_interface_add_del_output_feature(self.pg1.sw_if_index,
3809 is_inside=0)
3810
3811 # from client to service
3812 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
3813 IP(src=self.pg1.remote_ip4, dst=external_addr) /
3814 TCP(sport=12345, dport=external_port))
3815 self.pg1.add_stream(p)
3816 self.pg_enable_capture(self.pg_interfaces)
3817 self.pg_start()
3818 capture = self.pg0.get_capture(1)
3819 p = capture[0]
3820 try:
3821 ip = p[IP]
3822 tcp = p[TCP]
3823 self.assertEqual(ip.dst, self.pg0.remote_ip4)
3824 self.assertEqual(tcp.dport, local_port)
3825 self.assert_packet_checksums_valid(p)
3826 except:
3827 self.logger.error(ppp("Unexpected or invalid packet:", p))
3828 raise
3829
3830 # from service back to client
3831 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
3832 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
3833 TCP(sport=local_port, dport=12345))
3834 self.pg0.add_stream(p)
3835 self.pg_enable_capture(self.pg_interfaces)
3836 self.pg_start()
3837 capture = self.pg1.get_capture(1)
3838 p = capture[0]
3839 try:
3840 ip = p[IP]
3841 tcp = p[TCP]
3842 self.assertEqual(ip.src, external_addr)
3843 self.assertEqual(tcp.sport, external_port)
3844 self.assert_packet_checksums_valid(p)
3845 except:
3846 self.logger.error(ppp("Unexpected or invalid packet:", p))
3847 raise
3848
3849 # from local network host to external network
3850 pkts = self.create_stream_in(self.pg0, self.pg1)
3851 self.pg0.add_stream(pkts)
3852 self.pg_enable_capture(self.pg_interfaces)
3853 self.pg_start()
3854 capture = self.pg1.get_capture(len(pkts))
3855 self.verify_capture_out(capture)
3856 pkts = self.create_stream_in(self.pg0, self.pg1)
3857 self.pg0.add_stream(pkts)
3858 self.pg_enable_capture(self.pg_interfaces)
3859 self.pg_start()
3860 capture = self.pg1.get_capture(len(pkts))
3861 self.verify_capture_out(capture)
3862
3863 # from external network back to local network host
3864 pkts = self.create_stream_out(self.pg1)
3865 self.pg1.add_stream(pkts)
3866 self.pg_enable_capture(self.pg_interfaces)
3867 self.pg_start()
3868 capture = self.pg0.get_capture(len(pkts))
3869 self.verify_capture_in(capture, self.pg0)
3870
3871 def test_output_feature_and_service2(self):
3872 """ NAT44 interface output feature and service host direct access """
3873 self.vapi.nat44_forwarding_enable_disable(1)
3874 self.nat44_add_address(self.nat_addr)
3875 self.vapi.nat44_interface_add_del_output_feature(self.pg1.sw_if_index,
3876 is_inside=0)
3877
3878 # session initiaded from service host - translate
3879 pkts = self.create_stream_in(self.pg0, self.pg1)
3880 self.pg0.add_stream(pkts)
3881 self.pg_enable_capture(self.pg_interfaces)
3882 self.pg_start()
3883 capture = self.pg1.get_capture(len(pkts))
3884 self.verify_capture_out(capture)
3885
3886 pkts = self.create_stream_out(self.pg1)
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 # session initiaded from remote host - do not translate
3894 self.tcp_port_in = 60303
3895 self.udp_port_in = 60304
3896 self.icmp_id_in = 60305
3897 pkts = self.create_stream_out(self.pg1,
3898 self.pg0.remote_ip4,
3899 use_inside_ports=True)
3900 self.pg1.add_stream(pkts)
3901 self.pg_enable_capture(self.pg_interfaces)
3902 self.pg_start()
3903 capture = self.pg0.get_capture(len(pkts))
3904 self.verify_capture_in(capture, self.pg0)
3905
3906 pkts = self.create_stream_in(self.pg0, self.pg1)
3907 self.pg0.add_stream(pkts)
3908 self.pg_enable_capture(self.pg_interfaces)
3909 self.pg_start()
3910 capture = self.pg1.get_capture(len(pkts))
3911 self.verify_capture_out(capture, nat_ip=self.pg0.remote_ip4,
3912 same_port=True)
3913
3914 def test_output_feature_and_service3(self):
3915 """ NAT44 interface output feature and DST NAT """
3916 external_addr = '1.2.3.4'
3917 external_port = 80
3918 local_port = 8080
3919
3920 self.vapi.nat44_forwarding_enable_disable(1)
3921 self.nat44_add_address(self.nat_addr)
3922 self.nat44_add_static_mapping(self.pg1.remote_ip4, external_addr,
3923 local_port, external_port,
3924 proto=IP_PROTOS.tcp, out2in_only=1)
3925 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3926 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index,
3927 is_inside=0)
3928 self.vapi.nat44_interface_add_del_output_feature(self.pg1.sw_if_index,
3929 is_inside=0)
3930
3931 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
3932 IP(src=self.pg0.remote_ip4, dst=external_addr) /
3933 TCP(sport=12345, dport=external_port))
3934 self.pg0.add_stream(p)
3935 self.pg_enable_capture(self.pg_interfaces)
3936 self.pg_start()
3937 capture = self.pg1.get_capture(1)
3938 p = capture[0]
3939 try:
3940 ip = p[IP]
3941 tcp = p[TCP]
3942 self.assertEqual(ip.src, self.pg0.remote_ip4)
3943 self.assertEqual(tcp.sport, 12345)
3944 self.assertEqual(ip.dst, self.pg1.remote_ip4)
3945 self.assertEqual(tcp.dport, local_port)
3946 self.assert_packet_checksums_valid(p)
3947 except:
3948 self.logger.error(ppp("Unexpected or invalid packet:", p))
3949 raise
3950
3951 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
3952 IP(src=self.pg1.remote_ip4, dst=self.pg0.remote_ip4) /
3953 TCP(sport=local_port, dport=12345))
3954 self.pg1.add_stream(p)
3955 self.pg_enable_capture(self.pg_interfaces)
3956 self.pg_start()
3957 capture = self.pg0.get_capture(1)
3958 p = capture[0]
3959 try:
3960 ip = p[IP]
3961 tcp = p[TCP]
3962 self.assertEqual(ip.src, external_addr)
3963 self.assertEqual(tcp.sport, external_port)
3964 self.assertEqual(ip.dst, self.pg0.remote_ip4)
3965 self.assertEqual(tcp.dport, 12345)
3966 self.assert_packet_checksums_valid(p)
3967 except:
3968 self.logger.error(ppp("Unexpected or invalid packet:", p))
3969 raise
3970
Juraj Sloboda1e5c07d2018-04-10 13:51:54 +02003971 def twice_nat_common(self, self_twice_nat=False, same_pg=False, lb=False,
3972 client_id=None):
Matus Fabianb932d262017-12-18 05:38:24 -08003973 twice_nat_addr = '10.0.1.3'
Juraj Sloboda1e5c07d2018-04-10 13:51:54 +02003974
Matus Fabianb932d262017-12-18 05:38:24 -08003975 port_in = 8080
Juraj Sloboda1e5c07d2018-04-10 13:51:54 +02003976 if lb:
3977 if not same_pg:
3978 port_in1 = port_in
3979 port_in2 = port_in
3980 else:
3981 port_in1 = port_in+1
3982 port_in2 = port_in+2
3983
Matus Fabianb932d262017-12-18 05:38:24 -08003984 port_out = 80
3985 eh_port_out = 4567
Juraj Sloboda1e5c07d2018-04-10 13:51:54 +02003986
3987 server1 = self.pg0.remote_hosts[0]
3988 server2 = self.pg0.remote_hosts[1]
3989 if lb and same_pg:
3990 server2 = server1
3991 if not lb:
3992 server = server1
3993
3994 pg0 = self.pg0
3995 if same_pg:
3996 pg1 = self.pg0
3997 else:
3998 pg1 = self.pg1
3999
4000 eh_translate = ((not self_twice_nat) or (not lb and same_pg) or
4001 client_id == 1)
4002
Matus Fabianb932d262017-12-18 05:38:24 -08004003 self.nat44_add_address(self.nat_addr)
4004 self.nat44_add_address(twice_nat_addr, twice_nat=1)
Juraj Sloboda1e5c07d2018-04-10 13:51:54 +02004005 if not lb:
4006 self.nat44_add_static_mapping(pg0.remote_ip4, self.nat_addr,
4007 port_in, port_out,
4008 proto=IP_PROTOS.tcp,
4009 twice_nat=int(not self_twice_nat),
4010 self_twice_nat=int(self_twice_nat))
4011 else:
4012 locals = [{'addr': server1.ip4n,
4013 'port': port_in1,
4014 'probability': 50},
4015 {'addr': server2.ip4n,
4016 'port': port_in2,
4017 'probability': 50}]
4018 out_addr_n = socket.inet_pton(socket.AF_INET, self.nat_addr)
4019 self.vapi.nat44_add_del_lb_static_mapping(out_addr_n,
4020 port_out,
4021 IP_PROTOS.tcp,
4022 twice_nat=int(
4023 not self_twice_nat),
4024 self_twice_nat=int(
4025 self_twice_nat),
4026 local_num=len(locals),
4027 locals=locals)
4028 self.vapi.nat44_interface_add_del_feature(pg0.sw_if_index)
4029 self.vapi.nat44_interface_add_del_feature(pg1.sw_if_index,
Matus Fabianb932d262017-12-18 05:38:24 -08004030 is_inside=0)
4031
Juraj Sloboda1e5c07d2018-04-10 13:51:54 +02004032 if same_pg:
4033 if not lb:
4034 client = server
4035 else:
4036 assert client_id is not None
4037 if client_id == 1:
4038 client = self.pg0.remote_hosts[0]
4039 elif client_id == 2:
4040 client = self.pg0.remote_hosts[1]
4041 else:
4042 client = pg1.remote_hosts[0]
4043 p = (Ether(src=pg1.remote_mac, dst=pg1.local_mac) /
4044 IP(src=client.ip4, dst=self.nat_addr) /
Matus Fabianb932d262017-12-18 05:38:24 -08004045 TCP(sport=eh_port_out, dport=port_out))
Juraj Sloboda1e5c07d2018-04-10 13:51:54 +02004046 pg1.add_stream(p)
Matus Fabianb932d262017-12-18 05:38:24 -08004047 self.pg_enable_capture(self.pg_interfaces)
4048 self.pg_start()
Juraj Sloboda1e5c07d2018-04-10 13:51:54 +02004049 capture = pg0.get_capture(1)
Matus Fabianb932d262017-12-18 05:38:24 -08004050 p = capture[0]
4051 try:
4052 ip = p[IP]
4053 tcp = p[TCP]
Juraj Sloboda1e5c07d2018-04-10 13:51:54 +02004054 if lb:
4055 if ip.dst == server1.ip4:
4056 server = server1
4057 port_in = port_in1
4058 else:
4059 server = server2
4060 port_in = port_in2
4061 self.assertEqual(ip.dst, server.ip4)
4062 if lb and same_pg:
4063 self.assertIn(tcp.dport, [port_in1, port_in2])
4064 else:
4065 self.assertEqual(tcp.dport, port_in)
4066 if eh_translate:
4067 self.assertEqual(ip.src, twice_nat_addr)
4068 self.assertNotEqual(tcp.sport, eh_port_out)
4069 else:
4070 self.assertEqual(ip.src, client.ip4)
4071 self.assertEqual(tcp.sport, eh_port_out)
4072 eh_addr_in = ip.src
Matus Fabianb932d262017-12-18 05:38:24 -08004073 eh_port_in = tcp.sport
Juraj Sloboda1e5c07d2018-04-10 13:51:54 +02004074 saved_port_in = tcp.dport
Klement Sekerad81ae412018-05-16 10:52:54 +02004075 self.assert_packet_checksums_valid(p)
Matus Fabianb932d262017-12-18 05:38:24 -08004076 except:
4077 self.logger.error(ppp("Unexpected or invalid packet:", p))
4078 raise
4079
Juraj Sloboda1e5c07d2018-04-10 13:51:54 +02004080 p = (Ether(src=server.mac, dst=pg0.local_mac) /
4081 IP(src=server.ip4, dst=eh_addr_in) /
4082 TCP(sport=saved_port_in, dport=eh_port_in))
4083 pg0.add_stream(p)
Matus Fabianb932d262017-12-18 05:38:24 -08004084 self.pg_enable_capture(self.pg_interfaces)
4085 self.pg_start()
Juraj Sloboda1e5c07d2018-04-10 13:51:54 +02004086 capture = pg1.get_capture(1)
Matus Fabianb932d262017-12-18 05:38:24 -08004087 p = capture[0]
4088 try:
4089 ip = p[IP]
4090 tcp = p[TCP]
Juraj Sloboda1e5c07d2018-04-10 13:51:54 +02004091 self.assertEqual(ip.dst, client.ip4)
Matus Fabianb932d262017-12-18 05:38:24 -08004092 self.assertEqual(ip.src, self.nat_addr)
4093 self.assertEqual(tcp.dport, eh_port_out)
4094 self.assertEqual(tcp.sport, port_out)
Klement Sekerad81ae412018-05-16 10:52:54 +02004095 self.assert_packet_checksums_valid(p)
Matus Fabianb932d262017-12-18 05:38:24 -08004096 except:
4097 self.logger.error(ppp("Unexpected or invalid packet:", p))
4098 raise
4099
Matus Fabian70a26ac2018-05-14 06:20:28 -07004100 if eh_translate:
4101 sessions = self.vapi.nat44_user_session_dump(server.ip4n, 0)
4102 self.assertEqual(len(sessions), 1)
4103 self.assertTrue(sessions[0].ext_host_valid)
4104 self.assertTrue(sessions[0].is_twicenat)
4105 self.vapi.nat44_del_session(
4106 sessions[0].inside_ip_address,
4107 sessions[0].inside_port,
4108 sessions[0].protocol,
4109 ext_host_address=sessions[0].ext_host_nat_address,
4110 ext_host_port=sessions[0].ext_host_nat_port)
4111 sessions = self.vapi.nat44_user_session_dump(server.ip4n, 0)
4112 self.assertEqual(len(sessions), 0)
4113
Juraj Sloboda1e5c07d2018-04-10 13:51:54 +02004114 def test_twice_nat(self):
4115 """ Twice NAT44 """
4116 self.twice_nat_common()
4117
4118 def test_self_twice_nat_positive(self):
4119 """ Self Twice NAT44 (positive test) """
4120 self.twice_nat_common(self_twice_nat=True, same_pg=True)
4121
4122 def test_self_twice_nat_negative(self):
4123 """ Self Twice NAT44 (negative test) """
4124 self.twice_nat_common(self_twice_nat=True)
4125
Matus Fabianb932d262017-12-18 05:38:24 -08004126 def test_twice_nat_lb(self):
4127 """ Twice NAT44 local service load balancing """
Juraj Sloboda1e5c07d2018-04-10 13:51:54 +02004128 self.twice_nat_common(lb=True)
Matus Fabianb932d262017-12-18 05:38:24 -08004129
Juraj Sloboda1e5c07d2018-04-10 13:51:54 +02004130 def test_self_twice_nat_lb_positive(self):
4131 """ Self Twice NAT44 local service load balancing (positive test) """
4132 self.twice_nat_common(lb=True, self_twice_nat=True, same_pg=True,
4133 client_id=1)
Matus Fabianb932d262017-12-18 05:38:24 -08004134
Juraj Sloboda1e5c07d2018-04-10 13:51:54 +02004135 def test_self_twice_nat_lb_negative(self):
4136 """ Self Twice NAT44 local service load balancing (negative test) """
4137 self.twice_nat_common(lb=True, self_twice_nat=True, same_pg=True,
4138 client_id=2)
Matus Fabianb932d262017-12-18 05:38:24 -08004139
4140 def test_twice_nat_interface_addr(self):
4141 """ Acquire twice NAT44 addresses from interface """
Matus Fabiana6110b62018-06-13 05:39:07 -07004142 self.vapi.nat44_add_interface_addr(self.pg3.sw_if_index, twice_nat=1)
Matus Fabianb932d262017-12-18 05:38:24 -08004143
4144 # no address in NAT pool
4145 adresses = self.vapi.nat44_address_dump()
4146 self.assertEqual(0, len(adresses))
4147
4148 # configure interface address and check NAT address pool
Matus Fabiana6110b62018-06-13 05:39:07 -07004149 self.pg3.config_ip4()
Matus Fabianb932d262017-12-18 05:38:24 -08004150 adresses = self.vapi.nat44_address_dump()
4151 self.assertEqual(1, len(adresses))
Matus Fabiana6110b62018-06-13 05:39:07 -07004152 self.assertEqual(adresses[0].ip_address[0:4], self.pg3.local_ip4n)
Matus Fabianb932d262017-12-18 05:38:24 -08004153 self.assertEqual(adresses[0].twice_nat, 1)
4154
4155 # remove interface address and check NAT address pool
Matus Fabiana6110b62018-06-13 05:39:07 -07004156 self.pg3.unconfig_ip4()
Matus Fabianb932d262017-12-18 05:38:24 -08004157 adresses = self.vapi.nat44_address_dump()
4158 self.assertEqual(0, len(adresses))
4159
Matus Fabianebdf1902018-05-04 03:57:42 -07004160 def test_tcp_session_close_in(self):
4161 """ Close TCP session from inside network """
Matus Fabian229c1aa2018-05-28 04:09:52 -07004162 self.tcp_port_out = 10505
Matus Fabianebdf1902018-05-04 03:57:42 -07004163 self.nat44_add_address(self.nat_addr)
Matus Fabian229c1aa2018-05-28 04:09:52 -07004164 self.nat44_add_static_mapping(self.pg0.remote_ip4,
4165 self.nat_addr,
4166 self.tcp_port_in,
4167 self.tcp_port_out,
4168 proto=IP_PROTOS.tcp,
4169 twice_nat=1)
Matus Fabianebdf1902018-05-04 03:57:42 -07004170 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
4171 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
4172 is_inside=0)
4173
4174 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n, 0)
4175 start_sessnum = len(sessions)
4176
4177 self.initiate_tcp_session(self.pg0, self.pg1)
4178
Matus Fabian229c1aa2018-05-28 04:09:52 -07004179 # FIN packet in -> out
4180 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
4181 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
4182 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
4183 flags="FA", seq=100, ack=300))
4184 self.pg0.add_stream(p)
4185 self.pg_enable_capture(self.pg_interfaces)
4186 self.pg_start()
4187 self.pg1.get_capture(1)
Matus Fabianebdf1902018-05-04 03:57:42 -07004188
Matus Fabian229c1aa2018-05-28 04:09:52 -07004189 pkts = []
Matus Fabianebdf1902018-05-04 03:57:42 -07004190
Matus Fabian229c1aa2018-05-28 04:09:52 -07004191 # ACK packet out -> in
4192 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
4193 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
4194 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
4195 flags="A", seq=300, ack=101))
4196 pkts.append(p)
Matus Fabianebdf1902018-05-04 03:57:42 -07004197
Matus Fabian229c1aa2018-05-28 04:09:52 -07004198 # FIN packet out -> in
4199 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
4200 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
4201 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
4202 flags="FA", seq=300, ack=101))
4203 pkts.append(p)
Matus Fabianebdf1902018-05-04 03:57:42 -07004204
Matus Fabian229c1aa2018-05-28 04:09:52 -07004205 self.pg1.add_stream(pkts)
4206 self.pg_enable_capture(self.pg_interfaces)
4207 self.pg_start()
4208 self.pg0.get_capture(2)
Matus Fabianebdf1902018-05-04 03:57:42 -07004209
Matus Fabian229c1aa2018-05-28 04:09:52 -07004210 # ACK packet in -> out
4211 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
4212 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
4213 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
4214 flags="A", seq=101, ack=301))
4215 self.pg0.add_stream(p)
4216 self.pg_enable_capture(self.pg_interfaces)
4217 self.pg_start()
4218 self.pg1.get_capture(1)
Matus Fabianebdf1902018-05-04 03:57:42 -07004219
Matus Fabian229c1aa2018-05-28 04:09:52 -07004220 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n,
4221 0)
4222 self.assertEqual(len(sessions) - start_sessnum, 0)
Matus Fabianebdf1902018-05-04 03:57:42 -07004223
4224 def test_tcp_session_close_out(self):
4225 """ Close TCP session from outside network """
Matus Fabian229c1aa2018-05-28 04:09:52 -07004226 self.tcp_port_out = 10505
Matus Fabianebdf1902018-05-04 03:57:42 -07004227 self.nat44_add_address(self.nat_addr)
Matus Fabian229c1aa2018-05-28 04:09:52 -07004228 self.nat44_add_static_mapping(self.pg0.remote_ip4,
4229 self.nat_addr,
4230 self.tcp_port_in,
4231 self.tcp_port_out,
4232 proto=IP_PROTOS.tcp,
4233 twice_nat=1)
Matus Fabianebdf1902018-05-04 03:57:42 -07004234 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
4235 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
4236 is_inside=0)
4237
4238 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n, 0)
4239 start_sessnum = len(sessions)
4240
4241 self.initiate_tcp_session(self.pg0, self.pg1)
4242
Matus Fabian229c1aa2018-05-28 04:09:52 -07004243 # FIN packet out -> in
4244 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
4245 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
4246 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
4247 flags="FA", seq=100, ack=300))
4248 self.pg1.add_stream(p)
4249 self.pg_enable_capture(self.pg_interfaces)
4250 self.pg_start()
4251 self.pg0.get_capture(1)
Matus Fabianebdf1902018-05-04 03:57:42 -07004252
Matus Fabian229c1aa2018-05-28 04:09:52 -07004253 # FIN+ACK packet in -> out
4254 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
4255 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
4256 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
4257 flags="FA", seq=300, ack=101))
Matus Fabianebdf1902018-05-04 03:57:42 -07004258
Matus Fabian229c1aa2018-05-28 04:09:52 -07004259 self.pg0.add_stream(p)
4260 self.pg_enable_capture(self.pg_interfaces)
4261 self.pg_start()
4262 self.pg1.get_capture(1)
Matus Fabianebdf1902018-05-04 03:57:42 -07004263
Matus Fabian229c1aa2018-05-28 04:09:52 -07004264 # ACK packet out -> in
4265 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
4266 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
4267 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
4268 flags="A", seq=101, ack=301))
4269 self.pg1.add_stream(p)
4270 self.pg_enable_capture(self.pg_interfaces)
4271 self.pg_start()
4272 self.pg0.get_capture(1)
Matus Fabianebdf1902018-05-04 03:57:42 -07004273
Matus Fabian229c1aa2018-05-28 04:09:52 -07004274 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n,
4275 0)
4276 self.assertEqual(len(sessions) - start_sessnum, 0)
Matus Fabianebdf1902018-05-04 03:57:42 -07004277
4278 def test_tcp_session_close_simultaneous(self):
4279 """ Close TCP session from inside network """
Matus Fabian229c1aa2018-05-28 04:09:52 -07004280 self.tcp_port_out = 10505
Matus Fabianebdf1902018-05-04 03:57:42 -07004281 self.nat44_add_address(self.nat_addr)
Matus Fabian229c1aa2018-05-28 04:09:52 -07004282 self.nat44_add_static_mapping(self.pg0.remote_ip4,
4283 self.nat_addr,
4284 self.tcp_port_in,
4285 self.tcp_port_out,
4286 proto=IP_PROTOS.tcp,
4287 twice_nat=1)
Matus Fabianebdf1902018-05-04 03:57:42 -07004288 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
4289 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
4290 is_inside=0)
4291
4292 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n, 0)
4293 start_sessnum = len(sessions)
4294
4295 self.initiate_tcp_session(self.pg0, self.pg1)
4296
Matus Fabian229c1aa2018-05-28 04:09:52 -07004297 # FIN packet in -> out
4298 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
4299 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
4300 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
4301 flags="FA", seq=100, ack=300))
4302 self.pg0.add_stream(p)
4303 self.pg_enable_capture(self.pg_interfaces)
4304 self.pg_start()
4305 self.pg1.get_capture(1)
Matus Fabianebdf1902018-05-04 03:57:42 -07004306
Matus Fabian229c1aa2018-05-28 04:09:52 -07004307 # FIN packet out -> in
4308 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
4309 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
4310 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
4311 flags="FA", seq=300, ack=100))
4312 self.pg1.add_stream(p)
4313 self.pg_enable_capture(self.pg_interfaces)
4314 self.pg_start()
4315 self.pg0.get_capture(1)
Matus Fabianebdf1902018-05-04 03:57:42 -07004316
Matus Fabian229c1aa2018-05-28 04:09:52 -07004317 # ACK packet in -> out
4318 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
4319 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
4320 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
4321 flags="A", seq=101, ack=301))
4322 self.pg0.add_stream(p)
4323 self.pg_enable_capture(self.pg_interfaces)
4324 self.pg_start()
4325 self.pg1.get_capture(1)
Matus Fabianebdf1902018-05-04 03:57:42 -07004326
Matus Fabian229c1aa2018-05-28 04:09:52 -07004327 # ACK packet out -> in
4328 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
4329 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
4330 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
4331 flags="A", seq=301, ack=101))
4332 self.pg1.add_stream(p)
4333 self.pg_enable_capture(self.pg_interfaces)
4334 self.pg_start()
4335 self.pg0.get_capture(1)
Matus Fabianebdf1902018-05-04 03:57:42 -07004336
Matus Fabian229c1aa2018-05-28 04:09:52 -07004337 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n,
4338 0)
4339 self.assertEqual(len(sessions) - start_sessnum, 0)
Matus Fabianebdf1902018-05-04 03:57:42 -07004340
Matus Fabiana6110b62018-06-13 05:39:07 -07004341 def test_one_armed_nat44_static(self):
4342 """ One armed NAT44 and 1:1 NAPT asymmetrical rule """
4343 remote_host = self.pg4.remote_hosts[0]
4344 local_host = self.pg4.remote_hosts[1]
4345 external_port = 80
4346 local_port = 8080
4347 eh_port_in = 0
4348
4349 self.vapi.nat44_forwarding_enable_disable(1)
4350 self.nat44_add_address(self.nat_addr, twice_nat=1)
4351 self.nat44_add_static_mapping(local_host.ip4, self.nat_addr,
4352 local_port, external_port,
4353 proto=IP_PROTOS.tcp, out2in_only=1,
4354 twice_nat=1)
4355 self.vapi.nat44_interface_add_del_feature(self.pg4.sw_if_index)
4356 self.vapi.nat44_interface_add_del_feature(self.pg4.sw_if_index,
4357 is_inside=0)
4358
4359 # from client to service
4360 p = (Ether(src=self.pg4.remote_mac, dst=self.pg4.local_mac) /
4361 IP(src=remote_host.ip4, dst=self.nat_addr) /
4362 TCP(sport=12345, dport=external_port))
4363 self.pg4.add_stream(p)
4364 self.pg_enable_capture(self.pg_interfaces)
4365 self.pg_start()
4366 capture = self.pg4.get_capture(1)
4367 p = capture[0]
4368 try:
4369 ip = p[IP]
4370 tcp = p[TCP]
4371 self.assertEqual(ip.dst, local_host.ip4)
4372 self.assertEqual(ip.src, self.nat_addr)
4373 self.assertEqual(tcp.dport, local_port)
4374 self.assertNotEqual(tcp.sport, 12345)
4375 eh_port_in = tcp.sport
4376 self.assert_packet_checksums_valid(p)
4377 except:
4378 self.logger.error(ppp("Unexpected or invalid packet:", p))
4379 raise
4380
4381 # from service back to client
4382 p = (Ether(src=self.pg4.remote_mac, dst=self.pg4.local_mac) /
4383 IP(src=local_host.ip4, dst=self.nat_addr) /
4384 TCP(sport=local_port, dport=eh_port_in))
4385 self.pg4.add_stream(p)
4386 self.pg_enable_capture(self.pg_interfaces)
4387 self.pg_start()
4388 capture = self.pg4.get_capture(1)
4389 p = capture[0]
4390 try:
4391 ip = p[IP]
4392 tcp = p[TCP]
4393 self.assertEqual(ip.src, self.nat_addr)
4394 self.assertEqual(ip.dst, remote_host.ip4)
4395 self.assertEqual(tcp.sport, external_port)
4396 self.assertEqual(tcp.dport, 12345)
4397 self.assert_packet_checksums_valid(p)
4398 except:
4399 self.logger.error(ppp("Unexpected or invalid packet:", p))
4400 raise
4401
4402 def test_static_with_port_out2(self):
4403 """ 1:1 NAPT asymmetrical rule """
4404
4405 external_port = 80
4406 local_port = 8080
4407
4408 self.vapi.nat44_forwarding_enable_disable(1)
4409 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
4410 local_port, external_port,
4411 proto=IP_PROTOS.tcp, out2in_only=1)
4412 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
4413 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
4414 is_inside=0)
4415
4416 # from client to service
4417 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
4418 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
4419 TCP(sport=12345, dport=external_port))
4420 self.pg1.add_stream(p)
4421 self.pg_enable_capture(self.pg_interfaces)
4422 self.pg_start()
4423 capture = self.pg0.get_capture(1)
4424 p = capture[0]
4425 try:
4426 ip = p[IP]
4427 tcp = p[TCP]
4428 self.assertEqual(ip.dst, self.pg0.remote_ip4)
4429 self.assertEqual(tcp.dport, local_port)
4430 self.assert_packet_checksums_valid(p)
4431 except:
4432 self.logger.error(ppp("Unexpected or invalid packet:", p))
4433 raise
4434
4435 # ICMP error
4436 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
4437 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
4438 ICMP(type=11) / capture[0][IP])
4439 self.pg0.add_stream(p)
4440 self.pg_enable_capture(self.pg_interfaces)
4441 self.pg_start()
4442 capture = self.pg1.get_capture(1)
4443 p = capture[0]
4444 try:
4445 self.assertEqual(p[IP].src, self.nat_addr)
4446 inner = p[IPerror]
4447 self.assertEqual(inner.dst, self.nat_addr)
4448 self.assertEqual(inner[TCPerror].dport, external_port)
4449 except:
4450 self.logger.error(ppp("Unexpected or invalid packet:", p))
4451 raise
4452
4453 # from service back to client
4454 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
4455 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
4456 TCP(sport=local_port, dport=12345))
4457 self.pg0.add_stream(p)
4458 self.pg_enable_capture(self.pg_interfaces)
4459 self.pg_start()
4460 capture = self.pg1.get_capture(1)
4461 p = capture[0]
4462 try:
4463 ip = p[IP]
4464 tcp = p[TCP]
4465 self.assertEqual(ip.src, self.nat_addr)
4466 self.assertEqual(tcp.sport, external_port)
4467 self.assert_packet_checksums_valid(p)
4468 except:
4469 self.logger.error(ppp("Unexpected or invalid packet:", p))
4470 raise
4471
4472 # ICMP error
4473 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
4474 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
4475 ICMP(type=11) / capture[0][IP])
4476 self.pg1.add_stream(p)
4477 self.pg_enable_capture(self.pg_interfaces)
4478 self.pg_start()
4479 capture = self.pg0.get_capture(1)
4480 p = capture[0]
4481 try:
4482 self.assertEqual(p[IP].dst, self.pg0.remote_ip4)
4483 inner = p[IPerror]
4484 self.assertEqual(inner.src, self.pg0.remote_ip4)
4485 self.assertEqual(inner[TCPerror].sport, local_port)
4486 except:
4487 self.logger.error(ppp("Unexpected or invalid packet:", p))
4488 raise
4489
4490 # from client to server (no translation)
4491 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
4492 IP(src=self.pg1.remote_ip4, dst=self.pg0.remote_ip4) /
4493 TCP(sport=12346, dport=local_port))
4494 self.pg1.add_stream(p)
4495 self.pg_enable_capture(self.pg_interfaces)
4496 self.pg_start()
4497 capture = self.pg0.get_capture(1)
4498 p = capture[0]
4499 try:
4500 ip = p[IP]
4501 tcp = p[TCP]
4502 self.assertEqual(ip.dst, self.pg0.remote_ip4)
4503 self.assertEqual(tcp.dport, local_port)
4504 self.assert_packet_checksums_valid(p)
4505 except:
4506 self.logger.error(ppp("Unexpected or invalid packet:", p))
4507 raise
4508
4509 # from service back to client (no translation)
4510 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
4511 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
4512 TCP(sport=local_port, dport=12346))
4513 self.pg0.add_stream(p)
4514 self.pg_enable_capture(self.pg_interfaces)
4515 self.pg_start()
4516 capture = self.pg1.get_capture(1)
4517 p = capture[0]
4518 try:
4519 ip = p[IP]
4520 tcp = p[TCP]
4521 self.assertEqual(ip.src, self.pg0.remote_ip4)
4522 self.assertEqual(tcp.sport, local_port)
4523 self.assert_packet_checksums_valid(p)
4524 except:
4525 self.logger.error(ppp("Unexpected or invalid packet:", p))
4526 raise
4527
Matus Fabian235a47e2018-06-25 16:42:36 -07004528 def test_output_feature(self):
4529 """ NAT44 interface output feature (in2out postrouting) """
4530 self.vapi.nat44_forwarding_enable_disable(1)
4531 self.nat44_add_address(self.nat_addr)
4532 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index,
4533 is_inside=0)
4534 self.vapi.nat44_interface_add_del_output_feature(self.pg1.sw_if_index,
4535 is_inside=0)
4536
4537 # in2out
4538 pkts = self.create_stream_in(self.pg0, self.pg1)
4539 self.pg0.add_stream(pkts)
4540 self.pg_enable_capture(self.pg_interfaces)
4541 self.pg_start()
4542 capture = self.pg1.get_capture(len(pkts))
4543 self.verify_capture_out(capture)
4544
4545 # out2in
4546 pkts = self.create_stream_out(self.pg1)
4547 self.pg1.add_stream(pkts)
4548 self.pg_enable_capture(self.pg_interfaces)
4549 self.pg_start()
4550 capture = self.pg0.get_capture(len(pkts))
4551 self.verify_capture_in(capture, self.pg0)
4552
Matus Fabian8008d7c2018-07-09 01:34:20 -07004553 def test_multiple_vrf(self):
4554 """ Multiple VRF setup """
4555 external_addr = '1.2.3.4'
4556 external_port = 80
4557 local_port = 8080
4558 port = 0
4559
4560 self.vapi.nat44_forwarding_enable_disable(1)
4561 self.nat44_add_address(self.nat_addr)
4562 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
4563 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index,
4564 is_inside=0)
4565 self.vapi.nat44_interface_add_del_output_feature(self.pg1.sw_if_index,
4566 is_inside=0)
4567 self.vapi.nat44_interface_add_del_feature(self.pg5.sw_if_index)
4568 self.vapi.nat44_interface_add_del_feature(self.pg5.sw_if_index,
4569 is_inside=0)
4570 self.vapi.nat44_interface_add_del_feature(self.pg6.sw_if_index,
4571 is_inside=0)
4572 self.nat44_add_static_mapping(self.pg5.remote_ip4, external_addr,
4573 local_port, external_port, vrf_id=1,
4574 proto=IP_PROTOS.tcp, out2in_only=1)
4575 self.nat44_add_static_mapping(
4576 self.pg0.remote_ip4, external_sw_if_index=self.pg0.sw_if_index,
4577 local_port=local_port, vrf_id=0, external_port=external_port,
4578 proto=IP_PROTOS.tcp, out2in_only=1)
4579
4580 # from client to service (both VRF1)
4581 p = (Ether(src=self.pg6.remote_mac, dst=self.pg6.local_mac) /
4582 IP(src=self.pg6.remote_ip4, dst=external_addr) /
4583 TCP(sport=12345, dport=external_port))
4584 self.pg6.add_stream(p)
4585 self.pg_enable_capture(self.pg_interfaces)
4586 self.pg_start()
4587 capture = self.pg5.get_capture(1)
4588 p = capture[0]
4589 try:
4590 ip = p[IP]
4591 tcp = p[TCP]
4592 self.assertEqual(ip.dst, self.pg5.remote_ip4)
4593 self.assertEqual(tcp.dport, local_port)
4594 self.assert_packet_checksums_valid(p)
4595 except:
4596 self.logger.error(ppp("Unexpected or invalid packet:", p))
4597 raise
4598
4599 # from service back to client (both VRF1)
4600 p = (Ether(src=self.pg5.remote_mac, dst=self.pg5.local_mac) /
4601 IP(src=self.pg5.remote_ip4, dst=self.pg6.remote_ip4) /
4602 TCP(sport=local_port, dport=12345))
4603 self.pg5.add_stream(p)
4604 self.pg_enable_capture(self.pg_interfaces)
4605 self.pg_start()
4606 capture = self.pg6.get_capture(1)
4607 p = capture[0]
4608 try:
4609 ip = p[IP]
4610 tcp = p[TCP]
4611 self.assertEqual(ip.src, external_addr)
4612 self.assertEqual(tcp.sport, external_port)
4613 self.assert_packet_checksums_valid(p)
4614 except:
4615 self.logger.error(ppp("Unexpected or invalid packet:", p))
4616 raise
4617
4618 # dynamic NAT from VRF1 to VRF0 (output-feature)
4619 p = (Ether(src=self.pg5.remote_mac, dst=self.pg5.local_mac) /
4620 IP(src=self.pg5.remote_ip4, dst=self.pg1.remote_ip4) /
4621 TCP(sport=2345, dport=22))
4622 self.pg5.add_stream(p)
4623 self.pg_enable_capture(self.pg_interfaces)
4624 self.pg_start()
4625 capture = self.pg1.get_capture(1)
4626 p = capture[0]
4627 try:
4628 ip = p[IP]
4629 tcp = p[TCP]
4630 self.assertEqual(ip.src, self.nat_addr)
4631 self.assertNotEqual(tcp.sport, 2345)
4632 self.assert_packet_checksums_valid(p)
4633 port = tcp.sport
4634 except:
4635 self.logger.error(ppp("Unexpected or invalid packet:", p))
4636 raise
4637
4638 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
4639 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
4640 TCP(sport=22, dport=port))
4641 self.pg1.add_stream(p)
4642 self.pg_enable_capture(self.pg_interfaces)
4643 self.pg_start()
4644 capture = self.pg5.get_capture(1)
4645 p = capture[0]
4646 try:
4647 ip = p[IP]
4648 tcp = p[TCP]
4649 self.assertEqual(ip.dst, self.pg5.remote_ip4)
4650 self.assertEqual(tcp.dport, 2345)
4651 self.assert_packet_checksums_valid(p)
4652 except:
4653 self.logger.error(ppp("Unexpected or invalid packet:", p))
4654 raise
4655
4656 # from client VRF1 to service VRF0
4657 p = (Ether(src=self.pg6.remote_mac, dst=self.pg6.local_mac) /
4658 IP(src=self.pg6.remote_ip4, dst=self.pg0.local_ip4) /
4659 TCP(sport=12346, dport=external_port))
4660 self.pg6.add_stream(p)
4661 self.pg_enable_capture(self.pg_interfaces)
4662 self.pg_start()
4663 capture = self.pg0.get_capture(1)
4664 p = capture[0]
4665 try:
4666 ip = p[IP]
4667 tcp = p[TCP]
4668 self.assertEqual(ip.dst, self.pg0.remote_ip4)
4669 self.assertEqual(tcp.dport, local_port)
4670 self.assert_packet_checksums_valid(p)
4671 except:
4672 self.logger.error(ppp("Unexpected or invalid packet:", p))
4673 raise
4674
4675 # from service VRF0 back to client VRF1
4676 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
4677 IP(src=self.pg0.remote_ip4, dst=self.pg6.remote_ip4) /
4678 TCP(sport=local_port, dport=12346))
4679 self.pg0.add_stream(p)
4680 self.pg_enable_capture(self.pg_interfaces)
4681 self.pg_start()
4682 capture = self.pg6.get_capture(1)
4683 p = capture[0]
4684 try:
4685 ip = p[IP]
4686 tcp = p[TCP]
4687 self.assertEqual(ip.src, self.pg0.local_ip4)
4688 self.assertEqual(tcp.sport, external_port)
4689 self.assert_packet_checksums_valid(p)
4690 except:
4691 self.logger.error(ppp("Unexpected or invalid packet:", p))
4692 raise
4693
4694 # from client VRF0 to service VRF1
4695 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
4696 IP(src=self.pg0.remote_ip4, dst=external_addr) /
4697 TCP(sport=12347, dport=external_port))
4698 self.pg0.add_stream(p)
4699 self.pg_enable_capture(self.pg_interfaces)
4700 self.pg_start()
4701 capture = self.pg5.get_capture(1)
4702 p = capture[0]
4703 try:
4704 ip = p[IP]
4705 tcp = p[TCP]
4706 self.assertEqual(ip.dst, self.pg5.remote_ip4)
4707 self.assertEqual(tcp.dport, local_port)
4708 self.assert_packet_checksums_valid(p)
4709 except:
4710 self.logger.error(ppp("Unexpected or invalid packet:", p))
4711 raise
4712
4713 # from service VRF1 back to client VRF0
4714 p = (Ether(src=self.pg5.remote_mac, dst=self.pg5.local_mac) /
4715 IP(src=self.pg5.remote_ip4, dst=self.pg0.remote_ip4) /
4716 TCP(sport=local_port, dport=12347))
4717 self.pg5.add_stream(p)
4718 self.pg_enable_capture(self.pg_interfaces)
4719 self.pg_start()
4720 capture = self.pg0.get_capture(1)
4721 p = capture[0]
4722 try:
4723 ip = p[IP]
4724 tcp = p[TCP]
4725 self.assertEqual(ip.src, external_addr)
4726 self.assertEqual(tcp.sport, external_port)
4727 self.assert_packet_checksums_valid(p)
4728 except:
4729 self.logger.error(ppp("Unexpected or invalid packet:", p))
4730 raise
4731
4732 # from client to server (both VRF1, no translation)
4733 p = (Ether(src=self.pg6.remote_mac, dst=self.pg6.local_mac) /
4734 IP(src=self.pg6.remote_ip4, dst=self.pg5.remote_ip4) /
4735 TCP(sport=12348, dport=local_port))
4736 self.pg6.add_stream(p)
4737 self.pg_enable_capture(self.pg_interfaces)
4738 self.pg_start()
4739 capture = self.pg5.get_capture(1)
4740 p = capture[0]
4741 try:
4742 ip = p[IP]
4743 tcp = p[TCP]
4744 self.assertEqual(ip.dst, self.pg5.remote_ip4)
4745 self.assertEqual(tcp.dport, local_port)
4746 self.assert_packet_checksums_valid(p)
4747 except:
4748 self.logger.error(ppp("Unexpected or invalid packet:", p))
4749 raise
4750
4751 # from server back to client (both VRF1, no translation)
4752 p = (Ether(src=self.pg5.remote_mac, dst=self.pg5.local_mac) /
4753 IP(src=self.pg5.remote_ip4, dst=self.pg6.remote_ip4) /
4754 TCP(sport=local_port, dport=12348))
4755 self.pg5.add_stream(p)
4756 self.pg_enable_capture(self.pg_interfaces)
4757 self.pg_start()
4758 capture = self.pg6.get_capture(1)
4759 p = capture[0]
4760 try:
4761 ip = p[IP]
4762 tcp = p[TCP]
4763 self.assertEqual(ip.src, self.pg5.remote_ip4)
4764 self.assertEqual(tcp.sport, local_port)
4765 self.assert_packet_checksums_valid(p)
4766 except:
4767 self.logger.error(ppp("Unexpected or invalid packet:", p))
4768 raise
4769
4770 # from client VRF1 to server VRF0 (no translation)
4771 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
4772 IP(src=self.pg0.remote_ip4, dst=self.pg6.remote_ip4) /
4773 TCP(sport=local_port, dport=12349))
4774 self.pg0.add_stream(p)
4775 self.pg_enable_capture(self.pg_interfaces)
4776 self.pg_start()
4777 capture = self.pg6.get_capture(1)
4778 p = capture[0]
4779 try:
4780 ip = p[IP]
4781 tcp = p[TCP]
4782 self.assertEqual(ip.src, self.pg0.remote_ip4)
4783 self.assertEqual(tcp.sport, local_port)
4784 self.assert_packet_checksums_valid(p)
4785 except:
4786 self.logger.error(ppp("Unexpected or invalid packet:", p))
4787 raise
4788
4789 # from server VRF0 back to client VRF1 (no translation)
4790 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
4791 IP(src=self.pg0.remote_ip4, dst=self.pg6.remote_ip4) /
4792 TCP(sport=local_port, dport=12349))
4793 self.pg0.add_stream(p)
4794 self.pg_enable_capture(self.pg_interfaces)
4795 self.pg_start()
4796 capture = self.pg6.get_capture(1)
4797 p = capture[0]
4798 try:
4799 ip = p[IP]
4800 tcp = p[TCP]
4801 self.assertEqual(ip.src, self.pg0.remote_ip4)
4802 self.assertEqual(tcp.sport, local_port)
4803 self.assert_packet_checksums_valid(p)
4804 except:
4805 self.logger.error(ppp("Unexpected or invalid packet:", p))
4806 raise
4807
4808 # from client VRF0 to server VRF1 (no translation)
4809 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
4810 IP(src=self.pg0.remote_ip4, dst=self.pg5.remote_ip4) /
4811 TCP(sport=12344, dport=local_port))
4812 self.pg0.add_stream(p)
4813 self.pg_enable_capture(self.pg_interfaces)
4814 self.pg_start()
4815 capture = self.pg5.get_capture(1)
4816 p = capture[0]
4817 try:
4818 ip = p[IP]
4819 tcp = p[TCP]
4820 self.assertEqual(ip.dst, self.pg5.remote_ip4)
4821 self.assertEqual(tcp.dport, local_port)
4822 self.assert_packet_checksums_valid(p)
4823 except:
4824 self.logger.error(ppp("Unexpected or invalid packet:", p))
4825 raise
4826
4827 # from server VRF1 back to client VRF0 (no translation)
4828 p = (Ether(src=self.pg5.remote_mac, dst=self.pg5.local_mac) /
4829 IP(src=self.pg5.remote_ip4, dst=self.pg0.remote_ip4) /
4830 TCP(sport=local_port, dport=12344))
4831 self.pg5.add_stream(p)
4832 self.pg_enable_capture(self.pg_interfaces)
4833 self.pg_start()
4834 capture = self.pg0.get_capture(1)
4835 p = capture[0]
4836 try:
4837 ip = p[IP]
4838 tcp = p[TCP]
4839 self.assertEqual(ip.src, self.pg5.remote_ip4)
4840 self.assertEqual(tcp.sport, local_port)
4841 self.assert_packet_checksums_valid(p)
4842 except:
4843 self.logger.error(ppp("Unexpected or invalid packet:", p))
4844 raise
4845
Matus Fabiande886752016-12-07 03:38:19 -08004846 def tearDown(self):
Matus Fabiana6110b62018-06-13 05:39:07 -07004847 super(TestNAT44EndpointDependent, self).tearDown()
Matus Fabiande886752016-12-07 03:38:19 -08004848 if not self.vpp_dead:
Matus Fabian82119542018-01-25 01:13:22 -08004849 self.logger.info(self.vapi.cli("show nat44 addresses"))
4850 self.logger.info(self.vapi.cli("show nat44 interfaces"))
4851 self.logger.info(self.vapi.cli("show nat44 static mappings"))
4852 self.logger.info(self.vapi.cli("show nat44 interface address"))
4853 self.logger.info(self.vapi.cli("show nat44 sessions detail"))
Matus Fabian229c1aa2018-05-28 04:09:52 -07004854 self.logger.info(self.vapi.cli("show nat44 hash tables detail"))
Matus Fabian2ba92e32017-08-21 07:05:03 -07004855 self.clear_nat44()
Matus Fabian229c1aa2018-05-28 04:09:52 -07004856 self.vapi.cli("clear logging")
Matus Fabiande886752016-12-07 03:38:19 -08004857
Matus Fabianeea28d72017-01-13 04:15:54 -08004858
Juraj Slobodacba69362017-12-19 02:09:32 +01004859class TestNAT44Out2InDPO(MethodHolder):
4860 """ NAT44 Test Cases using out2in DPO """
4861
4862 @classmethod
4863 def setUpConstants(cls):
4864 super(TestNAT44Out2InDPO, cls).setUpConstants()
4865 cls.vpp_cmdline.extend(["nat", "{", "out2in dpo", "}"])
4866
4867 @classmethod
4868 def setUpClass(cls):
4869 super(TestNAT44Out2InDPO, cls).setUpClass()
Matus Fabian229c1aa2018-05-28 04:09:52 -07004870 cls.vapi.cli("set log class nat level debug")
Juraj Slobodacba69362017-12-19 02:09:32 +01004871
4872 try:
4873 cls.tcp_port_in = 6303
4874 cls.tcp_port_out = 6303
4875 cls.udp_port_in = 6304
4876 cls.udp_port_out = 6304
4877 cls.icmp_id_in = 6305
4878 cls.icmp_id_out = 6305
4879 cls.nat_addr = '10.0.0.3'
4880 cls.nat_addr_n = socket.inet_pton(socket.AF_INET, cls.nat_addr)
4881 cls.dst_ip4 = '192.168.70.1'
4882
4883 cls.create_pg_interfaces(range(2))
4884
4885 cls.pg0.admin_up()
4886 cls.pg0.config_ip4()
4887 cls.pg0.resolve_arp()
4888
4889 cls.pg1.admin_up()
4890 cls.pg1.config_ip6()
4891 cls.pg1.resolve_ndp()
4892
4893 cls.vapi.ip_add_del_route(is_ipv6=True, dst_address='\x00'*16,
4894 dst_address_length=0,
4895 next_hop_address=cls.pg1.remote_ip6n,
4896 next_hop_sw_if_index=cls.pg1.sw_if_index)
4897
4898 except Exception:
4899 super(TestNAT44Out2InDPO, cls).tearDownClass()
4900 raise
4901
4902 def configure_xlat(self):
4903 self.dst_ip6_pfx = '1:2:3::'
4904 self.dst_ip6_pfx_n = socket.inet_pton(socket.AF_INET6,
4905 self.dst_ip6_pfx)
4906 self.dst_ip6_pfx_len = 96
4907 self.src_ip6_pfx = '4:5:6::'
4908 self.src_ip6_pfx_n = socket.inet_pton(socket.AF_INET6,
4909 self.src_ip6_pfx)
4910 self.src_ip6_pfx_len = 96
4911 self.vapi.map_add_domain(self.dst_ip6_pfx_n, self.dst_ip6_pfx_len,
4912 self.src_ip6_pfx_n, self.src_ip6_pfx_len,
4913 '\x00\x00\x00\x00', 0, is_translation=1,
4914 is_rfc6052=1)
4915
4916 def test_464xlat_ce(self):
4917 """ Test 464XLAT CE with NAT44 """
4918
4919 self.configure_xlat()
4920
4921 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
4922 self.vapi.nat44_add_del_address_range(self.nat_addr_n, self.nat_addr_n)
4923
4924 out_src_ip6 = self.compose_ip6(self.dst_ip4, self.dst_ip6_pfx,
4925 self.dst_ip6_pfx_len)
4926 out_dst_ip6 = self.compose_ip6(self.nat_addr, self.src_ip6_pfx,
4927 self.src_ip6_pfx_len)
4928
4929 try:
4930 pkts = self.create_stream_in(self.pg0, self.pg1, self.dst_ip4)
4931 self.pg0.add_stream(pkts)
4932 self.pg_enable_capture(self.pg_interfaces)
4933 self.pg_start()
4934 capture = self.pg1.get_capture(len(pkts))
4935 self.verify_capture_out_ip6(capture, nat_ip=out_dst_ip6,
4936 dst_ip=out_src_ip6)
4937
4938 pkts = self.create_stream_out_ip6(self.pg1, out_src_ip6,
4939 out_dst_ip6)
4940 self.pg1.add_stream(pkts)
4941 self.pg_enable_capture(self.pg_interfaces)
4942 self.pg_start()
4943 capture = self.pg0.get_capture(len(pkts))
4944 self.verify_capture_in(capture, self.pg0)
4945 finally:
4946 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index,
4947 is_add=0)
4948 self.vapi.nat44_add_del_address_range(self.nat_addr_n,
4949 self.nat_addr_n, is_add=0)
4950
4951 def test_464xlat_ce_no_nat(self):
4952 """ Test 464XLAT CE without NAT44 """
4953
4954 self.configure_xlat()
4955
4956 out_src_ip6 = self.compose_ip6(self.dst_ip4, self.dst_ip6_pfx,
4957 self.dst_ip6_pfx_len)
4958 out_dst_ip6 = self.compose_ip6(self.pg0.remote_ip4, self.src_ip6_pfx,
4959 self.src_ip6_pfx_len)
4960
4961 pkts = self.create_stream_in(self.pg0, self.pg1, self.dst_ip4)
4962 self.pg0.add_stream(pkts)
4963 self.pg_enable_capture(self.pg_interfaces)
4964 self.pg_start()
4965 capture = self.pg1.get_capture(len(pkts))
4966 self.verify_capture_out_ip6(capture, dst_ip=out_src_ip6,
4967 nat_ip=out_dst_ip6, same_port=True)
4968
4969 pkts = self.create_stream_out_ip6(self.pg1, out_src_ip6, out_dst_ip6)
4970 self.pg1.add_stream(pkts)
4971 self.pg_enable_capture(self.pg_interfaces)
4972 self.pg_start()
4973 capture = self.pg0.get_capture(len(pkts))
4974 self.verify_capture_in(capture, self.pg0)
4975
4976
Martin Gálikd7f75cd2017-03-27 06:02:47 -07004977class TestDeterministicNAT(MethodHolder):
Matus Fabian066f0342017-02-10 03:48:01 -08004978 """ Deterministic NAT Test Cases """
4979
4980 @classmethod
4981 def setUpConstants(cls):
4982 super(TestDeterministicNAT, cls).setUpConstants()
Matus Fabian2ba92e32017-08-21 07:05:03 -07004983 cls.vpp_cmdline.extend(["nat", "{", "deterministic", "}"])
Matus Fabian066f0342017-02-10 03:48:01 -08004984
4985 @classmethod
4986 def setUpClass(cls):
4987 super(TestDeterministicNAT, cls).setUpClass()
Matus Fabian229c1aa2018-05-28 04:09:52 -07004988 cls.vapi.cli("set log class nat level debug")
Matus Fabian066f0342017-02-10 03:48:01 -08004989
4990 try:
Martin Gálik977c1cb2017-03-30 23:21:51 -07004991 cls.tcp_port_in = 6303
Martin Gálik9806eae2017-04-25 01:25:08 -07004992 cls.tcp_external_port = 6303
Martin Gálik977c1cb2017-03-30 23:21:51 -07004993 cls.udp_port_in = 6304
Martin Gálik9806eae2017-04-25 01:25:08 -07004994 cls.udp_external_port = 6304
Martin Gálik977c1cb2017-03-30 23:21:51 -07004995 cls.icmp_id_in = 6305
Matus Fabian2ba92e32017-08-21 07:05:03 -07004996 cls.nat_addr = '10.0.0.3'
Martin Gálik977c1cb2017-03-30 23:21:51 -07004997
Matus Fabian2f2db1c2017-04-18 05:29:59 -07004998 cls.create_pg_interfaces(range(3))
Matus Fabian066f0342017-02-10 03:48:01 -08004999 cls.interfaces = list(cls.pg_interfaces)
5000
5001 for i in cls.interfaces:
5002 i.admin_up()
5003 i.config_ip4()
5004 i.resolve_arp()
5005
Martin Gálik977c1cb2017-03-30 23:21:51 -07005006 cls.pg0.generate_remote_hosts(2)
5007 cls.pg0.configure_ipv4_neighbors()
5008
Matus Fabian066f0342017-02-10 03:48:01 -08005009 except Exception:
5010 super(TestDeterministicNAT, cls).tearDownClass()
5011 raise
5012
Martin Gálik977c1cb2017-03-30 23:21:51 -07005013 def create_stream_in(self, in_if, out_if, ttl=64):
5014 """
5015 Create packet stream for inside network
5016
5017 :param in_if: Inside interface
5018 :param out_if: Outside interface
5019 :param ttl: TTL of generated packets
5020 """
5021 pkts = []
5022 # TCP
5023 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
5024 IP(src=in_if.remote_ip4, dst=out_if.remote_ip4, ttl=ttl) /
Martin Gálik9806eae2017-04-25 01:25:08 -07005025 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port))
Martin Gálik977c1cb2017-03-30 23:21:51 -07005026 pkts.append(p)
5027
5028 # UDP
5029 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
5030 IP(src=in_if.remote_ip4, dst=out_if.remote_ip4, ttl=ttl) /
Martin Gálik9806eae2017-04-25 01:25:08 -07005031 UDP(sport=self.udp_port_in, dport=self.udp_external_port))
Martin Gálik977c1cb2017-03-30 23:21:51 -07005032 pkts.append(p)
5033
5034 # ICMP
5035 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
5036 IP(src=in_if.remote_ip4, dst=out_if.remote_ip4, ttl=ttl) /
5037 ICMP(id=self.icmp_id_in, type='echo-request'))
5038 pkts.append(p)
5039
5040 return pkts
5041
5042 def create_stream_out(self, out_if, dst_ip=None, ttl=64):
5043 """
5044 Create packet stream for outside network
5045
5046 :param out_if: Outside interface
Matus Fabian2ba92e32017-08-21 07:05:03 -07005047 :param dst_ip: Destination IP address (Default use global NAT address)
Martin Gálik977c1cb2017-03-30 23:21:51 -07005048 :param ttl: TTL of generated packets
5049 """
5050 if dst_ip is None:
Matus Fabian2ba92e32017-08-21 07:05:03 -07005051 dst_ip = self.nat_addr
Martin Gálik977c1cb2017-03-30 23:21:51 -07005052 pkts = []
5053 # TCP
5054 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
5055 IP(src=out_if.remote_ip4, dst=dst_ip, ttl=ttl) /
Martin Gálik9806eae2017-04-25 01:25:08 -07005056 TCP(dport=self.tcp_port_out, sport=self.tcp_external_port))
Martin Gálik977c1cb2017-03-30 23:21:51 -07005057 pkts.append(p)
5058
5059 # UDP
5060 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
5061 IP(src=out_if.remote_ip4, dst=dst_ip, ttl=ttl) /
Martin Gálik9806eae2017-04-25 01:25:08 -07005062 UDP(dport=self.udp_port_out, sport=self.udp_external_port))
Martin Gálik977c1cb2017-03-30 23:21:51 -07005063 pkts.append(p)
5064
5065 # ICMP
5066 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
5067 IP(src=out_if.remote_ip4, dst=dst_ip, ttl=ttl) /
5068 ICMP(id=self.icmp_external_id, type='echo-reply'))
5069 pkts.append(p)
5070
5071 return pkts
5072
5073 def verify_capture_out(self, capture, nat_ip=None, packet_num=3):
5074 """
5075 Verify captured packets on outside network
5076
5077 :param capture: Captured packets
Matus Fabian2ba92e32017-08-21 07:05:03 -07005078 :param nat_ip: Translated IP address (Default use global NAT address)
Martin Gálik977c1cb2017-03-30 23:21:51 -07005079 :param same_port: Sorce port number is not translated (Default False)
5080 :param packet_num: Expected number of packets (Default 3)
5081 """
5082 if nat_ip is None:
Matus Fabian2ba92e32017-08-21 07:05:03 -07005083 nat_ip = self.nat_addr
Martin Gálik977c1cb2017-03-30 23:21:51 -07005084 self.assertEqual(packet_num, len(capture))
5085 for packet in capture:
5086 try:
5087 self.assertEqual(packet[IP].src, nat_ip)
5088 if packet.haslayer(TCP):
Martin Gálik9806eae2017-04-25 01:25:08 -07005089 self.tcp_port_out = packet[TCP].sport
Martin Gálik977c1cb2017-03-30 23:21:51 -07005090 elif packet.haslayer(UDP):
Martin Gálik9806eae2017-04-25 01:25:08 -07005091 self.udp_port_out = packet[UDP].sport
Martin Gálik977c1cb2017-03-30 23:21:51 -07005092 else:
5093 self.icmp_external_id = packet[ICMP].id
5094 except:
5095 self.logger.error(ppp("Unexpected or invalid packet "
5096 "(outside network):", packet))
5097 raise
5098
Matus Fabian2f2db1c2017-04-18 05:29:59 -07005099 def verify_ipfix_max_entries_per_user(self, data):
5100 """
5101 Verify IPFIX maximum entries per user exceeded event
5102
5103 :param data: Decoded IPFIX data records
5104 """
5105 self.assertEqual(1, len(data))
5106 record = data[0]
5107 # natEvent
5108 self.assertEqual(ord(record[230]), 13)
5109 # natQuotaExceededEvent
5110 self.assertEqual('\x03\x00\x00\x00', record[466])
Matus Fabiana431ad12018-01-04 04:03:14 -08005111 # maxEntriesPerUser
5112 self.assertEqual('\xe8\x03\x00\x00', record[473])
Matus Fabian2f2db1c2017-04-18 05:29:59 -07005113 # sourceIPv4Address
5114 self.assertEqual(self.pg0.remote_ip4n, record[8])
5115
Matus Fabian066f0342017-02-10 03:48:01 -08005116 def test_deterministic_mode(self):
Matus Fabian2ba92e32017-08-21 07:05:03 -07005117 """ NAT plugin run deterministic mode """
Matus Fabian066f0342017-02-10 03:48:01 -08005118 in_addr = '172.16.255.0'
5119 out_addr = '172.17.255.50'
5120 in_addr_t = '172.16.255.20'
5121 in_addr_n = socket.inet_aton(in_addr)
5122 out_addr_n = socket.inet_aton(out_addr)
5123 in_addr_t_n = socket.inet_aton(in_addr_t)
5124 in_plen = 24
5125 out_plen = 32
5126
Matus Fabian2ba92e32017-08-21 07:05:03 -07005127 nat_config = self.vapi.nat_show_config()
5128 self.assertEqual(1, nat_config.deterministic)
Matus Fabian066f0342017-02-10 03:48:01 -08005129
Matus Fabian2ba92e32017-08-21 07:05:03 -07005130 self.vapi.nat_det_add_del_map(in_addr_n, in_plen, out_addr_n, out_plen)
Matus Fabian066f0342017-02-10 03:48:01 -08005131
Matus Fabian2ba92e32017-08-21 07:05:03 -07005132 rep1 = self.vapi.nat_det_forward(in_addr_t_n)
Matus Fabian066f0342017-02-10 03:48:01 -08005133 self.assertEqual(rep1.out_addr[:4], out_addr_n)
Matus Fabian2ba92e32017-08-21 07:05:03 -07005134 rep2 = self.vapi.nat_det_reverse(out_addr_n, rep1.out_port_hi)
Matus Fabian066f0342017-02-10 03:48:01 -08005135 self.assertEqual(rep2.in_addr[:4], in_addr_t_n)
5136
Matus Fabian2ba92e32017-08-21 07:05:03 -07005137 deterministic_mappings = self.vapi.nat_det_map_dump()
Martin17a75cb2017-03-08 05:53:20 -08005138 self.assertEqual(len(deterministic_mappings), 1)
5139 dsm = deterministic_mappings[0]
5140 self.assertEqual(in_addr_n, dsm.in_addr[:4])
5141 self.assertEqual(in_plen, dsm.in_plen)
5142 self.assertEqual(out_addr_n, dsm.out_addr[:4])
5143 self.assertEqual(out_plen, dsm.out_plen)
5144
Matus Fabian2ba92e32017-08-21 07:05:03 -07005145 self.clear_nat_det()
5146 deterministic_mappings = self.vapi.nat_det_map_dump()
Martinb616e9f2017-03-14 02:25:45 -07005147 self.assertEqual(len(deterministic_mappings), 0)
5148
Matus Fabian6a0946f2017-04-12 03:36:13 -07005149 def test_set_timeouts(self):
5150 """ Set deterministic NAT timeouts """
Matus Fabian2ba92e32017-08-21 07:05:03 -07005151 timeouts_before = self.vapi.nat_det_get_timeouts()
Matus Fabian6a0946f2017-04-12 03:36:13 -07005152
Matus Fabian2ba92e32017-08-21 07:05:03 -07005153 self.vapi.nat_det_set_timeouts(timeouts_before.udp + 10,
5154 timeouts_before.tcp_established + 10,
5155 timeouts_before.tcp_transitory + 10,
5156 timeouts_before.icmp + 10)
Matus Fabian6a0946f2017-04-12 03:36:13 -07005157
Matus Fabian2ba92e32017-08-21 07:05:03 -07005158 timeouts_after = self.vapi.nat_det_get_timeouts()
Matus Fabian6a0946f2017-04-12 03:36:13 -07005159
5160 self.assertNotEqual(timeouts_before.udp, timeouts_after.udp)
5161 self.assertNotEqual(timeouts_before.icmp, timeouts_after.icmp)
5162 self.assertNotEqual(timeouts_before.tcp_established,
5163 timeouts_after.tcp_established)
5164 self.assertNotEqual(timeouts_before.tcp_transitory,
5165 timeouts_after.tcp_transitory)
5166
Martin Gálik977c1cb2017-03-30 23:21:51 -07005167 def test_det_in(self):
Matus Fabian2ba92e32017-08-21 07:05:03 -07005168 """ Deterministic NAT translation test (TCP, UDP, ICMP) """
Martin Gálik977c1cb2017-03-30 23:21:51 -07005169
5170 nat_ip = "10.0.0.10"
Martin Gálik977c1cb2017-03-30 23:21:51 -07005171
Matus Fabian2ba92e32017-08-21 07:05:03 -07005172 self.vapi.nat_det_add_del_map(self.pg0.remote_ip4n,
5173 32,
5174 socket.inet_aton(nat_ip),
5175 32)
5176 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
5177 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
5178 is_inside=0)
Martin Gálik977c1cb2017-03-30 23:21:51 -07005179
5180 # in2out
5181 pkts = self.create_stream_in(self.pg0, self.pg1)
5182 self.pg0.add_stream(pkts)
5183 self.pg_enable_capture(self.pg_interfaces)
5184 self.pg_start()
5185 capture = self.pg1.get_capture(len(pkts))
5186 self.verify_capture_out(capture, nat_ip)
5187
5188 # out2in
5189 pkts = self.create_stream_out(self.pg1, nat_ip)
5190 self.pg1.add_stream(pkts)
5191 self.pg_enable_capture(self.pg_interfaces)
5192 self.pg_start()
5193 capture = self.pg0.get_capture(len(pkts))
5194 self.verify_capture_in(capture, self.pg0)
5195
Martin Gálik9806eae2017-04-25 01:25:08 -07005196 # session dump test
Matus Fabian2ba92e32017-08-21 07:05:03 -07005197 sessions = self.vapi.nat_det_session_dump(self.pg0.remote_ip4n)
Martin Gálik9806eae2017-04-25 01:25:08 -07005198 self.assertEqual(len(sessions), 3)
5199
5200 # TCP session
5201 s = sessions[0]
5202 self.assertEqual(s.ext_addr[:4], self.pg1.remote_ip4n)
5203 self.assertEqual(s.in_port, self.tcp_port_in)
5204 self.assertEqual(s.out_port, self.tcp_port_out)
5205 self.assertEqual(s.ext_port, self.tcp_external_port)
5206
5207 # UDP session
5208 s = sessions[1]
5209 self.assertEqual(s.ext_addr[:4], self.pg1.remote_ip4n)
5210 self.assertEqual(s.in_port, self.udp_port_in)
5211 self.assertEqual(s.out_port, self.udp_port_out)
5212 self.assertEqual(s.ext_port, self.udp_external_port)
5213
5214 # ICMP session
5215 s = sessions[2]
5216 self.assertEqual(s.ext_addr[:4], self.pg1.remote_ip4n)
5217 self.assertEqual(s.in_port, self.icmp_id_in)
5218 self.assertEqual(s.out_port, self.icmp_external_id)
5219
Martin Gálik977c1cb2017-03-30 23:21:51 -07005220 def test_multiple_users(self):
Matus Fabian2ba92e32017-08-21 07:05:03 -07005221 """ Deterministic NAT multiple users """
Martin Gálik977c1cb2017-03-30 23:21:51 -07005222
5223 nat_ip = "10.0.0.10"
5224 port_in = 80
Martin Gálik9806eae2017-04-25 01:25:08 -07005225 external_port = 6303
Martin Gálik977c1cb2017-03-30 23:21:51 -07005226
5227 host0 = self.pg0.remote_hosts[0]
5228 host1 = self.pg0.remote_hosts[1]
5229
Matus Fabian2ba92e32017-08-21 07:05:03 -07005230 self.vapi.nat_det_add_del_map(host0.ip4n,
5231 24,
5232 socket.inet_aton(nat_ip),
5233 32)
5234 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
5235 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
5236 is_inside=0)
Martin Gálik977c1cb2017-03-30 23:21:51 -07005237
5238 # host0 to out
5239 p = (Ether(src=host0.mac, dst=self.pg0.local_mac) /
5240 IP(src=host0.ip4, dst=self.pg1.remote_ip4) /
Martin Gálik9806eae2017-04-25 01:25:08 -07005241 TCP(sport=port_in, dport=external_port))
Martin Gálik977c1cb2017-03-30 23:21:51 -07005242 self.pg0.add_stream(p)
5243 self.pg_enable_capture(self.pg_interfaces)
5244 self.pg_start()
5245 capture = self.pg1.get_capture(1)
5246 p = capture[0]
5247 try:
5248 ip = p[IP]
5249 tcp = p[TCP]
5250 self.assertEqual(ip.src, nat_ip)
5251 self.assertEqual(ip.dst, self.pg1.remote_ip4)
Martin Gálik9806eae2017-04-25 01:25:08 -07005252 self.assertEqual(tcp.dport, external_port)
5253 port_out0 = tcp.sport
Martin Gálik977c1cb2017-03-30 23:21:51 -07005254 except:
5255 self.logger.error(ppp("Unexpected or invalid packet:", p))
5256 raise
5257
5258 # host1 to out
5259 p = (Ether(src=host1.mac, dst=self.pg0.local_mac) /
5260 IP(src=host1.ip4, dst=self.pg1.remote_ip4) /
Martin Gálik9806eae2017-04-25 01:25:08 -07005261 TCP(sport=port_in, dport=external_port))
Martin Gálik977c1cb2017-03-30 23:21:51 -07005262 self.pg0.add_stream(p)
5263 self.pg_enable_capture(self.pg_interfaces)
5264 self.pg_start()
5265 capture = self.pg1.get_capture(1)
5266 p = capture[0]
5267 try:
5268 ip = p[IP]
5269 tcp = p[TCP]
5270 self.assertEqual(ip.src, nat_ip)
5271 self.assertEqual(ip.dst, self.pg1.remote_ip4)
Martin Gálik9806eae2017-04-25 01:25:08 -07005272 self.assertEqual(tcp.dport, external_port)
5273 port_out1 = tcp.sport
Martin Gálik977c1cb2017-03-30 23:21:51 -07005274 except:
5275 self.logger.error(ppp("Unexpected or invalid packet:", p))
5276 raise
5277
Matus Fabian2ba92e32017-08-21 07:05:03 -07005278 dms = self.vapi.nat_det_map_dump()
Martin Gálik977c1cb2017-03-30 23:21:51 -07005279 self.assertEqual(1, len(dms))
5280 self.assertEqual(2, dms[0].ses_num)
5281
5282 # out to host0
5283 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5284 IP(src=self.pg1.remote_ip4, dst=nat_ip) /
Martin Gálik9806eae2017-04-25 01:25:08 -07005285 TCP(sport=external_port, dport=port_out0))
Martin Gálik977c1cb2017-03-30 23:21:51 -07005286 self.pg1.add_stream(p)
5287 self.pg_enable_capture(self.pg_interfaces)
5288 self.pg_start()
5289 capture = self.pg0.get_capture(1)
5290 p = capture[0]
5291 try:
5292 ip = p[IP]
5293 tcp = p[TCP]
5294 self.assertEqual(ip.src, self.pg1.remote_ip4)
5295 self.assertEqual(ip.dst, host0.ip4)
5296 self.assertEqual(tcp.dport, port_in)
Martin Gálik9806eae2017-04-25 01:25:08 -07005297 self.assertEqual(tcp.sport, external_port)
Martin Gálik977c1cb2017-03-30 23:21:51 -07005298 except:
5299 self.logger.error(ppp("Unexpected or invalid packet:", p))
5300 raise
5301
5302 # out to host1
5303 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5304 IP(src=self.pg1.remote_ip4, dst=nat_ip) /
Martin Gálik9806eae2017-04-25 01:25:08 -07005305 TCP(sport=external_port, dport=port_out1))
Martin Gálik977c1cb2017-03-30 23:21:51 -07005306 self.pg1.add_stream(p)
5307 self.pg_enable_capture(self.pg_interfaces)
5308 self.pg_start()
5309 capture = self.pg0.get_capture(1)
5310 p = capture[0]
5311 try:
5312 ip = p[IP]
5313 tcp = p[TCP]
5314 self.assertEqual(ip.src, self.pg1.remote_ip4)
5315 self.assertEqual(ip.dst, host1.ip4)
5316 self.assertEqual(tcp.dport, port_in)
Martin Gálik9806eae2017-04-25 01:25:08 -07005317 self.assertEqual(tcp.sport, external_port)
Martin Gálik977c1cb2017-03-30 23:21:51 -07005318 except:
5319 self.logger.error(ppp("Unexpected or invalid packet", p))
5320 raise
5321
Martin Gálik6bc8c642017-04-19 01:12:27 -07005322 # session close api test
Matus Fabian2ba92e32017-08-21 07:05:03 -07005323 self.vapi.nat_det_close_session_out(socket.inet_aton(nat_ip),
5324 port_out1,
Martin Gálik6bc8c642017-04-19 01:12:27 -07005325 self.pg1.remote_ip4n,
Martin Gálik9806eae2017-04-25 01:25:08 -07005326 external_port)
Matus Fabian2ba92e32017-08-21 07:05:03 -07005327 dms = self.vapi.nat_det_map_dump()
5328 self.assertEqual(dms[0].ses_num, 1)
5329
5330 self.vapi.nat_det_close_session_in(host0.ip4n,
5331 port_in,
5332 self.pg1.remote_ip4n,
5333 external_port)
5334 dms = self.vapi.nat_det_map_dump()
Martin Gálik6bc8c642017-04-19 01:12:27 -07005335 self.assertEqual(dms[0].ses_num, 0)
5336
Martin Gálik977c1cb2017-03-30 23:21:51 -07005337 def test_tcp_session_close_detection_in(self):
Matus Fabian2ba92e32017-08-21 07:05:03 -07005338 """ Deterministic NAT TCP session close from inside network """
5339 self.vapi.nat_det_add_del_map(self.pg0.remote_ip4n,
5340 32,
5341 socket.inet_aton(self.nat_addr),
5342 32)
5343 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
5344 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
5345 is_inside=0)
Martin Gálik977c1cb2017-03-30 23:21:51 -07005346
5347 self.initiate_tcp_session(self.pg0, self.pg1)
5348
5349 # close the session from inside
5350 try:
5351 # FIN packet in -> out
5352 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5353 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
Martin Gálik9806eae2017-04-25 01:25:08 -07005354 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
Martin Gálik977c1cb2017-03-30 23:21:51 -07005355 flags="F"))
5356 self.pg0.add_stream(p)
5357 self.pg_enable_capture(self.pg_interfaces)
5358 self.pg_start()
5359 self.pg1.get_capture(1)
5360
5361 pkts = []
5362
5363 # ACK packet out -> in
5364 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
Matus Fabian2ba92e32017-08-21 07:05:03 -07005365 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
Martin Gálik9806eae2017-04-25 01:25:08 -07005366 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
Martin Gálik977c1cb2017-03-30 23:21:51 -07005367 flags="A"))
5368 pkts.append(p)
5369
5370 # FIN packet out -> in
5371 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
Matus Fabian2ba92e32017-08-21 07:05:03 -07005372 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
Martin Gálik9806eae2017-04-25 01:25:08 -07005373 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
Martin Gálik977c1cb2017-03-30 23:21:51 -07005374 flags="F"))
5375 pkts.append(p)
5376
5377 self.pg1.add_stream(pkts)
5378 self.pg_enable_capture(self.pg_interfaces)
5379 self.pg_start()
5380 self.pg0.get_capture(2)
5381
5382 # ACK packet in -> out
5383 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5384 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
Martin Gálik9806eae2017-04-25 01:25:08 -07005385 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
Martin Gálik977c1cb2017-03-30 23:21:51 -07005386 flags="A"))
5387 self.pg0.add_stream(p)
5388 self.pg_enable_capture(self.pg_interfaces)
5389 self.pg_start()
5390 self.pg1.get_capture(1)
5391
Matus Fabian2ba92e32017-08-21 07:05:03 -07005392 # Check if deterministic NAT44 closed the session
5393 dms = self.vapi.nat_det_map_dump()
Martin Gálik977c1cb2017-03-30 23:21:51 -07005394 self.assertEqual(0, dms[0].ses_num)
5395 except:
5396 self.logger.error("TCP session termination failed")
5397 raise
5398
5399 def test_tcp_session_close_detection_out(self):
Matus Fabian2ba92e32017-08-21 07:05:03 -07005400 """ Deterministic NAT TCP session close from outside network """
5401 self.vapi.nat_det_add_del_map(self.pg0.remote_ip4n,
5402 32,
5403 socket.inet_aton(self.nat_addr),
5404 32)
5405 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
5406 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
5407 is_inside=0)
Martin Gálik977c1cb2017-03-30 23:21:51 -07005408
5409 self.initiate_tcp_session(self.pg0, self.pg1)
5410
5411 # close the session from outside
5412 try:
5413 # FIN packet out -> in
5414 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
Matus Fabian2ba92e32017-08-21 07:05:03 -07005415 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
Martin Gálik9806eae2017-04-25 01:25:08 -07005416 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
Martin Gálik977c1cb2017-03-30 23:21:51 -07005417 flags="F"))
5418 self.pg1.add_stream(p)
5419 self.pg_enable_capture(self.pg_interfaces)
5420 self.pg_start()
5421 self.pg0.get_capture(1)
5422
5423 pkts = []
5424
5425 # ACK packet in -> out
5426 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5427 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
Martin Gálik9806eae2017-04-25 01:25:08 -07005428 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
Martin Gálik977c1cb2017-03-30 23:21:51 -07005429 flags="A"))
5430 pkts.append(p)
5431
5432 # ACK packet in -> out
5433 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5434 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
Martin Gálik9806eae2017-04-25 01:25:08 -07005435 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
Martin Gálik977c1cb2017-03-30 23:21:51 -07005436 flags="F"))
5437 pkts.append(p)
5438
5439 self.pg0.add_stream(pkts)
5440 self.pg_enable_capture(self.pg_interfaces)
5441 self.pg_start()
5442 self.pg1.get_capture(2)
5443
5444 # ACK packet out -> in
5445 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
Matus Fabian2ba92e32017-08-21 07:05:03 -07005446 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
Martin Gálik9806eae2017-04-25 01:25:08 -07005447 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
Martin Gálik977c1cb2017-03-30 23:21:51 -07005448 flags="A"))
5449 self.pg1.add_stream(p)
5450 self.pg_enable_capture(self.pg_interfaces)
5451 self.pg_start()
5452 self.pg0.get_capture(1)
5453
Matus Fabian2ba92e32017-08-21 07:05:03 -07005454 # Check if deterministic NAT44 closed the session
5455 dms = self.vapi.nat_det_map_dump()
Martin Gálik977c1cb2017-03-30 23:21:51 -07005456 self.assertEqual(0, dms[0].ses_num)
5457 except:
5458 self.logger.error("TCP session termination failed")
5459 raise
5460
5461 @unittest.skipUnless(running_extended_tests(), "part of extended tests")
5462 def test_session_timeout(self):
Matus Fabian2ba92e32017-08-21 07:05:03 -07005463 """ Deterministic NAT session timeouts """
5464 self.vapi.nat_det_add_del_map(self.pg0.remote_ip4n,
5465 32,
5466 socket.inet_aton(self.nat_addr),
5467 32)
5468 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
5469 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
5470 is_inside=0)
Martin Gálik977c1cb2017-03-30 23:21:51 -07005471
5472 self.initiate_tcp_session(self.pg0, self.pg1)
Matus Fabian2ba92e32017-08-21 07:05:03 -07005473 self.vapi.nat_det_set_timeouts(5, 5, 5, 5)
Martin Gálik977c1cb2017-03-30 23:21:51 -07005474 pkts = self.create_stream_in(self.pg0, self.pg1)
5475 self.pg0.add_stream(pkts)
5476 self.pg_enable_capture(self.pg_interfaces)
5477 self.pg_start()
5478 capture = self.pg1.get_capture(len(pkts))
5479 sleep(15)
5480
Matus Fabian2ba92e32017-08-21 07:05:03 -07005481 dms = self.vapi.nat_det_map_dump()
Martin Gálik977c1cb2017-03-30 23:21:51 -07005482 self.assertEqual(0, dms[0].ses_num)
5483
Matus Fabian7c0aecc2017-07-03 01:21:38 -07005484 @unittest.skipUnless(running_extended_tests(), "part of extended tests")
Martin Gálik977c1cb2017-03-30 23:21:51 -07005485 def test_session_limit_per_user(self):
Matus Fabian2ba92e32017-08-21 07:05:03 -07005486 """ Deterministic NAT maximum sessions per user limit """
5487 self.vapi.nat_det_add_del_map(self.pg0.remote_ip4n,
5488 32,
5489 socket.inet_aton(self.nat_addr),
5490 32)
5491 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
5492 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
5493 is_inside=0)
Matus Fabian2f2db1c2017-04-18 05:29:59 -07005494 self.vapi.set_ipfix_exporter(collector_address=self.pg2.remote_ip4n,
5495 src_address=self.pg2.local_ip4n,
5496 path_mtu=512,
5497 template_interval=10)
Matus Fabian2ba92e32017-08-21 07:05:03 -07005498 self.vapi.nat_ipfix()
Martin Gálik977c1cb2017-03-30 23:21:51 -07005499
5500 pkts = []
5501 for port in range(1025, 2025):
5502 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5503 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5504 UDP(sport=port, dport=port))
5505 pkts.append(p)
5506
5507 self.pg0.add_stream(pkts)
5508 self.pg_enable_capture(self.pg_interfaces)
5509 self.pg_start()
5510 capture = self.pg1.get_capture(len(pkts))
5511
5512 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5513 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
Martin Gálikf7e655d2017-04-27 02:13:26 -07005514 UDP(sport=3001, dport=3002))
Martin Gálik977c1cb2017-03-30 23:21:51 -07005515 self.pg0.add_stream(p)
5516 self.pg_enable_capture(self.pg_interfaces)
5517 self.pg_start()
5518 capture = self.pg1.assert_nothing_captured()
5519
Martin Gálikf7e655d2017-04-27 02:13:26 -07005520 # verify ICMP error packet
5521 capture = self.pg0.get_capture(1)
5522 p = capture[0]
5523 self.assertTrue(p.haslayer(ICMP))
5524 icmp = p[ICMP]
5525 self.assertEqual(icmp.type, 3)
5526 self.assertEqual(icmp.code, 1)
5527 self.assertTrue(icmp.haslayer(IPerror))
5528 inner_ip = icmp[IPerror]
5529 self.assertEqual(inner_ip[UDPerror].sport, 3001)
5530 self.assertEqual(inner_ip[UDPerror].dport, 3002)
5531
Matus Fabian2ba92e32017-08-21 07:05:03 -07005532 dms = self.vapi.nat_det_map_dump()
Martin Gálik977c1cb2017-03-30 23:21:51 -07005533
5534 self.assertEqual(1000, dms[0].ses_num)
5535
Matus Fabian2f2db1c2017-04-18 05:29:59 -07005536 # verify IPFIX logging
5537 self.vapi.cli("ipfix flush") # FIXME this should be an API call
Matus Fabian7c0aecc2017-07-03 01:21:38 -07005538 sleep(1)
Matus Fabian2f2db1c2017-04-18 05:29:59 -07005539 capture = self.pg2.get_capture(2)
5540 ipfix = IPFIXDecoder()
5541 # first load template
5542 for p in capture:
5543 self.assertTrue(p.haslayer(IPFIX))
5544 if p.haslayer(Template):
5545 ipfix.add_template(p.getlayer(Template))
5546 # verify events in data set
5547 for p in capture:
5548 if p.haslayer(Data):
5549 data = ipfix.decode_data_set(p.getlayer(Set))
5550 self.verify_ipfix_max_entries_per_user(data)
5551
Matus Fabian2ba92e32017-08-21 07:05:03 -07005552 def clear_nat_det(self):
Martin17a75cb2017-03-08 05:53:20 -08005553 """
Matus Fabian2ba92e32017-08-21 07:05:03 -07005554 Clear deterministic NAT configuration.
Martin17a75cb2017-03-08 05:53:20 -08005555 """
Matus Fabian2ba92e32017-08-21 07:05:03 -07005556 self.vapi.nat_ipfix(enable=0)
5557 self.vapi.nat_det_set_timeouts()
5558 deterministic_mappings = self.vapi.nat_det_map_dump()
Martin17a75cb2017-03-08 05:53:20 -08005559 for dsm in deterministic_mappings:
Matus Fabian2ba92e32017-08-21 07:05:03 -07005560 self.vapi.nat_det_add_del_map(dsm.in_addr,
5561 dsm.in_plen,
5562 dsm.out_addr,
5563 dsm.out_plen,
5564 is_add=0)
Martin17a75cb2017-03-08 05:53:20 -08005565
Matus Fabian2ba92e32017-08-21 07:05:03 -07005566 interfaces = self.vapi.nat44_interface_dump()
Martin Gálik977c1cb2017-03-30 23:21:51 -07005567 for intf in interfaces:
Matus Fabian2ba92e32017-08-21 07:05:03 -07005568 self.vapi.nat44_interface_add_del_feature(intf.sw_if_index,
5569 intf.is_inside,
5570 is_add=0)
Martin Gálik977c1cb2017-03-30 23:21:51 -07005571
Matus Fabian066f0342017-02-10 03:48:01 -08005572 def tearDown(self):
5573 super(TestDeterministicNAT, self).tearDown()
5574 if not self.vpp_dead:
Matus Fabian82119542018-01-25 01:13:22 -08005575 self.logger.info(self.vapi.cli("show nat44 interfaces"))
5576 self.logger.info(
5577 self.vapi.cli("show nat44 deterministic mappings"))
5578 self.logger.info(
5579 self.vapi.cli("show nat44 deterministic timeouts"))
5580 self.logger.info(
5581 self.vapi.cli("show nat44 deterministic sessions"))
Matus Fabian2ba92e32017-08-21 07:05:03 -07005582 self.clear_nat_det()
Matus Fabian066f0342017-02-10 03:48:01 -08005583
Matus Fabian06596c52017-06-06 04:53:28 -07005584
5585class TestNAT64(MethodHolder):
5586 """ NAT64 Test Cases """
5587
5588 @classmethod
Matus Fabiana431ad12018-01-04 04:03:14 -08005589 def setUpConstants(cls):
5590 super(TestNAT64, cls).setUpConstants()
5591 cls.vpp_cmdline.extend(["nat", "{", "nat64 bib hash buckets 128",
5592 "nat64 st hash buckets 256", "}"])
5593
5594 @classmethod
Matus Fabian06596c52017-06-06 04:53:28 -07005595 def setUpClass(cls):
5596 super(TestNAT64, cls).setUpClass()
5597
5598 try:
5599 cls.tcp_port_in = 6303
5600 cls.tcp_port_out = 6303
5601 cls.udp_port_in = 6304
5602 cls.udp_port_out = 6304
5603 cls.icmp_id_in = 6305
5604 cls.icmp_id_out = 6305
5605 cls.nat_addr = '10.0.0.3'
5606 cls.nat_addr_n = socket.inet_pton(socket.AF_INET, cls.nat_addr)
Matus Fabian029f3d22017-06-15 02:28:50 -07005607 cls.vrf1_id = 10
5608 cls.vrf1_nat_addr = '10.0.10.3'
5609 cls.vrf1_nat_addr_n = socket.inet_pton(socket.AF_INET,
5610 cls.vrf1_nat_addr)
Matus Fabiana431ad12018-01-04 04:03:14 -08005611 cls.ipfix_src_port = 4739
5612 cls.ipfix_domain_id = 1
Matus Fabian06596c52017-06-06 04:53:28 -07005613
Juraj Slobodac746a152018-07-09 02:36:37 +02005614 cls.create_pg_interfaces(range(6))
Matus Fabian06596c52017-06-06 04:53:28 -07005615 cls.ip6_interfaces = list(cls.pg_interfaces[0:1])
Matus Fabian029f3d22017-06-15 02:28:50 -07005616 cls.ip6_interfaces.append(cls.pg_interfaces[2])
Matus Fabian06596c52017-06-06 04:53:28 -07005617 cls.ip4_interfaces = list(cls.pg_interfaces[1:2])
5618
Neale Ranns15002542017-09-10 04:39:11 -07005619 cls.vapi.ip_table_add_del(cls.vrf1_id, is_add=1, is_ipv6=1)
5620
Matus Fabian029f3d22017-06-15 02:28:50 -07005621 cls.pg_interfaces[2].set_table_ip6(cls.vrf1_id)
5622
5623 cls.pg0.generate_remote_hosts(2)
5624
Matus Fabian06596c52017-06-06 04:53:28 -07005625 for i in cls.ip6_interfaces:
5626 i.admin_up()
5627 i.config_ip6()
Matus Fabian029f3d22017-06-15 02:28:50 -07005628 i.configure_ipv6_neighbors()
Matus Fabian06596c52017-06-06 04:53:28 -07005629
5630 for i in cls.ip4_interfaces:
5631 i.admin_up()
5632 i.config_ip4()
5633 i.resolve_arp()
5634
Matus Fabian36ea2d62017-10-24 04:13:49 -07005635 cls.pg3.admin_up()
5636 cls.pg3.config_ip4()
5637 cls.pg3.resolve_arp()
5638 cls.pg3.config_ip6()
5639 cls.pg3.configure_ipv6_neighbors()
5640
Juraj Slobodac746a152018-07-09 02:36:37 +02005641 cls.pg5.admin_up()
5642 cls.pg5.config_ip6()
5643
Matus Fabian06596c52017-06-06 04:53:28 -07005644 except Exception:
5645 super(TestNAT64, cls).tearDownClass()
5646 raise
5647
Juraj Slobodac746a152018-07-09 02:36:37 +02005648 def test_nat64_inside_interface_handles_neighbor_advertisement(self):
5649 """ NAT64 inside interface handles Neighbor Advertisement """
5650
5651 self.vapi.nat64_add_del_interface(self.pg5.sw_if_index)
5652
5653 # Try to send ping
5654 ping = (Ether(dst=self.pg5.local_mac, src=self.pg5.remote_mac) /
5655 IPv6(src=self.pg5.remote_ip6, dst=self.pg5.local_ip6) /
5656 ICMPv6EchoRequest())
5657 pkts = [ping]
5658 self.pg5.add_stream(pkts)
5659 self.pg_enable_capture(self.pg_interfaces)
5660 self.pg_start()
5661
5662 # Wait for Neighbor Solicitation
5663 capture = self.pg5.get_capture(len(pkts))
5664 self.assertEqual(1, len(capture))
5665 packet = capture[0]
5666 try:
5667 self.assertEqual(packet[IPv6].src, self.pg5.local_ip6)
5668 self.assertTrue(packet.haslayer(ICMPv6ND_NS))
5669 tgt = packet[ICMPv6ND_NS].tgt
5670 except:
5671 self.logger.error(ppp("Unexpected or invalid packet:", packet))
5672 raise
5673
5674 # Send Neighbor Advertisement
5675 p = (Ether(dst=self.pg5.local_mac, src=self.pg5.remote_mac) /
5676 IPv6(src=self.pg5.remote_ip6, dst=self.pg5.local_ip6) /
5677 ICMPv6ND_NA(tgt=tgt) /
5678 ICMPv6NDOptDstLLAddr(lladdr=self.pg5.remote_mac))
5679 pkts = [p]
5680 self.pg5.add_stream(pkts)
5681 self.pg_enable_capture(self.pg_interfaces)
5682 self.pg_start()
5683
5684 # Try to send ping again
5685 pkts = [ping]
5686 self.pg5.add_stream(pkts)
5687 self.pg_enable_capture(self.pg_interfaces)
5688 self.pg_start()
5689
5690 # Wait for ping reply
5691 capture = self.pg5.get_capture(len(pkts))
5692 self.assertEqual(1, len(capture))
5693 packet = capture[0]
5694 try:
5695 self.assertEqual(packet[IPv6].src, self.pg5.local_ip6)
5696 self.assertEqual(packet[IPv6].dst, self.pg5.remote_ip6)
5697 self.assertTrue(packet.haslayer(ICMPv6EchoReply))
5698 except:
5699 self.logger.error(ppp("Unexpected or invalid packet:", packet))
5700 raise
5701
Matus Fabian06596c52017-06-06 04:53:28 -07005702 def test_pool(self):
5703 """ Add/delete address to NAT64 pool """
5704 nat_addr = socket.inet_pton(socket.AF_INET, '1.2.3.4')
5705
5706 self.vapi.nat64_add_del_pool_addr_range(nat_addr, nat_addr)
5707
5708 addresses = self.vapi.nat64_pool_addr_dump()
5709 self.assertEqual(len(addresses), 1)
5710 self.assertEqual(addresses[0].address, nat_addr)
5711
5712 self.vapi.nat64_add_del_pool_addr_range(nat_addr, nat_addr, is_add=0)
5713
5714 addresses = self.vapi.nat64_pool_addr_dump()
5715 self.assertEqual(len(addresses), 0)
5716
5717 def test_interface(self):
5718 """ Enable/disable NAT64 feature on the interface """
5719 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
5720 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
5721
5722 interfaces = self.vapi.nat64_interface_dump()
5723 self.assertEqual(len(interfaces), 2)
5724 pg0_found = False
5725 pg1_found = False
5726 for intf in interfaces:
5727 if intf.sw_if_index == self.pg0.sw_if_index:
5728 self.assertEqual(intf.is_inside, 1)
5729 pg0_found = True
5730 elif intf.sw_if_index == self.pg1.sw_if_index:
5731 self.assertEqual(intf.is_inside, 0)
5732 pg1_found = True
5733 self.assertTrue(pg0_found)
5734 self.assertTrue(pg1_found)
5735
5736 features = self.vapi.cli("show interface features pg0")
5737 self.assertNotEqual(features.find('nat64-in2out'), -1)
5738 features = self.vapi.cli("show interface features pg1")
5739 self.assertNotEqual(features.find('nat64-out2in'), -1)
5740
5741 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index, is_add=0)
5742 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_add=0)
5743
5744 interfaces = self.vapi.nat64_interface_dump()
5745 self.assertEqual(len(interfaces), 0)
5746
5747 def test_static_bib(self):
5748 """ Add/delete static BIB entry """
5749 in_addr = socket.inet_pton(socket.AF_INET6,
5750 '2001:db8:85a3::8a2e:370:7334')
5751 out_addr = socket.inet_pton(socket.AF_INET, '10.1.1.3')
5752 in_port = 1234
5753 out_port = 5678
5754 proto = IP_PROTOS.tcp
5755
5756 self.vapi.nat64_add_del_static_bib(in_addr,
5757 out_addr,
5758 in_port,
5759 out_port,
5760 proto)
5761 bib = self.vapi.nat64_bib_dump(IP_PROTOS.tcp)
5762 static_bib_num = 0
5763 for bibe in bib:
5764 if bibe.is_static:
5765 static_bib_num += 1
5766 self.assertEqual(bibe.i_addr, in_addr)
5767 self.assertEqual(bibe.o_addr, out_addr)
5768 self.assertEqual(bibe.i_port, in_port)
5769 self.assertEqual(bibe.o_port, out_port)
5770 self.assertEqual(static_bib_num, 1)
5771
5772 self.vapi.nat64_add_del_static_bib(in_addr,
5773 out_addr,
5774 in_port,
5775 out_port,
5776 proto,
5777 is_add=0)
5778 bib = self.vapi.nat64_bib_dump(IP_PROTOS.tcp)
5779 static_bib_num = 0
5780 for bibe in bib:
5781 if bibe.is_static:
5782 static_bib_num += 1
5783 self.assertEqual(static_bib_num, 0)
5784
5785 def test_set_timeouts(self):
5786 """ Set NAT64 timeouts """
5787 # verify default values
5788 timeouts = self.vapi.nat64_get_timeouts()
5789 self.assertEqual(timeouts.udp, 300)
5790 self.assertEqual(timeouts.icmp, 60)
5791 self.assertEqual(timeouts.tcp_trans, 240)
5792 self.assertEqual(timeouts.tcp_est, 7440)
5793 self.assertEqual(timeouts.tcp_incoming_syn, 6)
5794
5795 # set and verify custom values
5796 self.vapi.nat64_set_timeouts(udp=200, icmp=30, tcp_trans=250,
5797 tcp_est=7450, tcp_incoming_syn=10)
5798 timeouts = self.vapi.nat64_get_timeouts()
5799 self.assertEqual(timeouts.udp, 200)
5800 self.assertEqual(timeouts.icmp, 30)
5801 self.assertEqual(timeouts.tcp_trans, 250)
5802 self.assertEqual(timeouts.tcp_est, 7450)
5803 self.assertEqual(timeouts.tcp_incoming_syn, 10)
5804
5805 def test_dynamic(self):
5806 """ NAT64 dynamic translation test """
5807 self.tcp_port_in = 6303
5808 self.udp_port_in = 6304
5809 self.icmp_id_in = 6305
5810
5811 ses_num_start = self.nat64_get_ses_num()
5812
5813 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
5814 self.nat_addr_n)
5815 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
5816 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
5817
5818 # in2out
5819 pkts = self.create_stream_in_ip6(self.pg0, self.pg1)
5820 self.pg0.add_stream(pkts)
5821 self.pg_enable_capture(self.pg_interfaces)
5822 self.pg_start()
Matus Fabian029f3d22017-06-15 02:28:50 -07005823 capture = self.pg1.get_capture(len(pkts))
5824 self.verify_capture_out(capture, nat_ip=self.nat_addr,
Matus Fabian06596c52017-06-06 04:53:28 -07005825 dst_ip=self.pg1.remote_ip4)
5826
5827 # out2in
5828 pkts = self.create_stream_out(self.pg1, dst_ip=self.nat_addr)
5829 self.pg1.add_stream(pkts)
5830 self.pg_enable_capture(self.pg_interfaces)
5831 self.pg_start()
Matus Fabian029f3d22017-06-15 02:28:50 -07005832 capture = self.pg0.get_capture(len(pkts))
Matus Fabian06596c52017-06-06 04:53:28 -07005833 ip = IPv6(src=''.join(['64:ff9b::', self.pg1.remote_ip4]))
5834 self.verify_capture_in_ip6(capture, ip[IPv6].src, self.pg0.remote_ip6)
5835
5836 # in2out
5837 pkts = self.create_stream_in_ip6(self.pg0, self.pg1)
5838 self.pg0.add_stream(pkts)
5839 self.pg_enable_capture(self.pg_interfaces)
5840 self.pg_start()
Matus Fabian029f3d22017-06-15 02:28:50 -07005841 capture = self.pg1.get_capture(len(pkts))
5842 self.verify_capture_out(capture, nat_ip=self.nat_addr,
Matus Fabian06596c52017-06-06 04:53:28 -07005843 dst_ip=self.pg1.remote_ip4)
5844
5845 # out2in
5846 pkts = self.create_stream_out(self.pg1, dst_ip=self.nat_addr)
5847 self.pg1.add_stream(pkts)
5848 self.pg_enable_capture(self.pg_interfaces)
5849 self.pg_start()
Matus Fabian029f3d22017-06-15 02:28:50 -07005850 capture = self.pg0.get_capture(len(pkts))
Matus Fabian06596c52017-06-06 04:53:28 -07005851 self.verify_capture_in_ip6(capture, ip[IPv6].src, self.pg0.remote_ip6)
5852
5853 ses_num_end = self.nat64_get_ses_num()
5854
5855 self.assertEqual(ses_num_end - ses_num_start, 3)
5856
Matus Fabian029f3d22017-06-15 02:28:50 -07005857 # tenant with specific VRF
5858 self.vapi.nat64_add_del_pool_addr_range(self.vrf1_nat_addr_n,
5859 self.vrf1_nat_addr_n,
5860 vrf_id=self.vrf1_id)
5861 self.vapi.nat64_add_del_interface(self.pg2.sw_if_index)
5862
5863 pkts = self.create_stream_in_ip6(self.pg2, self.pg1)
5864 self.pg2.add_stream(pkts)
5865 self.pg_enable_capture(self.pg_interfaces)
5866 self.pg_start()
5867 capture = self.pg1.get_capture(len(pkts))
5868 self.verify_capture_out(capture, nat_ip=self.vrf1_nat_addr,
5869 dst_ip=self.pg1.remote_ip4)
5870
5871 pkts = self.create_stream_out(self.pg1, dst_ip=self.vrf1_nat_addr)
5872 self.pg1.add_stream(pkts)
5873 self.pg_enable_capture(self.pg_interfaces)
5874 self.pg_start()
5875 capture = self.pg2.get_capture(len(pkts))
5876 self.verify_capture_in_ip6(capture, ip[IPv6].src, self.pg2.remote_ip6)
5877
Matus Fabian06596c52017-06-06 04:53:28 -07005878 def test_static(self):
5879 """ NAT64 static translation test """
5880 self.tcp_port_in = 60303
5881 self.udp_port_in = 60304
5882 self.icmp_id_in = 60305
5883 self.tcp_port_out = 60303
5884 self.udp_port_out = 60304
5885 self.icmp_id_out = 60305
5886
5887 ses_num_start = self.nat64_get_ses_num()
5888
5889 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
5890 self.nat_addr_n)
5891 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
5892 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
5893
5894 self.vapi.nat64_add_del_static_bib(self.pg0.remote_ip6n,
5895 self.nat_addr_n,
5896 self.tcp_port_in,
5897 self.tcp_port_out,
5898 IP_PROTOS.tcp)
5899 self.vapi.nat64_add_del_static_bib(self.pg0.remote_ip6n,
5900 self.nat_addr_n,
5901 self.udp_port_in,
5902 self.udp_port_out,
5903 IP_PROTOS.udp)
5904 self.vapi.nat64_add_del_static_bib(self.pg0.remote_ip6n,
5905 self.nat_addr_n,
5906 self.icmp_id_in,
5907 self.icmp_id_out,
5908 IP_PROTOS.icmp)
5909
5910 # in2out
5911 pkts = self.create_stream_in_ip6(self.pg0, self.pg1)
5912 self.pg0.add_stream(pkts)
5913 self.pg_enable_capture(self.pg_interfaces)
5914 self.pg_start()
Matus Fabian029f3d22017-06-15 02:28:50 -07005915 capture = self.pg1.get_capture(len(pkts))
5916 self.verify_capture_out(capture, nat_ip=self.nat_addr,
Matus Fabian06596c52017-06-06 04:53:28 -07005917 dst_ip=self.pg1.remote_ip4, same_port=True)
5918
5919 # out2in
5920 pkts = self.create_stream_out(self.pg1, dst_ip=self.nat_addr)
5921 self.pg1.add_stream(pkts)
5922 self.pg_enable_capture(self.pg_interfaces)
5923 self.pg_start()
Matus Fabian029f3d22017-06-15 02:28:50 -07005924 capture = self.pg0.get_capture(len(pkts))
Matus Fabian06596c52017-06-06 04:53:28 -07005925 ip = IPv6(src=''.join(['64:ff9b::', self.pg1.remote_ip4]))
5926 self.verify_capture_in_ip6(capture, ip[IPv6].src, self.pg0.remote_ip6)
5927
5928 ses_num_end = self.nat64_get_ses_num()
5929
5930 self.assertEqual(ses_num_end - ses_num_start, 3)
5931
5932 @unittest.skipUnless(running_extended_tests(), "part of extended tests")
5933 def test_session_timeout(self):
5934 """ NAT64 session timeout """
5935 self.icmp_id_in = 1234
5936 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
5937 self.nat_addr_n)
5938 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
5939 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
5940 self.vapi.nat64_set_timeouts(icmp=5)
5941
5942 pkts = self.create_stream_in_ip6(self.pg0, self.pg1)
5943 self.pg0.add_stream(pkts)
5944 self.pg_enable_capture(self.pg_interfaces)
5945 self.pg_start()
Matus Fabian029f3d22017-06-15 02:28:50 -07005946 capture = self.pg1.get_capture(len(pkts))
Matus Fabian06596c52017-06-06 04:53:28 -07005947
5948 ses_num_before_timeout = self.nat64_get_ses_num()
5949
5950 sleep(15)
5951
5952 # ICMP session after timeout
5953 ses_num_after_timeout = self.nat64_get_ses_num()
5954 self.assertNotEqual(ses_num_before_timeout, ses_num_after_timeout)
5955
Matus Fabian732036d2017-06-08 05:24:28 -07005956 def test_icmp_error(self):
5957 """ NAT64 ICMP Error message translation """
5958 self.tcp_port_in = 6303
5959 self.udp_port_in = 6304
5960 self.icmp_id_in = 6305
5961
Matus Fabian732036d2017-06-08 05:24:28 -07005962 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
5963 self.nat_addr_n)
5964 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
5965 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
5966
5967 # send some packets to create sessions
5968 pkts = self.create_stream_in_ip6(self.pg0, self.pg1)
5969 self.pg0.add_stream(pkts)
5970 self.pg_enable_capture(self.pg_interfaces)
5971 self.pg_start()
5972 capture_ip4 = self.pg1.get_capture(len(pkts))
Matus Fabian029f3d22017-06-15 02:28:50 -07005973 self.verify_capture_out(capture_ip4,
Matus Fabian732036d2017-06-08 05:24:28 -07005974 nat_ip=self.nat_addr,
5975 dst_ip=self.pg1.remote_ip4)
5976
5977 pkts = self.create_stream_out(self.pg1, dst_ip=self.nat_addr)
5978 self.pg1.add_stream(pkts)
5979 self.pg_enable_capture(self.pg_interfaces)
5980 self.pg_start()
5981 capture_ip6 = self.pg0.get_capture(len(pkts))
5982 ip = IPv6(src=''.join(['64:ff9b::', self.pg1.remote_ip4]))
5983 self.verify_capture_in_ip6(capture_ip6, ip[IPv6].src,
5984 self.pg0.remote_ip6)
5985
5986 # in2out
5987 pkts = [Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
5988 IPv6(src=self.pg0.remote_ip6, dst=ip[IPv6].src) /
5989 ICMPv6DestUnreach(code=1) /
5990 packet[IPv6] for packet in capture_ip6]
5991 self.pg0.add_stream(pkts)
5992 self.pg_enable_capture(self.pg_interfaces)
5993 self.pg_start()
5994 capture = self.pg1.get_capture(len(pkts))
5995 for packet in capture:
5996 try:
5997 self.assertEqual(packet[IP].src, self.nat_addr)
5998 self.assertEqual(packet[IP].dst, self.pg1.remote_ip4)
5999 self.assertEqual(packet[ICMP].type, 3)
6000 self.assertEqual(packet[ICMP].code, 13)
6001 inner = packet[IPerror]
6002 self.assertEqual(inner.src, self.pg1.remote_ip4)
6003 self.assertEqual(inner.dst, self.nat_addr)
Klement Sekerad81ae412018-05-16 10:52:54 +02006004 self.assert_packet_checksums_valid(packet)
Matus Fabian732036d2017-06-08 05:24:28 -07006005 if inner.haslayer(TCPerror):
6006 self.assertEqual(inner[TCPerror].dport, self.tcp_port_out)
6007 elif inner.haslayer(UDPerror):
6008 self.assertEqual(inner[UDPerror].dport, self.udp_port_out)
6009 else:
6010 self.assertEqual(inner[ICMPerror].id, self.icmp_id_out)
6011 except:
6012 self.logger.error(ppp("Unexpected or invalid packet:", packet))
6013 raise
6014
6015 # out2in
6016 pkts = [Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
6017 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6018 ICMP(type=3, code=13) /
6019 packet[IP] for packet in capture_ip4]
6020 self.pg1.add_stream(pkts)
6021 self.pg_enable_capture(self.pg_interfaces)
6022 self.pg_start()
6023 capture = self.pg0.get_capture(len(pkts))
6024 for packet in capture:
6025 try:
6026 self.assertEqual(packet[IPv6].src, ip.src)
6027 self.assertEqual(packet[IPv6].dst, self.pg0.remote_ip6)
6028 icmp = packet[ICMPv6DestUnreach]
6029 self.assertEqual(icmp.code, 1)
6030 inner = icmp[IPerror6]
6031 self.assertEqual(inner.src, self.pg0.remote_ip6)
6032 self.assertEqual(inner.dst, ip.src)
Klement Sekerad81ae412018-05-16 10:52:54 +02006033 self.assert_icmpv6_checksum_valid(packet)
Matus Fabian732036d2017-06-08 05:24:28 -07006034 if inner.haslayer(TCPerror):
6035 self.assertEqual(inner[TCPerror].sport, self.tcp_port_in)
6036 elif inner.haslayer(UDPerror):
6037 self.assertEqual(inner[UDPerror].sport, self.udp_port_in)
6038 else:
6039 self.assertEqual(inner[ICMPv6EchoRequest].id,
6040 self.icmp_id_in)
6041 except:
6042 self.logger.error(ppp("Unexpected or invalid packet:", packet))
6043 raise
6044
Matus Fabian029f3d22017-06-15 02:28:50 -07006045 def test_hairpinning(self):
6046 """ NAT64 hairpinning """
6047
6048 client = self.pg0.remote_hosts[0]
6049 server = self.pg0.remote_hosts[1]
6050 server_tcp_in_port = 22
6051 server_tcp_out_port = 4022
6052 server_udp_in_port = 23
6053 server_udp_out_port = 4023
6054 client_tcp_in_port = 1234
6055 client_udp_in_port = 1235
6056 client_tcp_out_port = 0
6057 client_udp_out_port = 0
6058 ip = IPv6(src=''.join(['64:ff9b::', self.nat_addr]))
6059 nat_addr_ip6 = ip.src
6060
6061 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
6062 self.nat_addr_n)
6063 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
6064 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
6065
6066 self.vapi.nat64_add_del_static_bib(server.ip6n,
6067 self.nat_addr_n,
6068 server_tcp_in_port,
6069 server_tcp_out_port,
6070 IP_PROTOS.tcp)
6071 self.vapi.nat64_add_del_static_bib(server.ip6n,
6072 self.nat_addr_n,
6073 server_udp_in_port,
6074 server_udp_out_port,
6075 IP_PROTOS.udp)
6076
6077 # client to server
6078 pkts = []
6079 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
6080 IPv6(src=client.ip6, dst=nat_addr_ip6) /
6081 TCP(sport=client_tcp_in_port, dport=server_tcp_out_port))
6082 pkts.append(p)
6083 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
6084 IPv6(src=client.ip6, dst=nat_addr_ip6) /
6085 UDP(sport=client_udp_in_port, dport=server_udp_out_port))
6086 pkts.append(p)
6087 self.pg0.add_stream(pkts)
6088 self.pg_enable_capture(self.pg_interfaces)
6089 self.pg_start()
6090 capture = self.pg0.get_capture(len(pkts))
6091 for packet in capture:
6092 try:
6093 self.assertEqual(packet[IPv6].src, nat_addr_ip6)
6094 self.assertEqual(packet[IPv6].dst, server.ip6)
Klement Sekerad81ae412018-05-16 10:52:54 +02006095 self.assert_packet_checksums_valid(packet)
Matus Fabian029f3d22017-06-15 02:28:50 -07006096 if packet.haslayer(TCP):
6097 self.assertNotEqual(packet[TCP].sport, client_tcp_in_port)
6098 self.assertEqual(packet[TCP].dport, server_tcp_in_port)
Matus Fabian029f3d22017-06-15 02:28:50 -07006099 client_tcp_out_port = packet[TCP].sport
6100 else:
6101 self.assertNotEqual(packet[UDP].sport, client_udp_in_port)
6102 self.assertEqual(packet[UDP].dport, server_udp_in_port)
Matus Fabian029f3d22017-06-15 02:28:50 -07006103 client_udp_out_port = packet[UDP].sport
6104 except:
6105 self.logger.error(ppp("Unexpected or invalid packet:", packet))
6106 raise
6107
6108 # server to client
6109 pkts = []
6110 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
6111 IPv6(src=server.ip6, dst=nat_addr_ip6) /
6112 TCP(sport=server_tcp_in_port, dport=client_tcp_out_port))
6113 pkts.append(p)
6114 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
6115 IPv6(src=server.ip6, dst=nat_addr_ip6) /
6116 UDP(sport=server_udp_in_port, dport=client_udp_out_port))
6117 pkts.append(p)
6118 self.pg0.add_stream(pkts)
6119 self.pg_enable_capture(self.pg_interfaces)
6120 self.pg_start()
6121 capture = self.pg0.get_capture(len(pkts))
6122 for packet in capture:
6123 try:
6124 self.assertEqual(packet[IPv6].src, nat_addr_ip6)
6125 self.assertEqual(packet[IPv6].dst, client.ip6)
Klement Sekerad81ae412018-05-16 10:52:54 +02006126 self.assert_packet_checksums_valid(packet)
Matus Fabian029f3d22017-06-15 02:28:50 -07006127 if packet.haslayer(TCP):
6128 self.assertEqual(packet[TCP].sport, server_tcp_out_port)
6129 self.assertEqual(packet[TCP].dport, client_tcp_in_port)
Matus Fabian029f3d22017-06-15 02:28:50 -07006130 else:
6131 self.assertEqual(packet[UDP].sport, server_udp_out_port)
6132 self.assertEqual(packet[UDP].dport, client_udp_in_port)
Matus Fabian029f3d22017-06-15 02:28:50 -07006133 except:
6134 self.logger.error(ppp("Unexpected or invalid packet:", packet))
6135 raise
6136
6137 # ICMP error
6138 pkts = []
6139 pkts = [Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
6140 IPv6(src=client.ip6, dst=nat_addr_ip6) /
6141 ICMPv6DestUnreach(code=1) /
6142 packet[IPv6] for packet in capture]
6143 self.pg0.add_stream(pkts)
6144 self.pg_enable_capture(self.pg_interfaces)
6145 self.pg_start()
6146 capture = self.pg0.get_capture(len(pkts))
6147 for packet in capture:
6148 try:
6149 self.assertEqual(packet[IPv6].src, nat_addr_ip6)
6150 self.assertEqual(packet[IPv6].dst, server.ip6)
6151 icmp = packet[ICMPv6DestUnreach]
6152 self.assertEqual(icmp.code, 1)
6153 inner = icmp[IPerror6]
6154 self.assertEqual(inner.src, server.ip6)
6155 self.assertEqual(inner.dst, nat_addr_ip6)
Klement Sekerad81ae412018-05-16 10:52:54 +02006156 self.assert_packet_checksums_valid(packet)
Matus Fabian029f3d22017-06-15 02:28:50 -07006157 if inner.haslayer(TCPerror):
6158 self.assertEqual(inner[TCPerror].sport, server_tcp_in_port)
6159 self.assertEqual(inner[TCPerror].dport,
6160 client_tcp_out_port)
6161 else:
6162 self.assertEqual(inner[UDPerror].sport, server_udp_in_port)
6163 self.assertEqual(inner[UDPerror].dport,
6164 client_udp_out_port)
6165 except:
6166 self.logger.error(ppp("Unexpected or invalid packet:", packet))
6167 raise
6168
Matus Fabian428dc912017-06-21 06:15:18 -07006169 def test_prefix(self):
6170 """ NAT64 Network-Specific Prefix """
6171
6172 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
6173 self.nat_addr_n)
6174 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
6175 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
6176 self.vapi.nat64_add_del_pool_addr_range(self.vrf1_nat_addr_n,
6177 self.vrf1_nat_addr_n,
6178 vrf_id=self.vrf1_id)
6179 self.vapi.nat64_add_del_interface(self.pg2.sw_if_index)
6180
6181 # Add global prefix
6182 global_pref64 = "2001:db8::"
6183 global_pref64_n = socket.inet_pton(socket.AF_INET6, global_pref64)
6184 global_pref64_len = 32
6185 self.vapi.nat64_add_del_prefix(global_pref64_n, global_pref64_len)
6186
6187 prefix = self.vapi.nat64_prefix_dump()
6188 self.assertEqual(len(prefix), 1)
6189 self.assertEqual(prefix[0].prefix, global_pref64_n)
6190 self.assertEqual(prefix[0].prefix_len, global_pref64_len)
6191 self.assertEqual(prefix[0].vrf_id, 0)
6192
6193 # Add tenant specific prefix
6194 vrf1_pref64 = "2001:db8:122:300::"
6195 vrf1_pref64_n = socket.inet_pton(socket.AF_INET6, vrf1_pref64)
6196 vrf1_pref64_len = 56
6197 self.vapi.nat64_add_del_prefix(vrf1_pref64_n,
6198 vrf1_pref64_len,
6199 vrf_id=self.vrf1_id)
6200 prefix = self.vapi.nat64_prefix_dump()
6201 self.assertEqual(len(prefix), 2)
6202
6203 # Global prefix
6204 pkts = self.create_stream_in_ip6(self.pg0,
6205 self.pg1,
6206 pref=global_pref64,
6207 plen=global_pref64_len)
6208 self.pg0.add_stream(pkts)
6209 self.pg_enable_capture(self.pg_interfaces)
6210 self.pg_start()
6211 capture = self.pg1.get_capture(len(pkts))
6212 self.verify_capture_out(capture, nat_ip=self.nat_addr,
6213 dst_ip=self.pg1.remote_ip4)
6214
6215 pkts = self.create_stream_out(self.pg1, dst_ip=self.nat_addr)
6216 self.pg1.add_stream(pkts)
6217 self.pg_enable_capture(self.pg_interfaces)
6218 self.pg_start()
6219 capture = self.pg0.get_capture(len(pkts))
6220 dst_ip = self.compose_ip6(self.pg1.remote_ip4,
6221 global_pref64,
6222 global_pref64_len)
6223 self.verify_capture_in_ip6(capture, dst_ip, self.pg0.remote_ip6)
6224
6225 # Tenant specific prefix
6226 pkts = self.create_stream_in_ip6(self.pg2,
6227 self.pg1,
6228 pref=vrf1_pref64,
6229 plen=vrf1_pref64_len)
6230 self.pg2.add_stream(pkts)
6231 self.pg_enable_capture(self.pg_interfaces)
6232 self.pg_start()
6233 capture = self.pg1.get_capture(len(pkts))
6234 self.verify_capture_out(capture, nat_ip=self.vrf1_nat_addr,
6235 dst_ip=self.pg1.remote_ip4)
6236
6237 pkts = self.create_stream_out(self.pg1, dst_ip=self.vrf1_nat_addr)
6238 self.pg1.add_stream(pkts)
6239 self.pg_enable_capture(self.pg_interfaces)
6240 self.pg_start()
6241 capture = self.pg2.get_capture(len(pkts))
6242 dst_ip = self.compose_ip6(self.pg1.remote_ip4,
6243 vrf1_pref64,
6244 vrf1_pref64_len)
6245 self.verify_capture_in_ip6(capture, dst_ip, self.pg2.remote_ip6)
6246
Matus Fabianf8cd5812017-07-11 03:55:02 -07006247 def test_unknown_proto(self):
Matus Fabian7968e6c2017-07-06 05:37:49 -07006248 """ NAT64 translate packet with unknown protocol """
6249
6250 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
6251 self.nat_addr_n)
6252 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
6253 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
6254 remote_ip6 = self.compose_ip6(self.pg1.remote_ip4, '64:ff9b::', 96)
6255
6256 # in2out
6257 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
6258 IPv6(src=self.pg0.remote_ip6, dst=remote_ip6) /
6259 TCP(sport=self.tcp_port_in, dport=20))
6260 self.pg0.add_stream(p)
6261 self.pg_enable_capture(self.pg_interfaces)
6262 self.pg_start()
6263 p = self.pg1.get_capture(1)
6264
6265 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
Matus Fabianf8cd5812017-07-11 03:55:02 -07006266 IPv6(src=self.pg0.remote_ip6, dst=remote_ip6, nh=47) /
Matus Fabian7968e6c2017-07-06 05:37:49 -07006267 GRE() /
6268 IP(src=self.pg2.local_ip4, dst=self.pg2.remote_ip4) /
6269 TCP(sport=1234, dport=1234))
6270 self.pg0.add_stream(p)
6271 self.pg_enable_capture(self.pg_interfaces)
6272 self.pg_start()
6273 p = self.pg1.get_capture(1)
6274 packet = p[0]
6275 try:
6276 self.assertEqual(packet[IP].src, self.nat_addr)
6277 self.assertEqual(packet[IP].dst, self.pg1.remote_ip4)
6278 self.assertTrue(packet.haslayer(GRE))
Klement Sekerad81ae412018-05-16 10:52:54 +02006279 self.assert_packet_checksums_valid(packet)
Matus Fabian7968e6c2017-07-06 05:37:49 -07006280 except:
6281 self.logger.error(ppp("Unexpected or invalid packet:", packet))
6282 raise
6283
6284 # out2in
6285 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
6286 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
6287 GRE() /
6288 IP(src=self.pg2.remote_ip4, dst=self.pg2.local_ip4) /
6289 TCP(sport=1234, dport=1234))
6290 self.pg1.add_stream(p)
6291 self.pg_enable_capture(self.pg_interfaces)
6292 self.pg_start()
6293 p = self.pg0.get_capture(1)
6294 packet = p[0]
6295 try:
6296 self.assertEqual(packet[IPv6].src, remote_ip6)
Matus Fabianf8cd5812017-07-11 03:55:02 -07006297 self.assertEqual(packet[IPv6].dst, self.pg0.remote_ip6)
6298 self.assertEqual(packet[IPv6].nh, 47)
Matus Fabian7968e6c2017-07-06 05:37:49 -07006299 except:
6300 self.logger.error(ppp("Unexpected or invalid packet:", packet))
6301 raise
6302
Matus Fabianf8cd5812017-07-11 03:55:02 -07006303 def test_hairpinning_unknown_proto(self):
Matus Fabian7968e6c2017-07-06 05:37:49 -07006304 """ NAT64 translate packet with unknown protocol - hairpinning """
6305
6306 client = self.pg0.remote_hosts[0]
6307 server = self.pg0.remote_hosts[1]
6308 server_tcp_in_port = 22
6309 server_tcp_out_port = 4022
6310 client_tcp_in_port = 1234
Matus Fabianf8cd5812017-07-11 03:55:02 -07006311 client_tcp_out_port = 1235
6312 server_nat_ip = "10.0.0.100"
6313 client_nat_ip = "10.0.0.110"
6314 server_nat_ip_n = socket.inet_pton(socket.AF_INET, server_nat_ip)
6315 client_nat_ip_n = socket.inet_pton(socket.AF_INET, client_nat_ip)
6316 server_nat_ip6 = self.compose_ip6(server_nat_ip, '64:ff9b::', 96)
6317 client_nat_ip6 = self.compose_ip6(client_nat_ip, '64:ff9b::', 96)
Matus Fabian7968e6c2017-07-06 05:37:49 -07006318
Matus Fabianf8cd5812017-07-11 03:55:02 -07006319 self.vapi.nat64_add_del_pool_addr_range(server_nat_ip_n,
6320 client_nat_ip_n)
Matus Fabian7968e6c2017-07-06 05:37:49 -07006321 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
6322 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
6323
6324 self.vapi.nat64_add_del_static_bib(server.ip6n,
Matus Fabianf8cd5812017-07-11 03:55:02 -07006325 server_nat_ip_n,
Matus Fabian7968e6c2017-07-06 05:37:49 -07006326 server_tcp_in_port,
6327 server_tcp_out_port,
6328 IP_PROTOS.tcp)
6329
Matus Fabianf8cd5812017-07-11 03:55:02 -07006330 self.vapi.nat64_add_del_static_bib(server.ip6n,
6331 server_nat_ip_n,
6332 0,
6333 0,
6334 IP_PROTOS.gre)
6335
6336 self.vapi.nat64_add_del_static_bib(client.ip6n,
6337 client_nat_ip_n,
6338 client_tcp_in_port,
6339 client_tcp_out_port,
6340 IP_PROTOS.tcp)
6341
Matus Fabian7968e6c2017-07-06 05:37:49 -07006342 # client to server
6343 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
Matus Fabianf8cd5812017-07-11 03:55:02 -07006344 IPv6(src=client.ip6, dst=server_nat_ip6) /
Matus Fabian7968e6c2017-07-06 05:37:49 -07006345 TCP(sport=client_tcp_in_port, dport=server_tcp_out_port))
6346 self.pg0.add_stream(p)
6347 self.pg_enable_capture(self.pg_interfaces)
6348 self.pg_start()
6349 p = self.pg0.get_capture(1)
6350
6351 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
Matus Fabianf8cd5812017-07-11 03:55:02 -07006352 IPv6(src=client.ip6, dst=server_nat_ip6, nh=IP_PROTOS.gre) /
Matus Fabian7968e6c2017-07-06 05:37:49 -07006353 GRE() /
6354 IP(src=self.pg2.local_ip4, dst=self.pg2.remote_ip4) /
6355 TCP(sport=1234, dport=1234))
6356 self.pg0.add_stream(p)
6357 self.pg_enable_capture(self.pg_interfaces)
6358 self.pg_start()
6359 p = self.pg0.get_capture(1)
6360 packet = p[0]
6361 try:
Matus Fabianf8cd5812017-07-11 03:55:02 -07006362 self.assertEqual(packet[IPv6].src, client_nat_ip6)
Matus Fabian7968e6c2017-07-06 05:37:49 -07006363 self.assertEqual(packet[IPv6].dst, server.ip6)
Matus Fabianf8cd5812017-07-11 03:55:02 -07006364 self.assertEqual(packet[IPv6].nh, IP_PROTOS.gre)
Matus Fabian7968e6c2017-07-06 05:37:49 -07006365 except:
6366 self.logger.error(ppp("Unexpected or invalid packet:", packet))
6367 raise
6368
6369 # server to client
6370 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
Matus Fabianf8cd5812017-07-11 03:55:02 -07006371 IPv6(src=server.ip6, dst=client_nat_ip6, nh=IP_PROTOS.gre) /
Matus Fabian7968e6c2017-07-06 05:37:49 -07006372 GRE() /
6373 IP(src=self.pg2.remote_ip4, dst=self.pg2.local_ip4) /
6374 TCP(sport=1234, dport=1234))
6375 self.pg0.add_stream(p)
6376 self.pg_enable_capture(self.pg_interfaces)
6377 self.pg_start()
6378 p = self.pg0.get_capture(1)
6379 packet = p[0]
6380 try:
Matus Fabianf8cd5812017-07-11 03:55:02 -07006381 self.assertEqual(packet[IPv6].src, server_nat_ip6)
Matus Fabian7968e6c2017-07-06 05:37:49 -07006382 self.assertEqual(packet[IPv6].dst, client.ip6)
Matus Fabianf8cd5812017-07-11 03:55:02 -07006383 self.assertEqual(packet[IPv6].nh, IP_PROTOS.gre)
Matus Fabian7968e6c2017-07-06 05:37:49 -07006384 except:
6385 self.logger.error(ppp("Unexpected or invalid packet:", packet))
6386 raise
6387
Matus Fabian36ea2d62017-10-24 04:13:49 -07006388 def test_one_armed_nat64(self):
6389 """ One armed NAT64 """
6390 external_port = 0
6391 remote_host_ip6 = self.compose_ip6(self.pg3.remote_ip4,
6392 '64:ff9b::',
6393 96)
6394
6395 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
6396 self.nat_addr_n)
6397 self.vapi.nat64_add_del_interface(self.pg3.sw_if_index)
6398 self.vapi.nat64_add_del_interface(self.pg3.sw_if_index, is_inside=0)
6399
6400 # in2out
6401 p = (Ether(src=self.pg3.remote_mac, dst=self.pg3.local_mac) /
6402 IPv6(src=self.pg3.remote_ip6, dst=remote_host_ip6) /
6403 TCP(sport=12345, dport=80))
6404 self.pg3.add_stream(p)
6405 self.pg_enable_capture(self.pg_interfaces)
6406 self.pg_start()
6407 capture = self.pg3.get_capture(1)
6408 p = capture[0]
6409 try:
6410 ip = p[IP]
6411 tcp = p[TCP]
6412 self.assertEqual(ip.src, self.nat_addr)
6413 self.assertEqual(ip.dst, self.pg3.remote_ip4)
6414 self.assertNotEqual(tcp.sport, 12345)
6415 external_port = tcp.sport
6416 self.assertEqual(tcp.dport, 80)
Klement Sekerad81ae412018-05-16 10:52:54 +02006417 self.assert_packet_checksums_valid(p)
Matus Fabian36ea2d62017-10-24 04:13:49 -07006418 except:
6419 self.logger.error(ppp("Unexpected or invalid packet:", p))
6420 raise
6421
6422 # out2in
6423 p = (Ether(src=self.pg3.remote_mac, dst=self.pg3.local_mac) /
6424 IP(src=self.pg3.remote_ip4, dst=self.nat_addr) /
6425 TCP(sport=80, dport=external_port))
6426 self.pg3.add_stream(p)
6427 self.pg_enable_capture(self.pg_interfaces)
6428 self.pg_start()
6429 capture = self.pg3.get_capture(1)
6430 p = capture[0]
6431 try:
6432 ip = p[IPv6]
6433 tcp = p[TCP]
6434 self.assertEqual(ip.src, remote_host_ip6)
6435 self.assertEqual(ip.dst, self.pg3.remote_ip6)
6436 self.assertEqual(tcp.sport, 80)
6437 self.assertEqual(tcp.dport, 12345)
Klement Sekerad81ae412018-05-16 10:52:54 +02006438 self.assert_packet_checksums_valid(p)
Matus Fabian36ea2d62017-10-24 04:13:49 -07006439 except:
6440 self.logger.error(ppp("Unexpected or invalid packet:", p))
6441 raise
6442
Matus Fabianefcd1e92017-08-15 06:59:19 -07006443 def test_frag_in_order(self):
6444 """ NAT64 translate fragments arriving in order """
6445 self.tcp_port_in = random.randint(1025, 65535)
6446
6447 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
6448 self.nat_addr_n)
6449 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
6450 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
6451
6452 reass = self.vapi.nat_reass_dump()
6453 reass_n_start = len(reass)
6454
6455 # in2out
6456 data = 'a' * 200
6457 pkts = self.create_stream_frag_ip6(self.pg0, self.pg1.remote_ip4,
6458 self.tcp_port_in, 20, data)
6459 self.pg0.add_stream(pkts)
6460 self.pg_enable_capture(self.pg_interfaces)
6461 self.pg_start()
6462 frags = self.pg1.get_capture(len(pkts))
6463 p = self.reass_frags_and_verify(frags,
6464 self.nat_addr,
6465 self.pg1.remote_ip4)
6466 self.assertEqual(p[TCP].dport, 20)
6467 self.assertNotEqual(p[TCP].sport, self.tcp_port_in)
6468 self.tcp_port_out = p[TCP].sport
6469 self.assertEqual(data, p[Raw].load)
6470
6471 # out2in
6472 data = "A" * 4 + "b" * 16 + "C" * 3
6473 pkts = self.create_stream_frag(self.pg1,
6474 self.nat_addr,
6475 20,
6476 self.tcp_port_out,
6477 data)
6478 self.pg1.add_stream(pkts)
6479 self.pg_enable_capture(self.pg_interfaces)
6480 self.pg_start()
6481 frags = self.pg0.get_capture(len(pkts))
6482 src = self.compose_ip6(self.pg1.remote_ip4, '64:ff9b::', 96)
6483 p = self.reass_frags_and_verify_ip6(frags, src, self.pg0.remote_ip6)
6484 self.assertEqual(p[TCP].sport, 20)
6485 self.assertEqual(p[TCP].dport, self.tcp_port_in)
6486 self.assertEqual(data, p[Raw].load)
6487
6488 reass = self.vapi.nat_reass_dump()
6489 reass_n_end = len(reass)
6490
6491 self.assertEqual(reass_n_end - reass_n_start, 2)
6492
6493 def test_reass_hairpinning(self):
6494 """ NAT64 fragments hairpinning """
6495 data = 'a' * 200
Matus Fabianefcd1e92017-08-15 06:59:19 -07006496 server = self.pg0.remote_hosts[1]
6497 server_in_port = random.randint(1025, 65535)
6498 server_out_port = random.randint(1025, 65535)
6499 client_in_port = random.randint(1025, 65535)
6500 ip = IPv6(src=''.join(['64:ff9b::', self.nat_addr]))
6501 nat_addr_ip6 = ip.src
6502
6503 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
6504 self.nat_addr_n)
6505 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
6506 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
6507
6508 # add static BIB entry for server
6509 self.vapi.nat64_add_del_static_bib(server.ip6n,
6510 self.nat_addr_n,
6511 server_in_port,
6512 server_out_port,
6513 IP_PROTOS.tcp)
6514
6515 # send packet from host to server
6516 pkts = self.create_stream_frag_ip6(self.pg0,
6517 self.nat_addr,
6518 client_in_port,
6519 server_out_port,
6520 data)
6521 self.pg0.add_stream(pkts)
6522 self.pg_enable_capture(self.pg_interfaces)
6523 self.pg_start()
6524 frags = self.pg0.get_capture(len(pkts))
6525 p = self.reass_frags_and_verify_ip6(frags, nat_addr_ip6, server.ip6)
6526 self.assertNotEqual(p[TCP].sport, client_in_port)
6527 self.assertEqual(p[TCP].dport, server_in_port)
6528 self.assertEqual(data, p[Raw].load)
6529
6530 def test_frag_out_of_order(self):
6531 """ NAT64 translate fragments arriving out of order """
6532 self.tcp_port_in = random.randint(1025, 65535)
6533
6534 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
6535 self.nat_addr_n)
6536 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
6537 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
6538
6539 # in2out
6540 data = 'a' * 200
6541 pkts = self.create_stream_frag_ip6(self.pg0, self.pg1.remote_ip4,
6542 self.tcp_port_in, 20, data)
6543 pkts.reverse()
6544 self.pg0.add_stream(pkts)
6545 self.pg_enable_capture(self.pg_interfaces)
6546 self.pg_start()
6547 frags = self.pg1.get_capture(len(pkts))
6548 p = self.reass_frags_and_verify(frags,
6549 self.nat_addr,
6550 self.pg1.remote_ip4)
6551 self.assertEqual(p[TCP].dport, 20)
6552 self.assertNotEqual(p[TCP].sport, self.tcp_port_in)
6553 self.tcp_port_out = p[TCP].sport
6554 self.assertEqual(data, p[Raw].load)
6555
6556 # out2in
6557 data = "A" * 4 + "B" * 16 + "C" * 3
6558 pkts = self.create_stream_frag(self.pg1,
6559 self.nat_addr,
6560 20,
6561 self.tcp_port_out,
6562 data)
6563 pkts.reverse()
6564 self.pg1.add_stream(pkts)
6565 self.pg_enable_capture(self.pg_interfaces)
6566 self.pg_start()
6567 frags = self.pg0.get_capture(len(pkts))
6568 src = self.compose_ip6(self.pg1.remote_ip4, '64:ff9b::', 96)
6569 p = self.reass_frags_and_verify_ip6(frags, src, self.pg0.remote_ip6)
6570 self.assertEqual(p[TCP].sport, 20)
6571 self.assertEqual(p[TCP].dport, self.tcp_port_in)
6572 self.assertEqual(data, p[Raw].load)
6573
Matus Fabian0938dcf2017-11-08 01:59:38 -08006574 def test_interface_addr(self):
6575 """ Acquire NAT64 pool addresses from interface """
6576 self.vapi.nat64_add_interface_addr(self.pg4.sw_if_index)
6577
6578 # no address in NAT64 pool
6579 adresses = self.vapi.nat44_address_dump()
6580 self.assertEqual(0, len(adresses))
6581
6582 # configure interface address and check NAT64 address pool
6583 self.pg4.config_ip4()
6584 addresses = self.vapi.nat64_pool_addr_dump()
6585 self.assertEqual(len(addresses), 1)
6586 self.assertEqual(addresses[0].address, self.pg4.local_ip4n)
6587
6588 # remove interface address and check NAT64 address pool
6589 self.pg4.unconfig_ip4()
6590 addresses = self.vapi.nat64_pool_addr_dump()
6591 self.assertEqual(0, len(adresses))
6592
Matus Fabiana431ad12018-01-04 04:03:14 -08006593 @unittest.skipUnless(running_extended_tests(), "part of extended tests")
6594 def test_ipfix_max_bibs_sessions(self):
6595 """ IPFIX logging maximum session and BIB entries exceeded """
6596 max_bibs = 1280
6597 max_sessions = 2560
6598 remote_host_ip6 = self.compose_ip6(self.pg1.remote_ip4,
6599 '64:ff9b::',
6600 96)
6601
6602 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
6603 self.nat_addr_n)
6604 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
6605 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
6606
6607 pkts = []
6608 src = ""
6609 for i in range(0, max_bibs):
6610 src = "fd01:aa::%x" % (i)
6611 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6612 IPv6(src=src, dst=remote_host_ip6) /
6613 TCP(sport=12345, dport=80))
6614 pkts.append(p)
6615 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6616 IPv6(src=src, dst=remote_host_ip6) /
6617 TCP(sport=12345, dport=22))
6618 pkts.append(p)
6619 self.pg0.add_stream(pkts)
6620 self.pg_enable_capture(self.pg_interfaces)
6621 self.pg_start()
6622 self.pg1.get_capture(max_sessions)
6623
6624 self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4n,
6625 src_address=self.pg3.local_ip4n,
6626 path_mtu=512,
6627 template_interval=10)
6628 self.vapi.nat_ipfix(domain_id=self.ipfix_domain_id,
6629 src_port=self.ipfix_src_port)
6630
6631 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6632 IPv6(src=src, dst=remote_host_ip6) /
6633 TCP(sport=12345, dport=25))
6634 self.pg0.add_stream(p)
6635 self.pg_enable_capture(self.pg_interfaces)
6636 self.pg_start()
Matus Fabian229c1aa2018-05-28 04:09:52 -07006637 self.pg1.assert_nothing_captured()
6638 sleep(1)
Matus Fabiana431ad12018-01-04 04:03:14 -08006639 self.vapi.cli("ipfix flush") # FIXME this should be an API call
6640 capture = self.pg3.get_capture(9)
6641 ipfix = IPFIXDecoder()
6642 # first load template
6643 for p in capture:
6644 self.assertTrue(p.haslayer(IPFIX))
6645 self.assertEqual(p[IP].src, self.pg3.local_ip4)
6646 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
6647 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
6648 self.assertEqual(p[UDP].dport, 4739)
6649 self.assertEqual(p[IPFIX].observationDomainID,
6650 self.ipfix_domain_id)
6651 if p.haslayer(Template):
6652 ipfix.add_template(p.getlayer(Template))
6653 # verify events in data set
6654 for p in capture:
6655 if p.haslayer(Data):
6656 data = ipfix.decode_data_set(p.getlayer(Set))
6657 self.verify_ipfix_max_sessions(data, max_sessions)
6658
6659 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6660 IPv6(src=self.pg0.remote_ip6, dst=remote_host_ip6) /
6661 TCP(sport=12345, dport=80))
6662 self.pg0.add_stream(p)
6663 self.pg_enable_capture(self.pg_interfaces)
6664 self.pg_start()
Matus Fabian229c1aa2018-05-28 04:09:52 -07006665 self.pg1.assert_nothing_captured()
6666 sleep(1)
Matus Fabiana431ad12018-01-04 04:03:14 -08006667 self.vapi.cli("ipfix flush") # FIXME this should be an API call
6668 capture = self.pg3.get_capture(1)
6669 # verify events in data set
6670 for p in capture:
6671 self.assertTrue(p.haslayer(IPFIX))
6672 self.assertEqual(p[IP].src, self.pg3.local_ip4)
6673 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
6674 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
6675 self.assertEqual(p[UDP].dport, 4739)
6676 self.assertEqual(p[IPFIX].observationDomainID,
6677 self.ipfix_domain_id)
6678 if p.haslayer(Data):
6679 data = ipfix.decode_data_set(p.getlayer(Set))
6680 self.verify_ipfix_max_bibs(data, max_bibs)
6681
6682 def test_ipfix_max_frags(self):
6683 """ IPFIX logging maximum fragments pending reassembly exceeded """
6684 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
6685 self.nat_addr_n)
6686 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
6687 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
6688 self.vapi.nat_set_reass(max_frag=0, is_ip6=1)
6689 self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4n,
6690 src_address=self.pg3.local_ip4n,
6691 path_mtu=512,
6692 template_interval=10)
6693 self.vapi.nat_ipfix(domain_id=self.ipfix_domain_id,
6694 src_port=self.ipfix_src_port)
6695
6696 data = 'a' * 200
6697 pkts = self.create_stream_frag_ip6(self.pg0, self.pg1.remote_ip4,
6698 self.tcp_port_in, 20, data)
6699 self.pg0.add_stream(pkts[-1])
6700 self.pg_enable_capture(self.pg_interfaces)
6701 self.pg_start()
Matus Fabian229c1aa2018-05-28 04:09:52 -07006702 self.pg1.assert_nothing_captured()
6703 sleep(1)
Matus Fabiana431ad12018-01-04 04:03:14 -08006704 self.vapi.cli("ipfix flush") # FIXME this should be an API call
6705 capture = self.pg3.get_capture(9)
6706 ipfix = IPFIXDecoder()
6707 # first load template
6708 for p in capture:
6709 self.assertTrue(p.haslayer(IPFIX))
6710 self.assertEqual(p[IP].src, self.pg3.local_ip4)
6711 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
6712 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
6713 self.assertEqual(p[UDP].dport, 4739)
6714 self.assertEqual(p[IPFIX].observationDomainID,
6715 self.ipfix_domain_id)
6716 if p.haslayer(Template):
6717 ipfix.add_template(p.getlayer(Template))
6718 # verify events in data set
6719 for p in capture:
6720 if p.haslayer(Data):
6721 data = ipfix.decode_data_set(p.getlayer(Set))
6722 self.verify_ipfix_max_fragments_ip6(data, 0,
6723 self.pg0.remote_ip6n)
6724
6725 def test_ipfix_bib_ses(self):
6726 """ IPFIX logging NAT64 BIB/session create and delete events """
6727 self.tcp_port_in = random.randint(1025, 65535)
6728 remote_host_ip6 = self.compose_ip6(self.pg1.remote_ip4,
6729 '64:ff9b::',
6730 96)
6731
6732 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
6733 self.nat_addr_n)
6734 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
6735 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
6736 self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4n,
6737 src_address=self.pg3.local_ip4n,
6738 path_mtu=512,
6739 template_interval=10)
6740 self.vapi.nat_ipfix(domain_id=self.ipfix_domain_id,
6741 src_port=self.ipfix_src_port)
6742
6743 # Create
6744 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6745 IPv6(src=self.pg0.remote_ip6, dst=remote_host_ip6) /
6746 TCP(sport=self.tcp_port_in, dport=25))
6747 self.pg0.add_stream(p)
6748 self.pg_enable_capture(self.pg_interfaces)
6749 self.pg_start()
6750 p = self.pg1.get_capture(1)
6751 self.tcp_port_out = p[0][TCP].sport
6752 self.vapi.cli("ipfix flush") # FIXME this should be an API call
6753 capture = self.pg3.get_capture(10)
6754 ipfix = IPFIXDecoder()
6755 # first load template
6756 for p in capture:
6757 self.assertTrue(p.haslayer(IPFIX))
6758 self.assertEqual(p[IP].src, self.pg3.local_ip4)
6759 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
6760 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
6761 self.assertEqual(p[UDP].dport, 4739)
6762 self.assertEqual(p[IPFIX].observationDomainID,
6763 self.ipfix_domain_id)
6764 if p.haslayer(Template):
6765 ipfix.add_template(p.getlayer(Template))
6766 # verify events in data set
6767 for p in capture:
6768 if p.haslayer(Data):
6769 data = ipfix.decode_data_set(p.getlayer(Set))
6770 if ord(data[0][230]) == 10:
6771 self.verify_ipfix_bib(data, 1, self.pg0.remote_ip6n)
6772 elif ord(data[0][230]) == 6:
6773 self.verify_ipfix_nat64_ses(data,
6774 1,
6775 self.pg0.remote_ip6n,
6776 self.pg1.remote_ip4,
6777 25)
6778 else:
6779 self.logger.error(ppp("Unexpected or invalid packet: ", p))
6780
6781 # Delete
6782 self.pg_enable_capture(self.pg_interfaces)
6783 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
6784 self.nat_addr_n,
6785 is_add=0)
6786 self.vapi.cli("ipfix flush") # FIXME this should be an API call
6787 capture = self.pg3.get_capture(2)
6788 # verify events in data set
6789 for p in capture:
6790 self.assertTrue(p.haslayer(IPFIX))
6791 self.assertEqual(p[IP].src, self.pg3.local_ip4)
6792 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
6793 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
6794 self.assertEqual(p[UDP].dport, 4739)
6795 self.assertEqual(p[IPFIX].observationDomainID,
6796 self.ipfix_domain_id)
6797 if p.haslayer(Data):
6798 data = ipfix.decode_data_set(p.getlayer(Set))
6799 if ord(data[0][230]) == 11:
6800 self.verify_ipfix_bib(data, 0, self.pg0.remote_ip6n)
6801 elif ord(data[0][230]) == 7:
6802 self.verify_ipfix_nat64_ses(data,
6803 0,
6804 self.pg0.remote_ip6n,
6805 self.pg1.remote_ip4,
6806 25)
6807 else:
6808 self.logger.error(ppp("Unexpected or invalid packet: ", p))
6809
Matus Fabian06596c52017-06-06 04:53:28 -07006810 def nat64_get_ses_num(self):
6811 """
6812 Return number of active NAT64 sessions.
6813 """
Matus Fabianab9a59c2017-08-16 05:37:36 -07006814 st = self.vapi.nat64_st_dump()
6815 return len(st)
Matus Fabian06596c52017-06-06 04:53:28 -07006816
6817 def clear_nat64(self):
6818 """
6819 Clear NAT64 configuration.
6820 """
Matus Fabiana431ad12018-01-04 04:03:14 -08006821 self.vapi.nat_ipfix(enable=0, src_port=self.ipfix_src_port,
6822 domain_id=self.ipfix_domain_id)
6823 self.ipfix_src_port = 4739
6824 self.ipfix_domain_id = 1
6825
Matus Fabian06596c52017-06-06 04:53:28 -07006826 self.vapi.nat64_set_timeouts()
6827
6828 interfaces = self.vapi.nat64_interface_dump()
6829 for intf in interfaces:
Matus Fabian36ea2d62017-10-24 04:13:49 -07006830 if intf.is_inside > 1:
6831 self.vapi.nat64_add_del_interface(intf.sw_if_index,
6832 0,
6833 is_add=0)
Matus Fabian06596c52017-06-06 04:53:28 -07006834 self.vapi.nat64_add_del_interface(intf.sw_if_index,
6835 intf.is_inside,
6836 is_add=0)
6837
Matus Fabiana431ad12018-01-04 04:03:14 -08006838 bib = self.vapi.nat64_bib_dump(255)
Matus Fabian06596c52017-06-06 04:53:28 -07006839 for bibe in bib:
6840 if bibe.is_static:
6841 self.vapi.nat64_add_del_static_bib(bibe.i_addr,
6842 bibe.o_addr,
6843 bibe.i_port,
6844 bibe.o_port,
6845 bibe.proto,
6846 bibe.vrf_id,
6847 is_add=0)
6848
6849 adresses = self.vapi.nat64_pool_addr_dump()
6850 for addr in adresses:
6851 self.vapi.nat64_add_del_pool_addr_range(addr.address,
6852 addr.address,
Matus Fabian029f3d22017-06-15 02:28:50 -07006853 vrf_id=addr.vrf_id,
Matus Fabian06596c52017-06-06 04:53:28 -07006854 is_add=0)
6855
Matus Fabian428dc912017-06-21 06:15:18 -07006856 prefixes = self.vapi.nat64_prefix_dump()
6857 for prefix in prefixes:
6858 self.vapi.nat64_add_del_prefix(prefix.prefix,
6859 prefix.prefix_len,
6860 vrf_id=prefix.vrf_id,
6861 is_add=0)
6862
Matus Fabian06596c52017-06-06 04:53:28 -07006863 def tearDown(self):
6864 super(TestNAT64, self).tearDown()
6865 if not self.vpp_dead:
6866 self.logger.info(self.vapi.cli("show nat64 pool"))
6867 self.logger.info(self.vapi.cli("show nat64 interfaces"))
Matus Fabian428dc912017-06-21 06:15:18 -07006868 self.logger.info(self.vapi.cli("show nat64 prefix"))
Matus Fabianab9a59c2017-08-16 05:37:36 -07006869 self.logger.info(self.vapi.cli("show nat64 bib all"))
6870 self.logger.info(self.vapi.cli("show nat64 session table all"))
Matus Fabianefcd1e92017-08-15 06:59:19 -07006871 self.logger.info(self.vapi.cli("show nat virtual-reassembly"))
Matus Fabian06596c52017-06-06 04:53:28 -07006872 self.clear_nat64()
6873
Matus Fabian8ebe6252017-11-06 05:04:53 -08006874
6875class TestDSlite(MethodHolder):
6876 """ DS-Lite Test Cases """
6877
6878 @classmethod
6879 def setUpClass(cls):
6880 super(TestDSlite, cls).setUpClass()
6881
6882 try:
6883 cls.nat_addr = '10.0.0.3'
6884 cls.nat_addr_n = socket.inet_pton(socket.AF_INET, cls.nat_addr)
6885
6886 cls.create_pg_interfaces(range(2))
6887 cls.pg0.admin_up()
6888 cls.pg0.config_ip4()
6889 cls.pg0.resolve_arp()
6890 cls.pg1.admin_up()
6891 cls.pg1.config_ip6()
6892 cls.pg1.generate_remote_hosts(2)
6893 cls.pg1.configure_ipv6_neighbors()
6894
6895 except Exception:
6896 super(TestDSlite, cls).tearDownClass()
6897 raise
6898
6899 def test_dslite(self):
6900 """ Test DS-Lite """
6901 self.vapi.dslite_add_del_pool_addr_range(self.nat_addr_n,
6902 self.nat_addr_n)
6903 aftr_ip4 = '192.0.0.1'
6904 aftr_ip4_n = socket.inet_pton(socket.AF_INET, aftr_ip4)
6905 aftr_ip6 = '2001:db8:85a3::8a2e:370:1'
6906 aftr_ip6_n = socket.inet_pton(socket.AF_INET6, aftr_ip6)
6907 self.vapi.dslite_set_aftr_addr(aftr_ip6_n, aftr_ip4_n)
6908
6909 # UDP
6910 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
6911 IPv6(dst=aftr_ip6, src=self.pg1.remote_hosts[0].ip6) /
6912 IP(dst=self.pg0.remote_ip4, src='192.168.1.1') /
6913 UDP(sport=20000, dport=10000))
6914 self.pg1.add_stream(p)
6915 self.pg_enable_capture(self.pg_interfaces)
6916 self.pg_start()
6917 capture = self.pg0.get_capture(1)
6918 capture = capture[0]
6919 self.assertFalse(capture.haslayer(IPv6))
6920 self.assertEqual(capture[IP].src, self.nat_addr)
6921 self.assertEqual(capture[IP].dst, self.pg0.remote_ip4)
6922 self.assertNotEqual(capture[UDP].sport, 20000)
6923 self.assertEqual(capture[UDP].dport, 10000)
Klement Sekerad81ae412018-05-16 10:52:54 +02006924 self.assert_packet_checksums_valid(capture)
Matus Fabian8ebe6252017-11-06 05:04:53 -08006925 out_port = capture[UDP].sport
6926
6927 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
6928 IP(dst=self.nat_addr, src=self.pg0.remote_ip4) /
6929 UDP(sport=10000, dport=out_port))
6930 self.pg0.add_stream(p)
6931 self.pg_enable_capture(self.pg_interfaces)
6932 self.pg_start()
6933 capture = self.pg1.get_capture(1)
6934 capture = capture[0]
6935 self.assertEqual(capture[IPv6].src, aftr_ip6)
6936 self.assertEqual(capture[IPv6].dst, self.pg1.remote_hosts[0].ip6)
6937 self.assertEqual(capture[IP].src, self.pg0.remote_ip4)
6938 self.assertEqual(capture[IP].dst, '192.168.1.1')
6939 self.assertEqual(capture[UDP].sport, 10000)
6940 self.assertEqual(capture[UDP].dport, 20000)
Klement Sekerad81ae412018-05-16 10:52:54 +02006941 self.assert_packet_checksums_valid(capture)
Matus Fabian8ebe6252017-11-06 05:04:53 -08006942
6943 # TCP
6944 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
6945 IPv6(dst=aftr_ip6, src=self.pg1.remote_hosts[1].ip6) /
6946 IP(dst=self.pg0.remote_ip4, src='192.168.1.1') /
6947 TCP(sport=20001, dport=10001))
6948 self.pg1.add_stream(p)
6949 self.pg_enable_capture(self.pg_interfaces)
6950 self.pg_start()
6951 capture = self.pg0.get_capture(1)
6952 capture = capture[0]
6953 self.assertFalse(capture.haslayer(IPv6))
6954 self.assertEqual(capture[IP].src, self.nat_addr)
6955 self.assertEqual(capture[IP].dst, self.pg0.remote_ip4)
6956 self.assertNotEqual(capture[TCP].sport, 20001)
6957 self.assertEqual(capture[TCP].dport, 10001)
Klement Sekerad81ae412018-05-16 10:52:54 +02006958 self.assert_packet_checksums_valid(capture)
Matus Fabian8ebe6252017-11-06 05:04:53 -08006959 out_port = capture[TCP].sport
6960
6961 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
6962 IP(dst=self.nat_addr, src=self.pg0.remote_ip4) /
6963 TCP(sport=10001, dport=out_port))
6964 self.pg0.add_stream(p)
6965 self.pg_enable_capture(self.pg_interfaces)
6966 self.pg_start()
6967 capture = self.pg1.get_capture(1)
6968 capture = capture[0]
6969 self.assertEqual(capture[IPv6].src, aftr_ip6)
6970 self.assertEqual(capture[IPv6].dst, self.pg1.remote_hosts[1].ip6)
6971 self.assertEqual(capture[IP].src, self.pg0.remote_ip4)
6972 self.assertEqual(capture[IP].dst, '192.168.1.1')
6973 self.assertEqual(capture[TCP].sport, 10001)
6974 self.assertEqual(capture[TCP].dport, 20001)
Klement Sekerad81ae412018-05-16 10:52:54 +02006975 self.assert_packet_checksums_valid(capture)
Matus Fabian8ebe6252017-11-06 05:04:53 -08006976
6977 # ICMP
6978 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
6979 IPv6(dst=aftr_ip6, src=self.pg1.remote_hosts[1].ip6) /
6980 IP(dst=self.pg0.remote_ip4, src='192.168.1.1') /
6981 ICMP(id=4000, type='echo-request'))
6982 self.pg1.add_stream(p)
6983 self.pg_enable_capture(self.pg_interfaces)
6984 self.pg_start()
6985 capture = self.pg0.get_capture(1)
6986 capture = capture[0]
6987 self.assertFalse(capture.haslayer(IPv6))
6988 self.assertEqual(capture[IP].src, self.nat_addr)
6989 self.assertEqual(capture[IP].dst, self.pg0.remote_ip4)
6990 self.assertNotEqual(capture[ICMP].id, 4000)
Klement Sekerad81ae412018-05-16 10:52:54 +02006991 self.assert_packet_checksums_valid(capture)
Matus Fabian8ebe6252017-11-06 05:04:53 -08006992 out_id = capture[ICMP].id
6993
6994 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
6995 IP(dst=self.nat_addr, src=self.pg0.remote_ip4) /
6996 ICMP(id=out_id, type='echo-reply'))
6997 self.pg0.add_stream(p)
6998 self.pg_enable_capture(self.pg_interfaces)
6999 self.pg_start()
7000 capture = self.pg1.get_capture(1)
7001 capture = capture[0]
7002 self.assertEqual(capture[IPv6].src, aftr_ip6)
7003 self.assertEqual(capture[IPv6].dst, self.pg1.remote_hosts[1].ip6)
7004 self.assertEqual(capture[IP].src, self.pg0.remote_ip4)
7005 self.assertEqual(capture[IP].dst, '192.168.1.1')
7006 self.assertEqual(capture[ICMP].id, 4000)
Klement Sekerad81ae412018-05-16 10:52:54 +02007007 self.assert_packet_checksums_valid(capture)
Matus Fabian8ebe6252017-11-06 05:04:53 -08007008
Matus Fabian331acc62017-12-08 03:38:51 -08007009 # ping DS-Lite AFTR tunnel endpoint address
7010 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
7011 IPv6(src=self.pg1.remote_hosts[1].ip6, dst=aftr_ip6) /
7012 ICMPv6EchoRequest())
7013 self.pg1.add_stream(p)
7014 self.pg_enable_capture(self.pg_interfaces)
7015 self.pg_start()
7016 capture = self.pg1.get_capture(1)
7017 self.assertEqual(1, len(capture))
7018 capture = capture[0]
7019 self.assertEqual(capture[IPv6].src, aftr_ip6)
7020 self.assertEqual(capture[IPv6].dst, self.pg1.remote_hosts[1].ip6)
7021 self.assertTrue(capture.haslayer(ICMPv6EchoReply))
7022
Matus Fabian8ebe6252017-11-06 05:04:53 -08007023 def tearDown(self):
7024 super(TestDSlite, self).tearDown()
7025 if not self.vpp_dead:
7026 self.logger.info(self.vapi.cli("show dslite pool"))
7027 self.logger.info(
7028 self.vapi.cli("show dslite aftr-tunnel-endpoint-address"))
7029 self.logger.info(self.vapi.cli("show dslite sessions"))
7030
Juraj Slobodac5c6a332018-01-09 16:08:32 +01007031
7032class TestDSliteCE(MethodHolder):
7033 """ DS-Lite CE Test Cases """
7034
7035 @classmethod
7036 def setUpConstants(cls):
7037 super(TestDSliteCE, cls).setUpConstants()
7038 cls.vpp_cmdline.extend(["nat", "{", "dslite ce", "}"])
7039
7040 @classmethod
7041 def setUpClass(cls):
7042 super(TestDSliteCE, cls).setUpClass()
7043
7044 try:
7045 cls.create_pg_interfaces(range(2))
7046 cls.pg0.admin_up()
7047 cls.pg0.config_ip4()
7048 cls.pg0.resolve_arp()
7049 cls.pg1.admin_up()
7050 cls.pg1.config_ip6()
7051 cls.pg1.generate_remote_hosts(1)
7052 cls.pg1.configure_ipv6_neighbors()
7053
7054 except Exception:
7055 super(TestDSliteCE, cls).tearDownClass()
7056 raise
7057
7058 def test_dslite_ce(self):
7059 """ Test DS-Lite CE """
7060
7061 b4_ip4 = '192.0.0.2'
7062 b4_ip4_n = socket.inet_pton(socket.AF_INET, b4_ip4)
7063 b4_ip6 = '2001:db8:62aa::375e:f4c1:1'
7064 b4_ip6_n = socket.inet_pton(socket.AF_INET6, b4_ip6)
7065 self.vapi.dslite_set_b4_addr(b4_ip6_n, b4_ip4_n)
7066
7067 aftr_ip4 = '192.0.0.1'
7068 aftr_ip4_n = socket.inet_pton(socket.AF_INET, aftr_ip4)
7069 aftr_ip6 = '2001:db8:85a3::8a2e:370:1'
7070 aftr_ip6_n = socket.inet_pton(socket.AF_INET6, aftr_ip6)
7071 self.vapi.dslite_set_aftr_addr(aftr_ip6_n, aftr_ip4_n)
7072
7073 self.vapi.ip_add_del_route(dst_address=aftr_ip6_n,
7074 dst_address_length=128,
7075 next_hop_address=self.pg1.remote_ip6n,
7076 next_hop_sw_if_index=self.pg1.sw_if_index,
7077 is_ipv6=1)
7078
7079 # UDP encapsulation
7080 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
7081 IP(dst=self.pg1.remote_ip4, src=self.pg0.remote_ip4) /
7082 UDP(sport=10000, dport=20000))
7083 self.pg0.add_stream(p)
7084 self.pg_enable_capture(self.pg_interfaces)
7085 self.pg_start()
7086 capture = self.pg1.get_capture(1)
7087 capture = capture[0]
7088 self.assertEqual(capture[IPv6].src, b4_ip6)
7089 self.assertEqual(capture[IPv6].dst, aftr_ip6)
7090 self.assertEqual(capture[IP].src, self.pg0.remote_ip4)
7091 self.assertEqual(capture[IP].dst, self.pg1.remote_ip4)
7092 self.assertEqual(capture[UDP].sport, 10000)
7093 self.assertEqual(capture[UDP].dport, 20000)
Klement Sekerad81ae412018-05-16 10:52:54 +02007094 self.assert_packet_checksums_valid(capture)
Juraj Slobodac5c6a332018-01-09 16:08:32 +01007095
7096 # UDP decapsulation
7097 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
7098 IPv6(dst=b4_ip6, src=aftr_ip6) /
7099 IP(dst=self.pg0.remote_ip4, src=self.pg1.remote_ip4) /
7100 UDP(sport=20000, dport=10000))
7101 self.pg1.add_stream(p)
7102 self.pg_enable_capture(self.pg_interfaces)
7103 self.pg_start()
7104 capture = self.pg0.get_capture(1)
7105 capture = capture[0]
7106 self.assertFalse(capture.haslayer(IPv6))
7107 self.assertEqual(capture[IP].src, self.pg1.remote_ip4)
7108 self.assertEqual(capture[IP].dst, self.pg0.remote_ip4)
7109 self.assertEqual(capture[UDP].sport, 20000)
7110 self.assertEqual(capture[UDP].dport, 10000)
Klement Sekerad81ae412018-05-16 10:52:54 +02007111 self.assert_packet_checksums_valid(capture)
Juraj Slobodac5c6a332018-01-09 16:08:32 +01007112
7113 # ping DS-Lite B4 tunnel endpoint address
7114 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
7115 IPv6(src=self.pg1.remote_hosts[0].ip6, dst=b4_ip6) /
7116 ICMPv6EchoRequest())
7117 self.pg1.add_stream(p)
7118 self.pg_enable_capture(self.pg_interfaces)
7119 self.pg_start()
7120 capture = self.pg1.get_capture(1)
7121 self.assertEqual(1, len(capture))
7122 capture = capture[0]
7123 self.assertEqual(capture[IPv6].src, b4_ip6)
7124 self.assertEqual(capture[IPv6].dst, self.pg1.remote_hosts[0].ip6)
7125 self.assertTrue(capture.haslayer(ICMPv6EchoReply))
7126
7127 def tearDown(self):
7128 super(TestDSliteCE, self).tearDown()
7129 if not self.vpp_dead:
7130 self.logger.info(
7131 self.vapi.cli("show dslite aftr-tunnel-endpoint-address"))
7132 self.logger.info(
7133 self.vapi.cli("show dslite b4-tunnel-endpoint-address"))
7134
Matus Fabianf2a23cc2018-01-22 03:41:53 -08007135
7136class TestNAT66(MethodHolder):
7137 """ NAT66 Test Cases """
7138
7139 @classmethod
7140 def setUpClass(cls):
7141 super(TestNAT66, cls).setUpClass()
7142
7143 try:
7144 cls.nat_addr = 'fd01:ff::2'
7145 cls.nat_addr_n = socket.inet_pton(socket.AF_INET6, cls.nat_addr)
7146
7147 cls.create_pg_interfaces(range(2))
7148 cls.interfaces = list(cls.pg_interfaces)
7149
7150 for i in cls.interfaces:
7151 i.admin_up()
7152 i.config_ip6()
7153 i.configure_ipv6_neighbors()
7154
7155 except Exception:
7156 super(TestNAT66, cls).tearDownClass()
7157 raise
7158
7159 def test_static(self):
7160 """ 1:1 NAT66 test """
7161 self.vapi.nat66_add_del_interface(self.pg0.sw_if_index)
7162 self.vapi.nat66_add_del_interface(self.pg1.sw_if_index, is_inside=0)
7163 self.vapi.nat66_add_del_static_mapping(self.pg0.remote_ip6n,
7164 self.nat_addr_n)
7165
7166 # in2out
7167 pkts = []
7168 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
7169 IPv6(src=self.pg0.remote_ip6, dst=self.pg1.remote_ip6) /
7170 TCP())
7171 pkts.append(p)
7172 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
7173 IPv6(src=self.pg0.remote_ip6, dst=self.pg1.remote_ip6) /
7174 UDP())
7175 pkts.append(p)
7176 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
7177 IPv6(src=self.pg0.remote_ip6, dst=self.pg1.remote_ip6) /
7178 ICMPv6EchoRequest())
7179 pkts.append(p)
7180 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
7181 IPv6(src=self.pg0.remote_ip6, dst=self.pg1.remote_ip6) /
7182 GRE() / IP() / TCP())
7183 pkts.append(p)
7184 self.pg0.add_stream(pkts)
7185 self.pg_enable_capture(self.pg_interfaces)
7186 self.pg_start()
7187 capture = self.pg1.get_capture(len(pkts))
7188 for packet in capture:
7189 try:
7190 self.assertEqual(packet[IPv6].src, self.nat_addr)
7191 self.assertEqual(packet[IPv6].dst, self.pg1.remote_ip6)
Klement Sekerad81ae412018-05-16 10:52:54 +02007192 self.assert_packet_checksums_valid(packet)
Matus Fabianf2a23cc2018-01-22 03:41:53 -08007193 except:
7194 self.logger.error(ppp("Unexpected or invalid packet:", packet))
7195 raise
7196
7197 # out2in
7198 pkts = []
7199 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
7200 IPv6(src=self.pg1.remote_ip6, dst=self.nat_addr) /
7201 TCP())
7202 pkts.append(p)
7203 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
7204 IPv6(src=self.pg1.remote_ip6, dst=self.nat_addr) /
7205 UDP())
7206 pkts.append(p)
7207 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
7208 IPv6(src=self.pg1.remote_ip6, dst=self.nat_addr) /
7209 ICMPv6EchoReply())
7210 pkts.append(p)
7211 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
7212 IPv6(src=self.pg1.remote_ip6, dst=self.nat_addr) /
7213 GRE() / IP() / TCP())
7214 pkts.append(p)
7215 self.pg1.add_stream(pkts)
7216 self.pg_enable_capture(self.pg_interfaces)
7217 self.pg_start()
7218 capture = self.pg0.get_capture(len(pkts))
7219 for packet in capture:
7220 try:
7221 self.assertEqual(packet[IPv6].src, self.pg1.remote_ip6)
7222 self.assertEqual(packet[IPv6].dst, self.pg0.remote_ip6)
Klement Sekerad81ae412018-05-16 10:52:54 +02007223 self.assert_packet_checksums_valid(packet)
Matus Fabianf2a23cc2018-01-22 03:41:53 -08007224 except:
7225 self.logger.error(ppp("Unexpected or invalid packet:", packet))
7226 raise
7227
7228 sm = self.vapi.nat66_static_mapping_dump()
7229 self.assertEqual(len(sm), 1)
7230 self.assertEqual(sm[0].total_pkts, 8)
7231
Juraj Sloboda9341e342018-04-13 12:00:46 +02007232 def test_check_no_translate(self):
7233 """ NAT66 translate only when egress interface is outside interface """
7234 self.vapi.nat66_add_del_interface(self.pg0.sw_if_index)
7235 self.vapi.nat66_add_del_interface(self.pg1.sw_if_index)
7236 self.vapi.nat66_add_del_static_mapping(self.pg0.remote_ip6n,
7237 self.nat_addr_n)
7238
7239 # in2out
7240 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
7241 IPv6(src=self.pg0.remote_ip6, dst=self.pg1.remote_ip6) /
7242 UDP())
7243 self.pg0.add_stream([p])
7244 self.pg_enable_capture(self.pg_interfaces)
7245 self.pg_start()
7246 capture = self.pg1.get_capture(1)
7247 packet = capture[0]
7248 try:
7249 self.assertEqual(packet[IPv6].src, self.pg0.remote_ip6)
7250 self.assertEqual(packet[IPv6].dst, self.pg1.remote_ip6)
7251 except:
7252 self.logger.error(ppp("Unexpected or invalid packet:", packet))
7253 raise
7254
Matus Fabianf2a23cc2018-01-22 03:41:53 -08007255 def clear_nat66(self):
7256 """
7257 Clear NAT66 configuration.
7258 """
7259 interfaces = self.vapi.nat66_interface_dump()
7260 for intf in interfaces:
7261 self.vapi.nat66_add_del_interface(intf.sw_if_index,
7262 intf.is_inside,
7263 is_add=0)
7264
7265 static_mappings = self.vapi.nat66_static_mapping_dump()
7266 for sm in static_mappings:
7267 self.vapi.nat66_add_del_static_mapping(sm.local_ip_address,
7268 sm.external_ip_address,
7269 sm.vrf_id,
7270 is_add=0)
7271
7272 def tearDown(self):
7273 super(TestNAT66, self).tearDown()
7274 if not self.vpp_dead:
7275 self.logger.info(self.vapi.cli("show nat66 interfaces"))
7276 self.logger.info(self.vapi.cli("show nat66 static mappings"))
7277 self.clear_nat66()
7278
Klement Sekerad81ae412018-05-16 10:52:54 +02007279
Matus Fabiande886752016-12-07 03:38:19 -08007280if __name__ == '__main__':
7281 unittest.main(testRunner=VppTestRunner)