]> git.proxmox.com Git - mirror_iproute2.git/blobdiff - tc/f_u32.c
rdma: Properly mark RDMAtool license
[mirror_iproute2.git] / tc / f_u32.c
index 1962dfe21455c3ada732ac05e82cce0964aa7ca7..e0a322d5a11c891107b95520ce480a50b41b689a 100644 (file)
@@ -14,7 +14,6 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <unistd.h>
-#include <syslog.h>
 #include <fcntl.h>
 #include <sys/socket.h>
 #include <netinet/in.h>
 #include "utils.h"
 #include "tc_util.h"
 
-extern int show_pretty;
-
 static void explain(void)
 {
-       fprintf(stderr, "Usage: ... u32 [ match SELECTOR ... ] [ link HTID ] [ classid CLASSID ]\n");
-       fprintf(stderr, "               [ action ACTION_SPEC ] [ offset OFFSET_SPEC ]\n");
-       fprintf(stderr, "               [ ht HTID ] [ hashkey HASHKEY_SPEC ]\n");
-       fprintf(stderr, "               [ sample SAMPLE ]\n");
-       fprintf(stderr, "or         u32 divisor DIVISOR\n");
-       fprintf(stderr, "\n");
-       fprintf(stderr, "Where: SELECTOR := SAMPLE SAMPLE ...\n");
-       fprintf(stderr, "       SAMPLE := { ip | ip6 | udp | tcp | icmp | u{32|16|8} | mark } SAMPLE_ARGS [divisor DIVISOR]\n");
-       fprintf(stderr, "       FILTERID := X:Y:Z\n");
-       fprintf(stderr, "\nNOTE: CLASSID is parsed at hexadecimal input.\n");
+       fprintf(stderr,
+               "Usage: ... u32 [ match SELECTOR ... ] [ link HTID ] [ classid CLASSID ]\n"
+               "               [ action ACTION_SPEC ] [ offset OFFSET_SPEC ]\n"
+               "               [ ht HTID ] [ hashkey HASHKEY_SPEC ]\n"
+               "               [ sample SAMPLE ] [skip_hw | skip_sw]\n"
+               "or         u32 divisor DIVISOR\n"
+               "\n"
+               "Where: SELECTOR := SAMPLE SAMPLE ...\n"
+               "       SAMPLE := { ip | ip6 | udp | tcp | icmp | u{32|16|8} | mark }\n"
+               "                 SAMPLE_ARGS [ divisor DIVISOR ]\n"
+               "       FILTERID := X:Y:Z\n"
+               "\nNOTE: CLASSID is parsed at hexadecimal input.\n");
 }
 
 static int get_u32_handle(__u32 *handle, const char *str)
