blob: 81aae4bd59ef7095e365ca4e71bc20faf05843da [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 Troan8006c6a2018-12-17 12:02:26 +010021from vpp_papi import mac_pton
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
Paul Vinciguerradefde0f2018-12-06 07:46:13 -08002722 @unittest.skipUnless(running_extended_tests, "part of extended tests")
Matus Fabiana431ad12018-01-04 04:03:14 -08002723 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 Troan8006c6a2018-12-17 12:02:26 +01002955 mac_pton(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 Troan8006c6a2018-12-17 12:02:26 +01002959 mac_pton(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 Troan8006c6a2018-12-17 12:02:26 +01002997 mac_pton(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 Troan8006c6a2018-12-17 12:02:26 +01003001 mac_pton(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 Troan8006c6a2018-12-17 12:02:26 +01003043 mac_pton(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 Troan8006c6a2018-12-17 12:02:26 +01003047 mac_pton(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
Paul Vinciguerradefde0f2018-12-06 07:46:13 -08003701 @unittest.skipUnless(running_extended_tests, "part of extended tests")
Matus Fabian878c6462018-08-23 00:33:35 -07003702 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
Paul Vinciguerradefde0f2018-12-06 07:46:13 -08004263 @unittest.skipUnless(running_extended_tests, "part of extended tests")
Matus Fabiana6110b62018-06-13 05:39:07 -07004264 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]
Matus Fabianb6865082018-12-06 03:11:09 -08004272 server3 = self.pg0.remote_hosts[2]
Matus Fabiana6110b62018-06-13 05:39:07 -07004273
4274 locals = [{'addr': server1.ip4n,
4275 'port': local_port,
Matus Fabianc6c0d2a2018-07-19 22:45:25 -07004276 'probability': 90,
4277 'vrf_id': 0},
Matus Fabiana6110b62018-06-13 05:39:07 -07004278 {'addr': server2.ip4n,
4279 'port': local_port,
Matus Fabianc6c0d2a2018-07-19 22:45:25 -07004280 'probability': 10,
4281 'vrf_id': 0}]
Matus Fabiana6110b62018-06-13 05:39:07 -07004282
4283 self.nat44_add_address(self.nat_addr)
4284 self.vapi.nat44_add_del_lb_static_mapping(external_addr_n,
4285 external_port,
4286 IP_PROTOS.tcp,
4287 local_num=len(locals),
4288 locals=locals)
4289 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
4290 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
4291 is_inside=0)
4292
4293 server1_n = 0
4294 server2_n = 0
4295 clients = ip4_range(self.pg1.remote_ip4, 10, 50)
4296 pkts = []
4297 for client in clients:
4298 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
4299 IP(src=client, dst=self.nat_addr) /
4300 TCP(sport=12345, dport=external_port))
4301 pkts.append(p)
4302 self.pg1.add_stream(pkts)
4303 self.pg_enable_capture(self.pg_interfaces)
4304 self.pg_start()
4305 capture = self.pg0.get_capture(len(pkts))
4306 for p in capture:
4307 if p[IP].dst == server1.ip4:
4308 server1_n += 1
4309 else:
4310 server2_n += 1
Paul Vinciguerra3d2df212018-11-24 23:19:53 -08004311 self.assertGreater(server1_n, server2_n)
Matus Fabiana6110b62018-06-13 05:39:07 -07004312
Matus Fabianb6865082018-12-06 03:11:09 -08004313 # add new back-end
4314 self.vapi.nat44_lb_static_mapping_add_del_local(external_addr_n,
4315 external_port,
4316 server3.ip4n,
4317 local_port,
4318 IP_PROTOS.tcp,
4319 20)
4320 server1_n = 0
4321 server2_n = 0
4322 server3_n = 0
4323 clients = ip4_range(self.pg1.remote_ip4, 60, 110)
4324 pkts = []
4325 for client in clients:
4326 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
4327 IP(src=client, dst=self.nat_addr) /
4328 TCP(sport=12346, dport=external_port))
4329 pkts.append(p)
4330 self.assertGreater(len(pkts), 0)
4331 self.pg1.add_stream(pkts)
4332 self.pg_enable_capture(self.pg_interfaces)
4333 self.pg_start()
4334 capture = self.pg0.get_capture(len(pkts))
4335 for p in capture:
4336 if p[IP].dst == server1.ip4:
4337 server1_n += 1
4338 elif p[IP].dst == server2.ip4:
4339 server2_n += 1
4340 else:
4341 server3_n += 1
4342 self.assertGreater(server1_n, 0)
4343 self.assertGreater(server2_n, 0)
4344 self.assertGreater(server3_n, 0)
4345
4346 # remove one back-end
4347 self.vapi.nat44_lb_static_mapping_add_del_local(external_addr_n,
4348 external_port,
4349 server2.ip4n,
4350 local_port,
4351 IP_PROTOS.tcp,
4352 10,
4353 is_add=0)
4354 server1_n = 0
4355 server2_n = 0
4356 server3_n = 0
4357 self.pg1.add_stream(pkts)
4358 self.pg_enable_capture(self.pg_interfaces)
4359 self.pg_start()
4360 capture = self.pg0.get_capture(len(pkts))
4361 for p in capture:
4362 if p[IP].dst == server1.ip4:
4363 server1_n += 1
4364 elif p[IP].dst == server2.ip4:
4365 server2_n += 1
4366 else:
4367 server3_n += 1
4368 self.assertGreater(server1_n, 0)
4369 self.assertEqual(server2_n, 0)
4370 self.assertGreater(server3_n, 0)
4371
Matus Fabiana6110b62018-06-13 05:39:07 -07004372 def test_static_lb_2(self):
4373 """ NAT44 local service load balancing (asymmetrical rule) """
4374 external_addr_n = socket.inet_pton(socket.AF_INET, self.nat_addr)
4375 external_port = 80
4376 local_port = 8080
4377 server1 = self.pg0.remote_hosts[0]
4378 server2 = self.pg0.remote_hosts[1]
4379
4380 locals = [{'addr': server1.ip4n,
4381 'port': local_port,
Matus Fabianc6c0d2a2018-07-19 22:45:25 -07004382 'probability': 70,
4383 'vrf_id': 0},
Matus Fabiana6110b62018-06-13 05:39:07 -07004384 {'addr': server2.ip4n,
4385 'port': local_port,
Matus Fabianc6c0d2a2018-07-19 22:45:25 -07004386 'probability': 30,
4387 'vrf_id': 0}]
Matus Fabiana6110b62018-06-13 05:39:07 -07004388
4389 self.vapi.nat44_forwarding_enable_disable(1)
4390 self.vapi.nat44_add_del_lb_static_mapping(external_addr_n,
4391 external_port,
4392 IP_PROTOS.tcp,
4393 out2in_only=1,
4394 local_num=len(locals),
4395 locals=locals)
4396 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
4397 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
4398 is_inside=0)
4399
4400 # from client to service
4401 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
4402 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
4403 TCP(sport=12345, dport=external_port))
4404 self.pg1.add_stream(p)
4405 self.pg_enable_capture(self.pg_interfaces)
4406 self.pg_start()
4407 capture = self.pg0.get_capture(1)
4408 p = capture[0]
4409 server = None
4410 try:
4411 ip = p[IP]
4412 tcp = p[TCP]
4413 self.assertIn(ip.dst, [server1.ip4, server2.ip4])
4414 if ip.dst == server1.ip4:
4415 server = server1
4416 else:
4417 server = server2
4418 self.assertEqual(tcp.dport, local_port)
4419 self.assert_packet_checksums_valid(p)
4420 except:
4421 self.logger.error(ppp("Unexpected or invalid packet:", p))
4422 raise
4423
4424 # from service back to client
4425 p = (Ether(src=server.mac, dst=self.pg0.local_mac) /
4426 IP(src=server.ip4, dst=self.pg1.remote_ip4) /
4427 TCP(sport=local_port, dport=12345))
4428 self.pg0.add_stream(p)
4429 self.pg_enable_capture(self.pg_interfaces)
4430 self.pg_start()
4431 capture = self.pg1.get_capture(1)
4432 p = capture[0]
4433 try:
4434 ip = p[IP]
4435 tcp = p[TCP]
4436 self.assertEqual(ip.src, self.nat_addr)
4437 self.assertEqual(tcp.sport, external_port)
4438 self.assert_packet_checksums_valid(p)
4439 except:
4440 self.logger.error(ppp("Unexpected or invalid packet:", p))
4441 raise
4442
4443 # from client to server (no translation)
4444 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
4445 IP(src=self.pg1.remote_ip4, dst=server1.ip4) /
4446 TCP(sport=12346, dport=local_port))
4447 self.pg1.add_stream(p)
4448 self.pg_enable_capture(self.pg_interfaces)
4449 self.pg_start()
4450 capture = self.pg0.get_capture(1)
4451 p = capture[0]
4452 server = None
4453 try:
4454 ip = p[IP]
4455 tcp = p[TCP]
4456 self.assertEqual(ip.dst, server1.ip4)
4457 self.assertEqual(tcp.dport, local_port)
4458 self.assert_packet_checksums_valid(p)
4459 except:
4460 self.logger.error(ppp("Unexpected or invalid packet:", p))
4461 raise
4462
4463 # from service back to client (no translation)
4464 p = (Ether(src=server1.mac, dst=self.pg0.local_mac) /
4465 IP(src=server1.ip4, dst=self.pg1.remote_ip4) /
4466 TCP(sport=local_port, dport=12346))
4467 self.pg0.add_stream(p)
4468 self.pg_enable_capture(self.pg_interfaces)
4469 self.pg_start()
4470 capture = self.pg1.get_capture(1)
4471 p = capture[0]
4472 try:
4473 ip = p[IP]
4474 tcp = p[TCP]
4475 self.assertEqual(ip.src, server1.ip4)
4476 self.assertEqual(tcp.sport, local_port)
4477 self.assert_packet_checksums_valid(p)
4478 except:
4479 self.logger.error(ppp("Unexpected or invalid packet:", p))
4480 raise
4481
Matus Fabianea5b5be2018-09-03 05:02:23 -07004482 def test_lb_affinity(self):
4483 """ NAT44 local service load balancing affinity """
4484 external_addr_n = socket.inet_pton(socket.AF_INET, self.nat_addr)
4485 external_port = 80
4486 local_port = 8080
4487 server1 = self.pg0.remote_hosts[0]
4488 server2 = self.pg0.remote_hosts[1]
4489
4490 locals = [{'addr': server1.ip4n,
4491 'port': local_port,
4492 'probability': 50,
4493 'vrf_id': 0},
4494 {'addr': server2.ip4n,
4495 'port': local_port,
4496 'probability': 50,
4497 'vrf_id': 0}]
4498
4499 self.nat44_add_address(self.nat_addr)
4500 self.vapi.nat44_add_del_lb_static_mapping(external_addr_n,
4501 external_port,
4502 IP_PROTOS.tcp,
4503 affinity=10800,
4504 local_num=len(locals),
4505 locals=locals)
4506 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
4507 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
4508 is_inside=0)
4509
4510 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
4511 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
4512 TCP(sport=1025, dport=external_port))
4513 self.pg1.add_stream(p)
4514 self.pg_enable_capture(self.pg_interfaces)
4515 self.pg_start()
4516 capture = self.pg0.get_capture(1)
4517 backend = capture[0][IP].dst
4518
4519 sessions = self.vapi.nat44_user_session_dump(
4520 socket.inet_pton(socket.AF_INET, backend), 0)
4521 self.assertEqual(len(sessions), 1)
4522 self.assertTrue(sessions[0].ext_host_valid)
4523 self.vapi.nat44_del_session(
4524 sessions[0].inside_ip_address,
4525 sessions[0].inside_port,
4526 sessions[0].protocol,
4527 ext_host_address=sessions[0].ext_host_address,
4528 ext_host_port=sessions[0].ext_host_port)
4529
4530 pkts = []
4531 for port in range(1030, 1100):
4532 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
4533 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
4534 TCP(sport=port, dport=external_port))
4535 pkts.append(p)
4536 self.pg1.add_stream(pkts)
4537 self.pg_enable_capture(self.pg_interfaces)
4538 self.pg_start()
4539 capture = self.pg0.get_capture(len(pkts))
4540 for p in capture:
4541 self.assertEqual(p[IP].dst, backend)
4542
Matus Fabiana6110b62018-06-13 05:39:07 -07004543 def test_unknown_proto(self):
4544 """ NAT44 translate packet with unknown protocol """
4545 self.nat44_add_address(self.nat_addr)
4546 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
4547 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
4548 is_inside=0)
4549
4550 # in2out
4551 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
4552 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
4553 TCP(sport=self.tcp_port_in, dport=20))
4554 self.pg0.add_stream(p)
4555 self.pg_enable_capture(self.pg_interfaces)
4556 self.pg_start()
4557 p = self.pg1.get_capture(1)
4558
4559 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
4560 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
4561 GRE() /
4562 IP(src=self.pg2.remote_ip4, dst=self.pg2.remote_ip4) /
4563 TCP(sport=1234, dport=1234))
4564 self.pg0.add_stream(p)
4565 self.pg_enable_capture(self.pg_interfaces)
4566 self.pg_start()
4567 p = self.pg1.get_capture(1)
4568 packet = p[0]
4569 try:
4570 self.assertEqual(packet[IP].src, self.nat_addr)
4571 self.assertEqual(packet[IP].dst, self.pg1.remote_ip4)
Paul Vinciguerra978aa642018-11-24 22:19:12 -08004572 self.assertEqual(packet.haslayer(GRE), 1)
Matus Fabiana6110b62018-06-13 05:39:07 -07004573 self.assert_packet_checksums_valid(packet)
4574 except:
4575 self.logger.error(ppp("Unexpected or invalid packet:", packet))
4576 raise
4577
4578 # out2in
4579 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
4580 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
4581 GRE() /
4582 IP(src=self.pg2.remote_ip4, dst=self.pg2.remote_ip4) /
4583 TCP(sport=1234, dport=1234))
4584 self.pg1.add_stream(p)
4585 self.pg_enable_capture(self.pg_interfaces)
4586 self.pg_start()
4587 p = self.pg0.get_capture(1)
4588 packet = p[0]
4589 try:
4590 self.assertEqual(packet[IP].src, self.pg1.remote_ip4)
4591 self.assertEqual(packet[IP].dst, self.pg0.remote_ip4)
Paul Vinciguerra978aa642018-11-24 22:19:12 -08004592 self.assertEqual(packet.haslayer(GRE), 1)
Matus Fabiana6110b62018-06-13 05:39:07 -07004593 self.assert_packet_checksums_valid(packet)
4594 except:
4595 self.logger.error(ppp("Unexpected or invalid packet:", packet))
4596 raise
4597
4598 def test_hairpinning_unknown_proto(self):
4599 """ NAT44 translate packet with unknown protocol - hairpinning """
4600 host = self.pg0.remote_hosts[0]
4601 server = self.pg0.remote_hosts[1]
4602 host_in_port = 1234
4603 server_out_port = 8765
4604 server_nat_ip = "10.0.0.11"
4605
4606 self.nat44_add_address(self.nat_addr)
4607 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
4608 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
4609 is_inside=0)
4610
4611 # add static mapping for server
4612 self.nat44_add_static_mapping(server.ip4, server_nat_ip)
4613
4614 # host to server
4615 p = (Ether(src=host.mac, dst=self.pg0.local_mac) /
4616 IP(src=host.ip4, dst=server_nat_ip) /
4617 TCP(sport=host_in_port, dport=server_out_port))
4618 self.pg0.add_stream(p)
4619 self.pg_enable_capture(self.pg_interfaces)
4620 self.pg_start()
4621 self.pg0.get_capture(1)
4622
4623 p = (Ether(dst=self.pg0.local_mac, src=host.mac) /
4624 IP(src=host.ip4, dst=server_nat_ip) /
4625 GRE() /
4626 IP(src=self.pg2.remote_ip4, dst=self.pg2.remote_ip4) /
4627 TCP(sport=1234, dport=1234))
4628 self.pg0.add_stream(p)
4629 self.pg_enable_capture(self.pg_interfaces)
4630 self.pg_start()
4631 p = self.pg0.get_capture(1)
4632 packet = p[0]
4633 try:
4634 self.assertEqual(packet[IP].src, self.nat_addr)
4635 self.assertEqual(packet[IP].dst, server.ip4)
Paul Vinciguerra978aa642018-11-24 22:19:12 -08004636 self.assertEqual(packet.haslayer(GRE), 1)
Matus Fabiana6110b62018-06-13 05:39:07 -07004637 self.assert_packet_checksums_valid(packet)
4638 except:
4639 self.logger.error(ppp("Unexpected or invalid packet:", packet))
4640 raise
4641
4642 # server to host
4643 p = (Ether(dst=self.pg0.local_mac, src=server.mac) /
4644 IP(src=server.ip4, dst=self.nat_addr) /
4645 GRE() /
4646 IP(src=self.pg2.remote_ip4, dst=self.pg2.remote_ip4) /
4647 TCP(sport=1234, dport=1234))
4648 self.pg0.add_stream(p)
4649 self.pg_enable_capture(self.pg_interfaces)
4650 self.pg_start()
4651 p = self.pg0.get_capture(1)
4652 packet = p[0]
4653 try:
4654 self.assertEqual(packet[IP].src, server_nat_ip)
4655 self.assertEqual(packet[IP].dst, host.ip4)
Paul Vinciguerra978aa642018-11-24 22:19:12 -08004656 self.assertEqual(packet.haslayer(GRE), 1)
Matus Fabiana6110b62018-06-13 05:39:07 -07004657 self.assert_packet_checksums_valid(packet)
4658 except:
4659 self.logger.error(ppp("Unexpected or invalid packet:", packet))
4660 raise
4661
4662 def test_output_feature_and_service(self):
4663 """ NAT44 interface output feature and services """
4664 external_addr = '1.2.3.4'
4665 external_port = 80
4666 local_port = 8080
4667
4668 self.vapi.nat44_forwarding_enable_disable(1)
4669 self.nat44_add_address(self.nat_addr)
4670 self.vapi.nat44_add_del_identity_mapping(ip=self.pg1.remote_ip4n)
4671 self.nat44_add_static_mapping(self.pg0.remote_ip4, external_addr,
4672 local_port, external_port,
4673 proto=IP_PROTOS.tcp, out2in_only=1)
4674 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
4675 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index,
4676 is_inside=0)
4677 self.vapi.nat44_interface_add_del_output_feature(self.pg1.sw_if_index,
4678 is_inside=0)
4679
4680 # from client to service
4681 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
4682 IP(src=self.pg1.remote_ip4, dst=external_addr) /
4683 TCP(sport=12345, dport=external_port))
4684 self.pg1.add_stream(p)
4685 self.pg_enable_capture(self.pg_interfaces)
4686 self.pg_start()
4687 capture = self.pg0.get_capture(1)
4688 p = capture[0]
4689 try:
4690 ip = p[IP]
4691 tcp = p[TCP]
4692 self.assertEqual(ip.dst, self.pg0.remote_ip4)
4693 self.assertEqual(tcp.dport, local_port)
4694 self.assert_packet_checksums_valid(p)
4695 except:
4696 self.logger.error(ppp("Unexpected or invalid packet:", p))
4697 raise
4698
4699 # from service back to client
4700 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
4701 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
4702 TCP(sport=local_port, dport=12345))
4703 self.pg0.add_stream(p)
4704 self.pg_enable_capture(self.pg_interfaces)
4705 self.pg_start()
4706 capture = self.pg1.get_capture(1)
4707 p = capture[0]
4708 try:
4709 ip = p[IP]
4710 tcp = p[TCP]
4711 self.assertEqual(ip.src, external_addr)
4712 self.assertEqual(tcp.sport, external_port)
4713 self.assert_packet_checksums_valid(p)
4714 except:
4715 self.logger.error(ppp("Unexpected or invalid packet:", p))
4716 raise
4717
4718 # from local network host to external network
4719 pkts = self.create_stream_in(self.pg0, self.pg1)
4720 self.pg0.add_stream(pkts)
4721 self.pg_enable_capture(self.pg_interfaces)
4722 self.pg_start()
4723 capture = self.pg1.get_capture(len(pkts))
4724 self.verify_capture_out(capture)
4725 pkts = self.create_stream_in(self.pg0, self.pg1)
4726 self.pg0.add_stream(pkts)
4727 self.pg_enable_capture(self.pg_interfaces)
4728 self.pg_start()
4729 capture = self.pg1.get_capture(len(pkts))
4730 self.verify_capture_out(capture)
4731
4732 # from external network back to local network host
4733 pkts = self.create_stream_out(self.pg1)
4734 self.pg1.add_stream(pkts)
4735 self.pg_enable_capture(self.pg_interfaces)
4736 self.pg_start()
4737 capture = self.pg0.get_capture(len(pkts))
4738 self.verify_capture_in(capture, self.pg0)
4739
4740 def test_output_feature_and_service2(self):
4741 """ NAT44 interface output feature and service host direct access """
4742 self.vapi.nat44_forwarding_enable_disable(1)
4743 self.nat44_add_address(self.nat_addr)
4744 self.vapi.nat44_interface_add_del_output_feature(self.pg1.sw_if_index,
4745 is_inside=0)
4746
4747 # session initiaded from service host - translate
4748 pkts = self.create_stream_in(self.pg0, self.pg1)
4749 self.pg0.add_stream(pkts)
4750 self.pg_enable_capture(self.pg_interfaces)
4751 self.pg_start()
4752 capture = self.pg1.get_capture(len(pkts))
4753 self.verify_capture_out(capture)
4754
4755 pkts = self.create_stream_out(self.pg1)
4756 self.pg1.add_stream(pkts)
4757 self.pg_enable_capture(self.pg_interfaces)
4758 self.pg_start()
4759 capture = self.pg0.get_capture(len(pkts))
4760 self.verify_capture_in(capture, self.pg0)
4761
4762 # session initiaded from remote host - do not translate
4763 self.tcp_port_in = 60303
4764 self.udp_port_in = 60304
4765 self.icmp_id_in = 60305
4766 pkts = self.create_stream_out(self.pg1,
4767 self.pg0.remote_ip4,
4768 use_inside_ports=True)
4769 self.pg1.add_stream(pkts)
4770 self.pg_enable_capture(self.pg_interfaces)
4771 self.pg_start()
4772 capture = self.pg0.get_capture(len(pkts))
4773 self.verify_capture_in(capture, self.pg0)
4774
4775 pkts = self.create_stream_in(self.pg0, self.pg1)
4776 self.pg0.add_stream(pkts)
4777 self.pg_enable_capture(self.pg_interfaces)
4778 self.pg_start()
4779 capture = self.pg1.get_capture(len(pkts))
4780 self.verify_capture_out(capture, nat_ip=self.pg0.remote_ip4,
4781 same_port=True)
4782
4783 def test_output_feature_and_service3(self):
4784 """ NAT44 interface output feature and DST NAT """
4785 external_addr = '1.2.3.4'
4786 external_port = 80
4787 local_port = 8080
4788
4789 self.vapi.nat44_forwarding_enable_disable(1)
4790 self.nat44_add_address(self.nat_addr)
4791 self.nat44_add_static_mapping(self.pg1.remote_ip4, external_addr,
4792 local_port, external_port,
4793 proto=IP_PROTOS.tcp, out2in_only=1)
4794 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
4795 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index,
4796 is_inside=0)
4797 self.vapi.nat44_interface_add_del_output_feature(self.pg1.sw_if_index,
4798 is_inside=0)
4799
4800 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
4801 IP(src=self.pg0.remote_ip4, dst=external_addr) /
4802 TCP(sport=12345, dport=external_port))
4803 self.pg0.add_stream(p)
4804 self.pg_enable_capture(self.pg_interfaces)
4805 self.pg_start()
4806 capture = self.pg1.get_capture(1)
4807 p = capture[0]
4808 try:
4809 ip = p[IP]
4810 tcp = p[TCP]
4811 self.assertEqual(ip.src, self.pg0.remote_ip4)
4812 self.assertEqual(tcp.sport, 12345)
4813 self.assertEqual(ip.dst, self.pg1.remote_ip4)
4814 self.assertEqual(tcp.dport, local_port)
4815 self.assert_packet_checksums_valid(p)
4816 except:
4817 self.logger.error(ppp("Unexpected or invalid packet:", p))
4818 raise
4819
4820 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
4821 IP(src=self.pg1.remote_ip4, dst=self.pg0.remote_ip4) /
4822 TCP(sport=local_port, dport=12345))
4823 self.pg1.add_stream(p)
4824 self.pg_enable_capture(self.pg_interfaces)
4825 self.pg_start()
4826 capture = self.pg0.get_capture(1)
4827 p = capture[0]
4828 try:
4829 ip = p[IP]
4830 tcp = p[TCP]
4831 self.assertEqual(ip.src, external_addr)
4832 self.assertEqual(tcp.sport, external_port)
4833 self.assertEqual(ip.dst, self.pg0.remote_ip4)
4834 self.assertEqual(tcp.dport, 12345)
4835 self.assert_packet_checksums_valid(p)
4836 except:
4837 self.logger.error(ppp("Unexpected or invalid packet:", p))
4838 raise
4839
Matus Fabian182e37e2018-08-14 04:21:26 -07004840 def test_next_src_nat(self):
4841 """ On way back forward packet to nat44-in2out node. """
4842 twice_nat_addr = '10.0.1.3'
4843 external_port = 80
4844 local_port = 8080
4845 post_twice_nat_port = 0
4846
4847 self.vapi.nat44_forwarding_enable_disable(1)
4848 self.nat44_add_address(twice_nat_addr, twice_nat=1)
4849 self.nat44_add_static_mapping(self.pg6.remote_ip4, self.pg1.remote_ip4,
4850 local_port, external_port,
4851 proto=IP_PROTOS.tcp, out2in_only=1,
4852 self_twice_nat=1, vrf_id=1)
4853 self.vapi.nat44_interface_add_del_feature(self.pg6.sw_if_index,
4854 is_inside=0)
4855
4856 p = (Ether(src=self.pg6.remote_mac, dst=self.pg6.local_mac) /
4857 IP(src=self.pg6.remote_ip4, dst=self.pg1.remote_ip4) /
4858 TCP(sport=12345, dport=external_port))
4859 self.pg6.add_stream(p)
4860 self.pg_enable_capture(self.pg_interfaces)
4861 self.pg_start()
4862 capture = self.pg6.get_capture(1)
4863 p = capture[0]
4864 try:
4865 ip = p[IP]
4866 tcp = p[TCP]
4867 self.assertEqual(ip.src, twice_nat_addr)
4868 self.assertNotEqual(tcp.sport, 12345)
4869 post_twice_nat_port = tcp.sport
4870 self.assertEqual(ip.dst, self.pg6.remote_ip4)
4871 self.assertEqual(tcp.dport, local_port)
4872 self.assert_packet_checksums_valid(p)
4873 except:
4874 self.logger.error(ppp("Unexpected or invalid packet:", p))
4875 raise
4876
4877 p = (Ether(src=self.pg6.remote_mac, dst=self.pg6.local_mac) /
4878 IP(src=self.pg6.remote_ip4, dst=twice_nat_addr) /
4879 TCP(sport=local_port, dport=post_twice_nat_port))
4880 self.pg6.add_stream(p)
4881 self.pg_enable_capture(self.pg_interfaces)
4882 self.pg_start()
4883 capture = self.pg6.get_capture(1)
4884 p = capture[0]
4885 try:
4886 ip = p[IP]
4887 tcp = p[TCP]
4888 self.assertEqual(ip.src, self.pg1.remote_ip4)
4889 self.assertEqual(tcp.sport, external_port)
4890 self.assertEqual(ip.dst, self.pg6.remote_ip4)
4891 self.assertEqual(tcp.dport, 12345)
4892 self.assert_packet_checksums_valid(p)
4893 except:
4894 self.logger.error(ppp("Unexpected or invalid packet:", p))
4895 raise
4896
Juraj Sloboda1e5c07d2018-04-10 13:51:54 +02004897 def twice_nat_common(self, self_twice_nat=False, same_pg=False, lb=False,
4898 client_id=None):
Matus Fabianb932d262017-12-18 05:38:24 -08004899 twice_nat_addr = '10.0.1.3'
Juraj Sloboda1e5c07d2018-04-10 13:51:54 +02004900
Matus Fabianb932d262017-12-18 05:38:24 -08004901 port_in = 8080
Juraj Sloboda1e5c07d2018-04-10 13:51:54 +02004902 if lb:
4903 if not same_pg:
4904 port_in1 = port_in
4905 port_in2 = port_in
4906 else:
4907 port_in1 = port_in+1
4908 port_in2 = port_in+2
4909
Matus Fabianb932d262017-12-18 05:38:24 -08004910 port_out = 80
4911 eh_port_out = 4567
Juraj Sloboda1e5c07d2018-04-10 13:51:54 +02004912
4913 server1 = self.pg0.remote_hosts[0]
4914 server2 = self.pg0.remote_hosts[1]
4915 if lb and same_pg:
4916 server2 = server1
4917 if not lb:
4918 server = server1
4919
4920 pg0 = self.pg0
4921 if same_pg:
4922 pg1 = self.pg0
4923 else:
4924 pg1 = self.pg1
4925
4926 eh_translate = ((not self_twice_nat) or (not lb and same_pg) or
4927 client_id == 1)
4928
Matus Fabianb932d262017-12-18 05:38:24 -08004929 self.nat44_add_address(self.nat_addr)
4930 self.nat44_add_address(twice_nat_addr, twice_nat=1)
Juraj Sloboda1e5c07d2018-04-10 13:51:54 +02004931 if not lb:
4932 self.nat44_add_static_mapping(pg0.remote_ip4, self.nat_addr,
4933 port_in, port_out,
4934 proto=IP_PROTOS.tcp,
4935 twice_nat=int(not self_twice_nat),
4936 self_twice_nat=int(self_twice_nat))
4937 else:
4938 locals = [{'addr': server1.ip4n,
4939 'port': port_in1,
Matus Fabianc6c0d2a2018-07-19 22:45:25 -07004940 'probability': 50,
4941 'vrf_id': 0},
Juraj Sloboda1e5c07d2018-04-10 13:51:54 +02004942 {'addr': server2.ip4n,
4943 'port': port_in2,
Matus Fabianc6c0d2a2018-07-19 22:45:25 -07004944 'probability': 50,
4945 'vrf_id': 0}]
Juraj Sloboda1e5c07d2018-04-10 13:51:54 +02004946 out_addr_n = socket.inet_pton(socket.AF_INET, self.nat_addr)
4947 self.vapi.nat44_add_del_lb_static_mapping(out_addr_n,
4948 port_out,
4949 IP_PROTOS.tcp,
4950 twice_nat=int(
4951 not self_twice_nat),
4952 self_twice_nat=int(
4953 self_twice_nat),
4954 local_num=len(locals),
4955 locals=locals)
4956 self.vapi.nat44_interface_add_del_feature(pg0.sw_if_index)
4957 self.vapi.nat44_interface_add_del_feature(pg1.sw_if_index,
Matus Fabianb932d262017-12-18 05:38:24 -08004958 is_inside=0)
4959
Juraj Sloboda1e5c07d2018-04-10 13:51:54 +02004960 if same_pg:
4961 if not lb:
4962 client = server
4963 else:
4964 assert client_id is not None
4965 if client_id == 1:
4966 client = self.pg0.remote_hosts[0]
4967 elif client_id == 2:
4968 client = self.pg0.remote_hosts[1]
4969 else:
4970 client = pg1.remote_hosts[0]
4971 p = (Ether(src=pg1.remote_mac, dst=pg1.local_mac) /
4972 IP(src=client.ip4, dst=self.nat_addr) /
Matus Fabianb932d262017-12-18 05:38:24 -08004973 TCP(sport=eh_port_out, dport=port_out))
Juraj Sloboda1e5c07d2018-04-10 13:51:54 +02004974 pg1.add_stream(p)
Matus Fabianb932d262017-12-18 05:38:24 -08004975 self.pg_enable_capture(self.pg_interfaces)
4976 self.pg_start()
Juraj Sloboda1e5c07d2018-04-10 13:51:54 +02004977 capture = pg0.get_capture(1)
Matus Fabianb932d262017-12-18 05:38:24 -08004978 p = capture[0]
4979 try:
4980 ip = p[IP]
4981 tcp = p[TCP]
Juraj Sloboda1e5c07d2018-04-10 13:51:54 +02004982 if lb:
4983 if ip.dst == server1.ip4:
4984 server = server1
4985 port_in = port_in1
4986 else:
4987 server = server2
4988 port_in = port_in2
4989 self.assertEqual(ip.dst, server.ip4)
4990 if lb and same_pg:
4991 self.assertIn(tcp.dport, [port_in1, port_in2])
4992 else:
4993 self.assertEqual(tcp.dport, port_in)
4994 if eh_translate:
4995 self.assertEqual(ip.src, twice_nat_addr)
4996 self.assertNotEqual(tcp.sport, eh_port_out)
4997 else:
4998 self.assertEqual(ip.src, client.ip4)
4999 self.assertEqual(tcp.sport, eh_port_out)
5000 eh_addr_in = ip.src
Matus Fabianb932d262017-12-18 05:38:24 -08005001 eh_port_in = tcp.sport
Juraj Sloboda1e5c07d2018-04-10 13:51:54 +02005002 saved_port_in = tcp.dport
Klement Sekerad81ae412018-05-16 10:52:54 +02005003 self.assert_packet_checksums_valid(p)
Matus Fabianb932d262017-12-18 05:38:24 -08005004 except:
5005 self.logger.error(ppp("Unexpected or invalid packet:", p))
5006 raise
5007
Juraj Sloboda1e5c07d2018-04-10 13:51:54 +02005008 p = (Ether(src=server.mac, dst=pg0.local_mac) /
5009 IP(src=server.ip4, dst=eh_addr_in) /
5010 TCP(sport=saved_port_in, dport=eh_port_in))
5011 pg0.add_stream(p)
Matus Fabianb932d262017-12-18 05:38:24 -08005012 self.pg_enable_capture(self.pg_interfaces)
5013 self.pg_start()
Juraj Sloboda1e5c07d2018-04-10 13:51:54 +02005014 capture = pg1.get_capture(1)
Matus Fabianb932d262017-12-18 05:38:24 -08005015 p = capture[0]
5016 try:
5017 ip = p[IP]
5018 tcp = p[TCP]
Juraj Sloboda1e5c07d2018-04-10 13:51:54 +02005019 self.assertEqual(ip.dst, client.ip4)
Matus Fabianb932d262017-12-18 05:38:24 -08005020 self.assertEqual(ip.src, self.nat_addr)
5021 self.assertEqual(tcp.dport, eh_port_out)
5022 self.assertEqual(tcp.sport, port_out)
Klement Sekerad81ae412018-05-16 10:52:54 +02005023 self.assert_packet_checksums_valid(p)
Matus Fabianb932d262017-12-18 05:38:24 -08005024 except:
5025 self.logger.error(ppp("Unexpected or invalid packet:", p))
5026 raise
5027
Matus Fabian70a26ac2018-05-14 06:20:28 -07005028 if eh_translate:
5029 sessions = self.vapi.nat44_user_session_dump(server.ip4n, 0)
5030 self.assertEqual(len(sessions), 1)
5031 self.assertTrue(sessions[0].ext_host_valid)
5032 self.assertTrue(sessions[0].is_twicenat)
5033 self.vapi.nat44_del_session(
5034 sessions[0].inside_ip_address,
5035 sessions[0].inside_port,
5036 sessions[0].protocol,
5037 ext_host_address=sessions[0].ext_host_nat_address,
5038 ext_host_port=sessions[0].ext_host_nat_port)
5039 sessions = self.vapi.nat44_user_session_dump(server.ip4n, 0)
5040 self.assertEqual(len(sessions), 0)
5041
Juraj Sloboda1e5c07d2018-04-10 13:51:54 +02005042 def test_twice_nat(self):
5043 """ Twice NAT44 """
5044 self.twice_nat_common()
5045
5046 def test_self_twice_nat_positive(self):
5047 """ Self Twice NAT44 (positive test) """
5048 self.twice_nat_common(self_twice_nat=True, same_pg=True)
5049
5050 def test_self_twice_nat_negative(self):
5051 """ Self Twice NAT44 (negative test) """
5052 self.twice_nat_common(self_twice_nat=True)
5053
Matus Fabianb932d262017-12-18 05:38:24 -08005054 def test_twice_nat_lb(self):
5055 """ Twice NAT44 local service load balancing """
Juraj Sloboda1e5c07d2018-04-10 13:51:54 +02005056 self.twice_nat_common(lb=True)
Matus Fabianb932d262017-12-18 05:38:24 -08005057
Juraj Sloboda1e5c07d2018-04-10 13:51:54 +02005058 def test_self_twice_nat_lb_positive(self):
5059 """ Self Twice NAT44 local service load balancing (positive test) """
5060 self.twice_nat_common(lb=True, self_twice_nat=True, same_pg=True,
5061 client_id=1)
Matus Fabianb932d262017-12-18 05:38:24 -08005062
Juraj Sloboda1e5c07d2018-04-10 13:51:54 +02005063 def test_self_twice_nat_lb_negative(self):
5064 """ Self Twice NAT44 local service load balancing (negative test) """
5065 self.twice_nat_common(lb=True, self_twice_nat=True, same_pg=True,
5066 client_id=2)
Matus Fabianb932d262017-12-18 05:38:24 -08005067
5068 def test_twice_nat_interface_addr(self):
5069 """ Acquire twice NAT44 addresses from interface """
Matus Fabiana6110b62018-06-13 05:39:07 -07005070 self.vapi.nat44_add_interface_addr(self.pg3.sw_if_index, twice_nat=1)
Matus Fabianb932d262017-12-18 05:38:24 -08005071
5072 # no address in NAT pool
5073 adresses = self.vapi.nat44_address_dump()
5074 self.assertEqual(0, len(adresses))
5075
5076 # configure interface address and check NAT address pool
Matus Fabiana6110b62018-06-13 05:39:07 -07005077 self.pg3.config_ip4()
Matus Fabianb932d262017-12-18 05:38:24 -08005078 adresses = self.vapi.nat44_address_dump()
5079 self.assertEqual(1, len(adresses))
Matus Fabiana6110b62018-06-13 05:39:07 -07005080 self.assertEqual(adresses[0].ip_address[0:4], self.pg3.local_ip4n)
Matus Fabianb932d262017-12-18 05:38:24 -08005081 self.assertEqual(adresses[0].twice_nat, 1)
5082
5083 # remove interface address and check NAT address pool
Matus Fabiana6110b62018-06-13 05:39:07 -07005084 self.pg3.unconfig_ip4()
Matus Fabianb932d262017-12-18 05:38:24 -08005085 adresses = self.vapi.nat44_address_dump()
5086 self.assertEqual(0, len(adresses))
5087
Matus Fabian6c01dce2018-11-16 04:41:31 -08005088 def test_tcp_close(self):
5089 """ Close TCP session from inside network - output feature """
5090 self.vapi.nat44_forwarding_enable_disable(1)
5091 self.nat44_add_address(self.pg1.local_ip4)
5092 twice_nat_addr = '10.0.1.3'
5093 service_ip = '192.168.16.150'
5094 self.nat44_add_address(twice_nat_addr, twice_nat=1)
5095 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
5096 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index,
5097 is_inside=0)
5098 self.vapi.nat44_interface_add_del_output_feature(self.pg1.sw_if_index,
5099 is_inside=0)
5100 self.nat44_add_static_mapping(self.pg0.remote_ip4,
5101 service_ip,
5102 80,
5103 80,
5104 proto=IP_PROTOS.tcp,
5105 out2in_only=1,
5106 twice_nat=1)
5107 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n, 0)
5108 start_sessnum = len(sessions)
5109
5110 # SYN packet out->in
5111 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5112 IP(src=self.pg1.remote_ip4, dst=service_ip) /
5113 TCP(sport=33898, dport=80, flags="S"))
5114 self.pg1.add_stream(p)
5115 self.pg_enable_capture(self.pg_interfaces)
5116 self.pg_start()
5117 capture = self.pg0.get_capture(1)
5118 p = capture[0]
5119 tcp_port = p[TCP].sport
5120
5121 # SYN + ACK packet in->out
5122 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5123 IP(src=self.pg0.remote_ip4, dst=twice_nat_addr) /
5124 TCP(sport=80, dport=tcp_port, flags="SA"))
5125 self.pg0.add_stream(p)
5126 self.pg_enable_capture(self.pg_interfaces)
5127 self.pg_start()
5128 self.pg1.get_capture(1)
5129
5130 # ACK packet out->in
5131 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5132 IP(src=self.pg1.remote_ip4, dst=service_ip) /
5133 TCP(sport=33898, dport=80, flags="A"))
5134 self.pg1.add_stream(p)
5135 self.pg_enable_capture(self.pg_interfaces)
5136 self.pg_start()
5137 self.pg0.get_capture(1)
5138
5139 # FIN packet in -> out
5140 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5141 IP(src=self.pg0.remote_ip4, dst=twice_nat_addr) /
5142 TCP(sport=80, dport=tcp_port, flags="FA", seq=100, ack=300))
5143 self.pg0.add_stream(p)
5144 self.pg_enable_capture(self.pg_interfaces)
5145 self.pg_start()
5146 self.pg1.get_capture(1)
5147
5148 # FIN+ACK packet out -> in
5149 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5150 IP(src=self.pg1.remote_ip4, dst=service_ip) /
5151 TCP(sport=33898, dport=80, flags="FA", seq=300, ack=101))
5152 self.pg1.add_stream(p)
5153 self.pg_enable_capture(self.pg_interfaces)
5154 self.pg_start()
5155 self.pg0.get_capture(1)
5156
5157 # ACK packet in -> out
5158 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5159 IP(src=self.pg0.remote_ip4, dst=twice_nat_addr) /
5160 TCP(sport=80, dport=tcp_port, flags="A", seq=101, ack=301))
5161 self.pg0.add_stream(p)
5162 self.pg_enable_capture(self.pg_interfaces)
5163 self.pg_start()
5164 self.pg1.get_capture(1)
5165
5166 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n,
5167 0)
5168 self.assertEqual(len(sessions) - start_sessnum, 0)
5169
Matus Fabianebdf1902018-05-04 03:57:42 -07005170 def test_tcp_session_close_in(self):
5171 """ Close TCP session from inside network """
Matus Fabian229c1aa2018-05-28 04:09:52 -07005172 self.tcp_port_out = 10505
Matus Fabianebdf1902018-05-04 03:57:42 -07005173 self.nat44_add_address(self.nat_addr)
Matus Fabian229c1aa2018-05-28 04:09:52 -07005174 self.nat44_add_static_mapping(self.pg0.remote_ip4,
5175 self.nat_addr,
5176 self.tcp_port_in,
5177 self.tcp_port_out,
5178 proto=IP_PROTOS.tcp,
5179 twice_nat=1)
Matus Fabianebdf1902018-05-04 03:57:42 -07005180 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
5181 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
5182 is_inside=0)
5183
5184 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n, 0)
5185 start_sessnum = len(sessions)
5186
5187 self.initiate_tcp_session(self.pg0, self.pg1)
5188
Matus Fabian229c1aa2018-05-28 04:09:52 -07005189 # FIN packet in -> out
5190 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5191 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5192 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
5193 flags="FA", seq=100, ack=300))
5194 self.pg0.add_stream(p)
5195 self.pg_enable_capture(self.pg_interfaces)
5196 self.pg_start()
5197 self.pg1.get_capture(1)
Matus Fabianebdf1902018-05-04 03:57:42 -07005198
Matus Fabian229c1aa2018-05-28 04:09:52 -07005199 pkts = []
Matus Fabianebdf1902018-05-04 03:57:42 -07005200
Matus Fabian229c1aa2018-05-28 04:09:52 -07005201 # ACK packet out -> in
5202 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5203 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5204 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
5205 flags="A", seq=300, ack=101))
5206 pkts.append(p)
Matus Fabianebdf1902018-05-04 03:57:42 -07005207
Matus Fabian229c1aa2018-05-28 04:09:52 -07005208 # FIN packet out -> in
5209 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5210 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5211 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
5212 flags="FA", seq=300, ack=101))
5213 pkts.append(p)
Matus Fabianebdf1902018-05-04 03:57:42 -07005214
Matus Fabian229c1aa2018-05-28 04:09:52 -07005215 self.pg1.add_stream(pkts)
5216 self.pg_enable_capture(self.pg_interfaces)
5217 self.pg_start()
5218 self.pg0.get_capture(2)
Matus Fabianebdf1902018-05-04 03:57:42 -07005219
Matus Fabian229c1aa2018-05-28 04:09:52 -07005220 # ACK packet in -> out
5221 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5222 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5223 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
5224 flags="A", seq=101, ack=301))
5225 self.pg0.add_stream(p)
5226 self.pg_enable_capture(self.pg_interfaces)
5227 self.pg_start()
5228 self.pg1.get_capture(1)
Matus Fabianebdf1902018-05-04 03:57:42 -07005229
Matus Fabian229c1aa2018-05-28 04:09:52 -07005230 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n,
5231 0)
5232 self.assertEqual(len(sessions) - start_sessnum, 0)
Matus Fabianebdf1902018-05-04 03:57:42 -07005233
5234 def test_tcp_session_close_out(self):
5235 """ Close TCP session from outside network """
Matus Fabian229c1aa2018-05-28 04:09:52 -07005236 self.tcp_port_out = 10505
Matus Fabianebdf1902018-05-04 03:57:42 -07005237 self.nat44_add_address(self.nat_addr)
Matus Fabian229c1aa2018-05-28 04:09:52 -07005238 self.nat44_add_static_mapping(self.pg0.remote_ip4,
5239 self.nat_addr,
5240 self.tcp_port_in,
5241 self.tcp_port_out,
5242 proto=IP_PROTOS.tcp,
5243 twice_nat=1)
Matus Fabianebdf1902018-05-04 03:57:42 -07005244 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
5245 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
5246 is_inside=0)
5247
5248 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n, 0)
5249 start_sessnum = len(sessions)
5250
5251 self.initiate_tcp_session(self.pg0, self.pg1)
5252
Matus Fabian229c1aa2018-05-28 04:09:52 -07005253 # FIN packet out -> in
5254 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5255 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5256 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
5257 flags="FA", seq=100, ack=300))
5258 self.pg1.add_stream(p)
5259 self.pg_enable_capture(self.pg_interfaces)
5260 self.pg_start()
5261 self.pg0.get_capture(1)
Matus Fabianebdf1902018-05-04 03:57:42 -07005262
Matus Fabian229c1aa2018-05-28 04:09:52 -07005263 # FIN+ACK packet in -> out
5264 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5265 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5266 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
5267 flags="FA", seq=300, ack=101))
Matus Fabianebdf1902018-05-04 03:57:42 -07005268
Matus Fabian229c1aa2018-05-28 04:09:52 -07005269 self.pg0.add_stream(p)
5270 self.pg_enable_capture(self.pg_interfaces)
5271 self.pg_start()
5272 self.pg1.get_capture(1)
Matus Fabianebdf1902018-05-04 03:57:42 -07005273
Matus Fabian229c1aa2018-05-28 04:09:52 -07005274 # ACK packet out -> in
5275 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5276 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5277 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
5278 flags="A", seq=101, ack=301))
5279 self.pg1.add_stream(p)
5280 self.pg_enable_capture(self.pg_interfaces)
5281 self.pg_start()
5282 self.pg0.get_capture(1)
Matus Fabianebdf1902018-05-04 03:57:42 -07005283
Matus Fabian229c1aa2018-05-28 04:09:52 -07005284 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n,
5285 0)
5286 self.assertEqual(len(sessions) - start_sessnum, 0)
Matus Fabianebdf1902018-05-04 03:57:42 -07005287
5288 def test_tcp_session_close_simultaneous(self):
5289 """ Close TCP session from inside network """
Matus Fabian229c1aa2018-05-28 04:09:52 -07005290 self.tcp_port_out = 10505
Matus Fabianebdf1902018-05-04 03:57:42 -07005291 self.nat44_add_address(self.nat_addr)
Matus Fabian229c1aa2018-05-28 04:09:52 -07005292 self.nat44_add_static_mapping(self.pg0.remote_ip4,
5293 self.nat_addr,
5294 self.tcp_port_in,
5295 self.tcp_port_out,
5296 proto=IP_PROTOS.tcp,
5297 twice_nat=1)
Matus Fabianebdf1902018-05-04 03:57:42 -07005298 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
5299 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
5300 is_inside=0)
5301
5302 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n, 0)
5303 start_sessnum = len(sessions)
5304
5305 self.initiate_tcp_session(self.pg0, self.pg1)
5306
Matus Fabian229c1aa2018-05-28 04:09:52 -07005307 # FIN packet in -> out
5308 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5309 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5310 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
5311 flags="FA", seq=100, ack=300))
5312 self.pg0.add_stream(p)
5313 self.pg_enable_capture(self.pg_interfaces)
5314 self.pg_start()
5315 self.pg1.get_capture(1)
Matus Fabianebdf1902018-05-04 03:57:42 -07005316
Matus Fabian229c1aa2018-05-28 04:09:52 -07005317 # FIN packet out -> in
5318 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5319 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5320 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
5321 flags="FA", seq=300, ack=100))
5322 self.pg1.add_stream(p)
5323 self.pg_enable_capture(self.pg_interfaces)
5324 self.pg_start()
5325 self.pg0.get_capture(1)
Matus Fabianebdf1902018-05-04 03:57:42 -07005326
Matus Fabian229c1aa2018-05-28 04:09:52 -07005327 # ACK packet in -> out
5328 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5329 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5330 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
5331 flags="A", seq=101, ack=301))
5332 self.pg0.add_stream(p)
5333 self.pg_enable_capture(self.pg_interfaces)
5334 self.pg_start()
5335 self.pg1.get_capture(1)
Matus Fabianebdf1902018-05-04 03:57:42 -07005336
Matus Fabian229c1aa2018-05-28 04:09:52 -07005337 # ACK packet out -> in
5338 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5339 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5340 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
5341 flags="A", seq=301, ack=101))
5342 self.pg1.add_stream(p)
5343 self.pg_enable_capture(self.pg_interfaces)
5344 self.pg_start()
5345 self.pg0.get_capture(1)
Matus Fabianebdf1902018-05-04 03:57:42 -07005346
Matus Fabian229c1aa2018-05-28 04:09:52 -07005347 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n,
5348 0)
5349 self.assertEqual(len(sessions) - start_sessnum, 0)
Matus Fabianebdf1902018-05-04 03:57:42 -07005350
Matus Fabiana6110b62018-06-13 05:39:07 -07005351 def test_one_armed_nat44_static(self):
5352 """ One armed NAT44 and 1:1 NAPT asymmetrical rule """
5353 remote_host = self.pg4.remote_hosts[0]
5354 local_host = self.pg4.remote_hosts[1]
5355 external_port = 80
5356 local_port = 8080
5357 eh_port_in = 0
5358
5359 self.vapi.nat44_forwarding_enable_disable(1)
5360 self.nat44_add_address(self.nat_addr, twice_nat=1)
5361 self.nat44_add_static_mapping(local_host.ip4, self.nat_addr,
5362 local_port, external_port,
5363 proto=IP_PROTOS.tcp, out2in_only=1,
5364 twice_nat=1)
5365 self.vapi.nat44_interface_add_del_feature(self.pg4.sw_if_index)
5366 self.vapi.nat44_interface_add_del_feature(self.pg4.sw_if_index,
5367 is_inside=0)
5368
5369 # from client to service
5370 p = (Ether(src=self.pg4.remote_mac, dst=self.pg4.local_mac) /
5371 IP(src=remote_host.ip4, dst=self.nat_addr) /
5372 TCP(sport=12345, dport=external_port))
5373 self.pg4.add_stream(p)
5374 self.pg_enable_capture(self.pg_interfaces)
5375 self.pg_start()
5376 capture = self.pg4.get_capture(1)
5377 p = capture[0]
5378 try:
5379 ip = p[IP]
5380 tcp = p[TCP]
5381 self.assertEqual(ip.dst, local_host.ip4)
5382 self.assertEqual(ip.src, self.nat_addr)
5383 self.assertEqual(tcp.dport, local_port)
5384 self.assertNotEqual(tcp.sport, 12345)
5385 eh_port_in = tcp.sport
5386 self.assert_packet_checksums_valid(p)
5387 except:
5388 self.logger.error(ppp("Unexpected or invalid packet:", p))
5389 raise
5390
5391 # from service back to client
5392 p = (Ether(src=self.pg4.remote_mac, dst=self.pg4.local_mac) /
5393 IP(src=local_host.ip4, dst=self.nat_addr) /
5394 TCP(sport=local_port, dport=eh_port_in))
5395 self.pg4.add_stream(p)
5396 self.pg_enable_capture(self.pg_interfaces)
5397 self.pg_start()
5398 capture = self.pg4.get_capture(1)
5399 p = capture[0]
5400 try:
5401 ip = p[IP]
5402 tcp = p[TCP]
5403 self.assertEqual(ip.src, self.nat_addr)
5404 self.assertEqual(ip.dst, remote_host.ip4)
5405 self.assertEqual(tcp.sport, external_port)
5406 self.assertEqual(tcp.dport, 12345)
5407 self.assert_packet_checksums_valid(p)
5408 except:
5409 self.logger.error(ppp("Unexpected or invalid packet:", p))
5410 raise
5411
5412 def test_static_with_port_out2(self):
5413 """ 1:1 NAPT asymmetrical rule """
5414
5415 external_port = 80
5416 local_port = 8080
5417
5418 self.vapi.nat44_forwarding_enable_disable(1)
5419 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
5420 local_port, external_port,
5421 proto=IP_PROTOS.tcp, out2in_only=1)
5422 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
5423 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
5424 is_inside=0)
5425
5426 # from client to service
5427 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5428 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5429 TCP(sport=12345, dport=external_port))
5430 self.pg1.add_stream(p)
5431 self.pg_enable_capture(self.pg_interfaces)
5432 self.pg_start()
5433 capture = self.pg0.get_capture(1)
5434 p = capture[0]
5435 try:
5436 ip = p[IP]
5437 tcp = p[TCP]
5438 self.assertEqual(ip.dst, self.pg0.remote_ip4)
5439 self.assertEqual(tcp.dport, local_port)
5440 self.assert_packet_checksums_valid(p)
5441 except:
5442 self.logger.error(ppp("Unexpected or invalid packet:", p))
5443 raise
5444
5445 # ICMP error
5446 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
5447 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5448 ICMP(type=11) / capture[0][IP])
5449 self.pg0.add_stream(p)
5450 self.pg_enable_capture(self.pg_interfaces)
5451 self.pg_start()
5452 capture = self.pg1.get_capture(1)
5453 p = capture[0]
5454 try:
5455 self.assertEqual(p[IP].src, self.nat_addr)
5456 inner = p[IPerror]
5457 self.assertEqual(inner.dst, self.nat_addr)
5458 self.assertEqual(inner[TCPerror].dport, external_port)
5459 except:
5460 self.logger.error(ppp("Unexpected or invalid packet:", p))
5461 raise
5462
5463 # from service back to client
5464 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5465 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5466 TCP(sport=local_port, dport=12345))
5467 self.pg0.add_stream(p)
5468 self.pg_enable_capture(self.pg_interfaces)
5469 self.pg_start()
5470 capture = self.pg1.get_capture(1)
5471 p = capture[0]
5472 try:
5473 ip = p[IP]
5474 tcp = p[TCP]
5475 self.assertEqual(ip.src, self.nat_addr)
5476 self.assertEqual(tcp.sport, external_port)
5477 self.assert_packet_checksums_valid(p)
5478 except:
5479 self.logger.error(ppp("Unexpected or invalid packet:", p))
5480 raise
5481
5482 # ICMP error
5483 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
5484 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5485 ICMP(type=11) / capture[0][IP])
5486 self.pg1.add_stream(p)
5487 self.pg_enable_capture(self.pg_interfaces)
5488 self.pg_start()
5489 capture = self.pg0.get_capture(1)
5490 p = capture[0]
5491 try:
5492 self.assertEqual(p[IP].dst, self.pg0.remote_ip4)
5493 inner = p[IPerror]
5494 self.assertEqual(inner.src, self.pg0.remote_ip4)
5495 self.assertEqual(inner[TCPerror].sport, local_port)
5496 except:
5497 self.logger.error(ppp("Unexpected or invalid packet:", p))
5498 raise
5499
5500 # from client to server (no translation)
5501 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5502 IP(src=self.pg1.remote_ip4, dst=self.pg0.remote_ip4) /
5503 TCP(sport=12346, dport=local_port))
5504 self.pg1.add_stream(p)
5505 self.pg_enable_capture(self.pg_interfaces)
5506 self.pg_start()
5507 capture = self.pg0.get_capture(1)
5508 p = capture[0]
5509 try:
5510 ip = p[IP]
5511 tcp = p[TCP]
5512 self.assertEqual(ip.dst, self.pg0.remote_ip4)
5513 self.assertEqual(tcp.dport, local_port)
5514 self.assert_packet_checksums_valid(p)
5515 except:
5516 self.logger.error(ppp("Unexpected or invalid packet:", p))
5517 raise
5518
5519 # from service back to client (no translation)
5520 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5521 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5522 TCP(sport=local_port, dport=12346))
5523 self.pg0.add_stream(p)
5524 self.pg_enable_capture(self.pg_interfaces)
5525 self.pg_start()
5526 capture = self.pg1.get_capture(1)
5527 p = capture[0]
5528 try:
5529 ip = p[IP]
5530 tcp = p[TCP]
5531 self.assertEqual(ip.src, self.pg0.remote_ip4)
5532 self.assertEqual(tcp.sport, local_port)
5533 self.assert_packet_checksums_valid(p)
5534 except:
5535 self.logger.error(ppp("Unexpected or invalid packet:", p))
5536 raise
5537
Matus Fabian235a47e2018-06-25 16:42:36 -07005538 def test_output_feature(self):
5539 """ NAT44 interface output feature (in2out postrouting) """
5540 self.vapi.nat44_forwarding_enable_disable(1)
5541 self.nat44_add_address(self.nat_addr)
5542 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index,
5543 is_inside=0)
5544 self.vapi.nat44_interface_add_del_output_feature(self.pg1.sw_if_index,
5545 is_inside=0)
5546
5547 # in2out
5548 pkts = self.create_stream_in(self.pg0, self.pg1)
5549 self.pg0.add_stream(pkts)
5550 self.pg_enable_capture(self.pg_interfaces)
5551 self.pg_start()
5552 capture = self.pg1.get_capture(len(pkts))
5553 self.verify_capture_out(capture)
5554
5555 # out2in
5556 pkts = self.create_stream_out(self.pg1)
5557 self.pg1.add_stream(pkts)
5558 self.pg_enable_capture(self.pg_interfaces)
5559 self.pg_start()
5560 capture = self.pg0.get_capture(len(pkts))
5561 self.verify_capture_in(capture, self.pg0)
5562
Matus Fabian8008d7c2018-07-09 01:34:20 -07005563 def test_multiple_vrf(self):
5564 """ Multiple VRF setup """
5565 external_addr = '1.2.3.4'
5566 external_port = 80
5567 local_port = 8080
5568 port = 0
5569
5570 self.vapi.nat44_forwarding_enable_disable(1)
5571 self.nat44_add_address(self.nat_addr)
5572 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
5573 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index,
5574 is_inside=0)
5575 self.vapi.nat44_interface_add_del_output_feature(self.pg1.sw_if_index,
5576 is_inside=0)
5577 self.vapi.nat44_interface_add_del_feature(self.pg5.sw_if_index)
5578 self.vapi.nat44_interface_add_del_feature(self.pg5.sw_if_index,
5579 is_inside=0)
5580 self.vapi.nat44_interface_add_del_feature(self.pg6.sw_if_index,
5581 is_inside=0)
5582 self.nat44_add_static_mapping(self.pg5.remote_ip4, external_addr,
5583 local_port, external_port, vrf_id=1,
5584 proto=IP_PROTOS.tcp, out2in_only=1)
5585 self.nat44_add_static_mapping(
5586 self.pg0.remote_ip4, external_sw_if_index=self.pg0.sw_if_index,
5587 local_port=local_port, vrf_id=0, external_port=external_port,
5588 proto=IP_PROTOS.tcp, out2in_only=1)
5589
5590 # from client to service (both VRF1)
5591 p = (Ether(src=self.pg6.remote_mac, dst=self.pg6.local_mac) /
5592 IP(src=self.pg6.remote_ip4, dst=external_addr) /
5593 TCP(sport=12345, dport=external_port))
5594 self.pg6.add_stream(p)
5595 self.pg_enable_capture(self.pg_interfaces)
5596 self.pg_start()
5597 capture = self.pg5.get_capture(1)
5598 p = capture[0]
5599 try:
5600 ip = p[IP]
5601 tcp = p[TCP]
5602 self.assertEqual(ip.dst, self.pg5.remote_ip4)
5603 self.assertEqual(tcp.dport, local_port)
5604 self.assert_packet_checksums_valid(p)
5605 except:
5606 self.logger.error(ppp("Unexpected or invalid packet:", p))
5607 raise
5608
5609 # from service back to client (both VRF1)
5610 p = (Ether(src=self.pg5.remote_mac, dst=self.pg5.local_mac) /
5611 IP(src=self.pg5.remote_ip4, dst=self.pg6.remote_ip4) /
5612 TCP(sport=local_port, dport=12345))
5613 self.pg5.add_stream(p)
5614 self.pg_enable_capture(self.pg_interfaces)
5615 self.pg_start()
5616 capture = self.pg6.get_capture(1)
5617 p = capture[0]
5618 try:
5619 ip = p[IP]
5620 tcp = p[TCP]
5621 self.assertEqual(ip.src, external_addr)
5622 self.assertEqual(tcp.sport, external_port)
5623 self.assert_packet_checksums_valid(p)
5624 except:
5625 self.logger.error(ppp("Unexpected or invalid packet:", p))
5626 raise
5627
5628 # dynamic NAT from VRF1 to VRF0 (output-feature)
5629 p = (Ether(src=self.pg5.remote_mac, dst=self.pg5.local_mac) /
5630 IP(src=self.pg5.remote_ip4, dst=self.pg1.remote_ip4) /
5631 TCP(sport=2345, dport=22))
5632 self.pg5.add_stream(p)
5633 self.pg_enable_capture(self.pg_interfaces)
5634 self.pg_start()
5635 capture = self.pg1.get_capture(1)
5636 p = capture[0]
5637 try:
5638 ip = p[IP]
5639 tcp = p[TCP]
5640 self.assertEqual(ip.src, self.nat_addr)
5641 self.assertNotEqual(tcp.sport, 2345)
5642 self.assert_packet_checksums_valid(p)
5643 port = tcp.sport
5644 except:
5645 self.logger.error(ppp("Unexpected or invalid packet:", p))
5646 raise
5647
5648 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5649 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5650 TCP(sport=22, dport=port))
5651 self.pg1.add_stream(p)
5652 self.pg_enable_capture(self.pg_interfaces)
5653 self.pg_start()
5654 capture = self.pg5.get_capture(1)
5655 p = capture[0]
5656 try:
5657 ip = p[IP]
5658 tcp = p[TCP]
5659 self.assertEqual(ip.dst, self.pg5.remote_ip4)
5660 self.assertEqual(tcp.dport, 2345)
5661 self.assert_packet_checksums_valid(p)
5662 except:
5663 self.logger.error(ppp("Unexpected or invalid packet:", p))
5664 raise
5665
5666 # from client VRF1 to service VRF0
5667 p = (Ether(src=self.pg6.remote_mac, dst=self.pg6.local_mac) /
5668 IP(src=self.pg6.remote_ip4, dst=self.pg0.local_ip4) /
5669 TCP(sport=12346, dport=external_port))
5670 self.pg6.add_stream(p)
5671 self.pg_enable_capture(self.pg_interfaces)
5672 self.pg_start()
5673 capture = self.pg0.get_capture(1)
5674 p = capture[0]
5675 try:
5676 ip = p[IP]
5677 tcp = p[TCP]
5678 self.assertEqual(ip.dst, self.pg0.remote_ip4)
5679 self.assertEqual(tcp.dport, local_port)
5680 self.assert_packet_checksums_valid(p)
5681 except:
5682 self.logger.error(ppp("Unexpected or invalid packet:", p))
5683 raise
5684
5685 # from service VRF0 back to client VRF1
5686 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5687 IP(src=self.pg0.remote_ip4, dst=self.pg6.remote_ip4) /
5688 TCP(sport=local_port, dport=12346))
5689 self.pg0.add_stream(p)
5690 self.pg_enable_capture(self.pg_interfaces)
5691 self.pg_start()
5692 capture = self.pg6.get_capture(1)
5693 p = capture[0]
5694 try:
5695 ip = p[IP]
5696 tcp = p[TCP]
5697 self.assertEqual(ip.src, self.pg0.local_ip4)
5698 self.assertEqual(tcp.sport, external_port)
5699 self.assert_packet_checksums_valid(p)
5700 except:
5701 self.logger.error(ppp("Unexpected or invalid packet:", p))
5702 raise
5703
5704 # from client VRF0 to service VRF1
5705 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5706 IP(src=self.pg0.remote_ip4, dst=external_addr) /
5707 TCP(sport=12347, dport=external_port))
5708 self.pg0.add_stream(p)
5709 self.pg_enable_capture(self.pg_interfaces)
5710 self.pg_start()
5711 capture = self.pg5.get_capture(1)
5712 p = capture[0]
5713 try:
5714 ip = p[IP]
5715 tcp = p[TCP]
5716 self.assertEqual(ip.dst, self.pg5.remote_ip4)
5717 self.assertEqual(tcp.dport, local_port)
5718 self.assert_packet_checksums_valid(p)
5719 except:
5720 self.logger.error(ppp("Unexpected or invalid packet:", p))
5721 raise
5722
5723 # from service VRF1 back to client VRF0
5724 p = (Ether(src=self.pg5.remote_mac, dst=self.pg5.local_mac) /
5725 IP(src=self.pg5.remote_ip4, dst=self.pg0.remote_ip4) /
5726 TCP(sport=local_port, dport=12347))
5727 self.pg5.add_stream(p)
5728 self.pg_enable_capture(self.pg_interfaces)
5729 self.pg_start()
5730 capture = self.pg0.get_capture(1)
5731 p = capture[0]
5732 try:
5733 ip = p[IP]
5734 tcp = p[TCP]
5735 self.assertEqual(ip.src, external_addr)
5736 self.assertEqual(tcp.sport, external_port)
5737 self.assert_packet_checksums_valid(p)
5738 except:
5739 self.logger.error(ppp("Unexpected or invalid packet:", p))
5740 raise
5741
5742 # from client to server (both VRF1, no translation)
5743 p = (Ether(src=self.pg6.remote_mac, dst=self.pg6.local_mac) /
5744 IP(src=self.pg6.remote_ip4, dst=self.pg5.remote_ip4) /
5745 TCP(sport=12348, dport=local_port))
5746 self.pg6.add_stream(p)
5747 self.pg_enable_capture(self.pg_interfaces)
5748 self.pg_start()
5749 capture = self.pg5.get_capture(1)
5750 p = capture[0]
5751 try:
5752 ip = p[IP]
5753 tcp = p[TCP]
5754 self.assertEqual(ip.dst, self.pg5.remote_ip4)
5755 self.assertEqual(tcp.dport, local_port)
5756 self.assert_packet_checksums_valid(p)
5757 except:
5758 self.logger.error(ppp("Unexpected or invalid packet:", p))
5759 raise
5760
5761 # from server back to client (both VRF1, no translation)
5762 p = (Ether(src=self.pg5.remote_mac, dst=self.pg5.local_mac) /
5763 IP(src=self.pg5.remote_ip4, dst=self.pg6.remote_ip4) /
5764 TCP(sport=local_port, dport=12348))
5765 self.pg5.add_stream(p)
5766 self.pg_enable_capture(self.pg_interfaces)
5767 self.pg_start()
5768 capture = self.pg6.get_capture(1)
5769 p = capture[0]
5770 try:
5771 ip = p[IP]
5772 tcp = p[TCP]
5773 self.assertEqual(ip.src, self.pg5.remote_ip4)
5774 self.assertEqual(tcp.sport, local_port)
5775 self.assert_packet_checksums_valid(p)
5776 except:
5777 self.logger.error(ppp("Unexpected or invalid packet:", p))
5778 raise
5779
5780 # from client VRF1 to server VRF0 (no translation)
5781 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5782 IP(src=self.pg0.remote_ip4, dst=self.pg6.remote_ip4) /
5783 TCP(sport=local_port, dport=12349))
5784 self.pg0.add_stream(p)
5785 self.pg_enable_capture(self.pg_interfaces)
5786 self.pg_start()
5787 capture = self.pg6.get_capture(1)
5788 p = capture[0]
5789 try:
5790 ip = p[IP]
5791 tcp = p[TCP]
5792 self.assertEqual(ip.src, self.pg0.remote_ip4)
5793 self.assertEqual(tcp.sport, local_port)
5794 self.assert_packet_checksums_valid(p)
5795 except:
5796 self.logger.error(ppp("Unexpected or invalid packet:", p))
5797 raise
5798
5799 # from server VRF0 back to client VRF1 (no translation)
5800 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5801 IP(src=self.pg0.remote_ip4, dst=self.pg6.remote_ip4) /
5802 TCP(sport=local_port, dport=12349))
5803 self.pg0.add_stream(p)
5804 self.pg_enable_capture(self.pg_interfaces)
5805 self.pg_start()
5806 capture = self.pg6.get_capture(1)
5807 p = capture[0]
5808 try:
5809 ip = p[IP]
5810 tcp = p[TCP]
5811 self.assertEqual(ip.src, self.pg0.remote_ip4)
5812 self.assertEqual(tcp.sport, local_port)
5813 self.assert_packet_checksums_valid(p)
5814 except:
5815 self.logger.error(ppp("Unexpected or invalid packet:", p))
5816 raise
5817
5818 # from client VRF0 to server VRF1 (no translation)
5819 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5820 IP(src=self.pg0.remote_ip4, dst=self.pg5.remote_ip4) /
5821 TCP(sport=12344, dport=local_port))
5822 self.pg0.add_stream(p)
5823 self.pg_enable_capture(self.pg_interfaces)
5824 self.pg_start()
5825 capture = self.pg5.get_capture(1)
5826 p = capture[0]
5827 try:
5828 ip = p[IP]
5829 tcp = p[TCP]
5830 self.assertEqual(ip.dst, self.pg5.remote_ip4)
5831 self.assertEqual(tcp.dport, local_port)
5832 self.assert_packet_checksums_valid(p)
5833 except:
5834 self.logger.error(ppp("Unexpected or invalid packet:", p))
5835 raise
5836
5837 # from server VRF1 back to client VRF0 (no translation)
5838 p = (Ether(src=self.pg5.remote_mac, dst=self.pg5.local_mac) /
5839 IP(src=self.pg5.remote_ip4, dst=self.pg0.remote_ip4) /
5840 TCP(sport=local_port, dport=12344))
5841 self.pg5.add_stream(p)
5842 self.pg_enable_capture(self.pg_interfaces)
5843 self.pg_start()
5844 capture = self.pg0.get_capture(1)
5845 p = capture[0]
5846 try:
5847 ip = p[IP]
5848 tcp = p[TCP]
5849 self.assertEqual(ip.src, self.pg5.remote_ip4)
5850 self.assertEqual(tcp.sport, local_port)
5851 self.assert_packet_checksums_valid(p)
5852 except:
5853 self.logger.error(ppp("Unexpected or invalid packet:", p))
5854 raise
5855
Paul Vinciguerradefde0f2018-12-06 07:46:13 -08005856 @unittest.skipUnless(running_extended_tests, "part of extended tests")
Matus Fabian878c6462018-08-23 00:33:35 -07005857 def test_session_timeout(self):
5858 """ NAT44 session timeouts """
5859 self.nat44_add_address(self.nat_addr)
5860 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
5861 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
5862 is_inside=0)
5863 self.vapi.nat_set_timeouts(icmp=5)
5864
5865 max_sessions = 1000
5866 pkts = []
5867 for i in range(0, max_sessions):
5868 src = "10.10.%u.%u" % ((i & 0xFF00) >> 8, i & 0xFF)
5869 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
5870 IP(src=src, dst=self.pg1.remote_ip4) /
5871 ICMP(id=1025, type='echo-request'))
5872 pkts.append(p)
5873 self.pg0.add_stream(pkts)
5874 self.pg_enable_capture(self.pg_interfaces)
5875 self.pg_start()
5876 self.pg1.get_capture(max_sessions)
5877
5878 sleep(10)
5879
5880 pkts = []
5881 for i in range(0, max_sessions):
Matus Fabian7f8a8db2018-11-22 00:12:15 -08005882 src = "10.11.%u.%u" % ((i & 0xFF00) >> 8, i & 0xFF)
Matus Fabian878c6462018-08-23 00:33:35 -07005883 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
5884 IP(src=src, dst=self.pg1.remote_ip4) /
5885 ICMP(id=1026, type='echo-request'))
5886 pkts.append(p)
5887 self.pg0.add_stream(pkts)
5888 self.pg_enable_capture(self.pg_interfaces)
5889 self.pg_start()
5890 self.pg1.get_capture(max_sessions)
5891
5892 nsessions = 0
5893 users = self.vapi.nat44_user_dump()
5894 for user in users:
5895 nsessions = nsessions + user.nsessions
5896 self.assertLess(nsessions, 2 * max_sessions)
5897
Paul Vinciguerradefde0f2018-12-06 07:46:13 -08005898 @unittest.skipUnless(running_extended_tests, "part of extended tests")
Matus Fabian15e8e682018-11-21 04:53:10 -08005899 def test_session_rst_timeout(self):
5900 """ NAT44 session RST timeouts """
5901 self.nat44_add_address(self.nat_addr)
5902 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
5903 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
5904 is_inside=0)
5905 self.vapi.nat_set_timeouts(tcp_transitory=5)
5906
Matus Fabian15e8e682018-11-21 04:53:10 -08005907 self.initiate_tcp_session(self.pg0, self.pg1)
5908 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5909 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5910 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
5911 flags="R"))
5912 self.pg0.add_stream(p)
5913 self.pg_enable_capture(self.pg_interfaces)
5914 self.pg_start()
5915 self.pg1.get_capture(1)
5916
Matus Fabian15e8e682018-11-21 04:53:10 -08005917 sleep(6)
5918
5919 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5920 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5921 TCP(sport=self.tcp_port_in + 1, dport=self.tcp_external_port + 1,
5922 flags="S"))
5923 self.pg0.add_stream(p)
5924 self.pg_enable_capture(self.pg_interfaces)
5925 self.pg_start()
5926 self.pg1.get_capture(1)
5927
5928 nsessions = 0
5929 users = self.vapi.nat44_user_dump()
5930 self.assertEqual(len(users), 1)
5931 self.assertEqual(users[0].ip_address, self.pg0.remote_ip4n)
Matus Fabian7f8a8db2018-11-22 00:12:15 -08005932 self.assertEqual(users[0].nsessions, 1)
Matus Fabian15e8e682018-11-21 04:53:10 -08005933
Paul Vinciguerradefde0f2018-12-06 07:46:13 -08005934 @unittest.skipUnless(running_extended_tests, "part of extended tests")
Matus Fabian878c6462018-08-23 00:33:35 -07005935 def test_session_limit_per_user(self):
5936 """ Maximum sessions per user limit """
5937 self.nat44_add_address(self.nat_addr)
5938 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
5939 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
5940 is_inside=0)
5941 self.vapi.set_ipfix_exporter(collector_address=self.pg2.remote_ip4n,
5942 src_address=self.pg2.local_ip4n,
5943 path_mtu=512,
5944 template_interval=10)
Matus Fabian8fdc0152018-09-24 04:41:28 -07005945 self.vapi.nat_set_timeouts(udp=5)
Matus Fabian878c6462018-08-23 00:33:35 -07005946
5947 # get maximum number of translations per user
5948 nat44_config = self.vapi.nat_show_config()
5949
5950 pkts = []
5951 for port in range(0, nat44_config.max_translations_per_user):
5952 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5953 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5954 UDP(sport=1025 + port, dport=1025 + port))
5955 pkts.append(p)
5956
5957 self.pg0.add_stream(pkts)
5958 self.pg_enable_capture(self.pg_interfaces)
5959 self.pg_start()
5960 capture = self.pg1.get_capture(len(pkts))
5961
5962 self.vapi.nat_ipfix(domain_id=self.ipfix_domain_id,
5963 src_port=self.ipfix_src_port)
5964
5965 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5966 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5967 UDP(sport=3001, dport=3002))
5968 self.pg0.add_stream(p)
5969 self.pg_enable_capture(self.pg_interfaces)
5970 self.pg_start()
5971 capture = self.pg1.assert_nothing_captured()
5972
5973 # verify IPFIX logging
5974 self.vapi.cli("ipfix flush") # FIXME this should be an API call
5975 sleep(1)
5976 capture = self.pg2.get_capture(10)
5977 ipfix = IPFIXDecoder()
5978 # first load template
5979 for p in capture:
5980 self.assertTrue(p.haslayer(IPFIX))
5981 if p.haslayer(Template):
5982 ipfix.add_template(p.getlayer(Template))
5983 # verify events in data set
5984 for p in capture:
5985 if p.haslayer(Data):
5986 data = ipfix.decode_data_set(p.getlayer(Set))
5987 self.verify_ipfix_max_entries_per_user(
5988 data,
5989 nat44_config.max_translations_per_user,
5990 self.pg0.remote_ip4n)
5991
Matus Fabian8fdc0152018-09-24 04:41:28 -07005992 sleep(6)
5993 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5994 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5995 UDP(sport=3001, dport=3002))
5996 self.pg0.add_stream(p)
5997 self.pg_enable_capture(self.pg_interfaces)
5998 self.pg_start()
5999 self.pg1.get_capture(1)
6000
Matus Fabianad1f3e12018-11-28 21:26:34 -08006001 def test_syslog_sess(self):
6002 """ Test syslog session creation and deletion """
6003 self.vapi.syslog_set_filter(SYSLOG_SEVERITY.INFO)
6004 self.vapi.syslog_set_sender(self.pg2.remote_ip4n, self.pg2.local_ip4n)
6005 self.nat44_add_address(self.nat_addr)
6006 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
6007 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
6008 is_inside=0)
6009
6010 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
6011 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6012 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port))
6013 self.pg0.add_stream(p)
6014 self.pg_enable_capture(self.pg_interfaces)
6015 self.pg_start()
6016 capture = self.pg1.get_capture(1)
6017 self.tcp_port_out = capture[0][TCP].sport
6018 capture = self.pg2.get_capture(1)
6019 self.verify_syslog_sess(capture[0][Raw].load)
6020
6021 self.pg_enable_capture(self.pg_interfaces)
6022 self.pg_start()
6023 self.nat44_add_address(self.nat_addr, is_add=0)
6024 capture = self.pg2.get_capture(1)
6025 self.verify_syslog_sess(capture[0][Raw].load, False)
6026
Matus Fabiande886752016-12-07 03:38:19 -08006027 def tearDown(self):
Matus Fabiana6110b62018-06-13 05:39:07 -07006028 super(TestNAT44EndpointDependent, self).tearDown()
Matus Fabiande886752016-12-07 03:38:19 -08006029 if not self.vpp_dead:
Matus Fabian82119542018-01-25 01:13:22 -08006030 self.logger.info(self.vapi.cli("show nat44 addresses"))
6031 self.logger.info(self.vapi.cli("show nat44 interfaces"))
6032 self.logger.info(self.vapi.cli("show nat44 static mappings"))
6033 self.logger.info(self.vapi.cli("show nat44 interface address"))
6034 self.logger.info(self.vapi.cli("show nat44 sessions detail"))
Matus Fabian229c1aa2018-05-28 04:09:52 -07006035 self.logger.info(self.vapi.cli("show nat44 hash tables detail"))
Matus Fabian878c6462018-08-23 00:33:35 -07006036 self.logger.info(self.vapi.cli("show nat timeouts"))
Matus Fabian2ba92e32017-08-21 07:05:03 -07006037 self.clear_nat44()
Matus Fabian229c1aa2018-05-28 04:09:52 -07006038 self.vapi.cli("clear logging")
Matus Fabiande886752016-12-07 03:38:19 -08006039
Matus Fabianeea28d72017-01-13 04:15:54 -08006040
Juraj Slobodacba69362017-12-19 02:09:32 +01006041class TestNAT44Out2InDPO(MethodHolder):
6042 """ NAT44 Test Cases using out2in DPO """
6043
6044 @classmethod
6045 def setUpConstants(cls):
6046 super(TestNAT44Out2InDPO, cls).setUpConstants()
6047 cls.vpp_cmdline.extend(["nat", "{", "out2in dpo", "}"])
6048
6049 @classmethod
6050 def setUpClass(cls):
6051 super(TestNAT44Out2InDPO, cls).setUpClass()
Matus Fabian229c1aa2018-05-28 04:09:52 -07006052 cls.vapi.cli("set log class nat level debug")
Juraj Slobodacba69362017-12-19 02:09:32 +01006053
6054 try:
6055 cls.tcp_port_in = 6303
6056 cls.tcp_port_out = 6303
6057 cls.udp_port_in = 6304
6058 cls.udp_port_out = 6304
6059 cls.icmp_id_in = 6305
6060 cls.icmp_id_out = 6305
6061 cls.nat_addr = '10.0.0.3'
6062 cls.nat_addr_n = socket.inet_pton(socket.AF_INET, cls.nat_addr)
6063 cls.dst_ip4 = '192.168.70.1'
6064
6065 cls.create_pg_interfaces(range(2))
6066
6067 cls.pg0.admin_up()
6068 cls.pg0.config_ip4()
6069 cls.pg0.resolve_arp()
6070
6071 cls.pg1.admin_up()
6072 cls.pg1.config_ip6()
6073 cls.pg1.resolve_ndp()
6074
6075 cls.vapi.ip_add_del_route(is_ipv6=True, dst_address='\x00'*16,
6076 dst_address_length=0,
6077 next_hop_address=cls.pg1.remote_ip6n,
6078 next_hop_sw_if_index=cls.pg1.sw_if_index)
6079
6080 except Exception:
6081 super(TestNAT44Out2InDPO, cls).tearDownClass()
6082 raise
6083
6084 def configure_xlat(self):
6085 self.dst_ip6_pfx = '1:2:3::'
6086 self.dst_ip6_pfx_n = socket.inet_pton(socket.AF_INET6,
6087 self.dst_ip6_pfx)
6088 self.dst_ip6_pfx_len = 96
6089 self.src_ip6_pfx = '4:5:6::'
6090 self.src_ip6_pfx_n = socket.inet_pton(socket.AF_INET6,
6091 self.src_ip6_pfx)
6092 self.src_ip6_pfx_len = 96
6093 self.vapi.map_add_domain(self.dst_ip6_pfx_n, self.dst_ip6_pfx_len,
6094 self.src_ip6_pfx_n, self.src_ip6_pfx_len,
6095 '\x00\x00\x00\x00', 0, is_translation=1,
6096 is_rfc6052=1)
6097
Ole Troanffba3c32018-11-22 12:53:00 +01006098 @unittest.skip('Temporary disabled')
Juraj Slobodacba69362017-12-19 02:09:32 +01006099 def test_464xlat_ce(self):
6100 """ Test 464XLAT CE with NAT44 """
6101
Matus Fabian69ce30d2018-08-22 01:27:10 -07006102 nat_config = self.vapi.nat_show_config()
6103 self.assertEqual(1, nat_config.out2in_dpo)
6104
Juraj Slobodacba69362017-12-19 02:09:32 +01006105 self.configure_xlat()
6106
6107 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
6108 self.vapi.nat44_add_del_address_range(self.nat_addr_n, self.nat_addr_n)
6109
6110 out_src_ip6 = self.compose_ip6(self.dst_ip4, self.dst_ip6_pfx,
6111 self.dst_ip6_pfx_len)
6112 out_dst_ip6 = self.compose_ip6(self.nat_addr, self.src_ip6_pfx,
6113 self.src_ip6_pfx_len)
6114
6115 try:
6116 pkts = self.create_stream_in(self.pg0, self.pg1, self.dst_ip4)
6117 self.pg0.add_stream(pkts)
6118 self.pg_enable_capture(self.pg_interfaces)
6119 self.pg_start()
6120 capture = self.pg1.get_capture(len(pkts))
6121 self.verify_capture_out_ip6(capture, nat_ip=out_dst_ip6,
6122 dst_ip=out_src_ip6)
6123
6124 pkts = self.create_stream_out_ip6(self.pg1, out_src_ip6,
6125 out_dst_ip6)
6126 self.pg1.add_stream(pkts)
6127 self.pg_enable_capture(self.pg_interfaces)
6128 self.pg_start()
6129 capture = self.pg0.get_capture(len(pkts))
6130 self.verify_capture_in(capture, self.pg0)
6131 finally:
6132 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index,
6133 is_add=0)
6134 self.vapi.nat44_add_del_address_range(self.nat_addr_n,
6135 self.nat_addr_n, is_add=0)
6136
Ole Troanffba3c32018-11-22 12:53:00 +01006137 @unittest.skip('Temporary disabled')
Juraj Slobodacba69362017-12-19 02:09:32 +01006138 def test_464xlat_ce_no_nat(self):
6139 """ Test 464XLAT CE without NAT44 """
6140
6141 self.configure_xlat()
6142
6143 out_src_ip6 = self.compose_ip6(self.dst_ip4, self.dst_ip6_pfx,
6144 self.dst_ip6_pfx_len)
6145 out_dst_ip6 = self.compose_ip6(self.pg0.remote_ip4, self.src_ip6_pfx,
6146 self.src_ip6_pfx_len)
6147
6148 pkts = self.create_stream_in(self.pg0, self.pg1, self.dst_ip4)
6149 self.pg0.add_stream(pkts)
6150 self.pg_enable_capture(self.pg_interfaces)
6151 self.pg_start()
6152 capture = self.pg1.get_capture(len(pkts))
6153 self.verify_capture_out_ip6(capture, dst_ip=out_src_ip6,
6154 nat_ip=out_dst_ip6, same_port=True)
6155
6156 pkts = self.create_stream_out_ip6(self.pg1, out_src_ip6, out_dst_ip6)
6157 self.pg1.add_stream(pkts)
6158 self.pg_enable_capture(self.pg_interfaces)
6159 self.pg_start()
6160 capture = self.pg0.get_capture(len(pkts))
6161 self.verify_capture_in(capture, self.pg0)
6162
6163
Martin Gálikd7f75cd2017-03-27 06:02:47 -07006164class TestDeterministicNAT(MethodHolder):
Matus Fabian066f0342017-02-10 03:48:01 -08006165 """ Deterministic NAT Test Cases """
6166
6167 @classmethod
6168 def setUpConstants(cls):
6169 super(TestDeterministicNAT, cls).setUpConstants()
Matus Fabian2ba92e32017-08-21 07:05:03 -07006170 cls.vpp_cmdline.extend(["nat", "{", "deterministic", "}"])
Matus Fabian066f0342017-02-10 03:48:01 -08006171
6172 @classmethod
6173 def setUpClass(cls):
6174 super(TestDeterministicNAT, cls).setUpClass()
Matus Fabian229c1aa2018-05-28 04:09:52 -07006175 cls.vapi.cli("set log class nat level debug")
Matus Fabian066f0342017-02-10 03:48:01 -08006176
6177 try:
Martin Gálik977c1cb2017-03-30 23:21:51 -07006178 cls.tcp_port_in = 6303
Martin Gálik9806eae2017-04-25 01:25:08 -07006179 cls.tcp_external_port = 6303
Martin Gálik977c1cb2017-03-30 23:21:51 -07006180 cls.udp_port_in = 6304
Martin Gálik9806eae2017-04-25 01:25:08 -07006181 cls.udp_external_port = 6304
Martin Gálik977c1cb2017-03-30 23:21:51 -07006182 cls.icmp_id_in = 6305
Matus Fabian2ba92e32017-08-21 07:05:03 -07006183 cls.nat_addr = '10.0.0.3'
Martin Gálik977c1cb2017-03-30 23:21:51 -07006184
Matus Fabian2f2db1c2017-04-18 05:29:59 -07006185 cls.create_pg_interfaces(range(3))
Matus Fabian066f0342017-02-10 03:48:01 -08006186 cls.interfaces = list(cls.pg_interfaces)
6187
6188 for i in cls.interfaces:
6189 i.admin_up()
6190 i.config_ip4()
6191 i.resolve_arp()
6192
Martin Gálik977c1cb2017-03-30 23:21:51 -07006193 cls.pg0.generate_remote_hosts(2)
6194 cls.pg0.configure_ipv4_neighbors()
6195
Matus Fabian066f0342017-02-10 03:48:01 -08006196 except Exception:
6197 super(TestDeterministicNAT, cls).tearDownClass()
6198 raise
6199
Martin Gálik977c1cb2017-03-30 23:21:51 -07006200 def create_stream_in(self, in_if, out_if, ttl=64):
6201 """
6202 Create packet stream for inside network
6203
6204 :param in_if: Inside interface
6205 :param out_if: Outside interface
6206 :param ttl: TTL of generated packets
6207 """
6208 pkts = []
6209 # TCP
6210 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
6211 IP(src=in_if.remote_ip4, dst=out_if.remote_ip4, ttl=ttl) /
Martin Gálik9806eae2017-04-25 01:25:08 -07006212 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port))
Martin Gálik977c1cb2017-03-30 23:21:51 -07006213 pkts.append(p)
6214
6215 # UDP
6216 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
6217 IP(src=in_if.remote_ip4, dst=out_if.remote_ip4, ttl=ttl) /
Martin Gálik9806eae2017-04-25 01:25:08 -07006218 UDP(sport=self.udp_port_in, dport=self.udp_external_port))
Martin Gálik977c1cb2017-03-30 23:21:51 -07006219 pkts.append(p)
6220
6221 # ICMP
6222 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
6223 IP(src=in_if.remote_ip4, dst=out_if.remote_ip4, ttl=ttl) /
6224 ICMP(id=self.icmp_id_in, type='echo-request'))
6225 pkts.append(p)
6226
6227 return pkts
6228
6229 def create_stream_out(self, out_if, dst_ip=None, ttl=64):
6230 """
6231 Create packet stream for outside network
6232
6233 :param out_if: Outside interface
Matus Fabian2ba92e32017-08-21 07:05:03 -07006234 :param dst_ip: Destination IP address (Default use global NAT address)
Martin Gálik977c1cb2017-03-30 23:21:51 -07006235 :param ttl: TTL of generated packets
6236 """
6237 if dst_ip is None:
Matus Fabian2ba92e32017-08-21 07:05:03 -07006238 dst_ip = self.nat_addr
Martin Gálik977c1cb2017-03-30 23:21:51 -07006239 pkts = []
6240 # TCP
6241 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
6242 IP(src=out_if.remote_ip4, dst=dst_ip, ttl=ttl) /
Martin Gálik9806eae2017-04-25 01:25:08 -07006243 TCP(dport=self.tcp_port_out, sport=self.tcp_external_port))
Martin Gálik977c1cb2017-03-30 23:21:51 -07006244 pkts.append(p)
6245
6246 # UDP
6247 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
6248 IP(src=out_if.remote_ip4, dst=dst_ip, ttl=ttl) /
Martin Gálik9806eae2017-04-25 01:25:08 -07006249 UDP(dport=self.udp_port_out, sport=self.udp_external_port))
Martin Gálik977c1cb2017-03-30 23:21:51 -07006250 pkts.append(p)
6251
6252 # ICMP
6253 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
6254 IP(src=out_if.remote_ip4, dst=dst_ip, ttl=ttl) /
6255 ICMP(id=self.icmp_external_id, type='echo-reply'))
6256 pkts.append(p)
6257
6258 return pkts
6259
Matus Fabian05ca4a32018-09-04 23:45:13 -07006260 def verify_capture_out(self, capture, nat_ip=None):
Martin Gálik977c1cb2017-03-30 23:21:51 -07006261 """
6262 Verify captured packets on outside network
6263
6264 :param capture: Captured packets
Matus Fabian2ba92e32017-08-21 07:05:03 -07006265 :param nat_ip: Translated IP address (Default use global NAT address)
Martin Gálik977c1cb2017-03-30 23:21:51 -07006266 :param same_port: Sorce port number is not translated (Default False)
Martin Gálik977c1cb2017-03-30 23:21:51 -07006267 """
6268 if nat_ip is None:
Matus Fabian2ba92e32017-08-21 07:05:03 -07006269 nat_ip = self.nat_addr
Martin Gálik977c1cb2017-03-30 23:21:51 -07006270 for packet in capture:
6271 try:
6272 self.assertEqual(packet[IP].src, nat_ip)
6273 if packet.haslayer(TCP):
Martin Gálik9806eae2017-04-25 01:25:08 -07006274 self.tcp_port_out = packet[TCP].sport
Martin Gálik977c1cb2017-03-30 23:21:51 -07006275 elif packet.haslayer(UDP):
Martin Gálik9806eae2017-04-25 01:25:08 -07006276 self.udp_port_out = packet[UDP].sport
Martin Gálik977c1cb2017-03-30 23:21:51 -07006277 else:
6278 self.icmp_external_id = packet[ICMP].id
6279 except:
6280 self.logger.error(ppp("Unexpected or invalid packet "
6281 "(outside network):", packet))
6282 raise
6283
Matus Fabian066f0342017-02-10 03:48:01 -08006284 def test_deterministic_mode(self):
Matus Fabian2ba92e32017-08-21 07:05:03 -07006285 """ NAT plugin run deterministic mode """
Matus Fabian066f0342017-02-10 03:48:01 -08006286 in_addr = '172.16.255.0'
6287 out_addr = '172.17.255.50'
6288 in_addr_t = '172.16.255.20'
6289 in_addr_n = socket.inet_aton(in_addr)
6290 out_addr_n = socket.inet_aton(out_addr)
6291 in_addr_t_n = socket.inet_aton(in_addr_t)
6292 in_plen = 24
6293 out_plen = 32
6294
Matus Fabian2ba92e32017-08-21 07:05:03 -07006295 nat_config = self.vapi.nat_show_config()
6296 self.assertEqual(1, nat_config.deterministic)
Matus Fabian066f0342017-02-10 03:48:01 -08006297
Matus Fabian2ba92e32017-08-21 07:05:03 -07006298 self.vapi.nat_det_add_del_map(in_addr_n, in_plen, out_addr_n, out_plen)
Matus Fabian066f0342017-02-10 03:48:01 -08006299
Matus Fabian2ba92e32017-08-21 07:05:03 -07006300 rep1 = self.vapi.nat_det_forward(in_addr_t_n)
Matus Fabian066f0342017-02-10 03:48:01 -08006301 self.assertEqual(rep1.out_addr[:4], out_addr_n)
Matus Fabian2ba92e32017-08-21 07:05:03 -07006302 rep2 = self.vapi.nat_det_reverse(out_addr_n, rep1.out_port_hi)
Matus Fabian066f0342017-02-10 03:48:01 -08006303 self.assertEqual(rep2.in_addr[:4], in_addr_t_n)
6304
Matus Fabian2ba92e32017-08-21 07:05:03 -07006305 deterministic_mappings = self.vapi.nat_det_map_dump()
Martin17a75cb2017-03-08 05:53:20 -08006306 self.assertEqual(len(deterministic_mappings), 1)
6307 dsm = deterministic_mappings[0]
6308 self.assertEqual(in_addr_n, dsm.in_addr[:4])
6309 self.assertEqual(in_plen, dsm.in_plen)
6310 self.assertEqual(out_addr_n, dsm.out_addr[:4])
6311 self.assertEqual(out_plen, dsm.out_plen)
6312
Matus Fabian2ba92e32017-08-21 07:05:03 -07006313 self.clear_nat_det()
6314 deterministic_mappings = self.vapi.nat_det_map_dump()
Martinb616e9f2017-03-14 02:25:45 -07006315 self.assertEqual(len(deterministic_mappings), 0)
6316
Matus Fabian6a0946f2017-04-12 03:36:13 -07006317 def test_set_timeouts(self):
6318 """ Set deterministic NAT timeouts """
Matus Fabian878c6462018-08-23 00:33:35 -07006319 timeouts_before = self.vapi.nat_get_timeouts()
Matus Fabian6a0946f2017-04-12 03:36:13 -07006320
Matus Fabian878c6462018-08-23 00:33:35 -07006321 self.vapi.nat_set_timeouts(timeouts_before.udp + 10,
6322 timeouts_before.tcp_established + 10,
6323 timeouts_before.tcp_transitory + 10,
6324 timeouts_before.icmp + 10)
Matus Fabian6a0946f2017-04-12 03:36:13 -07006325
Matus Fabian878c6462018-08-23 00:33:35 -07006326 timeouts_after = self.vapi.nat_get_timeouts()
Matus Fabian6a0946f2017-04-12 03:36:13 -07006327
6328 self.assertNotEqual(timeouts_before.udp, timeouts_after.udp)
6329 self.assertNotEqual(timeouts_before.icmp, timeouts_after.icmp)
6330 self.assertNotEqual(timeouts_before.tcp_established,
6331 timeouts_after.tcp_established)
6332 self.assertNotEqual(timeouts_before.tcp_transitory,
6333 timeouts_after.tcp_transitory)
6334
Martin Gálik977c1cb2017-03-30 23:21:51 -07006335 def test_det_in(self):
Matus Fabian2ba92e32017-08-21 07:05:03 -07006336 """ Deterministic NAT translation test (TCP, UDP, ICMP) """
Martin Gálik977c1cb2017-03-30 23:21:51 -07006337
6338 nat_ip = "10.0.0.10"
Martin Gálik977c1cb2017-03-30 23:21:51 -07006339
Matus Fabian2ba92e32017-08-21 07:05:03 -07006340 self.vapi.nat_det_add_del_map(self.pg0.remote_ip4n,
6341 32,
6342 socket.inet_aton(nat_ip),
6343 32)
6344 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
6345 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
6346 is_inside=0)
Martin Gálik977c1cb2017-03-30 23:21:51 -07006347
6348 # in2out
6349 pkts = self.create_stream_in(self.pg0, self.pg1)
6350 self.pg0.add_stream(pkts)
6351 self.pg_enable_capture(self.pg_interfaces)
6352 self.pg_start()
6353 capture = self.pg1.get_capture(len(pkts))
6354 self.verify_capture_out(capture, nat_ip)
6355
6356 # out2in
6357 pkts = self.create_stream_out(self.pg1, nat_ip)
6358 self.pg1.add_stream(pkts)
6359 self.pg_enable_capture(self.pg_interfaces)
6360 self.pg_start()
6361 capture = self.pg0.get_capture(len(pkts))
6362 self.verify_capture_in(capture, self.pg0)
6363
Martin Gálik9806eae2017-04-25 01:25:08 -07006364 # session dump test
Matus Fabian2ba92e32017-08-21 07:05:03 -07006365 sessions = self.vapi.nat_det_session_dump(self.pg0.remote_ip4n)
Martin Gálik9806eae2017-04-25 01:25:08 -07006366 self.assertEqual(len(sessions), 3)
6367
6368 # TCP session
6369 s = sessions[0]
6370 self.assertEqual(s.ext_addr[:4], self.pg1.remote_ip4n)
6371 self.assertEqual(s.in_port, self.tcp_port_in)
6372 self.assertEqual(s.out_port, self.tcp_port_out)
6373 self.assertEqual(s.ext_port, self.tcp_external_port)
6374
6375 # UDP session
6376 s = sessions[1]
6377 self.assertEqual(s.ext_addr[:4], self.pg1.remote_ip4n)
6378 self.assertEqual(s.in_port, self.udp_port_in)
6379 self.assertEqual(s.out_port, self.udp_port_out)
6380 self.assertEqual(s.ext_port, self.udp_external_port)
6381
6382 # ICMP session
6383 s = sessions[2]
6384 self.assertEqual(s.ext_addr[:4], self.pg1.remote_ip4n)
6385 self.assertEqual(s.in_port, self.icmp_id_in)
6386 self.assertEqual(s.out_port, self.icmp_external_id)
6387
Martin Gálik977c1cb2017-03-30 23:21:51 -07006388 def test_multiple_users(self):
Matus Fabian2ba92e32017-08-21 07:05:03 -07006389 """ Deterministic NAT multiple users """
Martin Gálik977c1cb2017-03-30 23:21:51 -07006390
6391 nat_ip = "10.0.0.10"
6392 port_in = 80
Martin Gálik9806eae2017-04-25 01:25:08 -07006393 external_port = 6303
Martin Gálik977c1cb2017-03-30 23:21:51 -07006394
6395 host0 = self.pg0.remote_hosts[0]
6396 host1 = self.pg0.remote_hosts[1]
6397
Matus Fabian2ba92e32017-08-21 07:05:03 -07006398 self.vapi.nat_det_add_del_map(host0.ip4n,
6399 24,
6400 socket.inet_aton(nat_ip),
6401 32)
6402 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
6403 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
6404 is_inside=0)
Martin Gálik977c1cb2017-03-30 23:21:51 -07006405
6406 # host0 to out
6407 p = (Ether(src=host0.mac, dst=self.pg0.local_mac) /
6408 IP(src=host0.ip4, dst=self.pg1.remote_ip4) /
Martin Gálik9806eae2017-04-25 01:25:08 -07006409 TCP(sport=port_in, dport=external_port))
Martin Gálik977c1cb2017-03-30 23:21:51 -07006410 self.pg0.add_stream(p)
6411 self.pg_enable_capture(self.pg_interfaces)
6412 self.pg_start()
6413 capture = self.pg1.get_capture(1)
6414 p = capture[0]
6415 try:
6416 ip = p[IP]
6417 tcp = p[TCP]
6418 self.assertEqual(ip.src, nat_ip)
6419 self.assertEqual(ip.dst, self.pg1.remote_ip4)
Martin Gálik9806eae2017-04-25 01:25:08 -07006420 self.assertEqual(tcp.dport, external_port)
6421 port_out0 = tcp.sport
Martin Gálik977c1cb2017-03-30 23:21:51 -07006422 except:
6423 self.logger.error(ppp("Unexpected or invalid packet:", p))
6424 raise
6425
6426 # host1 to out
6427 p = (Ether(src=host1.mac, dst=self.pg0.local_mac) /
6428 IP(src=host1.ip4, dst=self.pg1.remote_ip4) /
Martin Gálik9806eae2017-04-25 01:25:08 -07006429 TCP(sport=port_in, dport=external_port))
Martin Gálik977c1cb2017-03-30 23:21:51 -07006430 self.pg0.add_stream(p)
6431 self.pg_enable_capture(self.pg_interfaces)
6432 self.pg_start()
6433 capture = self.pg1.get_capture(1)
6434 p = capture[0]
6435 try:
6436 ip = p[IP]
6437 tcp = p[TCP]
6438 self.assertEqual(ip.src, nat_ip)
6439 self.assertEqual(ip.dst, self.pg1.remote_ip4)
Martin Gálik9806eae2017-04-25 01:25:08 -07006440 self.assertEqual(tcp.dport, external_port)
6441 port_out1 = tcp.sport
Martin Gálik977c1cb2017-03-30 23:21:51 -07006442 except:
6443 self.logger.error(ppp("Unexpected or invalid packet:", p))
6444 raise
6445
Matus Fabian2ba92e32017-08-21 07:05:03 -07006446 dms = self.vapi.nat_det_map_dump()
Martin Gálik977c1cb2017-03-30 23:21:51 -07006447 self.assertEqual(1, len(dms))
6448 self.assertEqual(2, dms[0].ses_num)
6449
6450 # out to host0
6451 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6452 IP(src=self.pg1.remote_ip4, dst=nat_ip) /
Martin Gálik9806eae2017-04-25 01:25:08 -07006453 TCP(sport=external_port, dport=port_out0))
Martin Gálik977c1cb2017-03-30 23:21:51 -07006454 self.pg1.add_stream(p)
6455 self.pg_enable_capture(self.pg_interfaces)
6456 self.pg_start()
6457 capture = self.pg0.get_capture(1)
6458 p = capture[0]
6459 try:
6460 ip = p[IP]
6461 tcp = p[TCP]
6462 self.assertEqual(ip.src, self.pg1.remote_ip4)
6463 self.assertEqual(ip.dst, host0.ip4)
6464 self.assertEqual(tcp.dport, port_in)
Martin Gálik9806eae2017-04-25 01:25:08 -07006465 self.assertEqual(tcp.sport, external_port)
Martin Gálik977c1cb2017-03-30 23:21:51 -07006466 except:
6467 self.logger.error(ppp("Unexpected or invalid packet:", p))
6468 raise
6469
6470 # out to host1
6471 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6472 IP(src=self.pg1.remote_ip4, dst=nat_ip) /
Martin Gálik9806eae2017-04-25 01:25:08 -07006473 TCP(sport=external_port, dport=port_out1))
Martin Gálik977c1cb2017-03-30 23:21:51 -07006474 self.pg1.add_stream(p)
6475 self.pg_enable_capture(self.pg_interfaces)
6476 self.pg_start()
6477 capture = self.pg0.get_capture(1)
6478 p = capture[0]
6479 try:
6480 ip = p[IP]
6481 tcp = p[TCP]
6482 self.assertEqual(ip.src, self.pg1.remote_ip4)
6483 self.assertEqual(ip.dst, host1.ip4)
6484 self.assertEqual(tcp.dport, port_in)
Martin Gálik9806eae2017-04-25 01:25:08 -07006485 self.assertEqual(tcp.sport, external_port)
Martin Gálik977c1cb2017-03-30 23:21:51 -07006486 except:
6487 self.logger.error(ppp("Unexpected or invalid packet", p))
6488 raise
6489
Martin Gálik6bc8c642017-04-19 01:12:27 -07006490 # session close api test
Matus Fabian2ba92e32017-08-21 07:05:03 -07006491 self.vapi.nat_det_close_session_out(socket.inet_aton(nat_ip),
6492 port_out1,
Martin Gálik6bc8c642017-04-19 01:12:27 -07006493 self.pg1.remote_ip4n,
Martin Gálik9806eae2017-04-25 01:25:08 -07006494 external_port)
Matus Fabian2ba92e32017-08-21 07:05:03 -07006495 dms = self.vapi.nat_det_map_dump()
6496 self.assertEqual(dms[0].ses_num, 1)
6497
6498 self.vapi.nat_det_close_session_in(host0.ip4n,
6499 port_in,
6500 self.pg1.remote_ip4n,
6501 external_port)
6502 dms = self.vapi.nat_det_map_dump()
Martin Gálik6bc8c642017-04-19 01:12:27 -07006503 self.assertEqual(dms[0].ses_num, 0)
6504
Martin Gálik977c1cb2017-03-30 23:21:51 -07006505 def test_tcp_session_close_detection_in(self):
Matus Fabian2ba92e32017-08-21 07:05:03 -07006506 """ Deterministic NAT TCP session close from inside network """
6507 self.vapi.nat_det_add_del_map(self.pg0.remote_ip4n,
6508 32,
6509 socket.inet_aton(self.nat_addr),
6510 32)
6511 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
6512 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
6513 is_inside=0)
Martin Gálik977c1cb2017-03-30 23:21:51 -07006514
6515 self.initiate_tcp_session(self.pg0, self.pg1)
6516
6517 # close the session from inside
6518 try:
6519 # FIN packet in -> out
6520 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6521 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
Martin Gálik9806eae2017-04-25 01:25:08 -07006522 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
Martin Gálik977c1cb2017-03-30 23:21:51 -07006523 flags="F"))
6524 self.pg0.add_stream(p)
6525 self.pg_enable_capture(self.pg_interfaces)
6526 self.pg_start()
6527 self.pg1.get_capture(1)
6528
6529 pkts = []
6530
6531 # ACK packet out -> in
6532 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
Matus Fabian2ba92e32017-08-21 07:05:03 -07006533 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
Martin Gálik9806eae2017-04-25 01:25:08 -07006534 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
Martin Gálik977c1cb2017-03-30 23:21:51 -07006535 flags="A"))
6536 pkts.append(p)
6537
6538 # FIN packet out -> in
6539 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
Matus Fabian2ba92e32017-08-21 07:05:03 -07006540 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
Martin Gálik9806eae2017-04-25 01:25:08 -07006541 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
Martin Gálik977c1cb2017-03-30 23:21:51 -07006542 flags="F"))
6543 pkts.append(p)
6544
6545 self.pg1.add_stream(pkts)
6546 self.pg_enable_capture(self.pg_interfaces)
6547 self.pg_start()
6548 self.pg0.get_capture(2)
6549
6550 # ACK packet in -> out
6551 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6552 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
Martin Gálik9806eae2017-04-25 01:25:08 -07006553 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
Martin Gálik977c1cb2017-03-30 23:21:51 -07006554 flags="A"))
6555 self.pg0.add_stream(p)
6556 self.pg_enable_capture(self.pg_interfaces)
6557 self.pg_start()
6558 self.pg1.get_capture(1)
6559
Matus Fabian2ba92e32017-08-21 07:05:03 -07006560 # Check if deterministic NAT44 closed the session
6561 dms = self.vapi.nat_det_map_dump()
Martin Gálik977c1cb2017-03-30 23:21:51 -07006562 self.assertEqual(0, dms[0].ses_num)
6563 except:
6564 self.logger.error("TCP session termination failed")
6565 raise
6566
6567 def test_tcp_session_close_detection_out(self):
Matus Fabian2ba92e32017-08-21 07:05:03 -07006568 """ Deterministic NAT TCP session close from outside network """
6569 self.vapi.nat_det_add_del_map(self.pg0.remote_ip4n,
6570 32,
6571 socket.inet_aton(self.nat_addr),
6572 32)
6573 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
6574 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
6575 is_inside=0)
Martin Gálik977c1cb2017-03-30 23:21:51 -07006576
6577 self.initiate_tcp_session(self.pg0, self.pg1)
6578
6579 # close the session from outside
6580 try:
6581 # FIN packet out -> in
6582 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
Matus Fabian2ba92e32017-08-21 07:05:03 -07006583 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
Martin Gálik9806eae2017-04-25 01:25:08 -07006584 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
Martin Gálik977c1cb2017-03-30 23:21:51 -07006585 flags="F"))
6586 self.pg1.add_stream(p)
6587 self.pg_enable_capture(self.pg_interfaces)
6588 self.pg_start()
6589 self.pg0.get_capture(1)
6590
6591 pkts = []
6592
6593 # ACK packet in -> out
6594 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6595 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
Martin Gálik9806eae2017-04-25 01:25:08 -07006596 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
Martin Gálik977c1cb2017-03-30 23:21:51 -07006597 flags="A"))
6598 pkts.append(p)
6599
6600 # ACK packet in -> out
6601 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6602 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
Martin Gálik9806eae2017-04-25 01:25:08 -07006603 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
Martin Gálik977c1cb2017-03-30 23:21:51 -07006604 flags="F"))
6605 pkts.append(p)
6606
6607 self.pg0.add_stream(pkts)
6608 self.pg_enable_capture(self.pg_interfaces)
6609 self.pg_start()
6610 self.pg1.get_capture(2)
6611
6612 # ACK packet out -> in
6613 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
Matus Fabian2ba92e32017-08-21 07:05:03 -07006614 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
Martin Gálik9806eae2017-04-25 01:25:08 -07006615 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
Martin Gálik977c1cb2017-03-30 23:21:51 -07006616 flags="A"))
6617 self.pg1.add_stream(p)
6618 self.pg_enable_capture(self.pg_interfaces)
6619 self.pg_start()
6620 self.pg0.get_capture(1)
6621
Matus Fabian2ba92e32017-08-21 07:05:03 -07006622 # Check if deterministic NAT44 closed the session
6623 dms = self.vapi.nat_det_map_dump()
Martin Gálik977c1cb2017-03-30 23:21:51 -07006624 self.assertEqual(0, dms[0].ses_num)
6625 except:
6626 self.logger.error("TCP session termination failed")
6627 raise
6628
Paul Vinciguerradefde0f2018-12-06 07:46:13 -08006629 @unittest.skipUnless(running_extended_tests, "part of extended tests")
Martin Gálik977c1cb2017-03-30 23:21:51 -07006630 def test_session_timeout(self):
Matus Fabian2ba92e32017-08-21 07:05:03 -07006631 """ Deterministic NAT session timeouts """
6632 self.vapi.nat_det_add_del_map(self.pg0.remote_ip4n,
6633 32,
6634 socket.inet_aton(self.nat_addr),
6635 32)
6636 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
6637 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
6638 is_inside=0)
Martin Gálik977c1cb2017-03-30 23:21:51 -07006639
6640 self.initiate_tcp_session(self.pg0, self.pg1)
Matus Fabian878c6462018-08-23 00:33:35 -07006641 self.vapi.nat_set_timeouts(5, 5, 5, 5)
Martin Gálik977c1cb2017-03-30 23:21:51 -07006642 pkts = self.create_stream_in(self.pg0, self.pg1)
6643 self.pg0.add_stream(pkts)
6644 self.pg_enable_capture(self.pg_interfaces)
6645 self.pg_start()
6646 capture = self.pg1.get_capture(len(pkts))
6647 sleep(15)
6648
Matus Fabian2ba92e32017-08-21 07:05:03 -07006649 dms = self.vapi.nat_det_map_dump()
Martin Gálik977c1cb2017-03-30 23:21:51 -07006650 self.assertEqual(0, dms[0].ses_num)
6651
Paul Vinciguerradefde0f2018-12-06 07:46:13 -08006652 @unittest.skipUnless(running_extended_tests, "part of extended tests")
Martin Gálik977c1cb2017-03-30 23:21:51 -07006653 def test_session_limit_per_user(self):
Matus Fabian2ba92e32017-08-21 07:05:03 -07006654 """ Deterministic NAT maximum sessions per user limit """
6655 self.vapi.nat_det_add_del_map(self.pg0.remote_ip4n,
6656 32,
6657 socket.inet_aton(self.nat_addr),
6658 32)
6659 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
6660 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
6661 is_inside=0)
Matus Fabian2f2db1c2017-04-18 05:29:59 -07006662 self.vapi.set_ipfix_exporter(collector_address=self.pg2.remote_ip4n,
6663 src_address=self.pg2.local_ip4n,
6664 path_mtu=512,
6665 template_interval=10)
Matus Fabian2ba92e32017-08-21 07:05:03 -07006666 self.vapi.nat_ipfix()
Martin Gálik977c1cb2017-03-30 23:21:51 -07006667
6668 pkts = []
6669 for port in range(1025, 2025):
6670 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6671 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6672 UDP(sport=port, dport=port))
6673 pkts.append(p)
6674
6675 self.pg0.add_stream(pkts)
6676 self.pg_enable_capture(self.pg_interfaces)
6677 self.pg_start()
6678 capture = self.pg1.get_capture(len(pkts))
6679
6680 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6681 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
Martin Gálikf7e655d2017-04-27 02:13:26 -07006682 UDP(sport=3001, dport=3002))
Martin Gálik977c1cb2017-03-30 23:21:51 -07006683 self.pg0.add_stream(p)
6684 self.pg_enable_capture(self.pg_interfaces)
6685 self.pg_start()
6686 capture = self.pg1.assert_nothing_captured()
6687
Martin Gálikf7e655d2017-04-27 02:13:26 -07006688 # verify ICMP error packet
6689 capture = self.pg0.get_capture(1)
6690 p = capture[0]
6691 self.assertTrue(p.haslayer(ICMP))
6692 icmp = p[ICMP]
6693 self.assertEqual(icmp.type, 3)
6694 self.assertEqual(icmp.code, 1)
6695 self.assertTrue(icmp.haslayer(IPerror))
6696 inner_ip = icmp[IPerror]
6697 self.assertEqual(inner_ip[UDPerror].sport, 3001)
6698 self.assertEqual(inner_ip[UDPerror].dport, 3002)
6699
Matus Fabian2ba92e32017-08-21 07:05:03 -07006700 dms = self.vapi.nat_det_map_dump()
Martin Gálik977c1cb2017-03-30 23:21:51 -07006701
6702 self.assertEqual(1000, dms[0].ses_num)
6703
Matus Fabian2f2db1c2017-04-18 05:29:59 -07006704 # verify IPFIX logging
6705 self.vapi.cli("ipfix flush") # FIXME this should be an API call
Matus Fabian7c0aecc2017-07-03 01:21:38 -07006706 sleep(1)
Matus Fabian2f2db1c2017-04-18 05:29:59 -07006707 capture = self.pg2.get_capture(2)
6708 ipfix = IPFIXDecoder()
6709 # first load template
6710 for p in capture:
6711 self.assertTrue(p.haslayer(IPFIX))
6712 if p.haslayer(Template):
6713 ipfix.add_template(p.getlayer(Template))
6714 # verify events in data set
6715 for p in capture:
6716 if p.haslayer(Data):
6717 data = ipfix.decode_data_set(p.getlayer(Set))
Matus Fabian878c6462018-08-23 00:33:35 -07006718 self.verify_ipfix_max_entries_per_user(data,
6719 1000,
6720 self.pg0.remote_ip4n)
Matus Fabian2f2db1c2017-04-18 05:29:59 -07006721
Matus Fabian2ba92e32017-08-21 07:05:03 -07006722 def clear_nat_det(self):
Martin17a75cb2017-03-08 05:53:20 -08006723 """
Matus Fabian2ba92e32017-08-21 07:05:03 -07006724 Clear deterministic NAT configuration.
Martin17a75cb2017-03-08 05:53:20 -08006725 """
Matus Fabian2ba92e32017-08-21 07:05:03 -07006726 self.vapi.nat_ipfix(enable=0)
Matus Fabian878c6462018-08-23 00:33:35 -07006727 self.vapi.nat_set_timeouts()
Matus Fabian2ba92e32017-08-21 07:05:03 -07006728 deterministic_mappings = self.vapi.nat_det_map_dump()
Martin17a75cb2017-03-08 05:53:20 -08006729 for dsm in deterministic_mappings:
Matus Fabian2ba92e32017-08-21 07:05:03 -07006730 self.vapi.nat_det_add_del_map(dsm.in_addr,
6731 dsm.in_plen,
6732 dsm.out_addr,
6733 dsm.out_plen,
6734 is_add=0)
Martin17a75cb2017-03-08 05:53:20 -08006735
Matus Fabian2ba92e32017-08-21 07:05:03 -07006736 interfaces = self.vapi.nat44_interface_dump()
Martin Gálik977c1cb2017-03-30 23:21:51 -07006737 for intf in interfaces:
Matus Fabian2ba92e32017-08-21 07:05:03 -07006738 self.vapi.nat44_interface_add_del_feature(intf.sw_if_index,
6739 intf.is_inside,
6740 is_add=0)
Martin Gálik977c1cb2017-03-30 23:21:51 -07006741
Matus Fabian066f0342017-02-10 03:48:01 -08006742 def tearDown(self):
6743 super(TestDeterministicNAT, self).tearDown()
6744 if not self.vpp_dead:
Matus Fabian82119542018-01-25 01:13:22 -08006745 self.logger.info(self.vapi.cli("show nat44 interfaces"))
Matus Fabian878c6462018-08-23 00:33:35 -07006746 self.logger.info(self.vapi.cli("show nat timeouts"))
Matus Fabian82119542018-01-25 01:13:22 -08006747 self.logger.info(
6748 self.vapi.cli("show nat44 deterministic mappings"))
6749 self.logger.info(
Matus Fabian82119542018-01-25 01:13:22 -08006750 self.vapi.cli("show nat44 deterministic sessions"))
Matus Fabian2ba92e32017-08-21 07:05:03 -07006751 self.clear_nat_det()
Matus Fabian066f0342017-02-10 03:48:01 -08006752
Matus Fabian06596c52017-06-06 04:53:28 -07006753
6754class TestNAT64(MethodHolder):
6755 """ NAT64 Test Cases """
6756
6757 @classmethod
Matus Fabiana431ad12018-01-04 04:03:14 -08006758 def setUpConstants(cls):
6759 super(TestNAT64, cls).setUpConstants()
6760 cls.vpp_cmdline.extend(["nat", "{", "nat64 bib hash buckets 128",
6761 "nat64 st hash buckets 256", "}"])
6762
6763 @classmethod
Matus Fabian06596c52017-06-06 04:53:28 -07006764 def setUpClass(cls):
6765 super(TestNAT64, cls).setUpClass()
6766
6767 try:
6768 cls.tcp_port_in = 6303
6769 cls.tcp_port_out = 6303
6770 cls.udp_port_in = 6304
6771 cls.udp_port_out = 6304
6772 cls.icmp_id_in = 6305
6773 cls.icmp_id_out = 6305
Matus Fabianad1f3e12018-11-28 21:26:34 -08006774 cls.tcp_external_port = 80
Matus Fabian06596c52017-06-06 04:53:28 -07006775 cls.nat_addr = '10.0.0.3'
6776 cls.nat_addr_n = socket.inet_pton(socket.AF_INET, cls.nat_addr)
Matus Fabian029f3d22017-06-15 02:28:50 -07006777 cls.vrf1_id = 10
6778 cls.vrf1_nat_addr = '10.0.10.3'
6779 cls.vrf1_nat_addr_n = socket.inet_pton(socket.AF_INET,
6780 cls.vrf1_nat_addr)
Matus Fabiana431ad12018-01-04 04:03:14 -08006781 cls.ipfix_src_port = 4739
6782 cls.ipfix_domain_id = 1
Matus Fabian06596c52017-06-06 04:53:28 -07006783
Juraj Slobodac746a152018-07-09 02:36:37 +02006784 cls.create_pg_interfaces(range(6))
Matus Fabian06596c52017-06-06 04:53:28 -07006785 cls.ip6_interfaces = list(cls.pg_interfaces[0:1])
Matus Fabian029f3d22017-06-15 02:28:50 -07006786 cls.ip6_interfaces.append(cls.pg_interfaces[2])
Matus Fabian06596c52017-06-06 04:53:28 -07006787 cls.ip4_interfaces = list(cls.pg_interfaces[1:2])
6788
Neale Ranns15002542017-09-10 04:39:11 -07006789 cls.vapi.ip_table_add_del(cls.vrf1_id, is_add=1, is_ipv6=1)
6790
Matus Fabian029f3d22017-06-15 02:28:50 -07006791 cls.pg_interfaces[2].set_table_ip6(cls.vrf1_id)
6792
6793 cls.pg0.generate_remote_hosts(2)
6794
Matus Fabian06596c52017-06-06 04:53:28 -07006795 for i in cls.ip6_interfaces:
6796 i.admin_up()
6797 i.config_ip6()
Matus Fabian029f3d22017-06-15 02:28:50 -07006798 i.configure_ipv6_neighbors()
Matus Fabian06596c52017-06-06 04:53:28 -07006799
6800 for i in cls.ip4_interfaces:
6801 i.admin_up()
6802 i.config_ip4()
6803 i.resolve_arp()
6804
Matus Fabian36ea2d62017-10-24 04:13:49 -07006805 cls.pg3.admin_up()
6806 cls.pg3.config_ip4()
6807 cls.pg3.resolve_arp()
6808 cls.pg3.config_ip6()
6809 cls.pg3.configure_ipv6_neighbors()
6810
Juraj Slobodac746a152018-07-09 02:36:37 +02006811 cls.pg5.admin_up()
6812 cls.pg5.config_ip6()
6813
Matus Fabian06596c52017-06-06 04:53:28 -07006814 except Exception:
6815 super(TestNAT64, cls).tearDownClass()
6816 raise
6817
Juraj Slobodac746a152018-07-09 02:36:37 +02006818 def test_nat64_inside_interface_handles_neighbor_advertisement(self):
6819 """ NAT64 inside interface handles Neighbor Advertisement """
6820
6821 self.vapi.nat64_add_del_interface(self.pg5.sw_if_index)
6822
6823 # Try to send ping
6824 ping = (Ether(dst=self.pg5.local_mac, src=self.pg5.remote_mac) /
6825 IPv6(src=self.pg5.remote_ip6, dst=self.pg5.local_ip6) /
6826 ICMPv6EchoRequest())
6827 pkts = [ping]
6828 self.pg5.add_stream(pkts)
6829 self.pg_enable_capture(self.pg_interfaces)
6830 self.pg_start()
6831
6832 # Wait for Neighbor Solicitation
6833 capture = self.pg5.get_capture(len(pkts))
Juraj Slobodac746a152018-07-09 02:36:37 +02006834 packet = capture[0]
6835 try:
6836 self.assertEqual(packet[IPv6].src, self.pg5.local_ip6)
Paul Vinciguerra978aa642018-11-24 22:19:12 -08006837 self.assertEqual(packet.haslayer(ICMPv6ND_NS), 1)
Juraj Slobodac746a152018-07-09 02:36:37 +02006838 tgt = packet[ICMPv6ND_NS].tgt
6839 except:
6840 self.logger.error(ppp("Unexpected or invalid packet:", packet))
6841 raise
6842
6843 # Send Neighbor Advertisement
6844 p = (Ether(dst=self.pg5.local_mac, src=self.pg5.remote_mac) /
6845 IPv6(src=self.pg5.remote_ip6, dst=self.pg5.local_ip6) /
6846 ICMPv6ND_NA(tgt=tgt) /
6847 ICMPv6NDOptDstLLAddr(lladdr=self.pg5.remote_mac))
6848 pkts = [p]
6849 self.pg5.add_stream(pkts)
6850 self.pg_enable_capture(self.pg_interfaces)
6851 self.pg_start()
6852
6853 # Try to send ping again
6854 pkts = [ping]
6855 self.pg5.add_stream(pkts)
6856 self.pg_enable_capture(self.pg_interfaces)
6857 self.pg_start()
6858
6859 # Wait for ping reply
6860 capture = self.pg5.get_capture(len(pkts))
Juraj Slobodac746a152018-07-09 02:36:37 +02006861 packet = capture[0]
6862 try:
6863 self.assertEqual(packet[IPv6].src, self.pg5.local_ip6)
6864 self.assertEqual(packet[IPv6].dst, self.pg5.remote_ip6)
Paul Vinciguerra978aa642018-11-24 22:19:12 -08006865 self.assertEqual(packet.haslayer(ICMPv6EchoReply), 1)
Juraj Slobodac746a152018-07-09 02:36:37 +02006866 except:
6867 self.logger.error(ppp("Unexpected or invalid packet:", packet))
6868 raise
6869
Matus Fabian06596c52017-06-06 04:53:28 -07006870 def test_pool(self):
6871 """ Add/delete address to NAT64 pool """
6872 nat_addr = socket.inet_pton(socket.AF_INET, '1.2.3.4')
6873
6874 self.vapi.nat64_add_del_pool_addr_range(nat_addr, nat_addr)
6875
6876 addresses = self.vapi.nat64_pool_addr_dump()
6877 self.assertEqual(len(addresses), 1)
6878 self.assertEqual(addresses[0].address, nat_addr)
6879
6880 self.vapi.nat64_add_del_pool_addr_range(nat_addr, nat_addr, is_add=0)
6881
6882 addresses = self.vapi.nat64_pool_addr_dump()
6883 self.assertEqual(len(addresses), 0)
6884
6885 def test_interface(self):
6886 """ Enable/disable NAT64 feature on the interface """
6887 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
6888 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
6889
6890 interfaces = self.vapi.nat64_interface_dump()
6891 self.assertEqual(len(interfaces), 2)
6892 pg0_found = False
6893 pg1_found = False
6894 for intf in interfaces:
6895 if intf.sw_if_index == self.pg0.sw_if_index:
6896 self.assertEqual(intf.is_inside, 1)
6897 pg0_found = True
6898 elif intf.sw_if_index == self.pg1.sw_if_index:
6899 self.assertEqual(intf.is_inside, 0)
6900 pg1_found = True
6901 self.assertTrue(pg0_found)
6902 self.assertTrue(pg1_found)
6903
6904 features = self.vapi.cli("show interface features pg0")
6905 self.assertNotEqual(features.find('nat64-in2out'), -1)
6906 features = self.vapi.cli("show interface features pg1")
6907 self.assertNotEqual(features.find('nat64-out2in'), -1)
6908
6909 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index, is_add=0)
6910 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_add=0)
6911
6912 interfaces = self.vapi.nat64_interface_dump()
6913 self.assertEqual(len(interfaces), 0)
6914
6915 def test_static_bib(self):
6916 """ Add/delete static BIB entry """
6917 in_addr = socket.inet_pton(socket.AF_INET6,
6918 '2001:db8:85a3::8a2e:370:7334')
6919 out_addr = socket.inet_pton(socket.AF_INET, '10.1.1.3')
6920 in_port = 1234
6921 out_port = 5678
6922 proto = IP_PROTOS.tcp
6923
6924 self.vapi.nat64_add_del_static_bib(in_addr,
6925 out_addr,
6926 in_port,
6927 out_port,
6928 proto)
6929 bib = self.vapi.nat64_bib_dump(IP_PROTOS.tcp)
6930 static_bib_num = 0
6931 for bibe in bib:
6932 if bibe.is_static:
6933 static_bib_num += 1
6934 self.assertEqual(bibe.i_addr, in_addr)
6935 self.assertEqual(bibe.o_addr, out_addr)
6936 self.assertEqual(bibe.i_port, in_port)
6937 self.assertEqual(bibe.o_port, out_port)
6938 self.assertEqual(static_bib_num, 1)
6939
6940 self.vapi.nat64_add_del_static_bib(in_addr,
6941 out_addr,
6942 in_port,
6943 out_port,
6944 proto,
6945 is_add=0)
6946 bib = self.vapi.nat64_bib_dump(IP_PROTOS.tcp)
6947 static_bib_num = 0
6948 for bibe in bib:
6949 if bibe.is_static:
6950 static_bib_num += 1
6951 self.assertEqual(static_bib_num, 0)
6952
6953 def test_set_timeouts(self):
6954 """ Set NAT64 timeouts """
6955 # verify default values
Matus Fabian878c6462018-08-23 00:33:35 -07006956 timeouts = self.vapi.nat_get_timeouts()
Matus Fabian06596c52017-06-06 04:53:28 -07006957 self.assertEqual(timeouts.udp, 300)
6958 self.assertEqual(timeouts.icmp, 60)
Matus Fabian878c6462018-08-23 00:33:35 -07006959 self.assertEqual(timeouts.tcp_transitory, 240)
6960 self.assertEqual(timeouts.tcp_established, 7440)
Matus Fabian06596c52017-06-06 04:53:28 -07006961
6962 # set and verify custom values
Matus Fabian878c6462018-08-23 00:33:35 -07006963 self.vapi.nat_set_timeouts(udp=200, icmp=30, tcp_transitory=250,
6964 tcp_established=7450)
6965 timeouts = self.vapi.nat_get_timeouts()
Matus Fabian06596c52017-06-06 04:53:28 -07006966 self.assertEqual(timeouts.udp, 200)
6967 self.assertEqual(timeouts.icmp, 30)
Matus Fabian878c6462018-08-23 00:33:35 -07006968 self.assertEqual(timeouts.tcp_transitory, 250)
6969 self.assertEqual(timeouts.tcp_established, 7450)
Matus Fabian06596c52017-06-06 04:53:28 -07006970
6971 def test_dynamic(self):
6972 """ NAT64 dynamic translation test """
6973 self.tcp_port_in = 6303
6974 self.udp_port_in = 6304
6975 self.icmp_id_in = 6305
6976
6977 ses_num_start = self.nat64_get_ses_num()
6978
6979 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
6980 self.nat_addr_n)
6981 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
6982 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
6983
6984 # in2out
Matus Fabiana5e73762018-12-14 01:55:16 -08006985 tcpn = self.statistics.get_counter('/err/nat64-in2out/TCP packets')
6986 udpn = self.statistics.get_counter('/err/nat64-in2out/UDP packets')
6987 icmpn = self.statistics.get_counter('/err/nat64-in2out/ICMP packets')
6988 totaln = self.statistics.get_counter(
6989 '/err/nat64-in2out/good in2out packets processed')
6990
Matus Fabian06596c52017-06-06 04:53:28 -07006991 pkts = self.create_stream_in_ip6(self.pg0, self.pg1)
6992 self.pg0.add_stream(pkts)
6993 self.pg_enable_capture(self.pg_interfaces)
6994 self.pg_start()
Matus Fabian029f3d22017-06-15 02:28:50 -07006995 capture = self.pg1.get_capture(len(pkts))
6996 self.verify_capture_out(capture, nat_ip=self.nat_addr,
Matus Fabian06596c52017-06-06 04:53:28 -07006997 dst_ip=self.pg1.remote_ip4)
6998
Matus Fabiana5e73762018-12-14 01:55:16 -08006999 err = self.statistics.get_counter('/err/nat64-in2out/TCP packets')
7000 self.assertEqual(err - tcpn, 1)
7001 err = self.statistics.get_counter('/err/nat64-in2out/UDP packets')
7002 self.assertEqual(err - udpn, 1)
7003 err = self.statistics.get_counter('/err/nat64-in2out/ICMP packets')
7004 self.assertEqual(err - icmpn, 1)
7005 err = self.statistics.get_counter(
7006 '/err/nat64-in2out/good in2out packets processed')
7007 self.assertEqual(err - totaln, 3)
7008
Matus Fabian06596c52017-06-06 04:53:28 -07007009 # out2in
Matus Fabiana5e73762018-12-14 01:55:16 -08007010 tcpn = self.statistics.get_counter('/err/nat64-out2in/TCP packets')
7011 udpn = self.statistics.get_counter('/err/nat64-out2in/UDP packets')
7012 icmpn = self.statistics.get_counter('/err/nat64-out2in/ICMP packets')
7013 totaln = self.statistics.get_counter(
7014 '/err/nat64-out2in/good out2in packets processed')
7015
Matus Fabian06596c52017-06-06 04:53:28 -07007016 pkts = self.create_stream_out(self.pg1, dst_ip=self.nat_addr)
7017 self.pg1.add_stream(pkts)
7018 self.pg_enable_capture(self.pg_interfaces)
7019 self.pg_start()
Matus Fabian029f3d22017-06-15 02:28:50 -07007020 capture = self.pg0.get_capture(len(pkts))
Matus Fabian06596c52017-06-06 04:53:28 -07007021 ip = IPv6(src=''.join(['64:ff9b::', self.pg1.remote_ip4]))
7022 self.verify_capture_in_ip6(capture, ip[IPv6].src, self.pg0.remote_ip6)
7023
Matus Fabiana5e73762018-12-14 01:55:16 -08007024 err = self.statistics.get_counter('/err/nat64-out2in/TCP packets')
7025 self.assertEqual(err - tcpn, 1)
7026 err = self.statistics.get_counter('/err/nat64-out2in/UDP packets')
7027 self.assertEqual(err - udpn, 1)
7028 err = self.statistics.get_counter('/err/nat64-out2in/ICMP packets')
7029 self.assertEqual(err - icmpn, 1)
7030 err = self.statistics.get_counter(
7031 '/err/nat64-out2in/good out2in packets processed')
7032 self.assertEqual(err - totaln, 3)
7033
Matus Fabian06596c52017-06-06 04:53:28 -07007034 # in2out
7035 pkts = self.create_stream_in_ip6(self.pg0, self.pg1)
7036 self.pg0.add_stream(pkts)
7037 self.pg_enable_capture(self.pg_interfaces)
7038 self.pg_start()
Matus Fabian029f3d22017-06-15 02:28:50 -07007039 capture = self.pg1.get_capture(len(pkts))
7040 self.verify_capture_out(capture, nat_ip=self.nat_addr,
Matus Fabian06596c52017-06-06 04:53:28 -07007041 dst_ip=self.pg1.remote_ip4)
7042
7043 # out2in
7044 pkts = self.create_stream_out(self.pg1, dst_ip=self.nat_addr)
7045 self.pg1.add_stream(pkts)
7046 self.pg_enable_capture(self.pg_interfaces)
7047 self.pg_start()
Matus Fabian029f3d22017-06-15 02:28:50 -07007048 capture = self.pg0.get_capture(len(pkts))
Matus Fabian06596c52017-06-06 04:53:28 -07007049 self.verify_capture_in_ip6(capture, ip[IPv6].src, self.pg0.remote_ip6)
7050
7051 ses_num_end = self.nat64_get_ses_num()
7052
7053 self.assertEqual(ses_num_end - ses_num_start, 3)
7054
Matus Fabian029f3d22017-06-15 02:28:50 -07007055 # tenant with specific VRF
7056 self.vapi.nat64_add_del_pool_addr_range(self.vrf1_nat_addr_n,
7057 self.vrf1_nat_addr_n,
7058 vrf_id=self.vrf1_id)
7059 self.vapi.nat64_add_del_interface(self.pg2.sw_if_index)
7060
7061 pkts = self.create_stream_in_ip6(self.pg2, self.pg1)
7062 self.pg2.add_stream(pkts)
7063 self.pg_enable_capture(self.pg_interfaces)
7064 self.pg_start()
7065 capture = self.pg1.get_capture(len(pkts))
7066 self.verify_capture_out(capture, nat_ip=self.vrf1_nat_addr,
7067 dst_ip=self.pg1.remote_ip4)
7068
7069 pkts = self.create_stream_out(self.pg1, dst_ip=self.vrf1_nat_addr)
7070 self.pg1.add_stream(pkts)
7071 self.pg_enable_capture(self.pg_interfaces)
7072 self.pg_start()
7073 capture = self.pg2.get_capture(len(pkts))
7074 self.verify_capture_in_ip6(capture, ip[IPv6].src, self.pg2.remote_ip6)
7075
Matus Fabian06596c52017-06-06 04:53:28 -07007076 def test_static(self):
7077 """ NAT64 static translation test """
7078 self.tcp_port_in = 60303
7079 self.udp_port_in = 60304
7080 self.icmp_id_in = 60305
7081 self.tcp_port_out = 60303
7082 self.udp_port_out = 60304
7083 self.icmp_id_out = 60305
7084
7085 ses_num_start = self.nat64_get_ses_num()
7086
7087 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
7088 self.nat_addr_n)
7089 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
7090 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
7091
7092 self.vapi.nat64_add_del_static_bib(self.pg0.remote_ip6n,
7093 self.nat_addr_n,
7094 self.tcp_port_in,
7095 self.tcp_port_out,
7096 IP_PROTOS.tcp)
7097 self.vapi.nat64_add_del_static_bib(self.pg0.remote_ip6n,
7098 self.nat_addr_n,
7099 self.udp_port_in,
7100 self.udp_port_out,
7101 IP_PROTOS.udp)
7102 self.vapi.nat64_add_del_static_bib(self.pg0.remote_ip6n,
7103 self.nat_addr_n,
7104 self.icmp_id_in,
7105 self.icmp_id_out,
7106 IP_PROTOS.icmp)
7107
7108 # in2out
7109 pkts = self.create_stream_in_ip6(self.pg0, self.pg1)
7110 self.pg0.add_stream(pkts)
7111 self.pg_enable_capture(self.pg_interfaces)
7112 self.pg_start()
Matus Fabian029f3d22017-06-15 02:28:50 -07007113 capture = self.pg1.get_capture(len(pkts))
7114 self.verify_capture_out(capture, nat_ip=self.nat_addr,
Matus Fabian06596c52017-06-06 04:53:28 -07007115 dst_ip=self.pg1.remote_ip4, same_port=True)
7116
7117 # out2in
7118 pkts = self.create_stream_out(self.pg1, dst_ip=self.nat_addr)
7119 self.pg1.add_stream(pkts)
7120 self.pg_enable_capture(self.pg_interfaces)
7121 self.pg_start()
Matus Fabian029f3d22017-06-15 02:28:50 -07007122 capture = self.pg0.get_capture(len(pkts))
Matus Fabian06596c52017-06-06 04:53:28 -07007123 ip = IPv6(src=''.join(['64:ff9b::', self.pg1.remote_ip4]))
7124 self.verify_capture_in_ip6(capture, ip[IPv6].src, self.pg0.remote_ip6)
7125
7126 ses_num_end = self.nat64_get_ses_num()
7127
7128 self.assertEqual(ses_num_end - ses_num_start, 3)
7129
Paul Vinciguerradefde0f2018-12-06 07:46:13 -08007130 @unittest.skipUnless(running_extended_tests, "part of extended tests")
Matus Fabian06596c52017-06-06 04:53:28 -07007131 def test_session_timeout(self):
7132 """ NAT64 session timeout """
7133 self.icmp_id_in = 1234
7134 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
7135 self.nat_addr_n)
7136 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
7137 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
Matus Fabian878c6462018-08-23 00:33:35 -07007138 self.vapi.nat_set_timeouts(icmp=5, tcp_transitory=5, tcp_established=5)
Matus Fabian06596c52017-06-06 04:53:28 -07007139
7140 pkts = self.create_stream_in_ip6(self.pg0, self.pg1)
7141 self.pg0.add_stream(pkts)
7142 self.pg_enable_capture(self.pg_interfaces)
7143 self.pg_start()
Matus Fabian029f3d22017-06-15 02:28:50 -07007144 capture = self.pg1.get_capture(len(pkts))
Matus Fabian06596c52017-06-06 04:53:28 -07007145
7146 ses_num_before_timeout = self.nat64_get_ses_num()
7147
7148 sleep(15)
7149
Matus Fabian8fed4242018-08-14 05:14:55 -07007150 # ICMP and TCP session after timeout
Matus Fabian06596c52017-06-06 04:53:28 -07007151 ses_num_after_timeout = self.nat64_get_ses_num()
Matus Fabian8fed4242018-08-14 05:14:55 -07007152 self.assertEqual(ses_num_before_timeout - ses_num_after_timeout, 2)
Matus Fabian06596c52017-06-06 04:53:28 -07007153
Matus Fabian732036d2017-06-08 05:24:28 -07007154 def test_icmp_error(self):
7155 """ NAT64 ICMP Error message translation """
7156 self.tcp_port_in = 6303
7157 self.udp_port_in = 6304
7158 self.icmp_id_in = 6305
7159
Matus Fabian732036d2017-06-08 05:24:28 -07007160 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
7161 self.nat_addr_n)
7162 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
7163 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
7164
7165 # send some packets to create sessions
7166 pkts = self.create_stream_in_ip6(self.pg0, self.pg1)
7167 self.pg0.add_stream(pkts)
7168 self.pg_enable_capture(self.pg_interfaces)
7169 self.pg_start()
7170 capture_ip4 = self.pg1.get_capture(len(pkts))
Matus Fabian029f3d22017-06-15 02:28:50 -07007171 self.verify_capture_out(capture_ip4,
Matus Fabian732036d2017-06-08 05:24:28 -07007172 nat_ip=self.nat_addr,
7173 dst_ip=self.pg1.remote_ip4)
7174
7175 pkts = self.create_stream_out(self.pg1, dst_ip=self.nat_addr)
7176 self.pg1.add_stream(pkts)
7177 self.pg_enable_capture(self.pg_interfaces)
7178 self.pg_start()
7179 capture_ip6 = self.pg0.get_capture(len(pkts))
7180 ip = IPv6(src=''.join(['64:ff9b::', self.pg1.remote_ip4]))
7181 self.verify_capture_in_ip6(capture_ip6, ip[IPv6].src,
7182 self.pg0.remote_ip6)
7183
7184 # in2out
7185 pkts = [Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
7186 IPv6(src=self.pg0.remote_ip6, dst=ip[IPv6].src) /
7187 ICMPv6DestUnreach(code=1) /
7188 packet[IPv6] for packet in capture_ip6]
7189 self.pg0.add_stream(pkts)
7190 self.pg_enable_capture(self.pg_interfaces)
7191 self.pg_start()
7192 capture = self.pg1.get_capture(len(pkts))
7193 for packet in capture:
7194 try:
7195 self.assertEqual(packet[IP].src, self.nat_addr)
7196 self.assertEqual(packet[IP].dst, self.pg1.remote_ip4)
7197 self.assertEqual(packet[ICMP].type, 3)
7198 self.assertEqual(packet[ICMP].code, 13)
7199 inner = packet[IPerror]
7200 self.assertEqual(inner.src, self.pg1.remote_ip4)
7201 self.assertEqual(inner.dst, self.nat_addr)
Klement Sekerad81ae412018-05-16 10:52:54 +02007202 self.assert_packet_checksums_valid(packet)
Matus Fabian732036d2017-06-08 05:24:28 -07007203 if inner.haslayer(TCPerror):
7204 self.assertEqual(inner[TCPerror].dport, self.tcp_port_out)
7205 elif inner.haslayer(UDPerror):
7206 self.assertEqual(inner[UDPerror].dport, self.udp_port_out)
7207 else:
7208 self.assertEqual(inner[ICMPerror].id, self.icmp_id_out)
7209 except:
7210 self.logger.error(ppp("Unexpected or invalid packet:", packet))
7211 raise
7212
7213 # out2in
7214 pkts = [Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
7215 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
7216 ICMP(type=3, code=13) /
7217 packet[IP] for packet in capture_ip4]
7218 self.pg1.add_stream(pkts)
7219 self.pg_enable_capture(self.pg_interfaces)
7220 self.pg_start()
7221 capture = self.pg0.get_capture(len(pkts))
7222 for packet in capture:
7223 try:
7224 self.assertEqual(packet[IPv6].src, ip.src)
7225 self.assertEqual(packet[IPv6].dst, self.pg0.remote_ip6)
7226 icmp = packet[ICMPv6DestUnreach]
7227 self.assertEqual(icmp.code, 1)
7228 inner = icmp[IPerror6]
7229 self.assertEqual(inner.src, self.pg0.remote_ip6)
7230 self.assertEqual(inner.dst, ip.src)
Klement Sekerad81ae412018-05-16 10:52:54 +02007231 self.assert_icmpv6_checksum_valid(packet)
Matus Fabian732036d2017-06-08 05:24:28 -07007232 if inner.haslayer(TCPerror):
7233 self.assertEqual(inner[TCPerror].sport, self.tcp_port_in)
7234 elif inner.haslayer(UDPerror):
7235 self.assertEqual(inner[UDPerror].sport, self.udp_port_in)
7236 else:
7237 self.assertEqual(inner[ICMPv6EchoRequest].id,
7238 self.icmp_id_in)
7239 except:
7240 self.logger.error(ppp("Unexpected or invalid packet:", packet))
7241 raise
7242
Matus Fabian029f3d22017-06-15 02:28:50 -07007243 def test_hairpinning(self):
7244 """ NAT64 hairpinning """
7245
7246 client = self.pg0.remote_hosts[0]
7247 server = self.pg0.remote_hosts[1]
7248 server_tcp_in_port = 22
7249 server_tcp_out_port = 4022
7250 server_udp_in_port = 23
7251 server_udp_out_port = 4023
7252 client_tcp_in_port = 1234
7253 client_udp_in_port = 1235
7254 client_tcp_out_port = 0
7255 client_udp_out_port = 0
7256 ip = IPv6(src=''.join(['64:ff9b::', self.nat_addr]))
7257 nat_addr_ip6 = ip.src
7258
7259 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
7260 self.nat_addr_n)
7261 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
7262 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
7263
7264 self.vapi.nat64_add_del_static_bib(server.ip6n,
7265 self.nat_addr_n,
7266 server_tcp_in_port,
7267 server_tcp_out_port,
7268 IP_PROTOS.tcp)
7269 self.vapi.nat64_add_del_static_bib(server.ip6n,
7270 self.nat_addr_n,
7271 server_udp_in_port,
7272 server_udp_out_port,
7273 IP_PROTOS.udp)
7274
7275 # client to server
7276 pkts = []
7277 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
7278 IPv6(src=client.ip6, dst=nat_addr_ip6) /
7279 TCP(sport=client_tcp_in_port, dport=server_tcp_out_port))
7280 pkts.append(p)
7281 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
7282 IPv6(src=client.ip6, dst=nat_addr_ip6) /
7283 UDP(sport=client_udp_in_port, dport=server_udp_out_port))
7284 pkts.append(p)
7285 self.pg0.add_stream(pkts)
7286 self.pg_enable_capture(self.pg_interfaces)
7287 self.pg_start()
7288 capture = self.pg0.get_capture(len(pkts))
7289 for packet in capture:
7290 try:
7291 self.assertEqual(packet[IPv6].src, nat_addr_ip6)
7292 self.assertEqual(packet[IPv6].dst, server.ip6)
Klement Sekerad81ae412018-05-16 10:52:54 +02007293 self.assert_packet_checksums_valid(packet)
Matus Fabian029f3d22017-06-15 02:28:50 -07007294 if packet.haslayer(TCP):
7295 self.assertNotEqual(packet[TCP].sport, client_tcp_in_port)
7296 self.assertEqual(packet[TCP].dport, server_tcp_in_port)
Matus Fabian029f3d22017-06-15 02:28:50 -07007297 client_tcp_out_port = packet[TCP].sport
7298 else:
7299 self.assertNotEqual(packet[UDP].sport, client_udp_in_port)
7300 self.assertEqual(packet[UDP].dport, server_udp_in_port)
Matus Fabian029f3d22017-06-15 02:28:50 -07007301 client_udp_out_port = packet[UDP].sport
7302 except:
7303 self.logger.error(ppp("Unexpected or invalid packet:", packet))
7304 raise
7305
7306 # server to client
7307 pkts = []
7308 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
7309 IPv6(src=server.ip6, dst=nat_addr_ip6) /
7310 TCP(sport=server_tcp_in_port, dport=client_tcp_out_port))
7311 pkts.append(p)
7312 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
7313 IPv6(src=server.ip6, dst=nat_addr_ip6) /
7314 UDP(sport=server_udp_in_port, dport=client_udp_out_port))
7315 pkts.append(p)
7316 self.pg0.add_stream(pkts)
7317 self.pg_enable_capture(self.pg_interfaces)
7318 self.pg_start()
7319 capture = self.pg0.get_capture(len(pkts))
7320 for packet in capture:
7321 try:
7322 self.assertEqual(packet[IPv6].src, nat_addr_ip6)
7323 self.assertEqual(packet[IPv6].dst, client.ip6)
Klement Sekerad81ae412018-05-16 10:52:54 +02007324 self.assert_packet_checksums_valid(packet)
Matus Fabian029f3d22017-06-15 02:28:50 -07007325 if packet.haslayer(TCP):
7326 self.assertEqual(packet[TCP].sport, server_tcp_out_port)
7327 self.assertEqual(packet[TCP].dport, client_tcp_in_port)
Matus Fabian029f3d22017-06-15 02:28:50 -07007328 else:
7329 self.assertEqual(packet[UDP].sport, server_udp_out_port)
7330 self.assertEqual(packet[UDP].dport, client_udp_in_port)
Matus Fabian029f3d22017-06-15 02:28:50 -07007331 except:
7332 self.logger.error(ppp("Unexpected or invalid packet:", packet))
7333 raise
7334
7335 # ICMP error
7336 pkts = []
7337 pkts = [Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
7338 IPv6(src=client.ip6, dst=nat_addr_ip6) /
7339 ICMPv6DestUnreach(code=1) /
7340 packet[IPv6] for packet in capture]
7341 self.pg0.add_stream(pkts)
7342 self.pg_enable_capture(self.pg_interfaces)
7343 self.pg_start()
7344 capture = self.pg0.get_capture(len(pkts))
7345 for packet in capture:
7346 try:
7347 self.assertEqual(packet[IPv6].src, nat_addr_ip6)
7348 self.assertEqual(packet[IPv6].dst, server.ip6)
7349 icmp = packet[ICMPv6DestUnreach]
7350 self.assertEqual(icmp.code, 1)
7351 inner = icmp[IPerror6]
7352 self.assertEqual(inner.src, server.ip6)
7353 self.assertEqual(inner.dst, nat_addr_ip6)
Klement Sekerad81ae412018-05-16 10:52:54 +02007354 self.assert_packet_checksums_valid(packet)
Matus Fabian029f3d22017-06-15 02:28:50 -07007355 if inner.haslayer(TCPerror):
7356 self.assertEqual(inner[TCPerror].sport, server_tcp_in_port)
7357 self.assertEqual(inner[TCPerror].dport,
7358 client_tcp_out_port)
7359 else:
7360 self.assertEqual(inner[UDPerror].sport, server_udp_in_port)
7361 self.assertEqual(inner[UDPerror].dport,
7362 client_udp_out_port)
7363 except:
7364 self.logger.error(ppp("Unexpected or invalid packet:", packet))
7365 raise
7366
Matus Fabian428dc912017-06-21 06:15:18 -07007367 def test_prefix(self):
7368 """ NAT64 Network-Specific Prefix """
7369
7370 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
7371 self.nat_addr_n)
7372 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
7373 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
7374 self.vapi.nat64_add_del_pool_addr_range(self.vrf1_nat_addr_n,
7375 self.vrf1_nat_addr_n,
7376 vrf_id=self.vrf1_id)
7377 self.vapi.nat64_add_del_interface(self.pg2.sw_if_index)
7378
7379 # Add global prefix
7380 global_pref64 = "2001:db8::"
7381 global_pref64_n = socket.inet_pton(socket.AF_INET6, global_pref64)
7382 global_pref64_len = 32
7383 self.vapi.nat64_add_del_prefix(global_pref64_n, global_pref64_len)
7384
7385 prefix = self.vapi.nat64_prefix_dump()
7386 self.assertEqual(len(prefix), 1)
7387 self.assertEqual(prefix[0].prefix, global_pref64_n)
7388 self.assertEqual(prefix[0].prefix_len, global_pref64_len)
7389 self.assertEqual(prefix[0].vrf_id, 0)
7390
7391 # Add tenant specific prefix
7392 vrf1_pref64 = "2001:db8:122:300::"
7393 vrf1_pref64_n = socket.inet_pton(socket.AF_INET6, vrf1_pref64)
7394 vrf1_pref64_len = 56
7395 self.vapi.nat64_add_del_prefix(vrf1_pref64_n,
7396 vrf1_pref64_len,
7397 vrf_id=self.vrf1_id)
7398 prefix = self.vapi.nat64_prefix_dump()
7399 self.assertEqual(len(prefix), 2)
7400
7401 # Global prefix
7402 pkts = self.create_stream_in_ip6(self.pg0,
7403 self.pg1,
7404 pref=global_pref64,
7405 plen=global_pref64_len)
7406 self.pg0.add_stream(pkts)
7407 self.pg_enable_capture(self.pg_interfaces)
7408 self.pg_start()
7409 capture = self.pg1.get_capture(len(pkts))
7410 self.verify_capture_out(capture, nat_ip=self.nat_addr,
7411 dst_ip=self.pg1.remote_ip4)
7412
7413 pkts = self.create_stream_out(self.pg1, dst_ip=self.nat_addr)
7414 self.pg1.add_stream(pkts)
7415 self.pg_enable_capture(self.pg_interfaces)
7416 self.pg_start()
7417 capture = self.pg0.get_capture(len(pkts))
7418 dst_ip = self.compose_ip6(self.pg1.remote_ip4,
7419 global_pref64,
7420 global_pref64_len)
7421 self.verify_capture_in_ip6(capture, dst_ip, self.pg0.remote_ip6)
7422
7423 # Tenant specific prefix
7424 pkts = self.create_stream_in_ip6(self.pg2,
7425 self.pg1,
7426 pref=vrf1_pref64,
7427 plen=vrf1_pref64_len)
7428 self.pg2.add_stream(pkts)
7429 self.pg_enable_capture(self.pg_interfaces)
7430 self.pg_start()
7431 capture = self.pg1.get_capture(len(pkts))
7432 self.verify_capture_out(capture, nat_ip=self.vrf1_nat_addr,
7433 dst_ip=self.pg1.remote_ip4)
7434
7435 pkts = self.create_stream_out(self.pg1, dst_ip=self.vrf1_nat_addr)
7436 self.pg1.add_stream(pkts)
7437 self.pg_enable_capture(self.pg_interfaces)
7438 self.pg_start()
7439 capture = self.pg2.get_capture(len(pkts))
7440 dst_ip = self.compose_ip6(self.pg1.remote_ip4,
7441 vrf1_pref64,
7442 vrf1_pref64_len)
7443 self.verify_capture_in_ip6(capture, dst_ip, self.pg2.remote_ip6)
7444
Matus Fabianf8cd5812017-07-11 03:55:02 -07007445 def test_unknown_proto(self):
Matus Fabian7968e6c2017-07-06 05:37:49 -07007446 """ NAT64 translate packet with unknown protocol """
7447
7448 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
7449 self.nat_addr_n)
7450 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
7451 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
7452 remote_ip6 = self.compose_ip6(self.pg1.remote_ip4, '64:ff9b::', 96)
7453
7454 # in2out
7455 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
7456 IPv6(src=self.pg0.remote_ip6, dst=remote_ip6) /
7457 TCP(sport=self.tcp_port_in, dport=20))
7458 self.pg0.add_stream(p)
7459 self.pg_enable_capture(self.pg_interfaces)
7460 self.pg_start()
7461 p = self.pg1.get_capture(1)
7462
7463 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
Matus Fabianf8cd5812017-07-11 03:55:02 -07007464 IPv6(src=self.pg0.remote_ip6, dst=remote_ip6, nh=47) /
Matus Fabian7968e6c2017-07-06 05:37:49 -07007465 GRE() /
7466 IP(src=self.pg2.local_ip4, dst=self.pg2.remote_ip4) /
7467 TCP(sport=1234, dport=1234))
7468 self.pg0.add_stream(p)
7469 self.pg_enable_capture(self.pg_interfaces)
7470 self.pg_start()
7471 p = self.pg1.get_capture(1)
7472 packet = p[0]
7473 try:
7474 self.assertEqual(packet[IP].src, self.nat_addr)
7475 self.assertEqual(packet[IP].dst, self.pg1.remote_ip4)
Paul Vinciguerra978aa642018-11-24 22:19:12 -08007476 self.assertEqual(packet.haslayer(GRE), 1)
Klement Sekerad81ae412018-05-16 10:52:54 +02007477 self.assert_packet_checksums_valid(packet)
Matus Fabian7968e6c2017-07-06 05:37:49 -07007478 except:
7479 self.logger.error(ppp("Unexpected or invalid packet:", packet))
7480 raise
7481
7482 # out2in
7483 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
7484 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
7485 GRE() /
7486 IP(src=self.pg2.remote_ip4, dst=self.pg2.local_ip4) /
7487 TCP(sport=1234, dport=1234))
7488 self.pg1.add_stream(p)
7489 self.pg_enable_capture(self.pg_interfaces)
7490 self.pg_start()
7491 p = self.pg0.get_capture(1)
7492 packet = p[0]
7493 try:
7494 self.assertEqual(packet[IPv6].src, remote_ip6)
Matus Fabianf8cd5812017-07-11 03:55:02 -07007495 self.assertEqual(packet[IPv6].dst, self.pg0.remote_ip6)
7496 self.assertEqual(packet[IPv6].nh, 47)
Matus Fabian7968e6c2017-07-06 05:37:49 -07007497 except:
7498 self.logger.error(ppp("Unexpected or invalid packet:", packet))
7499 raise
7500
Matus Fabianf8cd5812017-07-11 03:55:02 -07007501 def test_hairpinning_unknown_proto(self):
Matus Fabian7968e6c2017-07-06 05:37:49 -07007502 """ NAT64 translate packet with unknown protocol - hairpinning """
7503
7504 client = self.pg0.remote_hosts[0]
7505 server = self.pg0.remote_hosts[1]
7506 server_tcp_in_port = 22
7507 server_tcp_out_port = 4022
7508 client_tcp_in_port = 1234
Matus Fabianf8cd5812017-07-11 03:55:02 -07007509 client_tcp_out_port = 1235
7510 server_nat_ip = "10.0.0.100"
7511 client_nat_ip = "10.0.0.110"
7512 server_nat_ip_n = socket.inet_pton(socket.AF_INET, server_nat_ip)
7513 client_nat_ip_n = socket.inet_pton(socket.AF_INET, client_nat_ip)
7514 server_nat_ip6 = self.compose_ip6(server_nat_ip, '64:ff9b::', 96)
7515 client_nat_ip6 = self.compose_ip6(client_nat_ip, '64:ff9b::', 96)
Matus Fabian7968e6c2017-07-06 05:37:49 -07007516
Matus Fabianf8cd5812017-07-11 03:55:02 -07007517 self.vapi.nat64_add_del_pool_addr_range(server_nat_ip_n,
7518 client_nat_ip_n)
Matus Fabian7968e6c2017-07-06 05:37:49 -07007519 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
7520 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
7521
7522 self.vapi.nat64_add_del_static_bib(server.ip6n,
Matus Fabianf8cd5812017-07-11 03:55:02 -07007523 server_nat_ip_n,
Matus Fabian7968e6c2017-07-06 05:37:49 -07007524 server_tcp_in_port,
7525 server_tcp_out_port,
7526 IP_PROTOS.tcp)
7527
Matus Fabianf8cd5812017-07-11 03:55:02 -07007528 self.vapi.nat64_add_del_static_bib(server.ip6n,
7529 server_nat_ip_n,
7530 0,
7531 0,
7532 IP_PROTOS.gre)
7533
7534 self.vapi.nat64_add_del_static_bib(client.ip6n,
7535 client_nat_ip_n,
7536 client_tcp_in_port,
7537 client_tcp_out_port,
7538 IP_PROTOS.tcp)
7539
Matus Fabian7968e6c2017-07-06 05:37:49 -07007540 # client to server
7541 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
Matus Fabianf8cd5812017-07-11 03:55:02 -07007542 IPv6(src=client.ip6, dst=server_nat_ip6) /
Matus Fabian7968e6c2017-07-06 05:37:49 -07007543 TCP(sport=client_tcp_in_port, dport=server_tcp_out_port))
7544 self.pg0.add_stream(p)
7545 self.pg_enable_capture(self.pg_interfaces)
7546 self.pg_start()
7547 p = self.pg0.get_capture(1)
7548
7549 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
Matus Fabianf8cd5812017-07-11 03:55:02 -07007550 IPv6(src=client.ip6, dst=server_nat_ip6, nh=IP_PROTOS.gre) /
Matus Fabian7968e6c2017-07-06 05:37:49 -07007551 GRE() /
7552 IP(src=self.pg2.local_ip4, dst=self.pg2.remote_ip4) /
7553 TCP(sport=1234, dport=1234))
7554 self.pg0.add_stream(p)
7555 self.pg_enable_capture(self.pg_interfaces)
7556 self.pg_start()
7557 p = self.pg0.get_capture(1)
7558 packet = p[0]
7559 try:
Matus Fabianf8cd5812017-07-11 03:55:02 -07007560 self.assertEqual(packet[IPv6].src, client_nat_ip6)
Matus Fabian7968e6c2017-07-06 05:37:49 -07007561 self.assertEqual(packet[IPv6].dst, server.ip6)
Matus Fabianf8cd5812017-07-11 03:55:02 -07007562 self.assertEqual(packet[IPv6].nh, IP_PROTOS.gre)
Matus Fabian7968e6c2017-07-06 05:37:49 -07007563 except:
7564 self.logger.error(ppp("Unexpected or invalid packet:", packet))
7565 raise
7566
7567 # server to client
7568 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
Matus Fabianf8cd5812017-07-11 03:55:02 -07007569 IPv6(src=server.ip6, dst=client_nat_ip6, nh=IP_PROTOS.gre) /
Matus Fabian7968e6c2017-07-06 05:37:49 -07007570 GRE() /
7571 IP(src=self.pg2.remote_ip4, dst=self.pg2.local_ip4) /
7572 TCP(sport=1234, dport=1234))
7573 self.pg0.add_stream(p)
7574 self.pg_enable_capture(self.pg_interfaces)
7575 self.pg_start()
7576 p = self.pg0.get_capture(1)
7577 packet = p[0]
7578 try:
Matus Fabianf8cd5812017-07-11 03:55:02 -07007579 self.assertEqual(packet[IPv6].src, server_nat_ip6)
Matus Fabian7968e6c2017-07-06 05:37:49 -07007580 self.assertEqual(packet[IPv6].dst, client.ip6)
Matus Fabianf8cd5812017-07-11 03:55:02 -07007581 self.assertEqual(packet[IPv6].nh, IP_PROTOS.gre)
Matus Fabian7968e6c2017-07-06 05:37:49 -07007582 except:
7583 self.logger.error(ppp("Unexpected or invalid packet:", packet))
7584 raise
7585
Matus Fabian36ea2d62017-10-24 04:13:49 -07007586 def test_one_armed_nat64(self):
7587 """ One armed NAT64 """
7588 external_port = 0
7589 remote_host_ip6 = self.compose_ip6(self.pg3.remote_ip4,
7590 '64:ff9b::',
7591 96)
7592
7593 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
7594 self.nat_addr_n)
7595 self.vapi.nat64_add_del_interface(self.pg3.sw_if_index)
7596 self.vapi.nat64_add_del_interface(self.pg3.sw_if_index, is_inside=0)
7597
7598 # in2out
7599 p = (Ether(src=self.pg3.remote_mac, dst=self.pg3.local_mac) /
7600 IPv6(src=self.pg3.remote_ip6, dst=remote_host_ip6) /
7601 TCP(sport=12345, dport=80))
7602 self.pg3.add_stream(p)
7603 self.pg_enable_capture(self.pg_interfaces)
7604 self.pg_start()
7605 capture = self.pg3.get_capture(1)
7606 p = capture[0]
7607 try:
7608 ip = p[IP]
7609 tcp = p[TCP]
7610 self.assertEqual(ip.src, self.nat_addr)
7611 self.assertEqual(ip.dst, self.pg3.remote_ip4)
7612 self.assertNotEqual(tcp.sport, 12345)
7613 external_port = tcp.sport
7614 self.assertEqual(tcp.dport, 80)
Klement Sekerad81ae412018-05-16 10:52:54 +02007615 self.assert_packet_checksums_valid(p)
Matus Fabian36ea2d62017-10-24 04:13:49 -07007616 except:
7617 self.logger.error(ppp("Unexpected or invalid packet:", p))
7618 raise
7619
7620 # out2in
7621 p = (Ether(src=self.pg3.remote_mac, dst=self.pg3.local_mac) /
7622 IP(src=self.pg3.remote_ip4, dst=self.nat_addr) /
7623 TCP(sport=80, dport=external_port))
7624 self.pg3.add_stream(p)
7625 self.pg_enable_capture(self.pg_interfaces)
7626 self.pg_start()
7627 capture = self.pg3.get_capture(1)
7628 p = capture[0]
7629 try:
7630 ip = p[IPv6]
7631 tcp = p[TCP]
7632 self.assertEqual(ip.src, remote_host_ip6)
7633 self.assertEqual(ip.dst, self.pg3.remote_ip6)
7634 self.assertEqual(tcp.sport, 80)
7635 self.assertEqual(tcp.dport, 12345)
Klement Sekerad81ae412018-05-16 10:52:54 +02007636 self.assert_packet_checksums_valid(p)
Matus Fabian36ea2d62017-10-24 04:13:49 -07007637 except:
7638 self.logger.error(ppp("Unexpected or invalid packet:", p))
7639 raise
7640
Matus Fabianefcd1e92017-08-15 06:59:19 -07007641 def test_frag_in_order(self):
7642 """ NAT64 translate fragments arriving in order """
7643 self.tcp_port_in = random.randint(1025, 65535)
7644
7645 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
7646 self.nat_addr_n)
7647 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
7648 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
7649
7650 reass = self.vapi.nat_reass_dump()
7651 reass_n_start = len(reass)
7652
7653 # in2out
7654 data = 'a' * 200
7655 pkts = self.create_stream_frag_ip6(self.pg0, self.pg1.remote_ip4,
7656 self.tcp_port_in, 20, data)
7657 self.pg0.add_stream(pkts)
7658 self.pg_enable_capture(self.pg_interfaces)
7659 self.pg_start()
7660 frags = self.pg1.get_capture(len(pkts))
7661 p = self.reass_frags_and_verify(frags,
7662 self.nat_addr,
7663 self.pg1.remote_ip4)
7664 self.assertEqual(p[TCP].dport, 20)
7665 self.assertNotEqual(p[TCP].sport, self.tcp_port_in)
7666 self.tcp_port_out = p[TCP].sport
7667 self.assertEqual(data, p[Raw].load)
7668
7669 # out2in
7670 data = "A" * 4 + "b" * 16 + "C" * 3
7671 pkts = self.create_stream_frag(self.pg1,
7672 self.nat_addr,
7673 20,
7674 self.tcp_port_out,
7675 data)
7676 self.pg1.add_stream(pkts)
7677 self.pg_enable_capture(self.pg_interfaces)
7678 self.pg_start()
7679 frags = self.pg0.get_capture(len(pkts))
7680 src = self.compose_ip6(self.pg1.remote_ip4, '64:ff9b::', 96)
7681 p = self.reass_frags_and_verify_ip6(frags, src, self.pg0.remote_ip6)
7682 self.assertEqual(p[TCP].sport, 20)
7683 self.assertEqual(p[TCP].dport, self.tcp_port_in)
7684 self.assertEqual(data, p[Raw].load)
7685
7686 reass = self.vapi.nat_reass_dump()
7687 reass_n_end = len(reass)
7688
7689 self.assertEqual(reass_n_end - reass_n_start, 2)
7690
7691 def test_reass_hairpinning(self):
7692 """ NAT64 fragments hairpinning """
7693 data = 'a' * 200
Matus Fabianefcd1e92017-08-15 06:59:19 -07007694 server = self.pg0.remote_hosts[1]
7695 server_in_port = random.randint(1025, 65535)
7696 server_out_port = random.randint(1025, 65535)
7697 client_in_port = random.randint(1025, 65535)
7698 ip = IPv6(src=''.join(['64:ff9b::', self.nat_addr]))
7699 nat_addr_ip6 = ip.src
7700
7701 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
7702 self.nat_addr_n)
7703 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
7704 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
7705
7706 # add static BIB entry for server
7707 self.vapi.nat64_add_del_static_bib(server.ip6n,
7708 self.nat_addr_n,
7709 server_in_port,
7710 server_out_port,
7711 IP_PROTOS.tcp)
7712
7713 # send packet from host to server
7714 pkts = self.create_stream_frag_ip6(self.pg0,
7715 self.nat_addr,
7716 client_in_port,
7717 server_out_port,
7718 data)
7719 self.pg0.add_stream(pkts)
7720 self.pg_enable_capture(self.pg_interfaces)
7721 self.pg_start()
7722 frags = self.pg0.get_capture(len(pkts))
7723 p = self.reass_frags_and_verify_ip6(frags, nat_addr_ip6, server.ip6)
7724 self.assertNotEqual(p[TCP].sport, client_in_port)
7725 self.assertEqual(p[TCP].dport, server_in_port)
7726 self.assertEqual(data, p[Raw].load)
7727
7728 def test_frag_out_of_order(self):
7729 """ NAT64 translate fragments arriving out of order """
7730 self.tcp_port_in = random.randint(1025, 65535)
7731
7732 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
7733 self.nat_addr_n)
7734 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
7735 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
7736
7737 # in2out
7738 data = 'a' * 200
7739 pkts = self.create_stream_frag_ip6(self.pg0, self.pg1.remote_ip4,
7740 self.tcp_port_in, 20, data)
7741 pkts.reverse()
7742 self.pg0.add_stream(pkts)
7743 self.pg_enable_capture(self.pg_interfaces)
7744 self.pg_start()
7745 frags = self.pg1.get_capture(len(pkts))
7746 p = self.reass_frags_and_verify(frags,
7747 self.nat_addr,
7748 self.pg1.remote_ip4)
7749 self.assertEqual(p[TCP].dport, 20)
7750 self.assertNotEqual(p[TCP].sport, self.tcp_port_in)
7751 self.tcp_port_out = p[TCP].sport
7752 self.assertEqual(data, p[Raw].load)
7753
7754 # out2in
7755 data = "A" * 4 + "B" * 16 + "C" * 3
7756 pkts = self.create_stream_frag(self.pg1,
7757 self.nat_addr,
7758 20,
7759 self.tcp_port_out,
7760 data)
7761 pkts.reverse()
7762 self.pg1.add_stream(pkts)
7763 self.pg_enable_capture(self.pg_interfaces)
7764 self.pg_start()
7765 frags = self.pg0.get_capture(len(pkts))
7766 src = self.compose_ip6(self.pg1.remote_ip4, '64:ff9b::', 96)
7767 p = self.reass_frags_and_verify_ip6(frags, src, self.pg0.remote_ip6)
7768 self.assertEqual(p[TCP].sport, 20)
7769 self.assertEqual(p[TCP].dport, self.tcp_port_in)
7770 self.assertEqual(data, p[Raw].load)
7771
Matus Fabian0938dcf2017-11-08 01:59:38 -08007772 def test_interface_addr(self):
7773 """ Acquire NAT64 pool addresses from interface """
7774 self.vapi.nat64_add_interface_addr(self.pg4.sw_if_index)
7775
7776 # no address in NAT64 pool
7777 adresses = self.vapi.nat44_address_dump()
7778 self.assertEqual(0, len(adresses))
7779
7780 # configure interface address and check NAT64 address pool
7781 self.pg4.config_ip4()
7782 addresses = self.vapi.nat64_pool_addr_dump()
7783 self.assertEqual(len(addresses), 1)
7784 self.assertEqual(addresses[0].address, self.pg4.local_ip4n)
7785
7786 # remove interface address and check NAT64 address pool
7787 self.pg4.unconfig_ip4()
7788 addresses = self.vapi.nat64_pool_addr_dump()
7789 self.assertEqual(0, len(adresses))
7790
Paul Vinciguerradefde0f2018-12-06 07:46:13 -08007791 @unittest.skipUnless(running_extended_tests, "part of extended tests")
Matus Fabiana431ad12018-01-04 04:03:14 -08007792 def test_ipfix_max_bibs_sessions(self):
7793 """ IPFIX logging maximum session and BIB entries exceeded """
7794 max_bibs = 1280
7795 max_sessions = 2560
7796 remote_host_ip6 = self.compose_ip6(self.pg1.remote_ip4,
7797 '64:ff9b::',
7798 96)
7799
7800 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
7801 self.nat_addr_n)
7802 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
7803 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
7804
7805 pkts = []
7806 src = ""
7807 for i in range(0, max_bibs):
7808 src = "fd01:aa::%x" % (i)
7809 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
7810 IPv6(src=src, dst=remote_host_ip6) /
7811 TCP(sport=12345, dport=80))
7812 pkts.append(p)
7813 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
7814 IPv6(src=src, dst=remote_host_ip6) /
7815 TCP(sport=12345, dport=22))
7816 pkts.append(p)
7817 self.pg0.add_stream(pkts)
7818 self.pg_enable_capture(self.pg_interfaces)
7819 self.pg_start()
7820 self.pg1.get_capture(max_sessions)
7821
7822 self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4n,
7823 src_address=self.pg3.local_ip4n,
7824 path_mtu=512,
7825 template_interval=10)
7826 self.vapi.nat_ipfix(domain_id=self.ipfix_domain_id,
7827 src_port=self.ipfix_src_port)
7828
7829 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
7830 IPv6(src=src, dst=remote_host_ip6) /
7831 TCP(sport=12345, dport=25))
7832 self.pg0.add_stream(p)
7833 self.pg_enable_capture(self.pg_interfaces)
7834 self.pg_start()
Matus Fabian229c1aa2018-05-28 04:09:52 -07007835 self.pg1.assert_nothing_captured()
7836 sleep(1)
Matus Fabiana431ad12018-01-04 04:03:14 -08007837 self.vapi.cli("ipfix flush") # FIXME this should be an API call
7838 capture = self.pg3.get_capture(9)
7839 ipfix = IPFIXDecoder()
7840 # first load template
7841 for p in capture:
7842 self.assertTrue(p.haslayer(IPFIX))
7843 self.assertEqual(p[IP].src, self.pg3.local_ip4)
7844 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
7845 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
7846 self.assertEqual(p[UDP].dport, 4739)
7847 self.assertEqual(p[IPFIX].observationDomainID,
7848 self.ipfix_domain_id)
7849 if p.haslayer(Template):
7850 ipfix.add_template(p.getlayer(Template))
7851 # verify events in data set
7852 for p in capture:
7853 if p.haslayer(Data):
7854 data = ipfix.decode_data_set(p.getlayer(Set))
7855 self.verify_ipfix_max_sessions(data, max_sessions)
7856
7857 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
7858 IPv6(src=self.pg0.remote_ip6, dst=remote_host_ip6) /
7859 TCP(sport=12345, dport=80))
7860 self.pg0.add_stream(p)
7861 self.pg_enable_capture(self.pg_interfaces)
7862 self.pg_start()
Matus Fabian229c1aa2018-05-28 04:09:52 -07007863 self.pg1.assert_nothing_captured()
7864 sleep(1)
Matus Fabiana431ad12018-01-04 04:03:14 -08007865 self.vapi.cli("ipfix flush") # FIXME this should be an API call
7866 capture = self.pg3.get_capture(1)
7867 # verify events in data set
7868 for p in capture:
7869 self.assertTrue(p.haslayer(IPFIX))
7870 self.assertEqual(p[IP].src, self.pg3.local_ip4)
7871 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
7872 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
7873 self.assertEqual(p[UDP].dport, 4739)
7874 self.assertEqual(p[IPFIX].observationDomainID,
7875 self.ipfix_domain_id)
7876 if p.haslayer(Data):
7877 data = ipfix.decode_data_set(p.getlayer(Set))
7878 self.verify_ipfix_max_bibs(data, max_bibs)
7879
7880 def test_ipfix_max_frags(self):
7881 """ IPFIX logging maximum fragments pending reassembly exceeded """
7882 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
7883 self.nat_addr_n)
7884 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
7885 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
Matus Fabiana7f8b222018-09-05 06:01:55 -07007886 self.vapi.nat_set_reass(max_frag=1, is_ip6=1)
Matus Fabiana431ad12018-01-04 04:03:14 -08007887 self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4n,
7888 src_address=self.pg3.local_ip4n,
7889 path_mtu=512,
7890 template_interval=10)
7891 self.vapi.nat_ipfix(domain_id=self.ipfix_domain_id,
7892 src_port=self.ipfix_src_port)
7893
7894 data = 'a' * 200
7895 pkts = self.create_stream_frag_ip6(self.pg0, self.pg1.remote_ip4,
7896 self.tcp_port_in, 20, data)
Matus Fabiana7f8b222018-09-05 06:01:55 -07007897 pkts.reverse()
7898 self.pg0.add_stream(pkts)
Matus Fabiana431ad12018-01-04 04:03:14 -08007899 self.pg_enable_capture(self.pg_interfaces)
7900 self.pg_start()
Matus Fabian229c1aa2018-05-28 04:09:52 -07007901 self.pg1.assert_nothing_captured()
7902 sleep(1)
Matus Fabiana431ad12018-01-04 04:03:14 -08007903 self.vapi.cli("ipfix flush") # FIXME this should be an API call
7904 capture = self.pg3.get_capture(9)
7905 ipfix = IPFIXDecoder()
7906 # first load template
7907 for p in capture:
7908 self.assertTrue(p.haslayer(IPFIX))
7909 self.assertEqual(p[IP].src, self.pg3.local_ip4)
7910 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
7911 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
7912 self.assertEqual(p[UDP].dport, 4739)
7913 self.assertEqual(p[IPFIX].observationDomainID,
7914 self.ipfix_domain_id)
7915 if p.haslayer(Template):
7916 ipfix.add_template(p.getlayer(Template))
7917 # verify events in data set
7918 for p in capture:
7919 if p.haslayer(Data):
7920 data = ipfix.decode_data_set(p.getlayer(Set))
Matus Fabiana7f8b222018-09-05 06:01:55 -07007921 self.verify_ipfix_max_fragments_ip6(data, 1,
Matus Fabiana431ad12018-01-04 04:03:14 -08007922 self.pg0.remote_ip6n)
7923
7924 def test_ipfix_bib_ses(self):
7925 """ IPFIX logging NAT64 BIB/session create and delete events """
7926 self.tcp_port_in = random.randint(1025, 65535)
7927 remote_host_ip6 = self.compose_ip6(self.pg1.remote_ip4,
7928 '64:ff9b::',
7929 96)
7930
7931 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
7932 self.nat_addr_n)
7933 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
7934 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
7935 self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4n,
7936 src_address=self.pg3.local_ip4n,
7937 path_mtu=512,
7938 template_interval=10)
7939 self.vapi.nat_ipfix(domain_id=self.ipfix_domain_id,
7940 src_port=self.ipfix_src_port)
7941
7942 # Create
7943 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
7944 IPv6(src=self.pg0.remote_ip6, dst=remote_host_ip6) /
7945 TCP(sport=self.tcp_port_in, dport=25))
7946 self.pg0.add_stream(p)
7947 self.pg_enable_capture(self.pg_interfaces)
7948 self.pg_start()
7949 p = self.pg1.get_capture(1)
7950 self.tcp_port_out = p[0][TCP].sport
7951 self.vapi.cli("ipfix flush") # FIXME this should be an API call
7952 capture = self.pg3.get_capture(10)
7953 ipfix = IPFIXDecoder()
7954 # first load template
7955 for p in capture:
7956 self.assertTrue(p.haslayer(IPFIX))
7957 self.assertEqual(p[IP].src, self.pg3.local_ip4)
7958 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
7959 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
7960 self.assertEqual(p[UDP].dport, 4739)
7961 self.assertEqual(p[IPFIX].observationDomainID,
7962 self.ipfix_domain_id)
7963 if p.haslayer(Template):
7964 ipfix.add_template(p.getlayer(Template))
7965 # verify events in data set
7966 for p in capture:
7967 if p.haslayer(Data):
7968 data = ipfix.decode_data_set(p.getlayer(Set))
7969 if ord(data[0][230]) == 10:
7970 self.verify_ipfix_bib(data, 1, self.pg0.remote_ip6n)
7971 elif ord(data[0][230]) == 6:
7972 self.verify_ipfix_nat64_ses(data,
7973 1,
7974 self.pg0.remote_ip6n,
7975 self.pg1.remote_ip4,
7976 25)
7977 else:
7978 self.logger.error(ppp("Unexpected or invalid packet: ", p))
7979
7980 # Delete
7981 self.pg_enable_capture(self.pg_interfaces)
7982 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
7983 self.nat_addr_n,
7984 is_add=0)
7985 self.vapi.cli("ipfix flush") # FIXME this should be an API call
7986 capture = self.pg3.get_capture(2)
7987 # verify events in data set
7988 for p in capture:
7989 self.assertTrue(p.haslayer(IPFIX))
7990 self.assertEqual(p[IP].src, self.pg3.local_ip4)
7991 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
7992 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
7993 self.assertEqual(p[UDP].dport, 4739)
7994 self.assertEqual(p[IPFIX].observationDomainID,
7995 self.ipfix_domain_id)
7996 if p.haslayer(Data):
7997 data = ipfix.decode_data_set(p.getlayer(Set))
7998 if ord(data[0][230]) == 11:
7999 self.verify_ipfix_bib(data, 0, self.pg0.remote_ip6n)
8000 elif ord(data[0][230]) == 7:
8001 self.verify_ipfix_nat64_ses(data,
8002 0,
8003 self.pg0.remote_ip6n,
8004 self.pg1.remote_ip4,
8005 25)
8006 else:
8007 self.logger.error(ppp("Unexpected or invalid packet: ", p))
8008
Matus Fabianad1f3e12018-11-28 21:26:34 -08008009 def test_syslog_sess(self):
8010 """ Test syslog session creation and deletion """
8011 self.tcp_port_in = random.randint(1025, 65535)
8012 remote_host_ip6 = self.compose_ip6(self.pg1.remote_ip4,
8013 '64:ff9b::',
8014 96)
8015
8016 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
8017 self.nat_addr_n)
8018 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
8019 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
8020 self.vapi.syslog_set_filter(SYSLOG_SEVERITY.INFO)
8021 self.vapi.syslog_set_sender(self.pg3.remote_ip4n, self.pg3.local_ip4n)
8022
8023 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
8024 IPv6(src=self.pg0.remote_ip6, dst=remote_host_ip6) /
8025 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port))
8026 self.pg0.add_stream(p)
8027 self.pg_enable_capture(self.pg_interfaces)
8028 self.pg_start()
8029 p = self.pg1.get_capture(1)
8030 self.tcp_port_out = p[0][TCP].sport
8031 capture = self.pg3.get_capture(1)
8032 self.verify_syslog_sess(capture[0][Raw].load, is_ip6=True)
8033
8034 self.pg_enable_capture(self.pg_interfaces)
8035 self.pg_start()
8036 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
8037 self.nat_addr_n,
8038 is_add=0)
8039 capture = self.pg3.get_capture(1)
8040 self.verify_syslog_sess(capture[0][Raw].load, False, True)
8041
Matus Fabian06596c52017-06-06 04:53:28 -07008042 def nat64_get_ses_num(self):
8043 """
8044 Return number of active NAT64 sessions.
8045 """
Matus Fabianab9a59c2017-08-16 05:37:36 -07008046 st = self.vapi.nat64_st_dump()
8047 return len(st)
Matus Fabian06596c52017-06-06 04:53:28 -07008048
8049 def clear_nat64(self):
8050 """
8051 Clear NAT64 configuration.
8052 """
Matus Fabiana431ad12018-01-04 04:03:14 -08008053 self.vapi.nat_ipfix(enable=0, src_port=self.ipfix_src_port,
8054 domain_id=self.ipfix_domain_id)
8055 self.ipfix_src_port = 4739
8056 self.ipfix_domain_id = 1
8057
Matus Fabianad1f3e12018-11-28 21:26:34 -08008058 self.vapi.syslog_set_filter(SYSLOG_SEVERITY.EMERG)
8059
Matus Fabian878c6462018-08-23 00:33:35 -07008060 self.vapi.nat_set_timeouts()
Matus Fabian06596c52017-06-06 04:53:28 -07008061
8062 interfaces = self.vapi.nat64_interface_dump()
8063 for intf in interfaces:
Matus Fabian36ea2d62017-10-24 04:13:49 -07008064 if intf.is_inside > 1:
8065 self.vapi.nat64_add_del_interface(intf.sw_if_index,
8066 0,
8067 is_add=0)
Matus Fabian06596c52017-06-06 04:53:28 -07008068 self.vapi.nat64_add_del_interface(intf.sw_if_index,
8069 intf.is_inside,
8070 is_add=0)
8071
Matus Fabiana431ad12018-01-04 04:03:14 -08008072 bib = self.vapi.nat64_bib_dump(255)
Matus Fabian06596c52017-06-06 04:53:28 -07008073 for bibe in bib:
8074 if bibe.is_static:
8075 self.vapi.nat64_add_del_static_bib(bibe.i_addr,
8076 bibe.o_addr,
8077 bibe.i_port,
8078 bibe.o_port,
8079 bibe.proto,
8080 bibe.vrf_id,
8081 is_add=0)
8082
8083 adresses = self.vapi.nat64_pool_addr_dump()
8084 for addr in adresses:
8085 self.vapi.nat64_add_del_pool_addr_range(addr.address,
8086 addr.address,
Matus Fabian029f3d22017-06-15 02:28:50 -07008087 vrf_id=addr.vrf_id,
Matus Fabian06596c52017-06-06 04:53:28 -07008088 is_add=0)
8089
Matus Fabian428dc912017-06-21 06:15:18 -07008090 prefixes = self.vapi.nat64_prefix_dump()
8091 for prefix in prefixes:
8092 self.vapi.nat64_add_del_prefix(prefix.prefix,
8093 prefix.prefix_len,
8094 vrf_id=prefix.vrf_id,
8095 is_add=0)
8096
Matus Fabian06596c52017-06-06 04:53:28 -07008097 def tearDown(self):
8098 super(TestNAT64, self).tearDown()
8099 if not self.vpp_dead:
8100 self.logger.info(self.vapi.cli("show nat64 pool"))
8101 self.logger.info(self.vapi.cli("show nat64 interfaces"))
Matus Fabian428dc912017-06-21 06:15:18 -07008102 self.logger.info(self.vapi.cli("show nat64 prefix"))
Matus Fabianab9a59c2017-08-16 05:37:36 -07008103 self.logger.info(self.vapi.cli("show nat64 bib all"))
8104 self.logger.info(self.vapi.cli("show nat64 session table all"))
Matus Fabianefcd1e92017-08-15 06:59:19 -07008105 self.logger.info(self.vapi.cli("show nat virtual-reassembly"))
Matus Fabian06596c52017-06-06 04:53:28 -07008106 self.clear_nat64()
8107
Matus Fabian8ebe6252017-11-06 05:04:53 -08008108
8109class TestDSlite(MethodHolder):
8110 """ DS-Lite Test Cases """
8111
8112 @classmethod
8113 def setUpClass(cls):
8114 super(TestDSlite, cls).setUpClass()
8115
8116 try:
8117 cls.nat_addr = '10.0.0.3'
8118 cls.nat_addr_n = socket.inet_pton(socket.AF_INET, cls.nat_addr)
8119
Matus Fabianad1f3e12018-11-28 21:26:34 -08008120 cls.create_pg_interfaces(range(3))
Matus Fabian8ebe6252017-11-06 05:04:53 -08008121 cls.pg0.admin_up()
8122 cls.pg0.config_ip4()
8123 cls.pg0.resolve_arp()
8124 cls.pg1.admin_up()
8125 cls.pg1.config_ip6()
8126 cls.pg1.generate_remote_hosts(2)
8127 cls.pg1.configure_ipv6_neighbors()
Matus Fabianad1f3e12018-11-28 21:26:34 -08008128 cls.pg2.admin_up()
8129 cls.pg2.config_ip4()
8130 cls.pg2.resolve_arp()
Matus Fabian8ebe6252017-11-06 05:04:53 -08008131
8132 except Exception:
8133 super(TestDSlite, cls).tearDownClass()
8134 raise
8135
Matus Fabianad1f3e12018-11-28 21:26:34 -08008136 def verify_syslog_apmadd(self, data, isaddr, isport, xsaddr, xsport,
8137 sv6enc, proto):
8138 message = data.decode('utf-8')
8139 try:
8140 message = SyslogMessage.parse(message)
8141 self.assertEqual(message.severity, SyslogSeverity.info)
8142 self.assertEqual(message.appname, 'NAT')
8143 self.assertEqual(message.msgid, 'APMADD')
8144 sd_params = message.sd.get('napmap')
8145 self.assertTrue(sd_params is not None)
8146 self.assertEqual(sd_params.get('IATYP'), 'IPv4')
8147 self.assertEqual(sd_params.get('ISADDR'), isaddr)
8148 self.assertEqual(sd_params.get('ISPORT'), "%d" % isport)
8149 self.assertEqual(sd_params.get('XATYP'), 'IPv4')
8150 self.assertEqual(sd_params.get('XSADDR'), xsaddr)
8151 self.assertEqual(sd_params.get('XSPORT'), "%d" % xsport)
8152 self.assertEqual(sd_params.get('PROTO'), "%d" % proto)
8153 self.assertTrue(sd_params.get('SSUBIX') is not None)
8154 self.assertEqual(sd_params.get('SV6ENC'), sv6enc)
8155 except ParseError as e:
8156 self.logger.error(e)
8157
Matus Fabian8ebe6252017-11-06 05:04:53 -08008158 def test_dslite(self):
8159 """ Test DS-Lite """
Matus Fabian69ce30d2018-08-22 01:27:10 -07008160 nat_config = self.vapi.nat_show_config()
8161 self.assertEqual(0, nat_config.dslite_ce)
8162
Matus Fabian8ebe6252017-11-06 05:04:53 -08008163 self.vapi.dslite_add_del_pool_addr_range(self.nat_addr_n,
8164 self.nat_addr_n)
8165 aftr_ip4 = '192.0.0.1'
8166 aftr_ip4_n = socket.inet_pton(socket.AF_INET, aftr_ip4)
8167 aftr_ip6 = '2001:db8:85a3::8a2e:370:1'
8168 aftr_ip6_n = socket.inet_pton(socket.AF_INET6, aftr_ip6)
8169 self.vapi.dslite_set_aftr_addr(aftr_ip6_n, aftr_ip4_n)
Matus Fabianad1f3e12018-11-28 21:26:34 -08008170 self.vapi.syslog_set_sender(self.pg2.remote_ip4n, self.pg2.local_ip4n)
Matus Fabian8ebe6252017-11-06 05:04:53 -08008171
8172 # UDP
8173 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
8174 IPv6(dst=aftr_ip6, src=self.pg1.remote_hosts[0].ip6) /
8175 IP(dst=self.pg0.remote_ip4, src='192.168.1.1') /
8176 UDP(sport=20000, dport=10000))
8177 self.pg1.add_stream(p)
8178 self.pg_enable_capture(self.pg_interfaces)
8179 self.pg_start()
8180 capture = self.pg0.get_capture(1)
8181 capture = capture[0]
8182 self.assertFalse(capture.haslayer(IPv6))
8183 self.assertEqual(capture[IP].src, self.nat_addr)
8184 self.assertEqual(capture[IP].dst, self.pg0.remote_ip4)
8185 self.assertNotEqual(capture[UDP].sport, 20000)
8186 self.assertEqual(capture[UDP].dport, 10000)
Klement Sekerad81ae412018-05-16 10:52:54 +02008187 self.assert_packet_checksums_valid(capture)
Matus Fabian8ebe6252017-11-06 05:04:53 -08008188 out_port = capture[UDP].sport
Matus Fabianad1f3e12018-11-28 21:26:34 -08008189 capture = self.pg2.get_capture(1)
8190 self.verify_syslog_apmadd(capture[0][Raw].load, '192.168.1.1',
8191 20000, self.nat_addr, out_port,
8192 self.pg1.remote_hosts[0].ip6, IP_PROTOS.udp)
Matus Fabian8ebe6252017-11-06 05:04:53 -08008193
8194 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8195 IP(dst=self.nat_addr, src=self.pg0.remote_ip4) /
8196 UDP(sport=10000, dport=out_port))
8197 self.pg0.add_stream(p)
8198 self.pg_enable_capture(self.pg_interfaces)
8199 self.pg_start()
8200 capture = self.pg1.get_capture(1)
8201 capture = capture[0]
8202 self.assertEqual(capture[IPv6].src, aftr_ip6)
8203 self.assertEqual(capture[IPv6].dst, self.pg1.remote_hosts[0].ip6)
8204 self.assertEqual(capture[IP].src, self.pg0.remote_ip4)
8205 self.assertEqual(capture[IP].dst, '192.168.1.1')
8206 self.assertEqual(capture[UDP].sport, 10000)
8207 self.assertEqual(capture[UDP].dport, 20000)
Klement Sekerad81ae412018-05-16 10:52:54 +02008208 self.assert_packet_checksums_valid(capture)
Matus Fabian8ebe6252017-11-06 05:04:53 -08008209
8210 # TCP
8211 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
8212 IPv6(dst=aftr_ip6, src=self.pg1.remote_hosts[1].ip6) /
8213 IP(dst=self.pg0.remote_ip4, src='192.168.1.1') /
8214 TCP(sport=20001, dport=10001))
8215 self.pg1.add_stream(p)
8216 self.pg_enable_capture(self.pg_interfaces)
8217 self.pg_start()
8218 capture = self.pg0.get_capture(1)
8219 capture = capture[0]
8220 self.assertFalse(capture.haslayer(IPv6))
8221 self.assertEqual(capture[IP].src, self.nat_addr)
8222 self.assertEqual(capture[IP].dst, self.pg0.remote_ip4)
8223 self.assertNotEqual(capture[TCP].sport, 20001)
8224 self.assertEqual(capture[TCP].dport, 10001)
Klement Sekerad81ae412018-05-16 10:52:54 +02008225 self.assert_packet_checksums_valid(capture)
Matus Fabian8ebe6252017-11-06 05:04:53 -08008226 out_port = capture[TCP].sport
8227
8228 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8229 IP(dst=self.nat_addr, src=self.pg0.remote_ip4) /
8230 TCP(sport=10001, dport=out_port))
8231 self.pg0.add_stream(p)
8232 self.pg_enable_capture(self.pg_interfaces)
8233 self.pg_start()
8234 capture = self.pg1.get_capture(1)
8235 capture = capture[0]
8236 self.assertEqual(capture[IPv6].src, aftr_ip6)
8237 self.assertEqual(capture[IPv6].dst, self.pg1.remote_hosts[1].ip6)
8238 self.assertEqual(capture[IP].src, self.pg0.remote_ip4)
8239 self.assertEqual(capture[IP].dst, '192.168.1.1')
8240 self.assertEqual(capture[TCP].sport, 10001)
8241 self.assertEqual(capture[TCP].dport, 20001)
Klement Sekerad81ae412018-05-16 10:52:54 +02008242 self.assert_packet_checksums_valid(capture)
Matus Fabian8ebe6252017-11-06 05:04:53 -08008243
8244 # ICMP
8245 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
8246 IPv6(dst=aftr_ip6, src=self.pg1.remote_hosts[1].ip6) /
8247 IP(dst=self.pg0.remote_ip4, src='192.168.1.1') /
8248 ICMP(id=4000, type='echo-request'))
8249 self.pg1.add_stream(p)
8250 self.pg_enable_capture(self.pg_interfaces)
8251 self.pg_start()
8252 capture = self.pg0.get_capture(1)
8253 capture = capture[0]
8254 self.assertFalse(capture.haslayer(IPv6))
8255 self.assertEqual(capture[IP].src, self.nat_addr)
8256 self.assertEqual(capture[IP].dst, self.pg0.remote_ip4)
8257 self.assertNotEqual(capture[ICMP].id, 4000)
Klement Sekerad81ae412018-05-16 10:52:54 +02008258 self.assert_packet_checksums_valid(capture)
Matus Fabian8ebe6252017-11-06 05:04:53 -08008259 out_id = capture[ICMP].id
8260
8261 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8262 IP(dst=self.nat_addr, src=self.pg0.remote_ip4) /
8263 ICMP(id=out_id, type='echo-reply'))
8264 self.pg0.add_stream(p)
8265 self.pg_enable_capture(self.pg_interfaces)
8266 self.pg_start()
8267 capture = self.pg1.get_capture(1)
8268 capture = capture[0]
8269 self.assertEqual(capture[IPv6].src, aftr_ip6)
8270 self.assertEqual(capture[IPv6].dst, self.pg1.remote_hosts[1].ip6)
8271 self.assertEqual(capture[IP].src, self.pg0.remote_ip4)
8272 self.assertEqual(capture[IP].dst, '192.168.1.1')
8273 self.assertEqual(capture[ICMP].id, 4000)
Klement Sekerad81ae412018-05-16 10:52:54 +02008274 self.assert_packet_checksums_valid(capture)
Matus Fabian8ebe6252017-11-06 05:04:53 -08008275
Matus Fabian331acc62017-12-08 03:38:51 -08008276 # ping DS-Lite AFTR tunnel endpoint address
8277 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
8278 IPv6(src=self.pg1.remote_hosts[1].ip6, dst=aftr_ip6) /
8279 ICMPv6EchoRequest())
8280 self.pg1.add_stream(p)
8281 self.pg_enable_capture(self.pg_interfaces)
8282 self.pg_start()
8283 capture = self.pg1.get_capture(1)
Matus Fabian331acc62017-12-08 03:38:51 -08008284 capture = capture[0]
8285 self.assertEqual(capture[IPv6].src, aftr_ip6)
8286 self.assertEqual(capture[IPv6].dst, self.pg1.remote_hosts[1].ip6)
8287 self.assertTrue(capture.haslayer(ICMPv6EchoReply))
8288
Matus Fabian8ebe6252017-11-06 05:04:53 -08008289 def tearDown(self):
8290 super(TestDSlite, self).tearDown()
8291 if not self.vpp_dead:
8292 self.logger.info(self.vapi.cli("show dslite pool"))
8293 self.logger.info(
8294 self.vapi.cli("show dslite aftr-tunnel-endpoint-address"))
8295 self.logger.info(self.vapi.cli("show dslite sessions"))
8296
Juraj Slobodac5c6a332018-01-09 16:08:32 +01008297
8298class TestDSliteCE(MethodHolder):
8299 """ DS-Lite CE Test Cases """
8300
8301 @classmethod
8302 def setUpConstants(cls):
8303 super(TestDSliteCE, cls).setUpConstants()
8304 cls.vpp_cmdline.extend(["nat", "{", "dslite ce", "}"])
8305
8306 @classmethod
8307 def setUpClass(cls):
8308 super(TestDSliteCE, cls).setUpClass()
8309
8310 try:
8311 cls.create_pg_interfaces(range(2))
8312 cls.pg0.admin_up()
8313 cls.pg0.config_ip4()
8314 cls.pg0.resolve_arp()
8315 cls.pg1.admin_up()
8316 cls.pg1.config_ip6()
8317 cls.pg1.generate_remote_hosts(1)
8318 cls.pg1.configure_ipv6_neighbors()
8319
8320 except Exception:
8321 super(TestDSliteCE, cls).tearDownClass()
8322 raise
8323
8324 def test_dslite_ce(self):
8325 """ Test DS-Lite CE """
8326
Matus Fabian69ce30d2018-08-22 01:27:10 -07008327 nat_config = self.vapi.nat_show_config()
8328 self.assertEqual(1, nat_config.dslite_ce)
8329
Juraj Slobodac5c6a332018-01-09 16:08:32 +01008330 b4_ip4 = '192.0.0.2'
8331 b4_ip4_n = socket.inet_pton(socket.AF_INET, b4_ip4)
8332 b4_ip6 = '2001:db8:62aa::375e:f4c1:1'
8333 b4_ip6_n = socket.inet_pton(socket.AF_INET6, b4_ip6)
8334 self.vapi.dslite_set_b4_addr(b4_ip6_n, b4_ip4_n)
8335
8336 aftr_ip4 = '192.0.0.1'
8337 aftr_ip4_n = socket.inet_pton(socket.AF_INET, aftr_ip4)
8338 aftr_ip6 = '2001:db8:85a3::8a2e:370:1'
8339 aftr_ip6_n = socket.inet_pton(socket.AF_INET6, aftr_ip6)
8340 self.vapi.dslite_set_aftr_addr(aftr_ip6_n, aftr_ip4_n)
8341
8342 self.vapi.ip_add_del_route(dst_address=aftr_ip6_n,
8343 dst_address_length=128,
8344 next_hop_address=self.pg1.remote_ip6n,
8345 next_hop_sw_if_index=self.pg1.sw_if_index,
8346 is_ipv6=1)
8347
8348 # UDP encapsulation
8349 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8350 IP(dst=self.pg1.remote_ip4, src=self.pg0.remote_ip4) /
8351 UDP(sport=10000, dport=20000))
8352 self.pg0.add_stream(p)
8353 self.pg_enable_capture(self.pg_interfaces)
8354 self.pg_start()
8355 capture = self.pg1.get_capture(1)
8356 capture = capture[0]
8357 self.assertEqual(capture[IPv6].src, b4_ip6)
8358 self.assertEqual(capture[IPv6].dst, aftr_ip6)
8359 self.assertEqual(capture[IP].src, self.pg0.remote_ip4)
8360 self.assertEqual(capture[IP].dst, self.pg1.remote_ip4)
8361 self.assertEqual(capture[UDP].sport, 10000)
8362 self.assertEqual(capture[UDP].dport, 20000)
Klement Sekerad81ae412018-05-16 10:52:54 +02008363 self.assert_packet_checksums_valid(capture)
Juraj Slobodac5c6a332018-01-09 16:08:32 +01008364
8365 # UDP decapsulation
8366 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
8367 IPv6(dst=b4_ip6, src=aftr_ip6) /
8368 IP(dst=self.pg0.remote_ip4, src=self.pg1.remote_ip4) /
8369 UDP(sport=20000, dport=10000))
8370 self.pg1.add_stream(p)
8371 self.pg_enable_capture(self.pg_interfaces)
8372 self.pg_start()
8373 capture = self.pg0.get_capture(1)
8374 capture = capture[0]
8375 self.assertFalse(capture.haslayer(IPv6))
8376 self.assertEqual(capture[IP].src, self.pg1.remote_ip4)
8377 self.assertEqual(capture[IP].dst, self.pg0.remote_ip4)
8378 self.assertEqual(capture[UDP].sport, 20000)
8379 self.assertEqual(capture[UDP].dport, 10000)
Klement Sekerad81ae412018-05-16 10:52:54 +02008380 self.assert_packet_checksums_valid(capture)
Juraj Slobodac5c6a332018-01-09 16:08:32 +01008381
8382 # ping DS-Lite B4 tunnel endpoint address
8383 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
8384 IPv6(src=self.pg1.remote_hosts[0].ip6, dst=b4_ip6) /
8385 ICMPv6EchoRequest())
8386 self.pg1.add_stream(p)
8387 self.pg_enable_capture(self.pg_interfaces)
8388 self.pg_start()
8389 capture = self.pg1.get_capture(1)
Juraj Slobodac5c6a332018-01-09 16:08:32 +01008390 capture = capture[0]
8391 self.assertEqual(capture[IPv6].src, b4_ip6)
8392 self.assertEqual(capture[IPv6].dst, self.pg1.remote_hosts[0].ip6)
8393 self.assertTrue(capture.haslayer(ICMPv6EchoReply))
8394
8395 def tearDown(self):
8396 super(TestDSliteCE, self).tearDown()
8397 if not self.vpp_dead:
8398 self.logger.info(
8399 self.vapi.cli("show dslite aftr-tunnel-endpoint-address"))
8400 self.logger.info(
8401 self.vapi.cli("show dslite b4-tunnel-endpoint-address"))
8402
Matus Fabianf2a23cc2018-01-22 03:41:53 -08008403
8404class TestNAT66(MethodHolder):
8405 """ NAT66 Test Cases """
8406
8407 @classmethod
8408 def setUpClass(cls):
8409 super(TestNAT66, cls).setUpClass()
8410
8411 try:
8412 cls.nat_addr = 'fd01:ff::2'
8413 cls.nat_addr_n = socket.inet_pton(socket.AF_INET6, cls.nat_addr)
8414
8415 cls.create_pg_interfaces(range(2))
8416 cls.interfaces = list(cls.pg_interfaces)
8417
8418 for i in cls.interfaces:
8419 i.admin_up()
8420 i.config_ip6()
8421 i.configure_ipv6_neighbors()
8422
8423 except Exception:
8424 super(TestNAT66, cls).tearDownClass()
8425 raise
8426
8427 def test_static(self):
8428 """ 1:1 NAT66 test """
8429 self.vapi.nat66_add_del_interface(self.pg0.sw_if_index)
8430 self.vapi.nat66_add_del_interface(self.pg1.sw_if_index, is_inside=0)
8431 self.vapi.nat66_add_del_static_mapping(self.pg0.remote_ip6n,
8432 self.nat_addr_n)
8433
8434 # in2out
8435 pkts = []
8436 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8437 IPv6(src=self.pg0.remote_ip6, dst=self.pg1.remote_ip6) /
8438 TCP())
8439 pkts.append(p)
8440 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8441 IPv6(src=self.pg0.remote_ip6, dst=self.pg1.remote_ip6) /
8442 UDP())
8443 pkts.append(p)
8444 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8445 IPv6(src=self.pg0.remote_ip6, dst=self.pg1.remote_ip6) /
8446 ICMPv6EchoRequest())
8447 pkts.append(p)
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 GRE() / IP() / TCP())
8451 pkts.append(p)
8452 self.pg0.add_stream(pkts)
8453 self.pg_enable_capture(self.pg_interfaces)
8454 self.pg_start()
8455 capture = self.pg1.get_capture(len(pkts))
8456 for packet in capture:
8457 try:
8458 self.assertEqual(packet[IPv6].src, self.nat_addr)
8459 self.assertEqual(packet[IPv6].dst, self.pg1.remote_ip6)
Klement Sekerad81ae412018-05-16 10:52:54 +02008460 self.assert_packet_checksums_valid(packet)
Matus Fabianf2a23cc2018-01-22 03:41:53 -08008461 except:
8462 self.logger.error(ppp("Unexpected or invalid packet:", packet))
8463 raise
8464
8465 # out2in
8466 pkts = []
8467 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
8468 IPv6(src=self.pg1.remote_ip6, dst=self.nat_addr) /
8469 TCP())
8470 pkts.append(p)
8471 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
8472 IPv6(src=self.pg1.remote_ip6, dst=self.nat_addr) /
8473 UDP())
8474 pkts.append(p)
8475 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
8476 IPv6(src=self.pg1.remote_ip6, dst=self.nat_addr) /
8477 ICMPv6EchoReply())
8478 pkts.append(p)
8479 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
8480 IPv6(src=self.pg1.remote_ip6, dst=self.nat_addr) /
8481 GRE() / IP() / TCP())
8482 pkts.append(p)
8483 self.pg1.add_stream(pkts)
8484 self.pg_enable_capture(self.pg_interfaces)
8485 self.pg_start()
8486 capture = self.pg0.get_capture(len(pkts))
8487 for packet in capture:
8488 try:
8489 self.assertEqual(packet[IPv6].src, self.pg1.remote_ip6)
8490 self.assertEqual(packet[IPv6].dst, self.pg0.remote_ip6)
Klement Sekerad81ae412018-05-16 10:52:54 +02008491 self.assert_packet_checksums_valid(packet)
Matus Fabianf2a23cc2018-01-22 03:41:53 -08008492 except:
8493 self.logger.error(ppp("Unexpected or invalid packet:", packet))
8494 raise
8495
8496 sm = self.vapi.nat66_static_mapping_dump()
8497 self.assertEqual(len(sm), 1)
8498 self.assertEqual(sm[0].total_pkts, 8)
8499
Juraj Sloboda9341e342018-04-13 12:00:46 +02008500 def test_check_no_translate(self):
8501 """ NAT66 translate only when egress interface is outside interface """
8502 self.vapi.nat66_add_del_interface(self.pg0.sw_if_index)
8503 self.vapi.nat66_add_del_interface(self.pg1.sw_if_index)
8504 self.vapi.nat66_add_del_static_mapping(self.pg0.remote_ip6n,
8505 self.nat_addr_n)
8506
8507 # in2out
8508 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8509 IPv6(src=self.pg0.remote_ip6, dst=self.pg1.remote_ip6) /
8510 UDP())
8511 self.pg0.add_stream([p])
8512 self.pg_enable_capture(self.pg_interfaces)
8513 self.pg_start()
8514 capture = self.pg1.get_capture(1)
8515 packet = capture[0]
8516 try:
8517 self.assertEqual(packet[IPv6].src, self.pg0.remote_ip6)
8518 self.assertEqual(packet[IPv6].dst, self.pg1.remote_ip6)
8519 except:
8520 self.logger.error(ppp("Unexpected or invalid packet:", packet))
8521 raise
8522
Matus Fabianf2a23cc2018-01-22 03:41:53 -08008523 def clear_nat66(self):
8524 """
8525 Clear NAT66 configuration.
8526 """
8527 interfaces = self.vapi.nat66_interface_dump()
8528 for intf in interfaces:
8529 self.vapi.nat66_add_del_interface(intf.sw_if_index,
8530 intf.is_inside,
8531 is_add=0)
8532
8533 static_mappings = self.vapi.nat66_static_mapping_dump()
8534 for sm in static_mappings:
8535 self.vapi.nat66_add_del_static_mapping(sm.local_ip_address,
8536 sm.external_ip_address,
8537 sm.vrf_id,
8538 is_add=0)
8539
8540 def tearDown(self):
8541 super(TestNAT66, self).tearDown()
8542 if not self.vpp_dead:
8543 self.logger.info(self.vapi.cli("show nat66 interfaces"))
8544 self.logger.info(self.vapi.cli("show nat66 static mappings"))
8545 self.clear_nat66()
8546
Klement Sekerad81ae412018-05-16 10:52:54 +02008547
Matus Fabiande886752016-12-07 03:38:19 -08008548if __name__ == '__main__':
8549 unittest.main(testRunner=VppTestRunner)