1 /* 2 * src/nl-cls-add.c Add classifier 3 * 4 * This library is free software; you can redistribute it and/or 5 * modify it under the terms of the GNU General Public License as 6 * published by the Free Software Foundation version 2 of the License. 7 * 8 * Copyright (c) 2003-2009 Thomas Graf <tgraf (at) suug.ch> 9 */ 10 11 #include "cls/utils.h" 12 13 static int quiet = 0; 14 15 static void print_usage(void) 16 { 17 printf( 18 "Usage: nl-cls-add [OPTION]... [CLASSIFIER] TYPE [TYPE OPTIONS]...\n" 19 "\n" 20 "Options\n" 21 " -q, --quiet Do not print informal notifications.\n" 22 " -h, --help Show this help.\n" 23 " -v, --version Show versioning information.\n" 24 "\n" 25 "Classifier Options\n" 26 " -d, --dev=DEV Device the classifier should be assigned to.\n" 27 " -p, --parent=HANDLE Parent QDisc\n" 28 " --proto=PROTO Protocol (default=IPv4)\n" 29 " --prio=NUM Priority (0..256)\n" 30 " --id=HANDLE Unique identifier\n" 31 ); 32 exit(0); 33 } 34 35 int main(int argc, char *argv[]) 36 { 37 struct nl_sock *sock; 38 struct rtnl_cls *cls; 39 struct nl_cache *link_cache; 40 struct rtnl_cls_ops *ops; 41 struct cls_module *mod; 42 struct nl_dump_params dp = { 43 .dp_type = NL_DUMP_DETAILS, 44 .dp_fd = stdout, 45 }; 46 char *kind; 47 int err, nlflags = NLM_F_CREATE; 48 49 sock = nlt_alloc_socket(); 50 nlt_connect(sock, NETLINK_ROUTE); 51 link_cache = nlt_alloc_link_cache(sock); 52 cls = nlt_alloc_cls(); 53 54 for (;;) { 55 int c, optidx = 0; 56 enum { 57 ARG_PROTO = 257, 58 ARG_PRIO = 258, 59 ARG_ID, 60 }; 61 static struct option long_opts[] = { 62 { "quiet", 0, 0, 'q' }, 63 { "help", 0, 0, 'h' }, 64 { "version", 0, 0, 'v' }, 65 { "dev", 1, 0, 'd' }, 66 { "parent", 1, 0, 'p' }, 67 { "proto", 1, 0, ARG_PROTO }, 68 { "prio", 1, 0, ARG_PRIO }, 69 { "id", 1, 0, ARG_ID }, 70 { 0, 0, 0, 0 } 71 }; 72 73 c = getopt_long(argc, argv, "+qhva:d:", long_opts, &optidx); 74 if (c == -1) 75 break; 76 77 switch (c) { 78 case '?': exit(NLE_INVAL); 79 case 'q': quiet = 1; break; 80 case 'h': print_usage(); break; 81 case 'v': nlt_print_version(); break; 82 case 'd': parse_dev(cls, link_cache, optarg); break; 83 case 'p': parse_parent(cls, optarg); break; 84 case ARG_PRIO: parse_prio(cls, optarg); break; 85 case ARG_ID: parse_handle(cls, optarg); break; 86 case ARG_PROTO: parse_proto(cls, optarg); break; 87 } 88 } 89 90 if (optind >= argc) { 91 print_usage(); 92 fatal(EINVAL, "Missing classifier type"); 93 } 94 95 kind = argv[optind++]; 96 if ((err = rtnl_cls_set_kind(cls, kind)) < 0) 97 fatal(ENOENT, "Unknown classifier type \"%s\".", kind); 98 99 ops = rtnl_cls_get_ops(cls); 100 if (!(mod = lookup_cls_mod(ops))) 101 fatal(ENOTSUP, "Classifier type \"%s\" not supported.", kind); 102 103 mod->parse_argv(cls, argc, argv); 104 105 printf("Adding "); 106 nl_object_dump(OBJ_CAST(cls), &dp); 107 108 if ((err = rtnl_cls_add(sock, cls, nlflags)) < 0) 109 fatal(err, "Unable to add classifier: %s", nl_geterror(err)); 110 111 if (!quiet) { 112 printf("Added "); 113 nl_object_dump(OBJ_CAST(cls), &dp); 114 } 115 116 return 0; 117 } 118