aboutsummaryrefslogtreecommitdiffstats
path: root/net/xfrm
diff options
context:
space:
mode:
authorJamal Hadi Salim <hadi@cyberus.ca>2007-04-29 00:20:32 -0400
committerDavid S. Miller <davem@davemloft.net>2007-04-29 00:20:32 -0400
commitecfd6b183780c6d9e85873693b3ce6c5f4d08b58 (patch)
tree8ee1330176e3011d3fdf86e70b5933b50302b7e7 /net/xfrm
parent5632c5152aa621885d87ea0b8fdd5a6bb9f69c6f (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/xfrm')
-rw-r--r--net/xfrm/xfrm_policy.c16
-rw-r--r--net/xfrm/xfrm_user.c77
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
582static DEFINE_MUTEX(hash_resize_mutex); 582void 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}
595EXPORT_SYMBOL(xfrm_spd_getinfo);
583 596
597static DEFINE_MUTEX(hash_resize_mutex);
584static void xfrm_hash_resize(struct work_struct *__unused) 598static 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
675static 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
708nla_put_failure:
709 nlmsg_cancel(skb, nlh);
710 return -EMSGSIZE;
711}
712
713static 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
675static int build_sadinfo(struct sk_buff *skb, u32 pid, u32 seq, u32 flags) 750static 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
1912static int xfrm_user_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh) 1989static int xfrm_user_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh)