cilium/cilium · error

craft packet: %w

Error message

craft packet: %w

What it means

HaveSKBAdjustRoomL2RoomMACSupport serializes a fixed Ethernet/IPv4/UDP packet with gopacket to feed prog.Test(), because bpf_skb_adjust_room with BPF_ADJ_ROOM_MAC needs a valid L2 packet. If gopacket.SerializeLayers fails, the error is wrapped as 'craft packet: %w'. Failure here indicates a packet-construction problem, not a kernel limitation.

Source

Thrown at pkg/datapath/linux/probes/probes.go:496

		},
		&layers.IPv4{
			Version:  4,
			IHL:      5,
			Length:   49,
			Id:       0xCECB,
			TTL:      64,
			Protocol: layers.IPProtocolUDP,
			SrcIP:    net.IPv4(0xc0, 0xa8, 0xb2, 0x56),
			DstIP:    net.IPv4(0xc0, 0xa8, 0xb2, 0xff),
		},
		&layers.UDP{
			SrcPort: 23939,
			DstPort: 32412,
		},
		gopacket.Payload("M-SEARCH * HTTP/1.1\x0d\x0a"),
	)
	if err != nil {
		return fmt.Errorf("craft packet: %w", err)
	}

	ret, _, err := prog.Test(buf.Bytes())
	if err != nil {
		return err
	}
	if ret != 0 {
		return ebpf.ErrNotSupported
	}
	return nil
}

// HaveDeadCodeElim tests whether the kernel supports dead code elimination.
func HaveDeadCodeElim() error {
	spec := ebpf.ProgramSpec{
		Name: "test",
		Type: ebpf.XDP,
		Instructions: asm.Instructions{

View on GitHub (pinned to ac7b90affa)

Solutions

  1. Keep the hardcoded layer stack intact (Eth + IPv4 + UDP + payload) and lengths consistent.
  2. Use a fresh gopacket.NewSerializeBuffer() per serialization call.
  3. Check SerializeOptions — enable FixLengths only if all lengths can be computed; ensure IHL/Length fields remain valid.
  4. Upgrade/align the gopacket dependency version if serialization APIs changed.

Example fix

// before
err = gopacket.SerializeLayers(buf, gopacket.SerializeOptions{FixLengths: true, ComputeChecksums: true}, layers...)
// after
buf := gopacket.NewSerializeBuffer()
err = gopacket.SerializeLayers(buf, gopacket.SerializeOptions{},
	&layers.Ethernet{...}, &layers.IPv4{...}, &layers.UDP{...}, gopacket.Payload(...))
Defensive patterns

Strategy: validation

Validate before calling

// ensure the layer stack is well-formed before serialization
func validTestPacketLayers(eth *layers.Ethernet, ip *layers.IPv4, udp *layers.UDP) bool {
	return eth != nil && ip != nil && udp != nil && ip.IHL == 5
}

Try / catch

err := probes.HaveSKBAdjustRoomL2RoomMACSupport(logger)
if err != nil && !errors.Is(err, ebpf.ErrNotSupported) {
	// includes 'craft packet:' failures
	log.Warn("skb_adjust_room probe failed unexpectedly", "err", err)
}

Prevention

When it happens

Trigger: gopacket.SerializeLayers returns an error while building the hardcoded test packet — e.g. nil layer in the options, an invalid SerializeOptions (FixLengths computing an impossible length), or buffer reuse misuse.

Common situations: Custom patches that alter the layer stack or payload; passing a buffer already containing bytes; modifying the hardcoded layers and producing inconsistent lengths; gopacket API/version changes.

Related errors


AI-assisted analysis of cilium/cilium@ac7b90affa (2026-08-31). Data as JSON: /api/errors/c0f611e86542004a. Report an issue: GitHub.