0001
0002 #ifndef _NFNETLINK_H
0003 #define _NFNETLINK_H
0004
0005 #include <linux/netlink.h>
0006 #include <linux/capability.h>
0007 #include <net/netlink.h>
0008 #include <uapi/linux/netfilter/nfnetlink.h>
0009
0010 struct nfnl_info {
0011 struct net *net;
0012 struct sock *sk;
0013 const struct nlmsghdr *nlh;
0014 const struct nfgenmsg *nfmsg;
0015 struct netlink_ext_ack *extack;
0016 };
0017
0018 enum nfnl_callback_type {
0019 NFNL_CB_UNSPEC = 0,
0020 NFNL_CB_MUTEX,
0021 NFNL_CB_RCU,
0022 NFNL_CB_BATCH,
0023 };
0024
0025 struct nfnl_callback {
0026 int (*call)(struct sk_buff *skb, const struct nfnl_info *info,
0027 const struct nlattr * const cda[]);
0028 const struct nla_policy *policy;
0029 enum nfnl_callback_type type;
0030 __u16 attr_count;
0031 };
0032
0033 enum nfnl_abort_action {
0034 NFNL_ABORT_NONE = 0,
0035 NFNL_ABORT_AUTOLOAD,
0036 NFNL_ABORT_VALIDATE,
0037 };
0038
0039 struct nfnetlink_subsystem {
0040 const char *name;
0041 __u8 subsys_id;
0042 __u8 cb_count;
0043 const struct nfnl_callback *cb;
0044 struct module *owner;
0045 int (*commit)(struct net *net, struct sk_buff *skb);
0046 int (*abort)(struct net *net, struct sk_buff *skb,
0047 enum nfnl_abort_action action);
0048 void (*cleanup)(struct net *net);
0049 bool (*valid_genid)(struct net *net, u32 genid);
0050 };
0051
0052 int nfnetlink_subsys_register(const struct nfnetlink_subsystem *n);
0053 int nfnetlink_subsys_unregister(const struct nfnetlink_subsystem *n);
0054
0055 int nfnetlink_has_listeners(struct net *net, unsigned int group);
0056 int nfnetlink_send(struct sk_buff *skb, struct net *net, u32 portid,
0057 unsigned int group, int echo, gfp_t flags);
0058 int nfnetlink_set_err(struct net *net, u32 portid, u32 group, int error);
0059 int nfnetlink_unicast(struct sk_buff *skb, struct net *net, u32 portid);
0060 void nfnetlink_broadcast(struct net *net, struct sk_buff *skb, __u32 portid,
0061 __u32 group, gfp_t allocation);
0062
0063 static inline u16 nfnl_msg_type(u8 subsys, u8 msg_type)
0064 {
0065 return subsys << 8 | msg_type;
0066 }
0067
0068 static inline void nfnl_fill_hdr(struct nlmsghdr *nlh, u8 family, u8 version,
0069 __be16 res_id)
0070 {
0071 struct nfgenmsg *nfmsg;
0072
0073 nfmsg = nlmsg_data(nlh);
0074 nfmsg->nfgen_family = family;
0075 nfmsg->version = version;
0076 nfmsg->res_id = res_id;
0077 }
0078
0079 static inline struct nlmsghdr *nfnl_msg_put(struct sk_buff *skb, u32 portid,
0080 u32 seq, int type, int flags,
0081 u8 family, u8 version,
0082 __be16 res_id)
0083 {
0084 struct nlmsghdr *nlh;
0085
0086 nlh = nlmsg_put(skb, portid, seq, type, sizeof(struct nfgenmsg), flags);
0087 if (!nlh)
0088 return NULL;
0089
0090 nfnl_fill_hdr(nlh, family, version, res_id);
0091
0092 return nlh;
0093 }
0094
0095 void nfnl_lock(__u8 subsys_id);
0096 void nfnl_unlock(__u8 subsys_id);
0097 #ifdef CONFIG_PROVE_LOCKING
0098 bool lockdep_nfnl_is_held(__u8 subsys_id);
0099 #else
0100 static inline bool lockdep_nfnl_is_held(__u8 subsys_id)
0101 {
0102 return true;
0103 }
0104 #endif
0105
0106 #define MODULE_ALIAS_NFNL_SUBSYS(subsys) \
0107 MODULE_ALIAS("nfnetlink-subsys-" __stringify(subsys))
0108
0109 #endif