#include <linux/list.h>
#include <linux/skbuff.h>
#include <linux/socket.h>
-#include <linux/crypto.h>
#include <linux/pfkeyv2.h>
+#include <linux/ipsec.h>
#include <linux/in6.h>
+#include <linux/mutex.h>
#include <net/sock.h>
#include <net/dst.h>
#include <net/ip6_fib.h>
#define XFRM_ALIGN8(len) (((len) + 7) & ~7)
+#define MODULE_ALIAS_XFRM_MODE(family, encap) \
+ MODULE_ALIAS("xfrm-mode-" __stringify(family) "-" __stringify(encap))
-extern struct semaphore xfrm_cfg_sem;
+extern struct sock *xfrm_nl;
+extern u32 sysctl_xfrm_aevent_etime;
+extern u32 sysctl_xfrm_aevent_rseqth;
+
+extern struct mutex xfrm_cfg_mutex;
/* Organization of SPD aka "XFRM rules"
------------------------------------
struct xfrm_state
{
/* Note: bydst is re-used during gc */
- struct list_head bydst;
- struct list_head byspi;
+ 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;
+ u32 genid;
+
/* Key manger bits */
struct {
u8 state;
/* 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;
/* State for replay detection */
struct xfrm_replay_state replay;
+ /* Replay detection state at the time we sent the last notification */
+ struct xfrm_replay_state preplay;
+
+ /* 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 timer_list timer;
+ /* Last used time */
+ u64 lastused;
+
/* Reference to data common to all the instances of this
* transformer. */
struct xfrm_type *type;
+ struct xfrm_mode *mode;
/* Security context */
struct xfrm_sec_ctx *security;
void *data;
};
+/* xflags - make enum if more show up */
+#define XFRM_TIME_DEFER 1
+
enum {
XFRM_STATE_VOID,
XFRM_STATE_ACQ,
u32 hard;
u32 proto;
u32 byid;
+ u32 aevent;
+ u32 type;
} data;
u32 seq;
struct xfrm_dst;
struct xfrm_policy_afinfo {
unsigned short family;
- rwlock_t lock;
- struct xfrm_type_map *type_map;
+ struct xfrm_type *type_map[IPPROTO_MAX];
+ struct xfrm_mode *mode_map[XFRM_MODE_MAX];
struct dst_ops *dst_ops;
void (*garbage_collect)(void);
int (*dst_lookup)(struct xfrm_dst **dst, struct flowi *fl);
+ int (*get_saddr)(xfrm_address_t *saddr, xfrm_address_t *daddr);
struct dst_entry *(*find_bundle)(struct flowi *fl, struct xfrm_policy *policy);
int (*bundle_create)(struct xfrm_policy *policy,
struct xfrm_state **xfrm,
extern int xfrm_policy_unregister_afinfo(struct xfrm_policy_afinfo *afinfo);
extern void km_policy_notify(struct xfrm_policy *xp, int dir, struct km_event *c);
extern void km_state_notify(struct xfrm_state *x, struct km_event *c);
-
#define XFRM_ACQ_EXPIRES 30
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 short family;
- rwlock_t lock;
- struct list_head *state_bydst;
- struct list_head *state_byspi;
int (*init_flags)(struct xfrm_state *x);
void (*init_tempsel)(struct xfrm_state *x, struct flowi *fl,
struct xfrm_tmpl *tmpl,
xfrm_address_t *daddr, xfrm_address_t *saddr);
- struct xfrm_state *(*state_lookup)(xfrm_address_t *daddr, u32 spi, u8 proto);
- struct xfrm_state *(*find_acq)(u8 mode, u32 reqid, u8 proto,
- xfrm_address_t *daddr, xfrm_address_t *saddr,
- int create);
+ 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);
};
extern int xfrm_state_register_afinfo(struct xfrm_state_afinfo *afinfo);
extern void xfrm_state_delete_tunnel(struct xfrm_state *x);
-struct xfrm_decap_state;
struct xfrm_type
{
char *description;
struct module *owner;
__u8 proto;
+ __u8 flags;
+#define XFRM_TYPE_NON_FRAGMENT 1
int (*init_state)(struct xfrm_state *x);
void (*destructor)(struct xfrm_state *);
- int (*input)(struct xfrm_state *, struct xfrm_decap_state *, struct sk_buff *skb);
+ 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 *, struct flowi *);
+ int (*hdr_offset)(struct xfrm_state *, struct sk_buff *, u8 **);
+ xfrm_address_t *(*local_addr)(struct xfrm_state *, xfrm_address_t *);
+ xfrm_address_t *(*remote_addr)(struct xfrm_state *, xfrm_address_t *);
/* Estimate maximal size of result of transformation of a dgram */
u32 (*get_max_size)(struct xfrm_state *, int size);
};
-struct xfrm_type_map {
- rwlock_t lock;
- struct xfrm_type *map[256];
-};
-
extern int xfrm_register_type(struct xfrm_type *type, unsigned short family);
extern int xfrm_unregister_type(struct xfrm_type *type, unsigned short family);
extern struct xfrm_type *xfrm_get_type(u8 proto, unsigned short family);
extern void xfrm_put_type(struct xfrm_type *type);
+struct xfrm_mode {
+ int (*input)(struct xfrm_state *x, struct sk_buff *skb);
+ int (*output)(struct xfrm_state *x,struct sk_buff *skb);
+
+ struct module *owner;
+ unsigned int encap;
+};
+
+extern int xfrm_register_mode(struct xfrm_mode *mode, int family);
+extern int xfrm_unregister_mode(struct xfrm_mode *mode, int family);
+extern struct xfrm_mode *xfrm_get_mode(unsigned int encap, int family);
+extern void xfrm_put_mode(struct xfrm_mode *mode);
+
struct xfrm_tmpl
{
/* id in template is interpreted as:
/* Source address of tunnel. Ignored, if it is not a tunnel. */
xfrm_address_t saddr;
+ unsigned short encap_family;
+
__u32 reqid;
-/* Mode: transport/tunnel */
+/* Mode: transport, tunnel etc. */
__u8 mode;
/* Sharing mode: unique, this session only, this user only etc. */
__u32 calgos;
};
-#define XFRM_MAX_DEPTH 4
+#define XFRM_MAX_DEPTH 6
struct xfrm_policy
{
struct xfrm_policy *next;
- struct list_head list;
+ struct hlist_node bydst;
+ struct hlist_node byidx;
/* This lock only affects elements except for entry. */
rwlock_t lock;
struct xfrm_lifetime_cfg lft;
struct xfrm_lifetime_cur curlft;
struct dst_entry *bundles;
- __u16 family;
- __u8 action;
- __u8 flags;
- __u8 dead;
- __u8 xfrm_nr;
+ u16 family;
+ u8 type;
+ u8 action;
+ u8 flags;
+ u8 dead;
+ u8 xfrm_nr;
+ /* XXX 1 byte hole, try to pack */
struct xfrm_sec_ctx *security;
struct xfrm_tmpl xfrm_vec[XFRM_MAX_DEPTH];
};
-#define XFRM_KM_TIMEOUT 30
+#define XFRM_KM_TIMEOUT 30
+/* which seqno */
+#define XFRM_REPLAY_SEQ 1
+#define XFRM_REPLAY_OSEQ 2
+#define XFRM_REPLAY_SEQ_MASK 3
+/* what happened */
+#define XFRM_REPLAY_UPDATE XFRM_AE_CR
+#define XFRM_REPLAY_TIMEOUT XFRM_AE_CE
+
+/* default aevent timeout in units of 100ms */
+#define XFRM_AE_ETIME 10
+/* Async Event timer multiplier */
+#define XFRM_AE_ETH_M 10
+/* default seq threshold size */
+#define XFRM_AE_SEQT_SIZE 2
struct xfrm_mgr
{
char *id;
int (*notify)(struct xfrm_state *x, struct km_event *c);
int (*acquire)(struct xfrm_state *x, struct xfrm_tmpl *, struct xfrm_policy *xp, int dir);
- struct xfrm_policy *(*compile_policy)(u16 family, int opt, u8 *data, int len, int *dir);
- int (*new_mapping)(struct xfrm_state *x, xfrm_address_t *ipaddr, u16 sport);
+ struct xfrm_policy *(*compile_policy)(struct sock *sk, int opt, u8 *data, int len, int *dir);
+ int (*new_mapping)(struct xfrm_state *x, xfrm_address_t *ipaddr, __be16 sport);
int (*notify_policy)(struct xfrm_policy *x, int dir, struct km_event *c);
+ int (*report)(u8 proto, struct xfrm_selector *sel, xfrm_address_t *addr);
};
extern int xfrm_register_km(struct xfrm_mgr *km);
extern int xfrm_unregister_km(struct xfrm_mgr *km);
+extern unsigned int xfrm_policy_count[XFRM_POLICY_MAX*2];
-extern struct xfrm_policy *xfrm_policy_list[XFRM_POLICY_MAX*2];
+/* Audit Information */
+struct xfrm_audit
+{
+ uid_t loginuid;
+ u32 secid;
+};
+
+#ifdef CONFIG_AUDITSYSCALL
+extern void xfrm_audit_log(uid_t auid, u32 secid, int type, int result,
+ struct xfrm_policy *xp, struct xfrm_state *x);
+#else
+#define xfrm_audit_log(a,s,t,r,p,x) do { ; } while (0)
+#endif /* CONFIG_AUDITSYSCALL */
static inline void xfrm_pol_hold(struct xfrm_policy *policy)
{
__xfrm_policy_destroy(policy);
}
-#define XFRM_DST_HSIZE 1024
-
-static __inline__
-unsigned __xfrm4_dst_hash(xfrm_address_t *addr)
+#ifdef CONFIG_XFRM_SUB_POLICY
+static inline void xfrm_pols_put(struct xfrm_policy **pols, int npols)
{
- unsigned h;
- h = ntohl(addr->a4);
- h = (h ^ (h>>16)) % XFRM_DST_HSIZE;
- return h;
+ int i;
+ for (i = npols - 1; i >= 0; --i)
+ xfrm_pol_put(pols[i]);
}
-
-static __inline__
-unsigned __xfrm6_dst_hash(xfrm_address_t *addr)
-{
- unsigned h;
- h = ntohl(addr->a6[2]^addr->a6[3]);
- h = (h ^ (h>>16)) % XFRM_DST_HSIZE;
- return h;
-}
-
-static __inline__
-unsigned xfrm_dst_hash(xfrm_address_t *addr, unsigned short family)
-{
- switch (family) {
- case AF_INET:
- return __xfrm4_dst_hash(addr);
- case AF_INET6:
- return __xfrm6_dst_hash(addr);
- }
- return 0;
-}
-
-static __inline__
-unsigned __xfrm4_spi_hash(xfrm_address_t *addr, u32 spi, u8 proto)
-{
- unsigned h;
- h = ntohl(addr->a4^spi^proto);
- h = (h ^ (h>>10) ^ (h>>20)) % XFRM_DST_HSIZE;
- return h;
-}
-
-static __inline__
-unsigned __xfrm6_spi_hash(xfrm_address_t *addr, u32 spi, u8 proto)
-{
- unsigned h;
- h = ntohl(addr->a6[2]^addr->a6[3]^spi^proto);
- h = (h ^ (h>>10) ^ (h>>20)) % XFRM_DST_HSIZE;
- return h;
-}
-
-static __inline__
-unsigned xfrm_spi_hash(xfrm_address_t *addr, u32 spi, u8 proto, unsigned short family)
+#else
+static inline void xfrm_pols_put(struct xfrm_policy **pols, int npols)
{
- switch (family) {
- case AF_INET:
- return __xfrm4_spi_hash(addr, spi, proto);
- case AF_INET6:
- return __xfrm6_spi_hash(addr, spi, proto);
- }
- return 0; /*XXX*/
+ xfrm_pol_put(pols[0]);
}
+#endif
extern void __xfrm_state_destroy(struct xfrm_state *);
static __inline__ int addr_match(void *token1, void *token2, int prefixlen)
{
- __u32 *a1 = token1;
- __u32 *a2 = token2;
+ __be32 *a1 = token1;
+ __be32 *a2 = token2;
int pdw;
int pbi;
return 0;
if (pbi) {
- __u32 mask;
+ __be32 mask;
mask = htonl((0xffffffff) << (32 - pbi));
}
static __inline__
-u16 xfrm_flowi_sport(struct flowi *fl)
+__be16 xfrm_flowi_sport(struct flowi *fl)
{
- u16 port;
+ __be16 port;
switch(fl->proto) {
case IPPROTO_TCP:
case IPPROTO_UDP:
+ case IPPROTO_UDPLITE:
case IPPROTO_SCTP:
port = fl->fl_ip_sport;
break;
case IPPROTO_ICMPV6:
port = htons(fl->fl_icmp_type);
break;
+#ifdef CONFIG_IPV6_MIP6
+ case IPPROTO_MH:
+ port = htons(fl->fl_mh_type);
+ break;
+#endif
default:
port = 0; /*XXX*/
}
}
static __inline__
-u16 xfrm_flowi_dport(struct flowi *fl)
+__be16 xfrm_flowi_dport(struct flowi *fl)
{
- u16 port;
+ __be16 port;
switch(fl->proto) {
case IPPROTO_TCP:
case IPPROTO_UDP:
+ case IPPROTO_UDPLITE:
case IPPROTO_SCTP:
port = fl->fl_ip_dport;
break;
return port;
}
-static inline int
-__xfrm4_selector_match(struct xfrm_selector *sel, struct flowi *fl)
-{
- return addr_match(&fl->fl4_dst, &sel->daddr, sel->prefixlen_d) &&
- addr_match(&fl->fl4_src, &sel->saddr, sel->prefixlen_s) &&
- !((xfrm_flowi_dport(fl) ^ sel->dport) & sel->dport_mask) &&
- !((xfrm_flowi_sport(fl) ^ sel->sport) & sel->sport_mask) &&
- (fl->proto == sel->proto || !sel->proto) &&
- (fl->oif == sel->ifindex || !sel->ifindex);
-}
-
-static inline int
-__xfrm6_selector_match(struct xfrm_selector *sel, struct flowi *fl)
-{
- return addr_match(&fl->fl6_dst, &sel->daddr, sel->prefixlen_d) &&
- addr_match(&fl->fl6_src, &sel->saddr, sel->prefixlen_s) &&
- !((xfrm_flowi_dport(fl) ^ sel->dport) & sel->dport_mask) &&
- !((xfrm_flowi_sport(fl) ^ sel->sport) & sel->sport_mask) &&
- (fl->proto == sel->proto || !sel->proto) &&
- (fl->oif == sel->ifindex || !sel->ifindex);
-}
-
-static inline int
-xfrm_selector_match(struct xfrm_selector *sel, struct flowi *fl,
- unsigned short family)
-{
- switch (family) {
- case AF_INET:
- return __xfrm4_selector_match(sel, fl);
- case AF_INET6:
- return __xfrm6_selector_match(sel, fl);
- }
- return 0;
-}
+extern int xfrm_selector_match(struct xfrm_selector *sel, struct flowi *fl,
+ unsigned short family);
#ifdef CONFIG_SECURITY_NETWORK_XFRM
/* If neither has a context --> match
struct rt6_info rt6;
} u;
struct dst_entry *route;
+ u32 genid;
u32 route_mtu_cached;
u32 child_mtu_cached;
u32 route_cookie;
extern void xfrm_dst_ifdown(struct dst_entry *dst, struct net_device *dev);
-/* Decapsulation state, used by the input to store data during
- * decapsulation procedure, to be used later (during the policy
- * check
- */
-struct xfrm_decap_state {
- char decap_data[20];
- __u16 decap_type;
-};
-
-struct sec_decap_state {
- struct xfrm_state *xvec;
- struct xfrm_decap_state decap;
-};
-
struct sec_path
{
atomic_t refcnt;
int len;
- struct sec_decap_state x[XFRM_MAX_DEPTH];
+ struct xfrm_state *xvec[XFRM_MAX_DEPTH];
};
static inline struct sec_path *
#endif
}
+static inline int
+xfrm_addr_any(xfrm_address_t *addr, unsigned short family)
+{
+ switch (family) {
+ case AF_INET:
+ return addr->a4 == 0;
+ case AF_INET6:
+ return ipv6_addr_any((struct in6_addr *)&addr->a6);
+ }
+ return 0;
+}
+
static inline int
__xfrm4_state_addr_cmp(struct xfrm_tmpl *tmpl, struct xfrm_state *x)
{
{
if (sk && sk->sk_policy[XFRM_POLICY_IN])
return __xfrm_policy_check(sk, dir, skb, family);
-
- return (!xfrm_policy_list[dir] && !skb->sp) ||
+
+ return (!xfrm_policy_count[dir] && !skb->sp) ||
(skb->dst->flags & DST_NOPOLICY) ||
__xfrm_policy_check(sk, dir, skb, family);
}
static inline int xfrm_route_forward(struct sk_buff *skb, unsigned short family)
{
- return !xfrm_policy_list[XFRM_POLICY_OUT] ||
+ return !xfrm_policy_count[XFRM_POLICY_OUT] ||
(skb->dst->flags & DST_NOXFRM) ||
__xfrm_route_forward(skb, family);
}
return 0;
}
+static __inline__ int
+xfrm_state_addr_flow_check(struct xfrm_state *x, struct flowi *fl,
+ unsigned short family)
+{
+ switch (family) {
+ case AF_INET:
+ return __xfrm4_state_addr_check(x,
+ (xfrm_address_t *)&fl->fl4_dst,
+ (xfrm_address_t *)&fl->fl4_src);
+ case AF_INET6:
+ return __xfrm6_state_addr_check(x,
+ (xfrm_address_t *)&fl->fl6_dst,
+ (xfrm_address_t *)&fl->fl6_src);
+ }
+ return 0;
+}
+
static inline int xfrm_state_kern(struct xfrm_state *x)
{
return atomic_read(&x->tunnel_users);
}
+static inline int xfrm_id_proto_match(u8 proto, u8 userproto)
+{
+ return (!userproto || proto == userproto ||
+ (userproto == IPSEC_PROTO_ANY && (proto == IPPROTO_AH ||
+ proto == IPPROTO_ESP ||
+ proto == IPPROTO_COMP)));
+}
+
/*
* xfrm algorithm information
*/
struct xfrm_algo_desc {
char *name;
+ char *compat;
u8 available:1;
union {
struct xfrm_algo_auth_info auth;
/* XFRM tunnel handlers. */
struct xfrm_tunnel {
int (*handler)(struct sk_buff *skb);
- void (*err_handler)(struct sk_buff *skb, __u32 info);
+ int (*err_handler)(struct sk_buff *skb, __u32 info);
+
+ struct xfrm_tunnel *next;
+ int priority;
};
struct xfrm6_tunnel {
- int (*handler)(struct sk_buff **pskb);
- void (*err_handler)(struct sk_buff *skb, struct inet6_skb_parm *opt,
- int type, int code, int offset, __u32 info);
+ int (*handler)(struct sk_buff *skb);
+ int (*err_handler)(struct sk_buff *skb, struct inet6_skb_parm *opt,
+ int type, int code, int offset, __be32 info);
+ struct xfrm6_tunnel *next;
+ int priority;
};
extern void xfrm_init(void);
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(xfrm_address_t *daddr, u32 spi, u8 proto, unsigned short family);
+extern struct xfrm_state *xfrm_state_lookup(xfrm_address_t *daddr, __be32 spi, u8 proto, unsigned short family);
+extern struct xfrm_state *xfrm_state_lookup_byaddr(xfrm_address_t *daddr, 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);
+#else
+static inline int xfrm_tmpl_sort(struct xfrm_tmpl **dst, struct xfrm_tmpl **src,
+ int n, unsigned short family)
+{
+ return -ENOSYS;
+}
+
+static inline int xfrm_state_sort(struct xfrm_state **dst, struct xfrm_state **src,
+ int n, unsigned short family)
+{
+ return -ENOSYS;
+}
+#endif
extern struct xfrm_state *xfrm_find_acq_byseq(u32 seq);
extern int xfrm_state_delete(struct xfrm_state *x);
-extern void xfrm_state_flush(u8 proto);
-extern int xfrm_replay_check(struct xfrm_state *x, u32 seq);
-extern void xfrm_replay_advance(struct xfrm_state *x, u32 seq);
+extern void xfrm_state_flush(u8 proto, struct xfrm_audit *audit_info);
+extern int xfrm_replay_check(struct xfrm_state *x, __be32 seq);
+extern void xfrm_replay_advance(struct xfrm_state *x, __be32 seq);
+extern void xfrm_replay_notify(struct xfrm_state *x, int event);
extern int xfrm_state_check(struct xfrm_state *x, struct sk_buff *skb);
extern int xfrm_state_mtu(struct xfrm_state *x, int mtu);
extern int xfrm_init_state(struct xfrm_state *x);
extern int xfrm4_output(struct sk_buff *skb);
extern int xfrm4_tunnel_register(struct xfrm_tunnel *handler);
extern int xfrm4_tunnel_deregister(struct xfrm_tunnel *handler);
-extern int xfrm6_rcv_spi(struct sk_buff **pskb, u32 spi);
+extern int xfrm6_rcv_spi(struct sk_buff *skb, __be32 spi);
extern int xfrm6_rcv(struct sk_buff **pskb);
+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);
extern int xfrm6_tunnel_deregister(struct xfrm6_tunnel *handler);
-extern u32 xfrm6_tunnel_alloc_spi(xfrm_address_t *saddr);
+extern __be32 xfrm6_tunnel_alloc_spi(xfrm_address_t *saddr);
extern void xfrm6_tunnel_free_spi(xfrm_address_t *saddr);
-extern u32 xfrm6_tunnel_spi_lookup(xfrm_address_t *saddr);
+extern __be32 xfrm6_tunnel_spi_lookup(xfrm_address_t *saddr);
extern int xfrm6_output(struct sk_buff *skb);
+extern int xfrm6_find_1stfragopt(struct xfrm_state *x, struct sk_buff *skb,
+ u8 **prevhdr);
#ifdef CONFIG_XFRM
extern int xfrm4_rcv_encap(struct sk_buff *skb, __u16 encap_type);
#endif
struct xfrm_policy *xfrm_policy_alloc(gfp_t gfp);
-extern int xfrm_policy_walk(int (*func)(struct xfrm_policy *, int, int, void*), void *);
+extern int xfrm_policy_walk(u8 type, int (*func)(struct xfrm_policy *, int, int, void*), void *);
int xfrm_policy_insert(int dir, struct xfrm_policy *policy, int excl);
-struct xfrm_policy *xfrm_policy_bysel_ctx(int dir, struct xfrm_selector *sel,
+struct xfrm_policy *xfrm_policy_bysel_ctx(u8 type, int dir,
+ struct xfrm_selector *sel,
struct xfrm_sec_ctx *ctx, int delete);
-struct xfrm_policy *xfrm_policy_byid(int dir, u32 id, int delete);
-void xfrm_policy_flush(void);
+struct xfrm_policy *xfrm_policy_byid(u8, int dir, u32 id, int delete);
+void xfrm_policy_flush(u8 type, struct xfrm_audit *audit_info);
u32 xfrm_get_acqseq(void);
-void xfrm_alloc_spi(struct xfrm_state *x, u32 minspi, u32 maxspi);
-struct xfrm_state * xfrm_find_acq(u8 mode, u32 reqid, u8 proto,
- xfrm_address_t *daddr, xfrm_address_t *saddr,
+void xfrm_alloc_spi(struct xfrm_state *x, __be32 minspi, __be32 maxspi);
+struct xfrm_state * xfrm_find_acq(u8 mode, u32 reqid, u8 proto,
+ xfrm_address_t *daddr, xfrm_address_t *saddr,
int create, unsigned short family);
-extern void xfrm_policy_flush(void);
+extern void xfrm_policy_flush(u8 type, struct xfrm_audit *audit_info);
extern int xfrm_sk_policy_insert(struct sock *sk, int dir, struct xfrm_policy *pol);
-extern int xfrm_flush_bundles(void);
-extern void xfrm_flush_all_bundles(void);
-extern int xfrm_bundle_ok(struct xfrm_dst *xdst, struct flowi *fl, int family);
+extern int xfrm_bundle_ok(struct xfrm_policy *pol, struct xfrm_dst *xdst,
+ struct flowi *fl, int family, int strict);
extern void xfrm_init_pmtu(struct dst_entry *dst);
extern wait_queue_head_t km_waitq;
-extern int km_new_mapping(struct xfrm_state *x, xfrm_address_t *ipaddr, u16 sport);
-extern void km_policy_expired(struct xfrm_policy *pol, int dir, int hard);
+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 pid);
+extern int km_report(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, u32 *spi, u32 *seq);
+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_auth_supported(void);
extern struct xfrm_algo_desc *xfrm_ealg_get_byname(char *name, int probe);
extern struct xfrm_algo_desc *xfrm_calg_get_byname(char *name, int probe);
-struct crypto_tfm;
-typedef void (icv_update_fn_t)(struct crypto_tfm *, struct scatterlist *, unsigned int);
+struct hash_desc;
+struct scatterlist;
+typedef int (icv_update_fn_t)(struct hash_desc *, struct scatterlist *,
+ unsigned int);
-extern void skb_icv_walk(const struct sk_buff *skb, struct crypto_tfm *tfm,
- int offset, int len, icv_update_fn_t icv_update);
+extern int skb_icv_walk(const struct sk_buff *skb, struct hash_desc *tfm,
+ int offset, int len, icv_update_fn_t icv_update);
static inline int xfrm_addr_cmp(xfrm_address_t *a, xfrm_address_t *b,
int family)
switch (family) {
default:
case AF_INET:
- return a->a4 - b->a4;
+ return (__force __u32)a->a4 - (__force __u32)b->a4;
case AF_INET6:
return ipv6_addr_cmp((struct in6_addr *)a,
(struct in6_addr *)b);
return index & 7;
}
+static inline int xfrm_aevent_is_on(void)
+{
+ struct sock *nlsk;
+ int ret = 0;
+
+ rcu_read_lock();
+ nlsk = rcu_dereference(xfrm_nl);
+ if (nlsk)
+ ret = netlink_has_listeners(nlsk, XFRMNLGRP_AEVENTS);
+ rcu_read_unlock();
+ return ret;
+}
+
+static inline void xfrm_aevent_doreplay(struct xfrm_state *x)
+{
+ if (xfrm_aevent_is_on())
+ xfrm_replay_notify(x, XFRM_REPLAY_UPDATE);
+}
+
+
#endif /* _NET_XFRM_H */