1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138
|
package netlink
import (
"errors"
"fmt"
"net"
"os"
"strings"
)
// Error messages which can be returned by Validate.
var (
errMismatchedSequence = errors.New("mismatched sequence in netlink reply")
errMismatchedPID = errors.New("mismatched PID in netlink reply")
errShortErrorMessage = errors.New("not enough data for netlink error code")
)
// Errors which can be returned by a Socket that does not implement
// all exposed methods of Conn.
var errNotSupported = errors.New("operation not supported")
// notSupported provides a concise constructor for "not supported" errors.
func notSupported(op string) error {
return newOpError(op, errNotSupported)
}
// IsNotExist determines if an error is produced as the result of querying some
// file, object, resource, etc. which does not exist.
//
// Deprecated: use errors.Unwrap and/or `errors.Is(err, os.Permission)` in Go
// 1.13+.
func IsNotExist(err error) bool {
switch err := err.(type) {
case *OpError:
// Unwrap the inner error and use the stdlib's logic.
return os.IsNotExist(err.Err)
default:
return os.IsNotExist(err)
}
}
var (
_ error = &OpError{}
_ net.Error = &OpError{}
// Ensure compatibility with Go 1.13+ errors package.
_ interface{ Unwrap() error } = &OpError{}
)
// An OpError is an error produced as the result of a failed netlink operation.
type OpError struct {
// Op is the operation which caused this OpError, such as "send"
// or "receive".
Op string
// Err is the underlying error which caused this OpError.
//
// If Err was produced by a system call error, Err will be of type
// *os.SyscallError. If Err was produced by an error code in a netlink
// message, Err will contain a raw error value type such as a unix.Errno.
//
// Most callers should inspect Err using errors.Is from the standard
// library.
Err error
// Message and Offset contain additional error information provided by the
// kernel when the ExtendedAcknowledge option is set on a Conn and the
// kernel indicates the AcknowledgeTLVs flag in a response. If this option
// is not set, both of these fields will be empty.
Message string
Offset int
}
// newOpError is a small wrapper for creating an OpError. As a convenience, it
// returns nil if the input err is nil: akin to os.NewSyscallError.
func newOpError(op string, err error) error {
if err == nil {
return nil
}
return &OpError{
Op: op,
Err: err,
}
}
func (e *OpError) Error() string {
if e == nil {
return "<nil>"
}
var sb strings.Builder
_, _ = sb.WriteString(fmt.Sprintf("netlink %s: %v", e.Op, e.Err))
if e.Message != "" || e.Offset != 0 {
_, _ = sb.WriteString(fmt.Sprintf(", offset: %d, message: %q",
e.Offset, e.Message))
}
return sb.String()
}
// Unwrap unwraps the internal Err field for use with errors.Unwrap.
func (e *OpError) Unwrap() error { return e.Err }
// Portions of this code taken from the Go standard library:
//
// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
type timeout interface {
Timeout() bool
}
// Timeout reports whether the error was caused by an I/O timeout.
func (e *OpError) Timeout() bool {
if ne, ok := e.Err.(*os.SyscallError); ok {
t, ok := ne.Err.(timeout)
return ok && t.Timeout()
}
t, ok := e.Err.(timeout)
return ok && t.Timeout()
}
type temporary interface {
Temporary() bool
}
// Temporary reports whether an operation may succeed if retried.
func (e *OpError) Temporary() bool {
if ne, ok := e.Err.(*os.SyscallError); ok {
t, ok := ne.Err.(temporary)
return ok && t.Temporary()
}
t, ok := e.Err.(temporary)
return ok && t.Temporary()
}
|