]> git.proxmox.com Git - mirror_ubuntu-focal-kernel.git/blobdiff - drivers/net/veth.c
tuntap: add sanity checks about msg_controllen in sendmsg
[mirror_ubuntu-focal-kernel.git] / drivers / net / veth.c
index 9f3c839f9e5f2cda2f103f943f94badc09691a2b..10a876f8831c7571ba3ac69bd22d35bf1ba478ff 100644 (file)
@@ -209,9 +209,10 @@ static void __veth_xdp_flush(struct veth_rq *rq)
 {
        /* Write ptr_ring before reading rx_notify_masked */
        smp_mb();
-       if (!rq->rx_notify_masked) {
-               rq->rx_notify_masked = true;
-               napi_schedule(&rq->xdp_napi);
+       if (!READ_ONCE(rq->rx_notify_masked) &&
+           napi_schedule_prep(&rq->xdp_napi)) {
+               WRITE_ONCE(rq->rx_notify_masked, true);
+               __napi_schedule(&rq->xdp_napi);
        }
 }
 
@@ -254,8 +255,6 @@ static netdev_tx_t veth_xmit(struct sk_buff *skb, struct net_device *dev)
        if (rxq < rcv->real_num_rx_queues) {
                rq = &rcv_priv->rq[rxq];
                rcv_xdp = rcu_access_pointer(rq->xdp_prog);
-               if (rcv_xdp)
-                       skb_record_rx_queue(skb, rxq);
        }
 
        skb_tx_timestamp(skb);
@@ -510,13 +509,15 @@ static struct sk_buff *veth_xdp_rcv_one(struct veth_rq *rq,
                                        struct veth_xdp_tx_bq *bq)
 {
        void *hard_start = frame->data - frame->headroom;
-       void *head = hard_start - sizeof(struct xdp_frame);
        int len = frame->len, delta = 0;
        struct xdp_frame orig_frame;
        struct bpf_prog *xdp_prog;
        unsigned int headroom;
        struct sk_buff *skb;
 
+       /* bpf_xdp_adjust_head() assures BPF cannot access xdp_frame area */
+       hard_start -= sizeof(struct xdp_frame);
+
        rcu_read_lock();
        xdp_prog = rcu_dereference(rq->xdp_prog);
        if (likely(xdp_prog)) {
@@ -538,7 +539,6 @@ static struct sk_buff *veth_xdp_rcv_one(struct veth_rq *rq,
                        break;
                case XDP_TX:
                        orig_frame = *frame;
-                       xdp.data_hard_start = head;
                        xdp.rxq->mem = frame->mem;
                        if (unlikely(veth_xdp_tx(rq->dev, &xdp, bq) < 0)) {
                                trace_xdp_exception(rq->dev, xdp_prog, act);
@@ -550,7 +550,6 @@ static struct sk_buff *veth_xdp_rcv_one(struct veth_rq *rq,
                        goto xdp_xmit;
                case XDP_REDIRECT:
                        orig_frame = *frame;
-                       xdp.data_hard_start = head;
                        xdp.rxq->mem = frame->mem;
                        if (xdp_do_redirect(rq->dev, &xdp, xdp_prog)) {
                                frame = &orig_frame;
@@ -572,7 +571,7 @@ static struct sk_buff *veth_xdp_rcv_one(struct veth_rq *rq,
        rcu_read_unlock();
 
        headroom = sizeof(struct xdp_frame) + frame->headroom - delta;
-       skb = veth_build_skb(head, headroom, len, 0);
+       skb = veth_build_skb(hard_start, headroom, len, 0);
        if (!skb) {
                xdp_return_frame(frame);
                goto err;
@@ -782,8 +781,10 @@ static int veth_poll(struct napi_struct *napi, int budget)
                /* Write rx_notify_masked before reading ptr_ring */
                smp_store_mb(rq->rx_notify_masked, false);
                if (unlikely(!__ptr_ring_empty(&rq->xdp_ring))) {
-                       rq->rx_notify_masked = true;
-                       napi_schedule(&rq->xdp_napi);
+                       if (napi_schedule_prep(&rq->xdp_napi)) {
+                               WRITE_ONCE(rq->rx_notify_masked, true);
+                               __napi_schedule(&rq->xdp_napi);
+                       }
                }
        }