diff options
Diffstat (limited to 'drivers/net/tun.c')
-rw-r--r-- | drivers/net/tun.c | 24 |
1 files changed, 23 insertions, 1 deletions
diff --git a/drivers/net/tun.c b/drivers/net/tun.c index e367d6310353..e7c5f4b2a9a6 100644 --- a/drivers/net/tun.c +++ b/drivers/net/tun.c | |||
@@ -180,6 +180,7 @@ struct tun_file { | |||
180 | struct list_head next; | 180 | struct list_head next; |
181 | struct tun_struct *detached; | 181 | struct tun_struct *detached; |
182 | struct skb_array tx_array; | 182 | struct skb_array tx_array; |
183 | struct xdp_rxq_info xdp_rxq; | ||
183 | }; | 184 | }; |
184 | 185 | ||
185 | struct tun_flow_entry { | 186 | struct tun_flow_entry { |
@@ -687,8 +688,10 @@ static void __tun_detach(struct tun_file *tfile, bool clean) | |||
687 | tun->dev->reg_state == NETREG_REGISTERED) | 688 | tun->dev->reg_state == NETREG_REGISTERED) |
688 | unregister_netdevice(tun->dev); | 689 | unregister_netdevice(tun->dev); |
689 | } | 690 | } |
690 | if (tun) | 691 | if (tun) { |
691 | skb_array_cleanup(&tfile->tx_array); | 692 | skb_array_cleanup(&tfile->tx_array); |
693 | xdp_rxq_info_unreg(&tfile->xdp_rxq); | ||
694 | } | ||
692 | sock_put(&tfile->sk); | 695 | sock_put(&tfile->sk); |
693 | } | 696 | } |
694 | } | 697 | } |
@@ -728,11 +731,13 @@ static void tun_detach_all(struct net_device *dev) | |||
728 | tun_napi_del(tun, tfile); | 731 | tun_napi_del(tun, tfile); |
729 | /* Drop read queue */ | 732 | /* Drop read queue */ |
730 | tun_queue_purge(tfile); | 733 | tun_queue_purge(tfile); |
734 | xdp_rxq_info_unreg(&tfile->xdp_rxq); | ||
731 | sock_put(&tfile->sk); | 735 | sock_put(&tfile->sk); |
732 | } | 736 | } |
733 | list_for_each_entry_safe(tfile, tmp, &tun->disabled, next) { | 737 | list_for_each_entry_safe(tfile, tmp, &tun->disabled, next) { |
734 | tun_enable_queue(tfile); | 738 | tun_enable_queue(tfile); |
735 | tun_queue_purge(tfile); | 739 | tun_queue_purge(tfile); |
740 | xdp_rxq_info_unreg(&tfile->xdp_rxq); | ||
736 | sock_put(&tfile->sk); | 741 | sock_put(&tfile->sk); |
737 | } | 742 | } |
738 | BUG_ON(tun->numdisabled != 0); | 743 | BUG_ON(tun->numdisabled != 0); |
@@ -784,6 +789,22 @@ static int tun_attach(struct tun_struct *tun, struct file *file, | |||
784 | 789 | ||
785 | tfile->queue_index = tun->numqueues; | 790 | tfile->queue_index = tun->numqueues; |
786 | tfile->socket.sk->sk_shutdown &= ~RCV_SHUTDOWN; | 791 | tfile->socket.sk->sk_shutdown &= ~RCV_SHUTDOWN; |
792 | |||
793 | if (tfile->detached) { | ||
794 | /* Re-attach detached tfile, updating XDP queue_index */ | ||
795 | WARN_ON(!xdp_rxq_info_is_reg(&tfile->xdp_rxq)); | ||
796 | |||
797 | if (tfile->xdp_rxq.queue_index != tfile->queue_index) | ||
798 | tfile->xdp_rxq.queue_index = tfile->queue_index; | ||
799 | } else { | ||
800 | /* Setup XDP RX-queue info, for new tfile getting attached */ | ||
801 | err = xdp_rxq_info_reg(&tfile->xdp_rxq, | ||
802 | tun->dev, tfile->queue_index); | ||
803 | if (err < 0) | ||
804 | goto out; | ||
805 | err = 0; | ||
806 | } | ||
807 | |||
787 | rcu_assign_pointer(tfile->tun, tun); | 808 | rcu_assign_pointer(tfile->tun, tun); |
788 | rcu_assign_pointer(tun->tfiles[tun->numqueues], tfile); | 809 | rcu_assign_pointer(tun->tfiles[tun->numqueues], tfile); |
789 | tun->numqueues++; | 810 | tun->numqueues++; |
@@ -1508,6 +1529,7 @@ static struct sk_buff *tun_build_skb(struct tun_struct *tun, | |||
1508 | xdp.data = buf + pad; | 1529 | xdp.data = buf + pad; |
1509 | xdp_set_data_meta_invalid(&xdp); | 1530 | xdp_set_data_meta_invalid(&xdp); |
1510 | xdp.data_end = xdp.data + len; | 1531 | xdp.data_end = xdp.data + len; |
1532 | xdp.rxq = &tfile->xdp_rxq; | ||
1511 | orig_data = xdp.data; | 1533 | orig_data = xdp.data; |
1512 | act = bpf_prog_run_xdp(xdp_prog, &xdp); | 1534 | act = bpf_prog_run_xdp(xdp_prog, &xdp); |
1513 | 1535 | ||