1b2441318SGreg Kroah-Hartman /* SPDX-License-Identifier: GPL-2.0 */
277ab9cffSMartin Josefsson /*
377ab9cffSMartin Josefsson  * connection tracking expectations.
477ab9cffSMartin Josefsson  */
577ab9cffSMartin Josefsson 
677ab9cffSMartin Josefsson #ifndef _NF_CONNTRACK_EXPECT_H
777ab9cffSMartin Josefsson #define _NF_CONNTRACK_EXPECT_H
8308ac914SDaniel Borkmann 
9b54ab92bSReshetova, Elena #include <linux/refcount.h>
10b54ab92bSReshetova, Elena 
1177ab9cffSMartin Josefsson #include <net/netfilter/nf_conntrack.h>
12308ac914SDaniel Borkmann #include <net/netfilter/nf_conntrack_zones.h>
1377ab9cffSMartin Josefsson 
14a71c0855SPatrick McHardy extern unsigned int nf_ct_expect_hsize;
15f264a7dfSPatrick McHardy extern unsigned int nf_ct_expect_max;
160a93aaedSFlorian Westphal extern struct hlist_head *nf_ct_expect_hash;
1777ab9cffSMartin Josefsson 
18fd2c3ef7SEric Dumazet struct nf_conntrack_expect {
19b560580aSPatrick McHardy 	/* Conntrack expectation list member */
20b560580aSPatrick McHardy 	struct hlist_node lnode;
2177ab9cffSMartin Josefsson 
22a71c0855SPatrick McHardy 	/* Hash member */
23a71c0855SPatrick McHardy 	struct hlist_node hnode;
24a71c0855SPatrick McHardy 
2577ab9cffSMartin Josefsson 	/* We expect this tuple, with the following mask */
26d4156e8cSPatrick McHardy 	struct nf_conntrack_tuple tuple;
27d4156e8cSPatrick McHardy 	struct nf_conntrack_tuple_mask mask;
2877ab9cffSMartin Josefsson 
2961e03e91SChristophe JAILLET 	/* Usage count. */
3061e03e91SChristophe JAILLET 	refcount_t use;
3161e03e91SChristophe JAILLET 
3261e03e91SChristophe JAILLET 	/* Flags */
3361e03e91SChristophe JAILLET 	unsigned int flags;
3461e03e91SChristophe JAILLET 
3561e03e91SChristophe JAILLET 	/* Expectation class */
3661e03e91SChristophe JAILLET 	unsigned int class;
3761e03e91SChristophe JAILLET 
3877ab9cffSMartin Josefsson 	/* Function to call after setup and insertion */
3977ab9cffSMartin Josefsson 	void (*expectfn)(struct nf_conn *new,
4077ab9cffSMartin Josefsson 			 struct nf_conntrack_expect *this);
4177ab9cffSMartin Josefsson 
429457d851SPatrick McHardy 	/* Helper to assign to new connection */
439457d851SPatrick McHardy 	struct nf_conntrack_helper *helper;
449457d851SPatrick McHardy 
4577ab9cffSMartin Josefsson 	/* The conntrack of the master connection */
4677ab9cffSMartin Josefsson 	struct nf_conn *master;
4777ab9cffSMartin Josefsson 
4877ab9cffSMartin Josefsson 	/* Timer function; deletes the expectation. */
4977ab9cffSMartin Josefsson 	struct timer_list timeout;
5077ab9cffSMartin Josefsson 
514806e975SFlorian Westphal #if IS_ENABLED(CONFIG_NF_NAT)
52c7232c99SPatrick McHardy 	union nf_inet_addr saved_addr;
5377ab9cffSMartin Josefsson 	/* This is the original per-proto part, used to map the
5477ab9cffSMartin Josefsson 	 * expected connection the way the recipient expects. */
555b1158e9SJozsef Kadlecsik 	union nf_conntrack_man_proto saved_proto;
5677ab9cffSMartin Josefsson 	/* Direction relative to the master connection. */
5777ab9cffSMartin Josefsson 	enum ip_conntrack_dir dir;
5877ab9cffSMartin Josefsson #endif
597d0742daSPatrick McHardy 
607d0742daSPatrick McHardy 	struct rcu_head rcu;
6177ab9cffSMartin Josefsson };
6277ab9cffSMartin Josefsson 
nf_ct_exp_net(struct nf_conntrack_expect * exp)639b03f38dSAlexey Dobriyan static inline struct net *nf_ct_exp_net(struct nf_conntrack_expect *exp)
649b03f38dSAlexey Dobriyan {
65857b409aSAlexey Dobriyan 	return nf_ct_net(exp->master);
669b03f38dSAlexey Dobriyan }
679b03f38dSAlexey Dobriyan 
683a8fc53aSPablo Neira Ayuso #define NF_CT_EXP_POLICY_NAME_LEN	16
693a8fc53aSPablo Neira Ayuso 
70fd2c3ef7SEric Dumazet struct nf_conntrack_expect_policy {
716002f266SPatrick McHardy 	unsigned int	max_expected;
726002f266SPatrick McHardy 	unsigned int	timeout;
733a8fc53aSPablo Neira Ayuso 	char		name[NF_CT_EXP_POLICY_NAME_LEN];
746002f266SPatrick McHardy };
756002f266SPatrick McHardy 
766002f266SPatrick McHardy #define NF_CT_EXPECT_CLASS_DEFAULT	0
7792f73221SGao Feng #define NF_CT_EXPECT_MAX_CNT		255
786002f266SPatrick McHardy 
793c00fb0bSxiao ruizhu /* Allow to reuse expectations with the same tuples from different master
803c00fb0bSxiao ruizhu  * conntracks.
813c00fb0bSxiao ruizhu  */
823c00fb0bSxiao ruizhu #define NF_CT_EXP_F_SKIP_MASTER	0x1
833c00fb0bSxiao ruizhu 
8483b4dbe1SGao feng int nf_conntrack_expect_pernet_init(struct net *net);
8583b4dbe1SGao feng void nf_conntrack_expect_pernet_fini(struct net *net);
8683b4dbe1SGao feng 
8783b4dbe1SGao feng int nf_conntrack_expect_init(void);
8883b4dbe1SGao feng void nf_conntrack_expect_fini(void);
8977ab9cffSMartin Josefsson 
9077ab9cffSMartin Josefsson struct nf_conntrack_expect *
91308ac914SDaniel Borkmann __nf_ct_expect_find(struct net *net,
92308ac914SDaniel Borkmann 		    const struct nf_conntrack_zone *zone,
935d0aa2ccSPatrick McHardy 		    const struct nf_conntrack_tuple *tuple);
9477ab9cffSMartin Josefsson 
9577ab9cffSMartin Josefsson struct nf_conntrack_expect *
96308ac914SDaniel Borkmann nf_ct_expect_find_get(struct net *net,
97308ac914SDaniel Borkmann 		      const struct nf_conntrack_zone *zone,
985d0aa2ccSPatrick McHardy 		      const struct nf_conntrack_tuple *tuple);
9977ab9cffSMartin Josefsson 
10077ab9cffSMartin Josefsson struct nf_conntrack_expect *
101308ac914SDaniel Borkmann nf_ct_find_expectation(struct net *net,
102308ac914SDaniel Borkmann 		       const struct nf_conntrack_zone *zone,
103*4914109aSXin Long 		       const struct nf_conntrack_tuple *tuple, bool unlink);
10477ab9cffSMartin Josefsson 
105ebbf41dfSPablo Neira Ayuso void nf_ct_unlink_expect_report(struct nf_conntrack_expect *exp,
106ec464e5dSPatrick McHardy 				u32 portid, int report);
nf_ct_unlink_expect(struct nf_conntrack_expect * exp)107ebbf41dfSPablo Neira Ayuso static inline void nf_ct_unlink_expect(struct nf_conntrack_expect *exp)
108ebbf41dfSPablo Neira Ayuso {
109ebbf41dfSPablo Neira Ayuso 	nf_ct_unlink_expect_report(exp, 0, 0);
110ebbf41dfSPablo Neira Ayuso }
111ebbf41dfSPablo Neira Ayuso 
11277ab9cffSMartin Josefsson void nf_ct_remove_expectations(struct nf_conn *ct);
1136823645dSPatrick McHardy void nf_ct_unexpect_related(struct nf_conntrack_expect *exp);
114ec0e3f01SGao Feng bool nf_ct_remove_expect(struct nf_conntrack_expect *exp);
11577ab9cffSMartin Josefsson 
116ac7b8483SFlorian Westphal void nf_ct_expect_iterate_destroy(bool (*iter)(struct nf_conntrack_expect *e, void *data), void *data);
117ac7b8483SFlorian Westphal void nf_ct_expect_iterate_net(struct net *net,
118ac7b8483SFlorian Westphal 			      bool (*iter)(struct nf_conntrack_expect *e, void *data),
119ac7b8483SFlorian Westphal                               void *data, u32 portid, int report);
120ac7b8483SFlorian Westphal 
12177ab9cffSMartin Josefsson /* Allocate space for an expectation: this is mandatory before calling
1226823645dSPatrick McHardy    nf_ct_expect_related.  You will have to call put afterwards. */
1236823645dSPatrick McHardy struct nf_conntrack_expect *nf_ct_expect_alloc(struct nf_conn *me);
12476108ceaSJan Engelhardt void nf_ct_expect_init(struct nf_conntrack_expect *, unsigned int, u_int8_t,
1251d9d7522SPatrick McHardy 		       const union nf_inet_addr *,
1261d9d7522SPatrick McHardy 		       const union nf_inet_addr *,
1271d9d7522SPatrick McHardy 		       u_int8_t, const __be16 *, const __be16 *);
1286823645dSPatrick McHardy void nf_ct_expect_put(struct nf_conntrack_expect *exp);
12919abb7b0SPablo Neira Ayuso int nf_ct_expect_related_report(struct nf_conntrack_expect *expect,
1303c00fb0bSxiao ruizhu 				u32 portid, int report, unsigned int flags);
nf_ct_expect_related(struct nf_conntrack_expect * expect,unsigned int flags)1313c00fb0bSxiao ruizhu static inline int nf_ct_expect_related(struct nf_conntrack_expect *expect,
1323c00fb0bSxiao ruizhu 				       unsigned int flags)
13383731671SPablo Neira Ayuso {
1343c00fb0bSxiao ruizhu 	return nf_ct_expect_related_report(expect, 0, 0, flags);
13583731671SPablo Neira Ayuso }
13677ab9cffSMartin Josefsson 
13777ab9cffSMartin Josefsson #endif /*_NF_CONNTRACK_EXPECT_H*/
13877ab9cffSMartin Josefsson 
139