00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
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
00030 #define CGROUP_ATTR_EMATCH 0x001
00031
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
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