Home | History | Annotate | Download | only in src
      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