libnl
3.2.3
|
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-2011 Thomas Graf <tgraf@suug.ch> 00010 */ 00011 00012 /** 00013 * @ingroup cls 00014 * @defgroup cls_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/tc-api.h> 00025 #include <netlink/route/classifier.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 int cgroup_clone(void *dst, void *src) 00038 { 00039 return -NLE_OPNOTSUPP; 00040 } 00041 00042 static void cgroup_free_data(struct rtnl_tc *tc, void *data) 00043 { 00044 struct rtnl_cgroup *c = data; 00045 00046 if (!c) 00047 return; 00048 00049 rtnl_ematch_tree_free(c->cg_ematch); 00050 } 00051 00052 static int cgroup_msg_parser(struct rtnl_tc *tc, void *data) 00053 { 00054 struct nlattr *tb[TCA_CGROUP_MAX + 1]; 00055 struct rtnl_cgroup *c = data; 00056 int err; 00057 00058 err = tca_parse(tb, TCA_CGROUP_MAX, tc, cgroup_policy); 00059 if (err < 0) 00060 return err; 00061 00062 if (tb[TCA_CGROUP_EMATCHES]) { 00063 if ((err = rtnl_ematch_parse_attr(tb[TCA_CGROUP_EMATCHES], 00064 &c->cg_ematch)) < 0) 00065 return err; 00066 c->cg_mask |= CGROUP_ATTR_EMATCH; 00067 } 00068 00069 #if 0 00070 TODO: 00071 TCA_CGROUP_ACT, 00072 TCA_CGROUP_POLICE, 00073 #endif 00074 00075 return 0; 00076 } 00077 00078 static void cgroup_dump_line(struct rtnl_tc *tc, void *data, 00079 struct nl_dump_params *p) 00080 { 00081 struct rtnl_cgroup *c = data; 00082 00083 if (!c) 00084 return; 00085 00086 if (c->cg_mask & CGROUP_ATTR_EMATCH) 00087 nl_dump(p, " ematch"); 00088 else 00089 nl_dump(p, " match-all"); 00090 } 00091 00092 static void cgroup_dump_details(struct rtnl_tc *tc, void *data, 00093 struct nl_dump_params *p) 00094 { 00095 struct rtnl_cgroup *c = data; 00096 00097 if (!c) 00098 return; 00099 00100 if (c->cg_mask & CGROUP_ATTR_EMATCH) { 00101 nl_dump_line(p, " ematch "); 00102 00103 if (c->cg_ematch) 00104 rtnl_ematch_tree_dump(c->cg_ematch, p); 00105 else 00106 nl_dump(p, "<no tree>"); 00107 } else 00108 nl_dump(p, "no options"); 00109 } 00110 00111 static int cgroup_fill_msg(struct rtnl_tc *tc, void *data, 00112 struct nl_msg *msg) 00113 { 00114 struct rtnl_cgroup *c = data; 00115 00116 if (!c) 00117 BUG(); 00118 00119 if (!(tc->ce_mask & TCA_ATTR_HANDLE)) 00120 return -NLE_MISSING_ATTR; 00121 00122 if (c->cg_mask & CGROUP_ATTR_EMATCH) 00123 return rtnl_ematch_fill_attr(msg, TCA_CGROUP_EMATCHES, 00124 c->cg_ematch); 00125 00126 return 0; 00127 } 00128 00129 00130 /** 00131 * @name Attribute Modifications 00132 * @{ 00133 */ 00134 00135 void rtnl_cgroup_set_ematch(struct rtnl_cls *cls, struct rtnl_ematch_tree *tree) 00136 { 00137 struct rtnl_cgroup *c; 00138 00139 if (!(c = rtnl_tc_data(TC_CAST(cls)))) 00140 BUG(); 00141 00142 if (c->cg_ematch) { 00143 rtnl_ematch_tree_free(c->cg_ematch); 00144 c->cg_mask &= ~CGROUP_ATTR_EMATCH; 00145 } 00146 00147 c->cg_ematch = tree; 00148 00149 if (tree) 00150 c->cg_mask |= CGROUP_ATTR_EMATCH; 00151 } 00152 00153 struct rtnl_ematch_tree *rtnl_cgroup_get_ematch(struct rtnl_cls *cls) 00154 { 00155 struct rtnl_cgroup *c; 00156 00157 if (!(c = rtnl_tc_data(TC_CAST(cls)))) 00158 BUG(); 00159 00160 return c->cg_ematch; 00161 } 00162 00163 /** @} */ 00164 00165 static struct rtnl_tc_ops cgroup_ops = { 00166 .to_kind = "cgroup", 00167 .to_type = RTNL_TC_TYPE_CLS, 00168 .to_size = sizeof(struct rtnl_cgroup), 00169 .to_clone = cgroup_clone, 00170 .to_msg_parser = cgroup_msg_parser, 00171 .to_free_data = cgroup_free_data, 00172 .to_msg_fill = cgroup_fill_msg, 00173 .to_dump = { 00174 [NL_DUMP_LINE] = cgroup_dump_line, 00175 [NL_DUMP_DETAILS] = cgroup_dump_details, 00176 }, 00177 }; 00178 00179 static void __init cgroup_init(void) 00180 { 00181 rtnl_tc_register(&cgroup_ops); 00182 } 00183 00184 static void __exit cgroup_exit(void) 00185 { 00186 rtnl_tc_unregister(&cgroup_ops); 00187 } 00188 00189 /** @} */