]> git.proxmox.com Git - mirror_ovs.git/blob - datapath/linux-2.6/compat-2.6/genetlink.inc
ovsdb: Synchronize comments and code in ovsdb_file_commit().
[mirror_ovs.git] / datapath / linux-2.6 / compat-2.6 / genetlink.inc
1 /* -*- c -*- */
2
3 #include <net/genetlink.h>
4 #include <linux/version.h>
5
6 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,23)
7 #include <linux/mutex.h>
8
9 static DEFINE_MUTEX(mc_group_mutex);
10
11 int genl_register_mc_group(struct genl_family *family,
12 struct genl_multicast_group *grp)
13 {
14 static int next_group = GENL_FIRST_MCGROUP;
15
16 mutex_lock(&mc_group_mutex);
17 grp->id = next_group;
18 grp->family = family;
19
20 if (++next_group > GENL_LAST_MCGROUP)
21 next_group = GENL_FIRST_MCGROUP;
22 mutex_unlock(&mc_group_mutex);
23
24 return 0;
25 }
26 #endif /* kernel < 2.6.23 */
27
28 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,31)
29 /**
30 * genl_register_family_with_ops - register a generic netlink family
31 * @family: generic netlink family
32 * @ops: operations to be registered
33 * @n_ops: number of elements to register
34 *
35 * Registers the specified family and operations from the specified table.
36 * Only one family may be registered with the same family name or identifier.
37 *
38 * The family id may equal GENL_ID_GENERATE causing an unique id to
39 * be automatically generated and assigned.
40 *
41 * Either a doit or dumpit callback must be specified for every registered
42 * operation or the function will fail. Only one operation structure per
43 * command identifier may be registered.
44 *
45 * See include/net/genetlink.h for more documenation on the operations
46 * structure.
47 *
48 * This is equivalent to calling genl_register_family() followed by
49 * genl_register_ops() for every operation entry in the table taking
50 * care to unregister the family on error path.
51 *
52 * Return 0 on success or a negative error code.
53 */
54 int genl_register_family_with_ops(struct genl_family *family,
55 struct genl_ops *ops, size_t n_ops)
56 {
57 int err, i;
58
59 err = genl_register_family(family);
60 if (err)
61 return err;
62
63 for (i = 0; i < n_ops; ++i, ++ops) {
64 err = genl_register_ops(family, ops);
65 if (err)
66 goto err_out;
67 }
68 return 0;
69 err_out:
70 genl_unregister_family(family);
71 return err;
72 }
73 #endif
74
75 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19)
76 /**
77 * nlmsg_notify - send a notification netlink message
78 * @sk: netlink socket to use
79 * @skb: notification message
80 * @pid: destination netlink pid for reports or 0
81 * @group: destination multicast group or 0
82 * @report: 1 to report back, 0 to disable
83 * @flags: allocation flags
84 */
85 int nlmsg_notify(struct sock *sk, struct sk_buff *skb, u32 pid,
86 unsigned int group, int report, gfp_t flags)
87 {
88 int err = 0;
89
90 if (group) {
91 int exclude_pid = 0;
92
93 if (report) {
94 atomic_inc(&skb->users);
95 exclude_pid = pid;
96 }
97
98 /* errors reported via destination sk->sk_err, but propagate
99 * delivery errors if NETLINK_BROADCAST_ERROR flag is set */
100 err = nlmsg_multicast(sk, skb, exclude_pid, group, flags);
101 }
102
103 if (report) {
104 int err2;
105
106 err2 = nlmsg_unicast(sk, skb, pid);
107 if (!err || err == -ESRCH)
108 err = err2;
109 }
110
111 return err;
112 }
113 #endif
114
115 /* This is analogous to rtnl_notify() but uses genl_sock instead of rtnl.
116 *
117 * This is not (yet) in any upstream kernel. */
118 void genl_notify(struct sk_buff *skb, struct net *net, u32 pid, u32 group,
119 struct nlmsghdr *nlh, gfp_t flags)
120 {
121 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,32)
122 struct sock *sk = net->genl_sock;
123 #else
124 struct sock *sk = genl_sock;
125 #endif
126 int report = 0;
127
128 if (nlh)
129 report = nlmsg_report(nlh);
130
131 nlmsg_notify(sk, skb, pid, group, report, flags);
132 }
133
134 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,30)
135 /* This function wasn't exported before 2.6.30. Lose! */
136 void netlink_set_err(struct sock *ssk, u32 pid, u32 group, int code)
137 {
138 }
139 #endif