Commit cfe22689 authored by Gautam Dawar's avatar Gautam Dawar Committed by Michael S. Tsirkin

vdpa_sim: filter destination mac address

This patch implements a simple unicast filter for vDPA simulator.
Signed-off-by: default avatarJason Wang <jasowang@redhat.com>
Signed-off-by: default avatarGautam Dawar <gdawar@xilinx.com>
Message-Id: <20220330180436.24644-19-gdawar@xilinx.com>
Signed-off-by: default avatarMichael S. Tsirkin <mst@redhat.com>
parent ec103d98
...@@ -47,13 +47,28 @@ static void vdpasim_net_complete(struct vdpasim_virtqueue *vq, size_t len) ...@@ -47,13 +47,28 @@ static void vdpasim_net_complete(struct vdpasim_virtqueue *vq, size_t len)
local_bh_enable(); 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) static void vdpasim_net_work(struct work_struct *work)
{ {
struct vdpasim *vdpasim = container_of(work, struct vdpasim, work); struct vdpasim *vdpasim = container_of(work, struct vdpasim, work);
struct vdpasim_virtqueue *txq = &vdpasim->vqs[1]; struct vdpasim_virtqueue *txq = &vdpasim->vqs[1];
struct vdpasim_virtqueue *rxq = &vdpasim->vqs[0]; struct vdpasim_virtqueue *rxq = &vdpasim->vqs[0];
ssize_t read, write; ssize_t read, write;
size_t total_write;
int pkts = 0; int pkts = 0;
int err; int err;
...@@ -66,36 +81,34 @@ static void vdpasim_net_work(struct work_struct *work) ...@@ -66,36 +81,34 @@ static void vdpasim_net_work(struct work_struct *work)
goto out; goto out;
while (true) { while (true) {
total_write = 0;
err = vringh_getdesc_iotlb(&txq->vring, &txq->out_iov, NULL, err = vringh_getdesc_iotlb(&txq->vring, &txq->out_iov, NULL,
&txq->head, GFP_ATOMIC); &txq->head, GFP_ATOMIC);
if (err <= 0) if (err <= 0)
break; 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, err = vringh_getdesc_iotlb(&rxq->vring, NULL, &rxq->in_iov,
&rxq->head, GFP_ATOMIC); &rxq->head, GFP_ATOMIC);
if (err <= 0) { if (err <= 0) {
vringh_complete_iotlb(&txq->vring, txq->head, 0); vdpasim_net_complete(txq, 0);
break; break;
} }
while (true) { write = vringh_iov_push_iotlb(&rxq->vring, &rxq->in_iov,
read = vringh_iov_pull_iotlb(&txq->vring, &txq->out_iov, vdpasim->buffer, read);
vdpasim->buffer, if (write <= 0)
PAGE_SIZE); break;
if (read <= 0)
break;
write = vringh_iov_push_iotlb(&rxq->vring, &rxq->in_iov,
vdpasim->buffer, read);
if (write <= 0)
break;
total_write += write;
}
vdpasim_net_complete(txq, 0); vdpasim_net_complete(txq, 0);
vdpasim_net_complete(rxq, total_write); vdpasim_net_complete(rxq, write);
if (++pkts > 4) { if (++pkts > 4) {
schedule_work(&vdpasim->work); schedule_work(&vdpasim->work);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment