aboutsummaryrefslogtreecommitdiffstats
path: root/net/xfrm/xfrm_state.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/xfrm/xfrm_state.c')
-rw-r--r--net/xfrm/xfrm_state.c108
1 files changed, 98 insertions, 10 deletions
diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c
index c656cbaf35e8..a8e14dc1b04e 100644
--- a/net/xfrm/xfrm_state.c
+++ b/net/xfrm/xfrm_state.c
@@ -20,6 +20,15 @@
20#include <linux/module.h> 20#include <linux/module.h>
21#include <asm/uaccess.h> 21#include <asm/uaccess.h>
22 22
23struct sock *xfrm_nl;
24EXPORT_SYMBOL(xfrm_nl);
25
26u32 sysctl_xfrm_aevent_etime = XFRM_AE_ETIME;
27EXPORT_SYMBOL(sysctl_xfrm_aevent_etime);
28
29u32 sysctl_xfrm_aevent_rseqth = XFRM_AE_SEQT_SIZE;
30EXPORT_SYMBOL(sysctl_xfrm_aevent_rseqth);
31
23/* Each xfrm_state may be linked to two tables: 32/* Each xfrm_state may be linked to two tables:
24 33
25 1. Hash table by (spi,daddr,ah/esp) to find SA by SPI. (input,ctl) 34 1. Hash table by (spi,daddr,ah/esp) to find SA by SPI. (input,ctl)
@@ -50,18 +59,20 @@ static DEFINE_SPINLOCK(xfrm_state_gc_lock);
50 59
51static int xfrm_state_gc_flush_bundles; 60static int xfrm_state_gc_flush_bundles;
52 61
53static int __xfrm_state_delete(struct xfrm_state *x); 62int __xfrm_state_delete(struct xfrm_state *x);
54 63
55static struct xfrm_state_afinfo *xfrm_state_get_afinfo(unsigned short family); 64static struct xfrm_state_afinfo *xfrm_state_get_afinfo(unsigned short family);
56static void xfrm_state_put_afinfo(struct xfrm_state_afinfo *afinfo); 65static void xfrm_state_put_afinfo(struct xfrm_state_afinfo *afinfo);
57 66
58static int km_query(struct xfrm_state *x, struct xfrm_tmpl *t, struct xfrm_policy *pol); 67int km_query(struct xfrm_state *x, struct xfrm_tmpl *t, struct xfrm_policy *pol);
59static void km_state_expired(struct xfrm_state *x, int hard); 68void km_state_expired(struct xfrm_state *x, int hard, u32 pid);
60 69
61static void xfrm_state_gc_destroy(struct xfrm_state *x) 70static void xfrm_state_gc_destroy(struct xfrm_state *x)
62{ 71{
63 if (del_timer(&x->timer)) 72 if (del_timer(&x->timer))
64 BUG(); 73 BUG();
74 if (del_timer(&x->rtimer))
75 BUG();
65 kfree(x->aalg); 76 kfree(x->aalg);
66 kfree(x->ealg); 77 kfree(x->ealg);
67 kfree(x->calg); 78 kfree(x->calg);
@@ -153,7 +164,7 @@ static void xfrm_timer_handler(unsigned long data)
153 164
154 x->km.dying = warn; 165 x->km.dying = warn;
155 if (warn) 166 if (warn)
156 km_state_expired(x, 0); 167 km_state_expired(x, 0, 0);
157resched: 168resched:
158 if (next != LONG_MAX && 169 if (next != LONG_MAX &&
159 !mod_timer(&x->timer, jiffies + make_jiffies(next))) 170 !mod_timer(&x->timer, jiffies + make_jiffies(next)))
@@ -168,13 +179,15 @@ expired:
168 goto resched; 179 goto resched;
169 } 180 }
170 if (!__xfrm_state_delete(x) && x->id.spi) 181 if (!__xfrm_state_delete(x) && x->id.spi)
171 km_state_expired(x, 1); 182 km_state_expired(x, 1, 0);
172 183
173out: 184out:
174 spin_unlock(&x->lock); 185 spin_unlock(&x->lock);
175 xfrm_state_put(x); 186 xfrm_state_put(x);
176} 187}
177 188
189static void xfrm_replay_timer_handler(unsigned long data);
190
178struct xfrm_state *xfrm_state_alloc(void) 191struct xfrm_state *xfrm_state_alloc(void)
179{ 192{
180 struct xfrm_state *x; 193 struct xfrm_state *x;
@@ -190,11 +203,16 @@ struct xfrm_state *xfrm_state_alloc(void)
190 init_timer(&x->timer); 203 init_timer(&x->timer);
191 x->timer.function = xfrm_timer_handler; 204 x->timer.function = xfrm_timer_handler;
192 x->timer.data = (unsigned long)x; 205 x->timer.data = (unsigned long)x;
206 init_timer(&x->rtimer);
207 x->rtimer.function = xfrm_replay_timer_handler;
208 x->rtimer.data = (unsigned long)x;
193 x->curlft.add_time = (unsigned long)xtime.tv_sec; 209 x->curlft.add_time = (unsigned long)xtime.tv_sec;
194 x->lft.soft_byte_limit = XFRM_INF; 210 x->lft.soft_byte_limit = XFRM_INF;
195 x->lft.soft_packet_limit = XFRM_INF; 211 x->lft.soft_packet_limit = XFRM_INF;
196 x->lft.hard_byte_limit = XFRM_INF; 212 x->lft.hard_byte_limit = XFRM_INF;
197 x->lft.hard_packet_limit = XFRM_INF; 213 x->lft.hard_packet_limit = XFRM_INF;
214 x->replay_maxage = 0;
215 x->replay_maxdiff = 0;
198 spin_lock_init(&x->lock); 216 spin_lock_init(&x->lock);
199 } 217 }
200 return x; 218 return x;
@@ -212,7 +230,7 @@ void __xfrm_state_destroy(struct xfrm_state *x)
212} 230}
213EXPORT_SYMBOL(__xfrm_state_destroy); 231EXPORT_SYMBOL(__xfrm_state_destroy);
214 232
215static int __xfrm_state_delete(struct xfrm_state *x) 233int __xfrm_state_delete(struct xfrm_state *x)
216{ 234{
217 int err = -ESRCH; 235 int err = -ESRCH;
218 236
@@ -228,6 +246,8 @@ static int __xfrm_state_delete(struct xfrm_state *x)
228 spin_unlock(&xfrm_state_lock); 246 spin_unlock(&xfrm_state_lock);
229 if (del_timer(&x->timer)) 247 if (del_timer(&x->timer))
230 __xfrm_state_put(x); 248 __xfrm_state_put(x);
249 if (del_timer(&x->rtimer))
250 __xfrm_state_put(x);
231 251
232 /* The number two in this test is the reference 252 /* The number two in this test is the reference
233 * mentioned in the comment below plus the reference 253 * mentioned in the comment below plus the reference
@@ -249,6 +269,7 @@ static int __xfrm_state_delete(struct xfrm_state *x)
249 269
250 return err; 270 return err;
251} 271}
272EXPORT_SYMBOL(__xfrm_state_delete);
252 273
253int xfrm_state_delete(struct xfrm_state *x) 274int xfrm_state_delete(struct xfrm_state *x)
254{ 275{
@@ -426,6 +447,10 @@ static void __xfrm_state_insert(struct xfrm_state *x)
426 if (!mod_timer(&x->timer, jiffies + HZ)) 447 if (!mod_timer(&x->timer, jiffies + HZ))
427 xfrm_state_hold(x); 448 xfrm_state_hold(x);
428 449
450 if (x->replay_maxage &&
451 !mod_timer(&x->rtimer, jiffies + x->replay_maxage))
452 xfrm_state_hold(x);
453
429 wake_up(&km_waitq); 454 wake_up(&km_waitq);
430} 455}
431 456
@@ -580,7 +605,7 @@ int xfrm_state_check_expire(struct xfrm_state *x)
580 (x->curlft.bytes >= x->lft.soft_byte_limit || 605 (x->curlft.bytes >= x->lft.soft_byte_limit ||
581 x->curlft.packets >= x->lft.soft_packet_limit)) { 606 x->curlft.packets >= x->lft.soft_packet_limit)) {
582 x->km.dying = 1; 607 x->km.dying = 1;
583 km_state_expired(x, 0); 608 km_state_expired(x, 0, 0);
584 } 609 }
585 return 0; 610 return 0;
586} 611}
@@ -762,6 +787,61 @@ out:
762} 787}
763EXPORT_SYMBOL(xfrm_state_walk); 788EXPORT_SYMBOL(xfrm_state_walk);
764 789
790
791void xfrm_replay_notify(struct xfrm_state *x, int event)
792{
793 struct km_event c;
794 /* we send notify messages in case
795 * 1. we updated on of the sequence numbers, and the seqno difference
796 * is at least x->replay_maxdiff, in this case we also update the
797 * timeout of our timer function
798 * 2. if x->replay_maxage has elapsed since last update,
799 * and there were changes
800 *
801 * The state structure must be locked!
802 */
803
804 switch (event) {
805 case XFRM_REPLAY_UPDATE:
806 if (x->replay_maxdiff &&
807 (x->replay.seq - x->preplay.seq < x->replay_maxdiff) &&
808 (x->replay.oseq - x->preplay.oseq < x->replay_maxdiff))
809 return;
810
811 break;
812
813 case XFRM_REPLAY_TIMEOUT:
814 if ((x->replay.seq == x->preplay.seq) &&
815 (x->replay.bitmap == x->preplay.bitmap) &&
816 (x->replay.oseq == x->preplay.oseq))
817 return;
818
819 break;
820 }
821
822 memcpy(&x->preplay, &x->replay, sizeof(struct xfrm_replay_state));
823 c.event = XFRM_MSG_NEWAE;
824 c.data.aevent = event;
825 km_state_notify(x, &c);
826
827 if (x->replay_maxage &&
828 !mod_timer(&x->rtimer, jiffies + x->replay_maxage))
829 xfrm_state_hold(x);
830}
831EXPORT_SYMBOL(xfrm_replay_notify);
832
833static void xfrm_replay_timer_handler(unsigned long data)
834{
835 struct xfrm_state *x = (struct xfrm_state*)data;
836
837 spin_lock(&x->lock);
838
839 if (xfrm_aevent_is_on() && x->km.state == XFRM_STATE_VALID)
840 xfrm_replay_notify(x, XFRM_REPLAY_TIMEOUT);
841
842 spin_unlock(&x->lock);
843}
844
765int xfrm_replay_check(struct xfrm_state *x, u32 seq) 845int xfrm_replay_check(struct xfrm_state *x, u32 seq)
766{ 846{
767 u32 diff; 847 u32 diff;
@@ -805,6 +885,9 @@ void xfrm_replay_advance(struct xfrm_state *x, u32 seq)
805 diff = x->replay.seq - seq; 885 diff = x->replay.seq - seq;
806 x->replay.bitmap |= (1U << diff); 886 x->replay.bitmap |= (1U << diff);
807 } 887 }
888
889 if (xfrm_aevent_is_on())
890 xfrm_replay_notify(x, XFRM_REPLAY_UPDATE);
808} 891}
809EXPORT_SYMBOL(xfrm_replay_advance); 892EXPORT_SYMBOL(xfrm_replay_advance);
810 893
@@ -835,11 +918,12 @@ void km_state_notify(struct xfrm_state *x, struct km_event *c)
835EXPORT_SYMBOL(km_policy_notify); 918EXPORT_SYMBOL(km_policy_notify);
836EXPORT_SYMBOL(km_state_notify); 919EXPORT_SYMBOL(km_state_notify);
837 920
838static void km_state_expired(struct xfrm_state *x, int hard) 921void km_state_expired(struct xfrm_state *x, int hard, u32 pid)
839{ 922{
840 struct km_event c; 923 struct km_event c;
841 924
842 c.data.hard = hard; 925 c.data.hard = hard;
926 c.pid = pid;
843 c.event = XFRM_MSG_EXPIRE; 927 c.event = XFRM_MSG_EXPIRE;
844 km_state_notify(x, &c); 928 km_state_notify(x, &c);
845 929
@@ -847,11 +931,12 @@ static void km_state_expired(struct xfrm_state *x, int hard)
847 wake_up(&km_waitq); 931 wake_up(&km_waitq);
848} 932}
849 933
934EXPORT_SYMBOL(km_state_expired);
850/* 935/*
851 * We send to all registered managers regardless of failure 936 * We send to all registered managers regardless of failure
852 * We are happy with one success 937 * We are happy with one success
853*/ 938*/
854static int km_query(struct xfrm_state *x, struct xfrm_tmpl *t, struct xfrm_policy *pol) 939int km_query(struct xfrm_state *x, struct xfrm_tmpl *t, struct xfrm_policy *pol)
855{ 940{
856 int err = -EINVAL, acqret; 941 int err = -EINVAL, acqret;
857 struct xfrm_mgr *km; 942 struct xfrm_mgr *km;
@@ -865,6 +950,7 @@ static int km_query(struct xfrm_state *x, struct xfrm_tmpl *t, struct xfrm_polic
865 read_unlock(&xfrm_km_lock); 950 read_unlock(&xfrm_km_lock);
866 return err; 951 return err;
867} 952}
953EXPORT_SYMBOL(km_query);
868 954
869int km_new_mapping(struct xfrm_state *x, xfrm_address_t *ipaddr, u16 sport) 955int km_new_mapping(struct xfrm_state *x, xfrm_address_t *ipaddr, u16 sport)
870{ 956{
@@ -883,17 +969,19 @@ int km_new_mapping(struct xfrm_state *x, xfrm_address_t *ipaddr, u16 sport)
883} 969}
884EXPORT_SYMBOL(km_new_mapping); 970EXPORT_SYMBOL(km_new_mapping);
885 971
886void km_policy_expired(struct xfrm_policy *pol, int dir, int hard) 972void km_policy_expired(struct xfrm_policy *pol, int dir, int hard, u32 pid)
887{ 973{
888 struct km_event c; 974 struct km_event c;
889 975
890 c.data.hard = hard; 976 c.data.hard = hard;
977 c.pid = pid;
891 c.event = XFRM_MSG_POLEXPIRE; 978 c.event = XFRM_MSG_POLEXPIRE;
892 km_policy_notify(pol, dir, &c); 979 km_policy_notify(pol, dir, &c);
893 980
894 if (hard) 981 if (hard)
895 wake_up(&km_waitq); 982 wake_up(&km_waitq);
896} 983}
984EXPORT_SYMBOL(km_policy_expired);
897 985
898int xfrm_user_policy(struct sock *sk, int optname, u8 __user *optval, int optlen) 986int xfrm_user_policy(struct sock *sk, int optname, u8 __user *optval, int optlen)
899{ 987{