diff options
Diffstat (limited to 'include/net/xfrm.h')
| -rw-r--r-- | include/net/xfrm.h | 552 | 
1 files changed, 319 insertions, 233 deletions
diff --git a/include/net/xfrm.h b/include/net/xfrm.h index e253bf0cc7e..721e9c3b11b 100644 --- a/include/net/xfrm.h +++ b/include/net/xfrm.h @@ -53,7 +53,6 @@  #define XFRM_INC_STATS_USER(net, field)	((void)(net))  #endif -extern struct mutex xfrm_cfg_mutex;  /* Organization of SPD aka "XFRM rules"     ------------------------------------ @@ -119,11 +118,10 @@ extern struct mutex xfrm_cfg_mutex;  struct xfrm_state_walk {  	struct list_head	all;  	u8			state; -	union { -		u8		dying; -		u8		proto; -	}; +	u8			dying; +	u8			proto;  	u32			seq; +	struct xfrm_address_filter *filter;  };  /* Full description of state of transformer. */ @@ -307,15 +305,17 @@ struct xfrm_policy_afinfo {  	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); +int xfrm_policy_register_afinfo(struct xfrm_policy_afinfo *afinfo); +int xfrm_policy_unregister_afinfo(struct xfrm_policy_afinfo *afinfo); +void km_policy_notify(struct xfrm_policy *xp, int dir, +		      const struct km_event *c); +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 portid); -extern int __xfrm_state_delete(struct xfrm_state *x); +int km_query(struct xfrm_state *x, struct xfrm_tmpl *t, +	     struct xfrm_policy *pol); +void km_state_expired(struct xfrm_state *x, int hard, u32 portid); +int __xfrm_state_delete(struct xfrm_state *x);  struct xfrm_state_afinfo {  	unsigned int		family; @@ -333,7 +333,7 @@ struct xfrm_state_afinfo {  						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)(struct sock *sk, struct sk_buff *skb);  	int			(*output_finish)(struct sk_buff *skb);  	int			(*extract_input)(struct xfrm_state *x,  						 struct sk_buff *skb); @@ -344,12 +344,22 @@ struct xfrm_state_afinfo {  	void			(*local_error)(struct sk_buff *skb, u32 mtu);  }; -extern int xfrm_state_register_afinfo(struct xfrm_state_afinfo *afinfo); -extern int xfrm_state_unregister_afinfo(struct xfrm_state_afinfo *afinfo); -extern struct xfrm_state_afinfo *xfrm_state_get_afinfo(unsigned int family); -extern void xfrm_state_put_afinfo(struct xfrm_state_afinfo *afinfo); +int xfrm_state_register_afinfo(struct xfrm_state_afinfo *afinfo); +int xfrm_state_unregister_afinfo(struct xfrm_state_afinfo *afinfo); +struct xfrm_state_afinfo *xfrm_state_get_afinfo(unsigned int family); +void xfrm_state_put_afinfo(struct xfrm_state_afinfo *afinfo); + +struct xfrm_input_afinfo { +	unsigned int		family; +	struct module		*owner; +	int			(*callback)(struct sk_buff *skb, u8 protocol, +					    int err); +}; + +int xfrm_input_register_afinfo(struct xfrm_input_afinfo *afinfo); +int xfrm_input_unregister_afinfo(struct xfrm_input_afinfo *afinfo); -extern void xfrm_state_delete_tunnel(struct xfrm_state *x); +void xfrm_state_delete_tunnel(struct xfrm_state *x);  struct xfrm_type {  	char			*description; @@ -372,8 +382,8 @@ struct xfrm_type {  	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); +int xfrm_register_type(const struct xfrm_type *type, unsigned short family); +int xfrm_unregister_type(const struct xfrm_type *type, unsigned short family);  struct xfrm_mode {  	/* @@ -434,8 +444,8 @@ 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); +int xfrm_register_mode(struct xfrm_mode *mode, int family); +int xfrm_unregister_mode(struct xfrm_mode *mode, int family);  static inline int xfrm_af2proto(unsigned int family)  { @@ -593,10 +603,25 @@ struct xfrm_mgr {  					   const struct xfrm_migrate *m,  					   int num_bundles,  					   const struct xfrm_kmaddress *k); +	bool			(*is_alive)(const struct km_event *c);  }; -extern int xfrm_register_km(struct xfrm_mgr *km); -extern int xfrm_unregister_km(struct xfrm_mgr *km); +int xfrm_register_km(struct xfrm_mgr *km); +int xfrm_unregister_km(struct xfrm_mgr *km); + +struct xfrm_tunnel_skb_cb { +	union { +		struct inet_skb_parm h4; +		struct inet6_skb_parm h6; +	} header; + +	union { +		struct ip_tunnel *ip4; +		struct ip6_tnl *ip6; +	} tunnel; +}; + +#define XFRM_TUNNEL_SKB_CB(__skb) ((struct xfrm_tunnel_skb_cb *)&((__skb)->cb[0]))  /*   * This structure is used for the duration where packets are being @@ -604,10 +629,7 @@ extern int xfrm_unregister_km(struct xfrm_mgr *km);   * area beyond the generic IP part may be overwritten.   */  struct xfrm_skb_cb { -	union { -		struct inet_skb_parm h4; -		struct inet6_skb_parm h6; -        } header; +	struct xfrm_tunnel_skb_cb header;          /* Sequence number for replay protection. */  	union { @@ -629,10 +651,7 @@ struct xfrm_skb_cb {   * to transmit header information to the mode input/output functions.   */  struct xfrm_mode_skb_cb { -	union { -		struct inet_skb_parm h4; -		struct inet6_skb_parm h6; -	} header; +	struct xfrm_tunnel_skb_cb header;  	/* Copied from header for IPv4, always set to zero and DF for IPv6. */  	__be16 id; @@ -664,10 +683,7 @@ struct xfrm_mode_skb_cb {   * related information.   */  struct xfrm_spi_skb_cb { -	union { -		struct inet_skb_parm h4; -		struct inet6_skb_parm h6; -	} header; +	struct xfrm_tunnel_skb_cb header;  	unsigned int daddroff;  	unsigned int family; @@ -675,13 +691,6 @@ struct xfrm_spi_skb_cb {  #define XFRM_SPI_SKB_CB(__skb) ((struct xfrm_spi_skb_cb *)&((__skb)->cb[0])) -/* Audit Information */ -struct xfrm_audit { -	u32	secid; -	kuid_t	loginuid; -	u32	sessionid; -}; -  #ifdef CONFIG_AUDITSYSCALL  static inline struct audit_buffer *xfrm_audit_start(const char *op)  { @@ -697,58 +706,52 @@ static inline struct audit_buffer *xfrm_audit_start(const char *op)  	return audit_buf;  } -static inline void xfrm_audit_helper_usrinfo(kuid_t auid, u32 ses, u32 secid, +static inline void xfrm_audit_helper_usrinfo(bool task_valid,  					     struct audit_buffer *audit_buf)  { -	char *secctx; -	u32 secctx_len; - -	audit_log_format(audit_buf, " auid=%u ses=%u", -			 from_kuid(&init_user_ns, auid), ses); -	if (secid != 0 && -	    security_secid_to_secctx(secid, &secctx, &secctx_len) == 0) { -		audit_log_format(audit_buf, " subj=%s", secctx); -		security_release_secctx(secctx, secctx_len); -	} else -		audit_log_task_context(audit_buf); -} - -extern void xfrm_audit_policy_add(struct xfrm_policy *xp, int result, -				  kuid_t auid, u32 ses, u32 secid); -extern void xfrm_audit_policy_delete(struct xfrm_policy *xp, int result, -				  kuid_t auid, u32 ses, u32 secid); -extern void xfrm_audit_state_add(struct xfrm_state *x, int result, -				 kuid_t auid, u32 ses, u32 secid); -extern void xfrm_audit_state_delete(struct xfrm_state *x, int result, -				    kuid_t auid, u32 ses, u32 secid); -extern void xfrm_audit_state_replay_overflow(struct xfrm_state *x, -					     struct sk_buff *skb); -extern void xfrm_audit_state_replay(struct xfrm_state *x, -				    struct sk_buff *skb, __be32 net_seq); -extern void xfrm_audit_state_notfound_simple(struct sk_buff *skb, u16 family); -extern void xfrm_audit_state_notfound(struct sk_buff *skb, u16 family, -				      __be32 net_spi, __be32 net_seq); -extern void xfrm_audit_state_icvfail(struct xfrm_state *x, -				     struct sk_buff *skb, u8 proto); +	const unsigned int auid = from_kuid(&init_user_ns, task_valid ? +					    audit_get_loginuid(current) : +					    INVALID_UID); +	const unsigned int ses = task_valid ? audit_get_sessionid(current) : +		(unsigned int) -1; + +	audit_log_format(audit_buf, " auid=%u ses=%u", auid, ses); +	audit_log_task_context(audit_buf); +} + +void xfrm_audit_policy_add(struct xfrm_policy *xp, int result, bool task_valid); +void xfrm_audit_policy_delete(struct xfrm_policy *xp, int result, +			      bool task_valid); +void xfrm_audit_state_add(struct xfrm_state *x, int result, bool task_valid); +void xfrm_audit_state_delete(struct xfrm_state *x, int result, bool task_valid); +void xfrm_audit_state_replay_overflow(struct xfrm_state *x, +				      struct sk_buff *skb); +void xfrm_audit_state_replay(struct xfrm_state *x, struct sk_buff *skb, +			     __be32 net_seq); +void xfrm_audit_state_notfound_simple(struct sk_buff *skb, u16 family); +void xfrm_audit_state_notfound(struct sk_buff *skb, u16 family, __be32 net_spi, +			       __be32 net_seq); +void xfrm_audit_state_icvfail(struct xfrm_state *x, struct sk_buff *skb, +			      u8 proto);  #else  static inline void xfrm_audit_policy_add(struct xfrm_policy *xp, int result, -				  kuid_t auid, u32 ses, u32 secid) +					 bool task_valid)  {  }  static inline void xfrm_audit_policy_delete(struct xfrm_policy *xp, int result, -				  kuid_t auid, u32 ses, u32 secid) +					    bool task_valid)  {  }  static inline void xfrm_audit_state_add(struct xfrm_state *x, int result, -				 kuid_t auid, u32 ses, u32 secid) +					bool task_valid)  {  }  static inline void xfrm_audit_state_delete(struct xfrm_state *x, int result, -				    kuid_t auid, u32 ses, u32 secid) +					   bool task_valid)  {  } @@ -784,7 +787,7 @@ static inline void xfrm_pol_hold(struct xfrm_policy *policy)  		atomic_inc(&policy->refcnt);  } -extern void xfrm_policy_destroy(struct xfrm_policy *policy); +void xfrm_policy_destroy(struct xfrm_policy *policy);  static inline void xfrm_pol_put(struct xfrm_policy *policy)  { @@ -799,7 +802,7 @@ static inline void xfrm_pols_put(struct xfrm_policy **pols, int npols)  		xfrm_pol_put(pols[i]);  } -extern void __xfrm_state_destroy(struct xfrm_state *); +void __xfrm_state_destroy(struct xfrm_state *);  static inline void __xfrm_state_put(struct xfrm_state *x)  { @@ -903,9 +906,8 @@ __be16 xfrm_flowi_dport(const struct flowi *fl, const union flowi_uli *uli)  	return port;  } -extern bool xfrm_selector_match(const struct xfrm_selector *sel, -				const struct flowi *fl, -				unsigned short family); +bool xfrm_selector_match(const struct xfrm_selector *sel, +			 const struct flowi *fl, unsigned short family);  #ifdef CONFIG_SECURITY_NETWORK_XFRM  /*	If neither has a context --> match @@ -975,7 +977,7 @@ static inline void xfrm_dst_destroy(struct xfrm_dst *xdst)  }  #endif -extern void xfrm_dst_ifdown(struct dst_entry *dst, struct net_device *dev); +void xfrm_dst_ifdown(struct dst_entry *dst, struct net_device *dev);  struct sec_path {  	atomic_t		refcnt; @@ -1000,7 +1002,7 @@ secpath_get(struct sec_path *sp)  	return sp;  } -extern void __secpath_destroy(struct sec_path *sp); +void __secpath_destroy(struct sec_path *sp);  static inline void  secpath_put(struct sec_path *sp) @@ -1009,7 +1011,7 @@ secpath_put(struct sec_path *sp)  		__secpath_destroy(sp);  } -extern struct sec_path *secpath_dup(struct sec_path *src); +struct sec_path *secpath_dup(struct sec_path *src);  static inline void  secpath_reset(struct sk_buff *skb) @@ -1059,7 +1061,8 @@ xfrm_state_addr_cmp(const struct xfrm_tmpl *tmpl, const struct xfrm_state *x, un  }  #ifdef CONFIG_XFRM -extern int __xfrm_policy_check(struct sock *, int dir, struct sk_buff *skb, unsigned short family); +int __xfrm_policy_check(struct sock *, int dir, struct sk_buff *skb, +			unsigned short family);  static inline int __xfrm_policy_check2(struct sock *sk, int dir,  				       struct sk_buff *skb, @@ -1103,8 +1106,8 @@ static inline int xfrm6_policy_check_reverse(struct sock *sk, int dir,  	return __xfrm_policy_check2(sk, dir, skb, AF_INET6, 1);  } -extern int __xfrm_decode_session(struct sk_buff *skb, struct flowi *fl, -				 unsigned int family, int reverse); +int __xfrm_decode_session(struct sk_buff *skb, struct flowi *fl, +			  unsigned int family, int reverse);  static inline int xfrm_decode_session(struct sk_buff *skb, struct flowi *fl,  				      unsigned int family) @@ -1119,7 +1122,7 @@ static inline int xfrm_decode_session_reverse(struct sk_buff *skb,  	return __xfrm_decode_session(skb, fl, family, 1);  } -extern int __xfrm_route_forward(struct sk_buff *skb, unsigned short family); +int __xfrm_route_forward(struct sk_buff *skb, unsigned short family);  static inline int xfrm_route_forward(struct sk_buff *skb, unsigned short family)  { @@ -1140,7 +1143,7 @@ static inline int xfrm6_route_forward(struct sk_buff *skb)  	return xfrm_route_forward(skb, AF_INET6);  } -extern int __xfrm_sk_clone_policy(struct sock *sk); +int __xfrm_sk_clone_policy(struct sock *sk);  static inline int xfrm_sk_clone_policy(struct sock *sk)  { @@ -1149,7 +1152,7 @@ static inline int xfrm_sk_clone_policy(struct sock *sk)  	return 0;  } -extern int xfrm_policy_delete(struct xfrm_policy *pol, int dir); +int xfrm_policy_delete(struct xfrm_policy *pol, int dir);  static inline void xfrm_sk_free_policy(struct sock *sk)  { @@ -1163,7 +1166,7 @@ static inline void xfrm_sk_free_policy(struct sock *sk)  	}  } -extern void xfrm_garbage_collect(struct net *net); +void xfrm_garbage_collect(struct net *net);  #else @@ -1346,6 +1349,28 @@ struct xfrm_algo_desc {  	struct sadb_alg desc;  }; +/* XFRM protocol handlers.  */ +struct xfrm4_protocol { +	int (*handler)(struct sk_buff *skb); +	int (*input_handler)(struct sk_buff *skb, int nexthdr, __be32 spi, +			     int encap_type); +	int (*cb_handler)(struct sk_buff *skb, int err); +	int (*err_handler)(struct sk_buff *skb, u32 info); + +	struct xfrm4_protocol __rcu *next; +	int priority; +}; + +struct xfrm6_protocol { +	int (*handler)(struct sk_buff *skb); +	int (*cb_handler)(struct sk_buff *skb, int err); +	int (*err_handler)(struct sk_buff *skb, struct inet6_skb_parm *opt, +			   u8 type, u8 code, int offset, __be32 info); + +	struct xfrm6_protocol __rcu *next; +	int priority; +}; +  /* XFRM tunnel handlers.  */  struct xfrm_tunnel {  	int (*handler)(struct sk_buff *skb); @@ -1363,16 +1388,19 @@ struct xfrm6_tunnel {  	int priority;  }; -extern void xfrm_init(void); -extern void xfrm4_init(void); -extern int xfrm_state_init(struct net *net); -extern void xfrm_state_fini(struct net *net); -extern void xfrm4_state_init(void); +void xfrm_init(void); +void xfrm4_init(void); +int xfrm_state_init(struct net *net); +void xfrm_state_fini(struct net *net); +void xfrm4_state_init(void); +void xfrm4_protocol_init(void);  #ifdef CONFIG_XFRM -extern int xfrm6_init(void); -extern void xfrm6_fini(void); -extern int xfrm6_state_init(void); -extern void xfrm6_state_fini(void); +int xfrm6_init(void); +void xfrm6_fini(void); +int xfrm6_state_init(void); +void xfrm6_state_fini(void); +int xfrm6_protocol_init(void); +void xfrm6_protocol_fini(void);  #else  static inline int xfrm6_init(void)  { @@ -1385,55 +1413,58 @@ static inline void xfrm6_fini(void)  #endif  #ifdef CONFIG_XFRM_STATISTICS -extern int xfrm_proc_init(struct net *net); -extern void xfrm_proc_fini(struct net *net); +int xfrm_proc_init(struct net *net); +void xfrm_proc_fini(struct net *net);  #endif -extern int xfrm_sysctl_init(struct net *net); +int xfrm_sysctl_init(struct net *net);  #ifdef CONFIG_SYSCTL -extern void xfrm_sysctl_fini(struct net *net); +void xfrm_sysctl_fini(struct net *net);  #else  static inline void xfrm_sysctl_fini(struct net *net)  {  }  #endif -extern void xfrm_state_walk_init(struct xfrm_state_walk *walk, u8 proto); -extern int xfrm_state_walk(struct net *net, struct xfrm_state_walk *walk, -			   int (*func)(struct xfrm_state *, int, void*), void *); -extern void xfrm_state_walk_done(struct xfrm_state_walk *walk); -extern struct xfrm_state *xfrm_state_alloc(struct net *net); -extern struct xfrm_state *xfrm_state_find(const xfrm_address_t *daddr, -					  const xfrm_address_t *saddr, -					  const struct flowi *fl, -					  struct xfrm_tmpl *tmpl, -					  struct xfrm_policy *pol, int *err, -					  unsigned short family); -extern struct xfrm_state *xfrm_stateonly_find(struct net *net, u32 mark, -					       xfrm_address_t *daddr, -					       xfrm_address_t *saddr, -					       unsigned short family, -					       u8 mode, u8 proto, u32 reqid); -extern int xfrm_state_check_expire(struct xfrm_state *x); -extern void xfrm_state_insert(struct xfrm_state *x); -extern int xfrm_state_add(struct xfrm_state *x); -extern int xfrm_state_update(struct xfrm_state *x); -extern struct xfrm_state *xfrm_state_lookup(struct net *net, u32 mark, -					    const xfrm_address_t *daddr, __be32 spi, -					    u8 proto, unsigned short family); -extern struct xfrm_state *xfrm_state_lookup_byaddr(struct net *net, u32 mark, -						   const xfrm_address_t *daddr, -						   const xfrm_address_t *saddr, -						   u8 proto, -						   unsigned short family); +void xfrm_state_walk_init(struct xfrm_state_walk *walk, u8 proto, +			  struct xfrm_address_filter *filter); +int xfrm_state_walk(struct net *net, struct xfrm_state_walk *walk, +		    int (*func)(struct xfrm_state *, int, void*), void *); +void xfrm_state_walk_done(struct xfrm_state_walk *walk, struct net *net); +struct xfrm_state *xfrm_state_alloc(struct net *net); +struct xfrm_state *xfrm_state_find(const xfrm_address_t *daddr, +				   const xfrm_address_t *saddr, +				   const struct flowi *fl, +				   struct xfrm_tmpl *tmpl, +				   struct xfrm_policy *pol, int *err, +				   unsigned short family); +struct xfrm_state *xfrm_stateonly_find(struct net *net, u32 mark, +				       xfrm_address_t *daddr, +				       xfrm_address_t *saddr, +				       unsigned short family, +				       u8 mode, u8 proto, u32 reqid); +struct xfrm_state *xfrm_state_lookup_byspi(struct net *net, __be32 spi, +					      unsigned short family); +int xfrm_state_check_expire(struct xfrm_state *x); +void xfrm_state_insert(struct xfrm_state *x); +int xfrm_state_add(struct xfrm_state *x); +int xfrm_state_update(struct xfrm_state *x); +struct xfrm_state *xfrm_state_lookup(struct net *net, u32 mark, +				     const xfrm_address_t *daddr, __be32 spi, +				     u8 proto, unsigned short family); +struct xfrm_state *xfrm_state_lookup_byaddr(struct net *net, u32 mark, +					    const xfrm_address_t *daddr, +					    const xfrm_address_t *saddr, +					    u8 proto, +					    unsigned short family);  #ifdef CONFIG_XFRM_SUB_POLICY -extern int xfrm_tmpl_sort(struct xfrm_tmpl **dst, struct xfrm_tmpl **src, -			  int n, unsigned short family); -extern int xfrm_state_sort(struct xfrm_state **dst, struct xfrm_state **src, -			   int n, unsigned short family); +int xfrm_tmpl_sort(struct xfrm_tmpl **dst, struct xfrm_tmpl **src, int n, +		   unsigned short family, struct net *net); +int xfrm_state_sort(struct xfrm_state **dst, struct xfrm_state **src, int n, +		    unsigned short family);  #else  static inline int xfrm_tmpl_sort(struct xfrm_tmpl **dst, struct xfrm_tmpl **src, -				 int n, unsigned short family) +				 int n, unsigned short family, struct net *net)  {  	return -ENOSYS;  } @@ -1462,68 +1493,74 @@ struct xfrmk_spdinfo {  	u32 spdhmcnt;  }; -extern struct xfrm_state *xfrm_find_acq_byseq(struct net *net, u32 mark, -					      u32 seq); -extern int xfrm_state_delete(struct xfrm_state *x); -extern int xfrm_state_flush(struct net *net, u8 proto, struct xfrm_audit *audit_info); -extern void xfrm_sad_getinfo(struct net *net, struct xfrmk_sadinfo *si); -extern void xfrm_spd_getinfo(struct net *net, struct xfrmk_spdinfo *si); -extern u32 xfrm_replay_seqhi(struct xfrm_state *x, __be32 net_seq); -extern int xfrm_init_replay(struct xfrm_state *x); -extern int xfrm_state_mtu(struct xfrm_state *x, int mtu); -extern int __xfrm_init_state(struct xfrm_state *x, bool init_replay); -extern int xfrm_init_state(struct xfrm_state *x); -extern int xfrm_prepare_input(struct xfrm_state *x, struct sk_buff *skb); -extern int xfrm_input(struct sk_buff *skb, int nexthdr, __be32 spi, -		      int encap_type); -extern int xfrm_input_resume(struct sk_buff *skb, int nexthdr); -extern int xfrm_output_resume(struct sk_buff *skb, int err); -extern int xfrm_output(struct sk_buff *skb); -extern int xfrm_inner_extract_output(struct xfrm_state *x, struct sk_buff *skb); -extern void xfrm_local_error(struct sk_buff *skb, int mtu); -extern int xfrm4_extract_header(struct sk_buff *skb); -extern int xfrm4_extract_input(struct xfrm_state *x, struct sk_buff *skb); -extern int xfrm4_rcv_encap(struct sk_buff *skb, int nexthdr, __be32 spi, -			   int encap_type); -extern int xfrm4_transport_finish(struct sk_buff *skb, int async); -extern int xfrm4_rcv(struct sk_buff *skb); +struct xfrm_state *xfrm_find_acq_byseq(struct net *net, u32 mark, u32 seq); +int xfrm_state_delete(struct xfrm_state *x); +int xfrm_state_flush(struct net *net, u8 proto, bool task_valid); +void xfrm_sad_getinfo(struct net *net, struct xfrmk_sadinfo *si); +void xfrm_spd_getinfo(struct net *net, struct xfrmk_spdinfo *si); +u32 xfrm_replay_seqhi(struct xfrm_state *x, __be32 net_seq); +int xfrm_init_replay(struct xfrm_state *x); +int xfrm_state_mtu(struct xfrm_state *x, int mtu); +int __xfrm_init_state(struct xfrm_state *x, bool init_replay); +int xfrm_init_state(struct xfrm_state *x); +int xfrm_prepare_input(struct xfrm_state *x, struct sk_buff *skb); +int xfrm_input(struct sk_buff *skb, int nexthdr, __be32 spi, int encap_type); +int xfrm_input_resume(struct sk_buff *skb, int nexthdr); +int xfrm_output_resume(struct sk_buff *skb, int err); +int xfrm_output(struct sk_buff *skb); +int xfrm_inner_extract_output(struct xfrm_state *x, struct sk_buff *skb); +void xfrm_local_error(struct sk_buff *skb, int mtu); +int xfrm4_extract_header(struct sk_buff *skb); +int xfrm4_extract_input(struct xfrm_state *x, struct sk_buff *skb); +int xfrm4_rcv_encap(struct sk_buff *skb, int nexthdr, __be32 spi, +		    int encap_type); +int xfrm4_transport_finish(struct sk_buff *skb, int async); +int xfrm4_rcv(struct sk_buff *skb);  static inline int xfrm4_rcv_spi(struct sk_buff *skb, int nexthdr, __be32 spi)  { -	return xfrm4_rcv_encap(skb, nexthdr, spi, 0); -} - -extern int xfrm4_extract_output(struct xfrm_state *x, struct sk_buff *skb); -extern int xfrm4_prepare_output(struct xfrm_state *x, struct sk_buff *skb); -extern int xfrm4_output(struct sk_buff *skb); -extern int xfrm4_output_finish(struct sk_buff *skb); -extern int xfrm4_tunnel_register(struct xfrm_tunnel *handler, unsigned short family); -extern int xfrm4_tunnel_deregister(struct xfrm_tunnel *handler, unsigned short family); -extern int xfrm4_mode_tunnel_input_register(struct xfrm_tunnel *handler); -extern int xfrm4_mode_tunnel_input_deregister(struct xfrm_tunnel *handler); -extern void xfrm4_local_error(struct sk_buff *skb, u32 mtu); -extern int xfrm6_extract_header(struct sk_buff *skb); -extern int xfrm6_extract_input(struct xfrm_state *x, struct sk_buff *skb); -extern int xfrm6_rcv_spi(struct sk_buff *skb, int nexthdr, __be32 spi); -extern int xfrm6_transport_finish(struct sk_buff *skb, int async); -extern int xfrm6_rcv(struct sk_buff *skb); -extern int xfrm6_input_addr(struct sk_buff *skb, xfrm_address_t *daddr, -			    xfrm_address_t *saddr, u8 proto); -extern int xfrm6_tunnel_register(struct xfrm6_tunnel *handler, unsigned short family); -extern int xfrm6_tunnel_deregister(struct xfrm6_tunnel *handler, unsigned short family); -extern __be32 xfrm6_tunnel_alloc_spi(struct net *net, xfrm_address_t *saddr); -extern __be32 xfrm6_tunnel_spi_lookup(struct net *net, const xfrm_address_t *saddr); -extern int xfrm6_extract_output(struct xfrm_state *x, struct sk_buff *skb); -extern int xfrm6_prepare_output(struct xfrm_state *x, struct sk_buff *skb); -extern int xfrm6_output(struct sk_buff *skb); -extern int xfrm6_output_finish(struct sk_buff *skb); -extern int xfrm6_find_1stfragopt(struct xfrm_state *x, struct sk_buff *skb, -				 u8 **prevhdr); -extern void xfrm6_local_error(struct sk_buff *skb, u32 mtu); +	XFRM_TUNNEL_SKB_CB(skb)->tunnel.ip4 = NULL; +	XFRM_SPI_SKB_CB(skb)->family = AF_INET; +	XFRM_SPI_SKB_CB(skb)->daddroff = offsetof(struct iphdr, daddr); +	return xfrm_input(skb, nexthdr, spi, 0); +} + +int xfrm4_extract_output(struct xfrm_state *x, struct sk_buff *skb); +int xfrm4_prepare_output(struct xfrm_state *x, struct sk_buff *skb); +int xfrm4_output(struct sock *sk, struct sk_buff *skb); +int xfrm4_output_finish(struct sk_buff *skb); +int xfrm4_rcv_cb(struct sk_buff *skb, u8 protocol, int err); +int xfrm4_protocol_register(struct xfrm4_protocol *handler, unsigned char protocol); +int xfrm4_protocol_deregister(struct xfrm4_protocol *handler, unsigned char protocol); +int xfrm4_tunnel_register(struct xfrm_tunnel *handler, unsigned short family); +int xfrm4_tunnel_deregister(struct xfrm_tunnel *handler, unsigned short family); +void xfrm4_local_error(struct sk_buff *skb, u32 mtu); +int xfrm6_extract_header(struct sk_buff *skb); +int xfrm6_extract_input(struct xfrm_state *x, struct sk_buff *skb); +int xfrm6_rcv_spi(struct sk_buff *skb, int nexthdr, __be32 spi); +int xfrm6_transport_finish(struct sk_buff *skb, int async); +int xfrm6_rcv(struct sk_buff *skb); +int xfrm6_input_addr(struct sk_buff *skb, xfrm_address_t *daddr, +		     xfrm_address_t *saddr, u8 proto); +void xfrm6_local_error(struct sk_buff *skb, u32 mtu); +int xfrm6_rcv_cb(struct sk_buff *skb, u8 protocol, int err); +int xfrm6_protocol_register(struct xfrm6_protocol *handler, unsigned char protocol); +int xfrm6_protocol_deregister(struct xfrm6_protocol *handler, unsigned char protocol); +int xfrm6_tunnel_register(struct xfrm6_tunnel *handler, unsigned short family); +int xfrm6_tunnel_deregister(struct xfrm6_tunnel *handler, unsigned short family); +__be32 xfrm6_tunnel_alloc_spi(struct net *net, xfrm_address_t *saddr); +__be32 xfrm6_tunnel_spi_lookup(struct net *net, const xfrm_address_t *saddr); +int xfrm6_extract_output(struct xfrm_state *x, struct sk_buff *skb); +int xfrm6_prepare_output(struct xfrm_state *x, struct sk_buff *skb); +int xfrm6_output(struct sock *sk, struct sk_buff *skb); +int xfrm6_output_finish(struct sk_buff *skb); +int xfrm6_find_1stfragopt(struct xfrm_state *x, struct sk_buff *skb, +			  u8 **prevhdr);  #ifdef CONFIG_XFRM -extern int xfrm4_udp_encap_rcv(struct sock *sk, struct sk_buff *skb); -extern int xfrm_user_policy(struct sock *sk, int optname, u8 __user *optval, int optlen); +int xfrm4_udp_encap_rcv(struct sock *sk, struct sk_buff *skb); +int xfrm_user_policy(struct sock *sk, int optname, +		     u8 __user *optval, int optlen);  #else  static inline int xfrm_user_policy(struct sock *sk, int optname, u8 __user *optval, int optlen)  { @@ -1540,59 +1577,63 @@ static inline int xfrm4_udp_encap_rcv(struct sock *sk, struct sk_buff *skb)  struct xfrm_policy *xfrm_policy_alloc(struct net *net, gfp_t gfp); -extern void xfrm_policy_walk_init(struct xfrm_policy_walk *walk, u8 type); -extern int xfrm_policy_walk(struct net *net, struct xfrm_policy_walk *walk, -	int (*func)(struct xfrm_policy *, int, int, void*), void *); -extern void xfrm_policy_walk_done(struct xfrm_policy_walk *walk); +void xfrm_policy_walk_init(struct xfrm_policy_walk *walk, u8 type); +int xfrm_policy_walk(struct net *net, struct xfrm_policy_walk *walk, +		     int (*func)(struct xfrm_policy *, int, int, void*), +		     void *); +void xfrm_policy_walk_done(struct xfrm_policy_walk *walk, struct net *net);  int xfrm_policy_insert(int dir, struct xfrm_policy *policy, int excl);  struct xfrm_policy *xfrm_policy_bysel_ctx(struct net *net, u32 mark,  					  u8 type, int dir,  					  struct xfrm_selector *sel,  					  struct xfrm_sec_ctx *ctx, int delete,  					  int *err); -struct xfrm_policy *xfrm_policy_byid(struct net *net, u32 mark, u8, int dir, u32 id, int delete, int *err); -int xfrm_policy_flush(struct net *net, u8 type, struct xfrm_audit *audit_info); +struct xfrm_policy *xfrm_policy_byid(struct net *net, u32 mark, u8, int dir, +				     u32 id, int delete, int *err); +int xfrm_policy_flush(struct net *net, u8 type, bool task_valid);  u32 xfrm_get_acqseq(void); -extern int xfrm_alloc_spi(struct xfrm_state *x, u32 minspi, u32 maxspi); +int verify_spi_info(u8 proto, u32 min, u32 max); +int xfrm_alloc_spi(struct xfrm_state *x, u32 minspi, u32 maxspi);  struct xfrm_state *xfrm_find_acq(struct net *net, const struct xfrm_mark *mark,  				 u8 mode, u32 reqid, u8 proto,  				 const xfrm_address_t *daddr,  				 const xfrm_address_t *saddr, int create,  				 unsigned short family); -extern int xfrm_sk_policy_insert(struct sock *sk, int dir, struct xfrm_policy *pol); +int xfrm_sk_policy_insert(struct sock *sk, int dir, struct xfrm_policy *pol);  #ifdef CONFIG_XFRM_MIGRATE -extern int km_migrate(const struct xfrm_selector *sel, u8 dir, u8 type, -		      const struct xfrm_migrate *m, int num_bundles, -		      const struct xfrm_kmaddress *k); -extern struct xfrm_state * xfrm_migrate_state_find(struct xfrm_migrate *m); -extern struct xfrm_state * xfrm_state_migrate(struct xfrm_state *x, -					      struct xfrm_migrate *m); -extern int xfrm_migrate(const struct xfrm_selector *sel, u8 dir, u8 type, -			struct xfrm_migrate *m, int num_bundles, -			struct xfrm_kmaddress *k); +int km_migrate(const struct xfrm_selector *sel, u8 dir, u8 type, +	       const struct xfrm_migrate *m, int num_bundles, +	       const struct xfrm_kmaddress *k); +struct xfrm_state *xfrm_migrate_state_find(struct xfrm_migrate *m, struct net *net); +struct xfrm_state *xfrm_state_migrate(struct xfrm_state *x, +				      struct xfrm_migrate *m); +int xfrm_migrate(const struct xfrm_selector *sel, u8 dir, u8 type, +		 struct xfrm_migrate *m, int num_bundles, +		 struct xfrm_kmaddress *k, struct net *net);  #endif -extern int km_new_mapping(struct xfrm_state *x, xfrm_address_t *ipaddr, __be16 sport); -extern void km_policy_expired(struct xfrm_policy *pol, int dir, int hard, u32 portid); -extern int km_report(struct net *net, u8 proto, struct xfrm_selector *sel, xfrm_address_t *addr); - -extern void xfrm_input_init(void); -extern int xfrm_parse_spi(struct sk_buff *skb, u8 nexthdr, __be32 *spi, __be32 *seq); - -extern void xfrm_probe_algs(void); -extern int xfrm_count_pfkey_auth_supported(void); -extern int xfrm_count_pfkey_enc_supported(void); -extern struct xfrm_algo_desc *xfrm_aalg_get_byidx(unsigned int idx); -extern struct xfrm_algo_desc *xfrm_ealg_get_byidx(unsigned int idx); -extern struct xfrm_algo_desc *xfrm_aalg_get_byid(int alg_id); -extern struct xfrm_algo_desc *xfrm_ealg_get_byid(int alg_id); -extern struct xfrm_algo_desc *xfrm_calg_get_byid(int alg_id); -extern struct xfrm_algo_desc *xfrm_aalg_get_byname(const char *name, int probe); -extern struct xfrm_algo_desc *xfrm_ealg_get_byname(const char *name, int probe); -extern struct xfrm_algo_desc *xfrm_calg_get_byname(const char *name, int probe); -extern struct xfrm_algo_desc *xfrm_aead_get_byname(const char *name, int icv_len, -						   int probe); +int km_new_mapping(struct xfrm_state *x, xfrm_address_t *ipaddr, __be16 sport); +void km_policy_expired(struct xfrm_policy *pol, int dir, int hard, u32 portid); +int km_report(struct net *net, u8 proto, struct xfrm_selector *sel, +	      xfrm_address_t *addr); + +void xfrm_input_init(void); +int xfrm_parse_spi(struct sk_buff *skb, u8 nexthdr, __be32 *spi, __be32 *seq); + +void xfrm_probe_algs(void); +int xfrm_count_pfkey_auth_supported(void); +int xfrm_count_pfkey_enc_supported(void); +struct xfrm_algo_desc *xfrm_aalg_get_byidx(unsigned int idx); +struct xfrm_algo_desc *xfrm_ealg_get_byidx(unsigned int idx); +struct xfrm_algo_desc *xfrm_aalg_get_byid(int alg_id); +struct xfrm_algo_desc *xfrm_ealg_get_byid(int alg_id); +struct xfrm_algo_desc *xfrm_calg_get_byid(int alg_id); +struct xfrm_algo_desc *xfrm_aalg_get_byname(const char *name, int probe); +struct xfrm_algo_desc *xfrm_ealg_get_byname(const char *name, int probe); +struct xfrm_algo_desc *xfrm_calg_get_byname(const char *name, int probe); +struct xfrm_algo_desc *xfrm_aead_get_byname(const char *name, int icv_len, +					    int probe);  static inline bool xfrm6_addr_equal(const xfrm_address_t *a,  				    const xfrm_address_t *b) @@ -1632,8 +1673,27 @@ static inline int xfrm_aevent_is_on(struct net *net)  	rcu_read_unlock();  	return ret;  } + +static inline int xfrm_acquire_is_on(struct net *net) +{ +	struct sock *nlsk; +	int ret = 0; + +	rcu_read_lock(); +	nlsk = rcu_dereference(net->xfrm.nlsk); +	if (nlsk) +		ret = netlink_has_listeners(nlsk, XFRMNLGRP_ACQUIRE); +	rcu_read_unlock(); + +	return ret; +}  #endif +static inline int aead_len(struct xfrm_algo_aead *alg) +{ +	return sizeof(*alg) + ((alg->alg_key_len + 7) / 8); +} +  static inline int xfrm_alg_len(const struct xfrm_algo *alg)  {  	return sizeof(*alg) + ((alg->alg_key_len + 7) / 8); @@ -1672,6 +1732,12 @@ static inline int xfrm_replay_clone(struct xfrm_state *x,  	return 0;  } +static inline struct xfrm_algo_aead *xfrm_algo_aead_clone(struct xfrm_algo_aead *orig) +{ +	return kmemdup(orig, aead_len(orig), GFP_KERNEL); +} + +  static inline struct xfrm_algo *xfrm_algo_clone(struct xfrm_algo *orig)  {  	return kmemdup(orig, xfrm_alg_len(orig), GFP_KERNEL); @@ -1723,4 +1789,24 @@ static inline int xfrm_mark_put(struct sk_buff *skb, const struct xfrm_mark *m)  	return ret;  } +static inline int xfrm_tunnel_check(struct sk_buff *skb, struct xfrm_state *x, +				    unsigned int family) +{ +	bool tunnel = false; + +	switch(family) { +	case AF_INET: +		if (XFRM_TUNNEL_SKB_CB(skb)->tunnel.ip4) +			tunnel = true; +		break; +	case AF_INET6: +		if (XFRM_TUNNEL_SKB_CB(skb)->tunnel.ip6) +			tunnel = true; +		break; +	} +	if (tunnel && !(x->outer_mode->flags & XFRM_MODE_FLAG_TUNNEL)) +		return -EINVAL; + +	return 0; +}  #endif	/* _NET_XFRM_H */  | 
