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-2013 Thomas Graf <tgraf (at) suug.ch> 10 */ 11 12 /** 13 * @ingroup cls 14 * @defgroup cls_cgroup Control Groups Classifier 15 * 16 * @{ 17 */ 18 19 #include <netlink-private/netlink.h> 20 #include <netlink-private/tc.h> 21 #include <netlink/netlink.h> 22 #include <netlink/attr.h> 23 #include <netlink/utils.h> 24 #include <netlink-private/route/tc-api.h> 25 #include <netlink/route/classifier.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 int cgroup_clone(void *dst, void *src) 38 { 39 return -NLE_OPNOTSUPP; 40 } 41 42 static void cgroup_free_data(struct rtnl_tc *tc, void *data) 43 { 44 struct rtnl_cgroup *c = data; 45 46 if (!c) 47 return; 48 49 rtnl_ematch_tree_free(c->cg_ematch); 50 } 51 52 static int cgroup_msg_parser(struct rtnl_tc *tc, void *data) 53 { 54 struct nlattr *tb[TCA_CGROUP_MAX + 1]; 55 struct rtnl_cgroup *c = data; 56 int err; 57 58 err = tca_parse(tb, TCA_CGROUP_MAX, tc, cgroup_policy); 59 if (err < 0) 60 return err; 61 62 if (tb[TCA_CGROUP_EMATCHES]) { 63 if ((err = rtnl_ematch_parse_attr(tb[TCA_CGROUP_EMATCHES], 64 &c->cg_ematch)) < 0) 65 return err; 66 c->cg_mask |= CGROUP_ATTR_EMATCH; 67 } 68 69 #if 0 70 TODO: 71 TCA_CGROUP_ACT, 72 TCA_CGROUP_POLICE, 73 #endif 74 75 return 0; 76 } 77 78 static void cgroup_dump_line(struct rtnl_tc *tc, void *data, 79 struct nl_dump_params *p) 80 { 81 struct rtnl_cgroup *c = data; 82 83 if (!c) 84 return; 85 86 if (c->cg_mask & CGROUP_ATTR_EMATCH) 87 nl_dump(p, " ematch"); 88 else 89 nl_dump(p, " match-all"); 90 } 91 92 static void cgroup_dump_details(struct rtnl_tc *tc, void *data, 93 struct nl_dump_params *p) 94 { 95 struct rtnl_cgroup *c = data; 96 97 if (!c) 98 return; 99 100 if (c->cg_mask & CGROUP_ATTR_EMATCH) { 101 nl_dump_line(p, " ematch "); 102 103 if (c->cg_ematch) 104 rtnl_ematch_tree_dump(c->cg_ematch, p); 105 else 106 nl_dump(p, "<no tree>"); 107 } else 108 nl_dump(p, "no options"); 109 } 110 111 static int cgroup_fill_msg(struct rtnl_tc *tc, void *data, 112 struct nl_msg *msg) 113 { 114 struct rtnl_cgroup *c = data; 115 116 if (!c) 117 BUG(); 118 119 if (!(tc->ce_mask & TCA_ATTR_HANDLE)) 120 return -NLE_MISSING_ATTR; 121 122 if (c->cg_mask & CGROUP_ATTR_EMATCH) 123 return rtnl_ematch_fill_attr(msg, TCA_CGROUP_EMATCHES, 124 c->cg_ematch); 125 126 return 0; 127 } 128 129 130 /** 131 * @name Attribute Modifications 132 * @{ 133 */ 134 135 void rtnl_cgroup_set_ematch(struct rtnl_cls *cls, struct rtnl_ematch_tree *tree) 136 { 137 struct rtnl_cgroup *c; 138 139 if (!(c = rtnl_tc_data(TC_CAST(cls)))) 140 BUG(); 141 142 if (c->cg_ematch) { 143 rtnl_ematch_tree_free(c->cg_ematch); 144 c->cg_mask &= ~CGROUP_ATTR_EMATCH; 145 } 146 147 c->cg_ematch = tree; 148 149 if (tree) 150 c->cg_mask |= CGROUP_ATTR_EMATCH; 151 } 152 153 struct rtnl_ematch_tree *rtnl_cgroup_get_ematch(struct rtnl_cls *cls) 154 { 155 struct rtnl_cgroup *c; 156 157 if (!(c = rtnl_tc_data(TC_CAST(cls)))) 158 BUG(); 159 160 return c->cg_ematch; 161 } 162 163 /** @} */ 164 165 static struct rtnl_tc_ops cgroup_ops = { 166 .to_kind = "cgroup", 167 .to_type = RTNL_TC_TYPE_CLS, 168 .to_size = sizeof(struct rtnl_cgroup), 169 .to_clone = cgroup_clone, 170 .to_msg_parser = cgroup_msg_parser, 171 .to_free_data = cgroup_free_data, 172 .to_msg_fill = cgroup_fill_msg, 173 .to_dump = { 174 [NL_DUMP_LINE] = cgroup_dump_line, 175 [NL_DUMP_DETAILS] = cgroup_dump_details, 176 }, 177 }; 178 179 static void __init cgroup_init(void) 180 { 181 rtnl_tc_register(&cgroup_ops); 182 } 183 184 static void __exit cgroup_exit(void) 185 { 186 rtnl_tc_unregister(&cgroup_ops); 187 } 188 189 /** @} */ 190