1dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat/* 2dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat * f_route.c ROUTE filter. 3dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat * 4dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat * This program is free software; you can redistribute it and/or 5dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat * modify it under the terms of the GNU General Public License 6dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat * as published by the Free Software Foundation; either version 7dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat * 2 of the License, or (at your option) any later version. 8dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat * 9dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat * Authors: Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru> 10dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat * 11dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat */ 12dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 13dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat#include <stdio.h> 14dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat#include <stdlib.h> 15dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat#include <unistd.h> 16dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat#include <syslog.h> 17dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat#include <fcntl.h> 18dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat#include <sys/socket.h> 19dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat#include <netinet/in.h> 20dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat#include <arpa/inet.h> 21dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat#include <string.h> 22dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 23dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat#include "utils.h" 24dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat#include "rt_names.h" 25dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat#include "tc_common.h" 26dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat#include "tc_util.h" 27dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 28dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehatstatic void explain(void) 29dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat{ 30dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(stderr, "Usage: ... route [ from REALM | fromif TAG ] [ to REALM ]\n"); 31dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(stderr, " [ flowid CLASSID ] [ police POLICE_SPEC ]\n"); 32dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(stderr, " POLICE_SPEC := ... look at TBF\n"); 33dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(stderr, " CLASSID := X:Y\n"); 34dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(stderr, "\nNOTE: CLASSID is parsed as hexadecimal input.\n"); 35dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat} 36dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 37dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehatstatic int route_parse_opt(struct filter_util *qu, char *handle, int argc, char **argv, struct nlmsghdr *n) 38dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat{ 39dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat struct tc_police tp; 40dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat struct tcmsg *t = NLMSG_DATA(n); 41dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat struct rtattr *tail; 42dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat __u32 fh = 0xFFFF8000; 43dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat __u32 order = 0; 44dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 45dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat memset(&tp, 0, sizeof(tp)); 46dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 47dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (handle) { 48dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (get_u32(&t->tcm_handle, handle, 0)) { 49dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(stderr, "Illegal \"handle\"\n"); 50dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return -1; 51dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 52dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 53dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 54dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (argc == 0) 55dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return 0; 56dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 57dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat tail = NLMSG_TAIL(n); 58dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat addattr_l(n, 4096, TCA_OPTIONS, NULL, 0); 59dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 60dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat while (argc > 0) { 61dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (matches(*argv, "to") == 0) { 62dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat __u32 id; 63dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat NEXT_ARG(); 64dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (rtnl_rtrealm_a2n(&id, *argv)) { 65dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(stderr, "Illegal \"to\"\n"); 66dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return -1; 67dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 68dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat addattr_l(n, 4096, TCA_ROUTE4_TO, &id, 4); 69dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fh &= ~0x80FF; 70dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fh |= id&0xFF; 71dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } else if (matches(*argv, "from") == 0) { 72dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat __u32 id; 73dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat NEXT_ARG(); 74dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (rtnl_rtrealm_a2n(&id, *argv)) { 75dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(stderr, "Illegal \"from\"\n"); 76dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return -1; 77dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 78dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat addattr_l(n, 4096, TCA_ROUTE4_FROM, &id, 4); 79dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fh &= 0xFFFF; 80dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fh |= id<<16; 81dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } else if (matches(*argv, "fromif") == 0) { 82dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat __u32 id; 83dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat NEXT_ARG(); 84dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat ll_init_map(&rth); 85dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if ((id=ll_name_to_index(*argv)) <= 0) { 86dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(stderr, "Illegal \"fromif\"\n"); 87dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return -1; 88dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 89dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat addattr_l(n, 4096, TCA_ROUTE4_IIF, &id, 4); 90dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fh &= 0xFFFF; 91dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fh |= (0x8000|id)<<16; 92dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } else if (matches(*argv, "classid") == 0 || 93dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat strcmp(*argv, "flowid") == 0) { 94dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat unsigned handle; 95dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat NEXT_ARG(); 96dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (get_tc_classid(&handle, *argv)) { 97dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(stderr, "Illegal \"classid\"\n"); 98dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return -1; 99dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 100dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat addattr_l(n, 4096, TCA_ROUTE4_CLASSID, &handle, 4); 101dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } else if (matches(*argv, "police") == 0) { 102dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat NEXT_ARG(); 103dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (parse_police(&argc, &argv, TCA_ROUTE4_POLICE, n)) { 104dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(stderr, "Illegal \"police\"\n"); 105dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return -1; 106dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 107dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat continue; 108dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } else if (matches(*argv, "order") == 0) { 109dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat NEXT_ARG(); 110dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (get_u32(&order, *argv, 0)) { 111dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(stderr, "Illegal \"order\"\n"); 112dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return -1; 113dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 114dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } else if (strcmp(*argv, "help") == 0) { 115dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat explain(); 116dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return -1; 117dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } else { 118dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(stderr, "What is \"%s\"?\n", *argv); 119dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat explain(); 120dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return -1; 121dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 122dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat argc--; argv++; 123dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 124dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat tail->rta_len = (void *) NLMSG_TAIL(n) - (void *) tail; 125dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (order) { 126dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fh &= ~0x7F00; 127dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fh |= (order<<8)&0x7F00; 128dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 129dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (!t->tcm_handle) 130dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat t->tcm_handle = fh; 131dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return 0; 132dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat} 133dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 134dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehatstatic int route_print_opt(struct filter_util *qu, FILE *f, struct rtattr *opt, __u32 handle) 135dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat{ 136dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat struct rtattr *tb[TCA_ROUTE4_MAX+1]; 137dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat SPRINT_BUF(b1); 138dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 139dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (opt == NULL) 140dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return 0; 141dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 142dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat parse_rtattr_nested(tb, TCA_ROUTE4_MAX, opt); 143dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 144dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (handle) 145dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(f, "fh 0x%08x ", handle); 146dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (handle&0x7F00) 147dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(f, "order %d ", (handle>>8)&0x7F); 148dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 149dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (tb[TCA_ROUTE4_CLASSID]) { 150dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat SPRINT_BUF(b1); 151dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(f, "flowid %s ", sprint_tc_classid(*(__u32*)RTA_DATA(tb[TCA_ROUTE4_CLASSID]), b1)); 152dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 153dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (tb[TCA_ROUTE4_TO]) 154dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(f, "to %s ", rtnl_rtrealm_n2a(*(__u32*)RTA_DATA(tb[TCA_ROUTE4_TO]), b1, sizeof(b1))); 155dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (tb[TCA_ROUTE4_FROM]) 156dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(f, "from %s ", rtnl_rtrealm_n2a(*(__u32*)RTA_DATA(tb[TCA_ROUTE4_FROM]), b1, sizeof(b1))); 157dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (tb[TCA_ROUTE4_IIF]) 158dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(f, "fromif %s", ll_index_to_name(*(int*)RTA_DATA(tb[TCA_ROUTE4_IIF]))); 159dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (tb[TCA_ROUTE4_POLICE]) 160dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat tc_print_police(f, tb[TCA_ROUTE4_POLICE]); 161dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return 0; 162dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat} 163dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 164dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehatstruct filter_util route_filter_util = { 165dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat .id = "route", 166dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat .parse_fopt = route_parse_opt, 167dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat .print_fopt = route_print_opt, 168dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat}; 169