datapath: Account for "genetlink: pass only network namespace to genl_has_listeners()"
[cascardo/ovs.git] / datapath / linux / compat / include / net / genetlink.h
index 31ff282..8d1b89e 100644 (file)
@@ -4,6 +4,7 @@
 #include <linux/version.h>
 #include <linux/netlink.h>
 #include <net/net_namespace.h>
+#include_next <net/genetlink.h>
 
 /*
  * 15e473046cb6e5d18a4d0057e61d76315230382b renames pid to portid
 #define portid pid
 #endif
 
-/* Very special super-nasty workaround here:
- *
- * Before 2.6.19, nlmsg_multicast() lacked a 'flags' parameter.  We work
- * around that in our <net/netlink.h> replacement, so that nlmsg_multicast
- * is a macro that expands to rpl_nlmsg_multicast, which in turn has the
- * 'flags' parameter.
- *
- * However, also before 2.6.19, <net/genetlink.h> contains an inline definition
- * of genlmsg_multicast() that, of course, calls it without the 'flags'
- * parameter.  This causes a build failure.
- *
- * This works around the problem by temporarily renaming both nlmsg_multicast
- * and genlmsg_multicast with a "busted_" prefix.  (Nothing actually defines
- * busted_nlmsg_multicast(), so if anything actually tries to call it, then
- * we'll get a link error.)
- */
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19)
-#undef nlmsg_multicast
-#define nlmsg_multicast busted_nlmsg_multicast
-#define genlmsg_multicast busted_genlmsg_multicast
-extern int busted_nlmsg_multicast(struct sock *sk, struct sk_buff *skb,
-                                 u32 pid, unsigned int group);
-#endif /* linux kernel < v2.6.19 */
-
-#include_next <net/genetlink.h>
-
-/* Drop the "busted_" prefix described above. */
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19)
-#undef nlmsg_multicast
-#undef genlmsg_multicast
-#define nlmsg_multicast rpl_nlmsg_multicast
-#endif /* linux kernel < v2.6.19 */
-
-#include <net/net_namespace.h>
-
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,23)
-
-#include <linux/genetlink.h>
-
-/**
- * struct genl_multicast_group - generic netlink multicast group
- * @name: name of the multicast group, names are per-family
- * @id: multicast group ID, assigned by the core, to use with
- *       genlmsg_multicast().
- * @list: list entry for linking
- * @family: pointer to family, need not be set before registering
- */
-struct genl_multicast_group {
-       struct genl_family  *family;    /* private */
-       struct list_head        list;      /* private */
-       char name[GENL_NAMSIZ];
-       u32     id;
+#if LINUX_VERSION_CODE < KERNEL_VERSION(3,13,0)
+struct rpl_genl_family {
+       struct genl_family      compat_family;
+       unsigned int            id;
+       unsigned int            hdrsize;
+       char                    name[GENL_NAMSIZ];
+       unsigned int            version;
+       unsigned int            maxattr;
+       bool                    netnsok;
+       bool                    parallel_ops;
+       int                     (*pre_doit)(const struct genl_ops *ops,
+                                           struct sk_buff *skb,
+                                           struct genl_info *info);
+       void                    (*post_doit)(const struct genl_ops *ops,
+                                            struct sk_buff *skb,
+                                            struct genl_info *info);
+       struct nlattr **        attrbuf;        /* private */
+       const struct genl_ops * ops;            /* private */
+       const struct genl_multicast_group *mcgrps; /* private */
+       unsigned int            n_ops;          /* private */
+       unsigned int            n_mcgrps;       /* private */
+       unsigned int            mcgrp_offset;   /* private */
+       struct list_head        family_list;    /* private */
+       struct module           *module;
 };
 
-int genl_register_mc_group(struct genl_family *family,
-               struct genl_multicast_group *grp);
-#endif /* linux kernel < 2.6.23 */
-
+#define genl_family rpl_genl_family
+#define genl_notify rpl_genl_notify
+void genl_notify(struct genl_family *family,
+                struct sk_buff *skb, struct net *net, u32 portid, u32 group,
+                struct nlmsghdr *nlh, gfp_t flags);
 
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19)
-/**
- * genlmsg_msg_size - length of genetlink message not including padding
- * @payload: length of message payload
- */
-static inline int genlmsg_msg_size(int payload)
+static inline void *rpl_genlmsg_put(struct sk_buff *skb, u32 portid, u32 seq,
+                                   struct genl_family *family, int flags, u8 cmd)
 {
-       return GENL_HDRLEN + payload;
+       return genlmsg_put(skb, portid, seq, &family->compat_family, flags, cmd);
 }
 
-/**
- * genlmsg_total_size - length of genetlink message including padding
- * @payload: length of message payload
- */
-static inline int genlmsg_total_size(int payload)
+#define genlmsg_put rpl_genlmsg_put
+
+static inline int rpl_genl_unregister_family(struct genl_family *family)
 {
-       return NLMSG_ALIGN(genlmsg_msg_size(payload));
+       return genl_unregister_family(&family->compat_family);
 }
+#define genl_unregister_family rpl_genl_unregister_family
 
