aboutsummaryrefslogtreecommitdiffstats
path: root/net/key
diff options
context:
space:
mode:
authorAnton Altaparmakov <aia21@cantab.net>2005-06-23 06:26:22 -0400
committerAnton Altaparmakov <aia21@cantab.net>2005-06-23 06:26:22 -0400
commit3357d4c75f1fb67e7304998c4ad4e9a9fed66fa4 (patch)
treeceba46966a5a1112a05d257d8ecb25ae5eee95e0 /net/key
parent364f6c717deef4a3ac4982e670fa9846b43cd060 (diff)
parentee98689be1b054897ff17655008c3048fe88be94 (diff)
Automatic merge with /usr/src/ntfs-2.6.git.
Diffstat (limited to 'net/key')
-rw-r--r--net/key/af_key.c385
1 files changed, 279 insertions, 106 deletions
diff --git a/net/key/af_key.c b/net/key/af_key.c
index ce980aa94ed8..4879743b945a 100644
--- a/net/key/af_key.c
+++ b/net/key/af_key.c
@@ -656,13 +656,18 @@ static struct sk_buff * pfkey_xfrm_state2msg(struct xfrm_state *x, int add_keys,
656 sa->sadb_sa_exttype = SADB_EXT_SA; 656 sa->sadb_sa_exttype = SADB_EXT_SA;
657 sa->sadb_sa_spi = x->id.spi; 657 sa->sadb_sa_spi = x->id.spi;
658 sa->sadb_sa_replay = x->props.replay_window; 658 sa->sadb_sa_replay = x->props.replay_window;
659 sa->sadb_sa_state = SADB_SASTATE_DYING; 659 switch (x->km.state) {
660 if (x->km.state == XFRM_STATE_VALID && !x->km.dying) 660 case XFRM_STATE_VALID:
661 sa->sadb_sa_state = SADB_SASTATE_MATURE; 661 sa->sadb_sa_state = x->km.dying ?
662 else if (x->km.state == XFRM_STATE_ACQ) 662 SADB_SASTATE_DYING : SADB_SASTATE_MATURE;
663 break;
664 case XFRM_STATE_ACQ:
663 sa->sadb_sa_state = SADB_SASTATE_LARVAL; 665 sa->sadb_sa_state = SADB_SASTATE_LARVAL;
664 else if (x->km.state == XFRM_STATE_EXPIRED) 666 break;
667 default:
665 sa->sadb_sa_state = SADB_SASTATE_DEAD; 668 sa->sadb_sa_state = SADB_SASTATE_DEAD;
669 break;
670 }
666 sa->sadb_sa_auth = 0; 671 sa->sadb_sa_auth = 0;
667 if (x->aalg) { 672 if (x->aalg) {
668 struct xfrm_algo_desc *a = xfrm_aalg_get_byname(x->aalg->alg_name, 0); 673 struct xfrm_algo_desc *a = xfrm_aalg_get_byname(x->aalg->alg_name, 0);
@@ -685,6 +690,8 @@ static struct sk_buff * pfkey_xfrm_state2msg(struct xfrm_state *x, int add_keys,
685 sa->sadb_sa_flags |= SADB_SAFLAGS_NOECN; 690 sa->sadb_sa_flags |= SADB_SAFLAGS_NOECN;
686 if (x->props.flags & XFRM_STATE_DECAP_DSCP) 691 if (x->props.flags & XFRM_STATE_DECAP_DSCP)
687 sa->sadb_sa_flags |= SADB_SAFLAGS_DECAP_DSCP; 692 sa->sadb_sa_flags |= SADB_SAFLAGS_DECAP_DSCP;
693 if (x->props.flags & XFRM_STATE_NOPMTUDISC)
694 sa->sadb_sa_flags |= SADB_SAFLAGS_NOPMTUDISC;
688 695
689 /* hard time */ 696 /* hard time */
690 if (hsc & 2) { 697 if (hsc & 2) {
@@ -969,6 +976,8 @@ static struct xfrm_state * pfkey_msg2xfrm_state(struct sadb_msg *hdr,
969 x->props.flags |= XFRM_STATE_NOECN; 976 x->props.flags |= XFRM_STATE_NOECN;
970 if (sa->sadb_sa_flags & SADB_SAFLAGS_DECAP_DSCP) 977 if (sa->sadb_sa_flags & SADB_SAFLAGS_DECAP_DSCP)
971 x->props.flags |= XFRM_STATE_DECAP_DSCP; 978 x->props.flags |= XFRM_STATE_DECAP_DSCP;
979 if (sa->sadb_sa_flags & SADB_SAFLAGS_NOPMTUDISC)
980 x->props.flags |= XFRM_STATE_NOPMTUDISC;
972 981
973 lifetime = (struct sadb_lifetime*) ext_hdrs[SADB_EXT_LIFETIME_HARD-1]; 982 lifetime = (struct sadb_lifetime*) ext_hdrs[SADB_EXT_LIFETIME_HARD-1];
974 if (lifetime != NULL) { 983 if (lifetime != NULL) {
@@ -1091,17 +1100,11 @@ static struct xfrm_state * pfkey_msg2xfrm_state(struct sadb_msg *hdr,
1091 } 1100 }
1092 } 1101 }
1093 1102
1094 x->type = xfrm_get_type(proto, x->props.family); 1103 err = xfrm_init_state(x);
1095 if (x->type == NULL) { 1104 if (err)
1096 err = -ENOPROTOOPT;
1097 goto out;
1098 }
1099 if (x->type->init_state(x, NULL)) {
1100 err = -EINVAL;
1101 goto out; 1105 goto out;
1102 } 1106
1103 x->km.seq = hdr->sadb_msg_seq; 1107 x->km.seq = hdr->sadb_msg_seq;
1104 x->km.state = XFRM_STATE_VALID;
1105 return x; 1108 return x;
1106 1109
1107out: 1110out:
@@ -1240,13 +1243,78 @@ static int pfkey_acquire(struct sock *sk, struct sk_buff *skb, struct sadb_msg *
1240 return 0; 1243 return 0;
1241} 1244}
1242 1245
1246static inline int event2poltype(int event)
1247{
1248 switch (event) {
1249 case XFRM_MSG_DELPOLICY:
1250 return SADB_X_SPDDELETE;
1251 case XFRM_MSG_NEWPOLICY:
1252 return SADB_X_SPDADD;
1253 case XFRM_MSG_UPDPOLICY:
1254 return SADB_X_SPDUPDATE;
1255 case XFRM_MSG_POLEXPIRE:
1256 // return SADB_X_SPDEXPIRE;
1257 default:
1258 printk("pfkey: Unknown policy event %d\n", event);
1259 break;
1260 }
1261
1262 return 0;
1263}
1264
1265static inline int event2keytype(int event)
1266{
1267 switch (event) {
1268 case XFRM_MSG_DELSA:
1269 return SADB_DELETE;
1270 case XFRM_MSG_NEWSA:
1271 return SADB_ADD;
1272 case XFRM_MSG_UPDSA:
1273 return SADB_UPDATE;
1274 case XFRM_MSG_EXPIRE:
1275 return SADB_EXPIRE;
1276 default:
1277 printk("pfkey: Unknown SA event %d\n", event);
1278 break;
1279 }
1280
1281 return 0;
1282}
1283
1284/* ADD/UPD/DEL */
1285static int key_notify_sa(struct xfrm_state *x, struct km_event *c)
1286{
1287 struct sk_buff *skb;
1288 struct sadb_msg *hdr;
1289 int hsc = 3;
1290
1291 if (c->event == XFRM_MSG_DELSA)
1292 hsc = 0;
1293
1294 skb = pfkey_xfrm_state2msg(x, 0, hsc);
1295
1296 if (IS_ERR(skb))
1297 return PTR_ERR(skb);
1298
1299 hdr = (struct sadb_msg *) skb->data;
1300 hdr->sadb_msg_version = PF_KEY_V2;
1301 hdr->sadb_msg_type = event2keytype(c->event);
1302 hdr->sadb_msg_satype = pfkey_proto2satype(x->id.proto);
1303 hdr->sadb_msg_errno = 0;
1304 hdr->sadb_msg_reserved = 0;
1305 hdr->sadb_msg_seq = c->seq;
1306 hdr->sadb_msg_pid = c->pid;
1307
1308 pfkey_broadcast(skb, GFP_ATOMIC, BROADCAST_ALL, NULL);
1309
1310 return 0;
1311}
1243 1312
1244static int pfkey_add(struct sock *sk, struct sk_buff *skb, struct sadb_msg *hdr, void **ext_hdrs) 1313static int pfkey_add(struct sock *sk, struct sk_buff *skb, struct sadb_msg *hdr, void **ext_hdrs)
1245{ 1314{
1246 struct sk_buff *out_skb;
1247 struct sadb_msg *out_hdr;
1248 struct xfrm_state *x; 1315 struct xfrm_state *x;
1249 int err; 1316 int err;
1317 struct km_event c;
1250 1318
1251 xfrm_probe_algs(); 1319 xfrm_probe_algs();
1252 1320
@@ -1254,6 +1322,7 @@ static int pfkey_add(struct sock *sk, struct sk_buff *skb, struct sadb_msg *hdr,
1254 if (IS_ERR(x)) 1322 if (IS_ERR(x))
1255 return PTR_ERR(x); 1323 return PTR_ERR(x);
1256 1324
1325 xfrm_state_hold(x);
1257 if (hdr->sadb_msg_type == SADB_ADD) 1326 if (hdr->sadb_msg_type == SADB_ADD)
1258 err = xfrm_state_add(x); 1327 err = xfrm_state_add(x);
1259 else 1328 else
@@ -1262,30 +1331,26 @@ static int pfkey_add(struct sock *sk, struct sk_buff *skb, struct sadb_msg *hdr,
1262 if (err < 0) { 1331 if (err < 0) {
1263 x->km.state = XFRM_STATE_DEAD; 1332 x->km.state = XFRM_STATE_DEAD;
1264 xfrm_state_put(x); 1333 xfrm_state_put(x);
1265 return err; 1334 goto out;
1266 } 1335 }
1267 1336
1268 out_skb = pfkey_xfrm_state2msg(x, 0, 3); 1337 if (hdr->sadb_msg_type == SADB_ADD)
1269 if (IS_ERR(out_skb)) 1338 c.event = XFRM_MSG_NEWSA;
1270 return PTR_ERR(out_skb); /* XXX Should we return 0 here ? */ 1339 else
1271 1340 c.event = XFRM_MSG_UPDSA;
1272 out_hdr = (struct sadb_msg *) out_skb->data; 1341 c.seq = hdr->sadb_msg_seq;
1273 out_hdr->sadb_msg_version = hdr->sadb_msg_version; 1342 c.pid = hdr->sadb_msg_pid;
1274 out_hdr->sadb_msg_type = hdr->sadb_msg_type; 1343 km_state_notify(x, &c);
1275 out_hdr->sadb_msg_satype = pfkey_proto2satype(x->id.proto); 1344out:
1276 out_hdr->sadb_msg_errno = 0; 1345 xfrm_state_put(x);
1277 out_hdr->sadb_msg_reserved = 0; 1346 return err;
1278 out_hdr->sadb_msg_seq = hdr->sadb_msg_seq;
1279 out_hdr->sadb_msg_pid = hdr->sadb_msg_pid;
1280
1281 pfkey_broadcast(out_skb, GFP_ATOMIC, BROADCAST_ALL, sk);
1282
1283 return 0;
1284} 1347}
1285 1348
1286static int pfkey_delete(struct sock *sk, struct sk_buff *skb, struct sadb_msg *hdr, void **ext_hdrs) 1349static int pfkey_delete(struct sock *sk, struct sk_buff *skb, struct sadb_msg *hdr, void **ext_hdrs)
1287{ 1350{
1288 struct xfrm_state *x; 1351 struct xfrm_state *x;
1352 struct km_event c;
1353 int err;
1289 1354
1290 if (!ext_hdrs[SADB_EXT_SA-1] || 1355 if (!ext_hdrs[SADB_EXT_SA-1] ||
1291 !present_and_same_family(ext_hdrs[SADB_EXT_ADDRESS_SRC-1], 1356 !present_and_same_family(ext_hdrs[SADB_EXT_ADDRESS_SRC-1],
@@ -1301,13 +1366,19 @@ static int pfkey_delete(struct sock *sk, struct sk_buff *skb, struct sadb_msg *h
1301 return -EPERM; 1366 return -EPERM;
1302 } 1367 }
1303 1368
1304 xfrm_state_delete(x); 1369 err = xfrm_state_delete(x);
1305 xfrm_state_put(x); 1370 if (err < 0) {
1371 xfrm_state_put(x);
1372 return err;
1373 }
1306 1374
1307 pfkey_broadcast(skb_clone(skb, GFP_KERNEL), GFP_KERNEL, 1375 c.seq = hdr->sadb_msg_seq;
1308 BROADCAST_ALL, sk); 1376 c.pid = hdr->sadb_msg_pid;
1377 c.event = XFRM_MSG_DELSA;
1378 km_state_notify(x, &c);
1379 xfrm_state_put(x);
1309 1380
1310 return 0; 1381 return err;
1311} 1382}
1312 1383
1313static int pfkey_get(struct sock *sk, struct sk_buff *skb, struct sadb_msg *hdr, void **ext_hdrs) 1384static int pfkey_get(struct sock *sk, struct sk_buff *skb, struct sadb_msg *hdr, void **ext_hdrs)
@@ -1445,28 +1516,42 @@ static int pfkey_register(struct sock *sk, struct sk_buff *skb, struct sadb_msg
1445 return 0; 1516 return 0;
1446} 1517}
1447 1518
1519static int key_notify_sa_flush(struct km_event *c)
1520{
1521 struct sk_buff *skb;
1522 struct sadb_msg *hdr;
1523
1524 skb = alloc_skb(sizeof(struct sadb_msg) + 16, GFP_ATOMIC);
1525 if (!skb)
1526 return -ENOBUFS;
1527 hdr = (struct sadb_msg *) skb_put(skb, sizeof(struct sadb_msg));
1528 hdr->sadb_msg_satype = pfkey_proto2satype(c->data.proto);
1529 hdr->sadb_msg_seq = c->seq;
1530 hdr->sadb_msg_pid = c->pid;
1531 hdr->sadb_msg_version = PF_KEY_V2;
1532 hdr->sadb_msg_errno = (uint8_t) 0;
1533 hdr->sadb_msg_len = (sizeof(struct sadb_msg) / sizeof(uint64_t));
1534
1535 pfkey_broadcast(skb, GFP_ATOMIC, BROADCAST_ALL, NULL);
1536
1537 return 0;
1538}
1539
1448static int pfkey_flush(struct sock *sk, struct sk_buff *skb, struct sadb_msg *hdr, void **ext_hdrs) 1540static int pfkey_flush(struct sock *sk, struct sk_buff *skb, struct sadb_msg *hdr, void **ext_hdrs)
1449{ 1541{
1450 unsigned proto; 1542 unsigned proto;
1451 struct sk_buff *skb_out; 1543 struct km_event c;
1452 struct sadb_msg *hdr_out;
1453 1544
1454 proto = pfkey_satype2proto(hdr->sadb_msg_satype); 1545 proto = pfkey_satype2proto(hdr->sadb_msg_satype);
1455 if (proto == 0) 1546 if (proto == 0)
1456 return -EINVAL; 1547 return -EINVAL;
1457 1548
1458 skb_out = alloc_skb(sizeof(struct sadb_msg) + 16, GFP_KERNEL);
1459 if (!skb_out)
1460 return -ENOBUFS;
1461
1462 xfrm_state_flush(proto); 1549 xfrm_state_flush(proto);
1463 1550 c.data.proto = proto;
1464 hdr_out = (struct sadb_msg *) skb_put(skb_out, sizeof(struct sadb_msg)); 1551 c.seq = hdr->sadb_msg_seq;
1465 pfkey_hdr_dup(hdr_out, hdr); 1552 c.pid = hdr->sadb_msg_pid;
1466 hdr_out->sadb_msg_errno = (uint8_t) 0; 1553 c.event = XFRM_MSG_FLUSHSA;
1467 hdr_out->sadb_msg_len = (sizeof(struct sadb_msg) / sizeof(uint64_t)); 1554 km_state_notify(NULL, &c);
1468
1469 pfkey_broadcast(skb_out, GFP_KERNEL, BROADCAST_ALL, NULL);
1470 1555
1471 return 0; 1556 return 0;
1472} 1557}
@@ -1859,6 +1944,35 @@ static void pfkey_xfrm_policy2msg(struct sk_buff *skb, struct xfrm_policy *xp, i
1859 hdr->sadb_msg_reserved = atomic_read(&xp->refcnt); 1944 hdr->sadb_msg_reserved = atomic_read(&xp->refcnt);
1860} 1945}
1861 1946
1947static int key_notify_policy(struct xfrm_policy *xp, int dir, struct km_event *c)
1948{
1949 struct sk_buff *out_skb;
1950 struct sadb_msg *out_hdr;
1951 int err;
1952
1953 out_skb = pfkey_xfrm_policy2msg_prep(xp);
1954 if (IS_ERR(out_skb)) {
1955 err = PTR_ERR(out_skb);
1956 goto out;
1957 }
1958 pfkey_xfrm_policy2msg(out_skb, xp, dir);
1959
1960 out_hdr = (struct sadb_msg *) out_skb->data;
1961 out_hdr->sadb_msg_version = PF_KEY_V2;
1962
1963 if (c->data.byid && c->event == XFRM_MSG_DELPOLICY)
1964 out_hdr->sadb_msg_type = SADB_X_SPDDELETE2;
1965 else
1966 out_hdr->sadb_msg_type = event2poltype(c->event);
1967 out_hdr->sadb_msg_errno = 0;
1968 out_hdr->sadb_msg_seq = c->seq;
1969 out_hdr->sadb_msg_pid = c->pid;
1970 pfkey_broadcast(out_skb, GFP_ATOMIC, BROADCAST_ALL, NULL);
1971out:
1972 return 0;
1973
1974}
1975
1862static int pfkey_spdadd(struct sock *sk, struct sk_buff *skb, struct sadb_msg *hdr, void **ext_hdrs) 1976static int pfkey_spdadd(struct sock *sk, struct sk_buff *skb, struct sadb_msg *hdr, void **ext_hdrs)
1863{ 1977{
1864 int err; 1978 int err;
@@ -1866,8 +1980,7 @@ static int pfkey_spdadd(struct sock *sk, struct sk_buff *skb, struct sadb_msg *h
1866 struct sadb_address *sa; 1980 struct sadb_address *sa;
1867 struct sadb_x_policy *pol; 1981 struct sadb_x_policy *pol;
1868 struct xfrm_policy *xp; 1982 struct xfrm_policy *xp;
1869 struct sk_buff *out_skb; 1983 struct km_event c;
1870 struct sadb_msg *out_hdr;
1871 1984
1872 if (!present_and_same_family(ext_hdrs[SADB_EXT_ADDRESS_SRC-1], 1985 if (!present_and_same_family(ext_hdrs[SADB_EXT_ADDRESS_SRC-1],
1873 ext_hdrs[SADB_EXT_ADDRESS_DST-1]) || 1986 ext_hdrs[SADB_EXT_ADDRESS_DST-1]) ||
@@ -1935,31 +2048,23 @@ static int pfkey_spdadd(struct sock *sk, struct sk_buff *skb, struct sadb_msg *h
1935 (err = parse_ipsecrequests(xp, pol)) < 0) 2048 (err = parse_ipsecrequests(xp, pol)) < 0)
1936 goto out; 2049 goto out;
1937 2050
1938 out_skb = pfkey_xfrm_policy2msg_prep(xp);
1939 if (IS_ERR(out_skb)) {
1940 err = PTR_ERR(out_skb);
1941 goto out;
1942 }
1943
1944 err = xfrm_policy_insert(pol->sadb_x_policy_dir-1, xp, 2051 err = xfrm_policy_insert(pol->sadb_x_policy_dir-1, xp,
1945 hdr->sadb_msg_type != SADB_X_SPDUPDATE); 2052 hdr->sadb_msg_type != SADB_X_SPDUPDATE);
1946 if (err) { 2053 if (err) {
1947 kfree_skb(out_skb); 2054 kfree(xp);
1948 goto out; 2055 return err;
1949 } 2056 }
1950 2057
1951 pfkey_xfrm_policy2msg(out_skb, xp, pol->sadb_x_policy_dir-1); 2058 if (hdr->sadb_msg_type == SADB_X_SPDUPDATE)
2059 c.event = XFRM_MSG_UPDPOLICY;
2060 else
2061 c.event = XFRM_MSG_NEWPOLICY;
1952 2062
1953 xfrm_pol_put(xp); 2063 c.seq = hdr->sadb_msg_seq;
2064 c.pid = hdr->sadb_msg_pid;
1954 2065
1955 out_hdr = (struct sadb_msg *) out_skb->data; 2066 km_policy_notify(xp, pol->sadb_x_policy_dir-1, &c);
1956 out_hdr->sadb_msg_version = hdr->sadb_msg_version; 2067 xfrm_pol_put(xp);
1957 out_hdr->sadb_msg_type = hdr->sadb_msg_type;
1958 out_hdr->sadb_msg_satype = 0;
1959 out_hdr->sadb_msg_errno = 0;
1960 out_hdr->sadb_msg_seq = hdr->sadb_msg_seq;
1961 out_hdr->sadb_msg_pid = hdr->sadb_msg_pid;
1962 pfkey_broadcast(out_skb, GFP_ATOMIC, BROADCAST_ALL, sk);
1963 return 0; 2068 return 0;
1964 2069
1965out: 2070out:
@@ -1973,9 +2078,8 @@ static int pfkey_spddelete(struct sock *sk, struct sk_buff *skb, struct sadb_msg
1973 struct sadb_address *sa; 2078 struct sadb_address *sa;
1974 struct sadb_x_policy *pol; 2079 struct sadb_x_policy *pol;
1975 struct xfrm_policy *xp; 2080 struct xfrm_policy *xp;
1976 struct sk_buff *out_skb;
1977 struct sadb_msg *out_hdr;
1978 struct xfrm_selector sel; 2081 struct xfrm_selector sel;
2082 struct km_event c;
1979 2083
1980 if (!present_and_same_family(ext_hdrs[SADB_EXT_ADDRESS_SRC-1], 2084 if (!present_and_same_family(ext_hdrs[SADB_EXT_ADDRESS_SRC-1],
1981 ext_hdrs[SADB_EXT_ADDRESS_DST-1]) || 2085 ext_hdrs[SADB_EXT_ADDRESS_DST-1]) ||
@@ -2010,25 +2114,40 @@ static int pfkey_spddelete(struct sock *sk, struct sk_buff *skb, struct sadb_msg
2010 2114
2011 err = 0; 2115 err = 0;
2012 2116
2117 c.seq = hdr->sadb_msg_seq;
2118 c.pid = hdr->sadb_msg_pid;
2119 c.event = XFRM_MSG_DELPOLICY;
2120 km_policy_notify(xp, pol->sadb_x_policy_dir-1, &c);
2121
2122 xfrm_pol_put(xp);
2123 return err;
2124}
2125
2126static int key_pol_get_resp(struct sock *sk, struct xfrm_policy *xp, struct sadb_msg *hdr, int dir)
2127{
2128 int err;
2129 struct sk_buff *out_skb;
2130 struct sadb_msg *out_hdr;
2131 err = 0;
2132
2013 out_skb = pfkey_xfrm_policy2msg_prep(xp); 2133 out_skb = pfkey_xfrm_policy2msg_prep(xp);
2014 if (IS_ERR(out_skb)) { 2134 if (IS_ERR(out_skb)) {
2015 err = PTR_ERR(out_skb); 2135 err = PTR_ERR(out_skb);
2016 goto out; 2136 goto out;
2017 } 2137 }
2018 pfkey_xfrm_policy2msg(out_skb, xp, pol->sadb_x_policy_dir-1); 2138 pfkey_xfrm_policy2msg(out_skb, xp, dir);
2019 2139
2020 out_hdr = (struct sadb_msg *) out_skb->data; 2140 out_hdr = (struct sadb_msg *) out_skb->data;
2021 out_hdr->sadb_msg_version = hdr->sadb_msg_version; 2141 out_hdr->sadb_msg_version = hdr->sadb_msg_version;
2022 out_hdr->sadb_msg_type = SADB_X_SPDDELETE; 2142 out_hdr->sadb_msg_type = hdr->sadb_msg_type;
2023 out_hdr->sadb_msg_satype = 0; 2143 out_hdr->sadb_msg_satype = 0;
2024 out_hdr->sadb_msg_errno = 0; 2144 out_hdr->sadb_msg_errno = 0;
2025 out_hdr->sadb_msg_seq = hdr->sadb_msg_seq; 2145 out_hdr->sadb_msg_seq = hdr->sadb_msg_seq;
2026 out_hdr->sadb_msg_pid = hdr->sadb_msg_pid; 2146 out_hdr->sadb_msg_pid = hdr->sadb_msg_pid;
2027 pfkey_broadcast(out_skb, GFP_ATOMIC, BROADCAST_ALL, sk); 2147 pfkey_broadcast(out_skb, GFP_ATOMIC, BROADCAST_ONE, sk);
2028 err = 0; 2148 err = 0;
2029 2149
2030out: 2150out:
2031 xfrm_pol_put(xp);
2032 return err; 2151 return err;
2033} 2152}
2034 2153
@@ -2037,8 +2156,7 @@ static int pfkey_spdget(struct sock *sk, struct sk_buff *skb, struct sadb_msg *h
2037 int err; 2156 int err;
2038 struct sadb_x_policy *pol; 2157 struct sadb_x_policy *pol;
2039 struct xfrm_policy *xp; 2158 struct xfrm_policy *xp;
2040 struct sk_buff *out_skb; 2159 struct km_event c;
2041 struct sadb_msg *out_hdr;
2042 2160
2043 if ((pol = ext_hdrs[SADB_X_EXT_POLICY-1]) == NULL) 2161 if ((pol = ext_hdrs[SADB_X_EXT_POLICY-1]) == NULL)
2044 return -EINVAL; 2162 return -EINVAL;
@@ -2050,24 +2168,16 @@ static int pfkey_spdget(struct sock *sk, struct sk_buff *skb, struct sadb_msg *h
2050 2168
2051 err = 0; 2169 err = 0;
2052 2170
2053 out_skb = pfkey_xfrm_policy2msg_prep(xp); 2171 c.seq = hdr->sadb_msg_seq;
2054 if (IS_ERR(out_skb)) { 2172 c.pid = hdr->sadb_msg_pid;
2055 err = PTR_ERR(out_skb); 2173 if (hdr->sadb_msg_type == SADB_X_SPDDELETE2) {
2056 goto out; 2174 c.data.byid = 1;
2175 c.event = XFRM_MSG_DELPOLICY;
2176 km_policy_notify(xp, pol->sadb_x_policy_dir-1, &c);
2177 } else {
2178 err = key_pol_get_resp(sk, xp, hdr, pol->sadb_x_policy_dir-1);
2057 } 2179 }
2058 pfkey_xfrm_policy2msg(out_skb, xp, pol->sadb_x_policy_dir-1);
2059 2180
2060 out_hdr = (struct sadb_msg *) out_skb->data;
2061 out_hdr->sadb_msg_version = hdr->sadb_msg_version;
2062 out_hdr->sadb_msg_type = hdr->sadb_msg_type;
2063 out_hdr->sadb_msg_satype = 0;
2064 out_hdr->sadb_msg_errno = 0;
2065 out_hdr->sadb_msg_seq = hdr->sadb_msg_seq;
2066 out_hdr->sadb_msg_pid = hdr->sadb_msg_pid;
2067 pfkey_broadcast(out_skb, GFP_ATOMIC, BROADCAST_ALL, sk);
2068 err = 0;
2069
2070out:
2071 xfrm_pol_put(xp); 2181 xfrm_pol_put(xp);
2072 return err; 2182 return err;
2073} 2183}
@@ -2102,22 +2212,34 @@ static int pfkey_spddump(struct sock *sk, struct sk_buff *skb, struct sadb_msg *
2102 return xfrm_policy_walk(dump_sp, &data); 2212 return xfrm_policy_walk(dump_sp, &data);
2103} 2213}
2104 2214
2105static int pfkey_spdflush(struct sock *sk, struct sk_buff *skb, struct sadb_msg *hdr, void **ext_hdrs) 2215static int key_notify_policy_flush(struct km_event *c)
2106{ 2216{
2107 struct sk_buff *skb_out; 2217 struct sk_buff *skb_out;
2108 struct sadb_msg *hdr_out; 2218 struct sadb_msg *hdr;
2109 2219
2110 skb_out = alloc_skb(sizeof(struct sadb_msg) + 16, GFP_KERNEL); 2220 skb_out = alloc_skb(sizeof(struct sadb_msg) + 16, GFP_ATOMIC);
2111 if (!skb_out) 2221 if (!skb_out)
2112 return -ENOBUFS; 2222 return -ENOBUFS;
2223 hdr = (struct sadb_msg *) skb_put(skb_out, sizeof(struct sadb_msg));
2224 hdr->sadb_msg_seq = c->seq;
2225 hdr->sadb_msg_pid = c->pid;
2226 hdr->sadb_msg_version = PF_KEY_V2;
2227 hdr->sadb_msg_errno = (uint8_t) 0;
2228 hdr->sadb_msg_len = (sizeof(struct sadb_msg) / sizeof(uint64_t));
2229 pfkey_broadcast(skb_out, GFP_ATOMIC, BROADCAST_ALL, NULL);
2230 return 0;
2113 2231
2114 xfrm_policy_flush(); 2232}
2115 2233
2116 hdr_out = (struct sadb_msg *) skb_put(skb_out, sizeof(struct sadb_msg)); 2234static int pfkey_spdflush(struct sock *sk, struct sk_buff *skb, struct sadb_msg *hdr, void **ext_hdrs)
2117 pfkey_hdr_dup(hdr_out, hdr); 2235{
2118 hdr_out->sadb_msg_errno = (uint8_t) 0; 2236 struct km_event c;
2119 hdr_out->sadb_msg_len = (sizeof(struct sadb_msg) / sizeof(uint64_t)); 2237
2120 pfkey_broadcast(skb_out, GFP_KERNEL, BROADCAST_ALL, NULL); 2238 xfrm_policy_flush();
2239 c.event = XFRM_MSG_FLUSHPOLICY;
2240 c.pid = hdr->sadb_msg_pid;
2241 c.seq = hdr->sadb_msg_seq;
2242 km_policy_notify(NULL, 0, &c);
2121 2243
2122 return 0; 2244 return 0;
2123} 2245}
@@ -2317,11 +2439,23 @@ static void dump_esp_combs(struct sk_buff *skb, struct xfrm_tmpl *t)
2317 } 2439 }
2318} 2440}
2319 2441
2320static int pfkey_send_notify(struct xfrm_state *x, int hard) 2442static int key_notify_policy_expire(struct xfrm_policy *xp, struct km_event *c)
2443{
2444 return 0;
2445}
2446
2447static int key_notify_sa_expire(struct xfrm_state *x, struct km_event *c)
2321{ 2448{
2322 struct sk_buff *out_skb; 2449 struct sk_buff *out_skb;
2323 struct sadb_msg *out_hdr; 2450 struct sadb_msg *out_hdr;
2324 int hsc = (hard ? 2 : 1); 2451 int hard;
2452 int hsc;
2453
2454 hard = c->data.hard;
2455 if (hard)
2456 hsc = 2;
2457 else
2458 hsc = 1;
2325 2459
2326 out_skb = pfkey_xfrm_state2msg(x, 0, hsc); 2460 out_skb = pfkey_xfrm_state2msg(x, 0, hsc);
2327 if (IS_ERR(out_skb)) 2461 if (IS_ERR(out_skb))
@@ -2340,6 +2474,44 @@ static int pfkey_send_notify(struct xfrm_state *x, int hard)
2340 return 0; 2474 return 0;
2341} 2475}
2342 2476
2477static int pfkey_send_notify(struct xfrm_state *x, struct km_event *c)
2478{
2479 switch (c->event) {
2480 case XFRM_MSG_EXPIRE:
2481 return key_notify_sa_expire(x, c);
2482 case XFRM_MSG_DELSA:
2483 case XFRM_MSG_NEWSA:
2484 case XFRM_MSG_UPDSA:
2485 return key_notify_sa(x, c);
2486 case XFRM_MSG_FLUSHSA:
2487 return key_notify_sa_flush(c);
2488 default:
2489 printk("pfkey: Unknown SA event %d\n", c->event);
2490 break;
2491 }
2492
2493 return 0;
2494}
2495
2496static int pfkey_send_policy_notify(struct xfrm_policy *xp, int dir, struct km_event *c)
2497{
2498 switch (c->event) {
2499 case XFRM_MSG_POLEXPIRE:
2500 return key_notify_policy_expire(xp, c);
2501 case XFRM_MSG_DELPOLICY:
2502 case XFRM_MSG_NEWPOLICY:
2503 case XFRM_MSG_UPDPOLICY:
2504 return key_notify_policy(xp, dir, c);
2505 case XFRM_MSG_FLUSHPOLICY:
2506 return key_notify_policy_flush(c);
2507 default:
2508 printk("pfkey: Unknown policy event %d\n", c->event);
2509 break;
2510 }
2511
2512 return 0;
2513}
2514
2343static u32 get_acqseq(void) 2515static u32 get_acqseq(void)
2344{ 2516{
2345 u32 res; 2517 u32 res;
@@ -2856,6 +3028,7 @@ static struct xfrm_mgr pfkeyv2_mgr =
2856 .acquire = pfkey_send_acquire, 3028 .acquire = pfkey_send_acquire,
2857 .compile_policy = pfkey_compile_policy, 3029 .compile_policy = pfkey_compile_policy,
2858 .new_mapping = pfkey_send_new_mapping, 3030 .new_mapping = pfkey_send_new_mapping,
3031 .notify_policy = pfkey_send_policy_notify,
2859}; 3032};
2860 3033
2861static void __exit ipsec_pfkey_exit(void) 3034static void __exit ipsec_pfkey_exit(void)