[IPSEC]: Make x->lastused an unsigned long
[pandora-kernel.git] / include / net / xfrm.h
index 0e84484..311bbd1 100644 (file)
@@ -37,6 +37,8 @@
 extern struct sock *xfrm_nl;
 extern u32 sysctl_xfrm_aevent_etime;
 extern u32 sysctl_xfrm_aevent_rseqth;
+extern int sysctl_xfrm_larval_drop;
+extern u32 sysctl_xfrm_acq_expires;
 
 extern struct mutex xfrm_cfg_mutex;
 
@@ -181,12 +183,13 @@ struct xfrm_state
        struct timer_list       timer;
 
        /* Last used time */
-       u64                     lastused;
+       unsigned long           lastused;
 
        /* Reference to data common to all the instances of this
         * transformer. */
        struct xfrm_type        *type;
-       struct xfrm_mode        *mode;
+       struct xfrm_mode        *inner_mode;
+       struct xfrm_mode        *outer_mode;
 
        /* Security context */
        struct xfrm_sec_ctx     *security;
@@ -224,24 +227,22 @@ struct km_event
        u32     event;
 };
 
+struct net_device;
 struct xfrm_type;
 struct xfrm_dst;
 struct xfrm_policy_afinfo {
        unsigned short          family;
-       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);
+       struct dst_entry        *(*dst_lookup)(int tos, xfrm_address_t *saddr,
+                                              xfrm_address_t *daddr);
        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, 
-                                                int nx,
-                                                struct flowi *fl, 
-                                                struct dst_entry **dst_p);
        void                    (*decode_session)(struct sk_buff *skb,
                                                  struct flowi *fl);
+       int                     (*get_tos)(struct flowi *fl);
+       int                     (*fill_dst)(struct xfrm_dst *xdst,
+                                           struct net_device *dev);
 };
 
 extern int xfrm_policy_register_afinfo(struct xfrm_policy_afinfo *afinfo);
@@ -255,7 +256,13 @@ 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;
+       unsigned int            family;
+       unsigned int            proto;
+       unsigned int            eth_proto;
+       unsigned int            nf_post_routing;
+       struct module           *owner;
+       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,
                                                struct xfrm_tmpl *tmpl,
@@ -263,12 +270,16 @@ struct xfrm_state_afinfo {
        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                     (*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 struct xfrm_state_afinfo *xfrm_state_get_afinfo(unsigned short family);
-extern void xfrm_state_put_afinfo(struct xfrm_state_afinfo *afinfo);
 
 extern void xfrm_state_delete_tunnel(struct xfrm_state *x);
 
@@ -280,6 +291,8 @@ struct xfrm_type
        __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 *);
@@ -287,18 +300,35 @@ struct xfrm_type
        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_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 struct xfrm_type *xfrm_get_type(u8 proto, unsigned short family);
-extern void xfrm_put_type(struct xfrm_type *type);
 
 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);
 
        /*
@@ -312,16 +342,32 @@ struct xfrm_mode {
         * header.  The value of the network header will always point
         * to the top IP header while skb->data will point to the payload.
         */
