1694 lines · 46.4 KB · C
RawDownload
#ifndef _NET_XFRM_H#define _NET_XFRM_H #include <linux/compiler.h>#include <linux/xfrm.h>#include <linux/spinlock.h>#include <linux/list.h>#include <linux/skbuff.h>#include <linux/socket.h>#include <linux/pfkeyv2.h>#include <linux/ipsec.h>#include <linux/in6.h>#include <linux/mutex.h>#include <linux/audit.h>#include <linux/slab.h> #include <net/sock.h>#include <net/dst.h>#include <net/ip.h>#include <net/route.h>#include <net/ipv6.h>#include <net/ip6_fib.h>#include <net/flow.h> #include <linux/interrupt.h> #ifdef CONFIG_XFRM_STATISTICS#include <net/snmp.h>#endif #define XFRM_PROTO_ESP		50#define XFRM_PROTO_AH		51#define XFRM_PROTO_COMP		108#define XFRM_PROTO_IPIP		4#define XFRM_PROTO_IPV6		41#define XFRM_PROTO_ROUTING	IPPROTO_ROUTING#define XFRM_PROTO_DSTOPTS	IPPROTO_DSTOPTS #define XFRM_ALIGN4(len)	(((len) + 3) & ~3)#define XFRM_ALIGN8(len)	(((len) + 7) & ~7)#define MODULE_ALIAS_XFRM_MODE(family, encap) \	MODULE_ALIAS("xfrm-mode-" __stringify(family) "-" __stringify(encap))#define MODULE_ALIAS_XFRM_TYPE(family, proto) \	MODULE_ALIAS("xfrm-type-" __stringify(family) "-" __stringify(proto)) #ifdef CONFIG_XFRM_STATISTICS#define XFRM_INC_STATS(net, field)	SNMP_INC_STATS((net)->mib.xfrm_statistics, field)#define XFRM_INC_STATS_BH(net, field)	SNMP_INC_STATS_BH((net)->mib.xfrm_statistics, field)#define XFRM_INC_STATS_USER(net, field)	SNMP_INC_STATS_USER((net)-mib.xfrm_statistics, field)#else#define XFRM_INC_STATS(net, field)	((void)(net))#define XFRM_INC_STATS_BH(net, field)	((void)(net))#define XFRM_INC_STATS_USER(net, field)	((void)(net))#endif extern struct mutex xfrm_cfg_mutex; /* Organization of SPD aka "XFRM rules"   ------------------------------------    Basic objects:   - policy rule, struct xfrm_policy (=SPD entry)   - bundle of transformations, struct dst_entry == struct xfrm_dst (=SA bundle)   - instance of a transformer, struct xfrm_state (=SA)   - template to clone xfrm_state, struct xfrm_tmpl    SPD is plain linear list of xfrm_policy rules, ordered by priority.   (To be compatible with existing pfkeyv2 implementations,   many rules with priority of 0x7fffffff are allowed to exist and   such rules are ordered in an unpredictable way, thanks to bsd folks.)    Lookup is plain linear search until the first match with selector.    If "action" is "block", then we prohibit the flow, otherwise:   if "xfrms_nr" is zero, the flow passes untransformed. Otherwise,   policy entry has list of up to XFRM_MAX_DEPTH transformations,   described by templates xfrm_tmpl. Each template is resolved   to a complete xfrm_state (see below) and we pack bundle of transformations   to a dst_entry returned to requestor.    dst -. xfrm  .-> xfrm_state #1    |---. child .-> dst -. xfrm .-> xfrm_state #2                     |---. child .-> dst -. xfrm .-> xfrm_state #3                                      |---. child .-> NULL    Bundles are cached at xrfm_policy struct (field ->bundles).     Resolution of xrfm_tmpl   -----------------------   Template contains:   1. ->mode		Mode: transport or tunnel   2. ->id.proto	Protocol: AH/ESP/IPCOMP   3. ->id.daddr	Remote tunnel endpoint, ignored for transport mode.      Q: allow to resolve security gateway?   4. ->id.spi          If not zero, static SPI.   5. ->saddr		Local tunnel endpoint, ignored for transport mode.   6. ->algos		List of allowed algos. Plain bitmask now.      Q: ealgos, aalgos, calgos. What a mess...   7. ->share		Sharing mode.      Q: how to implement private sharing mode? To add struct sock* to      flow id?    Having this template we search through SAD searching for entries   with appropriate mode/proto/algo, permitted by selector.   If no appropriate entry found, it is requested from key manager.    PROBLEMS:   Q: How to find all the bundles referring to a physical path for      PMTU discovery? Seems, dst should contain list of all parents...      and enter to infinite locking hierarchy disaster.      No! It is easier, we will not search for them, let them find us.      We add genid to each dst plus pointer to genid of raw IP route,      pmtu disc will update pmtu on raw IP route and increase its genid.      dst_check() will see this for top level and trigger resyncing      metrics. Plus, it will be made via sk->sk_dst_cache. Solved. */ struct xfrm_state_walk {	struct list_head	all;	u8			state;	union {		u8		dying;		u8		proto;	};	u32			seq;}; /* Full description of state of transformer. */struct xfrm_state {#ifdef CONFIG_NET_NS	struct net		*xs_net;#endif	union {		struct hlist_node	gclist;		struct hlist_node	bydst;	};	struct hlist_node	bysrc;	struct hlist_node	byspi; 	atomic_t		refcnt;	spinlock_t		lock; 	struct xfrm_id		id;	struct xfrm_selector	sel;	struct xfrm_mark	mark;	u32			tfcpad; 	u32			genid; 	/* Key manager bits */	struct xfrm_state_walk	km; 	/* Parameters of this state. */	struct {		u32		reqid;		u8		mode;		u8		replay_window;		u8		aalgo, ealgo, calgo;		u8		flags;		u16		family;		xfrm_address_t	saddr;		int		header_len;		int		trailer_len;	} props; 	struct xfrm_lifetime_cfg lft; 	/* Data for transformer */	struct xfrm_algo_auth	*aalg;	struct xfrm_algo	*ealg;	struct xfrm_algo	*calg;	struct xfrm_algo_aead	*aead; 	/* Data for encapsulator */	struct xfrm_encap_tmpl	*encap; 	/* Data for care-of address */	xfrm_address_t	*coaddr; 	/* IPComp needs an IPIP tunnel for handling uncompressed packets */	struct xfrm_state	*tunnel; 	/* If a tunnel, number of users + 1 */	atomic_t		tunnel_users; 	/* State for replay detection */	struct xfrm_replay_state replay;	struct xfrm_replay_state_esn *replay_esn; 	/* Replay detection state at the time we sent the last notification */	struct xfrm_replay_state preplay;	struct xfrm_replay_state_esn *preplay_esn; 	/* The functions for replay detection. */	struct xfrm_replay	*repl; 	/* internal flag that only holds state for delayed aevent at the	 * moment	*/	u32			xflags; 	/* Replay detection notification settings */	u32			replay_maxage;	u32			replay_maxdiff; 	/* Replay detection notification timer */	struct timer_list	rtimer; 	/* Statistics */	struct xfrm_stats	stats; 	struct xfrm_lifetime_cur curlft;	struct tasklet_hrtimer	mtimer; 	/* Last used time */	unsigned long		lastused; 	/* Reference to data common to all the instances of this	 * transformer. */	const struct xfrm_type	*type;	struct xfrm_mode	*inner_mode;	struct xfrm_mode	*inner_mode_iaf;	struct xfrm_mode	*outer_mode; 	/* Security context */	struct xfrm_sec_ctx	*security; 	/* Private data of this transformer, format is opaque,	 * interpreted by xfrm_type methods. */	void			*data;}; static inline struct net *xs_net(struct xfrm_state *x){	return read_pnet(&x->xs_net);} /* xflags - make enum if more show up */#define XFRM_TIME_DEFER	1 enum {	XFRM_STATE_VOID,	XFRM_STATE_ACQ,	XFRM_STATE_VALID,	XFRM_STATE_ERROR,	XFRM_STATE_EXPIRED,	XFRM_STATE_DEAD}; /* callback structure passed from either netlink or pfkey */struct km_event {	union {		u32 hard;		u32 proto;		u32 byid;		u32 aevent;		u32 type;	} data; 	u32	seq;	u32	pid;	u32	event;	struct net *net;}; struct xfrm_replay {	void	(*advance)(struct xfrm_state *x, __be32 net_seq);	int	(*check)(struct xfrm_state *x,			 struct sk_buff *skb,			 __be32 net_seq);	void	(*notify)(struct xfrm_state *x, int event);	int	(*overflow)(struct xfrm_state *x, struct sk_buff *skb);}; struct net_device;struct xfrm_type;struct xfrm_dst;struct xfrm_policy_afinfo {	unsigned short		family;	struct dst_ops		*dst_ops;	void			(*garbage_collect)(struct net *net);	struct dst_entry	*(*dst_lookup)(struct net *net, int tos,					       const xfrm_address_t *saddr,					       const xfrm_address_t *daddr);	int			(*get_saddr)(struct net *net, xfrm_address_t *saddr, xfrm_address_t *daddr);	void			(*decode_session)(struct sk_buff *skb,						  struct flowi *fl,						  int reverse);	int			(*get_tos)(const struct flowi *fl);	int			(*init_path)(struct xfrm_dst *path,					     struct dst_entry *dst,					     int nfheader_len);	int			(*fill_dst)(struct xfrm_dst *xdst,					    struct net_device *dev,					    const struct flowi *fl);	struct dst_entry	*(*blackhole_route)(struct net *net, struct dst_entry *orig);}; extern int xfrm_policy_register_afinfo(struct xfrm_policy_afinfo *afinfo);extern int xfrm_policy_unregister_afinfo(struct xfrm_policy_afinfo *afinfo);extern void km_policy_notify(struct xfrm_policy *xp, int dir, const struct km_event *c);extern void km_state_notify(struct xfrm_state *x, const struct km_event *c); struct xfrm_tmpl;extern int km_query(struct xfrm_state *x, struct xfrm_tmpl *t, struct xfrm_policy *pol);extern void km_state_expired(struct xfrm_state *x, int hard, u32 pid);extern int __xfrm_state_delete(struct xfrm_state *x); struct xfrm_state_afinfo {	unsigned int		family;	unsigned int		proto;	__be16			eth_proto;	struct module		*owner;	const struct xfrm_type	*type_map[IPPROTO_MAX];	struct xfrm_mode	*mode_map[XFRM_MODE_MAX];	int			(*init_flags)(struct xfrm_state *x);	void			(*init_tempsel)(struct xfrm_selector *sel,						const struct flowi *fl);	void			(*init_temprop)(struct xfrm_state *x,						const struct xfrm_tmpl *tmpl,						const xfrm_address_t *daddr,						const xfrm_address_t *saddr);	int			(*tmpl_sort)(struct xfrm_tmpl **dst, struct xfrm_tmpl **src, int n);	int			(*state_sort)(struct xfrm_state **dst, struct xfrm_state **src, int n);	int			(*output)(struct sk_buff *skb);	int			(*output_finish)(struct sk_buff *skb);	int			(*extract_input)(struct xfrm_state *x,						 struct sk_buff *skb);	int			(*extract_output)(struct xfrm_state *x,						  struct sk_buff *skb);	int			(*transport_finish)(struct sk_buff *skb,						    int async);}; extern int xfrm_state_register_afinfo(struct xfrm_state_afinfo *afinfo);extern int xfrm_state_unregister_afinfo(struct xfrm_state_afinfo *afinfo); extern void xfrm_state_delete_tunnel(struct xfrm_state *x); struct xfrm_type {	char			*description;	struct module		*owner;	u8			proto;	u8			flags;#define XFRM_TYPE_NON_FRAGMENT	1#define XFRM_TYPE_REPLAY_PROT	2#define XFRM_TYPE_LOCAL_COADDR	4#define XFRM_TYPE_REMOTE_COADDR	8 	int			(*init_state)(struct xfrm_state *x);	void			(*destructor)(struct xfrm_state *);	int			(*input)(struct xfrm_state *, struct sk_buff *skb);	int			(*output)(struct xfrm_state *, struct sk_buff *pskb);	int			(*reject)(struct xfrm_state *, struct sk_buff *,					  const struct flowi *);	int			(*hdr_offset)(struct xfrm_state *, struct sk_buff *, u8 **);	/* Estimate maximal size of result of transformation of a dgram */	u32			(*get_mtu)(struct xfrm_state *, int size);}; extern int xfrm_register_type(const struct xfrm_type *type, unsigned short family);extern int xfrm_unregister_type(const struct xfrm_type *type, unsigned short family); struct xfrm_mode {	/*	 * Remove encapsulation header.	 *	 * The IP header will be moved over the top of the encapsulation	 * header.	 *	 * On entry, the transport header shall point to where the IP header	 * should be and the network header shall be set to where the IP	 * header currently is.  skb->data shall point to the start of the	 * payload.	 */	int (*input2)(struct xfrm_state *x, struct sk_buff *skb); 	/*	 * This is the actual input entry point.	 *	 * For transport mode and equivalent this would be identical to	 * input2 (which does not need to be set).  While tunnel mode	 * and equivalent would set this to the tunnel encapsulation function	 * xfrm4_prepare_input that would in turn call input2.	 */	int (*input)(struct xfrm_state *x, struct sk_buff *skb); 	/*	 * Add encapsulation header.	 *	 * On exit, the transport header will be set to the start of the	 * encapsulation header to be filled in by x->type->output and	 * the mac header will be set to the nextheader (protocol for	 * IPv4) field of the extension header directly preceding the	 * encapsulation header, or in its absence, that of the top IP	 * header.  The value of the network header will always point	 * to the top IP header while skb->data will point to the payload.	 */	int (*output2)(struct xfrm_state *x,struct sk_buff *skb); 	/*	 * This is the actual output entry point.	 *	 * For transport mode and equivalent this would be identical to	 * output2 (which does not need to be set).  While tunnel mode	 * and equivalent would set this to a tunnel encapsulation function	 * (xfrm4_prepare_output or xfrm6_prepare_output) that would in turn	 * call output2.	 */	int (*output)(struct xfrm_state *x, struct sk_buff *skb); 	struct xfrm_state_afinfo *afinfo;	struct module *owner;	unsigned int encap;	int flags;}; /* Flags for xfrm_mode. */enum {	XFRM_MODE_FLAG_TUNNEL = 1,}; extern int xfrm_register_mode(struct xfrm_mode *mode, int family);extern int xfrm_unregister_mode(struct xfrm_mode *mode, int family); static inline int xfrm_af2proto(unsigned int family){	switch(family) {	case AF_INET:		return IPPROTO_IPIP;	case AF_INET6:		return IPPROTO_IPV6;	default:		return 0;	}} static inline struct xfrm_mode *xfrm_ip2inner_mode(struct xfrm_state *x, int ipproto){	if ((ipproto == IPPROTO_IPIP && x->props.family == AF_INET) ||	    (ipproto == IPPROTO_IPV6 && x->props.family == AF_INET6))		return x->inner_mode;	else		return x->inner_mode_iaf;} struct xfrm_tmpl {/* id in template is interpreted as: * daddr - destination of tunnel, may be zero for transport mode. * spi   - zero to acquire spi. Not zero if spi is static, then *	   daddr must be fixed too. * proto - AH/ESP/IPCOMP */	struct xfrm_id		id; /* Source address of tunnel. Ignored, if it is not a tunnel. */	xfrm_address_t		saddr; 	unsigned short		encap_family; 	u32			reqid; /* Mode: transport, tunnel etc. */	u8			mode; /* Sharing mode: unique, this session only, this user only etc. */	u8			share; /* May skip this transfomration if no SA is found */	u8			optional; /* Skip aalgos/ealgos/calgos checks. */	u8			allalgs; /* Bit mask of algos allowed for acquisition */	u32			aalgos;	u32			ealgos;	u32			calgos;}; #define XFRM_MAX_DEPTH		6 struct xfrm_policy_walk_entry {	struct list_head	all;	u8			dead;}; struct xfrm_policy_walk {	struct xfrm_policy_walk_entry walk;	u8 type;	u32 seq;}; struct xfrm_policy {#ifdef CONFIG_NET_NS	struct net		*xp_net;#endif	struct hlist_node	bydst;	struct hlist_node	byidx;

Lines 1–500 of 1694.

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t