Checkign in new iproute2
[iproute2.git] / tc / f_fw.c
index 5a56098..b511735 100644 (file)
--- a/tc/f_fw.c
+++ b/tc/f_fw.c
@@ -28,6 +28,7 @@ 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, "\nNOTE: CLASSID is parsed as hexadecimal input.\n");
 }
 
 #define usage() return(-1)
@@ -40,19 +41,30 @@ static int fw_parse_opt(struct filter_util *qu, char *handle, int argc, char **a
 
        memset(&tp, 0, sizeof(tp));
 
+       tail = NLMSG_TAIL(n);
+       addattr_l(n, 4096, TCA_OPTIONS, NULL, 0);
+
        if (handle) {
+               char *slash;
+               __u32 mask = 0;
+               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;
+                       }
+                       addattr32(n, MAX_MSG, TCA_FW_MASK, mask);
+               }
        }
 
        if (argc == 0)
                return 0;
 
-       tail = NLMSG_TAIL(n);
-       addattr_l(n, 4096, TCA_OPTIONS, NULL, 0);
-
        while (argc > 0) {
                if (matches(*argv, "classid") == 0 ||
                    matches(*argv, "flowid") == 0) {
@@ -111,8 +123,16 @@ static int fw_print_opt(struct filter_util *qu, FILE *f, struct rtattr *opt, __u
 
        parse_rtattr_nested(tb, TCA_FW_MAX, opt);
 
-       if (handle)
-               fprintf(f, "handle 0x%x ", handle);
+       if (handle || tb[TCA_FW_MASK]) {
+               __u32 mark = 0, mask = 0;
+               if(handle)
+                       mark = handle;
+               if(tb[TCA_FW_MASK] &&
+                   (mask = *(__u32*)RTA_DATA(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);
@@ -125,7 +145,7 @@ static int fw_print_opt(struct filter_util *qu, FILE *f, struct rtattr *opt, __u
                struct rtattr *idev = tb[TCA_FW_INDEV];
                fprintf(f, "input dev %s ",(char *)RTA_DATA(idev));
        }
-       
+
        if (tb[TCA_FW_ACT]) {
                fprintf(f, "\n");
                tc_print_action(f, tb[TCA_FW_ACT]);