From 0bb4a4c20c9deeac26f7239d83c8747c4dfb4d89 Mon Sep 17 00:00:00 2001 From: jamal Date: Thu, 3 May 2007 19:09:41 -0400 Subject: [PATCH] see SAD info Stephen, Use this patch instead of the one i sent yesterday. As before, you will need to pull include/linux/xfrm.h from net-2.6 once Dave applies the kernel patch. cheers, jamal [XFRM] see SAD info i.e instead of something like ip xfrm state ls | grep -i src | wc -l do: ip xfrm state count And you get the count; you can also pass -s to the command line and get the hash info. Signed-off-by: Jamal Hadi Salim Signed-off-by: Stephen Hemminger --- ip/xfrm.h | 1 + ip/xfrm_state.c | 80 +++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 81 insertions(+) diff --git a/ip/xfrm.h b/ip/xfrm.h index d1959bbff..71345b9d0 100644 --- a/ip/xfrm.h +++ b/ip/xfrm.h @@ -57,6 +57,7 @@ #define XFRMREP_RTA(x) ((struct rtattr*)(((char*)(x)) + NLMSG_ALIGN(sizeof(struct xfrm_user_report)))) +#define XFRMSAPD_RTA(x) ((struct rtattr*)(((char*)(x)) + NLMSG_ALIGN(sizeof(__u32)))) #define XFRM_FLAG_PRINT(fp, flags, f, s) \ do { \ if (flags & f) { \ diff --git a/ip/xfrm_state.c b/ip/xfrm_state.c index 42e39499c..39b0f27ca 100644 --- a/ip/xfrm_state.c +++ b/ip/xfrm_state.c @@ -64,6 +64,7 @@ static void usage(void) fprintf(stderr, "Usage: ip xfrm state { deleteall | list } [ ID ] [ mode MODE ] [ reqid REQID ]\n"); fprintf(stderr, " [ flag FLAG_LIST ]\n"); fprintf(stderr, "Usage: ip xfrm state flush [ proto XFRM_PROTO ]\n"); + fprintf(stderr, "Usage: ip xfrm state count \n"); fprintf(stderr, "ID := [ src ADDR ] [ dst ADDR ] [ proto XFRM_PROTO ] [ spi SPI ]\n"); //fprintf(stderr, "XFRM_PROTO := [ esp | ah | comp ]\n"); @@ -933,6 +934,82 @@ static int xfrm_state_list_or_deleteall(int argc, char **argv, int deleteall) exit(0); } +int print_sadinfo(struct nlmsghdr *n, void *arg) +{ + FILE *fp = (FILE*)arg; + __u32 *f = NLMSG_DATA(n); + struct rtattr *tb[XFRMA_SAD_MAX+1]; + struct rtattr *rta; + struct xfrmu_sadhinfo *si; + __u32 *cnt; + + int len = n->nlmsg_len; + + len -= NLMSG_LENGTH(sizeof(__u32)); + if (len < 0) { + fprintf(stderr, "SADinfo: Wrong len %d\n", len); + return -1; + } + + rta = XFRMSAPD_RTA(f); + parse_rtattr(tb, XFRMA_SAD_MAX, rta, len); + + if (tb[XFRMA_SADCNT]) { + fprintf(fp,"\t SAD"); + cnt = (__u32 *)RTA_DATA(tb[XFRMA_SADCNT]); + fprintf(fp," count %d", *cnt); + } else { + fprintf(fp,"BAD SAD info returned\n"); + return -1; + } + + if (show_stats) { + if (!tb[XFRMA_SADHINFO]) { + } + if (RTA_PAYLOAD(tb[XFRMA_SADHINFO]) < sizeof(*si)) { + fprintf(fp,"BAD SAD length returned\n"); + return -1; + } + + si = (struct xfrmu_sadhinfo *)RTA_DATA(tb[XFRMA_SADHINFO]); + fprintf(fp," (buckets "); + fprintf(fp,"count %d", si->sadhcnt); + fprintf(fp," Max %d", si->sadhmcnt); + fprintf(fp,")"); + } + fprintf(fp,"\n"); + + return 0; +} + +static int xfrm_sad_getinfo(int argc, char **argv) +{ + struct rtnl_handle rth; + struct { + struct nlmsghdr n; + __u32 flags; + char ans[64]; + } req; + + memset(&req, 0, sizeof(req)); + req.n.nlmsg_len = NLMSG_LENGTH(sizeof(req.flags)); + req.n.nlmsg_flags = NLM_F_REQUEST; + req.n.nlmsg_type = XFRM_MSG_GETSADINFO; + req.flags = 0XFFFFFFFF; + + if (rtnl_open_byproto(&rth, 0, NETLINK_XFRM) < 0) + exit(1); + + if (rtnl_talk(&rth, &req.n, 0, 0, &req.n, NULL, NULL) < 0) + exit(2); + + print_sadinfo(&req.n, (void*)stdout); + + rtnl_close(&rth); + + return 0; +} + static int xfrm_state_flush(int argc, char **argv) { struct rtnl_handle rth; @@ -1010,6 +1087,9 @@ int do_xfrm_state(int argc, char **argv) return xfrm_state_get_or_delete(argc-1, argv+1, 0); if (matches(*argv, "flush") == 0) return xfrm_state_flush(argc-1, argv+1); + if (matches(*argv, "count") == 0) { + return xfrm_sad_getinfo(argc, argv); + } if (matches(*argv, "help") == 0) usage(); fprintf(stderr, "Command \"%s\" is unknown, try \"ip xfrm state help\".\n", *argv); -- 2.47.2