Blame tc/m_connmark.c

Packit Service 3880ab
/*
Packit Service 3880ab
 * m_connmark.c		Connection tracking marking import
Packit Service 3880ab
 *
Packit Service 3880ab
 * Copyright (c) 2011 Felix Fietkau <nbd@openwrt.org>
Packit Service 3880ab
 *
Packit Service 3880ab
 * This program is free software; you can redistribute it and/or modify it
Packit Service 3880ab
 * under the terms and conditions of the GNU General Public License,
Packit Service 3880ab
 * version 2, as published by the Free Software Foundation.
Packit Service 3880ab
 *
Packit Service 3880ab
 * This program is distributed in the hope it will be useful, but WITHOUT
Packit Service 3880ab
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
Packit Service 3880ab
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
Packit Service 3880ab
 * more details.
Packit Service 3880ab
 *
Packit Service 3880ab
 * You should have received a copy of the GNU General Public License along with
Packit Service 3880ab
 * this program; if not, see <http://www.gnu.org/licenses>.
Packit Service 3880ab
 */
Packit Service 3880ab
Packit Service 3880ab
#include <stdio.h>
Packit Service 3880ab
#include <stdlib.h>
Packit Service 3880ab
#include <unistd.h>
Packit Service 3880ab
#include <string.h>
Packit Service 3880ab
#include "utils.h"
Packit Service 3880ab
#include "tc_util.h"
Packit Service 3880ab
#include <linux/tc_act/tc_connmark.h>
Packit Service 3880ab
Packit Service 3880ab
static void
Packit Service 3880ab
explain(void)
Packit Service 3880ab
{
Packit Service 3880ab
	fprintf(stderr,
Packit Service 3880ab
		"Usage: ... connmark [zone ZONE] [CONTROL] [index <INDEX>]\n"
Packit Service 3880ab
		"where :\n"
Packit Service 3880ab
		"\tZONE is the conntrack zone\n"
Packit Service 3880ab
		"\tCONTROL := reclassify | pipe | drop | continue | ok |\n"
Packit Service 3880ab
		"\t           goto chain <CHAIN_INDEX>\n");
Packit Service 3880ab
}
Packit Service 3880ab
Packit Service 3880ab
static void
Packit Service 3880ab
usage(void)
Packit Service 3880ab
{
Packit Service 3880ab
	explain();
Packit Service 3880ab
	exit(-1);
Packit Service 3880ab
}
Packit Service 3880ab
Packit Service 3880ab
static int
Packit Service 3880ab
parse_connmark(struct action_util *a, int *argc_p, char ***argv_p, int tca_id,
Packit Service 3880ab
	      struct nlmsghdr *n)
