aboutsummaryrefslogtreecommitdiffstats
path: root/net/xfrm
diff options
context:
space:
mode:
Diffstat (limited to 'net/xfrm')
-rw-r--r--net/xfrm/xfrm_policy.c9
-rw-r--r--net/xfrm/xfrm_state.c108
-rw-r--r--net/xfrm/xfrm_user.c397
3 files changed, 481 insertions, 33 deletions
diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c
index ae62054a9fc4..f5eae9febd26 100644
--- a/net/xfrm/xfrm_policy.c
+++ b/net/xfrm/xfrm_policy.c
@@ -26,8 +26,8 @@
26#include <net/xfrm.h> 26#include <net/xfrm.h>
27#include <net/ip.h> 27#include <net/ip.h>
28 28
29DECLARE_MUTEX(xfrm_cfg_sem); 29DEFINE_MUTEX(xfrm_cfg_mutex);
30EXPORT_SYMBOL(xfrm_cfg_sem); 30EXPORT_SYMBOL(xfrm_cfg_mutex);
31 31
32static DEFINE_RWLOCK(xfrm_policy_lock); 32static DEFINE_RWLOCK(xfrm_policy_lock);
33 33
@@ -203,7 +203,7 @@ static void xfrm_policy_timer(unsigned long data)
203 } 203 }
204 204
205 if (warn) 205 if (warn)
206 km_policy_expired(xp, dir, 0); 206 km_policy_expired(xp, dir, 0, 0);
207 if (next != LONG_MAX && 207 if (next != LONG_MAX &&
208 !mod_timer(&xp->timer, jiffies + make_jiffies(next))) 208 !mod_timer(&xp->timer, jiffies + make_jiffies(next)))
209 xfrm_pol_hold(xp); 209 xfrm_pol_hold(xp);
@@ -216,7 +216,7 @@ out:
216expired: 216expired:
217 read_unlock(&xp->lock); 217 read_unlock(&xp->lock);
218 if (!xfrm_policy_delete(xp, dir)) 218 if (!xfrm_policy_delete(xp, dir))
219 km_policy_expired(xp, dir, 1); 219 km_policy_expired(xp, dir, 1, 0);
220 xfrm_pol_put(xp); 220 xfrm_pol_put(xp);
221} 221}
222 222
@@ -621,6 +621,7 @@ int xfrm_policy_delete(struct xfrm_policy *pol, int dir)
621 } 621 }
622 return -ENOENT; 622 return -ENOENT;
623} 623}
624EXPORT_SYMBOL(xfrm_policy_delete);
624 625
625int xfrm_sk_policy_insert(struct sock *sk, int dir, struct xfrm_policy *pol) 626int xfrm_sk_policy_insert(struct sock *sk, int dir, struct xfrm_policy *pol)
626{ 627{
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{
diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c
index 7de17559249a..81d1005830f4 100644
--- a/net/xfrm/xfrm_user.c
+++ b/net/xfrm/xfrm_user.c
@@ -28,8 +28,6 @@
28#include <net/netlink.h> 28#include <net/netlink.h>
29#include <asm/uaccess.h> 29#include <asm/uaccess.h>
30 30
31static struct sock *xfrm_nl;
32
33static int verify_one_alg(struct rtattr **xfrma, enum xfrm_attr_type_t type) 31static int verify_one_alg(struct rtattr **xfrma, enum xfrm_attr_type_t type)
34{ 32{
35 struct rtattr *rt = xfrma[type - 1]; 33 struct rtattr *rt = xfrma[type - 1];
@@ -103,9 +101,6 @@ static inline int verify_sec_ctx_len(struct rtattr **xfrma)
103 101
104 uctx = RTA_DATA(rt); 102 uctx = RTA_DATA(rt);
105 103
106 if (uctx->ctx_len > PAGE_SIZE)
107 return -EINVAL;
108
109 len += sizeof(struct xfrm_user_sec_ctx); 104 len += sizeof(struct xfrm_user_sec_ctx);
110 len += uctx->ctx_len; 105 len += uctx->ctx_len;
111 106
@@ -276,6 +271,56 @@ static void copy_from_user_state(struct xfrm_state *x, struct xfrm_usersa_info *
276 x->props.flags = p->flags; 271 x->props.flags = p->flags;
277} 272}
278 273
274/*
275 * someday when pfkey also has support, we could have the code
276 * somehow made shareable and move it to xfrm_state.c - JHS
277 *
278*/
279static int xfrm_update_ae_params(struct xfrm_state *x, struct rtattr **xfrma)
280{
281 int err = - EINVAL;
282 struct rtattr *rp = xfrma[XFRMA_REPLAY_VAL-1];
283 struct rtattr *lt = xfrma[XFRMA_LTIME_VAL-1];
284 struct rtattr *et = xfrma[XFRMA_ETIMER_THRESH-1];
285 struct rtattr *rt = xfrma[XFRMA_REPLAY_THRESH-1];
286
287 if (rp) {
288 struct xfrm_replay_state *replay;
289 if (RTA_PAYLOAD(rp) < sizeof(*replay))
290 goto error;
291 replay = RTA_DATA(rp);
292 memcpy(&x->replay, replay, sizeof(*replay));
293 memcpy(&x->preplay, replay, sizeof(*replay));
294 }
295
296 if (lt) {
297 struct xfrm_lifetime_cur *ltime;
298 if (RTA_PAYLOAD(lt) < sizeof(*ltime))
299 goto error;
300 ltime = RTA_DATA(lt);
301 x->curlft.bytes = ltime->bytes;
302 x->curlft.packets = ltime->packets;
303 x->curlft.add_time = ltime->add_time;
304 x->curlft.use_time = ltime->use_time;
305 }
306
307 if (et) {
308 if (RTA_PAYLOAD(et) < sizeof(u32))
309 goto error;
310 x->replay_maxage = *(u32*)RTA_DATA(et);
311 }
312
313 if (rt) {
314 if (RTA_PAYLOAD(rt) < sizeof(u32))
315 goto error;
316 x->replay_maxdiff = *(u32*)RTA_DATA(rt);
317 }
318
319 return 0;
320error:
321 return err;
322}
323
279static struct xfrm_state *xfrm_state_construct(struct xfrm_usersa_info *p, 324static struct xfrm_state *xfrm_state_construct(struct xfrm_usersa_info *p,
280 struct rtattr **xfrma, 325 struct rtattr **xfrma,
281 int *errp) 326 int *errp)
@@ -311,6 +356,18 @@ static struct xfrm_state *xfrm_state_construct(struct xfrm_usersa_info *p,
311 goto error; 356 goto error;
312 357
313 x->km.seq = p->seq; 358 x->km.seq = p->seq;
359 x->replay_maxdiff = sysctl_xfrm_aevent_rseqth;
360 /* sysctl_xfrm_aevent_etime is in 100ms units */
361 x->replay_maxage = (sysctl_xfrm_aevent_etime*HZ)/XFRM_AE_ETH_M;
362 x->preplay.bitmap = 0;
363 x->preplay.seq = x->replay.seq+x->replay_maxdiff;
364 x->preplay.oseq = x->replay.oseq +x->replay_maxdiff;
365
366 /* override default values from above */
367
368 err = xfrm_update_ae_params(x, (struct rtattr **)xfrma);
369 if (err < 0)
370 goto error;
314 371
315 return x; 372 return x;
316 373
@@ -1025,9 +1082,142 @@ static int xfrm_flush_sa(struct sk_buff *skb, struct nlmsghdr *nlh, void **xfrma
1025 return 0; 1082 return 0;
1026} 1083}
1027 1084
1028static int xfrm_flush_policy(struct sk_buff *skb, struct nlmsghdr *nlh, void **xfrma) 1085
1086static int build_aevent(struct sk_buff *skb, struct xfrm_state *x, struct km_event *c)
1087{
1088 struct xfrm_aevent_id *id;
1089 struct nlmsghdr *nlh;
1090 struct xfrm_lifetime_cur ltime;
1091 unsigned char *b = skb->tail;
1092
1093 nlh = NLMSG_PUT(skb, c->pid, c->seq, XFRM_MSG_NEWAE, sizeof(*id));
1094 id = NLMSG_DATA(nlh);
1095 nlh->nlmsg_flags = 0;
1096
1097 id->sa_id.daddr = x->id.daddr;
1098 id->sa_id.spi = x->id.spi;
1099 id->sa_id.family = x->props.family;
1100 id->sa_id.proto = x->id.proto;
1101 id->flags = c->data.aevent;
1102
1103 RTA_PUT(skb, XFRMA_REPLAY_VAL, sizeof(x->replay), &x->replay);
1104
1105 ltime.bytes = x->curlft.bytes;
1106 ltime.packets = x->curlft.packets;
1107 ltime.add_time = x->curlft.add_time;
1108 ltime.use_time = x->curlft.use_time;
1109
1110 RTA_PUT(skb, XFRMA_LTIME_VAL, sizeof(struct xfrm_lifetime_cur), &ltime);
1111
1112 if (id->flags&XFRM_AE_RTHR) {
1113 RTA_PUT(skb,XFRMA_REPLAY_THRESH,sizeof(u32),&x->replay_maxdiff);
1114 }
1115
1116 if (id->flags&XFRM_AE_ETHR) {
1117 u32 etimer = x->replay_maxage*10/HZ;
1118 RTA_PUT(skb,XFRMA_ETIMER_THRESH,sizeof(u32),&etimer);
1119 }
1120
1121 nlh->nlmsg_len = skb->tail - b;
1122 return skb->len;
1123
1124rtattr_failure:
1125nlmsg_failure:
1126 skb_trim(skb, b - skb->data);
1127 return -1;
1128}
1129
1130static int xfrm_get_ae(struct sk_buff *skb, struct nlmsghdr *nlh, void **xfrma)
1131{
1132 struct xfrm_state *x;
1133 struct sk_buff *r_skb;
1134 int err;
1135 struct km_event c;
1136 struct xfrm_aevent_id *p = NLMSG_DATA(nlh);
1137 int len = NLMSG_LENGTH(sizeof(struct xfrm_aevent_id));
1138 struct xfrm_usersa_id *id = &p->sa_id;
1139
1140 len += RTA_SPACE(sizeof(struct xfrm_replay_state));
1141 len += RTA_SPACE(sizeof(struct xfrm_lifetime_cur));
1142
1143 if (p->flags&XFRM_AE_RTHR)
1144 len+=RTA_SPACE(sizeof(u32));
1145
1146 if (p->flags&XFRM_AE_ETHR)
1147 len+=RTA_SPACE(sizeof(u32));
1148
1149 r_skb = alloc_skb(len, GFP_ATOMIC);
1150 if (r_skb == NULL)
1151 return -ENOMEM;
1152
1153 x = xfrm_state_lookup(&id->daddr, id->spi, id->proto, id->family);
1154 if (x == NULL) {
1155 kfree(r_skb);
1156 return -ESRCH;
1157 }
1158
1159 /*
1160 * XXX: is this lock really needed - none of the other
1161 * gets lock (the concern is things getting updated
1162 * while we are still reading) - jhs
1163 */
1164 spin_lock_bh(&x->lock);
1165 c.data.aevent = p->flags;
1166 c.seq = nlh->nlmsg_seq;
1167 c.pid = nlh->nlmsg_pid;
1168
1169 if (build_aevent(r_skb, x, &c) < 0)
1170 BUG();
1171 err = netlink_unicast(xfrm_nl, r_skb,
1172 NETLINK_CB(skb).pid, MSG_DONTWAIT);
1173 spin_unlock_bh(&x->lock);
1174 xfrm_state_put(x);
1175 return err;
1176}
1177
1178static int xfrm_new_ae(struct sk_buff *skb, struct nlmsghdr *nlh, void **xfrma)
1029{ 1179{
1180 struct xfrm_state *x;
1030 struct km_event c; 1181 struct km_event c;
1182 int err = - EINVAL;
1183 struct xfrm_aevent_id *p = NLMSG_DATA(nlh);
1184 struct rtattr *rp = xfrma[XFRMA_REPLAY_VAL-1];
1185 struct rtattr *lt = xfrma[XFRMA_LTIME_VAL-1];
1186
1187 if (!lt && !rp)
1188 return err;
1189
1190 /* pedantic mode - thou shalt sayeth replaceth */
1191 if (!(nlh->nlmsg_flags&NLM_F_REPLACE))
1192 return err;
1193
1194 x = xfrm_state_lookup(&p->sa_id.daddr, p->sa_id.spi, p->sa_id.proto, p->sa_id.family);
1195 if (x == NULL)
1196 return -ESRCH;
1197
1198 if (x->km.state != XFRM_STATE_VALID)
1199 goto out;
1200
1201 spin_lock_bh(&x->lock);
1202 err = xfrm_update_ae_params(x,(struct rtattr **)xfrma);
1203 spin_unlock_bh(&x->lock);
1204 if (err < 0)
1205 goto out;
1206
1207 c.event = nlh->nlmsg_type;
1208 c.seq = nlh->nlmsg_seq;
1209 c.pid = nlh->nlmsg_pid;
1210 c.data.aevent = XFRM_AE_CU;
1211 km_state_notify(x, &c);
1212 err = 0;
1213out:
1214 xfrm_state_put(x);
1215 return err;
1216}
1217
1218static int xfrm_flush_policy(struct sk_buff *skb, struct nlmsghdr *nlh, void **xfrma)
1219{
1220struct km_event c;
1031 1221
1032 xfrm_policy_flush(); 1222 xfrm_policy_flush();
1033 c.event = nlh->nlmsg_type; 1223 c.event = nlh->nlmsg_type;
@@ -1037,6 +1227,139 @@ static int xfrm_flush_policy(struct sk_buff *skb, struct nlmsghdr *nlh, void **x
1037 return 0; 1227 return 0;
1038} 1228}
1039 1229
1230static int xfrm_add_pol_expire(struct sk_buff *skb, struct nlmsghdr *nlh, void **xfrma)
1231{
1232 struct xfrm_policy *xp;
1233 struct xfrm_user_polexpire *up = NLMSG_DATA(nlh);
1234 struct xfrm_userpolicy_info *p = &up->pol;
1235 int err = -ENOENT;
1236
1237 if (p->index)
1238 xp = xfrm_policy_byid(p->dir, p->index, 0);
1239 else {
1240 struct rtattr **rtattrs = (struct rtattr **)xfrma;
1241 struct rtattr *rt = rtattrs[XFRMA_SEC_CTX-1];
1242 struct xfrm_policy tmp;
1243
1244 err = verify_sec_ctx_len(rtattrs);
1245 if (err)
1246 return err;
1247
1248 memset(&tmp, 0, sizeof(struct xfrm_policy));
1249 if (rt) {
1250 struct xfrm_user_sec_ctx *uctx = RTA_DATA(rt);
1251
1252 if ((err = security_xfrm_policy_alloc(&tmp, uctx)))
1253 return err;
1254 }
1255 xp = xfrm_policy_bysel_ctx(p->dir, &p->sel, tmp.security, 0);
1256 security_xfrm_policy_free(&tmp);
1257 }
1258
1259 if (xp == NULL)
1260 return err;
1261 read_lock(&xp->lock);
1262 if (xp->dead) {
1263 read_unlock(&xp->lock);
1264 goto out;
1265 }
1266
1267 read_unlock(&xp->lock);
1268 err = 0;
1269 if (up->hard) {
1270 xfrm_policy_delete(xp, p->dir);
1271 } else {
1272 // reset the timers here?
1273 printk("Dont know what to do with soft policy expire\n");
1274 }
1275 km_policy_expired(xp, p->dir, up->hard, current->pid);
1276
1277out:
1278 xfrm_pol_put(xp);
1279 return err;
1280}
1281
1282static int xfrm_add_sa_expire(struct sk_buff *skb, struct nlmsghdr *nlh, void **xfrma)
1283{
1284 struct xfrm_state *x;
1285 int err;
1286 struct xfrm_user_expire *ue = NLMSG_DATA(nlh);
1287 struct xfrm_usersa_info *p = &ue->state;
1288
1289 x = xfrm_state_lookup(&p->id.daddr, p->id.spi, p->id.proto, p->family);
1290 err = -ENOENT;
1291
1292 if (x == NULL)
1293 return err;
1294
1295 err = -EINVAL;
1296
1297 spin_lock_bh(&x->lock);
1298 if (x->km.state != XFRM_STATE_VALID)
1299 goto out;
1300 km_state_expired(x, ue->hard, current->pid);
1301
1302 if (ue->hard)
1303 __xfrm_state_delete(x);
1304out:
1305 spin_unlock_bh(&x->lock);
1306 xfrm_state_put(x);
1307 return err;
1308}
1309
1310static int xfrm_add_acquire(struct sk_buff *skb, struct nlmsghdr *nlh, void **xfrma)
1311{
1312 struct xfrm_policy *xp;
1313 struct xfrm_user_tmpl *ut;
1314 int i;
1315 struct rtattr *rt = xfrma[XFRMA_TMPL-1];
1316
1317 struct xfrm_user_acquire *ua = NLMSG_DATA(nlh);
1318 struct xfrm_state *x = xfrm_state_alloc();
1319 int err = -ENOMEM;
1320
1321 if (!x)
1322 return err;
1323
1324 err = verify_newpolicy_info(&ua->policy);
1325 if (err) {
1326 printk("BAD policy passed\n");
1327 kfree(x);
1328 return err;
1329 }
1330
1331 /* build an XP */
1332 xp = xfrm_policy_construct(&ua->policy, (struct rtattr **) xfrma, &err); if (!xp) {
1333 kfree(x);
1334 return err;
1335 }
1336
1337 memcpy(&x->id, &ua->id, sizeof(ua->id));
1338 memcpy(&x->props.saddr, &ua->saddr, sizeof(ua->saddr));
1339 memcpy(&x->sel, &ua->sel, sizeof(ua->sel));
1340
1341 ut = RTA_DATA(rt);
1342 /* extract the templates and for each call km_key */
1343 for (i = 0; i < xp->xfrm_nr; i++, ut++) {
1344 struct xfrm_tmpl *t = &xp->xfrm_vec[i];
1345 memcpy(&x->id, &t->id, sizeof(x->id));
1346 x->props.mode = t->mode;
1347 x->props.reqid = t->reqid;
1348 x->props.family = ut->family;
1349 t->aalgos = ua->aalgos;
1350 t->ealgos = ua->ealgos;
1351 t->calgos = ua->calgos;
1352 err = km_query(x, t, xp);
1353
1354 }
1355
1356 kfree(x);
1357 kfree(xp);
1358
1359 return 0;
1360}
1361
1362
1040#define XMSGSIZE(type) NLMSG_LENGTH(sizeof(struct type)) 1363#define XMSGSIZE(type) NLMSG_LENGTH(sizeof(struct type))
1041 1364
1042static const int xfrm_msg_min[XFRM_NR_MSGTYPES] = { 1365static const int xfrm_msg_min[XFRM_NR_MSGTYPES] = {
@@ -1054,6 +1377,8 @@ static const int xfrm_msg_min[XFRM_NR_MSGTYPES] = {
1054 [XFRM_MSG_POLEXPIRE - XFRM_MSG_BASE] = XMSGSIZE(xfrm_user_polexpire), 1377 [XFRM_MSG_POLEXPIRE - XFRM_MSG_BASE] = XMSGSIZE(xfrm_user_polexpire),
1055 [XFRM_MSG_FLUSHSA - XFRM_MSG_BASE] = XMSGSIZE(xfrm_usersa_flush), 1378 [XFRM_MSG_FLUSHSA - XFRM_MSG_BASE] = XMSGSIZE(xfrm_usersa_flush),
1056 [XFRM_MSG_FLUSHPOLICY - XFRM_MSG_BASE] = NLMSG_LENGTH(0), 1379 [XFRM_MSG_FLUSHPOLICY - XFRM_MSG_BASE] = NLMSG_LENGTH(0),
1380 [XFRM_MSG_NEWAE - XFRM_MSG_BASE] = XMSGSIZE(xfrm_aevent_id),
1381 [XFRM_MSG_GETAE - XFRM_MSG_BASE] = XMSGSIZE(xfrm_aevent_id),
1057}; 1382};
1058 1383
1059#undef XMSGSIZE 1384#undef XMSGSIZE
@@ -1071,10 +1396,15 @@ static struct xfrm_link {
1071 [XFRM_MSG_GETPOLICY - XFRM_MSG_BASE] = { .doit = xfrm_get_policy, 1396 [XFRM_MSG_GETPOLICY - XFRM_MSG_BASE] = { .doit = xfrm_get_policy,
1072 .dump = xfrm_dump_policy }, 1397 .dump = xfrm_dump_policy },
1073 [XFRM_MSG_ALLOCSPI - XFRM_MSG_BASE] = { .doit = xfrm_alloc_userspi }, 1398 [XFRM_MSG_ALLOCSPI - XFRM_MSG_BASE] = { .doit = xfrm_alloc_userspi },
1399 [XFRM_MSG_ACQUIRE - XFRM_MSG_BASE] = { .doit = xfrm_add_acquire },
1400 [XFRM_MSG_EXPIRE - XFRM_MSG_BASE] = { .doit = xfrm_add_sa_expire },
1074 [XFRM_MSG_UPDPOLICY - XFRM_MSG_BASE] = { .doit = xfrm_add_policy }, 1401 [XFRM_MSG_UPDPOLICY - XFRM_MSG_BASE] = { .doit = xfrm_add_policy },
1075 [XFRM_MSG_UPDSA - XFRM_MSG_BASE] = { .doit = xfrm_add_sa }, 1402 [XFRM_MSG_UPDSA - XFRM_MSG_BASE] = { .doit = xfrm_add_sa },
1403 [XFRM_MSG_POLEXPIRE - XFRM_MSG_BASE] = { .doit = xfrm_add_pol_expire},
1076 [XFRM_MSG_FLUSHSA - XFRM_MSG_BASE] = { .doit = xfrm_flush_sa }, 1404 [XFRM_MSG_FLUSHSA - XFRM_MSG_BASE] = { .doit = xfrm_flush_sa },
1077 [XFRM_MSG_FLUSHPOLICY - XFRM_MSG_BASE] = { .doit = xfrm_flush_policy }, 1405 [XFRM_MSG_FLUSHPOLICY - XFRM_MSG_BASE] = { .doit = xfrm_flush_policy },
1406 [XFRM_MSG_NEWAE - XFRM_MSG_BASE] = { .doit = xfrm_new_ae },
1407 [XFRM_MSG_GETAE - XFRM_MSG_BASE] = { .doit = xfrm_get_ae },
1078}; 1408};
1079 1409
1080static int xfrm_user_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh, int *errp) 1410static int xfrm_user_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh, int *errp)
@@ -1156,26 +1486,26 @@ static void xfrm_netlink_rcv(struct sock *sk, int len)
1156 unsigned int qlen = 0; 1486 unsigned int qlen = 0;
1157 1487
1158 do { 1488 do {
1159 down(&xfrm_cfg_sem); 1489 mutex_lock(&xfrm_cfg_mutex);
1160 netlink_run_queue(sk, &qlen, &xfrm_user_rcv_msg); 1490 netlink_run_queue(sk, &qlen, &xfrm_user_rcv_msg);
1161 up(&xfrm_cfg_sem); 1491 mutex_unlock(&xfrm_cfg_mutex);
1162 1492
1163 } while (qlen); 1493 } while (qlen);
1164} 1494}
1165 1495
1166static int build_expire(struct sk_buff *skb, struct xfrm_state *x, int hard) 1496static int build_expire(struct sk_buff *skb, struct xfrm_state *x, struct km_event *c)
1167{ 1497{
1168 struct xfrm_user_expire *ue; 1498 struct xfrm_user_expire *ue;
1169 struct nlmsghdr *nlh; 1499 struct nlmsghdr *nlh;
1170 unsigned char *b = skb->tail; 1500 unsigned char *b = skb->tail;
1171 1501
1172 nlh = NLMSG_PUT(skb, 0, 0, XFRM_MSG_EXPIRE, 1502 nlh = NLMSG_PUT(skb, c->pid, 0, XFRM_MSG_EXPIRE,
1173 sizeof(*ue)); 1503 sizeof(*ue));
1174 ue = NLMSG_DATA(nlh); 1504 ue = NLMSG_DATA(nlh);
1175 nlh->nlmsg_flags = 0; 1505 nlh->nlmsg_flags = 0;
1176 1506
1177 copy_to_user_state(x, &ue->state); 1507 copy_to_user_state(x, &ue->state);
1178 ue->hard = (hard != 0) ? 1 : 0; 1508 ue->hard = (c->data.hard != 0) ? 1 : 0;
1179 1509
1180 nlh->nlmsg_len = skb->tail - b; 1510 nlh->nlmsg_len = skb->tail - b;
1181 return skb->len; 1511 return skb->len;
@@ -1194,13 +1524,31 @@ static int xfrm_exp_state_notify(struct xfrm_state *x, struct km_event *c)
1194 if (skb == NULL) 1524 if (skb == NULL)
1195 return -ENOMEM; 1525 return -ENOMEM;
1196 1526
1197 if (build_expire(skb, x, c->data.hard) < 0) 1527 if (build_expire(skb, x, c) < 0)
1198 BUG(); 1528 BUG();
1199 1529
1200 NETLINK_CB(skb).dst_group = XFRMNLGRP_EXPIRE; 1530 NETLINK_CB(skb).dst_group = XFRMNLGRP_EXPIRE;
1201 return netlink_broadcast(xfrm_nl, skb, 0, XFRMNLGRP_EXPIRE, GFP_ATOMIC); 1531 return netlink_broadcast(xfrm_nl, skb, 0, XFRMNLGRP_EXPIRE, GFP_ATOMIC);
1202} 1532}
1203 1533
1534static int xfrm_aevent_state_notify(struct xfrm_state *x, struct km_event *c)
1535{
1536 struct sk_buff *skb;
1537 int len = NLMSG_LENGTH(sizeof(struct xfrm_aevent_id));
1538
1539 len += RTA_SPACE(sizeof(struct xfrm_replay_state));
1540 len += RTA_SPACE(sizeof(struct xfrm_lifetime_cur));
1541 skb = alloc_skb(len, GFP_ATOMIC);
1542 if (skb == NULL)
1543 return -ENOMEM;
1544
1545 if (build_aevent(skb, x, c) < 0)
1546 BUG();
1547
1548 NETLINK_CB(skb).dst_group = XFRMNLGRP_AEVENTS;
1549 return netlink_broadcast(xfrm_nl, skb, 0, XFRMNLGRP_AEVENTS, GFP_ATOMIC);
1550}
1551
1204static int xfrm_notify_sa_flush(struct km_event *c) 1552static int xfrm_notify_sa_flush(struct km_event *c)
1205{ 1553{
1206 struct xfrm_usersa_flush *p; 1554 struct xfrm_usersa_flush *p;
@@ -1313,6 +1661,8 @@ static int xfrm_send_state_notify(struct xfrm_state *x, struct km_event *c)
1313 switch (c->event) { 1661 switch (c->event) {
1314 case XFRM_MSG_EXPIRE: 1662 case XFRM_MSG_EXPIRE:
1315 return xfrm_exp_state_notify(x, c); 1663 return xfrm_exp_state_notify(x, c);
1664 case XFRM_MSG_NEWAE:
1665 return xfrm_aevent_state_notify(x, c);
1316 case XFRM_MSG_DELSA: 1666 case XFRM_MSG_DELSA:
1317 case XFRM_MSG_UPDSA: 1667 case XFRM_MSG_UPDSA:
1318 case XFRM_MSG_NEWSA: 1668 case XFRM_MSG_NEWSA:
@@ -1443,13 +1793,14 @@ static struct xfrm_policy *xfrm_compile_policy(u16 family, int opt,
1443} 1793}
1444 1794
1445static int build_polexpire(struct sk_buff *skb, struct xfrm_policy *xp, 1795static int build_polexpire(struct sk_buff *skb, struct xfrm_policy *xp,
1446 int dir, int hard) 1796 int dir, struct km_event *c)
1447{ 1797{
1448 struct xfrm_user_polexpire *upe; 1798 struct xfrm_user_polexpire *upe;
1449 struct nlmsghdr *nlh; 1799 struct nlmsghdr *nlh;
1800 int hard = c->data.hard;
1450 unsigned char *b = skb->tail; 1801 unsigned char *b = skb->tail;
1451 1802
1452 nlh = NLMSG_PUT(skb, 0, 0, XFRM_MSG_POLEXPIRE, sizeof(*upe)); 1803 nlh = NLMSG_PUT(skb, c->pid, 0, XFRM_MSG_POLEXPIRE, sizeof(*upe));
1453 upe = NLMSG_DATA(nlh); 1804 upe = NLMSG_DATA(nlh);
1454 nlh->nlmsg_flags = 0; 1805 nlh->nlmsg_flags = 0;
1455 1806
@@ -1480,7 +1831,7 @@ static int xfrm_exp_policy_notify(struct xfrm_policy *xp, int dir, struct km_eve
1480 if (skb == NULL) 1831 if (skb == NULL)
1481 return -ENOMEM; 1832 return -ENOMEM;
1482 1833
1483 if (build_polexpire(skb, xp, dir, c->data.hard) < 0) 1834 if (build_polexpire(skb, xp, dir, c) < 0)
1484 BUG(); 1835 BUG();
1485 1836
1486 NETLINK_CB(skb).dst_group = XFRMNLGRP_EXPIRE; 1837 NETLINK_CB(skb).dst_group = XFRMNLGRP_EXPIRE;
@@ -1596,12 +1947,15 @@ static struct xfrm_mgr netlink_mgr = {
1596 1947
1597static int __init xfrm_user_init(void) 1948static int __init xfrm_user_init(void)
1598{ 1949{
1950 struct sock *nlsk;
1951
1599 printk(KERN_INFO "Initializing IPsec netlink socket\n"); 1952 printk(KERN_INFO "Initializing IPsec netlink socket\n");
1600 1953
1601 xfrm_nl = netlink_kernel_create(NETLINK_XFRM, XFRMNLGRP_MAX, 1954 nlsk = netlink_kernel_create(NETLINK_XFRM, XFRMNLGRP_MAX,
1602 xfrm_netlink_rcv, THIS_MODULE); 1955 xfrm_netlink_rcv, THIS_MODULE);
1603 if (xfrm_nl == NULL) 1956 if (nlsk == NULL)
1604 return -ENOMEM; 1957 return -ENOMEM;
1958 rcu_assign_pointer(xfrm_nl, nlsk);
1605 1959
1606 xfrm_register_km(&netlink_mgr); 1960 xfrm_register_km(&netlink_mgr);
1607 1961
@@ -1610,11 +1964,16 @@ static int __init xfrm_user_init(void)
1610 1964
1611static void __exit xfrm_user_exit(void) 1965static void __exit xfrm_user_exit(void)
1612{ 1966{
1967 struct sock *nlsk = xfrm_nl;
1968
1613 xfrm_unregister_km(&netlink_mgr); 1969 xfrm_unregister_km(&netlink_mgr);
1614 sock_release(xfrm_nl->sk_socket); 1970 rcu_assign_pointer(xfrm_nl, NULL);
1971 synchronize_rcu();
1972 sock_release(nlsk->sk_socket);
1615} 1973}
1616 1974
1617module_init(xfrm_user_init); 1975module_init(xfrm_user_init);
1618module_exit(xfrm_user_exit); 1976module_exit(xfrm_user_exit);
1619MODULE_LICENSE("GPL"); 1977MODULE_LICENSE("GPL");
1620MODULE_ALIAS_NET_PF_PROTO(PF_NETLINK, NETLINK_XFRM); 1978MODULE_ALIAS_NET_PF_PROTO(PF_NETLINK, NETLINK_XFRM);
1979