-#define genlmsg_multicast(s, p, g, f) \
-               genlmsg_multicast_flags((s), (p), (g), (f))
+#define genl_set_err rpl_genl_set_err
+static inline int genl_set_err(struct genl_family *family, struct net *net,
+                              u32 portid, u32 group, int code)
+{
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,33)
+       netlink_set_err(net->genl_sock, portid, group, code);
+       return 0;
+#else
+       return netlink_set_err(net->genl_sock, portid, group, code);
+#endif
+}
 
-static inline int genlmsg_multicast_flags(struct sk_buff *skb, u32 pid,
-               unsigned int group, gfp_t flags)
+#define genlmsg_multicast_netns rpl_genlmsg_multicast_netns
+static inline int genlmsg_multicast_netns(struct genl_family *family,
+                                         struct net *net, struct sk_buff *skb,
+                                         u32 portid, unsigned int group, gfp_t flags)
 {
-       int err;
+       return nlmsg_multicast(net->genl_sock, skb, portid, group, flags);
+}
 
-       NETLINK_CB(skb).dst_group = group;
 
-       err = netlink_broadcast(genl_sock, skb, pid, group, flags);
-       if (err > 0)
-               err = 0;
+#define __genl_register_family rpl___genl_register_family
+int rpl___genl_register_family(struct genl_family *family);
 
-       return err;
+#define genl_register_family rpl_genl_register_family
+static inline int rpl_genl_register_family(struct genl_family *family)
+{
+       family->module = THIS_MODULE;
+       return rpl___genl_register_family(family);
 }
-#endif /* linux kernel < 2.6.19 */
 
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,32)
-#define genlmsg_multicast_netns(net, skb, pid, grp, flags) \
-               genlmsg_multicast(skb, pid, grp, flags)
 #endif
 
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
-
-#define genlmsg_put(skb, p, seq, fam, flg, c) \
-       genlmsg_put((skb), (p), (seq), (fam)->id, (fam)->hdrsize, \
-                       (flg), (c), (fam)->version)
-
-/**
- * genlmsg_put_reply - Add generic netlink header to a reply message
- * @skb: socket buffer holding the message
- * @info: receiver info
- * @family: generic netlink family
- * @flags: netlink message flags
- * @cmd: generic netlink command
- *
- * Returns pointer to user specific header
- */
-static inline void *genlmsg_put_reply(struct sk_buff *skb,
-                       struct genl_info *info, struct genl_family *family,
-                       int flags, u8 cmd)
+#ifndef HAVE_GENLMSG_NEW_UNICAST
+static inline struct sk_buff *genlmsg_new_unicast(size_t payload,
+                                                 struct genl_info *info,
+                                                 gfp_t flags)
 {
-       return genlmsg_put(skb, info->snd_portid, info->snd_seq, family,
-                               flags, cmd);
+       return genlmsg_new(payload, flags);
 }
+#endif
 
-/**
- * genlmsg_reply - reply to a request
- * @skb: netlink message to be sent back
- * @info: receiver information
- */
-static inline int genlmsg_reply(struct sk_buff *skb, struct genl_info *info)
+#ifndef HAVE_GENL_HAS_LISTENERS
+static inline int genl_has_listeners(struct genl_family *family,
+                                    struct net *net, unsigned int group)
 {
-       return genlmsg_unicast(skb, info->snd_portid);
+#ifdef HAVE_MCGRP_OFFSET
+       if (WARN_ON_ONCE(group >= family->n_mcgrps))
+               return -EINVAL;
+       group = family->mcgrp_offset + group;
+#endif
+       return netlink_has_listeners(net->genl_sock, group);
 }
+#else
 
-/**
- * genlmsg_new - Allocate a new generic netlink message
- * @payload: size of the message payload
- * @flags: the type of memory to allocate.
- */
-static inline struct sk_buff *genlmsg_new(size_t payload, gfp_t flags)
+#ifndef HAVE_GENL_HAS_LISTENERS_TAKES_NET
+static inline int rpl_genl_has_listeners(struct genl_family *family,
+                                        struct net *net, unsigned int group)
 {
-       return nlmsg_new(genlmsg_total_size(payload), flags);
+    return genl_has_listeners(family, net->genl_sock, group);
 }
-#endif /* linux kernel < 2.6.20 */
 
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,31)
-int genl_register_family_with_ops(struct genl_family *family,
-       struct genl_ops *ops, size_t n_ops);
+#define genl_has_listeners rpl_genl_has_listeners
 #endif
 
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24)
-#define genl_notify(skb, net, pid, group, nlh, flags) \
-       genl_notify(skb, pid, group, nlh, flags)
-#endif
-extern void genl_notify(struct sk_buff *skb, struct net *net, u32 pid,
-                       u32 group, struct nlmsghdr *nlh, gfp_t flags);
+#endif /* HAVE_GENL_HAS_LISTENERS */
 
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24) && \
-    LINUX_VERSION_CODE < KERNEL_VERSION(2,6,32)
-static inline struct net *genl_info_net(struct genl_info *info)
-{
-       return &init_net;
-}
-#endif
-
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,32)
-#define genlmsg_unicast(ignore_net, skb, pid)   genlmsg_unicast(skb, pid)
-#endif
 #endif /* genetlink.h */