meter.c 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. /*
  3. * Copyright (c) 2017 Nicira, Inc.
  4. */
  5. #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
  6. #include <linux/if.h>
  7. #include <linux/skbuff.h>
  8. #include <linux/ip.h>
  9. #include <linux/kernel.h>
  10. #include <linux/openvswitch.h>
  11. #include <linux/netlink.h>
  12. #include <linux/rculist.h>
  13. #include <net/netlink.h>
  14. #include <net/genetlink.h>
  15. #include "datapath.h"
  16. #include "meter.h"
  17. static const struct nla_policy meter_policy[OVS_METER_ATTR_MAX + 1] = {
  18. [OVS_METER_ATTR_ID] = { .type = NLA_U32, },
  19. [OVS_METER_ATTR_KBPS] = { .type = NLA_FLAG },
  20. [OVS_METER_ATTR_STATS] = { .len = sizeof(struct ovs_flow_stats) },
  21. [OVS_METER_ATTR_BANDS] = { .type = NLA_NESTED },
  22. [OVS_METER_ATTR_USED] = { .type = NLA_U64 },
  23. [OVS_METER_ATTR_CLEAR] = { .type = NLA_FLAG },
  24. [OVS_METER_ATTR_MAX_METERS] = { .type = NLA_U32 },
  25. [OVS_METER_ATTR_MAX_BANDS] = { .type = NLA_U32 },
  26. };
  27. static const struct nla_policy band_policy[OVS_BAND_ATTR_MAX + 1] = {
  28. [OVS_BAND_ATTR_TYPE] = { .type = NLA_U32, },
  29. [OVS_BAND_ATTR_RATE] = { .type = NLA_U32, },
  30. [OVS_BAND_ATTR_BURST] = { .type = NLA_U32, },
  31. [OVS_BAND_ATTR_STATS] = { .len = sizeof(struct ovs_flow_stats) },
  32. };
  33. static u32 meter_hash(struct dp_meter_instance *ti, u32 id)
  34. {
  35. return id % ti->n_meters;
  36. }
  37. static void ovs_meter_free(struct dp_meter *meter)
  38. {
  39. if (!meter)
  40. return;
  41. kfree_rcu(meter, rcu);
  42. }
  43. /* Call with ovs_mutex or RCU read lock. */
  44. static struct dp_meter *lookup_meter(const struct dp_meter_table *tbl,
  45. u32 meter_id)
  46. {
  47. struct dp_meter_instance *ti = rcu_dereference_ovsl(tbl->ti);
  48. u32 hash = meter_hash(ti, meter_id);
  49. struct dp_meter *meter;
  50. meter = rcu_dereference_ovsl(ti->dp_meters[hash]);
  51. if (meter && likely(meter->id == meter_id))
  52. return meter;
  53. return NULL;
  54. }
  55. static struct dp_meter_instance *dp_meter_instance_alloc(const u32 size)
  56. {
  57. struct dp_meter_instance *ti;
  58. ti = kvzalloc(sizeof(*ti) +
  59. sizeof(struct dp_meter *) * size,
  60. GFP_KERNEL);
  61. if (!ti)
  62. return NULL;
  63. ti->n_meters = size;
  64. return ti;
  65. }
  66. static void dp_meter_instance_free(struct dp_meter_instance *ti)
  67. {
  68. kvfree(ti);
  69. }
  70. static void dp_meter_instance_free_rcu(struct rcu_head *rcu)
  71. {
  72. struct dp_meter_instance *ti;
  73. ti = container_of(rcu, struct dp_meter_instance, rcu);
  74. kvfree(ti);
  75. }
  76. static int
  77. dp_meter_instance_realloc(struct dp_meter_table *tbl, u32 size)
  78. {
  79. struct dp_meter_instance *ti = rcu_dereference_ovsl(tbl->ti);
  80. int n_meters = min(size, ti->n_meters);
  81. struct dp_meter_instance *new_ti;
  82. int i;
  83. new_ti = dp_meter_instance_alloc(size);
  84. if (!new_ti)
  85. return -ENOMEM;
  86. for (i = 0; i < n_meters; i++)
  87. if (rcu_dereference_ovsl(ti->dp_meters[i]))
  88. new_ti->dp_meters[i] = ti->dp_meters[i];
  89. rcu_assign_pointer(tbl->ti, new_ti);
  90. call_rcu(&ti->rcu, dp_meter_instance_free_rcu);
  91. return 0;
  92. }
  93. static void dp_meter_instance_insert(struct dp_meter_instance *ti,
  94. struct dp_meter *meter)
  95. {
  96. u32 hash;
  97. hash = meter_hash(ti, meter->id);
  98. rcu_assign_pointer(ti->dp_meters[hash], meter);
  99. }
  100. static void dp_meter_instance_remove(struct dp_meter_instance *ti,
  101. struct dp_meter *meter)
  102. {
  103. u32 hash;
  104. hash = meter_hash(ti, meter->id);
  105. RCU_INIT_POINTER(ti->dp_meters[hash], NULL);
  106. }
  107. static int attach_meter(struct dp_meter_table *tbl, struct dp_meter *meter)
  108. {
  109. struct dp_meter_instance *ti = rcu_dereference_ovsl(tbl->ti);
  110. u32 hash = meter_hash(ti, meter->id);
  111. int err;
  112. /* In generally, slots selected should be empty, because
  113. * OvS uses id-pool to fetch a available id.
  114. */
  115. if (unlikely(rcu_dereference_ovsl(ti->dp_meters[hash])))
  116. return -EBUSY;
  117. dp_meter_instance_insert(ti, meter);
  118. /* That function is thread-safe. */
  119. tbl->count++;
  120. if (tbl->count >= tbl->max_meters_allowed) {
  121. err = -EFBIG;
  122. goto attach_err;
  123. }
  124. if (tbl->count >= ti->n_meters &&
  125. dp_meter_instance_realloc(tbl, ti->n_meters * 2)) {
  126. err = -ENOMEM;
  127. goto attach_err;
  128. }
  129. return 0;
  130. attach_err:
  131. dp_meter_instance_remove(ti, meter);
  132. tbl->count--;
  133. return err;
  134. }
  135. static int detach_meter(struct dp_meter_table *tbl, struct dp_meter *meter)
  136. {
  137. struct dp_meter_instance *ti;
  138. ASSERT_OVSL();
  139. if (!meter)
  140. return 0;
  141. ti = rcu_dereference_ovsl(tbl->ti);
  142. dp_meter_instance_remove(ti, meter);
  143. tbl->count--;
  144. /* Shrink the meter array if necessary. */
  145. if (ti->n_meters > DP_METER_ARRAY_SIZE_MIN &&
  146. tbl->count <= (ti->n_meters / 4)) {
  147. int half_size = ti->n_meters / 2;
  148. int i;
  149. /* Avoid hash collision, don't move slots to other place.
  150. * Make sure there are no references of meters in array
  151. * which will be released.
  152. */
  153. for (i = half_size; i < ti->n_meters; i++)
  154. if (rcu_dereference_ovsl(ti->dp_meters[i]))
  155. goto out;
  156. if (dp_meter_instance_realloc(tbl, half_size))
  157. goto shrink_err;
  158. }
  159. out:
  160. return 0;
  161. shrink_err:
  162. dp_meter_instance_insert(ti, meter);
  163. tbl->count++;
  164. return -ENOMEM;
  165. }
  166. static struct sk_buff *
  167. ovs_meter_cmd_reply_start(struct genl_info *info, u8 cmd,
  168. struct ovs_header **ovs_reply_header)
  169. {
  170. struct sk_buff *skb;
  171. struct ovs_header *ovs_header = info->userhdr;
  172. skb = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_ATOMIC);
  173. if (!skb)
  174. return ERR_PTR(-ENOMEM);
  175. *ovs_reply_header = genlmsg_put(skb, info->snd_portid,
  176. info->snd_seq,
  177. &dp_meter_genl_family, 0, cmd);
  178. if (!*ovs_reply_header) {
  179. nlmsg_free(skb);
  180. return ERR_PTR(-EMSGSIZE);
  181. }
  182. (*ovs_reply_header)->dp_ifindex = ovs_header->dp_ifindex;
  183. return skb;
  184. }
  185. static int ovs_meter_cmd_reply_stats(struct sk_buff *reply, u32 meter_id,
  186. struct dp_meter *meter)
  187. {
  188. struct nlattr *nla;
  189. struct dp_meter_band *band;
  190. u16 i;
  191. if (nla_put_u32(reply, OVS_METER_ATTR_ID, meter_id))
  192. goto error;
  193. if (nla_put(reply, OVS_METER_ATTR_STATS,
  194. sizeof(struct ovs_flow_stats), &meter->stats))
  195. goto error;
  196. if (nla_put_u64_64bit(reply, OVS_METER_ATTR_USED, meter->used,
  197. OVS_METER_ATTR_PAD))
  198. goto error;
  199. nla = nla_nest_start_noflag(reply, OVS_METER_ATTR_BANDS);
  200. if (!nla)
  201. goto error;
  202. band = meter->bands;
  203. for (i = 0; i < meter->n_bands; ++i, ++band) {
  204. struct nlattr *band_nla;
  205. band_nla = nla_nest_start_noflag(reply, OVS_BAND_ATTR_UNSPEC);
  206. if (!band_nla || nla_put(reply, OVS_BAND_ATTR_STATS,
  207. sizeof(struct ovs_flow_stats),
  208. &band->stats))
  209. goto error;
  210. nla_nest_end(reply, band_nla);
  211. }
  212. nla_nest_end(reply, nla);
  213. return 0;
  214. error:
  215. return -EMSGSIZE;
  216. }
  217. static int ovs_meter_cmd_features(struct sk_buff *skb, struct genl_info *info)
  218. {
  219. struct ovs_header *ovs_header = info->userhdr;
  220. struct ovs_header *ovs_reply_header;
  221. struct nlattr *nla, *band_nla;
  222. struct sk_buff *reply;
  223. struct datapath *dp;
  224. int err = -EMSGSIZE;
  225. reply = ovs_meter_cmd_reply_start(info, OVS_METER_CMD_FEATURES,
  226. &ovs_reply_header);
  227. if (IS_ERR(reply))
  228. return PTR_ERR(reply);
  229. ovs_lock();
  230. dp = get_dp(sock_net(skb->sk), ovs_header->dp_ifindex);
  231. if (!dp) {
  232. err = -ENODEV;
  233. goto exit_unlock;
  234. }
  235. if (nla_put_u32(reply, OVS_METER_ATTR_MAX_METERS,
  236. dp->meter_tbl.max_meters_allowed))
  237. goto exit_unlock;
  238. ovs_unlock();
  239. if (nla_put_u32(reply, OVS_METER_ATTR_MAX_BANDS, DP_MAX_BANDS))
  240. goto nla_put_failure;
  241. nla = nla_nest_start_noflag(reply, OVS_METER_ATTR_BANDS);
  242. if (!nla)
  243. goto nla_put_failure;
  244. band_nla = nla_nest_start_noflag(reply, OVS_BAND_ATTR_UNSPEC);
  245. if (!band_nla)
  246. goto nla_put_failure;
  247. /* Currently only DROP band type is supported. */
  248. if (nla_put_u32(reply, OVS_BAND_ATTR_TYPE, OVS_METER_BAND_TYPE_DROP))
  249. goto nla_put_failure;
  250. nla_nest_end(reply, band_nla);
  251. nla_nest_end(reply, nla);
  252. genlmsg_end(reply, ovs_reply_header);
  253. return genlmsg_reply(reply, info);
  254. exit_unlock:
  255. ovs_unlock();
  256. nla_put_failure:
  257. nlmsg_free(reply);
  258. return err;
  259. }
  260. static struct dp_meter *dp_meter_create(struct nlattr **a)
  261. {
  262. struct nlattr *nla;
  263. int rem;
  264. u16 n_bands = 0;
  265. struct dp_meter *meter;
  266. struct dp_meter_band *band;
  267. int err;
  268. /* Validate attributes, count the bands. */
  269. if (!a[OVS_METER_ATTR_BANDS])
  270. return ERR_PTR(-EINVAL);
  271. nla_for_each_nested(nla, a[OVS_METER_ATTR_BANDS], rem)
  272. if (++n_bands > DP_MAX_BANDS)
  273. return ERR_PTR(-EINVAL);
  274. /* Allocate and set up the meter before locking anything. */
  275. meter = kzalloc(struct_size(meter, bands, n_bands), GFP_KERNEL_ACCOUNT);
  276. if (!meter)
  277. return ERR_PTR(-ENOMEM);
  278. meter->id = nla_get_u32(a[OVS_METER_ATTR_ID]);
  279. meter->used = div_u64(ktime_get_ns(), 1000 * 1000);
  280. meter->kbps = a[OVS_METER_ATTR_KBPS] ? 1 : 0;
  281. meter->keep_stats = !a[OVS_METER_ATTR_CLEAR];
  282. spin_lock_init(&meter->lock);
  283. if (meter->keep_stats && a[OVS_METER_ATTR_STATS]) {
  284. meter->stats = *(struct ovs_flow_stats *)
  285. nla_data(a[OVS_METER_ATTR_STATS]);
  286. }
  287. meter->n_bands = n_bands;
  288. /* Set up meter bands. */
  289. band = meter->bands;
  290. nla_for_each_nested(nla, a[OVS_METER_ATTR_BANDS], rem) {
  291. struct nlattr *attr[OVS_BAND_ATTR_MAX + 1];
  292. u32 band_max_delta_t;
  293. err = nla_parse_deprecated((struct nlattr **)&attr,
  294. OVS_BAND_ATTR_MAX, nla_data(nla),
  295. nla_len(nla), band_policy, NULL);
  296. if (err)
  297. goto exit_free_meter;
  298. if (!attr[OVS_BAND_ATTR_TYPE] ||
  299. !attr[OVS_BAND_ATTR_RATE] ||
  300. !attr[OVS_BAND_ATTR_BURST]) {
  301. err = -EINVAL;
  302. goto exit_free_meter;
  303. }
  304. band->type = nla_get_u32(attr[OVS_BAND_ATTR_TYPE]);
  305. band->rate = nla_get_u32(attr[OVS_BAND_ATTR_RATE]);
  306. if (band->rate == 0) {
  307. err = -EINVAL;
  308. goto exit_free_meter;
  309. }
  310. band->burst_size = nla_get_u32(attr[OVS_BAND_ATTR_BURST]);
  311. /* Figure out max delta_t that is enough to fill any bucket.
  312. * Keep max_delta_t size to the bucket units:
  313. * pkts => 1/1000 packets, kilobits => bits.
  314. *
  315. * Start with a full bucket.
  316. */
  317. band->bucket = band->burst_size * 1000ULL;
  318. band_max_delta_t = div_u64(band->bucket, band->rate);
  319. if (band_max_delta_t > meter->max_delta_t)
  320. meter->max_delta_t = band_max_delta_t;
  321. band++;
  322. }
  323. return meter;
  324. exit_free_meter:
  325. kfree(meter);
  326. return ERR_PTR(err);
  327. }
  328. static int ovs_meter_cmd_set(struct sk_buff *skb, struct genl_info *info)
  329. {
  330. struct nlattr **a = info->attrs;
  331. struct dp_meter *meter, *old_meter;
  332. struct sk_buff *reply;
  333. struct ovs_header *ovs_reply_header;
  334. struct ovs_header *ovs_header = info->userhdr;
  335. struct dp_meter_table *meter_tbl;
  336. struct datapath *dp;
  337. int err;
  338. u32 meter_id;
  339. bool failed;
  340. if (!a[OVS_METER_ATTR_ID])
  341. return -EINVAL;
  342. meter = dp_meter_create(a);
  343. if (IS_ERR(meter))
  344. return PTR_ERR(meter);
  345. reply = ovs_meter_cmd_reply_start(info, OVS_METER_CMD_SET,
  346. &ovs_reply_header);
  347. if (IS_ERR(reply)) {
  348. err = PTR_ERR(reply);
  349. goto exit_free_meter;
  350. }
  351. ovs_lock();
  352. dp = get_dp(sock_net(skb->sk), ovs_header->dp_ifindex);
  353. if (!dp) {
  354. err = -ENODEV;
  355. goto exit_unlock;
  356. }
  357. meter_tbl = &dp->meter_tbl;
  358. meter_id = nla_get_u32(a[OVS_METER_ATTR_ID]);
  359. old_meter = lookup_meter(meter_tbl, meter_id);
  360. err = detach_meter(meter_tbl, old_meter);
  361. if (err)
  362. goto exit_unlock;
  363. err = attach_meter(meter_tbl, meter);
  364. if (err)
  365. goto exit_free_old_meter;
  366. ovs_unlock();
  367. /* Build response with the meter_id and stats from
  368. * the old meter, if any.
  369. */
  370. failed = nla_put_u32(reply, OVS_METER_ATTR_ID, meter_id);
  371. WARN_ON(failed);
  372. if (old_meter) {
  373. spin_lock_bh(&old_meter->lock);
  374. if (old_meter->keep_stats) {
  375. err = ovs_meter_cmd_reply_stats(reply, meter_id,
  376. old_meter);
  377. WARN_ON(err);
  378. }
  379. spin_unlock_bh(&old_meter->lock);
  380. ovs_meter_free(old_meter);
  381. }
  382. genlmsg_end(reply, ovs_reply_header);
  383. return genlmsg_reply(reply, info);
  384. exit_free_old_meter:
  385. ovs_meter_free(old_meter);
  386. exit_unlock:
  387. ovs_unlock();
  388. nlmsg_free(reply);
  389. exit_free_meter:
  390. kfree(meter);
  391. return err;
  392. }
  393. static int ovs_meter_cmd_get(struct sk_buff *skb, struct genl_info *info)
  394. {
  395. struct ovs_header *ovs_header = info->userhdr;
  396. struct ovs_header *ovs_reply_header;
  397. struct nlattr **a = info->attrs;
  398. struct dp_meter *meter;
  399. struct sk_buff *reply;
  400. struct datapath *dp;
  401. u32 meter_id;
  402. int err;
  403. if (!a[OVS_METER_ATTR_ID])
  404. return -EINVAL;
  405. meter_id = nla_get_u32(a[OVS_METER_ATTR_ID]);
  406. reply = ovs_meter_cmd_reply_start(info, OVS_METER_CMD_GET,
  407. &ovs_reply_header);
  408. if (IS_ERR(reply))
  409. return PTR_ERR(reply);
  410. ovs_lock();
  411. dp = get_dp(sock_net(skb->sk), ovs_header->dp_ifindex);
  412. if (!dp) {
  413. err = -ENODEV;
  414. goto exit_unlock;
  415. }
  416. /* Locate meter, copy stats. */
  417. meter = lookup_meter(&dp->meter_tbl, meter_id);
  418. if (!meter) {
  419. err = -ENOENT;
  420. goto exit_unlock;
  421. }
  422. spin_lock_bh(&meter->lock);
  423. err = ovs_meter_cmd_reply_stats(reply, meter_id, meter);
  424. spin_unlock_bh(&meter->lock);
  425. if (err)
  426. goto exit_unlock;
  427. ovs_unlock();
  428. genlmsg_end(reply, ovs_reply_header);
  429. return genlmsg_reply(reply, info);
  430. exit_unlock:
  431. ovs_unlock();
  432. nlmsg_free(reply);
  433. return err;
  434. }
  435. static int ovs_meter_cmd_del(struct sk_buff *skb, struct genl_info *info)
  436. {
  437. struct ovs_header *ovs_header = info->userhdr;
  438. struct ovs_header *ovs_reply_header;
  439. struct nlattr **a = info->attrs;
  440. struct dp_meter *old_meter;
  441. struct sk_buff *reply;
  442. struct datapath *dp;
  443. u32 meter_id;
  444. int err;
  445. if (!a[OVS_METER_ATTR_ID])
  446. return -EINVAL;
  447. reply = ovs_meter_cmd_reply_start(info, OVS_METER_CMD_DEL,
  448. &ovs_reply_header);
  449. if (IS_ERR(reply))
  450. return PTR_ERR(reply);
  451. ovs_lock();
  452. dp = get_dp(sock_net(skb->sk), ovs_header->dp_ifindex);
  453. if (!dp) {
  454. err = -ENODEV;
  455. goto exit_unlock;
  456. }
  457. meter_id = nla_get_u32(a[OVS_METER_ATTR_ID]);
  458. old_meter = lookup_meter(&dp->meter_tbl, meter_id);
  459. if (old_meter) {
  460. spin_lock_bh(&old_meter->lock);
  461. err = ovs_meter_cmd_reply_stats(reply, meter_id, old_meter);
  462. WARN_ON(err);
  463. spin_unlock_bh(&old_meter->lock);
  464. err = detach_meter(&dp->meter_tbl, old_meter);
  465. if (err)
  466. goto exit_unlock;
  467. }
  468. ovs_unlock();
  469. ovs_meter_free(old_meter);
  470. genlmsg_end(reply, ovs_reply_header);
  471. return genlmsg_reply(reply, info);
  472. exit_unlock:
  473. ovs_unlock();
  474. nlmsg_free(reply);
  475. return err;
  476. }
  477. /* Meter action execution.
  478. *
  479. * Return true 'meter_id' drop band is triggered. The 'skb' should be
  480. * dropped by the caller'.
  481. */
  482. bool ovs_meter_execute(struct datapath *dp, struct sk_buff *skb,
  483. struct sw_flow_key *key, u32 meter_id)
  484. {
  485. long long int now_ms = div_u64(ktime_get_ns(), 1000 * 1000);
  486. long long int long_delta_ms;
  487. struct dp_meter_band *band;
  488. struct dp_meter *meter;
  489. int i, band_exceeded_max = -1;
  490. u32 band_exceeded_rate = 0;
  491. u32 delta_ms;
  492. u32 cost;
  493. meter = lookup_meter(&dp->meter_tbl, meter_id);
  494. /* Do not drop the packet when there is no meter. */
  495. if (!meter)
  496. return false;
  497. /* Lock the meter while using it. */
  498. spin_lock(&meter->lock);
  499. long_delta_ms = (now_ms - meter->used); /* ms */
  500. if (long_delta_ms < 0) {
  501. /* This condition means that we have several threads fighting
  502. * for a meter lock, and the one who received the packets a
  503. * bit later wins. Assuming that all racing threads received
  504. * packets at the same time to avoid overflow.
  505. */
  506. long_delta_ms = 0;
  507. }
  508. /* Make sure delta_ms will not be too large, so that bucket will not
  509. * wrap around below.
  510. */
  511. delta_ms = (long_delta_ms > (long long int)meter->max_delta_t)
  512. ? meter->max_delta_t : (u32)long_delta_ms;
  513. /* Update meter statistics.
  514. */
  515. meter->used = now_ms;
  516. meter->stats.n_packets += 1;
  517. meter->stats.n_bytes += skb->len;
  518. /* Bucket rate is either in kilobits per second, or in packets per
  519. * second. We maintain the bucket in the units of either bits or
  520. * 1/1000th of a packet, correspondingly.
  521. * Then, when rate is multiplied with milliseconds, we get the
  522. * bucket units:
  523. * msec * kbps = bits, and
  524. * msec * packets/sec = 1/1000 packets.
  525. *
  526. * 'cost' is the number of bucket units in this packet.
  527. */
  528. cost = (meter->kbps) ? skb->len * 8 : 1000;
  529. /* Update all bands and find the one hit with the highest rate. */
  530. for (i = 0; i < meter->n_bands; ++i) {
  531. long long int max_bucket_size;
  532. band = &meter->bands[i];
  533. max_bucket_size = band->burst_size * 1000LL;
  534. band->bucket += delta_ms * band->rate;
  535. if (band->bucket > max_bucket_size)
  536. band->bucket = max_bucket_size;
  537. if (band->bucket >= cost) {
  538. band->bucket -= cost;
  539. } else if (band->rate > band_exceeded_rate) {
  540. band_exceeded_rate = band->rate;
  541. band_exceeded_max = i;
  542. }
  543. }
  544. if (band_exceeded_max >= 0) {
  545. /* Update band statistics. */
  546. band = &meter->bands[band_exceeded_max];
  547. band->stats.n_packets += 1;
  548. band->stats.n_bytes += skb->len;
  549. /* Drop band triggered, let the caller drop the 'skb'. */
  550. if (band->type == OVS_METER_BAND_TYPE_DROP) {
  551. spin_unlock(&meter->lock);
  552. return true;
  553. }
  554. }
  555. spin_unlock(&meter->lock);
  556. return false;
  557. }
  558. static const struct genl_small_ops dp_meter_genl_ops[] = {
  559. { .cmd = OVS_METER_CMD_FEATURES,
  560. .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
  561. .flags = 0, /* OK for unprivileged users. */
  562. .doit = ovs_meter_cmd_features
  563. },
  564. { .cmd = OVS_METER_CMD_SET,
  565. .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
  566. .flags = GENL_UNS_ADMIN_PERM, /* Requires CAP_NET_ADMIN
  567. * privilege.
  568. */
  569. .doit = ovs_meter_cmd_set,
  570. },
  571. { .cmd = OVS_METER_CMD_GET,
  572. .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
  573. .flags = 0, /* OK for unprivileged users. */
  574. .doit = ovs_meter_cmd_get,
  575. },
  576. { .cmd = OVS_METER_CMD_DEL,
  577. .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
  578. .flags = GENL_UNS_ADMIN_PERM, /* Requires CAP_NET_ADMIN
  579. * privilege.
  580. */
  581. .doit = ovs_meter_cmd_del
  582. },
  583. };
  584. static const struct genl_multicast_group ovs_meter_multicast_group = {
  585. .name = OVS_METER_MCGROUP,
  586. };
  587. struct genl_family dp_meter_genl_family __ro_after_init = {
  588. .hdrsize = sizeof(struct ovs_header),
  589. .name = OVS_METER_FAMILY,
  590. .version = OVS_METER_VERSION,
  591. .maxattr = OVS_METER_ATTR_MAX,
  592. .policy = meter_policy,
  593. .netnsok = true,
  594. .parallel_ops = true,
  595. .small_ops = dp_meter_genl_ops,
  596. .n_small_ops = ARRAY_SIZE(dp_meter_genl_ops),
  597. .resv_start_op = OVS_METER_CMD_GET + 1,
  598. .mcgrps = &ovs_meter_multicast_group,
  599. .n_mcgrps = 1,
  600. .module = THIS_MODULE,
  601. };
  602. int ovs_meters_init(struct datapath *dp)
  603. {
  604. struct dp_meter_table *tbl = &dp->meter_tbl;
  605. struct dp_meter_instance *ti;
  606. unsigned long free_mem_bytes;
  607. ti = dp_meter_instance_alloc(DP_METER_ARRAY_SIZE_MIN);
  608. if (!ti)
  609. return -ENOMEM;
  610. /* Allow meters in a datapath to use ~3.12% of physical memory. */
  611. free_mem_bytes = nr_free_buffer_pages() * (PAGE_SIZE >> 5);
  612. tbl->max_meters_allowed = min(free_mem_bytes / sizeof(struct dp_meter),
  613. DP_METER_NUM_MAX);
  614. if (!tbl->max_meters_allowed)
  615. goto out_err;
  616. rcu_assign_pointer(tbl->ti, ti);
  617. tbl->count = 0;
  618. return 0;
  619. out_err:
  620. dp_meter_instance_free(ti);
  621. return -ENOMEM;
  622. }
  623. void ovs_meters_exit(struct datapath *dp)
  624. {
  625. struct dp_meter_table *tbl = &dp->meter_tbl;
  626. struct dp_meter_instance *ti = rcu_dereference_raw(tbl->ti);
  627. int i;
  628. for (i = 0; i < ti->n_meters; i++)
  629. ovs_meter_free(rcu_dereference_raw(ti->dp_meters[i]));
  630. dp_meter_instance_free(ti);
  631. }