summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/netlink/route/cls/cgroup.h9
-rw-r--r--lib/Makefile.am5
-rw-r--r--lib/cli/cls/cgroup.c74
-rw-r--r--lib/route/cls/cgroup.c71
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,