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