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;
33EXPORT_SYMBOL(inet_offloads);
34
35
36
37
38
39int inet_add_protocol(const struct net_protocol *prot, unsigned char protocol)
40{
41 if (!prot->netns_ok) {
42 pr_err("Protocol %u is not namespace aware, cannot register.\n",
43 protocol);
44 return -EINVAL;
45 }
46
47 return !cmpxchg((const struct net_protocol **)&inet_protos[protocol],
48 NULL, prot) ? 0 : -1;
49}
50EXPORT_SYMBOL(inet_add_protocol);
51
52int inet_add_offload(const struct net_offload *prot, unsigned char protocol)
53{
54 return !cmpxchg((const struct net_offload **)&inet_offloads[protocol],
55 NULL, prot) ? 0 : -1;
56}
57EXPORT_SYMBOL(inet_add_offload);
58
59
60
61
62
63int inet_del_protocol(const struct net_protocol *prot, unsigned char protocol)
64{
65 int ret;
66
67 ret = (cmpxchg((const struct net_protocol **)&inet_protos[protocol],
68 prot, NULL) == prot) ? 0 : -1;
69
70 synchronize_net();
71
72 return ret;
73}
74EXPORT_SYMBOL(inet_del_protocol);
75
76int inet_del_offload(const struct net_offload *prot, unsigned char protocol)
77{
78 int ret;
79
80 ret = (cmpxchg((const struct net_offload **)&inet_offloads[protocol],
81 prot, NULL) == prot) ? 0 : -1;
82
83 synchronize_net();
84
85 return ret;
86}
87EXPORT_SYMBOL(inet_del_offload);
88