]> git.ipfire.org Git - thirdparty/strongswan.git/blob - linux/net/ipsec/ipsec_life.c
- import of strongswan-2.7.0
[thirdparty/strongswan.git] / linux / net / ipsec / ipsec_life.c
1 /*
2 * @(#) lifetime structure utilities
3 *
4 * Copyright (C) 2001 Richard Guy Briggs <rgb@freeswan.org>
5 * and Michael Richardson <mcr@freeswan.org>
6 *
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation; either version 2 of the License, or (at your
10 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 * for more details.
16 *
17 * RCSID $Id: ipsec_life.c,v 1.3 2004/04/28 08:06:22 as Exp $
18 *
19 */
20
21 /*
22 * This provides series of utility functions for dealing with lifetime
23 * structures.
24 *
25 * ipsec_check_lifetime - returns -1 hard lifetime exceeded
26 * 0 soft lifetime exceeded
27 * 1 everything is okay
28 * based upon whether or not the count exceeds hard/soft
29 *
30 */
31
32 #define __NO_VERSION__
33 #include <linux/module.h>
34 #include <linux/config.h> /* for CONFIG_IP_FORWARD */
35 #include <linux/version.h>
36 #include <linux/kernel.h> /* printk() */
37
38 #include "freeswan/ipsec_param.h"
39
40 #include <linux/netdevice.h> /* struct device, struct net_device_stats and other headers */
41 #include <linux/etherdevice.h> /* eth_type_trans */
42 #include <linux/skbuff.h>
43 #include <freeswan.h>
44
45 #include "freeswan/radij.h"
46 #include "freeswan/ipsec_life.h"
47 #include "freeswan/ipsec_xform.h"
48 #include "freeswan/ipsec_eroute.h"
49 #include "freeswan/ipsec_encap.h"
50 #include "freeswan/ipsec_radij.h"
51
52 #include "freeswan/ipsec_sa.h"
53 #include "freeswan/ipsec_tunnel.h"
54 #include "freeswan/ipsec_ipe4.h"
55 #include "freeswan/ipsec_ah.h"
56 #include "freeswan/ipsec_esp.h"
57
58 #ifdef CONFIG_IPSEC_IPCOMP
59 #include "freeswan/ipcomp.h"
60 #endif /* CONFIG_IPSEC_IPCOMP */
61
62 #include <pfkeyv2.h>
63 #include <pfkey.h>
64
65 #include "freeswan/ipsec_proto.h"
66
67
68 enum ipsec_life_alive
69 ipsec_lifetime_check(struct ipsec_lifetime64 *il64,
70 const char *lifename,
71 const char *saname,
72 enum ipsec_life_type ilt,
73 enum ipsec_direction idir,
74 struct ipsec_sa *ips)
75 {
76 __u64 count;
77 const char *dir;
78
79 if(saname == NULL) {
80 saname = "unknown-SA";
81 }
82
83 if(idir == ipsec_incoming) {
84 dir = "incoming";
85 } else {
86 dir = "outgoing";
87 }
88
89
90 if(ilt == ipsec_life_timebased) {
91 count = jiffies/HZ - il64->ipl_count;
92 } else {
93 count = il64->ipl_count;
94 }
95
96 if(il64->ipl_hard &&
97 (count > il64->ipl_hard)) {
98 KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
99 "klips_debug:ipsec_lifetime_check: "
100 "hard %s lifetime of SA:<%s%s%s> %s has been reached, SA expired, "
101 "%s packet dropped.\n",
102 lifename,
103 IPS_XFORM_NAME(ips),
104 saname,
105 dir);
106
107 pfkey_expire(ips, 1);
108 return ipsec_life_harddied;
109 }
110
111 if(il64->ipl_soft &&
112 (count > il64->ipl_soft)) {
113 KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
114 "klips_debug:ipsec_lifetime_check: "
115 "soft %s lifetime of SA:<%s%s%s> %s has been reached, SA expiring, "
116 "soft expire message sent up, %s packet still processed.\n",
117 lifename,
118 IPS_XFORM_NAME(ips),
119 saname,
120 dir);
121
122 if(ips->ips_state != SADB_SASTATE_DYING) {
123 pfkey_expire(ips, 0);
124 }
125 ips->ips_state = SADB_SASTATE_DYING;
126
127 return ipsec_life_softdied;
128 }
129 return ipsec_life_okay;
130 }
131
132
133 /*
134 * This function takes a buffer (with length), a lifetime name and type,
135 * and formats a string to represent the current values of the lifetime.
136 *
137 * It returns the number of bytes that the format took (or would take,
138 * if the buffer were large enough: snprintf semantics).
139 * This is used in /proc routines and in debug output.
140 */
141 int
142 ipsec_lifetime_format(char *buffer,
143 int buflen,
144 char *lifename,
145 enum ipsec_life_type timebaselife,
146 struct ipsec_lifetime64 *lifetime)
147 {
148 int len = 0;
149 __u64 count;
150
151 if(timebaselife == ipsec_life_timebased) {
152 count = jiffies/HZ - lifetime->ipl_count;
153 } else {
154 count = lifetime->ipl_count;
155 }
156
157 if(lifetime->ipl_count > 1 ||
158 lifetime->ipl_soft ||
159 lifetime->ipl_hard) {
160 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0))
161 len = ipsec_snprintf(buffer, buflen,
162 "%s(%Lu,%Lu,%Lu)",
163 lifename,
164 count,
165 lifetime->ipl_soft,
166 lifetime->ipl_hard);
167 #else /* XXX high 32 bits are not displayed */
168 len = ipsec_snprintf(buffer, buflen,
169 "%s(%lu,%lu,%lu)",
170 lifename,
171 (unsigned long)count,
172 (unsigned long)lifetime->ipl_soft,
173 (unsigned long)lifetime->ipl_hard);
174 #endif
175 }
176
177 return len;
178 }
179
180 void
181 ipsec_lifetime_update_hard(struct ipsec_lifetime64 *lifetime,
182 __u64 newvalue)
183 {
184 if(newvalue &&
185 (!lifetime->ipl_hard ||
186 (newvalue < lifetime->ipl_hard))) {
187 lifetime->ipl_hard = newvalue;
188
189 if(!lifetime->ipl_soft &&
190 (lifetime->ipl_hard < lifetime->ipl_soft)) {
191 lifetime->ipl_soft = lifetime->ipl_hard;
192 }
193 }
194 }
195
196 void
197 ipsec_lifetime_update_soft(struct ipsec_lifetime64 *lifetime,
198 __u64 newvalue)
199 {
200 if(newvalue &&
201 (!lifetime->ipl_soft ||
202 (newvalue < lifetime->ipl_soft))) {
203 lifetime->ipl_soft = newvalue;
204
205 if(lifetime->ipl_hard &&
206 (lifetime->ipl_hard < lifetime->ipl_soft)) {
207 lifetime->ipl_soft = lifetime->ipl_hard;
208 }
209 }
210 }