vdpa_sim: filter destination mac address
authorGautam Dawar <gautam.dawar@xilinx.com>
Wed, 30 Mar 2022 18:03:58 +0000 (23:33 +0530)
committerMichael S. Tsirkin <mst@redhat.com>
Tue, 31 May 2022 16:45:08 +0000 (12:45 -0400)
This patch implements a simple unicast filter for vDPA simulator.

Signed-off-by: Jason Wang <jasowang@redhat.com>
Signed-off-by: Gautam Dawar <gdawar@xilinx.com>
Message-Id: <20220330180436.24644-19-gdawar@xilinx.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
drivers/vdpa/vdpa_sim/vdpa_sim_net.c

index f460717..5fa59d4 100644 (file)
@@ -47,13 +47,28 @@ static void vdpasim_net_complete(struct vdpasim_virtqueue *vq, size_t len)
        local_bh_enable();
 }
 
+static bool receive_filter(struct vdpasim *vdpasim, size_t len)
+{
+       bool modern = vdpasim->features & (1ULL << VIRTIO_F_VERSION_1);
+       size_t hdr_len = modern ? sizeof(struct virtio_net_hdr_v1) :
+                                 sizeof(struct virtio_net_hdr);
+       struct virtio_net_config *vio_config = vdpasim->config;
+
+       if (len < ETH_ALEN + hdr_len)
+               return false;
+
+       if (!strncmp(vdpasim->buffer + hdr_len, vio_config->mac, ETH_ALEN))
+               return true;
+
+       return false;
+}
+
 static void vdpasim_net_work(struct work_struct *work)
 {
        struct vdpasim *vdpasim = container_of(work, struct vdpasim, work);
        struct vdpasim_virtqueue *txq = &vdpasim->vqs[1];
        struct vdpasim_virtqueue *rxq = &vdpasim->vqs[0];
        ssize_t read, write;
-       size_t total_write;
        int pkts = 0;
        int err;
 
@@ -66,36 +81,34 @@ static void vdpasim_net_work(struct work_struct *work)
                goto out;
 
        while (true) {
-               total_write = 0;
                err = vringh_getdesc_iotlb(&txq->vring, &txq->out_iov, NULL,
                                           &txq->head, GFP_ATOMIC);
                if (err <= 0)
                        break;
 
+               read = vringh_iov_pull_iotlb(&txq->vring, &txq->out_iov,
+                                            vdpasim->buffer,
+                                            PAGE_SIZE);
+
+               if (!receive_filter(vdpasim, read)) {
+                       vdpasim_net_complete(txq, 0);
+                       continue;
+               }
+
                err = vringh_getdesc_iotlb(&rxq->vring, NULL, &rxq->in_iov,
                                           &rxq->head, GFP_ATOMIC);
                if (err <= 0) {
-                       vringh_complete_iotlb(&txq->vring, txq->head, 0);
+                       vdpasim_net_complete(txq, 0);
                        break;
                }
 
-               while (true) {
-                       read = vringh_iov_pull_iotlb(&txq->vring, &txq->out_iov,
-                                                    vdpasim->buffer,
-                                                    PAGE_SIZE);
-                       if (read <= 0)
-                               break;
-
-                       write = vringh_iov_push_iotlb(&rxq->vring, &rxq->in_iov,
-                                                     vdpasim->buffer, read);
-                       if (write <= 0)
-                               break;
-
-                       total_write += write;
-               }
+               write = vringh_iov_push_iotlb(&rxq->vring, &rxq->in_iov,
+                                             vdpasim->buffer, read);
+               if (write <= 0)
+                       break;
 
                vdpasim_net_complete(txq, 0);
-               vdpasim_net_complete(rxq, total_write);
+               vdpasim_net_complete(rxq, write);
 
                if (++pkts > 4) {
                        schedule_work(&vdpasim->work);