#include <linux/skbuff.h>
#include <linux/socket.h>
#include <linux/pfkeyv2.h>
+#include <linux/ipsec.h>
#include <linux/in6.h>
#include <linux/mutex.h>
{
/* Note: bydst is re-used during gc */
struct list_head bydst;
+ struct list_head bysrc;
struct list_head byspi;
atomic_t refcnt;
/* 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;
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_state_afinfo {
unsigned short family;
struct list_head *state_bydst;
+ struct list_head *state_bysrc;
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 *(*state_lookup_byaddr)(xfrm_address_t *daddr, xfrm_address_t *saddr, u8 proto);
struct xfrm_state *(*find_acq)(u8 mode, u32 reqid, u8 proto,
xfrm_address_t *daddr, xfrm_address_t *saddr,
int create);
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 sk_buff *skb);
int (*output)(struct xfrm_state *, struct sk_buff *pskb);
+ 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);
};
__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
{
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);
+ 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, u16 sport);
int (*notify_policy)(struct xfrm_policy *x, int dir, struct km_event *c);
};
return 0;
}
+static __inline__
+unsigned __xfrm4_src_hash(xfrm_address_t *addr)
+{
+ return __xfrm4_dst_hash(addr);
+}
+
+static __inline__
+unsigned __xfrm6_src_hash(xfrm_address_t *addr)
+{
+ return __xfrm6_dst_hash(addr);
+}
+
+static __inline__
+unsigned xfrm_src_hash(xfrm_address_t *addr, unsigned short family)
+{
+ switch (family) {
+ case AF_INET:
+ return __xfrm4_src_hash(addr);
+ case AF_INET6:
+ return __xfrm6_src_hash(addr);
+ }
+ return 0;
+}
+
static __inline__
unsigned __xfrm4_spi_hash(xfrm_address_t *addr, u32 spi, u8 proto)
{
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*/
}
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
*/
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_byaddr(xfrm_address_t *daddr, xfrm_address_t *saddr, u8 proto, unsigned short family);
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 xfrm4_tunnel_deregister(struct xfrm_tunnel *handler);
extern int xfrm6_rcv_spi(struct sk_buff *skb, u32 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 void xfrm6_tunnel_free_spi(xfrm_address_t *saddr);
extern u32 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);
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_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;