/* SPDX-License-Identifier: GPL-2.0 */ /* Copyright (C) B.A.T.M.A.N. contributors: * * Marek Lindner, Simon Wunderlich * * This file contains macros for maintaining compatibility with older versions * of the Linux kernel. */ #ifndef _NET_BATMAN_ADV_COMPAT_NET_GENETLINK_H_ #define _NET_BATMAN_ADV_COMPAT_NET_GENETLINK_H_ #include #include_next #if LINUX_VERSION_IS_LESS(5, 10, 0) #if LINUX_VERSION_IS_LESS(5, 2, 0) enum genl_validate_flags { GENL_DONT_VALIDATE_STRICT = BIT(0), GENL_DONT_VALIDATE_DUMP = BIT(1), GENL_DONT_VALIDATE_DUMP_STRICT = BIT(2), }; #endif /* LINUX_VERSION_IS_LESS(5, 2, 0) */ struct batadv_genl_small_ops { 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); u8 cmd; u8 internal_flags; u8 flags; u8 validate; }; struct batadv_genl_family { /* data handled by the actual kernel */ struct genl_family family; /* data which has to be copied to family by * batadv_genl_register_family */ unsigned int hdrsize; char name[GENL_NAMSIZ]; unsigned int version; unsigned int maxattr; const struct nla_policy *policy; bool netnsok; 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); const struct batadv_genl_small_ops *small_ops; const struct genl_multicast_group *mcgrps; unsigned int n_small_ops; unsigned int n_mcgrps; struct module *module; /* allocated by batadv_genl_register_family and free'd by * batadv_genl_unregister_family. Used to modify the usually read-only * ops */ struct genl_ops *copy_ops; }; static inline int batadv_genl_register_family(struct batadv_genl_family *family) { struct genl_ops *ops; unsigned int i; family->family.hdrsize = family->hdrsize; strncpy(family->family.name, family->name, sizeof(family->family.name)); family->family.version = family->version; family->family.maxattr = family->maxattr; family->family.netnsok = family->netnsok; family->family.pre_doit = family->pre_doit; family->family.post_doit = family->post_doit; family->family.mcgrps = family->mcgrps; family->family.n_ops = family->n_small_ops; family->family.n_mcgrps = family->n_mcgrps; family->family.module = family->module; ops = kzalloc(sizeof(*ops) * family->n_small_ops, GFP_KERNEL); if (!ops) return -ENOMEM; for (i = 0; i < family->family.n_ops; i++) { ops[i].doit = family->small_ops[i].doit; ops[i].dumpit = family->small_ops[i].dumpit; ops[i].done = family->small_ops[i].done; ops[i].cmd = family->small_ops[i].cmd; ops[i].internal_flags = family->small_ops[i].internal_flags; ops[i].flags = family->small_ops[i].flags; #if LINUX_VERSION_IS_GEQ(5, 2, 0) ops[i].validate = family->small_ops[i].validate; #else ops[i].policy = family->policy; #endif } #if LINUX_VERSION_IS_GEQ(5, 2, 0) family->family.policy = family->policy; #endif family->family.ops = ops; family->copy_ops = ops; return genl_register_family(&family->family); } typedef struct genl_ops batadv_genl_ops_old; #define batadv_pre_doit(__x, __y, __z) \ batadv_pre_doit(const batadv_genl_ops_old *ops, __y, __z) #define batadv_post_doit(__x, __y, __z) \ batadv_post_doit(const batadv_genl_ops_old *ops, __y, __z) #define genl_small_ops batadv_genl_small_ops #define genl_family batadv_genl_family #define genl_register_family(family) \ batadv_genl_register_family((family)) static inline void batadv_genl_unregister_family(struct batadv_genl_family *family) { genl_unregister_family(&family->family); kfree(family->copy_ops); } #define genl_unregister_family(family) \ batadv_genl_unregister_family((family)) #define genlmsg_put(_skb, _pid, _seq, _family, _flags, _cmd) \ genlmsg_put(_skb, _pid, _seq, &(_family)->family, _flags, _cmd) #define genlmsg_multicast_netns(_family, _net, _skb, _portid, _group, _flags) \ genlmsg_multicast_netns(&(_family)->family, _net, _skb, _portid, \ _group, _flags) #endif /* LINUX_VERSION_IS_LESS(5, 10, 0) */ #if LINUX_VERSION_IS_LESS(6, 2, 0) #define genl_split_ops genl_ops #endif /* LINUX_VERSION_IS_LESS(6, 2, 0) */ #endif /* _NET_BATMAN_ADV_COMPAT_NET_GENETLINK_H_ */