aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/tun.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/tun.c')
-rw-r--r--drivers/net/tun.c24
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
185struct tun_flow_entry { 186struct 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