--- zzzz-none-000/linux-5.4.213/net/ipv6/protocol.c 2022-09-15 10:04:56.000000000 +0000 +++ alder-5690pro-762/linux-5.4.213/net/ipv6/protocol.c 2024-08-14 09:02:13.000000000 +0000 @@ -44,6 +44,32 @@ return ret; } EXPORT_SYMBOL(inet6_del_protocol); + +int inet6_update_protocol(const struct inet6_protocol *new_prot, + unsigned char protocol, const struct inet6_protocol **old_prot) +{ + int ret; + + rcu_read_lock(); + *old_prot = rcu_dereference(inet6_protos[protocol]); + if (!*old_prot) { + rcu_read_unlock(); + return -1; + } + rcu_read_unlock(); + + /* + * old_prot is not protected as cmpxchg is successful only if + * old_prot matches with the value in inet6_protos[protocol] + */ + ret = (cmpxchg((const struct inet6_protocol **)&inet6_protos[protocol], + *old_prot, new_prot) == *old_prot) ? 0 : -1; + + synchronize_net(); + + return ret; +} +EXPORT_SYMBOL(inet6_update_protocol); #endif const struct net_offload __rcu *inet6_offloads[MAX_INET_PROTOS] __read_mostly;