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); | ... | ... |