aboutsummaryrefslogtreecommitdiffstats
path: root/net/xfrm/xfrm_user.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2008-04-18 21:02:35 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2008-04-18 21:02:35 -0400
commit334d094504c2fe1c44211ecb49146ae6bca8c321 (patch)
treed3c0f68e4b9f8e3d2ccc39e7dfe5de0534a5fad9 /net/xfrm/xfrm_user.c
parentd1a4be630fb068f251d64b62919f143c49ca8057 (diff)
parentd1643d24c61b725bef399cc1cf2944b4c9c23177 (diff)
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-2.6.26
* git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-2.6.26: (1090 commits) [NET]: Fix and allocate less memory for ->priv'less netdevices [IPV6]: Fix dangling references on error in fib6_add(). [NETLABEL]: Fix NULL deref in netlbl_unlabel_staticlist_gen() if ifindex not found [PKT_SCHED]: Fix datalen check in tcf_simp_init(). [INET]: Uninline the __inet_inherit_port call. [INET]: Drop the inet_inherit_port() call. SCTP: Initialize partial_bytes_acked to 0, when all of the data is acked. [netdrvr] forcedeth: internal simplifications; changelog removal phylib: factor out get_phy_id from within get_phy_device PHY: add BCM5464 support to broadcom PHY driver cxgb3: Fix __must_check warning with dev_dbg. tc35815: Statistics cleanup natsemi: fix MMIO for PPC 44x platforms [TIPC]: Cleanup of TIPC reference table code [TIPC]: Optimized initialization of TIPC reference table [TIPC]: Remove inlining of reference table locking routines e1000: convert uint16_t style integers to u16 ixgb: convert uint16_t style integers to u16 sb1000.c: make const arrays static sb1000.c: stop inlining largish static functions ...
Diffstat (limited to 'net/xfrm/xfrm_user.c')
-rw-r--r--net/xfrm/xfrm_user.c100
1 files changed, 58 insertions, 42 deletions
diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c
index 019d21de19b3..1810f5645bb5 100644
--- a/net/xfrm/xfrm_user.c
+++ b/net/xfrm/xfrm_user.c
@@ -529,8 +529,6 @@ struct xfrm_dump_info {
529 struct sk_buff *out_skb; 529 struct sk_buff *out_skb;
530 u32 nlmsg_seq; 530 u32 nlmsg_seq;
531 u16 nlmsg_flags; 531 u16 nlmsg_flags;
532 int start_idx;
533 int this_idx;
534}; 532};
535 533
536static int copy_sec_ctx(struct xfrm_sec_ctx *s, struct sk_buff *skb) 534static int copy_sec_ctx(struct xfrm_sec_ctx *s, struct sk_buff *skb)
@@ -597,9 +595,6 @@ static int dump_one_state(struct xfrm_state *x, int count, void *ptr)
597 struct nlmsghdr *nlh; 595 struct nlmsghdr *nlh;
598 int err; 596 int err;
599 597
600 if (sp->this_idx < sp->start_idx)
601 goto out;
602
603 nlh = nlmsg_put(skb, NETLINK_CB(in_skb).pid, sp->nlmsg_seq, 598 nlh = nlmsg_put(skb, NETLINK_CB(in_skb).pid, sp->nlmsg_seq,
604 XFRM_MSG_NEWSA, sizeof(*p), sp->nlmsg_flags); 599 XFRM_MSG_NEWSA, sizeof(*p), sp->nlmsg_flags);
605 if (nlh == NULL) 600 if (nlh == NULL)
@@ -612,8 +607,6 @@ static int dump_one_state(struct xfrm_state *x, int count, void *ptr)
612 goto nla_put_failure; 607 goto nla_put_failure;
613 608
614 nlmsg_end(skb, nlh); 609 nlmsg_end(skb, nlh);
615out:
616 sp->this_idx++;
617 return 0; 610 return 0;
618 611
619nla_put_failure: 612nla_put_failure:
@@ -621,18 +614,32 @@ nla_put_failure:
621 return err; 614 return err;
622} 615}
623 616
617static int xfrm_dump_sa_done(struct netlink_callback *cb)
618{
619 struct xfrm_state_walk *walk = (struct xfrm_state_walk *) &cb->args[1];
620 xfrm_state_walk_done(walk);
621 return 0;
622}
623
624static int xfrm_dump_sa(struct sk_buff *skb, struct netlink_callback *cb) 624static int xfrm_dump_sa(struct sk_buff *skb, struct netlink_callback *cb)
625{ 625{
626 struct xfrm_state_walk *walk = (struct xfrm_state_walk *) &cb->args[1];
626 struct xfrm_dump_info info; 627 struct xfrm_dump_info info;
627 628
629 BUILD_BUG_ON(sizeof(struct xfrm_state_walk) >
630 sizeof(cb->args) - sizeof(cb->args[0]));
631
628 info.in_skb = cb->skb; 632 info.in_skb = cb->skb;
629 info.out_skb = skb; 633 info.out_skb = skb;
630 info.nlmsg_seq = cb->nlh->nlmsg_seq; 634 info.nlmsg_seq = cb->nlh->nlmsg_seq;
631 info.nlmsg_flags = NLM_F_MULTI; 635 info.nlmsg_flags = NLM_F_MULTI;
632 info.this_idx = 0; 636
633 info.start_idx = cb->args[0]; 637 if (!cb->args[0]) {
634 (void) xfrm_state_walk(0, dump_one_state, &info); 638 cb->args[0] = 1;
635 cb->args[0] = info.this_idx; 639 xfrm_state_walk_init(walk, 0);
640 }
641
642 (void) xfrm_state_walk(walk, dump_one_state, &info);
636 643
637 return skb->len; 644 return skb->len;
638} 645}
@@ -651,7 +658,6 @@ static struct sk_buff *xfrm_state_netlink(struct sk_buff *in_skb,
651 info.out_skb = skb; 658 info.out_skb = skb;
652 info.nlmsg_seq = seq; 659 info.nlmsg_seq = seq;
653 info.nlmsg_flags = 0; 660 info.nlmsg_flags = 0;
654 info.this_idx = info.start_idx = 0;
655 661
656 if (dump_one_state(x, 0, &info)) { 662 if (dump_one_state(x, 0, &info)) {
657 kfree_skb(skb); 663 kfree_skb(skb);
@@ -953,7 +959,7 @@ static int copy_from_user_sec_ctx(struct xfrm_policy *pol, struct nlattr **attrs
953 return 0; 959 return 0;
954 960
955 uctx = nla_data(rt); 961 uctx = nla_data(rt);
956 return security_xfrm_policy_alloc(pol, uctx); 962 return security_xfrm_policy_alloc(&pol->security, uctx);
957} 963}
958 964
959static void copy_templates(struct xfrm_policy *xp, struct xfrm_user_tmpl *ut, 965static void copy_templates(struct xfrm_policy *xp, struct xfrm_user_tmpl *ut,
@@ -1137,7 +1143,7 @@ static int xfrm_add_policy(struct sk_buff *skb, struct nlmsghdr *nlh,
1137 NETLINK_CB(skb).sid); 1143 NETLINK_CB(skb).sid);
1138 1144
1139 if (err) { 1145 if (err) {
1140 security_xfrm_policy_free(xp); 1146 security_xfrm_policy_free(xp->security);
1141 kfree(xp); 1147 kfree(xp);
1142 return err; 1148 return err;
1143 } 1149 }
@@ -1229,9 +1235,6 @@ static int dump_one_policy(struct xfrm_policy *xp, int dir, int count, void *ptr
1229 struct sk_buff *skb = sp->out_skb; 1235 struct sk_buff *skb = sp->out_skb;
1230 struct nlmsghdr *nlh; 1236 struct nlmsghdr *nlh;
1231 1237
1232 if (sp->this_idx < sp->start_idx)
1233 goto out;
1234
1235 nlh = nlmsg_put(skb, NETLINK_CB(in_skb).pid, sp->nlmsg_seq, 1238 nlh = nlmsg_put(skb, NETLINK_CB(in_skb).pid, sp->nlmsg_seq,
1236 XFRM_MSG_NEWPOLICY, sizeof(*p), sp->nlmsg_flags); 1239 XFRM_MSG_NEWPOLICY, sizeof(*p), sp->nlmsg_flags);
1237 if (nlh == NULL) 1240 if (nlh == NULL)
@@ -1247,8 +1250,6 @@ static int dump_one_policy(struct xfrm_policy *xp, int dir, int count, void *ptr
1247 goto nlmsg_failure; 1250 goto nlmsg_failure;
1248 1251
1249 nlmsg_end(skb, nlh); 1252 nlmsg_end(skb, nlh);
1250out:
1251 sp->this_idx++;
1252 return 0; 1253 return 0;
1253 1254
1254nlmsg_failure: 1255nlmsg_failure:
@@ -1256,21 +1257,33 @@ nlmsg_failure:
1256 return -EMSGSIZE; 1257 return -EMSGSIZE;
1257} 1258}
1258 1259
1260static int xfrm_dump_policy_done(struct netlink_callback *cb)
1261{
1262 struct xfrm_policy_walk *walk = (struct xfrm_policy_walk *) &cb->args[1];
1263
1264 xfrm_policy_walk_done(walk);
1265 return 0;
1266}
1267
1259static int xfrm_dump_policy(struct sk_buff *skb, struct netlink_callback *cb) 1268static int xfrm_dump_policy(struct sk_buff *skb, struct netlink_callback *cb)
1260{ 1269{
1270 struct xfrm_policy_walk *walk = (struct xfrm_policy_walk *) &cb->args[1];
1261 struct xfrm_dump_info info; 1271 struct xfrm_dump_info info;
1262 1272
1273 BUILD_BUG_ON(sizeof(struct xfrm_policy_walk) >
1274 sizeof(cb->args) - sizeof(cb->args[0]));
1275
1263 info.in_skb = cb->skb; 1276 info.in_skb = cb->skb;
1264 info.out_skb = skb; 1277 info.out_skb = skb;
1265 info.nlmsg_seq = cb->nlh->nlmsg_seq; 1278 info.nlmsg_seq = cb->nlh->nlmsg_seq;
1266 info.nlmsg_flags = NLM_F_MULTI; 1279 info.nlmsg_flags = NLM_F_MULTI;
1267 info.this_idx = 0; 1280
1268 info.start_idx = cb->args[0]; 1281 if (!cb->args[0]) {
1269 (void) xfrm_policy_walk(XFRM_POLICY_TYPE_MAIN, dump_one_policy, &info); 1282 cb->args[0] = 1;
1270#ifdef CONFIG_XFRM_SUB_POLICY 1283 xfrm_policy_walk_init(walk, XFRM_POLICY_TYPE_ANY);
1271 (void) xfrm_policy_walk(XFRM_POLICY_TYPE_SUB, dump_one_policy, &info); 1284 }
1272#endif 1285
1273 cb->args[0] = info.this_idx; 1286 (void) xfrm_policy_walk(walk, dump_one_policy, &info);
1274 1287
1275 return skb->len; 1288 return skb->len;
1276} 1289}
@@ -1290,7 +1303,6 @@ static struct sk_buff *xfrm_policy_netlink(struct sk_buff *in_skb,
1290 info.out_skb = skb; 1303 info.out_skb = skb;
1291 info.nlmsg_seq = seq; 1304 info.nlmsg_seq = seq;
1292 info.nlmsg_flags = 0; 1305 info.nlmsg_flags = 0;
1293 info.this_idx = info.start_idx = 0;
1294 1306
1295 if (dump_one_policy(xp, dir, 0, &info) < 0) { 1307 if (dump_one_policy(xp, dir, 0, &info) < 0) {
1296 kfree_skb(skb); 1308 kfree_skb(skb);
@@ -1325,22 +1337,23 @@ static int xfrm_get_policy(struct sk_buff *skb, struct nlmsghdr *nlh,
1325 xp = xfrm_policy_byid(type, p->dir, p->index, delete, &err); 1337 xp = xfrm_policy_byid(type, p->dir, p->index, delete, &err);
1326 else { 1338 else {
1327 struct nlattr *rt = attrs[XFRMA_SEC_CTX]; 1339 struct nlattr *rt = attrs[XFRMA_SEC_CTX];
1328 struct xfrm_policy tmp; 1340 struct xfrm_sec_ctx *ctx;
1329 1341
1330 err = verify_sec_ctx_len(attrs); 1342 err = verify_sec_ctx_len(attrs);
1331 if (err) 1343 if (err)
1332 return err; 1344 return err;
1333 1345
1334 memset(&tmp, 0, sizeof(struct xfrm_policy)); 1346 ctx = NULL;
1335 if (rt) { 1347 if (rt) {
1336 struct xfrm_user_sec_ctx *uctx = nla_data(rt); 1348 struct xfrm_user_sec_ctx *uctx = nla_data(rt);
1337 1349
1338 if ((err = security_xfrm_policy_alloc(&tmp, uctx))) 1350 err = security_xfrm_policy_alloc(&ctx, uctx);
1351 if (err)
1339 return err; 1352 return err;
1340 } 1353 }
1341 xp = xfrm_policy_bysel_ctx(type, p->dir, &p->sel, tmp.security, 1354 xp = xfrm_policy_bysel_ctx(type, p->dir, &p->sel, ctx,
1342 delete, &err); 1355 delete, &err);
1343 security_xfrm_policy_free(&tmp); 1356 security_xfrm_policy_free(ctx);
1344 } 1357 }
1345 if (xp == NULL) 1358 if (xp == NULL)
1346 return -ENOENT; 1359 return -ENOENT;
@@ -1560,26 +1573,26 @@ static int xfrm_add_pol_expire(struct sk_buff *skb, struct nlmsghdr *nlh,
1560 xp = xfrm_policy_byid(type, p->dir, p->index, 0, &err); 1573 xp = xfrm_policy_byid(type, p->dir, p->index, 0, &err);
1561 else { 1574 else {
1562 struct nlattr *rt = attrs[XFRMA_SEC_CTX]; 1575 struct nlattr *rt = attrs[XFRMA_SEC_CTX];
1563 struct xfrm_policy tmp; 1576 struct xfrm_sec_ctx *ctx;
1564 1577
1565 err = verify_sec_ctx_len(attrs); 1578 err = verify_sec_ctx_len(attrs);
1566 if (err) 1579 if (err)
1567 return err; 1580 return err;
1568 1581
1569 memset(&tmp, 0, sizeof(struct xfrm_policy)); 1582 ctx = NULL;
1570 if (rt) { 1583 if (rt) {
1571 struct xfrm_user_sec_ctx *uctx = nla_data(rt); 1584 struct xfrm_user_sec_ctx *uctx = nla_data(rt);
1572 1585
1573 if ((err = security_xfrm_policy_alloc(&tmp, uctx))) 1586 err = security_xfrm_policy_alloc(&ctx, uctx);
1587 if (err)
1574 return err; 1588 return err;
1575 } 1589 }
1576 xp = xfrm_policy_bysel_ctx(type, p->dir, &p->sel, tmp.security, 1590 xp = xfrm_policy_bysel_ctx(type, p->dir, &p->sel, ctx, 0, &err);
1577 0, &err); 1591 security_xfrm_policy_free(ctx);
1578 security_xfrm_policy_free(&tmp);
1579 } 1592 }
1580
1581 if (xp == NULL) 1593 if (xp == NULL)
1582 return -ENOENT; 1594 return -ENOENT;
1595
1583 read_lock(&xp->lock); 1596 read_lock(&xp->lock);
1584 if (xp->dead) { 1597 if (xp->dead) {
1585 read_unlock(&xp->lock); 1598 read_unlock(&xp->lock);
@@ -1888,15 +1901,18 @@ static const struct nla_policy xfrma_policy[XFRMA_MAX+1] = {
1888static struct xfrm_link { 1901static struct xfrm_link {
1889 int (*doit)(struct sk_buff *, struct nlmsghdr *, struct nlattr **); 1902 int (*doit)(struct sk_buff *, struct nlmsghdr *, struct nlattr **);
1890 int (*dump)(struct sk_buff *, struct netlink_callback *); 1903 int (*dump)(struct sk_buff *, struct netlink_callback *);
1904 int (*done)(struct netlink_callback *);
1891} xfrm_dispatch[XFRM_NR_MSGTYPES] = { 1905} xfrm_dispatch[XFRM_NR_MSGTYPES] = {
1892 [XFRM_MSG_NEWSA - XFRM_MSG_BASE] = { .doit = xfrm_add_sa }, 1906 [XFRM_MSG_NEWSA - XFRM_MSG_BASE] = { .doit = xfrm_add_sa },
1893 [XFRM_MSG_DELSA - XFRM_MSG_BASE] = { .doit = xfrm_del_sa }, 1907 [XFRM_MSG_DELSA - XFRM_MSG_BASE] = { .doit = xfrm_del_sa },
1894 [XFRM_MSG_GETSA - XFRM_MSG_BASE] = { .doit = xfrm_get_sa, 1908 [XFRM_MSG_GETSA - XFRM_MSG_BASE] = { .doit = xfrm_get_sa,
1895 .dump = xfrm_dump_sa }, 1909 .dump = xfrm_dump_sa,
1910 .done = xfrm_dump_sa_done },
1896 [XFRM_MSG_NEWPOLICY - XFRM_MSG_BASE] = { .doit = xfrm_add_policy }, 1911 [XFRM_MSG_NEWPOLICY - XFRM_MSG_BASE] = { .doit = xfrm_add_policy },
1897 [XFRM_MSG_DELPOLICY - XFRM_MSG_BASE] = { .doit = xfrm_get_policy }, 1912 [XFRM_MSG_DELPOLICY - XFRM_MSG_BASE] = { .doit = xfrm_get_policy },
1898 [XFRM_MSG_GETPOLICY - XFRM_MSG_BASE] = { .doit = xfrm_get_policy, 1913 [XFRM_MSG_GETPOLICY - XFRM_MSG_BASE] = { .doit = xfrm_get_policy,
1899 .dump = xfrm_dump_policy }, 1914 .dump = xfrm_dump_policy,
1915 .done = xfrm_dump_policy_done },
1900 [XFRM_MSG_ALLOCSPI - XFRM_MSG_BASE] = { .doit = xfrm_alloc_userspi }, 1916 [XFRM_MSG_ALLOCSPI - XFRM_MSG_BASE] = { .doit = xfrm_alloc_userspi },
1901 [XFRM_MSG_ACQUIRE - XFRM_MSG_BASE] = { .doit = xfrm_add_acquire }, 1917 [XFRM_MSG_ACQUIRE - XFRM_MSG_BASE] = { .doit = xfrm_add_acquire },
1902 [XFRM_MSG_EXPIRE - XFRM_MSG_BASE] = { .doit = xfrm_add_sa_expire }, 1918 [XFRM_MSG_EXPIRE - XFRM_MSG_BASE] = { .doit = xfrm_add_sa_expire },
@@ -1935,7 +1951,7 @@ static int xfrm_user_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
1935 if (link->dump == NULL) 1951 if (link->dump == NULL)
1936 return -EINVAL; 1952 return -EINVAL;
1937 1953
1938 return netlink_dump_start(xfrm_nl, skb, nlh, link->dump, NULL); 1954 return netlink_dump_start(xfrm_nl, skb, nlh, link->dump, link->done);
1939 } 1955 }
1940 1956
1941 err = nlmsg_parse(nlh, xfrm_msg_min[type], attrs, XFRMA_MAX, 1957 err = nlmsg_parse(nlh, xfrm_msg_min[type], attrs, XFRMA_MAX,