diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2008-04-18 21:02:35 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2008-04-18 21:02:35 -0400 |
commit | 334d094504c2fe1c44211ecb49146ae6bca8c321 (patch) | |
tree | d3c0f68e4b9f8e3d2ccc39e7dfe5de0534a5fad9 /net/xfrm/xfrm_user.c | |
parent | d1a4be630fb068f251d64b62919f143c49ca8057 (diff) | |
parent | d1643d24c61b725bef399cc1cf2944b4c9c23177 (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.c | 100 |
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 | ||
536 | static int copy_sec_ctx(struct xfrm_sec_ctx *s, struct sk_buff *skb) | 534 | static 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); |
615 | out: | ||
616 | sp->this_idx++; | ||
617 | return 0; | 610 | return 0; |
618 | 611 | ||
619 | nla_put_failure: | 612 | nla_put_failure: |
@@ -621,18 +614,32 @@ nla_put_failure: | |||
621 | return err; | 614 | return err; |
622 | } | 615 | } |
623 | 616 | ||
617 | static 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 | |||
624 | static int xfrm_dump_sa(struct sk_buff *skb, struct netlink_callback *cb) | 624 | static 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 | ||
959 | static void copy_templates(struct xfrm_policy *xp, struct xfrm_user_tmpl *ut, | 965 | static 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); |
1250 | out: | ||
1251 | sp->this_idx++; | ||
1252 | return 0; | 1253 | return 0; |
1253 | 1254 | ||
1254 | nlmsg_failure: | 1255 | nlmsg_failure: |
@@ -1256,21 +1257,33 @@ nlmsg_failure: | |||
1256 | return -EMSGSIZE; | 1257 | return -EMSGSIZE; |
1257 | } | 1258 | } |
1258 | 1259 | ||
1260 | static 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 | |||
1259 | static int xfrm_dump_policy(struct sk_buff *skb, struct netlink_callback *cb) | 1268 | static 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] = { | |||
1888 | static struct xfrm_link { | 1901 | static 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, |