From 1404698df397bc4d3007daea41f52ad75ed4486c Mon Sep 17 00:00:00 2001 From: Neale Ranns Date: Mon, 29 Jul 2019 14:49:52 +0000 Subject: [PATCH] ip: Ensure reassembly runs before IPSec decrypt. Type: fix Change-Id: I01eeedf8d5015b07b9422c65afe78bfe8177c22c Signed-off-by: Neale Ranns --- src/vnet/ip/ip4_reassembly.c | 4 ++- src/vnet/ip/ip6_reassembly.c | 4 ++- test/template_ipsec.py | 72 +++++++++++++++++++++++++++++++++++++++++++- test/util.py | 9 ++++-- 4 files changed, 84 insertions(+), 5 deletions(-) diff --git a/src/vnet/ip/ip4_reassembly.c b/src/vnet/ip/ip4_reassembly.c index b894c3b83fe..493f06fd43b 100644 --- a/src/vnet/ip/ip4_reassembly.c +++ b/src/vnet/ip/ip4_reassembly.c @@ -1202,7 +1202,9 @@ VLIB_REGISTER_NODE (ip4_reass_node_feature) = { VNET_FEATURE_INIT (ip4_reassembly_feature, static) = { .arc_name = "ip4-unicast", .node_name = "ip4-reassembly-feature", - .runs_before = VNET_FEATURES ("ip4-lookup"), + .runs_before = VNET_FEATURES ("ip4-lookup", + "esp4-decrypt", + "ah4-decrypt"), .runs_after = 0, }; /* *INDENT-ON* */ diff --git a/src/vnet/ip/ip6_reassembly.c b/src/vnet/ip/ip6_reassembly.c index 7b0d84de289..8d455e90e38 100644 --- a/src/vnet/ip/ip6_reassembly.c +++ b/src/vnet/ip/ip6_reassembly.c @@ -1181,7 +1181,9 @@ VLIB_REGISTER_NODE (ip6_reass_node_feature) = { VNET_FEATURE_INIT (ip6_reassembly_feature, static) = { .arc_name = "ip6-unicast", .node_name = "ip6-reassembly-feature", - .runs_before = VNET_FEATURES ("ip6-lookup"), + .runs_before = VNET_FEATURES ("ip6-lookup", + "esp6-decrypt", + "ah6-decrypt"), .runs_after = 0, }; /* *INDENT-ON* */ diff --git a/test/template_ipsec.py b/test/template_ipsec.py index 25cff7f2edf..773531fe038 100644 --- a/test/template_ipsec.py +++ b/test/template_ipsec.py @@ -8,7 +8,7 @@ from scapy.layers.l2 import Ether, Raw from scapy.layers.inet6 import IPv6, ICMPv6EchoRequest from framework import VppTestCase, VppTestRunner -from util import ppp, reassemble4 +from util import ppp, reassemble4, fragment_rfc791, fragment_rfc8200 from vpp_papi import VppEnum @@ -724,6 +724,37 @@ class IpsecTun4(object): self.verify_counters4(p, count, n_rx) + def verify_tun_reass_44(self, p): + self.vapi.cli("clear errors") + self.vapi.ip_reassembly_enable_disable( + sw_if_index=self.tun_if.sw_if_index, enable_ip4=True) + + try: + config_tun_params(p, self.encryption_type, self.tun_if) + send_pkts = self.gen_encrypt_pkts(p.scapy_tun_sa, self.tun_if, + src=p.remote_tun_if_host, + dst=self.pg1.remote_ip4, + payload_size=1900, + count=1) + send_pkts = fragment_rfc791(send_pkts[0], 1400) + recv_pkts = self.send_and_expect(self.tun_if, send_pkts, + self.pg1, n_rx=1) + self.verify_decrypted(p, recv_pkts) + + send_pkts = self.gen_pkts(self.pg1, src=self.pg1.remote_ip4, + dst=p.remote_tun_if_host, count=1) + recv_pkts = self.send_and_expect(self.pg1, send_pkts, + self.tun_if) + self.verify_encrypted(p, p.vpp_tun_sa, recv_pkts) + + finally: + self.logger.info(self.vapi.ppcli("show error")) + self.logger.info(self.vapi.ppcli("show ipsec all")) + + self.verify_counters4(p, 1, 1) + self.vapi.ip_reassembly_enable_disable( + sw_if_index=self.tun_if.sw_if_index, enable_ip4=False) + def verify_tun_64(self, p, count=1): self.vapi.cli("clear errors") try: @@ -786,6 +817,10 @@ class IpsecTun4Tests(IpsecTun4): """ ipsec 4o4 tunnel basic test """ self.verify_tun_44(self.params[socket.AF_INET], count=1) + def test_tun_reass_basic44(self): + """ ipsec 4o4 tunnel basic reassembly test """ + self.verify_tun_reass_44(self.params[socket.AF_INET]) + def test_tun_burst44(self): """ ipsec 4o4 tunnel burst test """ self.verify_tun_44(self.params[socket.AF_INET], count=257) @@ -873,6 +908,37 @@ class IpsecTun6(object): self.logger.info(self.vapi.ppcli("show ipsec all")) self.verify_counters6(p_in, p_out, count) + def verify_tun_reass_66(self, p): + self.vapi.cli("clear errors") + self.vapi.ip_reassembly_enable_disable( + sw_if_index=self.tun_if.sw_if_index, enable_ip6=True) + + try: + config_tun_params(p, self.encryption_type, self.tun_if) + send_pkts = self.gen_encrypt_pkts6(p.scapy_tun_sa, self.tun_if, + src=p.remote_tun_if_host, + dst=self.pg1.remote_ip6, + count=1, + payload_size=1900) + send_pkts = fragment_rfc8200(send_pkts[0], 1, 1400, self.logger) + recv_pkts = self.send_and_expect(self.tun_if, send_pkts, + self.pg1, n_rx=1) + self.verify_decrypted6(p, recv_pkts) + + send_pkts = self.gen_pkts6(self.pg1, src=self.pg1.remote_ip6, + dst=p.remote_tun_if_host, + count=1, + payload_size=64) + recv_pkts = self.send_and_expect(self.pg1, send_pkts, + self.tun_if) + self.verify_encrypted6(p, p.vpp_tun_sa, recv_pkts) + finally: + self.logger.info(self.vapi.ppcli("show error")) + self.logger.info(self.vapi.ppcli("show ipsec all")) + self.verify_counters6(p, p, 1) + self.vapi.ip_reassembly_enable_disable( + sw_if_index=self.tun_if.sw_if_index, enable_ip6=False) + def verify_tun_46(self, p, count=1): """ ipsec 4o6 tunnel basic test """ self.vapi.cli("clear errors") @@ -920,6 +986,10 @@ class IpsecTun6Tests(IpsecTun6): """ ipsec 6o6 tunnel basic test """ self.verify_tun_66(self.params[socket.AF_INET6], count=1) + def test_tun_reass_basic66(self): + """ ipsec 6o6 tunnel basic reassembly test """ + self.verify_tun_reass_66(self.params[socket.AF_INET6]) + def test_tun_burst66(self): """ ipsec 6o6 tunnel burst test """ self.verify_tun_66(self.params[socket.AF_INET6], count=257) diff --git a/test/util.py b/test/util.py index d27b3fb25e6..96d3c6068ef 100644 --- a/test/util.py +++ b/test/util.py @@ -386,14 +386,19 @@ def fragment_rfc8200(packet, identification, fragsize, _logger=None): fragment_ext_hdr = IPv6ExtHdrFragment() logger.debug(ppp("Fragment header:", fragment_ext_hdr)) + len_ext_and_upper_layer_payload = len(ext_and_upper_layer.payload) + if not len_ext_and_upper_layer_payload and \ + hasattr(ext_and_upper_layer, "data"): + len_ext_and_upper_layer_payload = len(ext_and_upper_layer.data) + if len(per_fragment_headers) + len(fragment_ext_hdr) +\ - len(ext_and_upper_layer) - len(ext_and_upper_layer.payload)\ + len(ext_and_upper_layer) - len_ext_and_upper_layer_payload\ > fragsize: raise Exception("Cannot fragment this packet - MTU too small " "(%s, %s, %s, %s, %s)" % ( len(per_fragment_headers), len(fragment_ext_hdr), len(ext_and_upper_layer), - len(ext_and_upper_layer.payload), fragsize)) + len_ext_and_upper_layer_payload, fragsize)) orig_nh = packet[IPv6].nh p = per_fragment_headers -- 2.16.6