19066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/* 29066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * src/nl-class-add.c Add/Update/Replace Traffic Class 39066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 49066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * This library is free software; you can redistribute it and/or 59066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * modify it under the terms of the GNU Lesser General Public 69066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * License as published by the Free Software Foundation version 2.1 79066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * of the License. 89066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 99066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Copyright (c) 2010 Thomas Graf <tgraf@suug.ch> 109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <netlink/cli/utils.h> 139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <netlink/cli/tc.h> 149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <netlink/cli/qdisc.h> 159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <netlink/cli/class.h> 169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <netlink/cli/link.h> 179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <netlink-private/route/tc-api.h> 1914272302a8b635bd8e9267c1411d0a7ef11bff45Dianne Hackborn 208c84109b9fbbf473b225707a38261ff5f99d95fbDianne Hackbornstatic int quiet = 0; 212139276ce8b54aba5faa858ca69ed5f01445c269Jeff Brown 229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic void print_usage(void) 239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 24ef2ea1faf6449f97a2423ecbdecce664c58bcbe1Adam Lesinski printf( 25ef2ea1faf6449f97a2423ecbdecce664c58bcbe1Adam Lesinski"Usage: nl-class-add [OPTIONS]... class [CONFIGURATION]...\n" 269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project"\n" 279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project"OPTIONS\n" 289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project" -q, --quiet Do not print informal notifications.\n" 299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project" -h, --help Show this help text.\n" 309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project" -v, --version Show versioning information.\n" 319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project" --update Update class if it exists.\n" 329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project" --update-only Only update class, never create it.\n" 332139276ce8b54aba5faa858ca69ed5f01445c269Jeff Brown" -d, --dev=DEV Network device the class should be attached to.\n" 3426faecc85ec3e809135b287173997e97fcb8fc30Todd Poynor" -i, --id=ID ID of new class (default: auto-generated)\n" 359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project" -p, --parent=ID ID of parent { root | ingress | class-ID }\n" 368bdf5935c0db4a66ab33a10b43398d2523cfa15dDianne Hackborn" --mtu=SIZE Overwrite MTU (default: MTU of network device)\n" 37605ea69ab16dee2047ea43905a9b443896cde121Jeff Brown" --mpu=SIZE Minimum packet size on the link (default: 0).\n" 3826faecc85ec3e809135b287173997e97fcb8fc30Todd Poynor" --overhead=SIZE Overhead in bytes per packet (default: 0).\n" 3926faecc85ec3e809135b287173997e97fcb8fc30Todd Poynor" --linktype=TYPE Overwrite linktype (default: type of network device)\n" 409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project"\n" 4118e939623556928f73fcc7511c85a537929a4a7eDan Egnor"CONFIGURATION\n" 429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project" -h, --help Show help text of class specific options.\n" 439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project"\n" 449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project"EXAMPLE\n" 459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project" $ nl-class-add --dev=eth1 --parent=root htb --rate=100mbit\n" 465ac72a29593ab9a20337a2225df52bdf4754be02Dianne Hackborn"\n" 479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ); 489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project exit(0); 498a9b22056b13477f59df934928c00c58b5871c95Joe Onorato} 509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectint main(int argc, char *argv[]) 529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project struct nl_sock *sock; 549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project struct rtnl_class *class; 559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project struct rtnl_tc *tc; 569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project struct nl_cache *link_cache; 579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project struct nl_dump_params dp = { 589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project .dp_type = NL_DUMP_DETAILS, 599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project .dp_fd = stdout, 609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project }; 619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project struct nl_cli_tc_module *tm; 629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project struct rtnl_tc_ops *ops; 639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int err, flags = NLM_F_CREATE | NLM_F_EXCL; 649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project char *kind, *id = NULL; 659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sock = nl_cli_alloc_socket(); 679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project nl_cli_connect(sock, NETLINK_ROUTE); 689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project link_cache = nl_cli_link_alloc_cache(sock); 709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project class = nl_cli_class_alloc(); 729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project tc = (struct rtnl_tc *) class; 739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (;;) { 759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int c, optidx = 0; 769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project enum { 779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ARG_UPDATE = 257, 789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ARG_UPDATE_ONLY = 258, 79605ea69ab16dee2047ea43905a9b443896cde121Jeff Brown ARG_MTU, 80605ea69ab16dee2047ea43905a9b443896cde121Jeff Brown ARG_MPU, 81605ea69ab16dee2047ea43905a9b443896cde121Jeff Brown ARG_OVERHEAD, 82605ea69ab16dee2047ea43905a9b443896cde121Jeff Brown ARG_LINKTYPE, 83605ea69ab16dee2047ea43905a9b443896cde121Jeff Brown }; 84605ea69ab16dee2047ea43905a9b443896cde121Jeff Brown static struct option long_opts[] = { 85605ea69ab16dee2047ea43905a9b443896cde121Jeff Brown { "quiet", 0, 0, 'q' }, 86605ea69ab16dee2047ea43905a9b443896cde121Jeff Brown { "help", 0, 0, 'h' }, 879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { "version", 0, 0, 'v' }, 882139276ce8b54aba5faa858ca69ed5f01445c269Jeff Brown { "dev", 1, 0, 'd' }, 899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { "parent", 1, 0, 'p' }, 90ab5c49c7e7f5f61040650109a76f38a443fb852dDoug Zongker { "id", 1, 0, 'i' }, 91a4d8204e3068b9d8d6908d4cf3440e81967867a3Jeff Brown { "update", 0, 0, ARG_UPDATE }, 92ab5c49c7e7f5f61040650109a76f38a443fb852dDoug Zongker { "update-only", 0, 0, ARG_UPDATE_ONLY }, 93a4d8204e3068b9d8d6908d4cf3440e81967867a3Jeff Brown { "mtu", 1, 0, ARG_MTU }, 949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { "mpu", 1, 0, ARG_MPU }, 959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { "overhead", 1, 0, ARG_OVERHEAD }, 969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { "linktype", 1, 0, ARG_LINKTYPE }, 974ca7f1e2811dc889e526de6c3d30bac8501c23d2Joe Onorato { 0, 0, 0, 0 } 989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project }; 999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 100ec43a6bc17d90058ba2c00e016846c863ab239bcJeff Sharkey c = getopt_long(argc, argv, "+qhvd:p:i:", 101ab5c49c7e7f5f61040650109a76f38a443fb852dDoug Zongker long_opts, &optidx); 1029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (c == -1) 1039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 1049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project switch (c) { 1069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case 'q': quiet = 1; break; 1079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case 'h': print_usage(); break; 1089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case 'v': nl_cli_print_version(); break; 109605ea69ab16dee2047ea43905a9b443896cde121Jeff Brown case 'd': nl_cli_tc_parse_dev(tc, link_cache, optarg); break; 110ab5c49c7e7f5f61040650109a76f38a443fb852dDoug Zongker case 'p': nl_cli_tc_parse_parent(tc, optarg); break; 111a4d8204e3068b9d8d6908d4cf3440e81967867a3Jeff Brown case 'i': id = strdup(optarg); break; 112a4d8204e3068b9d8d6908d4cf3440e81967867a3Jeff Brown case ARG_UPDATE: flags = NLM_F_CREATE; break; 11326faecc85ec3e809135b287173997e97fcb8fc30Todd Poynor case ARG_UPDATE_ONLY: flags = 0; break; 114a1f1a3c573acd91024fda0ceb3b921c73b186963Dianne Hackborn case ARG_MTU: nl_cli_tc_parse_mtu(tc, optarg); break; 1159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case ARG_MPU: nl_cli_tc_parse_mpu(tc, optarg); break; 1169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case ARG_OVERHEAD: nl_cli_tc_parse_overhead(tc, optarg); break; 1179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case ARG_LINKTYPE: nl_cli_tc_parse_linktype(tc, optarg); break; 1189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (optind >= argc) 1229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project print_usage(); 12376dc5a51cde1db0e8e193f22bc8a7ace9edef53dAdrian Roos 124f92fcfe36ad841cba4774e7f2129e8dab7ac784aBadhri Jagan Sridharan if (!rtnl_tc_get_ifindex(tc)) 125a4d8204e3068b9d8d6908d4cf3440e81967867a3Jeff Brown nl_cli_fatal(EINVAL, "You must specify a network device (--dev=XXX)"); 126a4d8204e3068b9d8d6908d4cf3440e81967867a3Jeff Brown 1274ca7f1e2811dc889e526de6c3d30bac8501c23d2Joe Onorato if (!rtnl_tc_get_parent(tc)) 128d81b1f41e5e7bf0ccd3e4c08838d65eacdc8dda0Mike Lockwood nl_cli_fatal(EINVAL, "You must specify a parent (--parent=XXX)"); 129d81b1f41e5e7bf0ccd3e4c08838d65eacdc8dda0Mike Lockwood 130d81b1f41e5e7bf0ccd3e4c08838d65eacdc8dda0Mike Lockwood if (id) { 131f3c74f34999337b8eb77e1a5ed0287561b512c21Brian Muramatsu nl_cli_tc_parse_handle(tc, id, 1); 132d81b1f41e5e7bf0ccd3e4c08838d65eacdc8dda0Mike Lockwood free(id); 1339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 135ab5c49c7e7f5f61040650109a76f38a443fb852dDoug Zongker kind = argv[optind++]; 136eb94fa7975b1e8742f3b00cec6bd4f9d6b329e3aDianne Hackborn rtnl_tc_set_kind(tc, kind); 137eb94fa7975b1e8742f3b00cec6bd4f9d6b329e3aDianne Hackborn 1389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!(ops = rtnl_tc_get_ops(tc))) 1399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project nl_cli_fatal(ENOENT, "Unknown class \"%s\"", kind); 140ab5c49c7e7f5f61040650109a76f38a443fb852dDoug Zongker 141c428aae6429c3fd5e2037c3793af399d9f6e23bfDianne Hackborn if (!(tm = nl_cli_tc_lookup(ops))) 142c428aae6429c3fd5e2037c3793af399d9f6e23bfDianne Hackborn nl_cli_fatal(ENOTSUP, "class type \"%s\" not supported.", kind); 143de1b359e88ef1dcafdc0c6a724f660ad0b55fc3aJoe Onorato 144de1b359e88ef1dcafdc0c6a724f660ad0b55fc3aJoe Onorato tm->tm_parse_argv(tc, argc, argv); 1458ec5b83fc8f8aa68805c4d5987f8f75bb28250caDianne Hackborn 146ab5c49c7e7f5f61040650109a76f38a443fb852dDoug Zongker if (!quiet) { 1472139276ce8b54aba5faa858ca69ed5f01445c269Jeff Brown printf("Adding "); 1482139276ce8b54aba5faa858ca69ed5f01445c269Jeff Brown nl_object_dump(OBJ_CAST(class), &dp); 1492139276ce8b54aba5faa858ca69ed5f01445c269Jeff Brown } 1509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 151605ea69ab16dee2047ea43905a9b443896cde121Jeff Brown if ((err = rtnl_class_add(sock, class, flags)) < 0) 1522139276ce8b54aba5faa858ca69ed5f01445c269Jeff Brown nl_cli_fatal(EINVAL, "Unable to add class: %s", nl_geterror(err)); 1539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return 0; 1554ca7f1e2811dc889e526de6c3d30bac8501c23d2Joe Onorato} 1564ca7f1e2811dc889e526de6c3d30bac8501c23d2Joe Onorato