# DF-4082 — oce_tx returns 0 (success) when oce_insert_vlan_tag fails: mbuf
# leaked and packet silently dropped while the caller believes it was sent

File: sys/dev/netif/oce/oce_if.c (pass 2)
Class: error-path logic bug (memory leak + silent drop)

## Root cause

oce_tx() (sys/dev/netif/oce/oce_if.c):

	if (oce_tx_asic_stall_verify(sc, m)) {          /* 833 */
		m = oce_insert_vlan_tag(sc, m, &complete);/* 834 */
		if (!m) {
			device_printf(sc->dev, "Insertion unsuccessful\n");
			return 0;                        /* 837 — SUCCESS! */
		}
	}

oce_insert_vlan_tag (oce_if.c:2202-2236) returns NULL exactly when
`!M_WRITABLE(m)` (2207-2208) — i.e. read-only external mbufs (M_EXT with a
non-standard free/readonly mapping, e.g. sendfile-style or otherwise
EXT_RDONLY chains).

On that path:
- `*mpp` is left untouched (still the original mbuf),
- the WQ/pckts state is untouched,
- the function returns 0 = success.

Caller oce_start_locked (oce_if.c:1129-1147): rc == 0 → BPF tap (1144-1145) →
loop continues → **the dequeued mbuf is never freed and never transmitted**.
Per-packet mbuf(+cluster) leak plus silent loss, with a false success return.

Gating (narrow): needs oce_tx_asic_stall_verify == TRUE, i.e. BE3 rev A1
(asic_revision < 2, oce_if.c:2193-2200) AND QnQ/UMC mode (pvid/qnqid set,
oce_if.h:1162-1163) AND an IPv6 packet with extension headers
(oce_check_ipv6_ext_hdr, oce_if.c:2167-2191) AND a read-only mbuf. Extremely
narrow hardware profile — hence Low severity — but the error-path logic is
plainly wrong.

## Fix

	Return an error and let the caller free/requeue, or free locally:

```diff
 		if (!m) {
 			device_printf(sc->dev, "Insertion unsuccessful\n");
-			return 0;
+			return ENOBUFS;   /* caller frees *mpp */
 		}
```
(ENXIO/ENOMEM both work with oce_start_locked's handling at 1135-1142 — with
m != NULL it prepends back to the ifq instead of leaking.)

## Verification status

UNTESTED — hardware-gated (BE3-A1 + UMC/QnQ profile cannot be present in
QEMU).
