]> git.proxmox.com Git - mirror_iproute2.git/blobdiff - tc/m_ife.c
tc: flower: support multiple MPLS LSE match
[mirror_iproute2.git] / tc / m_ife.c
index 862461bc23680ef3c472c30cbc06a783391b9858..6a85e087ede1cc2c4085d0c51abb54218fc257aa 100644 (file)
@@ -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>
@@ -29,8 +28,7 @@
 static void ife_explain(void)
 {
        fprintf(stderr,
-               "Usage:... ife {decode|encode} [{ALLOW|USE} ATTR] [dst DMAC] [src SMAC] [type TYPE] [CONTROL] [index INDEX]\n");
-       fprintf(stderr,
+               "Usage:... ife {decode|encode} [{ALLOW|USE} ATTR] [dst DMAC] [src SMAC] [type TYPE] [CONTROL] [index INDEX]\n"
                "\tALLOW := Encode direction. Allows encoding specified metadata\n"
                "\t\t e.g \"allow mark\"\n"
                "\tUSE := Encode direction. Enforce Static encoding of specified metadata\n"
@@ -40,9 +38,9 @@ static void ife_explain(void)
                "\tSMAC := optional 6 byte Source MAC address to encode\n"
                "\tTYPE := optional 16 bit ethertype to encode\n"
                "\tCONTROL := reclassify|pipe|drop|continue|ok\n"
-               "\tINDEX := optional IFE table index value used\n");
-       fprintf(stderr, "encode is used for sending IFE packets\n");
-       fprintf(stderr, "decode is used for receiving IFE packets\n");
+               "\tINDEX := optional IFE table index value used\n"
+               "encode is used for sending IFE packets\n"
+               "decode is used for receiving IFE packets\n");
 }
 
 static void ife_usage(void)
