Message ID | 20240215172107.3461054-3-edumazet@google.com (mailing list archive) |
---|---|
State | Accepted |
Commit | e898e4cd1aab271ca414f9ac6e08e4c761f6913c |
Delegated to: | Netdev Maintainers |
Headers | show |
Series | inet: fix NLM_F_DUMP_INTR logic | expand |
Le 15/02/2024 à 18:21, Eric Dumazet a écrit : > net->dev_base_seq and ipv6.dev_addr_genid are monotonically increasing. > > If we XOR their values, we could miss to detect if both values > were changed with the same amount. > > Fixes: 63998ac24f83 ("ipv6: provide addr and netconf dump consistency info") > Signed-off-by: Eric Dumazet <edumazet@google.com> > Cc: Nicolas Dichtel <nicolas.dichtel@6wind.com> > > Signed-off-by: Eric Dumazet <edumazet@google.com> The trailers are mangled, your sob is put twice. Acked-by: Nicolas Dichtel <nicolas.dichtel@6wind.com>
On Fri, Feb 16, 2024 at 10:17 AM Nicolas Dichtel <nicolas.dichtel@6wind.com> wrote: > > Le 15/02/2024 à 18:21, Eric Dumazet a écrit : > > net->dev_base_seq and ipv6.dev_addr_genid are monotonically increasing. > > > > If we XOR their values, we could miss to detect if both values > > were changed with the same amount. > > > > Fixes: 63998ac24f83 ("ipv6: provide addr and netconf dump consistency info") > > Signed-off-by: Eric Dumazet <edumazet@google.com> > > Cc: Nicolas Dichtel <nicolas.dichtel@6wind.com> > > > > Signed-off-by: Eric Dumazet <edumazet@google.com> > > The trailers are mangled, your sob is put twice. > > Acked-by: Nicolas Dichtel <nicolas.dichtel@6wind.com> Oops, copy/paste error ;) Thanks !
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c index 733ace18806c61f487d83081dc6d39d079959f77..5a839c5fb1a5aa55e5c7f2ad8081e401a76d5a93 100644 --- a/net/ipv6/addrconf.c +++ b/net/ipv6/addrconf.c @@ -708,6 +708,22 @@ static int inet6_netconf_get_devconf(struct sk_buff *in_skb, return err; } +/* Combine dev_addr_genid and dev_base_seq to detect changes. + */ +static u32 inet6_base_seq(const struct net *net) +{ + u32 res = atomic_read(&net->ipv6.dev_addr_genid) + + net->dev_base_seq; + + /* Must not return 0 (see nl_dump_check_consistent()). + * Chose a value far away from 0. + */ + if (!res) + res = 0x80000000; + return res; +} + + static int inet6_netconf_dump_devconf(struct sk_buff *skb, struct netlink_callback *cb) { @@ -741,8 +757,7 @@ static int inet6_netconf_dump_devconf(struct sk_buff *skb, idx = 0; head = &net->dev_index_head[h]; rcu_read_lock(); - cb->seq = atomic_read(&net->ipv6.dev_addr_genid) ^ - net->dev_base_seq; + cb->seq = inet6_base_seq(net); hlist_for_each_entry_rcu(dev, head, index_hlist) { if (idx < s_idx) goto cont; @@ -5362,7 +5377,7 @@ static int inet6_dump_addr(struct sk_buff *skb, struct netlink_callback *cb, } rcu_read_lock(); - cb->seq = atomic_read(&tgt_net->ipv6.dev_addr_genid) ^ tgt_net->dev_base_seq; + cb->seq = inet6_base_seq(tgt_net); for (h = s_h; h < NETDEV_HASHENTRIES; h++, s_idx = 0) { idx = 0; head = &tgt_net->dev_index_head[h];