Packit Service 3880ab
{
Packit Service 3880ab
	struct tc_connmark sel = {};
Packit Service 3880ab
	char **argv = *argv_p;
Packit Service 3880ab
	int argc = *argc_p;
Packit Service 3880ab
	int ok = 0;
Packit Service 3880ab
	struct rtattr *tail;
Packit Service 3880ab
Packit Service 3880ab
	while (argc > 0) {
Packit Service 3880ab
		if (matches(*argv, "connmark") == 0) {
Packit Service 3880ab
			ok = 1;
Packit Service 3880ab
			argc--;
Packit Service 3880ab
			argv++;
Packit Service 3880ab
		} else if (matches(*argv, "help") == 0) {
Packit Service 3880ab
			usage();
Packit Service 3880ab
		} else {
Packit Service 3880ab
			break;
Packit Service 3880ab
		}
Packit Service 3880ab
Packit Service 3880ab
	}
Packit Service 3880ab
Packit Service 3880ab
	if (!ok) {
Packit Service 3880ab
		explain();
Packit Service 3880ab
		return -1;
Packit Service 3880ab
	}
Packit Service 3880ab
Packit Service 3880ab
	if (argc) {
Packit Service 3880ab
		if (matches(*argv, "zone") == 0) {
Packit Service 3880ab
			NEXT_ARG();
Packit Service 3880ab
			if (get_u16(&sel.zone, *argv, 10)) {
Packit Service 3880ab
				fprintf(stderr, "connmark: Illegal \"zone\"\n");
Packit Service 3880ab
				return -1;
Packit Service 3880ab
			}
Packit Service 3880ab
			argc--;
Packit Service 3880ab
			argv++;
Packit Service 3880ab
		}
Packit Service 3880ab
	}
Packit Service 3880ab
Packit Service 3880ab
	parse_action_control_dflt(&argc, &argv, &sel.action, false, TC_ACT_PIPE);
Packit Service 3880ab
Packit Service 3880ab
	if (argc) {
Packit Service 3880ab
		if (matches(*argv, "index") == 0) {
Packit Service 3880ab
			NEXT_ARG();
Packit Service 3880ab
			if (get_u32(&sel.index, *argv, 10)) {
Packit Service 3880ab
				fprintf(stderr, "connmark: Illegal \"index\"\n");
Packit Service 3880ab
				return -1;
Packit Service 3880ab
			}
Packit Service 3880ab
			argc--;
Packit Service 3880ab
			argv++;
Packit Service 3880ab
		}
Packit Service 3880ab
	}
Packit Service 3880ab
Packit Service 3880ab
	tail = addattr_nest(n, MAX_MSG, tca_id);
Packit Service 3880ab
	addattr_l(n, MAX_MSG, TCA_CONNMARK_PARMS, &sel, sizeof(sel));
Packit Service 3880ab
	addattr_nest_end(n, tail);
Packit Service 3880ab
Packit Service 3880ab
	*argc_p = argc;
Packit Service 3880ab
	*argv_p = argv;
Packit Service 3880ab
	return 0;
Packit Service 3880ab
}
Packit Service 3880ab
Packit Service 3880ab
static int print_connmark(struct action_util *au, FILE *f, struct rtattr *arg)
Packit Service 3880ab
{
Packit Service 3880ab
	struct rtattr *tb[TCA_CONNMARK_MAX + 1];
Packit Service 3880ab
	struct tc_connmark *ci;
Packit Service 3880ab
Packit Service 3880ab
	if (arg == NULL)
Packit Service 3880ab
		return -1;
Packit Service 3880ab
Packit Service 3880ab
	parse_rtattr_nested(tb, TCA_CONNMARK_MAX, arg);
Packit Service 3880ab
	if (tb[TCA_CONNMARK_PARMS] == NULL) {
Packit Service 3880ab
		fprintf(stderr, "Missing connmark parameters\n");
Packit Service 3880ab
		return -1;
Packit Service 3880ab
	}
Packit Service 3880ab
Packit Service 3880ab
	ci = RTA_DATA(tb[TCA_CONNMARK_PARMS]);
Packit Service 3880ab
Packit Service 3880ab
	print_string(PRINT_ANY, "kind", "%s ", "connmark");
Packit Service 3880ab
	print_uint(PRINT_ANY, "zone", "zone %u", ci->zone);
Packit Service 3880ab
	print_action_control(f, " ", ci->action, "");
Packit Service 3880ab
Packit Service 3880ab
	print_nl();
Packit Service 3880ab
	print_uint(PRINT_ANY, "index", "\t index %u", ci->index);
Packit Service 3880ab
	print_int(PRINT_ANY, "ref", " ref %d", ci->refcnt);
Packit Service 3880ab
	print_int(PRINT_ANY, "bind", " bind %d", ci->bindcnt);
Packit Service 3880ab
Packit Service 3880ab
	if (show_stats) {
Packit Service 3880ab
		if (tb[TCA_CONNMARK_TM]) {
Packit Service 3880ab
			struct tcf_t *tm = RTA_DATA(tb[TCA_CONNMARK_TM]);
Packit Service 3880ab
Packit Service 3880ab
			print_tm(f, tm);
Packit Service 3880ab
		}
Packit Service 3880ab
	}
Packit Service 3880ab
	print_nl();
Packit Service 3880ab
Packit Service 3880ab
	return 0;
Packit Service 3880ab
}
Packit Service 3880ab
Packit Service 3880ab
struct action_util connmark_action_util = {
Packit Service 3880ab
	.id = "connmark",
Packit Service 3880ab
	.parse_aopt = parse_connmark,
Packit Service 3880ab
	.print_aopt = print_connmark,
Packit Service 3880ab
};