Home | History | Annotate | Download | only in cls
      1 /*
      2  * lib/route/cls/cgroup.c	Control Groups Classifier
      3  *
      4  *	This library is free software; you can redistribute it and/or
      5  *	modify it under the terms of the GNU Lesser General Public
      6  *	License as published by the Free Software Foundation version 2.1
      7  *	of the License.
      8  *
      9  * Copyright (c) 2009 Thomas Graf <tgraf (at) suug.ch>
     10  */
     11 
     12 /**
     13  * @ingroup cls_api
     14  * @defgroup cgroup Control Groups Classifier
     15  *
     16  * @{
     17  */
     18 
     19 #include <netlink-local.h>
     20 #include <netlink-tc.h>
     21 #include <netlink/netlink.h>
     22 #include <netlink/attr.h>
     23 #include <netlink/utils.h>
     24 #include <netlink/route/classifier.h>
     25 #include <netlink/route/classifier-modules.h>
     26 #include <netlink/route/cls/cgroup.h>
     27 #include <netlink/route/cls/ematch.h>
     28 
     29 /** @cond SKIP */
     30 #define CGROUP_ATTR_EMATCH      0x001
     31 /** @endcond */
     32 
     33 static struct nla_policy cgroup_policy[TCA_CGROUP_MAX+1] = {
     34 	[TCA_CGROUP_EMATCHES]	= { .type = NLA_NESTED },
     35 };
     36 
     37 static void cgroup_free_data(struct rtnl_cls *cls)
     38 {
     39 	struct rtnl_cgroup *cg = rtnl_cls_data(cls);
     40 
     41 	rtnl_ematch_tree_free(cg->cg_ematch);
     42 }
     43 
     44 static int cgroup_msg_parser(struct rtnl_cls *cls)
     45 {
     46 	struct rtnl_cgroup *cg = rtnl_cls_data(cls);
     47 	struct nlattr *tb[TCA_CGROUP_MAX + 1];
     48 	int err;
     49 
     50 	err = tca_parse(tb, TCA_CGROUP_MAX, (struct rtnl_tca *) cls,
     51 			cgroup_policy);
     52 	if (err < 0)
     53 		return err;
     54 
     55 	if (tb[TCA_CGROUP_EMATCHES]) {
     56 		if ((err = rtnl_ematch_parse(tb[TCA_CGROUP_EMATCHES],
     57 					     &cg->cg_ematch)) < 0)
     58 			return err;
     59 		cg->cg_mask |= CGROUP_ATTR_EMATCH;
     60 	}
     61 
     62 #if 0
     63 	TODO:
     64 	TCA_CGROUP_ACT,
     65 	TCA_CGROUP_POLICE,
     66 #endif
     67 
     68 	return 0;
     69 }
     70 
     71 static void cgroup_dump_line(struct rtnl_cls *cls, struct nl_dump_params *p)
     72 {
     73 	struct rtnl_cgroup *cg = rtnl_cls_data(cls);
     74 
     75 	if (cg->cg_mask & CGROUP_ATTR_EMATCH)
     76 		nl_dump(p, " ematch");
     77 	else
     78 		nl_dump(p, " match-all");
     79 }
     80 
     81 static void cgroup_dump_details(struct rtnl_cls *cls, struct nl_dump_params *p)
     82 {
     83 	struct rtnl_cgroup *cg = rtnl_cls_data(cls);
     84 
     85 	if (cg->cg_mask & CGROUP_ATTR_EMATCH) {
     86 		nl_dump(p, "\n");
     87 		nl_dump_line(p, "    ematch ");
     88 		rtnl_ematch_tree_dump(cg->cg_ematch, p);
     89 	}
     90 }
     91 
     92 /**
     93  * @name Attribute Modifications
     94  * @{
     95  */
     96 
     97 int rtnl_cgroup_set_ematch(struct rtnl_cls *cls, struct rtnl_ematch_tree *tree)
     98 {
     99 	struct rtnl_cgroup *cg = rtnl_cls_data(cls);
    100 
    101 	if (cg->cg_ematch) {
    102 		rtnl_ematch_tree_free(cg->cg_ematch);
    103 		cg->cg_mask &= ~CGROUP_ATTR_EMATCH;
    104 	}
    105 
    106 	cg->cg_ematch = tree;
    107 
    108 	if (tree)
    109 		cg->cg_mask |= CGROUP_ATTR_EMATCH;
    110 
    111 	return 0;
    112 }
    113 
    114 struct rtnl_ematch_tree *rtnl_cgroup_get_ematch(struct rtnl_cls *cls)
    115 {
    116 	struct rtnl_cgroup *cg = rtnl_cls_data(cls);
    117 	return cg->cg_ematch;
    118 }
    119 
    120 static struct rtnl_cls_ops cgroup_ops = {
    121 	.co_kind		= "cgroup",
    122 	.co_size		= sizeof(struct rtnl_cgroup),
    123 	.co_msg_parser		= cgroup_msg_parser,
    124 	.co_free_data		= cgroup_free_data,
    125 	.co_dump = {
    126 	    [NL_DUMP_LINE]	= cgroup_dump_line,
    127 	    [NL_DUMP_DETAILS]	= cgroup_dump_details,
    128 	},
    129 };
    130 
    131 static void __init cgroup_init(void)
    132 {
    133 	rtnl_cls_register(&cgroup_ops);
    134 }
    135 
    136 static void __exit cgroup_exit(void)
    137 {
    138 	rtnl_cls_unregister(&cgroup_ops);
    139 }
    140 
    141 /** @} */
    142