--- zzzz-none-000/linux-4.4.271/net/ipv6/protocol.c 2021-06-03 06:22:09.000000000 +0000 +++ hawkeye-5590-750/linux-4.4.271/net/ipv6/protocol.c 2023-04-19 10:22:30.000000000 +0000 @@ -72,3 +72,29 @@ return ret; } EXPORT_SYMBOL(inet6_del_offload); + +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);