aboutsummaryrefslogtreecommitdiffstats
path: root/net/key
diff options
context:
space:
mode:
authorJamal Hadi Salim <hadi@cyberus.ca>2005-06-19 01:42:13 -0400
committerDavid S. Miller <davem@davemloft.net>2005-06-19 01:42:13 -0400
commit26b15dad9f1c19d6d4f7b999b07eaa6d98e4b375 (patch)
tree2ca3039488d9df023fb84eaa7c1f52aa8d1ce69c /net/key
parent3aa3dfb372576f30835a94409556e3c8681b5756 (diff)
[IPSEC] Add complete xfrm event notification
Heres the final patch. What this patch provides - netlink xfrm events - ability to have events generated by netlink propagated to pfkey and vice versa. - fixes the acquire lets-be-happy-with-one-success issue Signed-off-by: Jamal Hadi Salim <hadi@cyberus.ca> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Diffstat (limited to 'net/key')
-rw-r--r--net/key/af_key.c357
1 files changed, 267 insertions, 90 deletions
diff --git a/net/key/af_key.c b/net/key/af_key.c
index ce980aa94ed8..d086c117f5f0 100644
--- a/net/key/af_key.c
+++ b/net/key/af_key.c
@@ -1240,13 +1240,85 @@ static int pfkey_acquire(struct sock *sk, struct sk_buff *skb, struct sadb_msg *
1240 return 0; 1240 return 0;
1241} 1241}
1242 1242
1243static inline int event2poltype(int event)
1244{
1245 switch (event) {
1246 case XFRM_SAP_DELETED:
1247 return SADB_X_SPDDELETE;
1248 case XFRM_SAP_ADDED:
1249 return SADB_X_SPDADD;
1250 case XFRM_SAP_UPDATED:
1251 return SADB_X_SPDUPDATE;
1252 case XFRM_SAP_EXPIRED:
1253 // return SADB_X_SPDEXPIRE;
1254 default:
1255 printk("pfkey: Unknown policy event %d\n", event);
1256 break;
1257 }
1258
1259 return 0;
1260}
1261
1262static inline int event2keytype(int event)
1263{
1264 switch (event) {
1265 case XFRM_SAP_DELETED:
1266 return SADB_DELETE;
1267 case XFRM_SAP_ADDED:
1268 return SADB_ADD;
1269 case XFRM_SAP_UPDATED:
1270 return SADB_UPDATE;
1271 case XFRM_SAP_EXPIRED:
1272 return SADB_EXPIRE;
1273 default:
1274 printk("pfkey: Unknown SA event %d\n", event);
1275 break;
1276 }
1277
1278 return 0;
1279}
1280
1281/* ADD/UPD/DEL */
1282static int key_notify_sa(struct xfrm_state *x, struct km_event *c)
1283{
1284 struct sk_buff *skb;
1285 struct sadb_msg *hdr;
1286 int hsc = 3;
1287
1288 if (c->event == XFRM_SAP_DELETED)
1289 hsc = 0;
1290
1291 if (c->event == XFRM_SAP_EXPIRED) {
1292 if (c->data)
1293 hsc = 2;
1294 else
1295 hsc = 1;
1296 }
1297
1298 skb = pfkey_xfrm_state2msg(x, 0, hsc);
1299
1300 if (IS_ERR(skb))
1301 return PTR_ERR(skb);
1302
1303 hdr = (struct sadb_msg *) skb->data;
1304 hdr->sadb_msg_version = PF_KEY_V2;
1305 hdr->sadb_msg_type = event2keytype(c->event);
1306 hdr->sadb_msg_satype = pfkey_proto2satype(x->id.proto);
1307 hdr->sadb_msg_errno = 0;
1308 hdr->sadb_msg_reserved = 0;
1309 hdr->sadb_msg_seq = c->seq;
1310 hdr->sadb_msg_pid = c->pid;
1311
1312 pfkey_broadcast(skb, GFP_ATOMIC, BROADCAST_ALL, NULL);
1313
1314 return 0;
1315}
1243 1316
1244static int pfkey_add(struct sock *sk, struct sk_buff *skb, struct sadb_msg *hdr, void **ext_hdrs) 1317static int pfkey_add(struct sock *sk, struct sk_buff *skb, struct sadb_msg *hdr, void **ext_hdrs)
1245{ 1318{
1246 struct sk_buff *out_skb;
1247 struct sadb_msg *out_hdr;
1248 struct xfrm_state *x; 1319 struct xfrm_state *x;
1249 int err; 1320 int err;
1321 struct km_event c;
1250 1322
1251 xfrm_probe_algs(); 1323 xfrm_probe_algs();
1252 1324
@@ -1254,6 +1326,7 @@ static int pfkey_add(struct sock *sk, struct sk_buff *skb, struct sadb_msg *hdr,
1254 if (IS_ERR(x)) 1326 if (IS_ERR(x))
1255 return PTR_ERR(x); 1327 return PTR_ERR(x);
1256 1328
1329 xfrm_state_hold(x);
1257 if (hdr->sadb_msg_type == SADB_ADD) 1330 if (hdr->sadb_msg_type == SADB_ADD)
1258 err = xfrm_state_add(x); 1331 err = xfrm_state_add(x);
1259 else 1332 else
@@ -1265,27 +1338,23 @@ static int pfkey_add(struct sock *sk, struct sk_buff *skb, struct sadb_msg *hdr,
1265 return err; 1338 return err;
1266 } 1339 }
1267 1340
1268 out_skb = pfkey_xfrm_state2msg(x, 0, 3); 1341 if (hdr->sadb_msg_type == SADB_ADD)
1269 if (IS_ERR(out_skb)) 1342 c.event = XFRM_SAP_ADDED;
1270 return PTR_ERR(out_skb); /* XXX Should we return 0 here ? */ 1343 else
1271 1344 c.event = XFRM_SAP_UPDATED;
1272 out_hdr = (struct sadb_msg *) out_skb->data; 1345 c.seq = hdr->sadb_msg_seq;
1273 out_hdr->sadb_msg_version = hdr->sadb_msg_version; 1346 c.pid = hdr->sadb_msg_pid;
1274 out_hdr->sadb_msg_type = hdr->sadb_msg_type; 1347 km_state_notify(x, &c);
1275 out_hdr->sadb_msg_satype = pfkey_proto2satype(x->id.proto); 1348 xfrm_state_put(x);
1276 out_hdr->sadb_msg_errno = 0;
1277 out_hdr->sadb_msg_reserved = 0;
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 1349
1283 return 0; 1350 return err;
1284} 1351}
1285 1352
1286static int pfkey_delete(struct sock *sk, struct sk_buff *skb, struct sadb_msg *hdr, void **ext_hdrs) 1353static int pfkey_delete(struct sock *sk, struct sk_buff *skb, struct sadb_msg *hdr, void **ext_hdrs)
1287{ 1354{
1288 struct xfrm_state *x; 1355 struct xfrm_state *x;
1356 struct km_event c;
1357 int err;
1289 1358
1290 if (!ext_hdrs[SADB_EXT_SA-1] || 1359 if (!ext_hdrs[SADB_EXT_SA-1] ||
1291 !present_and_same_family(ext_hdrs[SADB_EXT_ADDRESS_SRC-1], 1360 !present_and_same_family(ext_hdrs[SADB_EXT_ADDRESS_SRC-1],
@@ -1301,13 +1370,19 @@ static int pfkey_delete(struct sock *sk, struct sk_buff *skb, struct sadb_msg *h
1301 return -EPERM; 1370 return -EPERM;
1302 } 1371 }
1303 1372
1304 xfrm_state_delete(x); 1373 err = xfrm_state_delete(x);
1305 xfrm_state_put(x); 1374 if (err < 0) {
1375 xfrm_state_put(x);
1376 return err;
1377 }
1306 1378
1307 pfkey_broadcast(skb_clone(skb, GFP_KERNEL), GFP_KERNEL, 1379 c.seq = hdr->sadb_msg_seq;
1308 BROADCAST_ALL, sk); 1380 c.pid = hdr->sadb_msg_pid;
1381 c.event = XFRM_SAP_DELETED;
1382 km_state_notify(x, &c);
1383 xfrm_state_put(x);
1309 1384
1310 return 0; 1385 return err;
1311} 1386}
1312 1387
1313static int pfkey_get(struct sock *sk, struct sk_buff *skb, struct sadb_msg *hdr, void **ext_hdrs) 1388static int pfkey_get(struct sock *sk, struct sk_buff *skb, struct sadb_msg *hdr, void **ext_hdrs)
@@ -1445,28 +1520,42 @@ static int pfkey_register(struct sock *sk, struct sk_buff *skb, struct sadb_msg
1445 return 0; 1520 return 0;
1446} 1521}
1447 1522
1523static int key_notify_sa_flush(struct km_event *c)
1524{
1525 struct sk_buff *skb;
1526 struct sadb_msg *hdr;
1527
1528 skb = alloc_skb(sizeof(struct sadb_msg) + 16, GFP_ATOMIC);
1529 if (!skb)
1530 return -ENOBUFS;
1531 hdr = (struct sadb_msg *) skb_put(skb, sizeof(struct sadb_msg));
1532 hdr->sadb_msg_satype = pfkey_proto2satype(c->data);
1533 hdr->sadb_msg_seq = c->seq;
1534 hdr->sadb_msg_pid = c->pid;
1535 hdr->sadb_msg_version = PF_KEY_V2;
1536 hdr->sadb_msg_errno = (uint8_t) 0;
1537 hdr->sadb_msg_len = (sizeof(struct sadb_msg) / sizeof(uint64_t));
1538
1539 pfkey_broadcast(skb, GFP_ATOMIC, BROADCAST_ALL, NULL);
1540
1541 return 0;
1542}
1543
1448static int pfkey_flush(struct sock *sk, struct sk_buff *skb, struct sadb_msg *hdr, void **ext_hdrs) 1544static int pfkey_flush(struct sock *sk, struct sk_buff *skb, struct sadb_msg *hdr, void **ext_hdrs)
1449{ 1545{
1450 unsigned proto; 1546 unsigned proto;
1451 struct sk_buff *skb_out; 1547 struct km_event c;
1452 struct sadb_msg *hdr_out;
1453 1548
1454 proto = pfkey_satype2proto(hdr->sadb_msg_satype); 1549 proto = pfkey_satype2proto(hdr->sadb_msg_satype);
1455 if (proto == 0) 1550 if (proto == 0)
1456 return -EINVAL; 1551 return -EINVAL;
1457 1552
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); 1553 xfrm_state_flush(proto);
1463 1554 c.data = proto;
1464 hdr_out = (struct sadb_msg *) skb_put(skb_out, sizeof(struct sadb_msg)); 1555 c.seq = hdr->sadb_msg_seq;
1465 pfkey_hdr_dup(hdr_out, hdr); 1556 c.pid = hdr->sadb_msg_pid;
1466 hdr_out->sadb_msg_errno = (uint8_t) 0; 1557 c.event = XFRM_SAP_FLUSHED;
1467 hdr_out->sadb_msg_len = (sizeof(struct sadb_msg) / sizeof(uint64_t)); 1558 km_state_notify(NULL, &c);
1468
1469 pfkey_broadcast(skb_out, GFP_KERNEL, BROADCAST_ALL, NULL);
1470 1559
1471 return 0; 1560 return 0;
1472} 1561}
@@ -1859,6 +1948,35 @@ static void pfkey_xfrm_policy2msg(struct sk_buff *skb, struct xfrm_policy *xp, i
1859 hdr->sadb_msg_reserved = atomic_read(&xp->refcnt); 1948 hdr->sadb_msg_reserved = atomic_read(&xp->refcnt);
1860} 1949}
1861 1950
1951static int key_notify_policy(struct xfrm_policy *xp, int dir, struct km_event *c)
1952{
1953 struct sk_buff *out_skb;
1954 struct sadb_msg *out_hdr;
1955 int err;
1956
1957 out_skb = pfkey_xfrm_policy2msg_prep(xp);
1958 if (IS_ERR(out_skb)) {
1959 err = PTR_ERR(out_skb);
1960 goto out;
1961 }
1962 pfkey_xfrm_policy2msg(out_skb, xp, dir);
1963
1964 out_hdr = (struct sadb_msg *) out_skb->data;
1965 out_hdr->sadb_msg_version = PF_KEY_V2;
1966
1967 if (c->data && c->event == XFRM_SAP_DELETED)
1968 out_hdr->sadb_msg_type = SADB_X_SPDDELETE2;
1969 else
1970 out_hdr->sadb_msg_type = event2poltype(c->event);
1971 out_hdr->sadb_msg_errno = 0;
1972 out_hdr->sadb_msg_seq = c->seq;
1973 out_hdr->sadb_msg_pid = c->pid;
1974 pfkey_broadcast(out_skb, GFP_ATOMIC, BROADCAST_ALL, NULL);
1975out:
1976 return 0;
1977
1978}
1979
1862static int pfkey_spdadd(struct sock *sk, struct sk_buff *skb, struct sadb_msg *hdr, void **ext_hdrs) 1980static int pfkey_spdadd(struct sock *sk, struct sk_buff *skb, struct sadb_msg *hdr, void **ext_hdrs)
1863{ 1981{
1864 int err; 1982 int err;
@@ -1866,8 +1984,7 @@ static int pfkey_spdadd(struct sock *sk, struct sk_buff *skb, struct sadb_msg *h
1866 struct sadb_address *sa; 1984 struct sadb_address *sa;
1867 struct sadb_x_policy *pol; 1985 struct sadb_x_policy *pol;
1868 struct xfrm_policy *xp; 1986 struct xfrm_policy *xp;
1869 struct sk_buff *out_skb; 1987 struct km_event c;
1870 struct sadb_msg *out_hdr;
1871 1988
1872 if (!present_and_same_family(ext_hdrs[SADB_EXT_ADDRESS_SRC-1], 1989 if (!present_and_same_family(ext_hdrs[SADB_EXT_ADDRESS_SRC-1],
1873 ext_hdrs[SADB_EXT_ADDRESS_DST-1]) || 1990 ext_hdrs[SADB_EXT_ADDRESS_DST-1]) ||
@@ -1935,31 +2052,23 @@ static int pfkey_spdadd(struct sock *sk, struct sk_buff *skb, struct sadb_msg *h
1935 (err = parse_ipsecrequests(xp, pol)) < 0) 2052 (err = parse_ipsecrequests(xp, pol)) < 0)
1936 goto out; 2053 goto out;
1937 2054
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, 2055 err = xfrm_policy_insert(pol->sadb_x_policy_dir-1, xp,
1945 hdr->sadb_msg_type != SADB_X_SPDUPDATE); 2056 hdr->sadb_msg_type != SADB_X_SPDUPDATE);
1946 if (err) { 2057 if (err) {
1947 kfree_skb(out_skb); 2058 kfree(xp);
1948 goto out; 2059 return err;
1949 } 2060 }
1950 2061
1951 pfkey_xfrm_policy2msg(out_skb, xp, pol->sadb_x_policy_dir-1); 2062 if (hdr->sadb_msg_type == SADB_X_SPDUPDATE)
2063 c.event = XFRM_SAP_UPDATED;
2064 else
2065 c.event = XFRM_SAP_ADDED;
1952 2066
1953 xfrm_pol_put(xp); 2067 c.seq = hdr->sadb_msg_seq;
2068 c.pid = hdr->sadb_msg_pid;
1954 2069
1955 out_hdr = (struct sadb_msg *) out_skb->data; 2070 km_policy_notify(xp, pol->sadb_x_policy_dir-1, &c);
1956 out_hdr->sadb_msg_version = hdr->sadb_msg_version; 2071 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; 2072 return 0;
1964 2073
1965out: 2074out:
@@ -1973,9 +2082,8 @@ static int pfkey_spddelete(struct sock *sk, struct sk_buff *skb, struct sadb_msg
1973 struct sadb_address *sa; 2082 struct sadb_address *sa;
1974 struct sadb_x_policy *pol; 2083 struct sadb_x_policy *pol;
1975 struct xfrm_policy *xp; 2084 struct xfrm_policy *xp;
1976 struct sk_buff *out_skb;
1977 struct sadb_msg *out_hdr;
1978 struct xfrm_selector sel; 2085 struct xfrm_selector sel;
2086 struct km_event c;
1979 2087
1980 if (!present_and_same_family(ext_hdrs[SADB_EXT_ADDRESS_SRC-1], 2088 if (!present_and_same_family(ext_hdrs[SADB_EXT_ADDRESS_SRC-1],
1981 ext_hdrs[SADB_EXT_ADDRESS_DST-1]) || 2089 ext_hdrs[SADB_EXT_ADDRESS_DST-1]) ||
@@ -2010,25 +2118,40 @@ static int pfkey_spddelete(struct sock *sk, struct sk_buff *skb, struct sadb_msg
2010 2118
2011 err = 0; 2119 err = 0;
2012 2120
2121 c.seq = hdr->sadb_msg_seq;
2122 c.pid = hdr->sadb_msg_pid;
2123 c.event = XFRM_SAP_DELETED;
2124 km_policy_notify(xp, pol->sadb_x_policy_dir-1, &c);
2125
2126 xfrm_pol_put(xp);
2127 return err;
2128}
2129
2130static int key_pol_get_resp(struct sock *sk, struct xfrm_policy *xp, struct sadb_msg *hdr, int dir)
2131{
2132 int err;
2133 struct sk_buff *out_skb;
2134 struct sadb_msg *out_hdr;
2135 err = 0;
2136
2013 out_skb = pfkey_xfrm_policy2msg_prep(xp); 2137 out_skb = pfkey_xfrm_policy2msg_prep(xp);
2014 if (IS_ERR(out_skb)) { 2138 if (IS_ERR(out_skb)) {
2015 err = PTR_ERR(out_skb); 2139 err = PTR_ERR(out_skb);
2016 goto out; 2140 goto out;
2017 } 2141 }
2018 pfkey_xfrm_policy2msg(out_skb, xp, pol->sadb_x_policy_dir-1); 2142 pfkey_xfrm_policy2msg(out_skb, xp, dir);
2019 2143
2020 out_hdr = (struct sadb_msg *) out_skb->data; 2144 out_hdr = (struct sadb_msg *) out_skb->data;
2021 out_hdr->sadb_msg_version = hdr->sadb_msg_version; 2145 out_hdr->sadb_msg_version = hdr->sadb_msg_version;
2022 out_hdr->sadb_msg_type = SADB_X_SPDDELETE; 2146 out_hdr->sadb_msg_type = hdr->sadb_msg_type;
2023 out_hdr->sadb_msg_satype = 0; 2147 out_hdr->sadb_msg_satype = 0;
2024 out_hdr->sadb_msg_errno = 0; 2148 out_hdr->sadb_msg_errno = 0;
2025 out_hdr->sadb_msg_seq = hdr->sadb_msg_seq; 2149 out_hdr->sadb_msg_seq = hdr->sadb_msg_seq;
2026 out_hdr->sadb_msg_pid = hdr->sadb_msg_pid; 2150 out_hdr->sadb_msg_pid = hdr->sadb_msg_pid;
2027 pfkey_broadcast(out_skb, GFP_ATOMIC, BROADCAST_ALL, sk); 2151 pfkey_broadcast(out_skb, GFP_ATOMIC, BROADCAST_ONE, sk);
2028 err = 0; 2152 err = 0;
2029 2153
2030out: 2154out:
2031 xfrm_pol_put(xp);
2032 return err; 2155 return err;
2033} 2156}
2034 2157
@@ -2037,8 +2160,7 @@ static int pfkey_spdget(struct sock *sk, struct sk_buff *skb, struct sadb_msg *h
2037 int err; 2160 int err;
2038 struct sadb_x_policy *pol; 2161 struct sadb_x_policy *pol;
2039 struct xfrm_policy *xp; 2162 struct xfrm_policy *xp;
2040 struct sk_buff *out_skb; 2163 struct km_event c;
2041 struct sadb_msg *out_hdr;
2042 2164
2043 if ((pol = ext_hdrs[SADB_X_EXT_POLICY-1]) == NULL) 2165 if ((pol = ext_hdrs[SADB_X_EXT_POLICY-1]) == NULL)
2044 return -EINVAL; 2166 return -EINVAL;
@@ -2050,24 +2172,16 @@ static int pfkey_spdget(struct sock *sk, struct sk_buff *skb, struct sadb_msg *h
2050 2172
2051 err = 0; 2173 err = 0;
2052 2174
2053 out_skb = pfkey_xfrm_policy2msg_prep(xp); 2175 c.seq = hdr->sadb_msg_seq;
2054 if (IS_ERR(out_skb)) { 2176 c.pid = hdr->sadb_msg_pid;
2055 err = PTR_ERR(out_skb); 2177 if (hdr->sadb_msg_type == SADB_X_SPDDELETE2) {
2056 goto out; 2178 c.data = 1; // to signal pfkey of SADB_X_SPDDELETE2
2179 c.event = XFRM_SAP_DELETED;
2180 km_policy_notify(xp, pol->sadb_x_policy_dir-1, &c);
2181 } else {
2182 err = key_pol_get_resp(sk, xp, hdr, pol->sadb_x_policy_dir-1);
2057 } 2183 }
2058 pfkey_xfrm_policy2msg(out_skb, xp, pol->sadb_x_policy_dir-1);
2059 2184
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); 2185 xfrm_pol_put(xp);
2072 return err; 2186 return err;
2073} 2187}
@@ -2102,22 +2216,34 @@ static int pfkey_spddump(struct sock *sk, struct sk_buff *skb, struct sadb_msg *
2102 return xfrm_policy_walk(dump_sp, &data); 2216 return xfrm_policy_walk(dump_sp, &data);
2103} 2217}
2104 2218
2105static int pfkey_spdflush(struct sock *sk, struct sk_buff *skb, struct sadb_msg *hdr, void **ext_hdrs) 2219static int key_notify_policy_flush(struct km_event *c)
2106{ 2220{
2107 struct sk_buff *skb_out; 2221 struct sk_buff *skb_out;
2108 struct sadb_msg *hdr_out; 2222 struct sadb_msg *hdr;
2109 2223
2110 skb_out = alloc_skb(sizeof(struct sadb_msg) + 16, GFP_KERNEL); 2224 skb_out = alloc_skb(sizeof(struct sadb_msg) + 16, GFP_ATOMIC);
2111 if (!skb_out) 2225 if (!skb_out)
2112 return -ENOBUFS; 2226 return -ENOBUFS;
2227 hdr = (struct sadb_msg *) skb_put(skb_out, sizeof(struct sadb_msg));
2228 hdr->sadb_msg_seq = c->seq;
2229 hdr->sadb_msg_pid = c->pid;
2230 hdr->sadb_msg_version = PF_KEY_V2;
2231 hdr->sadb_msg_errno = (uint8_t) 0;
2232 hdr->sadb_msg_len = (sizeof(struct sadb_msg) / sizeof(uint64_t));
2233 pfkey_broadcast(skb_out, GFP_ATOMIC, BROADCAST_ALL, NULL);
2234 return 0;
2113 2235
2114 xfrm_policy_flush(); 2236}
2237
2238static int pfkey_spdflush(struct sock *sk, struct sk_buff *skb, struct sadb_msg *hdr, void **ext_hdrs)
2239{
2240 struct km_event c;
2115 2241
2116 hdr_out = (struct sadb_msg *) skb_put(skb_out, sizeof(struct sadb_msg)); 2242 xfrm_policy_flush();
2117 pfkey_hdr_dup(hdr_out, hdr); 2243 c.event = XFRM_SAP_FLUSHED;
2118 hdr_out->sadb_msg_errno = (uint8_t) 0; 2244 c.pid = hdr->sadb_msg_pid;
2119 hdr_out->sadb_msg_len = (sizeof(struct sadb_msg) / sizeof(uint64_t)); 2245 c.seq = hdr->sadb_msg_seq;
2120 pfkey_broadcast(skb_out, GFP_KERNEL, BROADCAST_ALL, NULL); 2246 km_policy_notify(NULL, 0, &c);
2121 2247
2122 return 0; 2248 return 0;
2123} 2249}
@@ -2317,11 +2443,23 @@ static void dump_esp_combs(struct sk_buff *skb, struct xfrm_tmpl *t)
2317 } 2443 }
2318} 2444}
2319 2445
2320static int pfkey_send_notify(struct xfrm_state *x, int hard) 2446static int key_notify_policy_expire(struct xfrm_policy *xp, struct km_event *c)
2447{
2448 return 0;
2449}
2450
2451static int key_notify_sa_expire(struct xfrm_state *x, struct km_event *c)
2321{ 2452{
2322 struct sk_buff *out_skb; 2453 struct sk_buff *out_skb;
2323 struct sadb_msg *out_hdr; 2454 struct sadb_msg *out_hdr;
2324 int hsc = (hard ? 2 : 1); 2455 int hard;
2456 int hsc;
2457
2458 hard = c->data;
2459 if (hard)
2460 hsc = 2;
2461 else
2462 hsc = 1;
2325 2463
2326 out_skb = pfkey_xfrm_state2msg(x, 0, hsc); 2464 out_skb = pfkey_xfrm_state2msg(x, 0, hsc);
2327 if (IS_ERR(out_skb)) 2465 if (IS_ERR(out_skb))
@@ -2340,6 +2478,44 @@ static int pfkey_send_notify(struct xfrm_state *x, int hard)
2340 return 0; 2478 return 0;
2341} 2479}
2342 2480
2481static int pfkey_send_notify(struct xfrm_state *x, struct km_event *c)
2482{
2483 switch (c->event) {
2484 case XFRM_SAP_EXPIRED:
2485 return key_notify_sa_expire(x, c);
2486 case XFRM_SAP_DELETED:
2487 case XFRM_SAP_ADDED:
2488 case XFRM_SAP_UPDATED:
2489 return key_notify_sa(x, c);
2490 case XFRM_SAP_FLUSHED:
2491 return key_notify_sa_flush(c);
2492 default:
2493 printk("pfkey: Unknown SA event %d\n", c->event);
2494 break;
2495 }
2496
2497 return 0;
2498}
2499
2500static int pfkey_send_policy_notify(struct xfrm_policy *xp, int dir, struct km_event *c)
2501{
2502 switch (c->event) {
2503 case XFRM_SAP_EXPIRED:
2504 return key_notify_policy_expire(xp, c);
2505 case XFRM_SAP_DELETED:
2506 case XFRM_SAP_ADDED:
2507 case XFRM_SAP_UPDATED:
2508 return key_notify_policy(xp, dir, c);
2509 case XFRM_SAP_FLUSHED:
2510 return key_notify_policy_flush(c);
2511 default:
2512 printk("pfkey: Unknown policy event %d\n", c->event);
2513 break;
2514 }
2515
2516 return 0;
2517}
2518
2343static u32 get_acqseq(void) 2519static u32 get_acqseq(void)
2344{ 2520{
2345 u32 res; 2521 u32 res;
@@ -2856,6 +3032,7 @@ static struct xfrm_mgr pfkeyv2_mgr =
2856 .acquire = pfkey_send_acquire, 3032 .acquire = pfkey_send_acquire,
2857 .compile_policy = pfkey_compile_policy, 3033 .compile_policy = pfkey_compile_policy,
2858 .new_mapping = pfkey_send_new_mapping, 3034 .new_mapping = pfkey_send_new_mapping,
3035 .notify_policy = pfkey_send_policy_notify,
2859}; 3036};
2860 3037
2861static void __exit ipsec_pfkey_exit(void) 3038static void __exit ipsec_pfkey_exit(void)