* [PATCH] compat: backport netlink changes used in the nl80211 cleanup
@ 2010-10-07 11:59 Felix Fietkau
2010-10-07 12:46 ` [PATCH v2] " Felix Fietkau
0 siblings, 1 reply; 6+ messages in thread
From: Felix Fietkau @ 2010-10-07 11:59 UTC (permalink / raw)
To: Luis R. Rodriguez; +Cc: linux-wireless
Signed-off-by: Felix Fietkau <nbd@openwrt.org>
---
--- a/include/linux/compat-2.6.37.h
+++ b/include/linux/compat-2.6.37.h
@@ -45,6 +45,65 @@ static inline void skb_checksum_none_ass
#define pcmcia_enable_device(link) pcmcia_request_configuration(link, &link->conf)
+#include <net/genetlink.h>
+
+struct compat_genl_info {
+ struct genl_info *info;
+
+ u32 snd_seq;
+ u32 snd_pid;
+ struct genlmsghdr *genlhdr;
+ struct nlattr **attrs;
+ void *user_ptr[2];
+};
+#define genl_info compat_genl_info
+
+struct compat_genl_ops {
+ struct genl_ops ops;
+
+ u8 cmd;
+ u8 internal_flags;
+ unsigned int flags;
+ const struct nla_policy *policy;
+
+ int (*doit)(struct sk_buff *skb, struct genl_info *info);
+ int (*dumpit)(struct sk_buff *skb, struct netlink_callback *cb);
+ int (*done)(struct netlink_callback *cb);
+};
+#define genl_ops compat_genl_ops
+
+struct compat_genl_family {
+ struct genl_family family;
+
+ struct list_head list;
+
+ unsigned int id, hdrsize, version, maxattr;
+ const char *name;
+ bool netnsok;
+
+ struct nlattr **attrbuf;
+
+ int (*pre_doit)(struct genl_ops *ops, struct sk_buff *skb,
+ struct genl_info *info);
+
+ void (*post_doit)(struct genl_ops *ops, struct sk_buff *skb,
+ struct genl_info *info);
+};
+
+#define genl_family compat_genl_family
+
+#define genl_register_family_with_ops compat_genl_register_family_with_ops
+
+int genl_register_family_with_ops(struct genl_family *family,
+ struct genl_ops *ops, size_t n_ops);
+
+#define genl_unregister_family(_family) genl_unregister_family(&(_family)->family)
+#define genl_info_net(_info) genl_info_net((_info)->info)
+#define genlmsg_reply(_msg, _info) genlmsg_reply(_msg, (_info)->info)
+#define genlmsg_put(_skb, _pid, _seq, _fam, _flags, _cmd) genlmsg_put(_skb, _pid, _seq, &(_fam)->family, _flags, _cmd)
+#define genl_register_mc_group(_fam, _grp) genl_register_mc_group(&(_fam)->family, _grp)
+#define genl_unregister_mc_group(_fam, _grp) genl_unregister_mc_group(&(_fam)->family, _grp)
+
#endif /* (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,37)) */
#endif /* LINUX_26_37_COMPAT_H */
--- a/compat/compat-2.6.37.c
+++ b/compat/compat-2.6.37.c
@@ -42,4 +42,98 @@ EXPORT_SYMBOL_GPL(net_ns_type_operations
#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,35)*/
+#undef genl_info
+
+static LIST_HEAD(compat_nl_fam);
+
+static struct genl_ops *genl_get_cmd(u8 cmd, struct genl_family *family)
+{
+ struct genl_ops *ops;
+
+ list_for_each_entry(ops, &family->family.ops_list, ops.ops_list)
+ if (ops->cmd == cmd)
+ return ops;
+
+ return NULL;
+}
+
+
+static int nl_doit_wrapper(struct sk_buff *skb, struct genl_info *info)
+{
+ struct compat_genl_info compat_info;
+ struct genl_family *family;
+ struct genl_ops *ops;
+
+ list_for_each_entry(family, &compat_nl_fam, list) {
+ if (family->id == info->nlhdr->nlmsg_type)
+ goto found;
+ }
+ return -ENOENT;
+
+found:
+ ops = genl_get_cmd(info->genlhdr->cmd, family);
+ if (!ops)
+ return -ENOENT;
+
+ memset(&compat_info, 0, sizeof(compat_info));
+ compat_info.info = info;
+#define __copy(_field) compat_info._field = info->_field
+ __copy(snd_seq);
+ __copy(snd_pid);
+ __copy(genlhdr);
+ __copy(attrs);
+#undef __copy
+ family->pre_doit(ops, skb, &compat_info);
+ ops->doit(skb, &compat_info);
+ family->post_doit(ops, skb, &compat_info);
+
+ return 0;
+}
+
+int compat_genl_register_family_with_ops(struct genl_family *family,
+ struct genl_ops *ops, size_t n_ops)
+{
+ int i, ret;
+
+#define __copy(_field) family->family._field = family->_field
+ __copy(id);
+ __copy(hdrsize);
+ __copy(version);
+ __copy(maxattr);
+ strncpy(family->family.name, family->name, sizeof(family->family.name));
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,32))
+ __copy(netnsok);
+#endif
+#undef __copy
+
+ ret = genl_register_family(&family->family);
+ if (ret < 0)
+ return ret;
+
+ family->attrbuf = family->family.attrbuf;
+ family->id = family->family.id;
+
+ for (i = 0; i < n_ops; i++) {
+#define __copy(_field) ops[i].ops._field = ops[i]._field
+ __copy(cmd);
+ __copy(flags);
+ __copy(policy);
+ __copy(dumpit);
+ __copy(done);
+#undef __copy
+ ops[i].ops.doit = nl_doit_wrapper;
+ ret = genl_register_ops(&family->family, &ops[i].ops);
+ if (ret < 0)
+ goto error_ops;
+ }
+ list_add(&family->list, &compat_nl_fam);
+
+ return ret;
+
+error_ops:
+ genl_unregister_family(family);
+ return ret;
+}
+EXPORT_SYMBOL(compat_genl_register_family_with_ops);
+
#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2,6,37) */
^ permalink raw reply [flat|nested] 6+ messages in thread* [PATCH v2] compat: backport netlink changes used in the nl80211 cleanup 2010-10-07 11:59 [PATCH] compat: backport netlink changes used in the nl80211 cleanup Felix Fietkau @ 2010-10-07 12:46 ` Felix Fietkau 2010-10-07 12:55 ` [PATCH v3] " Felix Fietkau 0 siblings, 1 reply; 6+ messages in thread From: Felix Fietkau @ 2010-10-07 12:46 UTC (permalink / raw) To: Luis R. Rodriguez; +Cc: linux-wireless Signed-off-by: Felix Fietkau <nbd@openwrt.org> --- v2: - fix genl_unregister_family wrapper (removes the family from the internal list) - fix error handling in doit ops --- a/include/linux/compat-2.6.37.h +++ b/include/linux/compat-2.6.37.h @@ -45,6 +45,68 @@ static inline void skb_checksum_none_ass #define pcmcia_enable_device(link) pcmcia_request_configuration(link, &link->conf) +#include <net/genetlink.h> + +struct compat_genl_info { + struct genl_info *info; + + u32 snd_seq; + u32 snd_pid; + struct genlmsghdr *genlhdr; + struct nlattr **attrs; + void *user_ptr[2]; +}; +#define genl_info compat_genl_info + +struct compat_genl_ops { + struct genl_ops ops; + + u8 cmd; + u8 internal_flags; + unsigned int flags; + const struct nla_policy *policy; + + int (*doit)(struct sk_buff *skb, struct genl_info *info); + int (*dumpit)(struct sk_buff *skb, struct netlink_callback *cb); + int (*done)(struct netlink_callback *cb); +}; +#define genl_ops compat_genl_ops + +struct compat_genl_family { + struct genl_family family; + + struct list_head list; + + unsigned int id, hdrsize, version, maxattr; + const char *name; + bool netnsok; + + struct nlattr **attrbuf; + + int (*pre_doit)(struct genl_ops *ops, struct sk_buff *skb, + struct genl_info *info); + + void (*post_doit)(struct genl_ops *ops, struct sk_buff *skb, + struct genl_info *info); +}; + +#define genl_family compat_genl_family + +#define genl_register_family_with_ops compat_genl_register_family_with_ops + +int genl_register_family_with_ops(struct genl_family *family, + struct genl_ops *ops, size_t n_ops); + +#define genl_unregister_family compat_genl_unregister_family + +int genl_unregister_family(struct genl_family *family); + +#define genl_info_net(_info) genl_info_net((_info)->info) +#define genlmsg_reply(_msg, _info) genlmsg_reply(_msg, (_info)->info) +#define genlmsg_put(_skb, _pid, _seq, _fam, _flags, _cmd) genlmsg_put(_skb, _pid, _seq, &(_fam)->family, _flags, _cmd) +#define genl_register_mc_group(_fam, _grp) genl_register_mc_group(&(_fam)->family, _grp) +#define genl_unregister_mc_group(_fam, _grp) genl_unregister_mc_group(&(_fam)->family, _grp) + #endif /* (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,37)) */ #endif /* LINUX_26_37_COMPAT_H */ --- a/compat/compat-2.6.37.c +++ b/compat/compat-2.6.37.c @@ -42,4 +42,114 @@ EXPORT_SYMBOL_GPL(net_ns_type_operations #endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,35)*/ +#undef genl_info +#undef genl_unregister_family + +static LIST_HEAD(compat_nl_fam); + +static struct genl_ops *genl_get_cmd(u8 cmd, struct genl_family *family) +{ + struct genl_ops *ops; + + list_for_each_entry(ops, &family->family.ops_list, ops.ops_list) + if (ops->cmd == cmd) + return ops; + + return NULL; +} + + +static int nl_doit_wrapper(struct sk_buff *skb, struct genl_info *info) +{ + struct compat_genl_info compat_info; + struct genl_family *family; + struct genl_ops *ops; + int err; + + list_for_each_entry(family, &compat_nl_fam, list) { + if (family->id == info->nlhdr->nlmsg_type) + goto found; + } + return -ENOENT; + +found: + ops = genl_get_cmd(info->genlhdr->cmd, family); + if (!ops) + return -ENOENT; + + memset(&compat_info.user_ptr, 0, sizeof(compat_info.user_ptr)); + compat_info.info = info; +#define __copy(_field) compat_info._field = info->_field + __copy(snd_seq); + __copy(snd_pid); + __copy(genlhdr); + __copy(attrs); +#undef __copy + if (family->pre_doit) { + err = family->pre_doit(ops, skb, &compat_info); + if (err) + return err; + } + + err = ops->doit(skb, &compat_info); + + if (family->post_doit) + family->post_doit(ops, skb, &compat_info); + + return err; +} + +int compat_genl_register_family_with_ops(struct genl_family *family, + struct genl_ops *ops, size_t n_ops) +{ + int i, ret; + +#define __copy(_field) family->family._field = family->_field + __copy(id); + __copy(hdrsize); + __copy(version); + __copy(maxattr); + strncpy(family->family.name, family->name, sizeof(family->family.name)); +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,32)) + __copy(netnsok); +#endif +#undef __copy + + ret = genl_register_family(&family->family); + if (ret < 0) + return ret; + + family->attrbuf = family->family.attrbuf; + family->id = family->family.id; + + for (i = 0; i < n_ops; i++) { +#define __copy(_field) ops[i].ops._field = ops[i]._field + __copy(cmd); + __copy(flags); + __copy(policy); + __copy(dumpit); + __copy(done); +#undef __copy + ops[i].ops.doit = nl_doit_wrapper; + ret = genl_register_ops(&family->family, &ops[i].ops); + if (ret < 0) + goto error_ops; + } + list_add(&family->list, &compat_nl_fam); + + return ret; + +error_ops: + compat_genl_unregister_family(family); + return ret; +} +EXPORT_SYMBOL(compat_genl_register_family_with_ops); + +int compat_genl_unregister_family(struct genl_family *family) +{ + list_del(&family->list); + return genl_unregister_family(&family->family); +} +EXPORT_SYMBOL(compat_genl_unregister_family); + #endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2,6,37) */ ^ permalink raw reply [flat|nested] 6+ messages in thread
* [PATCH v3] compat: backport netlink changes used in the nl80211 cleanup 2010-10-07 12:46 ` [PATCH v2] " Felix Fietkau @ 2010-10-07 12:55 ` Felix Fietkau 2010-10-07 18:39 ` Johannes Berg 2010-10-07 19:56 ` [PATCH v4] " Felix Fietkau 0 siblings, 2 replies; 6+ messages in thread From: Felix Fietkau @ 2010-10-07 12:55 UTC (permalink / raw) To: Luis R. Rodriguez; +Cc: linux-wireless Signed-off-by: Felix Fietkau <nbd@openwrt.org> --- v2: - fix genl_unregister_family wrapper (removes the family from the internal list) - fix error handling in doit ops v3: - fix a theoretical race in family unregister --- a/include/linux/compat-2.6.37.h +++ b/include/linux/compat-2.6.37.h @@ -45,6 +45,68 @@ static inline void skb_checksum_none_ass #define pcmcia_enable_device(link) pcmcia_request_configuration(link, &link->conf) +#include <net/genetlink.h> + +struct compat_genl_info { + struct genl_info *info; + + u32 snd_seq; + u32 snd_pid; + struct genlmsghdr *genlhdr; + struct nlattr **attrs; + void *user_ptr[2]; +}; +#define genl_info compat_genl_info + +struct compat_genl_ops { + struct genl_ops ops; + + u8 cmd; + u8 internal_flags; + unsigned int flags; + const struct nla_policy *policy; + + int (*doit)(struct sk_buff *skb, struct genl_info *info); + int (*dumpit)(struct sk_buff *skb, struct netlink_callback *cb); + int (*done)(struct netlink_callback *cb); +}; +#define genl_ops compat_genl_ops + +struct compat_genl_family { + struct genl_family family; + + struct list_head list; + + unsigned int id, hdrsize, version, maxattr; + const char *name; + bool netnsok; + + struct nlattr **attrbuf; + + int (*pre_doit)(struct genl_ops *ops, struct sk_buff *skb, + struct genl_info *info); + + void (*post_doit)(struct genl_ops *ops, struct sk_buff *skb, + struct genl_info *info); +}; + +#define genl_family compat_genl_family + +#define genl_register_family_with_ops compat_genl_register_family_with_ops + +int genl_register_family_with_ops(struct genl_family *family, + struct genl_ops *ops, size_t n_ops); + +#define genl_unregister_family compat_genl_unregister_family + +int genl_unregister_family(struct genl_family *family); + +#define genl_info_net(_info) genl_info_net((_info)->info) +#define genlmsg_reply(_msg, _info) genlmsg_reply(_msg, (_info)->info) +#define genlmsg_put(_skb, _pid, _seq, _fam, _flags, _cmd) genlmsg_put(_skb, _pid, _seq, &(_fam)->family, _flags, _cmd) +#define genl_register_mc_group(_fam, _grp) genl_register_mc_group(&(_fam)->family, _grp) +#define genl_unregister_mc_group(_fam, _grp) genl_unregister_mc_group(&(_fam)->family, _grp) + #endif /* (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,37)) */ #endif /* LINUX_26_37_COMPAT_H */ --- a/compat/compat-2.6.37.c +++ b/compat/compat-2.6.37.c @@ -42,4 +42,116 @@ EXPORT_SYMBOL_GPL(net_ns_type_operations #endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,35)*/ +#undef genl_info +#undef genl_unregister_family + +static LIST_HEAD(compat_nl_fam); + +static struct genl_ops *genl_get_cmd(u8 cmd, struct genl_family *family) +{ + struct genl_ops *ops; + + list_for_each_entry(ops, &family->family.ops_list, ops.ops_list) + if (ops->cmd == cmd) + return ops; + + return NULL; +} + + +static int nl_doit_wrapper(struct sk_buff *skb, struct genl_info *info) +{ + struct compat_genl_info compat_info; + struct genl_family *family; + struct genl_ops *ops; + int err; + + list_for_each_entry(family, &compat_nl_fam, list) { + if (family->id == info->nlhdr->nlmsg_type) + goto found; + } + return -ENOENT; + +found: + ops = genl_get_cmd(info->genlhdr->cmd, family); + if (!ops) + return -ENOENT; + + memset(&compat_info.user_ptr, 0, sizeof(compat_info.user_ptr)); + compat_info.info = info; +#define __copy(_field) compat_info._field = info->_field + __copy(snd_seq); + __copy(snd_pid); + __copy(genlhdr); + __copy(attrs); +#undef __copy + if (family->pre_doit) { + err = family->pre_doit(ops, skb, &compat_info); + if (err) + return err; + } + + err = ops->doit(skb, &compat_info); + + if (family->post_doit) + family->post_doit(ops, skb, &compat_info); + + return err; +} + +int compat_genl_register_family_with_ops(struct genl_family *family, + struct genl_ops *ops, size_t n_ops) +{ + int i, ret; + +#define __copy(_field) family->family._field = family->_field + __copy(id); + __copy(hdrsize); + __copy(version); + __copy(maxattr); + strncpy(family->family.name, family->name, sizeof(family->family.name)); +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,32)) + __copy(netnsok); +#endif +#undef __copy + + ret = genl_register_family(&family->family); + if (ret < 0) + return ret; + + family->attrbuf = family->family.attrbuf; + family->id = family->family.id; + + for (i = 0; i < n_ops; i++) { +#define __copy(_field) ops[i].ops._field = ops[i]._field + __copy(cmd); + __copy(flags); + __copy(policy); + __copy(dumpit); + __copy(done); +#undef __copy + ops[i].ops.doit = nl_doit_wrapper; + ret = genl_register_ops(&family->family, &ops[i].ops); + if (ret < 0) + goto error_ops; + } + list_add(&family->list, &compat_nl_fam); + + return ret; + +error_ops: + compat_genl_unregister_family(family); + return ret; +} +EXPORT_SYMBOL(compat_genl_register_family_with_ops); + +int compat_genl_unregister_family(struct genl_family *family) +{ + int err; + err = genl_unregister_family(&family->family); + list_del(&family->list); + return err; +} +EXPORT_SYMBOL(compat_genl_unregister_family); + #endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2,6,37) */ ^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH v3] compat: backport netlink changes used in the nl80211 cleanup 2010-10-07 12:55 ` [PATCH v3] " Felix Fietkau @ 2010-10-07 18:39 ` Johannes Berg 2010-10-07 19:56 ` [PATCH v4] " Felix Fietkau 1 sibling, 0 replies; 6+ messages in thread From: Johannes Berg @ 2010-10-07 18:39 UTC (permalink / raw) To: Felix Fietkau; +Cc: Luis R. Rodriguez, linux-wireless On Thu, 2010-10-07 at 14:55 +0200, Felix Fietkau wrote: > +#define genl_info_net(_info) genl_info_net((_info)->info) Need this instead: #if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,32) /* compat for even older kernels already defines this to &init_net */ #define genl_info_net(_info) genl_info_net((_info)->info) #endif johannes ^ permalink raw reply [flat|nested] 6+ messages in thread
* [PATCH v4] compat: backport netlink changes used in the nl80211 cleanup 2010-10-07 12:55 ` [PATCH v3] " Felix Fietkau 2010-10-07 18:39 ` Johannes Berg @ 2010-10-07 19:56 ` Felix Fietkau 2010-10-07 21:48 ` Luis R. Rodriguez 1 sibling, 1 reply; 6+ messages in thread From: Felix Fietkau @ 2010-10-07 19:56 UTC (permalink / raw) To: Luis R. Rodriguez; +Cc: linux-wireless Signed-off-by: Felix Fietkau <nbd@openwrt.org> --- v2: - fix genl_unregister_family wrapper (removes the family from the internal list) - fix error handling in doit ops v3: - fix a theoretical race in family unregister v4: - remove old genl_register_family_with_ops implementation - fix genl_info_net redefinition tested on 2.6.30 --- a/include/linux/compat-2.6.37.h +++ b/include/linux/compat-2.6.37.h @@ -45,6 +45,71 @@ static inline void skb_checksum_none_ass #define pcmcia_enable_device(link) pcmcia_request_configuration(link, &link->conf) +#include <net/genetlink.h> + +struct compat_genl_info { + struct genl_info *info; + + u32 snd_seq; + u32 snd_pid; + struct genlmsghdr *genlhdr; + struct nlattr **attrs; + void *user_ptr[2]; +}; +#define genl_info compat_genl_info + +struct compat_genl_ops { + struct genl_ops ops; + + u8 cmd; + u8 internal_flags; + unsigned int flags; + const struct nla_policy *policy; + + int (*doit)(struct sk_buff *skb, struct genl_info *info); + int (*dumpit)(struct sk_buff *skb, struct netlink_callback *cb); + int (*done)(struct netlink_callback *cb); +}; +#define genl_ops compat_genl_ops + +struct compat_genl_family { + struct genl_family family; + + struct list_head list; + + unsigned int id, hdrsize, version, maxattr; + const char *name; + bool netnsok; + + struct nlattr **attrbuf; + + int (*pre_doit)(struct genl_ops *ops, struct sk_buff *skb, + struct genl_info *info); + + void (*post_doit)(struct genl_ops *ops, struct sk_buff *skb, + struct genl_info *info); +}; + +#define genl_family compat_genl_family + +#define genl_register_family_with_ops compat_genl_register_family_with_ops + +int genl_register_family_with_ops(struct genl_family *family, + struct genl_ops *ops, size_t n_ops); + +#define genl_unregister_family compat_genl_unregister_family + +int genl_unregister_family(struct genl_family *family); + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,32)) +#define genl_info_net(_info) genl_info_net((_info)->info) +#endif + +#define genlmsg_reply(_msg, _info) genlmsg_reply(_msg, (_info)->info) +#define genlmsg_put(_skb, _pid, _seq, _fam, _flags, _cmd) genlmsg_put(_skb, _pid, _seq, &(_fam)->family, _flags, _cmd) +#define genl_register_mc_group(_fam, _grp) genl_register_mc_group(&(_fam)->family, _grp) +#define genl_unregister_mc_group(_fam, _grp) genl_unregister_mc_group(&(_fam)->family, _grp) + #endif /* (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,37)) */ #endif /* LINUX_26_37_COMPAT_H */ --- a/compat/compat-2.6.37.c +++ b/compat/compat-2.6.37.c @@ -42,4 +42,116 @@ EXPORT_SYMBOL_GPL(net_ns_type_operations #endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,35)*/ +#undef genl_info +#undef genl_unregister_family + +static LIST_HEAD(compat_nl_fam); + +static struct genl_ops *genl_get_cmd(u8 cmd, struct genl_family *family) +{ + struct genl_ops *ops; + + list_for_each_entry(ops, &family->family.ops_list, ops.ops_list) + if (ops->cmd == cmd) + return ops; + + return NULL; +} + + +static int nl_doit_wrapper(struct sk_buff *skb, struct genl_info *info) +{ + struct compat_genl_info compat_info; + struct genl_family *family; + struct genl_ops *ops; + int err; + + list_for_each_entry(family, &compat_nl_fam, list) { + if (family->id == info->nlhdr->nlmsg_type) + goto found; + } + return -ENOENT; + +found: + ops = genl_get_cmd(info->genlhdr->cmd, family); + if (!ops) + return -ENOENT; + + memset(&compat_info.user_ptr, 0, sizeof(compat_info.user_ptr)); + compat_info.info = info; +#define __copy(_field) compat_info._field = info->_field + __copy(snd_seq); + __copy(snd_pid); + __copy(genlhdr); + __copy(attrs); +#undef __copy + if (family->pre_doit) { + err = family->pre_doit(ops, skb, &compat_info); + if (err) + return err; + } + + err = ops->doit(skb, &compat_info); + + if (family->post_doit) + family->post_doit(ops, skb, &compat_info); + + return err; +} + +int compat_genl_register_family_with_ops(struct genl_family *family, + struct genl_ops *ops, size_t n_ops) +{ + int i, ret; + +#define __copy(_field) family->family._field = family->_field + __copy(id); + __copy(hdrsize); + __copy(version); + __copy(maxattr); + strncpy(family->family.name, family->name, sizeof(family->family.name)); +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,32)) + __copy(netnsok); +#endif +#undef __copy + + ret = genl_register_family(&family->family); + if (ret < 0) + return ret; + + family->attrbuf = family->family.attrbuf; + family->id = family->family.id; + + for (i = 0; i < n_ops; i++) { +#define __copy(_field) ops[i].ops._field = ops[i]._field + __copy(cmd); + __copy(flags); + __copy(policy); + __copy(dumpit); + __copy(done); +#undef __copy + ops[i].ops.doit = nl_doit_wrapper; + ret = genl_register_ops(&family->family, &ops[i].ops); + if (ret < 0) + goto error_ops; + } + list_add(&family->list, &compat_nl_fam); + + return ret; + +error_ops: + compat_genl_unregister_family(family); + return ret; +} +EXPORT_SYMBOL(compat_genl_register_family_with_ops); + +int compat_genl_unregister_family(struct genl_family *family) +{ + int err; + err = genl_unregister_family(&family->family); + list_del(&family->list); + return err; +} +EXPORT_SYMBOL(compat_genl_unregister_family); + #endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2,6,37) */ --- a/compat/compat-2.6.31.c +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Copyright 2007 Luis R. Rodriguez <mcgrof@winlab.rutgers.edu> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * Compatibility file for Linux wireless for kernels 2.6.31. - */ - -#include <linux/compat.h> - -#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,31)) - -#include <linux/netdevice.h> - -/** - * genl_register_family_with_ops - register a generic netlink family - * @family: generic netlink family - * @ops: operations to be registered - * @n_ops: number of elements to register - * - * Registers the specified family and operations from the specified table. - * Only one family may be registered with the same family name or identifier. - * - * The family id may equal GENL_ID_GENERATE causing an unique id to - * be automatically generated and assigned. - * - * Either a doit or dumpit callback must be specified for every registered - * operation or the function will fail. Only one operation structure per - * command identifier may be registered. - * - * See include/net/genetlink.h for more documenation on the operations - * structure. - * - * This is equivalent to calling genl_register_family() followed by - * genl_register_ops() for every operation entry in the table taking - * care to unregister the family on error path. - * - * Return 0 on success or a negative error code. - */ -int genl_register_family_with_ops(struct genl_family *family, - struct genl_ops *ops, size_t n_ops) -{ - int err, i; - - err = genl_register_family(family); - if (err) - return err; - - for (i = 0; i < n_ops; ++i, ++ops) { - err = genl_register_ops(family, ops); - if (err) - goto err_out; - } - return 0; -err_out: - genl_unregister_family(family); - return err; -} -EXPORT_SYMBOL(genl_register_family_with_ops); - -#endif /* (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,31)) */ - --- a/include/linux/compat-2.6.31.h +++ b/include/linux/compat-2.6.31.h @@ -114,10 +114,6 @@ static inline struct rtable *skb_rtable( return (struct rtable *)skb_dst(skb); } -extern int genl_register_family_with_ops(struct genl_family *family, - struct genl_ops *ops, size_t n_ops); - - /* Backport threaded IRQ support */ static inline --- a/compat/Makefile +++ b/compat/Makefile @@ -23,7 +23,6 @@ compat-$(CONFIG_COMPAT_KERNEL_27) += com compat-$(CONFIG_COMPAT_KERNEL_28) += compat-2.6.28.o compat-$(CONFIG_COMPAT_KERNEL_29) += compat-2.6.29.o compat-$(CONFIG_COMPAT_KERNEL_30) += compat-2.6.30.o -compat-$(CONFIG_COMPAT_KERNEL_31) += compat-2.6.31.o compat-$(CONFIG_COMPAT_KERNEL_32) += compat-2.6.32.o compat-$(CONFIG_COMPAT_KERNEL_33) += compat-2.6.33.o compat-$(CONFIG_COMPAT_KERNEL_35) += compat-2.6.35.o ^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH v4] compat: backport netlink changes used in the nl80211 cleanup 2010-10-07 19:56 ` [PATCH v4] " Felix Fietkau @ 2010-10-07 21:48 ` Luis R. Rodriguez 0 siblings, 0 replies; 6+ messages in thread From: Luis R. Rodriguez @ 2010-10-07 21:48 UTC (permalink / raw) To: Felix Fietkau; +Cc: linux-wireless On Thu, Oct 7, 2010 at 12:56 PM, Felix Fietkau <nbd@openwrt.org> wrote: > Signed-off-by: Felix Fietkau <nbd@openwrt.org> applied, thanks!!! Luis ^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2010-10-07 21:48 UTC | newest] Thread overview: 6+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2010-10-07 11:59 [PATCH] compat: backport netlink changes used in the nl80211 cleanup Felix Fietkau 2010-10-07 12:46 ` [PATCH v2] " Felix Fietkau 2010-10-07 12:55 ` [PATCH v3] " Felix Fietkau 2010-10-07 18:39 ` Johannes Berg 2010-10-07 19:56 ` [PATCH v4] " Felix Fietkau 2010-10-07 21:48 ` Luis R. Rodriguez
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).