cgroup classifier improvements

- enabled again
 - ematch support
 - cli tools module

Example:
	nl-qdisc-add --dev eth0 --parent root --id 1: htb
	nl-cls-add --dev eth0 --parent 1: --id dead: cgroup
	nl-class-add --dev eth0 --parent 1: --id 1:<CGROUP> htb --rate 77mbit
This commit is contained in:
Thomas Graf 2010-10-29 00:51:11 +02:00
parent 2f867686ac
commit 691905bc56
4 changed files with 128 additions and 31 deletions

View file

@ -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
}

View file

@ -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

74
lib/cli/cls/cgroup.c Normal file
View file

@ -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);
}

View file

@ -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,