Home | History | Annotate | Download | only in tc
      1 /*
      2  * f_cgroup.c		Control Group Classifier
      3  *
      4  *		This program is free software; you can distribute it and/or
      5  *		modify it under the terms of the GNU General Public License
      6  *		as published by the Free Software Foundation; either version
      7  *		2 of the License, or (at your option) any later version.
      8  *
      9  * Authors:	Thomas Graf <tgraf (at) infradead.org>
     10  *
     11  */
     12 
     13 #include <stdio.h>
     14 #include <stdlib.h>
     15 #include "utils.h"
     16 #include "tc_util.h"
     17 #include "m_ematch.h"
     18 
     19 static void explain(void)
     20 {
     21 	fprintf(stderr, "Usage: ... cgroup [ match EMATCH_TREE ]\n");
     22 	fprintf(stderr, "                  [ action ACTION_SPEC ]\n");
     23 }
     24 
     25 static int cgroup_parse_opt(struct filter_util *qu, char *handle,
     26 			   int argc, char **argv, struct nlmsghdr *n)
     27 {
     28 	struct tcmsg *t = NLMSG_DATA(n);
     29 	struct rtattr *tail;
     30 	long h = 0;
     31 
     32 	if (handle) {
     33 		h = strtol(handle, NULL, 0);
     34 		if (h == LONG_MIN || h == LONG_MAX) {
     35 			fprintf(stderr, "Illegal handle \"%s\", must be numeric.\n",
     36 			    handle);
     37 			return -1;
     38 		}
     39 	}
     40 
     41 	t->tcm_handle = h;
     42 
     43 	tail = (struct rtattr *)(((void *)n)+NLMSG_ALIGN(n->nlmsg_len));
     44 	addattr_l(n, MAX_MSG, TCA_OPTIONS, NULL, 0);
     45 
     46 	while (argc > 0) {
     47 		if (matches(*argv, "match") == 0) {
     48 			NEXT_ARG();
     49 			if (parse_ematch(&argc, &argv, TCA_CGROUP_EMATCHES, n)) {
     50 				fprintf(stderr, "Illegal \"ematch\"\n");
     51 				return -1;
     52 			}
     53 			continue;
     54 		} else if (matches(*argv, "action") == 0) {
     55 			NEXT_ARG();
     56 			if (parse_action(&argc, &argv, TCA_CGROUP_ACT, n)) {
     57 				fprintf(stderr, "Illegal \"action\"\n");
     58 				return -1;
     59 			}
     60 			continue;
     61 
     62 		} else if (matches(*argv, "police") == 0) {
     63 			NEXT_ARG();
     64 			if (parse_police(&argc, &argv, TCA_CGROUP_POLICE, n)) {
     65 				fprintf(stderr, "Illegal \"police\"\n");
     66 				return -1;
     67 			}
     68 			continue;
     69 		} else if (strcmp(*argv, "help") == 0) {
     70 			explain();
     71 			return -1;
     72 		} else {
     73 			fprintf(stderr, "What is \"%s\"?\n", *argv);
     74 			explain();
     75 			return -1;
     76 		}
     77 	}
     78 
     79 	tail->rta_len = (((void *)n)+n->nlmsg_len) - (void *)tail;
     80 	return 0;
     81 }
     82 
     83 static int cgroup_print_opt(struct filter_util *qu, FILE *f,
     84 			   struct rtattr *opt, __u32 handle)
     85 {
     86 	struct rtattr *tb[TCA_CGROUP_MAX+1];
     87 
     88 	if (opt == NULL)
     89 		return 0;
     90 
     91 	parse_rtattr_nested(tb, TCA_CGROUP_MAX, opt);
     92 
     93 	if (handle)
     94 		fprintf(f, "handle 0x%x ", handle);
     95 
     96 	if (tb[TCA_CGROUP_EMATCHES])
     97 		print_ematch(f, tb[TCA_CGROUP_EMATCHES]);
     98 
     99 	if (tb[TCA_CGROUP_POLICE]) {
    100 		fprintf(f, "\n");
    101 		tc_print_police(f, tb[TCA_CGROUP_POLICE]);
    102 	}
    103 
    104 	if (tb[TCA_CGROUP_ACT])
    105 		tc_print_action(f, tb[TCA_CGROUP_ACT], 0);
    106 
    107 	return 0;
    108 }
    109 
    110 struct filter_util cgroup_filter_util = {
    111 	.id = "cgroup",
    112 	.parse_fopt = cgroup_parse_opt,
    113 	.print_fopt = cgroup_print_opt,
    114 };
    115