hc
2024-05-10 23fa18eaa71266feff7ba8d83022d9e1cc83c65a
kernel/net/openvswitch/datapath.c
....@@ -1,19 +1,6 @@
1
+// SPDX-License-Identifier: GPL-2.0-only
12 /*
23 * Copyright (c) 2007-2014 Nicira, Inc.
3
- *
4
- * This program is free software; you can redistribute it and/or
5
- * modify it under the terms of version 2 of the GNU General Public
6
- * License as published by the Free Software Foundation.
7
- *
8
- * This program is distributed in the hope that it will be useful, but
9
- * WITHOUT ANY WARRANTY; without even the implied warranty of
10
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11
- * General Public License for more details.
12
- *
13
- * You should have received a copy of the GNU General Public License
14
- * along with this program; if not, write to the Free Software
15
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
16
- * 02110-1301, USA
174 */
185
196 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
....@@ -143,6 +130,8 @@
143130 const struct dp_upcall_info *,
144131 uint32_t cutlen);
145132
133
+static void ovs_dp_masks_rebalance(struct work_struct *work);
134
+
146135 /* Must be called with rcu_read_lock or ovs_mutex. */
147136 const char *ovs_dp_name(const struct datapath *dp)
148137 {
....@@ -192,7 +181,8 @@
192181 struct hlist_head *head;
193182
194183 head = vport_hash_bucket(dp, port_no);
195
- hlist_for_each_entry_rcu(vport, head, dp_hash_node) {
184
+ hlist_for_each_entry_rcu(vport, head, dp_hash_node,
185
+ lockdep_ovsl_is_held()) {
196186 if (vport->port_no == port_no)
197187 return vport;
198188 }
....@@ -235,31 +225,43 @@
235225 struct dp_stats_percpu *stats;
236226 u64 *stats_counter;
237227 u32 n_mask_hit;
228
+ u32 n_cache_hit;
229
+ int error;
238230
239231 stats = this_cpu_ptr(dp->stats_percpu);
240232
241233 /* Look up flow. */
242
- flow = ovs_flow_tbl_lookup_stats(&dp->table, key, &n_mask_hit);
234
+ flow = ovs_flow_tbl_lookup_stats(&dp->table, key, skb_get_hash(skb),
235
+ &n_mask_hit, &n_cache_hit);
243236 if (unlikely(!flow)) {
244237 struct dp_upcall_info upcall;
245
- int error;
246238
247239 memset(&upcall, 0, sizeof(upcall));
248240 upcall.cmd = OVS_PACKET_CMD_MISS;
249241 upcall.portid = ovs_vport_find_upcall_portid(p, skb);
250242 upcall.mru = OVS_CB(skb)->mru;
251243 error = ovs_dp_upcall(dp, skb, key, &upcall, 0);
252
- if (unlikely(error))
253
- kfree_skb(skb);
254
- else
244
+ switch (error) {
245
+ case 0:
246
+ case -EAGAIN:
247
+ case -ERESTARTSYS:
248
+ case -EINTR:
255249 consume_skb(skb);
250
+ break;
251
+ default:
252
+ kfree_skb(skb);
253
+ break;
254
+ }
256255 stats_counter = &stats->n_missed;
257256 goto out;
258257 }
259258
260259 ovs_flow_stats_update(flow, key->tp.flags, skb);
261260 sf_acts = rcu_dereference(flow->sf_acts);
262
- ovs_execute_actions(dp, skb, sf_acts, key);
261
+ error = ovs_execute_actions(dp, skb, sf_acts, key);
262
+ if (unlikely(error))
263
+ net_dbg_ratelimited("ovs: action execution error on datapath %s: %d\n",
264
+ ovs_dp_name(dp), error);
263265
264266 stats_counter = &stats->n_hit;
265267
....@@ -268,6 +270,7 @@
268270 u64_stats_update_begin(&stats->syncp);
269271 (*stats_counter)++;
270272 stats->n_mask_hit += n_mask_hit;
273
+ stats->n_cache_hit += n_cache_hit;
271274 u64_stats_update_end(&stats->syncp);
272275 }
273276
....@@ -306,14 +309,14 @@
306309 static int queue_gso_packets(struct datapath *dp, struct sk_buff *skb,
307310 const struct sw_flow_key *key,
308311 const struct dp_upcall_info *upcall_info,
309
- uint32_t cutlen)
312
+ uint32_t cutlen)
310313 {
311314 unsigned int gso_type = skb_shinfo(skb)->gso_type;
312315 struct sw_flow_key later_key;
313316 struct sk_buff *segs, *nskb;
314317 int err;
315318
316
- BUILD_BUG_ON(sizeof(*OVS_CB(skb)) > SKB_SGO_CB_OFFSET);
319
+ BUILD_BUG_ON(sizeof(*OVS_CB(skb)) > SKB_GSO_CB_OFFSET);
317320 segs = __skb_gso_segment(skb, NETIF_F_SG, false);
318321 if (IS_ERR(segs))
319322 return PTR_ERR(segs);
....@@ -330,8 +333,7 @@
330333 }
331334
332335 /* Queue all of the segments. */
333
- skb = segs;
334
- do {
336
+ skb_list_walk_safe(segs, skb, nskb) {
335337 if (gso_type & SKB_GSO_UDP && skb != segs)
336338 key = &later_key;
337339
....@@ -339,17 +341,15 @@
339341 if (err)
340342 break;
341343
342
- } while ((skb = skb->next));
344
+ }
343345
344346 /* Free all of the segments. */
345
- skb = segs;
346
- do {
347
- nskb = skb->next;
347
+ skb_list_walk_safe(segs, skb, nskb) {
348348 if (err)
349349 kfree_skb(skb);
350350 else
351351 consume_skb(skb);
352
- } while ((skb = nskb));
352
+ }
353353 return err;
354354 }
355355
....@@ -359,7 +359,8 @@
359359 size_t size = NLMSG_ALIGN(sizeof(struct ovs_header))
360360 + nla_total_size(hdrlen) /* OVS_PACKET_ATTR_PACKET */
361361 + nla_total_size(ovs_key_attr_size()) /* OVS_PACKET_ATTR_KEY */
362
- + nla_total_size(sizeof(unsigned int)); /* OVS_PACKET_ATTR_LEN */
362
+ + nla_total_size(sizeof(unsigned int)) /* OVS_PACKET_ATTR_LEN */
363
+ + nla_total_size(sizeof(u64)); /* OVS_PACKET_ATTR_HASH */
363364
364365 /* OVS_PACKET_ATTR_USERDATA */
365366 if (upcall_info->userdata)
....@@ -402,6 +403,7 @@
402403 size_t len;
403404 unsigned int hlen;
404405 int err, dp_ifindex;
406
+ u64 hash;
405407
406408 dp_ifindex = get_dpifindex(dp);
407409 if (!dp_ifindex)
....@@ -448,10 +450,15 @@
448450
449451 upcall = genlmsg_put(user_skb, 0, 0, &dp_packet_genl_family,
450452 0, upcall_info->cmd);
453
+ if (!upcall) {
454
+ err = -EINVAL;
455
+ goto out;
456
+ }
451457 upcall->dp_ifindex = dp_ifindex;
452458
453459 err = ovs_nla_put_key(key, key, OVS_PACKET_ATTR_KEY, false, user_skb);
454
- BUG_ON(err);
460
+ if (err)
461
+ goto out;
455462
456463 if (upcall_info->userdata)
457464 __nla_put(user_skb, OVS_PACKET_ATTR_USERDATA,
....@@ -459,15 +466,26 @@
459466 nla_data(upcall_info->userdata));
460467
461468 if (upcall_info->egress_tun_info) {
462
- nla = nla_nest_start(user_skb, OVS_PACKET_ATTR_EGRESS_TUN_KEY);
469
+ nla = nla_nest_start_noflag(user_skb,
470
+ OVS_PACKET_ATTR_EGRESS_TUN_KEY);
471
+ if (!nla) {
472
+ err = -EMSGSIZE;
473
+ goto out;
474
+ }
463475 err = ovs_nla_put_tunnel_info(user_skb,
464476 upcall_info->egress_tun_info);
465
- BUG_ON(err);
477
+ if (err)
478
+ goto out;
479
+
466480 nla_nest_end(user_skb, nla);
467481 }
468482
469483 if (upcall_info->actions_len) {
470
- nla = nla_nest_start(user_skb, OVS_PACKET_ATTR_ACTIONS);
484
+ nla = nla_nest_start_noflag(user_skb, OVS_PACKET_ATTR_ACTIONS);
485
+ if (!nla) {
486
+ err = -EMSGSIZE;
487
+ goto out;
488
+ }
471489 err = ovs_nla_put_actions(upcall_info->actions,
472490 upcall_info->actions_len,
473491 user_skb);
....@@ -478,23 +496,30 @@
478496 }
479497
480498 /* Add OVS_PACKET_ATTR_MRU */
481
- if (upcall_info->mru) {
482
- if (nla_put_u16(user_skb, OVS_PACKET_ATTR_MRU,
483
- upcall_info->mru)) {
484
- err = -ENOBUFS;
485
- goto out;
486
- }
487
- pad_packet(dp, user_skb);
499
+ if (upcall_info->mru &&
500
+ nla_put_u16(user_skb, OVS_PACKET_ATTR_MRU, upcall_info->mru)) {
501
+ err = -ENOBUFS;
502
+ goto out;
488503 }
489504
490505 /* Add OVS_PACKET_ATTR_LEN when packet is truncated */
491
- if (cutlen > 0) {
492
- if (nla_put_u32(user_skb, OVS_PACKET_ATTR_LEN,
493
- skb->len)) {
494
- err = -ENOBUFS;
495
- goto out;
496
- }
497
- pad_packet(dp, user_skb);
506
+ if (cutlen > 0 &&
507
+ nla_put_u32(user_skb, OVS_PACKET_ATTR_LEN, skb->len)) {
508
+ err = -ENOBUFS;
509
+ goto out;
510
+ }
511
+
512
+ /* Add OVS_PACKET_ATTR_HASH */
513
+ hash = skb_get_hash_raw(skb);
514
+ if (skb->sw_hash)
515
+ hash |= OVS_PACKET_HASH_SW_BIT;
516
+
517
+ if (skb->l4_hash)
518
+ hash |= OVS_PACKET_HASH_L4_BIT;
519
+
520
+ if (nla_put(user_skb, OVS_PACKET_ATTR_HASH, sizeof (u64), &hash)) {
521
+ err = -ENOBUFS;
522
+ goto out;
498523 }
499524
500525 /* Only reserve room for attribute header, packet data is added
....@@ -519,8 +544,9 @@
519544 out:
520545 if (err)
521546 skb_tx_error(skb);
522
- kfree_skb(user_skb);
523
- kfree_skb(nskb);
547
+ consume_skb(user_skb);
548
+ consume_skb(nskb);
549
+
524550 return err;
525551 }
526552
....@@ -536,6 +562,7 @@
536562 struct datapath *dp;
537563 struct vport *input_vport;
538564 u16 mru = 0;
565
+ u64 hash;
539566 int len;
540567 int err;
541568 bool log = !a[OVS_PACKET_ATTR_PROBE];
....@@ -560,6 +587,14 @@
560587 packet->ignore_df = 1;
561588 }
562589 OVS_CB(packet)->mru = mru;
590
+
591
+ if (a[OVS_PACKET_ATTR_HASH]) {
592
+ hash = nla_get_u64(a[OVS_PACKET_ATTR_HASH]);
593
+
594
+ __skb_set_hash(packet, hash & 0xFFFFFFFFULL,
595
+ !!(hash & OVS_PACKET_HASH_SW_BIT),
596
+ !!(hash & OVS_PACKET_HASH_L4_BIT));
597
+ }
563598
564599 /* Build an sw_flow for sending this packet. */
565600 flow = ovs_flow_alloc();
....@@ -622,12 +657,13 @@
622657 [OVS_PACKET_ATTR_ACTIONS] = { .type = NLA_NESTED },
623658 [OVS_PACKET_ATTR_PROBE] = { .type = NLA_FLAG },
624659 [OVS_PACKET_ATTR_MRU] = { .type = NLA_U16 },
660
+ [OVS_PACKET_ATTR_HASH] = { .type = NLA_U64 },
625661 };
626662
627
-static const struct genl_ops dp_packet_genl_ops[] = {
663
+static const struct genl_small_ops dp_packet_genl_ops[] = {
628664 { .cmd = OVS_PACKET_CMD_EXECUTE,
665
+ .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
629666 .flags = GENL_UNS_ADMIN_PERM, /* Requires CAP_NET_ADMIN privilege. */
630
- .policy = packet_policy,
631667 .doit = ovs_packet_cmd_execute
632668 }
633669 };
....@@ -637,10 +673,11 @@
637673 .name = OVS_PACKET_FAMILY,
638674 .version = OVS_PACKET_VERSION,
639675 .maxattr = OVS_PACKET_ATTR_MAX,
676
+ .policy = packet_policy,
640677 .netnsok = true,
641678 .parallel_ops = true,
642
- .ops = dp_packet_genl_ops,
643
- .n_ops = ARRAY_SIZE(dp_packet_genl_ops),
679
+ .small_ops = dp_packet_genl_ops,
680
+ .n_small_ops = ARRAY_SIZE(dp_packet_genl_ops),
644681 .module = THIS_MODULE,
645682 };
646683
....@@ -672,6 +709,7 @@
672709 stats->n_missed += local_stats.n_missed;
673710 stats->n_lost += local_stats.n_lost;
674711 mega_stats->n_mask_hit += local_stats.n_mask_hit;
712
+ mega_stats->n_cache_hit += local_stats.n_cache_hit;
675713 }
676714 }
677715
....@@ -768,7 +806,7 @@
768806 * This can only fail for dump operations because the skb is always
769807 * properly sized for single flows.
770808 */
771
- start = nla_nest_start(skb, OVS_FLOW_ATTR_ACTIONS);
809
+ start = nla_nest_start_noflag(skb, OVS_FLOW_ATTR_ACTIONS);
772810 if (start) {
773811 const struct sw_flow_actions *sf_acts;
774812
....@@ -895,6 +933,7 @@
895933 struct sw_flow_mask mask;
896934 struct sk_buff *reply;
897935 struct datapath *dp;
936
+ struct sw_flow_key *key;
898937 struct sw_flow_actions *acts;
899938 struct sw_flow_match match;
900939 u32 ufid_flags = ovs_nla_get_ufid_flags(a[OVS_FLOW_ATTR_UFID_FLAGS]);
....@@ -922,30 +961,32 @@
922961 }
923962
924963 /* Extract key. */
925
- ovs_match_init(&match, &new_flow->key, false, &mask);
964
+ key = kzalloc(sizeof(*key), GFP_KERNEL);
965
+ if (!key) {
966
+ error = -ENOMEM;
967
+ goto err_kfree_flow;
968
+ }
969
+
970
+ ovs_match_init(&match, key, false, &mask);
926971 error = ovs_nla_get_match(net, &match, a[OVS_FLOW_ATTR_KEY],
927972 a[OVS_FLOW_ATTR_MASK], log);
928973 if (error)
929
- goto err_kfree_flow;
974
+ goto err_kfree_key;
975
+
976
+ ovs_flow_mask_key(&new_flow->key, key, true, &mask);
930977
931978 /* Extract flow identifier. */
932979 error = ovs_nla_get_identifier(&new_flow->id, a[OVS_FLOW_ATTR_UFID],
933
- &new_flow->key, log);
980
+ key, log);
934981 if (error)
935
- goto err_kfree_flow;
936
-
937
- /* unmasked key is needed to match when ufid is not used. */
938
- if (ovs_identifier_is_key(&new_flow->id))
939
- match.key = new_flow->id.unmasked_key;
940
-
941
- ovs_flow_mask_key(&new_flow->key, &new_flow->key, true, &mask);
982
+ goto err_kfree_key;
942983
943984 /* Validate actions. */
944985 error = ovs_nla_copy_actions(net, a[OVS_FLOW_ATTR_ACTIONS],
945986 &new_flow->key, &acts, log);
946987 if (error) {
947988 OVS_NLERR(log, "Flow actions may not be safe on all matching packets.");
948
- goto err_kfree_flow;
989
+ goto err_kfree_key;
949990 }
950991
951992 reply = ovs_flow_cmd_alloc_info(acts, &new_flow->id, info, false,
....@@ -966,7 +1007,7 @@
9661007 if (ovs_identifier_is_ufid(&new_flow->id))
9671008 flow = ovs_flow_tbl_lookup_ufid(&dp->table, &new_flow->id);
9681009 if (!flow)
969
- flow = ovs_flow_tbl_lookup(&dp->table, &new_flow->key);
1010
+ flow = ovs_flow_tbl_lookup(&dp->table, key);
9701011 if (likely(!flow)) {
9711012 rcu_assign_pointer(new_flow->sf_acts, acts);
9721013
....@@ -1036,6 +1077,8 @@
10361077
10371078 if (reply)
10381079 ovs_notify(&dp_flow_genl_family, reply, info);
1080
+
1081
+ kfree(key);
10391082 return 0;
10401083
10411084 err_unlock_ovs:
....@@ -1043,6 +1086,8 @@
10431086 kfree_skb(reply);
10441087 err_kfree_acts:
10451088 ovs_nla_free_flow_actions(acts);
1089
+err_kfree_key:
1090
+ kfree(key);
10461091 err_kfree_flow:
10471092 ovs_flow_free(new_flow, false);
10481093 error:
....@@ -1050,11 +1095,12 @@
10501095 }
10511096
10521097 /* Factor out action copy to avoid "Wframe-larger-than=1024" warning. */
1053
-static struct sw_flow_actions *get_flow_actions(struct net *net,
1054
- const struct nlattr *a,
1055
- const struct sw_flow_key *key,
1056
- const struct sw_flow_mask *mask,
1057
- bool log)
1098
+static noinline_for_stack
1099
+struct sw_flow_actions *get_flow_actions(struct net *net,
1100
+ const struct nlattr *a,
1101
+ const struct sw_flow_key *key,
1102
+ const struct sw_flow_mask *mask,
1103
+ bool log)
10581104 {
10591105 struct sw_flow_actions *acts;
10601106 struct sw_flow_key masked_key;
....@@ -1084,12 +1130,13 @@
10841130 * we should not to return match object with dangling reference
10851131 * to mask.
10861132 * */
1087
-static int ovs_nla_init_match_and_action(struct net *net,
1088
- struct sw_flow_match *match,
1089
- struct sw_flow_key *key,
1090
- struct nlattr **a,
1091
- struct sw_flow_actions **acts,
1092
- bool log)
1133
+static noinline_for_stack int
1134
+ovs_nla_init_match_and_action(struct net *net,
1135
+ struct sw_flow_match *match,
1136
+ struct sw_flow_key *key,
1137
+ struct nlattr **a,
1138
+ struct sw_flow_actions **acts,
1139
+ bool log)
10931140 {
10941141 struct sw_flow_mask mask;
10951142 int error = 0;
....@@ -1189,14 +1236,14 @@
11891236 ovs_header->dp_ifindex,
11901237 reply, info->snd_portid,
11911238 info->snd_seq, 0,
1192
- OVS_FLOW_CMD_NEW,
1239
+ OVS_FLOW_CMD_SET,
11931240 ufid_flags);
11941241 BUG_ON(error < 0);
11951242 }
11961243 } else {
11971244 /* Could not alloc without acts before locking. */
11981245 reply = ovs_flow_cmd_build_info(flow, ovs_header->dp_ifindex,
1199
- info, OVS_FLOW_CMD_NEW, false,
1246
+ info, OVS_FLOW_CMD_SET, false,
12001247 ufid_flags);
12011248
12021249 if (IS_ERR(reply)) {
....@@ -1272,7 +1319,7 @@
12721319 }
12731320
12741321 reply = ovs_flow_cmd_build_info(flow, ovs_header->dp_ifindex, info,
1275
- OVS_FLOW_CMD_NEW, true, ufid_flags);
1322
+ OVS_FLOW_CMD_GET, true, ufid_flags);
12761323 if (IS_ERR(reply)) {
12771324 err = PTR_ERR(reply);
12781325 goto unlock;
....@@ -1337,7 +1384,7 @@
13371384 reply = ovs_flow_cmd_alloc_info((const struct sw_flow_actions __force *) flow->sf_acts,
13381385 &flow->id, info, false, ufid_flags);
13391386 if (likely(reply)) {
1340
- if (likely(!IS_ERR(reply))) {
1387
+ if (!IS_ERR(reply)) {
13411388 rcu_read_lock(); /*To keep RCU checker happy. */
13421389 err = ovs_flow_cmd_fill_info(flow, ovs_header->dp_ifindex,
13431390 reply, info->snd_portid,
....@@ -1352,7 +1399,8 @@
13521399
13531400 ovs_notify(&dp_flow_genl_family, reply, info);
13541401 } else {
1355
- netlink_set_err(sock_net(skb->sk)->genl_sock, 0, 0, PTR_ERR(reply));
1402
+ netlink_set_err(sock_net(skb->sk)->genl_sock, 0, 0,
1403
+ PTR_ERR(reply));
13561404 }
13571405 }
13581406
....@@ -1373,8 +1421,8 @@
13731421 u32 ufid_flags;
13741422 int err;
13751423
1376
- err = genlmsg_parse(cb->nlh, &dp_flow_genl_family, a,
1377
- OVS_FLOW_ATTR_MAX, flow_policy, NULL);
1424
+ err = genlmsg_parse_deprecated(cb->nlh, &dp_flow_genl_family, a,
1425
+ OVS_FLOW_ATTR_MAX, flow_policy, NULL);
13781426 if (err)
13791427 return err;
13801428 ufid_flags = ovs_nla_get_ufid_flags(a[OVS_FLOW_ATTR_UFID_FLAGS]);
....@@ -1400,7 +1448,7 @@
14001448 if (ovs_flow_cmd_fill_info(flow, ovs_header->dp_ifindex, skb,
14011449 NETLINK_CB(cb->skb).portid,
14021450 cb->nlh->nlmsg_seq, NLM_F_MULTI,
1403
- OVS_FLOW_CMD_NEW, ufid_flags) < 0)
1451
+ OVS_FLOW_CMD_GET, ufid_flags) < 0)
14041452 break;
14051453
14061454 cb->args[0] = bucket;
....@@ -1420,26 +1468,26 @@
14201468 [OVS_FLOW_ATTR_UFID_FLAGS] = { .type = NLA_U32 },
14211469 };
14221470
1423
-static const struct genl_ops dp_flow_genl_ops[] = {
1471
+static const struct genl_small_ops dp_flow_genl_ops[] = {
14241472 { .cmd = OVS_FLOW_CMD_NEW,
1473
+ .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
14251474 .flags = GENL_UNS_ADMIN_PERM, /* Requires CAP_NET_ADMIN privilege. */
1426
- .policy = flow_policy,
14271475 .doit = ovs_flow_cmd_new
14281476 },
14291477 { .cmd = OVS_FLOW_CMD_DEL,
1478
+ .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
14301479 .flags = GENL_UNS_ADMIN_PERM, /* Requires CAP_NET_ADMIN privilege. */
1431
- .policy = flow_policy,
14321480 .doit = ovs_flow_cmd_del
14331481 },
14341482 { .cmd = OVS_FLOW_CMD_GET,
1483
+ .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
14351484 .flags = 0, /* OK for unprivileged users. */
1436
- .policy = flow_policy,
14371485 .doit = ovs_flow_cmd_get,
14381486 .dumpit = ovs_flow_cmd_dump
14391487 },
14401488 { .cmd = OVS_FLOW_CMD_SET,
1489
+ .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
14411490 .flags = GENL_UNS_ADMIN_PERM, /* Requires CAP_NET_ADMIN privilege. */
1442
- .policy = flow_policy,
14431491 .doit = ovs_flow_cmd_set,
14441492 },
14451493 };
....@@ -1449,10 +1497,11 @@
14491497 .name = OVS_FLOW_FAMILY,
14501498 .version = OVS_FLOW_VERSION,
14511499 .maxattr = OVS_FLOW_ATTR_MAX,
1500
+ .policy = flow_policy,
14521501 .netnsok = true,
14531502 .parallel_ops = true,
1454
- .ops = dp_flow_genl_ops,
1455
- .n_ops = ARRAY_SIZE(dp_flow_genl_ops),
1503
+ .small_ops = dp_flow_genl_ops,
1504
+ .n_small_ops = ARRAY_SIZE(dp_flow_genl_ops),
14561505 .mcgrps = &ovs_dp_flow_multicast_group,
14571506 .n_mcgrps = 1,
14581507 .module = THIS_MODULE,
....@@ -1466,6 +1515,7 @@
14661515 msgsize += nla_total_size_64bit(sizeof(struct ovs_dp_stats));
14671516 msgsize += nla_total_size_64bit(sizeof(struct ovs_dp_megaflow_stats));
14681517 msgsize += nla_total_size(sizeof(u32)); /* OVS_DP_ATTR_USER_FEATURES */
1518
+ msgsize += nla_total_size(sizeof(u32)); /* OVS_DP_ATTR_MASKS_CACHE_SIZE */
14691519
14701520 return msgsize;
14711521 }
....@@ -1480,7 +1530,7 @@
14801530 int err;
14811531
14821532 ovs_header = genlmsg_put(skb, portid, seq, &dp_datapath_genl_family,
1483
- flags, cmd);
1533
+ flags, cmd);
14841534 if (!ovs_header)
14851535 goto error;
14861536
....@@ -1501,6 +1551,10 @@
15011551 goto nla_put_failure;
15021552
15031553 if (nla_put_u32(skb, OVS_DP_ATTR_USER_FEATURES, dp->user_features))
1554
+ goto nla_put_failure;
1555
+
1556
+ if (nla_put_u32(skb, OVS_DP_ATTR_MASKS_CACHE_SIZE,
1557
+ ovs_flow_tbl_masks_cache_size(&dp->table)))
15041558 goto nla_put_failure;
15051559
15061560 genlmsg_end(skb, ovs_header);
....@@ -1535,22 +1589,84 @@
15351589 return dp ? dp : ERR_PTR(-ENODEV);
15361590 }
15371591
1538
-static void ovs_dp_reset_user_features(struct sk_buff *skb, struct genl_info *info)
1592
+static void ovs_dp_reset_user_features(struct sk_buff *skb,
1593
+ struct genl_info *info)
15391594 {
15401595 struct datapath *dp;
15411596
1542
- dp = lookup_datapath(sock_net(skb->sk), info->userhdr, info->attrs);
1597
+ dp = lookup_datapath(sock_net(skb->sk), info->userhdr,
1598
+ info->attrs);
15431599 if (IS_ERR(dp))
15441600 return;
15451601
1546
- WARN(dp->user_features, "Dropping previously announced user features\n");
1602
+ pr_warn("%s: Dropping previously announced user features\n",
1603
+ ovs_dp_name(dp));
15471604 dp->user_features = 0;
15481605 }
15491606
1550
-static void ovs_dp_change(struct datapath *dp, struct nlattr *a[])
1607
+DEFINE_STATIC_KEY_FALSE(tc_recirc_sharing_support);
1608
+
1609
+static int ovs_dp_change(struct datapath *dp, struct nlattr *a[])
15511610 {
1552
- if (a[OVS_DP_ATTR_USER_FEATURES])
1553
- dp->user_features = nla_get_u32(a[OVS_DP_ATTR_USER_FEATURES]);
1611
+ u32 user_features = 0;
1612
+
1613
+ if (a[OVS_DP_ATTR_USER_FEATURES]) {
1614
+ user_features = nla_get_u32(a[OVS_DP_ATTR_USER_FEATURES]);
1615
+
1616
+ if (user_features & ~(OVS_DP_F_VPORT_PIDS |
1617
+ OVS_DP_F_UNALIGNED |
1618
+ OVS_DP_F_TC_RECIRC_SHARING))
1619
+ return -EOPNOTSUPP;
1620
+
1621
+#if !IS_ENABLED(CONFIG_NET_TC_SKB_EXT)
1622
+ if (user_features & OVS_DP_F_TC_RECIRC_SHARING)
1623
+ return -EOPNOTSUPP;
1624
+#endif
1625
+ }
1626
+
1627
+ if (a[OVS_DP_ATTR_MASKS_CACHE_SIZE]) {
1628
+ int err;
1629
+ u32 cache_size;
1630
+
1631
+ cache_size = nla_get_u32(a[OVS_DP_ATTR_MASKS_CACHE_SIZE]);
1632
+ err = ovs_flow_tbl_masks_cache_resize(&dp->table, cache_size);
1633
+ if (err)
1634
+ return err;
1635
+ }
1636
+
1637
+ dp->user_features = user_features;
1638
+
1639
+ if (dp->user_features & OVS_DP_F_TC_RECIRC_SHARING)
1640
+ static_branch_enable(&tc_recirc_sharing_support);
1641
+ else
1642
+ static_branch_disable(&tc_recirc_sharing_support);
1643
+
1644
+ return 0;
1645
+}
1646
+
1647
+static int ovs_dp_stats_init(struct datapath *dp)
1648
+{
1649
+ dp->stats_percpu = netdev_alloc_pcpu_stats(struct dp_stats_percpu);
1650
+ if (!dp->stats_percpu)
1651
+ return -ENOMEM;
1652
+
1653
+ return 0;
1654
+}
1655
+
1656
+static int ovs_dp_vport_init(struct datapath *dp)
1657
+{
1658
+ int i;
1659
+
1660
+ dp->ports = kmalloc_array(DP_VPORT_HASH_BUCKETS,
1661
+ sizeof(struct hlist_head),
1662
+ GFP_KERNEL);
1663
+ if (!dp->ports)
1664
+ return -ENOMEM;
1665
+
1666
+ for (i = 0; i < DP_VPORT_HASH_BUCKETS; i++)
1667
+ INIT_HLIST_HEAD(&dp->ports[i]);
1668
+
1669
+ return 0;
15541670 }
15551671
15561672 static int ovs_dp_cmd_new(struct sk_buff *skb, struct genl_info *info)
....@@ -1561,7 +1677,7 @@
15611677 struct datapath *dp;
15621678 struct vport *vport;
15631679 struct ovs_net *ovs_net;
1564
- int err, i;
1680
+ int err;
15651681
15661682 err = -EINVAL;
15671683 if (!a[OVS_DP_ATTR_NAME] || !a[OVS_DP_ATTR_UPCALL_PID])
....@@ -1574,35 +1690,26 @@
15741690 err = -ENOMEM;
15751691 dp = kzalloc(sizeof(*dp), GFP_KERNEL);
15761692 if (dp == NULL)
1577
- goto err_free_reply;
1693
+ goto err_destroy_reply;
15781694
15791695 ovs_dp_set_net(dp, sock_net(skb->sk));
15801696
15811697 /* Allocate table. */
15821698 err = ovs_flow_tbl_init(&dp->table);
15831699 if (err)
1584
- goto err_free_dp;
1700
+ goto err_destroy_dp;
15851701
1586
- dp->stats_percpu = netdev_alloc_pcpu_stats(struct dp_stats_percpu);
1587
- if (!dp->stats_percpu) {
1588
- err = -ENOMEM;
1702
+ err = ovs_dp_stats_init(dp);
1703
+ if (err)
15891704 goto err_destroy_table;
1590
- }
15911705
1592
- dp->ports = kmalloc_array(DP_VPORT_HASH_BUCKETS,
1593
- sizeof(struct hlist_head),
1594
- GFP_KERNEL);
1595
- if (!dp->ports) {
1596
- err = -ENOMEM;
1597
- goto err_destroy_percpu;
1598
- }
1599
-
1600
- for (i = 0; i < DP_VPORT_HASH_BUCKETS; i++)
1601
- INIT_HLIST_HEAD(&dp->ports[i]);
1706
+ err = ovs_dp_vport_init(dp);
1707
+ if (err)
1708
+ goto err_destroy_stats;
16021709
16031710 err = ovs_meters_init(dp);
16041711 if (err)
1605
- goto err_destroy_ports_array;
1712
+ goto err_destroy_ports;
16061713
16071714 /* Set up our datapath device. */
16081715 parms.name = nla_data(a[OVS_DP_ATTR_NAME]);
....@@ -1612,10 +1719,12 @@
16121719 parms.port_no = OVSP_LOCAL;
16131720 parms.upcall_portids = a[OVS_DP_ATTR_UPCALL_PID];
16141721
1615
- ovs_dp_change(dp, a);
1616
-
16171722 /* So far only local changes have been made, now need the lock. */
16181723 ovs_lock();
1724
+
1725
+ err = ovs_dp_change(dp, a);
1726
+ if (err)
1727
+ goto err_unlock_and_destroy_meters;
16191728
16201729 vport = new_vport(&parms);
16211730 if (IS_ERR(vport)) {
....@@ -1632,7 +1741,7 @@
16321741 ovs_dp_reset_user_features(skb, info);
16331742 }
16341743
1635
- goto err_destroy_meters;
1744
+ goto err_unlock_and_destroy_meters;
16361745 }
16371746
16381747 err = ovs_dp_cmd_fill_info(dp, reply, info->snd_portid,
....@@ -1647,18 +1756,18 @@
16471756 ovs_notify(&dp_datapath_genl_family, reply, info);
16481757 return 0;
16491758
1650
-err_destroy_meters:
1759
+err_unlock_and_destroy_meters:
16511760 ovs_unlock();
16521761 ovs_meters_exit(dp);
1653
-err_destroy_ports_array:
1762
+err_destroy_ports:
16541763 kfree(dp->ports);
1655
-err_destroy_percpu:
1764
+err_destroy_stats:
16561765 free_percpu(dp->stats_percpu);
16571766 err_destroy_table:
16581767 ovs_flow_tbl_destroy(&dp->table);
1659
-err_free_dp:
1768
+err_destroy_dp:
16601769 kfree(dp);
1661
-err_free_reply:
1770
+err_destroy_reply:
16621771 kfree_skb(reply);
16631772 err:
16641773 return err;
....@@ -1667,6 +1776,7 @@
16671776 /* Called with ovs_mutex. */
16681777 static void __dp_destroy(struct datapath *dp)
16691778 {
1779
+ struct flow_table *table = &dp->table;
16701780 int i;
16711781
16721782 for (i = 0; i < DP_VPORT_HASH_BUCKETS; i++) {
....@@ -1685,7 +1795,14 @@
16851795 */
16861796 ovs_dp_detach_port(ovs_vport_ovsl(dp, OVSP_LOCAL));
16871797
1688
- /* RCU destroy the flow table */
1798
+ /* Flush sw_flow in the tables. RCU cb only releases resource
1799
+ * such as dp, ports and tables. That may avoid some issues
1800
+ * such as RCU usage warning.
1801
+ */
1802
+ table_instance_flow_flush(table, ovsl_dereference(table->ti),
1803
+ ovsl_dereference(table->ufid_ti));
1804
+
1805
+ /* RCU destroy the ports, meters and flow tables. */
16891806 call_rcu(&dp->rcu, destroy_dp_rcu);
16901807 }
16911808
....@@ -1738,10 +1855,12 @@
17381855 if (IS_ERR(dp))
17391856 goto err_unlock_free;
17401857
1741
- ovs_dp_change(dp, info->attrs);
1858
+ err = ovs_dp_change(dp, info->attrs);
1859
+ if (err)
1860
+ goto err_unlock_free;
17421861
17431862 err = ovs_dp_cmd_fill_info(dp, reply, info->snd_portid,
1744
- info->snd_seq, 0, OVS_DP_CMD_NEW);
1863
+ info->snd_seq, 0, OVS_DP_CMD_SET);
17451864 BUG_ON(err < 0);
17461865
17471866 ovs_unlock();
....@@ -1772,7 +1891,7 @@
17721891 goto err_unlock_free;
17731892 }
17741893 err = ovs_dp_cmd_fill_info(dp, reply, info->snd_portid,
1775
- info->snd_seq, 0, OVS_DP_CMD_NEW);
1894
+ info->snd_seq, 0, OVS_DP_CMD_GET);
17761895 BUG_ON(err < 0);
17771896 ovs_unlock();
17781897
....@@ -1796,7 +1915,7 @@
17961915 if (i >= skip &&
17971916 ovs_dp_cmd_fill_info(dp, skb, NETLINK_CB(cb->skb).portid,
17981917 cb->nlh->nlmsg_seq, NLM_F_MULTI,
1799
- OVS_DP_CMD_NEW) < 0)
1918
+ OVS_DP_CMD_GET) < 0)
18001919 break;
18011920 i++;
18021921 }
....@@ -1811,28 +1930,30 @@
18111930 [OVS_DP_ATTR_NAME] = { .type = NLA_NUL_STRING, .len = IFNAMSIZ - 1 },
18121931 [OVS_DP_ATTR_UPCALL_PID] = { .type = NLA_U32 },
18131932 [OVS_DP_ATTR_USER_FEATURES] = { .type = NLA_U32 },
1933
+ [OVS_DP_ATTR_MASKS_CACHE_SIZE] = NLA_POLICY_RANGE(NLA_U32, 0,
1934
+ PCPU_MIN_UNIT_SIZE / sizeof(struct mask_cache_entry)),
18141935 };
18151936
1816
-static const struct genl_ops dp_datapath_genl_ops[] = {
1937
+static const struct genl_small_ops dp_datapath_genl_ops[] = {
18171938 { .cmd = OVS_DP_CMD_NEW,
1939
+ .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
18181940 .flags = GENL_UNS_ADMIN_PERM, /* Requires CAP_NET_ADMIN privilege. */
1819
- .policy = datapath_policy,
18201941 .doit = ovs_dp_cmd_new
18211942 },
18221943 { .cmd = OVS_DP_CMD_DEL,
1944
+ .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
18231945 .flags = GENL_UNS_ADMIN_PERM, /* Requires CAP_NET_ADMIN privilege. */
1824
- .policy = datapath_policy,
18251946 .doit = ovs_dp_cmd_del
18261947 },
18271948 { .cmd = OVS_DP_CMD_GET,
1949
+ .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
18281950 .flags = 0, /* OK for unprivileged users. */
1829
- .policy = datapath_policy,
18301951 .doit = ovs_dp_cmd_get,
18311952 .dumpit = ovs_dp_cmd_dump
18321953 },
18331954 { .cmd = OVS_DP_CMD_SET,
1955
+ .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
18341956 .flags = GENL_UNS_ADMIN_PERM, /* Requires CAP_NET_ADMIN privilege. */
1835
- .policy = datapath_policy,
18361957 .doit = ovs_dp_cmd_set,
18371958 },
18381959 };
....@@ -1842,10 +1963,11 @@
18421963 .name = OVS_DATAPATH_FAMILY,
18431964 .version = OVS_DATAPATH_VERSION,
18441965 .maxattr = OVS_DP_ATTR_MAX,
1966
+ .policy = datapath_policy,
18451967 .netnsok = true,
18461968 .parallel_ops = true,
1847
- .ops = dp_datapath_genl_ops,
1848
- .n_ops = ARRAY_SIZE(dp_datapath_genl_ops),
1969
+ .small_ops = dp_datapath_genl_ops,
1970
+ .n_small_ops = ARRAY_SIZE(dp_datapath_genl_ops),
18491971 .mcgrps = &ovs_dp_datapath_multicast_group,
18501972 .n_mcgrps = 1,
18511973 .module = THIS_MODULE,
....@@ -1964,16 +2086,16 @@
19642086
19652087 }
19662088
1967
-/* Called with ovs_mutex */
1968
-static void update_headroom(struct datapath *dp)
2089
+static unsigned int ovs_get_max_headroom(struct datapath *dp)
19692090 {
1970
- unsigned dev_headroom, max_headroom = 0;
2091
+ unsigned int dev_headroom, max_headroom = 0;
19712092 struct net_device *dev;
19722093 struct vport *vport;
19732094 int i;
19742095
19752096 for (i = 0; i < DP_VPORT_HASH_BUCKETS; i++) {
1976
- hlist_for_each_entry_rcu(vport, &dp->ports[i], dp_hash_node) {
2097
+ hlist_for_each_entry_rcu(vport, &dp->ports[i], dp_hash_node,
2098
+ lockdep_ovsl_is_held()) {
19772099 dev = vport->dev;
19782100 dev_headroom = netdev_get_fwd_headroom(dev);
19792101 if (dev_headroom > max_headroom)
....@@ -1981,10 +2103,21 @@
19812103 }
19822104 }
19832105
1984
- dp->max_headroom = max_headroom;
1985
- for (i = 0; i < DP_VPORT_HASH_BUCKETS; i++)
1986
- hlist_for_each_entry_rcu(vport, &dp->ports[i], dp_hash_node)
1987
- netdev_set_rx_headroom(vport->dev, max_headroom);
2106
+ return max_headroom;
2107
+}
2108
+
2109
+/* Called with ovs_mutex */
2110
+static void ovs_update_headroom(struct datapath *dp, unsigned int new_headroom)
2111
+{
2112
+ struct vport *vport;
2113
+ int i;
2114
+
2115
+ dp->max_headroom = new_headroom;
2116
+ for (i = 0; i < DP_VPORT_HASH_BUCKETS; i++) {
2117
+ hlist_for_each_entry_rcu(vport, &dp->ports[i], dp_hash_node,
2118
+ lockdep_ovsl_is_held())
2119
+ netdev_set_rx_headroom(vport->dev, new_headroom);
2120
+ }
19882121 }
19892122
19902123 static int ovs_vport_cmd_new(struct sk_buff *skb, struct genl_info *info)
....@@ -1995,6 +2128,7 @@
19952128 struct sk_buff *reply;
19962129 struct vport *vport;
19972130 struct datapath *dp;
2131
+ unsigned int new_headroom;
19982132 u32 port_no;
19992133 int err;
20002134
....@@ -2056,8 +2190,10 @@
20562190 info->snd_portid, info->snd_seq, 0,
20572191 OVS_VPORT_CMD_NEW, GFP_KERNEL);
20582192
2059
- if (netdev_get_fwd_headroom(vport->dev) > dp->max_headroom)
2060
- update_headroom(dp);
2193
+ new_headroom = netdev_get_fwd_headroom(vport->dev);
2194
+
2195
+ if (new_headroom > dp->max_headroom)
2196
+ ovs_update_headroom(dp, new_headroom);
20612197 else
20622198 netdev_set_rx_headroom(vport->dev, dp->max_headroom);
20632199
....@@ -2113,7 +2249,7 @@
21132249
21142250 err = ovs_vport_cmd_fill_info(vport, reply, genl_info_net(info),
21152251 info->snd_portid, info->snd_seq, 0,
2116
- OVS_VPORT_CMD_NEW, GFP_ATOMIC);
2252
+ OVS_VPORT_CMD_SET, GFP_KERNEL);
21172253 BUG_ON(err < 0);
21182254
21192255 ovs_unlock();
....@@ -2128,11 +2264,12 @@
21282264
21292265 static int ovs_vport_cmd_del(struct sk_buff *skb, struct genl_info *info)
21302266 {
2131
- bool must_update_headroom = false;
2267
+ bool update_headroom = false;
21322268 struct nlattr **a = info->attrs;
21332269 struct sk_buff *reply;
21342270 struct datapath *dp;
21352271 struct vport *vport;
2272
+ unsigned int new_headroom;
21362273 int err;
21372274
21382275 reply = ovs_vport_cmd_alloc_info();
....@@ -2158,12 +2295,17 @@
21582295 /* the vport deletion may trigger dp headroom update */
21592296 dp = vport->dp;
21602297 if (netdev_get_fwd_headroom(vport->dev) == dp->max_headroom)
2161
- must_update_headroom = true;
2298
+ update_headroom = true;
2299
+
21622300 netdev_reset_rx_headroom(vport->dev);
21632301 ovs_dp_detach_port(vport);
21642302
2165
- if (must_update_headroom)
2166
- update_headroom(dp);
2303
+ if (update_headroom) {
2304
+ new_headroom = ovs_get_max_headroom(dp);
2305
+
2306
+ if (new_headroom < dp->max_headroom)
2307
+ ovs_update_headroom(dp, new_headroom);
2308
+ }
21672309 ovs_unlock();
21682310
21692311 ovs_notify(&dp_vport_genl_family, reply, info);
....@@ -2194,7 +2336,7 @@
21942336 goto exit_unlock_free;
21952337 err = ovs_vport_cmd_fill_info(vport, reply, genl_info_net(info),
21962338 info->snd_portid, info->snd_seq, 0,
2197
- OVS_VPORT_CMD_NEW, GFP_ATOMIC);
2339
+ OVS_VPORT_CMD_GET, GFP_ATOMIC);
21982340 BUG_ON(err < 0);
21992341 rcu_read_unlock();
22002342
....@@ -2230,7 +2372,7 @@
22302372 NETLINK_CB(cb->skb).portid,
22312373 cb->nlh->nlmsg_seq,
22322374 NLM_F_MULTI,
2233
- OVS_VPORT_CMD_NEW,
2375
+ OVS_VPORT_CMD_GET,
22342376 GFP_ATOMIC) < 0)
22352377 goto out;
22362378
....@@ -2247,6 +2389,23 @@
22472389 return skb->len;
22482390 }
22492391
2392
+static void ovs_dp_masks_rebalance(struct work_struct *work)
2393
+{
2394
+ struct ovs_net *ovs_net = container_of(work, struct ovs_net,
2395
+ masks_rebalance.work);
2396
+ struct datapath *dp;
2397
+
2398
+ ovs_lock();
2399
+
2400
+ list_for_each_entry(dp, &ovs_net->dps, list_node)
2401
+ ovs_flow_masks_rebalance(&dp->table);
2402
+
2403
+ ovs_unlock();
2404
+
2405
+ schedule_delayed_work(&ovs_net->masks_rebalance,
2406
+ msecs_to_jiffies(DP_MASKS_REBALANCE_INTERVAL));
2407
+}
2408
+
22502409 static const struct nla_policy vport_policy[OVS_VPORT_ATTR_MAX + 1] = {
22512410 [OVS_VPORT_ATTR_NAME] = { .type = NLA_NUL_STRING, .len = IFNAMSIZ - 1 },
22522411 [OVS_VPORT_ATTR_STATS] = { .len = sizeof(struct ovs_vport_stats) },
....@@ -2258,26 +2417,26 @@
22582417 [OVS_VPORT_ATTR_NETNSID] = { .type = NLA_S32 },
22592418 };
22602419
2261
-static const struct genl_ops dp_vport_genl_ops[] = {
2420
+static const struct genl_small_ops dp_vport_genl_ops[] = {
22622421 { .cmd = OVS_VPORT_CMD_NEW,
2422
+ .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
22632423 .flags = GENL_UNS_ADMIN_PERM, /* Requires CAP_NET_ADMIN privilege. */
2264
- .policy = vport_policy,
22652424 .doit = ovs_vport_cmd_new
22662425 },
22672426 { .cmd = OVS_VPORT_CMD_DEL,
2427
+ .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
22682428 .flags = GENL_UNS_ADMIN_PERM, /* Requires CAP_NET_ADMIN privilege. */
2269
- .policy = vport_policy,
22702429 .doit = ovs_vport_cmd_del
22712430 },
22722431 { .cmd = OVS_VPORT_CMD_GET,
2432
+ .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
22732433 .flags = 0, /* OK for unprivileged users. */
2274
- .policy = vport_policy,
22752434 .doit = ovs_vport_cmd_get,
22762435 .dumpit = ovs_vport_cmd_dump
22772436 },
22782437 { .cmd = OVS_VPORT_CMD_SET,
2438
+ .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
22792439 .flags = GENL_UNS_ADMIN_PERM, /* Requires CAP_NET_ADMIN privilege. */
2280
- .policy = vport_policy,
22812440 .doit = ovs_vport_cmd_set,
22822441 },
22832442 };
....@@ -2287,10 +2446,11 @@
22872446 .name = OVS_VPORT_FAMILY,
22882447 .version = OVS_VPORT_VERSION,
22892448 .maxattr = OVS_VPORT_ATTR_MAX,
2449
+ .policy = vport_policy,
22902450 .netnsok = true,
22912451 .parallel_ops = true,
2292
- .ops = dp_vport_genl_ops,
2293
- .n_ops = ARRAY_SIZE(dp_vport_genl_ops),
2452
+ .small_ops = dp_vport_genl_ops,
2453
+ .n_small_ops = ARRAY_SIZE(dp_vport_genl_ops),
22942454 .mcgrps = &ovs_dp_vport_multicast_group,
22952455 .n_mcgrps = 1,
22962456 .module = THIS_MODULE,
....@@ -2337,10 +2497,19 @@
23372497 static int __net_init ovs_init_net(struct net *net)
23382498 {
23392499 struct ovs_net *ovs_net = net_generic(net, ovs_net_id);
2500
+ int err;
23402501
23412502 INIT_LIST_HEAD(&ovs_net->dps);
23422503 INIT_WORK(&ovs_net->dp_notify_work, ovs_dp_notify_wq);
2343
- return ovs_ct_init(net);
2504
+ INIT_DELAYED_WORK(&ovs_net->masks_rebalance, ovs_dp_masks_rebalance);
2505
+
2506
+ err = ovs_ct_init(net);
2507
+ if (err)
2508
+ return err;
2509
+
2510
+ schedule_delayed_work(&ovs_net->masks_rebalance,
2511
+ msecs_to_jiffies(DP_MASKS_REBALANCE_INTERVAL));
2512
+ return 0;
23442513 }
23452514
23462515 static void __net_exit list_vports_from_net(struct net *net, struct net *dnet,
....@@ -2374,8 +2543,10 @@
23742543 struct net *net;
23752544 LIST_HEAD(head);
23762545
2377
- ovs_ct_exit(dnet);
23782546 ovs_lock();
2547
+
2548
+ ovs_ct_exit(dnet);
2549
+
23792550 list_for_each_entry_safe(dp, dp_next, &ovs_net->dps, list_node)
23802551 __dp_destroy(dp);
23812552
....@@ -2392,6 +2563,7 @@
23922563
23932564 ovs_unlock();
23942565
2566
+ cancel_delayed_work_sync(&ovs_net->masks_rebalance);
23952567 cancel_work_sync(&ovs_net->dp_notify_work);
23962568 }
23972569
....@@ -2406,7 +2578,8 @@
24062578 {
24072579 int err;
24082580
2409
- BUILD_BUG_ON(sizeof(struct ovs_skb_cb) > FIELD_SIZEOF(struct sk_buff, cb));
2581
+ BUILD_BUG_ON(sizeof(struct ovs_skb_cb) >
2582
+ sizeof_field(struct sk_buff, cb));
24102583
24112584 pr_info("Open vSwitch switching datapath\n");
24122585