Commit 3831ab2094f6b573617b0f53b663bba1f036dc45
1 parent
002437cd
qemu:virtio-net: Enable filtering based on MAC, promisc, broadcast and allmulti (Alex Williamson)
Make use of the new RX_MODE control virtqueue class by dropping packets the guest doesn't want to see. Signed-off-by: Alex Williamson <alex.williamson@hp.com> Signed-off-by: Anthony Liguori <aliguori@us.ibm.com> git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@6538 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
1 changed file
with
28 additions
and
0 deletions
hw/virtio-net.c
| ... | ... | @@ -222,6 +222,31 @@ static int receive_header(VirtIONet *n, struct iovec *iov, int iovcnt, |
| 222 | 222 | return offset; |
| 223 | 223 | } |
| 224 | 224 | |
| 225 | +static int receive_filter(VirtIONet *n, const uint8_t *buf, int size) | |
| 226 | +{ | |
| 227 | + static const uint8_t bcast[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; | |
| 228 | + uint8_t *ptr = (uint8_t *)buf; | |
| 229 | + | |
| 230 | + if (n->promisc) | |
| 231 | + return 1; | |
| 232 | + | |
| 233 | +#ifdef TAP_VNET_HDR | |
| 234 | + if (tap_has_vnet_hdr(n->vc->vlan->first_client)) | |
| 235 | + ptr += sizeof(struct virtio_net_hdr); | |
| 236 | +#endif | |
| 237 | + | |
| 238 | + if ((ptr[0] & 1) && n->allmulti) | |
| 239 | + return 1; | |
| 240 | + | |
| 241 | + if (!memcmp(ptr, bcast, sizeof(bcast))) | |
| 242 | + return 1; | |
| 243 | + | |
| 244 | + if (!memcmp(ptr, n->mac, ETH_ALEN)) | |
| 245 | + return 1; | |
| 246 | + | |
| 247 | + return 0; | |
| 248 | +} | |
| 249 | + | |
| 225 | 250 | static void virtio_net_receive(void *opaque, const uint8_t *buf, int size) |
| 226 | 251 | { |
| 227 | 252 | VirtIONet *n = opaque; |
| ... | ... | @@ -231,6 +256,9 @@ static void virtio_net_receive(void *opaque, const uint8_t *buf, int size) |
| 231 | 256 | if (!do_virtio_net_can_receive(n, size)) |
| 232 | 257 | return; |
| 233 | 258 | |
| 259 | + if (!receive_filter(n, buf, size)) | |
| 260 | + return; | |
| 261 | + | |
| 234 | 262 | /* hdr_len refers to the header we supply to the guest */ |
| 235 | 263 | hdr_len = n->mergeable_rx_bufs ? |
| 236 | 264 | sizeof(struct virtio_net_hdr_mrg_rxbuf) : sizeof(struct virtio_net_hdr); | ... | ... |