@@ -19,17 +19,23 @@ const (
1919
2020const (
2121 // dropNotifyV1Len is the amount of packet data provided in a v0/v1 drop notification.
22- dropNotifyV1Len = 36
22+ dropNotifyV1Len = 36
23+ dropPktmonNotifyV1Len = 57
2324)
2425
2526var dropNotifyLengthFromVersion = map [uint16 ]uint {
2627 DropNotifyVersion0 : dropNotifyV1Len , // retain backwards compatibility for testing.
2728 DropNotifyVersion1 : dropNotifyV1Len ,
2829}
2930
31+ var pktmonDropNotifyLengthFromVersion = map [uint16 ]uint {
32+ DropNotifyVersion1 : dropPktmonNotifyV1Len ,
33+ }
34+
3035var (
31- errUnexpectedDropNotifyLength = errors .New ("unexpected DropNotify data length" )
32- errInvalidDropNotifyVersion = errors .New ("invalid DropNotify version" )
36+ errUnexpectedDropNotifyLength = errors .New ("unexpected DropNotify data length" )
37+ errInvalidDropNotifyVersion = errors .New ("invalid DropNotify version" )
38+ errInvalidPktmonDropNotifyVersion = errors .New ("invalid Pktmon DropNotify version" )
3339)
3440
3541// DropNotify is the message format of a drop notification in the BPF ring buffer
@@ -50,6 +56,90 @@ type DropNotify struct {
5056 Ifindex uint32
5157}
5258
59+ type NetEventDataHeader struct {
60+ Type uint8
61+ Version uint16
62+ }
63+
64+ type PktmonEvtStreamPacketDescriptor struct {
65+ PacketOriginalLength uint32
66+ PacketLoggedLength uint32
67+ PacketMetadataLength uint32
68+ }
69+
70+ type PktmonEvtStreamMetadata struct {
71+ PktGroupID uint64
72+ PktCount uint16
73+ AppearanceCount uint16
74+ DirectionName uint16
75+ PacketType uint16
76+ ComponentID uint16
77+ EdgeID uint16
78+ FilterID uint16
79+ DropReason uint32
80+ DropLocation uint32
81+ ProcNum uint16
82+ Timestamp uint64
83+ }
84+
85+ type PktmonEvtStreamPacketHeader struct {
86+ EventID uint8
87+ PacketDescriptor PktmonEvtStreamPacketDescriptor
88+ Metadata PktmonEvtStreamMetadata
89+ }
90+
91+ type PktmonDropNotify struct {
92+ VersionHeader NetEventDataHeader
93+ PktmonHeader PktmonEvtStreamPacketHeader
94+ }
95+
96+ // DecodePktmonDrop will decode 'data' into the provided DropNotify structure
97+ func DecodePktmonDrop (data []byte , pdn * PktmonDropNotify ) error {
98+ if err := pdn .decodePktmonDrop (data ); err != nil {
99+ return err
100+ }
101+ return nil
102+ }
103+
104+ // DataOffset returns the offset from the beginning of PktmonDropNotify where the
105+ // notification data begins.
106+ func (n * PktmonDropNotify ) DataOffset () uint {
107+ return pktmonDropNotifyLengthFromVersion [n .VersionHeader .Version ]
108+ }
109+
110+ func (n * PktmonDropNotify ) decodePktmonDrop (data []byte ) error {
111+ if l := len (data ); l < dropPktmonNotifyV1Len {
112+ return fmt .Errorf ("%w: expected at least %d but got %d" , errUnexpectedDropNotifyLength , dropPktmonNotifyV1Len , l )
113+ }
114+ version := byteorder .Native .Uint16 (data [2 :4 ])
115+
116+ // Check against max version.
117+ if version > DropNotifyVersion1 {
118+ return fmt .Errorf ("%w: Unrecognized drop event version %d" , errInvalidPktmonDropNotifyVersion , version )
119+ }
120+
121+ // Decode logic for version = v1.
122+ n .VersionHeader .Type = data [0 ]
123+ n .VersionHeader .Version = version
124+ n .PktmonHeader .EventID = data [4 ]
125+ n .PktmonHeader .PacketDescriptor .PacketOriginalLength = byteorder .Native .Uint32 (data [5 :9 ])
126+ n .PktmonHeader .PacketDescriptor .PacketLoggedLength = byteorder .Native .Uint32 (data [9 :13 ])
127+ n .PktmonHeader .PacketDescriptor .PacketMetadataLength = byteorder .Native .Uint32 (data [13 :17 ])
128+ n .PktmonHeader .Metadata .PktGroupID = byteorder .Native .Uint64 (data [17 :25 ])
129+ n .PktmonHeader .Metadata .PktCount = byteorder .Native .Uint16 (data [25 :27 ])
130+ n .PktmonHeader .Metadata .AppearanceCount = byteorder .Native .Uint16 (data [27 :29 ])
131+ n .PktmonHeader .Metadata .DirectionName = byteorder .Native .Uint16 (data [29 :31 ])
132+ n .PktmonHeader .Metadata .PacketType = byteorder .Native .Uint16 (data [31 :33 ])
133+ n .PktmonHeader .Metadata .ComponentID = byteorder .Native .Uint16 (data [33 :35 ])
134+ n .PktmonHeader .Metadata .EdgeID = byteorder .Native .Uint16 (data [35 :37 ])
135+ n .PktmonHeader .Metadata .FilterID = byteorder .Native .Uint16 (data [37 :39 ])
136+ n .PktmonHeader .Metadata .DropReason = byteorder .Native .Uint32 (data [39 :43 ])
137+ n .PktmonHeader .Metadata .DropLocation = byteorder .Native .Uint32 (data [43 :47 ])
138+ n .PktmonHeader .Metadata .ProcNum = byteorder .Native .Uint16 (data [47 :49 ])
139+ n .PktmonHeader .Metadata .Timestamp = byteorder .Native .Uint64 (data [49 :57 ])
140+ return nil
141+ }
142+
53143// DecodeDropNotify will decode 'data' into the provided DropNotify structure
54144func DecodeDropNotify (data []byte , dn * DropNotify ) error {
55145 return dn .decodeDropNotify (data )
0 commit comments