diff options
author | Jaroslav Kysela <perex@hera.kernel.org> | 2005-06-21 10:39:41 -0400 |
---|---|---|
committer | Jaroslav Kysela <perex@hera.kernel.org> | 2005-06-21 10:39:41 -0400 |
commit | fae6ec69c84d71b1d5bda9ede1a262c1681684aa (patch) | |
tree | eb4aff9a5c2b7d04ce09a3717bb1dd4a79fe7595 /net/xfrm/xfrm_user.c | |
parent | bbc0274e9bb2e3f1d724d445a2bd32566b9b66f7 (diff) | |
parent | 1d345dac1f30af1cd9f3a1faa12f9f18f17f236e (diff) |
Merge with /pub/scm/linux/kernel/git/torvalds/linux-2.6.git
Diffstat (limited to 'net/xfrm/xfrm_user.c')
-rw-r--r-- | net/xfrm/xfrm_user.c | 297 |
1 files changed, 282 insertions, 15 deletions
diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c index 97509011c274..ecade4893a13 100644 --- a/net/xfrm/xfrm_user.c +++ b/net/xfrm/xfrm_user.c | |||
@@ -249,17 +249,10 @@ static struct xfrm_state *xfrm_state_construct(struct xfrm_usersa_info *p, | |||
249 | if ((err = attach_encap_tmpl(&x->encap, xfrma[XFRMA_ENCAP-1]))) | 249 | if ((err = attach_encap_tmpl(&x->encap, xfrma[XFRMA_ENCAP-1]))) |
250 | goto error; | 250 | goto error; |
251 | 251 | ||
252 | err = -ENOENT; | 252 | err = xfrm_init_state(x); |
253 | x->type = xfrm_get_type(x->id.proto, x->props.family); | ||
254 | if (x->type == NULL) | ||
255 | goto error; | ||
256 | |||
257 | err = x->type->init_state(x, NULL); | ||
258 | if (err) | 253 | if (err) |
259 | goto error; | 254 | goto error; |
260 | 255 | ||
261 | x->curlft.add_time = (unsigned long) xtime.tv_sec; | ||
262 | x->km.state = XFRM_STATE_VALID; | ||
263 | x->km.seq = p->seq; | 256 | x->km.seq = p->seq; |
264 | 257 | ||
265 | return x; | 258 | return x; |
@@ -277,6 +270,7 @@ static int xfrm_add_sa(struct sk_buff *skb, struct nlmsghdr *nlh, void **xfrma) | |||
277 | struct xfrm_usersa_info *p = NLMSG_DATA(nlh); | 270 | struct xfrm_usersa_info *p = NLMSG_DATA(nlh); |
278 | struct xfrm_state *x; | 271 | struct xfrm_state *x; |
279 | int err; | 272 | int err; |
273 | struct km_event c; | ||
280 | 274 | ||
281 | err = verify_newsa_info(p, (struct rtattr **) xfrma); | 275 | err = verify_newsa_info(p, (struct rtattr **) xfrma); |
282 | if (err) | 276 | if (err) |
@@ -286,6 +280,7 @@ static int xfrm_add_sa(struct sk_buff *skb, struct nlmsghdr *nlh, void **xfrma) | |||
286 | if (!x) | 280 | if (!x) |
287 | return err; | 281 | return err; |
288 | 282 | ||
283 | xfrm_state_hold(x); | ||
289 | if (nlh->nlmsg_type == XFRM_MSG_NEWSA) | 284 | if (nlh->nlmsg_type == XFRM_MSG_NEWSA) |
290 | err = xfrm_state_add(x); | 285 | err = xfrm_state_add(x); |
291 | else | 286 | else |
@@ -294,14 +289,24 @@ static int xfrm_add_sa(struct sk_buff *skb, struct nlmsghdr *nlh, void **xfrma) | |||
294 | if (err < 0) { | 289 | if (err < 0) { |
295 | x->km.state = XFRM_STATE_DEAD; | 290 | x->km.state = XFRM_STATE_DEAD; |
296 | xfrm_state_put(x); | 291 | xfrm_state_put(x); |
292 | goto out; | ||
297 | } | 293 | } |
298 | 294 | ||
295 | c.seq = nlh->nlmsg_seq; | ||
296 | c.pid = nlh->nlmsg_pid; | ||
297 | c.event = nlh->nlmsg_type; | ||
298 | |||
299 | km_state_notify(x, &c); | ||
300 | out: | ||
301 | xfrm_state_put(x); | ||
299 | return err; | 302 | return err; |
300 | } | 303 | } |
301 | 304 | ||
302 | static int xfrm_del_sa(struct sk_buff *skb, struct nlmsghdr *nlh, void **xfrma) | 305 | static int xfrm_del_sa(struct sk_buff *skb, struct nlmsghdr *nlh, void **xfrma) |
303 | { | 306 | { |
304 | struct xfrm_state *x; | 307 | struct xfrm_state *x; |
308 | int err; | ||
309 | struct km_event c; | ||
305 | struct xfrm_usersa_id *p = NLMSG_DATA(nlh); | 310 | struct xfrm_usersa_id *p = NLMSG_DATA(nlh); |
306 | 311 | ||
307 | x = xfrm_state_lookup(&p->daddr, p->spi, p->proto, p->family); | 312 | x = xfrm_state_lookup(&p->daddr, p->spi, p->proto, p->family); |
@@ -313,10 +318,19 @@ static int xfrm_del_sa(struct sk_buff *skb, struct nlmsghdr *nlh, void **xfrma) | |||
313 | return -EPERM; | 318 | return -EPERM; |
314 | } | 319 | } |
315 | 320 | ||
316 | xfrm_state_delete(x); | 321 | err = xfrm_state_delete(x); |
322 | if (err < 0) { | ||
323 | xfrm_state_put(x); | ||
324 | return err; | ||
325 | } | ||
326 | |||
327 | c.seq = nlh->nlmsg_seq; | ||
328 | c.pid = nlh->nlmsg_pid; | ||
329 | c.event = nlh->nlmsg_type; | ||
330 | km_state_notify(x, &c); | ||
317 | xfrm_state_put(x); | 331 | xfrm_state_put(x); |
318 | 332 | ||
319 | return 0; | 333 | return err; |
320 | } | 334 | } |
321 | 335 | ||
322 | static void copy_to_user_state(struct xfrm_state *x, struct xfrm_usersa_info *p) | 336 | static void copy_to_user_state(struct xfrm_state *x, struct xfrm_usersa_info *p) |
@@ -681,6 +695,7 @@ static int xfrm_add_policy(struct sk_buff *skb, struct nlmsghdr *nlh, void **xfr | |||
681 | { | 695 | { |
682 | struct xfrm_userpolicy_info *p = NLMSG_DATA(nlh); | 696 | struct xfrm_userpolicy_info *p = NLMSG_DATA(nlh); |
683 | struct xfrm_policy *xp; | 697 | struct xfrm_policy *xp; |
698 | struct km_event c; | ||
684 | int err; | 699 | int err; |
685 | int excl; | 700 | int excl; |
686 | 701 | ||
@@ -692,6 +707,10 @@ static int xfrm_add_policy(struct sk_buff *skb, struct nlmsghdr *nlh, void **xfr | |||
692 | if (!xp) | 707 | if (!xp) |
693 | return err; | 708 | return err; |
694 | 709 | ||
710 | /* shouldnt excl be based on nlh flags?? | ||
711 | * Aha! this is anti-netlink really i.e more pfkey derived | ||
712 | * in netlink excl is a flag and you wouldnt need | ||
713 | * a type XFRM_MSG_UPDPOLICY - JHS */ | ||
695 | excl = nlh->nlmsg_type == XFRM_MSG_NEWPOLICY; | 714 | excl = nlh->nlmsg_type == XFRM_MSG_NEWPOLICY; |
696 | err = xfrm_policy_insert(p->dir, xp, excl); | 715 | err = xfrm_policy_insert(p->dir, xp, excl); |
697 | if (err) { | 716 | if (err) { |
@@ -699,6 +718,11 @@ static int xfrm_add_policy(struct sk_buff *skb, struct nlmsghdr *nlh, void **xfr | |||
699 | return err; | 718 | return err; |
700 | } | 719 | } |
701 | 720 | ||
721 | c.event = nlh->nlmsg_type; | ||
722 | c.seq = nlh->nlmsg_seq; | ||
723 | c.pid = nlh->nlmsg_pid; | ||
724 | km_policy_notify(xp, p->dir, &c); | ||
725 | |||
702 | xfrm_pol_put(xp); | 726 | xfrm_pol_put(xp); |
703 | 727 | ||
704 | return 0; | 728 | return 0; |
@@ -816,6 +840,7 @@ static int xfrm_get_policy(struct sk_buff *skb, struct nlmsghdr *nlh, void **xfr | |||
816 | struct xfrm_policy *xp; | 840 | struct xfrm_policy *xp; |
817 | struct xfrm_userpolicy_id *p; | 841 | struct xfrm_userpolicy_id *p; |
818 | int err; | 842 | int err; |
843 | struct km_event c; | ||
819 | int delete; | 844 | int delete; |
820 | 845 | ||
821 | p = NLMSG_DATA(nlh); | 846 | p = NLMSG_DATA(nlh); |
@@ -843,6 +868,12 @@ static int xfrm_get_policy(struct sk_buff *skb, struct nlmsghdr *nlh, void **xfr | |||
843 | NETLINK_CB(skb).pid, | 868 | NETLINK_CB(skb).pid, |
844 | MSG_DONTWAIT); | 869 | MSG_DONTWAIT); |
845 | } | 870 | } |
871 | } else { | ||
872 | c.data.byid = p->index; | ||
873 | c.event = nlh->nlmsg_type; | ||
874 | c.seq = nlh->nlmsg_seq; | ||
875 | c.pid = nlh->nlmsg_pid; | ||
876 | km_policy_notify(xp, p->dir, &c); | ||
846 | } | 877 | } |
847 | 878 | ||
848 | xfrm_pol_put(xp); | 879 | xfrm_pol_put(xp); |
@@ -852,15 +883,28 @@ static int xfrm_get_policy(struct sk_buff *skb, struct nlmsghdr *nlh, void **xfr | |||
852 | 883 | ||
853 | static int xfrm_flush_sa(struct sk_buff *skb, struct nlmsghdr *nlh, void **xfrma) | 884 | static int xfrm_flush_sa(struct sk_buff *skb, struct nlmsghdr *nlh, void **xfrma) |
854 | { | 885 | { |
886 | struct km_event c; | ||
855 | struct xfrm_usersa_flush *p = NLMSG_DATA(nlh); | 887 | struct xfrm_usersa_flush *p = NLMSG_DATA(nlh); |
856 | 888 | ||
857 | xfrm_state_flush(p->proto); | 889 | xfrm_state_flush(p->proto); |
890 | c.data.proto = p->proto; | ||
891 | c.event = nlh->nlmsg_type; | ||
892 | c.seq = nlh->nlmsg_seq; | ||
893 | c.pid = nlh->nlmsg_pid; | ||
894 | km_state_notify(NULL, &c); | ||
895 | |||
858 | return 0; | 896 | return 0; |
859 | } | 897 | } |
860 | 898 | ||
861 | static int xfrm_flush_policy(struct sk_buff *skb, struct nlmsghdr *nlh, void **xfrma) | 899 | static int xfrm_flush_policy(struct sk_buff *skb, struct nlmsghdr *nlh, void **xfrma) |
862 | { | 900 | { |
901 | struct km_event c; | ||
902 | |||
863 | xfrm_policy_flush(); | 903 | xfrm_policy_flush(); |
904 | c.event = nlh->nlmsg_type; | ||
905 | c.seq = nlh->nlmsg_seq; | ||
906 | c.pid = nlh->nlmsg_pid; | ||
907 | km_policy_notify(NULL, 0, &c); | ||
864 | return 0; | 908 | return 0; |
865 | } | 909 | } |
866 | 910 | ||
@@ -1069,15 +1113,16 @@ nlmsg_failure: | |||
1069 | return -1; | 1113 | return -1; |
1070 | } | 1114 | } |
1071 | 1115 | ||
1072 | static int xfrm_send_state_notify(struct xfrm_state *x, int hard) | 1116 | static int xfrm_exp_state_notify(struct xfrm_state *x, struct km_event *c) |
1073 | { | 1117 | { |
1074 | struct sk_buff *skb; | 1118 | struct sk_buff *skb; |
1119 | int len = NLMSG_LENGTH(sizeof(struct xfrm_user_expire)); | ||
1075 | 1120 | ||
1076 | skb = alloc_skb(sizeof(struct xfrm_user_expire) + 16, GFP_ATOMIC); | 1121 | skb = alloc_skb(len, GFP_ATOMIC); |
1077 | if (skb == NULL) | 1122 | if (skb == NULL) |
1078 | return -ENOMEM; | 1123 | return -ENOMEM; |
1079 | 1124 | ||
1080 | if (build_expire(skb, x, hard) < 0) | 1125 | if (build_expire(skb, x, c->data.hard) < 0) |
1081 | BUG(); | 1126 | BUG(); |
1082 | 1127 | ||
1083 | NETLINK_CB(skb).dst_groups = XFRMGRP_EXPIRE; | 1128 | NETLINK_CB(skb).dst_groups = XFRMGRP_EXPIRE; |
@@ -1085,6 +1130,131 @@ static int xfrm_send_state_notify(struct xfrm_state *x, int hard) | |||
1085 | return netlink_broadcast(xfrm_nl, skb, 0, XFRMGRP_EXPIRE, GFP_ATOMIC); | 1130 | return netlink_broadcast(xfrm_nl, skb, 0, XFRMGRP_EXPIRE, GFP_ATOMIC); |
1086 | } | 1131 | } |
1087 | 1132 | ||
1133 | static int xfrm_notify_sa_flush(struct km_event *c) | ||
1134 | { | ||
1135 | struct xfrm_usersa_flush *p; | ||
1136 | struct nlmsghdr *nlh; | ||
1137 | struct sk_buff *skb; | ||
1138 | unsigned char *b; | ||
1139 | int len = NLMSG_LENGTH(sizeof(struct xfrm_usersa_flush)); | ||
1140 | |||
1141 | skb = alloc_skb(len, GFP_ATOMIC); | ||
1142 | if (skb == NULL) | ||
1143 | return -ENOMEM; | ||
1144 | b = skb->tail; | ||
1145 | |||
1146 | nlh = NLMSG_PUT(skb, c->pid, c->seq, | ||
1147 | XFRM_MSG_FLUSHSA, sizeof(*p)); | ||
1148 | nlh->nlmsg_flags = 0; | ||
1149 | |||
1150 | p = NLMSG_DATA(nlh); | ||
1151 | p->proto = c->data.proto; | ||
1152 | |||
1153 | nlh->nlmsg_len = skb->tail - b; | ||
1154 | |||
1155 | return netlink_broadcast(xfrm_nl, skb, 0, XFRMGRP_SA, GFP_ATOMIC); | ||
1156 | |||
1157 | nlmsg_failure: | ||
1158 | kfree_skb(skb); | ||
1159 | return -1; | ||
1160 | } | ||
1161 | |||
1162 | static int inline xfrm_sa_len(struct xfrm_state *x) | ||
1163 | { | ||
1164 | int l = 0; | ||
1165 | if (x->aalg) | ||
1166 | l += RTA_SPACE(sizeof(*x->aalg) + (x->aalg->alg_key_len+7)/8); | ||
1167 | if (x->ealg) | ||
1168 | l += RTA_SPACE(sizeof(*x->ealg) + (x->ealg->alg_key_len+7)/8); | ||
1169 | if (x->calg) | ||
1170 | l += RTA_SPACE(sizeof(*x->calg)); | ||
1171 | if (x->encap) | ||
1172 | l += RTA_SPACE(sizeof(*x->encap)); | ||
1173 | |||
1174 | return l; | ||
1175 | } | ||
1176 | |||
1177 | static int xfrm_notify_sa(struct xfrm_state *x, struct km_event *c) | ||
1178 | { | ||
1179 | struct xfrm_usersa_info *p; | ||
1180 | struct xfrm_usersa_id *id; | ||
1181 | struct nlmsghdr *nlh; | ||
1182 | struct sk_buff *skb; | ||
1183 | unsigned char *b; | ||
1184 | int len = xfrm_sa_len(x); | ||
1185 | int headlen; | ||
1186 | |||
1187 | headlen = sizeof(*p); | ||
1188 | if (c->event == XFRM_MSG_DELSA) { | ||
1189 | len += RTA_SPACE(headlen); | ||
1190 | headlen = sizeof(*id); | ||
1191 | } | ||
1192 | len += NLMSG_SPACE(headlen); | ||
1193 | |||
1194 | skb = alloc_skb(len, GFP_ATOMIC); | ||
1195 | if (skb == NULL) | ||
1196 | return -ENOMEM; | ||
1197 | b = skb->tail; | ||
1198 | |||
1199 | nlh = NLMSG_PUT(skb, c->pid, c->seq, c->event, headlen); | ||
1200 | nlh->nlmsg_flags = 0; | ||
1201 | |||
1202 | p = NLMSG_DATA(nlh); | ||
1203 | if (c->event == XFRM_MSG_DELSA) { | ||
1204 | id = NLMSG_DATA(nlh); | ||
1205 | memcpy(&id->daddr, &x->id.daddr, sizeof(id->daddr)); | ||
1206 | id->spi = x->id.spi; | ||
1207 | id->family = x->props.family; | ||
1208 | id->proto = x->id.proto; | ||
1209 | |||
1210 | p = RTA_DATA(__RTA_PUT(skb, XFRMA_SA, sizeof(*p))); | ||
1211 | } | ||
1212 | |||
1213 | copy_to_user_state(x, p); | ||
1214 | |||
1215 | if (x->aalg) | ||
1216 | RTA_PUT(skb, XFRMA_ALG_AUTH, | ||
1217 | sizeof(*(x->aalg))+(x->aalg->alg_key_len+7)/8, x->aalg); | ||
1218 | if (x->ealg) | ||
1219 | RTA_PUT(skb, XFRMA_ALG_CRYPT, | ||
1220 | sizeof(*(x->ealg))+(x->ealg->alg_key_len+7)/8, x->ealg); | ||
1221 | if (x->calg) | ||
1222 | RTA_PUT(skb, XFRMA_ALG_COMP, sizeof(*(x->calg)), x->calg); | ||
1223 | |||
1224 | if (x->encap) | ||
1225 | RTA_PUT(skb, XFRMA_ENCAP, sizeof(*x->encap), x->encap); | ||
1226 | |||
1227 | nlh->nlmsg_len = skb->tail - b; | ||
1228 | |||
1229 | return netlink_broadcast(xfrm_nl, skb, 0, XFRMGRP_SA, GFP_ATOMIC); | ||
1230 | |||
1231 | nlmsg_failure: | ||
1232 | rtattr_failure: | ||
1233 | kfree_skb(skb); | ||
1234 | return -1; | ||
1235 | } | ||
1236 | |||
1237 | static int xfrm_send_state_notify(struct xfrm_state *x, struct km_event *c) | ||
1238 | { | ||
1239 | |||
1240 | switch (c->event) { | ||
1241 | case XFRM_MSG_EXPIRE: | ||
1242 | return xfrm_exp_state_notify(x, c); | ||
1243 | case XFRM_MSG_DELSA: | ||
1244 | case XFRM_MSG_UPDSA: | ||
1245 | case XFRM_MSG_NEWSA: | ||
1246 | return xfrm_notify_sa(x, c); | ||
1247 | case XFRM_MSG_FLUSHSA: | ||
1248 | return xfrm_notify_sa_flush(c); | ||
1249 | default: | ||
1250 | printk("xfrm_user: Unknown SA event %d\n", c->event); | ||
1251 | break; | ||
1252 | } | ||
1253 | |||
1254 | return 0; | ||
1255 | |||
1256 | } | ||
1257 | |||
1088 | static int build_acquire(struct sk_buff *skb, struct xfrm_state *x, | 1258 | static int build_acquire(struct sk_buff *skb, struct xfrm_state *x, |
1089 | struct xfrm_tmpl *xt, struct xfrm_policy *xp, | 1259 | struct xfrm_tmpl *xt, struct xfrm_policy *xp, |
1090 | int dir) | 1260 | int dir) |
@@ -1218,7 +1388,7 @@ nlmsg_failure: | |||
1218 | return -1; | 1388 | return -1; |
1219 | } | 1389 | } |
1220 | 1390 | ||
1221 | static int xfrm_send_policy_notify(struct xfrm_policy *xp, int dir, int hard) | 1391 | static int xfrm_exp_policy_notify(struct xfrm_policy *xp, int dir, struct km_event *c) |
1222 | { | 1392 | { |
1223 | struct sk_buff *skb; | 1393 | struct sk_buff *skb; |
1224 | size_t len; | 1394 | size_t len; |
@@ -1229,7 +1399,7 @@ static int xfrm_send_policy_notify(struct xfrm_policy *xp, int dir, int hard) | |||
1229 | if (skb == NULL) | 1399 | if (skb == NULL) |
1230 | return -ENOMEM; | 1400 | return -ENOMEM; |
1231 | 1401 | ||
1232 | if (build_polexpire(skb, xp, dir, hard) < 0) | 1402 | if (build_polexpire(skb, xp, dir, c->data.hard) < 0) |
1233 | BUG(); | 1403 | BUG(); |
1234 | 1404 | ||
1235 | NETLINK_CB(skb).dst_groups = XFRMGRP_EXPIRE; | 1405 | NETLINK_CB(skb).dst_groups = XFRMGRP_EXPIRE; |
@@ -1237,6 +1407,103 @@ static int xfrm_send_policy_notify(struct xfrm_policy *xp, int dir, int hard) | |||
1237 | return netlink_broadcast(xfrm_nl, skb, 0, XFRMGRP_EXPIRE, GFP_ATOMIC); | 1407 | return netlink_broadcast(xfrm_nl, skb, 0, XFRMGRP_EXPIRE, GFP_ATOMIC); |
1238 | } | 1408 | } |
1239 | 1409 | ||
1410 | static int xfrm_notify_policy(struct xfrm_policy *xp, int dir, struct km_event *c) | ||
1411 | { | ||
1412 | struct xfrm_userpolicy_info *p; | ||
1413 | struct xfrm_userpolicy_id *id; | ||
1414 | struct nlmsghdr *nlh; | ||
1415 | struct sk_buff *skb; | ||
1416 | unsigned char *b; | ||
1417 | int len = RTA_SPACE(sizeof(struct xfrm_user_tmpl) * xp->xfrm_nr); | ||
1418 | int headlen; | ||
1419 | |||
1420 | headlen = sizeof(*p); | ||
1421 | if (c->event == XFRM_MSG_DELPOLICY) { | ||
1422 | len += RTA_SPACE(headlen); | ||
1423 | headlen = sizeof(*id); | ||
1424 | } | ||
1425 | len += NLMSG_SPACE(headlen); | ||
1426 | |||
1427 | skb = alloc_skb(len, GFP_ATOMIC); | ||
1428 | if (skb == NULL) | ||
1429 | return -ENOMEM; | ||
1430 | b = skb->tail; | ||
1431 | |||
1432 | nlh = NLMSG_PUT(skb, c->pid, c->seq, c->event, headlen); | ||
1433 | |||
1434 | p = NLMSG_DATA(nlh); | ||
1435 | if (c->event == XFRM_MSG_DELPOLICY) { | ||
1436 | id = NLMSG_DATA(nlh); | ||
1437 | memset(id, 0, sizeof(*id)); | ||
1438 | id->dir = dir; | ||
1439 | if (c->data.byid) | ||
1440 | id->index = xp->index; | ||
1441 | else | ||
1442 | memcpy(&id->sel, &xp->selector, sizeof(id->sel)); | ||
1443 | |||
1444 | p = RTA_DATA(__RTA_PUT(skb, XFRMA_POLICY, sizeof(*p))); | ||
1445 | } | ||
1446 | |||
1447 | nlh->nlmsg_flags = 0; | ||
1448 | |||
1449 | copy_to_user_policy(xp, p, dir); | ||
1450 | if (copy_to_user_tmpl(xp, skb) < 0) | ||
1451 | goto nlmsg_failure; | ||
1452 | |||
1453 | nlh->nlmsg_len = skb->tail - b; | ||
1454 | |||
1455 | return netlink_broadcast(xfrm_nl, skb, 0, XFRMGRP_POLICY, GFP_ATOMIC); | ||
1456 | |||
1457 | nlmsg_failure: | ||
1458 | rtattr_failure: | ||
1459 | kfree_skb(skb); | ||
1460 | return -1; | ||
1461 | } | ||
1462 | |||
1463 | static int xfrm_notify_policy_flush(struct km_event *c) | ||
1464 | { | ||
1465 | struct nlmsghdr *nlh; | ||
1466 | struct sk_buff *skb; | ||
1467 | unsigned char *b; | ||
1468 | int len = NLMSG_LENGTH(0); | ||
1469 | |||
1470 | skb = alloc_skb(len, GFP_ATOMIC); | ||
1471 | if (skb == NULL) | ||
1472 | return -ENOMEM; | ||
1473 | b = skb->tail; | ||
1474 | |||
1475 | |||
1476 | nlh = NLMSG_PUT(skb, c->pid, c->seq, XFRM_MSG_FLUSHPOLICY, 0); | ||
1477 | |||
1478 | nlh->nlmsg_len = skb->tail - b; | ||
1479 | |||
1480 | return netlink_broadcast(xfrm_nl, skb, 0, XFRMGRP_POLICY, GFP_ATOMIC); | ||
1481 | |||
1482 | nlmsg_failure: | ||
1483 | kfree_skb(skb); | ||
1484 | return -1; | ||
1485 | } | ||
1486 | |||
1487 | static int xfrm_send_policy_notify(struct xfrm_policy *xp, int dir, struct km_event *c) | ||
1488 | { | ||
1489 | |||
1490 | switch (c->event) { | ||
1491 | case XFRM_MSG_NEWPOLICY: | ||
1492 | case XFRM_MSG_UPDPOLICY: | ||
1493 | case XFRM_MSG_DELPOLICY: | ||
1494 | return xfrm_notify_policy(xp, dir, c); | ||
1495 | case XFRM_MSG_FLUSHPOLICY: | ||
1496 | return xfrm_notify_policy_flush(c); | ||
1497 | case XFRM_MSG_POLEXPIRE: | ||
1498 | return xfrm_exp_policy_notify(xp, dir, c); | ||
1499 | default: | ||
1500 | printk("xfrm_user: Unknown Policy event %d\n", c->event); | ||
1501 | } | ||
1502 | |||
1503 | return 0; | ||
1504 | |||
1505 | } | ||
1506 | |||
1240 | static struct xfrm_mgr netlink_mgr = { | 1507 | static struct xfrm_mgr netlink_mgr = { |
1241 | .id = "netlink", | 1508 | .id = "netlink", |
1242 | .notify = xfrm_send_state_notify, | 1509 | .notify = xfrm_send_state_notify, |