struct xfrm_state
{
/* Note: bydst is re-used during gc */
+ struct list_head all;
struct hlist_node bydst;
struct hlist_node bysrc;
struct hlist_node byspi;
struct xfrm_algo *aalg;
struct xfrm_algo *ealg;
struct xfrm_algo *calg;
+ struct xfrm_algo_aead *aead;
/* Data for encapsulator */
struct xfrm_encap_tmpl *encap;
/* Reference to data common to all the instances of this
* transformer. */
- struct xfrm_type *type;
+ 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_state_afinfo {
unsigned int family;
unsigned int proto;
- unsigned int eth_proto;
+ __be16 eth_proto;
struct module *owner;
- struct xfrm_type *type_map[IPPROTO_MAX];
+ 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_state *x, struct flowi *fl,
u32 (*get_mtu)(struct xfrm_state *, int size);
};
-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 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 {
/*
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:
struct xfrm_policy
{
struct xfrm_policy *next;
+ struct list_head bytype;
struct hlist_node bydst;
struct hlist_node byidx;
} header;
/* Sequence number for replay protection. */
- u64 seq;
+ union {
+ u64 output;
+ __be32 input;
+ } seq;
};
#define XFRM_SKB_CB(__skb) ((struct xfrm_skb_cb *)&((__skb)->cb[0]))
__be16 id;
__be16 frag_off;
+ /* IP header length (excluding options or extension headers). */
+ u8 ihl;
+
/* TOS for IPv4, class for IPv6. */
u8 tos;
/* Protocol for IPv4, NH for IPv6. */
u8 protocol;
+ /* Option length for IPv4, zero for IPv6. */
+ u8 optlen;
+
/* Used by IPv6 only, zero for IPv4. */
u8 flow_lbl[3];
};
atomic_inc(&policy->refcnt);
}
-extern void __xfrm_policy_destroy(struct xfrm_policy *policy);
+extern void xfrm_policy_destroy(struct xfrm_policy *policy);
static inline void xfrm_pol_put(struct xfrm_policy *policy)
{
if (atomic_dec_and_test(&policy->refcnt))
- __xfrm_policy_destroy(policy);
+ xfrm_policy_destroy(policy);
}
#ifdef CONFIG_XFRM_SUB_POLICY
return NULL;
}
+static __inline__
+void xfrm_flowi_addr_get(struct flowi *fl,
+ xfrm_address_t *saddr, xfrm_address_t *daddr,
+ unsigned short family)
+{
+ switch(family) {
+ case AF_INET:
+ memcpy(&saddr->a4, &fl->fl4_src, sizeof(saddr->a4));
+ memcpy(&daddr->a4, &fl->fl4_dst, sizeof(daddr->a4));
+ break;
+ case AF_INET6:
+ ipv6_addr_copy((struct in6_addr *)&saddr->a6, &fl->fl6_src);
+ ipv6_addr_copy((struct in6_addr *)&daddr->a6, &fl->fl6_dst);
+ break;
+ }
+}
+
static __inline__ int
__xfrm4_state_addr_check(struct xfrm_state *x,
xfrm_address_t *daddr, xfrm_address_t *saddr)
/*
* xfrm algorithm information
*/
+struct xfrm_algo_aead_info {
+ u16 icv_truncbits;
+};
+
struct xfrm_algo_auth_info {
u16 icv_truncbits;
u16 icv_fullbits;
char *compat;
u8 available:1;
union {
+ struct xfrm_algo_aead_info aead;
struct xfrm_algo_auth_info auth;
struct xfrm_algo_encr_info encr;
struct xfrm_algo_comp_info comp;
int priority;
};
+struct xfrm_state_walk {
+ struct xfrm_state *state;
+ int count;
+ u8 proto;
+};
+
+struct xfrm_policy_walk {
+ struct xfrm_policy *policy;
+ int count;
+ u8 type, cur_type;
+};
+
extern void xfrm_init(void);
extern void xfrm4_init(void);
extern void xfrm_state_init(void);
extern int xfrm_proc_init(void);
#endif
-extern int xfrm_state_walk(u8 proto, int (*func)(struct xfrm_state *, int, void*), void *);
+static inline void xfrm_state_walk_init(struct xfrm_state_walk *walk, u8 proto)
+{
+ walk->proto = proto;
+ walk->state = NULL;
+ walk->count = 0;
+}
+
+static inline void xfrm_state_walk_done(struct xfrm_state_walk *walk)
+{
+ if (walk->state != NULL) {
+ xfrm_state_put(walk->state);
+ walk->state = NULL;
+ }
+}
+
+extern int xfrm_state_walk(struct xfrm_state_walk *walk,
+ int (*func)(struct xfrm_state *, int, void*), void *);
extern struct xfrm_state *xfrm_state_alloc(void);
extern struct xfrm_state *xfrm_state_find(xfrm_address_t *daddr, xfrm_address_t *saddr,
struct flowi *fl, struct xfrm_tmpl *tmpl,
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 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,
#endif
struct xfrm_policy *xfrm_policy_alloc(gfp_t gfp);
-extern int xfrm_policy_walk(u8 type, int (*func)(struct xfrm_policy *, int, int, void*), void *);
+
+static inline void xfrm_policy_walk_init(struct xfrm_policy_walk *walk, u8 type)
+{
+ walk->cur_type = XFRM_POLICY_TYPE_MAIN;
+ walk->type = type;
+ walk->policy = NULL;
+ walk->count = 0;
+}
+
+static inline void xfrm_policy_walk_done(struct xfrm_policy_walk *walk)
+{
+ if (walk->policy != NULL) {
+ xfrm_pol_put(walk->policy);
+ walk->policy = NULL;
+ }
+}
+
+extern int xfrm_policy_walk(struct xfrm_policy_walk *walk,
+ 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(u8 type, int dir,
struct xfrm_selector *sel,
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 int 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_bundle_ok(struct xfrm_policy *pol, struct xfrm_dst *xdst,
struct flowi *fl, int family, int strict);
extern struct xfrm_algo_desc *xfrm_aalg_get_byname(char *name, int probe);
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);
+extern struct xfrm_algo_desc *xfrm_aead_get_byname(char *name, int icv_len,
+ int probe);
struct hash_desc;
struct scatterlist;