1 #ifndef _NF_CONNTRACK_ZONES_H
2 #define _NF_CONNTRACK_ZONES_H
3 
4 #include <linux/netfilter/nf_conntrack_zones_common.h>
5 
6 #if IS_ENABLED(CONFIG_NF_CONNTRACK)
7 #include <net/netfilter/nf_conntrack_extend.h>
8 
9 static inline const struct nf_conntrack_zone *
10 nf_ct_zone(const struct nf_conn *ct)
11 {
12 	const struct nf_conntrack_zone *nf_ct_zone = NULL;
13 
14 #ifdef CONFIG_NF_CONNTRACK_ZONES
15 	nf_ct_zone = nf_ct_ext_find(ct, NF_CT_EXT_ZONE);
16 #endif
17 	return nf_ct_zone ? nf_ct_zone : &nf_ct_zone_dflt;
18 }
19 
20 static inline const struct nf_conntrack_zone *
21 nf_ct_zone_init(struct nf_conntrack_zone *zone, u16 id, u8 dir, u8 flags)
22 {
23 	zone->id = id;
24 	zone->flags = flags;
25 	zone->dir = dir;
26 
27 	return zone;
28 }
29 
30 static inline const struct nf_conntrack_zone *
31 nf_ct_zone_tmpl(const struct nf_conn *tmpl, const struct sk_buff *skb,
32 		struct nf_conntrack_zone *tmp)
33 {
34 	const struct nf_conntrack_zone *zone;
35 
36 	if (!tmpl)
37 		return &nf_ct_zone_dflt;
38 
39 	zone = nf_ct_zone(tmpl);
40 	if (zone->flags & NF_CT_FLAG_MARK)
41 		zone = nf_ct_zone_init(tmp, skb->mark, zone->dir, 0);
42 
43 	return zone;
44 }
45 
46 static inline int nf_ct_zone_add(struct nf_conn *ct, gfp_t flags,
47 				 const struct nf_conntrack_zone *info)
48 {
49 #ifdef CONFIG_NF_CONNTRACK_ZONES
50 	struct nf_conntrack_zone *nf_ct_zone;
51 
52 	nf_ct_zone = nf_ct_ext_add(ct, NF_CT_EXT_ZONE, flags);
53 	if (!nf_ct_zone)
54 		return -ENOMEM;
55 
56 	nf_ct_zone_init(nf_ct_zone, info->id, info->dir,
57 			info->flags);
58 #endif
59 	return 0;
60 }
61 
62 static inline bool nf_ct_zone_matches_dir(const struct nf_conntrack_zone *zone,
63 					  enum ip_conntrack_dir dir)
64 {
65 	return zone->dir & (1 << dir);
66 }
67 
68 static inline u16 nf_ct_zone_id(const struct nf_conntrack_zone *zone,
69 				enum ip_conntrack_dir dir)
70 {
71 	return nf_ct_zone_matches_dir(zone, dir) ?
72 	       zone->id : NF_CT_DEFAULT_ZONE_ID;
73 }
74 
75 static inline bool nf_ct_zone_equal(const struct nf_conn *a,
76 				    const struct nf_conntrack_zone *b,
77 				    enum ip_conntrack_dir dir)
78 {
79 	return nf_ct_zone_id(nf_ct_zone(a), dir) ==
80 	       nf_ct_zone_id(b, dir);
81 }
82 
83 static inline bool nf_ct_zone_equal_any(const struct nf_conn *a,
84 					const struct nf_conntrack_zone *b)
85 {
86 	return nf_ct_zone(a)->id == b->id;
87 }
88 #endif /* IS_ENABLED(CONFIG_NF_CONNTRACK) */
89 #endif /* _NF_CONNTRACK_ZONES_H */
90