-       int (*output)(struct xfrm_state *x,struct sk_buff *skb);
+       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);
-extern struct xfrm_mode *xfrm_get_mode(unsigned int encap, int family);
-extern void xfrm_put_mode(struct xfrm_mode *mode);
 
 struct xfrm_tmpl
 {
@@ -449,6 +495,51 @@ struct xfrm_skb_cb {
 
 #define XFRM_SKB_CB(__skb) ((struct xfrm_skb_cb *)&((__skb)->cb[0]))
 
+/*
+ * This structure is used by the afinfo prepare_input/prepare_output functions
+ * 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;
+
+       /* Copied from header for IPv4, always set to zero and DF for IPv6. */
+       __be16 id;
+       __be16 frag_off;
+
+       /* TOS for IPv4, class for IPv6. */
+       u8 tos;
+
+       /* TTL for IPv4, hop limitfor IPv6. */
+       u8 ttl;
+
+       /* Protocol for IPv4, NH for IPv6. */
+       u8 protocol;
+
+       /* Used by IPv6 only, zero for IPv4. */
+       u8 flow_lbl[3];
+};
+
+#define XFRM_MODE_SKB_CB(__skb) ((struct xfrm_mode_skb_cb *)&((__skb)->cb[0]))
+
+/*
+ * This structure is used by the input processing to locate the SPI and
+ * related information.
+ */
+struct xfrm_spi_skb_cb {
+       union {
+               struct inet_skb_parm h4;
+               struct inet6_skb_parm h6;
+       } header;
+
+       unsigned int nhoff;
+       unsigned int daddroff;
+};
+
+#define XFRM_SPI_SKB_CB(__skb) ((struct xfrm_spi_skb_cb *)&((__skb)->cb[0]))
+
 /* Audit Information */
 struct xfrm_audit
 {
@@ -1045,12 +1136,32 @@ 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_mtu(struct xfrm_state *x, int mtu);
 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_output_resume(struct sk_buff *skb, int err);
 extern int xfrm_output(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,
+                          int encap_type);
+extern int xfrm4_transport_finish(struct sk_buff *skb, int async);
 extern 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_tunnel_register(struct xfrm_tunnel *handler, unsigned short family);
 extern int xfrm4_tunnel_deregister(struct xfrm_tunnel *handler, unsigned short family);
-extern int xfrm6_rcv_spi(struct sk_buff *skb, __be32 spi);
+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);
@@ -1059,6 +1170,8 @@ extern int xfrm6_tunnel_deregister(struct xfrm6_tunnel *handler, unsigned short
 extern __be32 xfrm6_tunnel_alloc_spi(xfrm_address_t *saddr);
 extern void xfrm6_tunnel_free_spi(xfrm_address_t *saddr);
 extern __be32 xfrm6_tunnel_spi_lookup(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_find_1stfragopt(struct xfrm_state *x, struct sk_buff *skb,
                                 u8 **prevhdr);
@@ -1066,7 +1179,6 @@ extern int xfrm6_find_1stfragopt(struct xfrm_state *x, struct sk_buff *skb,
 #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);
-extern int xfrm_dst_lookup(struct xfrm_dst **dst, struct flowi *fl, unsigned short family);
 #else
 static inline int xfrm_user_policy(struct sock *sk, int optname, u8 __user *optval, int optlen)
 {
@@ -1079,11 +1191,6 @@ static inline int xfrm4_udp_encap_rcv(struct sock *sk, struct sk_buff *skb)
        kfree_skb(skb);
        return 0;
 }
-
-static inline int xfrm_dst_lookup(struct xfrm_dst **dst, struct flowi *fl, unsigned short family)
-{
-       return -EINVAL;
-} 
 #endif
 
 struct xfrm_policy *xfrm_policy_alloc(gfp_t gfp);
@@ -1104,7 +1211,6 @@ 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 void xfrm_init_pmtu(struct dst_entry *dst);
 
 #ifdef CONFIG_XFRM_MIGRATE
 extern int km_migrate(struct xfrm_selector *sel, u8 dir, u8 type,
@@ -1175,10 +1281,15 @@ static inline int xfrm_aevent_is_on(void)
        return ret;
 }
 
+static inline int xfrm_alg_len(struct xfrm_algo *alg)
+{
+       return sizeof(*alg) + ((alg->alg_key_len + 7) / 8);
+}
+
 #ifdef CONFIG_XFRM_MIGRATE
 static inline struct xfrm_algo *xfrm_algo_clone(struct xfrm_algo *orig)
 {
-       return (struct xfrm_algo *)kmemdup(orig, sizeof(*orig) + orig->alg_key_len, GFP_KERNEL);
+       return kmemdup(orig, xfrm_alg_len(orig), GFP_KERNEL);
 }
 
 static inline void xfrm_states_put(struct xfrm_state **states, int n)