1 /* 2 * net/sched/police.c Input police filter. 3 * 4 * This program is free software; you can redistribute it and/or 5 * modify it under the terms of the GNU General Public License 6 * as published by the Free Software Foundation; either version 7 * 2 of the License, or (at your option) any later version. 8 * 9 * Authors: Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru> 10 * J Hadi Salim (action changes) 11 */ 12 13 #include <linux/module.h> 14 #include <linux/types.h> 15 #include <linux/kernel.h> 16 #include <linux/string.h> 17 #include <linux/errno.h> 18 #include <linux/skbuff.h> 19 #include <linux/rtnetlink.h> 20 #include <linux/init.h> 21 #include <linux/slab.h> 22 #include <net/act_api.h> 23 #include <net/netlink.h> 24 25 struct tcf_police { 26 struct tcf_common common; 27 int tcfp_result; 28 u32 tcfp_ewma_rate; 29 s64 tcfp_burst; 30 u32 tcfp_mtu; 31 s64 tcfp_toks; 32 s64 tcfp_ptoks; 33 s64 tcfp_mtu_ptoks; 34 s64 tcfp_t_c; 35 struct psched_ratecfg rate; 36 bool rate_present; 37 struct psched_ratecfg peak; 38 bool peak_present; 39 }; 40 #define to_police(pc) \ 41 container_of(pc, struct tcf_police, common) 42 43 #define POL_TAB_MASK 15 44 static struct tcf_hashinfo police_hash_info; 45 46 /* old policer structure from before tc actions */ 47 struct tc_police_compat { 48 u32 index; 49 int action; 50 u32 limit; 51 u32 burst; 52 u32 mtu; 53 struct tc_ratespec rate; 54 struct tc_ratespec peakrate; 55 }; 56 57 /* Each policer is serialized by its individual spinlock */ 58 59 static int tcf_act_police_walker(struct sk_buff *skb, struct netlink_callback *cb, 60 int type, struct tc_action *a) 61 { 62 struct tcf_hashinfo *hinfo = a->ops->hinfo; 63 struct hlist_head *head; 64 struct tcf_common *p; 65 int err = 0, index = -1, i = 0, s_i = 0, n_i = 0; 66 struct nlattr *nest; 67 68 spin_lock_bh(&hinfo->lock); 69 70 s_i = cb->args[0]; 71 72 for (i = 0; i < (POL_TAB_MASK + 1); i++) { 73 head = &hinfo->htab[tcf_hash(i, POL_TAB_MASK)]; 74 75 hlist_for_each_entry_rcu(p, head, tcfc_head) { 76 index++; 77 if (index < s_i) 78 continue; 79 a->priv = p; 80 a->order = index; 81 nest = nla_nest_start(skb, a->order); 82 if (nest == NULL) 83 goto nla_put_failure; 84 if (type == RTM_DELACTION) 85 err = tcf_action_dump_1(skb, a, 0, 1); 86 else 87 err = tcf_action_dump_1(skb, a, 0, 0); 88 if (err < 0) { 89 index--; 90 nla_nest_cancel(skb, nest); 91 goto done; 92 } 93 nla_nest_end(skb, nest); 94 n_i++; 95 } 96 } 97 done: 98 spin_unlock_bh(&hinfo->lock); 99 if (n_i) 100 cb->args[0] += n_i; 101 return n_i; 102 103 nla_put_failure: 104 nla_nest_cancel(skb, nest); 105 goto done; 106 } 107 108 static const struct nla_policy police_policy[TCA_POLICE_MAX + 1] = { 109 [TCA_POLICE_RATE] = { .len = TC_RTAB_SIZE }, 110 [TCA_POLICE_PEAKRATE] = { .len = TC_RTAB_SIZE }, 111 [TCA_POLICE_AVRATE] = { .type = NLA_U32 }, 112 [TCA_POLICE_RESULT] = { .type = NLA_U32 }, 113 }; 114 115 static int tcf_act_police_locate(struct net *net, struct nlattr *nla, 116 struct nlattr *est, struct tc_action *a, 117 int ovr, int bind) 118 { 119 unsigned int h; 120 int ret = 0, err; 121 struct nlattr *tb[TCA_POLICE_MAX + 1]; 122 struct tc_police *parm; 123 struct tcf_police *police; 124 struct qdisc_rate_table *R_tab = NULL, *P_tab = NULL; 125 struct tcf_hashinfo *hinfo = a->ops->hinfo; 126 int size; 127 128 if (nla == NULL) 129 return -EINVAL; 130 131 err = nla_parse_nested(tb, TCA_POLICE_MAX, nla, police_policy); 132 if (err < 0) 133 return err; 134 135 if (tb[TCA_POLICE_TBF] == NULL) 136 return -EINVAL; 137 size = nla_len(tb[TCA_POLICE_TBF]); 138 if (size != sizeof(*parm) && size != sizeof(struct tc_police_compat)) 139 return -EINVAL; 140 parm = nla_data(tb[TCA_POLICE_TBF]); 141 142 if (parm->index) { 143 if (tcf_hash_search(a, parm->index)) { 144 police = to_police(a->priv); 145 if (bind) { 146 police->tcf_bindcnt += 1; 147 police->tcf_refcnt += 1; 148 return 0; 149 } 150 if (ovr) 151 goto override; 152 /* not replacing */ 153 return -EEXIST; 154 } 155 } 156 157 police = kzalloc(sizeof(*police), GFP_KERNEL); 158 if (police == NULL) 159 return -ENOMEM; 160 ret = ACT_P_CREATED; 161 police->tcf_refcnt = 1; 162 spin_lock_init(&police->tcf_lock); 163 if (bind) 164 police->tcf_bindcnt = 1; 165 override: 166 if (parm->rate.rate) { 167 err = -ENOMEM; 168 R_tab = qdisc_get_rtab(&parm->rate, tb[TCA_POLICE_RATE]); 169 if (R_tab == NULL) 170 goto failure; 171 172 if (parm->peakrate.rate) { 173 P_tab = qdisc_get_rtab(&parm->peakrate, 174 tb[TCA_POLICE_PEAKRATE]); 175 if (P_tab == NULL) 176 goto failure; 177 } 178 } 179 180 spin_lock_bh(&police->tcf_lock); 181 if (est) { 182 err = gen_replace_estimator(&police->tcf_bstats, 183 &police->tcf_rate_est, 184 &police->tcf_lock, est); 185 if (err) 186 goto failure_unlock; 187 } else if (tb[TCA_POLICE_AVRATE] && 188 (ret == ACT_P_CREATED || 189 !gen_estimator_active(&police->tcf_bstats, 190 &police->tcf_rate_est))) { 191 err = -EINVAL; 192 goto failure_unlock; 193 } 194 195 /* No failure allowed after this point */ 196 police->tcfp_mtu = parm->mtu; 197 if (police->tcfp_mtu == 0) { 198 police->tcfp_mtu = ~0; 199 if (R_tab) 200 police->tcfp_mtu = 255 << R_tab->rate.cell_log; 201 } 202 if (R_tab) { 203 police->rate_present = true; 204 psched_ratecfg_precompute(&police->rate, &R_tab->rate, 0); 205 qdisc_put_rtab(R_tab); 206 } else { 207 police->rate_present = false; 208 } 209 if (P_tab) { 210 police->peak_present = true; 211 psched_ratecfg_precompute(&police->peak, &P_tab->rate, 0); 212 qdisc_put_rtab(P_tab); 213 } else { 214 police->peak_present = false; 215 } 216 217 if (tb[TCA_POLICE_RESULT]) 218 police->tcfp_result = nla_get_u32(tb[TCA_POLICE_RESULT]); 219 police->tcfp_burst = PSCHED_TICKS2NS(parm->burst); 220 police->tcfp_toks = police->tcfp_burst; 221 if (police->peak_present) { 222 police->tcfp_mtu_ptoks = (s64) psched_l2t_ns(&police->peak, 223 police->tcfp_mtu); 224 police->tcfp_ptoks = police->tcfp_mtu_ptoks; 225 } 226 police->tcf_action = parm->action; 227 228 if (tb[TCA_POLICE_AVRATE]) 229 police->tcfp_ewma_rate = nla_get_u32(tb[TCA_POLICE_AVRATE]); 230 231 spin_unlock_bh(&police->tcf_lock); 232 if (ret != ACT_P_CREATED) 233 return ret; 234 235 police->tcfp_t_c = ktime_to_ns(ktime_get()); 236 police->tcf_index = parm->index ? parm->index : 237 tcf_hash_new_index(a->ops->hinfo); 238 h = tcf_hash(police->tcf_index, POL_TAB_MASK); 239 spin_lock_bh(&hinfo->lock); 240 hlist_add_head(&police->tcf_head, &hinfo->htab[h]); 241 spin_unlock_bh(&hinfo->lock); 242 243 a->priv = police; 244 return ret; 245 246 failure_unlock: 247 spin_unlock_bh(&police->tcf_lock); 248 failure: 249 qdisc_put_rtab(P_tab); 250 qdisc_put_rtab(R_tab); 251 if (ret == ACT_P_CREATED) 252 kfree(police); 253 return err; 254 } 255 256 static int tcf_act_police_cleanup(struct tc_action *a, int bind) 257 { 258 struct tcf_police *p = a->priv; 259 if (p) 260 return tcf_hash_release(&p->common, bind, &police_hash_info); 261 return 0; 262 } 263 264 static int tcf_act_police(struct sk_buff *skb, const struct tc_action *a, 265 struct tcf_result *res) 266 { 267 struct tcf_police *police = a->priv; 268 s64 now; 269 s64 toks; 270 s64 ptoks = 0; 271 272 spin_lock(&police->tcf_lock); 273 274 bstats_update(&police->tcf_bstats, skb); 275 276 if (police->tcfp_ewma_rate && 277 police->tcf_rate_est.bps >= police->tcfp_ewma_rate) { 278 police->tcf_qstats.overlimits++; 279 if (police->tcf_action == TC_ACT_SHOT) 280 police->tcf_qstats.drops++; 281 spin_unlock(&police->tcf_lock); 282 return police->tcf_action; 283 } 284 285 if (qdisc_pkt_len(skb) <= police->tcfp_mtu) { 286 if (!police->rate_present) { 287 spin_unlock(&police->tcf_lock); 288 return police->tcfp_result; 289 } 290 291 now = ktime_to_ns(ktime_get()); 292 toks = min_t(s64, now - police->tcfp_t_c, 293 police->tcfp_burst); 294 if (police->peak_present) { 295 ptoks = toks + police->tcfp_ptoks; 296 if (ptoks > police->tcfp_mtu_ptoks) 297 ptoks = police->tcfp_mtu_ptoks; 298 ptoks -= (s64) psched_l2t_ns(&police->peak, 299 qdisc_pkt_len(skb)); 300 } 301 toks += police->tcfp_toks; 302 if (toks > police->tcfp_burst) 303 toks = police->tcfp_burst; 304 toks -= (s64) psched_l2t_ns(&police->rate, qdisc_pkt_len(skb)); 305 if ((toks|ptoks) >= 0) { 306 police->tcfp_t_c = now; 307 police->tcfp_toks = toks; 308 police->tcfp_ptoks = ptoks; 309 spin_unlock(&police->tcf_lock); 310 return police->tcfp_result; 311 } 312 } 313 314 police->tcf_qstats.overlimits++; 315 if (police->tcf_action == TC_ACT_SHOT) 316 police->tcf_qstats.drops++; 317 spin_unlock(&police->tcf_lock); 318 return police->tcf_action; 319 } 320 321 static int 322 tcf_act_police_dump(struct sk_buff *skb, struct tc_action *a, int bind, int ref) 323 { 324 unsigned char *b = skb_tail_pointer(skb); 325 struct tcf_police *police = a->priv; 326 struct tc_police opt = { 327 .index = police->tcf_index, 328 .action = police->tcf_action, 329 .mtu = police->tcfp_mtu, 330 .burst = PSCHED_NS2TICKS(police->tcfp_burst), 331 .refcnt = police->tcf_refcnt - ref, 332 .bindcnt = police->tcf_bindcnt - bind, 333 }; 334 335 if (police->rate_present) 336 psched_ratecfg_getrate(&opt.rate, &police->rate); 337 if (police->peak_present) 338 psched_ratecfg_getrate(&opt.peakrate, &police->peak); 339 if (nla_put(skb, TCA_POLICE_TBF, sizeof(opt), &opt)) 340 goto nla_put_failure; 341 if (police->tcfp_result && 342 nla_put_u32(skb, TCA_POLICE_RESULT, police->tcfp_result)) 343 goto nla_put_failure; 344 if (police->tcfp_ewma_rate && 345 nla_put_u32(skb, TCA_POLICE_AVRATE, police->tcfp_ewma_rate)) 346 goto nla_put_failure; 347 return skb->len; 348 349 nla_put_failure: 350 nlmsg_trim(skb, b); 351 return -1; 352 } 353 354 MODULE_AUTHOR("Alexey Kuznetsov"); 355 MODULE_DESCRIPTION("Policing actions"); 356 MODULE_LICENSE("GPL"); 357 358 static struct tc_action_ops act_police_ops = { 359 .kind = "police", 360 .hinfo = &police_hash_info, 361 .type = TCA_ID_POLICE, 362 .owner = THIS_MODULE, 363 .act = tcf_act_police, 364 .dump = tcf_act_police_dump, 365 .cleanup = tcf_act_police_cleanup, 366 .init = tcf_act_police_locate, 367 .walk = tcf_act_police_walker 368 }; 369 370 static int __init 371 police_init_module(void) 372 { 373 int err = tcf_hashinfo_init(&police_hash_info, POL_TAB_MASK); 374 if (err) 375 return err; 376 err = tcf_register_action(&act_police_ops); 377 if (err) 378 tcf_hashinfo_destroy(&police_hash_info); 379 return err; 380 } 381 382 static void __exit 383 police_cleanup_module(void) 384 { 385 tcf_hashinfo_destroy(&police_hash_info); 386 tcf_unregister_action(&act_police_ops); 387 } 388 389 module_init(police_init_module); 390 module_exit(police_cleanup_module); 391