This commit was generated by cvs2svn to compensate for changes in r2587,
[iproute2.git] / ip / xfrm_policy.c
index c1331a4..433b513 100644 (file)
@@ -35,8 +35,8 @@
 #include "xfrm.h"
 #include "ip_common.h"
 
-//#define NLMSG_FLUSH_BUF_SIZE (4096-512)
-#define NLMSG_FLUSH_BUF_SIZE 8192
+//#define NLMSG_DELETEALL_BUF_SIZE (4096-512)
+#define NLMSG_DELETEALL_BUF_SIZE 8192
 
 /*
  * Receiving buffer defines:
@@ -56,8 +56,9 @@ static void usage(void)
        fprintf(stderr, "Usage: ip xfrm policy { add | update } dir DIR SELECTOR [ index INDEX ] \n");
        fprintf(stderr, "        [ action ACTION ] [ priority PRIORITY ] [ LIMIT-LIST ] [ TMPL-LIST ]\n");
        fprintf(stderr, "Usage: ip xfrm policy { delete | get } dir DIR [ SELECTOR | index INDEX ]\n");
-       fprintf(stderr, "Usage: ip xfrm policy { flush | list } [ dir DIR ] [ SELECTOR ]\n");
+       fprintf(stderr, "Usage: ip xfrm policy { deleteall | list } [ dir DIR ] [ SELECTOR ]\n");
        fprintf(stderr, "        [ index INDEX ] [ action ACTION ] [ priority PRIORITY ]\n");
+       fprintf(stderr, "Usage: ip xfrm policy flush\n");
        fprintf(stderr, "DIR := [ in | out | fwd ]\n");
 
        fprintf(stderr, "SELECTOR := src ADDR[/PLEN] dst ADDR[/PLEN] [ UPSPEC ] [ dev DEV ]\n");
@@ -331,84 +332,87 @@ static int xfrm_policy_filter_match(struct xfrm_userpolicy_info *xpinfo)
        return 1;
 }
 
-static int xfrm_policy_print(const struct sockaddr_nl *who, 
-                            struct nlmsghdr *n, void *arg)
+int xfrm_policy_print(const struct sockaddr_nl *who, struct nlmsghdr *n,
+                     void *arg)
 {
+       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;
-       struct xfrm_userpolicy_info *xpinfo = NLMSG_DATA(n);
        int len = n->nlmsg_len;
-       struct rtattr * tb[XFRMA_MAX+1];
 
        if (n->nlmsg_type != XFRM_MSG_NEWPOLICY &&
-           n->nlmsg_type != XFRM_MSG_DELPOLICY) {
+           n->nlmsg_type != XFRM_MSG_DELPOLICY &&
+           n->nlmsg_type != XFRM_MSG_UPDPOLICY &&
+           n->nlmsg_type != XFRM_MSG_POLEXPIRE) {
                fprintf(stderr, "Not a policy: %08x %08x %08x\n",
                        n->nlmsg_len, n->nlmsg_type, n->nlmsg_flags);
                return 0;
        }
 
-       len -= NLMSG_LENGTH(sizeof(*xpinfo));
+       if (n->nlmsg_type == XFRM_MSG_DELPOLICY)  {
+               xpid = NLMSG_DATA(n);
+               len -= NLMSG_LENGTH(sizeof(*xpid));
+       } else if (n->nlmsg_type == XFRM_MSG_POLEXPIRE) {
+               xpexp = NLMSG_DATA(n);
+               xpinfo = &xpexp->pol;
+               len -= NLMSG_LENGTH(sizeof(*xpexp));
+       } else {
+               xpexp = NULL;
+               xpinfo = NLMSG_DATA(n);
+               len -= NLMSG_LENGTH(sizeof(*xpinfo));
+       }
+
        if (len < 0) {
                fprintf(stderr, "BUG: wrong nlmsg len %d\n", len);
                return -1;
        }
 
-       if (!xfrm_policy_filter_match(xpinfo))
+       if (xpinfo && !xfrm_policy_filter_match(xpinfo))
                return 0;
 
-       parse_rtattr(tb, XFRMA_MAX, XFRMP_RTA(xpinfo), len);
-
        if (n->nlmsg_type == XFRM_MSG_DELPOLICY)
                fprintf(fp, "Deleted ");
+       else if (n->nlmsg_type == XFRM_MSG_UPDPOLICY)
+               fprintf(fp, "Updated ");
+       else if (n->nlmsg_type == XFRM_MSG_POLEXPIRE)
+               fprintf(fp, "Expired ");
 
-       xfrm_selector_print(&xpinfo->sel, preferred_family, fp, NULL);
-
-       fprintf(fp, "\t");
-       fprintf(fp, "dir ");
-       switch (xpinfo->dir) {
-       case XFRM_POLICY_IN:
-               fprintf(fp, "in");
-               break;
-       case XFRM_POLICY_OUT:
-               fprintf(fp, "out");
-               break;
-       case XFRM_POLICY_FWD:
-               fprintf(fp, "fwd");
-               break;
-       default:
-               fprintf(fp, "%u", xpinfo->dir);
-               break;
-       }
-       fprintf(fp, " ");
-
-       switch (xpinfo->action) {
-       case XFRM_POLICY_ALLOW:
-               if (show_stats > 0)
-                       fprintf(fp, "action allow ");
-               break;
-       case XFRM_POLICY_BLOCK:
-               fprintf(fp, "action block ");
-               break;
-       default:
-               fprintf(fp, "action %u ", xpinfo->action);
-               break;
-       }
+       if (n->nlmsg_type == XFRM_MSG_DELPOLICY)
+               rta = XFRMPID_RTA(xpid);
+       else if (n->nlmsg_type == XFRM_MSG_POLEXPIRE)
+               rta = XFRMPEXP_RTA(xpexp);
+       else
+               rta = XFRMP_RTA(xpinfo);
+
+       parse_rtattr(tb, XFRMA_MAX, rta, len);
 
-       if (show_stats)
-               fprintf(fp, "index %u ", xpinfo->index);
-       fprintf(fp, "priority %u ", xpinfo->priority);
-       if (show_stats > 0) {
-               fprintf(fp, "share %s ", strxf_share(xpinfo->share));
-               fprintf(fp, "flag 0x%s", strxf_mask8(xpinfo->flags));
+       if (n->nlmsg_type == XFRM_MSG_DELPOLICY) {
+               //xfrm_policy_id_print();
+               if (!tb[XFRMA_POLICY]) {
+                       fprintf(stderr, "Buggy XFRM_MSG_DELPOLICY: no XFRMA_POLICY\n");
+                       return -1;
+               }
+               if (RTA_PAYLOAD(tb[XFRMA_POLICY]) < sizeof(*xpinfo)) {
+                       fprintf(stderr, "Buggy XFRM_MSG_DELPOLICY: too short XFRMA_POLICY len\n");
+                       return -1;
+               }
+               xpinfo = (struct xfrm_userpolicy_info *)RTA_DATA(tb[XFRMA_POLICY]);
        }
-       fprintf(fp, "%s", _SL_);
 
-       if (show_stats > 0)
-               xfrm_lifetime_print(&xpinfo->lft, &xpinfo->curlft, fp, "\t");
+       xfrm_policy_info_print(xpinfo, tb, fp, NULL, NULL);
 
-       xfrm_xfrma_print(tb, xpinfo->sel.family, fp, "\t");
+       if (n->nlmsg_type == XFRM_MSG_POLEXPIRE) {
+               fprintf(fp, "\t");
+               fprintf(fp, "hard %u", xpexp->hard);
+               fprintf(fp, "%s", _SL_);
+       }
 
        if (oneline)
                fprintf(fp, "\n");
+       fflush(fp);
 
        return 0;
 }
@@ -541,7 +545,7 @@ static int xfrm_policy_keep(const struct sockaddr_nl *who,
                return 0;
 
        if (xb->offset > xb->size) {
-               fprintf(stderr, "Flush buffer overflow\n");
+               fprintf(stderr, "Policy buffer overflow\n");
                return -1;
        }
 
@@ -562,7 +566,7 @@ static int xfrm_policy_keep(const struct sockaddr_nl *who,
        return 0;
 }
 
-static int xfrm_policy_list_or_flush(int argc, char **argv, int flush)
+static int xfrm_policy_list_or_deleteall(int argc, char **argv, int deleteall)
 {
        char *selp = NULL;
        struct rtnl_handle rth;
@@ -620,9 +624,9 @@ static int xfrm_policy_list_or_flush(int argc, char **argv, int flush)
        if (rtnl_open_byproto(&rth, 0, NETLINK_XFRM) < 0)
                exit(1);
 
-       if (flush) {
+       if (deleteall) {
                struct xfrm_buffer xb;
-               char buf[NLMSG_FLUSH_BUF_SIZE];
+               char buf[NLMSG_DELETEALL_BUF_SIZE];
                int i;
 
                xb.buf = buf;
@@ -634,7 +638,7 @@ static int xfrm_policy_list_or_flush(int argc, char **argv, int flush)
                        xb.nlmsg_count = 0;
 
                        if (show_stats > 1)
-                               fprintf(stderr, "Flush round = %d\n", i);
+                               fprintf(stderr, "Delete-all round = %d\n", i);
 
                        if (rtnl_wilddump_request(&rth, preferred_family, XFRM_MSG_GETPOLICY) < 0) {
                                perror("Cannot send dump request");
@@ -642,21 +646,21 @@ static int xfrm_policy_list_or_flush(int argc, char **argv, int flush)
                        }
 
                        if (rtnl_dump_filter(&rth, xfrm_policy_keep, &xb, NULL, NULL) < 0) {
-                               fprintf(stderr, "Flush terminated\n");
+                               fprintf(stderr, "Delete-all terminated\n");
                                exit(1);
                        }
                        if (xb.nlmsg_count == 0) {
                                if (show_stats > 1)
-                                       fprintf(stderr, "Flush completed\n");
+                                       fprintf(stderr, "Delete-all completed\n");
                                break;
                        }
 
                        if (rtnl_send(&rth, xb.buf, xb.offset) < 0) {
-                               perror("Failed to send flush request\n");
+                               perror("Failed to send delete-all request\n");
                                exit(1);
                        }
                        if (show_stats > 1)
-                               fprintf(stderr, "Flushed nlmsg count = %d\n", xb.nlmsg_count);
+                               fprintf(stderr, "Delete-all nlmsg count = %d\n", xb.nlmsg_count);
 
                        xb.offset = 0;
                        xb.nlmsg_count = 0;
@@ -678,7 +682,7 @@ static int xfrm_policy_list_or_flush(int argc, char **argv, int flush)
        exit(0);
 }
 
-static int xfrm_policy_flush_all(void)
+static int xfrm_policy_flush(void)
 {
        struct rtnl_handle rth;
        struct {
@@ -695,7 +699,7 @@ static int xfrm_policy_flush_all(void)
                exit(1);
 
        if (show_stats > 1)
-               fprintf(stderr, "Flush all\n");
+               fprintf(stderr, "Flush policy\n");
 
        if (rtnl_talk(&rth, &req.n, 0, 0, NULL, NULL, NULL) < 0)
                exit(2);
@@ -708,7 +712,7 @@ static int xfrm_policy_flush_all(void)
 int do_xfrm_policy(int argc, char **argv)
 {
        if (argc < 1)
-               return xfrm_policy_list_or_flush(0, NULL, 0);
+               return xfrm_policy_list_or_deleteall(0, NULL, 0);
 
        if (matches(*argv, "add") == 0)
                return xfrm_policy_modify(XFRM_MSG_NEWPOLICY, 0,
@@ -716,19 +720,17 @@ int do_xfrm_policy(int argc, char **argv)
        if (matches(*argv, "update") == 0)
                return xfrm_policy_modify(XFRM_MSG_UPDPOLICY, 0,
                                          argc-1, argv+1);
-       if (matches(*argv, "delete") == 0 || matches(*argv, "del") == 0)
+       if (matches(*argv, "delete") == 0)
                return xfrm_policy_delete(argc-1, argv+1);
+       if (matches(*argv, "deleteall") == 0 || matches(*argv, "delall") == 0)
+               return xfrm_policy_list_or_deleteall(argc-1, argv+1, 1);
        if (matches(*argv, "list") == 0 || matches(*argv, "show") == 0
            || matches(*argv, "lst") == 0)
-               return xfrm_policy_list_or_flush(argc-1, argv+1, 0);
+               return xfrm_policy_list_or_deleteall(argc-1, argv+1, 0);
        if (matches(*argv, "get") == 0)
                return xfrm_policy_get(argc-1, argv+1);
-       if (matches(*argv, "flush") == 0) {
-               if (argc-1 < 1)
-                       return xfrm_policy_flush_all();
-               else
-                       return xfrm_policy_list_or_flush(argc-1, argv+1, 1);
-       }
+       if (matches(*argv, "flush") == 0)
+               return xfrm_policy_flush();
        if (matches(*argv, "help") == 0)
                usage();
        fprintf(stderr, "Command \"%s\" is unknown, try \"ip xfrm policy help\".\n", *argv);