Revision 2d9aba39

b/hw/virtio-net.c
37 37
    uint8_t allmulti;
38 38
    struct {
39 39
        int in_use;
40
        int first_multi;
40 41
        uint8_t multi_overflow;
41 42
        uint8_t uni_overflow;
42 43
        uint8_t *macs;
......
100 101

  
101 102
    /* Flush any MAC and VLAN filter table state */
102 103
    n->mac_table.in_use = 0;
104
    n->mac_table.first_multi = 0;
103 105
    n->mac_table.multi_overflow = 0;
104 106
    n->mac_table.uni_overflow = 0;
105 107
    memset(n->mac_table.macs, 0, MAC_TABLE_ENTRIES * ETH_ALEN);
......
172 174
        return VIRTIO_NET_ERR;
173 175

  
174 176
    n->mac_table.in_use = 0;
177
    n->mac_table.first_multi = 0;
175 178
    n->mac_table.uni_overflow = 0;
176 179
    n->mac_table.multi_overflow = 0;
177 180
    memset(n->mac_table.macs, 0, MAC_TABLE_ENTRIES * ETH_ALEN);
......
190 193
        n->mac_table.uni_overflow = 1;
191 194
    }
192 195

  
196
    n->mac_table.first_multi = n->mac_table.in_use;
197

  
193 198
    mac_data.entries = ldl_le_p(elem->out_sg[2].iov_base);
194 199

  
195 200
    if (sizeof(mac_data.entries) +
......
359 364
        } else if (n->allmulti || n->mac_table.multi_overflow) {
360 365
            return 1;
361 366
        }
367

  
368
        for (i = n->mac_table.first_multi; i < n->mac_table.in_use; i++) {
369
            if (!memcmp(ptr, &n->mac_table.macs[i * ETH_ALEN], ETH_ALEN)) {
370
                return 1;
371
            }
372
        }
362 373
    } else { // unicast
363 374
        if (n->mac_table.uni_overflow) {
364 375
            return 1;
365 376
        } else if (!memcmp(ptr, n->mac, ETH_ALEN)) {
366 377
            return 1;
367 378
        }
368
    }
369 379

  
370
    for (i = 0; i < n->mac_table.in_use; i++) {
371
        if (!memcmp(ptr, &n->mac_table.macs[i * ETH_ALEN], ETH_ALEN))
372
            return 1;
380
        for (i = 0; i < n->mac_table.first_multi; i++) {
381
            if (!memcmp(ptr, &n->mac_table.macs[i * ETH_ALEN], ETH_ALEN)) {
382
                return 1;
383
            }
384
        }
373 385
    }
374 386

  
375 387
    return 0;
......
547 559
static int virtio_net_load(QEMUFile *f, void *opaque, int version_id)
548 560
{
549 561
    VirtIONet *n = opaque;
562
    int i;
550 563

  
551 564
    if (version_id < 2 || version_id > VIRTIO_NET_VM_VERSION)
552 565
        return -EINVAL;
......
597 610
        n->mac_table.uni_overflow = qemu_get_byte(f);
598 611
    }
599 612

  
613
    /* Find the first multicast entry in the saved MAC filter */
614
    for (i = 0; i < n->mac_table.in_use; i++) {
615
        if (n->mac_table.macs[i * ETH_ALEN] & 1) {
616
            break;
617
        }
618
    }
619
    n->mac_table.first_multi = i;
620

  
600 621
    if (n->tx_timer_active) {
601 622
        qemu_mod_timer(n->tx_timer,
602 623
                       qemu_get_clock(vm_clock) + TX_TIMER_INTERVAL);

Also available in: Unified diff