1aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger/* 2aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger * tc_filter.c "tc filter". 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 */ 12aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 13aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger#include <stdio.h> 14aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger#include <stdlib.h> 15aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger#include <unistd.h> 16aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger#include <syslog.h> 17aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger#include <fcntl.h> 18aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger#include <sys/socket.h> 19aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger#include <netinet/in.h> 20aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger#include <arpa/inet.h> 21aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger#include <string.h> 22aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger#include <linux/if_ether.h> 23aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 24aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger#include "rt_names.h" 25aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger#include "utils.h" 26aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger#include "tc_util.h" 27aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger#include "tc_common.h" 28aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 29024481bbe1f50831fdbccd9b98f10efca84ae95cosdl.net!shemmingerstatic void usage(void); 30aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 31aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemmingerstatic void usage(void) 32aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger{ 33e5d179d81594e12c873d0b9ae19e09dced368e8aHasso Tepper fprintf(stderr, "Usage: tc filter [ add | del | change | replace | show ] dev STRING\n"); 34de33a4305563c3a3d6ee92193a65b9be9fc928a2Stephen Hemminger fprintf(stderr, " [ pref PRIO ] protocol PROTO\n"); 35aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger fprintf(stderr, " [ estimator INTERVAL TIME_CONSTANT ]\n"); 36aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger fprintf(stderr, " [ root | classid CLASSID ] [ handle FILTERID ]\n"); 37aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger fprintf(stderr, " [ [ FILTER_TYPE ] [ help | OPTIONS ] ]\n"); 38aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger fprintf(stderr, "\n"); 39aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger fprintf(stderr, " tc filter show [ dev STRING ] [ root | parent CLASSID ]\n"); 40aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger fprintf(stderr, "Where:\n"); 41aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger fprintf(stderr, "FILTER_TYPE := { rsvp | u32 | fw | route | etc. }\n"); 42aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger fprintf(stderr, "FILTERID := ... format depends on classifier, see there\n"); 43aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger fprintf(stderr, "OPTIONS := ... try tc filter add <desired FILTER_KIND> help\n"); 44024481bbe1f50831fdbccd9b98f10efca84ae95cosdl.net!shemminger return; 45aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger} 46aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 47aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 48aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemmingerint tc_filter_modify(int cmd, unsigned flags, int argc, char **argv) 49aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger{ 50aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger struct { 51aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger struct nlmsghdr n; 52aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger struct tcmsg t; 532373fde9b0ba14c1758290a68332f1af9882abc0osdl.net!shemminger char buf[MAX_MSG]; 54aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } req; 55aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger struct filter_util *q = NULL; 56aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger __u32 prio = 0; 57ae76106841d764fc64188e78f5c2a2575fba725ePatrick McHardy __u32 protocol = 0; 58083a5f00a15f6506815b0da2be82e7be761c5cbcPatrick McHardy int protocol_set = 0; 59aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger char *fhandle = NULL; 60aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger char d[16]; 61aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger char k[16]; 62aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger struct tc_estimator est; 63aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 64aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger memset(&req, 0, sizeof(req)); 65aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger memset(&est, 0, sizeof(est)); 66aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger memset(d, 0, sizeof(d)); 67aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger memset(k, 0, sizeof(k)); 68aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger memset(&req, 0, sizeof(req)); 69aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 70aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger req.n.nlmsg_len = NLMSG_LENGTH(sizeof(struct tcmsg)); 71aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger req.n.nlmsg_flags = NLM_F_REQUEST|flags; 72aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger req.n.nlmsg_type = cmd; 73aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger req.t.tcm_family = AF_UNSPEC; 74aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 75ae76106841d764fc64188e78f5c2a2575fba725ePatrick McHardy if (cmd == RTM_NEWTFILTER && flags & NLM_F_CREATE) 7605fb9184f2129c50cd0e406e9eda80509307af25Florian Westphal protocol = htons(ETH_P_ALL); 77ae76106841d764fc64188e78f5c2a2575fba725ePatrick McHardy 78aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger while (argc > 0) { 79aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (strcmp(*argv, "dev") == 0) { 80aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger NEXT_ARG(); 81aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (d[0]) 82aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger duparg("dev", *argv); 83aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger strncpy(d, *argv, sizeof(d)-1); 84aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } else if (strcmp(*argv, "root") == 0) { 85aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (req.t.tcm_parent) { 86aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger fprintf(stderr, "Error: \"root\" is duplicate parent ID\n"); 87024481bbe1f50831fdbccd9b98f10efca84ae95cosdl.net!shemminger return -1; 88aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } 89aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger req.t.tcm_parent = TC_H_ROOT; 90aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } else if (strcmp(*argv, "parent") == 0) { 91aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger __u32 handle; 92aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger NEXT_ARG(); 93aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (req.t.tcm_parent) 94aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger duparg("parent", *argv); 95aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (get_tc_classid(&handle, *argv)) 96aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger invarg(*argv, "Invalid parent ID"); 97aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger req.t.tcm_parent = handle; 98aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } else if (strcmp(*argv, "handle") == 0) { 99aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger NEXT_ARG(); 100aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (fhandle) 101aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger duparg("handle", *argv); 102aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger fhandle = *argv; 103aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } else if (matches(*argv, "preference") == 0 || 104aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger matches(*argv, "priority") == 0) { 105aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger NEXT_ARG(); 106aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (prio) 107aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger duparg("priority", *argv); 108aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (get_u32(&prio, *argv, 0)) 109de33a4305563c3a3d6ee92193a65b9be9fc928a2Stephen Hemminger invarg(*argv, "invalid priority value"); 110aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } else if (matches(*argv, "protocol") == 0) { 111aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger __u16 id; 112aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger NEXT_ARG(); 113083a5f00a15f6506815b0da2be82e7be761c5cbcPatrick McHardy if (protocol_set) 114aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger duparg("protocol", *argv); 115aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (ll_proto_a2n(&id, *argv)) 116aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger invarg(*argv, "invalid protocol"); 117aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger protocol = id; 118083a5f00a15f6506815b0da2be82e7be761c5cbcPatrick McHardy protocol_set = 1; 119aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } else if (matches(*argv, "estimator") == 0) { 120aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (parse_estimator(&argc, &argv, &est) < 0) 121aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger return -1; 122aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } else if (matches(*argv, "help") == 0) { 123aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger usage(); 1243a99df7074b7840b0383d90f56243d5b9e93547aStephen Hemminger return 0; 125aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } else { 126aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger strncpy(k, *argv, sizeof(k)-1); 127aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 128aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger q = get_filter_kind(k); 129aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger argc--; argv++; 130aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger break; 131aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } 132aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 133aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger argc--; argv++; 134aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } 135aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 136aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger req.t.tcm_info = TC_H_MAKE(prio<<16, protocol); 137aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 138aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (k[0]) 139aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger addattr_l(&req.n, sizeof(req), TCA_KIND, k, strlen(k)+1); 140aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 141aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (q) { 142aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (q->parse_fopt(q, fhandle, argc, argv, &req.n)) 143024481bbe1f50831fdbccd9b98f10efca84ae95cosdl.net!shemminger return 1; 144aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } else { 145aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (fhandle) { 146aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger fprintf(stderr, "Must specify filter type when using " 147aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger "\"handle\"\n"); 148024481bbe1f50831fdbccd9b98f10efca84ae95cosdl.net!shemminger return -1; 149aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } 150aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (argc) { 151aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (matches(*argv, "help") == 0) 152aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger usage(); 153aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger fprintf(stderr, "Garbage instead of arguments \"%s ...\". Try \"tc filter help\".\n", *argv); 154024481bbe1f50831fdbccd9b98f10efca84ae95cosdl.net!shemminger return -1; 155aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } 156aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } 157aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (est.ewma_log) 158aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger addattr_l(&req.n, sizeof(req), TCA_RATE, &est, sizeof(est)); 159aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 160aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 161aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (d[0]) { 1627901660a0de70528c50e812f76df9ba224680258osdl.net!shemminger ll_init_map(&rth); 163aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 164aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if ((req.t.tcm_ifindex = ll_name_to_index(d)) == 0) { 165aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger fprintf(stderr, "Cannot find device \"%s\"\n", d); 166024481bbe1f50831fdbccd9b98f10efca84ae95cosdl.net!shemminger return 1; 167aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } 168aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } 169aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 170cd70f3f522e04b4d2fa80ae10292379bf223a53bStephen Hemminger if (rtnl_talk(&rth, &req.n, 0, 0, NULL) < 0) { 1712373fde9b0ba14c1758290a68332f1af9882abc0osdl.net!shemminger fprintf(stderr, "We have an error talking to the kernel\n"); 172024481bbe1f50831fdbccd9b98f10efca84ae95cosdl.net!shemminger return 2; 1732373fde9b0ba14c1758290a68332f1af9882abc0osdl.net!shemminger } 174aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 175aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger return 0; 176aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger} 177aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 178aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemmingerstatic __u32 filter_parent; 179aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemmingerstatic int filter_ifindex; 180aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemmingerstatic __u32 filter_prio; 181aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemmingerstatic __u32 filter_protocol; 182eefcbc72062a235efe391163962f7353dba1af4cjamal__u16 f_proto = 0; 183aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 1845bec34845bba39dfc1efb409ebc2b158a9f0fbc4Jamal Hadi Salimint print_filter(const struct sockaddr_nl *who, 185ae665a522bd46bea44c5ea84c89c8b1731954170Stephen Hemminger struct nlmsghdr *n, 186de481780a582f2800a6398296f2ca8269a3ddcfbosdl.net!shemminger void *arg) 187aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger{ 188aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger FILE *fp = (FILE*)arg; 189aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger struct tcmsg *t = NLMSG_DATA(n); 190aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger int len = n->nlmsg_len; 191aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger struct rtattr * tb[TCA_MAX+1]; 192aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger struct filter_util *q; 193aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger char abuf[256]; 194aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 195aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (n->nlmsg_type != RTM_NEWTFILTER && n->nlmsg_type != RTM_DELTFILTER) { 196aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger fprintf(stderr, "Not a filter\n"); 197aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger return 0; 198aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } 199aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger len -= NLMSG_LENGTH(sizeof(*t)); 200aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (len < 0) { 201aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger fprintf(stderr, "Wrong len %d\n", len); 202aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger return -1; 203aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } 204aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 205aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger memset(tb, 0, sizeof(tb)); 206aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger parse_rtattr(tb, TCA_MAX, TCA_RTA(t), len); 207aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 208aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (tb[TCA_KIND] == NULL) { 2092373fde9b0ba14c1758290a68332f1af9882abc0osdl.net!shemminger fprintf(stderr, "print_filter: NULL kind\n"); 210aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger return -1; 211aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } 212aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 213aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (n->nlmsg_type == RTM_DELTFILTER) 214aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger fprintf(fp, "deleted "); 215aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 216aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger fprintf(fp, "filter "); 217aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (!filter_ifindex || filter_ifindex != t->tcm_ifindex) 218aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger fprintf(fp, "dev %s ", ll_index_to_name(t->tcm_ifindex)); 219aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 220aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (!filter_parent || filter_parent != t->tcm_parent) { 221aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (t->tcm_parent == TC_H_ROOT) 222aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger fprintf(fp, "root "); 223aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger else { 224aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger print_tc_classid(abuf, sizeof(abuf), t->tcm_parent); 225aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger fprintf(fp, "parent %s ", abuf); 226aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } 227aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } 228aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (t->tcm_info) { 229eefcbc72062a235efe391163962f7353dba1af4cjamal f_proto = TC_H_MIN(t->tcm_info); 230aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger __u32 prio = TC_H_MAJ(t->tcm_info)>>16; 231eefcbc72062a235efe391163962f7353dba1af4cjamal if (!filter_protocol || filter_protocol != f_proto) { 232eefcbc72062a235efe391163962f7353dba1af4cjamal if (f_proto) { 233aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger SPRINT_BUF(b1); 234aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger fprintf(fp, "protocol %s ", 235eefcbc72062a235efe391163962f7353dba1af4cjamal ll_proto_n2a(f_proto, b1, sizeof(b1))); 236aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } 237aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } 238aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (!filter_prio || filter_prio != prio) { 239aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (prio) 240aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger fprintf(fp, "pref %u ", prio); 241aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } 242aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } 243ff24746cca1ef0c92d46614158e6672acd6b63d3Stephen Hemminger fprintf(fp, "%s ", rta_getattr_str(tb[TCA_KIND])); 244aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger q = get_filter_kind(RTA_DATA(tb[TCA_KIND])); 245aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (tb[TCA_OPTIONS]) { 246aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (q) 247aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger q->print_fopt(q, fp, tb[TCA_OPTIONS], t->tcm_handle); 248aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger else 249aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger fprintf(fp, "[cannot parse parameters]"); 250aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } 251aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger fprintf(fp, "\n"); 252aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 253e5879dc603ca2e9f27ca6d754fdf5e20f8072344ch[shemminger]!tgraf if (show_stats && (tb[TCA_STATS] || tb[TCA_STATS2])) { 254e5879dc603ca2e9f27ca6d754fdf5e20f8072344ch[shemminger]!tgraf print_tcstats_attr(fp, tb, " ", NULL); 255de481780a582f2800a6398296f2ca8269a3ddcfbosdl.net!shemminger fprintf(fp, "\n"); 256aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } 257de481780a582f2800a6398296f2ca8269a3ddcfbosdl.net!shemminger 258aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger fflush(fp); 259aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger return 0; 260aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger} 261aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 262aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 263aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemmingerint tc_filter_list(int argc, char **argv) 264aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger{ 265aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger struct tcmsg t; 266aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger char d[16]; 267aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger __u32 prio = 0; 268aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger __u32 protocol = 0; 269aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger char *fhandle = NULL; 270aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 271aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger memset(&t, 0, sizeof(t)); 272aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger t.tcm_family = AF_UNSPEC; 273aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger memset(d, 0, sizeof(d)); 274aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 275aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger while (argc > 0) { 276aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (strcmp(*argv, "dev") == 0) { 277aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger NEXT_ARG(); 278aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (d[0]) 279aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger duparg("dev", *argv); 280aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger strncpy(d, *argv, sizeof(d)-1); 281aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } else if (strcmp(*argv, "root") == 0) { 282aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (t.tcm_parent) { 283aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger fprintf(stderr, "Error: \"root\" is duplicate parent ID\n"); 284024481bbe1f50831fdbccd9b98f10efca84ae95cosdl.net!shemminger return -1; 285aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } 286aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger filter_parent = t.tcm_parent = TC_H_ROOT; 287aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } else if (strcmp(*argv, "parent") == 0) { 288aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger __u32 handle; 289aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger NEXT_ARG(); 290aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (t.tcm_parent) 291aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger duparg("parent", *argv); 292aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (get_tc_classid(&handle, *argv)) 293aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger invarg(*argv, "invalid parent ID"); 294aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger filter_parent = t.tcm_parent = handle; 295aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } else if (strcmp(*argv, "handle") == 0) { 296aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger NEXT_ARG(); 297aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (fhandle) 298aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger duparg("handle", *argv); 299aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger fhandle = *argv; 300aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } else if (matches(*argv, "preference") == 0 || 301aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger matches(*argv, "priority") == 0) { 302aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger NEXT_ARG(); 303aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (prio) 304aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger duparg("priority", *argv); 305aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (get_u32(&prio, *argv, 0)) 306aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger invarg(*argv, "invalid preference"); 307aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger filter_prio = prio; 308aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } else if (matches(*argv, "protocol") == 0) { 309aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger __u16 res; 310aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger NEXT_ARG(); 311aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (protocol) 312aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger duparg("protocol", *argv); 313aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (ll_proto_a2n(&res, *argv)) 314aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger invarg(*argv, "invalid protocol"); 315aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger protocol = res; 316aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger filter_protocol = protocol; 317aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } else if (matches(*argv, "help") == 0) { 318aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger usage(); 319aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } else { 320aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger fprintf(stderr, " What is \"%s\"? Try \"tc filter help\"\n", *argv); 321024481bbe1f50831fdbccd9b98f10efca84ae95cosdl.net!shemminger return -1; 322aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } 323aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 324aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger argc--; argv++; 325aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } 326aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 327aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger t.tcm_info = TC_H_MAKE(prio<<16, protocol); 328aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 3297901660a0de70528c50e812f76df9ba224680258osdl.net!shemminger ll_init_map(&rth); 330aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 331aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (d[0]) { 332aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if ((t.tcm_ifindex = ll_name_to_index(d)) == 0) { 333aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger fprintf(stderr, "Cannot find device \"%s\"\n", d); 334024481bbe1f50831fdbccd9b98f10efca84ae95cosdl.net!shemminger return 1; 335aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } 336aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger filter_ifindex = t.tcm_ifindex; 337aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } 338aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 3397901660a0de70528c50e812f76df9ba224680258osdl.net!shemminger if (rtnl_dump_request(&rth, RTM_GETTFILTER, &t, sizeof(t)) < 0) { 340aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger perror("Cannot send dump request"); 341024481bbe1f50831fdbccd9b98f10efca84ae95cosdl.net!shemminger return 1; 342aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } 343aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 344cd70f3f522e04b4d2fa80ae10292379bf223a53bStephen Hemminger if (rtnl_dump_filter(&rth, print_filter, stdout) < 0) { 345aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger fprintf(stderr, "Dump terminated\n"); 346024481bbe1f50831fdbccd9b98f10efca84ae95cosdl.net!shemminger return 1; 347aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } 348aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 349aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger return 0; 350aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger} 351aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 352aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemmingerint do_filter(int argc, char **argv) 353aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger{ 354aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (argc < 1) 355aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger return tc_filter_list(0, NULL); 356aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (matches(*argv, "add") == 0) 357aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger return tc_filter_modify(RTM_NEWTFILTER, NLM_F_EXCL|NLM_F_CREATE, argc-1, argv+1); 358aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (matches(*argv, "change") == 0) 359aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger return tc_filter_modify(RTM_NEWTFILTER, 0, argc-1, argv+1); 360aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (matches(*argv, "replace") == 0) 361aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger return tc_filter_modify(RTM_NEWTFILTER, NLM_F_CREATE, argc-1, argv+1); 362aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (matches(*argv, "delete") == 0) 363aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger return tc_filter_modify(RTM_DELTFILTER, 0, argc-1, argv+1); 364aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger#if 0 365aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (matches(*argv, "get") == 0) 366aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger return tc_filter_get(RTM_GETTFILTER, 0, argc-1, argv+1); 367aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger#endif 368aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (matches(*argv, "list") == 0 || matches(*argv, "show") == 0 369aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger || matches(*argv, "lst") == 0) 370aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger return tc_filter_list(argc-1, argv+1); 371e5d179d81594e12c873d0b9ae19e09dced368e8aHasso Tepper if (matches(*argv, "help") == 0) { 372aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger usage(); 373e5d179d81594e12c873d0b9ae19e09dced368e8aHasso Tepper return 0; 374e5d179d81594e12c873d0b9ae19e09dced368e8aHasso Tepper } 375aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger fprintf(stderr, "Command \"%s\" is unknown, try \"tc filter help\".\n", *argv); 376024481bbe1f50831fdbccd9b98f10efca84ae95cosdl.net!shemminger return -1; 377aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger} 378aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 379