tc.c revision aa27f88c8444ad6a87ebb563d6ffacb4fe95d87c
1aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger/*
2aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger * tc.c		"tc" utility frontend.
3aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger *
4aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger *		This program is free software; you can redistribute it and/or
5aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger *		modify it under the terms of the GNU General Public License
6aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger *		as published by the Free Software Foundation; either version
7aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger *		2 of the License, or (at your option) any later version.
8aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger *
9aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger * Authors:	Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru>
10aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger *
11aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger * Fixes:
12aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger *
13aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger * Petri Mattila <petri@prihateam.fi> 990308: wrong memset's resulted in faults
14aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger */
15aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
16aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger#include <stdio.h>
17aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger#include <stdlib.h>
18aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger#include <unistd.h>
19aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger#include <syslog.h>
20aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger#include <fcntl.h>
21aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger#include <dlfcn.h>
22aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger#include <sys/socket.h>
23aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger#include <netinet/in.h>
24aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger#include <arpa/inet.h>
25aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger#include <string.h>
26aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger#include <errno.h>
27aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
28aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger#include "SNAPSHOT.h"
29aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger#include "utils.h"
30aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger#include "tc_util.h"
31aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger#include "tc_common.h"
32aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
33aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemmingerint show_stats = 0;
34aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemmingerint show_details = 0;
35aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemmingerint show_raw = 0;
36aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemmingerint resolve_hosts = 0;
373ea2bf45b0661bd3be3a5695043d0d4ea67224bdosdl.net!shemmingerint use_iec = 0;
3808856f02198e927f4d36ee3c3e5e5d8eb4976b21osdl.net!shemmingerint force = 0;
397901660a0de70528c50e812f76df9ba224680258osdl.net!shemmingerstruct rtnl_handle rth;
40aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
41f453a0d451706555690673e12b70069d84d5cf01shemmingerstatic void *BODY = NULL;	/* cached handle dlopen(NULL) */
42aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemmingerstatic struct qdisc_util * qdisc_list;
43aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemmingerstatic struct filter_util * filter_list;
44aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
45ae665a522bd46bea44c5ea84c89c8b1731954170Stephen Hemmingerstatic int print_noqopt(struct qdisc_util *qu, FILE *f,
461798c9d5a421f4c8136c8d887feb5c5b126643b9osdl.net!shemminger			struct rtattr *opt)
47aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger{
48aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	if (opt && RTA_PAYLOAD(opt))
49ae665a522bd46bea44c5ea84c89c8b1731954170Stephen Hemminger		fprintf(f, "[Unknown qdisc, optlen=%u] ",
50bb6a21a4fcaf400ca4766eea6064f2df30393d1eosdl.net!shemminger			(unsigned) RTA_PAYLOAD(opt));
51aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	return 0;
52aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger}
53aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
54aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemmingerstatic int parse_noqopt(struct qdisc_util *qu, int argc, char **argv, struct nlmsghdr *n)
55aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger{
56aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	if (argc) {
57aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		fprintf(stderr, "Unknown qdisc \"%s\", hence option \"%s\" is unparsable\n", qu->id, *argv);
58aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		return -1;
59aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	}
60aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	return 0;
61aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger}
62aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
63aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemmingerstatic int print_nofopt(struct filter_util *qu, FILE *f, struct rtattr *opt, __u32 fhandle)
64aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger{
65aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	if (opt && RTA_PAYLOAD(opt))
66ae665a522bd46bea44c5ea84c89c8b1731954170Stephen Hemminger		fprintf(f, "fh %08x [Unknown filter, optlen=%u] ",
67bb6a21a4fcaf400ca4766eea6064f2df30393d1eosdl.net!shemminger			fhandle, (unsigned) RTA_PAYLOAD(opt));
68aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	else if (fhandle)
69aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		fprintf(f, "fh %08x ", fhandle);
70aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	return 0;
71aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger}
72aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
73aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemmingerstatic int parse_nofopt(struct filter_util *qu, char *fhandle, int argc, char **argv, struct nlmsghdr *n)
74aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger{
75aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	__u32 handle;
76aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
77aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	if (argc) {
78aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		fprintf(stderr, "Unknown filter \"%s\", hence option \"%s\" is unparsable\n", qu->id, *argv);
79aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		return -1;
80aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	}
81aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	if (fhandle) {
82aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		struct tcmsg *t = NLMSG_DATA(n);
83aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		if (get_u32(&handle, fhandle, 16)) {
84aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			fprintf(stderr, "Unparsable filter ID \"%s\"\n", fhandle);
85aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			return -1;
86aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		}
87aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		t->tcm_handle = handle;
88aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	}
89aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	return 0;
90aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger}
91aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
924094db72b61dadd16e180eab5f62ccbc82e3976dosdl.org!shemmingerstruct qdisc_util *get_qdisc_kind(const char *str)
93aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger{
94aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	void *dlh;
95aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	char buf[256];
96aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	struct qdisc_util *q;
97aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
98aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	for (q = qdisc_list; q; q = q->next)
99aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		if (strcmp(q->id, str) == 0)
100aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			return q;
101aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
102aa27f88c8444ad6a87ebb563d6ffacb4fe95d87cStephen Hemminger	snprintf(buf, sizeof(buf), "%s/q_%s.so", get_tc_lib(), str);
103aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	dlh = dlopen(buf, RTLD_LAZY);
104b7a45150854a59bc95f65ec79af35dd390f05a50osdl.net!shemminger	if (!dlh) {
105b7a45150854a59bc95f65ec79af35dd390f05a50osdl.net!shemminger		/* look in current binary, only open once */
106aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		dlh = BODY;
107aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		if (dlh == NULL) {
108aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			dlh = BODY = dlopen(NULL, RTLD_LAZY);
109aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			if (dlh == NULL)
110aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger				goto noexist;
111aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		}
112aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	}
113aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
11495812b56a5a66e7e9a21744cfe8bc0bb9791ea98net[shemminger]!kaber	snprintf(buf, sizeof(buf), "%s_qdisc_util", str);
115aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	q = dlsym(dlh, buf);
116aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	if (q == NULL)
117aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		goto noexist;
118aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
119aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemmingerreg:
120aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	q->next = qdisc_list;
121aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	qdisc_list = q;
122aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	return q;
123aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
124aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemmingernoexist:
125aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	q = malloc(sizeof(*q));
126aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	if (q) {
1271798c9d5a421f4c8136c8d887feb5c5b126643b9osdl.net!shemminger
128aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		memset(q, 0, sizeof(*q));
1291798c9d5a421f4c8136c8d887feb5c5b126643b9osdl.net!shemminger		q->id = strcpy(malloc(strlen(str)+1), str);
130aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		q->parse_qopt = parse_noqopt;
131aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		q->print_qopt = print_noqopt;
132aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		goto reg;
133aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	}
134aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	return q;
135aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger}
136aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
137aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
1384094db72b61dadd16e180eab5f62ccbc82e3976dosdl.org!shemmingerstruct filter_util *get_filter_kind(const char *str)
139aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger{
140aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	void *dlh;
141aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	char buf[256];
142aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	struct filter_util *q;
143aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
144aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	for (q = filter_list; q; q = q->next)
145aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		if (strcmp(q->id, str) == 0)
146aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			return q;
147aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
148aa27f88c8444ad6a87ebb563d6ffacb4fe95d87cStephen Hemminger	snprintf(buf, sizeof(buf), "%s/f_%s.so", get_tc_lib(), str);
149aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	dlh = dlopen(buf, RTLD_LAZY);
150aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	if (dlh == NULL) {
151aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		dlh = BODY;
152aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		if (dlh == NULL) {
153aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			dlh = BODY = dlopen(NULL, RTLD_LAZY);
154aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			if (dlh == NULL)
155aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger				goto noexist;
156aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		}
157aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	}
158aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
15995812b56a5a66e7e9a21744cfe8bc0bb9791ea98net[shemminger]!kaber	snprintf(buf, sizeof(buf), "%s_filter_util", str);
160aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	q = dlsym(dlh, buf);
161aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	if (q == NULL)
162aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		goto noexist;
163aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
164aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemmingerreg:
165aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	q->next = filter_list;
166aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	filter_list = q;
167aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	return q;
168aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemmingernoexist:
169aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	q = malloc(sizeof(*q));
170aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	if (q) {
171aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		memset(q, 0, sizeof(*q));
172aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		strncpy(q->id, str, 15);
173aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		q->parse_fopt = parse_nofopt;
174aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		q->print_fopt = print_nofopt;
175aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		goto reg;
176aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	}
177aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	return q;
178aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger}
179aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
180c2f3a0f94de9b5424ae68093436b1e73d93dcc3asite!shemmingerstatic void usage(void)
181aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger{
182aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	fprintf(stderr, "Usage: tc [ OPTIONS ] OBJECT { COMMAND | help }\n"
1834073448cc886ef836d86c87d6e53dd82174ed1cashemminger			"       tc [-force] -batch file\n"
1845bec34845bba39dfc1efb409ebc2b158a9f0fbc4Jamal Hadi Salim	                "where  OBJECT := { qdisc | class | filter | action | monitor }\n"
185dd3e90853d955fd3ca4056fcc5cfc96d942c635ashemminger	                "       OPTIONS := { -s[tatistics] | -d[etails] | -r[aw] | -b[atch] [file] }\n");
186c2f3a0f94de9b5424ae68093436b1e73d93dcc3asite!shemminger}
187c2f3a0f94de9b5424ae68093436b1e73d93dcc3asite!shemminger
188c2f3a0f94de9b5424ae68093436b1e73d93dcc3asite!shemmingerstatic int do_cmd(int argc, char **argv)
189c2f3a0f94de9b5424ae68093436b1e73d93dcc3asite!shemminger{
190c2f3a0f94de9b5424ae68093436b1e73d93dcc3asite!shemminger	if (matches(*argv, "qdisc") == 0)
191c2f3a0f94de9b5424ae68093436b1e73d93dcc3asite!shemminger		return do_qdisc(argc-1, argv+1);
192c2f3a0f94de9b5424ae68093436b1e73d93dcc3asite!shemminger
193c2f3a0f94de9b5424ae68093436b1e73d93dcc3asite!shemminger	if (matches(*argv, "class") == 0)
194c2f3a0f94de9b5424ae68093436b1e73d93dcc3asite!shemminger		return do_class(argc-1, argv+1);
195c2f3a0f94de9b5424ae68093436b1e73d93dcc3asite!shemminger
196c2f3a0f94de9b5424ae68093436b1e73d93dcc3asite!shemminger	if (matches(*argv, "filter") == 0)
197c2f3a0f94de9b5424ae68093436b1e73d93dcc3asite!shemminger		return do_filter(argc-1, argv+1);
198c2f3a0f94de9b5424ae68093436b1e73d93dcc3asite!shemminger
199c2f3a0f94de9b5424ae68093436b1e73d93dcc3asite!shemminger	if (matches(*argv, "actions") == 0)
200c2f3a0f94de9b5424ae68093436b1e73d93dcc3asite!shemminger		return do_action(argc-1, argv+1);
201c2f3a0f94de9b5424ae68093436b1e73d93dcc3asite!shemminger
2025bec34845bba39dfc1efb409ebc2b158a9f0fbc4Jamal Hadi Salim	if (matches(*argv, "monitor") == 0)
2035bec34845bba39dfc1efb409ebc2b158a9f0fbc4Jamal Hadi Salim		return do_tcmonitor(argc-1, argv+1);
2045bec34845bba39dfc1efb409ebc2b158a9f0fbc4Jamal Hadi Salim
205c2f3a0f94de9b5424ae68093436b1e73d93dcc3asite!shemminger	if (matches(*argv, "help") == 0) {
206c2f3a0f94de9b5424ae68093436b1e73d93dcc3asite!shemminger		usage();
207c2f3a0f94de9b5424ae68093436b1e73d93dcc3asite!shemminger		return 0;
208c2f3a0f94de9b5424ae68093436b1e73d93dcc3asite!shemminger	}
209ae665a522bd46bea44c5ea84c89c8b1731954170Stephen Hemminger
210ae665a522bd46bea44c5ea84c89c8b1731954170Stephen Hemminger	fprintf(stderr, "Object \"%s\" is unknown, try \"tc help\".\n",
211c2f3a0f94de9b5424ae68093436b1e73d93dcc3asite!shemminger		*argv);
212044ebf35b10a462005354edcf3de17a79722035aosdl.net!shemminger	return -1;
213aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger}
214aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
215c2f3a0f94de9b5424ae68093436b1e73d93dcc3asite!shemmingerstatic int batch(const char *name)
216aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger{
217c2f3a0f94de9b5424ae68093436b1e73d93dcc3asite!shemminger	char *line = NULL;
218c2f3a0f94de9b5424ae68093436b1e73d93dcc3asite!shemminger	size_t len = 0;
21908856f02198e927f4d36ee3c3e5e5d8eb4976b21osdl.net!shemminger	int ret = 0;
220c2f3a0f94de9b5424ae68093436b1e73d93dcc3asite!shemminger
221dd3e90853d955fd3ca4056fcc5cfc96d942c635ashemminger	if (name && strcmp(name, "-") != 0) {
222c2f3a0f94de9b5424ae68093436b1e73d93dcc3asite!shemminger		if (freopen(name, "r", stdin) == NULL) {
223c2f3a0f94de9b5424ae68093436b1e73d93dcc3asite!shemminger			fprintf(stderr, "Cannot open file \"%s\" for reading: %s=n",
224c2f3a0f94de9b5424ae68093436b1e73d93dcc3asite!shemminger				name, strerror(errno));
225044ebf35b10a462005354edcf3de17a79722035aosdl.net!shemminger			return -1;
226aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		}
227c2f3a0f94de9b5424ae68093436b1e73d93dcc3asite!shemminger	}
228c2f3a0f94de9b5424ae68093436b1e73d93dcc3asite!shemminger
229c2f3a0f94de9b5424ae68093436b1e73d93dcc3asite!shemminger	tc_core_init();
230c2f3a0f94de9b5424ae68093436b1e73d93dcc3asite!shemminger
231c2f3a0f94de9b5424ae68093436b1e73d93dcc3asite!shemminger	if (rtnl_open(&rth, 0) < 0) {
232c2f3a0f94de9b5424ae68093436b1e73d93dcc3asite!shemminger		fprintf(stderr, "Cannot open rtnetlink\n");
233c2f3a0f94de9b5424ae68093436b1e73d93dcc3asite!shemminger		return -1;
234c2f3a0f94de9b5424ae68093436b1e73d93dcc3asite!shemminger	}
235c2f3a0f94de9b5424ae68093436b1e73d93dcc3asite!shemminger
236351efcde4e62967362a10b29f3b701cfecd7cdfcshemminger	cmdlineno = 0;
23708856f02198e927f4d36ee3c3e5e5d8eb4976b21osdl.net!shemminger	while (getcmdline(&line, &len, stdin) != -1) {
23808856f02198e927f4d36ee3c3e5e5d8eb4976b21osdl.net!shemminger		char *largv[100];
23908856f02198e927f4d36ee3c3e5e5d8eb4976b21osdl.net!shemminger		int largc;
240aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
241c2f3a0f94de9b5424ae68093436b1e73d93dcc3asite!shemminger		largc = makeargs(line, largv, 100);
24208856f02198e927f4d36ee3c3e5e5d8eb4976b21osdl.net!shemminger		if (largc == 0)
24308856f02198e927f4d36ee3c3e5e5d8eb4976b21osdl.net!shemminger			continue;	/* blank line */
244aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
24508856f02198e927f4d36ee3c3e5e5d8eb4976b21osdl.net!shemminger		if (do_cmd(largc, largv)) {
246351efcde4e62967362a10b29f3b701cfecd7cdfcshemminger			fprintf(stderr, "Command failed %s:%d\n", name, cmdlineno);
24708856f02198e927f4d36ee3c3e5e5d8eb4976b21osdl.net!shemminger			ret = 1;
24808856f02198e927f4d36ee3c3e5e5d8eb4976b21osdl.net!shemminger			if (!force)
24908856f02198e927f4d36ee3c3e5e5d8eb4976b21osdl.net!shemminger				break;
250aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		}
251c2f3a0f94de9b5424ae68093436b1e73d93dcc3asite!shemminger	}
2528ed63ab1f1283b2c63355fb7c1e80abead4b9399shemminger	if (line)
2538ed63ab1f1283b2c63355fb7c1e80abead4b9399shemminger		free(line);
2547901660a0de70528c50e812f76df9ba224680258osdl.net!shemminger
255c2f3a0f94de9b5424ae68093436b1e73d93dcc3asite!shemminger	rtnl_close(&rth);
256c2f3a0f94de9b5424ae68093436b1e73d93dcc3asite!shemminger	return ret;
257c2f3a0f94de9b5424ae68093436b1e73d93dcc3asite!shemminger}
2587901660a0de70528c50e812f76df9ba224680258osdl.net!shemminger
259c2f3a0f94de9b5424ae68093436b1e73d93dcc3asite!shemminger
260c2f3a0f94de9b5424ae68093436b1e73d93dcc3asite!shemmingerint main(int argc, char **argv)
261c2f3a0f94de9b5424ae68093436b1e73d93dcc3asite!shemminger{
262c2f3a0f94de9b5424ae68093436b1e73d93dcc3asite!shemminger	int ret;
263dd3e90853d955fd3ca4056fcc5cfc96d942c635ashemminger	int do_batching = 0;
26408856f02198e927f4d36ee3c3e5e5d8eb4976b21osdl.net!shemminger	char *batchfile = NULL;
265aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
266aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	while (argc > 1) {
267aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		if (argv[1][0] != '-')
268aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			break;
269aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		if (matches(argv[1], "-stats") == 0 ||
2703ea2bf45b0661bd3be3a5695043d0d4ea67224bdosdl.net!shemminger			 matches(argv[1], "-statistics") == 0) {
271aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			++show_stats;
272aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		} else if (matches(argv[1], "-details") == 0) {
273aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			++show_details;
274aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		} else if (matches(argv[1], "-raw") == 0) {
275aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			++show_raw;
276aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		} else if (matches(argv[1], "-Version") == 0) {
277aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			printf("tc utility, iproute2-ss%s\n", SNAPSHOT);
278044ebf35b10a462005354edcf3de17a79722035aosdl.net!shemminger			return 0;
2793ea2bf45b0661bd3be3a5695043d0d4ea67224bdosdl.net!shemminger		} else if (matches(argv[1], "-iec") == 0) {
2803ea2bf45b0661bd3be3a5695043d0d4ea67224bdosdl.net!shemminger			++use_iec;
281aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		} else if (matches(argv[1], "-help") == 0) {
282aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			usage();
283c2f3a0f94de9b5424ae68093436b1e73d93dcc3asite!shemminger			return 0;
28408856f02198e927f4d36ee3c3e5e5d8eb4976b21osdl.net!shemminger		} else if (matches(argv[1], "-force") == 0) {
28508856f02198e927f4d36ee3c3e5e5d8eb4976b21osdl.net!shemminger			++force;
286c2f3a0f94de9b5424ae68093436b1e73d93dcc3asite!shemminger		} else 	if (matches(argv[1], "-batch") == 0) {
287dd3e90853d955fd3ca4056fcc5cfc96d942c635ashemminger			do_batching = 1;
288dd3e90853d955fd3ca4056fcc5cfc96d942c635ashemminger			if (argc > 2)
289dd3e90853d955fd3ca4056fcc5cfc96d942c635ashemminger				batchfile = argv[2];
29008856f02198e927f4d36ee3c3e5e5d8eb4976b21osdl.net!shemminger			argc--;	argv++;
291aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		} else {
292aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			fprintf(stderr, "Option \"%s\" is unknown, try \"tc -help\".\n", argv[1]);
293044ebf35b10a462005354edcf3de17a79722035aosdl.net!shemminger			return -1;
294aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		}
295aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		argc--;	argv++;
296aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	}
297aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
298dd3e90853d955fd3ca4056fcc5cfc96d942c635ashemminger	if (do_batching)
29908856f02198e927f4d36ee3c3e5e5d8eb4976b21osdl.net!shemminger		return batch(batchfile);
30008856f02198e927f4d36ee3c3e5e5d8eb4976b21osdl.net!shemminger
301c2f3a0f94de9b5424ae68093436b1e73d93dcc3asite!shemminger	if (argc <= 1) {
302c2f3a0f94de9b5424ae68093436b1e73d93dcc3asite!shemminger		usage();
303c2f3a0f94de9b5424ae68093436b1e73d93dcc3asite!shemminger		return 0;
304c2f3a0f94de9b5424ae68093436b1e73d93dcc3asite!shemminger	}
305c2f3a0f94de9b5424ae68093436b1e73d93dcc3asite!shemminger
306aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	tc_core_init();
3077901660a0de70528c50e812f76df9ba224680258osdl.net!shemminger	if (rtnl_open(&rth, 0) < 0) {
3087901660a0de70528c50e812f76df9ba224680258osdl.net!shemminger		fprintf(stderr, "Cannot open rtnetlink\n");
3097901660a0de70528c50e812f76df9ba224680258osdl.net!shemminger		exit(1);
3107901660a0de70528c50e812f76df9ba224680258osdl.net!shemminger	}
311aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
312c2f3a0f94de9b5424ae68093436b1e73d93dcc3asite!shemminger	ret = do_cmd(argc-1, argv+1);
3137901660a0de70528c50e812f76df9ba224680258osdl.net!shemminger	rtnl_close(&rth);
314c2f3a0f94de9b5424ae68093436b1e73d93dcc3asite!shemminger
315c2f3a0f94de9b5424ae68093436b1e73d93dcc3asite!shemminger	return ret;
316aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger}
317