Skip to content

Commit dcc6cab

Browse files
authored
Add Sequence field to OpError for better error correlation (#236)
When a message with an errno is returned, it triggers an error in checkMessage and is not passed back to the caller. This can make it difficult to match the error to the specific message that caused it when using conn.SendMessages. This change includes the message’s Sequence value in OpError, making it easier to identify which message the error corresponds to.
1 parent b375150 commit dcc6cab

File tree

5 files changed

+42
-19
lines changed

5 files changed

+42
-19
lines changed

conn_linux_error_test.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,8 +43,9 @@ func TestConnReceiveErrorLinux(t *testing.T) {
4343
Data: []byte{0xfe, 0xff, 0xff, 0xff},
4444
}},
4545
want: &netlink.OpError{
46-
Op: "receive",
47-
Err: unix.ENOENT,
46+
Op: "receive",
47+
Err: unix.ENOENT,
48+
Sequence: 1,
4849
},
4950
},
5051
{

errors.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,11 @@ type OpError struct {
6969
// is not set, both of these fields will be empty.
7070
Message string
7171
Offset int
72+
73+
// Sequence is the netlink message sequence number associated with the
74+
// error. This field is only populated if the error was produced as the
75+
// result of a netlink message; otherwise, it will be zero.
76+
Sequence uint32
7277
}
7378

7479
// newOpError is a small wrapper for creating an OpError. As a convenience, it

internal/integration/integration_linux_test.go

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -126,13 +126,18 @@ func TestIntegrationRTNetlinkStrictCheckExtendedAcknowledge(t *testing.T) {
126126
t.Fatalf("failed to marshal request: %v", err)
127127
}
128128

129-
_, err = c.Execute(netlink.Message{
129+
sent, err := c.Send(netlink.Message{
130130
Header: netlink.Header{
131131
Type: unix.RTM_GETROUTE,
132132
Flags: netlink.Request | netlink.Dump,
133133
},
134134
Data: b,
135135
})
136+
if err != nil {
137+
t.Fatalf("failed to send request: %v", err)
138+
}
139+
140+
_, err = c.Receive()
136141

137142
oerr, ok := err.(*netlink.OpError)
138143
if !ok {
@@ -143,9 +148,10 @@ func TestIntegrationRTNetlinkStrictCheckExtendedAcknowledge(t *testing.T) {
143148
// offset just in case things change.
144149

145150
want := &netlink.OpError{
146-
Op: "receive",
147-
Err: unix.EINVAL,
148-
Message: "Invalid values in header for FIB dump request",
151+
Op: "receive",
152+
Err: unix.EINVAL,
153+
Message: "Invalid values in header for FIB dump request",
154+
Sequence: sent.Header.Sequence,
149155
}
150156

151157
if diff := cmp.Diff(want, oerr); diff != "" {
@@ -325,6 +331,9 @@ func TestIntegrationEthtoolExtendedAcknowledge(t *testing.T) {
325331
}
326332
oerr.Offset = 0
327333

334+
// Reset Sequence because we do not have access to the sent message.
335+
oerr.Sequence = 0
336+
328337
want := &netlink.OpError{
329338
Op: "receive",
330339
Err: unix.ENODEV,

message.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -293,7 +293,8 @@ func checkMessage(m Message) error {
293293
// Error code is a negative integer, convert it into an OS-specific raw
294294
// system call error, but do not wrap with os.NewSyscallError to signify
295295
// that this error was produced by a netlink message; not a system call.
296-
Err: newError(-1 * int(c)),
296+
Err: newError(-1 * int(c)),
297+
Sequence: m.Header.Sequence,
297298
}
298299

299300
// TODO(mdlayher): investigate the Capped flag.

message_linux_test.go

Lines changed: 19 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -65,15 +65,19 @@ func Test_checkMessageExtendedAcknowledgementTLVs(t *testing.T) {
6565
Header: Header{
6666
Type: Error,
6767
// Indicate the use of extended acknowledgement.
68-
Flags: AcknowledgeTLVs,
68+
Flags: AcknowledgeTLVs,
69+
Sequence: 3258842681,
6970
},
7071
Data: packExtACK(
7172
-1,
7273
// The caller's request message with arbitrary bytes that we
7374
// skip over when parsing the TLVs.
7475
&Message{
75-
Header: Header{Length: 4},
76-
Data: []byte{0xff, 0xff, 0xff, 0xff},
76+
Header: Header{
77+
Length: 4,
78+
Sequence: 3258842681,
79+
},
80+
Data: []byte{0xff, 0xff, 0xff, 0xff},
7781
},
7882
// The actual extended acknowledgement TLVs.
7983
[]Attribute{
@@ -89,10 +93,11 @@ func Test_checkMessageExtendedAcknowledgementTLVs(t *testing.T) {
8993
),
9094
},
9195
err: &OpError{
92-
Op: "receive",
93-
Err: unix.Errno(1),
94-
Message: "bad request",
95-
Offset: 2,
96+
Op: "receive",
97+
Err: unix.Errno(1),
98+
Message: "bad request",
99+
Offset: 2,
100+
Sequence: 3258842681,
96101
},
97102
},
98103
{
@@ -101,7 +106,8 @@ func Test_checkMessageExtendedAcknowledgementTLVs(t *testing.T) {
101106
Header: Header{
102107
Type: Done,
103108
// Indicate the use of extended acknowledgement.
104-
Flags: Multi | AcknowledgeTLVs,
109+
Flags: Multi | AcknowledgeTLVs,
110+
Sequence: 3258842681,
105111
},
106112
Data: packExtACK(
107113
-1,
@@ -120,10 +126,11 @@ func Test_checkMessageExtendedAcknowledgementTLVs(t *testing.T) {
120126
),
121127
},
122128
err: &OpError{
123-
Op: "receive",
124-
Err: unix.Errno(1),
125-
Message: "bad request",
126-
Offset: 2,
129+
Op: "receive",
130+
Err: unix.Errno(1),
131+
Message: "bad request",
132+
Offset: 2,
133+
Sequence: 3258842681,
127134
},
128135
},
129136
}

0 commit comments

Comments
 (0)