1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25#include <linux/cache.h>
26#include <linux/module.h>
27#include <linux/netdevice.h>
28#include <linux/spinlock.h>
29#include <net/protocol.h>
30
31const struct net_protocol __rcu *inet_protos[MAX_INET_PROTOS] __read_mostly;
32const struct net_offload __rcu *inet_offloads[MAX_INET_PROTOS] __read_mostly;
33
34
35
36
37
38int inet_add_protocol(const struct net_protocol *prot, unsigned char protocol)
39{
40 if (!prot->netns_ok) {
41 pr_err("Protocol %u is not namespace aware, cannot register.\n",
42 protocol);
43 return -EINVAL;
44 }
45
46 return !cmpxchg((const struct net_protocol **)&inet_protos[protocol],
47 NULL, prot) ? 0 : -1;
48}
49EXPORT_SYMBOL(inet_add_protocol);
50
51int inet_add_offload(const struct net_offload *prot, unsigned char protocol)
52{
53 return !cmpxchg((const struct net_offload **)&inet_offloads[protocol],
54 NULL, prot) ? 0 : -1;
55}
56EXPORT_SYMBOL(inet_add_offload);
57
58
59
60
61
62int inet_del_protocol(const struct net_protocol *prot, unsigned char protocol)
63{
64 int ret;
65
66 ret = (cmpxchg((const struct net_protocol **)&inet_protos[protocol],
67 prot, NULL) == prot) ? 0 : -1;
68
69 synchronize_net();
70
71 return ret;
72}
73EXPORT_SYMBOL(inet_del_protocol);
74
75int inet_del_offload(const struct net_offload *prot, unsigned char protocol)
76{
77 int ret;
78
79 ret = (cmpxchg((const struct net_offload **)&inet_offloads[protocol],
80 prot, NULL) == prot) ? 0 : -1;
81
82 synchronize_net();
83
84 return ret;
85}
86EXPORT_SYMBOL(inet_del_offload);
87