diff options
Diffstat (limited to 'include/net/flow.h')
| -rw-r--r-- | include/net/flow.h | 277 | 
1 files changed, 196 insertions, 81 deletions
diff --git a/include/net/flow.h b/include/net/flow.h index 7196e6864b8..8109a159d1b 100644 --- a/include/net/flow.h +++ b/include/net/flow.h @@ -7,82 +7,199 @@  #ifndef _NET_FLOW_H  #define _NET_FLOW_H +#include <linux/socket.h>  #include <linux/in6.h> -#include <asm/atomic.h> +#include <linux/atomic.h> -struct flowi { -	int	oif; -	int	iif; -	__u32	mark; +/* + * ifindex generation is per-net namespace, and loopback is + * always the 1st device in ns (see net_dev_init), thus any + * loopback device should get ifindex 1 + */ +#define LOOPBACK_IFINDEX	1 + +struct flowi_common { +	int	flowic_oif; +	int	flowic_iif; +	__u32	flowic_mark; +	__u8	flowic_tos; +	__u8	flowic_scope; +	__u8	flowic_proto; +	__u8	flowic_flags; +#define FLOWI_FLAG_ANYSRC		0x01 +#define FLOWI_FLAG_KNOWN_NH		0x02 +	__u32	flowic_secid; +}; + +union flowi_uli { +	struct { +		__be16	dport; +		__be16	sport; +	} ports; + +	struct { +		__u8	type; +		__u8	code; +	} icmpt; + +	struct { +		__le16	dport; +		__le16	sport; +	} dnports; + +	__be32		spi; +	__be32		gre_key; + +	struct { +		__u8	type; +	} mht; +}; + +struct flowi4 { +	struct flowi_common	__fl_common; +#define flowi4_oif		__fl_common.flowic_oif +#define flowi4_iif		__fl_common.flowic_iif +#define flowi4_mark		__fl_common.flowic_mark +#define flowi4_tos		__fl_common.flowic_tos +#define flowi4_scope		__fl_common.flowic_scope +#define flowi4_proto		__fl_common.flowic_proto +#define flowi4_flags		__fl_common.flowic_flags +#define flowi4_secid		__fl_common.flowic_secid + +	/* (saddr,daddr) must be grouped, same order as in IP header */ +	__be32			saddr; +	__be32			daddr; + +	union flowi_uli		uli; +#define fl4_sport		uli.ports.sport +#define fl4_dport		uli.ports.dport +#define fl4_icmp_type		uli.icmpt.type +#define fl4_icmp_code		uli.icmpt.code +#define fl4_ipsec_spi		uli.spi +#define fl4_mh_type		uli.mht.type +#define fl4_gre_key		uli.gre_key +} __attribute__((__aligned__(BITS_PER_LONG/8))); + +static inline void flowi4_init_output(struct flowi4 *fl4, int oif, +				      __u32 mark, __u8 tos, __u8 scope, +				      __u8 proto, __u8 flags, +				      __be32 daddr, __be32 saddr, +				      __be16 dport, __be16 sport) +{ +	fl4->flowi4_oif = oif; +	fl4->flowi4_iif = LOOPBACK_IFINDEX; +	fl4->flowi4_mark = mark; +	fl4->flowi4_tos = tos; +	fl4->flowi4_scope = scope; +	fl4->flowi4_proto = proto; +	fl4->flowi4_flags = flags; +	fl4->flowi4_secid = 0; +	fl4->daddr = daddr; +	fl4->saddr = saddr; +	fl4->fl4_dport = dport; +	fl4->fl4_sport = sport; +} + +/* Reset some input parameters after previous lookup */ +static inline void flowi4_update_output(struct flowi4 *fl4, int oif, __u8 tos, +					__be32 daddr, __be32 saddr) +{ +	fl4->flowi4_oif = oif; +	fl4->flowi4_tos = tos; +	fl4->daddr = daddr; +	fl4->saddr = saddr; +} +				       + +struct flowi6 { +	struct flowi_common	__fl_common; +#define flowi6_oif		__fl_common.flowic_oif +#define flowi6_iif		__fl_common.flowic_iif +#define flowi6_mark		__fl_common.flowic_mark +#define flowi6_tos		__fl_common.flowic_tos +#define flowi6_scope		__fl_common.flowic_scope +#define flowi6_proto		__fl_common.flowic_proto +#define flowi6_flags		__fl_common.flowic_flags +#define flowi6_secid		__fl_common.flowic_secid +	struct in6_addr		daddr; +	struct in6_addr		saddr; +	__be32			flowlabel; +	union flowi_uli		uli; +#define fl6_sport		uli.ports.sport +#define fl6_dport		uli.ports.dport +#define fl6_icmp_type		uli.icmpt.type +#define fl6_icmp_code		uli.icmpt.code +#define fl6_ipsec_spi		uli.spi +#define fl6_mh_type		uli.mht.type +#define fl6_gre_key		uli.gre_key +} __attribute__((__aligned__(BITS_PER_LONG/8))); + +struct flowidn { +	struct flowi_common	__fl_common; +#define flowidn_oif		__fl_common.flowic_oif +#define flowidn_iif		__fl_common.flowic_iif +#define flowidn_mark		__fl_common.flowic_mark +#define flowidn_scope		__fl_common.flowic_scope +#define flowidn_proto		__fl_common.flowic_proto +#define flowidn_flags		__fl_common.flowic_flags +	__le16			daddr; +	__le16			saddr; +	union flowi_uli		uli; +#define fld_sport		uli.ports.sport +#define fld_dport		uli.ports.dport +} __attribute__((__aligned__(BITS_PER_LONG/8))); + +struct flowi {  	union { -		struct { -			__be32			daddr; -			__be32			saddr; -			__u8			tos; -			__u8			scope; -		} ip4_u; -		 -		struct { -			struct in6_addr		daddr; -			struct in6_addr		saddr; -			__be32			flowlabel; -		} ip6_u; - -		struct { -			__le16			daddr; -			__le16			saddr; -			__u8			scope; -		} dn_u; -	} nl_u; -#define fld_dst		nl_u.dn_u.daddr -#define fld_src		nl_u.dn_u.saddr -#define fld_scope	nl_u.dn_u.scope -#define fl6_dst		nl_u.ip6_u.daddr -#define fl6_src		nl_u.ip6_u.saddr -#define fl6_flowlabel	nl_u.ip6_u.flowlabel -#define fl4_dst		nl_u.ip4_u.daddr -#define fl4_src		nl_u.ip4_u.saddr -#define fl4_tos		nl_u.ip4_u.tos -#define fl4_scope	nl_u.ip4_u.scope - -	__u8	proto; -	__u8	flags; -#define FLOWI_FLAG_ANYSRC 0x01 -#define FLOWI_FLAG_MATCH_ANY_IIF 0x02 -	union { -		struct { -			__be16	sport; -			__be16	dport; -		} ports; - -		struct { -			__u8	type; -			__u8	code; -		} icmpt; - -		struct { -			__le16	sport; -			__le16	dport; -		} dnports; - -		__be32		spi; -		__be32		gre_key; - -		struct { -			__u8	type; -		} mht; -	} uli_u; -#define fl_ip_sport	uli_u.ports.sport -#define fl_ip_dport	uli_u.ports.dport -#define fl_icmp_type	uli_u.icmpt.type -#define fl_icmp_code	uli_u.icmpt.code -#define fl_ipsec_spi	uli_u.spi -#define fl_mh_type	uli_u.mht.type -#define fl_gre_key	uli_u.gre_key -	__u32           secid;	/* used by xfrm; see secid.txt */ +		struct flowi_common	__fl_common; +		struct flowi4		ip4; +		struct flowi6		ip6; +		struct flowidn		dn; +	} u; +#define flowi_oif	u.__fl_common.flowic_oif +#define flowi_iif	u.__fl_common.flowic_iif +#define flowi_mark	u.__fl_common.flowic_mark +#define flowi_tos	u.__fl_common.flowic_tos +#define flowi_scope	u.__fl_common.flowic_scope +#define flowi_proto	u.__fl_common.flowic_proto +#define flowi_flags	u.__fl_common.flowic_flags +#define flowi_secid	u.__fl_common.flowic_secid  } __attribute__((__aligned__(BITS_PER_LONG/8))); +static inline struct flowi *flowi4_to_flowi(struct flowi4 *fl4) +{ +	return container_of(fl4, struct flowi, u.ip4); +} + +static inline struct flowi *flowi6_to_flowi(struct flowi6 *fl6) +{ +	return container_of(fl6, struct flowi, u.ip6); +} + +static inline struct flowi *flowidn_to_flowi(struct flowidn *fldn) +{ +	return container_of(fldn, struct flowi, u.dn); +} + +typedef unsigned long flow_compare_t; + +static inline size_t flow_key_size(u16 family) +{ +	switch (family) { +	case AF_INET: +		BUILD_BUG_ON(sizeof(struct flowi4) % sizeof(flow_compare_t)); +		return sizeof(struct flowi4) / sizeof(flow_compare_t); +	case AF_INET6: +		BUILD_BUG_ON(sizeof(struct flowi6) % sizeof(flow_compare_t)); +		return sizeof(struct flowi6) / sizeof(flow_compare_t); +	case AF_DECnet: +		BUILD_BUG_ON(sizeof(struct flowidn) % sizeof(flow_compare_t)); +		return sizeof(struct flowidn) / sizeof(flow_compare_t); +	} +	return 0; +} +  #define FLOW_DIR_IN	0  #define FLOW_DIR_OUT	1  #define FLOW_DIR_FWD	2 @@ -102,20 +219,18 @@ struct flow_cache_ops {  };  typedef struct flow_cache_object *(*flow_resolve_t)( -		struct net *net, struct flowi *key, u16 family, +		struct net *net, const struct flowi *key, u16 family,  		u8 dir, struct flow_cache_object *oldobj, void *ctx); -extern struct flow_cache_object *flow_cache_lookup( -		struct net *net, struct flowi *key, u16 family, -		u8 dir, flow_resolve_t resolver, void *ctx); +struct flow_cache_object *flow_cache_lookup(struct net *net, +					    const struct flowi *key, u16 family, +					    u8 dir, flow_resolve_t resolver, +					    void *ctx); +int flow_cache_init(struct net *net); +void flow_cache_fini(struct net *net); -extern void flow_cache_flush(void); +void flow_cache_flush(struct net *net); +void flow_cache_flush_deferred(struct net *net);  extern atomic_t flow_cache_genid; -static inline int flow_cache_uli_match(struct flowi *fl1, struct flowi *fl2) -{ -	return (fl1->proto == fl2->proto && -		!memcmp(&fl1->uli_u, &fl2->uli_u, sizeof(fl1->uli_u))); -} -  #endif  | 
