Merge branch 'master' into upstream
[pandora-kernel.git] / include / net / xfrm.h
index 8d362c4..9c5ee9f 100644 (file)
@@ -11,6 +11,7 @@
 #include <linux/crypto.h>
 #include <linux/pfkeyv2.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"
    ------------------------------------
@@ -135,6 +142,21 @@ struct xfrm_state
        /* 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;
 
@@ -144,6 +166,7 @@ struct xfrm_state
        /* 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;
@@ -153,6 +176,9 @@ struct xfrm_state
        void                    *data;
 };
 
+/* xflags - make enum if more show up */
+#define XFRM_TIME_DEFER        1
+
 enum {
        XFRM_STATE_VOID,
        XFRM_STATE_ACQ,
@@ -169,6 +195,7 @@ struct km_event
                u32 hard;
                u32 proto;
                u32 byid;
+               u32 aevent;
        } data;
 
        u32     seq;
@@ -180,8 +207,8 @@ struct xfrm_type;
 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);
@@ -199,13 +226,15 @@ 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, 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);
@@ -223,7 +252,6 @@ extern int xfrm_state_unregister_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;
@@ -232,22 +260,30 @@ struct xfrm_type
 
        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);
        /* 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 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:
@@ -305,7 +341,21 @@ struct xfrm_policy
        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
 {
@@ -573,25 +623,11 @@ static inline void xfrm_dst_destroy(struct xfrm_dst *xdst)
 
 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 *
@@ -831,13 +867,19 @@ struct xfrm_algo_desc {
 /* 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, __u32 info);
+
+       struct xfrm6_tunnel *next;
+       int priority;
 };
 
 extern void xfrm_init(void);
@@ -865,6 +907,7 @@ 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_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);
@@ -872,7 +915,7 @@ extern int xfrm4_rcv(struct sk_buff *skb);
 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, u32 spi);
 extern int xfrm6_rcv(struct sk_buff **pskb);
 extern int xfrm6_tunnel_register(struct xfrm6_tunnel *handler);
 extern int xfrm6_tunnel_deregister(struct xfrm6_tunnel *handler);
@@ -924,7 +967,7 @@ 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 void km_policy_expired(struct xfrm_policy *pol, int dir, int hard, u32 pid);
 
 extern void xfrm_input_init(void);
 extern int xfrm_parse_spi(struct sk_buff *skb, u8 nexthdr, u32 *spi, u32 *seq);
@@ -965,4 +1008,24 @@ static inline int xfrm_policy_id2dir(u32 index)
        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 */