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