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