# DF-4794 — ig_hal VF: E1000_VF_SET_MULTICAST_OVERFLOW flag overwritten before send — PF never told to enable multicast promiscuous

File: `sys/dev/netif/ig_hal/e1000_vf.c` (pass 2)
Function: `e1000_update_mc_addr_list_vf()` — lines 400-437

## What happens

When an interface served by an igb VF (82576 VF `8086:10ca` / I350 VF
`8086:1520`, bound by `if_igb.c` — `IGB_DEVICE(82576_VF)`/`IGB_DEVICE(I350_VF)`,
`sys/dev/netif/igb/if_igb.c:108,123`) has more than 30 multicast groups
joined, the VF can only forward 30 hash values to the PF; the protocol bit
`E1000_VF_SET_MULTICAST_OVERFLOW` is what tells the PF "enable multicast
promiscuous for me". In DragonFly's ordering the flag is dead:

```c
if (mc_addr_count > 30) {
        msgbuf[0] |= E1000_VF_SET_MULTICAST_OVERFLOW;   /* :422 set */
        mc_addr_count = 30;
}

msgbuf[0] = E1000_VF_SET_MULTICAST;                     /* :426 KILLS it */
msgbuf[0] |= mc_addr_count << E1000_VT_MSGINFO_SHIFT;
```

`e1000_write_msg_read_ack(hw, msgbuf, E1000_VFMAILBOX_SIZE)` (:436) then
sends `msgbuf[0] = 0x001E0003` — count 30, no OVERFLOW. The PF therefore
programs only 30 hash bits and never enables multicast promiscuous: traffic
for every group whose solicited hash is not among the 30 forwarded bits is
silently dropped. With >30 groups joined, IPv6 solicited-node multicast for
later addresses is a typical casualty (broken ND → connectivity loss).

Upstream FreeBSD fixed the ordering (cgit `sys/dev/e1000/e1000_vf.c`,
`e1000_update_mc_addr_list_vf`): `msgbuf[0] = E1000_VF_SET_MULTICAST;` is
assigned *before* the overflow OR, keeping the flag.

## Reproduce (logic-level; hardware path documented below)

    cc -Wall -O2 -o mcmsg_demo mcmsg_demo.c && ./mcmsg_demo

Expected decisive output:

    === CURRENT DragonFly ordering ===
      mc_addr_count= 31: PF-visible msgbuf[0]=0x001e0003 (OVERFLOW flag LOST)
    === FIXED (upstream) ordering ===
      mc_addr_count= 31: PF-visible msgbuf[0]=0x009e0003 (OVERFLOW flag SET)

The demo replays the exact `msgbuf[0]` arithmetic with the real
`e1000_mbx.h` macro values; it is a deterministic logic check, not a
kernel-hardware reproduction (no SR-IOV igb VF device exists on the audit
guest — see env.txt).

## Fix

`fix.diff` hunk 2 (git-apply-clean against `sys/`; compile-validated on the
audit guest: BASE_CC_RC=0 / FIXED_CC_RC=0 — build.log).

## Runtime PoC status

`untested` — reproducing the data path needs an actual 82576/I350 VF
presented to the guest (SR-IOV passthrough); the QEMU audit guest is
virtio-only (`pciconf -l` shows no e1000 device). The logic-level behavior
is proven from source ordering + upstream divergence (VERDICT.md).
