diff options
-rw-r--r-- | include/netlink/route/cls/cgroup.h | 9 | ||||
-rw-r--r-- | lib/Makefile.am | 5 | ||||
-rw-r--r-- | lib/cli/cls/cgroup.c | 74 | ||||
-rw-r--r-- | lib/route/cls/cgroup.c | 71 |
4 files changed, 128 insertions, 31 deletions
diff --git a/include/netlink/route/cls/cgroup.h b/include/netlink/route/cls/cgroup.h index 7b0e3d3..20346ff 100644 --- a/include/netlink/route/cls/cgroup.h +++ b/include/netlink/route/cls/cgroup.h @@ -6,7 +6,7 @@ * License as published by the Free Software Foundation version 2.1 * of the License. * - * Copyright (c) 2009 Thomas Graf <tgraf@suug.ch> + * Copyright (c) 2009-2010 Thomas Graf <tgraf@suug.ch> */ #ifndef NETLINK_CLS_CGROUP_H_ @@ -19,10 +19,9 @@ extern "C" { #endif -extern int rtnl_cgroup_set_ematch(struct rtnl_cls *, - struct rtnl_ematch_tree *); -extern struct rtnl_ematch_tree * - rtnl_cgroup_get_ematch(struct rtnl_cls *); +extern void rtnl_cgroup_set_ematch(struct rtnl_cls *, + struct rtnl_ematch_tree *); +struct rtnl_ematch_tree * rtnl_cgroup_get_ematch(struct rtnl_cls *); #ifdef __cplusplus } diff --git a/lib/Makefile.am b/lib/Makefile.am index 5a520cb..98a2863 100644 --- a/lib/Makefile.am +++ b/lib/Makefile.am @@ -50,6 +50,7 @@ libnl_route_la_SOURCES = \ route/route_utils.c route/rtnl.c route/rule.c route/tc.c route/classid.c \ \ route/cls/fw.c route/cls/police.c route/cls/u32.c route/cls/basic.c \ + route/cls/cgroup.c \ \ route/cls/ematch_syntax.c route/cls/ematch_grammar.c \ route/cls/ematch.c \ @@ -73,11 +74,13 @@ nobase_pkglib_LTLIBRARIES = \ cli/qdisc/blackhole.la \ cli/qdisc/pfifo.la \ cli/qdisc/bfifo.la \ - cli/cls/basic.la + cli/cls/basic.la \ + cli/cls/cgroup.la cli_qdisc_htb_la_LDFLAGS = -module -version-info 0:0:0 cli_qdisc_blackhole_la_LDFLAGS = -module -version-info 0:0:0 cli_qdisc_pfifo_la_LDFLAGS = -module -version-info 0:0:0 cli_qdisc_bfifo_la_LDFLAGS = -module -version-info 0:0:0 cli_cls_basic_la_LDFLAGS = -module -version-info 0:0:0 +cli_cls_cgroup_la_LDFLAGS = -module -version-info 0:0:0 endif diff --git a/lib/cli/cls/cgroup.c b/lib/cli/cls/cgroup.c new file mode 100644 index 0000000..41920ea --- /dev/null +++ b/lib/cli/cls/cgroup.c @@ -0,0 +1,74 @@ +/* + * lib/cli/cls/cgroup.c cgroup classifier module for CLI lib + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation version 2.1 + * of the License. + * + * Copyright (c) 2010 Thomas Graf <tgraf@suug.ch> + */ + +#include <netlink/cli/utils.h> +#include <netlink/cli/cls.h> +#include <netlink/route/cls/cgroup.h> + +static void print_usage(void) +{ + printf( +"Usage: nl-cls-add [...] cgroup [OPTIONS]...\n" +"\n" +"OPTIONS\n" +" -h, --help Show this help text.\n" +" -e, --ematch=EXPR Ematch expression\n" +"\n" +"EXAMPLE" +" nl-cls-add --dev=eth0 --parent=q_root cgroup\n"); +} + +static int parse_argv(struct rtnl_cls *cls, int argc, char **argv) +{ + struct rtnl_ematch_tree *tree; + + for (;;) { + int c, optidx = 0; + static struct option long_opts[] = { + { "help", 0, 0, 'h' }, + { "ematch", 1, 0, 'e' }, + { 0, 0, 0, 0 } + }; + + c = getopt_long(argc, argv, "he:", long_opts, &optidx); + if (c == -1) + break; + + switch (c) { + case 'h': + print_usage(); + exit(0); + + case 'e': + tree = nl_cli_cls_parse_ematch(cls, optarg); + rtnl_cgroup_set_ematch(cls, tree); + break; + } + } + + return 0; +} + +static struct nl_cli_cls_module cgroup_module = +{ + .cm_name = "cgroup", + .cm_parse_argv = parse_argv, +}; + +static void __init cgroup_init(void) +{ + nl_cli_cls_register(&cgroup_module); +} + +static void __exit cgroup_exit(void) +{ + nl_cli_cls_unregister(&cgroup_module); +} diff --git a/lib/route/cls/cgroup.c b/lib/route/cls/cgroup.c index 36ff4d4..751e385 100644 --- a/lib/route/cls/cgroup.c +++ b/lib/route/cls/cgroup.c @@ -6,7 +6,7 @@ * License as published by the Free Software Foundation version 2.1 * of the License. * - * Copyright (c) 2009 Thomas Graf <tgraf@suug.ch> + * Copyright (c) 2009-2010 Thomas Graf <tgraf@suug.ch> */ /** @@ -34,16 +34,21 @@ static struct nla_policy cgroup_policy[TCA_CGROUP_MAX+1] = { [TCA_CGROUP_EMATCHES] = { .type = NLA_NESTED }, }; +static int cgroup_clone(struct rtnl_cls *_dst, struct rtnl_cls *_src) +{ + return -NLE_OPNOTSUPP; +} + static void cgroup_free_data(struct rtnl_cls *cls) { - struct rtnl_cgroup *cg = rtnl_cls_data(cls); + struct rtnl_cgroup *c = rtnl_cls_data(cls); - rtnl_ematch_tree_free(cg->cg_ematch); + rtnl_ematch_tree_free(c->cg_ematch); } static int cgroup_msg_parser(struct rtnl_cls *cls) { - struct rtnl_cgroup *cg = rtnl_cls_data(cls); + struct rtnl_cgroup *c = rtnl_cls_data(cls); struct nlattr *tb[TCA_CGROUP_MAX + 1]; int err; @@ -53,10 +58,10 @@ static int cgroup_msg_parser(struct rtnl_cls *cls) return err; if (tb[TCA_CGROUP_EMATCHES]) { - if ((err = rtnl_ematch_parse(tb[TCA_CGROUP_EMATCHES], - &cg->cg_ematch)) < 0) + if ((err = rtnl_ematch_parse_attr(tb[TCA_CGROUP_EMATCHES], + &c->cg_ematch)) < 0) return err; - cg->cg_mask |= CGROUP_ATTR_EMATCH; + c->cg_mask |= CGROUP_ATTR_EMATCH; } #if 0 @@ -70,9 +75,9 @@ static int cgroup_msg_parser(struct rtnl_cls *cls) static void cgroup_dump_line(struct rtnl_cls *cls, struct nl_dump_params *p) { - struct rtnl_cgroup *cg = rtnl_cls_data(cls); + struct rtnl_cgroup *c = rtnl_cls_data(cls); - if (cg->cg_mask & CGROUP_ATTR_EMATCH) + if (c->cg_mask & CGROUP_ATTR_EMATCH) nl_dump(p, " ematch"); else nl_dump(p, " match-all"); @@ -80,48 +85,64 @@ static void cgroup_dump_line(struct rtnl_cls *cls, struct nl_dump_params *p) static void cgroup_dump_details(struct rtnl_cls *cls, struct nl_dump_params *p) { - struct rtnl_cgroup *cg = rtnl_cls_data(cls); + struct rtnl_cgroup *c = rtnl_cls_data(cls); - if (cg->cg_mask & CGROUP_ATTR_EMATCH) { - nl_dump(p, "\n"); + if (c->cg_mask & CGROUP_ATTR_EMATCH) { nl_dump_line(p, " ematch "); - rtnl_ematch_tree_dump(cg->cg_ematch, p); - } + rtnl_ematch_tree_dump(c->cg_ematch, p); + } else + nl_dump(p, "no options.\n"); +} + +static int cgroup_get_opts(struct rtnl_cls *cls, struct nl_msg *msg) +{ + struct rtnl_cgroup *c = rtnl_cls_data(cls); + + if (!(cls->ce_mask & TCA_ATTR_HANDLE)) + return -NLE_MISSING_ATTR; + + if (c->cg_mask & CGROUP_ATTR_EMATCH) + return rtnl_ematch_fill_attr(msg, TCA_CGROUP_EMATCHES, + c->cg_ematch); + + return 0; } + /** * @name Attribute Modifications * @{ */ -int rtnl_cgroup_set_ematch(struct rtnl_cls *cls, struct rtnl_ematch_tree *tree) +void rtnl_cgroup_set_ematch(struct rtnl_cls *cls, struct rtnl_ematch_tree *tree) { - struct rtnl_cgroup *cg = rtnl_cls_data(cls); + struct rtnl_cgroup *c = rtnl_cls_data(cls); - if (cg->cg_ematch) { - rtnl_ematch_tree_free(cg->cg_ematch); - cg->cg_mask &= ~CGROUP_ATTR_EMATCH; + if (c->cg_ematch) { + rtnl_ematch_tree_free(c->cg_ematch); + c->cg_mask &= ~CGROUP_ATTR_EMATCH; } - cg->cg_ematch = tree; + c->cg_ematch = tree; if (tree) - cg->cg_mask |= CGROUP_ATTR_EMATCH; - - return 0; + c->cg_mask |= CGROUP_ATTR_EMATCH; } struct rtnl_ematch_tree *rtnl_cgroup_get_ematch(struct rtnl_cls *cls) { - struct rtnl_cgroup *cg = rtnl_cls_data(cls); - return cg->cg_ematch; + return ((struct rtnl_cgroup *) rtnl_cls_data(cls))->cg_ematch; } +/** @} */ + static struct rtnl_cls_ops cgroup_ops = { .co_kind = "cgroup", .co_size = sizeof(struct rtnl_cgroup), + .co_clone = cgroup_clone, .co_msg_parser = cgroup_msg_parser, .co_free_data = cgroup_free_data, + .co_get_opts = cgroup_get_opts, .co_dump = { [NL_DUMP_LINE] = cgroup_dump_line, [NL_DUMP_DETAILS] = cgroup_dump_details, |