aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/plugins/map/ip4_map_t.c12
-rw-r--r--src/plugins/map/test/test_map_br.py45
2 files changed, 51 insertions, 6 deletions
diff --git a/src/plugins/map/ip4_map_t.c b/src/plugins/map/ip4_map_t.c
index 4c0dd629aa8..7d16d7aa455 100644
--- a/src/plugins/map/ip4_map_t.c
+++ b/src/plugins/map/ip4_map_t.c
@@ -92,14 +92,18 @@ ip4_to_ip6_set_inner_icmp_cb (vlib_buffer_t * b, ip4_header_t * ip4,
ip6_header_t * ip6, void *arg)
{
icmp_to_icmp6_ctx_t *ctx = arg;
+ ip4_address_t old_src, old_dst;
+
+ old_src.as_u32 = ip4->src_address.as_u32;
+ old_dst.as_u32 = ip4->dst_address.as_u32;
//Note that the source address is within the domain
//while the destination address is the one outside the domain
- ip4_map_t_embedded_address (ctx->d, &ip6->dst_address, &ip4->dst_address);
+ ip4_map_t_embedded_address (ctx->d, &ip6->dst_address, &old_dst);
ip6->src_address.as_u64[0] =
- map_get_pfx_net (ctx->d, ip4->src_address.as_u32, ctx->recv_port);
+ map_get_pfx_net (ctx->d, old_src.as_u32, ctx->recv_port);
ip6->src_address.as_u64[1] =
- map_get_sfx_net (ctx->d, ip4->src_address.as_u32, ctx->recv_port);
+ map_get_sfx_net (ctx->d, old_src.as_u32, ctx->recv_port);
return 0;
}
@@ -150,7 +154,7 @@ ip4_map_t_icmp (vlib_main_t * vm,
vnet_buffer (p0)->map_t.map_domain_index);
ip40 = vlib_buffer_get_current (p0);
- ctx0.recv_port = ip4_get_port (ip40, 1);
+ ctx0.recv_port = ip4_get_port (ip40, 0);
ctx0.d = d0;
if (ctx0.recv_port == 0)
{
diff --git a/src/plugins/map/test/test_map_br.py b/src/plugins/map/test/test_map_br.py
index db0a5fc00e3..631517e5d4e 100644
--- a/src/plugins/map/test/test_map_br.py
+++ b/src/plugins/map/test/test_map_br.py
@@ -11,9 +11,9 @@ from util import fragment_rfc791, fragment_rfc8200
import scapy.compat
from scapy.layers.l2 import Ether
from scapy.packet import Raw
-from scapy.layers.inet import IP, UDP, ICMP, TCP
+from scapy.layers.inet import IP, UDP, ICMP, TCP, IPerror, UDPerror
from scapy.layers.inet6 import IPv6, ICMPv6TimeExceeded, IPv6ExtHdrFragment
-from scapy.layers.inet6 import ICMPv6EchoRequest, ICMPv6EchoReply
+from scapy.layers.inet6 import ICMPv6EchoRequest, ICMPv6EchoReply, IPerror6
class TestMAPBR(VppTestCase):
@@ -333,6 +333,47 @@ class TestMAPBR(VppTestCase):
self.ipv6_udp_or_tcp_map_port)
#
+ # Translation of ICMP Time Exceeded v4 -> v6 direction
+ # Received packet should be translated into an IPv6 Time Exceeded.
+ #
+
+ def test_map_t_time_exceeded_ip4_to_ip6(self):
+ """ MAP-T time exceeded IPv4 -> IPv6 """
+
+ eth = Ether(src=self.pg0.remote_mac,
+ dst=self.pg0.local_mac)
+ ip = IP(src=self.pg0.remote_ip4,
+ dst=self.ipv4_map_address)
+ icmp = ICMP(type="time-exceeded", code="ttl-zero-during-transit")
+ ip_inner = IP(dst=self.pg0.remote_ip4,
+ src=self.ipv4_map_address, ttl=1)
+ udp_inner = UDP(sport=self.ipv4_udp_or_tcp_map_port,
+ dport=self.ipv4_udp_or_tcp_internet_port)
+ payload = "H" * 10
+ tx_pkt = eth / ip / icmp / ip_inner / udp_inner / payload
+
+ self.pg_send(self.pg0, tx_pkt * 1)
+
+ rx_pkts = self.pg1.get_capture(1)
+ rx_pkt = rx_pkts[0]
+
+ self.v6_address_check(rx_pkt)
+ self.assertEqual(rx_pkt[IPv6].nh, IPv6(nh="ICMPv6").nh)
+ self.assertEqual(rx_pkt[ICMPv6TimeExceeded].type,
+ ICMPv6TimeExceeded().type)
+ self.assertEqual(rx_pkt[ICMPv6TimeExceeded].code,
+ ICMPv6TimeExceeded(
+ code="hop limit exceeded in transit").code)
+ self.assertEqual(rx_pkt[ICMPv6TimeExceeded].hlim, tx_pkt[IP][1].ttl)
+ self.assertTrue(rx_pkt.haslayer(IPerror6))
+ self.assertTrue(rx_pkt.haslayer(UDPerror))
+ self.assertEqual(rx_pkt[IPv6].src, rx_pkt[IPerror6].dst)
+ self.assertEqual(rx_pkt[IPv6].dst, rx_pkt[IPerror6].src)
+ self.assertEqual(rx_pkt[UDPerror].sport, self.ipv6_udp_or_tcp_map_port)
+ self.assertEqual(rx_pkt[UDPerror].dport,
+ self.ipv6_udp_or_tcp_internet_port)
+
+ #
# Translation of ICMP Echo Request v6 -> v4 direction
# Received packet should be translated into an IPv4 Echo Request.
#