Commit 50f2db9e authored by Pablo Neira Ayuso's avatar Pablo Neira Ayuso

netfilter: nfnetlink: consolidate callback types

Add enum nfnl_callback_type to identify the callback type to provide one
single callback.
Signed-off-by: default avatarPablo Neira Ayuso <pablo@netfilter.org>
parent 7dab8ee3
...@@ -14,15 +14,19 @@ struct nfnl_info { ...@@ -14,15 +14,19 @@ struct nfnl_info {
struct netlink_ext_ack *extack; struct netlink_ext_ack *extack;
}; };
enum nfnl_callback_type {
NFNL_CB_UNSPEC = 0,
NFNL_CB_MUTEX,
NFNL_CB_RCU,
NFNL_CB_BATCH,
};
struct nfnl_callback { struct nfnl_callback {
int (*call)(struct sk_buff *skb, const struct nfnl_info *info, int (*call)(struct sk_buff *skb, const struct nfnl_info *info,
const struct nlattr * const cda[]); const struct nlattr * const cda[]);
int (*call_rcu)(struct sk_buff *skb, const struct nfnl_info *info, const struct nla_policy *policy;
const struct nlattr * const cda[]); enum nfnl_callback_type type;
int (*call_batch)(struct sk_buff *skb, const struct nfnl_info *info, __u16 attr_count;
const struct nlattr * const cda[]);
const struct nla_policy *policy; /* netlink attribute policy */
const u_int16_t attr_count; /* number of nlattr's */
}; };
enum nfnl_abort_action { enum nfnl_abort_action {
......
...@@ -2108,80 +2108,96 @@ static int ip_set_byindex(struct sk_buff *skb, const struct nfnl_info *info, ...@@ -2108,80 +2108,96 @@ static int ip_set_byindex(struct sk_buff *skb, const struct nfnl_info *info,
static const struct nfnl_callback ip_set_netlink_subsys_cb[IPSET_MSG_MAX] = { static const struct nfnl_callback ip_set_netlink_subsys_cb[IPSET_MSG_MAX] = {
[IPSET_CMD_NONE] = { [IPSET_CMD_NONE] = {
.call = ip_set_none, .call = ip_set_none,
.type = NFNL_CB_MUTEX,
.attr_count = IPSET_ATTR_CMD_MAX, .attr_count = IPSET_ATTR_CMD_MAX,
}, },
[IPSET_CMD_CREATE] = { [IPSET_CMD_CREATE] = {
.call = ip_set_create, .call = ip_set_create,
.type = NFNL_CB_MUTEX,
.attr_count = IPSET_ATTR_CMD_MAX, .attr_count = IPSET_ATTR_CMD_MAX,
.policy = ip_set_create_policy, .policy = ip_set_create_policy,
}, },
[IPSET_CMD_DESTROY] = { [IPSET_CMD_DESTROY] = {
.call = ip_set_destroy, .call = ip_set_destroy,
.type = NFNL_CB_MUTEX,
.attr_count = IPSET_ATTR_CMD_MAX, .attr_count = IPSET_ATTR_CMD_MAX,
.policy = ip_set_setname_policy, .policy = ip_set_setname_policy,
}, },
[IPSET_CMD_FLUSH] = { [IPSET_CMD_FLUSH] = {
.call = ip_set_flush, .call = ip_set_flush,
.type = NFNL_CB_MUTEX,
.attr_count = IPSET_ATTR_CMD_MAX, .attr_count = IPSET_ATTR_CMD_MAX,
.policy = ip_set_setname_policy, .policy = ip_set_setname_policy,
}, },
[IPSET_CMD_RENAME] = { [IPSET_CMD_RENAME] = {
.call = ip_set_rename, .call = ip_set_rename,
.type = NFNL_CB_MUTEX,
.attr_count = IPSET_ATTR_CMD_MAX, .attr_count = IPSET_ATTR_CMD_MAX,
.policy = ip_set_setname2_policy, .policy = ip_set_setname2_policy,
}, },
[IPSET_CMD_SWAP] = { [IPSET_CMD_SWAP] = {
.call = ip_set_swap, .call = ip_set_swap,
.type = NFNL_CB_MUTEX,
.attr_count = IPSET_ATTR_CMD_MAX, .attr_count = IPSET_ATTR_CMD_MAX,
.policy = ip_set_setname2_policy, .policy = ip_set_setname2_policy,
}, },
[IPSET_CMD_LIST] = { [IPSET_CMD_LIST] = {
.call = ip_set_dump, .call = ip_set_dump,
.type = NFNL_CB_MUTEX,
.attr_count = IPSET_ATTR_CMD_MAX, .attr_count = IPSET_ATTR_CMD_MAX,
.policy = ip_set_dump_policy, .policy = ip_set_dump_policy,
}, },
[IPSET_CMD_SAVE] = { [IPSET_CMD_SAVE] = {
.call = ip_set_dump, .call = ip_set_dump,
.type = NFNL_CB_MUTEX,
.attr_count = IPSET_ATTR_CMD_MAX, .attr_count = IPSET_ATTR_CMD_MAX,
.policy = ip_set_setname_policy, .policy = ip_set_setname_policy,
}, },
[IPSET_CMD_ADD] = { [IPSET_CMD_ADD] = {
.call = ip_set_uadd, .call = ip_set_uadd,
.type = NFNL_CB_MUTEX,
.attr_count = IPSET_ATTR_CMD_MAX, .attr_count = IPSET_ATTR_CMD_MAX,
.policy = ip_set_adt_policy, .policy = ip_set_adt_policy,
}, },
[IPSET_CMD_DEL] = { [IPSET_CMD_DEL] = {
.call = ip_set_udel, .call = ip_set_udel,
.type = NFNL_CB_MUTEX,
.attr_count = IPSET_ATTR_CMD_MAX, .attr_count = IPSET_ATTR_CMD_MAX,
.policy = ip_set_adt_policy, .policy = ip_set_adt_policy,
}, },
[IPSET_CMD_TEST] = { [IPSET_CMD_TEST] = {
.call = ip_set_utest, .call = ip_set_utest,
.type = NFNL_CB_MUTEX,
.attr_count = IPSET_ATTR_CMD_MAX, .attr_count = IPSET_ATTR_CMD_MAX,
.policy = ip_set_adt_policy, .policy = ip_set_adt_policy,
}, },
[IPSET_CMD_HEADER] = { [IPSET_CMD_HEADER] = {
.call = ip_set_header, .call = ip_set_header,
.type = NFNL_CB_MUTEX,
.attr_count = IPSET_ATTR_CMD_MAX, .attr_count = IPSET_ATTR_CMD_MAX,
.policy = ip_set_setname_policy, .policy = ip_set_setname_policy,
}, },
[IPSET_CMD_TYPE] = { [IPSET_CMD_TYPE] = {
.call = ip_set_type, .call = ip_set_type,
.type = NFNL_CB_MUTEX,
.attr_count = IPSET_ATTR_CMD_MAX, .attr_count = IPSET_ATTR_CMD_MAX,
.policy = ip_set_type_policy, .policy = ip_set_type_policy,
}, },
[IPSET_CMD_PROTOCOL] = { [IPSET_CMD_PROTOCOL] = {
.call = ip_set_protocol, .call = ip_set_protocol,
.type = NFNL_CB_MUTEX,
.attr_count = IPSET_ATTR_CMD_MAX, .attr_count = IPSET_ATTR_CMD_MAX,
.policy = ip_set_protocol_policy, .policy = ip_set_protocol_policy,
}, },
[IPSET_CMD_GET_BYNAME] = { [IPSET_CMD_GET_BYNAME] = {
.call = ip_set_byname, .call = ip_set_byname,
.type = NFNL_CB_MUTEX,
.attr_count = IPSET_ATTR_CMD_MAX, .attr_count = IPSET_ATTR_CMD_MAX,
.policy = ip_set_setname_policy, .policy = ip_set_setname_policy,
}, },
[IPSET_CMD_GET_BYINDEX] = { [IPSET_CMD_GET_BYINDEX] = {
.call = ip_set_byindex, .call = ip_set_byindex,
.type = NFNL_CB_MUTEX,
.attr_count = IPSET_ATTR_CMD_MAX, .attr_count = IPSET_ATTR_CMD_MAX,
.policy = ip_set_index_policy, .policy = ip_set_index_policy,
}, },
......
...@@ -3751,35 +3751,71 @@ static struct nf_exp_event_notifier ctnl_notifier_exp = { ...@@ -3751,35 +3751,71 @@ static struct nf_exp_event_notifier ctnl_notifier_exp = {
#endif #endif
static const struct nfnl_callback ctnl_cb[IPCTNL_MSG_MAX] = { static const struct nfnl_callback ctnl_cb[IPCTNL_MSG_MAX] = {
[IPCTNL_MSG_CT_NEW] = { .call = ctnetlink_new_conntrack, [IPCTNL_MSG_CT_NEW] = {
.attr_count = CTA_MAX, .call = ctnetlink_new_conntrack,
.policy = ct_nla_policy }, .type = NFNL_CB_MUTEX,
[IPCTNL_MSG_CT_GET] = { .call = ctnetlink_get_conntrack, .attr_count = CTA_MAX,
.attr_count = CTA_MAX, .policy = ct_nla_policy
.policy = ct_nla_policy }, },
[IPCTNL_MSG_CT_DELETE] = { .call = ctnetlink_del_conntrack, [IPCTNL_MSG_CT_GET] = {
.attr_count = CTA_MAX, .call = ctnetlink_get_conntrack,
.policy = ct_nla_policy }, .type = NFNL_CB_MUTEX,
[IPCTNL_MSG_CT_GET_CTRZERO] = { .call = ctnetlink_get_conntrack, .attr_count = CTA_MAX,
.attr_count = CTA_MAX, .policy = ct_nla_policy
.policy = ct_nla_policy }, },
[IPCTNL_MSG_CT_GET_STATS_CPU] = { .call = ctnetlink_stat_ct_cpu }, [IPCTNL_MSG_CT_DELETE] = {
[IPCTNL_MSG_CT_GET_STATS] = { .call = ctnetlink_stat_ct }, .call = ctnetlink_del_conntrack,
[IPCTNL_MSG_CT_GET_DYING] = { .call = ctnetlink_get_ct_dying }, .type = NFNL_CB_MUTEX,
[IPCTNL_MSG_CT_GET_UNCONFIRMED] = { .call = ctnetlink_get_ct_unconfirmed }, .attr_count = CTA_MAX,
.policy = ct_nla_policy
},
[IPCTNL_MSG_CT_GET_CTRZERO] = {
.call = ctnetlink_get_conntrack,
.type = NFNL_CB_MUTEX,
.attr_count = CTA_MAX,
.policy = ct_nla_policy
},
[IPCTNL_MSG_CT_GET_STATS_CPU] = {
.call = ctnetlink_stat_ct_cpu,
.type = NFNL_CB_MUTEX,
},
[IPCTNL_MSG_CT_GET_STATS] = {
.call = ctnetlink_stat_ct,
.type = NFNL_CB_MUTEX,
},
[IPCTNL_MSG_CT_GET_DYING] = {
.call = ctnetlink_get_ct_dying,
.type = NFNL_CB_MUTEX,
},
[IPCTNL_MSG_CT_GET_UNCONFIRMED] = {
.call = ctnetlink_get_ct_unconfirmed,
.type = NFNL_CB_MUTEX,
},
}; };
static const struct nfnl_callback ctnl_exp_cb[IPCTNL_MSG_EXP_MAX] = { static const struct nfnl_callback ctnl_exp_cb[IPCTNL_MSG_EXP_MAX] = {
[IPCTNL_MSG_EXP_GET] = { .call = ctnetlink_get_expect, [IPCTNL_MSG_EXP_GET] = {
.attr_count = CTA_EXPECT_MAX, .call = ctnetlink_get_expect,
.policy = exp_nla_policy }, .type = NFNL_CB_MUTEX,
[IPCTNL_MSG_EXP_NEW] = { .call = ctnetlink_new_expect, .attr_count = CTA_EXPECT_MAX,
.attr_count = CTA_EXPECT_MAX, .policy = exp_nla_policy
.policy = exp_nla_policy }, },
[IPCTNL_MSG_EXP_DELETE] = { .call = ctnetlink_del_expect, [IPCTNL_MSG_EXP_NEW] = {
.attr_count = CTA_EXPECT_MAX, .call = ctnetlink_new_expect,
.policy = exp_nla_policy }, .type = NFNL_CB_MUTEX,
[IPCTNL_MSG_EXP_GET_STATS_CPU] = { .call = ctnetlink_stat_exp_cpu }, .attr_count = CTA_EXPECT_MAX,
.policy = exp_nla_policy
},
[IPCTNL_MSG_EXP_DELETE] = {
.call = ctnetlink_del_expect,
.type = NFNL_CB_MUTEX,
.attr_count = CTA_EXPECT_MAX,
.policy = exp_nla_policy
},
[IPCTNL_MSG_EXP_GET_STATS_CPU] = {
.call = ctnetlink_stat_exp_cpu,
.type = NFNL_CB_MUTEX,
},
}; };
static const struct nfnetlink_subsystem ctnl_subsys = { static const struct nfnetlink_subsystem ctnl_subsys = {
......
...@@ -7554,115 +7554,138 @@ static int nf_tables_getgen(struct sk_buff *skb, const struct nfnl_info *info, ...@@ -7554,115 +7554,138 @@ static int nf_tables_getgen(struct sk_buff *skb, const struct nfnl_info *info,
static const struct nfnl_callback nf_tables_cb[NFT_MSG_MAX] = { static const struct nfnl_callback nf_tables_cb[NFT_MSG_MAX] = {
[NFT_MSG_NEWTABLE] = { [NFT_MSG_NEWTABLE] = {
.call_batch = nf_tables_newtable, .call = nf_tables_newtable,
.type = NFNL_CB_BATCH,
.attr_count = NFTA_TABLE_MAX, .attr_count = NFTA_TABLE_MAX,
.policy = nft_table_policy, .policy = nft_table_policy,
}, },
[NFT_MSG_GETTABLE] = { [NFT_MSG_GETTABLE] = {
.call_rcu = nf_tables_gettable, .call = nf_tables_gettable,
.type = NFNL_CB_RCU,
.attr_count = NFTA_TABLE_MAX, .attr_count = NFTA_TABLE_MAX,
.policy = nft_table_policy, .policy = nft_table_policy,
}, },
[NFT_MSG_DELTABLE] = { [NFT_MSG_DELTABLE] = {
.call_batch = nf_tables_deltable, .call = nf_tables_deltable,
.type = NFNL_CB_BATCH,
.attr_count = NFTA_TABLE_MAX, .attr_count = NFTA_TABLE_MAX,
.policy = nft_table_policy, .policy = nft_table_policy,
}, },
[NFT_MSG_NEWCHAIN] = { [NFT_MSG_NEWCHAIN] = {
.call_batch = nf_tables_newchain, .call = nf_tables_newchain,
.type = NFNL_CB_BATCH,
.attr_count = NFTA_CHAIN_MAX, .attr_count = NFTA_CHAIN_MAX,
.policy = nft_chain_policy, .policy = nft_chain_policy,
}, },
[NFT_MSG_GETCHAIN] = { [NFT_MSG_GETCHAIN] = {
.call_rcu = nf_tables_getchain, .call = nf_tables_getchain,
.type = NFNL_CB_RCU,
.attr_count = NFTA_CHAIN_MAX, .attr_count = NFTA_CHAIN_MAX,
.policy = nft_chain_policy, .policy = nft_chain_policy,
}, },
[NFT_MSG_DELCHAIN] = { [NFT_MSG_DELCHAIN] = {
.call_batch = nf_tables_delchain, .call = nf_tables_delchain,
.type = NFNL_CB_BATCH,
.attr_count = NFTA_CHAIN_MAX, .attr_count = NFTA_CHAIN_MAX,
.policy = nft_chain_policy, .policy = nft_chain_policy,
}, },
[NFT_MSG_NEWRULE] = { [NFT_MSG_NEWRULE] = {
.call_batch = nf_tables_newrule, .call = nf_tables_newrule,
.type = NFNL_CB_BATCH,
.attr_count = NFTA_RULE_MAX, .attr_count = NFTA_RULE_MAX,
.policy = nft_rule_policy, .policy = nft_rule_policy,
}, },
[NFT_MSG_GETRULE] = { [NFT_MSG_GETRULE] = {
.call_rcu = nf_tables_getrule, .call = nf_tables_getrule,
.type = NFNL_CB_RCU,
.attr_count = NFTA_RULE_MAX, .attr_count = NFTA_RULE_MAX,
.policy = nft_rule_policy, .policy = nft_rule_policy,
}, },
[NFT_MSG_DELRULE] = { [NFT_MSG_DELRULE] = {
.call_batch = nf_tables_delrule, .call = nf_tables_delrule,
.type = NFNL_CB_BATCH,
.attr_count = NFTA_RULE_MAX, .attr_count = NFTA_RULE_MAX,
.policy = nft_rule_policy, .policy = nft_rule_policy,
}, },
[NFT_MSG_NEWSET] = { [NFT_MSG_NEWSET] = {
.call_batch = nf_tables_newset, .call = nf_tables_newset,
.type = NFNL_CB_BATCH,
.attr_count = NFTA_SET_MAX, .attr_count = NFTA_SET_MAX,
.policy = nft_set_policy, .policy = nft_set_policy,
}, },
[NFT_MSG_GETSET] = { [NFT_MSG_GETSET] = {
.call_rcu = nf_tables_getset, .call = nf_tables_getset,
.type = NFNL_CB_RCU,
.attr_count = NFTA_SET_MAX, .attr_count = NFTA_SET_MAX,
.policy = nft_set_policy, .policy = nft_set_policy,
}, },
[NFT_MSG_DELSET] = { [NFT_MSG_DELSET] = {
.call_batch = nf_tables_delset, .call = nf_tables_delset,
.type = NFNL_CB_BATCH,
.attr_count = NFTA_SET_MAX, .attr_count = NFTA_SET_MAX,
.policy = nft_set_policy, .policy = nft_set_policy,
}, },
[NFT_MSG_NEWSETELEM] = { [NFT_MSG_NEWSETELEM] = {
.call_batch = nf_tables_newsetelem, .call = nf_tables_newsetelem,
.type = NFNL_CB_BATCH,
.attr_count = NFTA_SET_ELEM_LIST_MAX, .attr_count = NFTA_SET_ELEM_LIST_MAX,
.policy = nft_set_elem_list_policy, .policy = nft_set_elem_list_policy,
}, },
[NFT_MSG_GETSETELEM] = { [NFT_MSG_GETSETELEM] = {
.call_rcu = nf_tables_getsetelem, .call = nf_tables_getsetelem,
.type = NFNL_CB_RCU,
.attr_count = NFTA_SET_ELEM_LIST_MAX, .attr_count = NFTA_SET_ELEM_LIST_MAX,
.policy = nft_set_elem_list_policy, .policy = nft_set_elem_list_policy,
}, },
[NFT_MSG_DELSETELEM] = { [NFT_MSG_DELSETELEM] = {
.call_batch = nf_tables_delsetelem, .call = nf_tables_delsetelem,
.type = NFNL_CB_BATCH,
.attr_count = NFTA_SET_ELEM_LIST_MAX, .attr_count = NFTA_SET_ELEM_LIST_MAX,
.policy = nft_set_elem_list_policy, .policy = nft_set_elem_list_policy,
}, },
[NFT_MSG_GETGEN] = { [NFT_MSG_GETGEN] = {
.call_rcu = nf_tables_getgen, .call = nf_tables_getgen,
.type = NFNL_CB_RCU,
}, },
[NFT_MSG_NEWOBJ] = { [NFT_MSG_NEWOBJ] = {
.call_batch = nf_tables_newobj, .call = nf_tables_newobj,
.type = NFNL_CB_BATCH,
.attr_count = NFTA_OBJ_MAX, .attr_count = NFTA_OBJ_MAX,
.policy = nft_obj_policy, .policy = nft_obj_policy,
}, },
[NFT_MSG_GETOBJ] = { [NFT_MSG_GETOBJ] = {
.call_rcu = nf_tables_getobj, .call = nf_tables_getobj,
.type = NFNL_CB_RCU,
.attr_count = NFTA_OBJ_MAX, .attr_count = NFTA_OBJ_MAX,
.policy = nft_obj_policy, .policy = nft_obj_policy,
}, },
[NFT_MSG_DELOBJ] = { [NFT_MSG_DELOBJ] = {
.call_batch = nf_tables_delobj, .call = nf_tables_delobj,
.type = NFNL_CB_BATCH,
.attr_count = NFTA_OBJ_MAX, .attr_count = NFTA_OBJ_MAX,
.policy = nft_obj_policy, .policy = nft_obj_policy,
}, },
[NFT_MSG_GETOBJ_RESET] = { [NFT_MSG_GETOBJ_RESET] = {
.call_rcu = nf_tables_getobj, .call = nf_tables_getobj,
.type = NFNL_CB_RCU,
.attr_count = NFTA_OBJ_MAX, .attr_count = NFTA_OBJ_MAX,
.policy = nft_obj_policy, .policy = nft_obj_policy,
}, },
[NFT_MSG_NEWFLOWTABLE] = { [NFT_MSG_NEWFLOWTABLE] = {
.call_batch = nf_tables_newflowtable, .call = nf_tables_newflowtable,
.type = NFNL_CB_BATCH,
.attr_count = NFTA_FLOWTABLE_MAX, .attr_count = NFTA_FLOWTABLE_MAX,
.policy = nft_flowtable_policy, .policy = nft_flowtable_policy,
}, },
[NFT_MSG_GETFLOWTABLE] = { [NFT_MSG_GETFLOWTABLE] = {
.call_rcu = nf_tables_getflowtable, .call = nf_tables_getflowtable,
.type = NFNL_CB_RCU,
.attr_count = NFTA_FLOWTABLE_MAX, .attr_count = NFTA_FLOWTABLE_MAX,
.policy = nft_flowtable_policy, .policy = nft_flowtable_policy,
}, },
[NFT_MSG_DELFLOWTABLE] = { [NFT_MSG_DELFLOWTABLE] = {
.call_batch = nf_tables_delflowtable, .call = nf_tables_delflowtable,
.type = NFNL_CB_BATCH,
.attr_count = NFTA_FLOWTABLE_MAX, .attr_count = NFTA_FLOWTABLE_MAX,
.policy = nft_flowtable_policy, .policy = nft_flowtable_policy,
}, },
......
...@@ -273,23 +273,30 @@ static int nfnetlink_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh, ...@@ -273,23 +273,30 @@ static int nfnetlink_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh,
return err; return err;
} }
if (nc->call_rcu) { if (!nc->call) {
err = nc->call_rcu(skb, &info,
(const struct nlattr **)cda);
rcu_read_unlock(); rcu_read_unlock();
} else { return -EINVAL;
}
switch (nc->type) {
case NFNL_CB_RCU:
err = nc->call(skb, &info, (const struct nlattr **)cda);
rcu_read_unlock();
break;
case NFNL_CB_MUTEX:
rcu_read_unlock(); rcu_read_unlock();
nfnl_lock(subsys_id); nfnl_lock(subsys_id);
if (nfnl_dereference_protected(subsys_id) != ss || if (nfnl_dereference_protected(subsys_id) != ss ||
nfnetlink_find_client(type, ss) != nc) { nfnetlink_find_client(type, ss) != nc) {
err = -EAGAIN; err = -EAGAIN;
} else if (nc->call) { break;
err = nc->call(skb, &info,
(const struct nlattr **)cda);
} else {
err = -EINVAL;
} }
err = nc->call(skb, &info, (const struct nlattr **)cda);
nfnl_unlock(subsys_id); nfnl_unlock(subsys_id);
break;
default:
err = -EINVAL;
break;
} }
if (err == -EAGAIN) if (err == -EAGAIN)
goto replay; goto replay;
...@@ -467,12 +474,17 @@ static void nfnetlink_rcv_batch(struct sk_buff *skb, struct nlmsghdr *nlh, ...@@ -467,12 +474,17 @@ static void nfnetlink_rcv_batch(struct sk_buff *skb, struct nlmsghdr *nlh,
goto ack; goto ack;
} }
if (nc->type != NFNL_CB_BATCH) {
err = -EINVAL;
goto ack;
}
{ {
int min_len = nlmsg_total_size(sizeof(struct nfgenmsg)); int min_len = nlmsg_total_size(sizeof(struct nfgenmsg));
struct nfnl_net *nfnlnet = nfnl_pernet(net); struct nfnl_net *nfnlnet = nfnl_pernet(net);
u8 cb_id = NFNL_MSG_TYPE(nlh->nlmsg_type);
struct nlattr *cda[NFNL_MAX_ATTR_COUNT + 1]; struct nlattr *cda[NFNL_MAX_ATTR_COUNT + 1];
struct nlattr *attr = (void *)nlh + min_len; struct nlattr *attr = (void *)nlh + min_len;
u8 cb_id = NFNL_MSG_TYPE(nlh->nlmsg_type);
int attrlen = nlh->nlmsg_len - min_len; int attrlen = nlh->nlmsg_len - min_len;
struct nfnl_info info = { struct nfnl_info info = {
.net = net, .net = net,
...@@ -494,10 +506,7 @@ static void nfnetlink_rcv_batch(struct sk_buff *skb, struct nlmsghdr *nlh, ...@@ -494,10 +506,7 @@ static void nfnetlink_rcv_batch(struct sk_buff *skb, struct nlmsghdr *nlh,
if (err < 0) if (err < 0)
goto ack; goto ack;
if (nc->call_batch) { err = nc->call(skb, &info, (const struct nlattr **)cda);
err = nc->call_batch(skb, &info,
(const struct nlattr **)cda);
}
/* The lock was released to autoload some module, we /* The lock was released to autoload some module, we
* have to abort and start from scratch using the * have to abort and start from scratch using the
......
...@@ -382,18 +382,30 @@ static const struct nla_policy nfnl_acct_policy[NFACCT_MAX+1] = { ...@@ -382,18 +382,30 @@ static const struct nla_policy nfnl_acct_policy[NFACCT_MAX+1] = {
}; };
static const struct nfnl_callback nfnl_acct_cb[NFNL_MSG_ACCT_MAX] = { static const struct nfnl_callback nfnl_acct_cb[NFNL_MSG_ACCT_MAX] = {
[NFNL_MSG_ACCT_NEW] = { .call = nfnl_acct_new, [NFNL_MSG_ACCT_NEW] = {
.attr_count = NFACCT_MAX, .call = nfnl_acct_new,
.policy = nfnl_acct_policy }, .type = NFNL_CB_MUTEX,
[NFNL_MSG_ACCT_GET] = { .call = nfnl_acct_get, .attr_count = NFACCT_MAX,
.attr_count = NFACCT_MAX, .policy = nfnl_acct_policy
.policy = nfnl_acct_policy }, },
[NFNL_MSG_ACCT_GET_CTRZERO] = { .call = nfnl_acct_get, [NFNL_MSG_ACCT_GET] = {
.attr_count = NFACCT_MAX, .call = nfnl_acct_get,
.policy = nfnl_acct_policy }, .type = NFNL_CB_MUTEX,
[NFNL_MSG_ACCT_DEL] = { .call = nfnl_acct_del, .attr_count = NFACCT_MAX,
.attr_count = NFACCT_MAX, .policy = nfnl_acct_policy
.policy = nfnl_acct_policy }, },
[NFNL_MSG_ACCT_GET_CTRZERO] = {
.call = nfnl_acct_get,
.type = NFNL_CB_MUTEX,
.attr_count = NFACCT_MAX,
.policy = nfnl_acct_policy
},
[NFNL_MSG_ACCT_DEL] = {
.call = nfnl_acct_del,
.type = NFNL_CB_MUTEX,
.attr_count = NFACCT_MAX,
.policy = nfnl_acct_policy
},
}; };
static const struct nfnetlink_subsystem nfnl_acct_subsys = { static const struct nfnetlink_subsystem nfnl_acct_subsys = {
......
...@@ -737,15 +737,24 @@ static const struct nla_policy nfnl_cthelper_policy[NFCTH_MAX+1] = { ...@@ -737,15 +737,24 @@ static const struct nla_policy nfnl_cthelper_policy[NFCTH_MAX+1] = {
}; };
static const struct nfnl_callback nfnl_cthelper_cb[NFNL_MSG_CTHELPER_MAX] = { static const struct nfnl_callback nfnl_cthelper_cb[NFNL_MSG_CTHELPER_MAX] = {
[NFNL_MSG_CTHELPER_NEW] = { .call = nfnl_cthelper_new, [NFNL_MSG_CTHELPER_NEW] = {
.attr_count = NFCTH_MAX, .call = nfnl_cthelper_new,
.policy = nfnl_cthelper_policy }, .type = NFNL_CB_MUTEX,
[NFNL_MSG_CTHELPER_GET] = { .call = nfnl_cthelper_get, .attr_count = NFCTH_MAX,
.attr_count = NFCTH_MAX, .policy = nfnl_cthelper_policy
.policy = nfnl_cthelper_policy }, },
[NFNL_MSG_CTHELPER_DEL] = { .call = nfnl_cthelper_del, [NFNL_MSG_CTHELPER_GET] = {
.attr_count = NFCTH_MAX, .call = nfnl_cthelper_get,
.policy = nfnl_cthelper_policy }, .type = NFNL_CB_MUTEX,
.attr_count = NFCTH_MAX,
.policy = nfnl_cthelper_policy
},
[NFNL_MSG_CTHELPER_DEL] = {
.call = nfnl_cthelper_del,
.type = NFNL_CB_MUTEX,
.attr_count = NFCTH_MAX,
.policy = nfnl_cthelper_policy
},
}; };
static const struct nfnetlink_subsystem nfnl_cthelper_subsys = { static const struct nfnetlink_subsystem nfnl_cthelper_subsys = {
......
...@@ -546,21 +546,36 @@ static void ctnl_timeout_put(struct nf_ct_timeout *t) ...@@ -546,21 +546,36 @@ static void ctnl_timeout_put(struct nf_ct_timeout *t)
} }
static const struct nfnl_callback cttimeout_cb[IPCTNL_MSG_TIMEOUT_MAX] = { static const struct nfnl_callback cttimeout_cb[IPCTNL_MSG_TIMEOUT_MAX] = {
[IPCTNL_MSG_TIMEOUT_NEW] = { .call = cttimeout_new_timeout, [IPCTNL_MSG_TIMEOUT_NEW] = {
.attr_count = CTA_TIMEOUT_MAX, .call = cttimeout_new_timeout,
.policy = cttimeout_nla_policy }, .type = NFNL_CB_MUTEX,
[IPCTNL_MSG_TIMEOUT_GET] = { .call = cttimeout_get_timeout, .attr_count = CTA_TIMEOUT_MAX,
.attr_count = CTA_TIMEOUT_MAX, .policy = cttimeout_nla_policy
.policy = cttimeout_nla_policy }, },
[IPCTNL_MSG_TIMEOUT_DELETE] = { .call = cttimeout_del_timeout, [IPCTNL_MSG_TIMEOUT_GET] = {
.attr_count = CTA_TIMEOUT_MAX, .call = cttimeout_get_timeout,
.policy = cttimeout_nla_policy }, .type = NFNL_CB_MUTEX,
[IPCTNL_MSG_TIMEOUT_DEFAULT_SET]= { .call = cttimeout_default_set, .attr_count = CTA_TIMEOUT_MAX,
.attr_count = CTA_TIMEOUT_MAX, .policy = cttimeout_nla_policy
.policy = cttimeout_nla_policy }, },
[IPCTNL_MSG_TIMEOUT_DEFAULT_GET]= { .call = cttimeout_default_get, [IPCTNL_MSG_TIMEOUT_DELETE] = {
.attr_count = CTA_TIMEOUT_MAX, .call = cttimeout_del_timeout,
.policy = cttimeout_nla_policy }, .type = NFNL_CB_MUTEX,
.attr_count = CTA_TIMEOUT_MAX,
.policy = cttimeout_nla_policy
},
[IPCTNL_MSG_TIMEOUT_DEFAULT_SET] = {
.call = cttimeout_default_set,
.type = NFNL_CB_MUTEX,
.attr_count = CTA_TIMEOUT_MAX,
.policy = cttimeout_nla_policy
},
[IPCTNL_MSG_TIMEOUT_DEFAULT_GET] = {
.call = cttimeout_default_get,
.type = NFNL_CB_MUTEX,
.attr_count = CTA_TIMEOUT_MAX,
.policy = cttimeout_nla_policy
},
}; };
static const struct nfnetlink_subsystem cttimeout_subsys = { static const struct nfnetlink_subsystem cttimeout_subsys = {
......
...@@ -989,11 +989,17 @@ static int nfulnl_recv_config(struct sk_buff *skb, const struct nfnl_info *info, ...@@ -989,11 +989,17 @@ static int nfulnl_recv_config(struct sk_buff *skb, const struct nfnl_info *info,
} }
static const struct nfnl_callback nfulnl_cb[NFULNL_MSG_MAX] = { static const struct nfnl_callback nfulnl_cb[NFULNL_MSG_MAX] = {
[NFULNL_MSG_PACKET] = { .call = nfulnl_recv_unsupp, [NFULNL_MSG_PACKET] = {
.attr_count = NFULA_MAX, }, .call = nfulnl_recv_unsupp,
[NFULNL_MSG_CONFIG] = { .call = nfulnl_recv_config, .type = NFNL_CB_MUTEX,
.attr_count = NFULA_CFG_MAX, .attr_count = NFULA_MAX,
.policy = nfula_cfg_policy }, },
[NFULNL_MSG_CONFIG] = {
.call = nfulnl_recv_config,
.type = NFNL_CB_MUTEX,
.attr_count = NFULA_CFG_MAX,
.policy = nfula_cfg_policy
},
}; };
static const struct nfnetlink_subsystem nfulnl_subsys = { static const struct nfnetlink_subsystem nfulnl_subsys = {
......
...@@ -374,11 +374,13 @@ static int nfnl_osf_remove_callback(struct sk_buff *skb, ...@@ -374,11 +374,13 @@ static int nfnl_osf_remove_callback(struct sk_buff *skb,
static const struct nfnl_callback nfnl_osf_callbacks[OSF_MSG_MAX] = { static const struct nfnl_callback nfnl_osf_callbacks[OSF_MSG_MAX] = {
[OSF_MSG_ADD] = { [OSF_MSG_ADD] = {
.call = nfnl_osf_add_callback, .call = nfnl_osf_add_callback,
.type = NFNL_CB_MUTEX,
.attr_count = OSF_ATTR_MAX, .attr_count = OSF_ATTR_MAX,
.policy = nfnl_osf_policy, .policy = nfnl_osf_policy,
}, },
[OSF_MSG_REMOVE] = { [OSF_MSG_REMOVE] = {
.call = nfnl_osf_remove_callback, .call = nfnl_osf_remove_callback,
.type = NFNL_CB_MUTEX,
.attr_count = OSF_ATTR_MAX, .attr_count = OSF_ATTR_MAX,
.policy = nfnl_osf_policy, .policy = nfnl_osf_policy,
}, },
......
...@@ -1365,17 +1365,29 @@ static int nfqnl_recv_config(struct sk_buff *skb, const struct nfnl_info *info, ...@@ -1365,17 +1365,29 @@ static int nfqnl_recv_config(struct sk_buff *skb, const struct nfnl_info *info,
} }
static const struct nfnl_callback nfqnl_cb[NFQNL_MSG_MAX] = { static const struct nfnl_callback nfqnl_cb[NFQNL_MSG_MAX] = {
[NFQNL_MSG_PACKET] = { .call_rcu = nfqnl_recv_unsupp, [NFQNL_MSG_PACKET] = {
.attr_count = NFQA_MAX, }, .call = nfqnl_recv_unsupp,
[NFQNL_MSG_VERDICT] = { .call_rcu = nfqnl_recv_verdict, .type = NFNL_CB_RCU,
.attr_count = NFQA_MAX, .attr_count = NFQA_MAX,
.policy = nfqa_verdict_policy }, },
[NFQNL_MSG_CONFIG] = { .call = nfqnl_recv_config, [NFQNL_MSG_VERDICT] = {
.attr_count = NFQA_CFG_MAX, .call = nfqnl_recv_verdict,
.policy = nfqa_cfg_policy }, .type = NFNL_CB_RCU,
[NFQNL_MSG_VERDICT_BATCH]={ .call_rcu = nfqnl_recv_verdict_batch, .attr_count = NFQA_MAX,
.attr_count = NFQA_MAX, .policy = nfqa_verdict_policy
.policy = nfqa_verdict_batch_policy }, },
[NFQNL_MSG_CONFIG] = {
.call = nfqnl_recv_config,
.type = NFNL_CB_MUTEX,
.attr_count = NFQA_CFG_MAX,
.policy = nfqa_cfg_policy
},
[NFQNL_MSG_VERDICT_BATCH] = {
.call = nfqnl_recv_verdict_batch,
.type = NFNL_CB_RCU,
.attr_count = NFQA_MAX,
.policy = nfqa_verdict_batch_policy
},
}; };
static const struct nfnetlink_subsystem nfqnl_subsys = { static const struct nfnetlink_subsystem nfqnl_subsys = {
......
...@@ -698,9 +698,12 @@ static const struct nla_policy nfnl_compat_policy_get[NFTA_COMPAT_MAX+1] = { ...@@ -698,9 +698,12 @@ static const struct nla_policy nfnl_compat_policy_get[NFTA_COMPAT_MAX+1] = {
}; };
static const struct nfnl_callback nfnl_nft_compat_cb[NFNL_MSG_COMPAT_MAX] = { static const struct nfnl_callback nfnl_nft_compat_cb[NFNL_MSG_COMPAT_MAX] = {
[NFNL_MSG_COMPAT_GET] = { .call_rcu = nfnl_compat_get_rcu, [NFNL_MSG_COMPAT_GET] = {
.attr_count = NFTA_COMPAT_MAX, .call = nfnl_compat_get_rcu,
.policy = nfnl_compat_policy_get }, .type = NFNL_CB_RCU,
.attr_count = NFTA_COMPAT_MAX,
.policy = nfnl_compat_policy_get
},
}; };
static const struct nfnetlink_subsystem nfnl_compat_subsys = { static const struct nfnetlink_subsystem nfnl_compat_subsys = {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment