1/* 2 * 3 * Generic internet FLOW. 4 * 5 */ 6 7#ifndef _NET_FLOW_H 8#define _NET_FLOW_H 9 10#include <linux/socket.h> 11#include <linux/in6.h> 12#include <linux/atomic.h> 13 14/* 15 * ifindex generation is per-net namespace, and loopback is 16 * always the 1st device in ns (see net_dev_init), thus any 17 * loopback device should get ifindex 1 18 */ 19 20#define LOOPBACK_IFINDEX 1 21 22struct flowi_common { 23 int flowic_oif; 24 int flowic_iif; 25 __u32 flowic_mark; 26 __u8 flowic_tos; 27 __u8 flowic_scope; 28 __u8 flowic_proto; 29 __u8 flowic_flags; 30#define FLOWI_FLAG_ANYSRC 0x01 31#define FLOWI_FLAG_KNOWN_NH 0x02 32 __u32 flowic_secid; 33}; 34 35union flowi_uli { 36 struct { 37 __be16 dport; 38 __be16 sport; 39 } ports; 40 41 struct { 42 __u8 type; 43 __u8 code; 44 } icmpt; 45 46 struct { 47 __le16 dport; 48 __le16 sport; 49 } dnports; 50 51 __be32 spi; 52 __be32 gre_key; 53 54 struct { 55 __u8 type; 56 } mht; 57}; 58 59struct flowi4 { 60 struct flowi_common __fl_common; 61#define flowi4_oif __fl_common.flowic_oif 62#define flowi4_iif __fl_common.flowic_iif 63#define flowi4_mark __fl_common.flowic_mark 64#define flowi4_tos __fl_common.flowic_tos 65#define flowi4_scope __fl_common.flowic_scope 66#define flowi4_proto __fl_common.flowic_proto 67#define flowi4_flags __fl_common.flowic_flags 68#define flowi4_secid __fl_common.flowic_secid 69 70 /* (saddr,daddr) must be grouped, same order as in IP header */ 71 __be32 saddr; 72 __be32 daddr; 73 74 union flowi_uli uli; 75#define fl4_sport uli.ports.sport 76#define fl4_dport uli.ports.dport 77#define fl4_icmp_type uli.icmpt.type 78#define fl4_icmp_code uli.icmpt.code 79#define fl4_ipsec_spi uli.spi 80#define fl4_mh_type uli.mht.type 81#define fl4_gre_key uli.gre_key 82} __attribute__((__aligned__(BITS_PER_LONG/8))); 83 84static inline void flowi4_init_output(struct flowi4 *fl4, int oif, 85 __u32 mark, __u8 tos, __u8 scope, 86 __u8 proto, __u8 flags, 87 __be32 daddr, __be32 saddr, 88 __be16 dport, __be16 sport) 89{ 90 fl4->flowi4_oif = oif; 91 fl4->flowi4_iif = LOOPBACK_IFINDEX; 92 fl4->flowi4_mark = mark; 93 fl4->flowi4_tos = tos; 94 fl4->flowi4_scope = scope; 95 fl4->flowi4_proto = proto; 96 fl4->flowi4_flags = flags; 97 fl4->flowi4_secid = 0; 98 fl4->daddr = daddr; 99 fl4->saddr = saddr; 100 fl4->fl4_dport = dport; 101 fl4->fl4_sport = sport; 102} 103 104/* Reset some input parameters after previous lookup */ 105static inline void flowi4_update_output(struct flowi4 *fl4, int oif, __u8 tos, 106 __be32 daddr, __be32 saddr) 107{ 108 fl4->flowi4_oif = oif; 109 fl4->flowi4_tos = tos; 110 fl4->daddr = daddr; 111 fl4->saddr = saddr; 112} 113 114 115struct flowi6 { 116 struct flowi_common __fl_common; 117#define flowi6_oif __fl_common.flowic_oif 118#define flowi6_iif __fl_common.flowic_iif 119#define flowi6_mark __fl_common.flowic_mark 120#define flowi6_tos __fl_common.flowic_tos 121#define flowi6_scope __fl_common.flowic_scope 122#define flowi6_proto __fl_common.flowic_proto 123#define flowi6_flags __fl_common.flowic_flags 124#define flowi6_secid __fl_common.flowic_secid 125 struct in6_addr daddr; 126 struct in6_addr saddr; 127 __be32 flowlabel; 128 union flowi_uli uli; 129#define fl6_sport uli.ports.sport 130#define fl6_dport uli.ports.dport 131#define fl6_icmp_type uli.icmpt.type 132#define fl6_icmp_code uli.icmpt.code 133#define fl6_ipsec_spi uli.spi 134#define fl6_mh_type uli.mht.type 135#define fl6_gre_key uli.gre_key 136} __attribute__((__aligned__(BITS_PER_LONG/8))); 137 138struct flowidn { 139 struct flowi_common __fl_common; 140#define flowidn_oif __fl_common.flowic_oif 141#define flowidn_iif __fl_common.flowic_iif 142#define flowidn_mark __fl_common.flowic_mark 143#define flowidn_scope __fl_common.flowic_scope 144#define flowidn_proto __fl_common.flowic_proto 145#define flowidn_flags __fl_common.flowic_flags 146 __le16 daddr; 147 __le16 saddr; 148 union flowi_uli uli; 149#define fld_sport uli.ports.sport 150#define fld_dport uli.ports.dport 151} __attribute__((__aligned__(BITS_PER_LONG/8))); 152 153struct flowi { 154 union { 155 struct flowi_common __fl_common; 156 struct flowi4 ip4; 157 struct flowi6 ip6; 158 struct flowidn dn; 159 } u; 160#define flowi_oif u.__fl_common.flowic_oif 161#define flowi_iif u.__fl_common.flowic_iif 162#define flowi_mark u.__fl_common.flowic_mark 163#define flowi_tos u.__fl_common.flowic_tos 164#define flowi_scope u.__fl_common.flowic_scope 165#define flowi_proto u.__fl_common.flowic_proto 166#define flowi_flags u.__fl_common.flowic_flags 167#define flowi_secid u.__fl_common.flowic_secid 168} __attribute__((__aligned__(BITS_PER_LONG/8))); 169 170static inline struct flowi *flowi4_to_flowi(struct flowi4 *fl4) 171{ 172 return container_of(fl4, struct flowi, u.ip4); 173} 174 175static inline struct flowi *flowi6_to_flowi(struct flowi6 *fl6) 176{ 177 return container_of(fl6, struct flowi, u.ip6); 178} 179 180static inline struct flowi *flowidn_to_flowi(struct flowidn *fldn) 181{ 182 return container_of(fldn, struct flowi, u.dn); 183} 184 185typedef unsigned long flow_compare_t; 186 187static inline size_t flow_key_size(u16 family) 188{ 189 switch (family) { 190 case AF_INET: 191 BUILD_BUG_ON(sizeof(struct flowi4) % sizeof(flow_compare_t)); 192 return sizeof(struct flowi4) / sizeof(flow_compare_t); 193 case AF_INET6: 194 BUILD_BUG_ON(sizeof(struct flowi6) % sizeof(flow_compare_t)); 195 return sizeof(struct flowi6) / sizeof(flow_compare_t); 196 case AF_DECnet: 197 BUILD_BUG_ON(sizeof(struct flowidn) % sizeof(flow_compare_t)); 198 return sizeof(struct flowidn) / sizeof(flow_compare_t); 199 } 200 return 0; 201} 202 203#define FLOW_DIR_IN 0 204#define FLOW_DIR_OUT 1 205#define FLOW_DIR_FWD 2 206 207struct net; 208struct sock; 209struct flow_cache_ops; 210 211struct flow_cache_object { 212 const struct flow_cache_ops *ops; 213}; 214 215struct flow_cache_ops { 216 struct flow_cache_object *(*get)(struct flow_cache_object *); 217 int (*check)(struct flow_cache_object *); 218 void (*delete)(struct flow_cache_object *); 219}; 220 221typedef struct flow_cache_object *(*flow_resolve_t)( 222 struct net *net, const struct flowi *key, u16 family, 223 u8 dir, struct flow_cache_object *oldobj, void *ctx); 224 225struct flow_cache_object *flow_cache_lookup(struct net *net, 226 const struct flowi *key, u16 family, 227 u8 dir, flow_resolve_t resolver, 228 void *ctx); 229int flow_cache_init(struct net *net); 230void flow_cache_fini(struct net *net); 231 232void flow_cache_flush(struct net *net); 233void flow_cache_flush_deferred(struct net *net); 234extern atomic_t flow_cache_genid; 235 236#endif 237