From 3fb3e512bc90714907a520fb4a7ef84582bce6a7 Mon Sep 17 00:00:00 2001
Message-Id: <3fb3e512bc90714907a520fb4a7ef84582bce6a7.1578588395.git.lorenzo.bianconi@redhat.com>
In-Reply-To: <600a018ea1136e184b421c86da170b35d05e949f.1578588395.git.lorenzo.bianconi@redhat.com>
References: <600a018ea1136e184b421c86da170b35d05e949f.1578588395.git.lorenzo.bianconi@redhat.com>
From: Lorenzo Bianconi <lorenzo.bianconi@redhat.com>
Date: Tue, 7 Jan 2020 17:50:06 +0100
Subject: [PATCH 3/3] RA Route Info Option: copy route info string in order to
avoid truncated value
ipv6_ra_send can run 2 times in a row before prepare_ipv6_ras updates
the route info. Copy route info string in packet_put_ra_route_info_opt
in order to avoid sending truncated route info on the wire.
Moreover move ip6_hdr definition just before accessing it because the
packet can be reallocated if the data area is not big enough for packet
content
Fixes: 9f7f466af ("Add support for Route Info Option in RA - RFC 4191")
Signed-off-by: Lorenzo Bianconi <lorenzo.bianconi@redhat.com>
Signed-off-by: Numan Siddique <numans@ovn.org>
---
ovn/controller/pinctrl.c | 18 +++++++++++-------
1 file changed, 11 insertions(+), 7 deletions(-)
--- a/ovn/controller/pinctrl.c
+++ b/ovn/controller/pinctrl.c
@@ -2473,13 +2473,14 @@ out:
static void
packet_put_ra_route_info_opt(struct dp_packet *b, ovs_be32 lifetime,
- char *route_list)
+ char *route_data)
{
size_t prev_l4_size = dp_packet_l4_size(b);
- struct ip6_hdr *nh = dp_packet_l3(b);
- char *t0, *r0 = NULL;
+ char *route_list, *t0, *r0 = NULL;
size_t size = 0;
+ route_list = xstrdup(route_data);
+
for (t0 = strtok_r(route_list, ",", &r0); t0;
t0 = strtok_r(NULL, ",", &r0)) {
struct ovs_nd_route_info nd_rinfo;
@@ -2507,11 +2508,11 @@ packet_put_ra_route_info_opt(struct dp_p
uint8_t plen;
if (!extract_ip_addresses(t1, &route)) {
- return;
+ goto out;
}
if (!route.n_ipv6_addrs) {
destroy_lport_addresses(&route);
- return;
+ goto out;
}
nd_rinfo.prefix_len = route.ipv6_addrs->plen;
@@ -2526,17 +2527,20 @@ packet_put_ra_route_info_opt(struct dp_p
break;
}
default:
- return;
+ goto out;
}
}
}
+ struct ip6_hdr *nh = dp_packet_l3(b);
nh->ip6_plen = htons(prev_l4_size + size);
struct ovs_ra_msg *ra = dp_packet_l4(b);
ra->icmph.icmp6_cksum = 0;
uint32_t icmp_csum = packet_csum_pseudoheader6(dp_packet_l3(b));
ra->icmph.icmp6_cksum = csum_finish(csum_continue(icmp_csum, ra,
prev_l4_size + size));
+out:
+ free(route_list);
}
/* Called with in the pinctrl_handler thread context. */
@@ -2580,7 +2584,7 @@ ipv6_ra_send(struct rconn *swconn, struc
}
if (ra->config->route_info.length) {
packet_put_ra_route_info_opt(&packet, htonl(0xffffffff),
- ra->config->route_info.string);
+ ds_cstr(&ra->config->route_info));
}
uint64_t ofpacts_stub[4096 / 8];