]> granicus.if.org Git - libnl/commitdiff
cgroup classifier improvements
authorThomas Graf <tgraf@suug.ch>
Thu, 28 Oct 2010 22:51:11 +0000 (00:51 +0200)
committerThomas Graf <tgraf@suug.ch>
Thu, 28 Oct 2010 22:51:11 +0000 (00:51 +0200)
 - 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

include/netlink/route/cls/cgroup.h
lib/Makefile.am
lib/cli/cls/cgroup.c [new file with mode: 0644]
lib/route/cls/cgroup.c

index 7b0e3d3a3909734338f7065b64ed148c21005767..20346fffe826949475e87de5e8accd3575181a52 100644 (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_
 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
 }
index 5a520cbd048bb3ced50272953c38cafc12833dd3..98a28632315cc2548b56716117569a46a3bfd76d 100644 (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
diff --git a/lib/cli/cls/cgroup.c b/lib/cli/cls/cgroup.c
new file mode 100644 (file)
index 0000000..41920ea
--- /dev/null
@@ -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);
+}
index 36ff4d4ed98562b4879d5f8bd90cfda69368964b..751e3851a9bdf6dda9fbf492f84d968330869bfb 100644 (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,