]> rtime.felk.cvut.cz Git - lisovros/iproute2_canprio.git/commitdiff
add decode of match rules
authorStephen Hemminger <stephen.hemminger@vyatta.com>
Mon, 31 Dec 2007 18:29:52 +0000 (10:29 -0800)
committerStephen Hemminger <stephen.hemminger@vyatta.com>
Mon, 31 Dec 2007 18:29:52 +0000 (10:29 -0800)
Show ip address etc when decoding output of tc filter show

Signed-off-by: Stephen Hemminger <stephen.hemminger@vyatta.com>
include/utils.h
lib/utils.c
tc/f_u32.c

index 7223a10d4f90acd61107a0460c20100c4780db75..5daed6b313935e299cd15d92264464017a18ea35 100644 (file)
@@ -74,6 +74,7 @@ extern int get_addr_1(inet_prefix *dst, const char *arg, int family);
 extern int get_prefix_1(inet_prefix *dst, char *arg, int family);
 extern int get_addr(inet_prefix *dst, const char *arg, int family);
 extern int get_prefix(inet_prefix *dst, char *arg, int family);
+extern int mask2bits(__u32 netmask);
 
 extern int get_integer(int *val, const char *arg, int base);
 extern int get_unsigned(unsigned *val, const char *arg, int base);
index 84948513d7da43703035d18b209713a16c15c35c..d99deacd46f7115645db0c58b8f9587784b9a36d 100644 (file)
@@ -47,27 +47,18 @@ int get_integer(int *val, const char *arg, int base)
        return 0;
 }
 
-/* a valid netmask must be 2^n - 1 */
-static int is_valid_netmask(const inet_prefix *addr)
-{
-        uint32_t host;
-
-        if (addr->family != AF_INET)
-                return 0;
-
-        host = ~ntohl(addr->data[0]);
-
-        return (host & (host + 1)) == 0;
-}
-
-static unsigned cidr(const inet_prefix *addr)
+int mask2bits(__u32 netmask)
 {
        unsigned bits = 0;
-       u_int32_t mask;
+       __u32 mask = ntohl(netmask);
+       __u32 host = ~mask;
 
-       for (mask = ntohl(addr->data[0]); mask; mask <<= 1)
-               ++bits;
+       /* a valid netmask must be 2^n - 1 */
+       if ((host & (host + 1)) != 0)
+               return -1;
 
+       for (; mask; mask <<= 1)
+               ++bits;
        return bits;
 }
 
@@ -79,11 +70,13 @@ static int get_netmask(unsigned *val, const char *arg, int base)
                return 0;
 
        /* try coverting dotted quad to CIDR */
-       if (!get_addr_1(&addr, arg, AF_INET)) {
-               if (is_valid_netmask(&addr))
+       if (!get_addr_1(&addr, arg, AF_INET) && addr.family == AF_INET) {
+               int b = mask2bits(addr.data[0]);
+               
+               if (b >= 0) {
+                       *val = b;
                        return 0;
-
-               *val = cidr(&addr);
+               }
        }
 
        return -1;
index 1ac671b33059cb0244d9754334b936c015d80258..91f2838b7b3710473728980fdf269d22861bbd0c 100644 (file)
@@ -473,7 +473,7 @@ done:
        *argv_p = argv;
        return res;
 }
-
+                               
 static int parse_ip6(int *argc_p, char ***argv_p, struct tc_u32_sel *sel)
 {
        int res = -1;
@@ -564,6 +564,7 @@ done:
        return res;
 }
 
+
 static int parse_icmp(int *argc_p, char ***argv_p, struct tc_u32_sel *sel)
 {
        int res = -1;
@@ -771,7 +772,47 @@ static int parse_hashkey(int *argc_p, char ***argv_p, struct tc_u32_sel *sel)
        return 0;
 }
 
-static int u32_parse_opt(struct filter_util *qu, char *handle, int argc, char **argv, struct nlmsghdr *n)
+static void show_key(FILE *f, const struct tc_u32_key *key)
+{
+       char abuf[256];
+
+       if (show_raw)
+               goto raw;
+
+       switch (key->off) {
+       case 12:
+       case 16: {
+                       int bits = mask2bits(key->mask);
+                       if (bits >= 0) {
+                               fprintf(f, "\n  %s %s/%d\n", 
+                                       key->off == 12 ? "src" : "dst",
+                                       inet_ntop(AF_INET, &key->val, abuf, sizeof(abuf)),
+                                       bits);
+                               return;
+                       }
+               }
+               break;
+
+       case 20:
+       case 22:
+               if (key->mask == ntohl(0xffff)) {
+                       fprintf(f, "\n  %s %u\n", 
+                               key->off == 20 ? "sport" : "dport",
+                               (unsigned short) ntohl(key->val));
+                       return;
+               }
+       }
+
+raw:
+       fprintf(f, "\n  match %08x/%08x at %s%d",
+               (unsigned int)ntohl(key->val),
+               (unsigned int)ntohl(key->mask),
+               key->offmask ? "nexthdr+" : "",
+               key->off);
+}
+
+static int u32_parse_opt(struct filter_util *qu, char *handle, 
+                        int argc, char **argv, struct nlmsghdr *n)
 {
        struct {
                struct tc_u32_sel sel;
@@ -966,7 +1007,8 @@ static int u32_parse_opt(struct filter_util *qu, char *handle, int argc, char **
        return 0;
 }
 
-static int u32_print_opt(struct filter_util *qu, FILE *f, struct rtattr *opt, __u32 handle)
+static int u32_print_opt(struct filter_util *qu, FILE *f, struct rtattr *opt,
+                        __u32 handle)
 {
        struct rtattr *tb[TCA_U32_MAX+1];
        struct tc_u32_sel *sel = NULL;
@@ -1037,17 +1079,12 @@ static int u32_print_opt(struct filter_util *qu, FILE *f, struct rtattr *opt, __
        }
 
        if (sel) {
-               int i;
-               struct tc_u32_key *key = sel->keys;
                if (sel->nkeys) {
-                       for (i=0; i<sel->nkeys; i++, key++) {
-                               fprintf(f, "\n  match %08x/%08x at %s%d",
-                                       (unsigned int)ntohl(key->val),
-                                       (unsigned int)ntohl(key->mask),
-                                       key->offmask ? "nexthdr+" : "",
-                                       key->off);
+                       int i;
+                       for (i=0; i<sel->nkeys; i++) {
+                               show_key(f, sel->keys + i);
                                if (show_stats && NULL != pf)
-                                       fprintf(f, " (success %lld ) ",
+                                       fprintf(f, " (success %llu ) ",
                                                (unsigned long long) pf->kcnts[i]);
                        }
                }