diff --git a/ChangeLog b/ChangeLog index bda8f61a..60e4ba10 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2005-11-01 Jamal Hadi Salim + + * Fix handling of XFRM monitor and state + 2005-11-01 Stephen Hemminger nlmsg_type == XFRM_MSG_NEWSA || + n->nlmsg_type == XFRM_MSG_DELSA || + n->nlmsg_type == XFRM_MSG_UPDSA) { + xfrm_state_print(who, n, arg); + return 0; + } + if (n->nlmsg_type == XFRM_MSG_NEWPOLICY || + n->nlmsg_type == XFRM_MSG_DELPOLICY || + n->nlmsg_type == XFRM_MSG_UPDPOLICY) { + xfrm_policy_print(who, n, arg); + return 0; + } + if (n->nlmsg_type == XFRM_MSG_ACQUIRE) { xfrm_acquire_print(who, n, arg); return 0; @@ -138,7 +151,7 @@ static int xfrm_accept_msg(const struct sockaddr_nl *who, } if (n->nlmsg_type != NLMSG_ERROR && n->nlmsg_type != NLMSG_NOOP && n->nlmsg_type != NLMSG_DONE) { - fprintf(fp, "Unknown message: %08x %08x %08x\n", + fprintf(fp, "Unknown message: %08d 0x%08x 0x%08x\n", n->nlmsg_len, n->nlmsg_type, n->nlmsg_flags); } return 0; @@ -151,6 +164,8 @@ int do_xfrm_monitor(int argc, char **argv) unsigned groups = ~((unsigned)0); /* XXX */ int lacquire=0; int lexpire=0; + int lpolicy=0; + int lsa=0; while (argc > 0) { if (matches(*argv, "file") == 0) { @@ -162,6 +177,12 @@ int do_xfrm_monitor(int argc, char **argv) } else if (matches(*argv, "expire") == 0) { lexpire=1; groups = 0; + } else if (matches(*argv, "SA") == 0) { + lsa=1; + groups = 0; + } else if (matches(*argv, "policy") == 0) { + lpolicy=1; + groups = 0; } else if (matches(*argv, "help") == 0) { usage(); } else { @@ -175,6 +196,10 @@ int do_xfrm_monitor(int argc, char **argv) groups |= XFRMGRP_ACQUIRE; if (lexpire) groups |= XFRMGRP_EXPIRE; + if (lsa) + groups |= XFRMGRP_SA; + if (lpolicy) + groups |= XFRMGRP_POLICY; if (file) { FILE *fp; @@ -188,6 +213,9 @@ int do_xfrm_monitor(int argc, char **argv) //ll_init_map(&rth); + if (rtnl_open_byproto(&rth, groups, NETLINK_XFRM) < 0) + exit(1); + if (rtnl_listen(&rth, xfrm_accept_msg, (void*)stdout) < 0) exit(2); diff --git a/ip/xfrm_policy.c b/ip/xfrm_policy.c index e08e422f..e295eb96 100644 --- a/ip/xfrm_policy.c +++ b/ip/xfrm_policy.c @@ -335,12 +335,13 @@ static int xfrm_policy_filter_match(struct xfrm_userpolicy_info *xpinfo) int xfrm_policy_print(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg) { - FILE *fp = (FILE*)arg; - struct xfrm_userpolicy_info *xpinfo; - struct xfrm_user_polexpire *xpexp; - int len = n->nlmsg_len; struct rtattr * tb[XFRMA_MAX+1]; struct rtattr * rta; + struct xfrm_userpolicy_info *xpinfo = NULL; + struct xfrm_user_polexpire *xpexp = NULL; + struct xfrm_userpolicy_id *xpid = NULL; + FILE *fp = (FILE*)arg; + int len = n->nlmsg_len; if (n->nlmsg_type != XFRM_MSG_NEWPOLICY && n->nlmsg_type != XFRM_MSG_DELPOLICY && @@ -355,6 +356,9 @@ int xfrm_policy_print(const struct sockaddr_nl *who, struct nlmsghdr *n, xpinfo = &xpexp->pol; len -= NLMSG_LENGTH(sizeof(*xpexp)); + } else if (n->nlmsg_type == XFRM_MSG_DELPOLICY) { + xpid = NLMSG_DATA(n); + len -= NLMSG_LENGTH(sizeof(*xpid)); } else { xpexp = NULL; xpinfo = NLMSG_DATA(n); @@ -372,14 +376,25 @@ int xfrm_policy_print(const struct sockaddr_nl *who, struct nlmsghdr *n, if (n->nlmsg_type == XFRM_MSG_POLEXPIRE) rta = XFRMPEXP_RTA(xpexp); + else if (n->nlmsg_type == XFRM_MSG_DELPOLICY) + rta = (struct rtattr*)(((char*)(xpid)) + NLMSG_ALIGN(sizeof(*xpid))); else rta = XFRMP_RTA(xpinfo); parse_rtattr(tb, XFRMA_MAX, rta, len); - if (n->nlmsg_type == XFRM_MSG_DELPOLICY) + if (n->nlmsg_type == XFRM_MSG_DELPOLICY) { fprintf(fp, "Deleted "); - else if (n->nlmsg_type == XFRM_MSG_POLEXPIRE) + //xfrm_policy_id_print(); + + if (tb[XFRMA_POLICY]) + xpinfo = (struct xfrm_userpolicy_info *)RTA_DATA(tb[XFRMA_POLICY]); + else { + fprintf(stderr, "Buggy XFRM_MSG_DELPOLICY "); + return 0; + } + + } else if (n->nlmsg_type == XFRM_MSG_POLEXPIRE) fprintf(fp, "Expired "); xfrm_policy_info_print(xpinfo, tb, fp, NULL, NULL); diff --git a/ip/xfrm_state.c b/ip/xfrm_state.c index c3a91140..db7de0c1 100644 --- a/ip/xfrm_state.c +++ b/ip/xfrm_state.c @@ -556,11 +556,12 @@ int xfrm_state_print(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg) { FILE *fp = (FILE*)arg; - struct xfrm_usersa_info *xsinfo; - struct xfrm_user_expire *xexp; - int len = n->nlmsg_len; struct rtattr * tb[XFRMA_MAX+1]; struct rtattr * rta; + struct xfrm_usersa_info *xsinfo = NULL; + struct xfrm_user_expire *xexp = NULL; + struct xfrm_usersa_id *xsid = NULL; + int len = n->nlmsg_len; if (n->nlmsg_type != XFRM_MSG_NEWSA && n->nlmsg_type != XFRM_MSG_DELSA && @@ -575,6 +576,10 @@ int xfrm_state_print(const struct sockaddr_nl *who, struct nlmsghdr *n, xsinfo = &xexp->state; len -= NLMSG_LENGTH(sizeof(*xexp)); + } else if (n->nlmsg_type == XFRM_MSG_DELSA) { + /* Dont blame me for this .. Herbert made me do it */ + xsid = NLMSG_DATA(n); + len -= NLMSG_LENGTH(sizeof(struct xfrm_usersa_id)); } else { xexp = NULL; xsinfo = NLMSG_DATA(n); @@ -590,17 +595,31 @@ int xfrm_state_print(const struct sockaddr_nl *who, struct nlmsghdr *n, if (!xfrm_state_filter_match(xsinfo)) return 0; + if (n->nlmsg_type == XFRM_MSG_DELSA) { + fprintf(fp, "Deleted "); + //xfrm_state_print_id(); + } + else if (n->nlmsg_type == XFRM_MSG_EXPIRE) + fprintf(fp, "Expired "); + if (n->nlmsg_type == XFRM_MSG_EXPIRE) rta = XFRMEXP_RTA(xexp); - else + else if (n->nlmsg_type == XFRM_MSG_DELSA) + rta = (struct rtattr*)(((char*)(xsid)) + NLMSG_ALIGN(sizeof(*xsid))); + else rta = XFRMS_RTA(xsinfo); + parse_rtattr(tb, XFRMA_MAX, rta, len); - if (n->nlmsg_type == XFRM_MSG_DELSA) - fprintf(fp, "Deleted "); - else if (n->nlmsg_type == XFRM_MSG_EXPIRE) - fprintf(fp, "Expired "); + if (n->nlmsg_type == XFRM_MSG_DELSA) { + if (tb[XFRMA_SA]) + xsinfo = (struct xfrm_usersa_info *)RTA_DATA(tb[XFRMA_SA]); + else { + fprintf(stderr, "Buggy XFRM_MSG_DELSA "); + return 0; + } + } xfrm_state_info_print(xsinfo, tb, fp, NULL, NULL);