hc
2024-10-22 8ac6c7a54ed1b98d142dce24b11c6de6a1e239a5
kernel/net/8021q/vlan_core.c
....@@ -57,7 +57,7 @@
5757 }
5858
5959 skb->priority = vlan_get_ingress_priority(vlan_dev, skb->vlan_tci);
60
- skb->vlan_tci = 0;
60
+ __vlan_hwaccel_clear_tag(skb);
6161
6262 rx_stats = this_cpu_ptr(vlan_dev_priv(vlan_dev)->vlan_pcpu_stats);
6363
....@@ -223,6 +223,33 @@
223223 return -ENODEV;
224224 }
225225
226
+int vlan_for_each(struct net_device *dev,
227
+ int (*action)(struct net_device *dev, int vid, void *arg),
228
+ void *arg)
229
+{
230
+ struct vlan_vid_info *vid_info;
231
+ struct vlan_info *vlan_info;
232
+ struct net_device *vdev;
233
+ int ret;
234
+
235
+ ASSERT_RTNL();
236
+
237
+ vlan_info = rtnl_dereference(dev->vlan_info);
238
+ if (!vlan_info)
239
+ return 0;
240
+
241
+ list_for_each_entry(vid_info, &vlan_info->vid_list, list) {
242
+ vdev = vlan_group_get_device(&vlan_info->grp, vid_info->proto,
243
+ vid_info->vid);
244
+ ret = action(vdev, vid_info->vid, arg);
245
+ if (ret)
246
+ return ret;
247
+ }
248
+
249
+ return 0;
250
+}
251
+EXPORT_SYMBOL(vlan_for_each);
252
+
226253 int vlan_filter_push_vids(struct vlan_info *vlan_info, __be16 proto)
227254 {
228255 struct net_device *real_dev = vlan_info->real_dev;
....@@ -332,9 +359,8 @@
332359 int err;
333360
334361 err = vlan_kill_rx_filter_info(dev, proto, vid);
335
- if (err)
336
- pr_warn("failed to kill vid %04x/%d for device %s\n",
337
- proto, vid, dev->name);
362
+ if (err && dev->reg_state != NETREG_UNREGISTERING)
363
+ netdev_warn(dev, "failed to kill vid %04x/%d\n", proto, vid);
338364
339365 list_del(&vid_info->list);
340366 kfree(vid_info);
....@@ -426,3 +452,102 @@
426452 return vlan_info->grp.nr_vlan_devs ? true : false;
427453 }
428454 EXPORT_SYMBOL(vlan_uses_dev);
455
+
456
+static struct sk_buff *vlan_gro_receive(struct list_head *head,
457
+ struct sk_buff *skb)
458
+{
459
+ const struct packet_offload *ptype;
460
+ unsigned int hlen, off_vlan;
461
+ struct sk_buff *pp = NULL;
462
+ struct vlan_hdr *vhdr;
463
+ struct sk_buff *p;
464
+ __be16 type;
465
+ int flush = 1;
466
+
467
+ off_vlan = skb_gro_offset(skb);
468
+ hlen = off_vlan + sizeof(*vhdr);
469
+ vhdr = skb_gro_header_fast(skb, off_vlan);
470
+ if (skb_gro_header_hard(skb, hlen)) {
471
+ vhdr = skb_gro_header_slow(skb, hlen, off_vlan);
472
+ if (unlikely(!vhdr))
473
+ goto out;
474
+ }
475
+
476
+ type = vhdr->h_vlan_encapsulated_proto;
477
+
478
+ rcu_read_lock();
479
+ ptype = gro_find_receive_by_type(type);
480
+ if (!ptype)
481
+ goto out_unlock;
482
+
483
+ flush = 0;
484
+
485
+ list_for_each_entry(p, head, list) {
486
+ struct vlan_hdr *vhdr2;
487
+
488
+ if (!NAPI_GRO_CB(p)->same_flow)
489
+ continue;
490
+
491
+ vhdr2 = (struct vlan_hdr *)(p->data + off_vlan);
492
+ if (compare_vlan_header(vhdr, vhdr2))
493
+ NAPI_GRO_CB(p)->same_flow = 0;
494
+ }
495
+
496
+ skb_gro_pull(skb, sizeof(*vhdr));
497
+ skb_gro_postpull_rcsum(skb, vhdr, sizeof(*vhdr));
498
+ pp = call_gro_receive(ptype->callbacks.gro_receive, head, skb);
499
+
500
+out_unlock:
501
+ rcu_read_unlock();
502
+out:
503
+ skb_gro_flush_final(skb, pp, flush);
504
+
505
+ return pp;
506
+}
507
+
508
+static int vlan_gro_complete(struct sk_buff *skb, int nhoff)
509
+{
510
+ struct vlan_hdr *vhdr = (struct vlan_hdr *)(skb->data + nhoff);
511
+ __be16 type = vhdr->h_vlan_encapsulated_proto;
512
+ struct packet_offload *ptype;
513
+ int err = -ENOENT;
514
+
515
+ rcu_read_lock();
516
+ ptype = gro_find_complete_by_type(type);
517
+ if (ptype)
518
+ err = ptype->callbacks.gro_complete(skb, nhoff + sizeof(*vhdr));
519
+
520
+ rcu_read_unlock();
521
+ return err;
522
+}
523
+
524
+static struct packet_offload vlan_packet_offloads[] __read_mostly = {
525
+ {
526
+ .type = cpu_to_be16(ETH_P_8021Q),
527
+ .priority = 10,
528
+ .callbacks = {
529
+ .gro_receive = vlan_gro_receive,
530
+ .gro_complete = vlan_gro_complete,
531
+ },
532
+ },
533
+ {
534
+ .type = cpu_to_be16(ETH_P_8021AD),
535
+ .priority = 10,
536
+ .callbacks = {
537
+ .gro_receive = vlan_gro_receive,
538
+ .gro_complete = vlan_gro_complete,
539
+ },
540
+ },
541
+};
542
+
543
+static int __init vlan_offload_init(void)
544
+{
545
+ unsigned int i;
546
+
547
+ for (i = 0; i < ARRAY_SIZE(vlan_packet_offloads); i++)
548
+ dev_add_offload(&vlan_packet_offloads[i]);
549
+
550
+ return 0;
551
+}
552
+
553
+fs_initcall(vlan_offload_init);