libnl 2.0
|
00001 /* 00002 * lib/route/cls/cgroup.c Control Groups Classifier 00003 * 00004 * This library is free software; you can redistribute it and/or 00005 * modify it under the terms of the GNU Lesser General Public 00006 * License as published by the Free Software Foundation version 2.1 00007 * of the License. 00008 * 00009 * Copyright (c) 2009 Thomas Graf <tgraf@suug.ch> 00010 */ 00011 00012 /** 00013 * @ingroup cls_api 00014 * @defgroup cgroup Control Groups Classifier 00015 * 00016 * @{ 00017 */ 00018 00019 #include <netlink-local.h> 00020 #include <netlink-tc.h> 00021 #include <netlink/netlink.h> 00022 #include <netlink/attr.h> 00023 #include <netlink/utils.h> 00024 #include <netlink/route/classifier.h> 00025 #include <netlink/route/classifier-modules.h> 00026 #include <netlink/route/cls/cgroup.h> 00027 #include <netlink/route/cls/ematch.h> 00028 00029 /** @cond SKIP */ 00030 #define CGROUP_ATTR_EMATCH 0x001 00031 /** @endcond */ 00032 00033 static struct nla_policy cgroup_policy[TCA_CGROUP_MAX+1] = { 00034 [TCA_CGROUP_EMATCHES] = { .type = NLA_NESTED }, 00035 }; 00036 00037 static void cgroup_free_data(struct rtnl_cls *cls) 00038 { 00039 struct rtnl_cgroup *cg = rtnl_cls_data(cls); 00040 00041 rtnl_ematch_tree_free(cg->cg_ematch); 00042 } 00043 00044 static int cgroup_msg_parser(struct rtnl_cls *cls) 00045 { 00046 struct rtnl_cgroup *cg = rtnl_cls_data(cls); 00047 struct nlattr *tb[TCA_CGROUP_MAX + 1]; 00048 int err; 00049 00050 err = tca_parse(tb, TCA_CGROUP_MAX, (struct rtnl_tca *) cls, 00051 cgroup_policy); 00052 if (err < 0) 00053 return err; 00054 00055 if (tb[TCA_CGROUP_EMATCHES]) { 00056 if ((err = rtnl_ematch_parse(tb[TCA_CGROUP_EMATCHES], 00057 &cg->cg_ematch)) < 0) 00058 return err; 00059 cg->cg_mask |= CGROUP_ATTR_EMATCH; 00060 } 00061 00062 #if 0 00063 TODO: 00064 TCA_CGROUP_ACT, 00065 TCA_CGROUP_POLICE, 00066 #endif 00067 00068 return 0; 00069 } 00070 00071 static void cgroup_dump_line(struct rtnl_cls *cls, struct nl_dump_params *p) 00072 { 00073 struct rtnl_cgroup *cg = rtnl_cls_data(cls); 00074 00075 if (cg->cg_mask & CGROUP_ATTR_EMATCH) 00076 nl_dump(p, " ematch"); 00077 else 00078 nl_dump(p, " match-all"); 00079 } 00080 00081 static void cgroup_dump_details(struct rtnl_cls *cls, struct nl_dump_params *p) 00082 { 00083 struct rtnl_cgroup *cg = rtnl_cls_data(cls); 00084 00085 if (cg->cg_mask & CGROUP_ATTR_EMATCH) { 00086 nl_dump(p, "\n"); 00087 nl_dump_line(p, " ematch "); 00088 rtnl_ematch_tree_dump(cg->cg_ematch, p); 00089 } 00090 } 00091 00092 /** 00093 * @name Attribute Modifications 00094 * @{ 00095 */ 00096 00097 int rtnl_cgroup_set_ematch(struct rtnl_cls *cls, struct rtnl_ematch_tree *tree) 00098 { 00099 struct rtnl_cgroup *cg = rtnl_cls_data(cls); 00100 00101 if (cg->cg_ematch) { 00102 rtnl_ematch_tree_free(cg->cg_ematch); 00103 cg->cg_mask &= ~CGROUP_ATTR_EMATCH; 00104 } 00105 00106 cg->cg_ematch = tree; 00107 00108 if (tree) 00109 cg->cg_mask |= CGROUP_ATTR_EMATCH; 00110 00111 return 0; 00112 } 00113 00114 struct rtnl_ematch_tree *rtnl_cgroup_get_ematch(struct rtnl_cls *cls) 00115 { 00116 struct rtnl_cgroup *cg = rtnl_cls_data(cls); 00117 return cg->cg_ematch; 00118 } 00119 00120 static struct rtnl_cls_ops cgroup_ops = { 00121 .co_kind = "cgroup", 00122 .co_size = sizeof(struct rtnl_cgroup), 00123 .co_msg_parser = cgroup_msg_parser, 00124 .co_free_data = cgroup_free_data, 00125 .co_dump = { 00126 [NL_DUMP_LINE] = cgroup_dump_line, 00127 [NL_DUMP_DETAILS] = cgroup_dump_details, 00128 }, 00129 }; 00130 00131 static void __init cgroup_init(void) 00132 { 00133 rtnl_cls_register(&cgroup_ops); 00134 } 00135 00136 static void __exit cgroup_exit(void) 00137 { 00138 rtnl_cls_unregister(&cgroup_ops); 00139 } 00140 00141 /** @} */