iproute2/tc/m_connmark.c
<<
>>
Prefs
   1/*
   2 * m_connmark.c         Connection tracking marking import
   3 *
   4 * Copyright (c) 2011 Felix Fietkau <nbd@openwrt.org>
   5 *
   6 * This program is free software; you can redistribute it and/or modify it
   7 * under the terms and conditions of the GNU General Public License,
   8 * version 2, as published by the Free Software Foundation.
   9 *
  10 * This program is distributed in the hope it will be useful, but WITHOUT
  11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  12 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
  13 * more details.
  14 *
  15 * You should have received a copy of the GNU General Public License along with
  16 * this program; if not, see <http://www.gnu.org/licenses>.
  17 */
  18
  19#include <stdio.h>
  20#include <stdlib.h>
  21#include <unistd.h>
  22#include <string.h>
  23#include "utils.h"
  24#include "tc_util.h"
  25#include <linux/tc_act/tc_connmark.h>
  26
  27static void
  28explain(void)
  29{
  30        fprintf(stderr,
  31                "Usage: ... connmark [zone ZONE] [CONTROL] [index <INDEX>]\n"
  32                "where :\n"
  33                "\tZONE is the conntrack zone\n"
  34                "\tCONTROL := reclassify | pipe | drop | continue | ok |\n"
  35                "\t           goto chain <CHAIN_INDEX>\n");
  36}
  37
  38static void
  39usage(void)
  40{
  41        explain();
  42        exit(-1);
  43}
  44
  45static int
  46parse_connmark(struct action_util *a, int *argc_p, char ***argv_p, int tca_id,
  47              struct nlmsghdr *n)
  48{
  49        struct tc_connmark sel = {};
  50        char **argv = *argv_p;
  51        int argc = *argc_p;
  52        int ok = 0;
  53        struct rtattr *tail;
  54
  55        while (argc > 0) {
  56                if (matches(*argv, "connmark") == 0) {
  57                        ok = 1;
  58                        argc--;
  59                        argv++;
  60                } else if (matches(*argv, "help") == 0) {
  61                        usage();
  62                } else {
  63                        break;
  64                }
  65
  66        }
  67
  68        if (!ok) {
  69                explain();
  70                return -1;
  71        }
  72
  73        if (argc) {
  74                if (matches(*argv, "zone") == 0) {
  75                        NEXT_ARG();
  76                        if (get_u16(&sel.zone, *argv, 10)) {
  77                                fprintf(stderr, "connmark: Illegal \"zone\"\n");
  78                                return -1;
  79                        }
  80                        argc--;
  81                        argv++;
  82                }
  83        }
  84
  85        parse_action_control_dflt(&argc, &argv, &sel.action, false, TC_ACT_PIPE);
  86
  87        if (argc) {
  88                if (matches(*argv, "index") == 0) {
  89                        NEXT_ARG();
  90                        if (get_u32(&sel.index, *argv, 10)) {
  91                                fprintf(stderr, "connmark: Illegal \"index\"\n");
  92                                return -1;
  93                        }
  94                        argc--;
  95                        argv++;
  96                }
  97        }
  98
  99        tail = addattr_nest(n, MAX_MSG, tca_id);
 100        addattr_l(n, MAX_MSG, TCA_CONNMARK_PARMS, &sel, sizeof(sel));
 101        addattr_nest_end(n, tail);
 102
 103        *argc_p = argc;
 104        *argv_p = argv;
 105        return 0;
 106}
 107
 108static int print_connmark(struct action_util *au, FILE *f, struct rtattr *arg)
 109{
 110        struct rtattr *tb[TCA_CONNMARK_MAX + 1];
 111        struct tc_connmark *ci;
 112
 113        print_string(PRINT_ANY, "kind", "%s ", "connmark");
 114        if (arg == NULL)
 115                return 0;
 116
 117        parse_rtattr_nested(tb, TCA_CONNMARK_MAX, arg);
 118        if (tb[TCA_CONNMARK_PARMS] == NULL) {
 119                fprintf(stderr, "Missing connmark parameters\n");
 120                return -1;
 121        }
 122
 123        ci = RTA_DATA(tb[TCA_CONNMARK_PARMS]);
 124
 125        print_uint(PRINT_ANY, "zone", "zone %u", ci->zone);
 126        print_action_control(f, " ", ci->action, "");
 127
 128        print_nl();
 129        print_uint(PRINT_ANY, "index", "\t index %u", ci->index);
 130        print_int(PRINT_ANY, "ref", " ref %d", ci->refcnt);
 131        print_int(PRINT_ANY, "bind", " bind %d", ci->bindcnt);
 132
 133        if (show_stats) {
 134                if (tb[TCA_CONNMARK_TM]) {
 135                        struct tcf_t *tm = RTA_DATA(tb[TCA_CONNMARK_TM]);
 136
 137                        print_tm(f, tm);
 138                }
 139        }
 140        print_nl();
 141
 142        return 0;
 143}
 144
 145struct action_util connmark_action_util = {
 146        .id = "connmark",
 147        .parse_aopt = parse_connmark,
 148        .print_aopt = print_connmark,
 149};
 150