aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorVladimir Ratnikov <vratnikov@netgate.com>2020-01-14 09:48:31 -0500
committerOle Trøan <otroan@employees.org>2020-01-28 08:14:36 +0000
commit0d4a61216c2329eec5167d0411481431037ac5c1 (patch)
treee58415cb89d3603b03f67904d7b0467e6b185e16 /src
parente9595dba26b32abb673f74b777429ae5640dc325 (diff)
map: ip4-map-t more RFC compliant
When MTU is not set, ignore_df and mtu check always returns true and packets are dropped. This patch puts MTU checks after it was compared with 0 and set to maximum if not set. Added trace node. If MTU is less than the total length value of the IPv4 packet plus 20, the translator MUST send an ICMPv4 "Fragmentation Needed" error message to the IPv4 source address Type: fix Fixes: 87663cdf644fb7c94c0fec9460829b7e4e7c35ca Signed-off-by: Vladimir Ratnikov <vratnikov@netgate.com> Change-Id: I35b99bc2648984cdbf5b6a57ddec91c586b15bef
Diffstat (limited to 'src')
-rw-r--r--src/plugins/map/ip4_map_t.c28
1 files changed, 20 insertions, 8 deletions
diff --git a/src/plugins/map/ip4_map_t.c b/src/plugins/map/ip4_map_t.c
index dca32846480..d243a45cd41 100644
--- a/src/plugins/map/ip4_map_t.c
+++ b/src/plugins/map/ip4_map_t.c
@@ -22,6 +22,7 @@ typedef enum
IP4_MAPT_NEXT_MAPT_TCP_UDP,
IP4_MAPT_NEXT_MAPT_ICMP,
IP4_MAPT_NEXT_MAPT_FRAGMENTED,
+ IP4_MAPT_NEXT_ICMP_ERROR,
IP4_MAPT_NEXT_DROP,
IP4_MAPT_N_NEXT
} ip4_mapt_next_t;
@@ -575,21 +576,31 @@ ip4_map_t (vlib_main_t * vm, vlib_node_runtime_t * node, vlib_frame_t * frame)
goto exit;
}
+ dst_port0 = -1;
+
bool df0 =
ip40->flags_and_fragment_offset &
clib_host_to_net_u16 (IP4_HEADER_FLAG_DONT_FRAGMENT);
+ vnet_buffer (p0)->map_t.mtu = d0->mtu ? d0->mtu : ~0;
+
if (PREDICT_FALSE
- (df0 && !map_main.frag_ignore_df && (ip4_len0 > d0->mtu)))
+ (df0 && !map_main.frag_ignore_df
+ &&
+ ((ip4_len0 +
+ (sizeof (ip6_header_t) - sizeof (ip4_header_t))) >
+ vnet_buffer (p0)->map_t.mtu)))
{
- p0->error = error_node->errors[MAP_ERROR_FRAGMENT_DROPPED];
- next0 = IP4_MAPT_NEXT_DROP;
- goto exit;
+ icmp4_error_set_vnet_buffer (p0, ICMP4_destination_unreachable,
+ ICMP4_destination_unreachable_fragmentation_needed_and_dont_fragment_set,
+ vnet_buffer (p0)->map_t.mtu -
+ (sizeof (ip6_header_t) -
+ sizeof (ip4_header_t)));
+ p0->error = error_node->errors[MAP_ERROR_DF_SET];
+ next0 = IP4_MAPT_NEXT_ICMP_ERROR;
+ goto trace;
}
- vnet_buffer (p0)->map_t.mtu = d0->mtu ? d0->mtu : ~0;
-
- dst_port0 = -1;
ip4_map_t_classify (p0, d0, ip40, ip4_len0, &dst_port0, &error0,
&next0, l4_dst_port);
@@ -626,7 +637,7 @@ ip4_map_t (vlib_main_t * vm, vlib_node_runtime_t * node, vlib_frame_t * frame)
next0 = (error0 != MAP_ERROR_NONE) ? IP4_MAPT_NEXT_DROP : next0;
p0->error = error_node->errors[error0];
-
+ trace:
if (PREDICT_FALSE (p0->flags & VLIB_BUFFER_IS_TRACED))
{
map_add_trace (vm, node, p0, d0 - map_main.domains, dst_port0);
@@ -730,6 +741,7 @@ VLIB_REGISTER_NODE(ip4_map_t_node) = {
[IP4_MAPT_NEXT_MAPT_TCP_UDP] = "ip4-map-t-tcp-udp",
[IP4_MAPT_NEXT_MAPT_ICMP] = "ip4-map-t-icmp",
[IP4_MAPT_NEXT_MAPT_FRAGMENTED] = "ip4-map-t-fragmented",
+ [IP4_MAPT_NEXT_ICMP_ERROR] = "ip4-icmp-error",
[IP4_MAPT_NEXT_DROP] = "error-drop",
},
};