blob: c64359a4db743ebf187c4198a12b2e3c80f5433d [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)
Matus Fabianfd0d5082018-12-18 01:08:51 -08001018 users = self.statistics.get_counter('/nat44/total-users')
1019 self.assertEqual(users[0][0], 0)
1020 sessions = self.statistics.get_counter('/nat44/total-sessions')
1021 self.assertEqual(sessions[0][0], 0)
Matus Fabian68ba8802018-08-08 05:52:47 -07001022
Matus Fabian878c6462018-08-23 00:33:35 -07001023 def verify_ipfix_max_entries_per_user(self, data, limit, src_addr):
1024 """
1025 Verify IPFIX maximum entries per user exceeded event
1026
1027 :param data: Decoded IPFIX data records
1028 :param limit: Number of maximum entries per user
1029 :param src_addr: IPv4 source address
1030 """
1031 self.assertEqual(1, len(data))
1032 record = data[0]
1033 # natEvent
1034 self.assertEqual(ord(record[230]), 13)
1035 # natQuotaExceededEvent
1036 self.assertEqual(struct.pack("I", 3), record[466])
1037 # maxEntriesPerUser
1038 self.assertEqual(struct.pack("I", limit), record[473])
1039 # sourceIPv4Address
1040 self.assertEqual(src_addr, record[8])
1041
Matus Fabianad1f3e12018-11-28 21:26:34 -08001042 def verify_syslog_apmap(self, data, is_add=True):
1043 message = data.decode('utf-8')
1044 try:
1045 message = SyslogMessage.parse(message)
1046 self.assertEqual(message.severity, SyslogSeverity.info)
1047 self.assertEqual(message.appname, 'NAT')
1048 self.assertEqual(message.msgid, 'APMADD' if is_add else 'APMDEL')
1049 sd_params = message.sd.get('napmap')
1050 self.assertTrue(sd_params is not None)
1051 self.assertEqual(sd_params.get('IATYP'), 'IPv4')
1052 self.assertEqual(sd_params.get('ISADDR'), self.pg0.remote_ip4)
1053 self.assertEqual(sd_params.get('ISPORT'), "%d" % self.tcp_port_in)
1054 self.assertEqual(sd_params.get('XATYP'), 'IPv4')
1055 self.assertEqual(sd_params.get('XSADDR'), self.nat_addr)
1056 self.assertEqual(sd_params.get('XSPORT'), "%d" % self.tcp_port_out)
1057 self.assertEqual(sd_params.get('PROTO'), "%d" % IP_PROTOS.tcp)
1058 self.assertTrue(sd_params.get('SSUBIX') is not None)
1059 self.assertEqual(sd_params.get('SVLAN'), '0')
1060 except ParseError as e:
1061 self.logger.error(e)
1062
1063 def verify_syslog_sess(self, data, is_add=True, is_ip6=False):
1064 message = data.decode('utf-8')
1065 try:
1066 message = SyslogMessage.parse(message)
1067 self.assertEqual(message.severity, SyslogSeverity.info)
1068 self.assertEqual(message.appname, 'NAT')
1069 self.assertEqual(message.msgid, 'SADD' if is_add else 'SDEL')
1070 sd_params = message.sd.get('nsess')
1071 self.assertTrue(sd_params is not None)
1072 if is_ip6:
1073 self.assertEqual(sd_params.get('IATYP'), 'IPv6')
1074 self.assertEqual(sd_params.get('ISADDR'), self.pg0.remote_ip6)
1075 else:
1076 self.assertEqual(sd_params.get('IATYP'), 'IPv4')
1077 self.assertEqual(sd_params.get('ISADDR'), self.pg0.remote_ip4)
1078 self.assertTrue(sd_params.get('SSUBIX') is not None)
1079 self.assertEqual(sd_params.get('ISPORT'), "%d" % self.tcp_port_in)
1080 self.assertEqual(sd_params.get('XATYP'), 'IPv4')
1081 self.assertEqual(sd_params.get('XSADDR'), self.nat_addr)
1082 self.assertEqual(sd_params.get('XSPORT'), "%d" % self.tcp_port_out)
1083 self.assertEqual(sd_params.get('PROTO'), "%d" % IP_PROTOS.tcp)
1084 self.assertEqual(sd_params.get('SVLAN'), '0')
1085 self.assertEqual(sd_params.get('XDADDR'), self.pg1.remote_ip4)
1086 self.assertEqual(sd_params.get('XDPORT'),
1087 "%d" % self.tcp_external_port)
1088 except ParseError as e:
1089 self.logger.error(e)
1090
Matus Fabianbb4e0222018-09-13 02:36:25 -07001091 def verify_mss_value(self, pkt, mss):
1092 """
1093 Verify TCP MSS value
1094
1095 :param pkt:
1096 :param mss:
1097 """
1098 if not pkt.haslayer(IP) or not pkt.haslayer(TCP):
1099 raise TypeError("Not a TCP/IP packet")
1100
1101 for option in pkt[TCP].options:
1102 if option[0] == 'MSS':
1103 self.assertEqual(option[1], mss)
1104 self.assert_tcp_checksum_valid(pkt)
1105
Juraj Slobodafe0aa762018-07-23 12:22:54 +02001106 @staticmethod
1107 def proto2layer(proto):
1108 if proto == IP_PROTOS.tcp:
1109 return TCP
1110 elif proto == IP_PROTOS.udp:
1111 return UDP
1112 elif proto == IP_PROTOS.icmp:
1113 return ICMP
1114 else:
1115 raise Exception("Unsupported protocol")
1116
1117 def frag_in_order(self, proto=IP_PROTOS.tcp, dont_translate=False):
1118 layer = self.proto2layer(proto)
1119
1120 if proto == IP_PROTOS.tcp:
1121 data = "A" * 4 + "B" * 16 + "C" * 3
1122 else:
1123 data = "A" * 16 + "B" * 16 + "C" * 3
1124 self.port_in = random.randint(1025, 65535)
1125
1126 reass = self.vapi.nat_reass_dump()
1127 reass_n_start = len(reass)
1128
1129 # in2out
1130 pkts = self.create_stream_frag(self.pg0,
1131 self.pg1.remote_ip4,
1132 self.port_in,
1133 20,
1134 data,
1135 proto)
1136 self.pg0.add_stream(pkts)
1137 self.pg_enable_capture(self.pg_interfaces)
1138 self.pg_start()
1139 frags = self.pg1.get_capture(len(pkts))
1140 if not dont_translate:
1141 p = self.reass_frags_and_verify(frags,
1142 self.nat_addr,
1143 self.pg1.remote_ip4)
1144 else:
1145 p = self.reass_frags_and_verify(frags,
1146 self.pg0.remote_ip4,
1147 self.pg1.remote_ip4)
1148 if proto != IP_PROTOS.icmp:
1149 if not dont_translate:
1150 self.assertEqual(p[layer].dport, 20)
1151 self.assertNotEqual(p[layer].sport, self.port_in)
1152 else:
1153 self.assertEqual(p[layer].sport, self.port_in)
1154 else:
1155 if not dont_translate:
1156 self.assertNotEqual(p[layer].id, self.port_in)
1157 else:
1158 self.assertEqual(p[layer].id, self.port_in)
1159 self.assertEqual(data, p[Raw].load)
1160
1161 # out2in
1162 if not dont_translate:
1163 dst_addr = self.nat_addr
1164 else:
1165 dst_addr = self.pg0.remote_ip4
1166 if proto != IP_PROTOS.icmp:
1167 sport = 20
1168 dport = p[layer].sport
1169 else:
1170 sport = p[layer].id
1171 dport = 0
1172 pkts = self.create_stream_frag(self.pg1,
1173 dst_addr,
1174 sport,
1175 dport,
1176 data,
1177 proto,
1178 echo_reply=True)
1179 self.pg1.add_stream(pkts)
1180 self.pg_enable_capture(self.pg_interfaces)
1181 self.pg_start()
1182 frags = self.pg0.get_capture(len(pkts))
1183 p = self.reass_frags_and_verify(frags,
1184 self.pg1.remote_ip4,
1185 self.pg0.remote_ip4)
1186 if proto != IP_PROTOS.icmp:
1187 self.assertEqual(p[layer].sport, 20)
1188 self.assertEqual(p[layer].dport, self.port_in)
1189 else:
1190 self.assertEqual(p[layer].id, self.port_in)
1191 self.assertEqual(data, p[Raw].load)
1192
1193 reass = self.vapi.nat_reass_dump()
1194 reass_n_end = len(reass)
1195
1196 self.assertEqual(reass_n_end - reass_n_start, 2)
1197
1198 def frag_in_order_in_plus_out(self, proto=IP_PROTOS.tcp):
1199 layer = self.proto2layer(proto)
1200
1201 if proto == IP_PROTOS.tcp:
1202 data = "A" * 4 + "B" * 16 + "C" * 3
1203 else:
1204 data = "A" * 16 + "B" * 16 + "C" * 3
1205 self.port_in = random.randint(1025, 65535)
1206
1207 for i in range(2):
1208 reass = self.vapi.nat_reass_dump()
1209 reass_n_start = len(reass)
1210
1211 # out2in
1212 pkts = self.create_stream_frag(self.pg0,
1213 self.server_out_addr,
1214 self.port_in,
1215 self.server_out_port,
1216 data,
1217 proto)
1218 self.pg0.add_stream(pkts)
1219 self.pg_enable_capture(self.pg_interfaces)
1220 self.pg_start()
1221 frags = self.pg1.get_capture(len(pkts))
1222 p = self.reass_frags_and_verify(frags,
1223 self.pg0.remote_ip4,
1224 self.server_in_addr)
1225 if proto != IP_PROTOS.icmp:
1226 self.assertEqual(p[layer].sport, self.port_in)
1227 self.assertEqual(p[layer].dport, self.server_in_port)
1228 else:
1229 self.assertEqual(p[layer].id, self.port_in)
1230 self.assertEqual(data, p[Raw].load)
1231
1232 # in2out
1233 if proto != IP_PROTOS.icmp:
1234 pkts = self.create_stream_frag(self.pg1,
1235 self.pg0.remote_ip4,
1236 self.server_in_port,
1237 p[layer].sport,
1238 data,
1239 proto)
1240 else:
1241 pkts = self.create_stream_frag(self.pg1,
1242 self.pg0.remote_ip4,
1243 p[layer].id,
1244 0,
1245 data,
1246 proto,
1247 echo_reply=True)
1248 self.pg1.add_stream(pkts)
1249 self.pg_enable_capture(self.pg_interfaces)
1250 self.pg_start()
1251 frags = self.pg0.get_capture(len(pkts))
1252 p = self.reass_frags_and_verify(frags,
1253 self.server_out_addr,
1254 self.pg0.remote_ip4)
1255 if proto != IP_PROTOS.icmp:
1256 self.assertEqual(p[layer].sport, self.server_out_port)
1257 self.assertEqual(p[layer].dport, self.port_in)
1258 else:
1259 self.assertEqual(p[layer].id, self.port_in)
1260 self.assertEqual(data, p[Raw].load)
1261
1262 reass = self.vapi.nat_reass_dump()
1263 reass_n_end = len(reass)
1264
1265 self.assertEqual(reass_n_end - reass_n_start, 2)
1266
1267 def reass_hairpinning(self, proto=IP_PROTOS.tcp):
1268 layer = self.proto2layer(proto)
1269
1270 if proto == IP_PROTOS.tcp:
1271 data = "A" * 4 + "B" * 16 + "C" * 3
1272 else:
1273 data = "A" * 16 + "B" * 16 + "C" * 3
1274
1275 # send packet from host to server
1276 pkts = self.create_stream_frag(self.pg0,
1277 self.nat_addr,
1278 self.host_in_port,
1279 self.server_out_port,
1280 data,
1281 proto)
1282 self.pg0.add_stream(pkts)
1283 self.pg_enable_capture(self.pg_interfaces)
1284 self.pg_start()
1285 frags = self.pg0.get_capture(len(pkts))
1286 p = self.reass_frags_and_verify(frags,
1287 self.nat_addr,
1288 self.server.ip4)
1289 if proto != IP_PROTOS.icmp:
1290 self.assertNotEqual(p[layer].sport, self.host_in_port)
1291 self.assertEqual(p[layer].dport, self.server_in_port)
1292 else:
1293 self.assertNotEqual(p[layer].id, self.host_in_port)
1294 self.assertEqual(data, p[Raw].load)
1295
1296 def frag_out_of_order(self, proto=IP_PROTOS.tcp, dont_translate=False):
1297 layer = self.proto2layer(proto)
1298
1299 if proto == IP_PROTOS.tcp:
1300 data = "A" * 4 + "B" * 16 + "C" * 3
1301 else:
1302 data = "A" * 16 + "B" * 16 + "C" * 3
1303 self.port_in = random.randint(1025, 65535)
1304
1305 for i in range(2):
1306 # in2out
1307 pkts = self.create_stream_frag(self.pg0,
1308 self.pg1.remote_ip4,
1309 self.port_in,
1310 20,
1311 data,
1312 proto)
1313 pkts.reverse()
1314 self.pg0.add_stream(pkts)
1315 self.pg_enable_capture(self.pg_interfaces)
1316 self.pg_start()
1317 frags = self.pg1.get_capture(len(pkts))
1318 if not dont_translate:
1319 p = self.reass_frags_and_verify(frags,
1320 self.nat_addr,
1321 self.pg1.remote_ip4)
1322 else:
1323 p = self.reass_frags_and_verify(frags,
1324 self.pg0.remote_ip4,
1325 self.pg1.remote_ip4)
1326 if proto != IP_PROTOS.icmp:
1327 if not dont_translate:
1328 self.assertEqual(p[layer].dport, 20)
1329 self.assertNotEqual(p[layer].sport, self.port_in)
1330 else:
1331 self.assertEqual(p[layer].sport, self.port_in)
1332 else:
1333 if not dont_translate:
1334 self.assertNotEqual(p[layer].id, self.port_in)
1335 else:
1336 self.assertEqual(p[layer].id, self.port_in)
1337 self.assertEqual(data, p[Raw].load)
1338
1339 # out2in
1340 if not dont_translate:
1341 dst_addr = self.nat_addr
1342 else:
1343 dst_addr = self.pg0.remote_ip4
1344 if proto != IP_PROTOS.icmp:
1345 sport = 20
1346 dport = p[layer].sport
1347 else:
1348 sport = p[layer].id
1349 dport = 0
1350 pkts = self.create_stream_frag(self.pg1,
1351 dst_addr,
1352 sport,
1353 dport,
1354 data,
1355 proto,
1356 echo_reply=True)
1357 pkts.reverse()
1358 self.pg1.add_stream(pkts)
1359 self.pg_enable_capture(self.pg_interfaces)
1360 self.pg_start()
1361 frags = self.pg0.get_capture(len(pkts))
1362 p = self.reass_frags_and_verify(frags,
1363 self.pg1.remote_ip4,
1364 self.pg0.remote_ip4)
1365 if proto != IP_PROTOS.icmp:
1366 self.assertEqual(p[layer].sport, 20)
1367 self.assertEqual(p[layer].dport, self.port_in)
1368 else:
1369 self.assertEqual(p[layer].id, self.port_in)
1370 self.assertEqual(data, p[Raw].load)
1371
1372 def frag_out_of_order_in_plus_out(self, proto=IP_PROTOS.tcp):
1373 layer = self.proto2layer(proto)
1374
1375 if proto == IP_PROTOS.tcp:
1376 data = "A" * 4 + "B" * 16 + "C" * 3
1377 else:
1378 data = "A" * 16 + "B" * 16 + "C" * 3
1379 self.port_in = random.randint(1025, 65535)
1380
1381 for i in range(2):
1382 # out2in
1383 pkts = self.create_stream_frag(self.pg0,
1384 self.server_out_addr,
1385 self.port_in,
1386 self.server_out_port,
1387 data,
1388 proto)
1389 pkts.reverse()
1390 self.pg0.add_stream(pkts)
1391 self.pg_enable_capture(self.pg_interfaces)
1392 self.pg_start()
1393 frags = self.pg1.get_capture(len(pkts))
1394 p = self.reass_frags_and_verify(frags,
1395 self.pg0.remote_ip4,
1396 self.server_in_addr)
1397 if proto != IP_PROTOS.icmp:
1398 self.assertEqual(p[layer].dport, self.server_in_port)
1399 self.assertEqual(p[layer].sport, self.port_in)
1400 self.assertEqual(p[layer].dport, self.server_in_port)
1401 else:
1402 self.assertEqual(p[layer].id, self.port_in)
1403 self.assertEqual(data, p[Raw].load)
1404
1405 # in2out
1406 if proto != IP_PROTOS.icmp:
1407 pkts = self.create_stream_frag(self.pg1,
1408 self.pg0.remote_ip4,
1409 self.server_in_port,
1410 p[layer].sport,
1411 data,
1412 proto)
1413 else:
1414 pkts = self.create_stream_frag(self.pg1,
1415 self.pg0.remote_ip4,
1416 p[layer].id,
1417 0,
1418 data,
1419 proto,
1420 echo_reply=True)
1421 pkts.reverse()
1422 self.pg1.add_stream(pkts)
1423 self.pg_enable_capture(self.pg_interfaces)
1424 self.pg_start()
1425 frags = self.pg0.get_capture(len(pkts))
1426 p = self.reass_frags_and_verify(frags,
1427 self.server_out_addr,
1428 self.pg0.remote_ip4)
1429 if proto != IP_PROTOS.icmp:
1430 self.assertEqual(p[layer].sport, self.server_out_port)
1431 self.assertEqual(p[layer].dport, self.port_in)
1432 else:
1433 self.assertEqual(p[layer].id, self.port_in)
1434 self.assertEqual(data, p[Raw].load)
1435
Martin Gálikd7f75cd2017-03-27 06:02:47 -07001436
Matus Fabian2ba92e32017-08-21 07:05:03 -07001437class TestNAT44(MethodHolder):
1438 """ NAT44 Test Cases """
Martin Gálikd7f75cd2017-03-27 06:02:47 -07001439
1440 @classmethod
1441 def setUpClass(cls):
Matus Fabian2ba92e32017-08-21 07:05:03 -07001442 super(TestNAT44, cls).setUpClass()
Matus Fabian229c1aa2018-05-28 04:09:52 -07001443 cls.vapi.cli("set log class nat level debug")
Martin Gálikd7f75cd2017-03-27 06:02:47 -07001444
1445 try:
1446 cls.tcp_port_in = 6303
1447 cls.tcp_port_out = 6303
1448 cls.udp_port_in = 6304
1449 cls.udp_port_out = 6304
1450 cls.icmp_id_in = 6305
1451 cls.icmp_id_out = 6305
Matus Fabian2ba92e32017-08-21 07:05:03 -07001452 cls.nat_addr = '10.0.0.3'
Juraj Sloboda7b929792017-11-23 13:20:48 +01001453 cls.nat_addr_n = socket.inet_pton(socket.AF_INET, cls.nat_addr)
Matus Fabian6631e9c2017-05-24 01:52:20 -07001454 cls.ipfix_src_port = 4739
1455 cls.ipfix_domain_id = 1
Matus Fabianebdf1902018-05-04 03:57:42 -07001456 cls.tcp_external_port = 80
Martin Gálikd7f75cd2017-03-27 06:02:47 -07001457
Matus Fabian36ea2d62017-10-24 04:13:49 -07001458 cls.create_pg_interfaces(range(10))
Martin Gálikd7f75cd2017-03-27 06:02:47 -07001459 cls.interfaces = list(cls.pg_interfaces[0:4])
1460
1461 for i in cls.interfaces:
1462 i.admin_up()
1463 i.config_ip4()
1464 i.resolve_arp()
1465
Matus Fabian6fa74c62017-06-05 05:55:48 -07001466 cls.pg0.generate_remote_hosts(3)
Martin Gálikd7f75cd2017-03-27 06:02:47 -07001467 cls.pg0.configure_ipv4_neighbors()
1468
Juraj Sloboda1e5c07d2018-04-10 13:51:54 +02001469 cls.pg1.generate_remote_hosts(1)
1470 cls.pg1.configure_ipv4_neighbors()
1471
Martin Gálikd7f75cd2017-03-27 06:02:47 -07001472 cls.overlapping_interfaces = list(list(cls.pg_interfaces[4:7]))
Neale Ranns15002542017-09-10 04:39:11 -07001473 cls.vapi.ip_table_add_del(10, is_add=1)
1474 cls.vapi.ip_table_add_del(20, is_add=1)
Martin Gálikd7f75cd2017-03-27 06:02:47 -07001475
1476 cls.pg4._local_ip4 = "172.16.255.1"
1477 cls.pg4._local_ip4n = socket.inet_pton(socket.AF_INET, i.local_ip4)
1478 cls.pg4._remote_hosts[0]._ip4 = "172.16.255.2"
1479 cls.pg4.set_table_ip4(10)
Matus Fabian69126282017-08-14 23:39:58 -07001480 cls.pg5._local_ip4 = "172.17.255.3"
Martin Gálikd7f75cd2017-03-27 06:02:47 -07001481 cls.pg5._local_ip4n = socket.inet_pton(socket.AF_INET, i.local_ip4)
Matus Fabian69126282017-08-14 23:39:58 -07001482 cls.pg5._remote_hosts[0]._ip4 = "172.17.255.4"
Martin Gálikd7f75cd2017-03-27 06:02:47 -07001483 cls.pg5.set_table_ip4(10)
1484 cls.pg6._local_ip4 = "172.16.255.1"
1485 cls.pg6._local_ip4n = socket.inet_pton(socket.AF_INET, i.local_ip4)
1486 cls.pg6._remote_hosts[0]._ip4 = "172.16.255.2"
1487 cls.pg6.set_table_ip4(20)
1488 for i in cls.overlapping_interfaces:
1489 i.config_ip4()
1490 i.admin_up()
1491 i.resolve_arp()
1492
1493 cls.pg7.admin_up()
Martin Gálik406eb1d2017-05-04 04:35:04 -07001494 cls.pg8.admin_up()
Martin Gálikd7f75cd2017-03-27 06:02:47 -07001495
Matus Fabian36ea2d62017-10-24 04:13:49 -07001496 cls.pg9.generate_remote_hosts(2)
1497 cls.pg9.config_ip4()
1498 ip_addr_n = socket.inet_pton(socket.AF_INET, "10.0.0.1")
1499 cls.vapi.sw_interface_add_del_address(cls.pg9.sw_if_index,
1500 ip_addr_n,
1501 24)
1502 cls.pg9.admin_up()
1503 cls.pg9.resolve_arp()
1504 cls.pg9._remote_hosts[1]._ip4 = cls.pg9._remote_hosts[0]._ip4
1505 cls.pg4._remote_ip4 = cls.pg9._remote_hosts[0]._ip4 = "10.0.0.2"
1506 cls.pg9.resolve_arp()
1507
Martin Gálikd7f75cd2017-03-27 06:02:47 -07001508 except Exception:
Matus Fabian2ba92e32017-08-21 07:05:03 -07001509 super(TestNAT44, cls).tearDownClass()
Martin Gálikd7f75cd2017-03-27 06:02:47 -07001510 raise
1511
Matus Fabiande886752016-12-07 03:38:19 -08001512 def test_dynamic(self):
Matus Fabian2ba92e32017-08-21 07:05:03 -07001513 """ NAT44 dynamic translation test """
Matus Fabian2ba92e32017-08-21 07:05:03 -07001514 self.nat44_add_address(self.nat_addr)
1515 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
1516 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
1517 is_inside=0)
Matus Fabiande886752016-12-07 03:38:19 -08001518
1519 # in2out
Matus Fabiana5e73762018-12-14 01:55:16 -08001520 tcpn = self.statistics.get_counter(
1521 '/err/nat44-in2out-slowpath/TCP packets')
1522 udpn = self.statistics.get_counter(
1523 '/err/nat44-in2out-slowpath/UDP packets')
1524 icmpn = self.statistics.get_counter(
1525 '/err/nat44-in2out-slowpath/ICMP packets')
1526 totaln = self.statistics.get_counter(
1527 '/err/nat44-in2out-slowpath/good in2out packets processed')
1528
Matus Fabiande886752016-12-07 03:38:19 -08001529 pkts = self.create_stream_in(self.pg0, self.pg1)
1530 self.pg0.add_stream(pkts)
1531 self.pg_enable_capture(self.pg_interfaces)
1532 self.pg_start()
Klement Sekeradab231a2016-12-21 08:50:14 +01001533 capture = self.pg1.get_capture(len(pkts))
Matus Fabiande886752016-12-07 03:38:19 -08001534 self.verify_capture_out(capture)
1535
Matus Fabiana5e73762018-12-14 01:55:16 -08001536 err = self.statistics.get_counter(
1537 '/err/nat44-in2out-slowpath/TCP packets')
1538 self.assertEqual(err - tcpn, 1)
1539 err = self.statistics.get_counter(
1540 '/err/nat44-in2out-slowpath/UDP packets')
1541 self.assertEqual(err - udpn, 1)
1542 err = self.statistics.get_counter(
1543 '/err/nat44-in2out-slowpath/ICMP packets')
1544 self.assertEqual(err - icmpn, 1)
1545 err = self.statistics.get_counter(
1546 '/err/nat44-in2out-slowpath/good in2out packets processed')
1547 self.assertEqual(err - totaln, 3)
1548
Matus Fabiande886752016-12-07 03:38:19 -08001549 # out2in
Matus Fabiana5e73762018-12-14 01:55:16 -08001550 tcpn = self.statistics.get_counter('/err/nat44-out2in/TCP packets')
1551 udpn = self.statistics.get_counter('/err/nat44-out2in/UDP packets')
1552 icmpn = self.statistics.get_counter('/err/nat44-out2in/ICMP packets')
1553 totaln = self.statistics.get_counter(
1554 '/err/nat44-out2in/good out2in packets processed')
1555
Matus Fabiande886752016-12-07 03:38:19 -08001556 pkts = self.create_stream_out(self.pg1)
1557 self.pg1.add_stream(pkts)
1558 self.pg_enable_capture(self.pg_interfaces)
1559 self.pg_start()
Klement Sekeradab231a2016-12-21 08:50:14 +01001560 capture = self.pg0.get_capture(len(pkts))
Matus Fabiande886752016-12-07 03:38:19 -08001561 self.verify_capture_in(capture, self.pg0)
1562
Matus Fabiana5e73762018-12-14 01:55:16 -08001563 err = self.statistics.get_counter('/err/nat44-out2in/TCP packets')
1564 self.assertEqual(err - tcpn, 1)
1565 err = self.statistics.get_counter('/err/nat44-out2in/UDP packets')
1566 self.assertEqual(err - udpn, 1)
1567 err = self.statistics.get_counter('/err/nat44-out2in/ICMP packets')
1568 self.assertEqual(err - icmpn, 1)
1569 err = self.statistics.get_counter(
1570 '/err/nat44-out2in/good out2in packets processed')
1571 self.assertEqual(err - totaln, 3)
1572
Matus Fabianfd0d5082018-12-18 01:08:51 -08001573 users = self.statistics.get_counter('/nat44/total-users')
1574 self.assertEqual(users[0][0], 1)
1575 sessions = self.statistics.get_counter('/nat44/total-sessions')
1576 self.assertEqual(sessions[0][0], 3)
1577
Juraj Slobodab33f4132017-02-08 23:54:21 -08001578 def test_dynamic_icmp_errors_in2out_ttl_1(self):
Matus Fabian2ba92e32017-08-21 07:05:03 -07001579 """ NAT44 handling of client packets with TTL=1 """
Juraj Slobodab33f4132017-02-08 23:54:21 -08001580
Matus Fabian2ba92e32017-08-21 07:05:03 -07001581 self.nat44_add_address(self.nat_addr)
1582 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
1583 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
1584 is_inside=0)
Juraj Slobodab33f4132017-02-08 23:54:21 -08001585
1586 # Client side - generate traffic
1587 pkts = self.create_stream_in(self.pg0, self.pg1, ttl=1)
1588 self.pg0.add_stream(pkts)
1589 self.pg_enable_capture(self.pg_interfaces)
1590 self.pg_start()
1591
1592 # Client side - verify ICMP type 11 packets
1593 capture = self.pg0.get_capture(len(pkts))
1594 self.verify_capture_in_with_icmp_errors(capture, self.pg0)
1595
1596 def test_dynamic_icmp_errors_out2in_ttl_1(self):
Matus Fabian2ba92e32017-08-21 07:05:03 -07001597 """ NAT44 handling of server packets with TTL=1 """
Juraj Slobodab33f4132017-02-08 23:54:21 -08001598
Matus Fabian2ba92e32017-08-21 07:05:03 -07001599 self.nat44_add_address(self.nat_addr)
1600 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
1601 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
1602 is_inside=0)
Juraj Slobodab33f4132017-02-08 23:54:21 -08001603
1604 # Client side - create sessions
1605 pkts = self.create_stream_in(self.pg0, self.pg1)
1606 self.pg0.add_stream(pkts)
1607 self.pg_enable_capture(self.pg_interfaces)
1608 self.pg_start()
1609
1610 # Server side - generate traffic
1611 capture = self.pg1.get_capture(len(pkts))
1612 self.verify_capture_out(capture)
1613 pkts = self.create_stream_out(self.pg1, ttl=1)
1614 self.pg1.add_stream(pkts)
1615 self.pg_enable_capture(self.pg_interfaces)
1616 self.pg_start()
1617
1618 # Server side - verify ICMP type 11 packets
1619 capture = self.pg1.get_capture(len(pkts))
1620 self.verify_capture_out_with_icmp_errors(capture,
1621 src_ip=self.pg1.local_ip4)
1622
1623 def test_dynamic_icmp_errors_in2out_ttl_2(self):
Matus Fabian2ba92e32017-08-21 07:05:03 -07001624 """ NAT44 handling of error responses to client packets with TTL=2 """
Juraj Slobodab33f4132017-02-08 23:54:21 -08001625
Matus Fabian2ba92e32017-08-21 07:05:03 -07001626 self.nat44_add_address(self.nat_addr)
1627 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
1628 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
1629 is_inside=0)
Juraj Slobodab33f4132017-02-08 23:54:21 -08001630
1631 # Client side - generate traffic
1632 pkts = self.create_stream_in(self.pg0, self.pg1, ttl=2)
1633 self.pg0.add_stream(pkts)
1634 self.pg_enable_capture(self.pg_interfaces)
1635 self.pg_start()
1636
1637 # Server side - simulate ICMP type 11 response
1638 capture = self.pg1.get_capture(len(pkts))
1639 pkts = [Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
Matus Fabian2ba92e32017-08-21 07:05:03 -07001640 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
Juraj Slobodab33f4132017-02-08 23:54:21 -08001641 ICMP(type=11) / packet[IP] for packet in capture]
1642 self.pg1.add_stream(pkts)
1643 self.pg_enable_capture(self.pg_interfaces)
1644 self.pg_start()
1645
1646 # Client side - verify ICMP type 11 packets
1647 capture = self.pg0.get_capture(len(pkts))
1648 self.verify_capture_in_with_icmp_errors(capture, self.pg0)
1649
1650 def test_dynamic_icmp_errors_out2in_ttl_2(self):
Matus Fabian2ba92e32017-08-21 07:05:03 -07001651 """ NAT44 handling of error responses to server packets with TTL=2 """
Juraj Slobodab33f4132017-02-08 23:54:21 -08001652
Matus Fabian2ba92e32017-08-21 07:05:03 -07001653 self.nat44_add_address(self.nat_addr)
1654 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
1655 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
1656 is_inside=0)
Juraj Slobodab33f4132017-02-08 23:54:21 -08001657
1658 # Client side - create sessions
1659 pkts = self.create_stream_in(self.pg0, self.pg1)
1660 self.pg0.add_stream(pkts)
1661 self.pg_enable_capture(self.pg_interfaces)
1662 self.pg_start()
1663
1664 # Server side - generate traffic
1665 capture = self.pg1.get_capture(len(pkts))
1666 self.verify_capture_out(capture)
1667 pkts = self.create_stream_out(self.pg1, ttl=2)
1668 self.pg1.add_stream(pkts)
1669 self.pg_enable_capture(self.pg_interfaces)
1670 self.pg_start()
1671
1672 # Client side - simulate ICMP type 11 response
1673 capture = self.pg0.get_capture(len(pkts))
1674 pkts = [Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
1675 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
1676 ICMP(type=11) / packet[IP] for packet in capture]
1677 self.pg0.add_stream(pkts)
1678 self.pg_enable_capture(self.pg_interfaces)
1679 self.pg_start()
1680
1681 # Server side - verify ICMP type 11 packets
1682 capture = self.pg1.get_capture(len(pkts))
1683 self.verify_capture_out_with_icmp_errors(capture)
1684
Juraj Sloboda665e4822017-02-16 17:17:19 -08001685 def test_ping_out_interface_from_outside(self):
Matus Fabian2ba92e32017-08-21 07:05:03 -07001686 """ Ping NAT44 out interface from outside network """
Juraj Sloboda665e4822017-02-16 17:17:19 -08001687
Matus Fabian2ba92e32017-08-21 07:05:03 -07001688 self.nat44_add_address(self.nat_addr)
1689 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
1690 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
1691 is_inside=0)
Juraj Sloboda665e4822017-02-16 17:17:19 -08001692
1693 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
1694 IP(src=self.pg1.remote_ip4, dst=self.pg1.local_ip4) /
1695 ICMP(id=self.icmp_id_out, type='echo-request'))
1696 pkts = [p]
1697 self.pg1.add_stream(pkts)
1698 self.pg_enable_capture(self.pg_interfaces)
1699 self.pg_start()
1700 capture = self.pg1.get_capture(len(pkts))
Juraj Sloboda665e4822017-02-16 17:17:19 -08001701 packet = capture[0]
1702 try:
1703 self.assertEqual(packet[IP].src, self.pg1.local_ip4)
1704 self.assertEqual(packet[IP].dst, self.pg1.remote_ip4)
1705 self.assertEqual(packet[ICMP].id, self.icmp_id_in)
1706 self.assertEqual(packet[ICMP].type, 0) # echo reply
1707 except:
1708 self.logger.error(ppp("Unexpected or invalid packet "
1709 "(outside network):", packet))
1710 raise
1711
Juraj Slobodad3677682017-04-14 03:24:45 +02001712 def test_ping_internal_host_from_outside(self):
1713 """ Ping internal host from outside network """
1714
Matus Fabian2ba92e32017-08-21 07:05:03 -07001715 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr)
1716 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
1717 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
1718 is_inside=0)
Juraj Slobodad3677682017-04-14 03:24:45 +02001719
1720 # out2in
1721 pkt = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
Matus Fabian2ba92e32017-08-21 07:05:03 -07001722 IP(src=self.pg1.remote_ip4, dst=self.nat_addr, ttl=64) /
Juraj Slobodad3677682017-04-14 03:24:45 +02001723 ICMP(id=self.icmp_id_out, type='echo-request'))
1724 self.pg1.add_stream(pkt)
1725 self.pg_enable_capture(self.pg_interfaces)
1726 self.pg_start()
1727 capture = self.pg0.get_capture(1)
Matus Fabian05ca4a32018-09-04 23:45:13 -07001728 self.verify_capture_in(capture, self.pg0)
Juraj Slobodad3677682017-04-14 03:24:45 +02001729 self.assert_equal(capture[0][IP].proto, IP_PROTOS.icmp)
1730
1731 # in2out
1732 pkt = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
1733 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4, ttl=64) /
1734 ICMP(id=self.icmp_id_in, type='echo-reply'))
1735 self.pg0.add_stream(pkt)
1736 self.pg_enable_capture(self.pg_interfaces)
1737 self.pg_start()
1738 capture = self.pg1.get_capture(1)
Matus Fabian05ca4a32018-09-04 23:45:13 -07001739 self.verify_capture_out(capture, same_port=True)
Juraj Slobodad3677682017-04-14 03:24:45 +02001740 self.assert_equal(capture[0][IP].proto, IP_PROTOS.icmp)
1741
Matus Fabianc79396e2018-07-23 00:05:22 -07001742 def test_forwarding(self):
Juraj Sloboda7b929792017-11-23 13:20:48 +01001743 """ NAT44 forwarding test """
1744
1745 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
1746 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
1747 is_inside=0)
1748 self.vapi.nat44_forwarding_enable_disable(1)
1749
1750 real_ip = self.pg0.remote_ip4n
1751 alias_ip = self.nat_addr_n
1752 self.vapi.nat44_add_del_static_mapping(local_ip=real_ip,
1753 external_ip=alias_ip)
1754
1755 try:
Matus Fabianc79396e2018-07-23 00:05:22 -07001756 # static mapping match
Juraj Sloboda7b929792017-11-23 13:20:48 +01001757
1758 pkts = self.create_stream_out(self.pg1)
1759 self.pg1.add_stream(pkts)
1760 self.pg_enable_capture(self.pg_interfaces)
1761 self.pg_start()
1762 capture = self.pg0.get_capture(len(pkts))
1763 self.verify_capture_in(capture, self.pg0)
1764
1765 pkts = self.create_stream_in(self.pg0, self.pg1)
1766 self.pg0.add_stream(pkts)
1767 self.pg_enable_capture(self.pg_interfaces)
1768 self.pg_start()
1769 capture = self.pg1.get_capture(len(pkts))
1770 self.verify_capture_out(capture, same_port=True)
1771
Matus Fabianc79396e2018-07-23 00:05:22 -07001772 # no static mapping match
Juraj Sloboda7b929792017-11-23 13:20:48 +01001773
1774 host0 = self.pg0.remote_hosts[0]
1775 self.pg0.remote_hosts[0] = self.pg0.remote_hosts[1]
1776 try:
1777 pkts = self.create_stream_out(self.pg1,
1778 dst_ip=self.pg0.remote_ip4,
1779 use_inside_ports=True)
1780 self.pg1.add_stream(pkts)
1781 self.pg_enable_capture(self.pg_interfaces)
1782 self.pg_start()
1783 capture = self.pg0.get_capture(len(pkts))
1784 self.verify_capture_in(capture, self.pg0)
1785
1786 pkts = self.create_stream_in(self.pg0, self.pg1)
1787 self.pg0.add_stream(pkts)
1788 self.pg_enable_capture(self.pg_interfaces)
1789 self.pg_start()
1790 capture = self.pg1.get_capture(len(pkts))
1791 self.verify_capture_out(capture, nat_ip=self.pg0.remote_ip4,
1792 same_port=True)
1793 finally:
1794 self.pg0.remote_hosts[0] = host0
1795
1796 finally:
1797 self.vapi.nat44_forwarding_enable_disable(0)
1798 self.vapi.nat44_add_del_static_mapping(local_ip=real_ip,
1799 external_ip=alias_ip,
1800 is_add=0)
1801
Matus Fabiande886752016-12-07 03:38:19 -08001802 def test_static_in(self):
Matus Fabian2ba92e32017-08-21 07:05:03 -07001803 """ 1:1 NAT initialized from inside network """
Matus Fabiande886752016-12-07 03:38:19 -08001804
1805 nat_ip = "10.0.0.10"
1806 self.tcp_port_out = 6303
1807 self.udp_port_out = 6304
1808 self.icmp_id_out = 6305
1809
Matus Fabian2ba92e32017-08-21 07:05:03 -07001810 self.nat44_add_static_mapping(self.pg0.remote_ip4, nat_ip)
1811 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
1812 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
1813 is_inside=0)
Matus Fabian5f224992018-01-25 21:59:16 -08001814 sm = self.vapi.nat44_static_mapping_dump()
1815 self.assertEqual(len(sm), 1)
1816 self.assertEqual((sm[0].tag).split('\0', 1)[0], '')
Matus Fabian9dba7812018-01-31 01:13:23 -08001817 self.assertEqual(sm[0].protocol, 0)
1818 self.assertEqual(sm[0].local_port, 0)
1819 self.assertEqual(sm[0].external_port, 0)
Matus Fabiande886752016-12-07 03:38:19 -08001820
1821 # in2out
1822 pkts = self.create_stream_in(self.pg0, self.pg1)
1823 self.pg0.add_stream(pkts)
1824 self.pg_enable_capture(self.pg_interfaces)
1825 self.pg_start()
Klement Sekeradab231a2016-12-21 08:50:14 +01001826 capture = self.pg1.get_capture(len(pkts))
Matus Fabiande886752016-12-07 03:38:19 -08001827 self.verify_capture_out(capture, nat_ip, True)
1828
1829 # out2in
1830 pkts = self.create_stream_out(self.pg1, nat_ip)
1831 self.pg1.add_stream(pkts)
1832 self.pg_enable_capture(self.pg_interfaces)
1833 self.pg_start()
Klement Sekeradab231a2016-12-21 08:50:14 +01001834 capture = self.pg0.get_capture(len(pkts))
Matus Fabiande886752016-12-07 03:38:19 -08001835 self.verify_capture_in(capture, self.pg0)
1836
1837 def test_static_out(self):
Matus Fabian2ba92e32017-08-21 07:05:03 -07001838 """ 1:1 NAT initialized from outside network """
Matus Fabiande886752016-12-07 03:38:19 -08001839
1840 nat_ip = "10.0.0.20"
1841 self.tcp_port_out = 6303
1842 self.udp_port_out = 6304
1843 self.icmp_id_out = 6305
Matus Fabian5f224992018-01-25 21:59:16 -08001844 tag = "testTAG"
Matus Fabiande886752016-12-07 03:38:19 -08001845
Matus Fabian5f224992018-01-25 21:59:16 -08001846 self.nat44_add_static_mapping(self.pg0.remote_ip4, nat_ip, tag=tag)
Matus Fabian2ba92e32017-08-21 07:05:03 -07001847 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
1848 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
1849 is_inside=0)
Matus Fabian5f224992018-01-25 21:59:16 -08001850 sm = self.vapi.nat44_static_mapping_dump()
1851 self.assertEqual(len(sm), 1)
1852 self.assertEqual((sm[0].tag).split('\0', 1)[0], tag)
Matus Fabiande886752016-12-07 03:38:19 -08001853
1854 # out2in
1855 pkts = self.create_stream_out(self.pg1, nat_ip)
1856 self.pg1.add_stream(pkts)
1857 self.pg_enable_capture(self.pg_interfaces)
1858 self.pg_start()
Klement Sekeradab231a2016-12-21 08:50:14 +01001859 capture = self.pg0.get_capture(len(pkts))
Matus Fabiande886752016-12-07 03:38:19 -08001860 self.verify_capture_in(capture, self.pg0)
1861
1862 # in2out
1863 pkts = self.create_stream_in(self.pg0, self.pg1)
1864 self.pg0.add_stream(pkts)
1865 self.pg_enable_capture(self.pg_interfaces)
1866 self.pg_start()
Klement Sekeradab231a2016-12-21 08:50:14 +01001867 capture = self.pg1.get_capture(len(pkts))
Matus Fabiande886752016-12-07 03:38:19 -08001868 self.verify_capture_out(capture, nat_ip, True)
1869
1870 def test_static_with_port_in(self):
Matus Fabian2ba92e32017-08-21 07:05:03 -07001871 """ 1:1 NAPT initialized from inside network """
Matus Fabiande886752016-12-07 03:38:19 -08001872
1873 self.tcp_port_out = 3606
1874 self.udp_port_out = 3607
1875 self.icmp_id_out = 3608
1876
Matus Fabian2ba92e32017-08-21 07:05:03 -07001877 self.nat44_add_address(self.nat_addr)
1878 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
1879 self.tcp_port_in, self.tcp_port_out,
1880 proto=IP_PROTOS.tcp)
1881 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
1882 self.udp_port_in, self.udp_port_out,
1883 proto=IP_PROTOS.udp)
1884 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
1885 self.icmp_id_in, self.icmp_id_out,
1886 proto=IP_PROTOS.icmp)
1887 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
1888 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
1889 is_inside=0)
Matus Fabiande886752016-12-07 03:38:19 -08001890
1891 # in2out
1892 pkts = self.create_stream_in(self.pg0, self.pg1)
1893 self.pg0.add_stream(pkts)
1894 self.pg_enable_capture(self.pg_interfaces)
1895 self.pg_start()
Klement Sekeradab231a2016-12-21 08:50:14 +01001896 capture = self.pg1.get_capture(len(pkts))
Matus Fabiande886752016-12-07 03:38:19 -08001897 self.verify_capture_out(capture)
1898
1899 # out2in
1900 pkts = self.create_stream_out(self.pg1)
1901 self.pg1.add_stream(pkts)
1902 self.pg_enable_capture(self.pg_interfaces)
1903 self.pg_start()
Klement Sekeradab231a2016-12-21 08:50:14 +01001904 capture = self.pg0.get_capture(len(pkts))
Matus Fabiande886752016-12-07 03:38:19 -08001905 self.verify_capture_in(capture, self.pg0)
1906
1907 def test_static_with_port_out(self):
Matus Fabian2ba92e32017-08-21 07:05:03 -07001908 """ 1:1 NAPT initialized from outside network """
Matus Fabiande886752016-12-07 03:38:19 -08001909
1910 self.tcp_port_out = 30606
1911 self.udp_port_out = 30607
1912 self.icmp_id_out = 30608
1913
Matus Fabian2ba92e32017-08-21 07:05:03 -07001914 self.nat44_add_address(self.nat_addr)
1915 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
1916 self.tcp_port_in, self.tcp_port_out,
1917 proto=IP_PROTOS.tcp)
1918 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
1919 self.udp_port_in, self.udp_port_out,
1920 proto=IP_PROTOS.udp)
1921 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
1922 self.icmp_id_in, self.icmp_id_out,
1923 proto=IP_PROTOS.icmp)
1924 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
1925 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
1926 is_inside=0)
Matus Fabiande886752016-12-07 03:38:19 -08001927
1928 # out2in
1929 pkts = self.create_stream_out(self.pg1)
1930 self.pg1.add_stream(pkts)
1931 self.pg_enable_capture(self.pg_interfaces)
1932 self.pg_start()
Klement Sekeradab231a2016-12-21 08:50:14 +01001933 capture = self.pg0.get_capture(len(pkts))
Matus Fabiande886752016-12-07 03:38:19 -08001934 self.verify_capture_in(capture, self.pg0)
1935
1936 # in2out
1937 pkts = self.create_stream_in(self.pg0, self.pg1)
1938 self.pg0.add_stream(pkts)
1939 self.pg_enable_capture(self.pg_interfaces)
1940 self.pg_start()
Klement Sekeradab231a2016-12-21 08:50:14 +01001941 capture = self.pg1.get_capture(len(pkts))
Matus Fabiande886752016-12-07 03:38:19 -08001942 self.verify_capture_out(capture)
1943
1944 def test_static_vrf_aware(self):
Matus Fabian2ba92e32017-08-21 07:05:03 -07001945 """ 1:1 NAT VRF awareness """
Matus Fabiande886752016-12-07 03:38:19 -08001946
1947 nat_ip1 = "10.0.0.30"
1948 nat_ip2 = "10.0.0.40"
1949 self.tcp_port_out = 6303
1950 self.udp_port_out = 6304
1951 self.icmp_id_out = 6305
1952
Matus Fabian2ba92e32017-08-21 07:05:03 -07001953 self.nat44_add_static_mapping(self.pg4.remote_ip4, nat_ip1,
1954 vrf_id=10)
1955 self.nat44_add_static_mapping(self.pg0.remote_ip4, nat_ip2,
1956 vrf_id=10)
1957 self.vapi.nat44_interface_add_del_feature(self.pg3.sw_if_index,
1958 is_inside=0)
1959 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
1960 self.vapi.nat44_interface_add_del_feature(self.pg4.sw_if_index)
Matus Fabiande886752016-12-07 03:38:19 -08001961
Matus Fabian2ba92e32017-08-21 07:05:03 -07001962 # inside interface VRF match NAT44 static mapping VRF
Matus Fabiande886752016-12-07 03:38:19 -08001963 pkts = self.create_stream_in(self.pg4, self.pg3)
1964 self.pg4.add_stream(pkts)
1965 self.pg_enable_capture(self.pg_interfaces)
1966 self.pg_start()
Klement Sekeradab231a2016-12-21 08:50:14 +01001967 capture = self.pg3.get_capture(len(pkts))
Matus Fabiande886752016-12-07 03:38:19 -08001968 self.verify_capture_out(capture, nat_ip1, True)
1969
Matus Fabian2ba92e32017-08-21 07:05:03 -07001970 # inside interface VRF don't match NAT44 static mapping VRF (packets
Matus Fabiande886752016-12-07 03:38:19 -08001971 # are dropped)
1972 pkts = self.create_stream_in(self.pg0, self.pg3)
1973 self.pg0.add_stream(pkts)
1974 self.pg_enable_capture(self.pg_interfaces)
1975 self.pg_start()
Klement Sekera9225dee2016-12-12 08:36:58 +01001976 self.pg3.assert_nothing_captured()
Matus Fabiande886752016-12-07 03:38:19 -08001977
Matus Fabianb793d092018-01-31 05:50:21 -08001978 def test_dynamic_to_static(self):
1979 """ Switch from dynamic translation to 1:1NAT """
1980 nat_ip = "10.0.0.10"
1981 self.tcp_port_out = 6303
1982 self.udp_port_out = 6304
1983 self.icmp_id_out = 6305
1984
1985 self.nat44_add_address(self.nat_addr)
1986 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
1987 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
1988 is_inside=0)
1989
1990 # dynamic
1991 pkts = self.create_stream_in(self.pg0, self.pg1)
1992 self.pg0.add_stream(pkts)
1993 self.pg_enable_capture(self.pg_interfaces)
1994 self.pg_start()
1995 capture = self.pg1.get_capture(len(pkts))
1996 self.verify_capture_out(capture)
1997
1998 # 1:1NAT
1999 self.nat44_add_static_mapping(self.pg0.remote_ip4, nat_ip)
2000 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n, 0)
2001 self.assertEqual(len(sessions), 0)
2002 pkts = self.create_stream_in(self.pg0, self.pg1)
2003 self.pg0.add_stream(pkts)
2004 self.pg_enable_capture(self.pg_interfaces)
2005 self.pg_start()
2006 capture = self.pg1.get_capture(len(pkts))
2007 self.verify_capture_out(capture, nat_ip, True)
2008
Matus Fabianab7a8052017-11-28 04:29:41 -08002009 def test_identity_nat(self):
2010 """ Identity NAT """
2011
2012 self.vapi.nat44_add_del_identity_mapping(ip=self.pg0.remote_ip4n)
2013 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
2014 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
2015 is_inside=0)
2016
2017 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
2018 IP(src=self.pg1.remote_ip4, dst=self.pg0.remote_ip4) /
2019 TCP(sport=12345, dport=56789))
2020 self.pg1.add_stream(p)
2021 self.pg_enable_capture(self.pg_interfaces)
2022 self.pg_start()
2023 capture = self.pg0.get_capture(1)
2024 p = capture[0]
2025 try:
2026 ip = p[IP]
2027 tcp = p[TCP]
2028 self.assertEqual(ip.dst, self.pg0.remote_ip4)
2029 self.assertEqual(ip.src, self.pg1.remote_ip4)
2030 self.assertEqual(tcp.dport, 56789)
2031 self.assertEqual(tcp.sport, 12345)
Klement Sekerad81ae412018-05-16 10:52:54 +02002032 self.assert_packet_checksums_valid(p)
Matus Fabianab7a8052017-11-28 04:29:41 -08002033 except:
2034 self.logger.error(ppp("Unexpected or invalid packet:", p))
2035 raise
2036
Matus Fabiane2f4e2f2018-10-07 21:28:23 -07002037 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n, 0)
2038 self.assertEqual(len(sessions), 0)
Matus Fabian82b4ceb2018-10-11 04:28:48 -07002039 self.vapi.nat44_add_del_identity_mapping(ip=self.pg0.remote_ip4n,
2040 vrf_id=1)
2041 identity_mappings = self.vapi.nat44_identity_mapping_dump()
2042 self.assertEqual(len(identity_mappings), 2)
Matus Fabiane2f4e2f2018-10-07 21:28:23 -07002043
Matus Fabiande886752016-12-07 03:38:19 -08002044 def test_multiple_inside_interfaces(self):
Matus Fabian2ba92e32017-08-21 07:05:03 -07002045 """ NAT44 multiple non-overlapping address space inside interfaces """
Matus Fabiande886752016-12-07 03:38:19 -08002046
Matus Fabian2ba92e32017-08-21 07:05:03 -07002047 self.nat44_add_address(self.nat_addr)
2048 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
2049 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index)
2050 self.vapi.nat44_interface_add_del_feature(self.pg3.sw_if_index,
2051 is_inside=0)
Matus Fabiande886752016-12-07 03:38:19 -08002052
Matus Fabian2ba92e32017-08-21 07:05:03 -07002053 # between two NAT44 inside interfaces (no translation)
Matus Fabian675a69c2017-01-18 01:46:01 -08002054 pkts = self.create_stream_in(self.pg0, self.pg1)
2055 self.pg0.add_stream(pkts)
2056 self.pg_enable_capture(self.pg_interfaces)
2057 self.pg_start()
2058 capture = self.pg1.get_capture(len(pkts))
2059 self.verify_capture_no_translation(capture, self.pg0, self.pg1)
2060
Matus Fabian2ba92e32017-08-21 07:05:03 -07002061 # from NAT44 inside to interface without NAT44 feature (no translation)
Matus Fabian675a69c2017-01-18 01:46:01 -08002062 pkts = self.create_stream_in(self.pg0, self.pg2)
2063 self.pg0.add_stream(pkts)
2064 self.pg_enable_capture(self.pg_interfaces)
2065 self.pg_start()
2066 capture = self.pg2.get_capture(len(pkts))
2067 self.verify_capture_no_translation(capture, self.pg0, self.pg2)
2068
Matus Fabiande886752016-12-07 03:38:19 -08002069 # in2out 1st interface
2070 pkts = self.create_stream_in(self.pg0, self.pg3)
2071 self.pg0.add_stream(pkts)
2072 self.pg_enable_capture(self.pg_interfaces)
2073 self.pg_start()
Klement Sekeradab231a2016-12-21 08:50:14 +01002074 capture = self.pg3.get_capture(len(pkts))
Matus Fabiande886752016-12-07 03:38:19 -08002075 self.verify_capture_out(capture)
2076
2077 # out2in 1st interface
2078 pkts = self.create_stream_out(self.pg3)
2079 self.pg3.add_stream(pkts)
2080 self.pg_enable_capture(self.pg_interfaces)
2081 self.pg_start()
Klement Sekeradab231a2016-12-21 08:50:14 +01002082 capture = self.pg0.get_capture(len(pkts))
Matus Fabiande886752016-12-07 03:38:19 -08002083 self.verify_capture_in(capture, self.pg0)
2084
2085 # in2out 2nd interface
2086 pkts = self.create_stream_in(self.pg1, self.pg3)
2087 self.pg1.add_stream(pkts)
2088 self.pg_enable_capture(self.pg_interfaces)
2089 self.pg_start()
Klement Sekeradab231a2016-12-21 08:50:14 +01002090 capture = self.pg3.get_capture(len(pkts))
Matus Fabiande886752016-12-07 03:38:19 -08002091 self.verify_capture_out(capture)
2092
2093 # out2in 2nd interface
2094 pkts = self.create_stream_out(self.pg3)
2095 self.pg3.add_stream(pkts)
2096 self.pg_enable_capture(self.pg_interfaces)
2097 self.pg_start()
Klement Sekeradab231a2016-12-21 08:50:14 +01002098 capture = self.pg1.get_capture(len(pkts))
Matus Fabiande886752016-12-07 03:38:19 -08002099 self.verify_capture_in(capture, self.pg1)
2100
Matus Fabiande886752016-12-07 03:38:19 -08002101 def test_inside_overlapping_interfaces(self):
Matus Fabian2ba92e32017-08-21 07:05:03 -07002102 """ NAT44 multiple inside interfaces with overlapping address space """
Matus Fabiande886752016-12-07 03:38:19 -08002103
Matus Fabian675a69c2017-01-18 01:46:01 -08002104 static_nat_ip = "10.0.0.10"
Matus Fabian2ba92e32017-08-21 07:05:03 -07002105 self.nat44_add_address(self.nat_addr)
2106 self.vapi.nat44_interface_add_del_feature(self.pg3.sw_if_index,
2107 is_inside=0)
2108 self.vapi.nat44_interface_add_del_feature(self.pg4.sw_if_index)
2109 self.vapi.nat44_interface_add_del_feature(self.pg5.sw_if_index)
2110 self.vapi.nat44_interface_add_del_feature(self.pg6.sw_if_index)
2111 self.nat44_add_static_mapping(self.pg6.remote_ip4, static_nat_ip,
2112 vrf_id=20)
Matus Fabian675a69c2017-01-18 01:46:01 -08002113
Matus Fabian2ba92e32017-08-21 07:05:03 -07002114 # between NAT44 inside interfaces with same VRF (no translation)
Matus Fabian675a69c2017-01-18 01:46:01 -08002115 pkts = self.create_stream_in(self.pg4, self.pg5)
2116 self.pg4.add_stream(pkts)
2117 self.pg_enable_capture(self.pg_interfaces)
2118 self.pg_start()
2119 capture = self.pg5.get_capture(len(pkts))
2120 self.verify_capture_no_translation(capture, self.pg4, self.pg5)
2121
Matus Fabian2ba92e32017-08-21 07:05:03 -07002122 # between NAT44 inside interfaces with different VRF (hairpinning)
Matus Fabian675a69c2017-01-18 01:46:01 -08002123 p = (Ether(src=self.pg4.remote_mac, dst=self.pg4.local_mac) /
2124 IP(src=self.pg4.remote_ip4, dst=static_nat_ip) /
2125 TCP(sport=1234, dport=5678))
2126 self.pg4.add_stream(p)
2127 self.pg_enable_capture(self.pg_interfaces)
2128 self.pg_start()
2129 capture = self.pg6.get_capture(1)
2130 p = capture[0]
2131 try:
2132 ip = p[IP]
2133 tcp = p[TCP]
Matus Fabian2ba92e32017-08-21 07:05:03 -07002134 self.assertEqual(ip.src, self.nat_addr)
Matus Fabian675a69c2017-01-18 01:46:01 -08002135 self.assertEqual(ip.dst, self.pg6.remote_ip4)
2136 self.assertNotEqual(tcp.sport, 1234)
2137 self.assertEqual(tcp.dport, 5678)
2138 except:
2139 self.logger.error(ppp("Unexpected or invalid packet:", p))
2140 raise
Matus Fabiande886752016-12-07 03:38:19 -08002141
2142 # in2out 1st interface
2143 pkts = self.create_stream_in(self.pg4, self.pg3)
2144 self.pg4.add_stream(pkts)
2145 self.pg_enable_capture(self.pg_interfaces)
2146 self.pg_start()
Klement Sekeradab231a2016-12-21 08:50:14 +01002147 capture = self.pg3.get_capture(len(pkts))
Matus Fabiande886752016-12-07 03:38:19 -08002148 self.verify_capture_out(capture)
2149
2150 # out2in 1st interface
2151 pkts = self.create_stream_out(self.pg3)
2152 self.pg3.add_stream(pkts)
2153 self.pg_enable_capture(self.pg_interfaces)
2154 self.pg_start()
Klement Sekeradab231a2016-12-21 08:50:14 +01002155 capture = self.pg4.get_capture(len(pkts))
Matus Fabiande886752016-12-07 03:38:19 -08002156 self.verify_capture_in(capture, self.pg4)
2157
2158 # in2out 2nd interface
2159 pkts = self.create_stream_in(self.pg5, self.pg3)
2160 self.pg5.add_stream(pkts)
2161 self.pg_enable_capture(self.pg_interfaces)
2162 self.pg_start()
Klement Sekeradab231a2016-12-21 08:50:14 +01002163 capture = self.pg3.get_capture(len(pkts))
Matus Fabiande886752016-12-07 03:38:19 -08002164 self.verify_capture_out(capture)
2165
2166 # out2in 2nd interface
2167 pkts = self.create_stream_out(self.pg3)
2168 self.pg3.add_stream(pkts)
2169 self.pg_enable_capture(self.pg_interfaces)
2170 self.pg_start()
Klement Sekeradab231a2016-12-21 08:50:14 +01002171 capture = self.pg5.get_capture(len(pkts))
Matus Fabiande886752016-12-07 03:38:19 -08002172 self.verify_capture_in(capture, self.pg5)
2173
magalik23caa882017-02-08 23:25:45 -08002174 # pg5 session dump
Matus Fabian2ba92e32017-08-21 07:05:03 -07002175 addresses = self.vapi.nat44_address_dump()
magalik23caa882017-02-08 23:25:45 -08002176 self.assertEqual(len(addresses), 1)
Matus Fabian2ba92e32017-08-21 07:05:03 -07002177 sessions = self.vapi.nat44_user_session_dump(self.pg5.remote_ip4n, 10)
magalik23caa882017-02-08 23:25:45 -08002178 self.assertEqual(len(sessions), 3)
2179 for session in sessions:
2180 self.assertFalse(session.is_static)
2181 self.assertEqual(session.inside_ip_address[0:4],
2182 self.pg5.remote_ip4n)
2183 self.assertEqual(session.outside_ip_address,
2184 addresses[0].ip_address)
2185 self.assertEqual(sessions[0].protocol, IP_PROTOS.tcp)
2186 self.assertEqual(sessions[1].protocol, IP_PROTOS.udp)
2187 self.assertEqual(sessions[2].protocol, IP_PROTOS.icmp)
2188 self.assertEqual(sessions[0].inside_port, self.tcp_port_in)
2189 self.assertEqual(sessions[1].inside_port, self.udp_port_in)
2190 self.assertEqual(sessions[2].inside_port, self.icmp_id_in)
2191 self.assertEqual(sessions[0].outside_port, self.tcp_port_out)
2192 self.assertEqual(sessions[1].outside_port, self.udp_port_out)
2193 self.assertEqual(sessions[2].outside_port, self.icmp_id_out)
2194
Matus Fabiande886752016-12-07 03:38:19 -08002195 # in2out 3rd interface
2196 pkts = self.create_stream_in(self.pg6, self.pg3)
2197 self.pg6.add_stream(pkts)
2198 self.pg_enable_capture(self.pg_interfaces)
2199 self.pg_start()
Klement Sekeradab231a2016-12-21 08:50:14 +01002200 capture = self.pg3.get_capture(len(pkts))
Matus Fabian675a69c2017-01-18 01:46:01 -08002201 self.verify_capture_out(capture, static_nat_ip, True)
Matus Fabiande886752016-12-07 03:38:19 -08002202
2203 # out2in 3rd interface
Matus Fabian675a69c2017-01-18 01:46:01 -08002204 pkts = self.create_stream_out(self.pg3, static_nat_ip)
Matus Fabiande886752016-12-07 03:38:19 -08002205 self.pg3.add_stream(pkts)
2206 self.pg_enable_capture(self.pg_interfaces)
2207 self.pg_start()
Klement Sekeradab231a2016-12-21 08:50:14 +01002208 capture = self.pg6.get_capture(len(pkts))
Matus Fabiande886752016-12-07 03:38:19 -08002209 self.verify_capture_in(capture, self.pg6)
2210
magalik23caa882017-02-08 23:25:45 -08002211 # general user and session dump verifications
Matus Fabian2ba92e32017-08-21 07:05:03 -07002212 users = self.vapi.nat44_user_dump()
Paul Vinciguerra3d2df212018-11-24 23:19:53 -08002213 self.assertGreaterEqual(len(users), 3)
Matus Fabian2ba92e32017-08-21 07:05:03 -07002214 addresses = self.vapi.nat44_address_dump()
magalik23caa882017-02-08 23:25:45 -08002215 self.assertEqual(len(addresses), 1)
2216 for user in users:
Matus Fabian2ba92e32017-08-21 07:05:03 -07002217 sessions = self.vapi.nat44_user_session_dump(user.ip_address,
2218 user.vrf_id)
magalik23caa882017-02-08 23:25:45 -08002219 for session in sessions:
2220 self.assertEqual(user.ip_address, session.inside_ip_address)
2221 self.assertTrue(session.total_bytes > session.total_pkts > 0)
2222 self.assertTrue(session.protocol in
2223 [IP_PROTOS.tcp, IP_PROTOS.udp,
2224 IP_PROTOS.icmp])
Matus Fabian70a26ac2018-05-14 06:20:28 -07002225 self.assertFalse(session.ext_host_valid)
magalik23caa882017-02-08 23:25:45 -08002226
2227 # pg4 session dump
Matus Fabian2ba92e32017-08-21 07:05:03 -07002228 sessions = self.vapi.nat44_user_session_dump(self.pg4.remote_ip4n, 10)
Paul Vinciguerra3d2df212018-11-24 23:19:53 -08002229 self.assertGreaterEqual(len(sessions), 4)
magalik23caa882017-02-08 23:25:45 -08002230 for session in sessions:
2231 self.assertFalse(session.is_static)
2232 self.assertEqual(session.inside_ip_address[0:4],
2233 self.pg4.remote_ip4n)
2234 self.assertEqual(session.outside_ip_address,
2235 addresses[0].ip_address)
2236
2237 # pg6 session dump
Matus Fabian2ba92e32017-08-21 07:05:03 -07002238 sessions = self.vapi.nat44_user_session_dump(self.pg6.remote_ip4n, 20)
Paul Vinciguerra3d2df212018-11-24 23:19:53 -08002239 self.assertGreaterEqual(len(sessions), 3)
magalik23caa882017-02-08 23:25:45 -08002240 for session in sessions:
2241 self.assertTrue(session.is_static)
2242 self.assertEqual(session.inside_ip_address[0:4],
2243 self.pg6.remote_ip4n)
2244 self.assertEqual(map(ord, session.outside_ip_address[0:4]),
2245 map(int, static_nat_ip.split('.')))
2246 self.assertTrue(session.inside_port in
2247 [self.tcp_port_in, self.udp_port_in,
2248 self.icmp_id_in])
2249
Matus Fabianf78a70d2016-12-12 04:30:39 -08002250 def test_hairpinning(self):
Matus Fabian2ba92e32017-08-21 07:05:03 -07002251 """ NAT44 hairpinning - 1:1 NAPT """
Matus Fabianf78a70d2016-12-12 04:30:39 -08002252
2253 host = self.pg0.remote_hosts[0]
2254 server = self.pg0.remote_hosts[1]
2255 host_in_port = 1234
2256 host_out_port = 0
2257 server_in_port = 5678
2258 server_out_port = 8765
2259
Matus Fabian2ba92e32017-08-21 07:05:03 -07002260 self.nat44_add_address(self.nat_addr)
2261 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
2262 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
2263 is_inside=0)
Matus Fabianf78a70d2016-12-12 04:30:39 -08002264 # add static mapping for server
Matus Fabian2ba92e32017-08-21 07:05:03 -07002265 self.nat44_add_static_mapping(server.ip4, self.nat_addr,
2266 server_in_port, server_out_port,
2267 proto=IP_PROTOS.tcp)
Matus Fabianf78a70d2016-12-12 04:30:39 -08002268
2269 # send packet from host to server
2270 p = (Ether(src=host.mac, dst=self.pg0.local_mac) /
Matus Fabian2ba92e32017-08-21 07:05:03 -07002271 IP(src=host.ip4, dst=self.nat_addr) /
Matus Fabianf78a70d2016-12-12 04:30:39 -08002272 TCP(sport=host_in_port, dport=server_out_port))
2273 self.pg0.add_stream(p)
2274 self.pg_enable_capture(self.pg_interfaces)
2275 self.pg_start()
Klement Sekeradab231a2016-12-21 08:50:14 +01002276 capture = self.pg0.get_capture(1)
Matus Fabianf78a70d2016-12-12 04:30:39 -08002277 p = capture[0]
2278 try:
2279 ip = p[IP]
2280 tcp = p[TCP]
Matus Fabian2ba92e32017-08-21 07:05:03 -07002281 self.assertEqual(ip.src, self.nat_addr)
Matus Fabianf78a70d2016-12-12 04:30:39 -08002282 self.assertEqual(ip.dst, server.ip4)
2283 self.assertNotEqual(tcp.sport, host_in_port)
2284 self.assertEqual(tcp.dport, server_in_port)
Klement Sekerad81ae412018-05-16 10:52:54 +02002285 self.assert_packet_checksums_valid(p)
Matus Fabianf78a70d2016-12-12 04:30:39 -08002286 host_out_port = tcp.sport
2287 except:
Klement Sekera9225dee2016-12-12 08:36:58 +01002288 self.logger.error(ppp("Unexpected or invalid packet:", p))
Matus Fabianf78a70d2016-12-12 04:30:39 -08002289 raise
2290
2291 # send reply from server to host
2292 p = (Ether(src=server.mac, dst=self.pg0.local_mac) /
Matus Fabian2ba92e32017-08-21 07:05:03 -07002293 IP(src=server.ip4, dst=self.nat_addr) /
Matus Fabianf78a70d2016-12-12 04:30:39 -08002294 TCP(sport=server_in_port, dport=host_out_port))
2295 self.pg0.add_stream(p)
2296 self.pg_enable_capture(self.pg_interfaces)
2297 self.pg_start()
Klement Sekeradab231a2016-12-21 08:50:14 +01002298 capture = self.pg0.get_capture(1)
Matus Fabianf78a70d2016-12-12 04:30:39 -08002299 p = capture[0]
2300 try:
2301 ip = p[IP]
2302 tcp = p[TCP]
Matus Fabian2ba92e32017-08-21 07:05:03 -07002303 self.assertEqual(ip.src, self.nat_addr)
Matus Fabianf78a70d2016-12-12 04:30:39 -08002304 self.assertEqual(ip.dst, host.ip4)
2305 self.assertEqual(tcp.sport, server_out_port)
2306 self.assertEqual(tcp.dport, host_in_port)
Klement Sekerad81ae412018-05-16 10:52:54 +02002307 self.assert_packet_checksums_valid(p)
Matus Fabianf78a70d2016-12-12 04:30:39 -08002308 except:
Matus Fabiane82488f2018-01-18 03:38:45 -08002309 self.logger.error(ppp("Unexpected or invalid packet:", p))
Matus Fabianf78a70d2016-12-12 04:30:39 -08002310 raise
2311
Matus Fabian6fa74c62017-06-05 05:55:48 -07002312 def test_hairpinning2(self):
Matus Fabian2ba92e32017-08-21 07:05:03 -07002313 """ NAT44 hairpinning - 1:1 NAT"""
Matus Fabian6fa74c62017-06-05 05:55:48 -07002314
2315 server1_nat_ip = "10.0.0.10"
2316 server2_nat_ip = "10.0.0.11"
2317 host = self.pg0.remote_hosts[0]
2318 server1 = self.pg0.remote_hosts[1]
2319 server2 = self.pg0.remote_hosts[2]
2320 server_tcp_port = 22
2321 server_udp_port = 20
2322
Matus Fabian2ba92e32017-08-21 07:05:03 -07002323 self.nat44_add_address(self.nat_addr)
2324 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
2325 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
2326 is_inside=0)
Matus Fabian6fa74c62017-06-05 05:55:48 -07002327
2328 # add static mapping for servers
Matus Fabian2ba92e32017-08-21 07:05:03 -07002329 self.nat44_add_static_mapping(server1.ip4, server1_nat_ip)
2330 self.nat44_add_static_mapping(server2.ip4, server2_nat_ip)
Matus Fabian6fa74c62017-06-05 05:55:48 -07002331
2332 # host to server1
2333 pkts = []
2334 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2335 IP(src=host.ip4, dst=server1_nat_ip) /
2336 TCP(sport=self.tcp_port_in, dport=server_tcp_port))
2337 pkts.append(p)
2338 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2339 IP(src=host.ip4, dst=server1_nat_ip) /
2340 UDP(sport=self.udp_port_in, dport=server_udp_port))
2341 pkts.append(p)
2342 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2343 IP(src=host.ip4, dst=server1_nat_ip) /
2344 ICMP(id=self.icmp_id_in, type='echo-request'))
2345 pkts.append(p)
2346 self.pg0.add_stream(pkts)
2347 self.pg_enable_capture(self.pg_interfaces)
2348 self.pg_start()
2349 capture = self.pg0.get_capture(len(pkts))
2350 for packet in capture:
2351 try:
Matus Fabian2ba92e32017-08-21 07:05:03 -07002352 self.assertEqual(packet[IP].src, self.nat_addr)
Matus Fabian6fa74c62017-06-05 05:55:48 -07002353 self.assertEqual(packet[IP].dst, server1.ip4)
2354 if packet.haslayer(TCP):
2355 self.assertNotEqual(packet[TCP].sport, self.tcp_port_in)
2356 self.assertEqual(packet[TCP].dport, server_tcp_port)
2357 self.tcp_port_out = packet[TCP].sport
Klement Sekerad81ae412018-05-16 10:52:54 +02002358 self.assert_packet_checksums_valid(packet)
Matus Fabian6fa74c62017-06-05 05:55:48 -07002359 elif packet.haslayer(UDP):
2360 self.assertNotEqual(packet[UDP].sport, self.udp_port_in)
2361 self.assertEqual(packet[UDP].dport, server_udp_port)
2362 self.udp_port_out = packet[UDP].sport
2363 else:
2364 self.assertNotEqual(packet[ICMP].id, self.icmp_id_in)
2365 self.icmp_id_out = packet[ICMP].id
2366 except:
2367 self.logger.error(ppp("Unexpected or invalid packet:", packet))
2368 raise
2369
2370 # server1 to host
2371 pkts = []
2372 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
Matus Fabian2ba92e32017-08-21 07:05:03 -07002373 IP(src=server1.ip4, dst=self.nat_addr) /
Matus Fabian6fa74c62017-06-05 05:55:48 -07002374 TCP(sport=server_tcp_port, dport=self.tcp_port_out))
2375 pkts.append(p)
2376 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
Matus Fabian2ba92e32017-08-21 07:05:03 -07002377 IP(src=server1.ip4, dst=self.nat_addr) /
Matus Fabian6fa74c62017-06-05 05:55:48 -07002378 UDP(sport=server_udp_port, dport=self.udp_port_out))
2379 pkts.append(p)
2380 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
Matus Fabian2ba92e32017-08-21 07:05:03 -07002381 IP(src=server1.ip4, dst=self.nat_addr) /
Matus Fabian6fa74c62017-06-05 05:55:48 -07002382 ICMP(id=self.icmp_id_out, type='echo-reply'))
2383 pkts.append(p)
2384 self.pg0.add_stream(pkts)
2385 self.pg_enable_capture(self.pg_interfaces)
2386 self.pg_start()
2387 capture = self.pg0.get_capture(len(pkts))
2388 for packet in capture:
2389 try:
2390 self.assertEqual(packet[IP].src, server1_nat_ip)
2391 self.assertEqual(packet[IP].dst, host.ip4)
2392 if packet.haslayer(TCP):
2393 self.assertEqual(packet[TCP].dport, self.tcp_port_in)
2394 self.assertEqual(packet[TCP].sport, server_tcp_port)
Klement Sekerad81ae412018-05-16 10:52:54 +02002395 self.assert_packet_checksums_valid(packet)
Matus Fabian6fa74c62017-06-05 05:55:48 -07002396 elif packet.haslayer(UDP):
2397 self.assertEqual(packet[UDP].dport, self.udp_port_in)
2398 self.assertEqual(packet[UDP].sport, server_udp_port)
2399 else:
2400 self.assertEqual(packet[ICMP].id, self.icmp_id_in)
2401 except:
2402 self.logger.error(ppp("Unexpected or invalid packet:", packet))
2403 raise
2404
2405 # server2 to server1
2406 pkts = []
2407 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2408 IP(src=server2.ip4, dst=server1_nat_ip) /
2409 TCP(sport=self.tcp_port_in, dport=server_tcp_port))
2410 pkts.append(p)
2411 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2412 IP(src=server2.ip4, dst=server1_nat_ip) /
2413 UDP(sport=self.udp_port_in, dport=server_udp_port))
2414 pkts.append(p)
2415 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2416 IP(src=server2.ip4, dst=server1_nat_ip) /
2417 ICMP(id=self.icmp_id_in, type='echo-request'))
2418 pkts.append(p)
2419 self.pg0.add_stream(pkts)
2420 self.pg_enable_capture(self.pg_interfaces)
2421 self.pg_start()
2422 capture = self.pg0.get_capture(len(pkts))
2423 for packet in capture:
2424 try:
2425 self.assertEqual(packet[IP].src, server2_nat_ip)
2426 self.assertEqual(packet[IP].dst, server1.ip4)
2427 if packet.haslayer(TCP):
2428 self.assertEqual(packet[TCP].sport, self.tcp_port_in)
2429 self.assertEqual(packet[TCP].dport, server_tcp_port)
2430 self.tcp_port_out = packet[TCP].sport
Klement Sekerad81ae412018-05-16 10:52:54 +02002431 self.assert_packet_checksums_valid(packet)
Matus Fabian6fa74c62017-06-05 05:55:48 -07002432 elif packet.haslayer(UDP):
2433 self.assertEqual(packet[UDP].sport, self.udp_port_in)
2434 self.assertEqual(packet[UDP].dport, server_udp_port)
2435 self.udp_port_out = packet[UDP].sport
2436 else:
2437 self.assertEqual(packet[ICMP].id, self.icmp_id_in)
2438 self.icmp_id_out = packet[ICMP].id
2439 except:
2440 self.logger.error(ppp("Unexpected or invalid packet:", packet))
2441 raise
2442
2443 # server1 to server2
2444 pkts = []
2445 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2446 IP(src=server1.ip4, dst=server2_nat_ip) /
2447 TCP(sport=server_tcp_port, dport=self.tcp_port_out))
2448 pkts.append(p)
2449 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2450 IP(src=server1.ip4, dst=server2_nat_ip) /
2451 UDP(sport=server_udp_port, dport=self.udp_port_out))
2452 pkts.append(p)
2453 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2454 IP(src=server1.ip4, dst=server2_nat_ip) /
2455 ICMP(id=self.icmp_id_out, type='echo-reply'))
2456 pkts.append(p)
2457 self.pg0.add_stream(pkts)
2458 self.pg_enable_capture(self.pg_interfaces)
2459 self.pg_start()
2460 capture = self.pg0.get_capture(len(pkts))
2461 for packet in capture:
2462 try:
2463 self.assertEqual(packet[IP].src, server1_nat_ip)
2464 self.assertEqual(packet[IP].dst, server2.ip4)
2465 if packet.haslayer(TCP):
2466 self.assertEqual(packet[TCP].dport, self.tcp_port_in)
2467 self.assertEqual(packet[TCP].sport, server_tcp_port)
Klement Sekerad81ae412018-05-16 10:52:54 +02002468 self.assert_packet_checksums_valid(packet)
Matus Fabian6fa74c62017-06-05 05:55:48 -07002469 elif packet.haslayer(UDP):
2470 self.assertEqual(packet[UDP].dport, self.udp_port_in)
2471 self.assertEqual(packet[UDP].sport, server_udp_port)
2472 else:
2473 self.assertEqual(packet[ICMP].id, self.icmp_id_in)
2474 except:
2475 self.logger.error(ppp("Unexpected or invalid packet:", packet))
2476 raise
2477
Matus Fabian9902fcd2016-12-21 23:58:46 -08002478 def test_max_translations_per_user(self):
2479 """ MAX translations per user - recycle the least recently used """
2480
Matus Fabian2ba92e32017-08-21 07:05:03 -07002481 self.nat44_add_address(self.nat_addr)
2482 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
2483 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
2484 is_inside=0)
Matus Fabian9902fcd2016-12-21 23:58:46 -08002485
2486 # get maximum number of translations per user
Matus Fabian2ba92e32017-08-21 07:05:03 -07002487 nat44_config = self.vapi.nat_show_config()
Matus Fabian9902fcd2016-12-21 23:58:46 -08002488
2489 # send more than maximum number of translations per user packets
Matus Fabian2ba92e32017-08-21 07:05:03 -07002490 pkts_num = nat44_config.max_translations_per_user + 5
Matus Fabian9902fcd2016-12-21 23:58:46 -08002491 pkts = []
2492 for port in range(0, pkts_num):
2493 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2494 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
2495 TCP(sport=1025 + port))
2496 pkts.append(p)
2497 self.pg0.add_stream(pkts)
2498 self.pg_enable_capture(self.pg_interfaces)
2499 self.pg_start()
2500
2501 # verify number of translated packet
Klement Sekeradab231a2016-12-21 08:50:14 +01002502 self.pg1.get_capture(pkts_num)
Matus Fabian9902fcd2016-12-21 23:58:46 -08002503
Matus Fabian132dc492018-05-09 04:51:03 -07002504 users = self.vapi.nat44_user_dump()
2505 for user in users:
2506 if user.ip_address == self.pg0.remote_ip4n:
2507 self.assertEqual(user.nsessions,
2508 nat44_config.max_translations_per_user)
2509 self.assertEqual(user.nstaticsessions, 0)
2510
2511 tcp_port = 22
2512 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
2513 tcp_port, tcp_port,
2514 proto=IP_PROTOS.tcp)
2515 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2516 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
2517 TCP(sport=tcp_port))
2518 self.pg0.add_stream(p)
2519 self.pg_enable_capture(self.pg_interfaces)
2520 self.pg_start()
2521 self.pg1.get_capture(1)
2522 users = self.vapi.nat44_user_dump()
2523 for user in users:
2524 if user.ip_address == self.pg0.remote_ip4n:
2525 self.assertEqual(user.nsessions,
2526 nat44_config.max_translations_per_user - 1)
2527 self.assertEqual(user.nstaticsessions, 1)
2528
Matus Fabian8bf68e82017-01-12 04:24:35 -08002529 def test_interface_addr(self):
Matus Fabian2ba92e32017-08-21 07:05:03 -07002530 """ Acquire NAT44 addresses from interface """
2531 self.vapi.nat44_add_interface_addr(self.pg7.sw_if_index)
Matus Fabian8bf68e82017-01-12 04:24:35 -08002532
2533 # no address in NAT pool
Matus Fabian2ba92e32017-08-21 07:05:03 -07002534 adresses = self.vapi.nat44_address_dump()
Matus Fabian8bf68e82017-01-12 04:24:35 -08002535 self.assertEqual(0, len(adresses))
2536
2537 # configure interface address and check NAT address pool
2538 self.pg7.config_ip4()
Matus Fabian2ba92e32017-08-21 07:05:03 -07002539 adresses = self.vapi.nat44_address_dump()
Matus Fabian8bf68e82017-01-12 04:24:35 -08002540 self.assertEqual(1, len(adresses))
Matus Fabian36532bd2017-01-23 23:42:28 -08002541 self.assertEqual(adresses[0].ip_address[0:4], self.pg7.local_ip4n)
Matus Fabian8bf68e82017-01-12 04:24:35 -08002542
2543 # remove interface address and check NAT address pool
2544 self.pg7.unconfig_ip4()
Matus Fabian2ba92e32017-08-21 07:05:03 -07002545 adresses = self.vapi.nat44_address_dump()
Matus Fabian8bf68e82017-01-12 04:24:35 -08002546 self.assertEqual(0, len(adresses))
2547
Matus Fabian36532bd2017-01-23 23:42:28 -08002548 def test_interface_addr_static_mapping(self):
2549 """ Static mapping with addresses from interface """
Matus Fabian5f224992018-01-25 21:59:16 -08002550 tag = "testTAG"
2551
Matus Fabian2ba92e32017-08-21 07:05:03 -07002552 self.vapi.nat44_add_interface_addr(self.pg7.sw_if_index)
2553 self.nat44_add_static_mapping(
2554 '1.2.3.4',
Matus Fabian5f224992018-01-25 21:59:16 -08002555 external_sw_if_index=self.pg7.sw_if_index,
2556 tag=tag)
Matus Fabian36532bd2017-01-23 23:42:28 -08002557
Matus Fabiane22e5462017-02-14 23:33:43 -08002558 # static mappings with external interface
Matus Fabian2ba92e32017-08-21 07:05:03 -07002559 static_mappings = self.vapi.nat44_static_mapping_dump()
Matus Fabiane22e5462017-02-14 23:33:43 -08002560 self.assertEqual(1, len(static_mappings))
2561 self.assertEqual(self.pg7.sw_if_index,
2562 static_mappings[0].external_sw_if_index)
Matus Fabian5f224992018-01-25 21:59:16 -08002563 self.assertEqual((static_mappings[0].tag).split('\0', 1)[0], tag)
Matus Fabian36532bd2017-01-23 23:42:28 -08002564
2565 # configure interface address and check static mappings
2566 self.pg7.config_ip4()
Matus Fabian2ba92e32017-08-21 07:05:03 -07002567 static_mappings = self.vapi.nat44_static_mapping_dump()
Matus Fabianea2600a2018-03-28 04:06:26 -07002568 self.assertEqual(2, len(static_mappings))
2569 resolved = False
2570 for sm in static_mappings:
2571 if sm.external_sw_if_index == 0xFFFFFFFF:
2572 self.assertEqual(sm.external_ip_address[0:4],
2573 self.pg7.local_ip4n)
2574 self.assertEqual((sm.tag).split('\0', 1)[0], tag)
2575 resolved = True
2576 self.assertTrue(resolved)
Matus Fabian36532bd2017-01-23 23:42:28 -08002577
2578 # remove interface address and check static mappings
2579 self.pg7.unconfig_ip4()
Matus Fabian2ba92e32017-08-21 07:05:03 -07002580 static_mappings = self.vapi.nat44_static_mapping_dump()
Matus Fabianea2600a2018-03-28 04:06:26 -07002581 self.assertEqual(1, len(static_mappings))
2582 self.assertEqual(self.pg7.sw_if_index,
2583 static_mappings[0].external_sw_if_index)
2584 self.assertEqual((static_mappings[0].tag).split('\0', 1)[0], tag)
2585
2586 # configure interface address again and check static mappings
2587 self.pg7.config_ip4()
2588 static_mappings = self.vapi.nat44_static_mapping_dump()
2589 self.assertEqual(2, len(static_mappings))
2590 resolved = False
2591 for sm in static_mappings:
2592 if sm.external_sw_if_index == 0xFFFFFFFF:
2593 self.assertEqual(sm.external_ip_address[0:4],
2594 self.pg7.local_ip4n)
2595 self.assertEqual((sm.tag).split('\0', 1)[0], tag)
2596 resolved = True
2597 self.assertTrue(resolved)
2598
2599 # remove static mapping
2600 self.nat44_add_static_mapping(
2601 '1.2.3.4',
2602 external_sw_if_index=self.pg7.sw_if_index,
2603 tag=tag,
2604 is_add=0)
2605 static_mappings = self.vapi.nat44_static_mapping_dump()
Matus Fabian36532bd2017-01-23 23:42:28 -08002606 self.assertEqual(0, len(static_mappings))
2607
Matus Fabianab7a8052017-11-28 04:29:41 -08002608 def test_interface_addr_identity_nat(self):
2609 """ Identity NAT with addresses from interface """
2610
2611 port = 53053
2612 self.vapi.nat44_add_interface_addr(self.pg7.sw_if_index)
2613 self.vapi.nat44_add_del_identity_mapping(
2614 sw_if_index=self.pg7.sw_if_index,
2615 port=port,
2616 protocol=IP_PROTOS.tcp,
2617 addr_only=0)
2618
2619 # identity mappings with external interface
2620 identity_mappings = self.vapi.nat44_identity_mapping_dump()
2621 self.assertEqual(1, len(identity_mappings))
2622 self.assertEqual(self.pg7.sw_if_index,
2623 identity_mappings[0].sw_if_index)
2624
2625 # configure interface address and check identity mappings
2626 self.pg7.config_ip4()
2627 identity_mappings = self.vapi.nat44_identity_mapping_dump()
Matus Fabianea2600a2018-03-28 04:06:26 -07002628 resolved = False
2629 self.assertEqual(2, len(identity_mappings))
2630 for sm in identity_mappings:
2631 if sm.sw_if_index == 0xFFFFFFFF:
2632 self.assertEqual(identity_mappings[0].ip_address,
2633 self.pg7.local_ip4n)
2634 self.assertEqual(port, identity_mappings[0].port)
2635 self.assertEqual(IP_PROTOS.tcp, identity_mappings[0].protocol)
2636 resolved = True
2637 self.assertTrue(resolved)
Matus Fabianab7a8052017-11-28 04:29:41 -08002638
2639 # remove interface address and check identity mappings
2640 self.pg7.unconfig_ip4()
2641 identity_mappings = self.vapi.nat44_identity_mapping_dump()
Matus Fabianea2600a2018-03-28 04:06:26 -07002642 self.assertEqual(1, len(identity_mappings))
2643 self.assertEqual(self.pg7.sw_if_index,
2644 identity_mappings[0].sw_if_index)
Matus Fabianab7a8052017-11-28 04:29:41 -08002645
Matus Fabianeea28d72017-01-13 04:15:54 -08002646 def test_ipfix_nat44_sess(self):
Matus Fabian2ba92e32017-08-21 07:05:03 -07002647 """ IPFIX logging NAT44 session created/delted """
Matus Fabian6631e9c2017-05-24 01:52:20 -07002648 self.ipfix_domain_id = 10
2649 self.ipfix_src_port = 20202
2650 colector_port = 30303
2651 bind_layers(UDP, IPFIX, dport=30303)
Matus Fabian2ba92e32017-08-21 07:05:03 -07002652 self.nat44_add_address(self.nat_addr)
2653 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
2654 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
2655 is_inside=0)
Matus Fabianeea28d72017-01-13 04:15:54 -08002656 self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4n,
2657 src_address=self.pg3.local_ip4n,
2658 path_mtu=512,
Matus Fabian6631e9c2017-05-24 01:52:20 -07002659 template_interval=10,
2660 collector_port=colector_port)
Matus Fabian2ba92e32017-08-21 07:05:03 -07002661 self.vapi.nat_ipfix(domain_id=self.ipfix_domain_id,
2662 src_port=self.ipfix_src_port)
Matus Fabianeea28d72017-01-13 04:15:54 -08002663
2664 pkts = self.create_stream_in(self.pg0, self.pg1)
2665 self.pg0.add_stream(pkts)
2666 self.pg_enable_capture(self.pg_interfaces)
2667 self.pg_start()
2668 capture = self.pg1.get_capture(len(pkts))
2669 self.verify_capture_out(capture)
Matus Fabian2ba92e32017-08-21 07:05:03 -07002670 self.nat44_add_address(self.nat_addr, is_add=0)
Matus Fabianeea28d72017-01-13 04:15:54 -08002671 self.vapi.cli("ipfix flush") # FIXME this should be an API call
Matus Fabiana431ad12018-01-04 04:03:14 -08002672 capture = self.pg3.get_capture(9)
Matus Fabianeea28d72017-01-13 04:15:54 -08002673 ipfix = IPFIXDecoder()
2674 # first load template
2675 for p in capture:
2676 self.assertTrue(p.haslayer(IPFIX))
Matus Fabian6631e9c2017-05-24 01:52:20 -07002677 self.assertEqual(p[IP].src, self.pg3.local_ip4)
2678 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
2679 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
2680 self.assertEqual(p[UDP].dport, colector_port)
2681 self.assertEqual(p[IPFIX].observationDomainID,
2682 self.ipfix_domain_id)
Matus Fabianeea28d72017-01-13 04:15:54 -08002683 if p.haslayer(Template):
2684 ipfix.add_template(p.getlayer(Template))
2685 # verify events in data set
2686 for p in capture:
2687 if p.haslayer(Data):
2688 data = ipfix.decode_data_set(p.getlayer(Set))
2689 self.verify_ipfix_nat44_ses(data)
2690
2691 def test_ipfix_addr_exhausted(self):
Matus Fabian2ba92e32017-08-21 07:05:03 -07002692 """ IPFIX logging NAT addresses exhausted """
2693 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
2694 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
2695 is_inside=0)
Matus Fabianeea28d72017-01-13 04:15:54 -08002696 self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4n,
2697 src_address=self.pg3.local_ip4n,
2698 path_mtu=512,
2699 template_interval=10)
Matus Fabian2ba92e32017-08-21 07:05:03 -07002700 self.vapi.nat_ipfix(domain_id=self.ipfix_domain_id,
2701 src_port=self.ipfix_src_port)
Matus Fabianeea28d72017-01-13 04:15:54 -08002702
2703 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
2704 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
2705 TCP(sport=3025))
2706 self.pg0.add_stream(p)
2707 self.pg_enable_capture(self.pg_interfaces)
2708 self.pg_start()
Matus Fabian229c1aa2018-05-28 04:09:52 -07002709 self.pg1.assert_nothing_captured()
2710 sleep(1)
Matus Fabianeea28d72017-01-13 04:15:54 -08002711 self.vapi.cli("ipfix flush") # FIXME this should be an API call
Matus Fabiana431ad12018-01-04 04:03:14 -08002712 capture = self.pg3.get_capture(9)
Matus Fabianeea28d72017-01-13 04:15:54 -08002713 ipfix = IPFIXDecoder()
2714 # first load template
2715 for p in capture:
2716 self.assertTrue(p.haslayer(IPFIX))
Matus Fabian6631e9c2017-05-24 01:52:20 -07002717 self.assertEqual(p[IP].src, self.pg3.local_ip4)
2718 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
2719 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
2720 self.assertEqual(p[UDP].dport, 4739)
2721 self.assertEqual(p[IPFIX].observationDomainID,
2722 self.ipfix_domain_id)
Matus Fabianeea28d72017-01-13 04:15:54 -08002723 if p.haslayer(Template):
2724 ipfix.add_template(p.getlayer(Template))
2725 # verify events in data set
2726 for p in capture:
2727 if p.haslayer(Data):
2728 data = ipfix.decode_data_set(p.getlayer(Set))
2729 self.verify_ipfix_addr_exhausted(data)
2730
Paul Vinciguerradefde0f2018-12-06 07:46:13 -08002731 @unittest.skipUnless(running_extended_tests, "part of extended tests")
Matus Fabiana431ad12018-01-04 04:03:14 -08002732 def test_ipfix_max_sessions(self):
2733 """ IPFIX logging maximum session entries exceeded """
2734 self.nat44_add_address(self.nat_addr)
2735 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
2736 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
2737 is_inside=0)
2738
2739 nat44_config = self.vapi.nat_show_config()
2740 max_sessions = 10 * nat44_config.translation_buckets
2741
2742 pkts = []
2743 for i in range(0, max_sessions):
2744 src = "10.10.%u.%u" % ((i & 0xFF00) >> 8, i & 0xFF)
2745 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2746 IP(src=src, dst=self.pg1.remote_ip4) /
2747 TCP(sport=1025))
2748 pkts.append(p)
2749 self.pg0.add_stream(pkts)
2750 self.pg_enable_capture(self.pg_interfaces)
2751 self.pg_start()
2752
2753 self.pg1.get_capture(max_sessions)
2754 self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4n,
2755 src_address=self.pg3.local_ip4n,
2756 path_mtu=512,
2757 template_interval=10)
2758 self.vapi.nat_ipfix(domain_id=self.ipfix_domain_id,
2759 src_port=self.ipfix_src_port)
2760
2761 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2762 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
2763 TCP(sport=1025))
2764 self.pg0.add_stream(p)
2765 self.pg_enable_capture(self.pg_interfaces)
2766 self.pg_start()
Matus Fabian229c1aa2018-05-28 04:09:52 -07002767 self.pg1.assert_nothing_captured()
2768 sleep(1)
Matus Fabiana431ad12018-01-04 04:03:14 -08002769 self.vapi.cli("ipfix flush") # FIXME this should be an API call
2770 capture = self.pg3.get_capture(9)
2771 ipfix = IPFIXDecoder()
2772 # first load template
2773 for p in capture:
2774 self.assertTrue(p.haslayer(IPFIX))
2775 self.assertEqual(p[IP].src, self.pg3.local_ip4)
2776 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
2777 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
2778 self.assertEqual(p[UDP].dport, 4739)
2779 self.assertEqual(p[IPFIX].observationDomainID,
2780 self.ipfix_domain_id)
2781 if p.haslayer(Template):
2782 ipfix.add_template(p.getlayer(Template))
2783 # verify events in data set
2784 for p in capture:
2785 if p.haslayer(Data):
2786 data = ipfix.decode_data_set(p.getlayer(Set))
2787 self.verify_ipfix_max_sessions(data, max_sessions)
2788
Matus Fabianad1f3e12018-11-28 21:26:34 -08002789 def test_syslog_apmap(self):
2790 """ Test syslog address and port mapping creation and deletion """
2791 self.vapi.syslog_set_filter(SYSLOG_SEVERITY.INFO)
2792 self.vapi.syslog_set_sender(self.pg3.remote_ip4n, self.pg3.local_ip4n)
2793 self.nat44_add_address(self.nat_addr)
2794 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
2795 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
2796 is_inside=0)
2797
2798 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
2799 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
2800 TCP(sport=self.tcp_port_in, dport=20))
2801 self.pg0.add_stream(p)
2802 self.pg_enable_capture(self.pg_interfaces)
2803 self.pg_start()
2804 capture = self.pg1.get_capture(1)
2805 self.tcp_port_out = capture[0][TCP].sport
2806 capture = self.pg3.get_capture(1)
2807 self.verify_syslog_apmap(capture[0][Raw].load)
2808
2809 self.pg_enable_capture(self.pg_interfaces)
2810 self.pg_start()
2811 self.nat44_add_address(self.nat_addr, is_add=0)
2812 capture = self.pg3.get_capture(1)
2813 self.verify_syslog_apmap(capture[0][Raw].load, False)
2814
Matus Fabiane1ae29a2017-01-27 00:47:58 -08002815 def test_pool_addr_fib(self):
Matus Fabian2ba92e32017-08-21 07:05:03 -07002816 """ NAT44 add pool addresses to FIB """
Matus Fabiane1ae29a2017-01-27 00:47:58 -08002817 static_addr = '10.0.0.10'
Matus Fabian2ba92e32017-08-21 07:05:03 -07002818 self.nat44_add_address(self.nat_addr)
2819 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
2820 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
2821 is_inside=0)
2822 self.nat44_add_static_mapping(self.pg0.remote_ip4, static_addr)
Matus Fabiane1ae29a2017-01-27 00:47:58 -08002823
Matus Fabian2ba92e32017-08-21 07:05:03 -07002824 # NAT44 address
Matus Fabiane1ae29a2017-01-27 00:47:58 -08002825 p = (Ether(src=self.pg1.remote_mac, dst='ff:ff:ff:ff:ff:ff') /
Matus Fabian2ba92e32017-08-21 07:05:03 -07002826 ARP(op=ARP.who_has, pdst=self.nat_addr,
Matus Fabiane1ae29a2017-01-27 00:47:58 -08002827 psrc=self.pg1.remote_ip4, hwsrc=self.pg1.remote_mac))
2828 self.pg1.add_stream(p)
2829 self.pg_enable_capture(self.pg_interfaces)
2830 self.pg_start()
2831 capture = self.pg1.get_capture(1)
2832 self.assertTrue(capture[0].haslayer(ARP))
2833 self.assertTrue(capture[0][ARP].op, ARP.is_at)
2834
2835 # 1:1 NAT address
2836 p = (Ether(src=self.pg1.remote_mac, dst='ff:ff:ff:ff:ff:ff') /
2837 ARP(op=ARP.who_has, pdst=static_addr,
2838 psrc=self.pg1.remote_ip4, hwsrc=self.pg1.remote_mac))
2839 self.pg1.add_stream(p)
2840 self.pg_enable_capture(self.pg_interfaces)
2841 self.pg_start()
2842 capture = self.pg1.get_capture(1)
2843 self.assertTrue(capture[0].haslayer(ARP))
2844 self.assertTrue(capture[0][ARP].op, ARP.is_at)
2845
Matus Fabian2ba92e32017-08-21 07:05:03 -07002846 # send ARP to non-NAT44 interface
Matus Fabiane1ae29a2017-01-27 00:47:58 -08002847 p = (Ether(src=self.pg2.remote_mac, dst='ff:ff:ff:ff:ff:ff') /
Matus Fabian2ba92e32017-08-21 07:05:03 -07002848 ARP(op=ARP.who_has, pdst=self.nat_addr,
Matus Fabiane1ae29a2017-01-27 00:47:58 -08002849 psrc=self.pg2.remote_ip4, hwsrc=self.pg2.remote_mac))
2850 self.pg2.add_stream(p)
2851 self.pg_enable_capture(self.pg_interfaces)
2852 self.pg_start()
Matus Fabian229c1aa2018-05-28 04:09:52 -07002853 self.pg1.assert_nothing_captured()
Matus Fabiane1ae29a2017-01-27 00:47:58 -08002854
2855 # remove addresses and verify
Matus Fabian2ba92e32017-08-21 07:05:03 -07002856 self.nat44_add_address(self.nat_addr, is_add=0)
2857 self.nat44_add_static_mapping(self.pg0.remote_ip4, static_addr,
2858 is_add=0)
Matus Fabiane1ae29a2017-01-27 00:47:58 -08002859
2860 p = (Ether(src=self.pg1.remote_mac, dst='ff:ff:ff:ff:ff:ff') /
Matus Fabian2ba92e32017-08-21 07:05:03 -07002861 ARP(op=ARP.who_has, pdst=self.nat_addr,
Matus Fabiane1ae29a2017-01-27 00:47:58 -08002862 psrc=self.pg1.remote_ip4, hwsrc=self.pg1.remote_mac))
2863 self.pg1.add_stream(p)
2864 self.pg_enable_capture(self.pg_interfaces)
2865 self.pg_start()
Matus Fabian229c1aa2018-05-28 04:09:52 -07002866 self.pg1.assert_nothing_captured()
Matus Fabiane1ae29a2017-01-27 00:47:58 -08002867
2868 p = (Ether(src=self.pg1.remote_mac, dst='ff:ff:ff:ff:ff:ff') /
2869 ARP(op=ARP.who_has, pdst=static_addr,
2870 psrc=self.pg1.remote_ip4, hwsrc=self.pg1.remote_mac))
2871 self.pg1.add_stream(p)
2872 self.pg_enable_capture(self.pg_interfaces)
2873 self.pg_start()
Matus Fabian229c1aa2018-05-28 04:09:52 -07002874 self.pg1.assert_nothing_captured()
Matus Fabiane1ae29a2017-01-27 00:47:58 -08002875
Juraj Slobodaeab38d92017-03-06 19:55:21 -08002876 def test_vrf_mode(self):
Matus Fabian2ba92e32017-08-21 07:05:03 -07002877 """ NAT44 tenant VRF aware address pool mode """
Juraj Slobodaeab38d92017-03-06 19:55:21 -08002878
2879 vrf_id1 = 1
2880 vrf_id2 = 2
2881 nat_ip1 = "10.0.0.10"
2882 nat_ip2 = "10.0.0.11"
2883
2884 self.pg0.unconfig_ip4()
2885 self.pg1.unconfig_ip4()
Neale Ranns15002542017-09-10 04:39:11 -07002886 self.vapi.ip_table_add_del(vrf_id1, is_add=1)
2887 self.vapi.ip_table_add_del(vrf_id2, is_add=1)
Juraj Slobodaeab38d92017-03-06 19:55:21 -08002888 self.pg0.set_table_ip4(vrf_id1)
2889 self.pg1.set_table_ip4(vrf_id2)
2890 self.pg0.config_ip4()
2891 self.pg1.config_ip4()
Matus Fabian8008d7c2018-07-09 01:34:20 -07002892 self.pg0.resolve_arp()
2893 self.pg1.resolve_arp()
Juraj Slobodaeab38d92017-03-06 19:55:21 -08002894
Matus Fabian2ba92e32017-08-21 07:05:03 -07002895 self.nat44_add_address(nat_ip1, vrf_id=vrf_id1)
2896 self.nat44_add_address(nat_ip2, vrf_id=vrf_id2)
2897 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
2898 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index)
2899 self.vapi.nat44_interface_add_del_feature(self.pg2.sw_if_index,
2900 is_inside=0)
Juraj Slobodaeab38d92017-03-06 19:55:21 -08002901
Matus Fabian8008d7c2018-07-09 01:34:20 -07002902 try:
2903 # first VRF
2904 pkts = self.create_stream_in(self.pg0, self.pg2)
2905 self.pg0.add_stream(pkts)
2906 self.pg_enable_capture(self.pg_interfaces)
2907 self.pg_start()
2908 capture = self.pg2.get_capture(len(pkts))
2909 self.verify_capture_out(capture, nat_ip1)
Juraj Slobodaeab38d92017-03-06 19:55:21 -08002910
Matus Fabian8008d7c2018-07-09 01:34:20 -07002911 # second VRF
2912 pkts = self.create_stream_in(self.pg1, self.pg2)
2913 self.pg1.add_stream(pkts)
2914 self.pg_enable_capture(self.pg_interfaces)
2915 self.pg_start()
2916 capture = self.pg2.get_capture(len(pkts))
2917 self.verify_capture_out(capture, nat_ip2)
Juraj Slobodaeab38d92017-03-06 19:55:21 -08002918
Matus Fabian8008d7c2018-07-09 01:34:20 -07002919 finally:
2920 self.pg0.unconfig_ip4()
2921 self.pg1.unconfig_ip4()
2922 self.pg0.set_table_ip4(0)
2923 self.pg1.set_table_ip4(0)
2924 self.pg0.config_ip4()
2925 self.pg1.config_ip4()
2926 self.pg0.resolve_arp()
2927 self.pg1.resolve_arp()
2928 self.vapi.ip_table_add_del(vrf_id1, is_add=0)
2929 self.vapi.ip_table_add_del(vrf_id2, is_add=0)
Neale Ranns15002542017-09-10 04:39:11 -07002930
Juraj Slobodaeab38d92017-03-06 19:55:21 -08002931 def test_vrf_feature_independent(self):
Matus Fabian2ba92e32017-08-21 07:05:03 -07002932 """ NAT44 tenant VRF independent address pool mode """
Juraj Slobodaeab38d92017-03-06 19:55:21 -08002933
2934 nat_ip1 = "10.0.0.10"
2935 nat_ip2 = "10.0.0.11"
2936
Matus Fabian2ba92e32017-08-21 07:05:03 -07002937 self.nat44_add_address(nat_ip1)
Matus Fabian51e759f2017-12-07 23:22:51 -08002938 self.nat44_add_address(nat_ip2, vrf_id=99)
Matus Fabian2ba92e32017-08-21 07:05:03 -07002939 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
2940 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index)
2941 self.vapi.nat44_interface_add_del_feature(self.pg2.sw_if_index,
2942 is_inside=0)
Juraj Slobodaeab38d92017-03-06 19:55:21 -08002943
2944 # first VRF
2945 pkts = self.create_stream_in(self.pg0, self.pg2)
2946 self.pg0.add_stream(pkts)
2947 self.pg_enable_capture(self.pg_interfaces)
2948 self.pg_start()
2949 capture = self.pg2.get_capture(len(pkts))
2950 self.verify_capture_out(capture, nat_ip1)
2951
2952 # second VRF
2953 pkts = self.create_stream_in(self.pg1, self.pg2)
2954 self.pg1.add_stream(pkts)
2955 self.pg_enable_capture(self.pg_interfaces)
2956 self.pg_start()
2957 capture = self.pg2.get_capture(len(pkts))
2958 self.verify_capture_out(capture, nat_ip1)
2959
Martin Gálik406eb1d2017-05-04 04:35:04 -07002960 def test_dynamic_ipless_interfaces(self):
Matus Fabian2ba92e32017-08-21 07:05:03 -07002961 """ NAT44 interfaces without configured IP address """
Martin Gálik406eb1d2017-05-04 04:35:04 -07002962
2963 self.vapi.ip_neighbor_add_del(self.pg7.sw_if_index,
Ole Troan8006c6a2018-12-17 12:02:26 +01002964 mac_pton(self.pg7.remote_mac),
Martin Gálik406eb1d2017-05-04 04:35:04 -07002965 self.pg7.remote_ip4n,
2966 is_static=1)
2967 self.vapi.ip_neighbor_add_del(self.pg8.sw_if_index,
Ole Troan8006c6a2018-12-17 12:02:26 +01002968 mac_pton(self.pg8.remote_mac),
Martin Gálik406eb1d2017-05-04 04:35:04 -07002969 self.pg8.remote_ip4n,
2970 is_static=1)
2971
2972 self.vapi.ip_add_del_route(dst_address=self.pg7.remote_ip4n,
2973 dst_address_length=32,
2974 next_hop_address=self.pg7.remote_ip4n,
2975 next_hop_sw_if_index=self.pg7.sw_if_index)
2976 self.vapi.ip_add_del_route(dst_address=self.pg8.remote_ip4n,
2977 dst_address_length=32,
2978 next_hop_address=self.pg8.remote_ip4n,
2979 next_hop_sw_if_index=self.pg8.sw_if_index)
2980
Matus Fabian2ba92e32017-08-21 07:05:03 -07002981 self.nat44_add_address(self.nat_addr)
2982 self.vapi.nat44_interface_add_del_feature(self.pg7.sw_if_index)
2983 self.vapi.nat44_interface_add_del_feature(self.pg8.sw_if_index,
2984 is_inside=0)
Martin Gálik406eb1d2017-05-04 04:35:04 -07002985
2986 # in2out
2987 pkts = self.create_stream_in(self.pg7, self.pg8)
2988 self.pg7.add_stream(pkts)
2989 self.pg_enable_capture(self.pg_interfaces)
2990 self.pg_start()
2991 capture = self.pg8.get_capture(len(pkts))
2992 self.verify_capture_out(capture)
2993
2994 # out2in
Matus Fabian2ba92e32017-08-21 07:05:03 -07002995 pkts = self.create_stream_out(self.pg8, self.nat_addr)
Martin Gálik406eb1d2017-05-04 04:35:04 -07002996 self.pg8.add_stream(pkts)
2997 self.pg_enable_capture(self.pg_interfaces)
2998 self.pg_start()
2999 capture = self.pg7.get_capture(len(pkts))
3000 self.verify_capture_in(capture, self.pg7)
3001
3002 def test_static_ipless_interfaces(self):
Matus Fabian2ba92e32017-08-21 07:05:03 -07003003 """ NAT44 interfaces without configured IP address - 1:1 NAT """
Martin Gálik406eb1d2017-05-04 04:35:04 -07003004
3005 self.vapi.ip_neighbor_add_del(self.pg7.sw_if_index,
Ole Troan8006c6a2018-12-17 12:02:26 +01003006 mac_pton(self.pg7.remote_mac),
Martin Gálik406eb1d2017-05-04 04:35:04 -07003007 self.pg7.remote_ip4n,
3008 is_static=1)
3009 self.vapi.ip_neighbor_add_del(self.pg8.sw_if_index,
Ole Troan8006c6a2018-12-17 12:02:26 +01003010 mac_pton(self.pg8.remote_mac),
Martin Gálik406eb1d2017-05-04 04:35:04 -07003011 self.pg8.remote_ip4n,
3012 is_static=1)
3013
3014 self.vapi.ip_add_del_route(dst_address=self.pg7.remote_ip4n,
3015 dst_address_length=32,
3016 next_hop_address=self.pg7.remote_ip4n,
3017 next_hop_sw_if_index=self.pg7.sw_if_index)
3018 self.vapi.ip_add_del_route(dst_address=self.pg8.remote_ip4n,
3019 dst_address_length=32,
3020 next_hop_address=self.pg8.remote_ip4n,
3021 next_hop_sw_if_index=self.pg8.sw_if_index)
3022
Matus Fabian2ba92e32017-08-21 07:05:03 -07003023 self.nat44_add_static_mapping(self.pg7.remote_ip4, self.nat_addr)
3024 self.vapi.nat44_interface_add_del_feature(self.pg7.sw_if_index)
3025 self.vapi.nat44_interface_add_del_feature(self.pg8.sw_if_index,
3026 is_inside=0)
Martin Gálik406eb1d2017-05-04 04:35:04 -07003027
3028 # out2in
3029 pkts = self.create_stream_out(self.pg8)
3030 self.pg8.add_stream(pkts)
3031 self.pg_enable_capture(self.pg_interfaces)
3032 self.pg_start()
3033 capture = self.pg7.get_capture(len(pkts))
3034 self.verify_capture_in(capture, self.pg7)
3035
3036 # in2out
3037 pkts = self.create_stream_in(self.pg7, self.pg8)
3038 self.pg7.add_stream(pkts)
3039 self.pg_enable_capture(self.pg_interfaces)
3040 self.pg_start()
3041 capture = self.pg8.get_capture(len(pkts))
Matus Fabian2ba92e32017-08-21 07:05:03 -07003042 self.verify_capture_out(capture, self.nat_addr, True)
Martin Gálik406eb1d2017-05-04 04:35:04 -07003043
3044 def test_static_with_port_ipless_interfaces(self):
Matus Fabian2ba92e32017-08-21 07:05:03 -07003045 """ NAT44 interfaces without configured IP address - 1:1 NAPT """
Martin Gálik406eb1d2017-05-04 04:35:04 -07003046
3047 self.tcp_port_out = 30606
3048 self.udp_port_out = 30607
3049 self.icmp_id_out = 30608
3050
3051 self.vapi.ip_neighbor_add_del(self.pg7.sw_if_index,
Ole Troan8006c6a2018-12-17 12:02:26 +01003052 mac_pton(self.pg7.remote_mac),
Martin Gálik406eb1d2017-05-04 04:35:04 -07003053 self.pg7.remote_ip4n,
3054 is_static=1)
3055 self.vapi.ip_neighbor_add_del(self.pg8.sw_if_index,
Ole Troan8006c6a2018-12-17 12:02:26 +01003056 mac_pton(self.pg8.remote_mac),
Martin Gálik406eb1d2017-05-04 04:35:04 -07003057 self.pg8.remote_ip4n,
3058 is_static=1)
3059
3060 self.vapi.ip_add_del_route(dst_address=self.pg7.remote_ip4n,
3061 dst_address_length=32,
3062 next_hop_address=self.pg7.remote_ip4n,
3063 next_hop_sw_if_index=self.pg7.sw_if_index)
3064 self.vapi.ip_add_del_route(dst_address=self.pg8.remote_ip4n,
3065 dst_address_length=32,
3066 next_hop_address=self.pg8.remote_ip4n,
3067 next_hop_sw_if_index=self.pg8.sw_if_index)
3068
Matus Fabian2ba92e32017-08-21 07:05:03 -07003069 self.nat44_add_address(self.nat_addr)
3070 self.nat44_add_static_mapping(self.pg7.remote_ip4, self.nat_addr,
3071 self.tcp_port_in, self.tcp_port_out,
3072 proto=IP_PROTOS.tcp)
3073 self.nat44_add_static_mapping(self.pg7.remote_ip4, self.nat_addr,
3074 self.udp_port_in, self.udp_port_out,
3075 proto=IP_PROTOS.udp)
3076 self.nat44_add_static_mapping(self.pg7.remote_ip4, self.nat_addr,
3077 self.icmp_id_in, self.icmp_id_out,
3078 proto=IP_PROTOS.icmp)
3079 self.vapi.nat44_interface_add_del_feature(self.pg7.sw_if_index)
3080 self.vapi.nat44_interface_add_del_feature(self.pg8.sw_if_index,
3081 is_inside=0)
Martin Gálik406eb1d2017-05-04 04:35:04 -07003082
3083 # out2in
3084 pkts = self.create_stream_out(self.pg8)
3085 self.pg8.add_stream(pkts)
3086 self.pg_enable_capture(self.pg_interfaces)
3087 self.pg_start()
3088 capture = self.pg7.get_capture(len(pkts))
3089 self.verify_capture_in(capture, self.pg7)
3090
3091 # in2out
3092 pkts = self.create_stream_in(self.pg7, self.pg8)
3093 self.pg7.add_stream(pkts)
3094 self.pg_enable_capture(self.pg_interfaces)
3095 self.pg_start()
3096 capture = self.pg8.get_capture(len(pkts))
3097 self.verify_capture_out(capture)
3098
Matus Fabian328dbc82017-06-19 04:28:04 -07003099 def test_static_unknown_proto(self):
3100 """ 1:1 NAT translate packet with unknown protocol """
3101 nat_ip = "10.0.0.10"
Matus Fabian2ba92e32017-08-21 07:05:03 -07003102 self.nat44_add_static_mapping(self.pg0.remote_ip4, nat_ip)
3103 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3104 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3105 is_inside=0)
Matus Fabian328dbc82017-06-19 04:28:04 -07003106
3107 # in2out
3108 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
3109 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
3110 GRE() /
Matus Fabian1e8db5f2017-06-20 01:45:49 -07003111 IP(src=self.pg2.remote_ip4, dst=self.pg3.remote_ip4) /
Matus Fabian328dbc82017-06-19 04:28:04 -07003112 TCP(sport=1234, dport=1234))
3113 self.pg0.add_stream(p)
3114 self.pg_enable_capture(self.pg_interfaces)
3115 self.pg_start()
3116 p = self.pg1.get_capture(1)
3117 packet = p[0]
3118 try:
3119 self.assertEqual(packet[IP].src, nat_ip)
3120 self.assertEqual(packet[IP].dst, self.pg1.remote_ip4)
Paul Vinciguerra978aa642018-11-24 22:19:12 -08003121 self.assertEqual(packet.haslayer(GRE), 1)
Klement Sekerad81ae412018-05-16 10:52:54 +02003122 self.assert_packet_checksums_valid(packet)
Matus Fabian328dbc82017-06-19 04:28:04 -07003123 except:
3124 self.logger.error(ppp("Unexpected or invalid packet:", packet))
3125 raise
3126
3127 # out2in
3128 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
3129 IP(src=self.pg1.remote_ip4, dst=nat_ip) /
3130 GRE() /
Matus Fabian1e8db5f2017-06-20 01:45:49 -07003131 IP(src=self.pg3.remote_ip4, dst=self.pg2.remote_ip4) /
Matus Fabian328dbc82017-06-19 04:28:04 -07003132 TCP(sport=1234, dport=1234))
3133 self.pg1.add_stream(p)
3134 self.pg_enable_capture(self.pg_interfaces)
3135 self.pg_start()
3136 p = self.pg0.get_capture(1)
3137 packet = p[0]
3138 try:
3139 self.assertEqual(packet[IP].src, self.pg1.remote_ip4)
3140 self.assertEqual(packet[IP].dst, self.pg0.remote_ip4)
Paul Vinciguerra978aa642018-11-24 22:19:12 -08003141 self.assertEqual(packet.haslayer(GRE), 1)
Klement Sekerad81ae412018-05-16 10:52:54 +02003142 self.assert_packet_checksums_valid(packet)
Matus Fabian328dbc82017-06-19 04:28:04 -07003143 except:
3144 self.logger.error(ppp("Unexpected or invalid packet:", packet))
3145 raise
3146
Matus Fabian7968e6c2017-07-06 05:37:49 -07003147 def test_hairpinning_static_unknown_proto(self):
Matus Fabian1e8db5f2017-06-20 01:45:49 -07003148 """ 1:1 NAT translate packet with unknown protocol - hairpinning """
3149
3150 host = self.pg0.remote_hosts[0]
3151 server = self.pg0.remote_hosts[1]
3152
3153 host_nat_ip = "10.0.0.10"
3154 server_nat_ip = "10.0.0.11"
3155
Matus Fabian2ba92e32017-08-21 07:05:03 -07003156 self.nat44_add_static_mapping(host.ip4, host_nat_ip)
3157 self.nat44_add_static_mapping(server.ip4, server_nat_ip)
3158 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3159 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3160 is_inside=0)
Matus Fabian1e8db5f2017-06-20 01:45:49 -07003161
3162 # host to server
3163 p = (Ether(dst=self.pg0.local_mac, src=host.mac) /
3164 IP(src=host.ip4, dst=server_nat_ip) /
3165 GRE() /
3166 IP(src=self.pg2.remote_ip4, dst=self.pg3.remote_ip4) /
3167 TCP(sport=1234, dport=1234))
3168 self.pg0.add_stream(p)
3169 self.pg_enable_capture(self.pg_interfaces)
3170 self.pg_start()
3171 p = self.pg0.get_capture(1)
3172 packet = p[0]
3173 try:
3174 self.assertEqual(packet[IP].src, host_nat_ip)
3175 self.assertEqual(packet[IP].dst, server.ip4)
Paul Vinciguerra978aa642018-11-24 22:19:12 -08003176 self.assertEqual(packet.haslayer(GRE), 1)
Klement Sekerad81ae412018-05-16 10:52:54 +02003177 self.assert_packet_checksums_valid(packet)
Matus Fabian1e8db5f2017-06-20 01:45:49 -07003178 except:
3179 self.logger.error(ppp("Unexpected or invalid packet:", packet))
3180 raise
3181
3182 # server to host
3183 p = (Ether(dst=self.pg0.local_mac, src=server.mac) /
3184 IP(src=server.ip4, dst=host_nat_ip) /
3185 GRE() /
3186 IP(src=self.pg3.remote_ip4, dst=self.pg2.remote_ip4) /
3187 TCP(sport=1234, dport=1234))
3188 self.pg0.add_stream(p)
3189 self.pg_enable_capture(self.pg_interfaces)
3190 self.pg_start()
3191 p = self.pg0.get_capture(1)
3192 packet = p[0]
3193 try:
3194 self.assertEqual(packet[IP].src, server_nat_ip)
3195 self.assertEqual(packet[IP].dst, host.ip4)
Paul Vinciguerra978aa642018-11-24 22:19:12 -08003196 self.assertEqual(packet.haslayer(GRE), 1)
Klement Sekerad81ae412018-05-16 10:52:54 +02003197 self.assert_packet_checksums_valid(packet)
Matus Fabian1e8db5f2017-06-20 01:45:49 -07003198 except:
3199 self.logger.error(ppp("Unexpected or invalid packet:", packet))
3200 raise
3201
Matus Fabian93d84c92017-07-19 08:06:01 -07003202 def test_output_feature(self):
Matus Fabian2ba92e32017-08-21 07:05:03 -07003203 """ NAT44 interface output feature (in2out postrouting) """
3204 self.nat44_add_address(self.nat_addr)
3205 self.vapi.nat44_interface_add_del_output_feature(self.pg0.sw_if_index)
Matus Fabianb2d2fc72017-09-10 22:17:47 -07003206 self.vapi.nat44_interface_add_del_output_feature(self.pg1.sw_if_index)
3207 self.vapi.nat44_interface_add_del_output_feature(self.pg3.sw_if_index,
Matus Fabian2ba92e32017-08-21 07:05:03 -07003208 is_inside=0)
Matus Fabian93d84c92017-07-19 08:06:01 -07003209
3210 # in2out
Matus Fabianb2d2fc72017-09-10 22:17:47 -07003211 pkts = self.create_stream_in(self.pg0, self.pg3)
Matus Fabian93d84c92017-07-19 08:06:01 -07003212 self.pg0.add_stream(pkts)
3213 self.pg_enable_capture(self.pg_interfaces)
3214 self.pg_start()
Matus Fabianb2d2fc72017-09-10 22:17:47 -07003215 capture = self.pg3.get_capture(len(pkts))
Matus Fabian93d84c92017-07-19 08:06:01 -07003216 self.verify_capture_out(capture)
3217
3218 # out2in
Matus Fabianb2d2fc72017-09-10 22:17:47 -07003219 pkts = self.create_stream_out(self.pg3)
3220 self.pg3.add_stream(pkts)
Matus Fabian93d84c92017-07-19 08:06:01 -07003221 self.pg_enable_capture(self.pg_interfaces)
3222 self.pg_start()
3223 capture = self.pg0.get_capture(len(pkts))
3224 self.verify_capture_in(capture, self.pg0)
3225
Matus Fabianb2d2fc72017-09-10 22:17:47 -07003226 # from non-NAT interface to NAT inside interface
3227 pkts = self.create_stream_in(self.pg2, self.pg0)
3228 self.pg2.add_stream(pkts)
3229 self.pg_enable_capture(self.pg_interfaces)
3230 self.pg_start()
3231 capture = self.pg0.get_capture(len(pkts))
3232 self.verify_capture_no_translation(capture, self.pg2, self.pg0)
3233
Matus Fabian93d84c92017-07-19 08:06:01 -07003234 def test_output_feature_vrf_aware(self):
Matus Fabian2ba92e32017-08-21 07:05:03 -07003235 """ NAT44 interface output feature VRF aware (in2out postrouting) """
Matus Fabian93d84c92017-07-19 08:06:01 -07003236 nat_ip_vrf10 = "10.0.0.10"
3237 nat_ip_vrf20 = "10.0.0.20"
3238
3239 self.vapi.ip_add_del_route(dst_address=self.pg3.remote_ip4n,
3240 dst_address_length=32,
3241 next_hop_address=self.pg3.remote_ip4n,
3242 next_hop_sw_if_index=self.pg3.sw_if_index,
3243 table_id=10)
3244 self.vapi.ip_add_del_route(dst_address=self.pg3.remote_ip4n,
3245 dst_address_length=32,
3246 next_hop_address=self.pg3.remote_ip4n,
3247 next_hop_sw_if_index=self.pg3.sw_if_index,
3248 table_id=20)
3249
Matus Fabian2ba92e32017-08-21 07:05:03 -07003250 self.nat44_add_address(nat_ip_vrf10, vrf_id=10)
3251 self.nat44_add_address(nat_ip_vrf20, vrf_id=20)
3252 self.vapi.nat44_interface_add_del_output_feature(self.pg4.sw_if_index)
3253 self.vapi.nat44_interface_add_del_output_feature(self.pg6.sw_if_index)
3254 self.vapi.nat44_interface_add_del_output_feature(self.pg3.sw_if_index,
3255 is_inside=0)
Matus Fabian93d84c92017-07-19 08:06:01 -07003256
3257 # in2out VRF 10
3258 pkts = self.create_stream_in(self.pg4, self.pg3)
3259 self.pg4.add_stream(pkts)
3260 self.pg_enable_capture(self.pg_interfaces)
3261 self.pg_start()
3262 capture = self.pg3.get_capture(len(pkts))
3263 self.verify_capture_out(capture, nat_ip=nat_ip_vrf10)
3264
3265 # out2in VRF 10
3266 pkts = self.create_stream_out(self.pg3, dst_ip=nat_ip_vrf10)
3267 self.pg3.add_stream(pkts)
3268 self.pg_enable_capture(self.pg_interfaces)
3269 self.pg_start()
3270 capture = self.pg4.get_capture(len(pkts))
3271 self.verify_capture_in(capture, self.pg4)
3272
3273 # in2out VRF 20
3274 pkts = self.create_stream_in(self.pg6, self.pg3)
3275 self.pg6.add_stream(pkts)
3276 self.pg_enable_capture(self.pg_interfaces)
3277 self.pg_start()
3278 capture = self.pg3.get_capture(len(pkts))
3279 self.verify_capture_out(capture, nat_ip=nat_ip_vrf20)
3280
3281 # out2in VRF 20
3282 pkts = self.create_stream_out(self.pg3, dst_ip=nat_ip_vrf20)
3283 self.pg3.add_stream(pkts)
3284 self.pg_enable_capture(self.pg_interfaces)
3285 self.pg_start()
3286 capture = self.pg6.get_capture(len(pkts))
3287 self.verify_capture_in(capture, self.pg6)
3288
Matus Fabian161c59c2017-07-21 03:46:03 -07003289 def test_output_feature_hairpinning(self):
Matus Fabian2ba92e32017-08-21 07:05:03 -07003290 """ NAT44 interface output feature hairpinning (in2out postrouting) """
Matus Fabian93d84c92017-07-19 08:06:01 -07003291 host = self.pg0.remote_hosts[0]
3292 server = self.pg0.remote_hosts[1]
3293 host_in_port = 1234
3294 host_out_port = 0
3295 server_in_port = 5678
3296 server_out_port = 8765
3297
Matus Fabian2ba92e32017-08-21 07:05:03 -07003298 self.nat44_add_address(self.nat_addr)
3299 self.vapi.nat44_interface_add_del_output_feature(self.pg0.sw_if_index)
3300 self.vapi.nat44_interface_add_del_output_feature(self.pg1.sw_if_index,
3301 is_inside=0)
Matus Fabian93d84c92017-07-19 08:06:01 -07003302
3303 # add static mapping for server
Matus Fabian2ba92e32017-08-21 07:05:03 -07003304 self.nat44_add_static_mapping(server.ip4, self.nat_addr,
3305 server_in_port, server_out_port,
3306 proto=IP_PROTOS.tcp)
Matus Fabian93d84c92017-07-19 08:06:01 -07003307
3308 # send packet from host to server
3309 p = (Ether(src=host.mac, dst=self.pg0.local_mac) /
Matus Fabian2ba92e32017-08-21 07:05:03 -07003310 IP(src=host.ip4, dst=self.nat_addr) /
Matus Fabian93d84c92017-07-19 08:06:01 -07003311 TCP(sport=host_in_port, dport=server_out_port))
3312 self.pg0.add_stream(p)
3313 self.pg_enable_capture(self.pg_interfaces)
3314 self.pg_start()
3315 capture = self.pg0.get_capture(1)
3316 p = capture[0]
3317 try:
3318 ip = p[IP]
3319 tcp = p[TCP]
Matus Fabian2ba92e32017-08-21 07:05:03 -07003320 self.assertEqual(ip.src, self.nat_addr)
Matus Fabian93d84c92017-07-19 08:06:01 -07003321 self.assertEqual(ip.dst, server.ip4)
3322 self.assertNotEqual(tcp.sport, host_in_port)
3323 self.assertEqual(tcp.dport, server_in_port)
Klement Sekerad81ae412018-05-16 10:52:54 +02003324 self.assert_packet_checksums_valid(p)
Matus Fabian93d84c92017-07-19 08:06:01 -07003325 host_out_port = tcp.sport
3326 except:
3327 self.logger.error(ppp("Unexpected or invalid packet:", p))
3328 raise
3329
3330 # send reply from server to host
3331 p = (Ether(src=server.mac, dst=self.pg0.local_mac) /
Matus Fabian2ba92e32017-08-21 07:05:03 -07003332 IP(src=server.ip4, dst=self.nat_addr) /
Matus Fabian93d84c92017-07-19 08:06:01 -07003333 TCP(sport=server_in_port, dport=host_out_port))
3334 self.pg0.add_stream(p)
3335 self.pg_enable_capture(self.pg_interfaces)
3336 self.pg_start()
3337 capture = self.pg0.get_capture(1)
3338 p = capture[0]
3339 try:
3340 ip = p[IP]
3341 tcp = p[TCP]
Matus Fabian2ba92e32017-08-21 07:05:03 -07003342 self.assertEqual(ip.src, self.nat_addr)
Matus Fabian93d84c92017-07-19 08:06:01 -07003343 self.assertEqual(ip.dst, host.ip4)
3344 self.assertEqual(tcp.sport, server_out_port)
3345 self.assertEqual(tcp.dport, host_in_port)
Klement Sekerad81ae412018-05-16 10:52:54 +02003346 self.assert_packet_checksums_valid(p)
Matus Fabian93d84c92017-07-19 08:06:01 -07003347 except:
Matus Fabiane82488f2018-01-18 03:38:45 -08003348 self.logger.error(ppp("Unexpected or invalid packet:", p))
Matus Fabian93d84c92017-07-19 08:06:01 -07003349 raise
3350
Matus Fabian36ea2d62017-10-24 04:13:49 -07003351 def test_one_armed_nat44(self):
3352 """ One armed NAT44 """
3353 remote_host = self.pg9.remote_hosts[0]
3354 local_host = self.pg9.remote_hosts[1]
3355 external_port = 0
3356
3357 self.nat44_add_address(self.nat_addr)
3358 self.vapi.nat44_interface_add_del_feature(self.pg9.sw_if_index)
3359 self.vapi.nat44_interface_add_del_feature(self.pg9.sw_if_index,
3360 is_inside=0)
3361
3362 # in2out
3363 p = (Ether(src=self.pg9.remote_mac, dst=self.pg9.local_mac) /
3364 IP(src=local_host.ip4, dst=remote_host.ip4) /
3365 TCP(sport=12345, dport=80))
3366 self.pg9.add_stream(p)
3367 self.pg_enable_capture(self.pg_interfaces)
3368 self.pg_start()
3369 capture = self.pg9.get_capture(1)
3370 p = capture[0]
3371 try:
3372 ip = p[IP]
3373 tcp = p[TCP]
3374 self.assertEqual(ip.src, self.nat_addr)
3375 self.assertEqual(ip.dst, remote_host.ip4)
3376 self.assertNotEqual(tcp.sport, 12345)
3377 external_port = tcp.sport
3378 self.assertEqual(tcp.dport, 80)
Klement Sekerad81ae412018-05-16 10:52:54 +02003379 self.assert_packet_checksums_valid(p)
Matus Fabian36ea2d62017-10-24 04:13:49 -07003380 except:
3381 self.logger.error(ppp("Unexpected or invalid packet:", p))
3382 raise
3383
3384 # out2in
3385 p = (Ether(src=self.pg9.remote_mac, dst=self.pg9.local_mac) /
3386 IP(src=remote_host.ip4, dst=self.nat_addr) /
3387 TCP(sport=80, dport=external_port))
3388 self.pg9.add_stream(p)
3389 self.pg_enable_capture(self.pg_interfaces)
3390 self.pg_start()
3391 capture = self.pg9.get_capture(1)
3392 p = capture[0]
3393 try:
3394 ip = p[IP]
3395 tcp = p[TCP]
3396 self.assertEqual(ip.src, remote_host.ip4)
3397 self.assertEqual(ip.dst, local_host.ip4)
3398 self.assertEqual(tcp.sport, 80)
3399 self.assertEqual(tcp.dport, 12345)
Klement Sekerad81ae412018-05-16 10:52:54 +02003400 self.assert_packet_checksums_valid(p)
Matus Fabian36ea2d62017-10-24 04:13:49 -07003401 except:
3402 self.logger.error(ppp("Unexpected or invalid packet:", p))
3403 raise
3404
Matus Fabiana5e73762018-12-14 01:55:16 -08003405 err = self.statistics.get_counter('/err/nat44-classify/next in2out')
3406 self.assertEqual(err, 1)
3407 err = self.statistics.get_counter('/err/nat44-classify/next out2in')
3408 self.assertEqual(err, 1)
3409
Matus Fabian5ba86f72017-10-26 03:37:38 -07003410 def test_del_session(self):
3411 """ Delete NAT44 session """
3412 self.nat44_add_address(self.nat_addr)
3413 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3414 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3415 is_inside=0)
3416
3417 pkts = self.create_stream_in(self.pg0, self.pg1)
3418 self.pg0.add_stream(pkts)
3419 self.pg_enable_capture(self.pg_interfaces)
3420 self.pg_start()
Matus Fabian229c1aa2018-05-28 04:09:52 -07003421 self.pg1.get_capture(len(pkts))
Matus Fabian5ba86f72017-10-26 03:37:38 -07003422
3423 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n, 0)
3424 nsessions = len(sessions)
3425
3426 self.vapi.nat44_del_session(sessions[0].inside_ip_address,
3427 sessions[0].inside_port,
3428 sessions[0].protocol)
3429 self.vapi.nat44_del_session(sessions[1].outside_ip_address,
3430 sessions[1].outside_port,
3431 sessions[1].protocol,
3432 is_in=0)
3433
3434 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n, 0)
3435 self.assertEqual(nsessions - len(sessions), 2)
3436
Matus Fabian68ba8802018-08-08 05:52:47 -07003437 self.vapi.nat44_del_session(sessions[0].inside_ip_address,
3438 sessions[0].inside_port,
3439 sessions[0].protocol)
3440
3441 self.verify_no_nat44_user()
3442
Matus Fabianefcd1e92017-08-15 06:59:19 -07003443 def test_set_get_reass(self):
3444 """ NAT44 set/get virtual fragmentation reassembly """
3445 reas_cfg1 = self.vapi.nat_get_reass()
3446
3447 self.vapi.nat_set_reass(timeout=reas_cfg1.ip4_timeout + 5,
3448 max_reass=reas_cfg1.ip4_max_reass * 2,
3449 max_frag=reas_cfg1.ip4_max_frag * 2)
3450
3451 reas_cfg2 = self.vapi.nat_get_reass()
3452
3453 self.assertEqual(reas_cfg1.ip4_timeout + 5, reas_cfg2.ip4_timeout)
3454 self.assertEqual(reas_cfg1.ip4_max_reass * 2, reas_cfg2.ip4_max_reass)
3455 self.assertEqual(reas_cfg1.ip4_max_frag * 2, reas_cfg2.ip4_max_frag)
3456
3457 self.vapi.nat_set_reass(drop_frag=1)
3458 self.assertTrue(self.vapi.nat_get_reass().ip4_drop_frag)
3459
3460 def test_frag_in_order(self):
3461 """ NAT44 translate fragments arriving in order """
Juraj Slobodafe0aa762018-07-23 12:22:54 +02003462
Matus Fabianefcd1e92017-08-15 06:59:19 -07003463 self.nat44_add_address(self.nat_addr)
3464 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3465 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3466 is_inside=0)
3467
Matus Fabianda41d722018-10-19 04:01:19 -07003468 self.frag_in_order(proto=IP_PROTOS.tcp)
3469 self.frag_in_order(proto=IP_PROTOS.udp)
3470 self.frag_in_order(proto=IP_PROTOS.icmp)
Matus Fabianefcd1e92017-08-15 06:59:19 -07003471
Matus Fabian111add72018-11-20 02:19:05 -08003472 def test_frag_forwarding(self):
3473 """ NAT44 forwarding fragment test """
3474 self.vapi.nat44_add_interface_addr(self.pg1.sw_if_index)
3475 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3476 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3477 is_inside=0)
3478 self.vapi.nat44_forwarding_enable_disable(1)
3479
3480 data = "A" * 16 + "B" * 16 + "C" * 3
3481 pkts = self.create_stream_frag(self.pg1,
3482 self.pg0.remote_ip4,
3483 4789,
3484 4789,
3485 data,
3486 proto=IP_PROTOS.udp)
3487 self.pg1.add_stream(pkts)
3488 self.pg_enable_capture(self.pg_interfaces)
3489 self.pg_start()
3490 frags = self.pg0.get_capture(len(pkts))
3491 p = self.reass_frags_and_verify(frags,
3492 self.pg1.remote_ip4,
3493 self.pg0.remote_ip4)
3494 self.assertEqual(p[UDP].sport, 4789)
3495 self.assertEqual(p[UDP].dport, 4789)
3496 self.assertEqual(data, p[Raw].load)
3497
Matus Fabianefcd1e92017-08-15 06:59:19 -07003498 def test_reass_hairpinning(self):
3499 """ NAT44 fragments hairpinning """
Juraj Slobodafe0aa762018-07-23 12:22:54 +02003500
Matus Fabianda41d722018-10-19 04:01:19 -07003501 self.server = self.pg0.remote_hosts[1]
3502 self.host_in_port = random.randint(1025, 65535)
3503 self.server_in_port = random.randint(1025, 65535)
3504 self.server_out_port = random.randint(1025, 65535)
Matus Fabianefcd1e92017-08-15 06:59:19 -07003505
3506 self.nat44_add_address(self.nat_addr)
3507 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3508 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3509 is_inside=0)
3510 # add static mapping for server
Matus Fabianda41d722018-10-19 04:01:19 -07003511 self.nat44_add_static_mapping(self.server.ip4, self.nat_addr,
3512 self.server_in_port,
3513 self.server_out_port,
Matus Fabianefcd1e92017-08-15 06:59:19 -07003514 proto=IP_PROTOS.tcp)
Matus Fabianda41d722018-10-19 04:01:19 -07003515 self.nat44_add_static_mapping(self.server.ip4, self.nat_addr,
3516 self.server_in_port,
3517 self.server_out_port,
3518 proto=IP_PROTOS.udp)
3519 self.nat44_add_static_mapping(self.server.ip4, self.nat_addr)
Matus Fabianefcd1e92017-08-15 06:59:19 -07003520
Matus Fabianda41d722018-10-19 04:01:19 -07003521 self.reass_hairpinning(proto=IP_PROTOS.tcp)
3522 self.reass_hairpinning(proto=IP_PROTOS.udp)
3523 self.reass_hairpinning(proto=IP_PROTOS.icmp)
Matus Fabianefcd1e92017-08-15 06:59:19 -07003524
3525 def test_frag_out_of_order(self):
3526 """ NAT44 translate fragments arriving out of order """
Juraj Slobodafe0aa762018-07-23 12:22:54 +02003527
Matus Fabianefcd1e92017-08-15 06:59:19 -07003528 self.nat44_add_address(self.nat_addr)
3529 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3530 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3531 is_inside=0)
3532
Matus Fabianda41d722018-10-19 04:01:19 -07003533 self.frag_out_of_order(proto=IP_PROTOS.tcp)
3534 self.frag_out_of_order(proto=IP_PROTOS.udp)
3535 self.frag_out_of_order(proto=IP_PROTOS.icmp)
Matus Fabianefcd1e92017-08-15 06:59:19 -07003536
Matus Fabian27697102017-11-09 01:43:47 -08003537 def test_port_restricted(self):
3538 """ Port restricted NAT44 (MAP-E CE) """
3539 self.nat44_add_address(self.nat_addr)
3540 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3541 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3542 is_inside=0)
Matus Fabian5d28c7a2018-09-04 03:55:45 -07003543 self.vapi.nat_set_addr_and_port_alloc_alg(alg=1,
3544 psid_offset=6,
3545 psid_length=6,
3546 psid=10)
Matus Fabian27697102017-11-09 01:43:47 -08003547
3548 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
3549 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
3550 TCP(sport=4567, dport=22))
3551 self.pg0.add_stream(p)
3552 self.pg_enable_capture(self.pg_interfaces)
3553 self.pg_start()
3554 capture = self.pg1.get_capture(1)
3555 p = capture[0]
3556 try:
3557 ip = p[IP]
3558 tcp = p[TCP]
3559 self.assertEqual(ip.dst, self.pg1.remote_ip4)
3560 self.assertEqual(ip.src, self.nat_addr)
3561 self.assertEqual(tcp.dport, 22)
3562 self.assertNotEqual(tcp.sport, 4567)
3563 self.assertEqual((tcp.sport >> 6) & 63, 10)
Klement Sekerad81ae412018-05-16 10:52:54 +02003564 self.assert_packet_checksums_valid(p)
Matus Fabian27697102017-11-09 01:43:47 -08003565 except:
3566 self.logger.error(ppp("Unexpected or invalid packet:", p))
3567 raise
3568
Matus Fabian5d28c7a2018-09-04 03:55:45 -07003569 def test_port_range(self):
3570 """ External address port range """
3571 self.nat44_add_address(self.nat_addr)
3572 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3573 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3574 is_inside=0)
3575 self.vapi.nat_set_addr_and_port_alloc_alg(alg=2,
3576 start_port=1025,
3577 end_port=1027)
3578
3579 pkts = []
3580 for port in range(0, 5):
3581 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
3582 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
3583 TCP(sport=1125 + port))
3584 pkts.append(p)
3585 self.pg0.add_stream(pkts)
3586 self.pg_enable_capture(self.pg_interfaces)
3587 self.pg_start()
3588 capture = self.pg1.get_capture(3)
3589 for p in capture:
3590 tcp = p[TCP]
3591 self.assertGreaterEqual(tcp.sport, 1025)
3592 self.assertLessEqual(tcp.sport, 1027)
3593
Matus Fabiana6110b62018-06-13 05:39:07 -07003594 def test_ipfix_max_frags(self):
3595 """ IPFIX logging maximum fragments pending reassembly exceeded """
3596 self.nat44_add_address(self.nat_addr)
3597 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3598 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3599 is_inside=0)
Matus Fabiana7f8b222018-09-05 06:01:55 -07003600 self.vapi.nat_set_reass(max_frag=1)
Matus Fabiana6110b62018-06-13 05:39:07 -07003601 self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4n,
3602 src_address=self.pg3.local_ip4n,
3603 path_mtu=512,
3604 template_interval=10)
3605 self.vapi.nat_ipfix(domain_id=self.ipfix_domain_id,
3606 src_port=self.ipfix_src_port)
3607
3608 data = "A" * 4 + "B" * 16 + "C" * 3
3609 self.tcp_port_in = random.randint(1025, 65535)
3610 pkts = self.create_stream_frag(self.pg0,
3611 self.pg1.remote_ip4,
3612 self.tcp_port_in,
3613 20,
3614 data)
Matus Fabiana7f8b222018-09-05 06:01:55 -07003615 pkts.reverse()
3616 self.pg0.add_stream(pkts)
Matus Fabiana6110b62018-06-13 05:39:07 -07003617 self.pg_enable_capture(self.pg_interfaces)
3618 self.pg_start()
3619 self.pg1.assert_nothing_captured()
3620 sleep(1)
3621 self.vapi.cli("ipfix flush") # FIXME this should be an API call
3622 capture = self.pg3.get_capture(9)
3623 ipfix = IPFIXDecoder()
3624 # first load template
3625 for p in capture:
3626 self.assertTrue(p.haslayer(IPFIX))
3627 self.assertEqual(p[IP].src, self.pg3.local_ip4)
3628 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
3629 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
3630 self.assertEqual(p[UDP].dport, 4739)
3631 self.assertEqual(p[IPFIX].observationDomainID,
3632 self.ipfix_domain_id)
3633 if p.haslayer(Template):
3634 ipfix.add_template(p.getlayer(Template))
3635 # verify events in data set
3636 for p in capture:
3637 if p.haslayer(Data):
3638 data = ipfix.decode_data_set(p.getlayer(Set))
Matus Fabiana7f8b222018-09-05 06:01:55 -07003639 self.verify_ipfix_max_fragments_ip4(data, 1,
Matus Fabiana6110b62018-06-13 05:39:07 -07003640 self.pg0.remote_ip4n)
3641
Matus Fabian8008d7c2018-07-09 01:34:20 -07003642 def test_multiple_outside_vrf(self):
3643 """ Multiple outside VRF """
3644 vrf_id1 = 1
3645 vrf_id2 = 2
3646
3647 self.pg1.unconfig_ip4()
3648 self.pg2.unconfig_ip4()
3649 self.vapi.ip_table_add_del(vrf_id1, is_add=1)
3650 self.vapi.ip_table_add_del(vrf_id2, is_add=1)
3651 self.pg1.set_table_ip4(vrf_id1)
3652 self.pg2.set_table_ip4(vrf_id2)
3653 self.pg1.config_ip4()
3654 self.pg2.config_ip4()
3655 self.pg1.resolve_arp()
3656 self.pg2.resolve_arp()
3657
3658 self.nat44_add_address(self.nat_addr)
3659 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3660 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3661 is_inside=0)
3662 self.vapi.nat44_interface_add_del_feature(self.pg2.sw_if_index,
3663 is_inside=0)
3664
3665 try:
3666 # first VRF
3667 pkts = self.create_stream_in(self.pg0, self.pg1)
3668 self.pg0.add_stream(pkts)
3669 self.pg_enable_capture(self.pg_interfaces)
3670 self.pg_start()
3671 capture = self.pg1.get_capture(len(pkts))
3672 self.verify_capture_out(capture, self.nat_addr)
3673
3674 pkts = self.create_stream_out(self.pg1, self.nat_addr)
3675 self.pg1.add_stream(pkts)
3676 self.pg_enable_capture(self.pg_interfaces)
3677 self.pg_start()
3678 capture = self.pg0.get_capture(len(pkts))
3679 self.verify_capture_in(capture, self.pg0)
3680
3681 self.tcp_port_in = 60303
3682 self.udp_port_in = 60304
3683 self.icmp_id_in = 60305
3684
3685 # second VRF
3686 pkts = self.create_stream_in(self.pg0, self.pg2)
3687 self.pg0.add_stream(pkts)
3688 self.pg_enable_capture(self.pg_interfaces)
3689 self.pg_start()
3690 capture = self.pg2.get_capture(len(pkts))
3691 self.verify_capture_out(capture, self.nat_addr)
3692
3693 pkts = self.create_stream_out(self.pg2, self.nat_addr)
3694 self.pg2.add_stream(pkts)
3695 self.pg_enable_capture(self.pg_interfaces)
3696 self.pg_start()
3697 capture = self.pg0.get_capture(len(pkts))
3698 self.verify_capture_in(capture, self.pg0)
3699
3700 finally:
3701 self.pg1.unconfig_ip4()
3702 self.pg2.unconfig_ip4()
3703 self.pg1.set_table_ip4(0)
3704 self.pg2.set_table_ip4(0)
3705 self.pg1.config_ip4()
3706 self.pg2.config_ip4()
3707 self.pg1.resolve_arp()
3708 self.pg2.resolve_arp()
3709
Paul Vinciguerradefde0f2018-12-06 07:46:13 -08003710 @unittest.skipUnless(running_extended_tests, "part of extended tests")
Matus Fabian878c6462018-08-23 00:33:35 -07003711 def test_session_timeout(self):
3712 """ NAT44 session timeouts """
3713 self.nat44_add_address(self.nat_addr)
3714 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3715 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3716 is_inside=0)
3717 self.vapi.nat_set_timeouts(udp=5)
3718
3719 max_sessions = 1000
3720 pkts = []
3721 for i in range(0, max_sessions):
3722 src = "10.10.%u.%u" % ((i & 0xFF00) >> 8, i & 0xFF)
3723 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
3724 IP(src=src, dst=self.pg1.remote_ip4) /
3725 UDP(sport=1025, dport=53))
3726 pkts.append(p)
3727 self.pg0.add_stream(pkts)
3728 self.pg_enable_capture(self.pg_interfaces)
3729 self.pg_start()
3730 self.pg1.get_capture(max_sessions)
3731
3732 sleep(6)
3733
3734 pkts = []
3735 for i in range(0, max_sessions):
3736 src = "10.10.%u.%u" % ((i & 0xFF00) >> 8, i & 0xFF)
3737 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
3738 IP(src=src, dst=self.pg1.remote_ip4) /
3739 UDP(sport=1026, dport=53))
3740 pkts.append(p)
3741 self.pg0.add_stream(pkts)
3742 self.pg_enable_capture(self.pg_interfaces)
3743 self.pg_start()
3744 self.pg1.get_capture(max_sessions)
3745
3746 nsessions = 0
3747 users = self.vapi.nat44_user_dump()
3748 for user in users:
3749 nsessions = nsessions + user.nsessions
3750 self.assertLess(nsessions, 2 * max_sessions)
3751
Matus Fabianbb4e0222018-09-13 02:36:25 -07003752 def test_mss_clamping(self):
3753 """ TCP MSS clamping """
3754 self.nat44_add_address(self.nat_addr)
3755 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3756 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3757 is_inside=0)
3758
3759 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
3760 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
3761 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
3762 flags="S", options=[('MSS', 1400)]))
3763
3764 self.vapi.nat_set_mss_clamping(enable=1, mss_value=1000)
3765 self.pg0.add_stream(p)
3766 self.pg_enable_capture(self.pg_interfaces)
3767 self.pg_start()
3768 capture = self.pg1.get_capture(1)
3769 # Negotiated MSS value greater than configured - changed
3770 self.verify_mss_value(capture[0], 1000)
3771
3772 self.vapi.nat_set_mss_clamping(enable=0)
3773 self.pg0.add_stream(p)
3774 self.pg_enable_capture(self.pg_interfaces)
3775 self.pg_start()
3776 capture = self.pg1.get_capture(1)
3777 # MSS clamping disabled - negotiated MSS unchanged
3778 self.verify_mss_value(capture[0], 1400)
3779
3780 self.vapi.nat_set_mss_clamping(enable=1, mss_value=1500)
3781 self.pg0.add_stream(p)
3782 self.pg_enable_capture(self.pg_interfaces)
3783 self.pg_start()
3784 capture = self.pg1.get_capture(1)
3785 # Negotiated MSS value smaller than configured - unchanged
3786 self.verify_mss_value(capture[0], 1400)
3787
Matus Fabiana6110b62018-06-13 05:39:07 -07003788 def tearDown(self):
3789 super(TestNAT44, self).tearDown()
3790 if not self.vpp_dead:
3791 self.logger.info(self.vapi.cli("show nat44 addresses"))
3792 self.logger.info(self.vapi.cli("show nat44 interfaces"))
3793 self.logger.info(self.vapi.cli("show nat44 static mappings"))
3794 self.logger.info(self.vapi.cli("show nat44 interface address"))
3795 self.logger.info(self.vapi.cli("show nat44 sessions detail"))
3796 self.logger.info(self.vapi.cli("show nat virtual-reassembly"))
3797 self.logger.info(self.vapi.cli("show nat44 hash tables detail"))
Matus Fabian878c6462018-08-23 00:33:35 -07003798 self.logger.info(self.vapi.cli("show nat timeouts"))
Matus Fabian5d28c7a2018-09-04 03:55:45 -07003799 self.logger.info(
3800 self.vapi.cli("show nat addr-port-assignment-alg"))
Matus Fabiana6110b62018-06-13 05:39:07 -07003801 self.clear_nat44()
3802 self.vapi.cli("clear logging")
3803
3804
3805class TestNAT44EndpointDependent(MethodHolder):
3806 """ Endpoint-Dependent mapping and filtering test cases """
3807
3808 @classmethod
3809 def setUpConstants(cls):
3810 super(TestNAT44EndpointDependent, cls).setUpConstants()
3811 cls.vpp_cmdline.extend(["nat", "{", "endpoint-dependent", "}"])
3812
3813 @classmethod
3814 def setUpClass(cls):
3815 super(TestNAT44EndpointDependent, cls).setUpClass()
3816 cls.vapi.cli("set log class nat level debug")
3817 try:
3818 cls.tcp_port_in = 6303
3819 cls.tcp_port_out = 6303
3820 cls.udp_port_in = 6304
3821 cls.udp_port_out = 6304
3822 cls.icmp_id_in = 6305
3823 cls.icmp_id_out = 6305
3824 cls.nat_addr = '10.0.0.3'
3825 cls.nat_addr_n = socket.inet_pton(socket.AF_INET, cls.nat_addr)
3826 cls.ipfix_src_port = 4739
3827 cls.ipfix_domain_id = 1
3828 cls.tcp_external_port = 80
3829
Matus Fabian8008d7c2018-07-09 01:34:20 -07003830 cls.create_pg_interfaces(range(7))
Matus Fabiana6110b62018-06-13 05:39:07 -07003831 cls.interfaces = list(cls.pg_interfaces[0:3])
3832
3833 for i in cls.interfaces:
3834 i.admin_up()
3835 i.config_ip4()
3836 i.resolve_arp()
3837
3838 cls.pg0.generate_remote_hosts(3)
3839 cls.pg0.configure_ipv4_neighbors()
3840
3841 cls.pg3.admin_up()
3842
3843 cls.pg4.generate_remote_hosts(2)
3844 cls.pg4.config_ip4()
3845 ip_addr_n = socket.inet_pton(socket.AF_INET, "10.0.0.1")
3846 cls.vapi.sw_interface_add_del_address(cls.pg4.sw_if_index,
3847 ip_addr_n,
3848 24)
3849 cls.pg4.admin_up()
3850 cls.pg4.resolve_arp()
3851 cls.pg4._remote_hosts[1]._ip4 = cls.pg4._remote_hosts[0]._ip4
3852 cls.pg4.resolve_arp()
3853
Matus Fabian8008d7c2018-07-09 01:34:20 -07003854 zero_ip4n = socket.inet_pton(socket.AF_INET, "0.0.0.0")
3855 cls.vapi.ip_table_add_del(1, is_add=1)
3856
3857 cls.pg5._local_ip4 = "10.1.1.1"
3858 cls.pg5._local_ip4n = socket.inet_pton(socket.AF_INET,
3859 cls.pg5.local_ip4)
3860 cls.pg5._remote_hosts[0]._ip4 = "10.1.1.2"
3861 cls.pg5._remote_hosts[0]._ip4n = socket.inet_pton(
3862 socket.AF_INET, cls.pg5.remote_ip4)
3863 cls.pg5.set_table_ip4(1)
3864 cls.pg5.config_ip4()
3865 cls.pg5.admin_up()
3866 cls.vapi.ip_add_del_route(dst_address=cls.pg5.remote_ip4n,
3867 dst_address_length=32,
3868 table_id=1,
3869 next_hop_sw_if_index=cls.pg5.sw_if_index,
3870 next_hop_address=zero_ip4n)
3871
3872 cls.pg6._local_ip4 = "10.1.2.1"
3873 cls.pg6._local_ip4n = socket.inet_pton(socket.AF_INET,
3874 cls.pg6.local_ip4)
3875 cls.pg6._remote_hosts[0]._ip4 = "10.1.2.2"
3876 cls.pg6._remote_hosts[0]._ip4n = socket.inet_pton(
3877 socket.AF_INET, cls.pg6.remote_ip4)
3878 cls.pg6.set_table_ip4(1)
3879 cls.pg6.config_ip4()
3880 cls.pg6.admin_up()
3881 cls.vapi.ip_add_del_route(dst_address=cls.pg6.remote_ip4n,
3882 dst_address_length=32,
3883 table_id=1,
3884 next_hop_sw_if_index=cls.pg6.sw_if_index,
3885 next_hop_address=zero_ip4n)
3886
3887 cls.vapi.ip_add_del_route(dst_address=cls.pg6.remote_ip4n,
3888 dst_address_length=16,
3889 next_hop_address=zero_ip4n,
3890 table_id=0,
3891 next_hop_table_id=1)
3892 cls.vapi.ip_add_del_route(dst_address=zero_ip4n,
3893 dst_address_length=0,
3894 next_hop_address=zero_ip4n,
3895 table_id=1,
3896 next_hop_table_id=0)
3897 cls.vapi.ip_add_del_route(dst_address=zero_ip4n,
3898 dst_address_length=0,
3899 table_id=0,
3900 next_hop_sw_if_index=cls.pg1.sw_if_index,
3901 next_hop_address=cls.pg1.local_ip4n)
3902
3903 cls.pg5.resolve_arp()
3904 cls.pg6.resolve_arp()
3905
Matus Fabiana6110b62018-06-13 05:39:07 -07003906 except Exception:
3907 super(TestNAT44EndpointDependent, cls).tearDownClass()
3908 raise
3909
Juraj Slobodafe0aa762018-07-23 12:22:54 +02003910 def test_frag_in_order(self):
3911 """ NAT44 translate fragments arriving in order """
3912 self.nat44_add_address(self.nat_addr)
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.frag_in_order(proto=IP_PROTOS.tcp)
3917 self.frag_in_order(proto=IP_PROTOS.udp)
3918 self.frag_in_order(proto=IP_PROTOS.icmp)
3919
3920 def test_frag_in_order_dont_translate(self):
3921 """ NAT44 don't translate fragments arriving in order """
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.vapi.nat44_forwarding_enable_disable(enable=True)
3926 self.frag_in_order(proto=IP_PROTOS.tcp, dont_translate=True)
3927
3928 def test_frag_out_of_order(self):
3929 """ NAT44 translate fragments arriving out of order """
3930 self.nat44_add_address(self.nat_addr)
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.frag_out_of_order(proto=IP_PROTOS.tcp)
3935 self.frag_out_of_order(proto=IP_PROTOS.udp)
3936 self.frag_out_of_order(proto=IP_PROTOS.icmp)
3937
3938 def test_frag_out_of_order_dont_translate(self):
3939 """ NAT44 don't translate fragments arriving out of order """
3940 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3941 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3942 is_inside=0)
3943 self.vapi.nat44_forwarding_enable_disable(enable=True)
3944 self.frag_out_of_order(proto=IP_PROTOS.tcp, dont_translate=True)
3945
3946 def test_frag_in_order_in_plus_out(self):
3947 """ in+out interface fragments in order """
3948 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3949 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index,
3950 is_inside=0)
3951 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index)
3952 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3953 is_inside=0)
3954
3955 self.server = self.pg1.remote_hosts[0]
3956
3957 self.server_in_addr = self.server.ip4
3958 self.server_out_addr = '11.11.11.11'
3959 self.server_in_port = random.randint(1025, 65535)
3960 self.server_out_port = random.randint(1025, 65535)
3961
3962 self.nat44_add_address(self.server_out_addr)
3963
3964 # add static mappings for server
3965 self.nat44_add_static_mapping(self.server_in_addr,
3966 self.server_out_addr,
3967 self.server_in_port,
3968 self.server_out_port,
3969 proto=IP_PROTOS.tcp)
3970 self.nat44_add_static_mapping(self.server_in_addr,
3971 self.server_out_addr,
3972 self.server_in_port,
3973 self.server_out_port,
3974 proto=IP_PROTOS.udp)
3975 self.nat44_add_static_mapping(self.server_in_addr,
3976 self.server_out_addr,
3977 proto=IP_PROTOS.icmp)
3978
3979 self.vapi.nat_set_reass(timeout=10)
3980
3981 self.frag_in_order_in_plus_out(proto=IP_PROTOS.tcp)
3982 self.frag_in_order_in_plus_out(proto=IP_PROTOS.udp)
3983 self.frag_in_order_in_plus_out(proto=IP_PROTOS.icmp)
3984
3985 def test_frag_out_of_order_in_plus_out(self):
3986 """ in+out interface fragments out of order """
3987 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
3988 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index,
3989 is_inside=0)
3990 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index)
3991 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
3992 is_inside=0)
3993
3994 self.server = self.pg1.remote_hosts[0]
3995
3996 self.server_in_addr = self.server.ip4
3997 self.server_out_addr = '11.11.11.11'
3998 self.server_in_port = random.randint(1025, 65535)
3999 self.server_out_port = random.randint(1025, 65535)
4000
4001 self.nat44_add_address(self.server_out_addr)
4002
4003 # add static mappings for server
4004 self.nat44_add_static_mapping(self.server_in_addr,
4005 self.server_out_addr,
4006 self.server_in_port,
4007 self.server_out_port,
4008 proto=IP_PROTOS.tcp)
4009 self.nat44_add_static_mapping(self.server_in_addr,
4010 self.server_out_addr,
4011 self.server_in_port,
4012 self.server_out_port,
4013 proto=IP_PROTOS.udp)
4014 self.nat44_add_static_mapping(self.server_in_addr,
4015 self.server_out_addr,
4016 proto=IP_PROTOS.icmp)
4017
4018 self.vapi.nat_set_reass(timeout=10)
4019
4020 self.frag_out_of_order_in_plus_out(proto=IP_PROTOS.tcp)
4021 self.frag_out_of_order_in_plus_out(proto=IP_PROTOS.udp)
4022 self.frag_out_of_order_in_plus_out(proto=IP_PROTOS.icmp)
4023
4024 def test_reass_hairpinning(self):
4025 """ NAT44 fragments hairpinning """
4026 self.server = self.pg0.remote_hosts[1]
4027 self.host_in_port = random.randint(1025, 65535)
4028 self.server_in_port = random.randint(1025, 65535)
4029 self.server_out_port = random.randint(1025, 65535)
4030
4031 self.nat44_add_address(self.nat_addr)
4032 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
4033 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
4034 is_inside=0)
4035 # add static mapping for server
4036 self.nat44_add_static_mapping(self.server.ip4, self.nat_addr,
4037 self.server_in_port,
4038 self.server_out_port,
4039 proto=IP_PROTOS.tcp)
4040 self.nat44_add_static_mapping(self.server.ip4, self.nat_addr,
4041 self.server_in_port,
4042 self.server_out_port,
4043 proto=IP_PROTOS.udp)
Matus Fabianda41d722018-10-19 04:01:19 -07004044 self.nat44_add_static_mapping(self.server.ip4, self.nat_addr)
Juraj Slobodafe0aa762018-07-23 12:22:54 +02004045
4046 self.reass_hairpinning(proto=IP_PROTOS.tcp)
4047 self.reass_hairpinning(proto=IP_PROTOS.udp)
4048 self.reass_hairpinning(proto=IP_PROTOS.icmp)
4049
Matus Fabiana6110b62018-06-13 05:39:07 -07004050 def test_dynamic(self):
4051 """ NAT44 dynamic translation test """
4052
4053 self.nat44_add_address(self.nat_addr)
4054 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
4055 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
4056 is_inside=0)
4057
Matus Fabian69ce30d2018-08-22 01:27:10 -07004058 nat_config = self.vapi.nat_show_config()
4059 self.assertEqual(1, nat_config.endpoint_dependent)
4060
Matus Fabiana6110b62018-06-13 05:39:07 -07004061 # in2out
Matus Fabiana5e73762018-12-14 01:55:16 -08004062 tcpn = self.statistics.get_counter(
4063 '/err/nat44-ed-in2out-slowpath/TCP packets')
4064 udpn = self.statistics.get_counter(
4065 '/err/nat44-ed-in2out-slowpath/UDP packets')
4066 icmpn = self.statistics.get_counter(
4067 '/err/nat44-ed-in2out-slowpath/ICMP packets')
4068 totaln = self.statistics.get_counter(
4069 '/err/nat44-ed-in2out-slowpath/good in2out packets processed')
4070
Matus Fabiana6110b62018-06-13 05:39:07 -07004071 pkts = self.create_stream_in(self.pg0, self.pg1)
4072 self.pg0.add_stream(pkts)
4073 self.pg_enable_capture(self.pg_interfaces)
4074 self.pg_start()
4075 capture = self.pg1.get_capture(len(pkts))
4076 self.verify_capture_out(capture)
4077
Matus Fabiana5e73762018-12-14 01:55:16 -08004078 err = self.statistics.get_counter(
4079 '/err/nat44-ed-in2out-slowpath/TCP packets')
4080 self.assertEqual(err - tcpn, 1)
4081 err = self.statistics.get_counter(
4082 '/err/nat44-ed-in2out-slowpath/UDP packets')
4083 self.assertEqual(err - udpn, 1)
4084 err = self.statistics.get_counter(
4085 '/err/nat44-ed-in2out-slowpath/ICMP packets')
4086 self.assertEqual(err - icmpn, 1)
4087 err = self.statistics.get_counter(
4088 '/err/nat44-ed-in2out-slowpath/good in2out packets processed')
4089 self.assertEqual(err - totaln, 3)
4090
Matus Fabiana6110b62018-06-13 05:39:07 -07004091 # out2in
Matus Fabiana5e73762018-12-14 01:55:16 -08004092 tcpn = self.statistics.get_counter('/err/nat44-ed-out2in/TCP packets')
4093 udpn = self.statistics.get_counter('/err/nat44-ed-out2in/UDP packets')
4094 icmpn = self.statistics.get_counter(
4095 '/err/nat44-ed-out2in-slowpath/ICMP packets')
4096 totaln = self.statistics.get_counter(
4097 '/err/nat44-ed-out2in/good out2in packets processed')
4098
Matus Fabiana6110b62018-06-13 05:39:07 -07004099 pkts = self.create_stream_out(self.pg1)
4100 self.pg1.add_stream(pkts)
4101 self.pg_enable_capture(self.pg_interfaces)
4102 self.pg_start()
4103 capture = self.pg0.get_capture(len(pkts))
4104 self.verify_capture_in(capture, self.pg0)
4105
Matus Fabiana5e73762018-12-14 01:55:16 -08004106 err = self.statistics.get_counter('/err/nat44-ed-out2in/TCP packets')
4107 self.assertEqual(err - tcpn, 1)
4108 err = self.statistics.get_counter('/err/nat44-ed-out2in/UDP packets')
4109 self.assertEqual(err - udpn, 1)
4110 err = self.statistics.get_counter(
4111 '/err/nat44-ed-out2in-slowpath/ICMP packets')
4112 self.assertEqual(err - icmpn, 1)
4113 err = self.statistics.get_counter(
4114 '/err/nat44-ed-out2in/good out2in packets processed')
4115 self.assertEqual(err - totaln, 2)
4116
Matus Fabianfd0d5082018-12-18 01:08:51 -08004117 users = self.statistics.get_counter('/nat44/total-users')
4118 self.assertEqual(users[0][0], 1)
4119 sessions = self.statistics.get_counter('/nat44/total-sessions')
4120 self.assertEqual(sessions[0][0], 3)
4121
Matus Fabiana6110b62018-06-13 05:39:07 -07004122 def test_forwarding(self):
4123 """ NAT44 forwarding test """
4124
4125 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
4126 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
4127 is_inside=0)
4128 self.vapi.nat44_forwarding_enable_disable(1)
4129
4130 real_ip = self.pg0.remote_ip4n
4131 alias_ip = self.nat_addr_n
4132 self.vapi.nat44_add_del_static_mapping(local_ip=real_ip,
4133 external_ip=alias_ip)
4134
4135 try:
4136 # in2out - static mapping match
4137
4138 pkts = self.create_stream_out(self.pg1)
4139 self.pg1.add_stream(pkts)
4140 self.pg_enable_capture(self.pg_interfaces)
4141 self.pg_start()
4142 capture = self.pg0.get_capture(len(pkts))
4143 self.verify_capture_in(capture, self.pg0)
4144
4145 pkts = self.create_stream_in(self.pg0, self.pg1)
4146 self.pg0.add_stream(pkts)
4147 self.pg_enable_capture(self.pg_interfaces)
4148 self.pg_start()
4149 capture = self.pg1.get_capture(len(pkts))
4150 self.verify_capture_out(capture, same_port=True)
4151
4152 # in2out - no static mapping match
4153
4154 host0 = self.pg0.remote_hosts[0]
4155 self.pg0.remote_hosts[0] = self.pg0.remote_hosts[1]
4156 try:
4157 pkts = self.create_stream_out(self.pg1,
4158 dst_ip=self.pg0.remote_ip4,
4159 use_inside_ports=True)
4160 self.pg1.add_stream(pkts)
4161 self.pg_enable_capture(self.pg_interfaces)
4162 self.pg_start()
4163 capture = self.pg0.get_capture(len(pkts))
4164 self.verify_capture_in(capture, self.pg0)
4165
4166 pkts = self.create_stream_in(self.pg0, self.pg1)
4167 self.pg0.add_stream(pkts)
4168 self.pg_enable_capture(self.pg_interfaces)
4169 self.pg_start()
4170 capture = self.pg1.get_capture(len(pkts))
4171 self.verify_capture_out(capture, nat_ip=self.pg0.remote_ip4,
4172 same_port=True)
4173 finally:
4174 self.pg0.remote_hosts[0] = host0
4175
4176 user = self.pg0.remote_hosts[1]
4177 sessions = self.vapi.nat44_user_session_dump(user.ip4n, 0)
4178 self.assertEqual(len(sessions), 3)
4179 self.assertTrue(sessions[0].ext_host_valid)
4180 self.vapi.nat44_del_session(
4181 sessions[0].inside_ip_address,
4182 sessions[0].inside_port,
4183 sessions[0].protocol,
4184 ext_host_address=sessions[0].ext_host_address,
4185 ext_host_port=sessions[0].ext_host_port)
4186 sessions = self.vapi.nat44_user_session_dump(user.ip4n, 0)
4187 self.assertEqual(len(sessions), 2)
4188
4189 finally:
4190 self.vapi.nat44_forwarding_enable_disable(0)
4191 self.vapi.nat44_add_del_static_mapping(local_ip=real_ip,
4192 external_ip=alias_ip,
4193 is_add=0)
4194
4195 def test_static_lb(self):
4196 """ NAT44 local service load balancing """
4197 external_addr_n = socket.inet_pton(socket.AF_INET, self.nat_addr)
4198 external_port = 80
4199 local_port = 8080
4200 server1 = self.pg0.remote_hosts[0]
4201 server2 = self.pg0.remote_hosts[1]
4202
4203 locals = [{'addr': server1.ip4n,
4204 'port': local_port,
Matus Fabianc6c0d2a2018-07-19 22:45:25 -07004205 'probability': 70,
4206 'vrf_id': 0},
Matus Fabiana6110b62018-06-13 05:39:07 -07004207 {'addr': server2.ip4n,
4208 'port': local_port,
Matus Fabianc6c0d2a2018-07-19 22:45:25 -07004209 'probability': 30,
4210 'vrf_id': 0}]
Matus Fabiana6110b62018-06-13 05:39:07 -07004211
4212 self.nat44_add_address(self.nat_addr)
4213 self.vapi.nat44_add_del_lb_static_mapping(external_addr_n,
4214 external_port,
4215 IP_PROTOS.tcp,
4216 local_num=len(locals),
4217 locals=locals)
4218 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
4219 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
4220 is_inside=0)
4221
4222 # from client to service
4223 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
4224 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
4225 TCP(sport=12345, dport=external_port))
4226 self.pg1.add_stream(p)
4227 self.pg_enable_capture(self.pg_interfaces)
4228 self.pg_start()
4229 capture = self.pg0.get_capture(1)
4230 p = capture[0]
4231 server = None
4232 try:
4233 ip = p[IP]
4234 tcp = p[TCP]
4235 self.assertIn(ip.dst, [server1.ip4, server2.ip4])
4236 if ip.dst == server1.ip4:
4237 server = server1
4238 else:
4239 server = server2
4240 self.assertEqual(tcp.dport, local_port)
4241 self.assert_packet_checksums_valid(p)
4242 except:
4243 self.logger.error(ppp("Unexpected or invalid packet:", p))
4244 raise
4245
4246 # from service back to client
4247 p = (Ether(src=server.mac, dst=self.pg0.local_mac) /
4248 IP(src=server.ip4, dst=self.pg1.remote_ip4) /
4249 TCP(sport=local_port, dport=12345))
4250 self.pg0.add_stream(p)
4251 self.pg_enable_capture(self.pg_interfaces)
4252 self.pg_start()
4253 capture = self.pg1.get_capture(1)
4254 p = capture[0]
4255 try:
4256 ip = p[IP]
4257 tcp = p[TCP]
4258 self.assertEqual(ip.src, self.nat_addr)
4259 self.assertEqual(tcp.sport, external_port)
4260 self.assert_packet_checksums_valid(p)
4261 except:
4262 self.logger.error(ppp("Unexpected or invalid packet:", p))
4263 raise
4264
4265 sessions = self.vapi.nat44_user_session_dump(server.ip4n, 0)
4266 self.assertEqual(len(sessions), 1)
4267 self.assertTrue(sessions[0].ext_host_valid)
4268 self.vapi.nat44_del_session(
4269 sessions[0].inside_ip_address,
4270 sessions[0].inside_port,
4271 sessions[0].protocol,
4272 ext_host_address=sessions[0].ext_host_address,
4273 ext_host_port=sessions[0].ext_host_port)
4274 sessions = self.vapi.nat44_user_session_dump(server.ip4n, 0)
4275 self.assertEqual(len(sessions), 0)
4276
Paul Vinciguerradefde0f2018-12-06 07:46:13 -08004277 @unittest.skipUnless(running_extended_tests, "part of extended tests")
Matus Fabiana6110b62018-06-13 05:39:07 -07004278 def test_static_lb_multi_clients(self):
4279 """ NAT44 local service load balancing - multiple clients"""
4280
4281 external_addr_n = socket.inet_pton(socket.AF_INET, self.nat_addr)
4282 external_port = 80
4283 local_port = 8080
4284 server1 = self.pg0.remote_hosts[0]
4285 server2 = self.pg0.remote_hosts[1]
Matus Fabianb6865082018-12-06 03:11:09 -08004286 server3 = self.pg0.remote_hosts[2]
Matus Fabiana6110b62018-06-13 05:39:07 -07004287
4288 locals = [{'addr': server1.ip4n,
4289 'port': local_port,
Matus Fabianc6c0d2a2018-07-19 22:45:25 -07004290 'probability': 90,
4291 'vrf_id': 0},
Matus Fabiana6110b62018-06-13 05:39:07 -07004292 {'addr': server2.ip4n,
4293 'port': local_port,
Matus Fabianc6c0d2a2018-07-19 22:45:25 -07004294 'probability': 10,
4295 'vrf_id': 0}]
Matus Fabiana6110b62018-06-13 05:39:07 -07004296
4297 self.nat44_add_address(self.nat_addr)
4298 self.vapi.nat44_add_del_lb_static_mapping(external_addr_n,
4299 external_port,
4300 IP_PROTOS.tcp,
4301 local_num=len(locals),
4302 locals=locals)
4303 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
4304 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
4305 is_inside=0)
4306
4307 server1_n = 0
4308 server2_n = 0
4309 clients = ip4_range(self.pg1.remote_ip4, 10, 50)
4310 pkts = []
4311 for client in clients:
4312 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
4313 IP(src=client, dst=self.nat_addr) /
4314 TCP(sport=12345, dport=external_port))
4315 pkts.append(p)
4316 self.pg1.add_stream(pkts)
4317 self.pg_enable_capture(self.pg_interfaces)
4318 self.pg_start()
4319 capture = self.pg0.get_capture(len(pkts))
4320 for p in capture:
4321 if p[IP].dst == server1.ip4:
4322 server1_n += 1
4323 else:
4324 server2_n += 1
Paul Vinciguerra3d2df212018-11-24 23:19:53 -08004325 self.assertGreater(server1_n, server2_n)
Matus Fabiana6110b62018-06-13 05:39:07 -07004326
Matus Fabianb6865082018-12-06 03:11:09 -08004327 # add new back-end
4328 self.vapi.nat44_lb_static_mapping_add_del_local(external_addr_n,
4329 external_port,
4330 server3.ip4n,
4331 local_port,
4332 IP_PROTOS.tcp,
4333 20)
4334 server1_n = 0
4335 server2_n = 0
4336 server3_n = 0
4337 clients = ip4_range(self.pg1.remote_ip4, 60, 110)
4338 pkts = []
4339 for client in clients:
4340 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
4341 IP(src=client, dst=self.nat_addr) /
4342 TCP(sport=12346, dport=external_port))
4343 pkts.append(p)
4344 self.assertGreater(len(pkts), 0)
4345 self.pg1.add_stream(pkts)
4346 self.pg_enable_capture(self.pg_interfaces)
4347 self.pg_start()
4348 capture = self.pg0.get_capture(len(pkts))
4349 for p in capture:
4350 if p[IP].dst == server1.ip4:
4351 server1_n += 1
4352 elif p[IP].dst == server2.ip4:
4353 server2_n += 1
4354 else:
4355 server3_n += 1
4356 self.assertGreater(server1_n, 0)
4357 self.assertGreater(server2_n, 0)
4358 self.assertGreater(server3_n, 0)
4359
4360 # remove one back-end
4361 self.vapi.nat44_lb_static_mapping_add_del_local(external_addr_n,
4362 external_port,
4363 server2.ip4n,
4364 local_port,
4365 IP_PROTOS.tcp,
4366 10,
4367 is_add=0)
4368 server1_n = 0
4369 server2_n = 0
4370 server3_n = 0
4371 self.pg1.add_stream(pkts)
4372 self.pg_enable_capture(self.pg_interfaces)
4373 self.pg_start()
4374 capture = self.pg0.get_capture(len(pkts))
4375 for p in capture:
4376 if p[IP].dst == server1.ip4:
4377 server1_n += 1
4378 elif p[IP].dst == server2.ip4:
4379 server2_n += 1
4380 else:
4381 server3_n += 1
4382 self.assertGreater(server1_n, 0)
4383 self.assertEqual(server2_n, 0)
4384 self.assertGreater(server3_n, 0)
4385
Matus Fabiana6110b62018-06-13 05:39:07 -07004386 def test_static_lb_2(self):
4387 """ NAT44 local service load balancing (asymmetrical rule) """
4388 external_addr_n = socket.inet_pton(socket.AF_INET, self.nat_addr)
4389 external_port = 80
4390 local_port = 8080
4391 server1 = self.pg0.remote_hosts[0]
4392 server2 = self.pg0.remote_hosts[1]
4393
4394 locals = [{'addr': server1.ip4n,
4395 'port': local_port,
Matus Fabianc6c0d2a2018-07-19 22:45:25 -07004396 'probability': 70,
4397 'vrf_id': 0},
Matus Fabiana6110b62018-06-13 05:39:07 -07004398 {'addr': server2.ip4n,
4399 'port': local_port,
Matus Fabianc6c0d2a2018-07-19 22:45:25 -07004400 'probability': 30,
4401 'vrf_id': 0}]
Matus Fabiana6110b62018-06-13 05:39:07 -07004402
4403 self.vapi.nat44_forwarding_enable_disable(1)
4404 self.vapi.nat44_add_del_lb_static_mapping(external_addr_n,
4405 external_port,
4406 IP_PROTOS.tcp,
4407 out2in_only=1,
4408 local_num=len(locals),
4409 locals=locals)
4410 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
4411 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
4412 is_inside=0)
4413
4414 # from client to service
4415 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
4416 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
4417 TCP(sport=12345, dport=external_port))
4418 self.pg1.add_stream(p)
4419 self.pg_enable_capture(self.pg_interfaces)
4420 self.pg_start()
4421 capture = self.pg0.get_capture(1)
4422 p = capture[0]
4423 server = None
4424 try:
4425 ip = p[IP]
4426 tcp = p[TCP]
4427 self.assertIn(ip.dst, [server1.ip4, server2.ip4])
4428 if ip.dst == server1.ip4:
4429 server = server1
4430 else:
4431 server = server2
4432 self.assertEqual(tcp.dport, local_port)
4433 self.assert_packet_checksums_valid(p)
4434 except:
4435 self.logger.error(ppp("Unexpected or invalid packet:", p))
4436 raise
4437
4438 # from service back to client
4439 p = (Ether(src=server.mac, dst=self.pg0.local_mac) /
4440 IP(src=server.ip4, dst=self.pg1.remote_ip4) /
4441 TCP(sport=local_port, dport=12345))
4442 self.pg0.add_stream(p)
4443 self.pg_enable_capture(self.pg_interfaces)
4444 self.pg_start()
4445 capture = self.pg1.get_capture(1)
4446 p = capture[0]
4447 try:
4448 ip = p[IP]
4449 tcp = p[TCP]
4450 self.assertEqual(ip.src, self.nat_addr)
4451 self.assertEqual(tcp.sport, external_port)
4452 self.assert_packet_checksums_valid(p)
4453 except:
4454 self.logger.error(ppp("Unexpected or invalid packet:", p))
4455 raise
4456
4457 # from client to server (no translation)
4458 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
4459 IP(src=self.pg1.remote_ip4, dst=server1.ip4) /
4460 TCP(sport=12346, dport=local_port))
4461 self.pg1.add_stream(p)
4462 self.pg_enable_capture(self.pg_interfaces)
4463 self.pg_start()
4464 capture = self.pg0.get_capture(1)
4465 p = capture[0]
4466 server = None
4467 try:
4468 ip = p[IP]
4469 tcp = p[TCP]
4470 self.assertEqual(ip.dst, server1.ip4)
4471 self.assertEqual(tcp.dport, local_port)
4472 self.assert_packet_checksums_valid(p)
4473 except:
4474 self.logger.error(ppp("Unexpected or invalid packet:", p))
4475 raise
4476
4477 # from service back to client (no translation)
4478 p = (Ether(src=server1.mac, dst=self.pg0.local_mac) /
4479 IP(src=server1.ip4, dst=self.pg1.remote_ip4) /
4480 TCP(sport=local_port, dport=12346))
4481 self.pg0.add_stream(p)
4482 self.pg_enable_capture(self.pg_interfaces)
4483 self.pg_start()
4484 capture = self.pg1.get_capture(1)
4485 p = capture[0]
4486 try:
4487 ip = p[IP]
4488 tcp = p[TCP]
4489 self.assertEqual(ip.src, server1.ip4)
4490 self.assertEqual(tcp.sport, local_port)
4491 self.assert_packet_checksums_valid(p)
4492 except:
4493 self.logger.error(ppp("Unexpected or invalid packet:", p))
4494 raise
4495
Matus Fabianea5b5be2018-09-03 05:02:23 -07004496 def test_lb_affinity(self):
4497 """ NAT44 local service load balancing affinity """
4498 external_addr_n = socket.inet_pton(socket.AF_INET, self.nat_addr)
4499 external_port = 80
4500 local_port = 8080
4501 server1 = self.pg0.remote_hosts[0]
4502 server2 = self.pg0.remote_hosts[1]
4503
4504 locals = [{'addr': server1.ip4n,
4505 'port': local_port,
4506 'probability': 50,
4507 'vrf_id': 0},
4508 {'addr': server2.ip4n,
4509 'port': local_port,
4510 'probability': 50,
4511 'vrf_id': 0}]
4512
4513 self.nat44_add_address(self.nat_addr)
4514 self.vapi.nat44_add_del_lb_static_mapping(external_addr_n,
4515 external_port,
4516 IP_PROTOS.tcp,
4517 affinity=10800,
4518 local_num=len(locals),
4519 locals=locals)
4520 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
4521 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
4522 is_inside=0)
4523
4524 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
4525 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
4526 TCP(sport=1025, dport=external_port))
4527 self.pg1.add_stream(p)
4528 self.pg_enable_capture(self.pg_interfaces)
4529 self.pg_start()
4530 capture = self.pg0.get_capture(1)
4531 backend = capture[0][IP].dst
4532
4533 sessions = self.vapi.nat44_user_session_dump(
4534 socket.inet_pton(socket.AF_INET, backend), 0)
4535 self.assertEqual(len(sessions), 1)
4536 self.assertTrue(sessions[0].ext_host_valid)
4537 self.vapi.nat44_del_session(
4538 sessions[0].inside_ip_address,
4539 sessions[0].inside_port,
4540 sessions[0].protocol,
4541 ext_host_address=sessions[0].ext_host_address,
4542 ext_host_port=sessions[0].ext_host_port)
4543
4544 pkts = []
4545 for port in range(1030, 1100):
4546 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
4547 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
4548 TCP(sport=port, dport=external_port))
4549 pkts.append(p)
4550 self.pg1.add_stream(pkts)
4551 self.pg_enable_capture(self.pg_interfaces)
4552 self.pg_start()
4553 capture = self.pg0.get_capture(len(pkts))
4554 for p in capture:
4555 self.assertEqual(p[IP].dst, backend)
4556
Matus Fabiana6110b62018-06-13 05:39:07 -07004557 def test_unknown_proto(self):
4558 """ NAT44 translate packet with unknown protocol """
4559 self.nat44_add_address(self.nat_addr)
4560 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
4561 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
4562 is_inside=0)
4563
4564 # in2out
4565 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
4566 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
4567 TCP(sport=self.tcp_port_in, dport=20))
4568 self.pg0.add_stream(p)
4569 self.pg_enable_capture(self.pg_interfaces)
4570 self.pg_start()
4571 p = self.pg1.get_capture(1)
4572
4573 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
4574 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
4575 GRE() /
4576 IP(src=self.pg2.remote_ip4, dst=self.pg2.remote_ip4) /
4577 TCP(sport=1234, dport=1234))
4578 self.pg0.add_stream(p)
4579 self.pg_enable_capture(self.pg_interfaces)
4580 self.pg_start()
4581 p = self.pg1.get_capture(1)
4582 packet = p[0]
4583 try:
4584 self.assertEqual(packet[IP].src, self.nat_addr)
4585 self.assertEqual(packet[IP].dst, self.pg1.remote_ip4)
Paul Vinciguerra978aa642018-11-24 22:19:12 -08004586 self.assertEqual(packet.haslayer(GRE), 1)
Matus Fabiana6110b62018-06-13 05:39:07 -07004587 self.assert_packet_checksums_valid(packet)
4588 except:
4589 self.logger.error(ppp("Unexpected or invalid packet:", packet))
4590 raise
4591
4592 # out2in
4593 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
4594 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
4595 GRE() /
4596 IP(src=self.pg2.remote_ip4, dst=self.pg2.remote_ip4) /
4597 TCP(sport=1234, dport=1234))
4598 self.pg1.add_stream(p)
4599 self.pg_enable_capture(self.pg_interfaces)
4600 self.pg_start()
4601 p = self.pg0.get_capture(1)
4602 packet = p[0]
4603 try:
4604 self.assertEqual(packet[IP].src, self.pg1.remote_ip4)
4605 self.assertEqual(packet[IP].dst, self.pg0.remote_ip4)
Paul Vinciguerra978aa642018-11-24 22:19:12 -08004606 self.assertEqual(packet.haslayer(GRE), 1)
Matus Fabiana6110b62018-06-13 05:39:07 -07004607 self.assert_packet_checksums_valid(packet)
4608 except:
4609 self.logger.error(ppp("Unexpected or invalid packet:", packet))
4610 raise
4611
4612 def test_hairpinning_unknown_proto(self):
4613 """ NAT44 translate packet with unknown protocol - hairpinning """
4614 host = self.pg0.remote_hosts[0]
4615 server = self.pg0.remote_hosts[1]
4616 host_in_port = 1234
4617 server_out_port = 8765
4618 server_nat_ip = "10.0.0.11"
4619
4620 self.nat44_add_address(self.nat_addr)
4621 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
4622 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
4623 is_inside=0)
4624
4625 # add static mapping for server
4626 self.nat44_add_static_mapping(server.ip4, server_nat_ip)
4627
4628 # host to server
4629 p = (Ether(src=host.mac, dst=self.pg0.local_mac) /
4630 IP(src=host.ip4, dst=server_nat_ip) /
4631 TCP(sport=host_in_port, dport=server_out_port))
4632 self.pg0.add_stream(p)
4633 self.pg_enable_capture(self.pg_interfaces)
4634 self.pg_start()
4635 self.pg0.get_capture(1)
4636
4637 p = (Ether(dst=self.pg0.local_mac, src=host.mac) /
4638 IP(src=host.ip4, dst=server_nat_ip) /
4639 GRE() /
4640 IP(src=self.pg2.remote_ip4, dst=self.pg2.remote_ip4) /
4641 TCP(sport=1234, dport=1234))
4642 self.pg0.add_stream(p)
4643 self.pg_enable_capture(self.pg_interfaces)
4644 self.pg_start()
4645 p = self.pg0.get_capture(1)
4646 packet = p[0]
4647 try:
4648 self.assertEqual(packet[IP].src, self.nat_addr)
4649 self.assertEqual(packet[IP].dst, server.ip4)
Paul Vinciguerra978aa642018-11-24 22:19:12 -08004650 self.assertEqual(packet.haslayer(GRE), 1)
Matus Fabiana6110b62018-06-13 05:39:07 -07004651 self.assert_packet_checksums_valid(packet)
4652 except:
4653 self.logger.error(ppp("Unexpected or invalid packet:", packet))
4654 raise
4655
4656 # server to host
4657 p = (Ether(dst=self.pg0.local_mac, src=server.mac) /
4658 IP(src=server.ip4, dst=self.nat_addr) /
4659 GRE() /
4660 IP(src=self.pg2.remote_ip4, dst=self.pg2.remote_ip4) /
4661 TCP(sport=1234, dport=1234))
4662 self.pg0.add_stream(p)
4663 self.pg_enable_capture(self.pg_interfaces)
4664 self.pg_start()
4665 p = self.pg0.get_capture(1)
4666 packet = p[0]
4667 try:
4668 self.assertEqual(packet[IP].src, server_nat_ip)
4669 self.assertEqual(packet[IP].dst, host.ip4)
Paul Vinciguerra978aa642018-11-24 22:19:12 -08004670 self.assertEqual(packet.haslayer(GRE), 1)
Matus Fabiana6110b62018-06-13 05:39:07 -07004671 self.assert_packet_checksums_valid(packet)
4672 except:
4673 self.logger.error(ppp("Unexpected or invalid packet:", packet))
4674 raise
4675
4676 def test_output_feature_and_service(self):
4677 """ NAT44 interface output feature and services """
4678 external_addr = '1.2.3.4'
4679 external_port = 80
4680 local_port = 8080
4681
4682 self.vapi.nat44_forwarding_enable_disable(1)
4683 self.nat44_add_address(self.nat_addr)
4684 self.vapi.nat44_add_del_identity_mapping(ip=self.pg1.remote_ip4n)
4685 self.nat44_add_static_mapping(self.pg0.remote_ip4, external_addr,
4686 local_port, external_port,
4687 proto=IP_PROTOS.tcp, out2in_only=1)
4688 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
4689 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index,
4690 is_inside=0)
4691 self.vapi.nat44_interface_add_del_output_feature(self.pg1.sw_if_index,
4692 is_inside=0)
4693
4694 # from client to service
4695 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
4696 IP(src=self.pg1.remote_ip4, dst=external_addr) /
4697 TCP(sport=12345, dport=external_port))
4698 self.pg1.add_stream(p)
4699 self.pg_enable_capture(self.pg_interfaces)
4700 self.pg_start()
4701 capture = self.pg0.get_capture(1)
4702 p = capture[0]
4703 try:
4704 ip = p[IP]
4705 tcp = p[TCP]
4706 self.assertEqual(ip.dst, self.pg0.remote_ip4)
4707 self.assertEqual(tcp.dport, local_port)
4708 self.assert_packet_checksums_valid(p)
4709 except:
4710 self.logger.error(ppp("Unexpected or invalid packet:", p))
4711 raise
4712
4713 # from service back to client
4714 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
4715 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
4716 TCP(sport=local_port, dport=12345))
4717 self.pg0.add_stream(p)
4718 self.pg_enable_capture(self.pg_interfaces)
4719 self.pg_start()
4720 capture = self.pg1.get_capture(1)
4721 p = capture[0]
4722 try:
4723 ip = p[IP]
4724 tcp = p[TCP]
4725 self.assertEqual(ip.src, external_addr)
4726 self.assertEqual(tcp.sport, external_port)
4727 self.assert_packet_checksums_valid(p)
4728 except:
4729 self.logger.error(ppp("Unexpected or invalid packet:", p))
4730 raise
4731
4732 # from local network host to external network
4733 pkts = self.create_stream_in(self.pg0, self.pg1)
4734 self.pg0.add_stream(pkts)
4735 self.pg_enable_capture(self.pg_interfaces)
4736 self.pg_start()
4737 capture = self.pg1.get_capture(len(pkts))
4738 self.verify_capture_out(capture)
4739 pkts = self.create_stream_in(self.pg0, self.pg1)
4740 self.pg0.add_stream(pkts)
4741 self.pg_enable_capture(self.pg_interfaces)
4742 self.pg_start()
4743 capture = self.pg1.get_capture(len(pkts))
4744 self.verify_capture_out(capture)
4745
4746 # from external network back to local network host
4747 pkts = self.create_stream_out(self.pg1)
4748 self.pg1.add_stream(pkts)
4749 self.pg_enable_capture(self.pg_interfaces)
4750 self.pg_start()
4751 capture = self.pg0.get_capture(len(pkts))
4752 self.verify_capture_in(capture, self.pg0)
4753
4754 def test_output_feature_and_service2(self):
4755 """ NAT44 interface output feature and service host direct access """
4756 self.vapi.nat44_forwarding_enable_disable(1)
4757 self.nat44_add_address(self.nat_addr)
4758 self.vapi.nat44_interface_add_del_output_feature(self.pg1.sw_if_index,
4759 is_inside=0)
4760
4761 # session initiaded from service host - translate
4762 pkts = self.create_stream_in(self.pg0, self.pg1)
4763 self.pg0.add_stream(pkts)
4764 self.pg_enable_capture(self.pg_interfaces)
4765 self.pg_start()
4766 capture = self.pg1.get_capture(len(pkts))
4767 self.verify_capture_out(capture)
4768
4769 pkts = self.create_stream_out(self.pg1)
4770 self.pg1.add_stream(pkts)
4771 self.pg_enable_capture(self.pg_interfaces)
4772 self.pg_start()
4773 capture = self.pg0.get_capture(len(pkts))
4774 self.verify_capture_in(capture, self.pg0)
4775
4776 # session initiaded from remote host - do not translate
4777 self.tcp_port_in = 60303
4778 self.udp_port_in = 60304
4779 self.icmp_id_in = 60305
4780 pkts = self.create_stream_out(self.pg1,
4781 self.pg0.remote_ip4,
4782 use_inside_ports=True)
4783 self.pg1.add_stream(pkts)
4784 self.pg_enable_capture(self.pg_interfaces)
4785 self.pg_start()
4786 capture = self.pg0.get_capture(len(pkts))
4787 self.verify_capture_in(capture, self.pg0)
4788
4789 pkts = self.create_stream_in(self.pg0, self.pg1)
4790 self.pg0.add_stream(pkts)
4791 self.pg_enable_capture(self.pg_interfaces)
4792 self.pg_start()
4793 capture = self.pg1.get_capture(len(pkts))
4794 self.verify_capture_out(capture, nat_ip=self.pg0.remote_ip4,
4795 same_port=True)
4796
4797 def test_output_feature_and_service3(self):
4798 """ NAT44 interface output feature and DST NAT """
4799 external_addr = '1.2.3.4'
4800 external_port = 80
4801 local_port = 8080
4802
4803 self.vapi.nat44_forwarding_enable_disable(1)
4804 self.nat44_add_address(self.nat_addr)
4805 self.nat44_add_static_mapping(self.pg1.remote_ip4, external_addr,
4806 local_port, external_port,
4807 proto=IP_PROTOS.tcp, out2in_only=1)
4808 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
4809 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index,
4810 is_inside=0)
4811 self.vapi.nat44_interface_add_del_output_feature(self.pg1.sw_if_index,
4812 is_inside=0)
4813
4814 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
4815 IP(src=self.pg0.remote_ip4, dst=external_addr) /
4816 TCP(sport=12345, dport=external_port))
4817 self.pg0.add_stream(p)
4818 self.pg_enable_capture(self.pg_interfaces)
4819 self.pg_start()
4820 capture = self.pg1.get_capture(1)
4821 p = capture[0]
4822 try:
4823 ip = p[IP]
4824 tcp = p[TCP]
4825 self.assertEqual(ip.src, self.pg0.remote_ip4)
4826 self.assertEqual(tcp.sport, 12345)
4827 self.assertEqual(ip.dst, self.pg1.remote_ip4)
4828 self.assertEqual(tcp.dport, local_port)
4829 self.assert_packet_checksums_valid(p)
4830 except:
4831 self.logger.error(ppp("Unexpected or invalid packet:", p))
4832 raise
4833
4834 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
4835 IP(src=self.pg1.remote_ip4, dst=self.pg0.remote_ip4) /
4836 TCP(sport=local_port, dport=12345))
4837 self.pg1.add_stream(p)
4838 self.pg_enable_capture(self.pg_interfaces)
4839 self.pg_start()
4840 capture = self.pg0.get_capture(1)
4841 p = capture[0]
4842 try:
4843 ip = p[IP]
4844 tcp = p[TCP]
4845 self.assertEqual(ip.src, external_addr)
4846 self.assertEqual(tcp.sport, external_port)
4847 self.assertEqual(ip.dst, self.pg0.remote_ip4)
4848 self.assertEqual(tcp.dport, 12345)
4849 self.assert_packet_checksums_valid(p)
4850 except:
4851 self.logger.error(ppp("Unexpected or invalid packet:", p))
4852 raise
4853
Matus Fabian182e37e2018-08-14 04:21:26 -07004854 def test_next_src_nat(self):
4855 """ On way back forward packet to nat44-in2out node. """
4856 twice_nat_addr = '10.0.1.3'
4857 external_port = 80
4858 local_port = 8080
4859 post_twice_nat_port = 0
4860
4861 self.vapi.nat44_forwarding_enable_disable(1)
4862 self.nat44_add_address(twice_nat_addr, twice_nat=1)
4863 self.nat44_add_static_mapping(self.pg6.remote_ip4, self.pg1.remote_ip4,
4864 local_port, external_port,
4865 proto=IP_PROTOS.tcp, out2in_only=1,
4866 self_twice_nat=1, vrf_id=1)
4867 self.vapi.nat44_interface_add_del_feature(self.pg6.sw_if_index,
4868 is_inside=0)
4869
4870 p = (Ether(src=self.pg6.remote_mac, dst=self.pg6.local_mac) /
4871 IP(src=self.pg6.remote_ip4, dst=self.pg1.remote_ip4) /
4872 TCP(sport=12345, dport=external_port))
4873 self.pg6.add_stream(p)
4874 self.pg_enable_capture(self.pg_interfaces)
4875 self.pg_start()
4876 capture = self.pg6.get_capture(1)
4877 p = capture[0]
4878 try:
4879 ip = p[IP]
4880 tcp = p[TCP]
4881 self.assertEqual(ip.src, twice_nat_addr)
4882 self.assertNotEqual(tcp.sport, 12345)
4883 post_twice_nat_port = tcp.sport
4884 self.assertEqual(ip.dst, self.pg6.remote_ip4)
4885 self.assertEqual(tcp.dport, local_port)
4886 self.assert_packet_checksums_valid(p)
4887 except:
4888 self.logger.error(ppp("Unexpected or invalid packet:", p))
4889 raise
4890
4891 p = (Ether(src=self.pg6.remote_mac, dst=self.pg6.local_mac) /
4892 IP(src=self.pg6.remote_ip4, dst=twice_nat_addr) /
4893 TCP(sport=local_port, dport=post_twice_nat_port))
4894 self.pg6.add_stream(p)
4895 self.pg_enable_capture(self.pg_interfaces)
4896 self.pg_start()
4897 capture = self.pg6.get_capture(1)
4898 p = capture[0]
4899 try:
4900 ip = p[IP]
4901 tcp = p[TCP]
4902 self.assertEqual(ip.src, self.pg1.remote_ip4)
4903 self.assertEqual(tcp.sport, external_port)
4904 self.assertEqual(ip.dst, self.pg6.remote_ip4)
4905 self.assertEqual(tcp.dport, 12345)
4906 self.assert_packet_checksums_valid(p)
4907 except:
4908 self.logger.error(ppp("Unexpected or invalid packet:", p))
4909 raise
4910
Juraj Sloboda1e5c07d2018-04-10 13:51:54 +02004911 def twice_nat_common(self, self_twice_nat=False, same_pg=False, lb=False,
4912 client_id=None):
Matus Fabianb932d262017-12-18 05:38:24 -08004913 twice_nat_addr = '10.0.1.3'
Juraj Sloboda1e5c07d2018-04-10 13:51:54 +02004914
Matus Fabianb932d262017-12-18 05:38:24 -08004915 port_in = 8080
Juraj Sloboda1e5c07d2018-04-10 13:51:54 +02004916 if lb:
4917 if not same_pg:
4918 port_in1 = port_in
4919 port_in2 = port_in
4920 else:
4921 port_in1 = port_in+1
4922 port_in2 = port_in+2
4923
Matus Fabianb932d262017-12-18 05:38:24 -08004924 port_out = 80
4925 eh_port_out = 4567
Juraj Sloboda1e5c07d2018-04-10 13:51:54 +02004926
4927 server1 = self.pg0.remote_hosts[0]
4928 server2 = self.pg0.remote_hosts[1]
4929 if lb and same_pg:
4930 server2 = server1
4931 if not lb:
4932 server = server1
4933
4934 pg0 = self.pg0
4935 if same_pg:
4936 pg1 = self.pg0
4937 else:
4938 pg1 = self.pg1
4939
4940 eh_translate = ((not self_twice_nat) or (not lb and same_pg) or
4941 client_id == 1)
4942
Matus Fabianb932d262017-12-18 05:38:24 -08004943 self.nat44_add_address(self.nat_addr)
4944 self.nat44_add_address(twice_nat_addr, twice_nat=1)
Juraj Sloboda1e5c07d2018-04-10 13:51:54 +02004945 if not lb:
4946 self.nat44_add_static_mapping(pg0.remote_ip4, self.nat_addr,
4947 port_in, port_out,
4948 proto=IP_PROTOS.tcp,
4949 twice_nat=int(not self_twice_nat),
4950 self_twice_nat=int(self_twice_nat))
4951 else:
4952 locals = [{'addr': server1.ip4n,
4953 'port': port_in1,
Matus Fabianc6c0d2a2018-07-19 22:45:25 -07004954 'probability': 50,
4955 'vrf_id': 0},
Juraj Sloboda1e5c07d2018-04-10 13:51:54 +02004956 {'addr': server2.ip4n,
4957 'port': port_in2,
Matus Fabianc6c0d2a2018-07-19 22:45:25 -07004958 'probability': 50,
4959 'vrf_id': 0}]
Juraj Sloboda1e5c07d2018-04-10 13:51:54 +02004960 out_addr_n = socket.inet_pton(socket.AF_INET, self.nat_addr)
4961 self.vapi.nat44_add_del_lb_static_mapping(out_addr_n,
4962 port_out,
4963 IP_PROTOS.tcp,
4964 twice_nat=int(
4965 not self_twice_nat),
4966 self_twice_nat=int(
4967 self_twice_nat),
4968 local_num=len(locals),
4969 locals=locals)
4970 self.vapi.nat44_interface_add_del_feature(pg0.sw_if_index)
4971 self.vapi.nat44_interface_add_del_feature(pg1.sw_if_index,
Matus Fabianb932d262017-12-18 05:38:24 -08004972 is_inside=0)
4973
Juraj Sloboda1e5c07d2018-04-10 13:51:54 +02004974 if same_pg:
4975 if not lb:
4976 client = server
4977 else:
4978 assert client_id is not None
4979 if client_id == 1:
4980 client = self.pg0.remote_hosts[0]
4981 elif client_id == 2:
4982 client = self.pg0.remote_hosts[1]
4983 else:
4984 client = pg1.remote_hosts[0]
4985 p = (Ether(src=pg1.remote_mac, dst=pg1.local_mac) /
4986 IP(src=client.ip4, dst=self.nat_addr) /
Matus Fabianb932d262017-12-18 05:38:24 -08004987 TCP(sport=eh_port_out, dport=port_out))
Juraj Sloboda1e5c07d2018-04-10 13:51:54 +02004988 pg1.add_stream(p)
Matus Fabianb932d262017-12-18 05:38:24 -08004989 self.pg_enable_capture(self.pg_interfaces)
4990 self.pg_start()
Juraj Sloboda1e5c07d2018-04-10 13:51:54 +02004991 capture = pg0.get_capture(1)
Matus Fabianb932d262017-12-18 05:38:24 -08004992 p = capture[0]
4993 try:
4994 ip = p[IP]
4995 tcp = p[TCP]
Juraj Sloboda1e5c07d2018-04-10 13:51:54 +02004996 if lb:
4997 if ip.dst == server1.ip4:
4998 server = server1
4999 port_in = port_in1
5000 else:
5001 server = server2
5002 port_in = port_in2
5003 self.assertEqual(ip.dst, server.ip4)
5004 if lb and same_pg:
5005 self.assertIn(tcp.dport, [port_in1, port_in2])
5006 else:
5007 self.assertEqual(tcp.dport, port_in)
5008 if eh_translate:
5009 self.assertEqual(ip.src, twice_nat_addr)
5010 self.assertNotEqual(tcp.sport, eh_port_out)
5011 else:
5012 self.assertEqual(ip.src, client.ip4)
5013 self.assertEqual(tcp.sport, eh_port_out)
5014 eh_addr_in = ip.src
Matus Fabianb932d262017-12-18 05:38:24 -08005015 eh_port_in = tcp.sport
Juraj Sloboda1e5c07d2018-04-10 13:51:54 +02005016 saved_port_in = tcp.dport
Klement Sekerad81ae412018-05-16 10:52:54 +02005017 self.assert_packet_checksums_valid(p)
Matus Fabianb932d262017-12-18 05:38:24 -08005018 except:
5019 self.logger.error(ppp("Unexpected or invalid packet:", p))
5020 raise
5021
Juraj Sloboda1e5c07d2018-04-10 13:51:54 +02005022 p = (Ether(src=server.mac, dst=pg0.local_mac) /
5023 IP(src=server.ip4, dst=eh_addr_in) /
5024 TCP(sport=saved_port_in, dport=eh_port_in))
5025 pg0.add_stream(p)
Matus Fabianb932d262017-12-18 05:38:24 -08005026 self.pg_enable_capture(self.pg_interfaces)
5027 self.pg_start()
Juraj Sloboda1e5c07d2018-04-10 13:51:54 +02005028 capture = pg1.get_capture(1)
Matus Fabianb932d262017-12-18 05:38:24 -08005029 p = capture[0]
5030 try:
5031 ip = p[IP]
5032 tcp = p[TCP]
Juraj Sloboda1e5c07d2018-04-10 13:51:54 +02005033 self.assertEqual(ip.dst, client.ip4)
Matus Fabianb932d262017-12-18 05:38:24 -08005034 self.assertEqual(ip.src, self.nat_addr)
5035 self.assertEqual(tcp.dport, eh_port_out)
5036 self.assertEqual(tcp.sport, port_out)
Klement Sekerad81ae412018-05-16 10:52:54 +02005037 self.assert_packet_checksums_valid(p)
Matus Fabianb932d262017-12-18 05:38:24 -08005038 except:
5039 self.logger.error(ppp("Unexpected or invalid packet:", p))
5040 raise
5041
Matus Fabian70a26ac2018-05-14 06:20:28 -07005042 if eh_translate:
5043 sessions = self.vapi.nat44_user_session_dump(server.ip4n, 0)
5044 self.assertEqual(len(sessions), 1)
5045 self.assertTrue(sessions[0].ext_host_valid)
5046 self.assertTrue(sessions[0].is_twicenat)
5047 self.vapi.nat44_del_session(
5048 sessions[0].inside_ip_address,
5049 sessions[0].inside_port,
5050 sessions[0].protocol,
5051 ext_host_address=sessions[0].ext_host_nat_address,
5052 ext_host_port=sessions[0].ext_host_nat_port)
5053 sessions = self.vapi.nat44_user_session_dump(server.ip4n, 0)
5054 self.assertEqual(len(sessions), 0)
5055
Juraj Sloboda1e5c07d2018-04-10 13:51:54 +02005056 def test_twice_nat(self):
5057 """ Twice NAT44 """
5058 self.twice_nat_common()
5059
5060 def test_self_twice_nat_positive(self):
5061 """ Self Twice NAT44 (positive test) """
5062 self.twice_nat_common(self_twice_nat=True, same_pg=True)
5063
5064 def test_self_twice_nat_negative(self):
5065 """ Self Twice NAT44 (negative test) """
5066 self.twice_nat_common(self_twice_nat=True)
5067
Matus Fabianb932d262017-12-18 05:38:24 -08005068 def test_twice_nat_lb(self):
5069 """ Twice NAT44 local service load balancing """
Juraj Sloboda1e5c07d2018-04-10 13:51:54 +02005070 self.twice_nat_common(lb=True)
Matus Fabianb932d262017-12-18 05:38:24 -08005071
Juraj Sloboda1e5c07d2018-04-10 13:51:54 +02005072 def test_self_twice_nat_lb_positive(self):
5073 """ Self Twice NAT44 local service load balancing (positive test) """
5074 self.twice_nat_common(lb=True, self_twice_nat=True, same_pg=True,
5075 client_id=1)
Matus Fabianb932d262017-12-18 05:38:24 -08005076
Juraj Sloboda1e5c07d2018-04-10 13:51:54 +02005077 def test_self_twice_nat_lb_negative(self):
5078 """ Self Twice NAT44 local service load balancing (negative test) """
5079 self.twice_nat_common(lb=True, self_twice_nat=True, same_pg=True,
5080 client_id=2)
Matus Fabianb932d262017-12-18 05:38:24 -08005081
5082 def test_twice_nat_interface_addr(self):
5083 """ Acquire twice NAT44 addresses from interface """
Matus Fabiana6110b62018-06-13 05:39:07 -07005084 self.vapi.nat44_add_interface_addr(self.pg3.sw_if_index, twice_nat=1)
Matus Fabianb932d262017-12-18 05:38:24 -08005085
5086 # no address in NAT pool
5087 adresses = self.vapi.nat44_address_dump()
5088 self.assertEqual(0, len(adresses))
5089
5090 # configure interface address and check NAT address pool
Matus Fabiana6110b62018-06-13 05:39:07 -07005091 self.pg3.config_ip4()
Matus Fabianb932d262017-12-18 05:38:24 -08005092 adresses = self.vapi.nat44_address_dump()
5093 self.assertEqual(1, len(adresses))
Matus Fabiana6110b62018-06-13 05:39:07 -07005094 self.assertEqual(adresses[0].ip_address[0:4], self.pg3.local_ip4n)
Matus Fabianb932d262017-12-18 05:38:24 -08005095 self.assertEqual(adresses[0].twice_nat, 1)
5096
5097 # remove interface address and check NAT address pool
Matus Fabiana6110b62018-06-13 05:39:07 -07005098 self.pg3.unconfig_ip4()
Matus Fabianb932d262017-12-18 05:38:24 -08005099 adresses = self.vapi.nat44_address_dump()
5100 self.assertEqual(0, len(adresses))
5101
Matus Fabian6c01dce2018-11-16 04:41:31 -08005102 def test_tcp_close(self):
5103 """ Close TCP session from inside network - output feature """
5104 self.vapi.nat44_forwarding_enable_disable(1)
5105 self.nat44_add_address(self.pg1.local_ip4)
5106 twice_nat_addr = '10.0.1.3'
5107 service_ip = '192.168.16.150'
5108 self.nat44_add_address(twice_nat_addr, twice_nat=1)
5109 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
5110 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index,
5111 is_inside=0)
5112 self.vapi.nat44_interface_add_del_output_feature(self.pg1.sw_if_index,
5113 is_inside=0)
5114 self.nat44_add_static_mapping(self.pg0.remote_ip4,
5115 service_ip,
5116 80,
5117 80,
5118 proto=IP_PROTOS.tcp,
5119 out2in_only=1,
5120 twice_nat=1)
5121 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n, 0)
5122 start_sessnum = len(sessions)
5123
5124 # SYN packet out->in
5125 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5126 IP(src=self.pg1.remote_ip4, dst=service_ip) /
5127 TCP(sport=33898, dport=80, flags="S"))
5128 self.pg1.add_stream(p)
5129 self.pg_enable_capture(self.pg_interfaces)
5130 self.pg_start()
5131 capture = self.pg0.get_capture(1)
5132 p = capture[0]
5133 tcp_port = p[TCP].sport
5134
5135 # SYN + ACK packet in->out
5136 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5137 IP(src=self.pg0.remote_ip4, dst=twice_nat_addr) /
5138 TCP(sport=80, dport=tcp_port, flags="SA"))
5139 self.pg0.add_stream(p)
5140 self.pg_enable_capture(self.pg_interfaces)
5141 self.pg_start()
5142 self.pg1.get_capture(1)
5143
5144 # ACK packet out->in
5145 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5146 IP(src=self.pg1.remote_ip4, dst=service_ip) /
5147 TCP(sport=33898, dport=80, flags="A"))
5148 self.pg1.add_stream(p)
5149 self.pg_enable_capture(self.pg_interfaces)
5150 self.pg_start()
5151 self.pg0.get_capture(1)
5152
5153 # FIN packet in -> out
5154 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5155 IP(src=self.pg0.remote_ip4, dst=twice_nat_addr) /
5156 TCP(sport=80, dport=tcp_port, flags="FA", seq=100, ack=300))
5157 self.pg0.add_stream(p)
5158 self.pg_enable_capture(self.pg_interfaces)
5159 self.pg_start()
5160 self.pg1.get_capture(1)
5161
5162 # FIN+ACK packet out -> in
5163 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5164 IP(src=self.pg1.remote_ip4, dst=service_ip) /
5165 TCP(sport=33898, dport=80, flags="FA", seq=300, ack=101))
5166 self.pg1.add_stream(p)
5167 self.pg_enable_capture(self.pg_interfaces)
5168 self.pg_start()
5169 self.pg0.get_capture(1)
5170
5171 # ACK packet in -> out
5172 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5173 IP(src=self.pg0.remote_ip4, dst=twice_nat_addr) /
5174 TCP(sport=80, dport=tcp_port, flags="A", seq=101, ack=301))
5175 self.pg0.add_stream(p)
5176 self.pg_enable_capture(self.pg_interfaces)
5177 self.pg_start()
5178 self.pg1.get_capture(1)
5179
5180 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n,
5181 0)
5182 self.assertEqual(len(sessions) - start_sessnum, 0)
5183
Matus Fabianebdf1902018-05-04 03:57:42 -07005184 def test_tcp_session_close_in(self):
5185 """ Close TCP session from inside network """
Matus Fabian229c1aa2018-05-28 04:09:52 -07005186 self.tcp_port_out = 10505
Matus Fabianebdf1902018-05-04 03:57:42 -07005187 self.nat44_add_address(self.nat_addr)
Matus Fabian229c1aa2018-05-28 04:09:52 -07005188 self.nat44_add_static_mapping(self.pg0.remote_ip4,
5189 self.nat_addr,
5190 self.tcp_port_in,
5191 self.tcp_port_out,
5192 proto=IP_PROTOS.tcp,
5193 twice_nat=1)
Matus Fabianebdf1902018-05-04 03:57:42 -07005194 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
5195 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
5196 is_inside=0)
5197
5198 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n, 0)
5199 start_sessnum = len(sessions)
5200
5201 self.initiate_tcp_session(self.pg0, self.pg1)
5202
Matus Fabian229c1aa2018-05-28 04:09:52 -07005203 # FIN packet in -> out
5204 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5205 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5206 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
5207 flags="FA", seq=100, ack=300))
5208 self.pg0.add_stream(p)
5209 self.pg_enable_capture(self.pg_interfaces)
5210 self.pg_start()
5211 self.pg1.get_capture(1)
Matus Fabianebdf1902018-05-04 03:57:42 -07005212
Matus Fabian229c1aa2018-05-28 04:09:52 -07005213 pkts = []
Matus Fabianebdf1902018-05-04 03:57:42 -07005214
Matus Fabian229c1aa2018-05-28 04:09:52 -07005215 # ACK packet out -> in
5216 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5217 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5218 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
5219 flags="A", seq=300, ack=101))
5220 pkts.append(p)
Matus Fabianebdf1902018-05-04 03:57:42 -07005221
Matus Fabian229c1aa2018-05-28 04:09:52 -07005222 # FIN packet out -> in
5223 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5224 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5225 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
5226 flags="FA", seq=300, ack=101))
5227 pkts.append(p)
Matus Fabianebdf1902018-05-04 03:57:42 -07005228
Matus Fabian229c1aa2018-05-28 04:09:52 -07005229 self.pg1.add_stream(pkts)
5230 self.pg_enable_capture(self.pg_interfaces)
5231 self.pg_start()
5232 self.pg0.get_capture(2)
Matus Fabianebdf1902018-05-04 03:57:42 -07005233
Matus Fabian229c1aa2018-05-28 04:09:52 -07005234 # ACK packet in -> out
5235 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5236 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5237 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
5238 flags="A", seq=101, ack=301))
5239 self.pg0.add_stream(p)
5240 self.pg_enable_capture(self.pg_interfaces)
5241 self.pg_start()
5242 self.pg1.get_capture(1)
Matus Fabianebdf1902018-05-04 03:57:42 -07005243
Matus Fabian229c1aa2018-05-28 04:09:52 -07005244 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n,
5245 0)
5246 self.assertEqual(len(sessions) - start_sessnum, 0)
Matus Fabianebdf1902018-05-04 03:57:42 -07005247
5248 def test_tcp_session_close_out(self):
5249 """ Close TCP session from outside network """
Matus Fabian229c1aa2018-05-28 04:09:52 -07005250 self.tcp_port_out = 10505
Matus Fabianebdf1902018-05-04 03:57:42 -07005251 self.nat44_add_address(self.nat_addr)
Matus Fabian229c1aa2018-05-28 04:09:52 -07005252 self.nat44_add_static_mapping(self.pg0.remote_ip4,
5253 self.nat_addr,
5254 self.tcp_port_in,
5255 self.tcp_port_out,
5256 proto=IP_PROTOS.tcp,
5257 twice_nat=1)
Matus Fabianebdf1902018-05-04 03:57:42 -07005258 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
5259 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
5260 is_inside=0)
5261
5262 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n, 0)
5263 start_sessnum = len(sessions)
5264
5265 self.initiate_tcp_session(self.pg0, self.pg1)
5266
Matus Fabian229c1aa2018-05-28 04:09:52 -07005267 # FIN packet out -> in
5268 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5269 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5270 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
5271 flags="FA", seq=100, ack=300))
5272 self.pg1.add_stream(p)
5273 self.pg_enable_capture(self.pg_interfaces)
5274 self.pg_start()
5275 self.pg0.get_capture(1)
Matus Fabianebdf1902018-05-04 03:57:42 -07005276
Matus Fabian229c1aa2018-05-28 04:09:52 -07005277 # FIN+ACK packet in -> out
5278 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5279 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5280 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
5281 flags="FA", seq=300, ack=101))
Matus Fabianebdf1902018-05-04 03:57:42 -07005282
Matus Fabian229c1aa2018-05-28 04:09:52 -07005283 self.pg0.add_stream(p)
5284 self.pg_enable_capture(self.pg_interfaces)
5285 self.pg_start()
5286 self.pg1.get_capture(1)
Matus Fabianebdf1902018-05-04 03:57:42 -07005287
Matus Fabian229c1aa2018-05-28 04:09:52 -07005288 # ACK packet out -> in
5289 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5290 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5291 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
5292 flags="A", seq=101, ack=301))
5293 self.pg1.add_stream(p)
5294 self.pg_enable_capture(self.pg_interfaces)
5295 self.pg_start()
5296 self.pg0.get_capture(1)
Matus Fabianebdf1902018-05-04 03:57:42 -07005297
Matus Fabian229c1aa2018-05-28 04:09:52 -07005298 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n,
5299 0)
5300 self.assertEqual(len(sessions) - start_sessnum, 0)
Matus Fabianebdf1902018-05-04 03:57:42 -07005301
5302 def test_tcp_session_close_simultaneous(self):
5303 """ Close TCP session from inside network """
Matus Fabian229c1aa2018-05-28 04:09:52 -07005304 self.tcp_port_out = 10505
Matus Fabianebdf1902018-05-04 03:57:42 -07005305 self.nat44_add_address(self.nat_addr)
Matus Fabian229c1aa2018-05-28 04:09:52 -07005306 self.nat44_add_static_mapping(self.pg0.remote_ip4,
5307 self.nat_addr,
5308 self.tcp_port_in,
5309 self.tcp_port_out,
5310 proto=IP_PROTOS.tcp,
5311 twice_nat=1)
Matus Fabianebdf1902018-05-04 03:57:42 -07005312 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
5313 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
5314 is_inside=0)
5315
5316 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n, 0)
5317 start_sessnum = len(sessions)
5318
5319 self.initiate_tcp_session(self.pg0, self.pg1)
5320
Matus Fabian229c1aa2018-05-28 04:09:52 -07005321 # FIN packet in -> out
5322 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5323 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5324 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
5325 flags="FA", seq=100, ack=300))
5326 self.pg0.add_stream(p)
5327 self.pg_enable_capture(self.pg_interfaces)
5328 self.pg_start()
5329 self.pg1.get_capture(1)
Matus Fabianebdf1902018-05-04 03:57:42 -07005330
Matus Fabian229c1aa2018-05-28 04:09:52 -07005331 # FIN packet out -> in
5332 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5333 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5334 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
5335 flags="FA", seq=300, ack=100))
5336 self.pg1.add_stream(p)
5337 self.pg_enable_capture(self.pg_interfaces)
5338 self.pg_start()
5339 self.pg0.get_capture(1)
Matus Fabianebdf1902018-05-04 03:57:42 -07005340
Matus Fabian229c1aa2018-05-28 04:09:52 -07005341 # ACK packet in -> out
5342 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5343 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5344 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
5345 flags="A", seq=101, ack=301))
5346 self.pg0.add_stream(p)
5347 self.pg_enable_capture(self.pg_interfaces)
5348 self.pg_start()
5349 self.pg1.get_capture(1)
Matus Fabianebdf1902018-05-04 03:57:42 -07005350
Matus Fabian229c1aa2018-05-28 04:09:52 -07005351 # ACK packet out -> in
5352 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5353 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5354 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
5355 flags="A", seq=301, ack=101))
5356 self.pg1.add_stream(p)
5357 self.pg_enable_capture(self.pg_interfaces)
5358 self.pg_start()
5359 self.pg0.get_capture(1)
Matus Fabianebdf1902018-05-04 03:57:42 -07005360
Matus Fabian229c1aa2018-05-28 04:09:52 -07005361 sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4n,
5362 0)
5363 self.assertEqual(len(sessions) - start_sessnum, 0)
Matus Fabianebdf1902018-05-04 03:57:42 -07005364
Matus Fabiana6110b62018-06-13 05:39:07 -07005365 def test_one_armed_nat44_static(self):
5366 """ One armed NAT44 and 1:1 NAPT asymmetrical rule """
5367 remote_host = self.pg4.remote_hosts[0]
5368 local_host = self.pg4.remote_hosts[1]
5369 external_port = 80
5370 local_port = 8080
5371 eh_port_in = 0
5372
5373 self.vapi.nat44_forwarding_enable_disable(1)
5374 self.nat44_add_address(self.nat_addr, twice_nat=1)
5375 self.nat44_add_static_mapping(local_host.ip4, self.nat_addr,
5376 local_port, external_port,
5377 proto=IP_PROTOS.tcp, out2in_only=1,
5378 twice_nat=1)
5379 self.vapi.nat44_interface_add_del_feature(self.pg4.sw_if_index)
5380 self.vapi.nat44_interface_add_del_feature(self.pg4.sw_if_index,
5381 is_inside=0)
5382
5383 # from client to service
5384 p = (Ether(src=self.pg4.remote_mac, dst=self.pg4.local_mac) /
5385 IP(src=remote_host.ip4, dst=self.nat_addr) /
5386 TCP(sport=12345, dport=external_port))
5387 self.pg4.add_stream(p)
5388 self.pg_enable_capture(self.pg_interfaces)
5389 self.pg_start()
5390 capture = self.pg4.get_capture(1)
5391 p = capture[0]
5392 try:
5393 ip = p[IP]
5394 tcp = p[TCP]
5395 self.assertEqual(ip.dst, local_host.ip4)
5396 self.assertEqual(ip.src, self.nat_addr)
5397 self.assertEqual(tcp.dport, local_port)
5398 self.assertNotEqual(tcp.sport, 12345)
5399 eh_port_in = tcp.sport
5400 self.assert_packet_checksums_valid(p)
5401 except:
5402 self.logger.error(ppp("Unexpected or invalid packet:", p))
5403 raise
5404
5405 # from service back to client
5406 p = (Ether(src=self.pg4.remote_mac, dst=self.pg4.local_mac) /
5407 IP(src=local_host.ip4, dst=self.nat_addr) /
5408 TCP(sport=local_port, dport=eh_port_in))
5409 self.pg4.add_stream(p)
5410 self.pg_enable_capture(self.pg_interfaces)
5411 self.pg_start()
5412 capture = self.pg4.get_capture(1)
5413 p = capture[0]
5414 try:
5415 ip = p[IP]
5416 tcp = p[TCP]
5417 self.assertEqual(ip.src, self.nat_addr)
5418 self.assertEqual(ip.dst, remote_host.ip4)
5419 self.assertEqual(tcp.sport, external_port)
5420 self.assertEqual(tcp.dport, 12345)
5421 self.assert_packet_checksums_valid(p)
5422 except:
5423 self.logger.error(ppp("Unexpected or invalid packet:", p))
5424 raise
5425
5426 def test_static_with_port_out2(self):
5427 """ 1:1 NAPT asymmetrical rule """
5428
5429 external_port = 80
5430 local_port = 8080
5431
5432 self.vapi.nat44_forwarding_enable_disable(1)
5433 self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
5434 local_port, external_port,
5435 proto=IP_PROTOS.tcp, out2in_only=1)
5436 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
5437 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
5438 is_inside=0)
5439
5440 # from client to service
5441 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5442 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5443 TCP(sport=12345, dport=external_port))
5444 self.pg1.add_stream(p)
5445 self.pg_enable_capture(self.pg_interfaces)
5446 self.pg_start()
5447 capture = self.pg0.get_capture(1)
5448 p = capture[0]
5449 try:
5450 ip = p[IP]
5451 tcp = p[TCP]
5452 self.assertEqual(ip.dst, self.pg0.remote_ip4)
5453 self.assertEqual(tcp.dport, local_port)
5454 self.assert_packet_checksums_valid(p)
5455 except:
5456 self.logger.error(ppp("Unexpected or invalid packet:", p))
5457 raise
5458
5459 # ICMP error
5460 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
5461 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5462 ICMP(type=11) / capture[0][IP])
5463 self.pg0.add_stream(p)
5464 self.pg_enable_capture(self.pg_interfaces)
5465 self.pg_start()
5466 capture = self.pg1.get_capture(1)
5467 p = capture[0]
5468 try:
5469 self.assertEqual(p[IP].src, self.nat_addr)
5470 inner = p[IPerror]
5471 self.assertEqual(inner.dst, self.nat_addr)
5472 self.assertEqual(inner[TCPerror].dport, external_port)
5473 except:
5474 self.logger.error(ppp("Unexpected or invalid packet:", p))
5475 raise
5476
5477 # from service back to client
5478 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5479 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5480 TCP(sport=local_port, dport=12345))
5481 self.pg0.add_stream(p)
5482 self.pg_enable_capture(self.pg_interfaces)
5483 self.pg_start()
5484 capture = self.pg1.get_capture(1)
5485 p = capture[0]
5486 try:
5487 ip = p[IP]
5488 tcp = p[TCP]
5489 self.assertEqual(ip.src, self.nat_addr)
5490 self.assertEqual(tcp.sport, external_port)
5491 self.assert_packet_checksums_valid(p)
5492 except:
5493 self.logger.error(ppp("Unexpected or invalid packet:", p))
5494 raise
5495
5496 # ICMP error
5497 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
5498 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5499 ICMP(type=11) / capture[0][IP])
5500 self.pg1.add_stream(p)
5501 self.pg_enable_capture(self.pg_interfaces)
5502 self.pg_start()
5503 capture = self.pg0.get_capture(1)
5504 p = capture[0]
5505 try:
5506 self.assertEqual(p[IP].dst, self.pg0.remote_ip4)
5507 inner = p[IPerror]
5508 self.assertEqual(inner.src, self.pg0.remote_ip4)
5509 self.assertEqual(inner[TCPerror].sport, local_port)
5510 except:
5511 self.logger.error(ppp("Unexpected or invalid packet:", p))
5512 raise
5513
5514 # from client to server (no translation)
5515 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5516 IP(src=self.pg1.remote_ip4, dst=self.pg0.remote_ip4) /
5517 TCP(sport=12346, dport=local_port))
5518 self.pg1.add_stream(p)
5519 self.pg_enable_capture(self.pg_interfaces)
5520 self.pg_start()
5521 capture = self.pg0.get_capture(1)
5522 p = capture[0]
5523 try:
5524 ip = p[IP]
5525 tcp = p[TCP]
5526 self.assertEqual(ip.dst, self.pg0.remote_ip4)
5527 self.assertEqual(tcp.dport, local_port)
5528 self.assert_packet_checksums_valid(p)
5529 except:
5530 self.logger.error(ppp("Unexpected or invalid packet:", p))
5531 raise
5532
5533 # from service back to client (no translation)
5534 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5535 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5536 TCP(sport=local_port, dport=12346))
5537 self.pg0.add_stream(p)
5538 self.pg_enable_capture(self.pg_interfaces)
5539 self.pg_start()
5540 capture = self.pg1.get_capture(1)
5541 p = capture[0]
5542 try:
5543 ip = p[IP]
5544 tcp = p[TCP]
5545 self.assertEqual(ip.src, self.pg0.remote_ip4)
5546 self.assertEqual(tcp.sport, local_port)
5547 self.assert_packet_checksums_valid(p)
5548 except:
5549 self.logger.error(ppp("Unexpected or invalid packet:", p))
5550 raise
5551
Matus Fabian235a47e2018-06-25 16:42:36 -07005552 def test_output_feature(self):
5553 """ NAT44 interface output feature (in2out postrouting) """
5554 self.vapi.nat44_forwarding_enable_disable(1)
5555 self.nat44_add_address(self.nat_addr)
5556 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index,
5557 is_inside=0)
5558 self.vapi.nat44_interface_add_del_output_feature(self.pg1.sw_if_index,
5559 is_inside=0)
5560
5561 # in2out
5562 pkts = self.create_stream_in(self.pg0, self.pg1)
5563 self.pg0.add_stream(pkts)
5564 self.pg_enable_capture(self.pg_interfaces)
5565 self.pg_start()
5566 capture = self.pg1.get_capture(len(pkts))
5567 self.verify_capture_out(capture)
5568
5569 # out2in
5570 pkts = self.create_stream_out(self.pg1)
5571 self.pg1.add_stream(pkts)
5572 self.pg_enable_capture(self.pg_interfaces)
5573 self.pg_start()
5574 capture = self.pg0.get_capture(len(pkts))
5575 self.verify_capture_in(capture, self.pg0)
5576
Matus Fabian8008d7c2018-07-09 01:34:20 -07005577 def test_multiple_vrf(self):
5578 """ Multiple VRF setup """
5579 external_addr = '1.2.3.4'
5580 external_port = 80
5581 local_port = 8080
5582 port = 0
5583
5584 self.vapi.nat44_forwarding_enable_disable(1)
5585 self.nat44_add_address(self.nat_addr)
5586 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
5587 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index,
5588 is_inside=0)
5589 self.vapi.nat44_interface_add_del_output_feature(self.pg1.sw_if_index,
5590 is_inside=0)
5591 self.vapi.nat44_interface_add_del_feature(self.pg5.sw_if_index)
5592 self.vapi.nat44_interface_add_del_feature(self.pg5.sw_if_index,
5593 is_inside=0)
5594 self.vapi.nat44_interface_add_del_feature(self.pg6.sw_if_index,
5595 is_inside=0)
5596 self.nat44_add_static_mapping(self.pg5.remote_ip4, external_addr,
5597 local_port, external_port, vrf_id=1,
5598 proto=IP_PROTOS.tcp, out2in_only=1)
5599 self.nat44_add_static_mapping(
5600 self.pg0.remote_ip4, external_sw_if_index=self.pg0.sw_if_index,
5601 local_port=local_port, vrf_id=0, external_port=external_port,
5602 proto=IP_PROTOS.tcp, out2in_only=1)
5603
5604 # from client to service (both VRF1)
5605 p = (Ether(src=self.pg6.remote_mac, dst=self.pg6.local_mac) /
5606 IP(src=self.pg6.remote_ip4, dst=external_addr) /
5607 TCP(sport=12345, dport=external_port))
5608 self.pg6.add_stream(p)
5609 self.pg_enable_capture(self.pg_interfaces)
5610 self.pg_start()
5611 capture = self.pg5.get_capture(1)
5612 p = capture[0]
5613 try:
5614 ip = p[IP]
5615 tcp = p[TCP]
5616 self.assertEqual(ip.dst, self.pg5.remote_ip4)
5617 self.assertEqual(tcp.dport, local_port)
5618 self.assert_packet_checksums_valid(p)
5619 except:
5620 self.logger.error(ppp("Unexpected or invalid packet:", p))
5621 raise
5622
5623 # from service back to client (both VRF1)
5624 p = (Ether(src=self.pg5.remote_mac, dst=self.pg5.local_mac) /
5625 IP(src=self.pg5.remote_ip4, dst=self.pg6.remote_ip4) /
5626 TCP(sport=local_port, dport=12345))
5627 self.pg5.add_stream(p)
5628 self.pg_enable_capture(self.pg_interfaces)
5629 self.pg_start()
5630 capture = self.pg6.get_capture(1)
5631 p = capture[0]
5632 try:
5633 ip = p[IP]
5634 tcp = p[TCP]
5635 self.assertEqual(ip.src, external_addr)
5636 self.assertEqual(tcp.sport, external_port)
5637 self.assert_packet_checksums_valid(p)
5638 except:
5639 self.logger.error(ppp("Unexpected or invalid packet:", p))
5640 raise
5641
5642 # dynamic NAT from VRF1 to VRF0 (output-feature)
5643 p = (Ether(src=self.pg5.remote_mac, dst=self.pg5.local_mac) /
5644 IP(src=self.pg5.remote_ip4, dst=self.pg1.remote_ip4) /
5645 TCP(sport=2345, dport=22))
5646 self.pg5.add_stream(p)
5647 self.pg_enable_capture(self.pg_interfaces)
5648 self.pg_start()
5649 capture = self.pg1.get_capture(1)
5650 p = capture[0]
5651 try:
5652 ip = p[IP]
5653 tcp = p[TCP]
5654 self.assertEqual(ip.src, self.nat_addr)
5655 self.assertNotEqual(tcp.sport, 2345)
5656 self.assert_packet_checksums_valid(p)
5657 port = tcp.sport
5658 except:
5659 self.logger.error(ppp("Unexpected or invalid packet:", p))
5660 raise
5661
5662 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
5663 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
5664 TCP(sport=22, dport=port))
5665 self.pg1.add_stream(p)
5666 self.pg_enable_capture(self.pg_interfaces)
5667 self.pg_start()
5668 capture = self.pg5.get_capture(1)
5669 p = capture[0]
5670 try:
5671 ip = p[IP]
5672 tcp = p[TCP]
5673 self.assertEqual(ip.dst, self.pg5.remote_ip4)
5674 self.assertEqual(tcp.dport, 2345)
5675 self.assert_packet_checksums_valid(p)
5676 except:
5677 self.logger.error(ppp("Unexpected or invalid packet:", p))
5678 raise
5679
5680 # from client VRF1 to service VRF0
5681 p = (Ether(src=self.pg6.remote_mac, dst=self.pg6.local_mac) /
5682 IP(src=self.pg6.remote_ip4, dst=self.pg0.local_ip4) /
5683 TCP(sport=12346, dport=external_port))
5684 self.pg6.add_stream(p)
5685 self.pg_enable_capture(self.pg_interfaces)
5686 self.pg_start()
5687 capture = self.pg0.get_capture(1)
5688 p = capture[0]
5689 try:
5690 ip = p[IP]
5691 tcp = p[TCP]
5692 self.assertEqual(ip.dst, self.pg0.remote_ip4)
5693 self.assertEqual(tcp.dport, local_port)
5694 self.assert_packet_checksums_valid(p)
5695 except:
5696 self.logger.error(ppp("Unexpected or invalid packet:", p))
5697 raise
5698
5699 # from service VRF0 back to client VRF1
5700 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5701 IP(src=self.pg0.remote_ip4, dst=self.pg6.remote_ip4) /
5702 TCP(sport=local_port, dport=12346))
5703 self.pg0.add_stream(p)
5704 self.pg_enable_capture(self.pg_interfaces)
5705 self.pg_start()
5706 capture = self.pg6.get_capture(1)
5707 p = capture[0]
5708 try:
5709 ip = p[IP]
5710 tcp = p[TCP]
5711 self.assertEqual(ip.src, self.pg0.local_ip4)
5712 self.assertEqual(tcp.sport, external_port)
5713 self.assert_packet_checksums_valid(p)
5714 except:
5715 self.logger.error(ppp("Unexpected or invalid packet:", p))
5716 raise
5717
5718 # from client VRF0 to service VRF1
5719 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5720 IP(src=self.pg0.remote_ip4, dst=external_addr) /
5721 TCP(sport=12347, dport=external_port))
5722 self.pg0.add_stream(p)
5723 self.pg_enable_capture(self.pg_interfaces)
5724 self.pg_start()
5725 capture = self.pg5.get_capture(1)
5726 p = capture[0]
5727 try:
5728 ip = p[IP]
5729 tcp = p[TCP]
5730 self.assertEqual(ip.dst, self.pg5.remote_ip4)
5731 self.assertEqual(tcp.dport, local_port)
5732 self.assert_packet_checksums_valid(p)
5733 except:
5734 self.logger.error(ppp("Unexpected or invalid packet:", p))
5735 raise
5736
5737 # from service VRF1 back to client VRF0
5738 p = (Ether(src=self.pg5.remote_mac, dst=self.pg5.local_mac) /
5739 IP(src=self.pg5.remote_ip4, dst=self.pg0.remote_ip4) /
5740 TCP(sport=local_port, dport=12347))
5741 self.pg5.add_stream(p)
5742 self.pg_enable_capture(self.pg_interfaces)
5743 self.pg_start()
5744 capture = self.pg0.get_capture(1)
5745 p = capture[0]
5746 try:
5747 ip = p[IP]
5748 tcp = p[TCP]
5749 self.assertEqual(ip.src, external_addr)
5750 self.assertEqual(tcp.sport, external_port)
5751 self.assert_packet_checksums_valid(p)
5752 except:
5753 self.logger.error(ppp("Unexpected or invalid packet:", p))
5754 raise
5755
5756 # from client to server (both VRF1, no translation)
5757 p = (Ether(src=self.pg6.remote_mac, dst=self.pg6.local_mac) /
5758 IP(src=self.pg6.remote_ip4, dst=self.pg5.remote_ip4) /
5759 TCP(sport=12348, dport=local_port))
5760 self.pg6.add_stream(p)
5761 self.pg_enable_capture(self.pg_interfaces)
5762 self.pg_start()
5763 capture = self.pg5.get_capture(1)
5764 p = capture[0]
5765 try:
5766 ip = p[IP]
5767 tcp = p[TCP]
5768 self.assertEqual(ip.dst, self.pg5.remote_ip4)
5769 self.assertEqual(tcp.dport, local_port)
5770 self.assert_packet_checksums_valid(p)
5771 except:
5772 self.logger.error(ppp("Unexpected or invalid packet:", p))
5773 raise
5774
5775 # from server back to client (both VRF1, no translation)
5776 p = (Ether(src=self.pg5.remote_mac, dst=self.pg5.local_mac) /
5777 IP(src=self.pg5.remote_ip4, dst=self.pg6.remote_ip4) /
5778 TCP(sport=local_port, dport=12348))
5779 self.pg5.add_stream(p)
5780 self.pg_enable_capture(self.pg_interfaces)
5781 self.pg_start()
5782 capture = self.pg6.get_capture(1)
5783 p = capture[0]
5784 try:
5785 ip = p[IP]
5786 tcp = p[TCP]
5787 self.assertEqual(ip.src, self.pg5.remote_ip4)
5788 self.assertEqual(tcp.sport, local_port)
5789 self.assert_packet_checksums_valid(p)
5790 except:
5791 self.logger.error(ppp("Unexpected or invalid packet:", p))
5792 raise
5793
5794 # from client VRF1 to server VRF0 (no translation)
5795 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5796 IP(src=self.pg0.remote_ip4, dst=self.pg6.remote_ip4) /
5797 TCP(sport=local_port, dport=12349))
5798 self.pg0.add_stream(p)
5799 self.pg_enable_capture(self.pg_interfaces)
5800 self.pg_start()
5801 capture = self.pg6.get_capture(1)
5802 p = capture[0]
5803 try:
5804 ip = p[IP]
5805 tcp = p[TCP]
5806 self.assertEqual(ip.src, self.pg0.remote_ip4)
5807 self.assertEqual(tcp.sport, local_port)
5808 self.assert_packet_checksums_valid(p)
5809 except:
5810 self.logger.error(ppp("Unexpected or invalid packet:", p))
5811 raise
5812
5813 # from server VRF0 back to client VRF1 (no translation)
5814 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5815 IP(src=self.pg0.remote_ip4, dst=self.pg6.remote_ip4) /
5816 TCP(sport=local_port, dport=12349))
5817 self.pg0.add_stream(p)
5818 self.pg_enable_capture(self.pg_interfaces)
5819 self.pg_start()
5820 capture = self.pg6.get_capture(1)
5821 p = capture[0]
5822 try:
5823 ip = p[IP]
5824 tcp = p[TCP]
5825 self.assertEqual(ip.src, self.pg0.remote_ip4)
5826 self.assertEqual(tcp.sport, local_port)
5827 self.assert_packet_checksums_valid(p)
5828 except:
5829 self.logger.error(ppp("Unexpected or invalid packet:", p))
5830 raise
5831
5832 # from client VRF0 to server VRF1 (no translation)
5833 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5834 IP(src=self.pg0.remote_ip4, dst=self.pg5.remote_ip4) /
5835 TCP(sport=12344, dport=local_port))
5836 self.pg0.add_stream(p)
5837 self.pg_enable_capture(self.pg_interfaces)
5838 self.pg_start()
5839 capture = self.pg5.get_capture(1)
5840 p = capture[0]
5841 try:
5842 ip = p[IP]
5843 tcp = p[TCP]
5844 self.assertEqual(ip.dst, self.pg5.remote_ip4)
5845 self.assertEqual(tcp.dport, local_port)
5846 self.assert_packet_checksums_valid(p)
5847 except:
5848 self.logger.error(ppp("Unexpected or invalid packet:", p))
5849 raise
5850
5851 # from server VRF1 back to client VRF0 (no translation)
5852 p = (Ether(src=self.pg5.remote_mac, dst=self.pg5.local_mac) /
5853 IP(src=self.pg5.remote_ip4, dst=self.pg0.remote_ip4) /
5854 TCP(sport=local_port, dport=12344))
5855 self.pg5.add_stream(p)
5856 self.pg_enable_capture(self.pg_interfaces)
5857 self.pg_start()
5858 capture = self.pg0.get_capture(1)
5859 p = capture[0]
5860 try:
5861 ip = p[IP]
5862 tcp = p[TCP]
5863 self.assertEqual(ip.src, self.pg5.remote_ip4)
5864 self.assertEqual(tcp.sport, local_port)
5865 self.assert_packet_checksums_valid(p)
5866 except:
5867 self.logger.error(ppp("Unexpected or invalid packet:", p))
5868 raise
5869
Paul Vinciguerradefde0f2018-12-06 07:46:13 -08005870 @unittest.skipUnless(running_extended_tests, "part of extended tests")
Matus Fabian878c6462018-08-23 00:33:35 -07005871 def test_session_timeout(self):
5872 """ NAT44 session timeouts """
5873 self.nat44_add_address(self.nat_addr)
5874 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
5875 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
5876 is_inside=0)
5877 self.vapi.nat_set_timeouts(icmp=5)
5878
5879 max_sessions = 1000
5880 pkts = []
5881 for i in range(0, max_sessions):
5882 src = "10.10.%u.%u" % ((i & 0xFF00) >> 8, i & 0xFF)
5883 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
5884 IP(src=src, dst=self.pg1.remote_ip4) /
5885 ICMP(id=1025, 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 sleep(10)
5893
5894 pkts = []
5895 for i in range(0, max_sessions):
Matus Fabian7f8a8db2018-11-22 00:12:15 -08005896 src = "10.11.%u.%u" % ((i & 0xFF00) >> 8, i & 0xFF)
Matus Fabian878c6462018-08-23 00:33:35 -07005897 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
5898 IP(src=src, dst=self.pg1.remote_ip4) /
5899 ICMP(id=1026, type='echo-request'))
5900 pkts.append(p)
5901 self.pg0.add_stream(pkts)
5902 self.pg_enable_capture(self.pg_interfaces)
5903 self.pg_start()
5904 self.pg1.get_capture(max_sessions)
5905
5906 nsessions = 0
5907 users = self.vapi.nat44_user_dump()
5908 for user in users:
5909 nsessions = nsessions + user.nsessions
5910 self.assertLess(nsessions, 2 * max_sessions)
5911
Paul Vinciguerradefde0f2018-12-06 07:46:13 -08005912 @unittest.skipUnless(running_extended_tests, "part of extended tests")
Matus Fabian15e8e682018-11-21 04:53:10 -08005913 def test_session_rst_timeout(self):
5914 """ NAT44 session RST timeouts """
5915 self.nat44_add_address(self.nat_addr)
5916 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
5917 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
5918 is_inside=0)
5919 self.vapi.nat_set_timeouts(tcp_transitory=5)
5920
Matus Fabian15e8e682018-11-21 04:53:10 -08005921 self.initiate_tcp_session(self.pg0, self.pg1)
5922 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5923 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5924 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
5925 flags="R"))
5926 self.pg0.add_stream(p)
5927 self.pg_enable_capture(self.pg_interfaces)
5928 self.pg_start()
5929 self.pg1.get_capture(1)
5930
Matus Fabian15e8e682018-11-21 04:53:10 -08005931 sleep(6)
5932
5933 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5934 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5935 TCP(sport=self.tcp_port_in + 1, dport=self.tcp_external_port + 1,
5936 flags="S"))
5937 self.pg0.add_stream(p)
5938 self.pg_enable_capture(self.pg_interfaces)
5939 self.pg_start()
5940 self.pg1.get_capture(1)
5941
5942 nsessions = 0
5943 users = self.vapi.nat44_user_dump()
5944 self.assertEqual(len(users), 1)
5945 self.assertEqual(users[0].ip_address, self.pg0.remote_ip4n)
Matus Fabian7f8a8db2018-11-22 00:12:15 -08005946 self.assertEqual(users[0].nsessions, 1)
Matus Fabian15e8e682018-11-21 04:53:10 -08005947
Paul Vinciguerradefde0f2018-12-06 07:46:13 -08005948 @unittest.skipUnless(running_extended_tests, "part of extended tests")
Matus Fabian878c6462018-08-23 00:33:35 -07005949 def test_session_limit_per_user(self):
5950 """ Maximum sessions per user limit """
5951 self.nat44_add_address(self.nat_addr)
5952 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
5953 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
5954 is_inside=0)
5955 self.vapi.set_ipfix_exporter(collector_address=self.pg2.remote_ip4n,
5956 src_address=self.pg2.local_ip4n,
5957 path_mtu=512,
5958 template_interval=10)
Matus Fabian8fdc0152018-09-24 04:41:28 -07005959 self.vapi.nat_set_timeouts(udp=5)
Matus Fabian878c6462018-08-23 00:33:35 -07005960
5961 # get maximum number of translations per user
5962 nat44_config = self.vapi.nat_show_config()
5963
5964 pkts = []
5965 for port in range(0, nat44_config.max_translations_per_user):
5966 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5967 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5968 UDP(sport=1025 + port, dport=1025 + port))
5969 pkts.append(p)
5970
5971 self.pg0.add_stream(pkts)
5972 self.pg_enable_capture(self.pg_interfaces)
5973 self.pg_start()
5974 capture = self.pg1.get_capture(len(pkts))
5975
5976 self.vapi.nat_ipfix(domain_id=self.ipfix_domain_id,
5977 src_port=self.ipfix_src_port)
5978
5979 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
5980 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
5981 UDP(sport=3001, dport=3002))
5982 self.pg0.add_stream(p)
5983 self.pg_enable_capture(self.pg_interfaces)
5984 self.pg_start()
5985 capture = self.pg1.assert_nothing_captured()
5986
5987 # verify IPFIX logging
5988 self.vapi.cli("ipfix flush") # FIXME this should be an API call
5989 sleep(1)
5990 capture = self.pg2.get_capture(10)
5991 ipfix = IPFIXDecoder()
5992 # first load template
5993 for p in capture:
5994 self.assertTrue(p.haslayer(IPFIX))
5995 if p.haslayer(Template):
5996 ipfix.add_template(p.getlayer(Template))
5997 # verify events in data set
5998 for p in capture:
5999 if p.haslayer(Data):
6000 data = ipfix.decode_data_set(p.getlayer(Set))
6001 self.verify_ipfix_max_entries_per_user(
6002 data,
6003 nat44_config.max_translations_per_user,
6004 self.pg0.remote_ip4n)
6005
Matus Fabian8fdc0152018-09-24 04:41:28 -07006006 sleep(6)
6007 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6008 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6009 UDP(sport=3001, dport=3002))
6010 self.pg0.add_stream(p)
6011 self.pg_enable_capture(self.pg_interfaces)
6012 self.pg_start()
6013 self.pg1.get_capture(1)
6014
Matus Fabianad1f3e12018-11-28 21:26:34 -08006015 def test_syslog_sess(self):
6016 """ Test syslog session creation and deletion """
6017 self.vapi.syslog_set_filter(SYSLOG_SEVERITY.INFO)
6018 self.vapi.syslog_set_sender(self.pg2.remote_ip4n, self.pg2.local_ip4n)
6019 self.nat44_add_address(self.nat_addr)
6020 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
6021 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
6022 is_inside=0)
6023
6024 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
6025 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6026 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port))
6027 self.pg0.add_stream(p)
6028 self.pg_enable_capture(self.pg_interfaces)
6029 self.pg_start()
6030 capture = self.pg1.get_capture(1)
6031 self.tcp_port_out = capture[0][TCP].sport
6032 capture = self.pg2.get_capture(1)
6033 self.verify_syslog_sess(capture[0][Raw].load)
6034
6035 self.pg_enable_capture(self.pg_interfaces)
6036 self.pg_start()
6037 self.nat44_add_address(self.nat_addr, is_add=0)
6038 capture = self.pg2.get_capture(1)
6039 self.verify_syslog_sess(capture[0][Raw].load, False)
6040
Matus Fabiande886752016-12-07 03:38:19 -08006041 def tearDown(self):
Matus Fabiana6110b62018-06-13 05:39:07 -07006042 super(TestNAT44EndpointDependent, self).tearDown()
Matus Fabiande886752016-12-07 03:38:19 -08006043 if not self.vpp_dead:
Matus Fabian82119542018-01-25 01:13:22 -08006044 self.logger.info(self.vapi.cli("show nat44 addresses"))
6045 self.logger.info(self.vapi.cli("show nat44 interfaces"))
6046 self.logger.info(self.vapi.cli("show nat44 static mappings"))
6047 self.logger.info(self.vapi.cli("show nat44 interface address"))
6048 self.logger.info(self.vapi.cli("show nat44 sessions detail"))
Matus Fabian229c1aa2018-05-28 04:09:52 -07006049 self.logger.info(self.vapi.cli("show nat44 hash tables detail"))
Matus Fabian878c6462018-08-23 00:33:35 -07006050 self.logger.info(self.vapi.cli("show nat timeouts"))
Matus Fabian2ba92e32017-08-21 07:05:03 -07006051 self.clear_nat44()
Matus Fabian229c1aa2018-05-28 04:09:52 -07006052 self.vapi.cli("clear logging")
Matus Fabiande886752016-12-07 03:38:19 -08006053
Matus Fabianeea28d72017-01-13 04:15:54 -08006054
Juraj Slobodacba69362017-12-19 02:09:32 +01006055class TestNAT44Out2InDPO(MethodHolder):
6056 """ NAT44 Test Cases using out2in DPO """
6057
6058 @classmethod
6059 def setUpConstants(cls):
6060 super(TestNAT44Out2InDPO, cls).setUpConstants()
6061 cls.vpp_cmdline.extend(["nat", "{", "out2in dpo", "}"])
6062
6063 @classmethod
6064 def setUpClass(cls):
6065 super(TestNAT44Out2InDPO, cls).setUpClass()
Matus Fabian229c1aa2018-05-28 04:09:52 -07006066 cls.vapi.cli("set log class nat level debug")
Juraj Slobodacba69362017-12-19 02:09:32 +01006067
6068 try:
6069 cls.tcp_port_in = 6303
6070 cls.tcp_port_out = 6303
6071 cls.udp_port_in = 6304
6072 cls.udp_port_out = 6304
6073 cls.icmp_id_in = 6305
6074 cls.icmp_id_out = 6305
6075 cls.nat_addr = '10.0.0.3'
6076 cls.nat_addr_n = socket.inet_pton(socket.AF_INET, cls.nat_addr)
6077 cls.dst_ip4 = '192.168.70.1'
6078
6079 cls.create_pg_interfaces(range(2))
6080
6081 cls.pg0.admin_up()
6082 cls.pg0.config_ip4()
6083 cls.pg0.resolve_arp()
6084
6085 cls.pg1.admin_up()
6086 cls.pg1.config_ip6()
6087 cls.pg1.resolve_ndp()
6088
6089 cls.vapi.ip_add_del_route(is_ipv6=True, dst_address='\x00'*16,
6090 dst_address_length=0,
6091 next_hop_address=cls.pg1.remote_ip6n,
6092 next_hop_sw_if_index=cls.pg1.sw_if_index)
6093
6094 except Exception:
6095 super(TestNAT44Out2InDPO, cls).tearDownClass()
6096 raise
6097
6098 def configure_xlat(self):
6099 self.dst_ip6_pfx = '1:2:3::'
6100 self.dst_ip6_pfx_n = socket.inet_pton(socket.AF_INET6,
6101 self.dst_ip6_pfx)
6102 self.dst_ip6_pfx_len = 96
6103 self.src_ip6_pfx = '4:5:6::'
6104 self.src_ip6_pfx_n = socket.inet_pton(socket.AF_INET6,
6105 self.src_ip6_pfx)
6106 self.src_ip6_pfx_len = 96
6107 self.vapi.map_add_domain(self.dst_ip6_pfx_n, self.dst_ip6_pfx_len,
6108 self.src_ip6_pfx_n, self.src_ip6_pfx_len,
Jon Loeligerfc7344f2018-12-20 11:47:30 -06006109 '\x00\x00\x00\x00', 0)
Juraj Slobodacba69362017-12-19 02:09:32 +01006110
Ole Troanffba3c32018-11-22 12:53:00 +01006111 @unittest.skip('Temporary disabled')
Juraj Slobodacba69362017-12-19 02:09:32 +01006112 def test_464xlat_ce(self):
6113 """ Test 464XLAT CE with NAT44 """
6114
Matus Fabian69ce30d2018-08-22 01:27:10 -07006115 nat_config = self.vapi.nat_show_config()
6116 self.assertEqual(1, nat_config.out2in_dpo)
6117
Juraj Slobodacba69362017-12-19 02:09:32 +01006118 self.configure_xlat()
6119
6120 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
6121 self.vapi.nat44_add_del_address_range(self.nat_addr_n, self.nat_addr_n)
6122
6123 out_src_ip6 = self.compose_ip6(self.dst_ip4, self.dst_ip6_pfx,
6124 self.dst_ip6_pfx_len)
6125 out_dst_ip6 = self.compose_ip6(self.nat_addr, self.src_ip6_pfx,
6126 self.src_ip6_pfx_len)
6127
6128 try:
6129 pkts = self.create_stream_in(self.pg0, self.pg1, self.dst_ip4)
6130 self.pg0.add_stream(pkts)
6131 self.pg_enable_capture(self.pg_interfaces)
6132 self.pg_start()
6133 capture = self.pg1.get_capture(len(pkts))
6134 self.verify_capture_out_ip6(capture, nat_ip=out_dst_ip6,
6135 dst_ip=out_src_ip6)
6136
6137 pkts = self.create_stream_out_ip6(self.pg1, out_src_ip6,
6138 out_dst_ip6)
6139 self.pg1.add_stream(pkts)
6140 self.pg_enable_capture(self.pg_interfaces)
6141 self.pg_start()
6142 capture = self.pg0.get_capture(len(pkts))
6143 self.verify_capture_in(capture, self.pg0)
6144 finally:
6145 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index,
6146 is_add=0)
6147 self.vapi.nat44_add_del_address_range(self.nat_addr_n,
6148 self.nat_addr_n, is_add=0)
6149
Ole Troanffba3c32018-11-22 12:53:00 +01006150 @unittest.skip('Temporary disabled')
Juraj Slobodacba69362017-12-19 02:09:32 +01006151 def test_464xlat_ce_no_nat(self):
6152 """ Test 464XLAT CE without NAT44 """
6153
6154 self.configure_xlat()
6155
6156 out_src_ip6 = self.compose_ip6(self.dst_ip4, self.dst_ip6_pfx,
6157 self.dst_ip6_pfx_len)
6158 out_dst_ip6 = self.compose_ip6(self.pg0.remote_ip4, self.src_ip6_pfx,
6159 self.src_ip6_pfx_len)
6160
6161 pkts = self.create_stream_in(self.pg0, self.pg1, self.dst_ip4)
6162 self.pg0.add_stream(pkts)
6163 self.pg_enable_capture(self.pg_interfaces)
6164 self.pg_start()
6165 capture = self.pg1.get_capture(len(pkts))
6166 self.verify_capture_out_ip6(capture, dst_ip=out_src_ip6,
6167 nat_ip=out_dst_ip6, same_port=True)
6168
6169 pkts = self.create_stream_out_ip6(self.pg1, out_src_ip6, out_dst_ip6)
6170 self.pg1.add_stream(pkts)
6171 self.pg_enable_capture(self.pg_interfaces)
6172 self.pg_start()
6173 capture = self.pg0.get_capture(len(pkts))
6174 self.verify_capture_in(capture, self.pg0)
6175
6176
Martin Gálikd7f75cd2017-03-27 06:02:47 -07006177class TestDeterministicNAT(MethodHolder):
Matus Fabian066f0342017-02-10 03:48:01 -08006178 """ Deterministic NAT Test Cases """
6179
6180 @classmethod
6181 def setUpConstants(cls):
6182 super(TestDeterministicNAT, cls).setUpConstants()
Matus Fabian2ba92e32017-08-21 07:05:03 -07006183 cls.vpp_cmdline.extend(["nat", "{", "deterministic", "}"])
Matus Fabian066f0342017-02-10 03:48:01 -08006184
6185 @classmethod
6186 def setUpClass(cls):
6187 super(TestDeterministicNAT, cls).setUpClass()
Matus Fabian229c1aa2018-05-28 04:09:52 -07006188 cls.vapi.cli("set log class nat level debug")
Matus Fabian066f0342017-02-10 03:48:01 -08006189
6190 try:
Martin Gálik977c1cb2017-03-30 23:21:51 -07006191 cls.tcp_port_in = 6303
Martin Gálik9806eae2017-04-25 01:25:08 -07006192 cls.tcp_external_port = 6303
Martin Gálik977c1cb2017-03-30 23:21:51 -07006193 cls.udp_port_in = 6304
Martin Gálik9806eae2017-04-25 01:25:08 -07006194 cls.udp_external_port = 6304
Martin Gálik977c1cb2017-03-30 23:21:51 -07006195 cls.icmp_id_in = 6305
Matus Fabian2ba92e32017-08-21 07:05:03 -07006196 cls.nat_addr = '10.0.0.3'
Martin Gálik977c1cb2017-03-30 23:21:51 -07006197
Matus Fabian2f2db1c2017-04-18 05:29:59 -07006198 cls.create_pg_interfaces(range(3))
Matus Fabian066f0342017-02-10 03:48:01 -08006199 cls.interfaces = list(cls.pg_interfaces)
6200
6201 for i in cls.interfaces:
6202 i.admin_up()
6203 i.config_ip4()
6204 i.resolve_arp()
6205
Martin Gálik977c1cb2017-03-30 23:21:51 -07006206 cls.pg0.generate_remote_hosts(2)
6207 cls.pg0.configure_ipv4_neighbors()
6208
Matus Fabian066f0342017-02-10 03:48:01 -08006209 except Exception:
6210 super(TestDeterministicNAT, cls).tearDownClass()
6211 raise
6212
Martin Gálik977c1cb2017-03-30 23:21:51 -07006213 def create_stream_in(self, in_if, out_if, ttl=64):
6214 """
6215 Create packet stream for inside network
6216
6217 :param in_if: Inside interface
6218 :param out_if: Outside interface
6219 :param ttl: TTL of generated packets
6220 """
6221 pkts = []
6222 # TCP
6223 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
6224 IP(src=in_if.remote_ip4, dst=out_if.remote_ip4, ttl=ttl) /
Martin Gálik9806eae2017-04-25 01:25:08 -07006225 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port))
Martin Gálik977c1cb2017-03-30 23:21:51 -07006226 pkts.append(p)
6227
6228 # UDP
6229 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
6230 IP(src=in_if.remote_ip4, dst=out_if.remote_ip4, ttl=ttl) /
Martin Gálik9806eae2017-04-25 01:25:08 -07006231 UDP(sport=self.udp_port_in, dport=self.udp_external_port))
Martin Gálik977c1cb2017-03-30 23:21:51 -07006232 pkts.append(p)
6233
6234 # ICMP
6235 p = (Ether(dst=in_if.local_mac, src=in_if.remote_mac) /
6236 IP(src=in_if.remote_ip4, dst=out_if.remote_ip4, ttl=ttl) /
6237 ICMP(id=self.icmp_id_in, type='echo-request'))
6238 pkts.append(p)
6239
6240 return pkts
6241
6242 def create_stream_out(self, out_if, dst_ip=None, ttl=64):
6243 """
6244 Create packet stream for outside network
6245
6246 :param out_if: Outside interface
Matus Fabian2ba92e32017-08-21 07:05:03 -07006247 :param dst_ip: Destination IP address (Default use global NAT address)
Martin Gálik977c1cb2017-03-30 23:21:51 -07006248 :param ttl: TTL of generated packets
6249 """
6250 if dst_ip is None:
Matus Fabian2ba92e32017-08-21 07:05:03 -07006251 dst_ip = self.nat_addr
Martin Gálik977c1cb2017-03-30 23:21:51 -07006252 pkts = []
6253 # TCP
6254 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
6255 IP(src=out_if.remote_ip4, dst=dst_ip, ttl=ttl) /
Martin Gálik9806eae2017-04-25 01:25:08 -07006256 TCP(dport=self.tcp_port_out, sport=self.tcp_external_port))
Martin Gálik977c1cb2017-03-30 23:21:51 -07006257 pkts.append(p)
6258
6259 # UDP
6260 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
6261 IP(src=out_if.remote_ip4, dst=dst_ip, ttl=ttl) /
Martin Gálik9806eae2017-04-25 01:25:08 -07006262 UDP(dport=self.udp_port_out, sport=self.udp_external_port))
Martin Gálik977c1cb2017-03-30 23:21:51 -07006263 pkts.append(p)
6264
6265 # ICMP
6266 p = (Ether(dst=out_if.local_mac, src=out_if.remote_mac) /
6267 IP(src=out_if.remote_ip4, dst=dst_ip, ttl=ttl) /
6268 ICMP(id=self.icmp_external_id, type='echo-reply'))
6269 pkts.append(p)
6270
6271 return pkts
6272
Matus Fabian05ca4a32018-09-04 23:45:13 -07006273 def verify_capture_out(self, capture, nat_ip=None):
Martin Gálik977c1cb2017-03-30 23:21:51 -07006274 """
6275 Verify captured packets on outside network
6276
6277 :param capture: Captured packets
Matus Fabian2ba92e32017-08-21 07:05:03 -07006278 :param nat_ip: Translated IP address (Default use global NAT address)
Martin Gálik977c1cb2017-03-30 23:21:51 -07006279 :param same_port: Sorce port number is not translated (Default False)
Martin Gálik977c1cb2017-03-30 23:21:51 -07006280 """
6281 if nat_ip is None:
Matus Fabian2ba92e32017-08-21 07:05:03 -07006282 nat_ip = self.nat_addr
Martin Gálik977c1cb2017-03-30 23:21:51 -07006283 for packet in capture:
6284 try:
6285 self.assertEqual(packet[IP].src, nat_ip)
6286 if packet.haslayer(TCP):
Martin Gálik9806eae2017-04-25 01:25:08 -07006287 self.tcp_port_out = packet[TCP].sport
Martin Gálik977c1cb2017-03-30 23:21:51 -07006288 elif packet.haslayer(UDP):
Martin Gálik9806eae2017-04-25 01:25:08 -07006289 self.udp_port_out = packet[UDP].sport
Martin Gálik977c1cb2017-03-30 23:21:51 -07006290 else:
6291 self.icmp_external_id = packet[ICMP].id
6292 except:
6293 self.logger.error(ppp("Unexpected or invalid packet "
6294 "(outside network):", packet))
6295 raise
6296
Matus Fabian066f0342017-02-10 03:48:01 -08006297 def test_deterministic_mode(self):
Matus Fabian2ba92e32017-08-21 07:05:03 -07006298 """ NAT plugin run deterministic mode """
Matus Fabian066f0342017-02-10 03:48:01 -08006299 in_addr = '172.16.255.0'
6300 out_addr = '172.17.255.50'
6301 in_addr_t = '172.16.255.20'
6302 in_addr_n = socket.inet_aton(in_addr)
6303 out_addr_n = socket.inet_aton(out_addr)
6304 in_addr_t_n = socket.inet_aton(in_addr_t)
6305 in_plen = 24
6306 out_plen = 32
6307
Matus Fabian2ba92e32017-08-21 07:05:03 -07006308 nat_config = self.vapi.nat_show_config()
6309 self.assertEqual(1, nat_config.deterministic)
Matus Fabian066f0342017-02-10 03:48:01 -08006310
Matus Fabian2ba92e32017-08-21 07:05:03 -07006311 self.vapi.nat_det_add_del_map(in_addr_n, in_plen, out_addr_n, out_plen)
Matus Fabian066f0342017-02-10 03:48:01 -08006312
Matus Fabian2ba92e32017-08-21 07:05:03 -07006313 rep1 = self.vapi.nat_det_forward(in_addr_t_n)
Matus Fabian066f0342017-02-10 03:48:01 -08006314 self.assertEqual(rep1.out_addr[:4], out_addr_n)
Matus Fabian2ba92e32017-08-21 07:05:03 -07006315 rep2 = self.vapi.nat_det_reverse(out_addr_n, rep1.out_port_hi)
Matus Fabian066f0342017-02-10 03:48:01 -08006316 self.assertEqual(rep2.in_addr[:4], in_addr_t_n)
6317
Matus Fabian2ba92e32017-08-21 07:05:03 -07006318 deterministic_mappings = self.vapi.nat_det_map_dump()
Martin17a75cb2017-03-08 05:53:20 -08006319 self.assertEqual(len(deterministic_mappings), 1)
6320 dsm = deterministic_mappings[0]
6321 self.assertEqual(in_addr_n, dsm.in_addr[:4])
6322 self.assertEqual(in_plen, dsm.in_plen)
6323 self.assertEqual(out_addr_n, dsm.out_addr[:4])
6324 self.assertEqual(out_plen, dsm.out_plen)
6325
Matus Fabian2ba92e32017-08-21 07:05:03 -07006326 self.clear_nat_det()
6327 deterministic_mappings = self.vapi.nat_det_map_dump()
Martinb616e9f2017-03-14 02:25:45 -07006328 self.assertEqual(len(deterministic_mappings), 0)
6329
Matus Fabian6a0946f2017-04-12 03:36:13 -07006330 def test_set_timeouts(self):
6331 """ Set deterministic NAT timeouts """
Matus Fabian878c6462018-08-23 00:33:35 -07006332 timeouts_before = self.vapi.nat_get_timeouts()
Matus Fabian6a0946f2017-04-12 03:36:13 -07006333
Matus Fabian878c6462018-08-23 00:33:35 -07006334 self.vapi.nat_set_timeouts(timeouts_before.udp + 10,
6335 timeouts_before.tcp_established + 10,
6336 timeouts_before.tcp_transitory + 10,
6337 timeouts_before.icmp + 10)
Matus Fabian6a0946f2017-04-12 03:36:13 -07006338
Matus Fabian878c6462018-08-23 00:33:35 -07006339 timeouts_after = self.vapi.nat_get_timeouts()
Matus Fabian6a0946f2017-04-12 03:36:13 -07006340
6341 self.assertNotEqual(timeouts_before.udp, timeouts_after.udp)
6342 self.assertNotEqual(timeouts_before.icmp, timeouts_after.icmp)
6343 self.assertNotEqual(timeouts_before.tcp_established,
6344 timeouts_after.tcp_established)
6345 self.assertNotEqual(timeouts_before.tcp_transitory,
6346 timeouts_after.tcp_transitory)
6347
Martin Gálik977c1cb2017-03-30 23:21:51 -07006348 def test_det_in(self):
Matus Fabian2ba92e32017-08-21 07:05:03 -07006349 """ Deterministic NAT translation test (TCP, UDP, ICMP) """
Martin Gálik977c1cb2017-03-30 23:21:51 -07006350
6351 nat_ip = "10.0.0.10"
Martin Gálik977c1cb2017-03-30 23:21:51 -07006352
Matus Fabian2ba92e32017-08-21 07:05:03 -07006353 self.vapi.nat_det_add_del_map(self.pg0.remote_ip4n,
6354 32,
6355 socket.inet_aton(nat_ip),
6356 32)
6357 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
6358 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
6359 is_inside=0)
Martin Gálik977c1cb2017-03-30 23:21:51 -07006360
6361 # in2out
6362 pkts = self.create_stream_in(self.pg0, self.pg1)
6363 self.pg0.add_stream(pkts)
6364 self.pg_enable_capture(self.pg_interfaces)
6365 self.pg_start()
6366 capture = self.pg1.get_capture(len(pkts))
6367 self.verify_capture_out(capture, nat_ip)
6368
6369 # out2in
6370 pkts = self.create_stream_out(self.pg1, nat_ip)
6371 self.pg1.add_stream(pkts)
6372 self.pg_enable_capture(self.pg_interfaces)
6373 self.pg_start()
6374 capture = self.pg0.get_capture(len(pkts))
6375 self.verify_capture_in(capture, self.pg0)
6376
Martin Gálik9806eae2017-04-25 01:25:08 -07006377 # session dump test
Matus Fabian2ba92e32017-08-21 07:05:03 -07006378 sessions = self.vapi.nat_det_session_dump(self.pg0.remote_ip4n)
Martin Gálik9806eae2017-04-25 01:25:08 -07006379 self.assertEqual(len(sessions), 3)
6380
6381 # TCP session
6382 s = sessions[0]
6383 self.assertEqual(s.ext_addr[:4], self.pg1.remote_ip4n)
6384 self.assertEqual(s.in_port, self.tcp_port_in)
6385 self.assertEqual(s.out_port, self.tcp_port_out)
6386 self.assertEqual(s.ext_port, self.tcp_external_port)
6387
6388 # UDP session
6389 s = sessions[1]
6390 self.assertEqual(s.ext_addr[:4], self.pg1.remote_ip4n)
6391 self.assertEqual(s.in_port, self.udp_port_in)
6392 self.assertEqual(s.out_port, self.udp_port_out)
6393 self.assertEqual(s.ext_port, self.udp_external_port)
6394
6395 # ICMP session
6396 s = sessions[2]
6397 self.assertEqual(s.ext_addr[:4], self.pg1.remote_ip4n)
6398 self.assertEqual(s.in_port, self.icmp_id_in)
6399 self.assertEqual(s.out_port, self.icmp_external_id)
6400
Martin Gálik977c1cb2017-03-30 23:21:51 -07006401 def test_multiple_users(self):
Matus Fabian2ba92e32017-08-21 07:05:03 -07006402 """ Deterministic NAT multiple users """
Martin Gálik977c1cb2017-03-30 23:21:51 -07006403
6404 nat_ip = "10.0.0.10"
6405 port_in = 80
Martin Gálik9806eae2017-04-25 01:25:08 -07006406 external_port = 6303
Martin Gálik977c1cb2017-03-30 23:21:51 -07006407
6408 host0 = self.pg0.remote_hosts[0]
6409 host1 = self.pg0.remote_hosts[1]
6410
Matus Fabian2ba92e32017-08-21 07:05:03 -07006411 self.vapi.nat_det_add_del_map(host0.ip4n,
6412 24,
6413 socket.inet_aton(nat_ip),
6414 32)
6415 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
6416 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
6417 is_inside=0)
Martin Gálik977c1cb2017-03-30 23:21:51 -07006418
6419 # host0 to out
6420 p = (Ether(src=host0.mac, dst=self.pg0.local_mac) /
6421 IP(src=host0.ip4, dst=self.pg1.remote_ip4) /
Martin Gálik9806eae2017-04-25 01:25:08 -07006422 TCP(sport=port_in, dport=external_port))
Martin Gálik977c1cb2017-03-30 23:21:51 -07006423 self.pg0.add_stream(p)
6424 self.pg_enable_capture(self.pg_interfaces)
6425 self.pg_start()
6426 capture = self.pg1.get_capture(1)
6427 p = capture[0]
6428 try:
6429 ip = p[IP]
6430 tcp = p[TCP]
6431 self.assertEqual(ip.src, nat_ip)
6432 self.assertEqual(ip.dst, self.pg1.remote_ip4)
Martin Gálik9806eae2017-04-25 01:25:08 -07006433 self.assertEqual(tcp.dport, external_port)
6434 port_out0 = tcp.sport
Martin Gálik977c1cb2017-03-30 23:21:51 -07006435 except:
6436 self.logger.error(ppp("Unexpected or invalid packet:", p))
6437 raise
6438
6439 # host1 to out
6440 p = (Ether(src=host1.mac, dst=self.pg0.local_mac) /
6441 IP(src=host1.ip4, dst=self.pg1.remote_ip4) /
Martin Gálik9806eae2017-04-25 01:25:08 -07006442 TCP(sport=port_in, dport=external_port))
Martin Gálik977c1cb2017-03-30 23:21:51 -07006443 self.pg0.add_stream(p)
6444 self.pg_enable_capture(self.pg_interfaces)
6445 self.pg_start()
6446 capture = self.pg1.get_capture(1)
6447 p = capture[0]
6448 try:
6449 ip = p[IP]
6450 tcp = p[TCP]
6451 self.assertEqual(ip.src, nat_ip)
6452 self.assertEqual(ip.dst, self.pg1.remote_ip4)
Martin Gálik9806eae2017-04-25 01:25:08 -07006453 self.assertEqual(tcp.dport, external_port)
6454 port_out1 = tcp.sport
Martin Gálik977c1cb2017-03-30 23:21:51 -07006455 except:
6456 self.logger.error(ppp("Unexpected or invalid packet:", p))
6457 raise
6458
Matus Fabian2ba92e32017-08-21 07:05:03 -07006459 dms = self.vapi.nat_det_map_dump()
Martin Gálik977c1cb2017-03-30 23:21:51 -07006460 self.assertEqual(1, len(dms))
6461 self.assertEqual(2, dms[0].ses_num)
6462
6463 # out to host0
6464 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6465 IP(src=self.pg1.remote_ip4, dst=nat_ip) /
Martin Gálik9806eae2017-04-25 01:25:08 -07006466 TCP(sport=external_port, dport=port_out0))
Martin Gálik977c1cb2017-03-30 23:21:51 -07006467 self.pg1.add_stream(p)
6468 self.pg_enable_capture(self.pg_interfaces)
6469 self.pg_start()
6470 capture = self.pg0.get_capture(1)
6471 p = capture[0]
6472 try:
6473 ip = p[IP]
6474 tcp = p[TCP]
6475 self.assertEqual(ip.src, self.pg1.remote_ip4)
6476 self.assertEqual(ip.dst, host0.ip4)
6477 self.assertEqual(tcp.dport, port_in)
Martin Gálik9806eae2017-04-25 01:25:08 -07006478 self.assertEqual(tcp.sport, external_port)
Martin Gálik977c1cb2017-03-30 23:21:51 -07006479 except:
6480 self.logger.error(ppp("Unexpected or invalid packet:", p))
6481 raise
6482
6483 # out to host1
6484 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
6485 IP(src=self.pg1.remote_ip4, dst=nat_ip) /
Martin Gálik9806eae2017-04-25 01:25:08 -07006486 TCP(sport=external_port, dport=port_out1))
Martin Gálik977c1cb2017-03-30 23:21:51 -07006487 self.pg1.add_stream(p)
6488 self.pg_enable_capture(self.pg_interfaces)
6489 self.pg_start()
6490 capture = self.pg0.get_capture(1)
6491 p = capture[0]
6492 try:
6493 ip = p[IP]
6494 tcp = p[TCP]
6495 self.assertEqual(ip.src, self.pg1.remote_ip4)
6496 self.assertEqual(ip.dst, host1.ip4)
6497 self.assertEqual(tcp.dport, port_in)
Martin Gálik9806eae2017-04-25 01:25:08 -07006498 self.assertEqual(tcp.sport, external_port)
Martin Gálik977c1cb2017-03-30 23:21:51 -07006499 except:
6500 self.logger.error(ppp("Unexpected or invalid packet", p))
6501 raise
6502
Martin Gálik6bc8c642017-04-19 01:12:27 -07006503 # session close api test
Matus Fabian2ba92e32017-08-21 07:05:03 -07006504 self.vapi.nat_det_close_session_out(socket.inet_aton(nat_ip),
6505 port_out1,
Martin Gálik6bc8c642017-04-19 01:12:27 -07006506 self.pg1.remote_ip4n,
Martin Gálik9806eae2017-04-25 01:25:08 -07006507 external_port)
Matus Fabian2ba92e32017-08-21 07:05:03 -07006508 dms = self.vapi.nat_det_map_dump()
6509 self.assertEqual(dms[0].ses_num, 1)
6510
6511 self.vapi.nat_det_close_session_in(host0.ip4n,
6512 port_in,
6513 self.pg1.remote_ip4n,
6514 external_port)
6515 dms = self.vapi.nat_det_map_dump()
Martin Gálik6bc8c642017-04-19 01:12:27 -07006516 self.assertEqual(dms[0].ses_num, 0)
6517
Martin Gálik977c1cb2017-03-30 23:21:51 -07006518 def test_tcp_session_close_detection_in(self):
Matus Fabian2ba92e32017-08-21 07:05:03 -07006519 """ Deterministic NAT TCP session close from inside network """
6520 self.vapi.nat_det_add_del_map(self.pg0.remote_ip4n,
6521 32,
6522 socket.inet_aton(self.nat_addr),
6523 32)
6524 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
6525 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
6526 is_inside=0)
Martin Gálik977c1cb2017-03-30 23:21:51 -07006527
6528 self.initiate_tcp_session(self.pg0, self.pg1)
6529
6530 # close the session from inside
6531 try:
6532 # FIN packet in -> out
6533 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6534 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
Martin Gálik9806eae2017-04-25 01:25:08 -07006535 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
Martin Gálik977c1cb2017-03-30 23:21:51 -07006536 flags="F"))
6537 self.pg0.add_stream(p)
6538 self.pg_enable_capture(self.pg_interfaces)
6539 self.pg_start()
6540 self.pg1.get_capture(1)
6541
6542 pkts = []
6543
6544 # ACK packet out -> in
6545 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
Matus Fabian2ba92e32017-08-21 07:05:03 -07006546 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
Martin Gálik9806eae2017-04-25 01:25:08 -07006547 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
Martin Gálik977c1cb2017-03-30 23:21:51 -07006548 flags="A"))
6549 pkts.append(p)
6550
6551 # FIN packet out -> in
6552 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
Matus Fabian2ba92e32017-08-21 07:05:03 -07006553 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
Martin Gálik9806eae2017-04-25 01:25:08 -07006554 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
Martin Gálik977c1cb2017-03-30 23:21:51 -07006555 flags="F"))
6556 pkts.append(p)
6557
6558 self.pg1.add_stream(pkts)
6559 self.pg_enable_capture(self.pg_interfaces)
6560 self.pg_start()
6561 self.pg0.get_capture(2)
6562
6563 # ACK packet in -> out
6564 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6565 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
Martin Gálik9806eae2017-04-25 01:25:08 -07006566 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
Martin Gálik977c1cb2017-03-30 23:21:51 -07006567 flags="A"))
6568 self.pg0.add_stream(p)
6569 self.pg_enable_capture(self.pg_interfaces)
6570 self.pg_start()
6571 self.pg1.get_capture(1)
6572
Matus Fabian2ba92e32017-08-21 07:05:03 -07006573 # Check if deterministic NAT44 closed the session
6574 dms = self.vapi.nat_det_map_dump()
Martin Gálik977c1cb2017-03-30 23:21:51 -07006575 self.assertEqual(0, dms[0].ses_num)
6576 except:
6577 self.logger.error("TCP session termination failed")
6578 raise
6579
6580 def test_tcp_session_close_detection_out(self):
Matus Fabian2ba92e32017-08-21 07:05:03 -07006581 """ Deterministic NAT TCP session close from outside network """
6582 self.vapi.nat_det_add_del_map(self.pg0.remote_ip4n,
6583 32,
6584 socket.inet_aton(self.nat_addr),
6585 32)
6586 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
6587 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
6588 is_inside=0)
Martin Gálik977c1cb2017-03-30 23:21:51 -07006589
6590 self.initiate_tcp_session(self.pg0, self.pg1)
6591
6592 # close the session from outside
6593 try:
6594 # FIN packet out -> in
6595 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
Matus Fabian2ba92e32017-08-21 07:05:03 -07006596 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
Martin Gálik9806eae2017-04-25 01:25:08 -07006597 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
Martin Gálik977c1cb2017-03-30 23:21:51 -07006598 flags="F"))
6599 self.pg1.add_stream(p)
6600 self.pg_enable_capture(self.pg_interfaces)
6601 self.pg_start()
6602 self.pg0.get_capture(1)
6603
6604 pkts = []
6605
6606 # ACK packet in -> out
6607 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6608 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
Martin Gálik9806eae2017-04-25 01:25:08 -07006609 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
Martin Gálik977c1cb2017-03-30 23:21:51 -07006610 flags="A"))
6611 pkts.append(p)
6612
6613 # ACK packet in -> out
6614 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6615 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
Martin Gálik9806eae2017-04-25 01:25:08 -07006616 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
Martin Gálik977c1cb2017-03-30 23:21:51 -07006617 flags="F"))
6618 pkts.append(p)
6619
6620 self.pg0.add_stream(pkts)
6621 self.pg_enable_capture(self.pg_interfaces)
6622 self.pg_start()
6623 self.pg1.get_capture(2)
6624
6625 # ACK packet out -> in
6626 p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
Matus Fabian2ba92e32017-08-21 07:05:03 -07006627 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
Martin Gálik9806eae2017-04-25 01:25:08 -07006628 TCP(sport=self.tcp_external_port, dport=self.tcp_port_out,
Martin Gálik977c1cb2017-03-30 23:21:51 -07006629 flags="A"))
6630 self.pg1.add_stream(p)
6631 self.pg_enable_capture(self.pg_interfaces)
6632 self.pg_start()
6633 self.pg0.get_capture(1)
6634
Matus Fabian2ba92e32017-08-21 07:05:03 -07006635 # Check if deterministic NAT44 closed the session
6636 dms = self.vapi.nat_det_map_dump()
Martin Gálik977c1cb2017-03-30 23:21:51 -07006637 self.assertEqual(0, dms[0].ses_num)
6638 except:
6639 self.logger.error("TCP session termination failed")
6640 raise
6641
Paul Vinciguerradefde0f2018-12-06 07:46:13 -08006642 @unittest.skipUnless(running_extended_tests, "part of extended tests")
Martin Gálik977c1cb2017-03-30 23:21:51 -07006643 def test_session_timeout(self):
Matus Fabian2ba92e32017-08-21 07:05:03 -07006644 """ Deterministic NAT session timeouts """
6645 self.vapi.nat_det_add_del_map(self.pg0.remote_ip4n,
6646 32,
6647 socket.inet_aton(self.nat_addr),
6648 32)
6649 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
6650 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
6651 is_inside=0)
Martin Gálik977c1cb2017-03-30 23:21:51 -07006652
6653 self.initiate_tcp_session(self.pg0, self.pg1)
Matus Fabian878c6462018-08-23 00:33:35 -07006654 self.vapi.nat_set_timeouts(5, 5, 5, 5)
Martin Gálik977c1cb2017-03-30 23:21:51 -07006655 pkts = self.create_stream_in(self.pg0, self.pg1)
6656 self.pg0.add_stream(pkts)
6657 self.pg_enable_capture(self.pg_interfaces)
6658 self.pg_start()
6659 capture = self.pg1.get_capture(len(pkts))
6660 sleep(15)
6661
Matus Fabian2ba92e32017-08-21 07:05:03 -07006662 dms = self.vapi.nat_det_map_dump()
Martin Gálik977c1cb2017-03-30 23:21:51 -07006663 self.assertEqual(0, dms[0].ses_num)
6664
Paul Vinciguerradefde0f2018-12-06 07:46:13 -08006665 @unittest.skipUnless(running_extended_tests, "part of extended tests")
Martin Gálik977c1cb2017-03-30 23:21:51 -07006666 def test_session_limit_per_user(self):
Matus Fabian2ba92e32017-08-21 07:05:03 -07006667 """ Deterministic NAT maximum sessions per user limit """
6668 self.vapi.nat_det_add_del_map(self.pg0.remote_ip4n,
6669 32,
6670 socket.inet_aton(self.nat_addr),
6671 32)
6672 self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
6673 self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
6674 is_inside=0)
Matus Fabian2f2db1c2017-04-18 05:29:59 -07006675 self.vapi.set_ipfix_exporter(collector_address=self.pg2.remote_ip4n,
6676 src_address=self.pg2.local_ip4n,
6677 path_mtu=512,
6678 template_interval=10)
Matus Fabian2ba92e32017-08-21 07:05:03 -07006679 self.vapi.nat_ipfix()
Martin Gálik977c1cb2017-03-30 23:21:51 -07006680
6681 pkts = []
6682 for port in range(1025, 2025):
6683 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6684 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
6685 UDP(sport=port, dport=port))
6686 pkts.append(p)
6687
6688 self.pg0.add_stream(pkts)
6689 self.pg_enable_capture(self.pg_interfaces)
6690 self.pg_start()
6691 capture = self.pg1.get_capture(len(pkts))
6692
6693 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
6694 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
Martin Gálikf7e655d2017-04-27 02:13:26 -07006695 UDP(sport=3001, dport=3002))
Martin Gálik977c1cb2017-03-30 23:21:51 -07006696 self.pg0.add_stream(p)
6697 self.pg_enable_capture(self.pg_interfaces)
6698 self.pg_start()
6699 capture = self.pg1.assert_nothing_captured()
6700
Martin Gálikf7e655d2017-04-27 02:13:26 -07006701 # verify ICMP error packet
6702 capture = self.pg0.get_capture(1)
6703 p = capture[0]
6704 self.assertTrue(p.haslayer(ICMP))
6705 icmp = p[ICMP]
6706 self.assertEqual(icmp.type, 3)
6707 self.assertEqual(icmp.code, 1)
6708 self.assertTrue(icmp.haslayer(IPerror))
6709 inner_ip = icmp[IPerror]
6710 self.assertEqual(inner_ip[UDPerror].sport, 3001)
6711 self.assertEqual(inner_ip[UDPerror].dport, 3002)
6712
Matus Fabian2ba92e32017-08-21 07:05:03 -07006713 dms = self.vapi.nat_det_map_dump()
Martin Gálik977c1cb2017-03-30 23:21:51 -07006714
6715 self.assertEqual(1000, dms[0].ses_num)
6716
Matus Fabian2f2db1c2017-04-18 05:29:59 -07006717 # verify IPFIX logging
6718 self.vapi.cli("ipfix flush") # FIXME this should be an API call
Matus Fabian7c0aecc2017-07-03 01:21:38 -07006719 sleep(1)
Matus Fabian2f2db1c2017-04-18 05:29:59 -07006720 capture = self.pg2.get_capture(2)
6721 ipfix = IPFIXDecoder()
6722 # first load template
6723 for p in capture:
6724 self.assertTrue(p.haslayer(IPFIX))
6725 if p.haslayer(Template):
6726 ipfix.add_template(p.getlayer(Template))
6727 # verify events in data set
6728 for p in capture:
6729 if p.haslayer(Data):
6730 data = ipfix.decode_data_set(p.getlayer(Set))
Matus Fabian878c6462018-08-23 00:33:35 -07006731 self.verify_ipfix_max_entries_per_user(data,
6732 1000,
6733 self.pg0.remote_ip4n)
Matus Fabian2f2db1c2017-04-18 05:29:59 -07006734
Matus Fabian2ba92e32017-08-21 07:05:03 -07006735 def clear_nat_det(self):
Martin17a75cb2017-03-08 05:53:20 -08006736 """
Matus Fabian2ba92e32017-08-21 07:05:03 -07006737 Clear deterministic NAT configuration.
Martin17a75cb2017-03-08 05:53:20 -08006738 """
Matus Fabian2ba92e32017-08-21 07:05:03 -07006739 self.vapi.nat_ipfix(enable=0)
Matus Fabian878c6462018-08-23 00:33:35 -07006740 self.vapi.nat_set_timeouts()
Matus Fabian2ba92e32017-08-21 07:05:03 -07006741 deterministic_mappings = self.vapi.nat_det_map_dump()
Martin17a75cb2017-03-08 05:53:20 -08006742 for dsm in deterministic_mappings:
Matus Fabian2ba92e32017-08-21 07:05:03 -07006743 self.vapi.nat_det_add_del_map(dsm.in_addr,
6744 dsm.in_plen,
6745 dsm.out_addr,
6746 dsm.out_plen,
6747 is_add=0)
Martin17a75cb2017-03-08 05:53:20 -08006748
Matus Fabian2ba92e32017-08-21 07:05:03 -07006749 interfaces = self.vapi.nat44_interface_dump()
Martin Gálik977c1cb2017-03-30 23:21:51 -07006750 for intf in interfaces:
Matus Fabian2ba92e32017-08-21 07:05:03 -07006751 self.vapi.nat44_interface_add_del_feature(intf.sw_if_index,
6752 intf.is_inside,
6753 is_add=0)
Martin Gálik977c1cb2017-03-30 23:21:51 -07006754
Matus Fabian066f0342017-02-10 03:48:01 -08006755 def tearDown(self):
6756 super(TestDeterministicNAT, self).tearDown()
6757 if not self.vpp_dead:
Matus Fabian82119542018-01-25 01:13:22 -08006758 self.logger.info(self.vapi.cli("show nat44 interfaces"))
Matus Fabian878c6462018-08-23 00:33:35 -07006759 self.logger.info(self.vapi.cli("show nat timeouts"))
Matus Fabian82119542018-01-25 01:13:22 -08006760 self.logger.info(
6761 self.vapi.cli("show nat44 deterministic mappings"))
6762 self.logger.info(
Matus Fabian82119542018-01-25 01:13:22 -08006763 self.vapi.cli("show nat44 deterministic sessions"))
Matus Fabian2ba92e32017-08-21 07:05:03 -07006764 self.clear_nat_det()
Matus Fabian066f0342017-02-10 03:48:01 -08006765
Matus Fabian06596c52017-06-06 04:53:28 -07006766
6767class TestNAT64(MethodHolder):
6768 """ NAT64 Test Cases """
6769
6770 @classmethod
Matus Fabiana431ad12018-01-04 04:03:14 -08006771 def setUpConstants(cls):
6772 super(TestNAT64, cls).setUpConstants()
6773 cls.vpp_cmdline.extend(["nat", "{", "nat64 bib hash buckets 128",
6774 "nat64 st hash buckets 256", "}"])
6775
6776 @classmethod
Matus Fabian06596c52017-06-06 04:53:28 -07006777 def setUpClass(cls):
6778 super(TestNAT64, cls).setUpClass()
6779
6780 try:
6781 cls.tcp_port_in = 6303
6782 cls.tcp_port_out = 6303
6783 cls.udp_port_in = 6304
6784 cls.udp_port_out = 6304
6785 cls.icmp_id_in = 6305
6786 cls.icmp_id_out = 6305
Matus Fabianad1f3e12018-11-28 21:26:34 -08006787 cls.tcp_external_port = 80
Matus Fabian06596c52017-06-06 04:53:28 -07006788 cls.nat_addr = '10.0.0.3'
6789 cls.nat_addr_n = socket.inet_pton(socket.AF_INET, cls.nat_addr)
Matus Fabian029f3d22017-06-15 02:28:50 -07006790 cls.vrf1_id = 10
6791 cls.vrf1_nat_addr = '10.0.10.3'
6792 cls.vrf1_nat_addr_n = socket.inet_pton(socket.AF_INET,
6793 cls.vrf1_nat_addr)
Matus Fabiana431ad12018-01-04 04:03:14 -08006794 cls.ipfix_src_port = 4739
6795 cls.ipfix_domain_id = 1
Matus Fabian06596c52017-06-06 04:53:28 -07006796
Juraj Slobodac746a152018-07-09 02:36:37 +02006797 cls.create_pg_interfaces(range(6))
Matus Fabian06596c52017-06-06 04:53:28 -07006798 cls.ip6_interfaces = list(cls.pg_interfaces[0:1])
Matus Fabian029f3d22017-06-15 02:28:50 -07006799 cls.ip6_interfaces.append(cls.pg_interfaces[2])
Matus Fabian06596c52017-06-06 04:53:28 -07006800 cls.ip4_interfaces = list(cls.pg_interfaces[1:2])
6801
Neale Ranns15002542017-09-10 04:39:11 -07006802 cls.vapi.ip_table_add_del(cls.vrf1_id, is_add=1, is_ipv6=1)
6803
Matus Fabian029f3d22017-06-15 02:28:50 -07006804 cls.pg_interfaces[2].set_table_ip6(cls.vrf1_id)
6805
6806 cls.pg0.generate_remote_hosts(2)
6807
Matus Fabian06596c52017-06-06 04:53:28 -07006808 for i in cls.ip6_interfaces:
6809 i.admin_up()
6810 i.config_ip6()
Matus Fabian029f3d22017-06-15 02:28:50 -07006811 i.configure_ipv6_neighbors()
Matus Fabian06596c52017-06-06 04:53:28 -07006812
6813 for i in cls.ip4_interfaces:
6814 i.admin_up()
6815 i.config_ip4()
6816 i.resolve_arp()
6817
Matus Fabian36ea2d62017-10-24 04:13:49 -07006818 cls.pg3.admin_up()
6819 cls.pg3.config_ip4()
6820 cls.pg3.resolve_arp()
6821 cls.pg3.config_ip6()
6822 cls.pg3.configure_ipv6_neighbors()
6823
Juraj Slobodac746a152018-07-09 02:36:37 +02006824 cls.pg5.admin_up()
6825 cls.pg5.config_ip6()
6826
Matus Fabian06596c52017-06-06 04:53:28 -07006827 except Exception:
6828 super(TestNAT64, cls).tearDownClass()
6829 raise
6830
Juraj Slobodac746a152018-07-09 02:36:37 +02006831 def test_nat64_inside_interface_handles_neighbor_advertisement(self):
6832 """ NAT64 inside interface handles Neighbor Advertisement """
6833
6834 self.vapi.nat64_add_del_interface(self.pg5.sw_if_index)
6835
6836 # Try to send ping
6837 ping = (Ether(dst=self.pg5.local_mac, src=self.pg5.remote_mac) /
6838 IPv6(src=self.pg5.remote_ip6, dst=self.pg5.local_ip6) /
6839 ICMPv6EchoRequest())
6840 pkts = [ping]
6841 self.pg5.add_stream(pkts)
6842 self.pg_enable_capture(self.pg_interfaces)
6843 self.pg_start()
6844
6845 # Wait for Neighbor Solicitation
6846 capture = self.pg5.get_capture(len(pkts))
Juraj Slobodac746a152018-07-09 02:36:37 +02006847 packet = capture[0]
6848 try:
6849 self.assertEqual(packet[IPv6].src, self.pg5.local_ip6)
Paul Vinciguerra978aa642018-11-24 22:19:12 -08006850 self.assertEqual(packet.haslayer(ICMPv6ND_NS), 1)
Juraj Slobodac746a152018-07-09 02:36:37 +02006851 tgt = packet[ICMPv6ND_NS].tgt
6852 except:
6853 self.logger.error(ppp("Unexpected or invalid packet:", packet))
6854 raise
6855
6856 # Send Neighbor Advertisement
6857 p = (Ether(dst=self.pg5.local_mac, src=self.pg5.remote_mac) /
6858 IPv6(src=self.pg5.remote_ip6, dst=self.pg5.local_ip6) /
6859 ICMPv6ND_NA(tgt=tgt) /
6860 ICMPv6NDOptDstLLAddr(lladdr=self.pg5.remote_mac))
6861 pkts = [p]
6862 self.pg5.add_stream(pkts)
6863 self.pg_enable_capture(self.pg_interfaces)
6864 self.pg_start()
6865
6866 # Try to send ping again
6867 pkts = [ping]
6868 self.pg5.add_stream(pkts)
6869 self.pg_enable_capture(self.pg_interfaces)
6870 self.pg_start()
6871
6872 # Wait for ping reply
6873 capture = self.pg5.get_capture(len(pkts))
Juraj Slobodac746a152018-07-09 02:36:37 +02006874 packet = capture[0]
6875 try:
6876 self.assertEqual(packet[IPv6].src, self.pg5.local_ip6)
6877 self.assertEqual(packet[IPv6].dst, self.pg5.remote_ip6)
Paul Vinciguerra978aa642018-11-24 22:19:12 -08006878 self.assertEqual(packet.haslayer(ICMPv6EchoReply), 1)
Juraj Slobodac746a152018-07-09 02:36:37 +02006879 except:
6880 self.logger.error(ppp("Unexpected or invalid packet:", packet))
6881 raise
6882
Matus Fabian06596c52017-06-06 04:53:28 -07006883 def test_pool(self):
6884 """ Add/delete address to NAT64 pool """
6885 nat_addr = socket.inet_pton(socket.AF_INET, '1.2.3.4')
6886
6887 self.vapi.nat64_add_del_pool_addr_range(nat_addr, nat_addr)
6888
6889 addresses = self.vapi.nat64_pool_addr_dump()
6890 self.assertEqual(len(addresses), 1)
6891 self.assertEqual(addresses[0].address, nat_addr)
6892
6893 self.vapi.nat64_add_del_pool_addr_range(nat_addr, nat_addr, is_add=0)
6894
6895 addresses = self.vapi.nat64_pool_addr_dump()
6896 self.assertEqual(len(addresses), 0)
6897
6898 def test_interface(self):
6899 """ Enable/disable NAT64 feature on the interface """
6900 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
6901 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
6902
6903 interfaces = self.vapi.nat64_interface_dump()
6904 self.assertEqual(len(interfaces), 2)
6905 pg0_found = False
6906 pg1_found = False
6907 for intf in interfaces:
6908 if intf.sw_if_index == self.pg0.sw_if_index:
6909 self.assertEqual(intf.is_inside, 1)
6910 pg0_found = True
6911 elif intf.sw_if_index == self.pg1.sw_if_index:
6912 self.assertEqual(intf.is_inside, 0)
6913 pg1_found = True
6914 self.assertTrue(pg0_found)
6915 self.assertTrue(pg1_found)
6916
6917 features = self.vapi.cli("show interface features pg0")
6918 self.assertNotEqual(features.find('nat64-in2out'), -1)
6919 features = self.vapi.cli("show interface features pg1")
6920 self.assertNotEqual(features.find('nat64-out2in'), -1)
6921
6922 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index, is_add=0)
6923 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_add=0)
6924
6925 interfaces = self.vapi.nat64_interface_dump()
6926 self.assertEqual(len(interfaces), 0)
6927
6928 def test_static_bib(self):
6929 """ Add/delete static BIB entry """
6930 in_addr = socket.inet_pton(socket.AF_INET6,
6931 '2001:db8:85a3::8a2e:370:7334')
6932 out_addr = socket.inet_pton(socket.AF_INET, '10.1.1.3')
6933 in_port = 1234
6934 out_port = 5678
6935 proto = IP_PROTOS.tcp
6936
6937 self.vapi.nat64_add_del_static_bib(in_addr,
6938 out_addr,
6939 in_port,
6940 out_port,
6941 proto)
6942 bib = self.vapi.nat64_bib_dump(IP_PROTOS.tcp)
6943 static_bib_num = 0
6944 for bibe in bib:
6945 if bibe.is_static:
6946 static_bib_num += 1
6947 self.assertEqual(bibe.i_addr, in_addr)
6948 self.assertEqual(bibe.o_addr, out_addr)
6949 self.assertEqual(bibe.i_port, in_port)
6950 self.assertEqual(bibe.o_port, out_port)
6951 self.assertEqual(static_bib_num, 1)
Matus Fabianfd0d5082018-12-18 01:08:51 -08006952 bibs = self.statistics.get_counter('/nat64/total-bibs')
6953 self.assertEqual(bibs[0][0], 1)
Matus Fabian06596c52017-06-06 04:53:28 -07006954
6955 self.vapi.nat64_add_del_static_bib(in_addr,
6956 out_addr,
6957 in_port,
6958 out_port,
6959 proto,
6960 is_add=0)
6961 bib = self.vapi.nat64_bib_dump(IP_PROTOS.tcp)
6962 static_bib_num = 0
6963 for bibe in bib:
6964 if bibe.is_static:
6965 static_bib_num += 1
6966 self.assertEqual(static_bib_num, 0)
Matus Fabianfd0d5082018-12-18 01:08:51 -08006967 bibs = self.statistics.get_counter('/nat64/total-bibs')
6968 self.assertEqual(bibs[0][0], 0)
Matus Fabian06596c52017-06-06 04:53:28 -07006969
6970 def test_set_timeouts(self):
6971 """ Set NAT64 timeouts """
6972 # verify default values
Matus Fabian878c6462018-08-23 00:33:35 -07006973 timeouts = self.vapi.nat_get_timeouts()
Matus Fabian06596c52017-06-06 04:53:28 -07006974 self.assertEqual(timeouts.udp, 300)
6975 self.assertEqual(timeouts.icmp, 60)
Matus Fabian878c6462018-08-23 00:33:35 -07006976 self.assertEqual(timeouts.tcp_transitory, 240)
6977 self.assertEqual(timeouts.tcp_established, 7440)
Matus Fabian06596c52017-06-06 04:53:28 -07006978
6979 # set and verify custom values
Matus Fabian878c6462018-08-23 00:33:35 -07006980 self.vapi.nat_set_timeouts(udp=200, icmp=30, tcp_transitory=250,
6981 tcp_established=7450)
6982 timeouts = self.vapi.nat_get_timeouts()
Matus Fabian06596c52017-06-06 04:53:28 -07006983 self.assertEqual(timeouts.udp, 200)
6984 self.assertEqual(timeouts.icmp, 30)
Matus Fabian878c6462018-08-23 00:33:35 -07006985 self.assertEqual(timeouts.tcp_transitory, 250)
6986 self.assertEqual(timeouts.tcp_established, 7450)
Matus Fabian06596c52017-06-06 04:53:28 -07006987
6988 def test_dynamic(self):
6989 """ NAT64 dynamic translation test """
6990 self.tcp_port_in = 6303
6991 self.udp_port_in = 6304
6992 self.icmp_id_in = 6305
6993
6994 ses_num_start = self.nat64_get_ses_num()
6995
6996 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
6997 self.nat_addr_n)
6998 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
6999 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
7000
7001 # in2out
Matus Fabiana5e73762018-12-14 01:55:16 -08007002 tcpn = self.statistics.get_counter('/err/nat64-in2out/TCP packets')
7003 udpn = self.statistics.get_counter('/err/nat64-in2out/UDP packets')
7004 icmpn = self.statistics.get_counter('/err/nat64-in2out/ICMP packets')
7005 totaln = self.statistics.get_counter(
7006 '/err/nat64-in2out/good in2out packets processed')
7007
Matus Fabian06596c52017-06-06 04:53:28 -07007008 pkts = self.create_stream_in_ip6(self.pg0, self.pg1)
7009 self.pg0.add_stream(pkts)
7010 self.pg_enable_capture(self.pg_interfaces)
7011 self.pg_start()
Matus Fabian029f3d22017-06-15 02:28:50 -07007012 capture = self.pg1.get_capture(len(pkts))
7013 self.verify_capture_out(capture, nat_ip=self.nat_addr,
Matus Fabian06596c52017-06-06 04:53:28 -07007014 dst_ip=self.pg1.remote_ip4)
7015
Matus Fabiana5e73762018-12-14 01:55:16 -08007016 err = self.statistics.get_counter('/err/nat64-in2out/TCP packets')
7017 self.assertEqual(err - tcpn, 1)
7018 err = self.statistics.get_counter('/err/nat64-in2out/UDP packets')
7019 self.assertEqual(err - udpn, 1)
7020 err = self.statistics.get_counter('/err/nat64-in2out/ICMP packets')
7021 self.assertEqual(err - icmpn, 1)
7022 err = self.statistics.get_counter(
7023 '/err/nat64-in2out/good in2out packets processed')
7024 self.assertEqual(err - totaln, 3)
7025
Matus Fabian06596c52017-06-06 04:53:28 -07007026 # out2in
Matus Fabiana5e73762018-12-14 01:55:16 -08007027 tcpn = self.statistics.get_counter('/err/nat64-out2in/TCP packets')
7028 udpn = self.statistics.get_counter('/err/nat64-out2in/UDP packets')
7029 icmpn = self.statistics.get_counter('/err/nat64-out2in/ICMP packets')
7030 totaln = self.statistics.get_counter(
7031 '/err/nat64-out2in/good out2in packets processed')
7032
Matus Fabian06596c52017-06-06 04:53:28 -07007033 pkts = self.create_stream_out(self.pg1, dst_ip=self.nat_addr)
7034 self.pg1.add_stream(pkts)
7035 self.pg_enable_capture(self.pg_interfaces)
7036 self.pg_start()
Matus Fabian029f3d22017-06-15 02:28:50 -07007037 capture = self.pg0.get_capture(len(pkts))
Matus Fabian06596c52017-06-06 04:53:28 -07007038 ip = IPv6(src=''.join(['64:ff9b::', self.pg1.remote_ip4]))
7039 self.verify_capture_in_ip6(capture, ip[IPv6].src, self.pg0.remote_ip6)
7040
Matus Fabiana5e73762018-12-14 01:55:16 -08007041 err = self.statistics.get_counter('/err/nat64-out2in/TCP packets')
7042 self.assertEqual(err - tcpn, 1)
7043 err = self.statistics.get_counter('/err/nat64-out2in/UDP packets')
7044 self.assertEqual(err - udpn, 1)
7045 err = self.statistics.get_counter('/err/nat64-out2in/ICMP packets')
7046 self.assertEqual(err - icmpn, 1)
7047 err = self.statistics.get_counter(
7048 '/err/nat64-out2in/good out2in packets processed')
7049 self.assertEqual(err - totaln, 3)
7050
Matus Fabianfd0d5082018-12-18 01:08:51 -08007051 bibs = self.statistics.get_counter('/nat64/total-bibs')
7052 self.assertEqual(bibs[0][0], 3)
7053 sessions = self.statistics.get_counter('/nat64/total-sessions')
7054 self.assertEqual(sessions[0][0], 3)
7055
Matus Fabian06596c52017-06-06 04:53:28 -07007056 # in2out
7057 pkts = self.create_stream_in_ip6(self.pg0, self.pg1)
7058 self.pg0.add_stream(pkts)
7059 self.pg_enable_capture(self.pg_interfaces)
7060 self.pg_start()
Matus Fabian029f3d22017-06-15 02:28:50 -07007061 capture = self.pg1.get_capture(len(pkts))
7062 self.verify_capture_out(capture, nat_ip=self.nat_addr,
Matus Fabian06596c52017-06-06 04:53:28 -07007063 dst_ip=self.pg1.remote_ip4)
7064
7065 # out2in
7066 pkts = self.create_stream_out(self.pg1, dst_ip=self.nat_addr)
7067 self.pg1.add_stream(pkts)
7068 self.pg_enable_capture(self.pg_interfaces)
7069 self.pg_start()
Matus Fabian029f3d22017-06-15 02:28:50 -07007070 capture = self.pg0.get_capture(len(pkts))
Matus Fabian06596c52017-06-06 04:53:28 -07007071 self.verify_capture_in_ip6(capture, ip[IPv6].src, self.pg0.remote_ip6)
7072
7073 ses_num_end = self.nat64_get_ses_num()
7074
7075 self.assertEqual(ses_num_end - ses_num_start, 3)
7076
Matus Fabian029f3d22017-06-15 02:28:50 -07007077 # tenant with specific VRF
7078 self.vapi.nat64_add_del_pool_addr_range(self.vrf1_nat_addr_n,
7079 self.vrf1_nat_addr_n,
7080 vrf_id=self.vrf1_id)
7081 self.vapi.nat64_add_del_interface(self.pg2.sw_if_index)
7082
7083 pkts = self.create_stream_in_ip6(self.pg2, self.pg1)
7084 self.pg2.add_stream(pkts)
7085 self.pg_enable_capture(self.pg_interfaces)
7086 self.pg_start()
7087 capture = self.pg1.get_capture(len(pkts))
7088 self.verify_capture_out(capture, nat_ip=self.vrf1_nat_addr,
7089 dst_ip=self.pg1.remote_ip4)
7090
7091 pkts = self.create_stream_out(self.pg1, dst_ip=self.vrf1_nat_addr)
7092 self.pg1.add_stream(pkts)
7093 self.pg_enable_capture(self.pg_interfaces)
7094 self.pg_start()
7095 capture = self.pg2.get_capture(len(pkts))
7096 self.verify_capture_in_ip6(capture, ip[IPv6].src, self.pg2.remote_ip6)
7097
Matus Fabian06596c52017-06-06 04:53:28 -07007098 def test_static(self):
7099 """ NAT64 static translation test """
7100 self.tcp_port_in = 60303
7101 self.udp_port_in = 60304
7102 self.icmp_id_in = 60305
7103 self.tcp_port_out = 60303
7104 self.udp_port_out = 60304
7105 self.icmp_id_out = 60305
7106
7107 ses_num_start = self.nat64_get_ses_num()
7108
7109 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
7110 self.nat_addr_n)
7111 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
7112 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
7113
7114 self.vapi.nat64_add_del_static_bib(self.pg0.remote_ip6n,
7115 self.nat_addr_n,
7116 self.tcp_port_in,
7117 self.tcp_port_out,
7118 IP_PROTOS.tcp)
7119 self.vapi.nat64_add_del_static_bib(self.pg0.remote_ip6n,
7120 self.nat_addr_n,
7121 self.udp_port_in,
7122 self.udp_port_out,
7123 IP_PROTOS.udp)
7124 self.vapi.nat64_add_del_static_bib(self.pg0.remote_ip6n,
7125 self.nat_addr_n,
7126 self.icmp_id_in,
7127 self.icmp_id_out,
7128 IP_PROTOS.icmp)
7129
7130 # in2out
7131 pkts = self.create_stream_in_ip6(self.pg0, self.pg1)
7132 self.pg0.add_stream(pkts)
7133 self.pg_enable_capture(self.pg_interfaces)
7134 self.pg_start()
Matus Fabian029f3d22017-06-15 02:28:50 -07007135 capture = self.pg1.get_capture(len(pkts))
7136 self.verify_capture_out(capture, nat_ip=self.nat_addr,
Matus Fabian06596c52017-06-06 04:53:28 -07007137 dst_ip=self.pg1.remote_ip4, same_port=True)
7138
7139 # out2in
7140 pkts = self.create_stream_out(self.pg1, dst_ip=self.nat_addr)
7141 self.pg1.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.pg0.get_capture(len(pkts))
Matus Fabian06596c52017-06-06 04:53:28 -07007145 ip = IPv6(src=''.join(['64:ff9b::', self.pg1.remote_ip4]))
7146 self.verify_capture_in_ip6(capture, ip[IPv6].src, self.pg0.remote_ip6)
7147
7148 ses_num_end = self.nat64_get_ses_num()
7149
7150 self.assertEqual(ses_num_end - ses_num_start, 3)
7151
Paul Vinciguerradefde0f2018-12-06 07:46:13 -08007152 @unittest.skipUnless(running_extended_tests, "part of extended tests")
Matus Fabian06596c52017-06-06 04:53:28 -07007153 def test_session_timeout(self):
7154 """ NAT64 session timeout """
7155 self.icmp_id_in = 1234
7156 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
7157 self.nat_addr_n)
7158 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
7159 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
Matus Fabian878c6462018-08-23 00:33:35 -07007160 self.vapi.nat_set_timeouts(icmp=5, tcp_transitory=5, tcp_established=5)
Matus Fabian06596c52017-06-06 04:53:28 -07007161
7162 pkts = self.create_stream_in_ip6(self.pg0, self.pg1)
7163 self.pg0.add_stream(pkts)
7164 self.pg_enable_capture(self.pg_interfaces)
7165 self.pg_start()
Matus Fabian029f3d22017-06-15 02:28:50 -07007166 capture = self.pg1.get_capture(len(pkts))
Matus Fabian06596c52017-06-06 04:53:28 -07007167
7168 ses_num_before_timeout = self.nat64_get_ses_num()
7169
7170 sleep(15)
7171
Matus Fabian8fed4242018-08-14 05:14:55 -07007172 # ICMP and TCP session after timeout
Matus Fabian06596c52017-06-06 04:53:28 -07007173 ses_num_after_timeout = self.nat64_get_ses_num()
Matus Fabian8fed4242018-08-14 05:14:55 -07007174 self.assertEqual(ses_num_before_timeout - ses_num_after_timeout, 2)
Matus Fabian06596c52017-06-06 04:53:28 -07007175
Matus Fabian732036d2017-06-08 05:24:28 -07007176 def test_icmp_error(self):
7177 """ NAT64 ICMP Error message translation """
7178 self.tcp_port_in = 6303
7179 self.udp_port_in = 6304
7180 self.icmp_id_in = 6305
7181
Matus Fabian732036d2017-06-08 05:24:28 -07007182 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
7183 self.nat_addr_n)
7184 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
7185 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
7186
7187 # send some packets to create sessions
7188 pkts = self.create_stream_in_ip6(self.pg0, self.pg1)
7189 self.pg0.add_stream(pkts)
7190 self.pg_enable_capture(self.pg_interfaces)
7191 self.pg_start()
7192 capture_ip4 = self.pg1.get_capture(len(pkts))
Matus Fabian029f3d22017-06-15 02:28:50 -07007193 self.verify_capture_out(capture_ip4,
Matus Fabian732036d2017-06-08 05:24:28 -07007194 nat_ip=self.nat_addr,
7195 dst_ip=self.pg1.remote_ip4)
7196
7197 pkts = self.create_stream_out(self.pg1, dst_ip=self.nat_addr)
7198 self.pg1.add_stream(pkts)
7199 self.pg_enable_capture(self.pg_interfaces)
7200 self.pg_start()
7201 capture_ip6 = self.pg0.get_capture(len(pkts))
7202 ip = IPv6(src=''.join(['64:ff9b::', self.pg1.remote_ip4]))
7203 self.verify_capture_in_ip6(capture_ip6, ip[IPv6].src,
7204 self.pg0.remote_ip6)
7205
7206 # in2out
7207 pkts = [Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
7208 IPv6(src=self.pg0.remote_ip6, dst=ip[IPv6].src) /
7209 ICMPv6DestUnreach(code=1) /
7210 packet[IPv6] for packet in capture_ip6]
7211 self.pg0.add_stream(pkts)
7212 self.pg_enable_capture(self.pg_interfaces)
7213 self.pg_start()
7214 capture = self.pg1.get_capture(len(pkts))
7215 for packet in capture:
7216 try:
7217 self.assertEqual(packet[IP].src, self.nat_addr)
7218 self.assertEqual(packet[IP].dst, self.pg1.remote_ip4)
7219 self.assertEqual(packet[ICMP].type, 3)
7220 self.assertEqual(packet[ICMP].code, 13)
7221 inner = packet[IPerror]
7222 self.assertEqual(inner.src, self.pg1.remote_ip4)
7223 self.assertEqual(inner.dst, self.nat_addr)
Klement Sekerad81ae412018-05-16 10:52:54 +02007224 self.assert_packet_checksums_valid(packet)
Matus Fabian732036d2017-06-08 05:24:28 -07007225 if inner.haslayer(TCPerror):
7226 self.assertEqual(inner[TCPerror].dport, self.tcp_port_out)
7227 elif inner.haslayer(UDPerror):
7228 self.assertEqual(inner[UDPerror].dport, self.udp_port_out)
7229 else:
7230 self.assertEqual(inner[ICMPerror].id, self.icmp_id_out)
7231 except:
7232 self.logger.error(ppp("Unexpected or invalid packet:", packet))
7233 raise
7234
7235 # out2in
7236 pkts = [Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
7237 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
7238 ICMP(type=3, code=13) /
7239 packet[IP] for packet in capture_ip4]
7240 self.pg1.add_stream(pkts)
7241 self.pg_enable_capture(self.pg_interfaces)
7242 self.pg_start()
7243 capture = self.pg0.get_capture(len(pkts))
7244 for packet in capture:
7245 try:
7246 self.assertEqual(packet[IPv6].src, ip.src)
7247 self.assertEqual(packet[IPv6].dst, self.pg0.remote_ip6)
7248 icmp = packet[ICMPv6DestUnreach]
7249 self.assertEqual(icmp.code, 1)
7250 inner = icmp[IPerror6]
7251 self.assertEqual(inner.src, self.pg0.remote_ip6)
7252 self.assertEqual(inner.dst, ip.src)
Klement Sekerad81ae412018-05-16 10:52:54 +02007253 self.assert_icmpv6_checksum_valid(packet)
Matus Fabian732036d2017-06-08 05:24:28 -07007254 if inner.haslayer(TCPerror):
7255 self.assertEqual(inner[TCPerror].sport, self.tcp_port_in)
7256 elif inner.haslayer(UDPerror):
7257 self.assertEqual(inner[UDPerror].sport, self.udp_port_in)
7258 else:
7259 self.assertEqual(inner[ICMPv6EchoRequest].id,
7260 self.icmp_id_in)
7261 except:
7262 self.logger.error(ppp("Unexpected or invalid packet:", packet))
7263 raise
7264
Matus Fabian029f3d22017-06-15 02:28:50 -07007265 def test_hairpinning(self):
7266 """ NAT64 hairpinning """
7267
7268 client = self.pg0.remote_hosts[0]
7269 server = self.pg0.remote_hosts[1]
7270 server_tcp_in_port = 22
7271 server_tcp_out_port = 4022
7272 server_udp_in_port = 23
7273 server_udp_out_port = 4023
7274 client_tcp_in_port = 1234
7275 client_udp_in_port = 1235
7276 client_tcp_out_port = 0
7277 client_udp_out_port = 0
7278 ip = IPv6(src=''.join(['64:ff9b::', self.nat_addr]))
7279 nat_addr_ip6 = ip.src
7280
7281 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
7282 self.nat_addr_n)
7283 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
7284 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
7285
7286 self.vapi.nat64_add_del_static_bib(server.ip6n,
7287 self.nat_addr_n,
7288 server_tcp_in_port,
7289 server_tcp_out_port,
7290 IP_PROTOS.tcp)
7291 self.vapi.nat64_add_del_static_bib(server.ip6n,
7292 self.nat_addr_n,
7293 server_udp_in_port,
7294 server_udp_out_port,
7295 IP_PROTOS.udp)
7296
7297 # client to server
7298 pkts = []
7299 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
7300 IPv6(src=client.ip6, dst=nat_addr_ip6) /
7301 TCP(sport=client_tcp_in_port, dport=server_tcp_out_port))
7302 pkts.append(p)
7303 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
7304 IPv6(src=client.ip6, dst=nat_addr_ip6) /
7305 UDP(sport=client_udp_in_port, dport=server_udp_out_port))
7306 pkts.append(p)
7307 self.pg0.add_stream(pkts)
7308 self.pg_enable_capture(self.pg_interfaces)
7309 self.pg_start()
7310 capture = self.pg0.get_capture(len(pkts))
7311 for packet in capture:
7312 try:
7313 self.assertEqual(packet[IPv6].src, nat_addr_ip6)
7314 self.assertEqual(packet[IPv6].dst, server.ip6)
Klement Sekerad81ae412018-05-16 10:52:54 +02007315 self.assert_packet_checksums_valid(packet)
Matus Fabian029f3d22017-06-15 02:28:50 -07007316 if packet.haslayer(TCP):
7317 self.assertNotEqual(packet[TCP].sport, client_tcp_in_port)
7318 self.assertEqual(packet[TCP].dport, server_tcp_in_port)
Matus Fabian029f3d22017-06-15 02:28:50 -07007319 client_tcp_out_port = packet[TCP].sport
7320 else:
7321 self.assertNotEqual(packet[UDP].sport, client_udp_in_port)
7322 self.assertEqual(packet[UDP].dport, server_udp_in_port)
Matus Fabian029f3d22017-06-15 02:28:50 -07007323 client_udp_out_port = packet[UDP].sport
7324 except:
7325 self.logger.error(ppp("Unexpected or invalid packet:", packet))
7326 raise
7327
7328 # server to client
7329 pkts = []
7330 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
7331 IPv6(src=server.ip6, dst=nat_addr_ip6) /
7332 TCP(sport=server_tcp_in_port, dport=client_tcp_out_port))
7333 pkts.append(p)
7334 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
7335 IPv6(src=server.ip6, dst=nat_addr_ip6) /
7336 UDP(sport=server_udp_in_port, dport=client_udp_out_port))
7337 pkts.append(p)
7338 self.pg0.add_stream(pkts)
7339 self.pg_enable_capture(self.pg_interfaces)
7340 self.pg_start()
7341 capture = self.pg0.get_capture(len(pkts))
7342 for packet in capture:
7343 try:
7344 self.assertEqual(packet[IPv6].src, nat_addr_ip6)
7345 self.assertEqual(packet[IPv6].dst, client.ip6)
Klement Sekerad81ae412018-05-16 10:52:54 +02007346 self.assert_packet_checksums_valid(packet)
Matus Fabian029f3d22017-06-15 02:28:50 -07007347 if packet.haslayer(TCP):
7348 self.assertEqual(packet[TCP].sport, server_tcp_out_port)
7349 self.assertEqual(packet[TCP].dport, client_tcp_in_port)
Matus Fabian029f3d22017-06-15 02:28:50 -07007350 else:
7351 self.assertEqual(packet[UDP].sport, server_udp_out_port)
7352 self.assertEqual(packet[UDP].dport, client_udp_in_port)
Matus Fabian029f3d22017-06-15 02:28:50 -07007353 except:
7354 self.logger.error(ppp("Unexpected or invalid packet:", packet))
7355 raise
7356
7357 # ICMP error
7358 pkts = []
7359 pkts = [Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
7360 IPv6(src=client.ip6, dst=nat_addr_ip6) /
7361 ICMPv6DestUnreach(code=1) /
7362 packet[IPv6] for packet in capture]
7363 self.pg0.add_stream(pkts)
7364 self.pg_enable_capture(self.pg_interfaces)
7365 self.pg_start()
7366 capture = self.pg0.get_capture(len(pkts))
7367 for packet in capture:
7368 try:
7369 self.assertEqual(packet[IPv6].src, nat_addr_ip6)
7370 self.assertEqual(packet[IPv6].dst, server.ip6)
7371 icmp = packet[ICMPv6DestUnreach]
7372 self.assertEqual(icmp.code, 1)
7373 inner = icmp[IPerror6]
7374 self.assertEqual(inner.src, server.ip6)
7375 self.assertEqual(inner.dst, nat_addr_ip6)
Klement Sekerad81ae412018-05-16 10:52:54 +02007376 self.assert_packet_checksums_valid(packet)
Matus Fabian029f3d22017-06-15 02:28:50 -07007377 if inner.haslayer(TCPerror):
7378 self.assertEqual(inner[TCPerror].sport, server_tcp_in_port)
7379 self.assertEqual(inner[TCPerror].dport,
7380 client_tcp_out_port)
7381 else:
7382 self.assertEqual(inner[UDPerror].sport, server_udp_in_port)
7383 self.assertEqual(inner[UDPerror].dport,
7384 client_udp_out_port)
7385 except:
7386 self.logger.error(ppp("Unexpected or invalid packet:", packet))
7387 raise
7388
Matus Fabian428dc912017-06-21 06:15:18 -07007389 def test_prefix(self):
7390 """ NAT64 Network-Specific Prefix """
7391
7392 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
7393 self.nat_addr_n)
7394 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
7395 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
7396 self.vapi.nat64_add_del_pool_addr_range(self.vrf1_nat_addr_n,
7397 self.vrf1_nat_addr_n,
7398 vrf_id=self.vrf1_id)
7399 self.vapi.nat64_add_del_interface(self.pg2.sw_if_index)
7400
7401 # Add global prefix
7402 global_pref64 = "2001:db8::"
7403 global_pref64_n = socket.inet_pton(socket.AF_INET6, global_pref64)
7404 global_pref64_len = 32
7405 self.vapi.nat64_add_del_prefix(global_pref64_n, global_pref64_len)
7406
7407 prefix = self.vapi.nat64_prefix_dump()
7408 self.assertEqual(len(prefix), 1)
7409 self.assertEqual(prefix[0].prefix, global_pref64_n)
7410 self.assertEqual(prefix[0].prefix_len, global_pref64_len)
7411 self.assertEqual(prefix[0].vrf_id, 0)
7412
7413 # Add tenant specific prefix
7414 vrf1_pref64 = "2001:db8:122:300::"
7415 vrf1_pref64_n = socket.inet_pton(socket.AF_INET6, vrf1_pref64)
7416 vrf1_pref64_len = 56
7417 self.vapi.nat64_add_del_prefix(vrf1_pref64_n,
7418 vrf1_pref64_len,
7419 vrf_id=self.vrf1_id)
7420 prefix = self.vapi.nat64_prefix_dump()
7421 self.assertEqual(len(prefix), 2)
7422
7423 # Global prefix
7424 pkts = self.create_stream_in_ip6(self.pg0,
7425 self.pg1,
7426 pref=global_pref64,
7427 plen=global_pref64_len)
7428 self.pg0.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.nat_addr,
7433 dst_ip=self.pg1.remote_ip4)
7434
7435 pkts = self.create_stream_out(self.pg1, dst_ip=self.nat_addr)
7436 self.pg1.add_stream(pkts)
7437 self.pg_enable_capture(self.pg_interfaces)
7438 self.pg_start()
7439 capture = self.pg0.get_capture(len(pkts))
7440 dst_ip = self.compose_ip6(self.pg1.remote_ip4,
7441 global_pref64,
7442 global_pref64_len)
7443 self.verify_capture_in_ip6(capture, dst_ip, self.pg0.remote_ip6)
7444
7445 # Tenant specific prefix
7446 pkts = self.create_stream_in_ip6(self.pg2,
7447 self.pg1,
7448 pref=vrf1_pref64,
7449 plen=vrf1_pref64_len)
7450 self.pg2.add_stream(pkts)
7451 self.pg_enable_capture(self.pg_interfaces)
7452 self.pg_start()
7453 capture = self.pg1.get_capture(len(pkts))
7454 self.verify_capture_out(capture, nat_ip=self.vrf1_nat_addr,
7455 dst_ip=self.pg1.remote_ip4)
7456
7457 pkts = self.create_stream_out(self.pg1, dst_ip=self.vrf1_nat_addr)
7458 self.pg1.add_stream(pkts)
7459 self.pg_enable_capture(self.pg_interfaces)
7460 self.pg_start()
7461 capture = self.pg2.get_capture(len(pkts))
7462 dst_ip = self.compose_ip6(self.pg1.remote_ip4,
7463 vrf1_pref64,
7464 vrf1_pref64_len)
7465 self.verify_capture_in_ip6(capture, dst_ip, self.pg2.remote_ip6)
7466
Matus Fabianf8cd5812017-07-11 03:55:02 -07007467 def test_unknown_proto(self):
Matus Fabian7968e6c2017-07-06 05:37:49 -07007468 """ NAT64 translate packet with unknown protocol """
7469
7470 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
7471 self.nat_addr_n)
7472 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
7473 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
7474 remote_ip6 = self.compose_ip6(self.pg1.remote_ip4, '64:ff9b::', 96)
7475
7476 # in2out
7477 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
7478 IPv6(src=self.pg0.remote_ip6, dst=remote_ip6) /
7479 TCP(sport=self.tcp_port_in, dport=20))
7480 self.pg0.add_stream(p)
7481 self.pg_enable_capture(self.pg_interfaces)
7482 self.pg_start()
7483 p = self.pg1.get_capture(1)
7484
7485 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
Matus Fabianf8cd5812017-07-11 03:55:02 -07007486 IPv6(src=self.pg0.remote_ip6, dst=remote_ip6, nh=47) /
Matus Fabian7968e6c2017-07-06 05:37:49 -07007487 GRE() /
7488 IP(src=self.pg2.local_ip4, dst=self.pg2.remote_ip4) /
7489 TCP(sport=1234, dport=1234))
7490 self.pg0.add_stream(p)
7491 self.pg_enable_capture(self.pg_interfaces)
7492 self.pg_start()
7493 p = self.pg1.get_capture(1)
7494 packet = p[0]
7495 try:
7496 self.assertEqual(packet[IP].src, self.nat_addr)
7497 self.assertEqual(packet[IP].dst, self.pg1.remote_ip4)
Paul Vinciguerra978aa642018-11-24 22:19:12 -08007498 self.assertEqual(packet.haslayer(GRE), 1)
Klement Sekerad81ae412018-05-16 10:52:54 +02007499 self.assert_packet_checksums_valid(packet)
Matus Fabian7968e6c2017-07-06 05:37:49 -07007500 except:
7501 self.logger.error(ppp("Unexpected or invalid packet:", packet))
7502 raise
7503
7504 # out2in
7505 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
7506 IP(src=self.pg1.remote_ip4, dst=self.nat_addr) /
7507 GRE() /
7508 IP(src=self.pg2.remote_ip4, dst=self.pg2.local_ip4) /
7509 TCP(sport=1234, dport=1234))
7510 self.pg1.add_stream(p)
7511 self.pg_enable_capture(self.pg_interfaces)
7512 self.pg_start()
7513 p = self.pg0.get_capture(1)
7514 packet = p[0]
7515 try:
7516 self.assertEqual(packet[IPv6].src, remote_ip6)
Matus Fabianf8cd5812017-07-11 03:55:02 -07007517 self.assertEqual(packet[IPv6].dst, self.pg0.remote_ip6)
7518 self.assertEqual(packet[IPv6].nh, 47)
Matus Fabian7968e6c2017-07-06 05:37:49 -07007519 except:
7520 self.logger.error(ppp("Unexpected or invalid packet:", packet))
7521 raise
7522
Matus Fabianf8cd5812017-07-11 03:55:02 -07007523 def test_hairpinning_unknown_proto(self):
Matus Fabian7968e6c2017-07-06 05:37:49 -07007524 """ NAT64 translate packet with unknown protocol - hairpinning """
7525
7526 client = self.pg0.remote_hosts[0]
7527 server = self.pg0.remote_hosts[1]
7528 server_tcp_in_port = 22
7529 server_tcp_out_port = 4022
7530 client_tcp_in_port = 1234
Matus Fabianf8cd5812017-07-11 03:55:02 -07007531 client_tcp_out_port = 1235
7532 server_nat_ip = "10.0.0.100"
7533 client_nat_ip = "10.0.0.110"
7534 server_nat_ip_n = socket.inet_pton(socket.AF_INET, server_nat_ip)
7535 client_nat_ip_n = socket.inet_pton(socket.AF_INET, client_nat_ip)
7536 server_nat_ip6 = self.compose_ip6(server_nat_ip, '64:ff9b::', 96)
7537 client_nat_ip6 = self.compose_ip6(client_nat_ip, '64:ff9b::', 96)
Matus Fabian7968e6c2017-07-06 05:37:49 -07007538
Matus Fabianf8cd5812017-07-11 03:55:02 -07007539 self.vapi.nat64_add_del_pool_addr_range(server_nat_ip_n,
7540 client_nat_ip_n)
Matus Fabian7968e6c2017-07-06 05:37:49 -07007541 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
7542 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
7543
7544 self.vapi.nat64_add_del_static_bib(server.ip6n,
Matus Fabianf8cd5812017-07-11 03:55:02 -07007545 server_nat_ip_n,
Matus Fabian7968e6c2017-07-06 05:37:49 -07007546 server_tcp_in_port,
7547 server_tcp_out_port,
7548 IP_PROTOS.tcp)
7549
Matus Fabianf8cd5812017-07-11 03:55:02 -07007550 self.vapi.nat64_add_del_static_bib(server.ip6n,
7551 server_nat_ip_n,
7552 0,
7553 0,
7554 IP_PROTOS.gre)
7555
7556 self.vapi.nat64_add_del_static_bib(client.ip6n,
7557 client_nat_ip_n,
7558 client_tcp_in_port,
7559 client_tcp_out_port,
7560 IP_PROTOS.tcp)
7561
Matus Fabian7968e6c2017-07-06 05:37:49 -07007562 # client to server
7563 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
Matus Fabianf8cd5812017-07-11 03:55:02 -07007564 IPv6(src=client.ip6, dst=server_nat_ip6) /
Matus Fabian7968e6c2017-07-06 05:37:49 -07007565 TCP(sport=client_tcp_in_port, dport=server_tcp_out_port))
7566 self.pg0.add_stream(p)
7567 self.pg_enable_capture(self.pg_interfaces)
7568 self.pg_start()
7569 p = self.pg0.get_capture(1)
7570
7571 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
Matus Fabianf8cd5812017-07-11 03:55:02 -07007572 IPv6(src=client.ip6, dst=server_nat_ip6, nh=IP_PROTOS.gre) /
Matus Fabian7968e6c2017-07-06 05:37:49 -07007573 GRE() /
7574 IP(src=self.pg2.local_ip4, dst=self.pg2.remote_ip4) /
7575 TCP(sport=1234, dport=1234))
7576 self.pg0.add_stream(p)
7577 self.pg_enable_capture(self.pg_interfaces)
7578 self.pg_start()
7579 p = self.pg0.get_capture(1)
7580 packet = p[0]
7581 try:
Matus Fabianf8cd5812017-07-11 03:55:02 -07007582 self.assertEqual(packet[IPv6].src, client_nat_ip6)
Matus Fabian7968e6c2017-07-06 05:37:49 -07007583 self.assertEqual(packet[IPv6].dst, server.ip6)
Matus Fabianf8cd5812017-07-11 03:55:02 -07007584 self.assertEqual(packet[IPv6].nh, IP_PROTOS.gre)
Matus Fabian7968e6c2017-07-06 05:37:49 -07007585 except:
7586 self.logger.error(ppp("Unexpected or invalid packet:", packet))
7587 raise
7588
7589 # server to client
7590 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
Matus Fabianf8cd5812017-07-11 03:55:02 -07007591 IPv6(src=server.ip6, dst=client_nat_ip6, nh=IP_PROTOS.gre) /
Matus Fabian7968e6c2017-07-06 05:37:49 -07007592 GRE() /
7593 IP(src=self.pg2.remote_ip4, dst=self.pg2.local_ip4) /
7594 TCP(sport=1234, dport=1234))
7595 self.pg0.add_stream(p)
7596 self.pg_enable_capture(self.pg_interfaces)
7597 self.pg_start()
7598 p = self.pg0.get_capture(1)
7599 packet = p[0]
7600 try:
Matus Fabianf8cd5812017-07-11 03:55:02 -07007601 self.assertEqual(packet[IPv6].src, server_nat_ip6)
Matus Fabian7968e6c2017-07-06 05:37:49 -07007602 self.assertEqual(packet[IPv6].dst, client.ip6)
Matus Fabianf8cd5812017-07-11 03:55:02 -07007603 self.assertEqual(packet[IPv6].nh, IP_PROTOS.gre)
Matus Fabian7968e6c2017-07-06 05:37:49 -07007604 except:
7605 self.logger.error(ppp("Unexpected or invalid packet:", packet))
7606 raise
7607
Matus Fabian36ea2d62017-10-24 04:13:49 -07007608 def test_one_armed_nat64(self):
7609 """ One armed NAT64 """
7610 external_port = 0
7611 remote_host_ip6 = self.compose_ip6(self.pg3.remote_ip4,
7612 '64:ff9b::',
7613 96)
7614
7615 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
7616 self.nat_addr_n)
7617 self.vapi.nat64_add_del_interface(self.pg3.sw_if_index)
7618 self.vapi.nat64_add_del_interface(self.pg3.sw_if_index, is_inside=0)
7619
7620 # in2out
7621 p = (Ether(src=self.pg3.remote_mac, dst=self.pg3.local_mac) /
7622 IPv6(src=self.pg3.remote_ip6, dst=remote_host_ip6) /
7623 TCP(sport=12345, dport=80))
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[IP]
7631 tcp = p[TCP]
7632 self.assertEqual(ip.src, self.nat_addr)
7633 self.assertEqual(ip.dst, self.pg3.remote_ip4)
7634 self.assertNotEqual(tcp.sport, 12345)
7635 external_port = tcp.sport
7636 self.assertEqual(tcp.dport, 80)
Klement Sekerad81ae412018-05-16 10:52:54 +02007637 self.assert_packet_checksums_valid(p)
Matus Fabian36ea2d62017-10-24 04:13:49 -07007638 except:
7639 self.logger.error(ppp("Unexpected or invalid packet:", p))
7640 raise
7641
7642 # out2in
7643 p = (Ether(src=self.pg3.remote_mac, dst=self.pg3.local_mac) /
7644 IP(src=self.pg3.remote_ip4, dst=self.nat_addr) /
7645 TCP(sport=80, dport=external_port))
7646 self.pg3.add_stream(p)
7647 self.pg_enable_capture(self.pg_interfaces)
7648 self.pg_start()
7649 capture = self.pg3.get_capture(1)
7650 p = capture[0]
7651 try:
7652 ip = p[IPv6]
7653 tcp = p[TCP]
7654 self.assertEqual(ip.src, remote_host_ip6)
7655 self.assertEqual(ip.dst, self.pg3.remote_ip6)
7656 self.assertEqual(tcp.sport, 80)
7657 self.assertEqual(tcp.dport, 12345)
Klement Sekerad81ae412018-05-16 10:52:54 +02007658 self.assert_packet_checksums_valid(p)
Matus Fabian36ea2d62017-10-24 04:13:49 -07007659 except:
7660 self.logger.error(ppp("Unexpected or invalid packet:", p))
7661 raise
7662
Matus Fabianefcd1e92017-08-15 06:59:19 -07007663 def test_frag_in_order(self):
7664 """ NAT64 translate fragments arriving in order """
7665 self.tcp_port_in = random.randint(1025, 65535)
7666
7667 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
7668 self.nat_addr_n)
7669 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
7670 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
7671
7672 reass = self.vapi.nat_reass_dump()
7673 reass_n_start = len(reass)
7674
7675 # in2out
7676 data = 'a' * 200
7677 pkts = self.create_stream_frag_ip6(self.pg0, self.pg1.remote_ip4,
7678 self.tcp_port_in, 20, data)
7679 self.pg0.add_stream(pkts)
7680 self.pg_enable_capture(self.pg_interfaces)
7681 self.pg_start()
7682 frags = self.pg1.get_capture(len(pkts))
7683 p = self.reass_frags_and_verify(frags,
7684 self.nat_addr,
7685 self.pg1.remote_ip4)
7686 self.assertEqual(p[TCP].dport, 20)
7687 self.assertNotEqual(p[TCP].sport, self.tcp_port_in)
7688 self.tcp_port_out = p[TCP].sport
7689 self.assertEqual(data, p[Raw].load)
7690
7691 # out2in
7692 data = "A" * 4 + "b" * 16 + "C" * 3
7693 pkts = self.create_stream_frag(self.pg1,
7694 self.nat_addr,
7695 20,
7696 self.tcp_port_out,
7697 data)
7698 self.pg1.add_stream(pkts)
7699 self.pg_enable_capture(self.pg_interfaces)
7700 self.pg_start()
7701 frags = self.pg0.get_capture(len(pkts))
7702 src = self.compose_ip6(self.pg1.remote_ip4, '64:ff9b::', 96)
7703 p = self.reass_frags_and_verify_ip6(frags, src, self.pg0.remote_ip6)
7704 self.assertEqual(p[TCP].sport, 20)
7705 self.assertEqual(p[TCP].dport, self.tcp_port_in)
7706 self.assertEqual(data, p[Raw].load)
7707
7708 reass = self.vapi.nat_reass_dump()
7709 reass_n_end = len(reass)
7710
7711 self.assertEqual(reass_n_end - reass_n_start, 2)
7712
7713 def test_reass_hairpinning(self):
7714 """ NAT64 fragments hairpinning """
7715 data = 'a' * 200
Matus Fabianefcd1e92017-08-15 06:59:19 -07007716 server = self.pg0.remote_hosts[1]
7717 server_in_port = random.randint(1025, 65535)
7718 server_out_port = random.randint(1025, 65535)
7719 client_in_port = random.randint(1025, 65535)
7720 ip = IPv6(src=''.join(['64:ff9b::', self.nat_addr]))
7721 nat_addr_ip6 = ip.src
7722
7723 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
7724 self.nat_addr_n)
7725 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
7726 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
7727
7728 # add static BIB entry for server
7729 self.vapi.nat64_add_del_static_bib(server.ip6n,
7730 self.nat_addr_n,
7731 server_in_port,
7732 server_out_port,
7733 IP_PROTOS.tcp)
7734
7735 # send packet from host to server
7736 pkts = self.create_stream_frag_ip6(self.pg0,
7737 self.nat_addr,
7738 client_in_port,
7739 server_out_port,
7740 data)
7741 self.pg0.add_stream(pkts)
7742 self.pg_enable_capture(self.pg_interfaces)
7743 self.pg_start()
7744 frags = self.pg0.get_capture(len(pkts))
7745 p = self.reass_frags_and_verify_ip6(frags, nat_addr_ip6, server.ip6)
7746 self.assertNotEqual(p[TCP].sport, client_in_port)
7747 self.assertEqual(p[TCP].dport, server_in_port)
7748 self.assertEqual(data, p[Raw].load)
7749
7750 def test_frag_out_of_order(self):
7751 """ NAT64 translate fragments arriving out of order """
7752 self.tcp_port_in = random.randint(1025, 65535)
7753
7754 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
7755 self.nat_addr_n)
7756 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
7757 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
7758
7759 # in2out
7760 data = 'a' * 200
7761 pkts = self.create_stream_frag_ip6(self.pg0, self.pg1.remote_ip4,
7762 self.tcp_port_in, 20, data)
7763 pkts.reverse()
7764 self.pg0.add_stream(pkts)
7765 self.pg_enable_capture(self.pg_interfaces)
7766 self.pg_start()
7767 frags = self.pg1.get_capture(len(pkts))
7768 p = self.reass_frags_and_verify(frags,
7769 self.nat_addr,
7770 self.pg1.remote_ip4)
7771 self.assertEqual(p[TCP].dport, 20)
7772 self.assertNotEqual(p[TCP].sport, self.tcp_port_in)
7773 self.tcp_port_out = p[TCP].sport
7774 self.assertEqual(data, p[Raw].load)
7775
7776 # out2in
7777 data = "A" * 4 + "B" * 16 + "C" * 3
7778 pkts = self.create_stream_frag(self.pg1,
7779 self.nat_addr,
7780 20,
7781 self.tcp_port_out,
7782 data)
7783 pkts.reverse()
7784 self.pg1.add_stream(pkts)
7785 self.pg_enable_capture(self.pg_interfaces)
7786 self.pg_start()
7787 frags = self.pg0.get_capture(len(pkts))
7788 src = self.compose_ip6(self.pg1.remote_ip4, '64:ff9b::', 96)
7789 p = self.reass_frags_and_verify_ip6(frags, src, self.pg0.remote_ip6)
7790 self.assertEqual(p[TCP].sport, 20)
7791 self.assertEqual(p[TCP].dport, self.tcp_port_in)
7792 self.assertEqual(data, p[Raw].load)
7793
Matus Fabian0938dcf2017-11-08 01:59:38 -08007794 def test_interface_addr(self):
7795 """ Acquire NAT64 pool addresses from interface """
7796 self.vapi.nat64_add_interface_addr(self.pg4.sw_if_index)
7797
7798 # no address in NAT64 pool
7799 adresses = self.vapi.nat44_address_dump()
7800 self.assertEqual(0, len(adresses))
7801
7802 # configure interface address and check NAT64 address pool
7803 self.pg4.config_ip4()
7804 addresses = self.vapi.nat64_pool_addr_dump()
7805 self.assertEqual(len(addresses), 1)
7806 self.assertEqual(addresses[0].address, self.pg4.local_ip4n)
7807
7808 # remove interface address and check NAT64 address pool
7809 self.pg4.unconfig_ip4()
7810 addresses = self.vapi.nat64_pool_addr_dump()
7811 self.assertEqual(0, len(adresses))
7812
Paul Vinciguerradefde0f2018-12-06 07:46:13 -08007813 @unittest.skipUnless(running_extended_tests, "part of extended tests")
Matus Fabiana431ad12018-01-04 04:03:14 -08007814 def test_ipfix_max_bibs_sessions(self):
7815 """ IPFIX logging maximum session and BIB entries exceeded """
7816 max_bibs = 1280
7817 max_sessions = 2560
7818 remote_host_ip6 = self.compose_ip6(self.pg1.remote_ip4,
7819 '64:ff9b::',
7820 96)
7821
7822 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
7823 self.nat_addr_n)
7824 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
7825 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
7826
7827 pkts = []
7828 src = ""
7829 for i in range(0, max_bibs):
7830 src = "fd01:aa::%x" % (i)
7831 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
7832 IPv6(src=src, dst=remote_host_ip6) /
7833 TCP(sport=12345, dport=80))
7834 pkts.append(p)
7835 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
7836 IPv6(src=src, dst=remote_host_ip6) /
7837 TCP(sport=12345, dport=22))
7838 pkts.append(p)
7839 self.pg0.add_stream(pkts)
7840 self.pg_enable_capture(self.pg_interfaces)
7841 self.pg_start()
7842 self.pg1.get_capture(max_sessions)
7843
7844 self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4n,
7845 src_address=self.pg3.local_ip4n,
7846 path_mtu=512,
7847 template_interval=10)
7848 self.vapi.nat_ipfix(domain_id=self.ipfix_domain_id,
7849 src_port=self.ipfix_src_port)
7850
7851 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
7852 IPv6(src=src, dst=remote_host_ip6) /
7853 TCP(sport=12345, dport=25))
7854 self.pg0.add_stream(p)
7855 self.pg_enable_capture(self.pg_interfaces)
7856 self.pg_start()
Matus Fabian229c1aa2018-05-28 04:09:52 -07007857 self.pg1.assert_nothing_captured()
7858 sleep(1)
Matus Fabiana431ad12018-01-04 04:03:14 -08007859 self.vapi.cli("ipfix flush") # FIXME this should be an API call
7860 capture = self.pg3.get_capture(9)
7861 ipfix = IPFIXDecoder()
7862 # first load template
7863 for p in capture:
7864 self.assertTrue(p.haslayer(IPFIX))
7865 self.assertEqual(p[IP].src, self.pg3.local_ip4)
7866 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
7867 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
7868 self.assertEqual(p[UDP].dport, 4739)
7869 self.assertEqual(p[IPFIX].observationDomainID,
7870 self.ipfix_domain_id)
7871 if p.haslayer(Template):
7872 ipfix.add_template(p.getlayer(Template))
7873 # verify events in data set
7874 for p in capture:
7875 if p.haslayer(Data):
7876 data = ipfix.decode_data_set(p.getlayer(Set))
7877 self.verify_ipfix_max_sessions(data, max_sessions)
7878
7879 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
7880 IPv6(src=self.pg0.remote_ip6, dst=remote_host_ip6) /
7881 TCP(sport=12345, dport=80))
7882 self.pg0.add_stream(p)
7883 self.pg_enable_capture(self.pg_interfaces)
7884 self.pg_start()
Matus Fabian229c1aa2018-05-28 04:09:52 -07007885 self.pg1.assert_nothing_captured()
7886 sleep(1)
Matus Fabiana431ad12018-01-04 04:03:14 -08007887 self.vapi.cli("ipfix flush") # FIXME this should be an API call
7888 capture = self.pg3.get_capture(1)
7889 # verify events in data set
7890 for p in capture:
7891 self.assertTrue(p.haslayer(IPFIX))
7892 self.assertEqual(p[IP].src, self.pg3.local_ip4)
7893 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
7894 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
7895 self.assertEqual(p[UDP].dport, 4739)
7896 self.assertEqual(p[IPFIX].observationDomainID,
7897 self.ipfix_domain_id)
7898 if p.haslayer(Data):
7899 data = ipfix.decode_data_set(p.getlayer(Set))
7900 self.verify_ipfix_max_bibs(data, max_bibs)
7901
7902 def test_ipfix_max_frags(self):
7903 """ IPFIX logging maximum fragments pending reassembly exceeded """
7904 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
7905 self.nat_addr_n)
7906 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
7907 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
Matus Fabiana7f8b222018-09-05 06:01:55 -07007908 self.vapi.nat_set_reass(max_frag=1, is_ip6=1)
Matus Fabiana431ad12018-01-04 04:03:14 -08007909 self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4n,
7910 src_address=self.pg3.local_ip4n,
7911 path_mtu=512,
7912 template_interval=10)
7913 self.vapi.nat_ipfix(domain_id=self.ipfix_domain_id,
7914 src_port=self.ipfix_src_port)
7915
7916 data = 'a' * 200
7917 pkts = self.create_stream_frag_ip6(self.pg0, self.pg1.remote_ip4,
7918 self.tcp_port_in, 20, data)
Matus Fabiana7f8b222018-09-05 06:01:55 -07007919 pkts.reverse()
7920 self.pg0.add_stream(pkts)
Matus Fabiana431ad12018-01-04 04:03:14 -08007921 self.pg_enable_capture(self.pg_interfaces)
7922 self.pg_start()
Matus Fabian229c1aa2018-05-28 04:09:52 -07007923 self.pg1.assert_nothing_captured()
7924 sleep(1)
Matus Fabiana431ad12018-01-04 04:03:14 -08007925 self.vapi.cli("ipfix flush") # FIXME this should be an API call
7926 capture = self.pg3.get_capture(9)
7927 ipfix = IPFIXDecoder()
7928 # first load template
7929 for p in capture:
7930 self.assertTrue(p.haslayer(IPFIX))
7931 self.assertEqual(p[IP].src, self.pg3.local_ip4)
7932 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
7933 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
7934 self.assertEqual(p[UDP].dport, 4739)
7935 self.assertEqual(p[IPFIX].observationDomainID,
7936 self.ipfix_domain_id)
7937 if p.haslayer(Template):
7938 ipfix.add_template(p.getlayer(Template))
7939 # verify events in data set
7940 for p in capture:
7941 if p.haslayer(Data):
7942 data = ipfix.decode_data_set(p.getlayer(Set))
Matus Fabiana7f8b222018-09-05 06:01:55 -07007943 self.verify_ipfix_max_fragments_ip6(data, 1,
Matus Fabiana431ad12018-01-04 04:03:14 -08007944 self.pg0.remote_ip6n)
7945
7946 def test_ipfix_bib_ses(self):
7947 """ IPFIX logging NAT64 BIB/session create and delete events """
7948 self.tcp_port_in = random.randint(1025, 65535)
7949 remote_host_ip6 = self.compose_ip6(self.pg1.remote_ip4,
7950 '64:ff9b::',
7951 96)
7952
7953 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
7954 self.nat_addr_n)
7955 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
7956 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
7957 self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4n,
7958 src_address=self.pg3.local_ip4n,
7959 path_mtu=512,
7960 template_interval=10)
7961 self.vapi.nat_ipfix(domain_id=self.ipfix_domain_id,
7962 src_port=self.ipfix_src_port)
7963
7964 # Create
7965 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
7966 IPv6(src=self.pg0.remote_ip6, dst=remote_host_ip6) /
7967 TCP(sport=self.tcp_port_in, dport=25))
7968 self.pg0.add_stream(p)
7969 self.pg_enable_capture(self.pg_interfaces)
7970 self.pg_start()
7971 p = self.pg1.get_capture(1)
7972 self.tcp_port_out = p[0][TCP].sport
7973 self.vapi.cli("ipfix flush") # FIXME this should be an API call
7974 capture = self.pg3.get_capture(10)
7975 ipfix = IPFIXDecoder()
7976 # first load template
7977 for p in capture:
7978 self.assertTrue(p.haslayer(IPFIX))
7979 self.assertEqual(p[IP].src, self.pg3.local_ip4)
7980 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
7981 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
7982 self.assertEqual(p[UDP].dport, 4739)
7983 self.assertEqual(p[IPFIX].observationDomainID,
7984 self.ipfix_domain_id)
7985 if p.haslayer(Template):
7986 ipfix.add_template(p.getlayer(Template))
7987 # verify events in data set
7988 for p in capture:
7989 if p.haslayer(Data):
7990 data = ipfix.decode_data_set(p.getlayer(Set))
7991 if ord(data[0][230]) == 10:
7992 self.verify_ipfix_bib(data, 1, self.pg0.remote_ip6n)
7993 elif ord(data[0][230]) == 6:
7994 self.verify_ipfix_nat64_ses(data,
7995 1,
7996 self.pg0.remote_ip6n,
7997 self.pg1.remote_ip4,
7998 25)
7999 else:
8000 self.logger.error(ppp("Unexpected or invalid packet: ", p))
8001
8002 # Delete
8003 self.pg_enable_capture(self.pg_interfaces)
8004 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
8005 self.nat_addr_n,
8006 is_add=0)
8007 self.vapi.cli("ipfix flush") # FIXME this should be an API call
8008 capture = self.pg3.get_capture(2)
8009 # verify events in data set
8010 for p in capture:
8011 self.assertTrue(p.haslayer(IPFIX))
8012 self.assertEqual(p[IP].src, self.pg3.local_ip4)
8013 self.assertEqual(p[IP].dst, self.pg3.remote_ip4)
8014 self.assertEqual(p[UDP].sport, self.ipfix_src_port)
8015 self.assertEqual(p[UDP].dport, 4739)
8016 self.assertEqual(p[IPFIX].observationDomainID,
8017 self.ipfix_domain_id)
8018 if p.haslayer(Data):
8019 data = ipfix.decode_data_set(p.getlayer(Set))
8020 if ord(data[0][230]) == 11:
8021 self.verify_ipfix_bib(data, 0, self.pg0.remote_ip6n)
8022 elif ord(data[0][230]) == 7:
8023 self.verify_ipfix_nat64_ses(data,
8024 0,
8025 self.pg0.remote_ip6n,
8026 self.pg1.remote_ip4,
8027 25)
8028 else:
8029 self.logger.error(ppp("Unexpected or invalid packet: ", p))
8030
Matus Fabianad1f3e12018-11-28 21:26:34 -08008031 def test_syslog_sess(self):
8032 """ Test syslog session creation and deletion """
8033 self.tcp_port_in = random.randint(1025, 65535)
8034 remote_host_ip6 = self.compose_ip6(self.pg1.remote_ip4,
8035 '64:ff9b::',
8036 96)
8037
8038 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
8039 self.nat_addr_n)
8040 self.vapi.nat64_add_del_interface(self.pg0.sw_if_index)
8041 self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
8042 self.vapi.syslog_set_filter(SYSLOG_SEVERITY.INFO)
8043 self.vapi.syslog_set_sender(self.pg3.remote_ip4n, self.pg3.local_ip4n)
8044
8045 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
8046 IPv6(src=self.pg0.remote_ip6, dst=remote_host_ip6) /
8047 TCP(sport=self.tcp_port_in, dport=self.tcp_external_port))
8048 self.pg0.add_stream(p)
8049 self.pg_enable_capture(self.pg_interfaces)
8050 self.pg_start()
8051 p = self.pg1.get_capture(1)
8052 self.tcp_port_out = p[0][TCP].sport
8053 capture = self.pg3.get_capture(1)
8054 self.verify_syslog_sess(capture[0][Raw].load, is_ip6=True)
8055
8056 self.pg_enable_capture(self.pg_interfaces)
8057 self.pg_start()
8058 self.vapi.nat64_add_del_pool_addr_range(self.nat_addr_n,
8059 self.nat_addr_n,
8060 is_add=0)
8061 capture = self.pg3.get_capture(1)
8062 self.verify_syslog_sess(capture[0][Raw].load, False, True)
8063
Matus Fabian06596c52017-06-06 04:53:28 -07008064 def nat64_get_ses_num(self):
8065 """
8066 Return number of active NAT64 sessions.
8067 """
Matus Fabianab9a59c2017-08-16 05:37:36 -07008068 st = self.vapi.nat64_st_dump()
8069 return len(st)
Matus Fabian06596c52017-06-06 04:53:28 -07008070
8071 def clear_nat64(self):
8072 """
8073 Clear NAT64 configuration.
8074 """
Matus Fabiana431ad12018-01-04 04:03:14 -08008075 self.vapi.nat_ipfix(enable=0, src_port=self.ipfix_src_port,
8076 domain_id=self.ipfix_domain_id)
8077 self.ipfix_src_port = 4739
8078 self.ipfix_domain_id = 1
8079
Matus Fabianad1f3e12018-11-28 21:26:34 -08008080 self.vapi.syslog_set_filter(SYSLOG_SEVERITY.EMERG)
8081
Matus Fabian878c6462018-08-23 00:33:35 -07008082 self.vapi.nat_set_timeouts()
Matus Fabian06596c52017-06-06 04:53:28 -07008083
8084 interfaces = self.vapi.nat64_interface_dump()
8085 for intf in interfaces:
Matus Fabian36ea2d62017-10-24 04:13:49 -07008086 if intf.is_inside > 1:
8087 self.vapi.nat64_add_del_interface(intf.sw_if_index,
8088 0,
8089 is_add=0)
Matus Fabian06596c52017-06-06 04:53:28 -07008090 self.vapi.nat64_add_del_interface(intf.sw_if_index,
8091 intf.is_inside,
8092 is_add=0)
8093
Matus Fabiana431ad12018-01-04 04:03:14 -08008094 bib = self.vapi.nat64_bib_dump(255)
Matus Fabian06596c52017-06-06 04:53:28 -07008095 for bibe in bib:
8096 if bibe.is_static:
8097 self.vapi.nat64_add_del_static_bib(bibe.i_addr,
8098 bibe.o_addr,
8099 bibe.i_port,
8100 bibe.o_port,
8101 bibe.proto,
8102 bibe.vrf_id,
8103 is_add=0)
8104
8105 adresses = self.vapi.nat64_pool_addr_dump()
8106 for addr in adresses:
8107 self.vapi.nat64_add_del_pool_addr_range(addr.address,
8108 addr.address,
Matus Fabian029f3d22017-06-15 02:28:50 -07008109 vrf_id=addr.vrf_id,
Matus Fabian06596c52017-06-06 04:53:28 -07008110 is_add=0)
8111
Matus Fabian428dc912017-06-21 06:15:18 -07008112 prefixes = self.vapi.nat64_prefix_dump()
8113 for prefix in prefixes:
8114 self.vapi.nat64_add_del_prefix(prefix.prefix,
8115 prefix.prefix_len,
8116 vrf_id=prefix.vrf_id,
8117 is_add=0)
8118
Matus Fabianfd0d5082018-12-18 01:08:51 -08008119 bibs = self.statistics.get_counter('/nat64/total-bibs')
8120 self.assertEqual(bibs[0][0], 0)
8121 sessions = self.statistics.get_counter('/nat64/total-sessions')
8122 self.assertEqual(sessions[0][0], 0)
8123
Matus Fabian06596c52017-06-06 04:53:28 -07008124 def tearDown(self):
8125 super(TestNAT64, self).tearDown()
8126 if not self.vpp_dead:
8127 self.logger.info(self.vapi.cli("show nat64 pool"))
8128 self.logger.info(self.vapi.cli("show nat64 interfaces"))
Matus Fabian428dc912017-06-21 06:15:18 -07008129 self.logger.info(self.vapi.cli("show nat64 prefix"))
Matus Fabianab9a59c2017-08-16 05:37:36 -07008130 self.logger.info(self.vapi.cli("show nat64 bib all"))
8131 self.logger.info(self.vapi.cli("show nat64 session table all"))
Matus Fabianefcd1e92017-08-15 06:59:19 -07008132 self.logger.info(self.vapi.cli("show nat virtual-reassembly"))
Matus Fabian06596c52017-06-06 04:53:28 -07008133 self.clear_nat64()
8134
Matus Fabian8ebe6252017-11-06 05:04:53 -08008135
8136class TestDSlite(MethodHolder):
8137 """ DS-Lite Test Cases """
8138
8139 @classmethod
8140 def setUpClass(cls):
8141 super(TestDSlite, cls).setUpClass()
8142
8143 try:
8144 cls.nat_addr = '10.0.0.3'
8145 cls.nat_addr_n = socket.inet_pton(socket.AF_INET, cls.nat_addr)
8146
Matus Fabianad1f3e12018-11-28 21:26:34 -08008147 cls.create_pg_interfaces(range(3))
Matus Fabian8ebe6252017-11-06 05:04:53 -08008148 cls.pg0.admin_up()
8149 cls.pg0.config_ip4()
8150 cls.pg0.resolve_arp()
8151 cls.pg1.admin_up()
8152 cls.pg1.config_ip6()
8153 cls.pg1.generate_remote_hosts(2)
8154 cls.pg1.configure_ipv6_neighbors()
Matus Fabianad1f3e12018-11-28 21:26:34 -08008155 cls.pg2.admin_up()
8156 cls.pg2.config_ip4()
8157 cls.pg2.resolve_arp()
Matus Fabian8ebe6252017-11-06 05:04:53 -08008158
8159 except Exception:
8160 super(TestDSlite, cls).tearDownClass()
8161 raise
8162
Matus Fabianad1f3e12018-11-28 21:26:34 -08008163 def verify_syslog_apmadd(self, data, isaddr, isport, xsaddr, xsport,
8164 sv6enc, proto):
8165 message = data.decode('utf-8')
8166 try:
8167 message = SyslogMessage.parse(message)
8168 self.assertEqual(message.severity, SyslogSeverity.info)
8169 self.assertEqual(message.appname, 'NAT')
8170 self.assertEqual(message.msgid, 'APMADD')
8171 sd_params = message.sd.get('napmap')
8172 self.assertTrue(sd_params is not None)
8173 self.assertEqual(sd_params.get('IATYP'), 'IPv4')
8174 self.assertEqual(sd_params.get('ISADDR'), isaddr)
8175 self.assertEqual(sd_params.get('ISPORT'), "%d" % isport)
8176 self.assertEqual(sd_params.get('XATYP'), 'IPv4')
8177 self.assertEqual(sd_params.get('XSADDR'), xsaddr)
8178 self.assertEqual(sd_params.get('XSPORT'), "%d" % xsport)
8179 self.assertEqual(sd_params.get('PROTO'), "%d" % proto)
8180 self.assertTrue(sd_params.get('SSUBIX') is not None)
8181 self.assertEqual(sd_params.get('SV6ENC'), sv6enc)
8182 except ParseError as e:
8183 self.logger.error(e)
8184
Matus Fabian8ebe6252017-11-06 05:04:53 -08008185 def test_dslite(self):
8186 """ Test DS-Lite """
Matus Fabian69ce30d2018-08-22 01:27:10 -07008187 nat_config = self.vapi.nat_show_config()
8188 self.assertEqual(0, nat_config.dslite_ce)
8189
Matus Fabian8ebe6252017-11-06 05:04:53 -08008190 self.vapi.dslite_add_del_pool_addr_range(self.nat_addr_n,
8191 self.nat_addr_n)
8192 aftr_ip4 = '192.0.0.1'
8193 aftr_ip4_n = socket.inet_pton(socket.AF_INET, aftr_ip4)
8194 aftr_ip6 = '2001:db8:85a3::8a2e:370:1'
8195 aftr_ip6_n = socket.inet_pton(socket.AF_INET6, aftr_ip6)
8196 self.vapi.dslite_set_aftr_addr(aftr_ip6_n, aftr_ip4_n)
Matus Fabianad1f3e12018-11-28 21:26:34 -08008197 self.vapi.syslog_set_sender(self.pg2.remote_ip4n, self.pg2.local_ip4n)
Matus Fabian8ebe6252017-11-06 05:04:53 -08008198
8199 # UDP
8200 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
8201 IPv6(dst=aftr_ip6, src=self.pg1.remote_hosts[0].ip6) /
8202 IP(dst=self.pg0.remote_ip4, src='192.168.1.1') /
8203 UDP(sport=20000, dport=10000))
8204 self.pg1.add_stream(p)
8205 self.pg_enable_capture(self.pg_interfaces)
8206 self.pg_start()
8207 capture = self.pg0.get_capture(1)
8208 capture = capture[0]
8209 self.assertFalse(capture.haslayer(IPv6))
8210 self.assertEqual(capture[IP].src, self.nat_addr)
8211 self.assertEqual(capture[IP].dst, self.pg0.remote_ip4)
8212 self.assertNotEqual(capture[UDP].sport, 20000)
8213 self.assertEqual(capture[UDP].dport, 10000)
Klement Sekerad81ae412018-05-16 10:52:54 +02008214 self.assert_packet_checksums_valid(capture)
Matus Fabian8ebe6252017-11-06 05:04:53 -08008215 out_port = capture[UDP].sport
Matus Fabianad1f3e12018-11-28 21:26:34 -08008216 capture = self.pg2.get_capture(1)
8217 self.verify_syslog_apmadd(capture[0][Raw].load, '192.168.1.1',
8218 20000, self.nat_addr, out_port,
8219 self.pg1.remote_hosts[0].ip6, IP_PROTOS.udp)
Matus Fabian8ebe6252017-11-06 05:04:53 -08008220
8221 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8222 IP(dst=self.nat_addr, src=self.pg0.remote_ip4) /
8223 UDP(sport=10000, dport=out_port))
8224 self.pg0.add_stream(p)
8225 self.pg_enable_capture(self.pg_interfaces)
8226 self.pg_start()
8227 capture = self.pg1.get_capture(1)
8228 capture = capture[0]
8229 self.assertEqual(capture[IPv6].src, aftr_ip6)
8230 self.assertEqual(capture[IPv6].dst, self.pg1.remote_hosts[0].ip6)
8231 self.assertEqual(capture[IP].src, self.pg0.remote_ip4)
8232 self.assertEqual(capture[IP].dst, '192.168.1.1')
8233 self.assertEqual(capture[UDP].sport, 10000)
8234 self.assertEqual(capture[UDP].dport, 20000)
Klement Sekerad81ae412018-05-16 10:52:54 +02008235 self.assert_packet_checksums_valid(capture)
Matus Fabian8ebe6252017-11-06 05:04:53 -08008236
8237 # TCP
8238 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
8239 IPv6(dst=aftr_ip6, src=self.pg1.remote_hosts[1].ip6) /
8240 IP(dst=self.pg0.remote_ip4, src='192.168.1.1') /
8241 TCP(sport=20001, dport=10001))
8242 self.pg1.add_stream(p)
8243 self.pg_enable_capture(self.pg_interfaces)
8244 self.pg_start()
8245 capture = self.pg0.get_capture(1)
8246 capture = capture[0]
8247 self.assertFalse(capture.haslayer(IPv6))
8248 self.assertEqual(capture[IP].src, self.nat_addr)
8249 self.assertEqual(capture[IP].dst, self.pg0.remote_ip4)
8250 self.assertNotEqual(capture[TCP].sport, 20001)
8251 self.assertEqual(capture[TCP].dport, 10001)
Klement Sekerad81ae412018-05-16 10:52:54 +02008252 self.assert_packet_checksums_valid(capture)
Matus Fabian8ebe6252017-11-06 05:04:53 -08008253 out_port = capture[TCP].sport
8254
8255 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8256 IP(dst=self.nat_addr, src=self.pg0.remote_ip4) /
8257 TCP(sport=10001, dport=out_port))
8258 self.pg0.add_stream(p)
8259 self.pg_enable_capture(self.pg_interfaces)
8260 self.pg_start()
8261 capture = self.pg1.get_capture(1)
8262 capture = capture[0]
8263 self.assertEqual(capture[IPv6].src, aftr_ip6)
8264 self.assertEqual(capture[IPv6].dst, self.pg1.remote_hosts[1].ip6)
8265 self.assertEqual(capture[IP].src, self.pg0.remote_ip4)
8266 self.assertEqual(capture[IP].dst, '192.168.1.1')
8267 self.assertEqual(capture[TCP].sport, 10001)
8268 self.assertEqual(capture[TCP].dport, 20001)
Klement Sekerad81ae412018-05-16 10:52:54 +02008269 self.assert_packet_checksums_valid(capture)
Matus Fabian8ebe6252017-11-06 05:04:53 -08008270
8271 # ICMP
8272 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
8273 IPv6(dst=aftr_ip6, src=self.pg1.remote_hosts[1].ip6) /
8274 IP(dst=self.pg0.remote_ip4, src='192.168.1.1') /
8275 ICMP(id=4000, type='echo-request'))
8276 self.pg1.add_stream(p)
8277 self.pg_enable_capture(self.pg_interfaces)
8278 self.pg_start()
8279 capture = self.pg0.get_capture(1)
8280 capture = capture[0]
8281 self.assertFalse(capture.haslayer(IPv6))
8282 self.assertEqual(capture[IP].src, self.nat_addr)
8283 self.assertEqual(capture[IP].dst, self.pg0.remote_ip4)
8284 self.assertNotEqual(capture[ICMP].id, 4000)
Klement Sekerad81ae412018-05-16 10:52:54 +02008285 self.assert_packet_checksums_valid(capture)
Matus Fabian8ebe6252017-11-06 05:04:53 -08008286 out_id = capture[ICMP].id
8287
8288 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8289 IP(dst=self.nat_addr, src=self.pg0.remote_ip4) /
8290 ICMP(id=out_id, type='echo-reply'))
8291 self.pg0.add_stream(p)
8292 self.pg_enable_capture(self.pg_interfaces)
8293 self.pg_start()
8294 capture = self.pg1.get_capture(1)
8295 capture = capture[0]
8296 self.assertEqual(capture[IPv6].src, aftr_ip6)
8297 self.assertEqual(capture[IPv6].dst, self.pg1.remote_hosts[1].ip6)
8298 self.assertEqual(capture[IP].src, self.pg0.remote_ip4)
8299 self.assertEqual(capture[IP].dst, '192.168.1.1')
8300 self.assertEqual(capture[ICMP].id, 4000)
Klement Sekerad81ae412018-05-16 10:52:54 +02008301 self.assert_packet_checksums_valid(capture)
Matus Fabian8ebe6252017-11-06 05:04:53 -08008302
Matus Fabian331acc62017-12-08 03:38:51 -08008303 # ping DS-Lite AFTR tunnel endpoint address
8304 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
8305 IPv6(src=self.pg1.remote_hosts[1].ip6, dst=aftr_ip6) /
8306 ICMPv6EchoRequest())
8307 self.pg1.add_stream(p)
8308 self.pg_enable_capture(self.pg_interfaces)
8309 self.pg_start()
8310 capture = self.pg1.get_capture(1)
Matus Fabian331acc62017-12-08 03:38:51 -08008311 capture = capture[0]
8312 self.assertEqual(capture[IPv6].src, aftr_ip6)
8313 self.assertEqual(capture[IPv6].dst, self.pg1.remote_hosts[1].ip6)
8314 self.assertTrue(capture.haslayer(ICMPv6EchoReply))
8315
Matus Fabianfd0d5082018-12-18 01:08:51 -08008316 b4s = self.statistics.get_counter('/dslite/total-b4s')
8317 self.assertEqual(b4s[0][0], 2)
8318 sessions = self.statistics.get_counter('/dslite/total-sessions')
8319 self.assertEqual(sessions[0][0], 3)
8320
Matus Fabian8ebe6252017-11-06 05:04:53 -08008321 def tearDown(self):
8322 super(TestDSlite, self).tearDown()
8323 if not self.vpp_dead:
8324 self.logger.info(self.vapi.cli("show dslite pool"))
8325 self.logger.info(
8326 self.vapi.cli("show dslite aftr-tunnel-endpoint-address"))
8327 self.logger.info(self.vapi.cli("show dslite sessions"))
8328
Juraj Slobodac5c6a332018-01-09 16:08:32 +01008329
8330class TestDSliteCE(MethodHolder):
8331 """ DS-Lite CE Test Cases """
8332
8333 @classmethod
8334 def setUpConstants(cls):
8335 super(TestDSliteCE, cls).setUpConstants()
8336 cls.vpp_cmdline.extend(["nat", "{", "dslite ce", "}"])
8337
8338 @classmethod
8339 def setUpClass(cls):
8340 super(TestDSliteCE, cls).setUpClass()
8341
8342 try:
8343 cls.create_pg_interfaces(range(2))
8344 cls.pg0.admin_up()
8345 cls.pg0.config_ip4()
8346 cls.pg0.resolve_arp()
8347 cls.pg1.admin_up()
8348 cls.pg1.config_ip6()
8349 cls.pg1.generate_remote_hosts(1)
8350 cls.pg1.configure_ipv6_neighbors()
8351
8352 except Exception:
8353 super(TestDSliteCE, cls).tearDownClass()
8354 raise
8355
8356 def test_dslite_ce(self):
8357 """ Test DS-Lite CE """
8358
Matus Fabian69ce30d2018-08-22 01:27:10 -07008359 nat_config = self.vapi.nat_show_config()
8360 self.assertEqual(1, nat_config.dslite_ce)
8361
Juraj Slobodac5c6a332018-01-09 16:08:32 +01008362 b4_ip4 = '192.0.0.2'
8363 b4_ip4_n = socket.inet_pton(socket.AF_INET, b4_ip4)
8364 b4_ip6 = '2001:db8:62aa::375e:f4c1:1'
8365 b4_ip6_n = socket.inet_pton(socket.AF_INET6, b4_ip6)
8366 self.vapi.dslite_set_b4_addr(b4_ip6_n, b4_ip4_n)
8367
8368 aftr_ip4 = '192.0.0.1'
8369 aftr_ip4_n = socket.inet_pton(socket.AF_INET, aftr_ip4)
8370 aftr_ip6 = '2001:db8:85a3::8a2e:370:1'
8371 aftr_ip6_n = socket.inet_pton(socket.AF_INET6, aftr_ip6)
8372 self.vapi.dslite_set_aftr_addr(aftr_ip6_n, aftr_ip4_n)
8373
8374 self.vapi.ip_add_del_route(dst_address=aftr_ip6_n,
8375 dst_address_length=128,
8376 next_hop_address=self.pg1.remote_ip6n,
8377 next_hop_sw_if_index=self.pg1.sw_if_index,
8378 is_ipv6=1)
8379
8380 # UDP encapsulation
8381 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8382 IP(dst=self.pg1.remote_ip4, src=self.pg0.remote_ip4) /
8383 UDP(sport=10000, dport=20000))
8384 self.pg0.add_stream(p)
8385 self.pg_enable_capture(self.pg_interfaces)
8386 self.pg_start()
8387 capture = self.pg1.get_capture(1)
8388 capture = capture[0]
8389 self.assertEqual(capture[IPv6].src, b4_ip6)
8390 self.assertEqual(capture[IPv6].dst, aftr_ip6)
8391 self.assertEqual(capture[IP].src, self.pg0.remote_ip4)
8392 self.assertEqual(capture[IP].dst, self.pg1.remote_ip4)
8393 self.assertEqual(capture[UDP].sport, 10000)
8394 self.assertEqual(capture[UDP].dport, 20000)
Klement Sekerad81ae412018-05-16 10:52:54 +02008395 self.assert_packet_checksums_valid(capture)
Juraj Slobodac5c6a332018-01-09 16:08:32 +01008396
8397 # UDP decapsulation
8398 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
8399 IPv6(dst=b4_ip6, src=aftr_ip6) /
8400 IP(dst=self.pg0.remote_ip4, src=self.pg1.remote_ip4) /
8401 UDP(sport=20000, dport=10000))
8402 self.pg1.add_stream(p)
8403 self.pg_enable_capture(self.pg_interfaces)
8404 self.pg_start()
8405 capture = self.pg0.get_capture(1)
8406 capture = capture[0]
8407 self.assertFalse(capture.haslayer(IPv6))
8408 self.assertEqual(capture[IP].src, self.pg1.remote_ip4)
8409 self.assertEqual(capture[IP].dst, self.pg0.remote_ip4)
8410 self.assertEqual(capture[UDP].sport, 20000)
8411 self.assertEqual(capture[UDP].dport, 10000)
Klement Sekerad81ae412018-05-16 10:52:54 +02008412 self.assert_packet_checksums_valid(capture)
Juraj Slobodac5c6a332018-01-09 16:08:32 +01008413
8414 # ping DS-Lite B4 tunnel endpoint address
8415 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
8416 IPv6(src=self.pg1.remote_hosts[0].ip6, dst=b4_ip6) /
8417 ICMPv6EchoRequest())
8418 self.pg1.add_stream(p)
8419 self.pg_enable_capture(self.pg_interfaces)
8420 self.pg_start()
8421 capture = self.pg1.get_capture(1)
Juraj Slobodac5c6a332018-01-09 16:08:32 +01008422 capture = capture[0]
8423 self.assertEqual(capture[IPv6].src, b4_ip6)
8424 self.assertEqual(capture[IPv6].dst, self.pg1.remote_hosts[0].ip6)
8425 self.assertTrue(capture.haslayer(ICMPv6EchoReply))
8426
8427 def tearDown(self):
8428 super(TestDSliteCE, self).tearDown()
8429 if not self.vpp_dead:
8430 self.logger.info(
8431 self.vapi.cli("show dslite aftr-tunnel-endpoint-address"))
8432 self.logger.info(
8433 self.vapi.cli("show dslite b4-tunnel-endpoint-address"))
8434
Matus Fabianf2a23cc2018-01-22 03:41:53 -08008435
8436class TestNAT66(MethodHolder):
8437 """ NAT66 Test Cases """
8438
8439 @classmethod
8440 def setUpClass(cls):
8441 super(TestNAT66, cls).setUpClass()
8442
8443 try:
8444 cls.nat_addr = 'fd01:ff::2'
8445 cls.nat_addr_n = socket.inet_pton(socket.AF_INET6, cls.nat_addr)
8446
8447 cls.create_pg_interfaces(range(2))
8448 cls.interfaces = list(cls.pg_interfaces)
8449
8450 for i in cls.interfaces:
8451 i.admin_up()
8452 i.config_ip6()
8453 i.configure_ipv6_neighbors()
8454
8455 except Exception:
8456 super(TestNAT66, cls).tearDownClass()
8457 raise
8458
8459 def test_static(self):
8460 """ 1:1 NAT66 test """
8461 self.vapi.nat66_add_del_interface(self.pg0.sw_if_index)
8462 self.vapi.nat66_add_del_interface(self.pg1.sw_if_index, is_inside=0)
8463 self.vapi.nat66_add_del_static_mapping(self.pg0.remote_ip6n,
8464 self.nat_addr_n)
8465
8466 # in2out
8467 pkts = []
8468 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8469 IPv6(src=self.pg0.remote_ip6, dst=self.pg1.remote_ip6) /
8470 TCP())
8471 pkts.append(p)
8472 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8473 IPv6(src=self.pg0.remote_ip6, dst=self.pg1.remote_ip6) /
8474 UDP())
8475 pkts.append(p)
8476 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8477 IPv6(src=self.pg0.remote_ip6, dst=self.pg1.remote_ip6) /
8478 ICMPv6EchoRequest())
8479 pkts.append(p)
8480 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8481 IPv6(src=self.pg0.remote_ip6, dst=self.pg1.remote_ip6) /
8482 GRE() / IP() / TCP())
8483 pkts.append(p)
8484 self.pg0.add_stream(pkts)
8485 self.pg_enable_capture(self.pg_interfaces)
8486 self.pg_start()
8487 capture = self.pg1.get_capture(len(pkts))
8488 for packet in capture:
8489 try:
8490 self.assertEqual(packet[IPv6].src, self.nat_addr)
8491 self.assertEqual(packet[IPv6].dst, self.pg1.remote_ip6)
Klement Sekerad81ae412018-05-16 10:52:54 +02008492 self.assert_packet_checksums_valid(packet)
Matus Fabianf2a23cc2018-01-22 03:41:53 -08008493 except:
8494 self.logger.error(ppp("Unexpected or invalid packet:", packet))
8495 raise
8496
8497 # out2in
8498 pkts = []
8499 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
8500 IPv6(src=self.pg1.remote_ip6, dst=self.nat_addr) /
8501 TCP())
8502 pkts.append(p)
8503 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
8504 IPv6(src=self.pg1.remote_ip6, dst=self.nat_addr) /
8505 UDP())
8506 pkts.append(p)
8507 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
8508 IPv6(src=self.pg1.remote_ip6, dst=self.nat_addr) /
8509 ICMPv6EchoReply())
8510 pkts.append(p)
8511 p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
8512 IPv6(src=self.pg1.remote_ip6, dst=self.nat_addr) /
8513 GRE() / IP() / TCP())
8514 pkts.append(p)
8515 self.pg1.add_stream(pkts)
8516 self.pg_enable_capture(self.pg_interfaces)
8517 self.pg_start()
8518 capture = self.pg0.get_capture(len(pkts))
8519 for packet in capture:
8520 try:
8521 self.assertEqual(packet[IPv6].src, self.pg1.remote_ip6)
8522 self.assertEqual(packet[IPv6].dst, self.pg0.remote_ip6)
Klement Sekerad81ae412018-05-16 10:52:54 +02008523 self.assert_packet_checksums_valid(packet)
Matus Fabianf2a23cc2018-01-22 03:41:53 -08008524 except:
8525 self.logger.error(ppp("Unexpected or invalid packet:", packet))
8526 raise
8527
8528 sm = self.vapi.nat66_static_mapping_dump()
8529 self.assertEqual(len(sm), 1)
8530 self.assertEqual(sm[0].total_pkts, 8)
8531
Juraj Sloboda9341e342018-04-13 12:00:46 +02008532 def test_check_no_translate(self):
8533 """ NAT66 translate only when egress interface is outside interface """
8534 self.vapi.nat66_add_del_interface(self.pg0.sw_if_index)
8535 self.vapi.nat66_add_del_interface(self.pg1.sw_if_index)
8536 self.vapi.nat66_add_del_static_mapping(self.pg0.remote_ip6n,
8537 self.nat_addr_n)
8538
8539 # in2out
8540 p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
8541 IPv6(src=self.pg0.remote_ip6, dst=self.pg1.remote_ip6) /
8542 UDP())
8543 self.pg0.add_stream([p])
8544 self.pg_enable_capture(self.pg_interfaces)
8545 self.pg_start()
8546 capture = self.pg1.get_capture(1)
8547 packet = capture[0]
8548 try:
8549 self.assertEqual(packet[IPv6].src, self.pg0.remote_ip6)
8550 self.assertEqual(packet[IPv6].dst, self.pg1.remote_ip6)
8551 except:
8552 self.logger.error(ppp("Unexpected or invalid packet:", packet))
8553 raise
8554
Matus Fabianf2a23cc2018-01-22 03:41:53 -08008555 def clear_nat66(self):
8556 """
8557 Clear NAT66 configuration.
8558 """
8559 interfaces = self.vapi.nat66_interface_dump()
8560 for intf in interfaces:
8561 self.vapi.nat66_add_del_interface(intf.sw_if_index,
8562 intf.is_inside,
8563 is_add=0)
8564
8565 static_mappings = self.vapi.nat66_static_mapping_dump()
8566 for sm in static_mappings:
8567 self.vapi.nat66_add_del_static_mapping(sm.local_ip_address,
8568 sm.external_ip_address,
8569 sm.vrf_id,
8570 is_add=0)
8571
8572 def tearDown(self):
8573 super(TestNAT66, self).tearDown()
8574 if not self.vpp_dead:
8575 self.logger.info(self.vapi.cli("show nat66 interfaces"))
8576 self.logger.info(self.vapi.cli("show nat66 static mappings"))
8577 self.clear_nat66()
8578
Klement Sekerad81ae412018-05-16 10:52:54 +02008579
Matus Fabiande886752016-12-07 03:38:19 -08008580if __name__ == '__main__':
8581 unittest.main(testRunner=VppTestRunner)