* [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).