removed old FreeS/WAN cvs revision entries
[strongswan.git] / src / libfreeswan / ipsec_sa.h
1 /*
2 * @(#) Definitions of IPsec Security Association (ipsec_sa)
3 *
4 * Copyright (C) 2001, 2002, 2003
5 * Richard Guy Briggs <rgb@freeswan.org>
6 * and Michael Richardson <mcr@freeswan.org>
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by the
10 * Free Software Foundation; either version 2 of the License, or (at your
11 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
12 *
13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
15 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
16 * for more details.
17 *
18 * RCSID $Id: ipsec_sa.h,v 1.3 2004/04/28 08:07:11 as Exp $
19 *
20 * This file derived from ipsec_xform.h on 2001/9/18 by mcr.
21 *
22 */
23
24 /*
25 * This file describes the IPsec Security Association Structure.
26 *
27 * This structure keeps track of a single transform that may be done
28 * to a set of packets. It can describe applying the transform or
29 * apply the reverse. (e.g. compression vs expansion). However, it
30 * only describes one at a time. To describe both, two structures would
31 * be used, but since the sides of the transform are performed
32 * on different machines typically it is usual to have only one side
33 * of each association.
34 *
35 */
36
37 #ifndef _IPSEC_SA_H_
38
39 #ifdef __KERNEL__
40 #include "ipsec_stats.h"
41 #include "ipsec_life.h"
42 #include "ipsec_eroute.h"
43 #endif /* __KERNEL__ */
44 #include "ipsec_param.h"
45
46
47 /* SAs are held in a table.
48 * Entries in this table are referenced by IPsecSAref_t values.
49 * IPsecSAref_t values are conceptually subscripts. Because
50 * we want to allocate the table piece-meal, the subscripting
51 * is implemented with two levels, a bit like paged virtual memory.
52 * This representation mechanism is known as an Iliffe Vector.
53 *
54 * The Main table (AKA the refTable) consists of 2^IPSEC_SA_REF_MAINTABLE_IDX_WIDTH
55 * pointers to subtables.
56 * Each subtable has 2^IPSEC_SA_REF_SUBTABLE_IDX_WIDTH entries, each of which
57 * is a pointer to an SA.
58 *
59 * An IPsecSAref_t contains either an exceptional value (signified by the
60 * high-order bit being on) or a reference to a table entry. A table entry
61 * reference has the subtable subscript in the low-order
62 * IPSEC_SA_REF_SUBTABLE_IDX_WIDTH bits and the Main table subscript
63 * in the next lowest IPSEC_SA_REF_MAINTABLE_IDX_WIDTH bits.
64 *
65 * The Maintable entry for an IPsecSAref_t x, a pointer to its subtable, is
66 * IPsecSAref2table(x). It is of type struct IPsecSArefSubTable *.
67 *
68 * The pointer to the SA for x is IPsecSAref2SA(x). It is of type
69 * struct ipsec_sa*. The macro definition clearly shows the two-level
70 * access needed to find the SA pointer.
71 *
72 * The Maintable is allocated when IPsec is initialized.
73 * Each subtable is allocated when needed, but the first is allocated
74 * when IPsec is initialized.
75 *
76 * IPsecSAref_t is designed to be smaller than an NFmark so that
77 * they can be stored in NFmarks and still leave a few bits for other
78 * purposes. The spare bits are in the low order of the NFmark
79 * but in the high order of the IPsecSAref_t, so conversion is required.
80 * We pick the upper bits of NFmark on the theory that they are less likely to
81 * interfere with more pedestrian uses of nfmark.
82 */
83
84
85 typedef unsigned short int IPsecRefTableUnusedCount;
86
87 #define IPSEC_SA_REF_TABLE_NUM_ENTRIES (1 << IPSEC_SA_REF_TABLE_IDX_WIDTH)
88
89 #ifdef __KERNEL__
90 #if ((IPSEC_SA_REF_TABLE_IDX_WIDTH - (1 + IPSEC_SA_REF_MAINTABLE_IDX_WIDTH)) < 0)
91 #error "IPSEC_SA_REF_TABLE_IDX_WIDTH("IPSEC_SA_REF_TABLE_IDX_WIDTH") MUST be < 1 + IPSEC_SA_REF_MAINTABLE_IDX_WIDTH("IPSEC_SA_REF_MAINTABLE_IDX_WIDTH")"
92 #endif
93
94 #define IPSEC_SA_REF_SUBTABLE_IDX_WIDTH (IPSEC_SA_REF_TABLE_IDX_WIDTH - IPSEC_SA_REF_MAINTABLE_IDX_WIDTH)
95
96 #define IPSEC_SA_REF_MAINTABLE_NUM_ENTRIES (1 << IPSEC_SA_REF_MAINTABLE_IDX_WIDTH)
97 #define IPSEC_SA_REF_SUBTABLE_NUM_ENTRIES (1 << IPSEC_SA_REF_SUBTABLE_IDX_WIDTH)
98
99 #ifdef CONFIG_NETFILTER
100 #define IPSEC_SA_REF_HOST_FIELD(x) ((struct sk_buff*)(x))->nfmark
101 #define IPSEC_SA_REF_HOST_FIELD_TYPE typeof(IPSEC_SA_REF_HOST_FIELD(NULL))
102 #else /* CONFIG_NETFILTER */
103 /* just make it work for now, it doesn't matter, since there is no nfmark */
104 #define IPSEC_SA_REF_HOST_FIELD_TYPE unsigned long
105 #endif /* CONFIG_NETFILTER */
106 #define IPSEC_SA_REF_HOST_FIELD_WIDTH (8 * sizeof(IPSEC_SA_REF_HOST_FIELD_TYPE))
107 #define IPSEC_SA_REF_FIELD_WIDTH (8 * sizeof(IPsecSAref_t))
108
109 #define IPSEC_SA_REF_MASK (IPSEC_SAREF_NULL >> (IPSEC_SA_REF_FIELD_WIDTH - IPSEC_SA_REF_TABLE_IDX_WIDTH))
110 #define IPSEC_SA_REF_TABLE_MASK ((IPSEC_SAREF_NULL >> (IPSEC_SA_REF_FIELD_WIDTH - IPSEC_SA_REF_MAINTABLE_IDX_WIDTH)) << IPSEC_SA_REF_SUBTABLE_IDX_WIDTH)
111 #define IPSEC_SA_REF_ENTRY_MASK (IPSEC_SAREF_NULL >> (IPSEC_SA_REF_FIELD_WIDTH - IPSEC_SA_REF_SUBTABLE_IDX_WIDTH))
112
113 #define IPsecSAref2table(x) (((x) & IPSEC_SA_REF_TABLE_MASK) >> IPSEC_SA_REF_SUBTABLE_IDX_WIDTH)
114 #define IPsecSAref2entry(x) ((x) & IPSEC_SA_REF_ENTRY_MASK)
115 #define IPsecSArefBuild(x,y) (((x) << IPSEC_SA_REF_SUBTABLE_IDX_WIDTH) + (y))
116
117 #define IPsecSAref2SA(x) (ipsec_sadb.refTable[IPsecSAref2table(x)]->entry[IPsecSAref2entry(x)])
118 #define IPsecSA2SAref(x) ((x)->ips_ref)
119
120 #define EMT_INBOUND 0x01 /* SA direction, 1=inbound */
121
122 /* 'struct ipsec_sa' should be 64bit aligned when allocated. */
123 struct ipsec_sa
124 {
125 IPsecSAref_t ips_ref; /* reference table entry number */
126 atomic_t ips_refcount; /* reference count for this struct */
127 struct ipsec_sa *ips_hnext; /* next in hash chain */
128 struct ipsec_sa *ips_inext; /* pointer to next xform */
129 struct ipsec_sa *ips_onext; /* pointer to prev xform */
130
131 struct ifnet *ips_rcvif; /* related rcv encap interface */
132
133 struct sa_id ips_said; /* SA ID */
134
135 __u32 ips_seq; /* seq num of msg that initiated this SA */
136 __u32 ips_pid; /* PID of process that initiated this SA */
137 __u8 ips_authalg; /* auth algorithm for this SA */
138 __u8 ips_encalg; /* enc algorithm for this SA */
139
140 struct ipsec_stats ips_errs;
141
142 __u8 ips_replaywin; /* replay window size */
143 __u8 ips_state; /* state of SA */
144 __u32 ips_replaywin_lastseq; /* last pkt sequence num */
145 __u64 ips_replaywin_bitmap; /* bitmap of received pkts */
146 __u32 ips_replaywin_maxdiff; /* max pkt sequence difference */
147
148 __u32 ips_flags; /* generic xform flags */
149
150
151 struct ipsec_lifetimes ips_life; /* lifetime records */
152
153 /* selector information */
154 struct sockaddr*ips_addr_s; /* src sockaddr */
155 struct sockaddr*ips_addr_d; /* dst sockaddr */
156 struct sockaddr*ips_addr_p; /* proxy sockaddr */
157 __u16 ips_addr_s_size;
158 __u16 ips_addr_d_size;
159 __u16 ips_addr_p_size;
160 ip_address ips_flow_s;
161 ip_address ips_flow_d;
162 ip_address ips_mask_s;
163 ip_address ips_mask_d;
164
165 __u16 ips_key_bits_a; /* size of authkey in bits */
166 __u16 ips_auth_bits; /* size of authenticator in bits */
167 __u16 ips_key_bits_e; /* size of enckey in bits */
168 __u16 ips_iv_bits; /* size of IV in bits */
169 __u8 ips_iv_size;
170 __u16 ips_key_a_size;
171 __u16 ips_key_e_size;
172
173 caddr_t ips_key_a; /* authentication key */
174 caddr_t ips_key_e; /* encryption key */
175 caddr_t ips_iv; /* Initialisation Vector */
176
177 struct ident ips_ident_s; /* identity src */
178 struct ident ips_ident_d; /* identity dst */
179
180 #ifdef CONFIG_IPSEC_IPCOMP
181 __u16 ips_comp_adapt_tries; /* ipcomp self-adaption tries */
182 __u16 ips_comp_adapt_skip; /* ipcomp self-adaption to-skip */
183 __u64 ips_comp_ratio_cbytes; /* compressed bytes */
184 __u64 ips_comp_ratio_dbytes; /* decompressed (or uncompressed) bytes */
185 #endif /* CONFIG_IPSEC_IPCOMP */
186
187 #ifdef CONFIG_IPSEC_NAT_TRAVERSAL
188 __u8 ips_natt_type;
189 __u8 ips_natt_reserved[3];
190 __u16 ips_natt_sport;
191 __u16 ips_natt_dport;
192
193 struct sockaddr *ips_natt_oa;
194 __u16 ips_natt_oa_size;
195 __u16 ips_natt_reserved2;
196 #endif
197
198 #if 0
199 __u32 ips_sens_dpd;
200 __u8 ips_sens_sens_level;
201 __u8 ips_sens_sens_len;
202 __u64* ips_sens_sens_bitmap;
203 __u8 ips_sens_integ_level;
204 __u8 ips_sens_integ_len;
205 __u64* ips_sens_integ_bitmap;
206 #endif
207 struct ipsec_alg_enc *ips_alg_enc;
208 struct ipsec_alg_auth *ips_alg_auth;
209 IPsecSAref_t ips_ref_rel;
210 };
211
212 struct IPsecSArefSubTable
213 {
214 struct ipsec_sa* entry[IPSEC_SA_REF_SUBTABLE_NUM_ENTRIES];
215 };
216
217 struct ipsec_sadb {
218 struct IPsecSArefSubTable* refTable[IPSEC_SA_REF_MAINTABLE_NUM_ENTRIES];
219 IPsecSAref_t refFreeList[IPSEC_SA_REF_FREELIST_NUM_ENTRIES];
220 int refFreeListHead;
221 int refFreeListTail;
222 IPsecSAref_t refFreeListCont;
223 IPsecSAref_t said_hash[SADB_HASHMOD];
224 spinlock_t sadb_lock;
225 };
226
227 extern struct ipsec_sadb ipsec_sadb;
228
229 extern int ipsec_SAref_recycle(void);
230 extern int ipsec_SArefSubTable_alloc(unsigned table);
231 extern int ipsec_saref_freelist_init(void);
232 extern int ipsec_sadb_init(void);
233 extern struct ipsec_sa *ipsec_sa_alloc(int*error); /* pass in error var by pointer */
234 extern IPsecSAref_t ipsec_SAref_alloc(int*erorr); /* pass in error var by pointer */
235 extern int ipsec_sa_free(struct ipsec_sa* ips);
236 extern struct ipsec_sa *ipsec_sa_getbyid(struct sa_id *said);
237 extern int ipsec_sa_put(struct ipsec_sa *ips);
238 extern int ipsec_sa_add(struct ipsec_sa *ips);
239 extern int ipsec_sa_del(struct ipsec_sa *ips);
240 extern int ipsec_sa_delchain(struct ipsec_sa *ips);
241 extern int ipsec_sadb_cleanup(__u8 proto);
242 extern int ipsec_sadb_free(void);
243 extern int ipsec_sa_wipe(struct ipsec_sa *ips);
244 #endif /* __KERNEL__ */
245
246 enum ipsec_direction {
247 ipsec_incoming = 1,
248 ipsec_outgoing = 2
249 };
250
251 #define _IPSEC_SA_H_
252 #endif /* _IPSEC_SA_H_ */