--- zzzz-none-000/linux-4.4.60/net/ipv4/protocol.c 2017-04-08 07:53:53.000000000 +0000 +++ hawkeye-5590-729/linux-4.4.60/net/ipv4/protocol.c 2022-03-30 14:21:53.000000000 +0000 @@ -77,3 +77,29 @@ return ret; } EXPORT_SYMBOL(inet_del_offload); + +int inet_update_protocol(const struct net_protocol *new_prot, + unsigned char protocol, const struct net_protocol **old_prot) +{ + int ret; + + rcu_read_lock(); + *old_prot = rcu_dereference(inet_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 inet_protos[protocol] + */ + ret = (cmpxchg((const struct net_protocol **)&inet_protos[protocol], + *old_prot, new_prot) == *old_prot) ? 0 : -1; + + synchronize_net(); + + return ret; +} +EXPORT_SYMBOL(inet_update_protocol);