]> git.proxmox.com Git - mirror_iproute2.git/blobdiff - tc/f_fw.c
man: tc-taprio.8: fix syntax error
[mirror_iproute2.git] / tc / f_fw.c
index 64084bbfeeec961a566a1c0171330dbd053e99e2..adce2bdb7d8af353133af9a852b0494e2dd36e15 100644 (file)
--- a/tc/f_fw.c
+++ b/tc/f_fw.c
@@ -13,7 +13,6 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <unistd.h>
-#include <syslog.h>
 #include <fcntl.h>
 #include <sys/socket.h>
 #include <netinet/in.h>
 
 static void explain(void)
 {
-       fprintf(stderr, "Usage: ... fw [ classid CLASSID ] [ police POLICE_SPEC ]\n");
-       fprintf(stderr, "       POLICE_SPEC := ... look at TBF\n");
-       fprintf(stderr, "       CLASSID := X:Y\n");
+       fprintf(stderr,
+               "Usage: ... fw [ classid CLASSID ] [ indev DEV ] [ action ACTION_SPEC ]\n");
+       fprintf(stderr,
+               "       CLASSID := Push matching packets to the class identified by CLASSID with format X:Y\n");
+       fprintf(stderr,
+               "                  CLASSID is parsed as hexadecimal input.\n");
+       fprintf(stderr,
+               "       DEV := specify device for incoming device classification.\n");
+       fprintf(stderr,
+               "       ACTION_SPEC := Apply an action on matching packets.\n");
+       fprintf(stderr,
+               "       NOTE: handle is represented as HANDLE[/FWMASK].\n");
+       fprintf(stderr, "             FWMASK is 0xffffffff by default.\n");
 }
 
-#define usage() return(-1)
-
 static int fw_parse_opt(struct filter_util *qu, char *handle, int argc, char **argv, struct nlmsghdr *n)
 {
-       struct tc_police tp;
        struct tcmsg *t = NLMSG_DATA(n);
        struct rtattr *tail;
-
-       memset(&tp, 0, sizeof(tp));
+       __u32 mask = 0;
+       int mask_set = 0;
 
        if (handle) {
+               char *slash;
+
+               if ((slash = strchr(handle, '/')) != NULL)
+                       *slash = '\0';
                if (get_u32(&t->tcm_handle, handle, 0)) {
                        fprintf(stderr, "Illegal \"handle\"\n");
                        return -1;
                }
+               if (slash) {
+                       if (get_u32(&mask, slash+1, 0)) {
+                               fprintf(stderr, "Illegal \"handle\" mask\n");
+                               return -1;
+                       }
+                       mask_set = 1;
+               }
        }
 
        if (argc == 0)
                return 0;
 
-       tail = (struct rtattr*)(((void*)n)+NLMSG_ALIGN(n->nlmsg_len));
-       addattr_l(n, 4096, TCA_OPTIONS, NULL, 0);
+       tail = addattr_nest(n, 4096, TCA_OPTIONS);
+
+       if (mask_set)
+               addattr32(n, MAX_MSG, TCA_FW_MASK, mask);
 
        while (argc > 0) {
                if (matches(*argv, "classid") == 0 ||
                    matches(*argv, "flowid") == 0) {
-                       unsigned handle;
+                       unsigned int handle;
+
                        NEXT_ARG();
                        if (get_tc_classid(&handle, *argv)) {
                                fprintf(stderr, "Illegal \"classid\"\n");
@@ -78,15 +98,15 @@ static int fw_parse_opt(struct filter_util *qu, char *handle, int argc, char **a
                        }
                        continue;
                } else if (strcmp(*argv, "indev") == 0) {
-                       char d[IFNAMSIZ+1];
-                       memset(d, 0, sizeof (d));
+                       char d[IFNAMSIZ+1] = {};
+
                        argc--;
                        argv++;
                        if (argc < 1) {
                                fprintf(stderr, "Illegal indev\n");
                                return -1;
                        }
-                       strncpy(d, *argv, sizeof (d) - 1);
+                       strncpy(d, *argv, sizeof(d) - 1);
                        addattr_l(n, MAX_MSG, TCA_FW_INDEV, d, strlen(d) + 1);
                } else if (strcmp(*argv, "help") == 0) {
                        explain();
@@ -98,7 +118,7 @@ static int fw_parse_opt(struct filter_util *qu, char *handle, int argc, char **a
                }
                argc--; argv++;
        }
-       tail->rta_len = (((void*)n)+n->nlmsg_len) - (void*)tail;
+       addattr_nest_end(n, tail);
        return 0;
 }
 
@@ -109,28 +129,36 @@ static int fw_print_opt(struct filter_util *qu, FILE *f, struct rtattr *opt, __u
        if (opt == NULL)
                return 0;
 
-       memset(tb, 0, sizeof(tb));
-       if (opt)
-               parse_rtattr(tb, TCA_FW_MAX, RTA_DATA(opt), RTA_PAYLOAD(opt));
+       parse_rtattr_nested(tb, TCA_FW_MAX, opt);
+
+       if (handle || tb[TCA_FW_MASK]) {
+               __u32 mark = 0, mask = 0;
 
-       if (handle)
-               fprintf(f, "handle 0x%x ", handle);
+               if (handle)
+                       mark = handle;
+               if (tb[TCA_FW_MASK] &&
+                   (mask = rta_getattr_u32(tb[TCA_FW_MASK])) != 0xFFFFFFFF)
+                       fprintf(f, "handle 0x%x/0x%x ", mark, mask);
+               else
+                       fprintf(f, "handle 0x%x ", handle);
+       }
 
        if (tb[TCA_FW_CLASSID]) {
                SPRINT_BUF(b1);
-               fprintf(f, "classid %s ", sprint_tc_classid(*(__u32*)RTA_DATA(tb[TCA_FW_CLASSID]), b1));
+               fprintf(f, "classid %s ", sprint_tc_classid(rta_getattr_u32(tb[TCA_FW_CLASSID]), b1));
        }
 
        if (tb[TCA_FW_POLICE])
                tc_print_police(f, tb[TCA_FW_POLICE]);
        if (tb[TCA_FW_INDEV]) {
                struct rtattr *idev = tb[TCA_FW_INDEV];
-               fprintf(f, "input dev %s ",(char *)RTA_DATA(idev));
+
+               fprintf(f, "input dev %s ", rta_getattr_str(idev));
        }
-       
+
        if (tb[TCA_FW_ACT]) {
                fprintf(f, "\n");
-               tc_print_action(f, tb[TCA_FW_ACT]);
+               tc_print_action(f, tb[TCA_FW_ACT], 0);
        }
        return 0;
 }