diff mbox series

[netifd] interface-ip: Normalise prefix address using netmask before using it

Message ID 20201125173536.1175-1-dxld@darkboxed.org
State Not Applicable
Headers show
Series [netifd] interface-ip: Normalise prefix address using netmask before using it | expand

Commit Message

Daniel Gröber Nov. 25, 2020, 5:35 p.m. UTC
When a proto registers a prefix with an address which has bits outside the
netmask set this confuses the prefix-assignment code further down the line.

For example if we have an interface with

    option ip6prefix fdff:ffff:ffff:ffff::1/48

and a couple with

    option ip6assign 64

then all these interfaces will be assigned fdff:ffff:ffff:ffff::1/64 which
is obviously wrong, they should at least have unique prefixes.

What is happening here is that we simply OR the calculated assignment part
into the address in interface_set_prefix_address:961, like so:

    addr.addr.in6.s6_addr32[1] |= htonl(assignment->assigned);

but we never masked the host address bits out of the address after parsing
it using inet_pton. To fix this we simply mask away the host bits in the
address before using it.

Signed-off-by: Daniel Gröber <dxld@darkboxed.org>
---
 interface-ip.c | 2 ++
 1 file changed, 2 insertions(+)

Comments

Hans Dedecker Nov. 25, 2020, 7:23 p.m. UTC | #1
Hi,

On Wed, Nov 25, 2020 at 6:36 PM Daniel Gröber <dxld@darkboxed.org> wrote:
>
> When a proto registers a prefix with an address which has bits outside the
> netmask set this confuses the prefix-assignment code further down the line.
>
> For example if we have an interface with
>
>     option ip6prefix fdff:ffff:ffff:ffff::1/48
>
> and a couple with
>
>     option ip6assign 64
>
> then all these interfaces will be assigned fdff:ffff:ffff:ffff::1/64 which
> is obviously wrong, they should at least have unique prefixes.
>
> What is happening here is that we simply OR the calculated assignment part
> into the address in interface_set_prefix_address:961, like so:
>
>     addr.addr.in6.s6_addr32[1] |= htonl(assignment->assigned);
>
> but we never masked the host address bits out of the address after parsing
> it using inet_pton. To fix this we simply mask away the host bits in the
> address before using it.
This is fixed in netifd by commit
https://git.openwrt.org/?p=project/netifd.git;a=commitdiff;h=645ceed0ed706b073edd6a0d5a2eb936208b48c9

Hans
>
> Signed-off-by: Daniel Gröber <dxld@darkboxed.org>
> ---
>  interface-ip.c | 2 ++
>  1 file changed, 2 insertions(+)
>
> diff --git a/interface-ip.c b/interface-ip.c
> index 6efc3c5..e8f2dbd 100644
> --- a/interface-ip.c
> +++ b/interface-ip.c
> @@ -1294,6 +1294,8 @@ interface_ip_add_device_prefix(struct interface *iface, struct in6_addr *addr,
>         prefix->iface = iface;
>         INIT_LIST_HEAD(&prefix->assignments);
>
> +       clear_if_addr((union if_addr *)&prefix->addr, prefix->length);
> +
>         if (excl_addr) {
>                 prefix->excl_addr = *excl_addr;
>                 prefix->excl_length = excl_length;
> --
> 2.20.1
>
>
> _______________________________________________
> openwrt-devel mailing list
> openwrt-devel@lists.openwrt.org
> https://lists.openwrt.org/mailman/listinfo/openwrt-devel
Daniel Gröber Nov. 25, 2020, 7:37 p.m. UTC | #2
On Wed, Nov 25, 2020 at 08:23:08PM +0100, Hans Dedecker wrote:
> This is fixed in netifd by commit
> https://git.openwrt.org/?p=project/netifd.git;a=commitdiff;h=645ceed0ed706b073edd6a0d5a2eb936208b48c9

Cool I didn't see that. Thanks!

I'm a bit bummed you didn't just include the more detailed explaination in
my commit message since you obviously saw the original patch though.

--Daniel
diff mbox series

Patch

diff --git a/interface-ip.c b/interface-ip.c
index 6efc3c5..e8f2dbd 100644
--- a/interface-ip.c
+++ b/interface-ip.c
@@ -1294,6 +1294,8 @@  interface_ip_add_device_prefix(struct interface *iface, struct in6_addr *addr,
 	prefix->iface = iface;
 	INIT_LIST_HEAD(&prefix->assignments);
 
+	clear_if_addr((union if_addr *)&prefix->addr, prefix->length);
+
 	if (excl_addr) {
 		prefix->excl_addr = *excl_addr;
 		prefix->excl_length = excl_length;