On Tue, Oct 18, 2016 at 11:28:23PM +0200, Sven Eckelmann wrote:
> Doesn't seem to scale. Especially when we think about batadv_netlink_ops
> which should also be const. It is currently not const because of the
> Linux <= 3.13 workaround.

Hm, okay, batadv_netlink_ops is a little more tricky/larger, yes.
What about a memcpy'ing approach with BUILD_BUG_ON()'s as
safe-guards like this:


diff --git a/compat-include/net/genetlink.h b/compat-include/net/genetlink.h
index 72a8991..f16bf35 100644
--- a/compat-include/net/genetlink.h
+++ b/compat-include/net/genetlink.h
@@ -28,6 +28,9 @@
 
 #include <linux/export.h>
 
+static struct genl_ops __batadv_netlink_ops[12];
+static struct genl_multicast_group __batadv_netlink_mcgrps[1];
+
 struct batadv_genl_family {
        /* data handled by the actual kernel */
        struct genl_family family;
@@ -137,15 +140,23 @@ static inline int batadv_genl_register_family(struct 
genl_family *family)
        return ret;
 }
 
-static inline int
+static inline int __init
 batadv_genl_register_family_with_ops_grps(struct genl_family *family,
-                                         struct genl_ops *ops, size_t n_ops,
-                                         struct genl_multicast_group *mcgrps,
+                                         const struct genl_ops *ops, size_t 
n_ops,
+                                         const struct genl_multicast_group 
*mcgrps,
                                          size_t n_mcgrps)
 {
-       family->ops = ops;
+       BUILD_BUG_ON(ARRAY_SIZE(__batadv_netlink_ops) != n_ops);
+       BUILD_BUG_ON(ARRAY_SIZE(__batadv_netlink_mcgrps) != n_mcgrps);
+       BUILD_BUG_ON(sizeof(__batadv_netlink_ops) != sizeof(*ops) * n_ops);
+       BUILD_BUG_ON(sizeof(__batadv_netlink_mcgrps) != sizeof(*mcgrps) * 
n_mcgrps);
+
+       memcpy(__batadv_netlink_ops, ops, sizeof(__batadv_netlink_ops));
+       memcpy(__batadv_netlink_mcgrps, mcgrps, 
sizeof(__batadv_netlink_mcgrps));
+
+       family->ops = __batadv_netlink_ops;
        family->n_ops = n_ops;
-       family->mcgrps = mcgrps;
+       family->mcgrps = __batadv_netlink_mcgrps;
        family->n_mcgrps = n_mcgrps;
        family->module = THIS_MODULE;
 
diff --git a/net/batman-adv/netlink.c b/net/batman-adv/netlink.c
index 64cb6ac..aee20a3 100644
--- a/net/batman-adv/netlink.c
+++ b/net/batman-adv/netlink.c
@@ -534,7 +534,7 @@ batadv_netlink_dump_hardifs(struct sk_buff *msg, struct 
netlink_callback *cb)
        return msg->len;
 }
 
-static struct genl_ops batadv_netlink_ops[] = {
+static const struct genl_ops batadv_netlink_ops[] = {
        {
                .cmd = BATADV_CMD_GET_MESH_INFO,
                .flags = GENL_ADMIN_PERM,

Reply via email to