xref: /openbmc/linux/include/net/flow.h (revision e2d118a1)
11da177e4SLinus Torvalds /*
21da177e4SLinus Torvalds  *
31da177e4SLinus Torvalds  *	Generic internet FLOW.
41da177e4SLinus Torvalds  *
51da177e4SLinus Torvalds  */
61da177e4SLinus Torvalds 
71da177e4SLinus Torvalds #ifndef _NET_FLOW_H
81da177e4SLinus Torvalds #define _NET_FLOW_H
91da177e4SLinus Torvalds 
10aa1c366eSdpward #include <linux/socket.h>
111da177e4SLinus Torvalds #include <linux/in6.h>
1260063497SArun Sharma #include <linux/atomic.h>
13c6cc1ca7STom Herbert #include <net/flow_dissector.h>
14622ec2c9SLorenzo Colitti #include <linux/uidgid.h>
151da177e4SLinus Torvalds 
166a662719SCong Wang /*
176a662719SCong Wang  * ifindex generation is per-net namespace, and loopback is
186a662719SCong Wang  * always the 1st device in ns (see net_dev_init), thus any
196a662719SCong Wang  * loopback device should get ifindex 1
206a662719SCong Wang  */
216a662719SCong Wang 
226a662719SCong Wang #define LOOPBACK_IFINDEX	1
236a662719SCong Wang 
241b7179d3SThomas Graf struct flowi_tunnel {
251b7179d3SThomas Graf 	__be64			tun_id;
261b7179d3SThomas Graf };
271b7179d3SThomas Graf 
28806566ccSDavid S. Miller struct flowi_common {
29806566ccSDavid S. Miller 	int	flowic_oif;
30806566ccSDavid S. Miller 	int	flowic_iif;
31806566ccSDavid S. Miller 	__u32	flowic_mark;
32806566ccSDavid S. Miller 	__u8	flowic_tos;
33806566ccSDavid S. Miller 	__u8	flowic_scope;
34806566ccSDavid S. Miller 	__u8	flowic_proto;
35806566ccSDavid S. Miller 	__u8	flowic_flags;
36fbef0a40SDavid S. Miller #define FLOWI_FLAG_ANYSRC		0x01
370e0d44abSSteffen Klassert #define FLOWI_FLAG_KNOWN_NH		0x02
38c71ad3d4SDavid Ahern #define FLOWI_FLAG_SKIP_NH_OIF		0x04
39806566ccSDavid S. Miller 	__u32	flowic_secid;
401b7179d3SThomas Graf 	struct flowi_tunnel flowic_tun_key;
41622ec2c9SLorenzo Colitti 	kuid_t  flowic_uid;
42806566ccSDavid S. Miller };
43806566ccSDavid S. Miller 
4408704bcbSDavid S. Miller union flowi_uli {
4508704bcbSDavid S. Miller 	struct {
4608704bcbSDavid S. Miller 		__be16	dport;
479b12c75bSDavid S. Miller 		__be16	sport;
4808704bcbSDavid S. Miller 	} ports;
4908704bcbSDavid S. Miller 
5008704bcbSDavid S. Miller 	struct {
5108704bcbSDavid S. Miller 		__u8	type;
5208704bcbSDavid S. Miller 		__u8	code;
5308704bcbSDavid S. Miller 	} icmpt;
5408704bcbSDavid S. Miller 
5508704bcbSDavid S. Miller 	struct {
5608704bcbSDavid S. Miller 		__le16	dport;
579b12c75bSDavid S. Miller 		__le16	sport;
5808704bcbSDavid S. Miller 	} dnports;
5908704bcbSDavid S. Miller 
6008704bcbSDavid S. Miller 	__be32		spi;
6108704bcbSDavid S. Miller 	__be32		gre_key;
6208704bcbSDavid S. Miller 
6308704bcbSDavid S. Miller 	struct {
6408704bcbSDavid S. Miller 		__u8	type;
6508704bcbSDavid S. Miller 	} mht;
6608704bcbSDavid S. Miller };
6708704bcbSDavid S. Miller 
6856bb8059SDavid S. Miller struct flowi4 {
69806566ccSDavid S. Miller 	struct flowi_common	__fl_common;
7022bd5b9bSDavid S. Miller #define flowi4_oif		__fl_common.flowic_oif
7122bd5b9bSDavid S. Miller #define flowi4_iif		__fl_common.flowic_iif
7222bd5b9bSDavid S. Miller #define flowi4_mark		__fl_common.flowic_mark
7322bd5b9bSDavid S. Miller #define flowi4_tos		__fl_common.flowic_tos
7422bd5b9bSDavid S. Miller #define flowi4_scope		__fl_common.flowic_scope
7522bd5b9bSDavid S. Miller #define flowi4_proto		__fl_common.flowic_proto
7622bd5b9bSDavid S. Miller #define flowi4_flags		__fl_common.flowic_flags
7722bd5b9bSDavid S. Miller #define flowi4_secid		__fl_common.flowic_secid
781b7179d3SThomas Graf #define flowi4_tun_key		__fl_common.flowic_tun_key
79622ec2c9SLorenzo Colitti #define flowi4_uid		__fl_common.flowic_uid
8084f9307cSEric Dumazet 
8184f9307cSEric Dumazet 	/* (saddr,daddr) must be grouped, same order as in IP header */
82f2c3fe24SAl Viro 	__be32			saddr;
8384f9307cSEric Dumazet 	__be32			daddr;
8484f9307cSEric Dumazet 
8556bb8059SDavid S. Miller 	union flowi_uli		uli;
869cce96dfSDavid S. Miller #define fl4_sport		uli.ports.sport
879cce96dfSDavid S. Miller #define fl4_dport		uli.ports.dport
889cce96dfSDavid S. Miller #define fl4_icmp_type		uli.icmpt.type
899cce96dfSDavid S. Miller #define fl4_icmp_code		uli.icmpt.code
909cce96dfSDavid S. Miller #define fl4_ipsec_spi		uli.spi
919cce96dfSDavid S. Miller #define fl4_mh_type		uli.mht.type
929cce96dfSDavid S. Miller #define fl4_gre_key		uli.gre_key
93728871bcSDavid Ward } __attribute__((__aligned__(BITS_PER_LONG/8)));
941da177e4SLinus Torvalds 
9583229aa5SDavid S. Miller static inline void flowi4_init_output(struct flowi4 *fl4, int oif,
9683229aa5SDavid S. Miller 				      __u32 mark, __u8 tos, __u8 scope,
9783229aa5SDavid S. Miller 				      __u8 proto, __u8 flags,
9883229aa5SDavid S. Miller 				      __be32 daddr, __be32 saddr,
99e2d118a1SLorenzo Colitti 				      __be16 dport, __be16 sport,
100e2d118a1SLorenzo Colitti 				      kuid_t uid)
10183229aa5SDavid S. Miller {
10283229aa5SDavid S. Miller 	fl4->flowi4_oif = oif;
1036a662719SCong Wang 	fl4->flowi4_iif = LOOPBACK_IFINDEX;
10483229aa5SDavid S. Miller 	fl4->flowi4_mark = mark;
10583229aa5SDavid S. Miller 	fl4->flowi4_tos = tos;
10683229aa5SDavid S. Miller 	fl4->flowi4_scope = scope;
10783229aa5SDavid S. Miller 	fl4->flowi4_proto = proto;
10883229aa5SDavid S. Miller 	fl4->flowi4_flags = flags;
10983229aa5SDavid S. Miller 	fl4->flowi4_secid = 0;
1101b7179d3SThomas Graf 	fl4->flowi4_tun_key.tun_id = 0;
111e2d118a1SLorenzo Colitti 	fl4->flowi4_uid = uid;
11283229aa5SDavid S. Miller 	fl4->daddr = daddr;
11383229aa5SDavid S. Miller 	fl4->saddr = saddr;
11483229aa5SDavid S. Miller 	fl4->fl4_dport = dport;
1159b12c75bSDavid S. Miller 	fl4->fl4_sport = sport;
11683229aa5SDavid S. Miller }
117e6b45241SJulian Anastasov 
118e6b45241SJulian Anastasov /* Reset some input parameters after previous lookup */
119e6b45241SJulian Anastasov static inline void flowi4_update_output(struct flowi4 *fl4, int oif, __u8 tos,
120e6b45241SJulian Anastasov 					__be32 daddr, __be32 saddr)
121e6b45241SJulian Anastasov {
122e6b45241SJulian Anastasov 	fl4->flowi4_oif = oif;
123e6b45241SJulian Anastasov 	fl4->flowi4_tos = tos;
124e6b45241SJulian Anastasov 	fl4->daddr = daddr;
125e6b45241SJulian Anastasov 	fl4->saddr = saddr;
126e6b45241SJulian Anastasov }
12783229aa5SDavid S. Miller 
12883229aa5SDavid S. Miller 
12956bb8059SDavid S. Miller struct flowi6 {
13056bb8059SDavid S. Miller 	struct flowi_common	__fl_common;
1312032656eSDavid S. Miller #define flowi6_oif		__fl_common.flowic_oif
1322032656eSDavid S. Miller #define flowi6_iif		__fl_common.flowic_iif
1332032656eSDavid S. Miller #define flowi6_mark		__fl_common.flowic_mark
1342032656eSDavid S. Miller #define flowi6_scope		__fl_common.flowic_scope
1352032656eSDavid S. Miller #define flowi6_proto		__fl_common.flowic_proto
1362032656eSDavid S. Miller #define flowi6_flags		__fl_common.flowic_flags
1372032656eSDavid S. Miller #define flowi6_secid		__fl_common.flowic_secid
138904af04dSJiri Benc #define flowi6_tun_key		__fl_common.flowic_tun_key
139622ec2c9SLorenzo Colitti #define flowi6_uid		__fl_common.flowic_uid
1401da177e4SLinus Torvalds 	struct in6_addr		daddr;
1411da177e4SLinus Torvalds 	struct in6_addr		saddr;
14269716a2bSDaniel Borkmann 	/* Note: flowi6_tos is encoded in flowlabel, too. */
14390bcaf7bSAl Viro 	__be32			flowlabel;
14456bb8059SDavid S. Miller 	union flowi_uli		uli;
1451958b856SDavid S. Miller #define fl6_sport		uli.ports.sport
1461958b856SDavid S. Miller #define fl6_dport		uli.ports.dport
1471958b856SDavid S. Miller #define fl6_icmp_type		uli.icmpt.type
1481958b856SDavid S. Miller #define fl6_icmp_code		uli.icmpt.code
1491958b856SDavid S. Miller #define fl6_ipsec_spi		uli.spi
1501958b856SDavid S. Miller #define fl6_mh_type		uli.mht.type
1511958b856SDavid S. Miller #define fl6_gre_key		uli.gre_key
152728871bcSDavid Ward } __attribute__((__aligned__(BITS_PER_LONG/8)));
1531da177e4SLinus Torvalds 
15456bb8059SDavid S. Miller struct flowidn {
15556bb8059SDavid S. Miller 	struct flowi_common	__fl_common;
156bef55aebSDavid S. Miller #define flowidn_oif		__fl_common.flowic_oif
157bef55aebSDavid S. Miller #define flowidn_iif		__fl_common.flowic_iif
158bef55aebSDavid S. Miller #define flowidn_mark		__fl_common.flowic_mark
159bef55aebSDavid S. Miller #define flowidn_scope		__fl_common.flowic_scope
160bef55aebSDavid S. Miller #define flowidn_proto		__fl_common.flowic_proto
161bef55aebSDavid S. Miller #define flowidn_flags		__fl_common.flowic_flags
162c4ea94abSSteven Whitehouse 	__le16			daddr;
163c4ea94abSSteven Whitehouse 	__le16			saddr;
16456bb8059SDavid S. Miller 	union flowi_uli		uli;
165bef55aebSDavid S. Miller #define fld_sport		uli.ports.sport
166bef55aebSDavid S. Miller #define fld_dport		uli.ports.dport
167728871bcSDavid Ward } __attribute__((__aligned__(BITS_PER_LONG/8)));
16856bb8059SDavid S. Miller 
16956bb8059SDavid S. Miller struct flowi {
17056bb8059SDavid S. Miller 	union {
17156bb8059SDavid S. Miller 		struct flowi_common	__fl_common;
17256bb8059SDavid S. Miller 		struct flowi4		ip4;
17356bb8059SDavid S. Miller 		struct flowi6		ip6;
17456bb8059SDavid S. Miller 		struct flowidn		dn;
17556bb8059SDavid S. Miller 	} u;
17656bb8059SDavid S. Miller #define flowi_oif	u.__fl_common.flowic_oif
17756bb8059SDavid S. Miller #define flowi_iif	u.__fl_common.flowic_iif
17856bb8059SDavid S. Miller #define flowi_mark	u.__fl_common.flowic_mark
17956bb8059SDavid S. Miller #define flowi_tos	u.__fl_common.flowic_tos
18056bb8059SDavid S. Miller #define flowi_scope	u.__fl_common.flowic_scope
18156bb8059SDavid S. Miller #define flowi_proto	u.__fl_common.flowic_proto
18256bb8059SDavid S. Miller #define flowi_flags	u.__fl_common.flowic_flags
18356bb8059SDavid S. Miller #define flowi_secid	u.__fl_common.flowic_secid
1841b7179d3SThomas Graf #define flowi_tun_key	u.__fl_common.flowic_tun_key
185622ec2c9SLorenzo Colitti #define flowi_uid	u.__fl_common.flowic_uid
1861da177e4SLinus Torvalds } __attribute__((__aligned__(BITS_PER_LONG/8)));
1871da177e4SLinus Torvalds 
18859b1a94cSDavid S. Miller static inline struct flowi *flowi4_to_flowi(struct flowi4 *fl4)
18959b1a94cSDavid S. Miller {
19059b1a94cSDavid S. Miller 	return container_of(fl4, struct flowi, u.ip4);
19159b1a94cSDavid S. Miller }
19259b1a94cSDavid S. Miller 
19359b1a94cSDavid S. Miller static inline struct flowi *flowi6_to_flowi(struct flowi6 *fl6)
19459b1a94cSDavid S. Miller {
19559b1a94cSDavid S. Miller 	return container_of(fl6, struct flowi, u.ip6);
19659b1a94cSDavid S. Miller }
19759b1a94cSDavid S. Miller 
19859b1a94cSDavid S. Miller static inline struct flowi *flowidn_to_flowi(struct flowidn *fldn)
19959b1a94cSDavid S. Miller {
20059b1a94cSDavid S. Miller 	return container_of(fldn, struct flowi, u.dn);
20159b1a94cSDavid S. Miller }
20259b1a94cSDavid S. Miller 
203aa1c366eSdpward typedef unsigned long flow_compare_t;
204aa1c366eSdpward 
205aa1c366eSdpward static inline size_t flow_key_size(u16 family)
206aa1c366eSdpward {
207aa1c366eSdpward 	switch (family) {
208aa1c366eSdpward 	case AF_INET:
209aa1c366eSdpward 		BUILD_BUG_ON(sizeof(struct flowi4) % sizeof(flow_compare_t));
210aa1c366eSdpward 		return sizeof(struct flowi4) / sizeof(flow_compare_t);
211aa1c366eSdpward 	case AF_INET6:
212aa1c366eSdpward 		BUILD_BUG_ON(sizeof(struct flowi6) % sizeof(flow_compare_t));
213aa1c366eSdpward 		return sizeof(struct flowi6) / sizeof(flow_compare_t);
214aa1c366eSdpward 	case AF_DECnet:
215aa1c366eSdpward 		BUILD_BUG_ON(sizeof(struct flowidn) % sizeof(flow_compare_t));
216aa1c366eSdpward 		return sizeof(struct flowidn) / sizeof(flow_compare_t);
217aa1c366eSdpward 	}
218aa1c366eSdpward 	return 0;
219aa1c366eSdpward }
220aa1c366eSdpward 
2211da177e4SLinus Torvalds #define FLOW_DIR_IN	0
2221da177e4SLinus Torvalds #define FLOW_DIR_OUT	1
2231da177e4SLinus Torvalds #define FLOW_DIR_FWD	2
2241da177e4SLinus Torvalds 
22552479b62SAlexey Dobriyan struct net;
226df71837dSTrent Jaeger struct sock;
227fe1a5f03STimo Teräs struct flow_cache_ops;
2281da177e4SLinus Torvalds 
229fe1a5f03STimo Teräs struct flow_cache_object {
230fe1a5f03STimo Teräs 	const struct flow_cache_ops *ops;
231fe1a5f03STimo Teräs };
232fe1a5f03STimo Teräs 
233fe1a5f03STimo Teräs struct flow_cache_ops {
234fe1a5f03STimo Teräs 	struct flow_cache_object *(*get)(struct flow_cache_object *);
235fe1a5f03STimo Teräs 	int (*check)(struct flow_cache_object *);
236fe1a5f03STimo Teräs 	void (*delete)(struct flow_cache_object *);
237fe1a5f03STimo Teräs };
238fe1a5f03STimo Teräs 
239fe1a5f03STimo Teräs typedef struct flow_cache_object *(*flow_resolve_t)(
240dee9f4bcSDavid S. Miller 		struct net *net, const struct flowi *key, u16 family,
241fe1a5f03STimo Teräs 		u8 dir, struct flow_cache_object *oldobj, void *ctx);
242fe1a5f03STimo Teräs 
2434787342cSJoe Perches struct flow_cache_object *flow_cache_lookup(struct net *net,
2444787342cSJoe Perches 					    const struct flowi *key, u16 family,
2454787342cSJoe Perches 					    u8 dir, flow_resolve_t resolver,
2464787342cSJoe Perches 					    void *ctx);
247ca925cf1SFan Du int flow_cache_init(struct net *net);
2484a93f509SSteffen Klassert void flow_cache_fini(struct net *net);
249fe1a5f03STimo Teräs 
250ca925cf1SFan Du void flow_cache_flush(struct net *net);
251ca925cf1SFan Du void flow_cache_flush_deferred(struct net *net);
2521da177e4SLinus Torvalds extern atomic_t flow_cache_genid;
2531da177e4SLinus Torvalds 
25420a17bf6SDavid S. Miller __u32 __get_hash_from_flowi6(const struct flowi6 *fl6, struct flow_keys *keys);
255c6cc1ca7STom Herbert 
25620a17bf6SDavid S. Miller static inline __u32 get_hash_from_flowi6(const struct flowi6 *fl6)
257c6cc1ca7STom Herbert {
258c6cc1ca7STom Herbert 	struct flow_keys keys;
259c6cc1ca7STom Herbert 
260c6cc1ca7STom Herbert 	return __get_hash_from_flowi6(fl6, &keys);
261c6cc1ca7STom Herbert }
262c6cc1ca7STom Herbert 
26320a17bf6SDavid S. Miller __u32 __get_hash_from_flowi4(const struct flowi4 *fl4, struct flow_keys *keys);
264c6cc1ca7STom Herbert 
26520a17bf6SDavid S. Miller static inline __u32 get_hash_from_flowi4(const struct flowi4 *fl4)
266c6cc1ca7STom Herbert {
267c6cc1ca7STom Herbert 	struct flow_keys keys;
268c6cc1ca7STom Herbert 
269c6cc1ca7STom Herbert 	return __get_hash_from_flowi4(fl4, &keys);
270c6cc1ca7STom Herbert }
271c6cc1ca7STom Herbert 
2721da177e4SLinus Torvalds #endif
273