From 942f7b2b9e3acfc7b1d6ea5c48fc22171b14549a Mon Sep 17 00:00:00 2001 Message-Id: <942f7b2b9e3acfc7b1d6ea5c48fc22171b14549a.1588586761.git.lorenzo.bianconi@redhat.com> From: Lorenzo Bianconi Date: Thu, 23 Apr 2020 18:25:20 +0200 Subject: [PATCH] IPv6 PD: time parameter checks RFC3633 imposes the following constraints for IPv6 pd time parameters: Identity Association for Prefix Delegation Option: -------------------------------------------------- t1 must not be greater than t2 if both of them are greater than 0 IA_PD Prefix option: -------------------- preferred lifetime must not be greater than valid lifetime Add checks for previous constraints in ovn implementation Signed-off-by: Lorenzo Bianconi Signed-off-by: Numan Siddique --- controller/pinctrl.c | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) --- a/controller/pinctrl.c +++ b/controller/pinctrl.c @@ -653,6 +653,11 @@ pinctrl_parse_dhcpv6_advt(struct rconn * case DHCPV6_OPT_IA_PD: { struct dhcpv6_opt_ia_na *ia_na = (struct dhcpv6_opt_ia_na *)in_opt; int orig_len = len, hdr_len = 0, size = sizeof *in_opt + 12; + uint32_t t1 = ntohl(ia_na->t1), t2 = ntohl(ia_na->t2); + + if (t1 > t2 && t2 > 0) { + goto out; + } aid = ntohl(ia_na->iaid); memcpy(&data[len], in_opt, size); @@ -667,6 +672,15 @@ pinctrl_parse_dhcpv6_advt(struct rconn * } if (ntohs(in_opt->code) == DHCPV6_OPT_IA_PREFIX) { + struct dhcpv6_opt_ia_prefix *ia_hdr = + (struct dhcpv6_opt_ia_prefix *)in_opt; + uint32_t plife_time = ntohl(ia_hdr->plife_time); + uint32_t vlife_time = ntohl(ia_hdr->vlife_time); + + if (plife_time > vlife_time) { + goto out; + } + memcpy(&data[len], in_opt, flen); hdr_len += flen; len += flen; @@ -831,9 +845,12 @@ pinctrl_parse_dhcpv6_reply(struct dp_pac struct dhcpv6_opt_ia_prefix *ia_hdr = (struct dhcpv6_opt_ia_prefix *)(in_dhcpv6_data + size); - prefix_len = ia_hdr->plen; plife_time = ntohl(ia_hdr->plife_time); vlife_time = ntohl(ia_hdr->vlife_time); + if (plife_time > vlife_time) { + break; + } + prefix_len = ia_hdr->plen; memcpy(&ipv6, &ia_hdr->ipv6, sizeof (struct in6_addr)); status = true; }