Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 21 additions & 12 deletions pkg/plugin/ebpfwindows/datapath_drop_windows.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,16 +21,17 @@
// dropNotifyV1Len is the amount of packet data provided in a v0/v1 drop notification.
dropNotifyV1Len = 36
dropPktmonNotifyV1Len = 57
maxCapLength = 128
)

var dropNotifyLengthFromVersion = map[uint16]uint{
DropNotifyVersion0: dropNotifyV1Len, // retain backwards compatibility for testing.
DropNotifyVersion1: dropNotifyV1Len,
}

// var PktmonDropNotifyLengthFromVersion = map[uint16]uint{
// DropNotifyVersion0: dropPktmonNotifyV1Len, // retain backwards compatibility for testing.
// }
var PktmonDropNotifyLengthFromVersion = map[uint16]uint{
DropNotifyVersion1: dropPktmonNotifyV1Len, // retain backwards compatibility for testing.
}

var (
errUnexpectedDropNotifyLength = errors.New("unexpected DropNotify data length")
Expand All @@ -40,7 +41,7 @@
// DropNotify is the message format of a drop notification in the BPF ring buffer
type DropNotify struct {
Type uint8
SubType uint8
SubType uint32
Source uint16
Hash uint32
OrigLen uint32
Expand Down Expand Up @@ -93,19 +94,19 @@
}

// DecodeDropNotify will decode 'data' into the provided DropNotify structure
func DecodePktmonDrop(data []byte, dn *DropNotify) error {
pdn := &PktmonDropNotify{}
func DecodePktmonDrop(data []byte, pdn *PktmonDropNotify) error {
if err := pdn.decodePktmonDrop(data); err != nil {
return err
}
dn.Type = 1
dn.SubType = uint8(pdn.PktmonHeader.Metadata.DropReason)
dn.OrigLen = 128
dn.CapLen = 128
dn.Version = pdn.VersionHeader.Version
return nil
}

// DataOffset returns the offset from the beginning of PktmonDropNotify where the
// notification data begins.
func (n *PktmonDropNotify) DataOffset() uint {
return dropNotifyLengthFromVersion[n.VersionHeader.Version]
}

func (n *PktmonDropNotify) decodePktmonDrop(data []byte) error {
if l := len(data); l < dropPktmonNotifyV1Len {
return fmt.Errorf("%w: expected at least %d but got %d", errUnexpectedDropNotifyLength, dropPktmonNotifyV1Len, l)
Expand Down Expand Up @@ -142,6 +143,14 @@
return nil
}

func (n *PktmonDropNotify) ConvertToDropNotify(dn *DropNotify) {
dn.Type = 1
dn.SubType = n.PktmonHeader.Metadata.DropReason
dn.OrigLen = n.PktmonHeader.PacketDescriptor.PacketOriginalLength
dn.CapLen = uint16(min(maxCapLength, dn.OrigLen))

Check failure on line 150 in pkg/plugin/ebpfwindows/datapath_drop_windows.go

View workflow job for this annotation

GitHub Actions / Lint (windows, arm64)

G115: integer overflow conversion uint32 -> uint16 (gosec)

Check failure on line 150 in pkg/plugin/ebpfwindows/datapath_drop_windows.go

View workflow job for this annotation

GitHub Actions / Lint (windows, amd64)

G115: integer overflow conversion uint32 -> uint16 (gosec)
dn.Version = n.VersionHeader.Version
}

// DecodeDropNotify will decode 'data' into the provided DropNotify structure
func DecodeDropNotify(data []byte, dn *DropNotify) error {
return dn.decodeDropNotify(data)
Expand All @@ -161,7 +170,7 @@

// Decode logic for version >= v0/v1.
n.Type = data[0]
n.SubType = data[1]
n.SubType = uint32(data[1])
n.Source = byteorder.Native.Uint16(data[2:4])
n.Hash = byteorder.Native.Uint32(data[4:8])
n.OrigLen = byteorder.Native.Uint32(data[8:12])
Expand Down
21 changes: 13 additions & 8 deletions pkg/plugin/ebpfwindows/parser_windows.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import (
)

const MaxInt = int(^uint(0) >> 1)
const MessageTypePktmonDrop = 100

// Parser is a parser for L3/L4 payloads
type Parser struct {
Expand Down Expand Up @@ -143,8 +144,6 @@ func (p *Parser) Decode(monitorEvent *observerTypes.MonitorEvent) (*v1.Event, er
}
}

const MessageTypePktmonDrop = 100

// Decode decodes the data from 'data' into 'decoded'
func (p *Parser) decode(data []byte, decoded *pb.Flow) error {
if len(data) == 0 {
Expand All @@ -157,7 +156,7 @@ func (p *Parser) decode(data []byte, decoded *pb.Flow) error {
var offset uint
var dn *DropNotify
var tn *TraceNotify
var eventSubType uint8
var eventSubType uint32
var authType pb.AuthType

switch eventType {
Expand All @@ -179,7 +178,7 @@ func (p *Parser) decode(data []byte, decoded *pb.Flow) error {
if err := DecodeTraceNotify(data, tn); err != nil {
return fmt.Errorf("failed to parse trace: %w", err)
}
eventSubType = tn.ObsPoint
eventSubType = uint32(tn.ObsPoint)

if tn.ObsPoint != 0 {
decoded.TraceObservationPoint = pb.TraceObservationPoint(tn.ObsPoint)
Expand All @@ -199,13 +198,19 @@ func (p *Parser) decode(data []byte, decoded *pb.Flow) error {
case MessageTypePktmonDrop:
slog.Info("Reached pktmon drop event")

dn = &DropNotify{}
if err := DecodePktmonDrop(data, dn); err != nil {
pdn := &PktmonDropNotify{}
if err := DecodePktmonDrop(data, pdn); err != nil {
return fmt.Errorf("failed to parse pktmon drop here: %w", err)
}
offset = pdn.DataOffset()

dn = &DropNotify{}
pdn.ConvertToDropNotify(dn)
dn.Type = monitorAPI.MessageTypeDrop
slog.Info("Pktmon DropNotify", "PktmonNotify", pdn)
slog.Info("Pktmon DropNotify", "DropNotify", dn)

eventSubType = dn.SubType
offset = 57
if offset > uint(MaxInt) {
return fmt.Errorf("%w: %d", errDataOffsetTooLarge, offset)
}
Expand Down Expand Up @@ -507,7 +512,7 @@ func decodeIsReply(tn *TraceNotify) *wrapperspb.BoolValue {
}
}

func decodeCiliumEventType(eventType, eventSubType uint8) *pb.CiliumEventType {
func decodeCiliumEventType(eventType uint8, eventSubType uint32) *pb.CiliumEventType {
return &pb.CiliumEventType{
Type: int32(eventType),
SubType: int32(eventSubType),
Expand Down
47 changes: 25 additions & 22 deletions test/e2e/tools/event-writer/bpf_event_writer.c
Original file line number Diff line number Diff line change
Expand Up @@ -270,28 +270,6 @@ event_writer(xdp_md_t* ctx) {

drp_elm->subtype = 9;
bpf_perf_event_output(ctx, &cilium_events, EBPF_MAP_FLAG_CURRENT_CPU , drp_elm, sizeof(struct drop_notify));

// Create Windows specific drop event with hardcoded reason code
{
struct metrics_value *win_entry, win_new_entry = {};
struct windows_metrics_key win_key = {};

win_key.type = -DROP_PKTMON;
win_key.reason = Drop_FL_InterfaceNotReady;
win_key.dir = METRIC_INGRESS;
win_key.line = 0;
win_key.file = 0;

win_entry = bpf_map_lookup_elem(&windows_metrics, &win_key);
if (win_entry) {
win_entry->count += 1;
win_entry->bytes += size_to_copy;
} else {
win_new_entry.count = 1;
win_new_entry.bytes = size_to_copy;
bpf_map_update_elem(&windows_metrics, &win_key, &win_new_entry, 0);
}
}
}
else if (flt_evttype == PKTMON_NOTIFY_DROP) {
struct pktmon_notify* pkt_drp_elm;
Expand Down Expand Up @@ -336,6 +314,31 @@ event_writer(xdp_md_t* ctx) {

// memcpy(drp_elm->data, ctx->data, size_to_copy);
bpf_perf_event_output(ctx, &cilium_events, EBPF_MAP_FLAG_CURRENT_CPU , pkt_drp_elm, sizeof(struct pktmon_notify));
pkt_drp_elm->pktmon_header.metadata.drop_reason = 0x10000000;
bpf_perf_event_output(ctx, &cilium_events, EBPF_MAP_FLAG_CURRENT_CPU , pkt_drp_elm, sizeof(struct pktmon_notify));


// Create Windows specific drop event with hardcoded reason code
{
struct metrics_value *win_entry, win_new_entry = {};
struct windows_metrics_key win_key = {};

win_key.type = -DROP_PKTMON;
win_key.reason = Drop_FL_InterfaceNotReady;
win_key.dir = METRIC_INGRESS;
win_key.line = 0;
win_key.file = 0;

win_entry = bpf_map_lookup_elem(&windows_metrics, &win_key);
if (win_entry) {
win_entry->count += 1;
win_entry->bytes += size_to_copy;
} else {
win_new_entry.count = 1;
win_new_entry.bytes = size_to_copy;
bpf_map_update_elem(&windows_metrics, &win_key, &win_new_entry, 0);
}
}
}
update_metrics(size_to_copy, METRIC_INGRESS, reason, 0, 0);

Expand Down
Loading