Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

net: ipv6: support reporting otherwise unknown prefix flags in RTM_NEWPREFIX

Lorenzo points out that we effectively clear all unknown
flags from PIO when copying them to userspace in the netlink
RTM_NEWPREFIX notification.

We could fix this one at a time as new flags are defined,
or in one fell swoop - I choose the latter.

We could either define 6 new reserved flags (reserved1..6) and handle
them individually (and rename them as new flags are defined), or we
could simply copy the entire unmodified byte over - I choose the latter.

This unfortunately requires some anonymous union/struct magic,
so we add a static assert on the struct size for a little extra safety.

Cc: David Ahern <dsahern@kernel.org>
Cc: Lorenzo Colitti <lorenzo@google.com>
Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Signed-off-by: Maciej Żenczykowski <maze@google.com>
Reviewed-by: David Ahern <dsahern@kernel.org>
Signed-off-by: David S. Miller <davem@davemloft.net>

authored by

Maciej Żenczykowski and committed by
David S. Miller
bd4a8167 e5dc5aff

+11 -11
+10 -2
include/net/addrconf.h
··· 31 31 __u8 length; 32 32 __u8 prefix_len; 33 33 34 + union __packed { 35 + __u8 flags; 36 + struct __packed { 34 37 #if defined(__BIG_ENDIAN_BITFIELD) 35 - __u8 onlink : 1, 38 + __u8 onlink : 1, 36 39 autoconf : 1, 37 40 reserved : 6; 38 41 #elif defined(__LITTLE_ENDIAN_BITFIELD) 39 - __u8 reserved : 6, 42 + __u8 reserved : 6, 40 43 autoconf : 1, 41 44 onlink : 1; 42 45 #else 43 46 #error "Please fix <asm/byteorder.h>" 44 47 #endif 48 + }; 49 + }; 45 50 __be32 valid; 46 51 __be32 prefered; 47 52 __be32 reserved2; 48 53 49 54 struct in6_addr prefix; 50 55 }; 56 + 57 + /* rfc4861 4.6.2: IPv6 PIO is 32 bytes in size */ 58 + static_assert(sizeof(struct prefix_info) == 32); 51 59 52 60 #include <linux/ipv6.h> 53 61 #include <linux/netdevice.h>
-4
include/net/if_inet6.h
··· 22 22 #define IF_RS_SENT 0x10 23 23 #define IF_READY 0x80000000 24 24 25 - /* prefix flags */ 26 - #define IF_PREFIX_ONLINK 0x01 27 - #define IF_PREFIX_AUTOCONF 0x02 28 - 29 25 enum { 30 26 INET6_IFADDR_STATE_PREDAD, 31 27 INET6_IFADDR_STATE_DAD,
+1 -5
net/ipv6/addrconf.c
··· 6149 6149 pmsg->prefix_len = pinfo->prefix_len; 6150 6150 pmsg->prefix_type = pinfo->type; 6151 6151 pmsg->prefix_pad3 = 0; 6152 - pmsg->prefix_flags = 0; 6153 - if (pinfo->onlink) 6154 - pmsg->prefix_flags |= IF_PREFIX_ONLINK; 6155 - if (pinfo->autoconf) 6156 - pmsg->prefix_flags |= IF_PREFIX_AUTOCONF; 6152 + pmsg->prefix_flags = pinfo->flags; 6157 6153 6158 6154 if (nla_put(skb, PREFIX_ADDRESS, sizeof(pinfo->prefix), &pinfo->prefix)) 6159 6155 goto nla_put_failure;