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