diff mbox series

[ovs-dev,v2,ovn,2/2] RA Route Info Option: copy route info string in order to avoid truncated value

Message ID 8bc6b374e3a80fcac7a8a92951ae629ad6879d49.1578414443.git.lorenzo.bianconi@redhat.com
State Accepted
Headers show
Series fix DNSSL and Route Info Option in RA | expand

Commit Message

Lorenzo Bianconi Jan. 7, 2020, 4:50 p.m. UTC
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>
---
 controller/pinctrl.c | 18 +++++++++++-------
 1 file changed, 11 insertions(+), 7 deletions(-)
diff mbox series

Patch

diff --git a/controller/pinctrl.c b/controller/pinctrl.c
index 1a577f62a..c4752c673 100644
--- a/controller/pinctrl.c
+++ b/controller/pinctrl.c
@@ -2469,13 +2469,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;
@@ -2503,11 +2504,11 @@  packet_put_ra_route_info_opt(struct dp_packet *b, ovs_be32 lifetime,
                 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;
@@ -2522,17 +2523,20 @@  packet_put_ra_route_info_opt(struct dp_packet *b, ovs_be32 lifetime,
                 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. */
@@ -2576,7 +2580,7 @@  ipv6_ra_send(struct rconn *swconn, struct ipv6_ra_state *ra)
     }
     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];