1 #include <net/genetlink.h>
2 #include <linux/version.h>
4 #define GENL_FIRST_MCGROUP 16
5 #define GENL_LAST_MCGROUP 31
7 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,23)
8 #include <linux/mutex.h>
9 #include <linux/openvswitch.h>
11 #include "openvswitch/datapath-compat.h"
13 static DEFINE_MUTEX(mc_group_mutex);
15 int genl_register_mc_group(struct genl_family *family,
16 struct genl_multicast_group *grp)
18 static int next_group = GENL_FIRST_MCGROUP;
22 if (!strcmp(grp->name, OVS_VPORT_MCGROUP)) {
23 grp->id = OVS_VPORT_MCGROUP_FALLBACK_ID;
27 mutex_lock(&mc_group_mutex);
30 if (++next_group > GENL_LAST_MCGROUP)
31 next_group = GENL_FIRST_MCGROUP;
32 mutex_unlock(&mc_group_mutex);
36 #endif /* kernel < 2.6.23 */
38 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,31)
40 * genl_register_family_with_ops - register a generic netlink family
41 * @family: generic netlink family
42 * @ops: operations to be registered
43 * @n_ops: number of elements to register
45 * Registers the specified family and operations from the specified table.
46 * Only one family may be registered with the same family name or identifier.
48 * The family id may equal GENL_ID_GENERATE causing an unique id to
49 * be automatically generated and assigned.
51 * Either a doit or dumpit callback must be specified for every registered
52 * operation or the function will fail. Only one operation structure per
53 * command identifier may be registered.
55 * See include/net/genetlink.h for more documenation on the operations
58 * This is equivalent to calling genl_register_family() followed by
59 * genl_register_ops() for every operation entry in the table taking
60 * care to unregister the family on error path.
62 * Return 0 on success or a negative error code.
64 int genl_register_family_with_ops(struct genl_family *family,
65 struct genl_ops *ops, size_t n_ops)
69 err = genl_register_family(family);
73 for (i = 0; i < n_ops; ++i, ++ops) {
74 err = genl_register_ops(family, ops);
80 genl_unregister_family(family);
85 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19)
87 * nlmsg_notify - send a notification netlink message
88 * @sk: netlink socket to use
89 * @skb: notification message
90 * @portid: destination netlink portid for reports or 0
91 * @group: destination multicast group or 0
92 * @report: 1 to report back, 0 to disable
93 * @flags: allocation flags
95 int nlmsg_notify(struct sock *sk, struct sk_buff *skb, u32 portid,
96 unsigned int group, int report, gfp_t flags)
101 int exclude_portid = 0;
104 atomic_inc(&skb->users);
105 exclude_portid = portid;
108 /* errors reported via destination sk->sk_err, but propagate
109 * delivery errors if NETLINK_BROADCAST_ERROR flag is set */
110 err = nlmsg_multicast(sk, skb, exclude_portid, group, flags);
116 err2 = nlmsg_unicast(sk, skb, portid);
117 if (!err || err == -ESRCH)
125 /* This is analogous to rtnl_notify() but uses genl_sock instead of rtnl.
127 * This is not (yet) in any upstream kernel. */
128 void genl_notify(struct sk_buff *skb, struct net *net, u32 portid, u32 group,
129 struct nlmsghdr *nlh, gfp_t flags)
131 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,32)
132 struct sock *sk = net->genl_sock;
134 struct sock *sk = genl_sock;
139 report = nlmsg_report(nlh);
141 nlmsg_notify(sk, skb, portid, group, report, flags);
144 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,30)
145 /* This function wasn't exported before 2.6.30. Lose! */
146 void netlink_set_err(struct sock *ssk, u32 portid, u32 group, int code)