IPSEC: tunnel fragmentation
Change-Id: I63741a22bc82f5f861e1c0f26a93b5569cc52061 Signed-off-by: Neale Ranns <nranns@cisco.com>
This commit is contained in:
committed by
Damjan Marion
parent
74b7437bd1
commit
d7603d97e0
@@ -563,6 +563,11 @@ VLIB_REGISTER_NODE (esp4_encrypt_tun_node) = {
|
||||
|
||||
.n_errors = ARRAY_LEN(esp_encrypt_error_strings),
|
||||
.error_strings = esp_encrypt_error_strings,
|
||||
|
||||
.n_next_nodes = 1,
|
||||
.next_nodes = {
|
||||
[ESP_ENCRYPT_NEXT_DROP] = "ip4-drop",
|
||||
},
|
||||
};
|
||||
|
||||
VNET_FEATURE_INIT (esp4_encrypt_tun_feat_node, static) =
|
||||
@@ -590,6 +595,11 @@ VLIB_REGISTER_NODE (esp6_encrypt_tun_node) = {
|
||||
|
||||
.n_errors = ARRAY_LEN(esp_encrypt_error_strings),
|
||||
.error_strings = esp_encrypt_error_strings,
|
||||
|
||||
.n_next_nodes = 1,
|
||||
.next_nodes = {
|
||||
[ESP_ENCRYPT_NEXT_DROP] = "ip6-drop",
|
||||
},
|
||||
};
|
||||
|
||||
VNET_FEATURE_INIT (esp6_encrypt_tun_feat_node, static) =
|
||||
|
||||
@@ -352,6 +352,9 @@ ipsec_add_del_tunnel_if_internal (vnet_main_t * vnm,
|
||||
t->hw_if_index = hw_if_index;
|
||||
t->sw_if_index = hi->sw_if_index;
|
||||
|
||||
/* Standard default jumbo MTU. */
|
||||
vnet_sw_interface_set_mtu (vnm, t->sw_if_index, 9000);
|
||||
|
||||
/* Add the new tunnel to the DB of tunnels per sw_if_index ... */
|
||||
vec_validate_init_empty (im->ipsec_if_by_sw_if_index, t->sw_if_index,
|
||||
~0);
|
||||
|
||||
+4
-2
@@ -1017,9 +1017,11 @@ class VppTestCase(unittest.TestCase):
|
||||
i.assert_nothing_captured(remark=remark)
|
||||
timeout = 0.1
|
||||
|
||||
def send_and_expect(self, intf, pkts, output):
|
||||
def send_and_expect(self, intf, pkts, output, n_rx=None):
|
||||
if not n_rx:
|
||||
n_rx = len(pkts)
|
||||
self.pg_send(intf, pkts)
|
||||
rx = output.get_capture(len(pkts))
|
||||
rx = output.get_capture(n_rx)
|
||||
return rx
|
||||
|
||||
def send_and_expect_only(self, intf, pkts, output, timeout=None):
|
||||
|
||||
+25
-15
@@ -7,7 +7,7 @@ from scapy.layers.l2 import Ether, Raw
|
||||
from scapy.layers.inet6 import IPv6, ICMPv6EchoRequest
|
||||
|
||||
from framework import VppTestCase, VppTestRunner
|
||||
from util import ppp
|
||||
from util import ppp, reassemble4
|
||||
from vpp_papi import VppEnum
|
||||
|
||||
|
||||
@@ -161,8 +161,6 @@ class TemplateIpsec(VppTestCase):
|
||||
super(TemplateIpsec, self).setUp()
|
||||
|
||||
self.setup_params()
|
||||
self.payload = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"\
|
||||
"XXXXXXXXXXXXXXXXXXXXX"
|
||||
|
||||
self.tun_spd_id = 1
|
||||
self.tra_spd_id = 2
|
||||
@@ -193,26 +191,30 @@ class TemplateIpsec(VppTestCase):
|
||||
if not self.vpp_dead:
|
||||
self.vapi.cli("show hardware")
|
||||
|
||||
def gen_encrypt_pkts(self, sa, sw_intf, src, dst, count=1):
|
||||
def gen_encrypt_pkts(self, sa, sw_intf, src, dst, count=1,
|
||||
payload_size=54):
|
||||
return [Ether(src=sw_intf.remote_mac, dst=sw_intf.local_mac) /
|
||||
sa.encrypt(IP(src=src, dst=dst) / ICMP() / self.payload)
|
||||
sa.encrypt(IP(src=src, dst=dst) /
|
||||
ICMP() / Raw('X' * payload_size))
|
||||
for i in range(count)]
|
||||
|
||||
def gen_encrypt_pkts6(self, sa, sw_intf, src, dst, count=1):
|
||||
def gen_encrypt_pkts6(self, sa, sw_intf, src, dst, count=1,
|
||||
payload_size=54):
|
||||
return [Ether(src=sw_intf.remote_mac, dst=sw_intf.local_mac) /
|
||||
sa.encrypt(IPv6(src=src, dst=dst) /
|
||||
ICMPv6EchoRequest(id=0, seq=1, data=self.payload))
|
||||
ICMPv6EchoRequest(id=0, seq=1,
|
||||
data='X' * payload_size))
|
||||
for i in range(count)]
|
||||
|
||||
def gen_pkts(self, sw_intf, src, dst, count=1):
|
||||
def gen_pkts(self, sw_intf, src, dst, count=1, payload_size=54):
|
||||
return [Ether(src=sw_intf.remote_mac, dst=sw_intf.local_mac) /
|
||||
IP(src=src, dst=dst) / ICMP() / self.payload
|
||||
IP(src=src, dst=dst) / ICMP() / Raw('X' * payload_size)
|
||||
for i in range(count)]
|
||||
|
||||
def gen_pkts6(self, sw_intf, src, dst, count=1):
|
||||
def gen_pkts6(self, sw_intf, src, dst, count=1, payload_size=54):
|
||||
return [Ether(src=sw_intf.remote_mac, dst=sw_intf.local_mac) /
|
||||
IPv6(src=src, dst=dst) /
|
||||
ICMPv6EchoRequest(id=0, seq=1, data=self.payload)
|
||||
ICMPv6EchoRequest(id=0, seq=1, data='X' * payload_size)
|
||||
for i in range(count)]
|
||||
|
||||
|
||||
@@ -470,8 +472,10 @@ class IpsecTun4(object):
|
||||
self.assert_packet_counter_equal(self.tun4_encrypt_node_name, count)
|
||||
self.assert_packet_counter_equal(self.tun4_decrypt_node_name, count)
|
||||
|
||||
def verify_tun_44(self, p, count=1):
|
||||
def verify_tun_44(self, p, count=1, payload_size=64, n_rx=None):
|
||||
self.vapi.cli("clear errors")
|
||||
if not n_rx:
|
||||
n_rx = count
|
||||
try:
|
||||
config_tun_params(p, self.encryption_type, self.tun_if)
|
||||
send_pkts = self.gen_encrypt_pkts(p.scapy_tun_sa, self.tun_if,
|
||||
@@ -484,16 +488,19 @@ class IpsecTun4(object):
|
||||
self.assert_equal(recv_pkt[IP].dst, self.pg1.remote_ip4)
|
||||
self.assert_packet_checksums_valid(recv_pkt)
|
||||
send_pkts = self.gen_pkts(self.pg1, src=self.pg1.remote_ip4,
|
||||
dst=p.remote_tun_if_host, count=count)
|
||||
recv_pkts = self.send_and_expect(self.pg1, send_pkts, self.tun_if)
|
||||
dst=p.remote_tun_if_host, count=count,
|
||||
payload_size=payload_size)
|
||||
recv_pkts = self.send_and_expect(self.pg1, send_pkts,
|
||||
self.tun_if, n_rx)
|
||||
decrypt_pkts = []
|
||||
for recv_pkt in recv_pkts:
|
||||
try:
|
||||
decrypt_pkt = p.vpp_tun_sa.decrypt(recv_pkt[IP])
|
||||
if not decrypt_pkt.haslayer(IP):
|
||||
decrypt_pkt = IP(decrypt_pkt[Raw].load)
|
||||
decrypt_pkts.append(decrypt_pkt)
|
||||
self.assert_equal(decrypt_pkt.src, self.pg1.remote_ip4)
|
||||
self.assert_equal(decrypt_pkt.dst, p.remote_tun_if_host)
|
||||
self.assert_packet_checksums_valid(decrypt_pkt)
|
||||
except:
|
||||
self.logger.debug(ppp("Unexpected packet:", recv_pkt))
|
||||
try:
|
||||
@@ -502,6 +509,9 @@ class IpsecTun4(object):
|
||||
except:
|
||||
pass
|
||||
raise
|
||||
pkts = reassemble4(decrypt_pkts)
|
||||
for pkt in pkts:
|
||||
self.assert_packet_checksums_valid(pkt)
|
||||
finally:
|
||||
self.logger.info(self.vapi.ppcli("show error"))
|
||||
self.logger.info(self.vapi.ppcli("show ipsec"))
|
||||
|
||||
@@ -20,21 +20,22 @@ class TemplateIpsec4TunIfEsp(TemplateIpsec):
|
||||
self.tun_if = self.pg0
|
||||
|
||||
p = self.ipv4_params
|
||||
tun_if = VppIpsecTunInterface(self, self.pg0, p.vpp_tun_spi,
|
||||
p.scapy_tun_spi, p.crypt_algo_vpp_id,
|
||||
p.crypt_key, p.crypt_key,
|
||||
p.auth_algo_vpp_id, p.auth_key,
|
||||
p.auth_key)
|
||||
tun_if.add_vpp_config()
|
||||
tun_if.admin_up()
|
||||
tun_if.config_ip4()
|
||||
tun_if.config_ip6()
|
||||
|
||||
p.tun_if = VppIpsecTunInterface(self, self.pg0, p.vpp_tun_spi,
|
||||
p.scapy_tun_spi, p.crypt_algo_vpp_id,
|
||||
p.crypt_key, p.crypt_key,
|
||||
p.auth_algo_vpp_id, p.auth_key,
|
||||
p.auth_key)
|
||||
p.tun_if.add_vpp_config()
|
||||
p.tun_if.admin_up()
|
||||
p.tun_if.config_ip4()
|
||||
p.tun_if.config_ip6()
|
||||
|
||||
VppIpRoute(self, p.remote_tun_if_host, 32,
|
||||
[VppRoutePath(tun_if.remote_ip4,
|
||||
[VppRoutePath(p.tun_if.remote_ip4,
|
||||
0xffffffff)]).add_vpp_config()
|
||||
VppIpRoute(self, p.remote_tun_if_host6, 128,
|
||||
[VppRoutePath(tun_if.remote_ip6,
|
||||
[VppRoutePath(p.tun_if.remote_ip6,
|
||||
0xffffffff,
|
||||
proto=DpoProto.DPO_PROTO_IP6)],
|
||||
is_ip6=1).add_vpp_config()
|
||||
@@ -58,6 +59,17 @@ class TestIpsec4TunIfEsp1(TemplateIpsec4TunIfEsp, IpsecTun4Tests):
|
||||
""" ipsec 6o4 tunnel basic test """
|
||||
self.verify_tun_64(self.params[socket.AF_INET], count=257)
|
||||
|
||||
def test_tun_basic_frag44(self):
|
||||
""" ipsec 4o4 tunnel frag basic test """
|
||||
p = self.ipv4_params
|
||||
|
||||
self.vapi.sw_interface_set_mtu(p.tun_if.sw_if_index,
|
||||
[1500, 0, 0, 0])
|
||||
self.verify_tun_44(self.params[socket.AF_INET],
|
||||
count=1, payload_size=1800, n_rx=2)
|
||||
self.vapi.sw_interface_set_mtu(p.tun_if.sw_if_index,
|
||||
[9000, 0, 0, 0])
|
||||
|
||||
|
||||
class TestIpsec4TunIfEsp2(TemplateIpsec4TunIfEsp, IpsecTcpTests):
|
||||
""" Ipsec ESP - TCP tests """
|
||||
|
||||
Reference in New Issue
Block a user