@@ -57,16 +55,19 @@ static int parse_ife(struct action_util *a, int *argc_p, char ***argv_p,
        int argc = *argc_p;
        char **argv = *argv_p;
        int ok = 0;
-       struct tc_ife p = { .action = TC_ACT_PIPE };    /* good default */
+       struct tc_ife p = { 0 };
        struct rtattr *tail;
        struct rtattr *tail2;
        char dbuf[ETH_ALEN];
        char sbuf[ETH_ALEN];
        __u16 ife_type = 0;
+       int user_type = 0;
        __u32 ife_prio = 0;
        __u32 ife_prio_v = 0;
        __u32 ife_mark = 0;
        __u32 ife_mark_v = 0;
+       __u16 ife_tcindex = 0;
+       __u16 ife_tcindex_v = 0;
        char *daddr = NULL;
        char *saddr = NULL;
 
@@ -89,10 +90,10 @@ static int parse_ife(struct action_util *a, int *argc_p, char ***argv_p,
                                ife_mark = IFE_META_SKBMARK;
                        } else if (matches(*argv, "prio") == 0) {
                                ife_prio = IFE_META_PRIO;
+                       } else if (matches(*argv, "tcindex") == 0) {
+                               ife_tcindex = IFE_META_TCINDEX;
                        } else {
-                               fprintf(stderr, "Illegal meta define <%s>\n",
-                                       *argv);
-                               return -1;
+                               invarg("Illegal meta define", *argv);
                        }
                } else if (matches(*argv, "use") == 0) {
                        NEXT_ARG();
@@ -106,24 +107,27 @@ static int parse_ife(struct action_util *a, int *argc_p, char ***argv_p,
                                if (get_u32(&ife_prio_v, *argv, 0))
                                        invarg("ife prio val is invalid",
                                               *argv);
+                       } else if (matches(*argv, "tcindex") == 0) {
+                               NEXT_ARG();
+                               if (get_u16(&ife_tcindex_v, *argv, 0))
+                                       invarg("ife tcindex val is invalid",
+                                              *argv);
                        } else {
-                               fprintf(stderr, "Illegal meta use type <%s>\n",
-                                       *argv);
-                               return -1;
+                               invarg("Illegal meta use type", *argv);
                        }
                } else if (matches(*argv, "type") == 0) {
                        NEXT_ARG();
                        if (get_u16(&ife_type, *argv, 0))
                                invarg("ife type is invalid", *argv);
-                       fprintf(stderr, "IFE type 0x%x\n", ife_type);
+                       fprintf(stderr, "IFE type 0x%04X\n", ife_type);
+                       user_type = 1;
                } else if (matches(*argv, "dst") == 0) {
                        NEXT_ARG();
                        daddr = *argv;
                        if (sscanf(daddr, "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx",
                                   dbuf, dbuf + 1, dbuf + 2,
                                   dbuf + 3, dbuf + 4, dbuf + 5) != 6) {
-                               fprintf(stderr, "Invalid mac address %s\n",
-                                       daddr);
+                               invarg("Invalid mac address", *argv);
                        }
                        fprintf(stderr, "dst MAC address <%s>\n", daddr);
 
@@ -133,8 +137,7 @@ static int parse_ife(struct action_util *a, int *argc_p, char ***argv_p,
                        if (sscanf(saddr, "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx",
                                   sbuf, sbuf + 1, sbuf + 2,
                                   sbuf + 3, sbuf + 4, sbuf + 5) != 6) {
-                               fprintf(stderr, "Invalid mac address %s\n",
-                                       saddr);
+                               invarg("Invalid mac address", *argv);
                        }
                        fprintf(stderr, "src MAC address <%s>\n", saddr);
                } else if (matches(*argv, "help") == 0) {
@@ -147,8 +150,7 @@ static int parse_ife(struct action_util *a, int *argc_p, char ***argv_p,
                argv++;
        }
 
-       if (argc && !action_a2n(*argv, &p.action, false))
-               NEXT_ARG_FWD();
+       parse_action_control_dflt(&argc, &argv, &p.action, false, TC_ACT_PIPE);
 
        if (argc) {
                if (matches(*argv, "index") == 0) {
@@ -168,8 +170,7 @@ static int parse_ife(struct action_util *a, int *argc_p, char ***argv_p,
                ife_usage();
        }
 
-       tail = NLMSG_TAIL(n);
-       addattr_l(n, MAX_MSG, tca_id, NULL, 0);
+       tail = addattr_nest(n, MAX_MSG, tca_id);
        addattr_l(n, MAX_MSG, TCA_IFE_PARMS, &p, sizeof(p));
 
        if (!(p.flags & IFE_ENCODE))
@@ -177,13 +178,14 @@ static int parse_ife(struct action_util *a, int *argc_p, char ***argv_p,
 
        if (daddr)
                addattr_l(n, MAX_MSG, TCA_IFE_DMAC, dbuf, ETH_ALEN);
-       if (ife_type)
+       if (user_type)
                addattr_l(n, MAX_MSG, TCA_IFE_TYPE, &ife_type, 2);
+       else
+               fprintf(stderr, "IFE type 0x%04X\n", ETH_P_IFE);
        if (saddr)
                addattr_l(n, MAX_MSG, TCA_IFE_SMAC, sbuf, ETH_ALEN);
 
-       tail2 = NLMSG_TAIL(n);
-       addattr_l(n, MAX_MSG, TCA_IFE_METALST, NULL, 0);
+       tail2 = addattr_nest(n, MAX_MSG, TCA_IFE_METALST);
        if (ife_mark || ife_mark_v) {
                if (ife_mark_v)
                        addattr_l(n, MAX_MSG, IFE_META_SKBMARK, &ife_mark_v, 4);
@@ -196,11 +198,18 @@ static int parse_ife(struct action_util *a, int *argc_p, char ***argv_p,
                else
                        addattr_l(n, MAX_MSG, IFE_META_PRIO, NULL, 0);
        }
+       if (ife_tcindex || ife_tcindex_v) {
+               if (ife_tcindex_v)
+                       addattr_l(n, MAX_MSG, IFE_META_TCINDEX, &ife_tcindex_v,
+                                 2);
+               else
+                       addattr_l(n, MAX_MSG, IFE_META_TCINDEX, NULL, 0);
+       }
 
-       tail2->rta_len = (void *)NLMSG_TAIL(n) - (void *)tail2;
+       addattr_nest_end(n, tail2);
 
 skip_encode:
-       tail->rta_len = (void *)NLMSG_TAIL(n) - (void *)tail;
+       addattr_nest_end(n, tail);
 
        *argc_p = argc;
        *argv_p = argv;
@@ -209,11 +218,11 @@ skip_encode:
 
 static int print_ife(struct action_util *au, FILE *f, struct rtattr *arg)
 {
-       struct tc_ife *p = NULL;
+       struct tc_ife *p;
        struct rtattr *tb[TCA_IFE_MAX + 1];
        __u16 ife_type = 0;
        __u32 mmark = 0;
-       __u32 mhash = 0;
+       __u16 mtcindex = 0;
        __u32 mprio = 0;
        int has_optional = 0;
        SPRINT_BUF(b2);
@@ -224,23 +233,24 @@ static int print_ife(struct action_util *au, FILE *f, struct rtattr *arg)
        parse_rtattr_nested(tb, TCA_IFE_MAX, arg);
 
        if (tb[TCA_IFE_PARMS] == NULL) {
-               fprintf(f, "[NULL ife parameters]");
+               fprintf(stderr, "Missing ife parameters\n");
                return -1;
        }
        p = RTA_DATA(tb[TCA_IFE_PARMS]);
 
-       fprintf(f, "ife %s action %s ",
-               (p->flags & IFE_ENCODE) ? "encode" : "decode",
-               action_n2a(p->action));
+       print_string(PRINT_ANY, "kind", "%s ", "ife");
+       print_string(PRINT_ANY, "mode", "%s ",
+                    p->flags & IFE_ENCODE ? "encode" : "decode");
+       print_action_control(f, "action ", p->action, " ");
 
        if (tb[TCA_IFE_TYPE]) {
                ife_type = rta_getattr_u16(tb[TCA_IFE_TYPE]);
                has_optional = 1;
-               fprintf(f, "type 0x%X ", ife_type);
+               print_0xhex(PRINT_ANY, "type", "type %#llX ", ife_type);
        }
 
        if (has_optional)
-               fprintf(f, "\n\t ");
+               print_string(PRINT_FP, NULL, "%s\t", _SL_);
 
        if (tb[TCA_IFE_METALST]) {
                struct rtattr *metalist[IFE_META_MAX + 1];
@@ -253,50 +263,59 @@ static int print_ife(struct action_util *au, FILE *f, struct rtattr *arg)
                        len = RTA_PAYLOAD(metalist[IFE_META_SKBMARK]);
                        if (len) {
                                mmark = rta_getattr_u32(metalist[IFE_META_SKBMARK]);
-                               fprintf(f, "use mark %u ", mmark);
+                               print_uint(PRINT_ANY, "mark", "use mark %u ",
+                                          mmark);
                        } else
-                               fprintf(f, "allow mark ");
+                               print_string(PRINT_ANY, "mark", "%s mark ",
+                                            "allow");
                }
 
-               if (metalist[IFE_META_HASHID]) {
-                       len = RTA_PAYLOAD(metalist[IFE_META_HASHID]);
+               if (metalist[IFE_META_TCINDEX]) {
+                       len = RTA_PAYLOAD(metalist[IFE_META_TCINDEX]);
                        if (len) {
-                               mhash = rta_getattr_u32(metalist[IFE_META_HASHID]);
-                               fprintf(f, "use hash %u ", mhash);
+                               mtcindex =
+                                       rta_getattr_u16(metalist[IFE_META_TCINDEX]);
+                               print_uint(PRINT_ANY, "tcindex",
+                                          "use tcindex %u ", mtcindex);
                        } else
-                               fprintf(f, "allow hash ");
+                               print_string(PRINT_ANY, "tcindex",
+                                            "%s tcindex ", "allow");
                }
 
                if (metalist[IFE_META_PRIO]) {
                        len = RTA_PAYLOAD(metalist[IFE_META_PRIO]);
                        if (len) {
                                mprio = rta_getattr_u32(metalist[IFE_META_PRIO]);
-                               fprintf(f, "use prio %u ", mprio);
+                               print_uint(PRINT_ANY, "prio", "use prio %u ",
+                                          mprio);
                        } else
-                               fprintf(f, "allow prio ");
+                               print_string(PRINT_ANY, "prio", "%s prio ",
+                                            "allow");
                }
 
        }
 
        if (tb[TCA_IFE_DMAC]) {
                has_optional = 1;
-               fprintf(f, "dst %s ",
-                       ll_addr_n2a(RTA_DATA(tb[TCA_IFE_DMAC]),
-                                   RTA_PAYLOAD(tb[TCA_IFE_DMAC]), 0, b2,
-                                   sizeof(b2)));
-
+               print_string(PRINT_ANY, "dst", "dst %s ",
+                            ll_addr_n2a(RTA_DATA(tb[TCA_IFE_DMAC]),
+                                        RTA_PAYLOAD(tb[TCA_IFE_DMAC]), 0, b2,
+                                        sizeof(b2)));
        }
 
        if (tb[TCA_IFE_SMAC]) {
                has_optional = 1;
-               fprintf(f, "src %s ",
-                       ll_addr_n2a(RTA_DATA(tb[TCA_IFE_SMAC]),
-                                   RTA_PAYLOAD(tb[TCA_IFE_SMAC]), 0, b2,
-                                   sizeof(b2)));
+               print_string(PRINT_ANY, "src", "src %s ",
+                            ll_addr_n2a(RTA_DATA(tb[TCA_IFE_SMAC]),
+                                        RTA_PAYLOAD(tb[TCA_IFE_SMAC]), 0, b2,
+                                        sizeof(b2)));
        }
 
-       fprintf(f, "\n\t index %d ref %d bind %d", p->index, p->refcnt,
-               p->bindcnt);
+       print_nl();
+       print_uint(PRINT_ANY, "index", "\t index %u", p->index);
+       print_int(PRINT_ANY, "ref", " ref %d", p->refcnt);
+       print_int(PRINT_ANY, "bind", " bind %d", p->bindcnt);
+
        if (show_stats) {
                if (tb[TCA_IFE_TM]) {
                        struct tcf_t *tm = RTA_DATA(tb[TCA_IFE_TM]);
@@ -305,7 +324,7 @@ static int print_ife(struct action_util *au, FILE *f, struct rtattr *arg)
                }
        }
 
-       fprintf(f, "\n");
+       print_nl();
 
        return 0;
 }