aboutsummaryrefslogtreecommitdiffstats
path: root/net/xfrm/xfrm_user.c
diff options
context:
space:
mode:
authorJamal Hadi Salim <hadi@cyberus.ca>2010-02-22 06:33:00 -0500
committerDavid S. Miller <davem@davemloft.net>2010-02-22 19:21:26 -0500
commit295fae568885a93c39a0e29a9455054608b6cc0e (patch)
tree1cce881be6501a8ddad33e6ea7c6336b93e5562f /net/xfrm/xfrm_user.c
parent6f26b61e177e57a41795355f6222cf817f1212dc (diff)
xfrm: Allow user space manipulation of SPD mark
Add ability for netlink userspace to manipulate the SPD and manipulate the mark, retrieve it and get events with a defined mark, etc. Signed-off-by: Jamal Hadi Salim <hadi@cyberus.ca> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/xfrm/xfrm_user.c')
-rw-r--r--net/xfrm/xfrm_user.c31
1 files changed, 25 insertions, 6 deletions
diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c
index 303092f7088b..6106b72826d3 100644
--- a/net/xfrm/xfrm_user.c
+++ b/net/xfrm/xfrm_user.c
@@ -31,8 +31,6 @@
31#include <linux/in6.h> 31#include <linux/in6.h>
32#endif 32#endif
33 33
34#define DUMMY_MARK 0
35
36static inline int aead_len(struct xfrm_algo_aead *alg) 34static inline int aead_len(struct xfrm_algo_aead *alg)
37{ 35{
38 return sizeof(*alg) + ((alg->alg_key_len + 7) / 8); 36 return sizeof(*alg) + ((alg->alg_key_len + 7) / 8);
@@ -1234,6 +1232,8 @@ static struct xfrm_policy *xfrm_policy_construct(struct net *net, struct xfrm_us
1234 if (err) 1232 if (err)
1235 goto error; 1233 goto error;
1236 1234
1235 xfrm_mark_get(attrs, &xp->mark);
1236
1237 return xp; 1237 return xp;
1238 error: 1238 error:
1239 *errp = err; 1239 *errp = err;
@@ -1380,10 +1380,13 @@ static int dump_one_policy(struct xfrm_policy *xp, int dir, int count, void *ptr
1380 goto nlmsg_failure; 1380 goto nlmsg_failure;
1381 if (copy_to_user_policy_type(xp->type, skb) < 0) 1381 if (copy_to_user_policy_type(xp->type, skb) < 0)
1382 goto nlmsg_failure; 1382 goto nlmsg_failure;
1383 if (xfrm_mark_put(skb, &xp->mark))
1384 goto nla_put_failure;
1383 1385
1384 nlmsg_end(skb, nlh); 1386 nlmsg_end(skb, nlh);
1385 return 0; 1387 return 0;
1386 1388
1389nla_put_failure:
1387nlmsg_failure: 1390nlmsg_failure:
1388 nlmsg_cancel(skb, nlh); 1391 nlmsg_cancel(skb, nlh);
1389 return -EMSGSIZE; 1392 return -EMSGSIZE;
@@ -1455,6 +1458,8 @@ static int xfrm_get_policy(struct sk_buff *skb, struct nlmsghdr *nlh,
1455 int err; 1458 int err;
1456 struct km_event c; 1459 struct km_event c;
1457 int delete; 1460 int delete;
1461 struct xfrm_mark m;
1462 u32 mark = xfrm_mark_get(attrs, &m);
1458 1463
1459 p = nlmsg_data(nlh); 1464 p = nlmsg_data(nlh);
1460 delete = nlh->nlmsg_type == XFRM_MSG_DELPOLICY; 1465 delete = nlh->nlmsg_type == XFRM_MSG_DELPOLICY;
@@ -1468,7 +1473,7 @@ static int xfrm_get_policy(struct sk_buff *skb, struct nlmsghdr *nlh,
1468 return err; 1473 return err;
1469 1474
1470 if (p->index) 1475 if (p->index)
1471 xp = xfrm_policy_byid(net, DUMMY_MARK, type, p->dir, p->index, delete, &err); 1476 xp = xfrm_policy_byid(net, mark, type, p->dir, p->index, delete, &err);
1472 else { 1477 else {
1473 struct nlattr *rt = attrs[XFRMA_SEC_CTX]; 1478 struct nlattr *rt = attrs[XFRMA_SEC_CTX];
1474 struct xfrm_sec_ctx *ctx; 1479 struct xfrm_sec_ctx *ctx;
@@ -1485,7 +1490,7 @@ static int xfrm_get_policy(struct sk_buff *skb, struct nlmsghdr *nlh,
1485 if (err) 1490 if (err)
1486 return err; 1491 return err;
1487 } 1492 }
1488 xp = xfrm_policy_bysel_ctx(net, DUMMY_MARK, type, p->dir, &p->sel, 1493 xp = xfrm_policy_bysel_ctx(net, mark, type, p->dir, &p->sel,
1489 ctx, delete, &err); 1494 ctx, delete, &err);
1490 security_xfrm_policy_free(ctx); 1495 security_xfrm_policy_free(ctx);
1491 } 1496 }
@@ -1729,13 +1734,15 @@ static int xfrm_add_pol_expire(struct sk_buff *skb, struct nlmsghdr *nlh,
1729 struct xfrm_userpolicy_info *p = &up->pol; 1734 struct xfrm_userpolicy_info *p = &up->pol;
1730 u8 type = XFRM_POLICY_TYPE_MAIN; 1735 u8 type = XFRM_POLICY_TYPE_MAIN;
1731 int err = -ENOENT; 1736 int err = -ENOENT;
1737 struct xfrm_mark m;
1738 u32 mark = xfrm_mark_get(attrs, &m);
1732 1739
1733 err = copy_from_user_policy_type(&type, attrs); 1740 err = copy_from_user_policy_type(&type, attrs);
1734 if (err) 1741 if (err)
1735 return err; 1742 return err;
1736 1743
1737 if (p->index) 1744 if (p->index)
1738 xp = xfrm_policy_byid(net, DUMMY_MARK, type, p->dir, p->index, 0, &err); 1745 xp = xfrm_policy_byid(net, mark, type, p->dir, p->index, 0, &err);
1739 else { 1746 else {
1740 struct nlattr *rt = attrs[XFRMA_SEC_CTX]; 1747 struct nlattr *rt = attrs[XFRMA_SEC_CTX];
1741 struct xfrm_sec_ctx *ctx; 1748 struct xfrm_sec_ctx *ctx;
@@ -1752,7 +1759,7 @@ static int xfrm_add_pol_expire(struct sk_buff *skb, struct nlmsghdr *nlh,
1752 if (err) 1759 if (err)
1753 return err; 1760 return err;
1754 } 1761 }
1755 xp = xfrm_policy_bysel_ctx(net, DUMMY_MARK, type, p->dir, 1762 xp = xfrm_policy_bysel_ctx(net, mark, type, p->dir,
1756 &p->sel, ctx, 0, &err); 1763 &p->sel, ctx, 0, &err);
1757 security_xfrm_policy_free(ctx); 1764 security_xfrm_policy_free(ctx);
1758 } 1765 }
@@ -2424,9 +2431,12 @@ static int build_acquire(struct sk_buff *skb, struct xfrm_state *x,
2424 goto nlmsg_failure; 2431 goto nlmsg_failure;
2425 if (copy_to_user_policy_type(xp->type, skb) < 0) 2432 if (copy_to_user_policy_type(xp->type, skb) < 0)
2426 goto nlmsg_failure; 2433 goto nlmsg_failure;
2434 if (xfrm_mark_put(skb, &xp->mark))
2435 goto nla_put_failure;
2427 2436
2428 return nlmsg_end(skb, nlh); 2437 return nlmsg_end(skb, nlh);
2429 2438
2439nla_put_failure:
2430nlmsg_failure: 2440nlmsg_failure:
2431 nlmsg_cancel(skb, nlh); 2441 nlmsg_cancel(skb, nlh);
2432 return -EMSGSIZE; 2442 return -EMSGSIZE;
@@ -2513,6 +2523,7 @@ static inline size_t xfrm_polexpire_msgsize(struct xfrm_policy *xp)
2513 return NLMSG_ALIGN(sizeof(struct xfrm_user_polexpire)) 2523 return NLMSG_ALIGN(sizeof(struct xfrm_user_polexpire))
2514 + nla_total_size(sizeof(struct xfrm_user_tmpl) * xp->xfrm_nr) 2524 + nla_total_size(sizeof(struct xfrm_user_tmpl) * xp->xfrm_nr)
2515 + nla_total_size(xfrm_user_sec_ctx_size(xp->security)) 2525 + nla_total_size(xfrm_user_sec_ctx_size(xp->security))
2526 + nla_total_size(sizeof(struct xfrm_mark))
2516 + userpolicy_type_attrsize(); 2527 + userpolicy_type_attrsize();
2517} 2528}
2518 2529
@@ -2535,10 +2546,13 @@ static int build_polexpire(struct sk_buff *skb, struct xfrm_policy *xp,
2535 goto nlmsg_failure; 2546 goto nlmsg_failure;
2536 if (copy_to_user_policy_type(xp->type, skb) < 0) 2547 if (copy_to_user_policy_type(xp->type, skb) < 0)
2537 goto nlmsg_failure; 2548 goto nlmsg_failure;
2549 if (xfrm_mark_put(skb, &xp->mark))
2550 goto nla_put_failure;
2538 upe->hard = !!hard; 2551 upe->hard = !!hard;
2539 2552
2540 return nlmsg_end(skb, nlh); 2553 return nlmsg_end(skb, nlh);
2541 2554
2555nla_put_failure:
2542nlmsg_failure: 2556nlmsg_failure:
2543 nlmsg_cancel(skb, nlh); 2557 nlmsg_cancel(skb, nlh);
2544 return -EMSGSIZE; 2558 return -EMSGSIZE;
@@ -2575,6 +2589,7 @@ static int xfrm_notify_policy(struct xfrm_policy *xp, int dir, struct km_event *
2575 headlen = sizeof(*id); 2589 headlen = sizeof(*id);
2576 } 2590 }
2577 len += userpolicy_type_attrsize(); 2591 len += userpolicy_type_attrsize();
2592 len += nla_total_size(sizeof(struct xfrm_mark));
2578 len += NLMSG_ALIGN(headlen); 2593 len += NLMSG_ALIGN(headlen);
2579 2594
2580 skb = nlmsg_new(len, GFP_ATOMIC); 2595 skb = nlmsg_new(len, GFP_ATOMIC);
@@ -2610,10 +2625,14 @@ static int xfrm_notify_policy(struct xfrm_policy *xp, int dir, struct km_event *
2610 if (copy_to_user_policy_type(xp->type, skb) < 0) 2625 if (copy_to_user_policy_type(xp->type, skb) < 0)
2611 goto nlmsg_failure; 2626 goto nlmsg_failure;
2612 2627
2628 if (xfrm_mark_put(skb, &xp->mark))
2629 goto nla_put_failure;
2630
2613 nlmsg_end(skb, nlh); 2631 nlmsg_end(skb, nlh);
2614 2632
2615 return nlmsg_multicast(net->xfrm.nlsk, skb, 0, XFRMNLGRP_POLICY, GFP_ATOMIC); 2633 return nlmsg_multicast(net->xfrm.nlsk, skb, 0, XFRMNLGRP_POLICY, GFP_ATOMIC);
2616 2634
2635nla_put_failure:
2617nlmsg_failure: 2636nlmsg_failure:
2618 kfree_skb(skb); 2637 kfree_skb(skb);
2619 return -1; 2638 return -1;