@@ -383,8 +382,7 @@ static int parse_ip6_addr(int *argc_p, char ***argv_p,
 
        plen = addr.bitlen;
        for (i = 0; i < plen; i += 32) {
-               /* if (((i + 31) & ~0x1F) <= plen) { */
-               if (i + 31 <= plen) {
+               if (i + 31 < plen) {
                        res = pack_key(sel, addr.data[i / 32],
                                       0xFFFFFFFF, off + 4 * (i / 32), offmask);
                        if (res < 0)
@@ -767,12 +765,9 @@ static int parse_offset(int *argc_p, char ***argv_p, struct tc_u32_sel *sel)
                        }
                        sel->flags |= TC_U32_VAROFFSET;
                } else if (matches(*argv, "mask") == 0) {
-                       __u16 mask;
-
                        NEXT_ARG();
-                       if (get_u16(&mask, *argv, 16))
+                       if (get_be16(&sel->offmask, *argv, 16))
                                return -1;
-                       sel->offmask = htons(mask);
                        sel->flags |= TC_U32_VAROFFSET;
                } else if (matches(*argv, "shift") == 0) {
                        int shift;
@@ -802,12 +797,9 @@ static int parse_hashkey(int *argc_p, char ***argv_p, struct tc_u32_sel *sel)
 
        while (argc > 0) {
                if (matches(*argv, "mask") == 0) {
-                       __u32 mask;
-
                        NEXT_ARG();
-                       if (get_u32(&mask, *argv, 16))
+                       if (get_be32(&sel->hmask, *argv, 16))
                                return -1;
-                       sel->hmask = htonl(mask);
                } else if (matches(*argv, "at") == 0) {
                        int num;
 
@@ -971,7 +963,7 @@ static void show_keys(FILE *f, const struct tc_u32_key *key)
 {
        int i = 0;
 
-       if (!show_pretty)
+       if (!pretty)
                goto show_k;
 
        for (i = 0; i < ARRAY_SIZE(u32_pprinters); i++) {
@@ -992,15 +984,14 @@ static int u32_parse_opt(struct filter_util *qu, char *handle,
        struct {
                struct tc_u32_sel sel;
                struct tc_u32_key keys[128];
-       } sel;
+       } sel = {};
        struct tcmsg *t = NLMSG_DATA(n);
        struct rtattr *tail;
        int sel_ok = 0, terminal_ok = 0;
        int sample_ok = 0;
        __u32 htid = 0;
        __u32 order = 0;
-
-       memset(&sel, 0, sizeof(sel));
+       __u32 flags = 0;
 
        if (handle && get_u32_handle(&t->tcm_handle, handle)) {
                fprintf(stderr, "Illegal filter ID\n");
@@ -1010,8 +1001,7 @@ static int u32_parse_opt(struct filter_util *qu, char *handle,
        if (argc == 0)
                return 0;
 
-       tail = NLMSG_TAIL(n);
-       addattr_l(n, MAX_MSG, TCA_OPTIONS, NULL, 0);
+       tail = addattr_nest(n, MAX_MSG, TCA_OPTIONS);
 
        while (argc > 0) {
                if (matches(*argv, "match") == 0) {
@@ -1076,7 +1066,7 @@ static int u32_parse_opt(struct filter_util *qu, char *handle,
                                fprintf(stderr, "\"link\" must be a hash table.\n");
                                return -1;
                        }
-                       addattr_l(n, MAX_MSG, TCA_U32_LINK, &handle, 4);
+                       addattr_l(n, MAX_MSG, TCA_U32_LINK, &linkid, 4);
                } else if (strcmp(*argv, "ht") == 0) {
                        unsigned int ht;
 
@@ -1096,12 +1086,11 @@ static int u32_parse_opt(struct filter_util *qu, char *handle,
                } else if (strcmp(*argv, "sample") == 0) {
                        __u32 hash;
                        unsigned int divisor = 0x100;
-
                        struct {
                                struct tc_u32_sel sel;
                                struct tc_u32_key keys[4];
-                       } sel2;
-                       memset(&sel2, 0, sizeof(sel2));
+                       } sel2 = {};
+
                        NEXT_ARG();
                        if (parse_selector(&argc, &argv, &sel2.sel, n)) {
                                fprintf(stderr, "Illegal \"sample\"\n");
@@ -1128,9 +1117,8 @@ static int u32_parse_opt(struct filter_util *qu, char *handle,
                        sample_ok = 1;
                        continue;
                } else if (strcmp(*argv, "indev") == 0) {
-                       char ind[IFNAMSIZ + 1];
+                       char ind[IFNAMSIZ + 1] = {};
 
-                       memset(ind, 0, sizeof(ind));
                        argc--;
                        argv++;
                        if (argc < 1) {
@@ -1158,6 +1146,10 @@ static int u32_parse_opt(struct filter_util *qu, char *handle,
                        }
                        terminal_ok++;
                        continue;
+               } else if (strcmp(*argv, "skip_hw") == 0) {
+                       flags |= TCA_CLS_FLAGS_SKIP_HW;
+               } else if (strcmp(*argv, "skip_sw") == 0) {
+                       flags |= TCA_CLS_FLAGS_SKIP_SW;
                } else if (strcmp(*argv, "help") == 0) {
                        explain();
                        return -1;
@@ -1169,7 +1161,7 @@ static int u32_parse_opt(struct filter_util *qu, char *handle,
                argc--; argv++;
        }
 
-       /* We dont necessarily need class/flowids */
+       /* We don't necessarily need class/flowids */
        if (terminal_ok)
                sel.sel.flags |= TC_U32_TERMINAL;
 
@@ -1188,7 +1180,17 @@ static int u32_parse_opt(struct filter_util *qu, char *handle,
                addattr_l(n, MAX_MSG, TCA_U32_SEL, &sel,
                          sizeof(sel.sel) +
                          sel.sel.nkeys * sizeof(struct tc_u32_key));
-       tail->rta_len = (void *) NLMSG_TAIL(n) - (void *) tail;
+       if (flags) {
+               if (!(flags ^ (TCA_CLS_FLAGS_SKIP_HW |
+                              TCA_CLS_FLAGS_SKIP_SW))) {
+                       fprintf(stderr,
+                               "skip_hw and skip_sw are mutually exclusive\n");
+                       return -1;
+               }
+               addattr_l(n, MAX_MSG, TCA_U32_FLAGS, &flags, 4);
+       }
+
+       addattr_nest_end(n, tail);
        return 0;
 }
 
@@ -1208,9 +1210,9 @@ static int u32_print_opt(struct filter_util *qu, FILE *f, struct rtattr *opt,
                SPRINT_BUF(b1);
                fprintf(f, "fh %s ", sprint_u32_handle(handle, b1));
        }
-       if (TC_U32_NODE(handle)) {
+
+       if (TC_U32_NODE(handle))
                fprintf(f, "order %d ", TC_U32_NODE(handle));
-       }
 
        if (tb[TCA_U32_SEL]) {
                if (RTA_PAYLOAD(tb[TCA_U32_SEL])  < sizeof(*sel))
@@ -1246,6 +1248,20 @@ static int u32_print_opt(struct filter_util *qu, FILE *f, struct rtattr *opt,
                                          b1));
        }
 
+       if (tb[TCA_U32_FLAGS]) {
+               __u32 flags = rta_getattr_u32(tb[TCA_U32_FLAGS]);
+
+               if (flags & TCA_CLS_FLAGS_SKIP_HW)
+                       fprintf(f, "skip_hw ");
+               if (flags & TCA_CLS_FLAGS_SKIP_SW)
+                       fprintf(f, "skip_sw ");
+
+               if (flags & TCA_CLS_FLAGS_IN_HW)
+                       fprintf(f, "in_hw ");
+               else if (flags & TCA_CLS_FLAGS_NOT_IN_HW)
+                       fprintf(f, "not_in_hw ");
+       }
+
        if (tb[TCA_U32_PCNT]) {
                if (RTA_PAYLOAD(tb[TCA_U32_PCNT])  < sizeof(*pf)) {
                        fprintf(f, "Broken perf counters\n");
@@ -1304,14 +1320,15 @@ static int u32_print_opt(struct filter_util *qu, FILE *f, struct rtattr *opt,
                fprintf(f, "\n");
                tc_print_police(f, tb[TCA_U32_POLICE]);
        }
+
        if (tb[TCA_U32_INDEV]) {
                struct rtattr *idev = tb[TCA_U32_INDEV];
 
                fprintf(f, "\n  input dev %s\n", rta_getattr_str(idev));
        }
-       if (tb[TCA_U32_ACT]) {
-               tc_print_action(f, tb[TCA_U32_ACT]);
-       }
+
+       if (tb[TCA_U32_ACT])
+               tc_print_action(f, tb[TCA_U32_ACT], 0);
 
        return 0;
 }