Skip to content

Commit 990c304

Browse files
Patrick Rohrdavem330
authored andcommitted
Add support for PIO p flag
draft-ietf-6man-pio-pflag is adding a new flag to the Prefix Information Option to signal that the network can allocate a unique IPv6 prefix per client via DHCPv6-PD (see draft-ietf-v6ops-dhcp-pd-per-device). When ra_honor_pio_pflag is enabled, the presence of a P-flag causes SLAAC autoconfiguration to be disabled for that particular PIO. An automated test has been added in Android (r.android.com/3195335) to go along with this change. Cc: Maciej Żenczykowski <[email protected]> Cc: Lorenzo Colitti <[email protected]> Cc: David Lamparter <[email protected]> Cc: Simon Horman <[email protected]> Signed-off-by: Patrick Rohr <[email protected]> Reviewed-by: Maciej Żenczykowski <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 59f7265 commit 990c304

File tree

4 files changed

+36
-4
lines changed

4 files changed

+36
-4
lines changed

Documentation/networking/ip-sysctl.rst

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2362,6 +2362,20 @@ ra_honor_pio_life - BOOLEAN
23622362

23632363
Default: 0 (disabled)
23642364

2365+
ra_honor_pio_pflag - BOOLEAN
2366+
The Prefix Information Option P-flag indicates the network can
2367+
allocate a unique IPv6 prefix per client using DHCPv6-PD.
2368+
This sysctl can be enabled when a userspace DHCPv6-PD client
2369+
is running to cause the P-flag to take effect: i.e. the
2370+
P-flag suppresses any effects of the A-flag within the same
2371+
PIO. For a given PIO, P=1 and A=1 is treated as A=0.
2372+
2373+
- If disabled, the P-flag is ignored.
2374+
- If enabled, the P-flag will disable SLAAC autoconfiguration
2375+
for the given Prefix Information Option.
2376+
2377+
Default: 0 (disabled)
2378+
23652379
accept_ra_rt_info_min_plen - INTEGER
23662380
Minimum prefix length of Route Information in RA.
23672381

include/linux/ipv6.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,7 @@ struct ipv6_devconf {
8989
__u8 ioam6_enabled;
9090
__u8 ndisc_evict_nocarrier;
9191
__u8 ra_honor_pio_life;
92+
__u8 ra_honor_pio_pflag;
9293

9394
struct ctl_table_header *sysctl_header;
9495
};

include/net/addrconf.h

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -37,10 +37,14 @@ struct prefix_info {
3737
struct __packed {
3838
#if defined(__BIG_ENDIAN_BITFIELD)
3939
__u8 onlink : 1,
40-
autoconf : 1,
41-
reserved : 6;
40+
autoconf : 1,
41+
routeraddr : 1,
42+
preferpd : 1,
43+
reserved : 4;
4244
#elif defined(__LITTLE_ENDIAN_BITFIELD)
43-
__u8 reserved : 6,
45+
__u8 reserved : 4,
46+
preferpd : 1,
47+
routeraddr : 1,
4448
autoconf : 1,
4549
onlink : 1;
4650
#else

net/ipv6/addrconf.c

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -239,6 +239,7 @@ static struct ipv6_devconf ipv6_devconf __read_mostly = {
239239
.ioam6_id_wide = IOAM6_DEFAULT_IF_ID_WIDE,
240240
.ndisc_evict_nocarrier = 1,
241241
.ra_honor_pio_life = 0,
242+
.ra_honor_pio_pflag = 0,
242243
};
243244

244245
static struct ipv6_devconf ipv6_devconf_dflt __read_mostly = {
@@ -302,6 +303,7 @@ static struct ipv6_devconf ipv6_devconf_dflt __read_mostly = {
302303
.ioam6_id_wide = IOAM6_DEFAULT_IF_ID_WIDE,
303304
.ndisc_evict_nocarrier = 1,
304305
.ra_honor_pio_life = 0,
306+
.ra_honor_pio_pflag = 0,
305307
};
306308

307309
/* Check if link is ready: is it up and is a valid qdisc available */
@@ -2762,6 +2764,7 @@ void addrconf_prefix_rcv(struct net_device *dev, u8 *opt, int len, bool sllao)
27622764
u32 addr_flags = 0;
27632765
struct inet6_dev *in6_dev;
27642766
struct net *net = dev_net(dev);
2767+
bool ignore_autoconf = false;
27652768

27662769
pinfo = (struct prefix_info *) opt;
27672770

@@ -2864,7 +2867,8 @@ void addrconf_prefix_rcv(struct net_device *dev, u8 *opt, int len, bool sllao)
28642867

28652868
/* Try to figure out our local address for this prefix */
28662869

2867-
if (pinfo->autoconf && in6_dev->cnf.autoconf) {
2870+
ignore_autoconf = READ_ONCE(in6_dev->cnf.ra_honor_pio_pflag) && pinfo->preferpd;
2871+
if (pinfo->autoconf && in6_dev->cnf.autoconf && !ignore_autoconf) {
28682872
struct in6_addr addr;
28692873
bool tokenized = false, dev_addr_generated = false;
28702874

@@ -6926,6 +6930,15 @@ static const struct ctl_table addrconf_sysctl[] = {
69266930
.extra1 = SYSCTL_ZERO,
69276931
.extra2 = SYSCTL_ONE,
69286932
},
6933+
{
6934+
.procname = "ra_honor_pio_pflag",
6935+
.data = &ipv6_devconf.ra_honor_pio_pflag,
6936+
.maxlen = sizeof(u8),
6937+
.mode = 0644,
6938+
.proc_handler = proc_dou8vec_minmax,
6939+
.extra1 = SYSCTL_ZERO,
6940+
.extra2 = SYSCTL_ONE,
6941+
},
69296942
#ifdef CONFIG_IPV6_ROUTER_PREF
69306943
{
69316944
.procname = "accept_ra_rtr_pref",

0 commit comments

Comments
 (0)