vdpa_sim: filter destination mac address
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>
This commit is contained in:
parent
ec103d983b
commit
cfe2268929
@ -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)
|
|||||||
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);
|
||||||
|
Loading…
Reference in New Issue
Block a user