Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 544d5c7d authored by Pablo Neira Ayuso's avatar Pablo Neira Ayuso
Browse files

netfilter: ctnetlink: allow to set expectfn for expectations



This patch allows you to set expectfn which is specifically used
by the NAT side of most of the existing conntrack helpers.

I have added a symbol map that uses a string as key to look up for
the function that is attached to the expectation object. This is
the best solution I came out with to solve this issue.

Signed-off-by: default avatarPablo Neira Ayuso <pablo@netfilter.org>
parent 076a0ca0
Loading
Loading
Loading
Loading
+1 −0
Original line number Original line Diff line number Diff line
@@ -175,6 +175,7 @@ enum ctattr_expect {
	CTA_EXPECT_FLAGS,
	CTA_EXPECT_FLAGS,
	CTA_EXPECT_CLASS,
	CTA_EXPECT_CLASS,
	CTA_EXPECT_NAT,
	CTA_EXPECT_NAT,
	CTA_EXPECT_FN,
	__CTA_EXPECT_MAX
	__CTA_EXPECT_MAX
};
};
#define CTA_EXPECT_MAX (__CTA_EXPECT_MAX - 1)
#define CTA_EXPECT_MAX (__CTA_EXPECT_MAX - 1)
+13 −0
Original line number Original line Diff line number Diff line
@@ -69,4 +69,17 @@ extern int nf_conntrack_broadcast_help(struct sk_buff *skb,
				       enum ip_conntrack_info ctinfo,
				       enum ip_conntrack_info ctinfo,
				       unsigned int timeout);
				       unsigned int timeout);


struct nf_ct_helper_expectfn {
	struct list_head head;
	const char *name;
	void (*expectfn)(struct nf_conn *ct, struct nf_conntrack_expect *exp);
};

void nf_ct_helper_expectfn_register(struct nf_ct_helper_expectfn *n);
void nf_ct_helper_expectfn_unregister(struct nf_ct_helper_expectfn *n);
struct nf_ct_helper_expectfn *
nf_ct_helper_expectfn_find_by_name(const char *name);
struct nf_ct_helper_expectfn *
nf_ct_helper_expectfn_find_by_symbol(const void *symbol);

#endif /*_NF_CONNTRACK_HELPER_H*/
#endif /*_NF_CONNTRACK_HELPER_H*/
+8 −0
Original line number Original line Diff line number Diff line
@@ -686,6 +686,11 @@ static struct pernet_operations nf_nat_net_ops = {
	.exit = nf_nat_net_exit,
	.exit = nf_nat_net_exit,
};
};


static struct nf_ct_helper_expectfn follow_master_nat = {
	.name		= "nat-follow-master",
	.expectfn	= nf_nat_follow_master,
};

static int __init nf_nat_init(void)
static int __init nf_nat_init(void)
{
{
	size_t i;
	size_t i;
@@ -717,6 +722,8 @@ static int __init nf_nat_init(void)


	l3proto = nf_ct_l3proto_find_get((u_int16_t)AF_INET);
	l3proto = nf_ct_l3proto_find_get((u_int16_t)AF_INET);


	nf_ct_helper_expectfn_register(&follow_master_nat);

	BUG_ON(nf_nat_seq_adjust_hook != NULL);
	BUG_ON(nf_nat_seq_adjust_hook != NULL);
	RCU_INIT_POINTER(nf_nat_seq_adjust_hook, nf_nat_seq_adjust);
	RCU_INIT_POINTER(nf_nat_seq_adjust_hook, nf_nat_seq_adjust);
	BUG_ON(nfnetlink_parse_nat_setup_hook != NULL);
	BUG_ON(nfnetlink_parse_nat_setup_hook != NULL);
@@ -736,6 +743,7 @@ static void __exit nf_nat_cleanup(void)
	unregister_pernet_subsys(&nf_nat_net_ops);
	unregister_pernet_subsys(&nf_nat_net_ops);
	nf_ct_l3proto_put(l3proto);
	nf_ct_l3proto_put(l3proto);
	nf_ct_extend_unregister(&nat_extend);
	nf_ct_extend_unregister(&nat_extend);
	nf_ct_helper_expectfn_unregister(&follow_master_nat);
	RCU_INIT_POINTER(nf_nat_seq_adjust_hook, NULL);
	RCU_INIT_POINTER(nf_nat_seq_adjust_hook, NULL);
	RCU_INIT_POINTER(nfnetlink_parse_nat_setup_hook, NULL);
	RCU_INIT_POINTER(nfnetlink_parse_nat_setup_hook, NULL);
	RCU_INIT_POINTER(nf_ct_nat_offset, NULL);
	RCU_INIT_POINTER(nf_ct_nat_offset, NULL);
+14 −0
Original line number Original line Diff line number Diff line
@@ -568,6 +568,16 @@ static int nat_callforwarding(struct sk_buff *skb, struct nf_conn *ct,
	return 0;
	return 0;
}
}


static struct nf_ct_helper_expectfn q931_nat = {
	.name		= "Q.931",
	.expectfn	= ip_nat_q931_expect,
};

static struct nf_ct_helper_expectfn callforwarding_nat = {
	.name		= "callforwarding",
	.expectfn	= ip_nat_callforwarding_expect,
};

/****************************************************************************/
/****************************************************************************/
static int __init init(void)
static int __init init(void)
{
{
@@ -590,6 +600,8 @@ static int __init init(void)
	RCU_INIT_POINTER(nat_h245_hook, nat_h245);
	RCU_INIT_POINTER(nat_h245_hook, nat_h245);
	RCU_INIT_POINTER(nat_callforwarding_hook, nat_callforwarding);
	RCU_INIT_POINTER(nat_callforwarding_hook, nat_callforwarding);
	RCU_INIT_POINTER(nat_q931_hook, nat_q931);
	RCU_INIT_POINTER(nat_q931_hook, nat_q931);
	nf_ct_helper_expectfn_register(&q931_nat);
	nf_ct_helper_expectfn_register(&callforwarding_nat);
	return 0;
	return 0;
}
}


@@ -605,6 +617,8 @@ static void __exit fini(void)
	RCU_INIT_POINTER(nat_h245_hook, NULL);
	RCU_INIT_POINTER(nat_h245_hook, NULL);
	RCU_INIT_POINTER(nat_callforwarding_hook, NULL);
	RCU_INIT_POINTER(nat_callforwarding_hook, NULL);
	RCU_INIT_POINTER(nat_q931_hook, NULL);
	RCU_INIT_POINTER(nat_q931_hook, NULL);
	nf_ct_helper_expectfn_unregister(&q931_nat);
	nf_ct_helper_expectfn_unregister(&callforwarding_nat);
	synchronize_rcu();
	synchronize_rcu();
}
}


+7 −0
Original line number Original line Diff line number Diff line
@@ -526,6 +526,11 @@ static unsigned int ip_nat_sdp_media(struct sk_buff *skb, unsigned int dataoff,
	return NF_DROP;
	return NF_DROP;
}
}


static struct nf_ct_helper_expectfn sip_nat = {
        .name           = "sip",
        .expectfn       = ip_nat_sip_expected,
};

static void __exit nf_nat_sip_fini(void)
static void __exit nf_nat_sip_fini(void)
{
{
	RCU_INIT_POINTER(nf_nat_sip_hook, NULL);
	RCU_INIT_POINTER(nf_nat_sip_hook, NULL);
@@ -535,6 +540,7 @@ static void __exit nf_nat_sip_fini(void)
	RCU_INIT_POINTER(nf_nat_sdp_port_hook, NULL);
	RCU_INIT_POINTER(nf_nat_sdp_port_hook, NULL);
	RCU_INIT_POINTER(nf_nat_sdp_session_hook, NULL);
	RCU_INIT_POINTER(nf_nat_sdp_session_hook, NULL);
	RCU_INIT_POINTER(nf_nat_sdp_media_hook, NULL);
	RCU_INIT_POINTER(nf_nat_sdp_media_hook, NULL);
	nf_ct_helper_expectfn_unregister(&sip_nat);
	synchronize_rcu();
	synchronize_rcu();
}
}


@@ -554,6 +560,7 @@ static int __init nf_nat_sip_init(void)
	RCU_INIT_POINTER(nf_nat_sdp_port_hook, ip_nat_sdp_port);
	RCU_INIT_POINTER(nf_nat_sdp_port_hook, ip_nat_sdp_port);
	RCU_INIT_POINTER(nf_nat_sdp_session_hook, ip_nat_sdp_session);
	RCU_INIT_POINTER(nf_nat_sdp_session_hook, ip_nat_sdp_session);
	RCU_INIT_POINTER(nf_nat_sdp_media_hook, ip_nat_sdp_media);
	RCU_INIT_POINTER(nf_nat_sdp_media_hook, ip_nat_sdp_media);
	nf_ct_helper_expectfn_register(&sip_nat);
	return 0;
	return 0;
}
}


Loading