diff options
author | Jamal Hadi Salim <hadi@cyberus.ca> | 2007-04-29 00:20:32 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2007-04-29 00:20:32 -0400 |
commit | ecfd6b183780c6d9e85873693b3ce6c5f4d08b58 (patch) | |
tree | 8ee1330176e3011d3fdf86e70b5933b50302b7e7 /net | |
parent | 5632c5152aa621885d87ea0b8fdd5a6bb9f69c6f (diff) |
[XFRM]: Export SPD info
With this patch you can use iproute2 in user space to efficiently see
how many policies exist in different directions.
Signed-off-by: Jamal Hadi Salim <hadi@cyberus.ca>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net')
-rw-r--r-- | net/xfrm/xfrm_policy.c | 16 | ||||
-rw-r--r-- | net/xfrm/xfrm_user.c | 77 |
2 files changed, 92 insertions, 1 deletions
diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c index 762926009c04..dbf9d96a2f0b 100644 --- a/net/xfrm/xfrm_policy.c +++ b/net/xfrm/xfrm_policy.c | |||
@@ -579,8 +579,22 @@ static inline int xfrm_byidx_should_resize(int total) | |||
579 | return 0; | 579 | return 0; |
580 | } | 580 | } |
581 | 581 | ||
582 | static DEFINE_MUTEX(hash_resize_mutex); | 582 | void xfrm_spd_getinfo(struct xfrm_spdinfo *si) |
583 | { | ||
584 | read_lock_bh(&xfrm_policy_lock); | ||
585 | si->incnt = xfrm_policy_count[XFRM_POLICY_IN]; | ||
586 | si->outcnt = xfrm_policy_count[XFRM_POLICY_OUT]; | ||
587 | si->fwdcnt = xfrm_policy_count[XFRM_POLICY_FWD]; | ||
588 | si->inscnt = xfrm_policy_count[XFRM_POLICY_IN+XFRM_POLICY_MAX]; | ||
589 | si->outscnt = xfrm_policy_count[XFRM_POLICY_OUT+XFRM_POLICY_MAX]; | ||
590 | si->fwdscnt = xfrm_policy_count[XFRM_POLICY_FWD+XFRM_POLICY_MAX]; | ||
591 | si->spdhcnt = xfrm_idx_hmask; | ||
592 | si->spdhmcnt = xfrm_policy_hashmax; | ||
593 | read_unlock_bh(&xfrm_policy_lock); | ||
594 | } | ||
595 | EXPORT_SYMBOL(xfrm_spd_getinfo); | ||
583 | 596 | ||
597 | static DEFINE_MUTEX(hash_resize_mutex); | ||
584 | static void xfrm_hash_resize(struct work_struct *__unused) | 598 | static void xfrm_hash_resize(struct work_struct *__unused) |
585 | { | 599 | { |
586 | int dir, total; | 600 | int dir, total; |
diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c index 69110fed64b6..4210d91624cd 100644 --- a/net/xfrm/xfrm_user.c +++ b/net/xfrm/xfrm_user.c | |||
@@ -672,6 +672,81 @@ static struct sk_buff *xfrm_state_netlink(struct sk_buff *in_skb, | |||
672 | return skb; | 672 | return skb; |
673 | } | 673 | } |
674 | 674 | ||
675 | static int build_spdinfo(struct sk_buff *skb, u32 pid, u32 seq, u32 flags) | ||
676 | { | ||
677 | struct xfrm_spdinfo si; | ||
678 | struct nlmsghdr *nlh; | ||
679 | u32 *f; | ||
680 | |||
681 | nlh = nlmsg_put(skb, pid, seq, XFRM_MSG_NEWSPDINFO, sizeof(u32), 0); | ||
682 | if (nlh == NULL) /* shouldnt really happen ... */ | ||
683 | return -EMSGSIZE; | ||
684 | |||
685 | f = nlmsg_data(nlh); | ||
686 | *f = flags; | ||
687 | xfrm_spd_getinfo(&si); | ||
688 | |||
689 | if (flags & XFRM_SPD_HMASK) | ||
690 | NLA_PUT_U32(skb, XFRMA_SPDHMASK, si.spdhcnt); | ||
691 | if (flags & XFRM_SPD_HMAX) | ||
692 | NLA_PUT_U32(skb, XFRMA_SPDHMAX, si.spdhmcnt); | ||
693 | if (flags & XFRM_SPD_ICNT) | ||
694 | NLA_PUT_U32(skb, XFRMA_SPDICNT, si.incnt); | ||
695 | if (flags & XFRM_SPD_OCNT) | ||
696 | NLA_PUT_U32(skb, XFRMA_SPDOCNT, si.outcnt); | ||
697 | if (flags & XFRM_SPD_FCNT) | ||
698 | NLA_PUT_U32(skb, XFRMA_SPDFCNT, si.fwdcnt); | ||
699 | if (flags & XFRM_SPD_ISCNT) | ||
700 | NLA_PUT_U32(skb, XFRMA_SPDISCNT, si.inscnt); | ||
701 | if (flags & XFRM_SPD_OSCNT) | ||
702 | NLA_PUT_U32(skb, XFRMA_SPDOSCNT, si.inscnt); | ||
703 | if (flags & XFRM_SPD_FSCNT) | ||
704 | NLA_PUT_U32(skb, XFRMA_SPDFSCNT, si.inscnt); | ||
705 | |||
706 | return nlmsg_end(skb, nlh); | ||
707 | |||
708 | nla_put_failure: | ||
709 | nlmsg_cancel(skb, nlh); | ||
710 | return -EMSGSIZE; | ||
711 | } | ||
712 | |||
713 | static int xfrm_get_spdinfo(struct sk_buff *skb, struct nlmsghdr *nlh, | ||
714 | struct rtattr **xfrma) | ||
715 | { | ||
716 | struct sk_buff *r_skb; | ||
717 | u32 *flags = NLMSG_DATA(nlh); | ||
718 | u32 spid = NETLINK_CB(skb).pid; | ||
719 | u32 seq = nlh->nlmsg_seq; | ||
720 | int len = NLMSG_LENGTH(sizeof(u32)); | ||
721 | |||
722 | |||
723 | if (*flags & XFRM_SPD_HMASK) | ||
724 | len += RTA_SPACE(sizeof(u32)); | ||
725 | if (*flags & XFRM_SPD_HMAX) | ||
726 | len += RTA_SPACE(sizeof(u32)); | ||
727 | if (*flags & XFRM_SPD_ICNT) | ||
728 | len += RTA_SPACE(sizeof(u32)); | ||
729 | if (*flags & XFRM_SPD_OCNT) | ||
730 | len += RTA_SPACE(sizeof(u32)); | ||
731 | if (*flags & XFRM_SPD_FCNT) | ||
732 | len += RTA_SPACE(sizeof(u32)); | ||
733 | if (*flags & XFRM_SPD_ISCNT) | ||
734 | len += RTA_SPACE(sizeof(u32)); | ||
735 | if (*flags & XFRM_SPD_OSCNT) | ||
736 | len += RTA_SPACE(sizeof(u32)); | ||
737 | if (*flags & XFRM_SPD_FSCNT) | ||
738 | len += RTA_SPACE(sizeof(u32)); | ||
739 | |||
740 | r_skb = alloc_skb(len, GFP_ATOMIC); | ||
741 | if (r_skb == NULL) | ||
742 | return -ENOMEM; | ||
743 | |||
744 | if (build_spdinfo(r_skb, spid, seq, *flags) < 0) | ||
745 | BUG(); | ||
746 | |||
747 | return nlmsg_unicast(xfrm_nl, r_skb, spid); | ||
748 | } | ||
749 | |||
675 | static int build_sadinfo(struct sk_buff *skb, u32 pid, u32 seq, u32 flags) | 750 | static int build_sadinfo(struct sk_buff *skb, u32 pid, u32 seq, u32 flags) |
676 | { | 751 | { |
677 | struct xfrm_sadinfo si; | 752 | struct xfrm_sadinfo si; |
@@ -1879,6 +1954,7 @@ static const int xfrm_msg_min[XFRM_NR_MSGTYPES] = { | |||
1879 | [XFRM_MSG_REPORT - XFRM_MSG_BASE] = XMSGSIZE(xfrm_user_report), | 1954 | [XFRM_MSG_REPORT - XFRM_MSG_BASE] = XMSGSIZE(xfrm_user_report), |
1880 | [XFRM_MSG_MIGRATE - XFRM_MSG_BASE] = XMSGSIZE(xfrm_userpolicy_id), | 1955 | [XFRM_MSG_MIGRATE - XFRM_MSG_BASE] = XMSGSIZE(xfrm_userpolicy_id), |
1881 | [XFRM_MSG_GETSADINFO - XFRM_MSG_BASE] = NLMSG_LENGTH(sizeof(u32)), | 1956 | [XFRM_MSG_GETSADINFO - XFRM_MSG_BASE] = NLMSG_LENGTH(sizeof(u32)), |
1957 | [XFRM_MSG_GETSPDINFO - XFRM_MSG_BASE] = NLMSG_LENGTH(sizeof(u32)), | ||
1882 | }; | 1958 | }; |
1883 | 1959 | ||
1884 | #undef XMSGSIZE | 1960 | #undef XMSGSIZE |
@@ -1907,6 +1983,7 @@ static struct xfrm_link { | |||
1907 | [XFRM_MSG_GETAE - XFRM_MSG_BASE] = { .doit = xfrm_get_ae }, | 1983 | [XFRM_MSG_GETAE - XFRM_MSG_BASE] = { .doit = xfrm_get_ae }, |
1908 | [XFRM_MSG_MIGRATE - XFRM_MSG_BASE] = { .doit = xfrm_do_migrate }, | 1984 | [XFRM_MSG_MIGRATE - XFRM_MSG_BASE] = { .doit = xfrm_do_migrate }, |
1909 | [XFRM_MSG_GETSADINFO - XFRM_MSG_BASE] = { .doit = xfrm_get_sadinfo }, | 1985 | [XFRM_MSG_GETSADINFO - XFRM_MSG_BASE] = { .doit = xfrm_get_sadinfo }, |
1986 | [XFRM_MSG_GETSPDINFO - XFRM_MSG_BASE] = { .doit = xfrm_get_spdinfo }, | ||
1910 | }; | 1987 | }; |
1911 | 1988 | ||
1912 | static int xfrm_user_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh) | 1989 | static int xfrm_user_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh) |