blob: a7ca6d3a6e00e49d92cedbff102d8f7b15373f3e [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 random
Matus Fabiande886752016-12-07 03:38:19 -08007
Martin Gálik977c1cb2017-03-30 23:21:51 -07008from framework import VppTestCase, VppTestRunner, running_extended_tests
Matus Fabiande886752016-12-07 03:38:19 -08009from scapy.layers.inet import IP, TCP, UDP, ICMP
Juraj Slobodab33f4132017-02-08 23:54:21 -080010from scapy.layers.inet import IPerror, TCPerror, UDPerror, ICMPerror
Juraj Slobodac746a152018-07-09 02:36:37 +020011from scapy.layers.inet6 import IPv6, ICMPv6EchoRequest, ICMPv6EchoReply, \
Paul Vinciguerra978aa642018-11-24 22:19:12 -080012 ICMPv6ND_NS, ICMPv6ND_NA, ICMPv6NDOptDstLLAddr, fragment6
Matus Fabianefcd1e92017-08-15 06:59:19 -070013from scapy.layers.inet6 import ICMPv6DestUnreach, IPerror6, IPv6ExtHdrFragment
Matus Fabian328dbc82017-06-19 04:28:04 -070014from scapy.layers.l2 import Ether, ARP, GRE
Matus Fabianeea28d72017-01-13 04:15:54 -080015from scapy.data import IP_PROTOS
Matus Fabianefcd1e92017-08-15 06:59:19 -070016from scapy.packet import bind_layers, Raw
Klement Sekera9225dee2016-12-12 08:36:58 +010017from util import ppp
Matus Fabianeea28d72017-01-13 04:15:54 -080018from ipfix import IPFIX, Set, Template, Data, IPFIXDecoder
Martin Gálik977c1cb2017-03-30 23:21:51 -070019from time import sleep
Matus Fabian704018c2017-09-04 02:17:18 -070020from util import ip4_range
Ole Troan7f991832018-12-06 17:35:12 +010021from vpp_mac import mactobinary
Matus Fabianad1f3e12018-11-28 21:26:34 -080022from syslog_rfc5424_parser import SyslogMessage, ParseError
23from syslog_rfc5424_parser.constants import SyslogFacility, SyslogSeverity
24from vpp_papi_provider import SYSLOG_SEVERITY
Ole Troan7f991832018-12-06 17:35:12 +010025from io import BytesIO
Matus Fabiande886752016-12-07 03:38:19 -080026
27
Martin Gálikd7f75cd2017-03-27 06:02:47 -070028class MethodHolder(VppTestCase):
Matus Fabian2ba92e32017-08-21 07:05:03 -070029 """ NAT create capture and verify method holder """
Matus Fabiande886752016-12-07 03:38:19 -080030
Matus Fabiana6110b62018-06-13 05:39:07 -070031 def clear_nat44(self):
32 """
33 Clear NAT44 configuration.
34 """
35 if hasattr(self, 'pg7') and hasattr(self, 'pg8'):
36 # I found no elegant way to do this
37 self.vapi.ip_add_del_route(
38 dst_address=self.pg7.remote_ip4n,
39 dst_address_length=32,
40 next_hop_address=self.pg7.remote_ip4n,
41 next_hop_sw_if_index=self.pg7.sw_if_index,
42 is_add=0)
43 self.vapi.ip_add_del_route(
44 dst_address=self.pg8.remote_ip4n,
45 dst_address_length=32,
46 next_hop_address=self.pg8.remote_ip4n,
47 next_hop_sw_if_index=self.pg8.sw_if_index,
48 is_add=0)
49
50 for intf in [self.pg7, self.pg8]:
51 neighbors = self.vapi.ip_neighbor_dump(intf.sw_if_index)
52 for n in neighbors:
53 self.vapi.ip_neighbor_add_del(intf.sw_if_index,
54 n.mac_address,
55 n.ip_address,
56 is_add=0)
57
58 if self.pg7.has_ip4_config:
59 self.pg7.unconfig_ip4()
60
61 self.vapi.nat44_forwarding_enable_disable(0)
62
63 interfaces = self.vapi.nat44_interface_addr_dump()
64 for intf in interfaces:
65 self.vapi.nat44_add_interface_addr(intf.sw_if_index,
66 twice_nat=intf.twice_nat,
67 is_add=0)
68
69 self.vapi.nat_ipfix(enable=0, src_port=self.ipfix_src_port,
70 domain_id=self.ipfix_domain_id)
71 self.ipfix_src_port = 4739
72 self.ipfix_domain_id = 1
73
Matus Fabianad1f3e12018-11-28 21:26:34 -080074 self.vapi.syslog_set_filter(SYSLOG_SEVERITY.EMERG)
75
Matus Fabiana6110b62018-06-13 05:39:07 -070076 interfaces = self.vapi.nat44_interface_dump()
77 for intf in interfaces:
78 if intf.is_inside > 1:
79 self.vapi.nat44_interface_add_del_feature(intf.sw_if_index,
80 0,
81 is_add=0)
82 self.vapi.nat44_interface_add_del_feature(intf.sw_if_index,
83 intf.is_inside,
84 is_add=0)
85
86 interfaces = self.vapi.nat44_interface_output_feature_dump()
87 for intf in interfaces:
88 self.vapi.nat44_interface_add_del_output_feature(intf.sw_if_index,
89 intf.is_inside,
90 is_add=0)
91
92 static_mappings = self.vapi.nat44_static_mapping_dump()
93 for sm in static_mappings:
94 self.vapi.nat44_add_del_static_mapping(
95 sm.local_ip_address,
96 sm.external_ip_address,
97 local_port=sm.local_port,
98 external_port=sm.external_port,
99 addr_only=sm.addr_only,
100 vrf_id=sm.vrf_id,
101 protocol=sm.protocol,
102 twice_nat=sm.twice_nat,
103 self_twice_nat=sm.self_twice_nat,
104 out2in_only=sm.out2in_only,
105 tag=sm.tag,
106 external_sw_if_index=sm.external_sw_if_index,
107 is_add=0)
108
109 lb_static_mappings = self.vapi.nat44_lb_static_mapping_dump()
110 for lb_sm in lb_static_mappings:
111 self.vapi.nat44_add_del_lb_static_mapping(
112 lb_sm.external_addr,
113 lb_sm.external_port,
114 lb_sm.protocol,
Matus Fabiana6110b62018-06-13 05:39:07 -0700115 twice_nat=lb_sm.twice_nat,
116 self_twice_nat=lb_sm.self_twice_nat,
117 out2in_only=lb_sm.out2in_only,
118 tag=lb_sm.tag,
119 is_add=0,
120 local_num=0,
121 locals=[])
122
123 identity_mappings = self.vapi.nat44_identity_mapping_dump()
124 for id_m in identity_mappings:
125 self.vapi.nat44_add_del_identity_mapping(
126 addr_only=id_m.addr_only,
127 ip=id_m.ip_address,
128 port=id_m.port,
129 sw_if_index=id_m.sw_if_index,
130 vrf_id=id_m.vrf_id,
131 protocol=id_m.protocol,
132 is_add=0)
133
134 adresses = self.vapi.nat44_address_dump()
135 for addr in adresses:
136 self.vapi.nat44_add_del_address_range(addr.ip_address,
137 addr.ip_address,
138 twice_nat=addr.twice_nat,
139 is_add=0)
140
141 self.vapi.nat_set_reass()
142 self.vapi.nat_set_reass(is_ip6=1)
Matus Fabian68ba8802018-08-08 05:52:47 -0700143 self.verify_no_nat44_user()
Matus Fabian878c6462018-08-23 00:33:35 -0700144 self.vapi.nat_set_timeouts()
Matus Fabian5d28c7a2018-09-04 03:55:45 -0700145 self.vapi.nat_set_addr_and_port_alloc_alg()
Matus Fabianbb4e0222018-09-13 02:36:25 -0700146 self.vapi.nat_set_mss_clamping()
Matus Fabiana6110b62018-06-13 05:39:07 -0700147
148 def nat44_add_static_mapping(self, local_ip, external_ip='0.0.0.0',
149 local_port=0, external_port=0, vrf_id=0,
150 is_add=1, external_sw_if_index=0xFFFFFFFF,
151 proto=0, twice_nat=0, self_twice_nat=0,
152 out2in_only=0, tag=""):
153 """
154 Add/delete NAT44 static mapping
155
156 :param local_ip: Local IP address
157 :param external_ip: External IP address
158 :param local_port: Local port number (Optional)
159 :param external_port: External port number (Optional)
160 :param vrf_id: VRF ID (Default 0)
161 :param is_add: 1 if add, 0 if delete (Default add)
162 :param external_sw_if_index: External interface instead of IP address
163 :param proto: IP protocol (Mandatory if port specified)
164 :param twice_nat: 1 if translate external host address and port
165 :param self_twice_nat: 1 if translate external host address and port
166 whenever external host address equals
167 local address of internal host
168 :param out2in_only: if 1 rule is matching only out2in direction
169 :param tag: Opaque string tag
170 """
171 addr_only = 1
172 if local_port and external_port:
173 addr_only = 0
174 l_ip = socket.inet_pton(socket.AF_INET, local_ip)
175 e_ip = socket.inet_pton(socket.AF_INET, external_ip)
176 self.vapi.nat44_add_del_static_mapping(
177 l_ip,
178 e_ip,
179 external_sw_if_index,
180 local_port,
181 external_port,
182 addr_only,
183 vrf_id,
184 proto,
185 twice_nat,
186 self_twice_nat,
187 out2in_only,
188 tag,
189 is_add)
190
191 def nat44_add_address(self, ip, is_add=1, vrf_id=0xFFFFFFFF, twice_nat=0):
192 """
193 Add/delete NAT44 address
194
195 :param ip: IP address
196 :param is_add: 1 if add, 0 if delete (Default add)
197 :param twice_nat: twice NAT address for extenal hosts
198 """
199 nat_addr = socket.inet_pton(socket.AF_INET, ip)
200 self.vapi.nat44_add_del_address_range(nat_addr, nat_addr, is_add,
201 vrf_id=vrf_id,
202 twice_nat=twice_nat)
203
Juraj Slobodacba69362017-12-19 02:09:32 +0100204 def create_stream_in(self, in_if, out_if, dst_ip=None, ttl=64):
Matus Fabiande886752016-12-07 03:38:19 -0800205 """
206 Create packet stream for inside network
207
208 :param in_if: Inside interface
209 :param out_if: Outside interface
Juraj Slobodacba69362017-12-19 02:09:32 +0100210 :param dst_ip: Destination address
Juraj Slobodab33f4132017-02-08 23:54:21 -0800211 :param ttl: TTL of generated packets
Matus Fabiande886752016-12-07 03:38:19 -0800212 """
Juraj Slobodacba69362017-12-19 02:09:32 +0100213 if dst_ip is None:
214 dst_ip = out_if.remote_ip4
215
Matus Fabiande886752016-12-07 03:38:19 -0800216 pkts = []
217 # TCP
218 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
Juraj Slobodacba69362017-12-19 02:09:32 +0100219 IP(src=in_if.remote_ip4, dst=dst_ip, ttl=ttl) /
Matus Fabian06596c52017-06-06 04:53:28 -0700220 TCP(sport=self.tcp_port_in, dport=20))
Matus Fabiande886752016-12-07 03:38:19 -0800221 pkts.append(p)
222
223 # UDP
224 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
Juraj Slobodacba69362017-12-19 02:09:32 +0100225 IP(src=in_if.remote_ip4, dst=dst_ip, ttl=ttl) /
Matus Fabian06596c52017-06-06 04:53:28 -0700226 UDP(sport=self.udp_port_in, dport=20))
Matus Fabiande886752016-12-07 03:38:19 -0800227 pkts.append(p)
228
229 # ICMP
230 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
Juraj Slobodacba69362017-12-19 02:09:32 +0100231 IP(src=in_if.remote_ip4, dst=dst_ip, ttl=ttl) /
Matus Fabiande886752016-12-07 03:38:19 -0800232 ICMP(id=self.icmp_id_in, type='echo-request'))
233 pkts.append(p)
234
235 return pkts
236
Matus Fabian428dc912017-06-21 06:15:18 -0700237 def compose_ip6(self, ip4, pref, plen):
238 """
239 Compose IPv4-embedded IPv6 addresses
240
241 :param ip4: IPv4 address
242 :param pref: IPv6 prefix
243 :param plen: IPv6 prefix length
244 :returns: IPv4-embedded IPv6 addresses
245 """
246 pref_n = list(socket.inet_pton(socket.AF_INET6, pref))
247 ip4_n = list(socket.inet_pton(socket.AF_INET, ip4))
248 if plen == 32:
249 pref_n[4] = ip4_n[0]
250 pref_n[5] = ip4_n[1]
251 pref_n[6] = ip4_n[2]
252 pref_n[7] = ip4_n[3]
253 elif plen == 40:
254 pref_n[5] = ip4_n[0]
255 pref_n[6] = ip4_n[1]
256 pref_n[7] = ip4_n[2]
257 pref_n[9] = ip4_n[3]
258 elif plen == 48:
259 pref_n[6] = ip4_n[0]
260 pref_n[7] = ip4_n[1]
261 pref_n[9] = ip4_n[2]
262 pref_n[10] = ip4_n[3]
263 elif plen == 56:
264 pref_n[7] = ip4_n[0]
265 pref_n[9] = ip4_n[1]
266 pref_n[10] = ip4_n[2]
267 pref_n[11] = ip4_n[3]
268 elif plen == 64:
269 pref_n[9] = ip4_n[0]
270 pref_n[10] = ip4_n[1]
271 pref_n[11] = ip4_n[2]
272 pref_n[12] = ip4_n[3]
273 elif plen == 96:
274 pref_n[12] = ip4_n[0]
275 pref_n[13] = ip4_n[1]
276 pref_n[14] = ip4_n[2]
277 pref_n[15] = ip4_n[3]
278 return socket.inet_ntop(socket.AF_INET6, ''.join(pref_n))
279
Juraj Slobodacba69362017-12-19 02:09:32 +0100280 def extract_ip4(self, ip6, plen):
281 """
282 Extract IPv4 address embedded in IPv6 addresses
283
284 :param ip6: IPv6 address
285 :param plen: IPv6 prefix length
286 :returns: extracted IPv4 address
287 """
288 ip6_n = list(socket.inet_pton(socket.AF_INET6, ip6))
289 ip4_n = [None] * 4
290 if plen == 32:
291 ip4_n[0] = ip6_n[4]
292 ip4_n[1] = ip6_n[5]
293 ip4_n[2] = ip6_n[6]
294 ip4_n[3] = ip6_n[7]
295 elif plen == 40:
296 ip4_n[0] = ip6_n[5]
297 ip4_n[1] = ip6_n[6]
298 ip4_n[2] = ip6_n[7]
299 ip4_n[3] = ip6_n[9]
300 elif plen == 48:
301 ip4_n[0] = ip6_n[6]
302 ip4_n[1] = ip6_n[7]
303 ip4_n[2] = ip6_n[9]
304 ip4_n[3] = ip6_n[10]
305 elif plen == 56:
306 ip4_n[0] = ip6_n[7]
307 ip4_n[1] = ip6_n[9]
308 ip4_n[2] = ip6_n[10]
309 ip4_n[3] = ip6_n[11]
310 elif plen == 64:
311 ip4_n[0] = ip6_n[9]
312 ip4_n[1] = ip6_n[10]
313 ip4_n[2] = ip6_n[11]
314 ip4_n[3] = ip6_n[12]
315 elif plen == 96:
316 ip4_n[0] = ip6_n[12]
317 ip4_n[1] = ip6_n[13]
318 ip4_n[2] = ip6_n[14]
319 ip4_n[3] = ip6_n[15]
320 return socket.inet_ntop(socket.AF_INET, ''.join(ip4_n))
321
Matus Fabian428dc912017-06-21 06:15:18 -0700322 def create_stream_in_ip6(self, in_if, out_if, hlim=64, pref=None, plen=0):
Matus Fabian06596c52017-06-06 04:53:28 -0700323 """
324 Create IPv6 packet stream for inside network
325
326 :param in_if: Inside interface
327 :param out_if: Outside interface
328 :param ttl: Hop Limit of generated packets
Matus Fabian428dc912017-06-21 06:15:18 -0700329 :param pref: NAT64 prefix
330 :param plen: NAT64 prefix length
Matus Fabian06596c52017-06-06 04:53:28 -0700331 """
332 pkts = []
Matus Fabian428dc912017-06-21 06:15:18 -0700333 if pref is None:
334 dst = ''.join(['64:ff9b::', out_if.remote_ip4])
335 else:
336 dst = self.compose_ip6(out_if.remote_ip4, pref, plen)
337
Matus Fabian06596c52017-06-06 04:53:28 -0700338 # TCP
339 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
340 IPv6(src=in_if.remote_ip6, dst=dst, hlim=hlim) /
341 TCP(sport=self.tcp_port_in, dport=20))
342 pkts.append(p)
343
344 # UDP
345 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
346 IPv6(src=in_if.remote_ip6, dst=dst, hlim=hlim) /
347 UDP(sport=self.udp_port_in, dport=20))
348 pkts.append(p)
349
350 # ICMP
351 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
352 IPv6(src=in_if.remote_ip6, dst=dst, hlim=hlim) /
353 ICMPv6EchoRequest(id=self.icmp_id_in))
354 pkts.append(p)
355
356 return pkts
357
Juraj Sloboda7b929792017-11-23 13:20:48 +0100358 def create_stream_out(self, out_if, dst_ip=None, ttl=64,
359 use_inside_ports=False):
Matus Fabiande886752016-12-07 03:38:19 -0800360 """
361 Create packet stream for outside network
362
363 :param out_if: Outside interface
Matus Fabian2ba92e32017-08-21 07:05:03 -0700364 :param dst_ip: Destination IP address (Default use global NAT address)
Juraj Slobodab33f4132017-02-08 23:54:21 -0800365 :param ttl: TTL of generated packets
Juraj Sloboda7b929792017-11-23 13:20:48 +0100366 :param use_inside_ports: Use inside NAT ports as destination ports
367 instead of outside ports
Matus Fabiande886752016-12-07 03:38:19 -0800368 """
369 if dst_ip is None:
Matus Fabian2ba92e32017-08-21 07:05:03 -0700370 dst_ip = self.nat_addr
Juraj Sloboda7b929792017-11-23 13:20:48 +0100371 if not use_inside_ports:
372 tcp_port = self.tcp_port_out
373 udp_port = self.udp_port_out
374 icmp_id = self.icmp_id_out
375 else:
376 tcp_port = self.tcp_port_in
377 udp_port = self.udp_port_in
378 icmp_id = self.icmp_id_in
Matus Fabiande886752016-12-07 03:38:19 -0800379 pkts = []
380 # TCP
381 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
Juraj Slobodab33f4132017-02-08 23:54:21 -0800382 IP(src=out_if.remote_ip4, dst=dst_ip, ttl=ttl) /
Juraj Sloboda7b929792017-11-23 13:20:48 +0100383 TCP(dport=tcp_port, sport=20))
Matus Fabiande886752016-12-07 03:38:19 -0800384 pkts.append(p)
385
386 # UDP
387 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
Juraj Slobodab33f4132017-02-08 23:54:21 -0800388 IP(src=out_if.remote_ip4, dst=dst_ip, ttl=ttl) /
Juraj Sloboda7b929792017-11-23 13:20:48 +0100389 UDP(dport=udp_port, sport=20))
Matus Fabiande886752016-12-07 03:38:19 -0800390 pkts.append(p)
391
392 # ICMP
393 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
Juraj Slobodab33f4132017-02-08 23:54:21 -0800394 IP(src=out_if.remote_ip4, dst=dst_ip, ttl=ttl) /
Juraj Sloboda7b929792017-11-23 13:20:48 +0100395 ICMP(id=icmp_id, type='echo-reply'))
Matus Fabiande886752016-12-07 03:38:19 -0800396 pkts.append(p)
397
398 return pkts
399
Juraj Slobodacba69362017-12-19 02:09:32 +0100400 def create_stream_out_ip6(self, out_if, src_ip, dst_ip, hl=64):
401 """
402 Create packet stream for outside network
403
404 :param out_if: Outside interface
405 :param dst_ip: Destination IP address (Default use global NAT address)
406 :param hl: HL of generated packets
407 """
408 pkts = []
409 # TCP
410 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
411 IPv6(src=src_ip, dst=dst_ip, hlim=hl) /
412 TCP(dport=self.tcp_port_out, sport=20))
413 pkts.append(p)
414
415 # UDP
416 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
417 IPv6(src=src_ip, dst=dst_ip, hlim=hl) /
418 UDP(dport=self.udp_port_out, sport=20))
419 pkts.append(p)
420
421 # ICMP
422 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
423 IPv6(src=src_ip, dst=dst_ip, hlim=hl) /
424 ICMPv6EchoReply(id=self.icmp_id_out))
425 pkts.append(p)
426
427 return pkts
428
Matus Fabiande886752016-12-07 03:38:19 -0800429 def verify_capture_out(self, capture, nat_ip=None, same_port=False,
Matus Fabian05ca4a32018-09-04 23:45:13 -0700430 dst_ip=None, is_ip6=False):
Matus Fabiande886752016-12-07 03:38:19 -0800431 """
432 Verify captured packets on outside network
433
434 :param capture: Captured packets
Matus Fabian2ba92e32017-08-21 07:05:03 -0700435 :param nat_ip: Translated IP address (Default use global NAT address)
Matus Fabiande886752016-12-07 03:38:19 -0800436 :param same_port: Sorce port number is not translated (Default False)
Matus Fabian06596c52017-06-06 04:53:28 -0700437 :param dst_ip: Destination IP address (Default do not verify)
Juraj Slobodacba69362017-12-19 02:09:32 +0100438 :param is_ip6: If L3 protocol is IPv6 (Default False)
Matus Fabiande886752016-12-07 03:38:19 -0800439 """
Juraj Slobodacba69362017-12-19 02:09:32 +0100440 if is_ip6:
441 IP46 = IPv6
442 ICMP46 = ICMPv6EchoRequest
443 else:
444 IP46 = IP
445 ICMP46 = ICMP
Matus Fabiande886752016-12-07 03:38:19 -0800446 if nat_ip is None:
Matus Fabian2ba92e32017-08-21 07:05:03 -0700447 nat_ip = self.nat_addr
Matus Fabiande886752016-12-07 03:38:19 -0800448 for packet in capture:
449 try:
Juraj Slobodacba69362017-12-19 02:09:32 +0100450 if not is_ip6:
Klement Sekerad81ae412018-05-16 10:52:54 +0200451 self.assert_packet_checksums_valid(packet)
Juraj Slobodacba69362017-12-19 02:09:32 +0100452 self.assertEqual(packet[IP46].src, nat_ip)
Matus Fabian06596c52017-06-06 04:53:28 -0700453 if dst_ip is not None:
Juraj Slobodacba69362017-12-19 02:09:32 +0100454 self.assertEqual(packet[IP46].dst, dst_ip)
Matus Fabiande886752016-12-07 03:38:19 -0800455 if packet.haslayer(TCP):
456 if same_port:
457 self.assertEqual(packet[TCP].sport, self.tcp_port_in)
458 else:
Klement Sekerada505f62017-01-04 12:58:53 +0100459 self.assertNotEqual(
460 packet[TCP].sport, self.tcp_port_in)
Matus Fabiande886752016-12-07 03:38:19 -0800461 self.tcp_port_out = packet[TCP].sport
Klement Sekerad81ae412018-05-16 10:52:54 +0200462 self.assert_packet_checksums_valid(packet)
Matus Fabiande886752016-12-07 03:38:19 -0800463 elif packet.haslayer(UDP):
464 if same_port:
465 self.assertEqual(packet[UDP].sport, self.udp_port_in)
466 else:
Klement Sekerada505f62017-01-04 12:58:53 +0100467 self.assertNotEqual(
468 packet[UDP].sport, self.udp_port_in)
Matus Fabiande886752016-12-07 03:38:19 -0800469 self.udp_port_out = packet[UDP].sport
470 else:
471 if same_port:
Juraj Slobodacba69362017-12-19 02:09:32 +0100472 self.assertEqual(packet[ICMP46].id, self.icmp_id_in)
Matus Fabiande886752016-12-07 03:38:19 -0800473 else:
Juraj Slobodacba69362017-12-19 02:09:32 +0100474 self.assertNotEqual(packet[ICMP46].id, self.icmp_id_in)
475 self.icmp_id_out = packet[ICMP46].id
Klement Sekerad81ae412018-05-16 10:52:54 +0200476 self.assert_packet_checksums_valid(packet)
Matus Fabiande886752016-12-07 03:38:19 -0800477 except:
Klement Sekera9225dee2016-12-12 08:36:58 +0100478 self.logger.error(ppp("Unexpected or invalid packet "
479 "(outside network):", packet))
Matus Fabiande886752016-12-07 03:38:19 -0800480 raise
481
Juraj Slobodacba69362017-12-19 02:09:32 +0100482 def verify_capture_out_ip6(self, capture, nat_ip, same_port=False,
Matus Fabian05ca4a32018-09-04 23:45:13 -0700483 dst_ip=None):
Juraj Slobodacba69362017-12-19 02:09:32 +0100484 """
485 Verify captured packets on outside network
486
487 :param capture: Captured packets
488 :param nat_ip: Translated IP address
489 :param same_port: Sorce port number is not translated (Default False)
Juraj Slobodacba69362017-12-19 02:09:32 +0100490 :param dst_ip: Destination IP address (Default do not verify)
491 """
Matus Fabian05ca4a32018-09-04 23:45:13 -0700492 return self.verify_capture_out(capture, nat_ip, same_port, dst_ip,
493 True)
Juraj Slobodacba69362017-12-19 02:09:32 +0100494
Matus Fabian05ca4a32018-09-04 23:45:13 -0700495 def verify_capture_in(self, capture, in_if):
Matus Fabiande886752016-12-07 03:38:19 -0800496 """
497 Verify captured packets on inside network
498
499 :param capture: Captured packets
500 :param in_if: Inside interface
Matus Fabiande886752016-12-07 03:38:19 -0800501 """
Matus Fabiande886752016-12-07 03:38:19 -0800502 for packet in capture:
503 try:
Klement Sekerad81ae412018-05-16 10:52:54 +0200504 self.assert_packet_checksums_valid(packet)
Matus Fabiande886752016-12-07 03:38:19 -0800505 self.assertEqual(packet[IP].dst, in_if.remote_ip4)
506 if packet.haslayer(TCP):
507 self.assertEqual(packet[TCP].dport, self.tcp_port_in)
508 elif packet.haslayer(UDP):
509 self.assertEqual(packet[UDP].dport, self.udp_port_in)
510 else:
511 self.assertEqual(packet[ICMP].id, self.icmp_id_in)
512 except:
Klement Sekera9225dee2016-12-12 08:36:58 +0100513 self.logger.error(ppp("Unexpected or invalid packet "
514 "(inside network):", packet))
Matus Fabiande886752016-12-07 03:38:19 -0800515 raise
516
Matus Fabian05ca4a32018-09-04 23:45:13 -0700517 def verify_capture_in_ip6(self, capture, src_ip, dst_ip):
Matus Fabian06596c52017-06-06 04:53:28 -0700518 """
519 Verify captured IPv6 packets on inside network
520
521 :param capture: Captured packets
522 :param src_ip: Source IP
523 :param dst_ip: Destination IP address
Matus Fabian06596c52017-06-06 04:53:28 -0700524 """
Matus Fabian06596c52017-06-06 04:53:28 -0700525 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,
Matus Fabian05ca4a32018-09-04 23:45:13 -0700566 icmp_type=11):
Juraj Slobodab33f4132017-02-08 23:54:21 -0800567 """
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 icmp_type: Type of error ICMP packet
574 we are expecting (Default 11)
575 """
576 if src_ip is None:
Matus Fabian2ba92e32017-08-21 07:05:03 -0700577 src_ip = self.nat_addr
Juraj Slobodab33f4132017-02-08 23:54:21 -0800578 for packet in capture:
579 try:
580 self.assertEqual(packet[IP].src, src_ip)
Paul Vinciguerra978aa642018-11-24 22:19:12 -0800581 self.assertEqual(packet.haslayer(ICMP), 1)
Juraj Slobodab33f4132017-02-08 23:54:21 -0800582 icmp = packet[ICMP]
583 self.assertEqual(icmp.type, icmp_type)
584 self.assertTrue(icmp.haslayer(IPerror))
585 inner_ip = icmp[IPerror]
586 if inner_ip.haslayer(TCPerror):
587 self.assertEqual(inner_ip[TCPerror].dport,
588 self.tcp_port_out)
589 elif inner_ip.haslayer(UDPerror):
590 self.assertEqual(inner_ip[UDPerror].dport,
591 self.udp_port_out)
592 else:
593 self.assertEqual(inner_ip[ICMPerror].id, self.icmp_id_out)
594 except:
595 self.logger.error(ppp("Unexpected or invalid packet "
596 "(outside network):", packet))
597 raise
598
Matus Fabian05ca4a32018-09-04 23:45:13 -0700599 def verify_capture_in_with_icmp_errors(self, capture, in_if, icmp_type=11):
Juraj Slobodab33f4132017-02-08 23:54:21 -0800600 """
601 Verify captured packets with ICMP errors on inside network
602
603 :param capture: Captured packets
604 :param in_if: Inside interface
Juraj Slobodab33f4132017-02-08 23:54:21 -0800605 :param icmp_type: Type of error ICMP packet
606 we are expecting (Default 11)
607 """
Juraj Slobodab33f4132017-02-08 23:54:21 -0800608 for packet in capture:
609 try:
610 self.assertEqual(packet[IP].dst, in_if.remote_ip4)
Paul Vinciguerra978aa642018-11-24 22:19:12 -0800611 self.assertEqual(packet.haslayer(ICMP), 1)
Juraj Slobodab33f4132017-02-08 23:54:21 -0800612 icmp = packet[ICMP]
613 self.assertEqual(icmp.type, icmp_type)
614 self.assertTrue(icmp.haslayer(IPerror))
615 inner_ip = icmp[IPerror]
616 if inner_ip.haslayer(TCPerror):
617 self.assertEqual(inner_ip[TCPerror].sport,
618 self.tcp_port_in)
619 elif inner_ip.haslayer(UDPerror):
620 self.assertEqual(inner_ip[UDPerror].sport,
621 self.udp_port_in)
622 else:
623 self.assertEqual(inner_ip[ICMPerror].id, self.icmp_id_in)
624 except:
625 self.logger.error(ppp("Unexpected or invalid packet "
626 "(inside network):", packet))
627 raise
628
Juraj Slobodafe0aa762018-07-23 12:22:54 +0200629 def create_stream_frag(self, src_if, dst, sport, dport, data,
630 proto=IP_PROTOS.tcp, echo_reply=False):
Matus Fabianefcd1e92017-08-15 06:59:19 -0700631 """
632 Create fragmented packet stream
633
634 :param src_if: Source interface
635 :param dst: Destination IPv4 address
Juraj Slobodafe0aa762018-07-23 12:22:54 +0200636 :param sport: Source port
637 :param dport: Destination port
Matus Fabianefcd1e92017-08-15 06:59:19 -0700638 :param data: Payload data
Juraj Slobodafe0aa762018-07-23 12:22:54 +0200639 :param proto: protocol (TCP, UDP, ICMP)
640 :param echo_reply: use echo_reply if protocol is ICMP
Matus Fabianefcd1e92017-08-15 06:59:19 -0700641 :returns: Fragmets
642 """
Juraj Slobodafe0aa762018-07-23 12:22:54 +0200643 if proto == IP_PROTOS.tcp:
644 p = (IP(src=src_if.remote_ip4, dst=dst) /
645 TCP(sport=sport, dport=dport) /
646 Raw(data))
647 p = p.__class__(str(p))
648 chksum = p['TCP'].chksum
649 proto_header = TCP(sport=sport, dport=dport, chksum=chksum)
650 elif proto == IP_PROTOS.udp:
651 proto_header = UDP(sport=sport, dport=dport)
652 elif proto == IP_PROTOS.icmp:
653 if not echo_reply:
654 proto_header = ICMP(id=sport, type='echo-request')
655 else:
656 proto_header = ICMP(id=sport, type='echo-reply')
657 else:
658 raise Exception("Unsupported protocol")
Matus Fabianefcd1e92017-08-15 06:59:19 -0700659 id = random.randint(0, 65535)
Matus Fabianefcd1e92017-08-15 06:59:19 -0700660 pkts = []
Juraj Slobodafe0aa762018-07-23 12:22:54 +0200661 if proto == IP_PROTOS.tcp:
662 raw = Raw(data[0:4])
663 else:
664 raw = Raw(data[0:16])
Matus Fabianefcd1e92017-08-15 06:59:19 -0700665 p = (Ether(src=src_if.remote_mac, dst=src_if.local_mac) /
666 IP(src=src_if.remote_ip4, dst=dst, flags="MF", frag=0, id=id) /
Juraj Slobodafe0aa762018-07-23 12:22:54 +0200667 proto_header /
668 raw)
Matus Fabianefcd1e92017-08-15 06:59:19 -0700669 pkts.append(p)
Juraj Slobodafe0aa762018-07-23 12:22:54 +0200670 if proto == IP_PROTOS.tcp:
671 raw = Raw(data[4:20])
672 else:
673 raw = Raw(data[16:32])
Matus Fabianefcd1e92017-08-15 06:59:19 -0700674 p = (Ether(src=src_if.remote_mac, dst=src_if.local_mac) /
675 IP(src=src_if.remote_ip4, dst=dst, flags="MF", frag=3, id=id,
Juraj Slobodafe0aa762018-07-23 12:22:54 +0200676 proto=proto) /
677 raw)
Matus Fabianefcd1e92017-08-15 06:59:19 -0700678 pkts.append(p)
Juraj Slobodafe0aa762018-07-23 12:22:54 +0200679 if proto == IP_PROTOS.tcp:
680 raw = Raw(data[20:])
681 else:
682 raw = Raw(data[32:])
Matus Fabianefcd1e92017-08-15 06:59:19 -0700683 p = (Ether(src=src_if.remote_mac, dst=src_if.local_mac) /
Juraj Slobodafe0aa762018-07-23 12:22:54 +0200684 IP(src=src_if.remote_ip4, dst=dst, frag=5, proto=proto,
Matus Fabianefcd1e92017-08-15 06:59:19 -0700685 id=id) /
Juraj Slobodafe0aa762018-07-23 12:22:54 +0200686 raw)
Matus Fabianefcd1e92017-08-15 06:59:19 -0700687 pkts.append(p)
688 return pkts
689
690 def create_stream_frag_ip6(self, src_if, dst, sport, dport, data,
691 pref=None, plen=0, frag_size=128):
692 """
693 Create fragmented packet stream
694
695 :param src_if: Source interface
696 :param dst: Destination IPv4 address
697 :param sport: Source TCP port
698 :param dport: Destination TCP port
699 :param data: Payload data
700 :param pref: NAT64 prefix
701 :param plen: NAT64 prefix length
702 :param fragsize: size of fragments
703 :returns: Fragmets
704 """
705 if pref is None:
706 dst_ip6 = ''.join(['64:ff9b::', dst])
707 else:
708 dst_ip6 = self.compose_ip6(dst, pref, plen)
709
710 p = (Ether(dst=src_if.local_mac, src=src_if.remote_mac) /
711 IPv6(src=src_if.remote_ip6, dst=dst_ip6) /
712 IPv6ExtHdrFragment(id=random.randint(0, 65535)) /
713 TCP(sport=sport, dport=dport) /
714 Raw(data))
715
716 return fragment6(p, frag_size)
717
718 def reass_frags_and_verify(self, frags, src, dst):
719 """
720 Reassemble and verify fragmented packet
721
722 :param frags: Captured fragments
723 :param src: Source IPv4 address to verify
724 :param dst: Destination IPv4 address to verify
725
726 :returns: Reassembled IPv4 packet
727 """
Ole Troan7f991832018-12-06 17:35:12 +0100728 buffer = BytesIO()
Matus Fabianefcd1e92017-08-15 06:59:19 -0700729 for p in frags:
730 self.assertEqual(p[IP].src, src)
731 self.assertEqual(p[IP].dst, dst)
Klement Sekerad81ae412018-05-16 10:52:54 +0200732 self.assert_ip_checksum_valid(p)
Matus Fabianefcd1e92017-08-15 06:59:19 -0700733 buffer.seek(p[IP].frag * 8)
Ole Troan7f991832018-12-06 17:35:12 +0100734 buffer.write(bytes(p[IP].payload))
Matus Fabianefcd1e92017-08-15 06:59:19 -0700735 ip = IP(src=frags[0][IP].src, dst=frags[0][IP].dst,
736 proto=frags[0][IP].proto)
737 if ip.proto == IP_PROTOS.tcp:
738 p = (ip / TCP(buffer.getvalue()))
Klement Sekerad81ae412018-05-16 10:52:54 +0200739 self.assert_tcp_checksum_valid(p)
Matus Fabianefcd1e92017-08-15 06:59:19 -0700740 elif ip.proto == IP_PROTOS.udp:
Juraj Slobodafe0aa762018-07-23 12:22:54 +0200741 p = (ip / UDP(buffer.getvalue()[:8]) /
742 Raw(buffer.getvalue()[8:]))
743 elif ip.proto == IP_PROTOS.icmp:
744 p = (ip / ICMP(buffer.getvalue()))
Matus Fabianefcd1e92017-08-15 06:59:19 -0700745 return p
746
747 def reass_frags_and_verify_ip6(self, frags, src, dst):
748 """
749 Reassemble and verify fragmented packet
750
751 :param frags: Captured fragments
752 :param src: Source IPv6 address to verify
753 :param dst: Destination IPv6 address to verify
754
755 :returns: Reassembled IPv6 packet
756 """
Ole Troan7f991832018-12-06 17:35:12 +0100757 buffer = BytesIO()
Matus Fabianefcd1e92017-08-15 06:59:19 -0700758 for p in frags:
759 self.assertEqual(p[IPv6].src, src)
760 self.assertEqual(p[IPv6].dst, dst)
761 buffer.seek(p[IPv6ExtHdrFragment].offset * 8)
Ole Troan7f991832018-12-06 17:35:12 +0100762 buffer.write(bytes(p[IPv6ExtHdrFragment].payload))
Matus Fabianefcd1e92017-08-15 06:59:19 -0700763 ip = IPv6(src=frags[0][IPv6].src, dst=frags[0][IPv6].dst,
764 nh=frags[0][IPv6ExtHdrFragment].nh)
765 if ip.nh == IP_PROTOS.tcp:
766 p = (ip / TCP(buffer.getvalue()))
Matus Fabianefcd1e92017-08-15 06:59:19 -0700767 elif ip.nh == IP_PROTOS.udp:
768 p = (ip / UDP(buffer.getvalue()))
Klement Sekerad81ae412018-05-16 10:52:54 +0200769 self.assert_packet_checksums_valid(p)
Matus Fabianefcd1e92017-08-15 06:59:19 -0700770 return p
771
Matus Fabianebdf1902018-05-04 03:57:42 -0700772 def initiate_tcp_session(self, in_if, out_if):
773 """
774 Initiates TCP session
775
776 :param in_if: Inside interface
777 :param out_if: Outside interface
778 """
779 try:
780 # SYN packet in->out
781 p = (Ether(src=in_if.remote_mac, dst=in_if.local_mac) /
782 IP(src=in_if.remote_ip4, dst=out_if.remote_ip4) /
783 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
784 flags="S"))
785 in_if.add_stream(p)
786 self.pg_enable_capture(self.pg_interfaces)
787 self.pg_start()
788 capture = out_if.get_capture(1)
789 p = capture[0]
790 self.tcp_port_out = p[TCP].sport
791
792 # SYN + ACK packet out->in
793 p = (Ether(src=out_if.remote_mac, dst=out_if.local_mac) /
794 IP(src=out_if.remote_ip4, dst=self.nat_addr) /
795 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
796 flags="SA"))
797 out_if.add_stream(p)
798 self.pg_enable_capture(self.pg_interfaces)
799 self.pg_start()
800 in_if.get_capture(1)
801
802 # ACK packet in->out
803 p = (Ether(src=in_if.remote_mac, dst=in_if.local_mac) /
804 IP(src=in_if.remote_ip4, dst=out_if.remote_ip4) /
805 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
806 flags="A"))
807 in_if.add_stream(p)
808 self.pg_enable_capture(self.pg_interfaces)
809 self.pg_start()
810 out_if.get_capture(1)
811
812 except:
813 self.logger.error("TCP 3 way handshake failed")
814 raise
815
Matus Fabianeea28d72017-01-13 04:15:54 -0800816 def verify_ipfix_nat44_ses(self, data):
817 """
818 Verify IPFIX NAT44 session create/delete event
819
820 :param data: Decoded IPFIX data records
821 """
822 nat44_ses_create_num = 0
823 nat44_ses_delete_num = 0
824 self.assertEqual(6, len(data))
825 for record in data:
826 # natEvent
827 self.assertIn(ord(record[230]), [4, 5])
828 if ord(record[230]) == 4:
829 nat44_ses_create_num += 1
830 else:
831 nat44_ses_delete_num += 1
832 # sourceIPv4Address
833 self.assertEqual(self.pg0.remote_ip4n, record[8])
834 # postNATSourceIPv4Address
Matus Fabian2ba92e32017-08-21 07:05:03 -0700835 self.assertEqual(socket.inet_pton(socket.AF_INET, self.nat_addr),
Matus Fabianeea28d72017-01-13 04:15:54 -0800836 record[225])
837 # ingressVRFID
838 self.assertEqual(struct.pack("!I", 0), record[234])
839 # protocolIdentifier/sourceTransportPort/postNAPTSourceTransportPort
840 if IP_PROTOS.icmp == ord(record[4]):
841 self.assertEqual(struct.pack("!H", self.icmp_id_in), record[7])
842 self.assertEqual(struct.pack("!H", self.icmp_id_out),
843 record[227])
844 elif IP_PROTOS.tcp == ord(record[4]):
845 self.assertEqual(struct.pack("!H", self.tcp_port_in),
846 record[7])
847 self.assertEqual(struct.pack("!H", self.tcp_port_out),
848 record[227])
849 elif IP_PROTOS.udp == ord(record[4]):
850 self.assertEqual(struct.pack("!H", self.udp_port_in),
851 record[7])
852 self.assertEqual(struct.pack("!H", self.udp_port_out),
853 record[227])
854 else:
855 self.fail("Invalid protocol")
856 self.assertEqual(3, nat44_ses_create_num)
857 self.assertEqual(3, nat44_ses_delete_num)
858
859 def verify_ipfix_addr_exhausted(self, data):
860 """
861 Verify IPFIX NAT addresses event
862
863 :param data: Decoded IPFIX data records
864 """
865 self.assertEqual(1, len(data))
866 record = data[0]
867 # natEvent
868 self.assertEqual(ord(record[230]), 3)
869 # natPoolID
870 self.assertEqual(struct.pack("!I", 0), record[283])
871
Matus Fabiana431ad12018-01-04 04:03:14 -0800872 def verify_ipfix_max_sessions(self, data, limit):
873 """
874 Verify IPFIX maximum session entries exceeded event
875
876 :param data: Decoded IPFIX data records
877 :param limit: Number of maximum session entries that can be created.
878 """
879 self.assertEqual(1, len(data))
880 record = data[0]
881 # natEvent
882 self.assertEqual(ord(record[230]), 13)
883 # natQuotaExceededEvent
884 self.assertEqual(struct.pack("I", 1), record[466])
885 # maxSessionEntries
886 self.assertEqual(struct.pack("I", limit), record[471])
887
888 def verify_ipfix_max_bibs(self, data, limit):
889 """
890 Verify IPFIX maximum BIB entries exceeded event
891
892 :param data: Decoded IPFIX data records
893 :param limit: Number of maximum BIB entries that can be created.
894 """
895 self.assertEqual(1, len(data))
896 record = data[0]
897 # natEvent
898 self.assertEqual(ord(record[230]), 13)
899 # natQuotaExceededEvent
900 self.assertEqual(struct.pack("I", 2), record[466])
901 # maxBIBEntries
902 self.assertEqual(struct.pack("I", limit), record[472])
903
904 def verify_ipfix_max_fragments_ip6(self, data, limit, src_addr):
905 """
906 Verify IPFIX maximum IPv6 fragments pending reassembly exceeded event
907
908 :param data: Decoded IPFIX data records
909 :param limit: Number of maximum fragments pending reassembly
910 :param src_addr: IPv6 source address
911 """
912 self.assertEqual(1, len(data))
913 record = data[0]
914 # natEvent
915 self.assertEqual(ord(record[230]), 13)
916 # natQuotaExceededEvent
917 self.assertEqual(struct.pack("I", 5), record[466])
918 # maxFragmentsPendingReassembly
919 self.assertEqual(struct.pack("I", limit), record[475])
920 # sourceIPv6Address
921 self.assertEqual(src_addr, record[27])
922
923 def verify_ipfix_max_fragments_ip4(self, data, limit, src_addr):
924 """
925 Verify IPFIX maximum IPv4 fragments pending reassembly exceeded event
926
927 :param data: Decoded IPFIX data records
928 :param limit: Number of maximum fragments pending reassembly
929 :param src_addr: IPv4 source address
930 """
931 self.assertEqual(1, len(data))
932 record = data[0]
933 # natEvent
934 self.assertEqual(ord(record[230]), 13)
935 # natQuotaExceededEvent
936 self.assertEqual(struct.pack("I", 5), record[466])
937 # maxFragmentsPendingReassembly
938 self.assertEqual(struct.pack("I", limit), record[475])
939 # sourceIPv4Address
940 self.assertEqual(src_addr, record[8])
941
942 def verify_ipfix_bib(self, data, is_create, src_addr):
943 """
944 Verify IPFIX NAT64 BIB create and delete events
945
946 :param data: Decoded IPFIX data records
947 :param is_create: Create event if nonzero value otherwise delete event
948 :param src_addr: IPv6 source address
949 """
950 self.assertEqual(1, len(data))
951 record = data[0]
952 # natEvent
953 if is_create:
954 self.assertEqual(ord(record[230]), 10)
955 else:
956 self.assertEqual(ord(record[230]), 11)
957 # sourceIPv6Address
958 self.assertEqual(src_addr, record[27])
959 # postNATSourceIPv4Address
960 self.assertEqual(self.nat_addr_n, record[225])
961 # protocolIdentifier
962 self.assertEqual(IP_PROTOS.tcp, ord(record[4]))
963 # ingressVRFID
964 self.assertEqual(struct.pack("!I", 0), record[234])
965 # sourceTransportPort
966 self.assertEqual(struct.pack("!H", self.tcp_port_in), record[7])
967 # postNAPTSourceTransportPort
968 self.assertEqual(struct.pack("!H", self.tcp_port_out), record[227])
969
970 def verify_ipfix_nat64_ses(self, data, is_create, src_addr, dst_addr,
971 dst_port):
972 """
973 Verify IPFIX NAT64 session create and delete events
974
975 :param data: Decoded IPFIX data records
976 :param is_create: Create event if nonzero value otherwise delete event
977 :param src_addr: IPv6 source address
978 :param dst_addr: IPv4 destination address
979 :param dst_port: destination TCP port
980 """
981 self.assertEqual(1, len(data))
982 record = data[0]
983 # natEvent
984 if is_create:
985 self.assertEqual(ord(record[230]), 6)
986 else:
987 self.assertEqual(ord(record[230]), 7)
988 # sourceIPv6Address
989 self.assertEqual(src_addr, record[27])
990 # destinationIPv6Address
991 self.assertEqual(socket.inet_pton(socket.AF_INET6,
992 self.compose_ip6(dst_addr,
993 '64:ff9b::',
994 96)),
995 record[28])
996 # postNATSourceIPv4Address
997 self.assertEqual(self.nat_addr_n, record[225])
998 # postNATDestinationIPv4Address
999 self.assertEqual(socket.inet_pton(socket.AF_INET, dst_addr),
1000 record[226])
1001 # protocolIdentifier
1002 self.assertEqual(IP_PROTOS.tcp, ord(record[4]))
1003 # ingressVRFID
1004 self.assertEqual(struct.pack("!I", 0), record[234])
1005 # sourceTransportPort
1006 self.assertEqual(struct.pack("!H", self.tcp_port_in), record[7])
1007 # postNAPTSourceTransportPort
1008 self.assertEqual(struct.pack("!H", self.tcp_port_out), record[227])
1009 # destinationTransportPort
1010 self.assertEqual(struct.pack("!H", dst_port), record[11])
1011 # postNAPTDestinationTransportPort
1012 self.assertEqual(struct.pack("!H", dst_port), record[228])
1013
Matus Fabian68ba8802018-08-08 05:52:47 -07001014 def verify_no_nat44_user(self):
1015 """ Verify that there is no NAT44 user """
1016 users = self.vapi.nat44_user_dump()
1017 self.assertEqual(len(users), 0)
1018
Matus Fabian878c6462018-08-23 00:33:35 -07001019 def verify_ipfix_max_entries_per_user(self, data, limit, src_addr):
1020 """
1021 Verify IPFIX maximum entries per user exceeded event
1022
1023 :param data: Decoded IPFIX data records
1024 :param limit: Number of maximum entries per user
1025 :param src_addr: IPv4 source address
1026 """
1027 self.assertEqual(1, len(data))
1028 record = data[0]
1029 # natEvent
1030 self.assertEqual(ord(record[230]), 13)
1031 # natQuotaExceededEvent
1032 self.assertEqual(struct.pack("I", 3), record[466])
1033 # maxEntriesPerUser
1034 self.assertEqual(struct.pack("I", limit), record[473])
1035 # sourceIPv4Address
1036 self.assertEqual(src_addr, record[8])
1037
Matus Fabianad1f3e12018-11-28 21:26:34 -08001038 def verify_syslog_apmap(self, data, is_add=True):
1039 message = data.decode('utf-8')
1040 try:
1041 message = SyslogMessage.parse(message)
1042 self.assertEqual(message.severity, SyslogSeverity.info)
1043 self.assertEqual(message.appname, 'NAT')
1044 self.assertEqual(message.msgid, 'APMADD' if is_add else 'APMDEL')
1045 sd_params = message.sd.get('napmap')
1046 self.assertTrue(sd_params is not None)
1047 self.assertEqual(sd_params.get('IATYP'), 'IPv4')
1048 self.assertEqual(sd_params.get('ISADDR'), self.pg0.remote_ip4)
1049 self.assertEqual(sd_params.get('ISPORT'), "%d" % self.tcp_port_in)
1050 self.assertEqual(sd_params.get('XATYP'), 'IPv4')
1051 self.assertEqual(sd_params.get('XSADDR'), self.nat_addr)
1052 self.assertEqual(sd_params.get('XSPORT'), "%d" % self.tcp_port_out)
1053 self.assertEqual(sd_params.get('PROTO'), "%d" % IP_PROTOS.tcp)
1054 self.assertTrue(sd_params.get('SSUBIX') is not None)
1055 self.assertEqual(sd_params.get('SVLAN'), '0')
1056 except ParseError as e:
1057 self.logger.error(e)
1058
1059 def verify_syslog_sess(self, data, is_add=True, is_ip6=False):
1060 message = data.decode('utf-8')
1061 try:
1062 message = SyslogMessage.parse(message)
1063 self.assertEqual(message.severity, SyslogSeverity.info)
1064 self.assertEqual(message.appname, 'NAT')
1065 self.assertEqual(message.msgid, 'SADD' if is_add else 'SDEL')
1066 sd_params = message.sd.get('nsess')
1067 self.assertTrue(sd_params is not None)
1068 if is_ip6:
1069 self.assertEqual(sd_params.get('IATYP'), 'IPv6')
1070 self.assertEqual(sd_params.get('ISADDR'), self.pg0.remote_ip6)
1071 else:
1072 self.assertEqual(sd_params.get('IATYP'), 'IPv4')
1073 self.assertEqual(sd_params.get('ISADDR'), self.pg0.remote_ip4)
1074 self.assertTrue(sd_params.get('SSUBIX') is not None)
1075 self.assertEqual(sd_params.get('ISPORT'), "%d" % self.tcp_port_in)
1076 self.assertEqual(sd_params.get('XATYP'), 'IPv4')
1077 self.assertEqual(sd_params.get('XSADDR'), self.nat_addr)
1078 self.assertEqual(sd_params.get('XSPORT'), "%d" % self.tcp_port_out)
1079 self.assertEqual(sd_params.get('PROTO'), "%d" % IP_PROTOS.tcp)
1080 self.assertEqual(sd_params.get('SVLAN'), '0')
1081 self.assertEqual(sd_params.get('XDADDR'), self.pg1.remote_ip4)
1082 self.assertEqual(sd_params.get('XDPORT'),
1083 "%d" % self.tcp_external_port)
1084 except ParseError as e:
1085 self.logger.error(e)
1086
Matus Fabianbb4e0222018-09-13 02:36:25 -07001087 def verify_mss_value(self, pkt, mss):
1088 """
1089 Verify TCP MSS value
1090
1091 :param pkt:
1092 :param mss:
1093 """
1094 if not pkt.haslayer(IP) or not pkt.haslayer(TCP):
1095 raise TypeError("Not a TCP/IP packet")
1096
1097 for option in pkt[TCP].options:
1098 if option[0] == 'MSS':
1099 self.assertEqual(option[1], mss)
1100 self.assert_tcp_checksum_valid(pkt)
1101
Juraj Slobodafe0aa762018-07-23 12:22:54 +02001102 @staticmethod
1103 def proto2layer(proto):
1104 if proto == IP_PROTOS.tcp:
1105 return TCP
1106 elif proto == IP_PROTOS.udp:
1107 return UDP
1108 elif proto == IP_PROTOS.icmp:
1109 return ICMP
1110 else:
1111 raise Exception("Unsupported protocol")
1112
1113 def frag_in_order(self, proto=IP_PROTOS.tcp, dont_translate=False):
1114 layer = self.proto2layer(proto)
1115
1116 if proto == IP_PROTOS.tcp:
1117 data = "A" * 4 + "B" * 16 + "C" * 3
1118 else:
1119 data = "A" * 16 + "B" * 16 + "C" * 3
1120 self.port_in = random.randint(1025, 65535)
1121
1122 reass = self.vapi.nat_reass_dump()
1123 reass_n_start = len(reass)
1124
1125 # in2out
1126 pkts = self.create_stream_frag(self.pg0,
1127 self.pg1.remote_ip4,
1128 self.port_in,
1129 20,
1130 data,
1131 proto)
1132 self.pg0.add_stream(pkts)
1133 self.pg_enable_capture(self.pg_interfaces)
1134 self.pg_start()
1135 frags = self.pg1.get_capture(len(pkts))
1136 if not dont_translate:
1137 p = self.reass_frags_and_verify(frags,
1138 self.nat_addr,
1139 self.pg1.remote_ip4)
1140 else:
1141 p = self.reass_frags_and_verify(frags,
1142 self.pg0.remote_ip4,
1143 self.pg1.remote_ip4)
1144 if proto != IP_PROTOS.icmp:
1145 if not dont_translate:
1146 self.assertEqual(p[layer].dport, 20)
1147 self.assertNotEqual(p[layer].sport, self.port_in)
1148 else:
1149 self.assertEqual(p[layer].sport, self.port_in)
1150 else:
1151 if not dont_translate:
1152 self.assertNotEqual(p[layer].id, self.port_in)
1153 else:
1154 self.assertEqual(p[layer].id, self.port_in)
1155 self.assertEqual(data, p[Raw].load)
1156
1157 # out2in
1158 if not dont_translate:
1159 dst_addr = self.nat_addr
1160 else:
1161 dst_addr = self.pg0.remote_ip4
1162 if proto != IP_PROTOS.icmp:
1163 sport = 20
1164 dport = p[layer].sport
1165 else:
1166 sport = p[layer].id
1167 dport = 0
1168 pkts = self.create_stream_frag(self.pg1,
1169 dst_addr,
1170 sport,
1171 dport,
1172 data,
1173 proto,
1174 echo_reply=True)
1175 self.pg1.add_stream(pkts)
1176 self.pg_enable_capture(self.pg_interfaces)
1177 self.pg_start()
1178 frags = self.pg0.get_capture(len(pkts))
1179 p = self.reass_frags_and_verify(frags,
1180 self.pg1.remote_ip4,
1181 self.pg0.remote_ip4)
1182 if proto != IP_PROTOS.icmp:
1183 self.assertEqual(p[layer].sport, 20)
1184 self.assertEqual(p[layer].dport, self.port_in)
1185 else:
1186 self.assertEqual(p[layer].id, self.port_in)
1187 self.assertEqual(data, p[Raw].load)
1188
1189 reass = self.vapi.nat_reass_dump()
1190 reass_n_end = len(reass)
1191
1192 self.assertEqual(reass_n_end - reass_n_start, 2)
1193
1194 def frag_in_order_in_plus_out(self, proto=IP_PROTOS.tcp):
1195 layer = self.proto2layer(proto)
1196
1197 if proto == IP_PROTOS.tcp:
1198 data = "A" * 4 + "B" * 16 + "C" * 3
1199 else:
1200 data = "A" * 16 + "B" * 16 + "C" * 3
1201 self.port_in = random.randint(1025, 65535)
1202
1203 for i in range(2):
1204 reass = self.vapi.nat_reass_dump()
1205 reass_n_start = len(reass)
1206
1207 # out2in
1208 pkts = self.create_stream_frag(self.pg0,
1209 self.server_out_addr,
1210 self.port_in,
1211 self.server_out_port,
1212 data,
1213 proto)
1214 self.pg0.add_stream(pkts)
1215 self.pg_enable_capture(self.pg_interfaces)
1216 self.pg_start()
1217 frags = self.pg1.get_capture(len(pkts))
1218 p = self.reass_frags_and_verify(frags,
1219 self.pg0.remote_ip4,
1220 self.server_in_addr)
1221 if proto != IP_PROTOS.icmp:
1222 self.assertEqual(p[layer].sport, self.port_in)
1223 self.assertEqual(p[layer].dport, self.server_in_port)
1224 else:
1225 self.assertEqual(p[layer].id, self.port_in)
1226 self.assertEqual(data, p[Raw].load)
1227
1228 # in2out
1229 if proto != IP_PROTOS.icmp:
1230 pkts = self.create_stream_frag(self.pg1,
1231 self.pg0.remote_ip4,
1232 self.server_in_port,
1233 p[layer].sport,
1234 data,
1235 proto)
1236 else:
1237 pkts = self.create_stream_frag(self.pg1,
1238 self.pg0.remote_ip4,
1239 p[layer].id,
1240 0,
1241 data,
1242 proto,
1243 echo_reply=True)
1244 self.pg1.add_stream(pkts)
1245 self.pg_enable_capture(self.pg_interfaces)
1246 self.pg_start()
1247 frags = self.pg0.get_capture(len(pkts))
1248 p = self.reass_frags_and_verify(frags,
1249 self.server_out_addr,
1250 self.pg0.remote_ip4)
1251 if proto != IP_PROTOS.icmp:
1252 self.assertEqual(p[layer].sport, self.server_out_port)
1253 self.assertEqual(p[layer].dport, self.port_in)
1254 else:
1255 self.assertEqual(p[layer].id, self.port_in)
1256 self.assertEqual(data, p[Raw].load)
1257
1258 reass = self.vapi.nat_reass_dump()
1259 reass_n_end = len(reass)
1260
1261 self.assertEqual(reass_n_end - reass_n_start, 2)
1262
1263 def reass_hairpinning(self, proto=IP_PROTOS.tcp):
1264 layer = self.proto2layer(proto)
1265
1266 if proto == IP_PROTOS.tcp:
1267 data = "A" * 4 + "B" * 16 + "C" * 3
1268 else:
1269 data = "A" * 16 + "B" * 16 + "C" * 3
1270
1271 # send packet from host to server
1272 pkts = self.create_stream_frag(self.pg0,
1273 self.nat_addr,
1274 self.host_in_port,
1275 self.server_out_port,
1276 data,
1277 proto)
1278 self.pg0.add_stream(pkts)
1279 self.pg_enable_capture(self.pg_interfaces)
1280 self.pg_start()
1281 frags = self.pg0.get_capture(len(pkts))
1282 p = self.reass_frags_and_verify(frags,
1283 self.nat_addr,
1284 self.server.ip4)
1285 if proto != IP_PROTOS.icmp:
1286 self.assertNotEqual(p[layer].sport, self.host_in_port)
1287 self.assertEqual(p[layer].dport, self.server_in_port)
1288 else:
1289 self.assertNotEqual(p[layer].id, self.host_in_port)
1290 self.assertEqual(data, p[Raw].load)
1291
1292 def frag_out_of_order(self, proto=IP_PROTOS.tcp, dont_translate=False):
1293 layer = self.proto2layer(proto)
1294
1295 if proto == IP_PROTOS.tcp:
1296 data = "A" * 4 + "B" * 16 + "C" * 3
1297 else:
1298 data = "A" * 16 + "B" * 16 + "C" * 3
1299 self.port_in = random.randint(1025, 65535)
1300
1301 for i in range(2):
1302 # in2out
1303 pkts = self.create_stream_frag(self.pg0,
1304 self.pg1.remote_ip4,
1305 self.port_in,
1306 20,
1307 data,
1308 proto)
1309 pkts.reverse()
1310 self.pg0.add_stream(pkts)
1311 self.pg_enable_capture(self.pg_interfaces)
1312 self.pg_start()
1313 frags = self.pg1.get_capture(len(pkts))
1314 if not dont_translate:
1315 p = self.reass_frags_and_verify(frags,
1316 self.nat_addr,
1317 self.pg1.remote_ip4)
1318 else:
1319 p = self.reass_frags_and_verify(frags,
1320 self.pg0.remote_ip4,
1321 self.pg1.remote_ip4)
1322 if proto != IP_PROTOS.icmp:
1323 if not dont_translate:
1324 self.assertEqual(p[layer].dport, 20)
1325 self.assertNotEqual(p[layer].sport, self.port_in)
1326 else:
1327 self.assertEqual(p[layer].sport, self.port_in)
1328 else:
1329 if not dont_translate:
1330 self.assertNotEqual(p[layer].id, self.port_in)
1331 else:
1332 self.assertEqual(p[layer].id, self.port_in)
1333 self.assertEqual(data, p[Raw].load)
1334
1335 # out2in
1336 if not dont_translate:
1337 dst_addr = self.nat_addr
1338 else:
1339 dst_addr = self.pg0.remote_ip4
1340 if proto != IP_PROTOS.icmp:
1341 sport = 20
1342 dport = p[layer].sport
1343 else:
1344 sport = p[layer].id
1345 dport = 0
1346 pkts = self.create_stream_frag(self.pg1,
1347 dst_addr,
1348 sport,
1349 dport,
1350 data,
1351 proto,
1352 echo_reply=True)
1353 pkts.reverse()
1354 self.pg1.add_stream(pkts)
1355 self.pg_enable_capture(self.pg_interfaces)
1356 self.pg_start()
1357 frags = self.pg0.get_capture(len(pkts))
1358 p = self.reass_frags_and_verify(frags,
1359 self.pg1.remote_ip4,
1360 self.pg0.remote_ip4)
1361 if proto != IP_PROTOS.icmp:
1362 self.assertEqual(p[layer].sport, 20)
1363 self.assertEqual(p[layer].dport, self.port_in)
1364 else:
1365 self.assertEqual(p[layer].id, self.port_in)
1366 self.assertEqual(data, p[Raw].load)
1367
1368 def frag_out_of_order_in_plus_out(self, proto=IP_PROTOS.tcp):
1369 layer = self.proto2layer(proto)
1370
1371 if proto == IP_PROTOS.tcp:
1372 data = "A" * 4 + "B" * 16 + "C" * 3
1373 else:
1374 data = "A" * 16 + "B" * 16 + "C" * 3
1375 self.port_in = random.randint(1025, 65535)
1376
1377 for i in range(2):
1378 # out2in
1379 pkts = self.create_stream_frag(self.pg0,
1380 self.server_out_addr,
1381 self.port_in,
1382 self.server_out_port,
1383 data,
1384 proto)
1385 pkts.reverse()
1386 self.pg0.add_stream(pkts)
1387 self.pg_enable_capture(self.pg_interfaces)
1388 self.pg_start()
1389 frags = self.pg1.get_capture(len(pkts))
1390 p = self.reass_frags_and_verify(frags,
1391 self.pg0.remote_ip4,
1392 self.server_in_addr)
1393 if proto != IP_PROTOS.icmp:
1394 self.assertEqual(p[layer].dport, self.server_in_port)
1395 self.assertEqual(p[layer].sport, self.port_in)
1396 self.assertEqual(p[layer].dport, self.server_in_port)
1397 else:
1398 self.assertEqual(p[layer].id, self.port_in)
1399 self.assertEqual(data, p[Raw].load)
1400
1401 # in2out
1402 if proto != IP_PROTOS.icmp:
1403 pkts = self.create_stream_frag(self.pg1,
1404 self.pg0.remote_ip4,
1405 self.server_in_port,
1406 p[layer].sport,
1407 data,
1408 proto)
1409 else:
1410 pkts = self.create_stream_frag(self.pg1,
1411 self.pg0.remote_ip4,
1412 p[layer].id,
1413 0,
1414 data,
1415 proto,
1416 echo_reply=True)
1417 pkts.reverse()
1418 self.pg1.add_stream(pkts)
1419 self.pg_enable_capture(self.pg_interfaces)
1420 self.pg_start()
1421 frags = self.pg0.get_capture(len(pkts))
1422 p = self.reass_frags_and_verify(frags,
1423 self.server_out_addr,
1424 self.pg0.remote_ip4)
1425 if proto != IP_PROTOS.icmp:
1426 self.assertEqual(p[layer].sport, self.server_out_port)
1427 self.assertEqual(p[layer].dport, self.port_in)
1428 else:
1429 self.assertEqual(p[layer].id, self.port_in)
1430 self.assertEqual(data, p[Raw].load)
1431
Martin Gálikd7f75cd2017-03-27 06:02:47 -07001432
Matus Fabian2ba92e32017-08-21 07:05:03 -07001433class TestNAT44(MethodHolder):
1434 """ NAT44 Test Cases """
Martin Gálikd7f75cd2017-03-27 06:02:47 -07001435
1436 @classmethod
1437 def setUpClass(cls):
Matus Fabian2ba92e32017-08-21 07:05:03 -07001438 super(TestNAT44, cls).setUpClass()
Matus Fabian229c1aa2018-05-28 04:09:52 -07001439 cls.vapi.cli("set log class nat level debug")
Martin Gálikd7f75cd2017-03-27 06:02:47 -07001440
1441 try:
1442 cls.tcp_port_in = 6303
1443 cls.tcp_port_out = 6303
1444 cls.udp_port_in = 6304
1445 cls.udp_port_out = 6304
1446 cls.icmp_id_in = 6305
1447 cls.icmp_id_out = 6305
Matus Fabian2ba92e32017-08-21 07:05:03 -07001448 cls.nat_addr = '10.0.0.3'
Juraj Sloboda7b929792017-11-23 13:20:48 +01001449 cls.nat_addr_n = socket.inet_pton(socket.AF_INET, cls.nat_addr)
Matus Fabian6631e9c2017-05-24 01:52:20 -07001450 cls.ipfix_src_port = 4739
1451 cls.ipfix_domain_id = 1
Matus Fabianebdf1902018-05-04 03:57:42 -07001452 cls.tcp_external_port = 80
Martin Gálikd7f75cd2017-03-27 06:02:47 -07001453
Matus Fabian36ea2d62017-10-24 04:13:49 -07001454 cls.create_pg_interfaces(range(10))
Martin Gálikd7f75cd2017-03-27 06:02:47 -07001455 cls.interfaces = list(cls.pg_interfaces[0:4])
1456
1457 for i in cls.interfaces:
1458 i.admin_up()
1459 i.config_ip4()
1460 i.resolve_arp()
1461
Matus Fabian6fa74c62017-06-05 05:55:48 -07001462 cls.pg0.generate_remote_hosts(3)
Martin Gálikd7f75cd2017-03-27 06:02:47 -07001463 cls.pg0.configure_ipv4_neighbors()
1464
Juraj Sloboda1e5c07d2018-04-10 13:51:54 +02001465 cls.pg1.generate_remote_hosts(1)
1466 cls.pg1.configure_ipv4_neighbors()
1467
Martin Gálikd7f75cd2017-03-27 06:02:47 -07001468 cls.overlapping_interfaces = list(list(cls.pg_interfaces[4:7]))
Neale Ranns15002542017-09-10 04:39:11 -07001469 cls.vapi.ip_table_add_del(10, is_add=1)
1470 cls.vapi.ip_table_add_del(20, is_add=1)
Martin Gálikd7f75cd2017-03-27 06:02:47 -07001471
1472 cls.pg4._local_ip4 = "172.16.255.1"
1473 cls.pg4._local_ip4n = socket.inet_pton(socket.AF_INET, i.local_ip4)
1474 cls.pg4._remote_hosts[0]._ip4 = "172.16.255.2"
1475 cls.pg4.set_table_ip4(10)
Matus Fabian69126282017-08-14 23:39:58 -07001476 cls.pg5._local_ip4 = "172.17.255.3"
Martin Gálikd7f75cd2017-03-27 06:02:47 -07001477 cls.pg5._local_ip4n = socket.inet_pton(socket.AF_INET, i.local_ip4)
Matus Fabian69126282017-08-14 23:39:58 -07001478 cls.pg5._remote_hosts[0]._ip4 = "172.17.255.4"
Martin Gálikd7f75cd2017-03-27 06:02:47 -07001479 cls.pg5.set_table_ip4(10)
1480 cls.pg6._local_ip4 = "172.16.255.1"
1481 cls.pg6._local_ip4n = socket.inet_pton(socket.AF_INET, i.local_ip4)
1482 cls.pg6._remote_hosts[0]._ip4 = "172.16.255.2"
1483 cls.pg6.set_table_ip4(20)
1484 for i in cls.overlapping_interfaces:
1485 i.config_ip4()
1486 i.admin_up()
1487 i.resolve_arp()
1488
1489 cls.pg7.admin_up()
Martin Gálik406eb1d2017-05-04 04:35:04 -07001490 cls.pg8.admin_up()
Martin Gálikd7f75cd2017-03-27 06:02:47 -07001491
Matus Fabian36ea2d62017-10-24 04:13:49 -07001492 cls.pg9.generate_remote_hosts(2)
1493 cls.pg9.config_ip4()
1494 ip_addr_n = socket.inet_pton(socket.AF_INET, "10.0.0.1")
1495 cls.vapi.sw_interface_add_del_address(cls.pg9.sw_if_index,
1496 ip_addr_n,
1497 24)
1498 cls.pg9.admin_up()
1499 cls.pg9.resolve_arp()
1500 cls.pg9._remote_hosts[1]._ip4 = cls.pg9._remote_hosts[0]._ip4
1501 cls.pg4._remote_ip4 = cls.pg9._remote_hosts[0]._ip4 = "10.0.0.2"
1502 cls.pg9.resolve_arp()
1503
Martin Gálikd7f75cd2017-03-27 06:02:47 -07001504 except Exception:
Matus Fabian2ba92e32017-08-21 07:05:03 -07001505 super(TestNAT44, cls).tearDownClass()
Martin Gálikd7f75cd2017-03-27 06:02:47 -07001506 raise
1507
Matus Fabiande886752016-12-07 03:38:19 -08001508 def test_dynamic(self):
Matus Fabian2ba92e32017-08-21 07:05:03 -07001509 """ NAT44 dynamic translation test """
Matus Fabian2ba92e32017-08-21 07:05:03 -07001510 self.nat44_add_address(self.nat_addr)
1511 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
1512 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
1513 is_inside=0)
Matus Fabiande886752016-12-07 03:38:19 -08001514
1515 # in2out
Matus Fabiana5e73762018-12-14 01:55:16 -08001516 tcpn = self.statistics.get_counter(
1517 '/err/nat44-in2out-slowpath/TCP packets')
1518 udpn = self.statistics.get_counter(
1519 '/err/nat44-in2out-slowpath/UDP packets')
1520 icmpn = self.statistics.get_counter(
1521 '/err/nat44-in2out-slowpath/ICMP packets')
1522 totaln = self.statistics.get_counter(
1523 '/err/nat44-in2out-slowpath/good in2out packets processed')
1524
Matus Fabiande886752016-12-07 03:38:19 -08001525 pkts = self.create_stream_in(self.pg0, self.pg1)
1526 self.pg0.add_stream(pkts)
1527 self.pg_enable_capture(self.pg_interfaces)
1528 self.pg_start()
Klement Sekeradab231a2016-12-21 08:50:14 +01001529 capture = self.pg1.get_capture(len(pkts))
Matus Fabiande886752016-12-07 03:38:19 -08001530 self.verify_capture_out(capture)
1531
Matus Fabiana5e73762018-12-14 01:55:16 -08001532 err = self.statistics.get_counter(
1533 '/err/nat44-in2out-slowpath/TCP packets')
1534 self.assertEqual(err - tcpn, 1)
1535 err = self.statistics.get_counter(
1536 '/err/nat44-in2out-slowpath/UDP packets')
1537 self.assertEqual(err - udpn, 1)
1538 err = self.statistics.get_counter(
1539 '/err/nat44-in2out-slowpath/ICMP packets')
1540 self.assertEqual(err - icmpn, 1)
1541 err = self.statistics.get_counter(
1542 '/err/nat44-in2out-slowpath/good in2out packets processed')
1543 self.assertEqual(err - totaln, 3)
1544
Matus Fabiande886752016-12-07 03:38:19 -08001545 # out2in
Matus Fabiana5e73762018-12-14 01:55:16 -08001546 tcpn = self.statistics.get_counter('/err/nat44-out2in/TCP packets')
1547 udpn = self.statistics.get_counter('/err/nat44-out2in/UDP packets')
1548 icmpn = self.statistics.get_counter('/err/nat44-out2in/ICMP packets')
1549 totaln = self.statistics.get_counter(
1550 '/err/nat44-out2in/good out2in packets processed')
1551
Matus Fabiande886752016-12-07 03:38:19 -08001552 pkts = self.create_stream_out(self.pg1)
1553 self.pg1.add_stream(pkts)
1554 self.pg_enable_capture(self.pg_interfaces)
1555 self.pg_start()
Klement Sekeradab231a2016-12-21 08:50:14 +01001556 capture = self.pg0.get_capture(len(pkts))
Matus Fabiande886752016-12-07 03:38:19 -08001557 self.verify_capture_in(capture, self.pg0)
1558
Matus Fabiana5e73762018-12-14 01:55:16 -08001559 err = self.statistics.get_counter('/err/nat44-out2in/TCP packets')
1560 self.assertEqual(err - tcpn, 1)
1561 err = self.statistics.get_counter('/err/nat44-out2in/UDP packets')
1562 self.assertEqual(err - udpn, 1)
1563 err = self.statistics.get_counter('/err/nat44-out2in/ICMP packets')
1564 self.assertEqual(err - icmpn, 1)
1565 err = self.statistics.get_counter(
1566 '/err/nat44-out2in/good out2in packets processed')
1567 self.assertEqual(err - totaln, 3)
1568
Juraj Slobodab33f4132017-02-08 23:54:21 -08001569 def test_dynamic_icmp_errors_in2out_ttl_1(self):
Matus Fabian2ba92e32017-08-21 07:05:03 -07001570 """ NAT44 handling of client packets with TTL=1 """
Juraj Slobodab33f4132017-02-08 23:54:21 -08001571
Matus Fabian2ba92e32017-08-21 07:05:03 -07001572 self.nat44_add_address(self.nat_addr)
1573 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
1574 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
1575 is_inside=0)
Juraj Slobodab33f4132017-02-08 23:54:21 -08001576
1577 # Client side - generate traffic
1578 pkts = self.create_stream_in(self.pg0, self.pg1, ttl=1)
1579 self.pg0.add_stream(pkts)
1580 self.pg_enable_capture(self.pg_interfaces)
1581 self.pg_start()
1582
1583 # Client side - verify ICMP type 11 packets
1584 capture = self.pg0.get_capture(len(pkts))
1585 self.verify_capture_in_with_icmp_errors(capture, self.pg0)
1586
1587 def test_dynamic_icmp_errors_out2in_ttl_1(self):
Matus Fabian2ba92e32017-08-21 07:05:03 -07001588 """ NAT44 handling of server packets with TTL=1 """
Juraj Slobodab33f4132017-02-08 23:54:21 -08001589
Matus Fabian2ba92e32017-08-21 07:05:03 -07001590 self.nat44_add_address(self.nat_addr)
1591 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
1592 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
1593 is_inside=0)
Juraj Slobodab33f4132017-02-08 23:54:21 -08001594
1595 # Client side - create sessions
1596 pkts = self.create_stream_in(self.pg0, self.pg1)
1597 self.pg0.add_stream(pkts)
1598 self.pg_enable_capture(self.pg_interfaces)
1599 self.pg_start()
1600
1601 # Server side - generate traffic
1602 capture = self.pg1.get_capture(len(pkts))
1603 self.verify_capture_out(capture)
1604 pkts = self.create_stream_out(self.pg1, ttl=1)
1605 self.pg1.add_stream(pkts)
1606 self.pg_enable_capture(self.pg_interfaces)
1607 self.pg_start()
1608
1609 # Server side - verify ICMP type 11 packets
1610 capture = self.pg1.get_capture(len(pkts))
1611 self.verify_capture_out_with_icmp_errors(capture,
1612 src_ip=self.pg1.local_ip4)
1613
1614 def test_dynamic_icmp_errors_in2out_ttl_2(self):
Matus Fabian2ba92e32017-08-21 07:05:03 -07001615 """ NAT44 handling of error responses to client packets with TTL=2 """
Juraj Slobodab33f4132017-02-08 23:54:21 -08001616
Matus Fabian2ba92e32017-08-21 07:05:03 -07001617 self.nat44_add_address(self.nat_addr)
1618 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
1619 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
1620 is_inside=0)
Juraj Slobodab33f4132017-02-08 23:54:21 -08001621
1622 # Client side - generate traffic
1623 pkts = self.create_stream_in(self.pg0, self.pg1, ttl=2)
1624 self.pg0.add_stream(pkts)
1625 self.pg_enable_capture(self.pg_interfaces)
1626 self.pg_start()
1627
1628 # Server side - simulate ICMP type 11 response
1629 capture = self.pg1.get_capture(len(pkts))
1630 pkts = [Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
Matus Fabian2ba92e32017-08-21 07:05:03 -07001631 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
Juraj Slobodab33f4132017-02-08 23:54:21 -08001632 ICMP(type=11) / packet[IP] for packet in capture]
1633 self.pg1.add_stream(pkts)
1634 self.pg_enable_capture(self.pg_interfaces)
1635 self.pg_start()
1636
1637 # Client side - verify ICMP type 11 packets
1638 capture = self.pg0.get_capture(len(pkts))
1639 self.verify_capture_in_with_icmp_errors(capture, self.pg0)
1640
1641 def test_dynamic_icmp_errors_out2in_ttl_2(self):
Matus Fabian2ba92e32017-08-21 07:05:03 -07001642 """ NAT44 handling of error responses to server packets with TTL=2 """
Juraj Slobodab33f4132017-02-08 23:54:21 -08001643
Matus Fabian2ba92e32017-08-21 07:05:03 -07001644 self.nat44_add_address(self.nat_addr)
1645 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
1646 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
1647 is_inside=0)
Juraj Slobodab33f4132017-02-08 23:54:21 -08001648
1649 # Client side - create sessions
1650 pkts = self.create_stream_in(self.pg0, self.pg1)
1651 self.pg0.add_stream(pkts)
1652 self.pg_enable_capture(self.pg_interfaces)
1653 self.pg_start()
1654
1655 # Server side - generate traffic
1656 capture = self.pg1.get_capture(len(pkts))
1657 self.verify_capture_out(capture)
1658 pkts = self.create_stream_out(self.pg1, ttl=2)
1659 self.pg1.add_stream(pkts)
1660 self.pg_enable_capture(self.pg_interfaces)
1661 self.pg_start()
1662
1663 # Client side - simulate ICMP type 11 response
1664 capture = self.pg0.get_capture(len(pkts))
1665 pkts = [Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
1666 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
1667 ICMP(type=11) / packet[IP] for packet in capture]
1668 self.pg0.add_stream(pkts)
1669 self.pg_enable_capture(self.pg_interfaces)
1670 self.pg_start()
1671
1672 # Server side - verify ICMP type 11 packets
1673 capture = self.pg1.get_capture(len(pkts))
1674 self.verify_capture_out_with_icmp_errors(capture)
1675
Juraj Sloboda665e4822017-02-16 17:17:19 -08001676 def test_ping_out_interface_from_outside(self):
Matus Fabian2ba92e32017-08-21 07:05:03 -07001677 """ Ping NAT44 out interface from outside network """
Juraj Sloboda665e4822017-02-16 17:17:19 -08001678
Matus Fabian2ba92e32017-08-21 07:05:03 -07001679 self.nat44_add_address(self.nat_addr)
1680 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
1681 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
1682 is_inside=0)
Juraj Sloboda665e4822017-02-16 17:17:19 -08001683
1684 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
1685 IP(src=self.pg1.remote_ip4, dst=self.pg1.local_ip4) /
1686 ICMP(id=self.icmp_id_out, type='echo-request'))
1687 pkts = [p]
1688 self.pg1.add_stream(pkts)
1689 self.pg_enable_capture(self.pg_interfaces)
1690 self.pg_start()
1691 capture = self.pg1.get_capture(len(pkts))
Juraj Sloboda665e4822017-02-16 17:17:19 -08001692 packet = capture[0]
1693 try:
1694 self.assertEqual(packet[IP].src, self.pg1.local_ip4)
1695 self.assertEqual(packet[IP].dst, self.pg1.remote_ip4)
1696 self.assertEqual(packet[ICMP].id, self.icmp_id_in)
1697 self.assertEqual(packet[ICMP].type, 0) # echo reply
1698 except:
1699 self.logger.error(ppp("Unexpected or invalid packet "
1700 "(outside network):", packet))
1701 raise
1702
Juraj Slobodad3677682017-04-14 03:24:45 +02001703 def test_ping_internal_host_from_outside(self):
1704 """ Ping internal host from outside network """
1705
Matus Fabian2ba92e32017-08-21 07:05:03 -07001706 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr)
1707 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
1708 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
1709 is_inside=0)
Juraj Slobodad3677682017-04-14 03:24:45 +02001710
1711 # out2in
1712 pkt = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
Matus Fabian2ba92e32017-08-21 07:05:03 -07001713 IP(src=self.pg1.remote_ip4, dst=self.nat_addr, ttl=64) /
Juraj Slobodad3677682017-04-14 03:24:45 +02001714 ICMP(id=self.icmp_id_out, type='echo-request'))
1715 self.pg1.add_stream(pkt)
1716 self.pg_enable_capture(self.pg_interfaces)
1717 self.pg_start()
1718 capture = self.pg0.get_capture(1)
Matus Fabian05ca4a32018-09-04 23:45:13 -07001719 self.verify_capture_in(capture, self.pg0)
Juraj Slobodad3677682017-04-14 03:24:45 +02001720 self.assert_equal(capture[0][IP].proto, IP_PROTOS.icmp)
1721
1722 # in2out
1723 pkt = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
1724 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4, ttl=64) /
1725 ICMP(id=self.icmp_id_in, type='echo-reply'))
1726 self.pg0.add_stream(pkt)
1727 self.pg_enable_capture(self.pg_interfaces)
1728 self.pg_start()
1729 capture = self.pg1.get_capture(1)
Matus Fabian05ca4a32018-09-04 23:45:13 -07001730 self.verify_capture_out(capture, same_port=True)
Juraj Slobodad3677682017-04-14 03:24:45 +02001731 self.assert_equal(capture[0][IP].proto, IP_PROTOS.icmp)
1732
Matus Fabianc79396e2018-07-23 00:05:22 -07001733 def test_forwarding(self):
Juraj Sloboda7b929792017-11-23 13:20:48 +01001734 """ NAT44 forwarding test """
1735
1736 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
1737 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
1738 is_inside=0)
1739 self.vapi.nat44_forwarding_enable_disable(1)
1740
1741 real_ip = self.pg0.remote_ip4n
1742 alias_ip = self.nat_addr_n
1743 self.vapi.nat44_add_del_static_mapping(local_ip=real_ip,
1744 external_ip=alias_ip)
1745
1746 try:
Matus Fabianc79396e2018-07-23 00:05:22 -07001747 # static mapping match
Juraj Sloboda7b929792017-11-23 13:20:48 +01001748
1749 pkts = self.create_stream_out(self.pg1)
1750 self.pg1.add_stream(pkts)
1751 self.pg_enable_capture(self.pg_interfaces)
1752 self.pg_start()
1753 capture = self.pg0.get_capture(len(pkts))
1754 self.verify_capture_in(capture, self.pg0)
1755
1756 pkts = self.create_stream_in(self.pg0, self.pg1)
1757 self.pg0.add_stream(pkts)
1758 self.pg_enable_capture(self.pg_interfaces)
1759 self.pg_start()
1760 capture = self.pg1.get_capture(len(pkts))
1761 self.verify_capture_out(capture, same_port=True)
1762
Matus Fabianc79396e2018-07-23 00:05:22 -07001763 # no static mapping match
Juraj Sloboda7b929792017-11-23 13:20:48 +01001764
1765 host0 = self.pg0.remote_hosts[0]
1766 self.pg0.remote_hosts[0] = self.pg0.remote_hosts[1]
1767 try:
1768 pkts = self.create_stream_out(self.pg1,
1769 dst_ip=self.pg0.remote_ip4,
1770 use_inside_ports=True)
1771 self.pg1.add_stream(pkts)
1772 self.pg_enable_capture(self.pg_interfaces)
1773 self.pg_start()
1774 capture = self.pg0.get_capture(len(pkts))
1775 self.verify_capture_in(capture, self.pg0)
1776
1777 pkts = self.create_stream_in(self.pg0, self.pg1)
1778 self.pg0.add_stream(pkts)
1779 self.pg_enable_capture(self.pg_interfaces)
1780 self.pg_start()
1781 capture = self.pg1.get_capture(len(pkts))
1782 self.verify_capture_out(capture, nat_ip=self.pg0.remote_ip4,
1783 same_port=True)
1784 finally:
1785 self.pg0.remote_hosts[0] = host0
1786
1787 finally:
1788 self.vapi.nat44_forwarding_enable_disable(0)
1789 self.vapi.nat44_add_del_static_mapping(local_ip=real_ip,
1790 external_ip=alias_ip,
1791 is_add=0)
1792
Matus Fabiande886752016-12-07 03:38:19 -08001793 def test_static_in(self):
Matus Fabian2ba92e32017-08-21 07:05:03 -07001794 """ 1:1 NAT initialized from inside network """
Matus Fabiande886752016-12-07 03:38:19 -08001795
1796 nat_ip = "10.0.0.10"
1797 self.tcp_port_out = 6303
1798 self.udp_port_out = 6304
1799 self.icmp_id_out = 6305
1800
Matus Fabian2ba92e32017-08-21 07:05:03 -07001801 self.nat44_add_static_mapping(self.pg0.remote_ip4, nat_ip)
1802 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
1803 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
1804 is_inside=0)
Matus Fabian5f224992018-01-25 21:59:16 -08001805 sm = self.vapi.nat44_static_mapping_dump()
1806 self.assertEqual(len(sm), 1)
1807 self.assertEqual((sm[0].tag).split('\0', 1)[0], '')
Matus Fabian9dba7812018-01-31 01:13:23 -08001808 self.assertEqual(sm[0].protocol, 0)
1809 self.assertEqual(sm[0].local_port, 0)
1810 self.assertEqual(sm[0].external_port, 0)
Matus Fabiande886752016-12-07 03:38:19 -08001811
1812 # in2out
1813 pkts = self.create_stream_in(self.pg0, self.pg1)
1814 self.pg0.add_stream(pkts)
1815 self.pg_enable_capture(self.pg_interfaces)
1816 self.pg_start()
Klement Sekeradab231a2016-12-21 08:50:14 +01001817 capture = self.pg1.get_capture(len(pkts))
Matus Fabiande886752016-12-07 03:38:19 -08001818 self.verify_capture_out(capture, nat_ip, True)
1819
1820 # out2in
1821 pkts = self.create_stream_out(self.pg1, nat_ip)
1822 self.pg1.add_stream(pkts)
1823 self.pg_enable_capture(self.pg_interfaces)
1824 self.pg_start()
Klement Sekeradab231a2016-12-21 08:50:14 +01001825 capture = self.pg0.get_capture(len(pkts))
Matus Fabiande886752016-12-07 03:38:19 -08001826 self.verify_capture_in(capture, self.pg0)
1827
1828 def test_static_out(self):
Matus Fabian2ba92e32017-08-21 07:05:03 -07001829 """ 1:1 NAT initialized from outside network """
Matus Fabiande886752016-12-07 03:38:19 -08001830
1831 nat_ip = "10.0.0.20"
1832 self.tcp_port_out = 6303
1833 self.udp_port_out = 6304
1834 self.icmp_id_out = 6305
Matus Fabian5f224992018-01-25 21:59:16 -08001835 tag = "testTAG"
Matus Fabiande886752016-12-07 03:38:19 -08001836
Matus Fabian5f224992018-01-25 21:59:16 -08001837 self.nat44_add_static_mapping(self.pg0.remote_ip4, nat_ip, tag=tag)
Matus Fabian2ba92e32017-08-21 07:05:03 -07001838 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
1839 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
1840 is_inside=0)
Matus Fabian5f224992018-01-25 21:59:16 -08001841 sm = self.vapi.nat44_static_mapping_dump()
1842 self.assertEqual(len(sm), 1)
1843 self.assertEqual((sm[0].tag).split('\0', 1)[0], tag)
Matus Fabiande886752016-12-07 03:38:19 -08001844
1845 # out2in
1846 pkts = self.create_stream_out(self.pg1, nat_ip)
1847 self.pg1.add_stream(pkts)
1848 self.pg_enable_capture(self.pg_interfaces)
1849 self.pg_start()
Klement Sekeradab231a2016-12-21 08:50:14 +01001850 capture = self.pg0.get_capture(len(pkts))
Matus Fabiande886752016-12-07 03:38:19 -08001851 self.verify_capture_in(capture, self.pg0)
1852
1853 # in2out
1854 pkts = self.create_stream_in(self.pg0, self.pg1)
1855 self.pg0.add_stream(pkts)
1856 self.pg_enable_capture(self.pg_interfaces)
1857 self.pg_start()
Klement Sekeradab231a2016-12-21 08:50:14 +01001858 capture = self.pg1.get_capture(len(pkts))
Matus Fabiande886752016-12-07 03:38:19 -08001859 self.verify_capture_out(capture, nat_ip, True)
1860
1861 def test_static_with_port_in(self):
Matus Fabian2ba92e32017-08-21 07:05:03 -07001862 """ 1:1 NAPT initialized from inside network """
Matus Fabiande886752016-12-07 03:38:19 -08001863
1864 self.tcp_port_out = 3606
1865 self.udp_port_out = 3607
1866 self.icmp_id_out = 3608
1867
Matus Fabian2ba92e32017-08-21 07:05:03 -07001868 self.nat44_add_address(self.nat_addr)
1869 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
1870 self.tcp_port_in, self.tcp_port_out,
1871 proto=IP_PROTOS.tcp)
1872 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
1873 self.udp_port_in, self.udp_port_out,
1874 proto=IP_PROTOS.udp)
1875 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
1876 self.icmp_id_in, self.icmp_id_out,
1877 proto=IP_PROTOS.icmp)
1878 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
1879 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
1880 is_inside=0)
Matus Fabiande886752016-12-07 03:38:19 -08001881
1882 # in2out
1883 pkts = self.create_stream_in(self.pg0, self.pg1)
1884 self.pg0.add_stream(pkts)
1885 self.pg_enable_capture(self.pg_interfaces)
1886 self.pg_start()
Klement Sekeradab231a2016-12-21 08:50:14 +01001887 capture = self.pg1.get_capture(len(pkts))
Matus Fabiande886752016-12-07 03:38:19 -08001888 self.verify_capture_out(capture)
1889
1890 # out2in
1891 pkts = self.create_stream_out(self.pg1)
1892 self.pg1.add_stream(pkts)
1893 self.pg_enable_capture(self.pg_interfaces)
1894 self.pg_start()
Klement Sekeradab231a2016-12-21 08:50:14 +01001895 capture = self.pg0.get_capture(len(pkts))
Matus Fabiande886752016-12-07 03:38:19 -08001896 self.verify_capture_in(capture, self.pg0)
1897
1898 def test_static_with_port_out(self):
Matus Fabian2ba92e32017-08-21 07:05:03 -07001899 """ 1:1 NAPT initialized from outside network """
Matus Fabiande886752016-12-07 03:38:19 -08001900
1901 self.tcp_port_out = 30606
1902 self.udp_port_out = 30607
1903 self.icmp_id_out = 30608
1904
Matus Fabian2ba92e32017-08-21 07:05:03 -07001905 self.nat44_add_address(self.nat_addr)
1906 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
1907 self.tcp_port_in, self.tcp_port_out,
1908 proto=IP_PROTOS.tcp)
1909 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
1910 self.udp_port_in, self.udp_port_out,
1911 proto=IP_PROTOS.udp)
1912 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
1913 self.icmp_id_in, self.icmp_id_out,
1914 proto=IP_PROTOS.icmp)
1915 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
1916 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
1917 is_inside=0)
Matus Fabiande886752016-12-07 03:38:19 -08001918
1919 # out2in
1920 pkts = self.create_stream_out(self.pg1)
1921 self.pg1.add_stream(pkts)
1922 self.pg_enable_capture(self.pg_interfaces)
1923 self.pg_start()
Klement Sekeradab231a2016-12-21 08:50:14 +01001924 capture = self.pg0.get_capture(len(pkts))
Matus Fabiande886752016-12-07 03:38:19 -08001925 self.verify_capture_in(capture, self.pg0)
1926
1927 # in2out
1928 pkts = self.create_stream_in(self.pg0, self.pg1)
1929 self.pg0.add_stream(pkts)
1930 self.pg_enable_capture(self.pg_interfaces)
1931 self.pg_start()
Klement Sekeradab231a2016-12-21 08:50:14 +01001932 capture = self.pg1.get_capture(len(pkts))
Matus Fabiande886752016-12-07 03:38:19 -08001933 self.verify_capture_out(capture)
1934
1935 def test_static_vrf_aware(self):
Matus Fabian2ba92e32017-08-21 07:05:03 -07001936 """ 1:1 NAT VRF awareness """
Matus Fabiande886752016-12-07 03:38:19 -08001937
1938 nat_ip1 = "10.0.0.30"
1939 nat_ip2 = "10.0.0.40"
1940 self.tcp_port_out = 6303
1941 self.udp_port_out = 6304
1942 self.icmp_id_out = 6305
1943
Matus Fabian2ba92e32017-08-21 07:05:03 -07001944 self.nat44_add_static_mapping(self.pg4.remote_ip4, nat_ip1,
1945 vrf_id=10)
1946 self.nat44_add_static_mapping(self.pg0.remote_ip4, nat_ip2,
1947 vrf_id=10)
1948 self.vapi.nat44_interface_add_del_feature(self.pg3.sw_if_index,
1949 is_inside=0)
1950 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
1951 self.vapi.nat44_interface_add_del_feature(self.pg4.sw_if_index)
Matus Fabiande886752016-12-07 03:38:19 -08001952
Matus Fabian2ba92e32017-08-21 07:05:03 -07001953 # inside interface VRF match NAT44 static mapping VRF
Matus Fabiande886752016-12-07 03:38:19 -08001954 pkts = self.create_stream_in(self.pg4, self.pg3)
1955 self.pg4.add_stream(pkts)
1956 self.pg_enable_capture(self.pg_interfaces)
1957 self.pg_start()
Klement Sekeradab231a2016-12-21 08:50:14 +01001958 capture = self.pg3.get_capture(len(pkts))
Matus Fabiande886752016-12-07 03:38:19 -08001959 self.verify_capture_out(capture, nat_ip1, True)
1960
Matus Fabian2ba92e32017-08-21 07:05:03 -07001961 # inside interface VRF don't match NAT44 static mapping VRF (packets
Matus Fabiande886752016-12-07 03:38:19 -08001962 # are dropped)
1963 pkts = self.create_stream_in(self.pg0, self.pg3)
1964 self.pg0.add_stream(pkts)
1965 self.pg_enable_capture(self.pg_interfaces)
1966 self.pg_start()
Klement Sekera9225dee2016-12-12 08:36:58 +01001967 self.pg3.assert_nothing_captured()
Matus Fabiande886752016-12-07 03:38:19 -08001968
Matus Fabianb793d092018-01-31 05:50:21 -08001969 def test_dynamic_to_static(self):
1970 """ Switch from dynamic translation to 1:1NAT """
1971 nat_ip = "10.0.0.10"
1972 self.tcp_port_out = 6303
1973 self.udp_port_out = 6304
1974 self.icmp_id_out = 6305
1975
1976 self.nat44_add_address(self.nat_addr)
1977 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
1978 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
1979 is_inside=0)
1980
1981 # dynamic
1982 pkts = self.create_stream_in(self.pg0, self.pg1)
1983 self.pg0.add_stream(pkts)
1984 self.pg_enable_capture(self.pg_interfaces)
1985 self.pg_start()
1986 capture = self.pg1.get_capture(len(pkts))
1987 self.verify_capture_out(capture)
1988
1989 # 1:1NAT
1990 self.nat44_add_static_mapping(self.pg0.remote_ip4, nat_ip)
1991 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n, 0)
1992 self.assertEqual(len(sessions), 0)
1993 pkts = self.create_stream_in(self.pg0, self.pg1)
1994 self.pg0.add_stream(pkts)
1995 self.pg_enable_capture(self.pg_interfaces)
1996 self.pg_start()
1997 capture = self.pg1.get_capture(len(pkts))
1998 self.verify_capture_out(capture, nat_ip, True)
1999
Matus Fabianab7a8052017-11-28 04:29:41 -08002000 def test_identity_nat(self):
2001 """ Identity NAT """
2002
2003 self.vapi.nat44_add_del_identity_mapping(ip=self.pg0.remote_ip4n)
2004 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
2005 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
2006 is_inside=0)
2007
2008 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
2009 IP(src=self.pg1.remote_ip4, dst=self.pg0.remote_ip4) /
2010 TCP(sport=12345, dport=56789))
2011 self.pg1.add_stream(p)
2012 self.pg_enable_capture(self.pg_interfaces)
2013 self.pg_start()
2014 capture = self.pg0.get_capture(1)
2015 p = capture[0]
2016 try:
2017 ip = p[IP]
2018 tcp = p[TCP]
2019 self.assertEqual(ip.dst, self.pg0.remote_ip4)
2020 self.assertEqual(ip.src, self.pg1.remote_ip4)
2021 self.assertEqual(tcp.dport, 56789)
2022 self.assertEqual(tcp.sport, 12345)
Klement Sekerad81ae412018-05-16 10:52:54 +02002023 self.assert_packet_checksums_valid(p)
Matus Fabianab7a8052017-11-28 04:29:41 -08002024 except:
2025 self.logger.error(ppp("Unexpected or invalid packet:", p))
2026 raise
2027
Matus Fabiane2f4e2f2018-10-07 21:28:23 -07002028 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n, 0)
2029 self.assertEqual(len(sessions), 0)
Matus Fabian82b4ceb2018-10-11 04:28:48 -07002030 self.vapi.nat44_add_del_identity_mapping(ip=self.pg0.remote_ip4n,
2031 vrf_id=1)
2032 identity_mappings = self.vapi.nat44_identity_mapping_dump()
2033 self.assertEqual(len(identity_mappings), 2)
Matus Fabiane2f4e2f2018-10-07 21:28:23 -07002034
Matus Fabiande886752016-12-07 03:38:19 -08002035 def test_multiple_inside_interfaces(self):
Matus Fabian2ba92e32017-08-21 07:05:03 -07002036 """ NAT44 multiple non-overlapping address space inside interfaces """
Matus Fabiande886752016-12-07 03:38:19 -08002037
Matus Fabian2ba92e32017-08-21 07:05:03 -07002038 self.nat44_add_address(self.nat_addr)
2039 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
2040 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index)
2041 self.vapi.nat44_interface_add_del_feature(self.pg3.sw_if_index,
2042 is_inside=0)
Matus Fabiande886752016-12-07 03:38:19 -08002043
Matus Fabian2ba92e32017-08-21 07:05:03 -07002044 # between two NAT44 inside interfaces (no translation)
Matus Fabian675a69c2017-01-18 01:46:01 -08002045 pkts = self.create_stream_in(self.pg0, self.pg1)
2046 self.pg0.add_stream(pkts)
2047 self.pg_enable_capture(self.pg_interfaces)
2048 self.pg_start()
2049 capture = self.pg1.get_capture(len(pkts))
2050 self.verify_capture_no_translation(capture, self.pg0, self.pg1)
2051
Matus Fabian2ba92e32017-08-21 07:05:03 -07002052 # from NAT44 inside to interface without NAT44 feature (no translation)
Matus Fabian675a69c2017-01-18 01:46:01 -08002053 pkts = self.create_stream_in(self.pg0, self.pg2)
2054 self.pg0.add_stream(pkts)
2055 self.pg_enable_capture(self.pg_interfaces)
2056 self.pg_start()
2057 capture = self.pg2.get_capture(len(pkts))
2058 self.verify_capture_no_translation(capture, self.pg0, self.pg2)
2059
Matus Fabiande886752016-12-07 03:38:19 -08002060 # in2out 1st interface
2061 pkts = self.create_stream_in(self.pg0, self.pg3)
2062 self.pg0.add_stream(pkts)
2063 self.pg_enable_capture(self.pg_interfaces)
2064 self.pg_start()
Klement Sekeradab231a2016-12-21 08:50:14 +01002065 capture = self.pg3.get_capture(len(pkts))
Matus Fabiande886752016-12-07 03:38:19 -08002066 self.verify_capture_out(capture)
2067
2068 # out2in 1st interface
2069 pkts = self.create_stream_out(self.pg3)
2070 self.pg3.add_stream(pkts)
2071 self.pg_enable_capture(self.pg_interfaces)
2072 self.pg_start()
Klement Sekeradab231a2016-12-21 08:50:14 +01002073 capture = self.pg0.get_capture(len(pkts))
Matus Fabiande886752016-12-07 03:38:19 -08002074 self.verify_capture_in(capture, self.pg0)
2075
2076 # in2out 2nd interface
2077 pkts = self.create_stream_in(self.pg1, self.pg3)
2078 self.pg1.add_stream(pkts)
2079 self.pg_enable_capture(self.pg_interfaces)
2080 self.pg_start()
Klement Sekeradab231a2016-12-21 08:50:14 +01002081 capture = self.pg3.get_capture(len(pkts))
Matus Fabiande886752016-12-07 03:38:19 -08002082 self.verify_capture_out(capture)
2083
2084 # out2in 2nd interface
2085 pkts = self.create_stream_out(self.pg3)
2086 self.pg3.add_stream(pkts)
2087 self.pg_enable_capture(self.pg_interfaces)
2088 self.pg_start()
Klement Sekeradab231a2016-12-21 08:50:14 +01002089 capture = self.pg1.get_capture(len(pkts))
Matus Fabiande886752016-12-07 03:38:19 -08002090 self.verify_capture_in(capture, self.pg1)
2091
Matus Fabiande886752016-12-07 03:38:19 -08002092 def test_inside_overlapping_interfaces(self):
Matus Fabian2ba92e32017-08-21 07:05:03 -07002093 """ NAT44 multiple inside interfaces with overlapping address space """
Matus Fabiande886752016-12-07 03:38:19 -08002094
Matus Fabian675a69c2017-01-18 01:46:01 -08002095 static_nat_ip = "10.0.0.10"
Matus Fabian2ba92e32017-08-21 07:05:03 -07002096 self.nat44_add_address(self.nat_addr)
2097 self.vapi.nat44_interface_add_del_feature(self.pg3.sw_if_index,
2098 is_inside=0)
2099 self.vapi.nat44_interface_add_del_feature(self.pg4.sw_if_index)
2100 self.vapi.nat44_interface_add_del_feature(self.pg5.sw_if_index)
2101 self.vapi.nat44_interface_add_del_feature(self.pg6.sw_if_index)
2102 self.nat44_add_static_mapping(self.pg6.remote_ip4, static_nat_ip,
2103 vrf_id=20)
Matus Fabian675a69c2017-01-18 01:46:01 -08002104
Matus Fabian2ba92e32017-08-21 07:05:03 -07002105 # between NAT44 inside interfaces with same VRF (no translation)
Matus Fabian675a69c2017-01-18 01:46:01 -08002106 pkts = self.create_stream_in(self.pg4, self.pg5)
2107 self.pg4.add_stream(pkts)
2108 self.pg_enable_capture(self.pg_interfaces)
2109 self.pg_start()
2110 capture = self.pg5.get_capture(len(pkts))
2111 self.verify_capture_no_translation(capture, self.pg4, self.pg5)
2112
Matus Fabian2ba92e32017-08-21 07:05:03 -07002113 # between NAT44 inside interfaces with different VRF (hairpinning)
Matus Fabian675a69c2017-01-18 01:46:01 -08002114 p = (Ether(src=self.pg4.remote_mac, dst=self.pg4.local_mac) /
2115 IP(src=self.pg4.remote_ip4, dst=static_nat_ip) /
2116 TCP(sport=1234, dport=5678))
2117 self.pg4.add_stream(p)
2118 self.pg_enable_capture(self.pg_interfaces)
2119 self.pg_start()
2120 capture = self.pg6.get_capture(1)
2121 p = capture[0]
2122 try:
2123 ip = p[IP]
2124 tcp = p[TCP]
Matus Fabian2ba92e32017-08-21 07:05:03 -07002125 self.assertEqual(ip.src, self.nat_addr)
Matus Fabian675a69c2017-01-18 01:46:01 -08002126 self.assertEqual(ip.dst, self.pg6.remote_ip4)
2127 self.assertNotEqual(tcp.sport, 1234)
2128 self.assertEqual(tcp.dport, 5678)
2129 except:
2130 self.logger.error(ppp("Unexpected or invalid packet:", p))
2131 raise
Matus Fabiande886752016-12-07 03:38:19 -08002132
2133 # in2out 1st interface
2134 pkts = self.create_stream_in(self.pg4, self.pg3)
2135 self.pg4.add_stream(pkts)
2136 self.pg_enable_capture(self.pg_interfaces)
2137 self.pg_start()
Klement Sekeradab231a2016-12-21 08:50:14 +01002138 capture = self.pg3.get_capture(len(pkts))
Matus Fabiande886752016-12-07 03:38:19 -08002139 self.verify_capture_out(capture)
2140
2141 # out2in 1st interface
2142 pkts = self.create_stream_out(self.pg3)
2143 self.pg3.add_stream(pkts)
2144 self.pg_enable_capture(self.pg_interfaces)
2145 self.pg_start()
Klement Sekeradab231a2016-12-21 08:50:14 +01002146 capture = self.pg4.get_capture(len(pkts))
Matus Fabiande886752016-12-07 03:38:19 -08002147 self.verify_capture_in(capture, self.pg4)
2148
2149 # in2out 2nd interface
2150 pkts = self.create_stream_in(self.pg5, self.pg3)
2151 self.pg5.add_stream(pkts)
2152 self.pg_enable_capture(self.pg_interfaces)
2153 self.pg_start()
Klement Sekeradab231a2016-12-21 08:50:14 +01002154 capture = self.pg3.get_capture(len(pkts))
Matus Fabiande886752016-12-07 03:38:19 -08002155 self.verify_capture_out(capture)
2156
2157 # out2in 2nd interface
2158 pkts = self.create_stream_out(self.pg3)
2159 self.pg3.add_stream(pkts)
2160 self.pg_enable_capture(self.pg_interfaces)
2161 self.pg_start()
Klement Sekeradab231a2016-12-21 08:50:14 +01002162 capture = self.pg5.get_capture(len(pkts))
Matus Fabiande886752016-12-07 03:38:19 -08002163 self.verify_capture_in(capture, self.pg5)
2164
magalik23caa882017-02-08 23:25:45 -08002165 # pg5 session dump
Matus Fabian2ba92e32017-08-21 07:05:03 -07002166 addresses = self.vapi.nat44_address_dump()
magalik23caa882017-02-08 23:25:45 -08002167 self.assertEqual(len(addresses), 1)
Matus Fabian2ba92e32017-08-21 07:05:03 -07002168 sessions = self.vapi.nat44_user_session_dump(self.pg5.remote_ip4n, 10)
magalik23caa882017-02-08 23:25:45 -08002169 self.assertEqual(len(sessions), 3)
2170 for session in sessions:
2171 self.assertFalse(session.is_static)
2172 self.assertEqual(session.inside_ip_address[0:4],
2173 self.pg5.remote_ip4n)
2174 self.assertEqual(session.outside_ip_address,
2175 addresses[0].ip_address)
2176 self.assertEqual(sessions[0].protocol, IP_PROTOS.tcp)
2177 self.assertEqual(sessions[1].protocol, IP_PROTOS.udp)
2178 self.assertEqual(sessions[2].protocol, IP_PROTOS.icmp)
2179 self.assertEqual(sessions[0].inside_port, self.tcp_port_in)
2180 self.assertEqual(sessions[1].inside_port, self.udp_port_in)
2181 self.assertEqual(sessions[2].inside_port, self.icmp_id_in)
2182 self.assertEqual(sessions[0].outside_port, self.tcp_port_out)
2183 self.assertEqual(sessions[1].outside_port, self.udp_port_out)
2184 self.assertEqual(sessions[2].outside_port, self.icmp_id_out)
2185
Matus Fabiande886752016-12-07 03:38:19 -08002186 # in2out 3rd interface
2187 pkts = self.create_stream_in(self.pg6, self.pg3)
2188 self.pg6.add_stream(pkts)
2189 self.pg_enable_capture(self.pg_interfaces)
2190 self.pg_start()
Klement Sekeradab231a2016-12-21 08:50:14 +01002191 capture = self.pg3.get_capture(len(pkts))
Matus Fabian675a69c2017-01-18 01:46:01 -08002192 self.verify_capture_out(capture, static_nat_ip, True)
Matus Fabiande886752016-12-07 03:38:19 -08002193
2194 # out2in 3rd interface
Matus Fabian675a69c2017-01-18 01:46:01 -08002195 pkts = self.create_stream_out(self.pg3, static_nat_ip)
Matus Fabiande886752016-12-07 03:38:19 -08002196 self.pg3.add_stream(pkts)
2197 self.pg_enable_capture(self.pg_interfaces)
2198 self.pg_start()
Klement Sekeradab231a2016-12-21 08:50:14 +01002199 capture = self.pg6.get_capture(len(pkts))
Matus Fabiande886752016-12-07 03:38:19 -08002200 self.verify_capture_in(capture, self.pg6)
2201
magalik23caa882017-02-08 23:25:45 -08002202 # general user and session dump verifications
Matus Fabian2ba92e32017-08-21 07:05:03 -07002203 users = self.vapi.nat44_user_dump()
Paul Vinciguerra3d2df212018-11-24 23:19:53 -08002204 self.assertGreaterEqual(len(users), 3)
Matus Fabian2ba92e32017-08-21 07:05:03 -07002205 addresses = self.vapi.nat44_address_dump()
magalik23caa882017-02-08 23:25:45 -08002206 self.assertEqual(len(addresses), 1)
2207 for user in users:
Matus Fabian2ba92e32017-08-21 07:05:03 -07002208 sessions = self.vapi.nat44_user_session_dump(user.ip_address,
2209 user.vrf_id)
magalik23caa882017-02-08 23:25:45 -08002210 for session in sessions:
2211 self.assertEqual(user.ip_address, session.inside_ip_address)
2212 self.assertTrue(session.total_bytes > session.total_pkts > 0)
2213 self.assertTrue(session.protocol in
2214 [IP_PROTOS.tcp, IP_PROTOS.udp,
2215 IP_PROTOS.icmp])
Matus Fabian70a26ac2018-05-14 06:20:28 -07002216 self.assertFalse(session.ext_host_valid)
magalik23caa882017-02-08 23:25:45 -08002217
2218 # pg4 session dump
Matus Fabian2ba92e32017-08-21 07:05:03 -07002219 sessions = self.vapi.nat44_user_session_dump(self.pg4.remote_ip4n, 10)
Paul Vinciguerra3d2df212018-11-24 23:19:53 -08002220 self.assertGreaterEqual(len(sessions), 4)
magalik23caa882017-02-08 23:25:45 -08002221 for session in sessions:
2222 self.assertFalse(session.is_static)
2223 self.assertEqual(session.inside_ip_address[0:4],
2224 self.pg4.remote_ip4n)
2225 self.assertEqual(session.outside_ip_address,
2226 addresses[0].ip_address)
2227
2228 # pg6 session dump
Matus Fabian2ba92e32017-08-21 07:05:03 -07002229 sessions = self.vapi.nat44_user_session_dump(self.pg6.remote_ip4n, 20)
Paul Vinciguerra3d2df212018-11-24 23:19:53 -08002230 self.assertGreaterEqual(len(sessions), 3)
magalik23caa882017-02-08 23:25:45 -08002231 for session in sessions:
2232 self.assertTrue(session.is_static)
2233 self.assertEqual(session.inside_ip_address[0:4],
2234 self.pg6.remote_ip4n)
2235 self.assertEqual(map(ord, session.outside_ip_address[0:4]),
2236 map(int, static_nat_ip.split('.')))
2237 self.assertTrue(session.inside_port in
2238 [self.tcp_port_in, self.udp_port_in,
2239 self.icmp_id_in])
2240
Matus Fabianf78a70d2016-12-12 04:30:39 -08002241 def test_hairpinning(self):
Matus Fabian2ba92e32017-08-21 07:05:03 -07002242 """ NAT44 hairpinning - 1:1 NAPT """
Matus Fabianf78a70d2016-12-12 04:30:39 -08002243
2244 host = self.pg0.remote_hosts[0]
2245 server = self.pg0.remote_hosts[1]
2246 host_in_port = 1234
2247 host_out_port = 0
2248 server_in_port = 5678
2249 server_out_port = 8765
2250
Matus Fabian2ba92e32017-08-21 07:05:03 -07002251 self.nat44_add_address(self.nat_addr)
2252 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
2253 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
2254 is_inside=0)
Matus Fabianf78a70d2016-12-12 04:30:39 -08002255 # add static mapping for server
Matus Fabian2ba92e32017-08-21 07:05:03 -07002256 self.nat44_add_static_mapping(server.ip4, self.nat_addr,
2257 server_in_port, server_out_port,
2258 proto=IP_PROTOS.tcp)
Matus Fabianf78a70d2016-12-12 04:30:39 -08002259
2260 # send packet from host to server
2261 p = (Ether(src=host.mac, dst=self.pg0.local_mac) /
Matus Fabian2ba92e32017-08-21 07:05:03 -07002262 IP(src=host.ip4, dst=self.nat_addr) /
Matus Fabianf78a70d2016-12-12 04:30:39 -08002263 TCP(sport=host_in_port, dport=server_out_port))
2264 self.pg0.add_stream(p)
2265 self.pg_enable_capture(self.pg_interfaces)
2266 self.pg_start()
Klement Sekeradab231a2016-12-21 08:50:14 +01002267 capture = self.pg0.get_capture(1)
Matus Fabianf78a70d2016-12-12 04:30:39 -08002268 p = capture[0]
2269 try:
2270 ip = p[IP]
2271 tcp = p[TCP]
Matus Fabian2ba92e32017-08-21 07:05:03 -07002272 self.assertEqual(ip.src, self.nat_addr)
Matus Fabianf78a70d2016-12-12 04:30:39 -08002273 self.assertEqual(ip.dst, server.ip4)
2274 self.assertNotEqual(tcp.sport, host_in_port)
2275 self.assertEqual(tcp.dport, server_in_port)
Klement Sekerad81ae412018-05-16 10:52:54 +02002276 self.assert_packet_checksums_valid(p)
Matus Fabianf78a70d2016-12-12 04:30:39 -08002277 host_out_port = tcp.sport
2278 except:
Klement Sekera9225dee2016-12-12 08:36:58 +01002279 self.logger.error(ppp("Unexpected or invalid packet:", p))
Matus Fabianf78a70d2016-12-12 04:30:39 -08002280 raise
2281
2282 # send reply from server to host
2283 p = (Ether(src=server.mac, dst=self.pg0.local_mac) /
Matus Fabian2ba92e32017-08-21 07:05:03 -07002284 IP(src=server.ip4, dst=self.nat_addr) /
Matus Fabianf78a70d2016-12-12 04:30:39 -08002285 TCP(sport=server_in_port, dport=host_out_port))
2286 self.pg0.add_stream(p)
2287 self.pg_enable_capture(self.pg_interfaces)
2288 self.pg_start()
Klement Sekeradab231a2016-12-21 08:50:14 +01002289 capture = self.pg0.get_capture(1)
Matus Fabianf78a70d2016-12-12 04:30:39 -08002290 p = capture[0]
2291 try:
2292 ip = p[IP]
2293 tcp = p[TCP]
Matus Fabian2ba92e32017-08-21 07:05:03 -07002294 self.assertEqual(ip.src, self.nat_addr)
Matus Fabianf78a70d2016-12-12 04:30:39 -08002295 self.assertEqual(ip.dst, host.ip4)
2296 self.assertEqual(tcp.sport, server_out_port)
2297 self.assertEqual(tcp.dport, host_in_port)
Klement Sekerad81ae412018-05-16 10:52:54 +02002298 self.assert_packet_checksums_valid(p)
Matus Fabianf78a70d2016-12-12 04:30:39 -08002299 except:
Matus Fabiane82488f2018-01-18 03:38:45 -08002300 self.logger.error(ppp("Unexpected or invalid packet:", p))
Matus Fabianf78a70d2016-12-12 04:30:39 -08002301 raise
2302
Matus Fabian6fa74c62017-06-05 05:55:48 -07002303 def test_hairpinning2(self):
Matus Fabian2ba92e32017-08-21 07:05:03 -07002304 """ NAT44 hairpinning - 1:1 NAT"""
Matus Fabian6fa74c62017-06-05 05:55:48 -07002305
2306 server1_nat_ip = "10.0.0.10"
2307 server2_nat_ip = "10.0.0.11"
2308 host = self.pg0.remote_hosts[0]
2309 server1 = self.pg0.remote_hosts[1]
2310 server2 = self.pg0.remote_hosts[2]
2311 server_tcp_port = 22
2312 server_udp_port = 20
2313
Matus Fabian2ba92e32017-08-21 07:05:03 -07002314 self.nat44_add_address(self.nat_addr)
2315 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
2316 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
2317 is_inside=0)
Matus Fabian6fa74c62017-06-05 05:55:48 -07002318
2319 # add static mapping for servers
Matus Fabian2ba92e32017-08-21 07:05:03 -07002320 self.nat44_add_static_mapping(server1.ip4, server1_nat_ip)
2321 self.nat44_add_static_mapping(server2.ip4, server2_nat_ip)
Matus Fabian6fa74c62017-06-05 05:55:48 -07002322
2323 # host to server1
2324 pkts = []
2325 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2326 IP(src=host.ip4, dst=server1_nat_ip) /
2327 TCP(sport=self.tcp_port_in, dport=server_tcp_port))
2328 pkts.append(p)
2329 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2330 IP(src=host.ip4, dst=server1_nat_ip) /
2331 UDP(sport=self.udp_port_in, dport=server_udp_port))
2332 pkts.append(p)
2333 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2334 IP(src=host.ip4, dst=server1_nat_ip) /
2335 ICMP(id=self.icmp_id_in, type='echo-request'))
2336 pkts.append(p)
2337 self.pg0.add_stream(pkts)
2338 self.pg_enable_capture(self.pg_interfaces)
2339 self.pg_start()
2340 capture = self.pg0.get_capture(len(pkts))
2341 for packet in capture:
2342 try:
Matus Fabian2ba92e32017-08-21 07:05:03 -07002343 self.assertEqual(packet[IP].src, self.nat_addr)
Matus Fabian6fa74c62017-06-05 05:55:48 -07002344 self.assertEqual(packet[IP].dst, server1.ip4)
2345 if packet.haslayer(TCP):
2346 self.assertNotEqual(packet[TCP].sport, self.tcp_port_in)
2347 self.assertEqual(packet[TCP].dport, server_tcp_port)
2348 self.tcp_port_out = packet[TCP].sport
Klement Sekerad81ae412018-05-16 10:52:54 +02002349 self.assert_packet_checksums_valid(packet)
Matus Fabian6fa74c62017-06-05 05:55:48 -07002350 elif packet.haslayer(UDP):
2351 self.assertNotEqual(packet[UDP].sport, self.udp_port_in)
2352 self.assertEqual(packet[UDP].dport, server_udp_port)
2353 self.udp_port_out = packet[UDP].sport
2354 else:
2355 self.assertNotEqual(packet[ICMP].id, self.icmp_id_in)
2356 self.icmp_id_out = packet[ICMP].id
2357 except:
2358 self.logger.error(ppp("Unexpected or invalid packet:", packet))
2359 raise
2360
2361 # server1 to host
2362 pkts = []
2363 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
Matus Fabian2ba92e32017-08-21 07:05:03 -07002364 IP(src=server1.ip4, dst=self.nat_addr) /
Matus Fabian6fa74c62017-06-05 05:55:48 -07002365 TCP(sport=server_tcp_port, dport=self.tcp_port_out))
2366 pkts.append(p)
2367 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
Matus Fabian2ba92e32017-08-21 07:05:03 -07002368 IP(src=server1.ip4, dst=self.nat_addr) /
Matus Fabian6fa74c62017-06-05 05:55:48 -07002369 UDP(sport=server_udp_port, dport=self.udp_port_out))
2370 pkts.append(p)
2371 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
Matus Fabian2ba92e32017-08-21 07:05:03 -07002372 IP(src=server1.ip4, dst=self.nat_addr) /
Matus Fabian6fa74c62017-06-05 05:55:48 -07002373 ICMP(id=self.icmp_id_out, type='echo-reply'))
2374 pkts.append(p)
2375 self.pg0.add_stream(pkts)
2376 self.pg_enable_capture(self.pg_interfaces)
2377 self.pg_start()
2378 capture = self.pg0.get_capture(len(pkts))
2379 for packet in capture:
2380 try:
2381 self.assertEqual(packet[IP].src, server1_nat_ip)
2382 self.assertEqual(packet[IP].dst, host.ip4)
2383 if packet.haslayer(TCP):
2384 self.assertEqual(packet[TCP].dport, self.tcp_port_in)
2385 self.assertEqual(packet[TCP].sport, server_tcp_port)
Klement Sekerad81ae412018-05-16 10:52:54 +02002386 self.assert_packet_checksums_valid(packet)
Matus Fabian6fa74c62017-06-05 05:55:48 -07002387 elif packet.haslayer(UDP):
2388 self.assertEqual(packet[UDP].dport, self.udp_port_in)
2389 self.assertEqual(packet[UDP].sport, server_udp_port)
2390 else:
2391 self.assertEqual(packet[ICMP].id, self.icmp_id_in)
2392 except:
2393 self.logger.error(ppp("Unexpected or invalid packet:", packet))
2394 raise
2395
2396 # server2 to server1
2397 pkts = []
2398 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2399 IP(src=server2.ip4, dst=server1_nat_ip) /
2400 TCP(sport=self.tcp_port_in, dport=server_tcp_port))
2401 pkts.append(p)
2402 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2403 IP(src=server2.ip4, dst=server1_nat_ip) /
2404 UDP(sport=self.udp_port_in, dport=server_udp_port))
2405 pkts.append(p)
2406 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2407 IP(src=server2.ip4, dst=server1_nat_ip) /
2408 ICMP(id=self.icmp_id_in, type='echo-request'))
2409 pkts.append(p)
2410 self.pg0.add_stream(pkts)
2411 self.pg_enable_capture(self.pg_interfaces)
2412 self.pg_start()
2413 capture = self.pg0.get_capture(len(pkts))
2414 for packet in capture:
2415 try:
2416 self.assertEqual(packet[IP].src, server2_nat_ip)
2417 self.assertEqual(packet[IP].dst, server1.ip4)
2418 if packet.haslayer(TCP):
2419 self.assertEqual(packet[TCP].sport, self.tcp_port_in)
2420 self.assertEqual(packet[TCP].dport, server_tcp_port)
2421 self.tcp_port_out = packet[TCP].sport
Klement Sekerad81ae412018-05-16 10:52:54 +02002422 self.assert_packet_checksums_valid(packet)
Matus Fabian6fa74c62017-06-05 05:55:48 -07002423 elif packet.haslayer(UDP):
2424 self.assertEqual(packet[UDP].sport, self.udp_port_in)
2425 self.assertEqual(packet[UDP].dport, server_udp_port)
2426 self.udp_port_out = packet[UDP].sport
2427 else:
2428 self.assertEqual(packet[ICMP].id, self.icmp_id_in)
2429 self.icmp_id_out = packet[ICMP].id
2430 except:
2431 self.logger.error(ppp("Unexpected or invalid packet:", packet))
2432 raise
2433
2434 # server1 to server2
2435 pkts = []
2436 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2437 IP(src=server1.ip4, dst=server2_nat_ip) /
2438 TCP(sport=server_tcp_port, dport=self.tcp_port_out))
2439 pkts.append(p)
2440 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2441 IP(src=server1.ip4, dst=server2_nat_ip) /
2442 UDP(sport=server_udp_port, dport=self.udp_port_out))
2443 pkts.append(p)
2444 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2445 IP(src=server1.ip4, dst=server2_nat_ip) /
2446 ICMP(id=self.icmp_id_out, type='echo-reply'))
2447 pkts.append(p)
2448 self.pg0.add_stream(pkts)
2449 self.pg_enable_capture(self.pg_interfaces)
2450 self.pg_start()
2451 capture = self.pg0.get_capture(len(pkts))
2452 for packet in capture:
2453 try:
2454 self.assertEqual(packet[IP].src, server1_nat_ip)
2455 self.assertEqual(packet[IP].dst, server2.ip4)
2456 if packet.haslayer(TCP):
2457 self.assertEqual(packet[TCP].dport, self.tcp_port_in)
2458 self.assertEqual(packet[TCP].sport, server_tcp_port)
Klement Sekerad81ae412018-05-16 10:52:54 +02002459 self.assert_packet_checksums_valid(packet)
Matus Fabian6fa74c62017-06-05 05:55:48 -07002460 elif packet.haslayer(UDP):
2461 self.assertEqual(packet[UDP].dport, self.udp_port_in)
2462 self.assertEqual(packet[UDP].sport, server_udp_port)
2463 else:
2464 self.assertEqual(packet[ICMP].id, self.icmp_id_in)
2465 except:
2466 self.logger.error(ppp("Unexpected or invalid packet:", packet))
2467 raise
2468
Matus Fabian9902fcd2016-12-21 23:58:46 -08002469 def test_max_translations_per_user(self):
2470 """ MAX translations per user - recycle the least recently used """
2471
Matus Fabian2ba92e32017-08-21 07:05:03 -07002472 self.nat44_add_address(self.nat_addr)
2473 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
2474 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
2475 is_inside=0)
Matus Fabian9902fcd2016-12-21 23:58:46 -08002476
2477 # get maximum number of translations per user
Matus Fabian2ba92e32017-08-21 07:05:03 -07002478 nat44_config = self.vapi.nat_show_config()
Matus Fabian9902fcd2016-12-21 23:58:46 -08002479
2480 # send more than maximum number of translations per user packets
Matus Fabian2ba92e32017-08-21 07:05:03 -07002481 pkts_num = nat44_config.max_translations_per_user + 5
Matus Fabian9902fcd2016-12-21 23:58:46 -08002482 pkts = []
2483 for port in range(0, pkts_num):
2484 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2485 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
2486 TCP(sport=1025 + port))
2487 pkts.append(p)
2488 self.pg0.add_stream(pkts)
2489 self.pg_enable_capture(self.pg_interfaces)
2490 self.pg_start()
2491
2492 # verify number of translated packet
Klement Sekeradab231a2016-12-21 08:50:14 +01002493 self.pg1.get_capture(pkts_num)
Matus Fabian9902fcd2016-12-21 23:58:46 -08002494
Matus Fabian132dc492018-05-09 04:51:03 -07002495 users = self.vapi.nat44_user_dump()
2496 for user in users:
2497 if user.ip_address == self.pg0.remote_ip4n:
2498 self.assertEqual(user.nsessions,
2499 nat44_config.max_translations_per_user)
2500 self.assertEqual(user.nstaticsessions, 0)
2501
2502 tcp_port = 22
2503 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
2504 tcp_port, tcp_port,
2505 proto=IP_PROTOS.tcp)
2506 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2507 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
2508 TCP(sport=tcp_port))
2509 self.pg0.add_stream(p)
2510 self.pg_enable_capture(self.pg_interfaces)
2511 self.pg_start()
2512 self.pg1.get_capture(1)
2513 users = self.vapi.nat44_user_dump()
2514 for user in users:
2515 if user.ip_address == self.pg0.remote_ip4n:
2516 self.assertEqual(user.nsessions,
2517 nat44_config.max_translations_per_user - 1)
2518 self.assertEqual(user.nstaticsessions, 1)
2519
Matus Fabian8bf68e82017-01-12 04:24:35 -08002520 def test_interface_addr(self):
Matus Fabian2ba92e32017-08-21 07:05:03 -07002521 """ Acquire NAT44 addresses from interface """
2522 self.vapi.nat44_add_interface_addr(self.pg7.sw_if_index)
Matus Fabian8bf68e82017-01-12 04:24:35 -08002523
2524 # no address in NAT pool
Matus Fabian2ba92e32017-08-21 07:05:03 -07002525 adresses = self.vapi.nat44_address_dump()
Matus Fabian8bf68e82017-01-12 04:24:35 -08002526 self.assertEqual(0, len(adresses))
2527
2528 # configure interface address and check NAT address pool
2529 self.pg7.config_ip4()
Matus Fabian2ba92e32017-08-21 07:05:03 -07002530 adresses = self.vapi.nat44_address_dump()
Matus Fabian8bf68e82017-01-12 04:24:35 -08002531 self.assertEqual(1, len(adresses))
Matus Fabian36532bd2017-01-23 23:42:28 -08002532 self.assertEqual(adresses[0].ip_address[0:4], self.pg7.local_ip4n)
Matus Fabian8bf68e82017-01-12 04:24:35 -08002533
2534 # remove interface address and check NAT address pool
2535 self.pg7.unconfig_ip4()
Matus Fabian2ba92e32017-08-21 07:05:03 -07002536 adresses = self.vapi.nat44_address_dump()
Matus Fabian8bf68e82017-01-12 04:24:35 -08002537 self.assertEqual(0, len(adresses))
2538
Matus Fabian36532bd2017-01-23 23:42:28 -08002539 def test_interface_addr_static_mapping(self):
2540 """ Static mapping with addresses from interface """
Matus Fabian5f224992018-01-25 21:59:16 -08002541 tag = "testTAG"
2542
Matus Fabian2ba92e32017-08-21 07:05:03 -07002543 self.vapi.nat44_add_interface_addr(self.pg7.sw_if_index)
2544 self.nat44_add_static_mapping(
2545 '1.2.3.4',
Matus Fabian5f224992018-01-25 21:59:16 -08002546 external_sw_if_index=self.pg7.sw_if_index,
2547 tag=tag)
Matus Fabian36532bd2017-01-23 23:42:28 -08002548
Matus Fabiane22e5462017-02-14 23:33:43 -08002549 # static mappings with external interface
Matus Fabian2ba92e32017-08-21 07:05:03 -07002550 static_mappings = self.vapi.nat44_static_mapping_dump()
Matus Fabiane22e5462017-02-14 23:33:43 -08002551 self.assertEqual(1, len(static_mappings))
2552 self.assertEqual(self.pg7.sw_if_index,
2553 static_mappings[0].external_sw_if_index)
Matus Fabian5f224992018-01-25 21:59:16 -08002554 self.assertEqual((static_mappings[0].tag).split('\0', 1)[0], tag)
Matus Fabian36532bd2017-01-23 23:42:28 -08002555
2556 # configure interface address and check static mappings
2557 self.pg7.config_ip4()
Matus Fabian2ba92e32017-08-21 07:05:03 -07002558 static_mappings = self.vapi.nat44_static_mapping_dump()
Matus Fabianea2600a2018-03-28 04:06:26 -07002559 self.assertEqual(2, len(static_mappings))
2560 resolved = False
2561 for sm in static_mappings:
2562 if sm.external_sw_if_index == 0xFFFFFFFF:
2563 self.assertEqual(sm.external_ip_address[0:4],
2564 self.pg7.local_ip4n)
2565 self.assertEqual((sm.tag).split('\0', 1)[0], tag)
2566 resolved = True
2567 self.assertTrue(resolved)
Matus Fabian36532bd2017-01-23 23:42:28 -08002568
2569 # remove interface address and check static mappings
2570 self.pg7.unconfig_ip4()
Matus Fabian2ba92e32017-08-21 07:05:03 -07002571 static_mappings = self.vapi.nat44_static_mapping_dump()
Matus Fabianea2600a2018-03-28 04:06:26 -07002572 self.assertEqual(1, len(static_mappings))
2573 self.assertEqual(self.pg7.sw_if_index,
2574 static_mappings[0].external_sw_if_index)
2575 self.assertEqual((static_mappings[0].tag).split('\0', 1)[0], tag)
2576
2577 # configure interface address again and check static mappings
2578 self.pg7.config_ip4()
2579 static_mappings = self.vapi.nat44_static_mapping_dump()
2580 self.assertEqual(2, len(static_mappings))
2581 resolved = False
2582 for sm in static_mappings:
2583 if sm.external_sw_if_index == 0xFFFFFFFF:
2584 self.assertEqual(sm.external_ip_address[0:4],
2585 self.pg7.local_ip4n)
2586 self.assertEqual((sm.tag).split('\0', 1)[0], tag)
2587 resolved = True
2588 self.assertTrue(resolved)
2589
2590 # remove static mapping
2591 self.nat44_add_static_mapping(
2592 '1.2.3.4',
2593 external_sw_if_index=self.pg7.sw_if_index,
2594 tag=tag,
2595 is_add=0)
2596 static_mappings = self.vapi.nat44_static_mapping_dump()
Matus Fabian36532bd2017-01-23 23:42:28 -08002597 self.assertEqual(0, len(static_mappings))
2598
Matus Fabianab7a8052017-11-28 04:29:41 -08002599 def test_interface_addr_identity_nat(self):
2600 """ Identity NAT with addresses from interface """
2601
2602 port = 53053
2603 self.vapi.nat44_add_interface_addr(self.pg7.sw_if_index)
2604 self.vapi.nat44_add_del_identity_mapping(
2605 sw_if_index=self.pg7.sw_if_index,
2606 port=port,
2607 protocol=IP_PROTOS.tcp,
2608 addr_only=0)
2609
2610 # identity mappings with external interface
2611 identity_mappings = self.vapi.nat44_identity_mapping_dump()
2612 self.assertEqual(1, len(identity_mappings))
2613 self.assertEqual(self.pg7.sw_if_index,
2614 identity_mappings[0].sw_if_index)
2615
2616 # configure interface address and check identity mappings
2617 self.pg7.config_ip4()
2618 identity_mappings = self.vapi.nat44_identity_mapping_dump()
Matus Fabianea2600a2018-03-28 04:06:26 -07002619 resolved = False
2620 self.assertEqual(2, len(identity_mappings))
2621 for sm in identity_mappings:
2622 if sm.sw_if_index == 0xFFFFFFFF:
2623 self.assertEqual(identity_mappings[0].ip_address,
2624 self.pg7.local_ip4n)
2625 self.assertEqual(port, identity_mappings[0].port)
2626 self.assertEqual(IP_PROTOS.tcp, identity_mappings[0].protocol)
2627 resolved = True
2628 self.assertTrue(resolved)
Matus Fabianab7a8052017-11-28 04:29:41 -08002629
2630 # remove interface address and check identity mappings
2631 self.pg7.unconfig_ip4()
2632 identity_mappings = self.vapi.nat44_identity_mapping_dump()
Matus Fabianea2600a2018-03-28 04:06:26 -07002633 self.assertEqual(1, len(identity_mappings))
2634 self.assertEqual(self.pg7.sw_if_index,
2635 identity_mappings[0].sw_if_index)
Matus Fabianab7a8052017-11-28 04:29:41 -08002636
Matus Fabianeea28d72017-01-13 04:15:54 -08002637 def test_ipfix_nat44_sess(self):
Matus Fabian2ba92e32017-08-21 07:05:03 -07002638 """ IPFIX logging NAT44 session created/delted """
Matus Fabian6631e9c2017-05-24 01:52:20 -07002639 self.ipfix_domain_id = 10
2640 self.ipfix_src_port = 20202
2641 colector_port = 30303
2642 bind_layers(UDP, IPFIX, dport=30303)
Matus Fabian2ba92e32017-08-21 07:05:03 -07002643 self.nat44_add_address(self.nat_addr)
2644 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
2645 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
2646 is_inside=0)
Matus Fabianeea28d72017-01-13 04:15:54 -08002647 self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4n,
2648 src_address=self.pg3.local_ip4n,
2649 path_mtu=512,
Matus Fabian6631e9c2017-05-24 01:52:20 -07002650 template_interval=10,
2651 collector_port=colector_port)
Matus Fabian2ba92e32017-08-21 07:05:03 -07002652 self.vapi.nat_ipfix(domain_id=self.ipfix_domain_id,
2653 src_port=self.ipfix_src_port)
Matus Fabianeea28d72017-01-13 04:15:54 -08002654
2655 pkts = self.create_stream_in(self.pg0, self.pg1)
2656 self.pg0.add_stream(pkts)
2657 self.pg_enable_capture(self.pg_interfaces)
2658 self.pg_start()
2659 capture = self.pg1.get_capture(len(pkts))
2660 self.verify_capture_out(capture)
Matus Fabian2ba92e32017-08-21 07:05:03 -07002661 self.nat44_add_address(self.nat_addr, is_add=0)
Matus Fabianeea28d72017-01-13 04:15:54 -08002662 self.vapi.cli("ipfix flush") # FIXME this should be an API call
Matus Fabiana431ad12018-01-04 04:03:14 -08002663 capture = self.pg3.get_capture(9)
Matus Fabianeea28d72017-01-13 04:15:54 -08002664 ipfix = IPFIXDecoder()
2665 # first load template
2666 for p in capture:
2667 self.assertTrue(p.haslayer(IPFIX))
Matus Fabian6631e9c2017-05-24 01:52:20 -07002668 self.assertEqual(p[IP].src, self.pg3.local_ip4)
2669 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
2670 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
2671 self.assertEqual(p[UDP].dport, colector_port)
2672 self.assertEqual(p[IPFIX].observationDomainID,
2673 self.ipfix_domain_id)
Matus Fabianeea28d72017-01-13 04:15:54 -08002674 if p.haslayer(Template):
2675 ipfix.add_template(p.getlayer(Template))
2676 # verify events in data set
2677 for p in capture:
2678 if p.haslayer(Data):
2679 data = ipfix.decode_data_set(p.getlayer(Set))
2680 self.verify_ipfix_nat44_ses(data)
2681
2682 def test_ipfix_addr_exhausted(self):
Matus Fabian2ba92e32017-08-21 07:05:03 -07002683 """ IPFIX logging NAT addresses exhausted """
2684 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
2685 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
2686 is_inside=0)
Matus Fabianeea28d72017-01-13 04:15:54 -08002687 self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4n,
2688 src_address=self.pg3.local_ip4n,
2689 path_mtu=512,
2690 template_interval=10)
Matus Fabian2ba92e32017-08-21 07:05:03 -07002691 self.vapi.nat_ipfix(domain_id=self.ipfix_domain_id,
2692 src_port=self.ipfix_src_port)
Matus Fabianeea28d72017-01-13 04:15:54 -08002693
2694 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
2695 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
2696 TCP(sport=3025))
2697 self.pg0.add_stream(p)
2698 self.pg_enable_capture(self.pg_interfaces)
2699 self.pg_start()
Matus Fabian229c1aa2018-05-28 04:09:52 -07002700 self.pg1.assert_nothing_captured()
2701 sleep(1)
Matus Fabianeea28d72017-01-13 04:15:54 -08002702 self.vapi.cli("ipfix flush") # FIXME this should be an API call
Matus Fabiana431ad12018-01-04 04:03:14 -08002703 capture = self.pg3.get_capture(9)
Matus Fabianeea28d72017-01-13 04:15:54 -08002704 ipfix = IPFIXDecoder()
2705 # first load template
2706 for p in capture:
2707 self.assertTrue(p.haslayer(IPFIX))
Matus Fabian6631e9c2017-05-24 01:52:20 -07002708 self.assertEqual(p[IP].src, self.pg3.local_ip4)
2709 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
2710 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
2711 self.assertEqual(p[UDP].dport, 4739)
2712 self.assertEqual(p[IPFIX].observationDomainID,
2713 self.ipfix_domain_id)
Matus Fabianeea28d72017-01-13 04:15:54 -08002714 if p.haslayer(Template):
2715 ipfix.add_template(p.getlayer(Template))
2716 # verify events in data set
2717 for p in capture:
2718 if p.haslayer(Data):
2719 data = ipfix.decode_data_set(p.getlayer(Set))
2720 self.verify_ipfix_addr_exhausted(data)
2721
Matus Fabiana431ad12018-01-04 04:03:14 -08002722 @unittest.skipUnless(running_extended_tests(), "part of extended tests")
2723 def test_ipfix_max_sessions(self):
2724 """ IPFIX logging maximum session entries exceeded """
2725 self.nat44_add_address(self.nat_addr)
2726 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
2727 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
2728 is_inside=0)
2729
2730 nat44_config = self.vapi.nat_show_config()
2731 max_sessions = 10 * nat44_config.translation_buckets
2732
2733 pkts = []
2734 for i in range(0, max_sessions):
2735 src = "10.10.%u.%u" % ((i & 0xFF00) >> 8, i & 0xFF)
2736 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2737 IP(src=src, dst=self.pg1.remote_ip4) /
2738 TCP(sport=1025))
2739 pkts.append(p)
2740 self.pg0.add_stream(pkts)
2741 self.pg_enable_capture(self.pg_interfaces)
2742 self.pg_start()
2743
2744 self.pg1.get_capture(max_sessions)
2745 self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4n,
2746 src_address=self.pg3.local_ip4n,
2747 path_mtu=512,
2748 template_interval=10)
2749 self.vapi.nat_ipfix(domain_id=self.ipfix_domain_id,
2750 src_port=self.ipfix_src_port)
2751
2752 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2753 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
2754 TCP(sport=1025))
2755 self.pg0.add_stream(p)
2756 self.pg_enable_capture(self.pg_interfaces)
2757 self.pg_start()
Matus Fabian229c1aa2018-05-28 04:09:52 -07002758 self.pg1.assert_nothing_captured()
2759 sleep(1)
Matus Fabiana431ad12018-01-04 04:03:14 -08002760 self.vapi.cli("ipfix flush") # FIXME this should be an API call
2761 capture = self.pg3.get_capture(9)
2762 ipfix = IPFIXDecoder()
2763 # first load template
2764 for p in capture:
2765 self.assertTrue(p.haslayer(IPFIX))
2766 self.assertEqual(p[IP].src, self.pg3.local_ip4)
2767 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
2768 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
2769 self.assertEqual(p[UDP].dport, 4739)
2770 self.assertEqual(p[IPFIX].observationDomainID,
2771 self.ipfix_domain_id)
2772 if p.haslayer(Template):
2773 ipfix.add_template(p.getlayer(Template))
2774 # verify events in data set
2775 for p in capture:
2776 if p.haslayer(Data):
2777 data = ipfix.decode_data_set(p.getlayer(Set))
2778 self.verify_ipfix_max_sessions(data, max_sessions)
2779
Matus Fabianad1f3e12018-11-28 21:26:34 -08002780 def test_syslog_apmap(self):
2781 """ Test syslog address and port mapping creation and deletion """
2782 self.vapi.syslog_set_filter(SYSLOG_SEVERITY.INFO)
2783 self.vapi.syslog_set_sender(self.pg3.remote_ip4n, self.pg3.local_ip4n)
2784 self.nat44_add_address(self.nat_addr)
2785 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
2786 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
2787 is_inside=0)
2788
2789 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2790 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
2791 TCP(sport=self.tcp_port_in, dport=20))
2792 self.pg0.add_stream(p)
2793 self.pg_enable_capture(self.pg_interfaces)
2794 self.pg_start()
2795 capture = self.pg1.get_capture(1)
2796 self.tcp_port_out = capture[0][TCP].sport
2797 capture = self.pg3.get_capture(1)
2798 self.verify_syslog_apmap(capture[0][Raw].load)
2799
2800 self.pg_enable_capture(self.pg_interfaces)
2801 self.pg_start()
2802 self.nat44_add_address(self.nat_addr, is_add=0)
2803 capture = self.pg3.get_capture(1)
2804 self.verify_syslog_apmap(capture[0][Raw].load, False)
2805
Matus Fabiane1ae29a2017-01-27 00:47:58 -08002806 def test_pool_addr_fib(self):
Matus Fabian2ba92e32017-08-21 07:05:03 -07002807 """ NAT44 add pool addresses to FIB """
Matus Fabiane1ae29a2017-01-27 00:47:58 -08002808 static_addr = '10.0.0.10'
Matus Fabian2ba92e32017-08-21 07:05:03 -07002809 self.nat44_add_address(self.nat_addr)
2810 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
2811 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
2812 is_inside=0)
2813 self.nat44_add_static_mapping(self.pg0.remote_ip4, static_addr)
Matus Fabiane1ae29a2017-01-27 00:47:58 -08002814
Matus Fabian2ba92e32017-08-21 07:05:03 -07002815 # NAT44 address
Matus Fabiane1ae29a2017-01-27 00:47:58 -08002816 p = (Ether(src=self.pg1.remote_mac, dst='ff:ff:ff:ff:ff:ff') /
Matus Fabian2ba92e32017-08-21 07:05:03 -07002817 ARP(op=ARP.who_has, pdst=self.nat_addr,
Matus Fabiane1ae29a2017-01-27 00:47:58 -08002818 psrc=self.pg1.remote_ip4, hwsrc=self.pg1.remote_mac))
2819 self.pg1.add_stream(p)
2820 self.pg_enable_capture(self.pg_interfaces)
2821 self.pg_start()
2822 capture = self.pg1.get_capture(1)
2823 self.assertTrue(capture[0].haslayer(ARP))
2824 self.assertTrue(capture[0][ARP].op, ARP.is_at)
2825
2826 # 1:1 NAT address
2827 p = (Ether(src=self.pg1.remote_mac, dst='ff:ff:ff:ff:ff:ff') /
2828 ARP(op=ARP.who_has, pdst=static_addr,
2829 psrc=self.pg1.remote_ip4, hwsrc=self.pg1.remote_mac))
2830 self.pg1.add_stream(p)
2831 self.pg_enable_capture(self.pg_interfaces)
2832 self.pg_start()
2833 capture = self.pg1.get_capture(1)
2834 self.assertTrue(capture[0].haslayer(ARP))
2835 self.assertTrue(capture[0][ARP].op, ARP.is_at)
2836
Matus Fabian2ba92e32017-08-21 07:05:03 -07002837 # send ARP to non-NAT44 interface
Matus Fabiane1ae29a2017-01-27 00:47:58 -08002838 p = (Ether(src=self.pg2.remote_mac, dst='ff:ff:ff:ff:ff:ff') /
Matus Fabian2ba92e32017-08-21 07:05:03 -07002839 ARP(op=ARP.who_has, pdst=self.nat_addr,
Matus Fabiane1ae29a2017-01-27 00:47:58 -08002840 psrc=self.pg2.remote_ip4, hwsrc=self.pg2.remote_mac))
2841 self.pg2.add_stream(p)
2842 self.pg_enable_capture(self.pg_interfaces)
2843 self.pg_start()
Matus Fabian229c1aa2018-05-28 04:09:52 -07002844 self.pg1.assert_nothing_captured()
Matus Fabiane1ae29a2017-01-27 00:47:58 -08002845
2846 # remove addresses and verify
Matus Fabian2ba92e32017-08-21 07:05:03 -07002847 self.nat44_add_address(self.nat_addr, is_add=0)
2848 self.nat44_add_static_mapping(self.pg0.remote_ip4, static_addr,
2849 is_add=0)
Matus Fabiane1ae29a2017-01-27 00:47:58 -08002850
2851 p = (Ether(src=self.pg1.remote_mac, dst='ff:ff:ff:ff:ff:ff') /
Matus Fabian2ba92e32017-08-21 07:05:03 -07002852 ARP(op=ARP.who_has, pdst=self.nat_addr,
Matus Fabiane1ae29a2017-01-27 00:47:58 -08002853 psrc=self.pg1.remote_ip4, hwsrc=self.pg1.remote_mac))
2854 self.pg1.add_stream(p)
2855 self.pg_enable_capture(self.pg_interfaces)
2856 self.pg_start()
Matus Fabian229c1aa2018-05-28 04:09:52 -07002857 self.pg1.assert_nothing_captured()
Matus Fabiane1ae29a2017-01-27 00:47:58 -08002858
2859 p = (Ether(src=self.pg1.remote_mac, dst='ff:ff:ff:ff:ff:ff') /
2860 ARP(op=ARP.who_has, pdst=static_addr,
2861 psrc=self.pg1.remote_ip4, hwsrc=self.pg1.remote_mac))
2862 self.pg1.add_stream(p)
2863 self.pg_enable_capture(self.pg_interfaces)
2864 self.pg_start()
Matus Fabian229c1aa2018-05-28 04:09:52 -07002865 self.pg1.assert_nothing_captured()
Matus Fabiane1ae29a2017-01-27 00:47:58 -08002866
Juraj Slobodaeab38d92017-03-06 19:55:21 -08002867 def test_vrf_mode(self):
Matus Fabian2ba92e32017-08-21 07:05:03 -07002868 """ NAT44 tenant VRF aware address pool mode """
Juraj Slobodaeab38d92017-03-06 19:55:21 -08002869
2870 vrf_id1 = 1
2871 vrf_id2 = 2
2872 nat_ip1 = "10.0.0.10"
2873 nat_ip2 = "10.0.0.11"
2874
2875 self.pg0.unconfig_ip4()
2876 self.pg1.unconfig_ip4()
Neale Ranns15002542017-09-10 04:39:11 -07002877 self.vapi.ip_table_add_del(vrf_id1, is_add=1)
2878 self.vapi.ip_table_add_del(vrf_id2, is_add=1)
Juraj Slobodaeab38d92017-03-06 19:55:21 -08002879 self.pg0.set_table_ip4(vrf_id1)
2880 self.pg1.set_table_ip4(vrf_id2)
2881 self.pg0.config_ip4()
2882 self.pg1.config_ip4()
Matus Fabian8008d7c2018-07-09 01:34:20 -07002883 self.pg0.resolve_arp()
2884 self.pg1.resolve_arp()
Juraj Slobodaeab38d92017-03-06 19:55:21 -08002885
Matus Fabian2ba92e32017-08-21 07:05:03 -07002886 self.nat44_add_address(nat_ip1, vrf_id=vrf_id1)
2887 self.nat44_add_address(nat_ip2, vrf_id=vrf_id2)
2888 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
2889 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index)
2890 self.vapi.nat44_interface_add_del_feature(self.pg2.sw_if_index,
2891 is_inside=0)
Juraj Slobodaeab38d92017-03-06 19:55:21 -08002892
Matus Fabian8008d7c2018-07-09 01:34:20 -07002893 try:
2894 # first VRF
2895 pkts = self.create_stream_in(self.pg0, self.pg2)
2896 self.pg0.add_stream(pkts)
2897 self.pg_enable_capture(self.pg_interfaces)
2898 self.pg_start()
2899 capture = self.pg2.get_capture(len(pkts))
2900 self.verify_capture_out(capture, nat_ip1)
Juraj Slobodaeab38d92017-03-06 19:55:21 -08002901
Matus Fabian8008d7c2018-07-09 01:34:20 -07002902 # second VRF
2903 pkts = self.create_stream_in(self.pg1, self.pg2)
2904 self.pg1.add_stream(pkts)
2905 self.pg_enable_capture(self.pg_interfaces)
2906 self.pg_start()
2907 capture = self.pg2.get_capture(len(pkts))
2908 self.verify_capture_out(capture, nat_ip2)
Juraj Slobodaeab38d92017-03-06 19:55:21 -08002909
Matus Fabian8008d7c2018-07-09 01:34:20 -07002910 finally:
2911 self.pg0.unconfig_ip4()
2912 self.pg1.unconfig_ip4()
2913 self.pg0.set_table_ip4(0)
2914 self.pg1.set_table_ip4(0)
2915 self.pg0.config_ip4()
2916 self.pg1.config_ip4()
2917 self.pg0.resolve_arp()
2918 self.pg1.resolve_arp()
2919 self.vapi.ip_table_add_del(vrf_id1, is_add=0)
2920 self.vapi.ip_table_add_del(vrf_id2, is_add=0)
Neale Ranns15002542017-09-10 04:39:11 -07002921
Juraj Slobodaeab38d92017-03-06 19:55:21 -08002922 def test_vrf_feature_independent(self):
Matus Fabian2ba92e32017-08-21 07:05:03 -07002923 """ NAT44 tenant VRF independent address pool mode """
Juraj Slobodaeab38d92017-03-06 19:55:21 -08002924
2925 nat_ip1 = "10.0.0.10"
2926 nat_ip2 = "10.0.0.11"
2927
Matus Fabian2ba92e32017-08-21 07:05:03 -07002928 self.nat44_add_address(nat_ip1)
Matus Fabian51e759f2017-12-07 23:22:51 -08002929 self.nat44_add_address(nat_ip2, vrf_id=99)
Matus Fabian2ba92e32017-08-21 07:05:03 -07002930 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
2931 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index)
2932 self.vapi.nat44_interface_add_del_feature(self.pg2.sw_if_index,
2933 is_inside=0)
Juraj Slobodaeab38d92017-03-06 19:55:21 -08002934
2935 # first VRF
2936 pkts = self.create_stream_in(self.pg0, self.pg2)
2937 self.pg0.add_stream(pkts)
2938 self.pg_enable_capture(self.pg_interfaces)
2939 self.pg_start()
2940 capture = self.pg2.get_capture(len(pkts))
2941 self.verify_capture_out(capture, nat_ip1)
2942
2943 # second VRF
2944 pkts = self.create_stream_in(self.pg1, self.pg2)
2945 self.pg1.add_stream(pkts)
2946 self.pg_enable_capture(self.pg_interfaces)
2947 self.pg_start()
2948 capture = self.pg2.get_capture(len(pkts))
2949 self.verify_capture_out(capture, nat_ip1)
2950
Martin Gálik406eb1d2017-05-04 04:35:04 -07002951 def test_dynamic_ipless_interfaces(self):
Matus Fabian2ba92e32017-08-21 07:05:03 -07002952 """ NAT44 interfaces without configured IP address """
Martin Gálik406eb1d2017-05-04 04:35:04 -07002953
2954 self.vapi.ip_neighbor_add_del(self.pg7.sw_if_index,
Ole Troan895b6e82017-10-20 13:28:20 +02002955 mactobinary(self.pg7.remote_mac),
Martin Gálik406eb1d2017-05-04 04:35:04 -07002956 self.pg7.remote_ip4n,
2957 is_static=1)
2958 self.vapi.ip_neighbor_add_del(self.pg8.sw_if_index,
Ole Troan895b6e82017-10-20 13:28:20 +02002959 mactobinary(self.pg8.remote_mac),
Martin Gálik406eb1d2017-05-04 04:35:04 -07002960 self.pg8.remote_ip4n,
2961 is_static=1)
2962
2963 self.vapi.ip_add_del_route(dst_address=self.pg7.remote_ip4n,
2964 dst_address_length=32,
2965 next_hop_address=self.pg7.remote_ip4n,
2966 next_hop_sw_if_index=self.pg7.sw_if_index)
2967 self.vapi.ip_add_del_route(dst_address=self.pg8.remote_ip4n,
2968 dst_address_length=32,
2969 next_hop_address=self.pg8.remote_ip4n,
2970 next_hop_sw_if_index=self.pg8.sw_if_index)
2971
Matus Fabian2ba92e32017-08-21 07:05:03 -07002972 self.nat44_add_address(self.nat_addr)
2973 self.vapi.nat44_interface_add_del_feature(self.pg7.sw_if_index)
2974 self.vapi.nat44_interface_add_del_feature(self.pg8.sw_if_index,
2975 is_inside=0)
Martin Gálik406eb1d2017-05-04 04:35:04 -07002976
2977 # in2out
2978 pkts = self.create_stream_in(self.pg7, self.pg8)
2979 self.pg7.add_stream(pkts)
2980 self.pg_enable_capture(self.pg_interfaces)
2981 self.pg_start()
2982 capture = self.pg8.get_capture(len(pkts))
2983 self.verify_capture_out(capture)
2984
2985 # out2in
Matus Fabian2ba92e32017-08-21 07:05:03 -07002986 pkts = self.create_stream_out(self.pg8, self.nat_addr)
Martin Gálik406eb1d2017-05-04 04:35:04 -07002987 self.pg8.add_stream(pkts)
2988 self.pg_enable_capture(self.pg_interfaces)
2989 self.pg_start()
2990 capture = self.pg7.get_capture(len(pkts))
2991 self.verify_capture_in(capture, self.pg7)
2992
2993 def test_static_ipless_interfaces(self):
Matus Fabian2ba92e32017-08-21 07:05:03 -07002994 """ NAT44 interfaces without configured IP address - 1:1 NAT """
Martin Gálik406eb1d2017-05-04 04:35:04 -07002995
2996 self.vapi.ip_neighbor_add_del(self.pg7.sw_if_index,
Ole Troan895b6e82017-10-20 13:28:20 +02002997 mactobinary(self.pg7.remote_mac),
Martin Gálik406eb1d2017-05-04 04:35:04 -07002998 self.pg7.remote_ip4n,
2999 is_static=1)
3000 self.vapi.ip_neighbor_add_del(self.pg8.sw_if_index,
Ole Troan895b6e82017-10-20 13:28:20 +02003001 mactobinary(self.pg8.remote_mac),
Martin Gálik406eb1d2017-05-04 04:35:04 -07003002 self.pg8.remote_ip4n,
3003 is_static=1)
3004
3005 self.vapi.ip_add_del_route(dst_address=self.pg7.remote_ip4n,
3006 dst_address_length=32,
3007 next_hop_address=self.pg7.remote_ip4n,
3008 next_hop_sw_if_index=self.pg7.sw_if_index)
3009 self.vapi.ip_add_del_route(dst_address=self.pg8.remote_ip4n,
3010 dst_address_length=32,
3011 next_hop_address=self.pg8.remote_ip4n,
3012 next_hop_sw_if_index=self.pg8.sw_if_index)
3013
Matus Fabian2ba92e32017-08-21 07:05:03 -07003014 self.nat44_add_static_mapping(self.pg7.remote_ip4, self.nat_addr)
3015 self.vapi.nat44_interface_add_del_feature(self.pg7.sw_if_index)
3016 self.vapi.nat44_interface_add_del_feature(self.pg8.sw_if_index,
3017 is_inside=0)
Martin Gálik406eb1d2017-05-04 04:35:04 -07003018
3019 # out2in
3020 pkts = self.create_stream_out(self.pg8)
3021 self.pg8.add_stream(pkts)
3022 self.pg_enable_capture(self.pg_interfaces)
3023 self.pg_start()
3024 capture = self.pg7.get_capture(len(pkts))
3025 self.verify_capture_in(capture, self.pg7)
3026
3027 # in2out
3028 pkts = self.create_stream_in(self.pg7, self.pg8)
3029 self.pg7.add_stream(pkts)
3030 self.pg_enable_capture(self.pg_interfaces)
3031 self.pg_start()
3032 capture = self.pg8.get_capture(len(pkts))
Matus Fabian2ba92e32017-08-21 07:05:03 -07003033 self.verify_capture_out(capture, self.nat_addr, True)
Martin Gálik406eb1d2017-05-04 04:35:04 -07003034
3035 def test_static_with_port_ipless_interfaces(self):
Matus Fabian2ba92e32017-08-21 07:05:03 -07003036 """ NAT44 interfaces without configured IP address - 1:1 NAPT """
Martin Gálik406eb1d2017-05-04 04:35:04 -07003037
3038 self.tcp_port_out = 30606
3039 self.udp_port_out = 30607
3040 self.icmp_id_out = 30608
3041
3042 self.vapi.ip_neighbor_add_del(self.pg7.sw_if_index,
Ole Troan895b6e82017-10-20 13:28:20 +02003043 mactobinary(self.pg7.remote_mac),
Martin Gálik406eb1d2017-05-04 04:35:04 -07003044 self.pg7.remote_ip4n,
3045 is_static=1)
3046 self.vapi.ip_neighbor_add_del(self.pg8.sw_if_index,
Ole Troan895b6e82017-10-20 13:28:20 +02003047 mactobinary(self.pg8.remote_mac),
Martin Gálik406eb1d2017-05-04 04:35:04 -07003048 self.pg8.remote_ip4n,
3049 is_static=1)
3050
3051 self.vapi.ip_add_del_route(dst_address=self.pg7.remote_ip4n,
3052 dst_address_length=32,
3053 next_hop_address=self.pg7.remote_ip4n,
3054 next_hop_sw_if_index=self.pg7.sw_if_index)
3055 self.vapi.ip_add_del_route(dst_address=self.pg8.remote_ip4n,
3056 dst_address_length=32,
3057 next_hop_address=self.pg8.remote_ip4n,
3058 next_hop_sw_if_index=self.pg8.sw_if_index)
3059
Matus Fabian2ba92e32017-08-21 07:05:03 -07003060 self.nat44_add_address(self.nat_addr)
3061 self.nat44_add_static_mapping(self.pg7.remote_ip4, self.nat_addr,
3062 self.tcp_port_in, self.tcp_port_out,
3063 proto=IP_PROTOS.tcp)
3064 self.nat44_add_static_mapping(self.pg7.remote_ip4, self.nat_addr,
3065 self.udp_port_in, self.udp_port_out,
3066 proto=IP_PROTOS.udp)
3067 self.nat44_add_static_mapping(self.pg7.remote_ip4, self.nat_addr,
3068 self.icmp_id_in, self.icmp_id_out,
3069 proto=IP_PROTOS.icmp)
3070 self.vapi.nat44_interface_add_del_feature(self.pg7.sw_if_index)
3071 self.vapi.nat44_interface_add_del_feature(self.pg8.sw_if_index,
3072 is_inside=0)
Martin Gálik406eb1d2017-05-04 04:35:04 -07003073
3074 # out2in
3075 pkts = self.create_stream_out(self.pg8)
3076 self.pg8.add_stream(pkts)
3077 self.pg_enable_capture(self.pg_interfaces)
3078 self.pg_start()
3079 capture = self.pg7.get_capture(len(pkts))
3080 self.verify_capture_in(capture, self.pg7)
3081
3082 # in2out
3083 pkts = self.create_stream_in(self.pg7, self.pg8)
3084 self.pg7.add_stream(pkts)
3085 self.pg_enable_capture(self.pg_interfaces)
3086 self.pg_start()
3087 capture = self.pg8.get_capture(len(pkts))
3088 self.verify_capture_out(capture)
3089
Matus Fabian328dbc82017-06-19 04:28:04 -07003090 def test_static_unknown_proto(self):
3091 """ 1:1 NAT translate packet with unknown protocol """
3092 nat_ip = "10.0.0.10"
Matus Fabian2ba92e32017-08-21 07:05:03 -07003093 self.nat44_add_static_mapping(self.pg0.remote_ip4, nat_ip)
3094 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3095 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3096 is_inside=0)
Matus Fabian328dbc82017-06-19 04:28:04 -07003097
3098 # in2out
3099 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
3100 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
3101 GRE() /
Matus Fabian1e8db5f2017-06-20 01:45:49 -07003102 IP(src=self.pg2.remote_ip4, dst=self.pg3.remote_ip4) /
Matus Fabian328dbc82017-06-19 04:28:04 -07003103 TCP(sport=1234, dport=1234))
3104 self.pg0.add_stream(p)
3105 self.pg_enable_capture(self.pg_interfaces)
3106 self.pg_start()
3107 p = self.pg1.get_capture(1)
3108 packet = p[0]
3109 try:
3110 self.assertEqual(packet[IP].src, nat_ip)
3111 self.assertEqual(packet[IP].dst, self.pg1.remote_ip4)
Paul Vinciguerra978aa642018-11-24 22:19:12 -08003112 self.assertEqual(packet.haslayer(GRE), 1)
Klement Sekerad81ae412018-05-16 10:52:54 +02003113 self.assert_packet_checksums_valid(packet)
Matus Fabian328dbc82017-06-19 04:28:04 -07003114 except:
3115 self.logger.error(ppp("Unexpected or invalid packet:", packet))
3116 raise
3117
3118 # out2in
3119 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
3120 IP(src=self.pg1.remote_ip4, dst=nat_ip) /
3121 GRE() /
Matus Fabian1e8db5f2017-06-20 01:45:49 -07003122 IP(src=self.pg3.remote_ip4, dst=self.pg2.remote_ip4) /
Matus Fabian328dbc82017-06-19 04:28:04 -07003123 TCP(sport=1234, dport=1234))
3124 self.pg1.add_stream(p)
3125 self.pg_enable_capture(self.pg_interfaces)
3126 self.pg_start()
3127 p = self.pg0.get_capture(1)
3128 packet = p[0]
3129 try:
3130 self.assertEqual(packet[IP].src, self.pg1.remote_ip4)
3131 self.assertEqual(packet[IP].dst, self.pg0.remote_ip4)
Paul Vinciguerra978aa642018-11-24 22:19:12 -08003132 self.assertEqual(packet.haslayer(GRE), 1)
Klement Sekerad81ae412018-05-16 10:52:54 +02003133 self.assert_packet_checksums_valid(packet)
Matus Fabian328dbc82017-06-19 04:28:04 -07003134 except:
3135 self.logger.error(ppp("Unexpected or invalid packet:", packet))
3136 raise
3137
Matus Fabian7968e6c2017-07-06 05:37:49 -07003138 def test_hairpinning_static_unknown_proto(self):
Matus Fabian1e8db5f2017-06-20 01:45:49 -07003139 """ 1:1 NAT translate packet with unknown protocol - hairpinning """
3140
3141 host = self.pg0.remote_hosts[0]
3142 server = self.pg0.remote_hosts[1]
3143
3144 host_nat_ip = "10.0.0.10"
3145 server_nat_ip = "10.0.0.11"
3146
Matus Fabian2ba92e32017-08-21 07:05:03 -07003147 self.nat44_add_static_mapping(host.ip4, host_nat_ip)
3148 self.nat44_add_static_mapping(server.ip4, server_nat_ip)
3149 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3150 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3151 is_inside=0)
Matus Fabian1e8db5f2017-06-20 01:45:49 -07003152
3153 # host to server
3154 p = (Ether(dst=self.pg0.local_mac, src=host.mac) /
3155 IP(src=host.ip4, dst=server_nat_ip) /
3156 GRE() /
3157 IP(src=self.pg2.remote_ip4, dst=self.pg3.remote_ip4) /
3158 TCP(sport=1234, dport=1234))
3159 self.pg0.add_stream(p)
3160 self.pg_enable_capture(self.pg_interfaces)
3161 self.pg_start()
3162 p = self.pg0.get_capture(1)
3163 packet = p[0]
3164 try:
3165 self.assertEqual(packet[IP].src, host_nat_ip)
3166 self.assertEqual(packet[IP].dst, server.ip4)
Paul Vinciguerra978aa642018-11-24 22:19:12 -08003167 self.assertEqual(packet.haslayer(GRE), 1)
Klement Sekerad81ae412018-05-16 10:52:54 +02003168 self.assert_packet_checksums_valid(packet)
Matus Fabian1e8db5f2017-06-20 01:45:49 -07003169 except:
3170 self.logger.error(ppp("Unexpected or invalid packet:", packet))
3171 raise
3172
3173 # server to host
3174 p = (Ether(dst=self.pg0.local_mac, src=server.mac) /
3175 IP(src=server.ip4, dst=host_nat_ip) /
3176 GRE() /
3177 IP(src=self.pg3.remote_ip4, dst=self.pg2.remote_ip4) /
3178 TCP(sport=1234, dport=1234))
3179 self.pg0.add_stream(p)
3180 self.pg_enable_capture(self.pg_interfaces)
3181 self.pg_start()
3182 p = self.pg0.get_capture(1)
3183 packet = p[0]
3184 try:
3185 self.assertEqual(packet[IP].src, server_nat_ip)
3186 self.assertEqual(packet[IP].dst, host.ip4)
Paul Vinciguerra978aa642018-11-24 22:19:12 -08003187 self.assertEqual(packet.haslayer(GRE), 1)
Klement Sekerad81ae412018-05-16 10:52:54 +02003188 self.assert_packet_checksums_valid(packet)
Matus Fabian1e8db5f2017-06-20 01:45:49 -07003189 except:
3190 self.logger.error(ppp("Unexpected or invalid packet:", packet))
3191 raise
3192
Matus Fabian93d84c92017-07-19 08:06:01 -07003193 def test_output_feature(self):
Matus Fabian2ba92e32017-08-21 07:05:03 -07003194 """ NAT44 interface output feature (in2out postrouting) """
3195 self.nat44_add_address(self.nat_addr)
3196 self.vapi.nat44_interface_add_del_output_feature(self.pg0.sw_if_index)
Matus Fabianb2d2fc72017-09-10 22:17:47 -07003197 self.vapi.nat44_interface_add_del_output_feature(self.pg1.sw_if_index)
3198 self.vapi.nat44_interface_add_del_output_feature(self.pg3.sw_if_index,
Matus Fabian2ba92e32017-08-21 07:05:03 -07003199 is_inside=0)
Matus Fabian93d84c92017-07-19 08:06:01 -07003200
3201 # in2out
Matus Fabianb2d2fc72017-09-10 22:17:47 -07003202 pkts = self.create_stream_in(self.pg0, self.pg3)
Matus Fabian93d84c92017-07-19 08:06:01 -07003203 self.pg0.add_stream(pkts)
3204 self.pg_enable_capture(self.pg_interfaces)
3205 self.pg_start()
Matus Fabianb2d2fc72017-09-10 22:17:47 -07003206 capture = self.pg3.get_capture(len(pkts))
Matus Fabian93d84c92017-07-19 08:06:01 -07003207 self.verify_capture_out(capture)
3208
3209 # out2in
Matus Fabianb2d2fc72017-09-10 22:17:47 -07003210 pkts = self.create_stream_out(self.pg3)
3211 self.pg3.add_stream(pkts)
Matus Fabian93d84c92017-07-19 08:06:01 -07003212 self.pg_enable_capture(self.pg_interfaces)
3213 self.pg_start()
3214 capture = self.pg0.get_capture(len(pkts))
3215 self.verify_capture_in(capture, self.pg0)
3216
Matus Fabianb2d2fc72017-09-10 22:17:47 -07003217 # from non-NAT interface to NAT inside interface
3218 pkts = self.create_stream_in(self.pg2, self.pg0)
3219 self.pg2.add_stream(pkts)
3220 self.pg_enable_capture(self.pg_interfaces)
3221 self.pg_start()
3222 capture = self.pg0.get_capture(len(pkts))
3223 self.verify_capture_no_translation(capture, self.pg2, self.pg0)
3224
Matus Fabian93d84c92017-07-19 08:06:01 -07003225 def test_output_feature_vrf_aware(self):
Matus Fabian2ba92e32017-08-21 07:05:03 -07003226 """ NAT44 interface output feature VRF aware (in2out postrouting) """
Matus Fabian93d84c92017-07-19 08:06:01 -07003227 nat_ip_vrf10 = "10.0.0.10"
3228 nat_ip_vrf20 = "10.0.0.20"
3229
3230 self.vapi.ip_add_del_route(dst_address=self.pg3.remote_ip4n,
3231 dst_address_length=32,
3232 next_hop_address=self.pg3.remote_ip4n,
3233 next_hop_sw_if_index=self.pg3.sw_if_index,
3234 table_id=10)
3235 self.vapi.ip_add_del_route(dst_address=self.pg3.remote_ip4n,
3236 dst_address_length=32,
3237 next_hop_address=self.pg3.remote_ip4n,
3238 next_hop_sw_if_index=self.pg3.sw_if_index,
3239 table_id=20)
3240
Matus Fabian2ba92e32017-08-21 07:05:03 -07003241 self.nat44_add_address(nat_ip_vrf10, vrf_id=10)
3242 self.nat44_add_address(nat_ip_vrf20, vrf_id=20)
3243 self.vapi.nat44_interface_add_del_output_feature(self.pg4.sw_if_index)
3244 self.vapi.nat44_interface_add_del_output_feature(self.pg6.sw_if_index)
3245 self.vapi.nat44_interface_add_del_output_feature(self.pg3.sw_if_index,
3246 is_inside=0)
Matus Fabian93d84c92017-07-19 08:06:01 -07003247
3248 # in2out VRF 10
3249 pkts = self.create_stream_in(self.pg4, self.pg3)
3250 self.pg4.add_stream(pkts)
3251 self.pg_enable_capture(self.pg_interfaces)
3252 self.pg_start()
3253 capture = self.pg3.get_capture(len(pkts))
3254 self.verify_capture_out(capture, nat_ip=nat_ip_vrf10)
3255
3256 # out2in VRF 10
3257 pkts = self.create_stream_out(self.pg3, dst_ip=nat_ip_vrf10)
3258 self.pg3.add_stream(pkts)
3259 self.pg_enable_capture(self.pg_interfaces)
3260 self.pg_start()
3261 capture = self.pg4.get_capture(len(pkts))
3262 self.verify_capture_in(capture, self.pg4)
3263
3264 # in2out VRF 20
3265 pkts = self.create_stream_in(self.pg6, self.pg3)
3266 self.pg6.add_stream(pkts)
3267 self.pg_enable_capture(self.pg_interfaces)
3268 self.pg_start()
3269 capture = self.pg3.get_capture(len(pkts))
3270 self.verify_capture_out(capture, nat_ip=nat_ip_vrf20)
3271
3272 # out2in VRF 20
3273 pkts = self.create_stream_out(self.pg3, dst_ip=nat_ip_vrf20)
3274 self.pg3.add_stream(pkts)
3275 self.pg_enable_capture(self.pg_interfaces)
3276 self.pg_start()
3277 capture = self.pg6.get_capture(len(pkts))
3278 self.verify_capture_in(capture, self.pg6)
3279
Matus Fabian161c59c2017-07-21 03:46:03 -07003280 def test_output_feature_hairpinning(self):
Matus Fabian2ba92e32017-08-21 07:05:03 -07003281 """ NAT44 interface output feature hairpinning (in2out postrouting) """
Matus Fabian93d84c92017-07-19 08:06:01 -07003282 host = self.pg0.remote_hosts[0]
3283 server = self.pg0.remote_hosts[1]
3284 host_in_port = 1234
3285 host_out_port = 0
3286 server_in_port = 5678
3287 server_out_port = 8765
3288
Matus Fabian2ba92e32017-08-21 07:05:03 -07003289 self.nat44_add_address(self.nat_addr)
3290 self.vapi.nat44_interface_add_del_output_feature(self.pg0.sw_if_index)
3291 self.vapi.nat44_interface_add_del_output_feature(self.pg1.sw_if_index,
3292 is_inside=0)
Matus Fabian93d84c92017-07-19 08:06:01 -07003293
3294 # add static mapping for server
Matus Fabian2ba92e32017-08-21 07:05:03 -07003295 self.nat44_add_static_mapping(server.ip4, self.nat_addr,
3296 server_in_port, server_out_port,
3297 proto=IP_PROTOS.tcp)
Matus Fabian93d84c92017-07-19 08:06:01 -07003298
3299 # send packet from host to server
3300 p = (Ether(src=host.mac, dst=self.pg0.local_mac) /
Matus Fabian2ba92e32017-08-21 07:05:03 -07003301 IP(src=host.ip4, dst=self.nat_addr) /
Matus Fabian93d84c92017-07-19 08:06:01 -07003302 TCP(sport=host_in_port, dport=server_out_port))
3303 self.pg0.add_stream(p)
3304 self.pg_enable_capture(self.pg_interfaces)
3305 self.pg_start()
3306 capture = self.pg0.get_capture(1)
3307 p = capture[0]
3308 try:
3309 ip = p[IP]
3310 tcp = p[TCP]
Matus Fabian2ba92e32017-08-21 07:05:03 -07003311 self.assertEqual(ip.src, self.nat_addr)
Matus Fabian93d84c92017-07-19 08:06:01 -07003312 self.assertEqual(ip.dst, server.ip4)
3313 self.assertNotEqual(tcp.sport, host_in_port)
3314 self.assertEqual(tcp.dport, server_in_port)
Klement Sekerad81ae412018-05-16 10:52:54 +02003315 self.assert_packet_checksums_valid(p)
Matus Fabian93d84c92017-07-19 08:06:01 -07003316 host_out_port = tcp.sport
3317 except:
3318 self.logger.error(ppp("Unexpected or invalid packet:", p))
3319 raise
3320
3321 # send reply from server to host
3322 p = (Ether(src=server.mac, dst=self.pg0.local_mac) /
Matus Fabian2ba92e32017-08-21 07:05:03 -07003323 IP(src=server.ip4, dst=self.nat_addr) /
Matus Fabian93d84c92017-07-19 08:06:01 -07003324 TCP(sport=server_in_port, dport=host_out_port))
3325 self.pg0.add_stream(p)
3326 self.pg_enable_capture(self.pg_interfaces)
3327 self.pg_start()
3328 capture = self.pg0.get_capture(1)
3329 p = capture[0]
3330 try:
3331 ip = p[IP]
3332 tcp = p[TCP]
Matus Fabian2ba92e32017-08-21 07:05:03 -07003333 self.assertEqual(ip.src, self.nat_addr)
Matus Fabian93d84c92017-07-19 08:06:01 -07003334 self.assertEqual(ip.dst, host.ip4)
3335 self.assertEqual(tcp.sport, server_out_port)
3336 self.assertEqual(tcp.dport, host_in_port)
Klement Sekerad81ae412018-05-16 10:52:54 +02003337 self.assert_packet_checksums_valid(p)
Matus Fabian93d84c92017-07-19 08:06:01 -07003338 except:
Matus Fabiane82488f2018-01-18 03:38:45 -08003339 self.logger.error(ppp("Unexpected or invalid packet:", p))
Matus Fabian93d84c92017-07-19 08:06:01 -07003340 raise
3341
Matus Fabian36ea2d62017-10-24 04:13:49 -07003342 def test_one_armed_nat44(self):
3343 """ One armed NAT44 """
3344 remote_host = self.pg9.remote_hosts[0]
3345 local_host = self.pg9.remote_hosts[1]
3346 external_port = 0
3347
3348 self.nat44_add_address(self.nat_addr)
3349 self.vapi.nat44_interface_add_del_feature(self.pg9.sw_if_index)
3350 self.vapi.nat44_interface_add_del_feature(self.pg9.sw_if_index,
3351 is_inside=0)
3352
3353 # in2out
3354 p = (Ether(src=self.pg9.remote_mac, dst=self.pg9.local_mac) /
3355 IP(src=local_host.ip4, dst=remote_host.ip4) /
3356 TCP(sport=12345, dport=80))
3357 self.pg9.add_stream(p)
3358 self.pg_enable_capture(self.pg_interfaces)
3359 self.pg_start()
3360 capture = self.pg9.get_capture(1)
3361 p = capture[0]
3362 try:
3363 ip = p[IP]
3364 tcp = p[TCP]
3365 self.assertEqual(ip.src, self.nat_addr)
3366 self.assertEqual(ip.dst, remote_host.ip4)
3367 self.assertNotEqual(tcp.sport, 12345)
3368 external_port = tcp.sport
3369 self.assertEqual(tcp.dport, 80)
Klement Sekerad81ae412018-05-16 10:52:54 +02003370 self.assert_packet_checksums_valid(p)
Matus Fabian36ea2d62017-10-24 04:13:49 -07003371 except:
3372 self.logger.error(ppp("Unexpected or invalid packet:", p))
3373 raise
3374
3375 # out2in
3376 p = (Ether(src=self.pg9.remote_mac, dst=self.pg9.local_mac) /
3377 IP(src=remote_host.ip4, dst=self.nat_addr) /
3378 TCP(sport=80, dport=external_port))
3379 self.pg9.add_stream(p)
3380 self.pg_enable_capture(self.pg_interfaces)
3381 self.pg_start()
3382 capture = self.pg9.get_capture(1)
3383 p = capture[0]
3384 try:
3385 ip = p[IP]
3386 tcp = p[TCP]
3387 self.assertEqual(ip.src, remote_host.ip4)
3388 self.assertEqual(ip.dst, local_host.ip4)
3389 self.assertEqual(tcp.sport, 80)
3390 self.assertEqual(tcp.dport, 12345)
Klement Sekerad81ae412018-05-16 10:52:54 +02003391 self.assert_packet_checksums_valid(p)
Matus Fabian36ea2d62017-10-24 04:13:49 -07003392 except:
3393 self.logger.error(ppp("Unexpected or invalid packet:", p))
3394 raise
3395
Matus Fabiana5e73762018-12-14 01:55:16 -08003396 err = self.statistics.get_counter('/err/nat44-classify/next in2out')
3397 self.assertEqual(err, 1)
3398 err = self.statistics.get_counter('/err/nat44-classify/next out2in')
3399 self.assertEqual(err, 1)
3400
Matus Fabian5ba86f72017-10-26 03:37:38 -07003401 def test_del_session(self):
3402 """ Delete NAT44 session """
3403 self.nat44_add_address(self.nat_addr)
3404 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3405 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3406 is_inside=0)
3407
3408 pkts = self.create_stream_in(self.pg0, self.pg1)
3409 self.pg0.add_stream(pkts)
3410 self.pg_enable_capture(self.pg_interfaces)
3411 self.pg_start()
Matus Fabian229c1aa2018-05-28 04:09:52 -07003412 self.pg1.get_capture(len(pkts))
Matus Fabian5ba86f72017-10-26 03:37:38 -07003413
3414 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n, 0)
3415 nsessions = len(sessions)
3416
3417 self.vapi.nat44_del_session(sessions[0].inside_ip_address,
3418 sessions[0].inside_port,
3419 sessions[0].protocol)
3420 self.vapi.nat44_del_session(sessions[1].outside_ip_address,
3421 sessions[1].outside_port,
3422 sessions[1].protocol,
3423 is_in=0)
3424
3425 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n, 0)
3426 self.assertEqual(nsessions - len(sessions), 2)
3427
Matus Fabian68ba8802018-08-08 05:52:47 -07003428 self.vapi.nat44_del_session(sessions[0].inside_ip_address,
3429 sessions[0].inside_port,
3430 sessions[0].protocol)
3431
3432 self.verify_no_nat44_user()
3433
Matus Fabianefcd1e92017-08-15 06:59:19 -07003434 def test_set_get_reass(self):
3435 """ NAT44 set/get virtual fragmentation reassembly """
3436 reas_cfg1 = self.vapi.nat_get_reass()
3437
3438 self.vapi.nat_set_reass(timeout=reas_cfg1.ip4_timeout + 5,
3439 max_reass=reas_cfg1.ip4_max_reass * 2,
3440 max_frag=reas_cfg1.ip4_max_frag * 2)
3441
3442 reas_cfg2 = self.vapi.nat_get_reass()
3443
3444 self.assertEqual(reas_cfg1.ip4_timeout + 5, reas_cfg2.ip4_timeout)
3445 self.assertEqual(reas_cfg1.ip4_max_reass * 2, reas_cfg2.ip4_max_reass)
3446 self.assertEqual(reas_cfg1.ip4_max_frag * 2, reas_cfg2.ip4_max_frag)
3447
3448 self.vapi.nat_set_reass(drop_frag=1)
3449 self.assertTrue(self.vapi.nat_get_reass().ip4_drop_frag)
3450
3451 def test_frag_in_order(self):
3452 """ NAT44 translate fragments arriving in order """
Juraj Slobodafe0aa762018-07-23 12:22:54 +02003453
Matus Fabianefcd1e92017-08-15 06:59:19 -07003454 self.nat44_add_address(self.nat_addr)
3455 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3456 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3457 is_inside=0)
3458
Matus Fabianda41d722018-10-19 04:01:19 -07003459 self.frag_in_order(proto=IP_PROTOS.tcp)
3460 self.frag_in_order(proto=IP_PROTOS.udp)
3461 self.frag_in_order(proto=IP_PROTOS.icmp)
Matus Fabianefcd1e92017-08-15 06:59:19 -07003462
Matus Fabian111add72018-11-20 02:19:05 -08003463 def test_frag_forwarding(self):
3464 """ NAT44 forwarding fragment test """
3465 self.vapi.nat44_add_interface_addr(self.pg1.sw_if_index)
3466 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3467 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3468 is_inside=0)
3469 self.vapi.nat44_forwarding_enable_disable(1)
3470
3471 data = "A" * 16 + "B" * 16 + "C" * 3
3472 pkts = self.create_stream_frag(self.pg1,
3473 self.pg0.remote_ip4,
3474 4789,
3475 4789,
3476 data,
3477 proto=IP_PROTOS.udp)
3478 self.pg1.add_stream(pkts)
3479 self.pg_enable_capture(self.pg_interfaces)
3480 self.pg_start()
3481 frags = self.pg0.get_capture(len(pkts))
3482 p = self.reass_frags_and_verify(frags,
3483 self.pg1.remote_ip4,
3484 self.pg0.remote_ip4)
3485 self.assertEqual(p[UDP].sport, 4789)
3486 self.assertEqual(p[UDP].dport, 4789)
3487 self.assertEqual(data, p[Raw].load)
3488
Matus Fabianefcd1e92017-08-15 06:59:19 -07003489 def test_reass_hairpinning(self):
3490 """ NAT44 fragments hairpinning """
Juraj Slobodafe0aa762018-07-23 12:22:54 +02003491
Matus Fabianda41d722018-10-19 04:01:19 -07003492 self.server = self.pg0.remote_hosts[1]
3493 self.host_in_port = random.randint(1025, 65535)
3494 self.server_in_port = random.randint(1025, 65535)
3495 self.server_out_port = random.randint(1025, 65535)
Matus Fabianefcd1e92017-08-15 06:59:19 -07003496
3497 self.nat44_add_address(self.nat_addr)
3498 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3499 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3500 is_inside=0)
3501 # add static mapping for server
Matus Fabianda41d722018-10-19 04:01:19 -07003502 self.nat44_add_static_mapping(self.server.ip4, self.nat_addr,
3503 self.server_in_port,
3504 self.server_out_port,
Matus Fabianefcd1e92017-08-15 06:59:19 -07003505 proto=IP_PROTOS.tcp)
Matus Fabianda41d722018-10-19 04:01:19 -07003506 self.nat44_add_static_mapping(self.server.ip4, self.nat_addr,
3507 self.server_in_port,
3508 self.server_out_port,
3509 proto=IP_PROTOS.udp)
3510 self.nat44_add_static_mapping(self.server.ip4, self.nat_addr)
Matus Fabianefcd1e92017-08-15 06:59:19 -07003511
Matus Fabianda41d722018-10-19 04:01:19 -07003512 self.reass_hairpinning(proto=IP_PROTOS.tcp)
3513 self.reass_hairpinning(proto=IP_PROTOS.udp)
3514 self.reass_hairpinning(proto=IP_PROTOS.icmp)
Matus Fabianefcd1e92017-08-15 06:59:19 -07003515
3516 def test_frag_out_of_order(self):
3517 """ NAT44 translate fragments arriving out of order """
Juraj Slobodafe0aa762018-07-23 12:22:54 +02003518
Matus Fabianefcd1e92017-08-15 06:59:19 -07003519 self.nat44_add_address(self.nat_addr)
3520 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3521 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3522 is_inside=0)
3523
Matus Fabianda41d722018-10-19 04:01:19 -07003524 self.frag_out_of_order(proto=IP_PROTOS.tcp)
3525 self.frag_out_of_order(proto=IP_PROTOS.udp)
3526 self.frag_out_of_order(proto=IP_PROTOS.icmp)
Matus Fabianefcd1e92017-08-15 06:59:19 -07003527
Matus Fabian27697102017-11-09 01:43:47 -08003528 def test_port_restricted(self):
3529 """ Port restricted NAT44 (MAP-E CE) """
3530 self.nat44_add_address(self.nat_addr)
3531 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3532 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3533 is_inside=0)
Matus Fabian5d28c7a2018-09-04 03:55:45 -07003534 self.vapi.nat_set_addr_and_port_alloc_alg(alg=1,
3535 psid_offset=6,
3536 psid_length=6,
3537 psid=10)
Matus Fabian27697102017-11-09 01:43:47 -08003538
3539 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
3540 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
3541 TCP(sport=4567, dport=22))
3542 self.pg0.add_stream(p)
3543 self.pg_enable_capture(self.pg_interfaces)
3544 self.pg_start()
3545 capture = self.pg1.get_capture(1)
3546 p = capture[0]
3547 try:
3548 ip = p[IP]
3549 tcp = p[TCP]
3550 self.assertEqual(ip.dst, self.pg1.remote_ip4)
3551 self.assertEqual(ip.src, self.nat_addr)
3552 self.assertEqual(tcp.dport, 22)
3553 self.assertNotEqual(tcp.sport, 4567)
3554 self.assertEqual((tcp.sport >> 6) & 63, 10)
Klement Sekerad81ae412018-05-16 10:52:54 +02003555 self.assert_packet_checksums_valid(p)
Matus Fabian27697102017-11-09 01:43:47 -08003556 except:
3557 self.logger.error(ppp("Unexpected or invalid packet:", p))
3558 raise
3559
Matus Fabian5d28c7a2018-09-04 03:55:45 -07003560 def test_port_range(self):
3561 """ External address port range """
3562 self.nat44_add_address(self.nat_addr)
3563 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3564 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3565 is_inside=0)
3566 self.vapi.nat_set_addr_and_port_alloc_alg(alg=2,
3567 start_port=1025,
3568 end_port=1027)
3569
3570 pkts = []
3571 for port in range(0, 5):
3572 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
3573 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
3574 TCP(sport=1125 + port))
3575 pkts.append(p)
3576 self.pg0.add_stream(pkts)
3577 self.pg_enable_capture(self.pg_interfaces)
3578 self.pg_start()
3579 capture = self.pg1.get_capture(3)
3580 for p in capture:
3581 tcp = p[TCP]
3582 self.assertGreaterEqual(tcp.sport, 1025)
3583 self.assertLessEqual(tcp.sport, 1027)
3584
Matus Fabiana6110b62018-06-13 05:39:07 -07003585 def test_ipfix_max_frags(self):
3586 """ IPFIX logging maximum fragments pending reassembly exceeded """
3587 self.nat44_add_address(self.nat_addr)
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)
Matus Fabiana7f8b222018-09-05 06:01:55 -07003591 self.vapi.nat_set_reass(max_frag=1)
Matus Fabiana6110b62018-06-13 05:39:07 -07003592 self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4n,
3593 src_address=self.pg3.local_ip4n,
3594 path_mtu=512,
3595 template_interval=10)
3596 self.vapi.nat_ipfix(domain_id=self.ipfix_domain_id,
3597 src_port=self.ipfix_src_port)
3598
3599 data = "A" * 4 + "B" * 16 + "C" * 3
3600 self.tcp_port_in = random.randint(1025, 65535)
3601 pkts = self.create_stream_frag(self.pg0,
3602 self.pg1.remote_ip4,
3603 self.tcp_port_in,
3604 20,
3605 data)
Matus Fabiana7f8b222018-09-05 06:01:55 -07003606 pkts.reverse()
3607 self.pg0.add_stream(pkts)
Matus Fabiana6110b62018-06-13 05:39:07 -07003608 self.pg_enable_capture(self.pg_interfaces)
3609 self.pg_start()
3610 self.pg1.assert_nothing_captured()
3611 sleep(1)
3612 self.vapi.cli("ipfix flush") # FIXME this should be an API call
3613 capture = self.pg3.get_capture(9)
3614 ipfix = IPFIXDecoder()
3615 # first load template
3616 for p in capture:
3617 self.assertTrue(p.haslayer(IPFIX))
3618 self.assertEqual(p[IP].src, self.pg3.local_ip4)
3619 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
3620 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
3621 self.assertEqual(p[UDP].dport, 4739)
3622 self.assertEqual(p[IPFIX].observationDomainID,
3623 self.ipfix_domain_id)
3624 if p.haslayer(Template):
3625 ipfix.add_template(p.getlayer(Template))
3626 # verify events in data set
3627 for p in capture:
3628 if p.haslayer(Data):
3629 data = ipfix.decode_data_set(p.getlayer(Set))
Matus Fabiana7f8b222018-09-05 06:01:55 -07003630 self.verify_ipfix_max_fragments_ip4(data, 1,
Matus Fabiana6110b62018-06-13 05:39:07 -07003631 self.pg0.remote_ip4n)
3632
Matus Fabian8008d7c2018-07-09 01:34:20 -07003633 def test_multiple_outside_vrf(self):
3634 """ Multiple outside VRF """
3635 vrf_id1 = 1
3636 vrf_id2 = 2
3637
3638 self.pg1.unconfig_ip4()
3639 self.pg2.unconfig_ip4()
3640 self.vapi.ip_table_add_del(vrf_id1, is_add=1)
3641 self.vapi.ip_table_add_del(vrf_id2, is_add=1)
3642 self.pg1.set_table_ip4(vrf_id1)
3643 self.pg2.set_table_ip4(vrf_id2)
3644 self.pg1.config_ip4()
3645 self.pg2.config_ip4()
3646 self.pg1.resolve_arp()
3647 self.pg2.resolve_arp()
3648
3649 self.nat44_add_address(self.nat_addr)
3650 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3651 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3652 is_inside=0)
3653 self.vapi.nat44_interface_add_del_feature(self.pg2.sw_if_index,
3654 is_inside=0)
3655
3656 try:
3657 # first VRF
3658 pkts = self.create_stream_in(self.pg0, self.pg1)
3659 self.pg0.add_stream(pkts)
3660 self.pg_enable_capture(self.pg_interfaces)
3661 self.pg_start()
3662 capture = self.pg1.get_capture(len(pkts))
3663 self.verify_capture_out(capture, self.nat_addr)
3664
3665 pkts = self.create_stream_out(self.pg1, self.nat_addr)
3666 self.pg1.add_stream(pkts)
3667 self.pg_enable_capture(self.pg_interfaces)
3668 self.pg_start()
3669 capture = self.pg0.get_capture(len(pkts))
3670 self.verify_capture_in(capture, self.pg0)
3671
3672 self.tcp_port_in = 60303
3673 self.udp_port_in = 60304
3674 self.icmp_id_in = 60305
3675
3676 # second VRF
3677 pkts = self.create_stream_in(self.pg0, self.pg2)
3678 self.pg0.add_stream(pkts)
3679 self.pg_enable_capture(self.pg_interfaces)
3680 self.pg_start()
3681 capture = self.pg2.get_capture(len(pkts))
3682 self.verify_capture_out(capture, self.nat_addr)
3683
3684 pkts = self.create_stream_out(self.pg2, self.nat_addr)
3685 self.pg2.add_stream(pkts)
3686 self.pg_enable_capture(self.pg_interfaces)
3687 self.pg_start()
3688 capture = self.pg0.get_capture(len(pkts))
3689 self.verify_capture_in(capture, self.pg0)
3690
3691 finally:
3692 self.pg1.unconfig_ip4()
3693 self.pg2.unconfig_ip4()
3694 self.pg1.set_table_ip4(0)
3695 self.pg2.set_table_ip4(0)
3696 self.pg1.config_ip4()
3697 self.pg2.config_ip4()
3698 self.pg1.resolve_arp()
3699 self.pg2.resolve_arp()
3700
Matus Fabian878c6462018-08-23 00:33:35 -07003701 @unittest.skipUnless(running_extended_tests(), "part of extended tests")
3702 def test_session_timeout(self):
3703 """ NAT44 session timeouts """
3704 self.nat44_add_address(self.nat_addr)
3705 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3706 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3707 is_inside=0)
3708 self.vapi.nat_set_timeouts(udp=5)
3709
3710 max_sessions = 1000
3711 pkts = []
3712 for i in range(0, max_sessions):
3713 src = "10.10.%u.%u" % ((i & 0xFF00) >> 8, i & 0xFF)
3714 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
3715 IP(src=src, dst=self.pg1.remote_ip4) /
3716 UDP(sport=1025, dport=53))
3717 pkts.append(p)
3718 self.pg0.add_stream(pkts)
3719 self.pg_enable_capture(self.pg_interfaces)
3720 self.pg_start()
3721 self.pg1.get_capture(max_sessions)
3722
3723 sleep(6)
3724
3725 pkts = []
3726 for i in range(0, max_sessions):
3727 src = "10.10.%u.%u" % ((i & 0xFF00) >> 8, i & 0xFF)
3728 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
3729 IP(src=src, dst=self.pg1.remote_ip4) /
3730 UDP(sport=1026, dport=53))
3731 pkts.append(p)
3732 self.pg0.add_stream(pkts)
3733 self.pg_enable_capture(self.pg_interfaces)
3734 self.pg_start()
3735 self.pg1.get_capture(max_sessions)
3736
3737 nsessions = 0
3738 users = self.vapi.nat44_user_dump()
3739 for user in users:
3740 nsessions = nsessions + user.nsessions
3741 self.assertLess(nsessions, 2 * max_sessions)
3742
Matus Fabianbb4e0222018-09-13 02:36:25 -07003743 def test_mss_clamping(self):
3744 """ TCP MSS clamping """
3745 self.nat44_add_address(self.nat_addr)
3746 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3747 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3748 is_inside=0)
3749
3750 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
3751 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
3752 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
3753 flags="S", options=[('MSS', 1400)]))
3754
3755 self.vapi.nat_set_mss_clamping(enable=1, mss_value=1000)
3756 self.pg0.add_stream(p)
3757 self.pg_enable_capture(self.pg_interfaces)
3758 self.pg_start()
3759 capture = self.pg1.get_capture(1)
3760 # Negotiated MSS value greater than configured - changed
3761 self.verify_mss_value(capture[0], 1000)
3762
3763 self.vapi.nat_set_mss_clamping(enable=0)
3764 self.pg0.add_stream(p)
3765 self.pg_enable_capture(self.pg_interfaces)
3766 self.pg_start()
3767 capture = self.pg1.get_capture(1)
3768 # MSS clamping disabled - negotiated MSS unchanged
3769 self.verify_mss_value(capture[0], 1400)
3770
3771 self.vapi.nat_set_mss_clamping(enable=1, mss_value=1500)
3772 self.pg0.add_stream(p)
3773 self.pg_enable_capture(self.pg_interfaces)
3774 self.pg_start()
3775 capture = self.pg1.get_capture(1)
3776 # Negotiated MSS value smaller than configured - unchanged
3777 self.verify_mss_value(capture[0], 1400)
3778
Matus Fabiana6110b62018-06-13 05:39:07 -07003779 def tearDown(self):
3780 super(TestNAT44, self).tearDown()
3781 if not self.vpp_dead:
3782 self.logger.info(self.vapi.cli("show nat44 addresses"))
3783 self.logger.info(self.vapi.cli("show nat44 interfaces"))
3784 self.logger.info(self.vapi.cli("show nat44 static mappings"))
3785 self.logger.info(self.vapi.cli("show nat44 interface address"))
3786 self.logger.info(self.vapi.cli("show nat44 sessions detail"))
3787 self.logger.info(self.vapi.cli("show nat virtual-reassembly"))
3788 self.logger.info(self.vapi.cli("show nat44 hash tables detail"))
Matus Fabian878c6462018-08-23 00:33:35 -07003789 self.logger.info(self.vapi.cli("show nat timeouts"))
Matus Fabian5d28c7a2018-09-04 03:55:45 -07003790 self.logger.info(
3791 self.vapi.cli("show nat addr-port-assignment-alg"))
Matus Fabiana6110b62018-06-13 05:39:07 -07003792 self.clear_nat44()
3793 self.vapi.cli("clear logging")
3794
3795
3796class TestNAT44EndpointDependent(MethodHolder):
3797 """ Endpoint-Dependent mapping and filtering test cases """
3798
3799 @classmethod
3800 def setUpConstants(cls):
3801 super(TestNAT44EndpointDependent, cls).setUpConstants()
3802 cls.vpp_cmdline.extend(["nat", "{", "endpoint-dependent", "}"])
3803
3804 @classmethod
3805 def setUpClass(cls):
3806 super(TestNAT44EndpointDependent, cls).setUpClass()
3807 cls.vapi.cli("set log class nat level debug")
3808 try:
3809 cls.tcp_port_in = 6303
3810 cls.tcp_port_out = 6303
3811 cls.udp_port_in = 6304
3812 cls.udp_port_out = 6304
3813 cls.icmp_id_in = 6305
3814 cls.icmp_id_out = 6305
3815 cls.nat_addr = '10.0.0.3'
3816 cls.nat_addr_n = socket.inet_pton(socket.AF_INET, cls.nat_addr)
3817 cls.ipfix_src_port = 4739
3818 cls.ipfix_domain_id = 1
3819 cls.tcp_external_port = 80
3820
Matus Fabian8008d7c2018-07-09 01:34:20 -07003821 cls.create_pg_interfaces(range(7))
Matus Fabiana6110b62018-06-13 05:39:07 -07003822 cls.interfaces = list(cls.pg_interfaces[0:3])
3823
3824 for i in cls.interfaces:
3825 i.admin_up()
3826 i.config_ip4()
3827 i.resolve_arp()
3828
3829 cls.pg0.generate_remote_hosts(3)
3830 cls.pg0.configure_ipv4_neighbors()
3831
3832 cls.pg3.admin_up()
3833
3834 cls.pg4.generate_remote_hosts(2)
3835 cls.pg4.config_ip4()
3836 ip_addr_n = socket.inet_pton(socket.AF_INET, "10.0.0.1")
3837 cls.vapi.sw_interface_add_del_address(cls.pg4.sw_if_index,
3838 ip_addr_n,
3839 24)
3840 cls.pg4.admin_up()
3841 cls.pg4.resolve_arp()
3842 cls.pg4._remote_hosts[1]._ip4 = cls.pg4._remote_hosts[0]._ip4
3843 cls.pg4.resolve_arp()
3844
Matus Fabian8008d7c2018-07-09 01:34:20 -07003845 zero_ip4n = socket.inet_pton(socket.AF_INET, "0.0.0.0")
3846 cls.vapi.ip_table_add_del(1, is_add=1)
3847
3848 cls.pg5._local_ip4 = "10.1.1.1"
3849 cls.pg5._local_ip4n = socket.inet_pton(socket.AF_INET,
3850 cls.pg5.local_ip4)
3851 cls.pg5._remote_hosts[0]._ip4 = "10.1.1.2"
3852 cls.pg5._remote_hosts[0]._ip4n = socket.inet_pton(
3853 socket.AF_INET, cls.pg5.remote_ip4)
3854 cls.pg5.set_table_ip4(1)
3855 cls.pg5.config_ip4()
3856 cls.pg5.admin_up()
3857 cls.vapi.ip_add_del_route(dst_address=cls.pg5.remote_ip4n,
3858 dst_address_length=32,
3859 table_id=1,
3860 next_hop_sw_if_index=cls.pg5.sw_if_index,
3861 next_hop_address=zero_ip4n)
3862
3863 cls.pg6._local_ip4 = "10.1.2.1"
3864 cls.pg6._local_ip4n = socket.inet_pton(socket.AF_INET,
3865 cls.pg6.local_ip4)
3866 cls.pg6._remote_hosts[0]._ip4 = "10.1.2.2"
3867 cls.pg6._remote_hosts[0]._ip4n = socket.inet_pton(
3868 socket.AF_INET, cls.pg6.remote_ip4)
3869 cls.pg6.set_table_ip4(1)
3870 cls.pg6.config_ip4()
3871 cls.pg6.admin_up()
3872 cls.vapi.ip_add_del_route(dst_address=cls.pg6.remote_ip4n,
3873 dst_address_length=32,
3874 table_id=1,
3875 next_hop_sw_if_index=cls.pg6.sw_if_index,
3876 next_hop_address=zero_ip4n)
3877
3878 cls.vapi.ip_add_del_route(dst_address=cls.pg6.remote_ip4n,
3879 dst_address_length=16,
3880 next_hop_address=zero_ip4n,
3881 table_id=0,
3882 next_hop_table_id=1)
3883 cls.vapi.ip_add_del_route(dst_address=zero_ip4n,
3884 dst_address_length=0,
3885 next_hop_address=zero_ip4n,
3886 table_id=1,
3887 next_hop_table_id=0)
3888 cls.vapi.ip_add_del_route(dst_address=zero_ip4n,
3889 dst_address_length=0,
3890 table_id=0,
3891 next_hop_sw_if_index=cls.pg1.sw_if_index,
3892 next_hop_address=cls.pg1.local_ip4n)
3893
3894 cls.pg5.resolve_arp()
3895 cls.pg6.resolve_arp()
3896
Matus Fabiana6110b62018-06-13 05:39:07 -07003897 except Exception:
3898 super(TestNAT44EndpointDependent, cls).tearDownClass()
3899 raise
3900
Juraj Slobodafe0aa762018-07-23 12:22:54 +02003901 def test_frag_in_order(self):
3902 """ NAT44 translate fragments arriving in order """
3903 self.nat44_add_address(self.nat_addr)
3904 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3905 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3906 is_inside=0)
3907 self.frag_in_order(proto=IP_PROTOS.tcp)
3908 self.frag_in_order(proto=IP_PROTOS.udp)
3909 self.frag_in_order(proto=IP_PROTOS.icmp)
3910
3911 def test_frag_in_order_dont_translate(self):
3912 """ NAT44 don't translate fragments arriving in order """
3913 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3914 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3915 is_inside=0)
3916 self.vapi.nat44_forwarding_enable_disable(enable=True)
3917 self.frag_in_order(proto=IP_PROTOS.tcp, dont_translate=True)
3918
3919 def test_frag_out_of_order(self):
3920 """ NAT44 translate fragments arriving out of order """
3921 self.nat44_add_address(self.nat_addr)
3922 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3923 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3924 is_inside=0)
3925 self.frag_out_of_order(proto=IP_PROTOS.tcp)
3926 self.frag_out_of_order(proto=IP_PROTOS.udp)
3927 self.frag_out_of_order(proto=IP_PROTOS.icmp)
3928
3929 def test_frag_out_of_order_dont_translate(self):
3930 """ NAT44 don't translate fragments arriving out of order """
3931 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3932 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3933 is_inside=0)
3934 self.vapi.nat44_forwarding_enable_disable(enable=True)
3935 self.frag_out_of_order(proto=IP_PROTOS.tcp, dont_translate=True)
3936
3937 def test_frag_in_order_in_plus_out(self):
3938 """ in+out interface fragments in order """
3939 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3940 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index,
3941 is_inside=0)
3942 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index)
3943 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3944 is_inside=0)
3945
3946 self.server = self.pg1.remote_hosts[0]
3947
3948 self.server_in_addr = self.server.ip4
3949 self.server_out_addr = '11.11.11.11'
3950 self.server_in_port = random.randint(1025, 65535)
3951 self.server_out_port = random.randint(1025, 65535)
3952
3953 self.nat44_add_address(self.server_out_addr)
3954
3955 # add static mappings for server
3956 self.nat44_add_static_mapping(self.server_in_addr,
3957 self.server_out_addr,
3958 self.server_in_port,
3959 self.server_out_port,
3960 proto=IP_PROTOS.tcp)
3961 self.nat44_add_static_mapping(self.server_in_addr,
3962 self.server_out_addr,
3963 self.server_in_port,
3964 self.server_out_port,
3965 proto=IP_PROTOS.udp)
3966 self.nat44_add_static_mapping(self.server_in_addr,
3967 self.server_out_addr,
3968 proto=IP_PROTOS.icmp)
3969
3970 self.vapi.nat_set_reass(timeout=10)
3971
3972 self.frag_in_order_in_plus_out(proto=IP_PROTOS.tcp)
3973 self.frag_in_order_in_plus_out(proto=IP_PROTOS.udp)
3974 self.frag_in_order_in_plus_out(proto=IP_PROTOS.icmp)
3975
3976 def test_frag_out_of_order_in_plus_out(self):
3977 """ in+out interface fragments out of order """
3978 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3979 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index,
3980 is_inside=0)
3981 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index)
3982 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3983 is_inside=0)
3984
3985 self.server = self.pg1.remote_hosts[0]
3986
3987 self.server_in_addr = self.server.ip4
3988 self.server_out_addr = '11.11.11.11'
3989 self.server_in_port = random.randint(1025, 65535)
3990 self.server_out_port = random.randint(1025, 65535)
3991
3992 self.nat44_add_address(self.server_out_addr)
3993
3994 # add static mappings for server
3995 self.nat44_add_static_mapping(self.server_in_addr,
3996 self.server_out_addr,
3997 self.server_in_port,
3998 self.server_out_port,
3999 proto=IP_PROTOS.tcp)
4000 self.nat44_add_static_mapping(self.server_in_addr,
4001 self.server_out_addr,
4002 self.server_in_port,
4003 self.server_out_port,
4004 proto=IP_PROTOS.udp)
4005 self.nat44_add_static_mapping(self.server_in_addr,
4006 self.server_out_addr,
4007 proto=IP_PROTOS.icmp)
4008
4009 self.vapi.nat_set_reass(timeout=10)
4010
4011 self.frag_out_of_order_in_plus_out(proto=IP_PROTOS.tcp)
4012 self.frag_out_of_order_in_plus_out(proto=IP_PROTOS.udp)
4013 self.frag_out_of_order_in_plus_out(proto=IP_PROTOS.icmp)
4014
4015 def test_reass_hairpinning(self):
4016 """ NAT44 fragments hairpinning """
4017 self.server = self.pg0.remote_hosts[1]
4018 self.host_in_port = random.randint(1025, 65535)
4019 self.server_in_port = random.randint(1025, 65535)
4020 self.server_out_port = random.randint(1025, 65535)
4021
4022 self.nat44_add_address(self.nat_addr)
4023 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
4024 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
4025 is_inside=0)
4026 # add static mapping for server
4027 self.nat44_add_static_mapping(self.server.ip4, self.nat_addr,
4028 self.server_in_port,
4029 self.server_out_port,
4030 proto=IP_PROTOS.tcp)
4031 self.nat44_add_static_mapping(self.server.ip4, self.nat_addr,
4032 self.server_in_port,
4033 self.server_out_port,
4034 proto=IP_PROTOS.udp)
Matus Fabianda41d722018-10-19 04:01:19 -07004035 self.nat44_add_static_mapping(self.server.ip4, self.nat_addr)
Juraj Slobodafe0aa762018-07-23 12:22:54 +02004036
4037 self.reass_hairpinning(proto=IP_PROTOS.tcp)
4038 self.reass_hairpinning(proto=IP_PROTOS.udp)
4039 self.reass_hairpinning(proto=IP_PROTOS.icmp)
4040
Matus Fabiana6110b62018-06-13 05:39:07 -07004041 def test_dynamic(self):
4042 """ NAT44 dynamic translation test """
4043
4044 self.nat44_add_address(self.nat_addr)
4045 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
4046 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
4047 is_inside=0)
4048
Matus Fabian69ce30d2018-08-22 01:27:10 -07004049 nat_config = self.vapi.nat_show_config()
4050 self.assertEqual(1, nat_config.endpoint_dependent)
4051
Matus Fabiana6110b62018-06-13 05:39:07 -07004052 # in2out
Matus Fabiana5e73762018-12-14 01:55:16 -08004053 tcpn = self.statistics.get_counter(
4054 '/err/nat44-ed-in2out-slowpath/TCP packets')
4055 udpn = self.statistics.get_counter(
4056 '/err/nat44-ed-in2out-slowpath/UDP packets')
4057 icmpn = self.statistics.get_counter(
4058 '/err/nat44-ed-in2out-slowpath/ICMP packets')
4059 totaln = self.statistics.get_counter(
4060 '/err/nat44-ed-in2out-slowpath/good in2out packets processed')
4061
Matus Fabiana6110b62018-06-13 05:39:07 -07004062 pkts = self.create_stream_in(self.pg0, self.pg1)
4063 self.pg0.add_stream(pkts)
4064 self.pg_enable_capture(self.pg_interfaces)
4065 self.pg_start()
4066 capture = self.pg1.get_capture(len(pkts))
4067 self.verify_capture_out(capture)
4068
Matus Fabiana5e73762018-12-14 01:55:16 -08004069 err = self.statistics.get_counter(
4070 '/err/nat44-ed-in2out-slowpath/TCP packets')
4071 self.assertEqual(err - tcpn, 1)
4072 err = self.statistics.get_counter(
4073 '/err/nat44-ed-in2out-slowpath/UDP packets')
4074 self.assertEqual(err - udpn, 1)
4075 err = self.statistics.get_counter(
4076 '/err/nat44-ed-in2out-slowpath/ICMP packets')
4077 self.assertEqual(err - icmpn, 1)
4078 err = self.statistics.get_counter(
4079 '/err/nat44-ed-in2out-slowpath/good in2out packets processed')
4080 self.assertEqual(err - totaln, 3)
4081
Matus Fabiana6110b62018-06-13 05:39:07 -07004082 # out2in
Matus Fabiana5e73762018-12-14 01:55:16 -08004083 tcpn = self.statistics.get_counter('/err/nat44-ed-out2in/TCP packets')
4084 udpn = self.statistics.get_counter('/err/nat44-ed-out2in/UDP packets')
4085 icmpn = self.statistics.get_counter(
4086 '/err/nat44-ed-out2in-slowpath/ICMP packets')
4087 totaln = self.statistics.get_counter(
4088 '/err/nat44-ed-out2in/good out2in packets processed')
4089
Matus Fabiana6110b62018-06-13 05:39:07 -07004090 pkts = self.create_stream_out(self.pg1)
4091 self.pg1.add_stream(pkts)
4092 self.pg_enable_capture(self.pg_interfaces)
4093 self.pg_start()
4094 capture = self.pg0.get_capture(len(pkts))
4095 self.verify_capture_in(capture, self.pg0)
4096
Matus Fabiana5e73762018-12-14 01:55:16 -08004097 err = self.statistics.get_counter('/err/nat44-ed-out2in/TCP packets')
4098 self.assertEqual(err - tcpn, 1)
4099 err = self.statistics.get_counter('/err/nat44-ed-out2in/UDP packets')
4100 self.assertEqual(err - udpn, 1)
4101 err = self.statistics.get_counter(
4102 '/err/nat44-ed-out2in-slowpath/ICMP packets')
4103 self.assertEqual(err - icmpn, 1)
4104 err = self.statistics.get_counter(
4105 '/err/nat44-ed-out2in/good out2in packets processed')
4106 self.assertEqual(err - totaln, 2)
4107
Matus Fabiana6110b62018-06-13 05:39:07 -07004108 def test_forwarding(self):
4109 """ NAT44 forwarding test """
4110
4111 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
4112 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
4113 is_inside=0)
4114 self.vapi.nat44_forwarding_enable_disable(1)
4115
4116 real_ip = self.pg0.remote_ip4n
4117 alias_ip = self.nat_addr_n
4118 self.vapi.nat44_add_del_static_mapping(local_ip=real_ip,
4119 external_ip=alias_ip)
4120
4121 try:
4122 # in2out - static mapping match
4123
4124 pkts = self.create_stream_out(self.pg1)
4125 self.pg1.add_stream(pkts)
4126 self.pg_enable_capture(self.pg_interfaces)
4127 self.pg_start()
4128 capture = self.pg0.get_capture(len(pkts))
4129 self.verify_capture_in(capture, self.pg0)
4130
4131 pkts = self.create_stream_in(self.pg0, self.pg1)
4132 self.pg0.add_stream(pkts)
4133 self.pg_enable_capture(self.pg_interfaces)
4134 self.pg_start()
4135 capture = self.pg1.get_capture(len(pkts))
4136 self.verify_capture_out(capture, same_port=True)
4137
4138 # in2out - no static mapping match
4139
4140 host0 = self.pg0.remote_hosts[0]
4141 self.pg0.remote_hosts[0] = self.pg0.remote_hosts[1]
4142 try:
4143 pkts = self.create_stream_out(self.pg1,
4144 dst_ip=self.pg0.remote_ip4,
4145 use_inside_ports=True)
4146 self.pg1.add_stream(pkts)
4147 self.pg_enable_capture(self.pg_interfaces)
4148 self.pg_start()
4149 capture = self.pg0.get_capture(len(pkts))
4150 self.verify_capture_in(capture, self.pg0)
4151
4152 pkts = self.create_stream_in(self.pg0, self.pg1)
4153 self.pg0.add_stream(pkts)
4154 self.pg_enable_capture(self.pg_interfaces)
4155 self.pg_start()
4156 capture = self.pg1.get_capture(len(pkts))
4157 self.verify_capture_out(capture, nat_ip=self.pg0.remote_ip4,
4158 same_port=True)
4159 finally:
4160 self.pg0.remote_hosts[0] = host0
4161
4162 user = self.pg0.remote_hosts[1]
4163 sessions = self.vapi.nat44_user_session_dump(user.ip4n, 0)
4164 self.assertEqual(len(sessions), 3)
4165 self.assertTrue(sessions[0].ext_host_valid)
4166 self.vapi.nat44_del_session(
4167 sessions[0].inside_ip_address,
4168 sessions[0].inside_port,
4169 sessions[0].protocol,
4170 ext_host_address=sessions[0].ext_host_address,
4171 ext_host_port=sessions[0].ext_host_port)
4172 sessions = self.vapi.nat44_user_session_dump(user.ip4n, 0)
4173 self.assertEqual(len(sessions), 2)
4174
4175 finally:
4176 self.vapi.nat44_forwarding_enable_disable(0)
4177 self.vapi.nat44_add_del_static_mapping(local_ip=real_ip,
4178 external_ip=alias_ip,
4179 is_add=0)
4180
4181 def test_static_lb(self):
4182 """ NAT44 local service load balancing """
4183 external_addr_n = socket.inet_pton(socket.AF_INET, self.nat_addr)
4184 external_port = 80
4185 local_port = 8080
4186 server1 = self.pg0.remote_hosts[0]
4187 server2 = self.pg0.remote_hosts[1]
4188
4189 locals = [{'addr': server1.ip4n,
4190 'port': local_port,
Matus Fabianc6c0d2a2018-07-19 22:45:25 -07004191 'probability': 70,
4192 'vrf_id': 0},
Matus Fabiana6110b62018-06-13 05:39:07 -07004193 {'addr': server2.ip4n,
4194 'port': local_port,
Matus Fabianc6c0d2a2018-07-19 22:45:25 -07004195 'probability': 30,
4196 'vrf_id': 0}]
Matus Fabiana6110b62018-06-13 05:39:07 -07004197
4198 self.nat44_add_address(self.nat_addr)
4199 self.vapi.nat44_add_del_lb_static_mapping(external_addr_n,
4200 external_port,
4201 IP_PROTOS.tcp,
4202 local_num=len(locals),
4203 locals=locals)
4204 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
4205 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
4206 is_inside=0)
4207
4208 # from client to service
4209 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
4210 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
4211 TCP(sport=12345, dport=external_port))
4212 self.pg1.add_stream(p)
4213 self.pg_enable_capture(self.pg_interfaces)
4214 self.pg_start()
4215 capture = self.pg0.get_capture(1)
4216 p = capture[0]
4217 server = None
4218 try:
4219 ip = p[IP]
4220 tcp = p[TCP]
4221 self.assertIn(ip.dst, [server1.ip4, server2.ip4])
4222 if ip.dst == server1.ip4:
4223 server = server1
4224 else:
4225 server = server2
4226 self.assertEqual(tcp.dport, local_port)
4227 self.assert_packet_checksums_valid(p)
4228 except:
4229 self.logger.error(ppp("Unexpected or invalid packet:", p))
4230 raise
4231
4232 # from service back to client
4233 p = (Ether(src=server.mac, dst=self.pg0.local_mac) /
4234 IP(src=server.ip4, dst=self.pg1.remote_ip4) /
4235 TCP(sport=local_port, dport=12345))
4236 self.pg0.add_stream(p)
4237 self.pg_enable_capture(self.pg_interfaces)
4238 self.pg_start()
4239 capture = self.pg1.get_capture(1)
4240 p = capture[0]
4241 try:
4242 ip = p[IP]
4243 tcp = p[TCP]
4244 self.assertEqual(ip.src, self.nat_addr)
4245 self.assertEqual(tcp.sport, external_port)
4246 self.assert_packet_checksums_valid(p)
4247 except:
4248 self.logger.error(ppp("Unexpected or invalid packet:", p))
4249 raise
4250
4251 sessions = self.vapi.nat44_user_session_dump(server.ip4n, 0)
4252 self.assertEqual(len(sessions), 1)
4253 self.assertTrue(sessions[0].ext_host_valid)
4254 self.vapi.nat44_del_session(
4255 sessions[0].inside_ip_address,
4256 sessions[0].inside_port,
4257 sessions[0].protocol,
4258 ext_host_address=sessions[0].ext_host_address,
4259 ext_host_port=sessions[0].ext_host_port)
4260 sessions = self.vapi.nat44_user_session_dump(server.ip4n, 0)
4261 self.assertEqual(len(sessions), 0)
4262
4263 @unittest.skipUnless(running_extended_tests(), "part of extended tests")
4264 def test_static_lb_multi_clients(self):
4265 """ NAT44 local service load balancing - multiple clients"""
4266
4267 external_addr_n = socket.inet_pton(socket.AF_INET, self.nat_addr)
4268 external_port = 80
4269 local_port = 8080
4270 server1 = self.pg0.remote_hosts[0]
4271 server2 = self.pg0.remote_hosts[1]
4272
4273 locals = [{'addr': server1.ip4n,
4274 'port': local_port,
Matus Fabianc6c0d2a2018-07-19 22:45:25 -07004275 'probability': 90,
4276 'vrf_id': 0},
Matus Fabiana6110b62018-06-13 05:39:07 -07004277 {'addr': server2.ip4n,
4278 'port': local_port,
Matus Fabianc6c0d2a2018-07-19 22:45:25 -07004279 'probability': 10,
4280 'vrf_id': 0}]
Matus Fabiana6110b62018-06-13 05:39:07 -07004281
4282 self.nat44_add_address(self.nat_addr)
4283 self.vapi.nat44_add_del_lb_static_mapping(external_addr_n,
4284 external_port,
4285 IP_PROTOS.tcp,
4286 local_num=len(locals),
4287 locals=locals)
4288 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 server1_n = 0
4293 server2_n = 0
4294 clients = ip4_range(self.pg1.remote_ip4, 10, 50)
4295 pkts = []
4296 for client in clients:
4297 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
4298 IP(src=client, dst=self.nat_addr) /
4299 TCP(sport=12345, dport=external_port))
4300 pkts.append(p)
4301 self.pg1.add_stream(pkts)
4302 self.pg_enable_capture(self.pg_interfaces)
4303 self.pg_start()
4304 capture = self.pg0.get_capture(len(pkts))
4305 for p in capture:
4306 if p[IP].dst == server1.ip4:
4307 server1_n += 1
4308 else:
4309 server2_n += 1
Paul Vinciguerra3d2df212018-11-24 23:19:53 -08004310 self.assertGreater(server1_n, server2_n)
Matus Fabiana6110b62018-06-13 05:39:07 -07004311
4312 def test_static_lb_2(self):
4313 """ NAT44 local service load balancing (asymmetrical rule) """
4314 external_addr_n = socket.inet_pton(socket.AF_INET, self.nat_addr)
4315 external_port = 80
4316 local_port = 8080
4317 server1 = self.pg0.remote_hosts[0]
4318 server2 = self.pg0.remote_hosts[1]
4319
4320 locals = [{'addr': server1.ip4n,
4321 'port': local_port,
Matus Fabianc6c0d2a2018-07-19 22:45:25 -07004322 'probability': 70,
4323 'vrf_id': 0},
Matus Fabiana6110b62018-06-13 05:39:07 -07004324 {'addr': server2.ip4n,
4325 'port': local_port,
Matus Fabianc6c0d2a2018-07-19 22:45:25 -07004326 'probability': 30,
4327 'vrf_id': 0}]
Matus Fabiana6110b62018-06-13 05:39:07 -07004328
4329 self.vapi.nat44_forwarding_enable_disable(1)
4330 self.vapi.nat44_add_del_lb_static_mapping(external_addr_n,
4331 external_port,
4332 IP_PROTOS.tcp,
4333 out2in_only=1,
4334 local_num=len(locals),
4335 locals=locals)
4336 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
4337 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
4338 is_inside=0)
4339
4340 # from client to service
4341 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
4342 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
4343 TCP(sport=12345, dport=external_port))
4344 self.pg1.add_stream(p)
4345 self.pg_enable_capture(self.pg_interfaces)
4346 self.pg_start()
4347 capture = self.pg0.get_capture(1)
4348 p = capture[0]
4349 server = None
4350 try:
4351 ip = p[IP]
4352 tcp = p[TCP]
4353 self.assertIn(ip.dst, [server1.ip4, server2.ip4])
4354 if ip.dst == server1.ip4:
4355 server = server1
4356 else:
4357 server = server2
4358 self.assertEqual(tcp.dport, local_port)
4359 self.assert_packet_checksums_valid(p)
4360 except:
4361 self.logger.error(ppp("Unexpected or invalid packet:", p))
4362 raise
4363
4364 # from service back to client
4365 p = (Ether(src=server.mac, dst=self.pg0.local_mac) /
4366 IP(src=server.ip4, dst=self.pg1.remote_ip4) /
4367 TCP(sport=local_port, dport=12345))
4368 self.pg0.add_stream(p)
4369 self.pg_enable_capture(self.pg_interfaces)
4370 self.pg_start()
4371 capture = self.pg1.get_capture(1)
4372 p = capture[0]
4373 try:
4374 ip = p[IP]
4375 tcp = p[TCP]
4376 self.assertEqual(ip.src, self.nat_addr)
4377 self.assertEqual(tcp.sport, external_port)
4378 self.assert_packet_checksums_valid(p)
4379 except:
4380 self.logger.error(ppp("Unexpected or invalid packet:", p))
4381 raise
4382
4383 # from client to server (no translation)
4384 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
4385 IP(src=self.pg1.remote_ip4, dst=server1.ip4) /
4386 TCP(sport=12346, dport=local_port))
4387 self.pg1.add_stream(p)
4388 self.pg_enable_capture(self.pg_interfaces)
4389 self.pg_start()
4390 capture = self.pg0.get_capture(1)
4391 p = capture[0]
4392 server = None
4393 try:
4394 ip = p[IP]
4395 tcp = p[TCP]
4396 self.assertEqual(ip.dst, server1.ip4)
4397 self.assertEqual(tcp.dport, local_port)
4398 self.assert_packet_checksums_valid(p)
4399 except:
4400 self.logger.error(ppp("Unexpected or invalid packet:", p))
4401 raise
4402
4403 # from service back to client (no translation)
4404 p = (Ether(src=server1.mac, dst=self.pg0.local_mac) /
4405 IP(src=server1.ip4, dst=self.pg1.remote_ip4) /
4406 TCP(sport=local_port, dport=12346))
4407 self.pg0.add_stream(p)
4408 self.pg_enable_capture(self.pg_interfaces)
4409 self.pg_start()
4410 capture = self.pg1.get_capture(1)
4411 p = capture[0]
4412 try:
4413 ip = p[IP]
4414 tcp = p[TCP]
4415 self.assertEqual(ip.src, server1.ip4)
4416 self.assertEqual(tcp.sport, local_port)
4417 self.assert_packet_checksums_valid(p)
4418 except:
4419 self.logger.error(ppp("Unexpected or invalid packet:", p))
4420 raise
4421
Matus Fabianea5b5be2018-09-03 05:02:23 -07004422 def test_lb_affinity(self):
4423 """ NAT44 local service load balancing affinity """
4424 external_addr_n = socket.inet_pton(socket.AF_INET, self.nat_addr)
4425 external_port = 80
4426 local_port = 8080
4427 server1 = self.pg0.remote_hosts[0]
4428 server2 = self.pg0.remote_hosts[1]
4429
4430 locals = [{'addr': server1.ip4n,
4431 'port': local_port,
4432 'probability': 50,
4433 'vrf_id': 0},
4434 {'addr': server2.ip4n,
4435 'port': local_port,
4436 'probability': 50,
4437 'vrf_id': 0}]
4438
4439 self.nat44_add_address(self.nat_addr)
4440 self.vapi.nat44_add_del_lb_static_mapping(external_addr_n,
4441 external_port,
4442 IP_PROTOS.tcp,
4443 affinity=10800,
4444 local_num=len(locals),
4445 locals=locals)
4446 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
4447 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
4448 is_inside=0)
4449
4450 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
4451 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
4452 TCP(sport=1025, dport=external_port))
4453 self.pg1.add_stream(p)
4454 self.pg_enable_capture(self.pg_interfaces)
4455 self.pg_start()
4456 capture = self.pg0.get_capture(1)
4457 backend = capture[0][IP].dst
4458
4459 sessions = self.vapi.nat44_user_session_dump(
4460 socket.inet_pton(socket.AF_INET, backend), 0)
4461 self.assertEqual(len(sessions), 1)
4462 self.assertTrue(sessions[0].ext_host_valid)
4463 self.vapi.nat44_del_session(
4464 sessions[0].inside_ip_address,
4465 sessions[0].inside_port,
4466 sessions[0].protocol,
4467 ext_host_address=sessions[0].ext_host_address,
4468 ext_host_port=sessions[0].ext_host_port)
4469
4470 pkts = []
4471 for port in range(1030, 1100):
4472 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
4473 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
4474 TCP(sport=port, dport=external_port))
4475 pkts.append(p)
4476 self.pg1.add_stream(pkts)
4477 self.pg_enable_capture(self.pg_interfaces)
4478 self.pg_start()
4479 capture = self.pg0.get_capture(len(pkts))
4480 for p in capture:
4481 self.assertEqual(p[IP].dst, backend)
4482
Matus Fabiana6110b62018-06-13 05:39:07 -07004483 def test_unknown_proto(self):
4484 """ NAT44 translate packet with unknown protocol """
4485 self.nat44_add_address(self.nat_addr)
4486 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
4487 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
4488 is_inside=0)
4489
4490 # in2out
4491 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
4492 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
4493 TCP(sport=self.tcp_port_in, dport=20))
4494 self.pg0.add_stream(p)
4495 self.pg_enable_capture(self.pg_interfaces)
4496 self.pg_start()
4497 p = self.pg1.get_capture(1)
4498
4499 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
4500 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
4501 GRE() /
4502 IP(src=self.pg2.remote_ip4, dst=self.pg2.remote_ip4) /
4503 TCP(sport=1234, dport=1234))
4504 self.pg0.add_stream(p)
4505 self.pg_enable_capture(self.pg_interfaces)
4506 self.pg_start()
4507 p = self.pg1.get_capture(1)
4508 packet = p[0]
4509 try:
4510 self.assertEqual(packet[IP].src, self.nat_addr)
4511 self.assertEqual(packet[IP].dst, self.pg1.remote_ip4)
Paul Vinciguerra978aa642018-11-24 22:19:12 -08004512 self.assertEqual(packet.haslayer(GRE), 1)
Matus Fabiana6110b62018-06-13 05:39:07 -07004513 self.assert_packet_checksums_valid(packet)
4514 except:
4515 self.logger.error(ppp("Unexpected or invalid packet:", packet))
4516 raise
4517
4518 # out2in
4519 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
4520 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
4521 GRE() /
4522 IP(src=self.pg2.remote_ip4, dst=self.pg2.remote_ip4) /
4523 TCP(sport=1234, dport=1234))
4524 self.pg1.add_stream(p)
4525 self.pg_enable_capture(self.pg_interfaces)
4526 self.pg_start()
4527 p = self.pg0.get_capture(1)
4528 packet = p[0]
4529 try:
4530 self.assertEqual(packet[IP].src, self.pg1.remote_ip4)
4531 self.assertEqual(packet[IP].dst, self.pg0.remote_ip4)
Paul Vinciguerra978aa642018-11-24 22:19:12 -08004532 self.assertEqual(packet.haslayer(GRE), 1)
Matus Fabiana6110b62018-06-13 05:39:07 -07004533 self.assert_packet_checksums_valid(packet)
4534 except:
4535 self.logger.error(ppp("Unexpected or invalid packet:", packet))
4536 raise
4537
4538 def test_hairpinning_unknown_proto(self):
4539 """ NAT44 translate packet with unknown protocol - hairpinning """
4540 host = self.pg0.remote_hosts[0]
4541 server = self.pg0.remote_hosts[1]
4542 host_in_port = 1234
4543 server_out_port = 8765
4544 server_nat_ip = "10.0.0.11"
4545
4546 self.nat44_add_address(self.nat_addr)
4547 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
4548 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
4549 is_inside=0)
4550
4551 # add static mapping for server
4552 self.nat44_add_static_mapping(server.ip4, server_nat_ip)
4553
4554 # host to server
4555 p = (Ether(src=host.mac, dst=self.pg0.local_mac) /
4556 IP(src=host.ip4, dst=server_nat_ip) /
4557 TCP(sport=host_in_port, dport=server_out_port))
4558 self.pg0.add_stream(p)
4559 self.pg_enable_capture(self.pg_interfaces)
4560 self.pg_start()
4561 self.pg0.get_capture(1)
4562
4563 p = (Ether(dst=self.pg0.local_mac, src=host.mac) /
4564 IP(src=host.ip4, dst=server_nat_ip) /
4565 GRE() /
4566 IP(src=self.pg2.remote_ip4, dst=self.pg2.remote_ip4) /
4567 TCP(sport=1234, dport=1234))
4568 self.pg0.add_stream(p)
4569 self.pg_enable_capture(self.pg_interfaces)
4570 self.pg_start()
4571 p = self.pg0.get_capture(1)
4572 packet = p[0]
4573 try:
4574 self.assertEqual(packet[IP].src, self.nat_addr)
4575 self.assertEqual(packet[IP].dst, server.ip4)
Paul Vinciguerra978aa642018-11-24 22:19:12 -08004576 self.assertEqual(packet.haslayer(GRE), 1)
Matus Fabiana6110b62018-06-13 05:39:07 -07004577 self.assert_packet_checksums_valid(packet)
4578 except:
4579 self.logger.error(ppp("Unexpected or invalid packet:", packet))
4580 raise
4581
4582 # server to host
4583 p = (Ether(dst=self.pg0.local_mac, src=server.mac) /
4584 IP(src=server.ip4, dst=self.nat_addr) /
4585 GRE() /
4586 IP(src=self.pg2.remote_ip4, dst=self.pg2.remote_ip4) /
4587 TCP(sport=1234, dport=1234))
4588 self.pg0.add_stream(p)
4589 self.pg_enable_capture(self.pg_interfaces)
4590 self.pg_start()
4591 p = self.pg0.get_capture(1)
4592 packet = p[0]
4593 try:
4594 self.assertEqual(packet[IP].src, server_nat_ip)
4595 self.assertEqual(packet[IP].dst, host.ip4)
Paul Vinciguerra978aa642018-11-24 22:19:12 -08004596 self.assertEqual(packet.haslayer(GRE), 1)
Matus Fabiana6110b62018-06-13 05:39:07 -07004597 self.assert_packet_checksums_valid(packet)
4598 except:
4599 self.logger.error(ppp("Unexpected or invalid packet:", packet))
4600 raise
4601
4602 def test_output_feature_and_service(self):
4603 """ NAT44 interface output feature and services """
4604 external_addr = '1.2.3.4'
4605 external_port = 80
4606 local_port = 8080
4607
4608 self.vapi.nat44_forwarding_enable_disable(1)
4609 self.nat44_add_address(self.nat_addr)
4610 self.vapi.nat44_add_del_identity_mapping(ip=self.pg1.remote_ip4n)
4611 self.nat44_add_static_mapping(self.pg0.remote_ip4, external_addr,
4612 local_port, external_port,
4613 proto=IP_PROTOS.tcp, out2in_only=1)
4614 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
4615 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index,
4616 is_inside=0)
4617 self.vapi.nat44_interface_add_del_output_feature(self.pg1.sw_if_index,
4618 is_inside=0)
4619
4620 # from client to service
4621 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
4622 IP(src=self.pg1.remote_ip4, dst=external_addr) /
4623 TCP(sport=12345, dport=external_port))
4624 self.pg1.add_stream(p)
4625 self.pg_enable_capture(self.pg_interfaces)
4626 self.pg_start()
4627 capture = self.pg0.get_capture(1)
4628 p = capture[0]
4629 try:
4630 ip = p[IP]
4631 tcp = p[TCP]
4632 self.assertEqual(ip.dst, self.pg0.remote_ip4)
4633 self.assertEqual(tcp.dport, local_port)
4634 self.assert_packet_checksums_valid(p)
4635 except:
4636 self.logger.error(ppp("Unexpected or invalid packet:", p))
4637 raise
4638
4639 # from service back to client
4640 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
4641 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
4642 TCP(sport=local_port, dport=12345))
4643 self.pg0.add_stream(p)
4644 self.pg_enable_capture(self.pg_interfaces)
4645 self.pg_start()
4646 capture = self.pg1.get_capture(1)
4647 p = capture[0]
4648 try:
4649 ip = p[IP]
4650 tcp = p[TCP]
4651 self.assertEqual(ip.src, external_addr)
4652 self.assertEqual(tcp.sport, external_port)
4653 self.assert_packet_checksums_valid(p)
4654 except:
4655 self.logger.error(ppp("Unexpected or invalid packet:", p))
4656 raise
4657
4658 # from local network host to external network
4659 pkts = self.create_stream_in(self.pg0, self.pg1)
4660 self.pg0.add_stream(pkts)
4661 self.pg_enable_capture(self.pg_interfaces)
4662 self.pg_start()
4663 capture = self.pg1.get_capture(len(pkts))
4664 self.verify_capture_out(capture)
4665 pkts = self.create_stream_in(self.pg0, self.pg1)
4666 self.pg0.add_stream(pkts)
4667 self.pg_enable_capture(self.pg_interfaces)
4668 self.pg_start()
4669 capture = self.pg1.get_capture(len(pkts))
4670 self.verify_capture_out(capture)
4671
4672 # from external network back to local network host
4673 pkts = self.create_stream_out(self.pg1)
4674 self.pg1.add_stream(pkts)
4675 self.pg_enable_capture(self.pg_interfaces)
4676 self.pg_start()
4677 capture = self.pg0.get_capture(len(pkts))
4678 self.verify_capture_in(capture, self.pg0)
4679
4680 def test_output_feature_and_service2(self):
4681 """ NAT44 interface output feature and service host direct access """
4682 self.vapi.nat44_forwarding_enable_disable(1)
4683 self.nat44_add_address(self.nat_addr)
4684 self.vapi.nat44_interface_add_del_output_feature(self.pg1.sw_if_index,
4685 is_inside=0)
4686
4687 # session initiaded from service host - translate
4688 pkts = self.create_stream_in(self.pg0, self.pg1)
4689 self.pg0.add_stream(pkts)
4690 self.pg_enable_capture(self.pg_interfaces)
4691 self.pg_start()
4692 capture = self.pg1.get_capture(len(pkts))
4693 self.verify_capture_out(capture)
4694
4695 pkts = self.create_stream_out(self.pg1)
4696 self.pg1.add_stream(pkts)
4697 self.pg_enable_capture(self.pg_interfaces)
4698 self.pg_start()
4699 capture = self.pg0.get_capture(len(pkts))
4700 self.verify_capture_in(capture, self.pg0)
4701
4702 # session initiaded from remote host - do not translate
4703 self.tcp_port_in = 60303
4704 self.udp_port_in = 60304
4705 self.icmp_id_in = 60305
4706 pkts = self.create_stream_out(self.pg1,
4707 self.pg0.remote_ip4,
4708 use_inside_ports=True)
4709 self.pg1.add_stream(pkts)
4710 self.pg_enable_capture(self.pg_interfaces)
4711 self.pg_start()
4712 capture = self.pg0.get_capture(len(pkts))
4713 self.verify_capture_in(capture, self.pg0)
4714
4715 pkts = self.create_stream_in(self.pg0, self.pg1)
4716 self.pg0.add_stream(pkts)
4717 self.pg_enable_capture(self.pg_interfaces)
4718 self.pg_start()
4719 capture = self.pg1.get_capture(len(pkts))
4720 self.verify_capture_out(capture, nat_ip=self.pg0.remote_ip4,
4721 same_port=True)
4722
4723 def test_output_feature_and_service3(self):
4724 """ NAT44 interface output feature and DST NAT """
4725 external_addr = '1.2.3.4'
4726 external_port = 80
4727 local_port = 8080
4728
4729 self.vapi.nat44_forwarding_enable_disable(1)
4730 self.nat44_add_address(self.nat_addr)
4731 self.nat44_add_static_mapping(self.pg1.remote_ip4, external_addr,
4732 local_port, external_port,
4733 proto=IP_PROTOS.tcp, out2in_only=1)
4734 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
4735 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index,
4736 is_inside=0)
4737 self.vapi.nat44_interface_add_del_output_feature(self.pg1.sw_if_index,
4738 is_inside=0)
4739
4740 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
4741 IP(src=self.pg0.remote_ip4, dst=external_addr) /
4742 TCP(sport=12345, dport=external_port))
4743 self.pg0.add_stream(p)
4744 self.pg_enable_capture(self.pg_interfaces)
4745 self.pg_start()
4746 capture = self.pg1.get_capture(1)
4747 p = capture[0]
4748 try:
4749 ip = p[IP]
4750 tcp = p[TCP]
4751 self.assertEqual(ip.src, self.pg0.remote_ip4)
4752 self.assertEqual(tcp.sport, 12345)
4753 self.assertEqual(ip.dst, self.pg1.remote_ip4)
4754 self.assertEqual(tcp.dport, local_port)
4755 self.assert_packet_checksums_valid(p)
4756 except:
4757 self.logger.error(ppp("Unexpected or invalid packet:", p))
4758 raise
4759
4760 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
4761 IP(src=self.pg1.remote_ip4, dst=self.pg0.remote_ip4) /
4762 TCP(sport=local_port, dport=12345))
4763 self.pg1.add_stream(p)
4764 self.pg_enable_capture(self.pg_interfaces)
4765 self.pg_start()
4766 capture = self.pg0.get_capture(1)
4767 p = capture[0]
4768 try:
4769 ip = p[IP]
4770 tcp = p[TCP]
4771 self.assertEqual(ip.src, external_addr)
4772 self.assertEqual(tcp.sport, external_port)
4773 self.assertEqual(ip.dst, self.pg0.remote_ip4)
4774 self.assertEqual(tcp.dport, 12345)
4775 self.assert_packet_checksums_valid(p)
4776 except:
4777 self.logger.error(ppp("Unexpected or invalid packet:", p))
4778 raise
4779
Matus Fabian182e37e2018-08-14 04:21:26 -07004780 def test_next_src_nat(self):
4781 """ On way back forward packet to nat44-in2out node. """
4782 twice_nat_addr = '10.0.1.3'
4783 external_port = 80
4784 local_port = 8080
4785 post_twice_nat_port = 0
4786
4787 self.vapi.nat44_forwarding_enable_disable(1)
4788 self.nat44_add_address(twice_nat_addr, twice_nat=1)
4789 self.nat44_add_static_mapping(self.pg6.remote_ip4, self.pg1.remote_ip4,
4790 local_port, external_port,
4791 proto=IP_PROTOS.tcp, out2in_only=1,
4792 self_twice_nat=1, vrf_id=1)
4793 self.vapi.nat44_interface_add_del_feature(self.pg6.sw_if_index,
4794 is_inside=0)
4795
4796 p = (Ether(src=self.pg6.remote_mac, dst=self.pg6.local_mac) /
4797 IP(src=self.pg6.remote_ip4, dst=self.pg1.remote_ip4) /
4798 TCP(sport=12345, dport=external_port))
4799 self.pg6.add_stream(p)
4800 self.pg_enable_capture(self.pg_interfaces)
4801 self.pg_start()
4802 capture = self.pg6.get_capture(1)
4803 p = capture[0]
4804 try:
4805 ip = p[IP]
4806 tcp = p[TCP]
4807 self.assertEqual(ip.src, twice_nat_addr)
4808 self.assertNotEqual(tcp.sport, 12345)
4809 post_twice_nat_port = tcp.sport
4810 self.assertEqual(ip.dst, self.pg6.remote_ip4)
4811 self.assertEqual(tcp.dport, local_port)
4812 self.assert_packet_checksums_valid(p)
4813 except:
4814 self.logger.error(ppp("Unexpected or invalid packet:", p))
4815 raise
4816
4817 p = (Ether(src=self.pg6.remote_mac, dst=self.pg6.local_mac) /
4818 IP(src=self.pg6.remote_ip4, dst=twice_nat_addr) /
4819 TCP(sport=local_port, dport=post_twice_nat_port))
4820 self.pg6.add_stream(p)
4821 self.pg_enable_capture(self.pg_interfaces)
4822 self.pg_start()
4823 capture = self.pg6.get_capture(1)
4824 p = capture[0]
4825 try:
4826 ip = p[IP]
4827 tcp = p[TCP]
4828 self.assertEqual(ip.src, self.pg1.remote_ip4)
4829 self.assertEqual(tcp.sport, external_port)
4830 self.assertEqual(ip.dst, self.pg6.remote_ip4)
4831 self.assertEqual(tcp.dport, 12345)
4832 self.assert_packet_checksums_valid(p)
4833 except:
4834 self.logger.error(ppp("Unexpected or invalid packet:", p))
4835 raise
4836
Juraj Sloboda1e5c07d2018-04-10 13:51:54 +02004837 def twice_nat_common(self, self_twice_nat=False, same_pg=False, lb=False,
4838 client_id=None):
Matus Fabianb932d262017-12-18 05:38:24 -08004839 twice_nat_addr = '10.0.1.3'
Juraj Sloboda1e5c07d2018-04-10 13:51:54 +02004840
Matus Fabianb932d262017-12-18 05:38:24 -08004841 port_in = 8080
Juraj Sloboda1e5c07d2018-04-10 13:51:54 +02004842 if lb:
4843 if not same_pg:
4844 port_in1 = port_in
4845 port_in2 = port_in
4846 else:
4847 port_in1 = port_in+1
4848 port_in2 = port_in+2
4849
Matus Fabianb932d262017-12-18 05:38:24 -08004850 port_out = 80
4851 eh_port_out = 4567
Juraj Sloboda1e5c07d2018-04-10 13:51:54 +02004852
4853 server1 = self.pg0.remote_hosts[0]
4854 server2 = self.pg0.remote_hosts[1]
4855 if lb and same_pg:
4856 server2 = server1
4857 if not lb:
4858 server = server1
4859
4860 pg0 = self.pg0
4861 if same_pg:
4862 pg1 = self.pg0
4863 else:
4864 pg1 = self.pg1
4865
4866 eh_translate = ((not self_twice_nat) or (not lb and same_pg) or
4867 client_id == 1)
4868
Matus Fabianb932d262017-12-18 05:38:24 -08004869 self.nat44_add_address(self.nat_addr)
4870 self.nat44_add_address(twice_nat_addr, twice_nat=1)
Juraj Sloboda1e5c07d2018-04-10 13:51:54 +02004871 if not lb:
4872 self.nat44_add_static_mapping(pg0.remote_ip4, self.nat_addr,
4873 port_in, port_out,
4874 proto=IP_PROTOS.tcp,
4875 twice_nat=int(not self_twice_nat),
4876 self_twice_nat=int(self_twice_nat))
4877 else:
4878 locals = [{'addr': server1.ip4n,
4879 'port': port_in1,
Matus Fabianc6c0d2a2018-07-19 22:45:25 -07004880 'probability': 50,
4881 'vrf_id': 0},
Juraj Sloboda1e5c07d2018-04-10 13:51:54 +02004882 {'addr': server2.ip4n,
4883 'port': port_in2,
Matus Fabianc6c0d2a2018-07-19 22:45:25 -07004884 'probability': 50,
4885 'vrf_id': 0}]
Juraj Sloboda1e5c07d2018-04-10 13:51:54 +02004886 out_addr_n = socket.inet_pton(socket.AF_INET, self.nat_addr)
4887 self.vapi.nat44_add_del_lb_static_mapping(out_addr_n,
4888 port_out,
4889 IP_PROTOS.tcp,
4890 twice_nat=int(
4891 not self_twice_nat),
4892 self_twice_nat=int(
4893 self_twice_nat),
4894 local_num=len(locals),
4895 locals=locals)
4896 self.vapi.nat44_interface_add_del_feature(pg0.sw_if_index)
4897 self.vapi.nat44_interface_add_del_feature(pg1.sw_if_index,
Matus Fabianb932d262017-12-18 05:38:24 -08004898 is_inside=0)
4899
Juraj Sloboda1e5c07d2018-04-10 13:51:54 +02004900 if same_pg:
4901 if not lb:
4902 client = server
4903 else:
4904 assert client_id is not None
4905 if client_id == 1:
4906 client = self.pg0.remote_hosts[0]
4907 elif client_id == 2:
4908 client = self.pg0.remote_hosts[1]
4909 else:
4910 client = pg1.remote_hosts[0]
4911 p = (Ether(src=pg1.remote_mac, dst=pg1.local_mac) /
4912 IP(src=client.ip4, dst=self.nat_addr) /
Matus Fabianb932d262017-12-18 05:38:24 -08004913 TCP(sport=eh_port_out, dport=port_out))
Juraj Sloboda1e5c07d2018-04-10 13:51:54 +02004914 pg1.add_stream(p)
Matus Fabianb932d262017-12-18 05:38:24 -08004915 self.pg_enable_capture(self.pg_interfaces)
4916 self.pg_start()
Juraj Sloboda1e5c07d2018-04-10 13:51:54 +02004917 capture = pg0.get_capture(1)
Matus Fabianb932d262017-12-18 05:38:24 -08004918 p = capture[0]
4919 try:
4920 ip = p[IP]
4921 tcp = p[TCP]
Juraj Sloboda1e5c07d2018-04-10 13:51:54 +02004922 if lb:
4923 if ip.dst == server1.ip4:
4924 server = server1
4925 port_in = port_in1
4926 else:
4927 server = server2
4928 port_in = port_in2
4929 self.assertEqual(ip.dst, server.ip4)
4930 if lb and same_pg:
4931 self.assertIn(tcp.dport, [port_in1, port_in2])
4932 else:
4933 self.assertEqual(tcp.dport, port_in)
4934 if eh_translate:
4935 self.assertEqual(ip.src, twice_nat_addr)
4936 self.assertNotEqual(tcp.sport, eh_port_out)
4937 else:
4938 self.assertEqual(ip.src, client.ip4)
4939 self.assertEqual(tcp.sport, eh_port_out)
4940 eh_addr_in = ip.src
Matus Fabianb932d262017-12-18 05:38:24 -08004941 eh_port_in = tcp.sport
Juraj Sloboda1e5c07d2018-04-10 13:51:54 +02004942 saved_port_in = tcp.dport
Klement Sekerad81ae412018-05-16 10:52:54 +02004943 self.assert_packet_checksums_valid(p)
Matus Fabianb932d262017-12-18 05:38:24 -08004944 except:
4945 self.logger.error(ppp("Unexpected or invalid packet:", p))
4946 raise
4947
Juraj Sloboda1e5c07d2018-04-10 13:51:54 +02004948 p = (Ether(src=server.mac, dst=pg0.local_mac) /
4949 IP(src=server.ip4, dst=eh_addr_in) /
4950 TCP(sport=saved_port_in, dport=eh_port_in))
4951 pg0.add_stream(p)
Matus Fabianb932d262017-12-18 05:38:24 -08004952 self.pg_enable_capture(self.pg_interfaces)
4953 self.pg_start()
Juraj Sloboda1e5c07d2018-04-10 13:51:54 +02004954 capture = pg1.get_capture(1)
Matus Fabianb932d262017-12-18 05:38:24 -08004955 p = capture[0]
4956 try:
4957 ip = p[IP]
4958 tcp = p[TCP]
Juraj Sloboda1e5c07d2018-04-10 13:51:54 +02004959 self.assertEqual(ip.dst, client.ip4)
Matus Fabianb932d262017-12-18 05:38:24 -08004960 self.assertEqual(ip.src, self.nat_addr)
4961 self.assertEqual(tcp.dport, eh_port_out)
4962 self.assertEqual(tcp.sport, port_out)
Klement Sekerad81ae412018-05-16 10:52:54 +02004963 self.assert_packet_checksums_valid(p)
Matus Fabianb932d262017-12-18 05:38:24 -08004964 except:
4965 self.logger.error(ppp("Unexpected or invalid packet:", p))
4966 raise
4967
Matus Fabian70a26ac2018-05-14 06:20:28 -07004968 if eh_translate:
4969 sessions = self.vapi.nat44_user_session_dump(server.ip4n, 0)
4970 self.assertEqual(len(sessions), 1)
4971 self.assertTrue(sessions[0].ext_host_valid)
4972 self.assertTrue(sessions[0].is_twicenat)
4973 self.vapi.nat44_del_session(
4974 sessions[0].inside_ip_address,
4975 sessions[0].inside_port,
4976 sessions[0].protocol,
4977 ext_host_address=sessions[0].ext_host_nat_address,
4978 ext_host_port=sessions[0].ext_host_nat_port)
4979 sessions = self.vapi.nat44_user_session_dump(server.ip4n, 0)
4980 self.assertEqual(len(sessions), 0)
4981
Juraj Sloboda1e5c07d2018-04-10 13:51:54 +02004982 def test_twice_nat(self):
4983 """ Twice NAT44 """
4984 self.twice_nat_common()
4985
4986 def test_self_twice_nat_positive(self):
4987 """ Self Twice NAT44 (positive test) """
4988 self.twice_nat_common(self_twice_nat=True, same_pg=True)
4989
4990 def test_self_twice_nat_negative(self):
4991 """ Self Twice NAT44 (negative test) """
4992 self.twice_nat_common(self_twice_nat=True)
4993
Matus Fabianb932d262017-12-18 05:38:24 -08004994 def test_twice_nat_lb(self):
4995 """ Twice NAT44 local service load balancing """
Juraj Sloboda1e5c07d2018-04-10 13:51:54 +02004996 self.twice_nat_common(lb=True)
Matus Fabianb932d262017-12-18 05:38:24 -08004997
Juraj Sloboda1e5c07d2018-04-10 13:51:54 +02004998 def test_self_twice_nat_lb_positive(self):
4999 """ Self Twice NAT44 local service load balancing (positive test) """
5000 self.twice_nat_common(lb=True, self_twice_nat=True, same_pg=True,
5001 client_id=1)
Matus Fabianb932d262017-12-18 05:38:24 -08005002
Juraj Sloboda1e5c07d2018-04-10 13:51:54 +02005003 def test_self_twice_nat_lb_negative(self):
5004 """ Self Twice NAT44 local service load balancing (negative test) """
5005 self.twice_nat_common(lb=True, self_twice_nat=True, same_pg=True,
5006 client_id=2)
Matus Fabianb932d262017-12-18 05:38:24 -08005007
5008 def test_twice_nat_interface_addr(self):
5009 """ Acquire twice NAT44 addresses from interface """
Matus Fabiana6110b62018-06-13 05:39:07 -07005010 self.vapi.nat44_add_interface_addr(self.pg3.sw_if_index, twice_nat=1)
Matus Fabianb932d262017-12-18 05:38:24 -08005011
5012 # no address in NAT pool
5013 adresses = self.vapi.nat44_address_dump()
5014 self.assertEqual(0, len(adresses))
5015
5016 # configure interface address and check NAT address pool
Matus Fabiana6110b62018-06-13 05:39:07 -07005017 self.pg3.config_ip4()
Matus Fabianb932d262017-12-18 05:38:24 -08005018 adresses = self.vapi.nat44_address_dump()
5019 self.assertEqual(1, len(adresses))
Matus Fabiana6110b62018-06-13 05:39:07 -07005020 self.assertEqual(adresses[0].ip_address[0:4], self.pg3.local_ip4n)
Matus Fabianb932d262017-12-18 05:38:24 -08005021 self.assertEqual(adresses[0].twice_nat, 1)
5022
5023 # remove interface address and check NAT address pool
Matus Fabiana6110b62018-06-13 05:39:07 -07005024 self.pg3.unconfig_ip4()
Matus Fabianb932d262017-12-18 05:38:24 -08005025 adresses = self.vapi.nat44_address_dump()
5026 self.assertEqual(0, len(adresses))
5027
Matus Fabian6c01dce2018-11-16 04:41:31 -08005028 def test_tcp_close(self):
5029 """ Close TCP session from inside network - output feature """
5030 self.vapi.nat44_forwarding_enable_disable(1)
5031 self.nat44_add_address(self.pg1.local_ip4)
5032 twice_nat_addr = '10.0.1.3'
5033 service_ip = '192.168.16.150'
5034 self.nat44_add_address(twice_nat_addr, twice_nat=1)
5035 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
5036 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index,
5037 is_inside=0)
5038 self.vapi.nat44_interface_add_del_output_feature(self.pg1.sw_if_index,
5039 is_inside=0)
5040 self.nat44_add_static_mapping(self.pg0.remote_ip4,
5041 service_ip,
5042 80,
5043 80,
5044 proto=IP_PROTOS.tcp,
5045 out2in_only=1,
5046 twice_nat=1)
5047 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n, 0)
5048 start_sessnum = len(sessions)
5049
5050 # SYN packet out->in
5051 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5052 IP(src=self.pg1.remote_ip4, dst=service_ip) /
5053 TCP(sport=33898, dport=80, flags="S"))
5054 self.pg1.add_stream(p)
5055 self.pg_enable_capture(self.pg_interfaces)
5056 self.pg_start()
5057 capture = self.pg0.get_capture(1)
5058 p = capture[0]
5059 tcp_port = p[TCP].sport
5060
5061 # SYN + ACK packet in->out
5062 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5063 IP(src=self.pg0.remote_ip4, dst=twice_nat_addr) /
5064 TCP(sport=80, dport=tcp_port, flags="SA"))
5065 self.pg0.add_stream(p)
5066 self.pg_enable_capture(self.pg_interfaces)
5067 self.pg_start()
5068 self.pg1.get_capture(1)
5069
5070 # ACK packet out->in
5071 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5072 IP(src=self.pg1.remote_ip4, dst=service_ip) /
5073 TCP(sport=33898, dport=80, flags="A"))
5074 self.pg1.add_stream(p)
5075 self.pg_enable_capture(self.pg_interfaces)
5076 self.pg_start()
5077 self.pg0.get_capture(1)
5078
5079 # FIN packet in -> out
5080 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5081 IP(src=self.pg0.remote_ip4, dst=twice_nat_addr) /
5082 TCP(sport=80, dport=tcp_port, flags="FA", seq=100, ack=300))
5083 self.pg0.add_stream(p)
5084 self.pg_enable_capture(self.pg_interfaces)
5085 self.pg_start()
5086 self.pg1.get_capture(1)
5087
5088 # FIN+ACK packet out -> in
5089 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5090 IP(src=self.pg1.remote_ip4, dst=service_ip) /
5091 TCP(sport=33898, dport=80, flags="FA", seq=300, ack=101))
5092 self.pg1.add_stream(p)
5093 self.pg_enable_capture(self.pg_interfaces)
5094 self.pg_start()
5095 self.pg0.get_capture(1)
5096
5097 # ACK packet in -> out
5098 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5099 IP(src=self.pg0.remote_ip4, dst=twice_nat_addr) /
5100 TCP(sport=80, dport=tcp_port, flags="A", seq=101, ack=301))
5101 self.pg0.add_stream(p)
5102 self.pg_enable_capture(self.pg_interfaces)
5103 self.pg_start()
5104 self.pg1.get_capture(1)
5105
5106 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n,
5107 0)
5108 self.assertEqual(len(sessions) - start_sessnum, 0)
5109
Matus Fabianebdf1902018-05-04 03:57:42 -07005110 def test_tcp_session_close_in(self):
5111 """ Close TCP session from inside network """
Matus Fabian229c1aa2018-05-28 04:09:52 -07005112 self.tcp_port_out = 10505
Matus Fabianebdf1902018-05-04 03:57:42 -07005113 self.nat44_add_address(self.nat_addr)
Matus Fabian229c1aa2018-05-28 04:09:52 -07005114 self.nat44_add_static_mapping(self.pg0.remote_ip4,
5115 self.nat_addr,
5116 self.tcp_port_in,
5117 self.tcp_port_out,
5118 proto=IP_PROTOS.tcp,
5119 twice_nat=1)
Matus Fabianebdf1902018-05-04 03:57:42 -07005120 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
5121 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
5122 is_inside=0)
5123
5124 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n, 0)
5125 start_sessnum = len(sessions)
5126
5127 self.initiate_tcp_session(self.pg0, self.pg1)
5128
Matus Fabian229c1aa2018-05-28 04:09:52 -07005129 # FIN packet in -> out
5130 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5131 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5132 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
5133 flags="FA", seq=100, ack=300))
5134 self.pg0.add_stream(p)
5135 self.pg_enable_capture(self.pg_interfaces)
5136 self.pg_start()
5137 self.pg1.get_capture(1)
Matus Fabianebdf1902018-05-04 03:57:42 -07005138
Matus Fabian229c1aa2018-05-28 04:09:52 -07005139 pkts = []
Matus Fabianebdf1902018-05-04 03:57:42 -07005140
Matus Fabian229c1aa2018-05-28 04:09:52 -07005141 # ACK packet out -> in
5142 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5143 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5144 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
5145 flags="A", seq=300, ack=101))
5146 pkts.append(p)
Matus Fabianebdf1902018-05-04 03:57:42 -07005147
Matus Fabian229c1aa2018-05-28 04:09:52 -07005148 # FIN packet out -> in
5149 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5150 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5151 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
5152 flags="FA", seq=300, ack=101))
5153 pkts.append(p)
Matus Fabianebdf1902018-05-04 03:57:42 -07005154
Matus Fabian229c1aa2018-05-28 04:09:52 -07005155 self.pg1.add_stream(pkts)
5156 self.pg_enable_capture(self.pg_interfaces)
5157 self.pg_start()
5158 self.pg0.get_capture(2)
Matus Fabianebdf1902018-05-04 03:57:42 -07005159
Matus Fabian229c1aa2018-05-28 04:09:52 -07005160 # ACK packet in -> out
5161 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5162 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5163 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
5164 flags="A", seq=101, ack=301))
5165 self.pg0.add_stream(p)
5166 self.pg_enable_capture(self.pg_interfaces)
5167 self.pg_start()
5168 self.pg1.get_capture(1)
Matus Fabianebdf1902018-05-04 03:57:42 -07005169
Matus Fabian229c1aa2018-05-28 04:09:52 -07005170 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n,
5171 0)
5172 self.assertEqual(len(sessions) - start_sessnum, 0)
Matus Fabianebdf1902018-05-04 03:57:42 -07005173
5174 def test_tcp_session_close_out(self):
5175 """ Close TCP session from outside network """
Matus Fabian229c1aa2018-05-28 04:09:52 -07005176 self.tcp_port_out = 10505
Matus Fabianebdf1902018-05-04 03:57:42 -07005177 self.nat44_add_address(self.nat_addr)
Matus Fabian229c1aa2018-05-28 04:09:52 -07005178 self.nat44_add_static_mapping(self.pg0.remote_ip4,
5179 self.nat_addr,
5180 self.tcp_port_in,
5181 self.tcp_port_out,
5182 proto=IP_PROTOS.tcp,
5183 twice_nat=1)
Matus Fabianebdf1902018-05-04 03:57:42 -07005184 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
5185 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
5186 is_inside=0)
5187
5188 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n, 0)
5189 start_sessnum = len(sessions)
5190
5191 self.initiate_tcp_session(self.pg0, self.pg1)
5192
Matus Fabian229c1aa2018-05-28 04:09:52 -07005193 # FIN packet out -> in
5194 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5195 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5196 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
5197 flags="FA", seq=100, ack=300))
5198 self.pg1.add_stream(p)
5199 self.pg_enable_capture(self.pg_interfaces)
5200 self.pg_start()
5201 self.pg0.get_capture(1)
Matus Fabianebdf1902018-05-04 03:57:42 -07005202
Matus Fabian229c1aa2018-05-28 04:09:52 -07005203 # FIN+ACK packet in -> out
5204 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5205 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5206 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
5207 flags="FA", seq=300, ack=101))
Matus Fabianebdf1902018-05-04 03:57:42 -07005208
Matus Fabian229c1aa2018-05-28 04:09:52 -07005209 self.pg0.add_stream(p)
5210 self.pg_enable_capture(self.pg_interfaces)
5211 self.pg_start()
5212 self.pg1.get_capture(1)
Matus Fabianebdf1902018-05-04 03:57:42 -07005213
Matus Fabian229c1aa2018-05-28 04:09:52 -07005214 # ACK packet out -> in
5215 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5216 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5217 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
5218 flags="A", seq=101, ack=301))
5219 self.pg1.add_stream(p)
5220 self.pg_enable_capture(self.pg_interfaces)
5221 self.pg_start()
5222 self.pg0.get_capture(1)
Matus Fabianebdf1902018-05-04 03:57:42 -07005223
Matus Fabian229c1aa2018-05-28 04:09:52 -07005224 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n,
5225 0)
5226 self.assertEqual(len(sessions) - start_sessnum, 0)
Matus Fabianebdf1902018-05-04 03:57:42 -07005227
5228 def test_tcp_session_close_simultaneous(self):
5229 """ Close TCP session from inside network """
Matus Fabian229c1aa2018-05-28 04:09:52 -07005230 self.tcp_port_out = 10505
Matus Fabianebdf1902018-05-04 03:57:42 -07005231 self.nat44_add_address(self.nat_addr)
Matus Fabian229c1aa2018-05-28 04:09:52 -07005232 self.nat44_add_static_mapping(self.pg0.remote_ip4,
5233 self.nat_addr,
5234 self.tcp_port_in,
5235 self.tcp_port_out,
5236 proto=IP_PROTOS.tcp,
5237 twice_nat=1)
Matus Fabianebdf1902018-05-04 03:57:42 -07005238 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
5239 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
5240 is_inside=0)
5241
5242 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n, 0)
5243 start_sessnum = len(sessions)
5244
5245 self.initiate_tcp_session(self.pg0, self.pg1)
5246
Matus Fabian229c1aa2018-05-28 04:09:52 -07005247 # FIN packet in -> out
5248 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5249 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5250 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
5251 flags="FA", seq=100, ack=300))
5252 self.pg0.add_stream(p)
5253 self.pg_enable_capture(self.pg_interfaces)
5254 self.pg_start()
5255 self.pg1.get_capture(1)
Matus Fabianebdf1902018-05-04 03:57:42 -07005256
Matus Fabian229c1aa2018-05-28 04:09:52 -07005257 # FIN packet out -> in
5258 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5259 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5260 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
5261 flags="FA", seq=300, ack=100))
5262 self.pg1.add_stream(p)
5263 self.pg_enable_capture(self.pg_interfaces)
5264 self.pg_start()
5265 self.pg0.get_capture(1)
Matus Fabianebdf1902018-05-04 03:57:42 -07005266
Matus Fabian229c1aa2018-05-28 04:09:52 -07005267 # ACK packet in -> out
5268 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5269 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5270 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
5271 flags="A", seq=101, ack=301))
5272 self.pg0.add_stream(p)
5273 self.pg_enable_capture(self.pg_interfaces)
5274 self.pg_start()
5275 self.pg1.get_capture(1)
Matus Fabianebdf1902018-05-04 03:57:42 -07005276
Matus Fabian229c1aa2018-05-28 04:09:52 -07005277 # ACK packet out -> in
5278 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5279 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5280 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
5281 flags="A", seq=301, ack=101))
5282 self.pg1.add_stream(p)
5283 self.pg_enable_capture(self.pg_interfaces)
5284 self.pg_start()
5285 self.pg0.get_capture(1)
Matus Fabianebdf1902018-05-04 03:57:42 -07005286
Matus Fabian229c1aa2018-05-28 04:09:52 -07005287 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n,
5288 0)
5289 self.assertEqual(len(sessions) - start_sessnum, 0)
Matus Fabianebdf1902018-05-04 03:57:42 -07005290
Matus Fabiana6110b62018-06-13 05:39:07 -07005291 def test_one_armed_nat44_static(self):
5292 """ One armed NAT44 and 1:1 NAPT asymmetrical rule """
5293 remote_host = self.pg4.remote_hosts[0]
5294 local_host = self.pg4.remote_hosts[1]
5295 external_port = 80
5296 local_port = 8080
5297 eh_port_in = 0
5298
5299 self.vapi.nat44_forwarding_enable_disable(1)
5300 self.nat44_add_address(self.nat_addr, twice_nat=1)
5301 self.nat44_add_static_mapping(local_host.ip4, self.nat_addr,
5302 local_port, external_port,
5303 proto=IP_PROTOS.tcp, out2in_only=1,
5304 twice_nat=1)
5305 self.vapi.nat44_interface_add_del_feature(self.pg4.sw_if_index)
5306 self.vapi.nat44_interface_add_del_feature(self.pg4.sw_if_index,
5307 is_inside=0)
5308
5309 # from client to service
5310 p = (Ether(src=self.pg4.remote_mac, dst=self.pg4.local_mac) /
5311 IP(src=remote_host.ip4, dst=self.nat_addr) /
5312 TCP(sport=12345, dport=external_port))
5313 self.pg4.add_stream(p)
5314 self.pg_enable_capture(self.pg_interfaces)
5315 self.pg_start()
5316 capture = self.pg4.get_capture(1)
5317 p = capture[0]
5318 try:
5319 ip = p[IP]
5320 tcp = p[TCP]
5321 self.assertEqual(ip.dst, local_host.ip4)
5322 self.assertEqual(ip.src, self.nat_addr)
5323 self.assertEqual(tcp.dport, local_port)
5324 self.assertNotEqual(tcp.sport, 12345)
5325 eh_port_in = tcp.sport
5326 self.assert_packet_checksums_valid(p)
5327 except:
5328 self.logger.error(ppp("Unexpected or invalid packet:", p))
5329 raise
5330
5331 # from service back to client
5332 p = (Ether(src=self.pg4.remote_mac, dst=self.pg4.local_mac) /
5333 IP(src=local_host.ip4, dst=self.nat_addr) /
5334 TCP(sport=local_port, dport=eh_port_in))
5335 self.pg4.add_stream(p)
5336 self.pg_enable_capture(self.pg_interfaces)
5337 self.pg_start()
5338 capture = self.pg4.get_capture(1)
5339 p = capture[0]
5340 try:
5341 ip = p[IP]
5342 tcp = p[TCP]
5343 self.assertEqual(ip.src, self.nat_addr)
5344 self.assertEqual(ip.dst, remote_host.ip4)
5345 self.assertEqual(tcp.sport, external_port)
5346 self.assertEqual(tcp.dport, 12345)
5347 self.assert_packet_checksums_valid(p)
5348 except:
5349 self.logger.error(ppp("Unexpected or invalid packet:", p))
5350 raise
5351
5352 def test_static_with_port_out2(self):
5353 """ 1:1 NAPT asymmetrical rule """
5354
5355 external_port = 80
5356 local_port = 8080
5357
5358 self.vapi.nat44_forwarding_enable_disable(1)
5359 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
5360 local_port, external_port,
5361 proto=IP_PROTOS.tcp, out2in_only=1)
5362 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
5363 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
5364 is_inside=0)
5365
5366 # from client to service
5367 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5368 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5369 TCP(sport=12345, dport=external_port))
5370 self.pg1.add_stream(p)
5371 self.pg_enable_capture(self.pg_interfaces)
5372 self.pg_start()
5373 capture = self.pg0.get_capture(1)
5374 p = capture[0]
5375 try:
5376 ip = p[IP]
5377 tcp = p[TCP]
5378 self.assertEqual(ip.dst, self.pg0.remote_ip4)
5379 self.assertEqual(tcp.dport, local_port)
5380 self.assert_packet_checksums_valid(p)
5381 except:
5382 self.logger.error(ppp("Unexpected or invalid packet:", p))
5383 raise
5384
5385 # ICMP error
5386 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
5387 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5388 ICMP(type=11) / capture[0][IP])
5389 self.pg0.add_stream(p)
5390 self.pg_enable_capture(self.pg_interfaces)
5391 self.pg_start()
5392 capture = self.pg1.get_capture(1)
5393 p = capture[0]
5394 try:
5395 self.assertEqual(p[IP].src, self.nat_addr)
5396 inner = p[IPerror]
5397 self.assertEqual(inner.dst, self.nat_addr)
5398 self.assertEqual(inner[TCPerror].dport, external_port)
5399 except:
5400 self.logger.error(ppp("Unexpected or invalid packet:", p))
5401 raise
5402
5403 # from service back to client
5404 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5405 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5406 TCP(sport=local_port, dport=12345))
5407 self.pg0.add_stream(p)
5408 self.pg_enable_capture(self.pg_interfaces)
5409 self.pg_start()
5410 capture = self.pg1.get_capture(1)
5411 p = capture[0]
5412 try:
5413 ip = p[IP]
5414 tcp = p[TCP]
5415 self.assertEqual(ip.src, self.nat_addr)
5416 self.assertEqual(tcp.sport, external_port)
5417 self.assert_packet_checksums_valid(p)
5418 except:
5419 self.logger.error(ppp("Unexpected or invalid packet:", p))
5420 raise
5421
5422 # ICMP error
5423 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
5424 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5425 ICMP(type=11) / capture[0][IP])
5426 self.pg1.add_stream(p)
5427 self.pg_enable_capture(self.pg_interfaces)
5428 self.pg_start()
5429 capture = self.pg0.get_capture(1)
5430 p = capture[0]
5431 try:
5432 self.assertEqual(p[IP].dst, self.pg0.remote_ip4)
5433 inner = p[IPerror]
5434 self.assertEqual(inner.src, self.pg0.remote_ip4)
5435 self.assertEqual(inner[TCPerror].sport, local_port)
5436 except:
5437 self.logger.error(ppp("Unexpected or invalid packet:", p))
5438 raise
5439
5440 # from client to server (no translation)
5441 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5442 IP(src=self.pg1.remote_ip4, dst=self.pg0.remote_ip4) /
5443 TCP(sport=12346, dport=local_port))
5444 self.pg1.add_stream(p)
5445 self.pg_enable_capture(self.pg_interfaces)
5446 self.pg_start()
5447 capture = self.pg0.get_capture(1)
5448 p = capture[0]
5449 try:
5450 ip = p[IP]
5451 tcp = p[TCP]
5452 self.assertEqual(ip.dst, self.pg0.remote_ip4)
5453 self.assertEqual(tcp.dport, local_port)
5454 self.assert_packet_checksums_valid(p)
5455 except:
5456 self.logger.error(ppp("Unexpected or invalid packet:", p))
5457 raise
5458
5459 # from service back to client (no translation)
5460 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5461 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5462 TCP(sport=local_port, dport=12346))
5463 self.pg0.add_stream(p)
5464 self.pg_enable_capture(self.pg_interfaces)
5465 self.pg_start()
5466 capture = self.pg1.get_capture(1)
5467 p = capture[0]
5468 try:
5469 ip = p[IP]
5470 tcp = p[TCP]
5471 self.assertEqual(ip.src, self.pg0.remote_ip4)
5472 self.assertEqual(tcp.sport, local_port)
5473 self.assert_packet_checksums_valid(p)
5474 except:
5475 self.logger.error(ppp("Unexpected or invalid packet:", p))
5476 raise
5477
Matus Fabian235a47e2018-06-25 16:42:36 -07005478 def test_output_feature(self):
5479 """ NAT44 interface output feature (in2out postrouting) """
5480 self.vapi.nat44_forwarding_enable_disable(1)
5481 self.nat44_add_address(self.nat_addr)
5482 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index,
5483 is_inside=0)
5484 self.vapi.nat44_interface_add_del_output_feature(self.pg1.sw_if_index,
5485 is_inside=0)
5486
5487 # in2out
5488 pkts = self.create_stream_in(self.pg0, self.pg1)
5489 self.pg0.add_stream(pkts)
5490 self.pg_enable_capture(self.pg_interfaces)
5491 self.pg_start()
5492 capture = self.pg1.get_capture(len(pkts))
5493 self.verify_capture_out(capture)
5494
5495 # out2in
5496 pkts = self.create_stream_out(self.pg1)
5497 self.pg1.add_stream(pkts)
5498 self.pg_enable_capture(self.pg_interfaces)
5499 self.pg_start()
5500 capture = self.pg0.get_capture(len(pkts))
5501 self.verify_capture_in(capture, self.pg0)
5502
Matus Fabian8008d7c2018-07-09 01:34:20 -07005503 def test_multiple_vrf(self):
5504 """ Multiple VRF setup """
5505 external_addr = '1.2.3.4'
5506 external_port = 80
5507 local_port = 8080
5508 port = 0
5509
5510 self.vapi.nat44_forwarding_enable_disable(1)
5511 self.nat44_add_address(self.nat_addr)
5512 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
5513 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index,
5514 is_inside=0)
5515 self.vapi.nat44_interface_add_del_output_feature(self.pg1.sw_if_index,
5516 is_inside=0)
5517 self.vapi.nat44_interface_add_del_feature(self.pg5.sw_if_index)
5518 self.vapi.nat44_interface_add_del_feature(self.pg5.sw_if_index,
5519 is_inside=0)
5520 self.vapi.nat44_interface_add_del_feature(self.pg6.sw_if_index,
5521 is_inside=0)
5522 self.nat44_add_static_mapping(self.pg5.remote_ip4, external_addr,
5523 local_port, external_port, vrf_id=1,
5524 proto=IP_PROTOS.tcp, out2in_only=1)
5525 self.nat44_add_static_mapping(
5526 self.pg0.remote_ip4, external_sw_if_index=self.pg0.sw_if_index,
5527 local_port=local_port, vrf_id=0, external_port=external_port,
5528 proto=IP_PROTOS.tcp, out2in_only=1)
5529
5530 # from client to service (both VRF1)
5531 p = (Ether(src=self.pg6.remote_mac, dst=self.pg6.local_mac) /
5532 IP(src=self.pg6.remote_ip4, dst=external_addr) /
5533 TCP(sport=12345, dport=external_port))
5534 self.pg6.add_stream(p)
5535 self.pg_enable_capture(self.pg_interfaces)
5536 self.pg_start()
5537 capture = self.pg5.get_capture(1)
5538 p = capture[0]
5539 try:
5540 ip = p[IP]
5541 tcp = p[TCP]
5542 self.assertEqual(ip.dst, self.pg5.remote_ip4)
5543 self.assertEqual(tcp.dport, local_port)
5544 self.assert_packet_checksums_valid(p)
5545 except:
5546 self.logger.error(ppp("Unexpected or invalid packet:", p))
5547 raise
5548
5549 # from service back to client (both VRF1)
5550 p = (Ether(src=self.pg5.remote_mac, dst=self.pg5.local_mac) /
5551 IP(src=self.pg5.remote_ip4, dst=self.pg6.remote_ip4) /
5552 TCP(sport=local_port, dport=12345))
5553 self.pg5.add_stream(p)
5554 self.pg_enable_capture(self.pg_interfaces)
5555 self.pg_start()
5556 capture = self.pg6.get_capture(1)
5557 p = capture[0]
5558 try:
5559 ip = p[IP]
5560 tcp = p[TCP]
5561 self.assertEqual(ip.src, external_addr)
5562 self.assertEqual(tcp.sport, external_port)
5563 self.assert_packet_checksums_valid(p)
5564 except:
5565 self.logger.error(ppp("Unexpected or invalid packet:", p))
5566 raise
5567
5568 # dynamic NAT from VRF1 to VRF0 (output-feature)
5569 p = (Ether(src=self.pg5.remote_mac, dst=self.pg5.local_mac) /
5570 IP(src=self.pg5.remote_ip4, dst=self.pg1.remote_ip4) /
5571 TCP(sport=2345, dport=22))
5572 self.pg5.add_stream(p)
5573 self.pg_enable_capture(self.pg_interfaces)
5574 self.pg_start()
5575 capture = self.pg1.get_capture(1)
5576 p = capture[0]
5577 try:
5578 ip = p[IP]
5579 tcp = p[TCP]
5580 self.assertEqual(ip.src, self.nat_addr)
5581 self.assertNotEqual(tcp.sport, 2345)
5582 self.assert_packet_checksums_valid(p)
5583 port = tcp.sport
5584 except:
5585 self.logger.error(ppp("Unexpected or invalid packet:", p))
5586 raise
5587
5588 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5589 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5590 TCP(sport=22, dport=port))
5591 self.pg1.add_stream(p)
5592 self.pg_enable_capture(self.pg_interfaces)
5593 self.pg_start()
5594 capture = self.pg5.get_capture(1)
5595 p = capture[0]
5596 try:
5597 ip = p[IP]
5598 tcp = p[TCP]
5599 self.assertEqual(ip.dst, self.pg5.remote_ip4)
5600 self.assertEqual(tcp.dport, 2345)
5601 self.assert_packet_checksums_valid(p)
5602 except:
5603 self.logger.error(ppp("Unexpected or invalid packet:", p))
5604 raise
5605
5606 # from client VRF1 to service VRF0
5607 p = (Ether(src=self.pg6.remote_mac, dst=self.pg6.local_mac) /
5608 IP(src=self.pg6.remote_ip4, dst=self.pg0.local_ip4) /
5609 TCP(sport=12346, dport=external_port))
5610 self.pg6.add_stream(p)
5611 self.pg_enable_capture(self.pg_interfaces)
5612 self.pg_start()
5613 capture = self.pg0.get_capture(1)
5614 p = capture[0]
5615 try:
5616 ip = p[IP]
5617 tcp = p[TCP]
5618 self.assertEqual(ip.dst, self.pg0.remote_ip4)
5619 self.assertEqual(tcp.dport, local_port)
5620 self.assert_packet_checksums_valid(p)
5621 except:
5622 self.logger.error(ppp("Unexpected or invalid packet:", p))
5623 raise
5624
5625 # from service VRF0 back to client VRF1
5626 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5627 IP(src=self.pg0.remote_ip4, dst=self.pg6.remote_ip4) /
5628 TCP(sport=local_port, dport=12346))
5629 self.pg0.add_stream(p)
5630 self.pg_enable_capture(self.pg_interfaces)
5631 self.pg_start()
5632 capture = self.pg6.get_capture(1)
5633 p = capture[0]
5634 try:
5635 ip = p[IP]
5636 tcp = p[TCP]
5637 self.assertEqual(ip.src, self.pg0.local_ip4)
5638 self.assertEqual(tcp.sport, external_port)
5639 self.assert_packet_checksums_valid(p)
5640 except:
5641 self.logger.error(ppp("Unexpected or invalid packet:", p))
5642 raise
5643
5644 # from client VRF0 to service VRF1
5645 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5646 IP(src=self.pg0.remote_ip4, dst=external_addr) /
5647 TCP(sport=12347, dport=external_port))
5648 self.pg0.add_stream(p)
5649 self.pg_enable_capture(self.pg_interfaces)
5650 self.pg_start()
5651 capture = self.pg5.get_capture(1)
5652 p = capture[0]
5653 try:
5654 ip = p[IP]
5655 tcp = p[TCP]
5656 self.assertEqual(ip.dst, self.pg5.remote_ip4)
5657 self.assertEqual(tcp.dport, local_port)
5658 self.assert_packet_checksums_valid(p)
5659 except:
5660 self.logger.error(ppp("Unexpected or invalid packet:", p))
5661 raise
5662
5663 # from service VRF1 back to client VRF0
5664 p = (Ether(src=self.pg5.remote_mac, dst=self.pg5.local_mac) /
5665 IP(src=self.pg5.remote_ip4, dst=self.pg0.remote_ip4) /
5666 TCP(sport=local_port, dport=12347))
5667 self.pg5.add_stream(p)
5668 self.pg_enable_capture(self.pg_interfaces)
5669 self.pg_start()
5670 capture = self.pg0.get_capture(1)
5671 p = capture[0]
5672 try:
5673 ip = p[IP]
5674 tcp = p[TCP]
5675 self.assertEqual(ip.src, external_addr)
5676 self.assertEqual(tcp.sport, external_port)
5677 self.assert_packet_checksums_valid(p)
5678 except:
5679 self.logger.error(ppp("Unexpected or invalid packet:", p))
5680 raise
5681
5682 # from client to server (both VRF1, no translation)
5683 p = (Ether(src=self.pg6.remote_mac, dst=self.pg6.local_mac) /
5684 IP(src=self.pg6.remote_ip4, dst=self.pg5.remote_ip4) /
5685 TCP(sport=12348, dport=local_port))
5686 self.pg6.add_stream(p)
5687 self.pg_enable_capture(self.pg_interfaces)
5688 self.pg_start()
5689 capture = self.pg5.get_capture(1)
5690 p = capture[0]
5691 try:
5692 ip = p[IP]
5693 tcp = p[TCP]
5694 self.assertEqual(ip.dst, self.pg5.remote_ip4)
5695 self.assertEqual(tcp.dport, local_port)
5696 self.assert_packet_checksums_valid(p)
5697 except:
5698 self.logger.error(ppp("Unexpected or invalid packet:", p))
5699 raise
5700
5701 # from server back to client (both VRF1, no translation)
5702 p = (Ether(src=self.pg5.remote_mac, dst=self.pg5.local_mac) /
5703 IP(src=self.pg5.remote_ip4, dst=self.pg6.remote_ip4) /
5704 TCP(sport=local_port, dport=12348))
5705 self.pg5.add_stream(p)
5706 self.pg_enable_capture(self.pg_interfaces)
5707 self.pg_start()
5708 capture = self.pg6.get_capture(1)
5709 p = capture[0]
5710 try:
5711 ip = p[IP]
5712 tcp = p[TCP]
5713 self.assertEqual(ip.src, self.pg5.remote_ip4)
5714 self.assertEqual(tcp.sport, local_port)
5715 self.assert_packet_checksums_valid(p)
5716 except:
5717 self.logger.error(ppp("Unexpected or invalid packet:", p))
5718 raise
5719
5720 # from client VRF1 to server VRF0 (no translation)
5721 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5722 IP(src=self.pg0.remote_ip4, dst=self.pg6.remote_ip4) /
5723 TCP(sport=local_port, dport=12349))
5724 self.pg0.add_stream(p)
5725 self.pg_enable_capture(self.pg_interfaces)
5726 self.pg_start()
5727 capture = self.pg6.get_capture(1)
5728 p = capture[0]
5729 try:
5730 ip = p[IP]
5731 tcp = p[TCP]
5732 self.assertEqual(ip.src, self.pg0.remote_ip4)
5733 self.assertEqual(tcp.sport, local_port)
5734 self.assert_packet_checksums_valid(p)
5735 except:
5736 self.logger.error(ppp("Unexpected or invalid packet:", p))
5737 raise
5738
5739 # from server VRF0 back to client VRF1 (no translation)
5740 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5741 IP(src=self.pg0.remote_ip4, dst=self.pg6.remote_ip4) /
5742 TCP(sport=local_port, dport=12349))
5743 self.pg0.add_stream(p)
5744 self.pg_enable_capture(self.pg_interfaces)
5745 self.pg_start()
5746 capture = self.pg6.get_capture(1)
5747 p = capture[0]
5748 try:
5749 ip = p[IP]
5750 tcp = p[TCP]
5751 self.assertEqual(ip.src, self.pg0.remote_ip4)
5752 self.assertEqual(tcp.sport, local_port)
5753 self.assert_packet_checksums_valid(p)
5754 except:
5755 self.logger.error(ppp("Unexpected or invalid packet:", p))
5756 raise
5757
5758 # from client VRF0 to server VRF1 (no translation)
5759 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5760 IP(src=self.pg0.remote_ip4, dst=self.pg5.remote_ip4) /
5761 TCP(sport=12344, dport=local_port))
5762 self.pg0.add_stream(p)
5763 self.pg_enable_capture(self.pg_interfaces)
5764 self.pg_start()
5765 capture = self.pg5.get_capture(1)
5766 p = capture[0]
5767 try:
5768 ip = p[IP]
5769 tcp = p[TCP]
5770 self.assertEqual(ip.dst, self.pg5.remote_ip4)
5771 self.assertEqual(tcp.dport, local_port)
5772 self.assert_packet_checksums_valid(p)
5773 except:
5774 self.logger.error(ppp("Unexpected or invalid packet:", p))
5775 raise
5776
5777 # from server VRF1 back to client VRF0 (no translation)
5778 p = (Ether(src=self.pg5.remote_mac, dst=self.pg5.local_mac) /
5779 IP(src=self.pg5.remote_ip4, dst=self.pg0.remote_ip4) /
5780 TCP(sport=local_port, dport=12344))
5781 self.pg5.add_stream(p)
5782 self.pg_enable_capture(self.pg_interfaces)
5783 self.pg_start()
5784 capture = self.pg0.get_capture(1)
5785 p = capture[0]
5786 try:
5787 ip = p[IP]
5788 tcp = p[TCP]
5789 self.assertEqual(ip.src, self.pg5.remote_ip4)
5790 self.assertEqual(tcp.sport, local_port)
5791 self.assert_packet_checksums_valid(p)
5792 except:
5793 self.logger.error(ppp("Unexpected or invalid packet:", p))
5794 raise
5795
Matus Fabian878c6462018-08-23 00:33:35 -07005796 @unittest.skipUnless(running_extended_tests(), "part of extended tests")
5797 def test_session_timeout(self):
5798 """ NAT44 session timeouts """
5799 self.nat44_add_address(self.nat_addr)
5800 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
5801 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
5802 is_inside=0)
5803 self.vapi.nat_set_timeouts(icmp=5)
5804
5805 max_sessions = 1000
5806 pkts = []
5807 for i in range(0, max_sessions):
5808 src = "10.10.%u.%u" % ((i & 0xFF00) >> 8, i & 0xFF)
5809 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
5810 IP(src=src, dst=self.pg1.remote_ip4) /
5811 ICMP(id=1025, type='echo-request'))
5812 pkts.append(p)
5813 self.pg0.add_stream(pkts)
5814 self.pg_enable_capture(self.pg_interfaces)
5815 self.pg_start()
5816 self.pg1.get_capture(max_sessions)
5817
5818 sleep(10)
5819
5820 pkts = []
5821 for i in range(0, max_sessions):
Matus Fabian7f8a8db2018-11-22 00:12:15 -08005822 src = "10.11.%u.%u" % ((i & 0xFF00) >> 8, i & 0xFF)
Matus Fabian878c6462018-08-23 00:33:35 -07005823 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
5824 IP(src=src, dst=self.pg1.remote_ip4) /
5825 ICMP(id=1026, type='echo-request'))
5826 pkts.append(p)
5827 self.pg0.add_stream(pkts)
5828 self.pg_enable_capture(self.pg_interfaces)
5829 self.pg_start()
5830 self.pg1.get_capture(max_sessions)
5831
5832 nsessions = 0
5833 users = self.vapi.nat44_user_dump()
5834 for user in users:
5835 nsessions = nsessions + user.nsessions
5836 self.assertLess(nsessions, 2 * max_sessions)
5837
5838 @unittest.skipUnless(running_extended_tests(), "part of extended tests")
Matus Fabian15e8e682018-11-21 04:53:10 -08005839 def test_session_rst_timeout(self):
5840 """ NAT44 session RST timeouts """
5841 self.nat44_add_address(self.nat_addr)
5842 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
5843 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
5844 is_inside=0)
5845 self.vapi.nat_set_timeouts(tcp_transitory=5)
5846
Matus Fabian15e8e682018-11-21 04:53:10 -08005847 self.initiate_tcp_session(self.pg0, self.pg1)
5848 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5849 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5850 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
5851 flags="R"))
5852 self.pg0.add_stream(p)
5853 self.pg_enable_capture(self.pg_interfaces)
5854 self.pg_start()
5855 self.pg1.get_capture(1)
5856
Matus Fabian15e8e682018-11-21 04:53:10 -08005857 sleep(6)
5858
5859 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5860 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5861 TCP(sport=self.tcp_port_in + 1, dport=self.tcp_external_port + 1,
5862 flags="S"))
5863 self.pg0.add_stream(p)
5864 self.pg_enable_capture(self.pg_interfaces)
5865 self.pg_start()
5866 self.pg1.get_capture(1)
5867
5868 nsessions = 0
5869 users = self.vapi.nat44_user_dump()
5870 self.assertEqual(len(users), 1)
5871 self.assertEqual(users[0].ip_address, self.pg0.remote_ip4n)
Matus Fabian7f8a8db2018-11-22 00:12:15 -08005872 self.assertEqual(users[0].nsessions, 1)
Matus Fabian15e8e682018-11-21 04:53:10 -08005873
5874 @unittest.skipUnless(running_extended_tests(), "part of extended tests")
Matus Fabian878c6462018-08-23 00:33:35 -07005875 def test_session_limit_per_user(self):
5876 """ Maximum sessions per user limit """
5877 self.nat44_add_address(self.nat_addr)
5878 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
5879 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
5880 is_inside=0)
5881 self.vapi.set_ipfix_exporter(collector_address=self.pg2.remote_ip4n,
5882 src_address=self.pg2.local_ip4n,
5883 path_mtu=512,
5884 template_interval=10)
Matus Fabian8fdc0152018-09-24 04:41:28 -07005885 self.vapi.nat_set_timeouts(udp=5)
Matus Fabian878c6462018-08-23 00:33:35 -07005886
5887 # get maximum number of translations per user
5888 nat44_config = self.vapi.nat_show_config()
5889
5890 pkts = []
5891 for port in range(0, nat44_config.max_translations_per_user):
5892 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5893 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5894 UDP(sport=1025 + port, dport=1025 + port))
5895 pkts.append(p)
5896
5897 self.pg0.add_stream(pkts)
5898 self.pg_enable_capture(self.pg_interfaces)
5899 self.pg_start()
5900 capture = self.pg1.get_capture(len(pkts))
5901
5902 self.vapi.nat_ipfix(domain_id=self.ipfix_domain_id,
5903 src_port=self.ipfix_src_port)
5904
5905 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5906 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5907 UDP(sport=3001, dport=3002))
5908 self.pg0.add_stream(p)
5909 self.pg_enable_capture(self.pg_interfaces)
5910 self.pg_start()
5911 capture = self.pg1.assert_nothing_captured()
5912
5913 # verify IPFIX logging
5914 self.vapi.cli("ipfix flush") # FIXME this should be an API call
5915 sleep(1)
5916 capture = self.pg2.get_capture(10)
5917 ipfix = IPFIXDecoder()
5918 # first load template
5919 for p in capture:
5920 self.assertTrue(p.haslayer(IPFIX))
5921 if p.haslayer(Template):
5922 ipfix.add_template(p.getlayer(Template))
5923 # verify events in data set
5924 for p in capture:
5925 if p.haslayer(Data):
5926 data = ipfix.decode_data_set(p.getlayer(Set))
5927 self.verify_ipfix_max_entries_per_user(
5928 data,
5929 nat44_config.max_translations_per_user,
5930 self.pg0.remote_ip4n)
5931
Matus Fabian8fdc0152018-09-24 04:41:28 -07005932 sleep(6)
5933 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5934 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5935 UDP(sport=3001, dport=3002))
5936 self.pg0.add_stream(p)
5937 self.pg_enable_capture(self.pg_interfaces)
5938 self.pg_start()
5939 self.pg1.get_capture(1)
5940
Matus Fabianad1f3e12018-11-28 21:26:34 -08005941 def test_syslog_sess(self):
5942 """ Test syslog session creation and deletion """
5943 self.vapi.syslog_set_filter(SYSLOG_SEVERITY.INFO)
5944 self.vapi.syslog_set_sender(self.pg2.remote_ip4n, self.pg2.local_ip4n)
5945 self.nat44_add_address(self.nat_addr)
5946 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
5947 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
5948 is_inside=0)
5949
5950 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
5951 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5952 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port))
5953 self.pg0.add_stream(p)
5954 self.pg_enable_capture(self.pg_interfaces)
5955 self.pg_start()
5956 capture = self.pg1.get_capture(1)
5957 self.tcp_port_out = capture[0][TCP].sport
5958 capture = self.pg2.get_capture(1)
5959 self.verify_syslog_sess(capture[0][Raw].load)
5960
5961 self.pg_enable_capture(self.pg_interfaces)
5962 self.pg_start()
5963 self.nat44_add_address(self.nat_addr, is_add=0)
5964 capture = self.pg2.get_capture(1)
5965 self.verify_syslog_sess(capture[0][Raw].load, False)
5966
Matus Fabiande886752016-12-07 03:38:19 -08005967 def tearDown(self):
Matus Fabiana6110b62018-06-13 05:39:07 -07005968 super(TestNAT44EndpointDependent, self).tearDown()
Matus Fabiande886752016-12-07 03:38:19 -08005969 if not self.vpp_dead:
Matus Fabian82119542018-01-25 01:13:22 -08005970 self.logger.info(self.vapi.cli("show nat44 addresses"))
5971 self.logger.info(self.vapi.cli("show nat44 interfaces"))
5972 self.logger.info(self.vapi.cli("show nat44 static mappings"))
5973 self.logger.info(self.vapi.cli("show nat44 interface address"))
5974 self.logger.info(self.vapi.cli("show nat44 sessions detail"))
Matus Fabian229c1aa2018-05-28 04:09:52 -07005975 self.logger.info(self.vapi.cli("show nat44 hash tables detail"))
Matus Fabian878c6462018-08-23 00:33:35 -07005976 self.logger.info(self.vapi.cli("show nat timeouts"))
Matus Fabian2ba92e32017-08-21 07:05:03 -07005977 self.clear_nat44()
Matus Fabian229c1aa2018-05-28 04:09:52 -07005978 self.vapi.cli("clear logging")
Matus Fabiande886752016-12-07 03:38:19 -08005979
Matus Fabianeea28d72017-01-13 04:15:54 -08005980
Juraj Slobodacba69362017-12-19 02:09:32 +01005981class TestNAT44Out2InDPO(MethodHolder):
5982 """ NAT44 Test Cases using out2in DPO """
5983
5984 @classmethod
5985 def setUpConstants(cls):
5986 super(TestNAT44Out2InDPO, cls).setUpConstants()
5987 cls.vpp_cmdline.extend(["nat", "{", "out2in dpo", "}"])
5988
5989 @classmethod
5990 def setUpClass(cls):
5991 super(TestNAT44Out2InDPO, cls).setUpClass()
Matus Fabian229c1aa2018-05-28 04:09:52 -07005992 cls.vapi.cli("set log class nat level debug")
Juraj Slobodacba69362017-12-19 02:09:32 +01005993
5994 try:
5995 cls.tcp_port_in = 6303
5996 cls.tcp_port_out = 6303
5997 cls.udp_port_in = 6304
5998 cls.udp_port_out = 6304
5999 cls.icmp_id_in = 6305
6000 cls.icmp_id_out = 6305
6001 cls.nat_addr = '10.0.0.3'
6002 cls.nat_addr_n = socket.inet_pton(socket.AF_INET, cls.nat_addr)
6003 cls.dst_ip4 = '192.168.70.1'
6004
6005 cls.create_pg_interfaces(range(2))
6006
6007 cls.pg0.admin_up()
6008 cls.pg0.config_ip4()
6009 cls.pg0.resolve_arp()
6010
6011 cls.pg1.admin_up()
6012 cls.pg1.config_ip6()
6013 cls.pg1.resolve_ndp()
6014
6015 cls.vapi.ip_add_del_route(is_ipv6=True, dst_address='\x00'*16,
6016 dst_address_length=0,
6017 next_hop_address=cls.pg1.remote_ip6n,
6018 next_hop_sw_if_index=cls.pg1.sw_if_index)
6019
6020 except Exception:
6021 super(TestNAT44Out2InDPO, cls).tearDownClass()
6022 raise
6023
6024 def configure_xlat(self):
6025 self.dst_ip6_pfx = '1:2:3::'
6026 self.dst_ip6_pfx_n = socket.inet_pton(socket.AF_INET6,
6027 self.dst_ip6_pfx)
6028 self.dst_ip6_pfx_len = 96
6029 self.src_ip6_pfx = '4:5:6::'
6030 self.src_ip6_pfx_n = socket.inet_pton(socket.AF_INET6,
6031 self.src_ip6_pfx)
6032 self.src_ip6_pfx_len = 96
6033 self.vapi.map_add_domain(self.dst_ip6_pfx_n, self.dst_ip6_pfx_len,
6034 self.src_ip6_pfx_n, self.src_ip6_pfx_len,
6035 '\x00\x00\x00\x00', 0, is_translation=1,
6036 is_rfc6052=1)
6037
Ole Troanffba3c32018-11-22 12:53:00 +01006038 @unittest.skip('Temporary disabled')
Juraj Slobodacba69362017-12-19 02:09:32 +01006039 def test_464xlat_ce(self):
6040 """ Test 464XLAT CE with NAT44 """
6041
Matus Fabian69ce30d2018-08-22 01:27:10 -07006042 nat_config = self.vapi.nat_show_config()
6043 self.assertEqual(1, nat_config.out2in_dpo)
6044
Juraj Slobodacba69362017-12-19 02:09:32 +01006045 self.configure_xlat()
6046
6047 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
6048 self.vapi.nat44_add_del_address_range(self.nat_addr_n, self.nat_addr_n)
6049
6050 out_src_ip6 = self.compose_ip6(self.dst_ip4, self.dst_ip6_pfx,
6051 self.dst_ip6_pfx_len)
6052 out_dst_ip6 = self.compose_ip6(self.nat_addr, self.src_ip6_pfx,
6053 self.src_ip6_pfx_len)
6054
6055 try:
6056 pkts = self.create_stream_in(self.pg0, self.pg1, self.dst_ip4)
6057 self.pg0.add_stream(pkts)
6058 self.pg_enable_capture(self.pg_interfaces)
6059 self.pg_start()
6060 capture = self.pg1.get_capture(len(pkts))
6061 self.verify_capture_out_ip6(capture, nat_ip=out_dst_ip6,
6062 dst_ip=out_src_ip6)
6063
6064 pkts = self.create_stream_out_ip6(self.pg1, out_src_ip6,
6065 out_dst_ip6)
6066 self.pg1.add_stream(pkts)
6067 self.pg_enable_capture(self.pg_interfaces)
6068 self.pg_start()
6069 capture = self.pg0.get_capture(len(pkts))
6070 self.verify_capture_in(capture, self.pg0)
6071 finally:
6072 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index,
6073 is_add=0)
6074 self.vapi.nat44_add_del_address_range(self.nat_addr_n,
6075 self.nat_addr_n, is_add=0)
6076
Ole Troanffba3c32018-11-22 12:53:00 +01006077 @unittest.skip('Temporary disabled')
Juraj Slobodacba69362017-12-19 02:09:32 +01006078 def test_464xlat_ce_no_nat(self):
6079 """ Test 464XLAT CE without NAT44 """
6080
6081 self.configure_xlat()
6082
6083 out_src_ip6 = self.compose_ip6(self.dst_ip4, self.dst_ip6_pfx,
6084 self.dst_ip6_pfx_len)
6085 out_dst_ip6 = self.compose_ip6(self.pg0.remote_ip4, self.src_ip6_pfx,
6086 self.src_ip6_pfx_len)
6087
6088 pkts = self.create_stream_in(self.pg0, self.pg1, self.dst_ip4)
6089 self.pg0.add_stream(pkts)
6090 self.pg_enable_capture(self.pg_interfaces)
6091 self.pg_start()
6092 capture = self.pg1.get_capture(len(pkts))
6093 self.verify_capture_out_ip6(capture, dst_ip=out_src_ip6,
6094 nat_ip=out_dst_ip6, same_port=True)
6095
6096 pkts = self.create_stream_out_ip6(self.pg1, out_src_ip6, out_dst_ip6)
6097 self.pg1.add_stream(pkts)
6098 self.pg_enable_capture(self.pg_interfaces)
6099 self.pg_start()
6100 capture = self.pg0.get_capture(len(pkts))
6101 self.verify_capture_in(capture, self.pg0)
6102
6103
Martin Gálikd7f75cd2017-03-27 06:02:47 -07006104class TestDeterministicNAT(MethodHolder):
Matus Fabian066f0342017-02-10 03:48:01 -08006105 """ Deterministic NAT Test Cases """
6106
6107 @classmethod
6108 def setUpConstants(cls):
6109 super(TestDeterministicNAT, cls).setUpConstants()
Matus Fabian2ba92e32017-08-21 07:05:03 -07006110 cls.vpp_cmdline.extend(["nat", "{", "deterministic", "}"])
Matus Fabian066f0342017-02-10 03:48:01 -08006111
6112 @classmethod
6113 def setUpClass(cls):
6114 super(TestDeterministicNAT, cls).setUpClass()
Matus Fabian229c1aa2018-05-28 04:09:52 -07006115 cls.vapi.cli("set log class nat level debug")
Matus Fabian066f0342017-02-10 03:48:01 -08006116
6117 try:
Martin Gálik977c1cb2017-03-30 23:21:51 -07006118 cls.tcp_port_in = 6303
Martin Gálik9806eae2017-04-25 01:25:08 -07006119 cls.tcp_external_port = 6303
Martin Gálik977c1cb2017-03-30 23:21:51 -07006120 cls.udp_port_in = 6304
Martin Gálik9806eae2017-04-25 01:25:08 -07006121 cls.udp_external_port = 6304
Martin Gálik977c1cb2017-03-30 23:21:51 -07006122 cls.icmp_id_in = 6305
Matus Fabian2ba92e32017-08-21 07:05:03 -07006123 cls.nat_addr = '10.0.0.3'
Martin Gálik977c1cb2017-03-30 23:21:51 -07006124
Matus Fabian2f2db1c2017-04-18 05:29:59 -07006125 cls.create_pg_interfaces(range(3))
Matus Fabian066f0342017-02-10 03:48:01 -08006126 cls.interfaces = list(cls.pg_interfaces)
6127
6128 for i in cls.interfaces:
6129 i.admin_up()
6130 i.config_ip4()
6131 i.resolve_arp()
6132
Martin Gálik977c1cb2017-03-30 23:21:51 -07006133 cls.pg0.generate_remote_hosts(2)
6134 cls.pg0.configure_ipv4_neighbors()
6135
Matus Fabian066f0342017-02-10 03:48:01 -08006136 except Exception:
6137 super(TestDeterministicNAT, cls).tearDownClass()
6138 raise
6139
Martin Gálik977c1cb2017-03-30 23:21:51 -07006140 def create_stream_in(self, in_if, out_if, ttl=64):
6141 """
6142 Create packet stream for inside network
6143
6144 :param in_if: Inside interface
6145 :param out_if: Outside interface
6146 :param ttl: TTL of generated packets
6147 """
6148 pkts = []
6149 # TCP
6150 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
6151 IP(src=in_if.remote_ip4, dst=out_if.remote_ip4, ttl=ttl) /
Martin Gálik9806eae2017-04-25 01:25:08 -07006152 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port))
Martin Gálik977c1cb2017-03-30 23:21:51 -07006153 pkts.append(p)
6154
6155 # UDP
6156 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
6157 IP(src=in_if.remote_ip4, dst=out_if.remote_ip4, ttl=ttl) /
Martin Gálik9806eae2017-04-25 01:25:08 -07006158 UDP(sport=self.udp_port_in, dport=self.udp_external_port))
Martin Gálik977c1cb2017-03-30 23:21:51 -07006159 pkts.append(p)
6160
6161 # ICMP
6162 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
6163 IP(src=in_if.remote_ip4, dst=out_if.remote_ip4, ttl=ttl) /
6164 ICMP(id=self.icmp_id_in, type='echo-request'))
6165 pkts.append(p)
6166
6167 return pkts
6168
6169 def create_stream_out(self, out_if, dst_ip=None, ttl=64):
6170 """
6171 Create packet stream for outside network
6172
6173 :param out_if: Outside interface
Matus Fabian2ba92e32017-08-21 07:05:03 -07006174 :param dst_ip: Destination IP address (Default use global NAT address)
Martin Gálik977c1cb2017-03-30 23:21:51 -07006175 :param ttl: TTL of generated packets
6176 """
6177 if dst_ip is None:
Matus Fabian2ba92e32017-08-21 07:05:03 -07006178 dst_ip = self.nat_addr
Martin Gálik977c1cb2017-03-30 23:21:51 -07006179 pkts = []
6180 # TCP
6181 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
6182 IP(src=out_if.remote_ip4, dst=dst_ip, ttl=ttl) /
Martin Gálik9806eae2017-04-25 01:25:08 -07006183 TCP(dport=self.tcp_port_out, sport=self.tcp_external_port))
Martin Gálik977c1cb2017-03-30 23:21:51 -07006184 pkts.append(p)
6185
6186 # UDP
6187 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
6188 IP(src=out_if.remote_ip4, dst=dst_ip, ttl=ttl) /
Martin Gálik9806eae2017-04-25 01:25:08 -07006189 UDP(dport=self.udp_port_out, sport=self.udp_external_port))
Martin Gálik977c1cb2017-03-30 23:21:51 -07006190 pkts.append(p)
6191
6192 # ICMP
6193 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
6194 IP(src=out_if.remote_ip4, dst=dst_ip, ttl=ttl) /
6195 ICMP(id=self.icmp_external_id, type='echo-reply'))
6196 pkts.append(p)
6197
6198 return pkts
6199
Matus Fabian05ca4a32018-09-04 23:45:13 -07006200 def verify_capture_out(self, capture, nat_ip=None):
Martin Gálik977c1cb2017-03-30 23:21:51 -07006201 """
6202 Verify captured packets on outside network
6203
6204 :param capture: Captured packets
Matus Fabian2ba92e32017-08-21 07:05:03 -07006205 :param nat_ip: Translated IP address (Default use global NAT address)
Martin Gálik977c1cb2017-03-30 23:21:51 -07006206 :param same_port: Sorce port number is not translated (Default False)
Martin Gálik977c1cb2017-03-30 23:21:51 -07006207 """
6208 if nat_ip is None:
Matus Fabian2ba92e32017-08-21 07:05:03 -07006209 nat_ip = self.nat_addr
Martin Gálik977c1cb2017-03-30 23:21:51 -07006210 for packet in capture:
6211 try:
6212 self.assertEqual(packet[IP].src, nat_ip)
6213 if packet.haslayer(TCP):
Martin Gálik9806eae2017-04-25 01:25:08 -07006214 self.tcp_port_out = packet[TCP].sport
Martin Gálik977c1cb2017-03-30 23:21:51 -07006215 elif packet.haslayer(UDP):
Martin Gálik9806eae2017-04-25 01:25:08 -07006216 self.udp_port_out = packet[UDP].sport
Martin Gálik977c1cb2017-03-30 23:21:51 -07006217 else:
6218 self.icmp_external_id = packet[ICMP].id
6219 except:
6220 self.logger.error(ppp("Unexpected or invalid packet "
6221 "(outside network):", packet))
6222 raise
6223
Matus Fabian066f0342017-02-10 03:48:01 -08006224 def test_deterministic_mode(self):
Matus Fabian2ba92e32017-08-21 07:05:03 -07006225 """ NAT plugin run deterministic mode """
Matus Fabian066f0342017-02-10 03:48:01 -08006226 in_addr = '172.16.255.0'
6227 out_addr = '172.17.255.50'
6228 in_addr_t = '172.16.255.20'
6229 in_addr_n = socket.inet_aton(in_addr)
6230 out_addr_n = socket.inet_aton(out_addr)
6231 in_addr_t_n = socket.inet_aton(in_addr_t)
6232 in_plen = 24
6233 out_plen = 32
6234
Matus Fabian2ba92e32017-08-21 07:05:03 -07006235 nat_config = self.vapi.nat_show_config()
6236 self.assertEqual(1, nat_config.deterministic)
Matus Fabian066f0342017-02-10 03:48:01 -08006237
Matus Fabian2ba92e32017-08-21 07:05:03 -07006238 self.vapi.nat_det_add_del_map(in_addr_n, in_plen, out_addr_n, out_plen)
Matus Fabian066f0342017-02-10 03:48:01 -08006239
Matus Fabian2ba92e32017-08-21 07:05:03 -07006240 rep1 = self.vapi.nat_det_forward(in_addr_t_n)
Matus Fabian066f0342017-02-10 03:48:01 -08006241 self.assertEqual(rep1.out_addr[:4], out_addr_n)
Matus Fabian2ba92e32017-08-21 07:05:03 -07006242 rep2 = self.vapi.nat_det_reverse(out_addr_n, rep1.out_port_hi)
Matus Fabian066f0342017-02-10 03:48:01 -08006243 self.assertEqual(rep2.in_addr[:4], in_addr_t_n)
6244
Matus Fabian2ba92e32017-08-21 07:05:03 -07006245 deterministic_mappings = self.vapi.nat_det_map_dump()
Martin17a75cb2017-03-08 05:53:20 -08006246 self.assertEqual(len(deterministic_mappings), 1)
6247 dsm = deterministic_mappings[0]
6248 self.assertEqual(in_addr_n, dsm.in_addr[:4])
6249 self.assertEqual(in_plen, dsm.in_plen)
6250 self.assertEqual(out_addr_n, dsm.out_addr[:4])
6251 self.assertEqual(out_plen, dsm.out_plen)
6252
Matus Fabian2ba92e32017-08-21 07:05:03 -07006253 self.clear_nat_det()
6254 deterministic_mappings = self.vapi.nat_det_map_dump()
Martinb616e9f2017-03-14 02:25:45 -07006255 self.assertEqual(len(deterministic_mappings), 0)
6256
Matus Fabian6a0946f2017-04-12 03:36:13 -07006257 def test_set_timeouts(self):
6258 """ Set deterministic NAT timeouts """
Matus Fabian878c6462018-08-23 00:33:35 -07006259 timeouts_before = self.vapi.nat_get_timeouts()
Matus Fabian6a0946f2017-04-12 03:36:13 -07006260
Matus Fabian878c6462018-08-23 00:33:35 -07006261 self.vapi.nat_set_timeouts(timeouts_before.udp + 10,
6262 timeouts_before.tcp_established + 10,
6263 timeouts_before.tcp_transitory + 10,
6264 timeouts_before.icmp + 10)
Matus Fabian6a0946f2017-04-12 03:36:13 -07006265
Matus Fabian878c6462018-08-23 00:33:35 -07006266 timeouts_after = self.vapi.nat_get_timeouts()
Matus Fabian6a0946f2017-04-12 03:36:13 -07006267
6268 self.assertNotEqual(timeouts_before.udp, timeouts_after.udp)
6269 self.assertNotEqual(timeouts_before.icmp, timeouts_after.icmp)
6270 self.assertNotEqual(timeouts_before.tcp_established,
6271 timeouts_after.tcp_established)
6272 self.assertNotEqual(timeouts_before.tcp_transitory,
6273 timeouts_after.tcp_transitory)
6274
Martin Gálik977c1cb2017-03-30 23:21:51 -07006275 def test_det_in(self):
Matus Fabian2ba92e32017-08-21 07:05:03 -07006276 """ Deterministic NAT translation test (TCP, UDP, ICMP) """
Martin Gálik977c1cb2017-03-30 23:21:51 -07006277
6278 nat_ip = "10.0.0.10"
Martin Gálik977c1cb2017-03-30 23:21:51 -07006279
Matus Fabian2ba92e32017-08-21 07:05:03 -07006280 self.vapi.nat_det_add_del_map(self.pg0.remote_ip4n,
6281 32,
6282 socket.inet_aton(nat_ip),
6283 32)
6284 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
6285 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
6286 is_inside=0)
Martin Gálik977c1cb2017-03-30 23:21:51 -07006287
6288 # in2out
6289 pkts = self.create_stream_in(self.pg0, self.pg1)
6290 self.pg0.add_stream(pkts)
6291 self.pg_enable_capture(self.pg_interfaces)
6292 self.pg_start()
6293 capture = self.pg1.get_capture(len(pkts))
6294 self.verify_capture_out(capture, nat_ip)
6295
6296 # out2in
6297 pkts = self.create_stream_out(self.pg1, nat_ip)
6298 self.pg1.add_stream(pkts)
6299 self.pg_enable_capture(self.pg_interfaces)
6300 self.pg_start()
6301 capture = self.pg0.get_capture(len(pkts))
6302 self.verify_capture_in(capture, self.pg0)
6303
Martin Gálik9806eae2017-04-25 01:25:08 -07006304 # session dump test
Matus Fabian2ba92e32017-08-21 07:05:03 -07006305 sessions = self.vapi.nat_det_session_dump(self.pg0.remote_ip4n)
Martin Gálik9806eae2017-04-25 01:25:08 -07006306 self.assertEqual(len(sessions), 3)
6307
6308 # TCP session
6309 s = sessions[0]
6310 self.assertEqual(s.ext_addr[:4], self.pg1.remote_ip4n)
6311 self.assertEqual(s.in_port, self.tcp_port_in)
6312 self.assertEqual(s.out_port, self.tcp_port_out)
6313 self.assertEqual(s.ext_port, self.tcp_external_port)
6314
6315 # UDP session
6316 s = sessions[1]
6317 self.assertEqual(s.ext_addr[:4], self.pg1.remote_ip4n)
6318 self.assertEqual(s.in_port, self.udp_port_in)
6319 self.assertEqual(s.out_port, self.udp_port_out)
6320 self.assertEqual(s.ext_port, self.udp_external_port)
6321
6322 # ICMP session
6323 s = sessions[2]
6324 self.assertEqual(s.ext_addr[:4], self.pg1.remote_ip4n)
6325 self.assertEqual(s.in_port, self.icmp_id_in)
6326 self.assertEqual(s.out_port, self.icmp_external_id)
6327
Martin Gálik977c1cb2017-03-30 23:21:51 -07006328 def test_multiple_users(self):
Matus Fabian2ba92e32017-08-21 07:05:03 -07006329 """ Deterministic NAT multiple users """
Martin Gálik977c1cb2017-03-30 23:21:51 -07006330
6331 nat_ip = "10.0.0.10"
6332 port_in = 80
Martin Gálik9806eae2017-04-25 01:25:08 -07006333 external_port = 6303
Martin Gálik977c1cb2017-03-30 23:21:51 -07006334
6335 host0 = self.pg0.remote_hosts[0]
6336 host1 = self.pg0.remote_hosts[1]
6337
Matus Fabian2ba92e32017-08-21 07:05:03 -07006338 self.vapi.nat_det_add_del_map(host0.ip4n,
6339 24,
6340 socket.inet_aton(nat_ip),
6341 32)
6342 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
6343 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
6344 is_inside=0)
Martin Gálik977c1cb2017-03-30 23:21:51 -07006345
6346 # host0 to out
6347 p = (Ether(src=host0.mac, dst=self.pg0.local_mac) /
6348 IP(src=host0.ip4, dst=self.pg1.remote_ip4) /
Martin Gálik9806eae2017-04-25 01:25:08 -07006349 TCP(sport=port_in, dport=external_port))
Martin Gálik977c1cb2017-03-30 23:21:51 -07006350 self.pg0.add_stream(p)
6351 self.pg_enable_capture(self.pg_interfaces)
6352 self.pg_start()
6353 capture = self.pg1.get_capture(1)
6354 p = capture[0]
6355 try:
6356 ip = p[IP]
6357 tcp = p[TCP]
6358 self.assertEqual(ip.src, nat_ip)
6359 self.assertEqual(ip.dst, self.pg1.remote_ip4)
Martin Gálik9806eae2017-04-25 01:25:08 -07006360 self.assertEqual(tcp.dport, external_port)
6361 port_out0 = tcp.sport
Martin Gálik977c1cb2017-03-30 23:21:51 -07006362 except:
6363 self.logger.error(ppp("Unexpected or invalid packet:", p))
6364 raise
6365
6366 # host1 to out
6367 p = (Ether(src=host1.mac, dst=self.pg0.local_mac) /
6368 IP(src=host1.ip4, dst=self.pg1.remote_ip4) /
Martin Gálik9806eae2017-04-25 01:25:08 -07006369 TCP(sport=port_in, dport=external_port))
Martin Gálik977c1cb2017-03-30 23:21:51 -07006370 self.pg0.add_stream(p)
6371 self.pg_enable_capture(self.pg_interfaces)
6372 self.pg_start()
6373 capture = self.pg1.get_capture(1)
6374 p = capture[0]
6375 try:
6376 ip = p[IP]
6377 tcp = p[TCP]
6378 self.assertEqual(ip.src, nat_ip)
6379 self.assertEqual(ip.dst, self.pg1.remote_ip4)
Martin Gálik9806eae2017-04-25 01:25:08 -07006380 self.assertEqual(tcp.dport, external_port)
6381 port_out1 = tcp.sport
Martin Gálik977c1cb2017-03-30 23:21:51 -07006382 except:
6383 self.logger.error(ppp("Unexpected or invalid packet:", p))
6384 raise
6385
Matus Fabian2ba92e32017-08-21 07:05:03 -07006386 dms = self.vapi.nat_det_map_dump()
Martin Gálik977c1cb2017-03-30 23:21:51 -07006387 self.assertEqual(1, len(dms))
6388 self.assertEqual(2, dms[0].ses_num)
6389
6390 # out to host0
6391 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6392 IP(src=self.pg1.remote_ip4, dst=nat_ip) /
Martin Gálik9806eae2017-04-25 01:25:08 -07006393 TCP(sport=external_port, dport=port_out0))
Martin Gálik977c1cb2017-03-30 23:21:51 -07006394 self.pg1.add_stream(p)
6395 self.pg_enable_capture(self.pg_interfaces)
6396 self.pg_start()
6397 capture = self.pg0.get_capture(1)
6398 p = capture[0]
6399 try:
6400 ip = p[IP]
6401 tcp = p[TCP]
6402 self.assertEqual(ip.src, self.pg1.remote_ip4)
6403 self.assertEqual(ip.dst, host0.ip4)
6404 self.assertEqual(tcp.dport, port_in)
Martin Gálik9806eae2017-04-25 01:25:08 -07006405 self.assertEqual(tcp.sport, external_port)
Martin Gálik977c1cb2017-03-30 23:21:51 -07006406 except:
6407 self.logger.error(ppp("Unexpected or invalid packet:", p))
6408 raise
6409
6410 # out to host1
6411 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6412 IP(src=self.pg1.remote_ip4, dst=nat_ip) /
Martin Gálik9806eae2017-04-25 01:25:08 -07006413 TCP(sport=external_port, dport=port_out1))
Martin Gálik977c1cb2017-03-30 23:21:51 -07006414 self.pg1.add_stream(p)
6415 self.pg_enable_capture(self.pg_interfaces)
6416 self.pg_start()
6417 capture = self.pg0.get_capture(1)
6418 p = capture[0]
6419 try:
6420 ip = p[IP]
6421 tcp = p[TCP]
6422 self.assertEqual(ip.src, self.pg1.remote_ip4)
6423 self.assertEqual(ip.dst, host1.ip4)
6424 self.assertEqual(tcp.dport, port_in)
Martin Gálik9806eae2017-04-25 01:25:08 -07006425 self.assertEqual(tcp.sport, external_port)
Martin Gálik977c1cb2017-03-30 23:21:51 -07006426 except:
6427 self.logger.error(ppp("Unexpected or invalid packet", p))
6428 raise
6429
Martin Gálik6bc8c642017-04-19 01:12:27 -07006430 # session close api test
Matus Fabian2ba92e32017-08-21 07:05:03 -07006431 self.vapi.nat_det_close_session_out(socket.inet_aton(nat_ip),
6432 port_out1,
Martin Gálik6bc8c642017-04-19 01:12:27 -07006433 self.pg1.remote_ip4n,
Martin Gálik9806eae2017-04-25 01:25:08 -07006434 external_port)
Matus Fabian2ba92e32017-08-21 07:05:03 -07006435 dms = self.vapi.nat_det_map_dump()
6436 self.assertEqual(dms[0].ses_num, 1)
6437
6438 self.vapi.nat_det_close_session_in(host0.ip4n,
6439 port_in,
6440 self.pg1.remote_ip4n,
6441 external_port)
6442 dms = self.vapi.nat_det_map_dump()
Martin Gálik6bc8c642017-04-19 01:12:27 -07006443 self.assertEqual(dms[0].ses_num, 0)
6444
Martin Gálik977c1cb2017-03-30 23:21:51 -07006445 def test_tcp_session_close_detection_in(self):
Matus Fabian2ba92e32017-08-21 07:05:03 -07006446 """ Deterministic NAT TCP session close from inside network """
6447 self.vapi.nat_det_add_del_map(self.pg0.remote_ip4n,
6448 32,
6449 socket.inet_aton(self.nat_addr),
6450 32)
6451 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
6452 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
6453 is_inside=0)
Martin Gálik977c1cb2017-03-30 23:21:51 -07006454
6455 self.initiate_tcp_session(self.pg0, self.pg1)
6456
6457 # close the session from inside
6458 try:
6459 # FIN packet in -> out
6460 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6461 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
Martin Gálik9806eae2017-04-25 01:25:08 -07006462 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
Martin Gálik977c1cb2017-03-30 23:21:51 -07006463 flags="F"))
6464 self.pg0.add_stream(p)
6465 self.pg_enable_capture(self.pg_interfaces)
6466 self.pg_start()
6467 self.pg1.get_capture(1)
6468
6469 pkts = []
6470
6471 # ACK packet out -> in
6472 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
Matus Fabian2ba92e32017-08-21 07:05:03 -07006473 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
Martin Gálik9806eae2017-04-25 01:25:08 -07006474 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
Martin Gálik977c1cb2017-03-30 23:21:51 -07006475 flags="A"))
6476 pkts.append(p)
6477
6478 # FIN packet out -> in
6479 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
Matus Fabian2ba92e32017-08-21 07:05:03 -07006480 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
Martin Gálik9806eae2017-04-25 01:25:08 -07006481 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
Martin Gálik977c1cb2017-03-30 23:21:51 -07006482 flags="F"))
6483 pkts.append(p)
6484
6485 self.pg1.add_stream(pkts)
6486 self.pg_enable_capture(self.pg_interfaces)
6487 self.pg_start()
6488 self.pg0.get_capture(2)
6489
6490 # ACK packet in -> out
6491 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6492 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
Martin Gálik9806eae2017-04-25 01:25:08 -07006493 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
Martin Gálik977c1cb2017-03-30 23:21:51 -07006494 flags="A"))
6495 self.pg0.add_stream(p)
6496 self.pg_enable_capture(self.pg_interfaces)
6497 self.pg_start()
6498 self.pg1.get_capture(1)
6499
Matus Fabian2ba92e32017-08-21 07:05:03 -07006500 # Check if deterministic NAT44 closed the session
6501 dms = self.vapi.nat_det_map_dump()
Martin Gálik977c1cb2017-03-30 23:21:51 -07006502 self.assertEqual(0, dms[0].ses_num)
6503 except:
6504 self.logger.error("TCP session termination failed")
6505 raise
6506
6507 def test_tcp_session_close_detection_out(self):
Matus Fabian2ba92e32017-08-21 07:05:03 -07006508 """ Deterministic NAT TCP session close from outside network """
6509 self.vapi.nat_det_add_del_map(self.pg0.remote_ip4n,
6510 32,
6511 socket.inet_aton(self.nat_addr),
6512 32)
6513 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
6514 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
6515 is_inside=0)
Martin Gálik977c1cb2017-03-30 23:21:51 -07006516
6517 self.initiate_tcp_session(self.pg0, self.pg1)
6518
6519 # close the session from outside
6520 try:
6521 # FIN packet out -> in
6522 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
Matus Fabian2ba92e32017-08-21 07:05:03 -07006523 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
Martin Gálik9806eae2017-04-25 01:25:08 -07006524 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
Martin Gálik977c1cb2017-03-30 23:21:51 -07006525 flags="F"))
6526 self.pg1.add_stream(p)
6527 self.pg_enable_capture(self.pg_interfaces)
6528 self.pg_start()
6529 self.pg0.get_capture(1)
6530
6531 pkts = []
6532
6533 # ACK packet in -> out
6534 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6535 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
Martin Gálik9806eae2017-04-25 01:25:08 -07006536 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
Martin Gálik977c1cb2017-03-30 23:21:51 -07006537 flags="A"))
6538 pkts.append(p)
6539
6540 # ACK packet in -> out
6541 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6542 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
Martin Gálik9806eae2017-04-25 01:25:08 -07006543 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
Martin Gálik977c1cb2017-03-30 23:21:51 -07006544 flags="F"))
6545 pkts.append(p)
6546
6547 self.pg0.add_stream(pkts)
6548 self.pg_enable_capture(self.pg_interfaces)
6549 self.pg_start()
6550 self.pg1.get_capture(2)
6551
6552 # ACK packet out -> in
6553 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
Matus Fabian2ba92e32017-08-21 07:05:03 -07006554 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
Martin Gálik9806eae2017-04-25 01:25:08 -07006555 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
Martin Gálik977c1cb2017-03-30 23:21:51 -07006556 flags="A"))
6557 self.pg1.add_stream(p)
6558 self.pg_enable_capture(self.pg_interfaces)
6559 self.pg_start()
6560 self.pg0.get_capture(1)
6561
Matus Fabian2ba92e32017-08-21 07:05:03 -07006562 # Check if deterministic NAT44 closed the session
6563 dms = self.vapi.nat_det_map_dump()
Martin Gálik977c1cb2017-03-30 23:21:51 -07006564 self.assertEqual(0, dms[0].ses_num)
6565 except:
6566 self.logger.error("TCP session termination failed")
6567 raise
6568
6569 @unittest.skipUnless(running_extended_tests(), "part of extended tests")
6570 def test_session_timeout(self):
Matus Fabian2ba92e32017-08-21 07:05:03 -07006571 """ Deterministic NAT session timeouts """
6572 self.vapi.nat_det_add_del_map(self.pg0.remote_ip4n,
6573 32,
6574 socket.inet_aton(self.nat_addr),
6575 32)
6576 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
6577 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
6578 is_inside=0)
Martin Gálik977c1cb2017-03-30 23:21:51 -07006579
6580 self.initiate_tcp_session(self.pg0, self.pg1)
Matus Fabian878c6462018-08-23 00:33:35 -07006581 self.vapi.nat_set_timeouts(5, 5, 5, 5)
Martin Gálik977c1cb2017-03-30 23:21:51 -07006582 pkts = self.create_stream_in(self.pg0, self.pg1)
6583 self.pg0.add_stream(pkts)
6584 self.pg_enable_capture(self.pg_interfaces)
6585 self.pg_start()
6586 capture = self.pg1.get_capture(len(pkts))
6587 sleep(15)
6588
Matus Fabian2ba92e32017-08-21 07:05:03 -07006589 dms = self.vapi.nat_det_map_dump()
Martin Gálik977c1cb2017-03-30 23:21:51 -07006590 self.assertEqual(0, dms[0].ses_num)
6591
Matus Fabian7c0aecc2017-07-03 01:21:38 -07006592 @unittest.skipUnless(running_extended_tests(), "part of extended tests")
Martin Gálik977c1cb2017-03-30 23:21:51 -07006593 def test_session_limit_per_user(self):
Matus Fabian2ba92e32017-08-21 07:05:03 -07006594 """ Deterministic NAT maximum sessions per user limit """
6595 self.vapi.nat_det_add_del_map(self.pg0.remote_ip4n,
6596 32,
6597 socket.inet_aton(self.nat_addr),
6598 32)
6599 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
6600 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
6601 is_inside=0)
Matus Fabian2f2db1c2017-04-18 05:29:59 -07006602 self.vapi.set_ipfix_exporter(collector_address=self.pg2.remote_ip4n,
6603 src_address=self.pg2.local_ip4n,
6604 path_mtu=512,
6605 template_interval=10)
Matus Fabian2ba92e32017-08-21 07:05:03 -07006606 self.vapi.nat_ipfix()
Martin Gálik977c1cb2017-03-30 23:21:51 -07006607
6608 pkts = []
6609 for port in range(1025, 2025):
6610 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6611 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6612 UDP(sport=port, dport=port))
6613 pkts.append(p)
6614
6615 self.pg0.add_stream(pkts)
6616 self.pg_enable_capture(self.pg_interfaces)
6617 self.pg_start()
6618 capture = self.pg1.get_capture(len(pkts))
6619
6620 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6621 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
Martin Gálikf7e655d2017-04-27 02:13:26 -07006622 UDP(sport=3001, dport=3002))
Martin Gálik977c1cb2017-03-30 23:21:51 -07006623 self.pg0.add_stream(p)
6624 self.pg_enable_capture(self.pg_interfaces)
6625 self.pg_start()
6626 capture = self.pg1.assert_nothing_captured()
6627
Martin Gálikf7e655d2017-04-27 02:13:26 -07006628 # verify ICMP error packet
6629 capture = self.pg0.get_capture(1)
6630 p = capture[0]
6631 self.assertTrue(p.haslayer(ICMP))
6632 icmp = p[ICMP]
6633 self.assertEqual(icmp.type, 3)
6634 self.assertEqual(icmp.code, 1)
6635 self.assertTrue(icmp.haslayer(IPerror))
6636 inner_ip = icmp[IPerror]
6637 self.assertEqual(inner_ip[UDPerror].sport, 3001)
6638 self.assertEqual(inner_ip[UDPerror].dport, 3002)
6639
Matus Fabian2ba92e32017-08-21 07:05:03 -07006640 dms = self.vapi.nat_det_map_dump()
Martin Gálik977c1cb2017-03-30 23:21:51 -07006641
6642 self.assertEqual(1000, dms[0].ses_num)
6643
Matus Fabian2f2db1c2017-04-18 05:29:59 -07006644 # verify IPFIX logging
6645 self.vapi.cli("ipfix flush") # FIXME this should be an API call
Matus Fabian7c0aecc2017-07-03 01:21:38 -07006646 sleep(1)
Matus Fabian2f2db1c2017-04-18 05:29:59 -07006647 capture = self.pg2.get_capture(2)
6648 ipfix = IPFIXDecoder()
6649 # first load template
6650 for p in capture:
6651 self.assertTrue(p.haslayer(IPFIX))
6652 if p.haslayer(Template):
6653 ipfix.add_template(p.getlayer(Template))
6654 # verify events in data set
6655 for p in capture:
6656 if p.haslayer(Data):
6657 data = ipfix.decode_data_set(p.getlayer(Set))
Matus Fabian878c6462018-08-23 00:33:35 -07006658 self.verify_ipfix_max_entries_per_user(data,
6659 1000,
6660 self.pg0.remote_ip4n)
Matus Fabian2f2db1c2017-04-18 05:29:59 -07006661
Matus Fabian2ba92e32017-08-21 07:05:03 -07006662 def clear_nat_det(self):
Martin17a75cb2017-03-08 05:53:20 -08006663 """
Matus Fabian2ba92e32017-08-21 07:05:03 -07006664 Clear deterministic NAT configuration.
Martin17a75cb2017-03-08 05:53:20 -08006665 """
Matus Fabian2ba92e32017-08-21 07:05:03 -07006666 self.vapi.nat_ipfix(enable=0)
Matus Fabian878c6462018-08-23 00:33:35 -07006667 self.vapi.nat_set_timeouts()
Matus Fabian2ba92e32017-08-21 07:05:03 -07006668 deterministic_mappings = self.vapi.nat_det_map_dump()
Martin17a75cb2017-03-08 05:53:20 -08006669 for dsm in deterministic_mappings:
Matus Fabian2ba92e32017-08-21 07:05:03 -07006670 self.vapi.nat_det_add_del_map(dsm.in_addr,
6671 dsm.in_plen,
6672 dsm.out_addr,
6673 dsm.out_plen,
6674 is_add=0)
Martin17a75cb2017-03-08 05:53:20 -08006675
Matus Fabian2ba92e32017-08-21 07:05:03 -07006676 interfaces = self.vapi.nat44_interface_dump()
Martin Gálik977c1cb2017-03-30 23:21:51 -07006677 for intf in interfaces:
Matus Fabian2ba92e32017-08-21 07:05:03 -07006678 self.vapi.nat44_interface_add_del_feature(intf.sw_if_index,
6679 intf.is_inside,
6680 is_add=0)
Martin Gálik977c1cb2017-03-30 23:21:51 -07006681
Matus Fabian066f0342017-02-10 03:48:01 -08006682 def tearDown(self):
6683 super(TestDeterministicNAT, self).tearDown()
6684 if not self.vpp_dead:
Matus Fabian82119542018-01-25 01:13:22 -08006685 self.logger.info(self.vapi.cli("show nat44 interfaces"))
Matus Fabian878c6462018-08-23 00:33:35 -07006686 self.logger.info(self.vapi.cli("show nat timeouts"))
Matus Fabian82119542018-01-25 01:13:22 -08006687 self.logger.info(
6688 self.vapi.cli("show nat44 deterministic mappings"))
6689 self.logger.info(
Matus Fabian82119542018-01-25 01:13:22 -08006690 self.vapi.cli("show nat44 deterministic sessions"))
Matus Fabian2ba92e32017-08-21 07:05:03 -07006691 self.clear_nat_det()
Matus Fabian066f0342017-02-10 03:48:01 -08006692
Matus Fabian06596c52017-06-06 04:53:28 -07006693
6694class TestNAT64(MethodHolder):
6695 """ NAT64 Test Cases """
6696
6697 @classmethod
Matus Fabiana431ad12018-01-04 04:03:14 -08006698 def setUpConstants(cls):
6699 super(TestNAT64, cls).setUpConstants()
6700 cls.vpp_cmdline.extend(["nat", "{", "nat64 bib hash buckets 128",
6701 "nat64 st hash buckets 256", "}"])
6702
6703 @classmethod
Matus Fabian06596c52017-06-06 04:53:28 -07006704 def setUpClass(cls):
6705 super(TestNAT64, cls).setUpClass()
6706
6707 try:
6708 cls.tcp_port_in = 6303
6709 cls.tcp_port_out = 6303
6710 cls.udp_port_in = 6304
6711 cls.udp_port_out = 6304
6712 cls.icmp_id_in = 6305
6713 cls.icmp_id_out = 6305
Matus Fabianad1f3e12018-11-28 21:26:34 -08006714 cls.tcp_external_port = 80
Matus Fabian06596c52017-06-06 04:53:28 -07006715 cls.nat_addr = '10.0.0.3'
6716 cls.nat_addr_n = socket.inet_pton(socket.AF_INET, cls.nat_addr)
Matus Fabian029f3d22017-06-15 02:28:50 -07006717 cls.vrf1_id = 10
6718 cls.vrf1_nat_addr = '10.0.10.3'
6719 cls.vrf1_nat_addr_n = socket.inet_pton(socket.AF_INET,
6720 cls.vrf1_nat_addr)
Matus Fabiana431ad12018-01-04 04:03:14 -08006721 cls.ipfix_src_port = 4739
6722 cls.ipfix_domain_id = 1
Matus Fabian06596c52017-06-06 04:53:28 -07006723
Juraj Slobodac746a152018-07-09 02:36:37 +02006724 cls.create_pg_interfaces(range(6))
Matus Fabian06596c52017-06-06 04:53:28 -07006725 cls.ip6_interfaces = list(cls.pg_interfaces[0:1])
Matus Fabian029f3d22017-06-15 02:28:50 -07006726 cls.ip6_interfaces.append(cls.pg_interfaces[2])
Matus Fabian06596c52017-06-06 04:53:28 -07006727 cls.ip4_interfaces = list(cls.pg_interfaces[1:2])
6728
Neale Ranns15002542017-09-10 04:39:11 -07006729 cls.vapi.ip_table_add_del(cls.vrf1_id, is_add=1, is_ipv6=1)
6730
Matus Fabian029f3d22017-06-15 02:28:50 -07006731 cls.pg_interfaces[2].set_table_ip6(cls.vrf1_id)
6732
6733 cls.pg0.generate_remote_hosts(2)
6734
Matus Fabian06596c52017-06-06 04:53:28 -07006735 for i in cls.ip6_interfaces:
6736 i.admin_up()
6737 i.config_ip6()
Matus Fabian029f3d22017-06-15 02:28:50 -07006738 i.configure_ipv6_neighbors()
Matus Fabian06596c52017-06-06 04:53:28 -07006739
6740 for i in cls.ip4_interfaces:
6741 i.admin_up()
6742 i.config_ip4()
6743 i.resolve_arp()
6744
Matus Fabian36ea2d62017-10-24 04:13:49 -07006745 cls.pg3.admin_up()
6746 cls.pg3.config_ip4()
6747 cls.pg3.resolve_arp()
6748 cls.pg3.config_ip6()
6749 cls.pg3.configure_ipv6_neighbors()
6750
Juraj Slobodac746a152018-07-09 02:36:37 +02006751 cls.pg5.admin_up()
6752 cls.pg5.config_ip6()
6753
Matus Fabian06596c52017-06-06 04:53:28 -07006754 except Exception:
6755 super(TestNAT64, cls).tearDownClass()
6756 raise
6757
Juraj Slobodac746a152018-07-09 02:36:37 +02006758 def test_nat64_inside_interface_handles_neighbor_advertisement(self):
6759 """ NAT64 inside interface handles Neighbor Advertisement """
6760
6761 self.vapi.nat64_add_del_interface(self.pg5.sw_if_index)
6762
6763 # Try to send ping
6764 ping = (Ether(dst=self.pg5.local_mac, src=self.pg5.remote_mac) /
6765 IPv6(src=self.pg5.remote_ip6, dst=self.pg5.local_ip6) /
6766 ICMPv6EchoRequest())
6767 pkts = [ping]
6768 self.pg5.add_stream(pkts)
6769 self.pg_enable_capture(self.pg_interfaces)
6770 self.pg_start()
6771
6772 # Wait for Neighbor Solicitation
6773 capture = self.pg5.get_capture(len(pkts))
Juraj Slobodac746a152018-07-09 02:36:37 +02006774 packet = capture[0]
6775 try:
6776 self.assertEqual(packet[IPv6].src, self.pg5.local_ip6)
Paul Vinciguerra978aa642018-11-24 22:19:12 -08006777 self.assertEqual(packet.haslayer(ICMPv6ND_NS), 1)
Juraj Slobodac746a152018-07-09 02:36:37 +02006778 tgt = packet[ICMPv6ND_NS].tgt
6779 except:
6780 self.logger.error(ppp("Unexpected or invalid packet:", packet))
6781 raise
6782
6783 # Send Neighbor Advertisement
6784 p = (Ether(dst=self.pg5.local_mac, src=self.pg5.remote_mac) /
6785 IPv6(src=self.pg5.remote_ip6, dst=self.pg5.local_ip6) /
6786 ICMPv6ND_NA(tgt=tgt) /
6787 ICMPv6NDOptDstLLAddr(lladdr=self.pg5.remote_mac))
6788 pkts = [p]
6789 self.pg5.add_stream(pkts)
6790 self.pg_enable_capture(self.pg_interfaces)
6791 self.pg_start()
6792
6793 # Try to send ping again
6794 pkts = [ping]
6795 self.pg5.add_stream(pkts)
6796 self.pg_enable_capture(self.pg_interfaces)
6797 self.pg_start()
6798
6799 # Wait for ping reply
6800 capture = self.pg5.get_capture(len(pkts))
Juraj Slobodac746a152018-07-09 02:36:37 +02006801 packet = capture[0]
6802 try:
6803 self.assertEqual(packet[IPv6].src, self.pg5.local_ip6)
6804 self.assertEqual(packet[IPv6].dst, self.pg5.remote_ip6)
Paul Vinciguerra978aa642018-11-24 22:19:12 -08006805 self.assertEqual(packet.haslayer(ICMPv6EchoReply), 1)
Juraj Slobodac746a152018-07-09 02:36:37 +02006806 except:
6807 self.logger.error(ppp("Unexpected or invalid packet:", packet))
6808 raise
6809
Matus Fabian06596c52017-06-06 04:53:28 -07006810 def test_pool(self):
6811 """ Add/delete address to NAT64 pool """
6812 nat_addr = socket.inet_pton(socket.AF_INET, '1.2.3.4')
6813
6814 self.vapi.nat64_add_del_pool_addr_range(nat_addr, nat_addr)
6815
6816 addresses = self.vapi.nat64_pool_addr_dump()
6817 self.assertEqual(len(addresses), 1)
6818 self.assertEqual(addresses[0].address, nat_addr)
6819
6820 self.vapi.nat64_add_del_pool_addr_range(nat_addr, nat_addr, is_add=0)
6821
6822 addresses = self.vapi.nat64_pool_addr_dump()
6823 self.assertEqual(len(addresses), 0)
6824
6825 def test_interface(self):
6826 """ Enable/disable NAT64 feature on the interface """
6827 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
6828 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
6829
6830 interfaces = self.vapi.nat64_interface_dump()
6831 self.assertEqual(len(interfaces), 2)
6832 pg0_found = False
6833 pg1_found = False
6834 for intf in interfaces:
6835 if intf.sw_if_index == self.pg0.sw_if_index:
6836 self.assertEqual(intf.is_inside, 1)
6837 pg0_found = True
6838 elif intf.sw_if_index == self.pg1.sw_if_index:
6839 self.assertEqual(intf.is_inside, 0)
6840 pg1_found = True
6841 self.assertTrue(pg0_found)
6842 self.assertTrue(pg1_found)
6843
6844 features = self.vapi.cli("show interface features pg0")
6845 self.assertNotEqual(features.find('nat64-in2out'), -1)
6846 features = self.vapi.cli("show interface features pg1")
6847 self.assertNotEqual(features.find('nat64-out2in'), -1)
6848
6849 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index, is_add=0)
6850 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_add=0)
6851
6852 interfaces = self.vapi.nat64_interface_dump()
6853 self.assertEqual(len(interfaces), 0)
6854
6855 def test_static_bib(self):
6856 """ Add/delete static BIB entry """
6857 in_addr = socket.inet_pton(socket.AF_INET6,
6858 '2001:db8:85a3::8a2e:370:7334')
6859 out_addr = socket.inet_pton(socket.AF_INET, '10.1.1.3')
6860 in_port = 1234
6861 out_port = 5678
6862 proto = IP_PROTOS.tcp
6863
6864 self.vapi.nat64_add_del_static_bib(in_addr,
6865 out_addr,
6866 in_port,
6867 out_port,
6868 proto)
6869 bib = self.vapi.nat64_bib_dump(IP_PROTOS.tcp)
6870 static_bib_num = 0
6871 for bibe in bib:
6872 if bibe.is_static:
6873 static_bib_num += 1
6874 self.assertEqual(bibe.i_addr, in_addr)
6875 self.assertEqual(bibe.o_addr, out_addr)
6876 self.assertEqual(bibe.i_port, in_port)
6877 self.assertEqual(bibe.o_port, out_port)
6878 self.assertEqual(static_bib_num, 1)
6879
6880 self.vapi.nat64_add_del_static_bib(in_addr,
6881 out_addr,
6882 in_port,
6883 out_port,
6884 proto,
6885 is_add=0)
6886 bib = self.vapi.nat64_bib_dump(IP_PROTOS.tcp)
6887 static_bib_num = 0
6888 for bibe in bib:
6889 if bibe.is_static:
6890 static_bib_num += 1
6891 self.assertEqual(static_bib_num, 0)
6892
6893 def test_set_timeouts(self):
6894 """ Set NAT64 timeouts """
6895 # verify default values
Matus Fabian878c6462018-08-23 00:33:35 -07006896 timeouts = self.vapi.nat_get_timeouts()
Matus Fabian06596c52017-06-06 04:53:28 -07006897 self.assertEqual(timeouts.udp, 300)
6898 self.assertEqual(timeouts.icmp, 60)
Matus Fabian878c6462018-08-23 00:33:35 -07006899 self.assertEqual(timeouts.tcp_transitory, 240)
6900 self.assertEqual(timeouts.tcp_established, 7440)
Matus Fabian06596c52017-06-06 04:53:28 -07006901
6902 # set and verify custom values
Matus Fabian878c6462018-08-23 00:33:35 -07006903 self.vapi.nat_set_timeouts(udp=200, icmp=30, tcp_transitory=250,
6904 tcp_established=7450)
6905 timeouts = self.vapi.nat_get_timeouts()
Matus Fabian06596c52017-06-06 04:53:28 -07006906 self.assertEqual(timeouts.udp, 200)
6907 self.assertEqual(timeouts.icmp, 30)
Matus Fabian878c6462018-08-23 00:33:35 -07006908 self.assertEqual(timeouts.tcp_transitory, 250)
6909 self.assertEqual(timeouts.tcp_established, 7450)
Matus Fabian06596c52017-06-06 04:53:28 -07006910
6911 def test_dynamic(self):
6912 """ NAT64 dynamic translation test """
6913 self.tcp_port_in = 6303
6914 self.udp_port_in = 6304
6915 self.icmp_id_in = 6305
6916
6917 ses_num_start = self.nat64_get_ses_num()
6918
6919 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
6920 self.nat_addr_n)
6921 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
6922 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
6923
6924 # in2out
Matus Fabiana5e73762018-12-14 01:55:16 -08006925 tcpn = self.statistics.get_counter('/err/nat64-in2out/TCP packets')
6926 udpn = self.statistics.get_counter('/err/nat64-in2out/UDP packets')
6927 icmpn = self.statistics.get_counter('/err/nat64-in2out/ICMP packets')
6928 totaln = self.statistics.get_counter(
6929 '/err/nat64-in2out/good in2out packets processed')
6930
Matus Fabian06596c52017-06-06 04:53:28 -07006931 pkts = self.create_stream_in_ip6(self.pg0, self.pg1)
6932 self.pg0.add_stream(pkts)
6933 self.pg_enable_capture(self.pg_interfaces)
6934 self.pg_start()
Matus Fabian029f3d22017-06-15 02:28:50 -07006935 capture = self.pg1.get_capture(len(pkts))
6936 self.verify_capture_out(capture, nat_ip=self.nat_addr,
Matus Fabian06596c52017-06-06 04:53:28 -07006937 dst_ip=self.pg1.remote_ip4)
6938
Matus Fabiana5e73762018-12-14 01:55:16 -08006939 err = self.statistics.get_counter('/err/nat64-in2out/TCP packets')
6940 self.assertEqual(err - tcpn, 1)
6941 err = self.statistics.get_counter('/err/nat64-in2out/UDP packets')
6942 self.assertEqual(err - udpn, 1)
6943 err = self.statistics.get_counter('/err/nat64-in2out/ICMP packets')
6944 self.assertEqual(err - icmpn, 1)
6945 err = self.statistics.get_counter(
6946 '/err/nat64-in2out/good in2out packets processed')
6947 self.assertEqual(err - totaln, 3)
6948
Matus Fabian06596c52017-06-06 04:53:28 -07006949 # out2in
Matus Fabiana5e73762018-12-14 01:55:16 -08006950 tcpn = self.statistics.get_counter('/err/nat64-out2in/TCP packets')
6951 udpn = self.statistics.get_counter('/err/nat64-out2in/UDP packets')
6952 icmpn = self.statistics.get_counter('/err/nat64-out2in/ICMP packets')
6953 totaln = self.statistics.get_counter(
6954 '/err/nat64-out2in/good out2in packets processed')
6955
Matus Fabian06596c52017-06-06 04:53:28 -07006956 pkts = self.create_stream_out(self.pg1, dst_ip=self.nat_addr)
6957 self.pg1.add_stream(pkts)
6958 self.pg_enable_capture(self.pg_interfaces)
6959 self.pg_start()
Matus Fabian029f3d22017-06-15 02:28:50 -07006960 capture = self.pg0.get_capture(len(pkts))
Matus Fabian06596c52017-06-06 04:53:28 -07006961 ip = IPv6(src=''.join(['64:ff9b::', self.pg1.remote_ip4]))
6962 self.verify_capture_in_ip6(capture, ip[IPv6].src, self.pg0.remote_ip6)
6963
Matus Fabiana5e73762018-12-14 01:55:16 -08006964 err = self.statistics.get_counter('/err/nat64-out2in/TCP packets')
6965 self.assertEqual(err - tcpn, 1)
6966 err = self.statistics.get_counter('/err/nat64-out2in/UDP packets')
6967 self.assertEqual(err - udpn, 1)
6968 err = self.statistics.get_counter('/err/nat64-out2in/ICMP packets')
6969 self.assertEqual(err - icmpn, 1)
6970 err = self.statistics.get_counter(
6971 '/err/nat64-out2in/good out2in packets processed')
6972 self.assertEqual(err - totaln, 3)
6973
Matus Fabian06596c52017-06-06 04:53:28 -07006974 # in2out
6975 pkts = self.create_stream_in_ip6(self.pg0, self.pg1)
6976 self.pg0.add_stream(pkts)
6977 self.pg_enable_capture(self.pg_interfaces)
6978 self.pg_start()
Matus Fabian029f3d22017-06-15 02:28:50 -07006979 capture = self.pg1.get_capture(len(pkts))
6980 self.verify_capture_out(capture, nat_ip=self.nat_addr,
Matus Fabian06596c52017-06-06 04:53:28 -07006981 dst_ip=self.pg1.remote_ip4)
6982
6983 # out2in
6984 pkts = self.create_stream_out(self.pg1, dst_ip=self.nat_addr)
6985 self.pg1.add_stream(pkts)
6986 self.pg_enable_capture(self.pg_interfaces)
6987 self.pg_start()
Matus Fabian029f3d22017-06-15 02:28:50 -07006988 capture = self.pg0.get_capture(len(pkts))
Matus Fabian06596c52017-06-06 04:53:28 -07006989 self.verify_capture_in_ip6(capture, ip[IPv6].src, self.pg0.remote_ip6)
6990
6991 ses_num_end = self.nat64_get_ses_num()
6992
6993 self.assertEqual(ses_num_end - ses_num_start, 3)
6994
Matus Fabian029f3d22017-06-15 02:28:50 -07006995 # tenant with specific VRF
6996 self.vapi.nat64_add_del_pool_addr_range(self.vrf1_nat_addr_n,
6997 self.vrf1_nat_addr_n,
6998 vrf_id=self.vrf1_id)
6999 self.vapi.nat64_add_del_interface(self.pg2.sw_if_index)
7000
7001 pkts = self.create_stream_in_ip6(self.pg2, self.pg1)
7002 self.pg2.add_stream(pkts)
7003 self.pg_enable_capture(self.pg_interfaces)
7004 self.pg_start()
7005 capture = self.pg1.get_capture(len(pkts))
7006 self.verify_capture_out(capture, nat_ip=self.vrf1_nat_addr,
7007 dst_ip=self.pg1.remote_ip4)
7008
7009 pkts = self.create_stream_out(self.pg1, dst_ip=self.vrf1_nat_addr)
7010 self.pg1.add_stream(pkts)
7011 self.pg_enable_capture(self.pg_interfaces)
7012 self.pg_start()
7013 capture = self.pg2.get_capture(len(pkts))
7014 self.verify_capture_in_ip6(capture, ip[IPv6].src, self.pg2.remote_ip6)
7015
Matus Fabian06596c52017-06-06 04:53:28 -07007016 def test_static(self):
7017 """ NAT64 static translation test """
7018 self.tcp_port_in = 60303
7019 self.udp_port_in = 60304
7020 self.icmp_id_in = 60305
7021 self.tcp_port_out = 60303
7022 self.udp_port_out = 60304
7023 self.icmp_id_out = 60305
7024
7025 ses_num_start = self.nat64_get_ses_num()
7026
7027 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
7028 self.nat_addr_n)
7029 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
7030 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
7031
7032 self.vapi.nat64_add_del_static_bib(self.pg0.remote_ip6n,
7033 self.nat_addr_n,
7034 self.tcp_port_in,
7035 self.tcp_port_out,
7036 IP_PROTOS.tcp)
7037 self.vapi.nat64_add_del_static_bib(self.pg0.remote_ip6n,
7038 self.nat_addr_n,
7039 self.udp_port_in,
7040 self.udp_port_out,
7041 IP_PROTOS.udp)
7042 self.vapi.nat64_add_del_static_bib(self.pg0.remote_ip6n,
7043 self.nat_addr_n,
7044 self.icmp_id_in,
7045 self.icmp_id_out,
7046 IP_PROTOS.icmp)
7047
7048 # in2out
7049 pkts = self.create_stream_in_ip6(self.pg0, self.pg1)
7050 self.pg0.add_stream(pkts)
7051 self.pg_enable_capture(self.pg_interfaces)
7052 self.pg_start()
Matus Fabian029f3d22017-06-15 02:28:50 -07007053 capture = self.pg1.get_capture(len(pkts))
7054 self.verify_capture_out(capture, nat_ip=self.nat_addr,
Matus Fabian06596c52017-06-06 04:53:28 -07007055 dst_ip=self.pg1.remote_ip4, same_port=True)
7056
7057 # out2in
7058 pkts = self.create_stream_out(self.pg1, dst_ip=self.nat_addr)
7059 self.pg1.add_stream(pkts)
7060 self.pg_enable_capture(self.pg_interfaces)
7061 self.pg_start()
Matus Fabian029f3d22017-06-15 02:28:50 -07007062 capture = self.pg0.get_capture(len(pkts))
Matus Fabian06596c52017-06-06 04:53:28 -07007063 ip = IPv6(src=''.join(['64:ff9b::', self.pg1.remote_ip4]))
7064 self.verify_capture_in_ip6(capture, ip[IPv6].src, self.pg0.remote_ip6)
7065
7066 ses_num_end = self.nat64_get_ses_num()
7067
7068 self.assertEqual(ses_num_end - ses_num_start, 3)
7069
7070 @unittest.skipUnless(running_extended_tests(), "part of extended tests")
7071 def test_session_timeout(self):
7072 """ NAT64 session timeout """
7073 self.icmp_id_in = 1234
7074 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
7075 self.nat_addr_n)
7076 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
7077 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
Matus Fabian878c6462018-08-23 00:33:35 -07007078 self.vapi.nat_set_timeouts(icmp=5, tcp_transitory=5, tcp_established=5)
Matus Fabian06596c52017-06-06 04:53:28 -07007079
7080 pkts = self.create_stream_in_ip6(self.pg0, self.pg1)
7081 self.pg0.add_stream(pkts)
7082 self.pg_enable_capture(self.pg_interfaces)
7083 self.pg_start()
Matus Fabian029f3d22017-06-15 02:28:50 -07007084 capture = self.pg1.get_capture(len(pkts))
Matus Fabian06596c52017-06-06 04:53:28 -07007085
7086 ses_num_before_timeout = self.nat64_get_ses_num()
7087
7088 sleep(15)
7089
Matus Fabian8fed4242018-08-14 05:14:55 -07007090 # ICMP and TCP session after timeout
Matus Fabian06596c52017-06-06 04:53:28 -07007091 ses_num_after_timeout = self.nat64_get_ses_num()
Matus Fabian8fed4242018-08-14 05:14:55 -07007092 self.assertEqual(ses_num_before_timeout - ses_num_after_timeout, 2)
Matus Fabian06596c52017-06-06 04:53:28 -07007093
Matus Fabian732036d2017-06-08 05:24:28 -07007094 def test_icmp_error(self):
7095 """ NAT64 ICMP Error message translation """
7096 self.tcp_port_in = 6303
7097 self.udp_port_in = 6304
7098 self.icmp_id_in = 6305
7099
Matus Fabian732036d2017-06-08 05:24:28 -07007100 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
7101 self.nat_addr_n)
7102 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
7103 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
7104
7105 # send some packets to create sessions
7106 pkts = self.create_stream_in_ip6(self.pg0, self.pg1)
7107 self.pg0.add_stream(pkts)
7108 self.pg_enable_capture(self.pg_interfaces)
7109 self.pg_start()
7110 capture_ip4 = self.pg1.get_capture(len(pkts))
Matus Fabian029f3d22017-06-15 02:28:50 -07007111 self.verify_capture_out(capture_ip4,
Matus Fabian732036d2017-06-08 05:24:28 -07007112 nat_ip=self.nat_addr,
7113 dst_ip=self.pg1.remote_ip4)
7114
7115 pkts = self.create_stream_out(self.pg1, dst_ip=self.nat_addr)
7116 self.pg1.add_stream(pkts)
7117 self.pg_enable_capture(self.pg_interfaces)
7118 self.pg_start()
7119 capture_ip6 = self.pg0.get_capture(len(pkts))
7120 ip = IPv6(src=''.join(['64:ff9b::', self.pg1.remote_ip4]))
7121 self.verify_capture_in_ip6(capture_ip6, ip[IPv6].src,
7122 self.pg0.remote_ip6)
7123
7124 # in2out
7125 pkts = [Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
7126 IPv6(src=self.pg0.remote_ip6, dst=ip[IPv6].src) /
7127 ICMPv6DestUnreach(code=1) /
7128 packet[IPv6] for packet in capture_ip6]
7129 self.pg0.add_stream(pkts)
7130 self.pg_enable_capture(self.pg_interfaces)
7131 self.pg_start()
7132 capture = self.pg1.get_capture(len(pkts))
7133 for packet in capture:
7134 try:
7135 self.assertEqual(packet[IP].src, self.nat_addr)
7136 self.assertEqual(packet[IP].dst, self.pg1.remote_ip4)
7137 self.assertEqual(packet[ICMP].type, 3)
7138 self.assertEqual(packet[ICMP].code, 13)
7139 inner = packet[IPerror]
7140 self.assertEqual(inner.src, self.pg1.remote_ip4)
7141 self.assertEqual(inner.dst, self.nat_addr)
Klement Sekerad81ae412018-05-16 10:52:54 +02007142 self.assert_packet_checksums_valid(packet)
Matus Fabian732036d2017-06-08 05:24:28 -07007143 if inner.haslayer(TCPerror):
7144 self.assertEqual(inner[TCPerror].dport, self.tcp_port_out)
7145 elif inner.haslayer(UDPerror):
7146 self.assertEqual(inner[UDPerror].dport, self.udp_port_out)
7147 else:
7148 self.assertEqual(inner[ICMPerror].id, self.icmp_id_out)
7149 except:
7150 self.logger.error(ppp("Unexpected or invalid packet:", packet))
7151 raise
7152
7153 # out2in
7154 pkts = [Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
7155 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
7156 ICMP(type=3, code=13) /
7157 packet[IP] for packet in capture_ip4]
7158 self.pg1.add_stream(pkts)
7159 self.pg_enable_capture(self.pg_interfaces)
7160 self.pg_start()
7161 capture = self.pg0.get_capture(len(pkts))
7162 for packet in capture:
7163 try:
7164 self.assertEqual(packet[IPv6].src, ip.src)
7165 self.assertEqual(packet[IPv6].dst, self.pg0.remote_ip6)
7166 icmp = packet[ICMPv6DestUnreach]
7167 self.assertEqual(icmp.code, 1)
7168 inner = icmp[IPerror6]
7169 self.assertEqual(inner.src, self.pg0.remote_ip6)
7170 self.assertEqual(inner.dst, ip.src)
Klement Sekerad81ae412018-05-16 10:52:54 +02007171 self.assert_icmpv6_checksum_valid(packet)
Matus Fabian732036d2017-06-08 05:24:28 -07007172 if inner.haslayer(TCPerror):
7173 self.assertEqual(inner[TCPerror].sport, self.tcp_port_in)
7174 elif inner.haslayer(UDPerror):
7175 self.assertEqual(inner[UDPerror].sport, self.udp_port_in)
7176 else:
7177 self.assertEqual(inner[ICMPv6EchoRequest].id,
7178 self.icmp_id_in)
7179 except:
7180 self.logger.error(ppp("Unexpected or invalid packet:", packet))
7181 raise
7182
Matus Fabian029f3d22017-06-15 02:28:50 -07007183 def test_hairpinning(self):
7184 """ NAT64 hairpinning """
7185
7186 client = self.pg0.remote_hosts[0]
7187 server = self.pg0.remote_hosts[1]
7188 server_tcp_in_port = 22
7189 server_tcp_out_port = 4022
7190 server_udp_in_port = 23
7191 server_udp_out_port = 4023
7192 client_tcp_in_port = 1234
7193 client_udp_in_port = 1235
7194 client_tcp_out_port = 0
7195 client_udp_out_port = 0
7196 ip = IPv6(src=''.join(['64:ff9b::', self.nat_addr]))
7197 nat_addr_ip6 = ip.src
7198
7199 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
7200 self.nat_addr_n)
7201 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
7202 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
7203
7204 self.vapi.nat64_add_del_static_bib(server.ip6n,
7205 self.nat_addr_n,
7206 server_tcp_in_port,
7207 server_tcp_out_port,
7208 IP_PROTOS.tcp)
7209 self.vapi.nat64_add_del_static_bib(server.ip6n,
7210 self.nat_addr_n,
7211 server_udp_in_port,
7212 server_udp_out_port,
7213 IP_PROTOS.udp)
7214
7215 # client to server
7216 pkts = []
7217 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
7218 IPv6(src=client.ip6, dst=nat_addr_ip6) /
7219 TCP(sport=client_tcp_in_port, dport=server_tcp_out_port))
7220 pkts.append(p)
7221 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
7222 IPv6(src=client.ip6, dst=nat_addr_ip6) /
7223 UDP(sport=client_udp_in_port, dport=server_udp_out_port))
7224 pkts.append(p)
7225 self.pg0.add_stream(pkts)
7226 self.pg_enable_capture(self.pg_interfaces)
7227 self.pg_start()
7228 capture = self.pg0.get_capture(len(pkts))
7229 for packet in capture:
7230 try:
7231 self.assertEqual(packet[IPv6].src, nat_addr_ip6)
7232 self.assertEqual(packet[IPv6].dst, server.ip6)
Klement Sekerad81ae412018-05-16 10:52:54 +02007233 self.assert_packet_checksums_valid(packet)
Matus Fabian029f3d22017-06-15 02:28:50 -07007234 if packet.haslayer(TCP):
7235 self.assertNotEqual(packet[TCP].sport, client_tcp_in_port)
7236 self.assertEqual(packet[TCP].dport, server_tcp_in_port)
Matus Fabian029f3d22017-06-15 02:28:50 -07007237 client_tcp_out_port = packet[TCP].sport
7238 else:
7239 self.assertNotEqual(packet[UDP].sport, client_udp_in_port)
7240 self.assertEqual(packet[UDP].dport, server_udp_in_port)
Matus Fabian029f3d22017-06-15 02:28:50 -07007241 client_udp_out_port = packet[UDP].sport
7242 except:
7243 self.logger.error(ppp("Unexpected or invalid packet:", packet))
7244 raise
7245
7246 # server to client
7247 pkts = []
7248 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
7249 IPv6(src=server.ip6, dst=nat_addr_ip6) /
7250 TCP(sport=server_tcp_in_port, dport=client_tcp_out_port))
7251 pkts.append(p)
7252 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
7253 IPv6(src=server.ip6, dst=nat_addr_ip6) /
7254 UDP(sport=server_udp_in_port, dport=client_udp_out_port))
7255 pkts.append(p)
7256 self.pg0.add_stream(pkts)
7257 self.pg_enable_capture(self.pg_interfaces)
7258 self.pg_start()
7259 capture = self.pg0.get_capture(len(pkts))
7260 for packet in capture:
7261 try:
7262 self.assertEqual(packet[IPv6].src, nat_addr_ip6)
7263 self.assertEqual(packet[IPv6].dst, client.ip6)
Klement Sekerad81ae412018-05-16 10:52:54 +02007264 self.assert_packet_checksums_valid(packet)
Matus Fabian029f3d22017-06-15 02:28:50 -07007265 if packet.haslayer(TCP):
7266 self.assertEqual(packet[TCP].sport, server_tcp_out_port)
7267 self.assertEqual(packet[TCP].dport, client_tcp_in_port)
Matus Fabian029f3d22017-06-15 02:28:50 -07007268 else:
7269 self.assertEqual(packet[UDP].sport, server_udp_out_port)
7270 self.assertEqual(packet[UDP].dport, client_udp_in_port)
Matus Fabian029f3d22017-06-15 02:28:50 -07007271 except:
7272 self.logger.error(ppp("Unexpected or invalid packet:", packet))
7273 raise
7274
7275 # ICMP error
7276 pkts = []
7277 pkts = [Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
7278 IPv6(src=client.ip6, dst=nat_addr_ip6) /
7279 ICMPv6DestUnreach(code=1) /
7280 packet[IPv6] for packet in capture]
7281 self.pg0.add_stream(pkts)
7282 self.pg_enable_capture(self.pg_interfaces)
7283 self.pg_start()
7284 capture = self.pg0.get_capture(len(pkts))
7285 for packet in capture:
7286 try:
7287 self.assertEqual(packet[IPv6].src, nat_addr_ip6)
7288 self.assertEqual(packet[IPv6].dst, server.ip6)
7289 icmp = packet[ICMPv6DestUnreach]
7290 self.assertEqual(icmp.code, 1)
7291 inner = icmp[IPerror6]
7292 self.assertEqual(inner.src, server.ip6)
7293 self.assertEqual(inner.dst, nat_addr_ip6)
Klement Sekerad81ae412018-05-16 10:52:54 +02007294 self.assert_packet_checksums_valid(packet)
Matus Fabian029f3d22017-06-15 02:28:50 -07007295 if inner.haslayer(TCPerror):
7296 self.assertEqual(inner[TCPerror].sport, server_tcp_in_port)
7297 self.assertEqual(inner[TCPerror].dport,
7298 client_tcp_out_port)
7299 else:
7300 self.assertEqual(inner[UDPerror].sport, server_udp_in_port)
7301 self.assertEqual(inner[UDPerror].dport,
7302 client_udp_out_port)
7303 except:
7304 self.logger.error(ppp("Unexpected or invalid packet:", packet))
7305 raise
7306
Matus Fabian428dc912017-06-21 06:15:18 -07007307 def test_prefix(self):
7308 """ NAT64 Network-Specific Prefix """
7309
7310 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
7311 self.nat_addr_n)
7312 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
7313 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
7314 self.vapi.nat64_add_del_pool_addr_range(self.vrf1_nat_addr_n,
7315 self.vrf1_nat_addr_n,
7316 vrf_id=self.vrf1_id)
7317 self.vapi.nat64_add_del_interface(self.pg2.sw_if_index)
7318
7319 # Add global prefix
7320 global_pref64 = "2001:db8::"
7321 global_pref64_n = socket.inet_pton(socket.AF_INET6, global_pref64)
7322 global_pref64_len = 32
7323 self.vapi.nat64_add_del_prefix(global_pref64_n, global_pref64_len)
7324
7325 prefix = self.vapi.nat64_prefix_dump()
7326 self.assertEqual(len(prefix), 1)
7327 self.assertEqual(prefix[0].prefix, global_pref64_n)
7328 self.assertEqual(prefix[0].prefix_len, global_pref64_len)
7329 self.assertEqual(prefix[0].vrf_id, 0)
7330
7331 # Add tenant specific prefix
7332 vrf1_pref64 = "2001:db8:122:300::"
7333 vrf1_pref64_n = socket.inet_pton(socket.AF_INET6, vrf1_pref64)
7334 vrf1_pref64_len = 56
7335 self.vapi.nat64_add_del_prefix(vrf1_pref64_n,
7336 vrf1_pref64_len,
7337 vrf_id=self.vrf1_id)
7338 prefix = self.vapi.nat64_prefix_dump()
7339 self.assertEqual(len(prefix), 2)
7340
7341 # Global prefix
7342 pkts = self.create_stream_in_ip6(self.pg0,
7343 self.pg1,
7344 pref=global_pref64,
7345 plen=global_pref64_len)
7346 self.pg0.add_stream(pkts)
7347 self.pg_enable_capture(self.pg_interfaces)
7348 self.pg_start()
7349 capture = self.pg1.get_capture(len(pkts))
7350 self.verify_capture_out(capture, nat_ip=self.nat_addr,
7351 dst_ip=self.pg1.remote_ip4)
7352
7353 pkts = self.create_stream_out(self.pg1, dst_ip=self.nat_addr)
7354 self.pg1.add_stream(pkts)
7355 self.pg_enable_capture(self.pg_interfaces)
7356 self.pg_start()
7357 capture = self.pg0.get_capture(len(pkts))
7358 dst_ip = self.compose_ip6(self.pg1.remote_ip4,
7359 global_pref64,
7360 global_pref64_len)
7361 self.verify_capture_in_ip6(capture, dst_ip, self.pg0.remote_ip6)
7362
7363 # Tenant specific prefix
7364 pkts = self.create_stream_in_ip6(self.pg2,
7365 self.pg1,
7366 pref=vrf1_pref64,
7367 plen=vrf1_pref64_len)
7368 self.pg2.add_stream(pkts)
7369 self.pg_enable_capture(self.pg_interfaces)
7370 self.pg_start()
7371 capture = self.pg1.get_capture(len(pkts))
7372 self.verify_capture_out(capture, nat_ip=self.vrf1_nat_addr,
7373 dst_ip=self.pg1.remote_ip4)
7374
7375 pkts = self.create_stream_out(self.pg1, dst_ip=self.vrf1_nat_addr)
7376 self.pg1.add_stream(pkts)
7377 self.pg_enable_capture(self.pg_interfaces)
7378 self.pg_start()
7379 capture = self.pg2.get_capture(len(pkts))
7380 dst_ip = self.compose_ip6(self.pg1.remote_ip4,
7381 vrf1_pref64,
7382 vrf1_pref64_len)
7383 self.verify_capture_in_ip6(capture, dst_ip, self.pg2.remote_ip6)
7384
Matus Fabianf8cd5812017-07-11 03:55:02 -07007385 def test_unknown_proto(self):
Matus Fabian7968e6c2017-07-06 05:37:49 -07007386 """ NAT64 translate packet with unknown protocol """
7387
7388 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
7389 self.nat_addr_n)
7390 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
7391 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
7392 remote_ip6 = self.compose_ip6(self.pg1.remote_ip4, '64:ff9b::', 96)
7393
7394 # in2out
7395 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
7396 IPv6(src=self.pg0.remote_ip6, dst=remote_ip6) /
7397 TCP(sport=self.tcp_port_in, dport=20))
7398 self.pg0.add_stream(p)
7399 self.pg_enable_capture(self.pg_interfaces)
7400 self.pg_start()
7401 p = self.pg1.get_capture(1)
7402
7403 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
Matus Fabianf8cd5812017-07-11 03:55:02 -07007404 IPv6(src=self.pg0.remote_ip6, dst=remote_ip6, nh=47) /
Matus Fabian7968e6c2017-07-06 05:37:49 -07007405 GRE() /
7406 IP(src=self.pg2.local_ip4, dst=self.pg2.remote_ip4) /
7407 TCP(sport=1234, dport=1234))
7408 self.pg0.add_stream(p)
7409 self.pg_enable_capture(self.pg_interfaces)
7410 self.pg_start()
7411 p = self.pg1.get_capture(1)
7412 packet = p[0]
7413 try:
7414 self.assertEqual(packet[IP].src, self.nat_addr)
7415 self.assertEqual(packet[IP].dst, self.pg1.remote_ip4)
Paul Vinciguerra978aa642018-11-24 22:19:12 -08007416 self.assertEqual(packet.haslayer(GRE), 1)
Klement Sekerad81ae412018-05-16 10:52:54 +02007417 self.assert_packet_checksums_valid(packet)
Matus Fabian7968e6c2017-07-06 05:37:49 -07007418 except:
7419 self.logger.error(ppp("Unexpected or invalid packet:", packet))
7420 raise
7421
7422 # out2in
7423 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
7424 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
7425 GRE() /
7426 IP(src=self.pg2.remote_ip4, dst=self.pg2.local_ip4) /
7427 TCP(sport=1234, dport=1234))
7428 self.pg1.add_stream(p)
7429 self.pg_enable_capture(self.pg_interfaces)
7430 self.pg_start()
7431 p = self.pg0.get_capture(1)
7432 packet = p[0]
7433 try:
7434 self.assertEqual(packet[IPv6].src, remote_ip6)
Matus Fabianf8cd5812017-07-11 03:55:02 -07007435 self.assertEqual(packet[IPv6].dst, self.pg0.remote_ip6)
7436 self.assertEqual(packet[IPv6].nh, 47)
Matus Fabian7968e6c2017-07-06 05:37:49 -07007437 except:
7438 self.logger.error(ppp("Unexpected or invalid packet:", packet))
7439 raise
7440
Matus Fabianf8cd5812017-07-11 03:55:02 -07007441 def test_hairpinning_unknown_proto(self):
Matus Fabian7968e6c2017-07-06 05:37:49 -07007442 """ NAT64 translate packet with unknown protocol - hairpinning """
7443
7444 client = self.pg0.remote_hosts[0]
7445 server = self.pg0.remote_hosts[1]
7446 server_tcp_in_port = 22
7447 server_tcp_out_port = 4022
7448 client_tcp_in_port = 1234
Matus Fabianf8cd5812017-07-11 03:55:02 -07007449 client_tcp_out_port = 1235
7450 server_nat_ip = "10.0.0.100"
7451 client_nat_ip = "10.0.0.110"
7452 server_nat_ip_n = socket.inet_pton(socket.AF_INET, server_nat_ip)
7453 client_nat_ip_n = socket.inet_pton(socket.AF_INET, client_nat_ip)
7454 server_nat_ip6 = self.compose_ip6(server_nat_ip, '64:ff9b::', 96)
7455 client_nat_ip6 = self.compose_ip6(client_nat_ip, '64:ff9b::', 96)
Matus Fabian7968e6c2017-07-06 05:37:49 -07007456
Matus Fabianf8cd5812017-07-11 03:55:02 -07007457 self.vapi.nat64_add_del_pool_addr_range(server_nat_ip_n,
7458 client_nat_ip_n)
Matus Fabian7968e6c2017-07-06 05:37:49 -07007459 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
7460 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
7461
7462 self.vapi.nat64_add_del_static_bib(server.ip6n,
Matus Fabianf8cd5812017-07-11 03:55:02 -07007463 server_nat_ip_n,
Matus Fabian7968e6c2017-07-06 05:37:49 -07007464 server_tcp_in_port,
7465 server_tcp_out_port,
7466 IP_PROTOS.tcp)
7467
Matus Fabianf8cd5812017-07-11 03:55:02 -07007468 self.vapi.nat64_add_del_static_bib(server.ip6n,
7469 server_nat_ip_n,
7470 0,
7471 0,
7472 IP_PROTOS.gre)
7473
7474 self.vapi.nat64_add_del_static_bib(client.ip6n,
7475 client_nat_ip_n,
7476 client_tcp_in_port,
7477 client_tcp_out_port,
7478 IP_PROTOS.tcp)
7479
Matus Fabian7968e6c2017-07-06 05:37:49 -07007480 # client to server
7481 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
Matus Fabianf8cd5812017-07-11 03:55:02 -07007482 IPv6(src=client.ip6, dst=server_nat_ip6) /
Matus Fabian7968e6c2017-07-06 05:37:49 -07007483 TCP(sport=client_tcp_in_port, dport=server_tcp_out_port))
7484 self.pg0.add_stream(p)
7485 self.pg_enable_capture(self.pg_interfaces)
7486 self.pg_start()
7487 p = self.pg0.get_capture(1)
7488
7489 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
Matus Fabianf8cd5812017-07-11 03:55:02 -07007490 IPv6(src=client.ip6, dst=server_nat_ip6, nh=IP_PROTOS.gre) /
Matus Fabian7968e6c2017-07-06 05:37:49 -07007491 GRE() /
7492 IP(src=self.pg2.local_ip4, dst=self.pg2.remote_ip4) /
7493 TCP(sport=1234, dport=1234))
7494 self.pg0.add_stream(p)
7495 self.pg_enable_capture(self.pg_interfaces)
7496 self.pg_start()
7497 p = self.pg0.get_capture(1)
7498 packet = p[0]
7499 try:
Matus Fabianf8cd5812017-07-11 03:55:02 -07007500 self.assertEqual(packet[IPv6].src, client_nat_ip6)
Matus Fabian7968e6c2017-07-06 05:37:49 -07007501 self.assertEqual(packet[IPv6].dst, server.ip6)
Matus Fabianf8cd5812017-07-11 03:55:02 -07007502 self.assertEqual(packet[IPv6].nh, IP_PROTOS.gre)
Matus Fabian7968e6c2017-07-06 05:37:49 -07007503 except:
7504 self.logger.error(ppp("Unexpected or invalid packet:", packet))
7505 raise
7506
7507 # server to client
7508 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
Matus Fabianf8cd5812017-07-11 03:55:02 -07007509 IPv6(src=server.ip6, dst=client_nat_ip6, nh=IP_PROTOS.gre) /
Matus Fabian7968e6c2017-07-06 05:37:49 -07007510 GRE() /
7511 IP(src=self.pg2.remote_ip4, dst=self.pg2.local_ip4) /
7512 TCP(sport=1234, dport=1234))
7513 self.pg0.add_stream(p)
7514 self.pg_enable_capture(self.pg_interfaces)
7515 self.pg_start()
7516 p = self.pg0.get_capture(1)
7517 packet = p[0]
7518 try:
Matus Fabianf8cd5812017-07-11 03:55:02 -07007519 self.assertEqual(packet[IPv6].src, server_nat_ip6)
Matus Fabian7968e6c2017-07-06 05:37:49 -07007520 self.assertEqual(packet[IPv6].dst, client.ip6)
Matus Fabianf8cd5812017-07-11 03:55:02 -07007521 self.assertEqual(packet[IPv6].nh, IP_PROTOS.gre)
Matus Fabian7968e6c2017-07-06 05:37:49 -07007522 except:
7523 self.logger.error(ppp("Unexpected or invalid packet:", packet))
7524 raise
7525
Matus Fabian36ea2d62017-10-24 04:13:49 -07007526 def test_one_armed_nat64(self):
7527 """ One armed NAT64 """
7528 external_port = 0
7529 remote_host_ip6 = self.compose_ip6(self.pg3.remote_ip4,
7530 '64:ff9b::',
7531 96)
7532
7533 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
7534 self.nat_addr_n)
7535 self.vapi.nat64_add_del_interface(self.pg3.sw_if_index)
7536 self.vapi.nat64_add_del_interface(self.pg3.sw_if_index, is_inside=0)
7537
7538 # in2out
7539 p = (Ether(src=self.pg3.remote_mac, dst=self.pg3.local_mac) /
7540 IPv6(src=self.pg3.remote_ip6, dst=remote_host_ip6) /
7541 TCP(sport=12345, dport=80))
7542 self.pg3.add_stream(p)
7543 self.pg_enable_capture(self.pg_interfaces)
7544 self.pg_start()
7545 capture = self.pg3.get_capture(1)
7546 p = capture[0]
7547 try:
7548 ip = p[IP]
7549 tcp = p[TCP]
7550 self.assertEqual(ip.src, self.nat_addr)
7551 self.assertEqual(ip.dst, self.pg3.remote_ip4)
7552 self.assertNotEqual(tcp.sport, 12345)
7553 external_port = tcp.sport
7554 self.assertEqual(tcp.dport, 80)
Klement Sekerad81ae412018-05-16 10:52:54 +02007555 self.assert_packet_checksums_valid(p)
Matus Fabian36ea2d62017-10-24 04:13:49 -07007556 except:
7557 self.logger.error(ppp("Unexpected or invalid packet:", p))
7558 raise
7559
7560 # out2in
7561 p = (Ether(src=self.pg3.remote_mac, dst=self.pg3.local_mac) /
7562 IP(src=self.pg3.remote_ip4, dst=self.nat_addr) /
7563 TCP(sport=80, dport=external_port))
7564 self.pg3.add_stream(p)
7565 self.pg_enable_capture(self.pg_interfaces)
7566 self.pg_start()
7567 capture = self.pg3.get_capture(1)
7568 p = capture[0]
7569 try:
7570 ip = p[IPv6]
7571 tcp = p[TCP]
7572 self.assertEqual(ip.src, remote_host_ip6)
7573 self.assertEqual(ip.dst, self.pg3.remote_ip6)
7574 self.assertEqual(tcp.sport, 80)
7575 self.assertEqual(tcp.dport, 12345)
Klement Sekerad81ae412018-05-16 10:52:54 +02007576 self.assert_packet_checksums_valid(p)
Matus Fabian36ea2d62017-10-24 04:13:49 -07007577 except:
7578 self.logger.error(ppp("Unexpected or invalid packet:", p))
7579 raise
7580
Matus Fabianefcd1e92017-08-15 06:59:19 -07007581 def test_frag_in_order(self):
7582 """ NAT64 translate fragments arriving in order """
7583 self.tcp_port_in = random.randint(1025, 65535)
7584
7585 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
7586 self.nat_addr_n)
7587 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
7588 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
7589
7590 reass = self.vapi.nat_reass_dump()
7591 reass_n_start = len(reass)
7592
7593 # in2out
7594 data = 'a' * 200
7595 pkts = self.create_stream_frag_ip6(self.pg0, self.pg1.remote_ip4,
7596 self.tcp_port_in, 20, data)
7597 self.pg0.add_stream(pkts)
7598 self.pg_enable_capture(self.pg_interfaces)
7599 self.pg_start()
7600 frags = self.pg1.get_capture(len(pkts))
7601 p = self.reass_frags_and_verify(frags,
7602 self.nat_addr,
7603 self.pg1.remote_ip4)
7604 self.assertEqual(p[TCP].dport, 20)
7605 self.assertNotEqual(p[TCP].sport, self.tcp_port_in)
7606 self.tcp_port_out = p[TCP].sport
7607 self.assertEqual(data, p[Raw].load)
7608
7609 # out2in
7610 data = "A" * 4 + "b" * 16 + "C" * 3
7611 pkts = self.create_stream_frag(self.pg1,
7612 self.nat_addr,
7613 20,
7614 self.tcp_port_out,
7615 data)
7616 self.pg1.add_stream(pkts)
7617 self.pg_enable_capture(self.pg_interfaces)
7618 self.pg_start()
7619 frags = self.pg0.get_capture(len(pkts))
7620 src = self.compose_ip6(self.pg1.remote_ip4, '64:ff9b::', 96)
7621 p = self.reass_frags_and_verify_ip6(frags, src, self.pg0.remote_ip6)
7622 self.assertEqual(p[TCP].sport, 20)
7623 self.assertEqual(p[TCP].dport, self.tcp_port_in)
7624 self.assertEqual(data, p[Raw].load)
7625
7626 reass = self.vapi.nat_reass_dump()
7627 reass_n_end = len(reass)
7628
7629 self.assertEqual(reass_n_end - reass_n_start, 2)
7630
7631 def test_reass_hairpinning(self):
7632 """ NAT64 fragments hairpinning """
7633 data = 'a' * 200
Matus Fabianefcd1e92017-08-15 06:59:19 -07007634 server = self.pg0.remote_hosts[1]
7635 server_in_port = random.randint(1025, 65535)
7636 server_out_port = random.randint(1025, 65535)
7637 client_in_port = random.randint(1025, 65535)
7638 ip = IPv6(src=''.join(['64:ff9b::', self.nat_addr]))
7639 nat_addr_ip6 = ip.src
7640
7641 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
7642 self.nat_addr_n)
7643 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
7644 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
7645
7646 # add static BIB entry for server
7647 self.vapi.nat64_add_del_static_bib(server.ip6n,
7648 self.nat_addr_n,
7649 server_in_port,
7650 server_out_port,
7651 IP_PROTOS.tcp)
7652
7653 # send packet from host to server
7654 pkts = self.create_stream_frag_ip6(self.pg0,
7655 self.nat_addr,
7656 client_in_port,
7657 server_out_port,
7658 data)
7659 self.pg0.add_stream(pkts)
7660 self.pg_enable_capture(self.pg_interfaces)
7661 self.pg_start()
7662 frags = self.pg0.get_capture(len(pkts))
7663 p = self.reass_frags_and_verify_ip6(frags, nat_addr_ip6, server.ip6)
7664 self.assertNotEqual(p[TCP].sport, client_in_port)
7665 self.assertEqual(p[TCP].dport, server_in_port)
7666 self.assertEqual(data, p[Raw].load)
7667
7668 def test_frag_out_of_order(self):
7669 """ NAT64 translate fragments arriving out of order """
7670 self.tcp_port_in = random.randint(1025, 65535)
7671
7672 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
7673 self.nat_addr_n)
7674 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
7675 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
7676
7677 # in2out
7678 data = 'a' * 200
7679 pkts = self.create_stream_frag_ip6(self.pg0, self.pg1.remote_ip4,
7680 self.tcp_port_in, 20, data)
7681 pkts.reverse()
7682 self.pg0.add_stream(pkts)
7683 self.pg_enable_capture(self.pg_interfaces)
7684 self.pg_start()
7685 frags = self.pg1.get_capture(len(pkts))
7686 p = self.reass_frags_and_verify(frags,
7687 self.nat_addr,
7688 self.pg1.remote_ip4)
7689 self.assertEqual(p[TCP].dport, 20)
7690 self.assertNotEqual(p[TCP].sport, self.tcp_port_in)
7691 self.tcp_port_out = p[TCP].sport
7692 self.assertEqual(data, p[Raw].load)
7693
7694 # out2in
7695 data = "A" * 4 + "B" * 16 + "C" * 3
7696 pkts = self.create_stream_frag(self.pg1,
7697 self.nat_addr,
7698 20,
7699 self.tcp_port_out,
7700 data)
7701 pkts.reverse()
7702 self.pg1.add_stream(pkts)
7703 self.pg_enable_capture(self.pg_interfaces)
7704 self.pg_start()
7705 frags = self.pg0.get_capture(len(pkts))
7706 src = self.compose_ip6(self.pg1.remote_ip4, '64:ff9b::', 96)
7707 p = self.reass_frags_and_verify_ip6(frags, src, self.pg0.remote_ip6)
7708 self.assertEqual(p[TCP].sport, 20)
7709 self.assertEqual(p[TCP].dport, self.tcp_port_in)
7710 self.assertEqual(data, p[Raw].load)
7711
Matus Fabian0938dcf2017-11-08 01:59:38 -08007712 def test_interface_addr(self):
7713 """ Acquire NAT64 pool addresses from interface """
7714 self.vapi.nat64_add_interface_addr(self.pg4.sw_if_index)
7715
7716 # no address in NAT64 pool
7717 adresses = self.vapi.nat44_address_dump()
7718 self.assertEqual(0, len(adresses))
7719
7720 # configure interface address and check NAT64 address pool
7721 self.pg4.config_ip4()
7722 addresses = self.vapi.nat64_pool_addr_dump()
7723 self.assertEqual(len(addresses), 1)
7724 self.assertEqual(addresses[0].address, self.pg4.local_ip4n)
7725
7726 # remove interface address and check NAT64 address pool
7727 self.pg4.unconfig_ip4()
7728 addresses = self.vapi.nat64_pool_addr_dump()
7729 self.assertEqual(0, len(adresses))
7730
Matus Fabiana431ad12018-01-04 04:03:14 -08007731 @unittest.skipUnless(running_extended_tests(), "part of extended tests")
7732 def test_ipfix_max_bibs_sessions(self):
7733 """ IPFIX logging maximum session and BIB entries exceeded """
7734 max_bibs = 1280
7735 max_sessions = 2560
7736 remote_host_ip6 = self.compose_ip6(self.pg1.remote_ip4,
7737 '64:ff9b::',
7738 96)
7739
7740 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
7741 self.nat_addr_n)
7742 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
7743 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
7744
7745 pkts = []
7746 src = ""
7747 for i in range(0, max_bibs):
7748 src = "fd01:aa::%x" % (i)
7749 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
7750 IPv6(src=src, dst=remote_host_ip6) /
7751 TCP(sport=12345, dport=80))
7752 pkts.append(p)
7753 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
7754 IPv6(src=src, dst=remote_host_ip6) /
7755 TCP(sport=12345, dport=22))
7756 pkts.append(p)
7757 self.pg0.add_stream(pkts)
7758 self.pg_enable_capture(self.pg_interfaces)
7759 self.pg_start()
7760 self.pg1.get_capture(max_sessions)
7761
7762 self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4n,
7763 src_address=self.pg3.local_ip4n,
7764 path_mtu=512,
7765 template_interval=10)
7766 self.vapi.nat_ipfix(domain_id=self.ipfix_domain_id,
7767 src_port=self.ipfix_src_port)
7768
7769 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
7770 IPv6(src=src, dst=remote_host_ip6) /
7771 TCP(sport=12345, dport=25))
7772 self.pg0.add_stream(p)
7773 self.pg_enable_capture(self.pg_interfaces)
7774 self.pg_start()
Matus Fabian229c1aa2018-05-28 04:09:52 -07007775 self.pg1.assert_nothing_captured()
7776 sleep(1)
Matus Fabiana431ad12018-01-04 04:03:14 -08007777 self.vapi.cli("ipfix flush") # FIXME this should be an API call
7778 capture = self.pg3.get_capture(9)
7779 ipfix = IPFIXDecoder()
7780 # first load template
7781 for p in capture:
7782 self.assertTrue(p.haslayer(IPFIX))
7783 self.assertEqual(p[IP].src, self.pg3.local_ip4)
7784 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
7785 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
7786 self.assertEqual(p[UDP].dport, 4739)
7787 self.assertEqual(p[IPFIX].observationDomainID,
7788 self.ipfix_domain_id)
7789 if p.haslayer(Template):
7790 ipfix.add_template(p.getlayer(Template))
7791 # verify events in data set
7792 for p in capture:
7793 if p.haslayer(Data):
7794 data = ipfix.decode_data_set(p.getlayer(Set))
7795 self.verify_ipfix_max_sessions(data, max_sessions)
7796
7797 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
7798 IPv6(src=self.pg0.remote_ip6, dst=remote_host_ip6) /
7799 TCP(sport=12345, dport=80))
7800 self.pg0.add_stream(p)
7801 self.pg_enable_capture(self.pg_interfaces)
7802 self.pg_start()
Matus Fabian229c1aa2018-05-28 04:09:52 -07007803 self.pg1.assert_nothing_captured()
7804 sleep(1)
Matus Fabiana431ad12018-01-04 04:03:14 -08007805 self.vapi.cli("ipfix flush") # FIXME this should be an API call
7806 capture = self.pg3.get_capture(1)
7807 # verify events in data set
7808 for p in capture:
7809 self.assertTrue(p.haslayer(IPFIX))
7810 self.assertEqual(p[IP].src, self.pg3.local_ip4)
7811 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
7812 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
7813 self.assertEqual(p[UDP].dport, 4739)
7814 self.assertEqual(p[IPFIX].observationDomainID,
7815 self.ipfix_domain_id)
7816 if p.haslayer(Data):
7817 data = ipfix.decode_data_set(p.getlayer(Set))
7818 self.verify_ipfix_max_bibs(data, max_bibs)
7819
7820 def test_ipfix_max_frags(self):
7821 """ IPFIX logging maximum fragments pending reassembly exceeded """
7822 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
7823 self.nat_addr_n)
7824 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
7825 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
Matus Fabiana7f8b222018-09-05 06:01:55 -07007826 self.vapi.nat_set_reass(max_frag=1, is_ip6=1)
Matus Fabiana431ad12018-01-04 04:03:14 -08007827 self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4n,
7828 src_address=self.pg3.local_ip4n,
7829 path_mtu=512,
7830 template_interval=10)
7831 self.vapi.nat_ipfix(domain_id=self.ipfix_domain_id,
7832 src_port=self.ipfix_src_port)
7833
7834 data = 'a' * 200
7835 pkts = self.create_stream_frag_ip6(self.pg0, self.pg1.remote_ip4,
7836 self.tcp_port_in, 20, data)
Matus Fabiana7f8b222018-09-05 06:01:55 -07007837 pkts.reverse()
7838 self.pg0.add_stream(pkts)
Matus Fabiana431ad12018-01-04 04:03:14 -08007839 self.pg_enable_capture(self.pg_interfaces)
7840 self.pg_start()
Matus Fabian229c1aa2018-05-28 04:09:52 -07007841 self.pg1.assert_nothing_captured()
7842 sleep(1)
Matus Fabiana431ad12018-01-04 04:03:14 -08007843 self.vapi.cli("ipfix flush") # FIXME this should be an API call
7844 capture = self.pg3.get_capture(9)
7845 ipfix = IPFIXDecoder()
7846 # first load template
7847 for p in capture:
7848 self.assertTrue(p.haslayer(IPFIX))
7849 self.assertEqual(p[IP].src, self.pg3.local_ip4)
7850 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
7851 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
7852 self.assertEqual(p[UDP].dport, 4739)
7853 self.assertEqual(p[IPFIX].observationDomainID,
7854 self.ipfix_domain_id)
7855 if p.haslayer(Template):
7856 ipfix.add_template(p.getlayer(Template))
7857 # verify events in data set
7858 for p in capture:
7859 if p.haslayer(Data):
7860 data = ipfix.decode_data_set(p.getlayer(Set))
Matus Fabiana7f8b222018-09-05 06:01:55 -07007861 self.verify_ipfix_max_fragments_ip6(data, 1,
Matus Fabiana431ad12018-01-04 04:03:14 -08007862 self.pg0.remote_ip6n)
7863
7864 def test_ipfix_bib_ses(self):
7865 """ IPFIX logging NAT64 BIB/session create and delete events """
7866 self.tcp_port_in = random.randint(1025, 65535)
7867 remote_host_ip6 = self.compose_ip6(self.pg1.remote_ip4,
7868 '64:ff9b::',
7869 96)
7870
7871 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
7872 self.nat_addr_n)
7873 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
7874 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
7875 self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4n,
7876 src_address=self.pg3.local_ip4n,
7877 path_mtu=512,
7878 template_interval=10)
7879 self.vapi.nat_ipfix(domain_id=self.ipfix_domain_id,
7880 src_port=self.ipfix_src_port)
7881
7882 # Create
7883 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
7884 IPv6(src=self.pg0.remote_ip6, dst=remote_host_ip6) /
7885 TCP(sport=self.tcp_port_in, dport=25))
7886 self.pg0.add_stream(p)
7887 self.pg_enable_capture(self.pg_interfaces)
7888 self.pg_start()
7889 p = self.pg1.get_capture(1)
7890 self.tcp_port_out = p[0][TCP].sport
7891 self.vapi.cli("ipfix flush") # FIXME this should be an API call
7892 capture = self.pg3.get_capture(10)
7893 ipfix = IPFIXDecoder()
7894 # first load template
7895 for p in capture:
7896 self.assertTrue(p.haslayer(IPFIX))
7897 self.assertEqual(p[IP].src, self.pg3.local_ip4)
7898 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
7899 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
7900 self.assertEqual(p[UDP].dport, 4739)
7901 self.assertEqual(p[IPFIX].observationDomainID,
7902 self.ipfix_domain_id)
7903 if p.haslayer(Template):
7904 ipfix.add_template(p.getlayer(Template))
7905 # verify events in data set
7906 for p in capture:
7907 if p.haslayer(Data):
7908 data = ipfix.decode_data_set(p.getlayer(Set))
7909 if ord(data[0][230]) == 10:
7910 self.verify_ipfix_bib(data, 1, self.pg0.remote_ip6n)
7911 elif ord(data[0][230]) == 6:
7912 self.verify_ipfix_nat64_ses(data,
7913 1,
7914 self.pg0.remote_ip6n,
7915 self.pg1.remote_ip4,
7916 25)
7917 else:
7918 self.logger.error(ppp("Unexpected or invalid packet: ", p))
7919
7920 # Delete
7921 self.pg_enable_capture(self.pg_interfaces)
7922 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
7923 self.nat_addr_n,
7924 is_add=0)
7925 self.vapi.cli("ipfix flush") # FIXME this should be an API call
7926 capture = self.pg3.get_capture(2)
7927 # verify events in data set
7928 for p in capture:
7929 self.assertTrue(p.haslayer(IPFIX))
7930 self.assertEqual(p[IP].src, self.pg3.local_ip4)
7931 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
7932 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
7933 self.assertEqual(p[UDP].dport, 4739)
7934 self.assertEqual(p[IPFIX].observationDomainID,
7935 self.ipfix_domain_id)
7936 if p.haslayer(Data):
7937 data = ipfix.decode_data_set(p.getlayer(Set))
7938 if ord(data[0][230]) == 11:
7939 self.verify_ipfix_bib(data, 0, self.pg0.remote_ip6n)
7940 elif ord(data[0][230]) == 7:
7941 self.verify_ipfix_nat64_ses(data,
7942 0,
7943 self.pg0.remote_ip6n,
7944 self.pg1.remote_ip4,
7945 25)
7946 else:
7947 self.logger.error(ppp("Unexpected or invalid packet: ", p))
7948
Matus Fabianad1f3e12018-11-28 21:26:34 -08007949 def test_syslog_sess(self):
7950 """ Test syslog session creation and deletion """
7951 self.tcp_port_in = random.randint(1025, 65535)
7952 remote_host_ip6 = self.compose_ip6(self.pg1.remote_ip4,
7953 '64:ff9b::',
7954 96)
7955
7956 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
7957 self.nat_addr_n)
7958 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
7959 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
7960 self.vapi.syslog_set_filter(SYSLOG_SEVERITY.INFO)
7961 self.vapi.syslog_set_sender(self.pg3.remote_ip4n, self.pg3.local_ip4n)
7962
7963 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
7964 IPv6(src=self.pg0.remote_ip6, dst=remote_host_ip6) /
7965 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port))
7966 self.pg0.add_stream(p)
7967 self.pg_enable_capture(self.pg_interfaces)
7968 self.pg_start()
7969 p = self.pg1.get_capture(1)
7970 self.tcp_port_out = p[0][TCP].sport
7971 capture = self.pg3.get_capture(1)
7972 self.verify_syslog_sess(capture[0][Raw].load, is_ip6=True)
7973
7974 self.pg_enable_capture(self.pg_interfaces)
7975 self.pg_start()
7976 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
7977 self.nat_addr_n,
7978 is_add=0)
7979 capture = self.pg3.get_capture(1)
7980 self.verify_syslog_sess(capture[0][Raw].load, False, True)
7981
Matus Fabian06596c52017-06-06 04:53:28 -07007982 def nat64_get_ses_num(self):
7983 """
7984 Return number of active NAT64 sessions.
7985 """
Matus Fabianab9a59c2017-08-16 05:37:36 -07007986 st = self.vapi.nat64_st_dump()
7987 return len(st)
Matus Fabian06596c52017-06-06 04:53:28 -07007988
7989 def clear_nat64(self):
7990 """
7991 Clear NAT64 configuration.
7992 """
Matus Fabiana431ad12018-01-04 04:03:14 -08007993 self.vapi.nat_ipfix(enable=0, src_port=self.ipfix_src_port,
7994 domain_id=self.ipfix_domain_id)
7995 self.ipfix_src_port = 4739
7996 self.ipfix_domain_id = 1
7997
Matus Fabianad1f3e12018-11-28 21:26:34 -08007998 self.vapi.syslog_set_filter(SYSLOG_SEVERITY.EMERG)
7999
Matus Fabian878c6462018-08-23 00:33:35 -07008000 self.vapi.nat_set_timeouts()
Matus Fabian06596c52017-06-06 04:53:28 -07008001
8002 interfaces = self.vapi.nat64_interface_dump()
8003 for intf in interfaces:
Matus Fabian36ea2d62017-10-24 04:13:49 -07008004 if intf.is_inside > 1:
8005 self.vapi.nat64_add_del_interface(intf.sw_if_index,
8006 0,
8007 is_add=0)
Matus Fabian06596c52017-06-06 04:53:28 -07008008 self.vapi.nat64_add_del_interface(intf.sw_if_index,
8009 intf.is_inside,
8010 is_add=0)
8011
Matus Fabiana431ad12018-01-04 04:03:14 -08008012 bib = self.vapi.nat64_bib_dump(255)
Matus Fabian06596c52017-06-06 04:53:28 -07008013 for bibe in bib:
8014 if bibe.is_static:
8015 self.vapi.nat64_add_del_static_bib(bibe.i_addr,
8016 bibe.o_addr,
8017 bibe.i_port,
8018 bibe.o_port,
8019 bibe.proto,
8020 bibe.vrf_id,
8021 is_add=0)
8022
8023 adresses = self.vapi.nat64_pool_addr_dump()
8024 for addr in adresses:
8025 self.vapi.nat64_add_del_pool_addr_range(addr.address,
8026 addr.address,
Matus Fabian029f3d22017-06-15 02:28:50 -07008027 vrf_id=addr.vrf_id,
Matus Fabian06596c52017-06-06 04:53:28 -07008028 is_add=0)
8029
Matus Fabian428dc912017-06-21 06:15:18 -07008030 prefixes = self.vapi.nat64_prefix_dump()
8031 for prefix in prefixes:
8032 self.vapi.nat64_add_del_prefix(prefix.prefix,
8033 prefix.prefix_len,
8034 vrf_id=prefix.vrf_id,
8035 is_add=0)
8036
Matus Fabian06596c52017-06-06 04:53:28 -07008037 def tearDown(self):
8038 super(TestNAT64, self).tearDown()
8039 if not self.vpp_dead:
8040 self.logger.info(self.vapi.cli("show nat64 pool"))
8041 self.logger.info(self.vapi.cli("show nat64 interfaces"))
Matus Fabian428dc912017-06-21 06:15:18 -07008042 self.logger.info(self.vapi.cli("show nat64 prefix"))
Matus Fabianab9a59c2017-08-16 05:37:36 -07008043 self.logger.info(self.vapi.cli("show nat64 bib all"))
8044 self.logger.info(self.vapi.cli("show nat64 session table all"))
Matus Fabianefcd1e92017-08-15 06:59:19 -07008045 self.logger.info(self.vapi.cli("show nat virtual-reassembly"))
Matus Fabian06596c52017-06-06 04:53:28 -07008046 self.clear_nat64()
8047
Matus Fabian8ebe6252017-11-06 05:04:53 -08008048
8049class TestDSlite(MethodHolder):
8050 """ DS-Lite Test Cases """
8051
8052 @classmethod
8053 def setUpClass(cls):
8054 super(TestDSlite, cls).setUpClass()
8055
8056 try:
8057 cls.nat_addr = '10.0.0.3'
8058 cls.nat_addr_n = socket.inet_pton(socket.AF_INET, cls.nat_addr)
8059
Matus Fabianad1f3e12018-11-28 21:26:34 -08008060 cls.create_pg_interfaces(range(3))
Matus Fabian8ebe6252017-11-06 05:04:53 -08008061 cls.pg0.admin_up()
8062 cls.pg0.config_ip4()
8063 cls.pg0.resolve_arp()
8064 cls.pg1.admin_up()
8065 cls.pg1.config_ip6()
8066 cls.pg1.generate_remote_hosts(2)
8067 cls.pg1.configure_ipv6_neighbors()
Matus Fabianad1f3e12018-11-28 21:26:34 -08008068 cls.pg2.admin_up()
8069 cls.pg2.config_ip4()
8070 cls.pg2.resolve_arp()
Matus Fabian8ebe6252017-11-06 05:04:53 -08008071
8072 except Exception:
8073 super(TestDSlite, cls).tearDownClass()
8074 raise
8075
Matus Fabianad1f3e12018-11-28 21:26:34 -08008076 def verify_syslog_apmadd(self, data, isaddr, isport, xsaddr, xsport,
8077 sv6enc, proto):
8078 message = data.decode('utf-8')
8079 try:
8080 message = SyslogMessage.parse(message)
8081 self.assertEqual(message.severity, SyslogSeverity.info)
8082 self.assertEqual(message.appname, 'NAT')
8083 self.assertEqual(message.msgid, 'APMADD')
8084 sd_params = message.sd.get('napmap')
8085 self.assertTrue(sd_params is not None)
8086 self.assertEqual(sd_params.get('IATYP'), 'IPv4')
8087 self.assertEqual(sd_params.get('ISADDR'), isaddr)
8088 self.assertEqual(sd_params.get('ISPORT'), "%d" % isport)
8089 self.assertEqual(sd_params.get('XATYP'), 'IPv4')
8090 self.assertEqual(sd_params.get('XSADDR'), xsaddr)
8091 self.assertEqual(sd_params.get('XSPORT'), "%d" % xsport)
8092 self.assertEqual(sd_params.get('PROTO'), "%d" % proto)
8093 self.assertTrue(sd_params.get('SSUBIX') is not None)
8094 self.assertEqual(sd_params.get('SV6ENC'), sv6enc)
8095 except ParseError as e:
8096 self.logger.error(e)
8097
Matus Fabian8ebe6252017-11-06 05:04:53 -08008098 def test_dslite(self):
8099 """ Test DS-Lite """
Matus Fabian69ce30d2018-08-22 01:27:10 -07008100 nat_config = self.vapi.nat_show_config()
8101 self.assertEqual(0, nat_config.dslite_ce)
8102
Matus Fabian8ebe6252017-11-06 05:04:53 -08008103 self.vapi.dslite_add_del_pool_addr_range(self.nat_addr_n,
8104 self.nat_addr_n)
8105 aftr_ip4 = '192.0.0.1'
8106 aftr_ip4_n = socket.inet_pton(socket.AF_INET, aftr_ip4)
8107 aftr_ip6 = '2001:db8:85a3::8a2e:370:1'
8108 aftr_ip6_n = socket.inet_pton(socket.AF_INET6, aftr_ip6)
8109 self.vapi.dslite_set_aftr_addr(aftr_ip6_n, aftr_ip4_n)
Matus Fabianad1f3e12018-11-28 21:26:34 -08008110 self.vapi.syslog_set_sender(self.pg2.remote_ip4n, self.pg2.local_ip4n)
Matus Fabian8ebe6252017-11-06 05:04:53 -08008111
8112 # UDP
8113 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
8114 IPv6(dst=aftr_ip6, src=self.pg1.remote_hosts[0].ip6) /
8115 IP(dst=self.pg0.remote_ip4, src='192.168.1.1') /
8116 UDP(sport=20000, dport=10000))
8117 self.pg1.add_stream(p)
8118 self.pg_enable_capture(self.pg_interfaces)
8119 self.pg_start()
8120 capture = self.pg0.get_capture(1)
8121 capture = capture[0]
8122 self.assertFalse(capture.haslayer(IPv6))
8123 self.assertEqual(capture[IP].src, self.nat_addr)
8124 self.assertEqual(capture[IP].dst, self.pg0.remote_ip4)
8125 self.assertNotEqual(capture[UDP].sport, 20000)
8126 self.assertEqual(capture[UDP].dport, 10000)
Klement Sekerad81ae412018-05-16 10:52:54 +02008127 self.assert_packet_checksums_valid(capture)
Matus Fabian8ebe6252017-11-06 05:04:53 -08008128 out_port = capture[UDP].sport
Matus Fabianad1f3e12018-11-28 21:26:34 -08008129 capture = self.pg2.get_capture(1)
8130 self.verify_syslog_apmadd(capture[0][Raw].load, '192.168.1.1',
8131 20000, self.nat_addr, out_port,
8132 self.pg1.remote_hosts[0].ip6, IP_PROTOS.udp)
Matus Fabian8ebe6252017-11-06 05:04:53 -08008133
8134 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8135 IP(dst=self.nat_addr, src=self.pg0.remote_ip4) /
8136 UDP(sport=10000, dport=out_port))
8137 self.pg0.add_stream(p)
8138 self.pg_enable_capture(self.pg_interfaces)
8139 self.pg_start()
8140 capture = self.pg1.get_capture(1)
8141 capture = capture[0]
8142 self.assertEqual(capture[IPv6].src, aftr_ip6)
8143 self.assertEqual(capture[IPv6].dst, self.pg1.remote_hosts[0].ip6)
8144 self.assertEqual(capture[IP].src, self.pg0.remote_ip4)
8145 self.assertEqual(capture[IP].dst, '192.168.1.1')
8146 self.assertEqual(capture[UDP].sport, 10000)
8147 self.assertEqual(capture[UDP].dport, 20000)
Klement Sekerad81ae412018-05-16 10:52:54 +02008148 self.assert_packet_checksums_valid(capture)
Matus Fabian8ebe6252017-11-06 05:04:53 -08008149
8150 # TCP
8151 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
8152 IPv6(dst=aftr_ip6, src=self.pg1.remote_hosts[1].ip6) /
8153 IP(dst=self.pg0.remote_ip4, src='192.168.1.1') /
8154 TCP(sport=20001, dport=10001))
8155 self.pg1.add_stream(p)
8156 self.pg_enable_capture(self.pg_interfaces)
8157 self.pg_start()
8158 capture = self.pg0.get_capture(1)
8159 capture = capture[0]
8160 self.assertFalse(capture.haslayer(IPv6))
8161 self.assertEqual(capture[IP].src, self.nat_addr)
8162 self.assertEqual(capture[IP].dst, self.pg0.remote_ip4)
8163 self.assertNotEqual(capture[TCP].sport, 20001)
8164 self.assertEqual(capture[TCP].dport, 10001)
Klement Sekerad81ae412018-05-16 10:52:54 +02008165 self.assert_packet_checksums_valid(capture)
Matus Fabian8ebe6252017-11-06 05:04:53 -08008166 out_port = capture[TCP].sport
8167
8168 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8169 IP(dst=self.nat_addr, src=self.pg0.remote_ip4) /
8170 TCP(sport=10001, dport=out_port))
8171 self.pg0.add_stream(p)
8172 self.pg_enable_capture(self.pg_interfaces)
8173 self.pg_start()
8174 capture = self.pg1.get_capture(1)
8175 capture = capture[0]
8176 self.assertEqual(capture[IPv6].src, aftr_ip6)
8177 self.assertEqual(capture[IPv6].dst, self.pg1.remote_hosts[1].ip6)
8178 self.assertEqual(capture[IP].src, self.pg0.remote_ip4)
8179 self.assertEqual(capture[IP].dst, '192.168.1.1')
8180 self.assertEqual(capture[TCP].sport, 10001)
8181 self.assertEqual(capture[TCP].dport, 20001)
Klement Sekerad81ae412018-05-16 10:52:54 +02008182 self.assert_packet_checksums_valid(capture)
Matus Fabian8ebe6252017-11-06 05:04:53 -08008183
8184 # ICMP
8185 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
8186 IPv6(dst=aftr_ip6, src=self.pg1.remote_hosts[1].ip6) /
8187 IP(dst=self.pg0.remote_ip4, src='192.168.1.1') /
8188 ICMP(id=4000, type='echo-request'))
8189 self.pg1.add_stream(p)
8190 self.pg_enable_capture(self.pg_interfaces)
8191 self.pg_start()
8192 capture = self.pg0.get_capture(1)
8193 capture = capture[0]
8194 self.assertFalse(capture.haslayer(IPv6))
8195 self.assertEqual(capture[IP].src, self.nat_addr)
8196 self.assertEqual(capture[IP].dst, self.pg0.remote_ip4)
8197 self.assertNotEqual(capture[ICMP].id, 4000)
Klement Sekerad81ae412018-05-16 10:52:54 +02008198 self.assert_packet_checksums_valid(capture)
Matus Fabian8ebe6252017-11-06 05:04:53 -08008199 out_id = capture[ICMP].id
8200
8201 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8202 IP(dst=self.nat_addr, src=self.pg0.remote_ip4) /
8203 ICMP(id=out_id, type='echo-reply'))
8204 self.pg0.add_stream(p)
8205 self.pg_enable_capture(self.pg_interfaces)
8206 self.pg_start()
8207 capture = self.pg1.get_capture(1)
8208 capture = capture[0]
8209 self.assertEqual(capture[IPv6].src, aftr_ip6)
8210 self.assertEqual(capture[IPv6].dst, self.pg1.remote_hosts[1].ip6)
8211 self.assertEqual(capture[IP].src, self.pg0.remote_ip4)
8212 self.assertEqual(capture[IP].dst, '192.168.1.1')
8213 self.assertEqual(capture[ICMP].id, 4000)
Klement Sekerad81ae412018-05-16 10:52:54 +02008214 self.assert_packet_checksums_valid(capture)
Matus Fabian8ebe6252017-11-06 05:04:53 -08008215
Matus Fabian331acc62017-12-08 03:38:51 -08008216 # ping DS-Lite AFTR tunnel endpoint address
8217 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
8218 IPv6(src=self.pg1.remote_hosts[1].ip6, dst=aftr_ip6) /
8219 ICMPv6EchoRequest())
8220 self.pg1.add_stream(p)
8221 self.pg_enable_capture(self.pg_interfaces)
8222 self.pg_start()
8223 capture = self.pg1.get_capture(1)
Matus Fabian331acc62017-12-08 03:38:51 -08008224 capture = capture[0]
8225 self.assertEqual(capture[IPv6].src, aftr_ip6)
8226 self.assertEqual(capture[IPv6].dst, self.pg1.remote_hosts[1].ip6)
8227 self.assertTrue(capture.haslayer(ICMPv6EchoReply))
8228
Matus Fabian8ebe6252017-11-06 05:04:53 -08008229 def tearDown(self):
8230 super(TestDSlite, self).tearDown()
8231 if not self.vpp_dead:
8232 self.logger.info(self.vapi.cli("show dslite pool"))
8233 self.logger.info(
8234 self.vapi.cli("show dslite aftr-tunnel-endpoint-address"))
8235 self.logger.info(self.vapi.cli("show dslite sessions"))
8236
Juraj Slobodac5c6a332018-01-09 16:08:32 +01008237
8238class TestDSliteCE(MethodHolder):
8239 """ DS-Lite CE Test Cases """
8240
8241 @classmethod
8242 def setUpConstants(cls):
8243 super(TestDSliteCE, cls).setUpConstants()
8244 cls.vpp_cmdline.extend(["nat", "{", "dslite ce", "}"])
8245
8246 @classmethod
8247 def setUpClass(cls):
8248 super(TestDSliteCE, cls).setUpClass()
8249
8250 try:
8251 cls.create_pg_interfaces(range(2))
8252 cls.pg0.admin_up()
8253 cls.pg0.config_ip4()
8254 cls.pg0.resolve_arp()
8255 cls.pg1.admin_up()
8256 cls.pg1.config_ip6()
8257 cls.pg1.generate_remote_hosts(1)
8258 cls.pg1.configure_ipv6_neighbors()
8259
8260 except Exception:
8261 super(TestDSliteCE, cls).tearDownClass()
8262 raise
8263
8264 def test_dslite_ce(self):
8265 """ Test DS-Lite CE """
8266
Matus Fabian69ce30d2018-08-22 01:27:10 -07008267 nat_config = self.vapi.nat_show_config()
8268 self.assertEqual(1, nat_config.dslite_ce)
8269
Juraj Slobodac5c6a332018-01-09 16:08:32 +01008270 b4_ip4 = '192.0.0.2'
8271 b4_ip4_n = socket.inet_pton(socket.AF_INET, b4_ip4)
8272 b4_ip6 = '2001:db8:62aa::375e:f4c1:1'
8273 b4_ip6_n = socket.inet_pton(socket.AF_INET6, b4_ip6)
8274 self.vapi.dslite_set_b4_addr(b4_ip6_n, b4_ip4_n)
8275
8276 aftr_ip4 = '192.0.0.1'
8277 aftr_ip4_n = socket.inet_pton(socket.AF_INET, aftr_ip4)
8278 aftr_ip6 = '2001:db8:85a3::8a2e:370:1'
8279 aftr_ip6_n = socket.inet_pton(socket.AF_INET6, aftr_ip6)
8280 self.vapi.dslite_set_aftr_addr(aftr_ip6_n, aftr_ip4_n)
8281
8282 self.vapi.ip_add_del_route(dst_address=aftr_ip6_n,
8283 dst_address_length=128,
8284 next_hop_address=self.pg1.remote_ip6n,
8285 next_hop_sw_if_index=self.pg1.sw_if_index,
8286 is_ipv6=1)
8287
8288 # UDP encapsulation
8289 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8290 IP(dst=self.pg1.remote_ip4, src=self.pg0.remote_ip4) /
8291 UDP(sport=10000, dport=20000))
8292 self.pg0.add_stream(p)
8293 self.pg_enable_capture(self.pg_interfaces)
8294 self.pg_start()
8295 capture = self.pg1.get_capture(1)
8296 capture = capture[0]
8297 self.assertEqual(capture[IPv6].src, b4_ip6)
8298 self.assertEqual(capture[IPv6].dst, aftr_ip6)
8299 self.assertEqual(capture[IP].src, self.pg0.remote_ip4)
8300 self.assertEqual(capture[IP].dst, self.pg1.remote_ip4)
8301 self.assertEqual(capture[UDP].sport, 10000)
8302 self.assertEqual(capture[UDP].dport, 20000)
Klement Sekerad81ae412018-05-16 10:52:54 +02008303 self.assert_packet_checksums_valid(capture)
Juraj Slobodac5c6a332018-01-09 16:08:32 +01008304
8305 # UDP decapsulation
8306 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
8307 IPv6(dst=b4_ip6, src=aftr_ip6) /
8308 IP(dst=self.pg0.remote_ip4, src=self.pg1.remote_ip4) /
8309 UDP(sport=20000, dport=10000))
8310 self.pg1.add_stream(p)
8311 self.pg_enable_capture(self.pg_interfaces)
8312 self.pg_start()
8313 capture = self.pg0.get_capture(1)
8314 capture = capture[0]
8315 self.assertFalse(capture.haslayer(IPv6))
8316 self.assertEqual(capture[IP].src, self.pg1.remote_ip4)
8317 self.assertEqual(capture[IP].dst, self.pg0.remote_ip4)
8318 self.assertEqual(capture[UDP].sport, 20000)
8319 self.assertEqual(capture[UDP].dport, 10000)
Klement Sekerad81ae412018-05-16 10:52:54 +02008320 self.assert_packet_checksums_valid(capture)
Juraj Slobodac5c6a332018-01-09 16:08:32 +01008321
8322 # ping DS-Lite B4 tunnel endpoint address
8323 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
8324 IPv6(src=self.pg1.remote_hosts[0].ip6, dst=b4_ip6) /
8325 ICMPv6EchoRequest())
8326 self.pg1.add_stream(p)
8327 self.pg_enable_capture(self.pg_interfaces)
8328 self.pg_start()
8329 capture = self.pg1.get_capture(1)
Juraj Slobodac5c6a332018-01-09 16:08:32 +01008330 capture = capture[0]
8331 self.assertEqual(capture[IPv6].src, b4_ip6)
8332 self.assertEqual(capture[IPv6].dst, self.pg1.remote_hosts[0].ip6)
8333 self.assertTrue(capture.haslayer(ICMPv6EchoReply))
8334
8335 def tearDown(self):
8336 super(TestDSliteCE, self).tearDown()
8337 if not self.vpp_dead:
8338 self.logger.info(
8339 self.vapi.cli("show dslite aftr-tunnel-endpoint-address"))
8340 self.logger.info(
8341 self.vapi.cli("show dslite b4-tunnel-endpoint-address"))
8342
Matus Fabianf2a23cc2018-01-22 03:41:53 -08008343
8344class TestNAT66(MethodHolder):
8345 """ NAT66 Test Cases """
8346
8347 @classmethod
8348 def setUpClass(cls):
8349 super(TestNAT66, cls).setUpClass()
8350
8351 try:
8352 cls.nat_addr = 'fd01:ff::2'
8353 cls.nat_addr_n = socket.inet_pton(socket.AF_INET6, cls.nat_addr)
8354
8355 cls.create_pg_interfaces(range(2))
8356 cls.interfaces = list(cls.pg_interfaces)
8357
8358 for i in cls.interfaces:
8359 i.admin_up()
8360 i.config_ip6()
8361 i.configure_ipv6_neighbors()
8362
8363 except Exception:
8364 super(TestNAT66, cls).tearDownClass()
8365 raise
8366
8367 def test_static(self):
8368 """ 1:1 NAT66 test """
8369 self.vapi.nat66_add_del_interface(self.pg0.sw_if_index)
8370 self.vapi.nat66_add_del_interface(self.pg1.sw_if_index, is_inside=0)
8371 self.vapi.nat66_add_del_static_mapping(self.pg0.remote_ip6n,
8372 self.nat_addr_n)
8373
8374 # in2out
8375 pkts = []
8376 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8377 IPv6(src=self.pg0.remote_ip6, dst=self.pg1.remote_ip6) /
8378 TCP())
8379 pkts.append(p)
8380 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8381 IPv6(src=self.pg0.remote_ip6, dst=self.pg1.remote_ip6) /
8382 UDP())
8383 pkts.append(p)
8384 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8385 IPv6(src=self.pg0.remote_ip6, dst=self.pg1.remote_ip6) /
8386 ICMPv6EchoRequest())
8387 pkts.append(p)
8388 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8389 IPv6(src=self.pg0.remote_ip6, dst=self.pg1.remote_ip6) /
8390 GRE() / IP() / TCP())
8391 pkts.append(p)
8392 self.pg0.add_stream(pkts)
8393 self.pg_enable_capture(self.pg_interfaces)
8394 self.pg_start()
8395 capture = self.pg1.get_capture(len(pkts))
8396 for packet in capture:
8397 try:
8398 self.assertEqual(packet[IPv6].src, self.nat_addr)
8399 self.assertEqual(packet[IPv6].dst, self.pg1.remote_ip6)
Klement Sekerad81ae412018-05-16 10:52:54 +02008400 self.assert_packet_checksums_valid(packet)
Matus Fabianf2a23cc2018-01-22 03:41:53 -08008401 except:
8402 self.logger.error(ppp("Unexpected or invalid packet:", packet))
8403 raise
8404
8405 # out2in
8406 pkts = []
8407 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
8408 IPv6(src=self.pg1.remote_ip6, dst=self.nat_addr) /
8409 TCP())
8410 pkts.append(p)
8411 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
8412 IPv6(src=self.pg1.remote_ip6, dst=self.nat_addr) /
8413 UDP())
8414 pkts.append(p)
8415 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
8416 IPv6(src=self.pg1.remote_ip6, dst=self.nat_addr) /
8417 ICMPv6EchoReply())
8418 pkts.append(p)
8419 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
8420 IPv6(src=self.pg1.remote_ip6, dst=self.nat_addr) /
8421 GRE() / IP() / TCP())
8422 pkts.append(p)
8423 self.pg1.add_stream(pkts)
8424 self.pg_enable_capture(self.pg_interfaces)
8425 self.pg_start()
8426 capture = self.pg0.get_capture(len(pkts))
8427 for packet in capture:
8428 try:
8429 self.assertEqual(packet[IPv6].src, self.pg1.remote_ip6)
8430 self.assertEqual(packet[IPv6].dst, self.pg0.remote_ip6)
Klement Sekerad81ae412018-05-16 10:52:54 +02008431 self.assert_packet_checksums_valid(packet)
Matus Fabianf2a23cc2018-01-22 03:41:53 -08008432 except:
8433 self.logger.error(ppp("Unexpected or invalid packet:", packet))
8434 raise
8435
8436 sm = self.vapi.nat66_static_mapping_dump()
8437 self.assertEqual(len(sm), 1)
8438 self.assertEqual(sm[0].total_pkts, 8)
8439
Juraj Sloboda9341e342018-04-13 12:00:46 +02008440 def test_check_no_translate(self):
8441 """ NAT66 translate only when egress interface is outside interface """
8442 self.vapi.nat66_add_del_interface(self.pg0.sw_if_index)
8443 self.vapi.nat66_add_del_interface(self.pg1.sw_if_index)
8444 self.vapi.nat66_add_del_static_mapping(self.pg0.remote_ip6n,
8445 self.nat_addr_n)
8446
8447 # in2out
8448 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8449 IPv6(src=self.pg0.remote_ip6, dst=self.pg1.remote_ip6) /
8450 UDP())
8451 self.pg0.add_stream([p])
8452 self.pg_enable_capture(self.pg_interfaces)
8453 self.pg_start()
8454 capture = self.pg1.get_capture(1)
8455 packet = capture[0]
8456 try:
8457 self.assertEqual(packet[IPv6].src, self.pg0.remote_ip6)
8458 self.assertEqual(packet[IPv6].dst, self.pg1.remote_ip6)
8459 except:
8460 self.logger.error(ppp("Unexpected or invalid packet:", packet))
8461 raise
8462
Matus Fabianf2a23cc2018-01-22 03:41:53 -08008463 def clear_nat66(self):
8464 """
8465 Clear NAT66 configuration.
8466 """
8467 interfaces = self.vapi.nat66_interface_dump()
8468 for intf in interfaces:
8469 self.vapi.nat66_add_del_interface(intf.sw_if_index,
8470 intf.is_inside,
8471 is_add=0)
8472
8473 static_mappings = self.vapi.nat66_static_mapping_dump()
8474 for sm in static_mappings:
8475 self.vapi.nat66_add_del_static_mapping(sm.local_ip_address,
8476 sm.external_ip_address,
8477 sm.vrf_id,
8478 is_add=0)
8479
8480 def tearDown(self):
8481 super(TestNAT66, self).tearDown()
8482 if not self.vpp_dead:
8483 self.logger.info(self.vapi.cli("show nat66 interfaces"))
8484 self.logger.info(self.vapi.cli("show nat66 static mappings"))
8485 self.clear_nat66()
8486
Klement Sekerad81ae412018-05-16 10:52:54 +02008487
Matus Fabiande886752016-12-07 03:38:19 -08008488if __name__ == '__main__':
8489 unittest.main(testRunner=VppTestRunner)