iproute2/tc/f_basic.c
<<
>>
Prefs
   1/*
   2 * f_basic.c            Basic Classifier
   3 *
   4 *              This program is free software; you can distribute it and/or
   5 *              modify it under the terms of the GNU General Public License
   6 *              as published by the Free Software Foundation; either version
   7 *              2 of the License, or (at your option) any later version.
   8 *
   9 * Authors:     Thomas Graf <tgraf@suug.ch>
  10 *
  11 */
  12
  13#include <stdio.h>
  14#include <stdlib.h>
  15#include <unistd.h>
  16#include <fcntl.h>
  17#include <sys/socket.h>
  18#include <netinet/in.h>
  19#include <arpa/inet.h>
  20#include <string.h>
  21#include <linux/if.h>
  22
  23#include "utils.h"
  24#include "tc_util.h"
  25#include "m_ematch.h"
  26
  27static void explain(void)
  28{
  29        fprintf(stderr,
  30                "Usage: ... basic [ match EMATCH_TREE ]\n"
  31                "                 [ action ACTION_SPEC ] [ classid CLASSID ]\n"
  32                "\n"
  33                "Where: SELECTOR := SAMPLE SAMPLE ...\n"
  34                "       FILTERID := X:Y:Z\n"
  35                "       ACTION_SPEC := ... look at individual actions\n"
  36                "\n"
  37                "NOTE: CLASSID is parsed as hexadecimal input.\n");
  38}
  39
  40static int basic_parse_opt(struct filter_util *qu, char *handle,
  41                           int argc, char **argv, struct nlmsghdr *n)
  42{
  43        struct tcmsg *t = NLMSG_DATA(n);
  44        struct rtattr *tail;
  45        long h = 0;
  46
  47        if (handle) {
  48                h = strtol(handle, NULL, 0);
  49                if (h == LONG_MIN || h == LONG_MAX) {
  50                        fprintf(stderr, "Illegal handle \"%s\", must be numeric.\n",
  51                            handle);
  52                        return -1;
  53                }
  54        }
  55        t->tcm_handle = h;
  56
  57        if (argc == 0)
  58                return 0;
  59
  60        tail = (struct rtattr *)(((void *)n)+NLMSG_ALIGN(n->nlmsg_len));
  61        addattr_l(n, MAX_MSG, TCA_OPTIONS, NULL, 0);
  62
  63        while (argc > 0) {
  64                if (matches(*argv, "match") == 0) {
  65                        NEXT_ARG();
  66                        if (parse_ematch(&argc, &argv, TCA_BASIC_EMATCHES, n)) {
  67                                fprintf(stderr, "Illegal \"ematch\"\n");
  68                                return -1;
  69                        }
  70                        continue;
  71                } else if (matches(*argv, "classid") == 0 ||
  72                           strcmp(*argv, "flowid") == 0) {
  73                        unsigned int handle;
  74
  75                        NEXT_ARG();
  76                        if (get_tc_classid(&handle, *argv)) {
  77                                fprintf(stderr, "Illegal \"classid\"\n");
  78                                return -1;
  79                        }
  80                        addattr_l(n, MAX_MSG, TCA_BASIC_CLASSID, &handle, 4);
  81                } else if (matches(*argv, "action") == 0) {
  82                        NEXT_ARG();
  83                        if (parse_action(&argc, &argv, TCA_BASIC_ACT, n)) {
  84                                fprintf(stderr, "Illegal \"action\"\n");
  85                                return -1;
  86                        }
  87                        continue;
  88
  89                } else if (matches(*argv, "police") == 0) {
  90                        NEXT_ARG();
  91                        if (parse_police(&argc, &argv, TCA_BASIC_POLICE, n)) {
  92                                fprintf(stderr, "Illegal \"police\"\n");
  93                                return -1;
  94                        }
  95                        continue;
  96                } else if (strcmp(*argv, "help") == 0) {
  97                        explain();
  98                        return -1;
  99                } else {
 100                        fprintf(stderr, "What is \"%s\"?\n", *argv);
 101                        explain();
 102                        return -1;
 103                }
 104                argc--; argv++;
 105        }
 106
 107        tail->rta_len = (((void *)n)+n->nlmsg_len) - (void *)tail;
 108        return 0;
 109}
 110
 111static int basic_print_opt(struct filter_util *qu, FILE *f,
 112                           struct rtattr *opt, __u32 handle)
 113{
 114        struct rtattr *tb[TCA_BASIC_MAX+1];
 115
 116        if (opt == NULL)
 117                return 0;
 118
 119        parse_rtattr_nested(tb, TCA_BASIC_MAX, opt);
 120
 121        if (handle)
 122                fprintf(f, "handle 0x%x ", handle);
 123
 124        if (tb[TCA_BASIC_CLASSID]) {
 125                SPRINT_BUF(b1);
 126                fprintf(f, "flowid %s ",
 127                        sprint_tc_classid(rta_getattr_u32(tb[TCA_BASIC_CLASSID]), b1));
 128        }
 129
 130        if (tb[TCA_BASIC_EMATCHES])
 131                print_ematch(f, tb[TCA_BASIC_EMATCHES]);
 132
 133        if (tb[TCA_BASIC_POLICE]) {
 134                fprintf(f, "\n");
 135                tc_print_police(f, tb[TCA_BASIC_POLICE]);
 136        }
 137
 138        if (tb[TCA_BASIC_ACT]) {
 139                tc_print_action(f, tb[TCA_BASIC_ACT], 0);
 140        }
 141
 142        return 0;
 143}
 144
 145struct filter_util basic_filter_util = {
 146        .id = "basic",
 147        .parse_fopt = basic_parse_opt,
 148        .print_fopt = basic_print_opt,
 149};
 150