@@ -70,6 +70,7 @@ struct nf_conntrack_helper {
struct nf_conn_help {
/* Helper. if any */
struct nf_conntrack_helper __rcu *helper;
+ const char *objname;
struct hlist_head expectations;
@@ -1065,6 +1065,7 @@ enum nft_socket_keys {
* @NFT_CT_SRC_IP6: conntrack layer 3 protocol source (IPv6 address)
* @NFT_CT_DST_IP6: conntrack layer 3 protocol destination (IPv6 address)
* @NFT_CT_ID: conntrack id
+ * @NFT_CT_HELPER_OBJNAME: connection tracking helper object assigned to conntrack
*/
enum nft_ct_keys {
NFT_CT_STATE,
@@ -1092,6 +1093,7 @@ enum nft_ct_keys {
NFT_CT_SRC_IP6,
NFT_CT_DST_IP6,
NFT_CT_ID,
+ NFT_CT_HELPER_OBJNAME,
__NFT_CT_MAX
};
#define NFT_CT_MAX (__NFT_CT_MAX - 1)
@@ -311,6 +311,7 @@ void nf_ct_helper_destroy(struct nf_conn *ct)
if (helper && helper->destroy)
helper->destroy(ct);
rcu_read_unlock();
+ kfree(help->objname);
}
}
@@ -219,6 +219,17 @@ static void nft_ct_get_eval(const struct nft_expr *expr,
goto err;
memcpy(dest, tuple->dst.u3.ip6, sizeof(struct in6_addr));
return;
+ case NFT_CT_HELPER_OBJNAME:
+ if (!ct->master)
+ goto err;
+ help = nfct_help(ct->master);
+ if (!help)
+ goto err;
+ helper = rcu_dereference(help->helper);
+ if (!helper || !help->objname)
+ goto err;
+ strncpy((char *)dest, help->objname, NF_CT_HELPER_NAME_LEN);
+ return;
default:
break;
}
@@ -1063,6 +1074,7 @@ static void nft_ct_helper_obj_eval(struct nft_object *obj,
struct nf_conn *ct = (struct nf_conn *)skb_nfct(pkt->skb);
struct nf_conntrack_helper *to_assign = NULL;
struct nf_conn_help *help;
+ const char *objname;
if (!ct ||
nf_ct_is_confirmed(ct) ||
@@ -1088,11 +1100,19 @@ static void nft_ct_helper_obj_eval(struct nft_object *obj,
if (test_bit(IPS_HELPER_BIT, &ct->status))
return;
+ objname = kstrdup(obj->key.name, GFP_ATOMIC);
+ if (!objname)
+ return;
+
help = nf_ct_helper_ext_add(ct, GFP_ATOMIC);
- if (help) {
- rcu_assign_pointer(help->helper, to_assign);
- set_bit(IPS_HELPER_BIT, &ct->status);
+ if (!help) {
+ kfree(objname);
+ return;
}
+
+ help->objname = objname;
+ rcu_assign_pointer(help->helper, to_assign);
+ set_bit(IPS_HELPER_BIT, &ct->status);
}
static int nft_ct_helper_obj_dump(struct sk_buff *skb,
Conntrack helper assignments refer to the helper object name, while NFT_CT_HELPER (now NFT_CT_HELPER_TYPE) refers to the helper type. This patch allows to match on helper object name so the ct helper matching and the assignment are consistent. Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org> --- include/net/netfilter/nf_conntrack_helper.h | 1 + include/uapi/linux/netfilter/nf_tables.h | 2 ++ net/netfilter/nf_conntrack_helper.c | 1 + net/netfilter/nft_ct.c | 26 ++++++++++++++++++--- 4 files changed, 27 insertions(+), 3 deletions(-)