Skip to content

Commit

Permalink
Merge branch 'vishvananda:main' into main
Browse files Browse the repository at this point in the history
  • Loading branch information
gunofmoon authored Nov 26, 2024
2 parents 7502e5a + 976bd8d commit 552d5d4
Show file tree
Hide file tree
Showing 32 changed files with 743 additions and 254 deletions.
15 changes: 11 additions & 4 deletions addr_linux.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package netlink

import (
"errors"
"fmt"
"net"
"strings"
Expand Down Expand Up @@ -169,21 +170,27 @@ func (h *Handle) addrHandle(link Link, addr *Addr, req *nl.NetlinkRequest) error
// AddrList gets a list of IP addresses in the system.
// Equivalent to: `ip addr show`.
// The list can be filtered by link and ip family.
//
// If the returned error is [ErrDumpInterrupted], results may be inconsistent
// or incomplete.
func AddrList(link Link, family int) ([]Addr, error) {
return pkgHandle.AddrList(link, family)
}

// AddrList gets a list of IP addresses in the system.
// Equivalent to: `ip addr show`.
// The list can be filtered by link and ip family.
//
// If the returned error is [ErrDumpInterrupted], results may be inconsistent
// or incomplete.
func (h *Handle) AddrList(link Link, family int) ([]Addr, error) {
req := h.newNetlinkRequest(unix.RTM_GETADDR, unix.NLM_F_DUMP)
msg := nl.NewIfAddrmsg(family)
req.AddData(msg)

msgs, err := req.Execute(unix.NETLINK_ROUTE, unix.RTM_NEWADDR)
if err != nil {
return nil, err
msgs, executeErr := req.Execute(unix.NETLINK_ROUTE, unix.RTM_NEWADDR)
if executeErr != nil && !errors.Is(executeErr, ErrDumpInterrupted) {
return nil, executeErr
}

indexFilter := 0
Expand Down Expand Up @@ -212,7 +219,7 @@ func (h *Handle) AddrList(link Link, family int) ([]Addr, error) {
res = append(res, addr)
}

return res, nil
return res, executeErr
}

func parseAddr(m []byte) (addr Addr, family int, err error) {
Expand Down
15 changes: 11 additions & 4 deletions bridge_linux.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package netlink

import (
"errors"
"fmt"

"github.com/vishvananda/netlink/nl"
Expand All @@ -9,21 +10,27 @@ import (

// BridgeVlanList gets a map of device id to bridge vlan infos.
// Equivalent to: `bridge vlan show`
//
// If the returned error is [ErrDumpInterrupted], results may be inconsistent
// or incomplete.
func BridgeVlanList() (map[int32][]*nl.BridgeVlanInfo, error) {
return pkgHandle.BridgeVlanList()
}

// BridgeVlanList gets a map of device id to bridge vlan infos.
// Equivalent to: `bridge vlan show`
//
// If the returned error is [ErrDumpInterrupted], results may be inconsistent
// or incomplete.
func (h *Handle) BridgeVlanList() (map[int32][]*nl.BridgeVlanInfo, error) {
req := h.newNetlinkRequest(unix.RTM_GETLINK, unix.NLM_F_DUMP)
msg := nl.NewIfInfomsg(unix.AF_BRIDGE)
req.AddData(msg)
req.AddData(nl.NewRtAttr(unix.IFLA_EXT_MASK, nl.Uint32Attr(uint32(nl.RTEXT_FILTER_BRVLAN))))

msgs, err := req.Execute(unix.NETLINK_ROUTE, unix.RTM_NEWLINK)
if err != nil {
return nil, err
msgs, executeErr := req.Execute(unix.NETLINK_ROUTE, unix.RTM_NEWLINK)
if executeErr != nil && !errors.Is(executeErr, ErrDumpInterrupted) {
return nil, executeErr
}
ret := make(map[int32][]*nl.BridgeVlanInfo)
for _, m := range msgs {
Expand Down Expand Up @@ -51,7 +58,7 @@ func (h *Handle) BridgeVlanList() (map[int32][]*nl.BridgeVlanInfo, error) {
}
}
}
return ret, nil
return ret, executeErr
}

// BridgeVlanAdd adds a new vlan filter entry
Expand Down
16 changes: 12 additions & 4 deletions chain_linux.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package netlink

import (
"errors"

"github.com/vishvananda/netlink/nl"
"golang.org/x/sys/unix"
)
Expand Down Expand Up @@ -56,13 +58,19 @@ func (h *Handle) chainModify(cmd, flags int, link Link, chain Chain) error {
// ChainList gets a list of chains in the system.
// Equivalent to: `tc chain list`.
// The list can be filtered by link.
//
// If the returned error is [ErrDumpInterrupted], results may be inconsistent
// or incomplete.
func ChainList(link Link, parent uint32) ([]Chain, error) {
return pkgHandle.ChainList(link, parent)
}

// ChainList gets a list of chains in the system.
// Equivalent to: `tc chain list`.
// The list can be filtered by link.
//
// If the returned error is [ErrDumpInterrupted], results may be inconsistent
// or incomplete.
func (h *Handle) ChainList(link Link, parent uint32) ([]Chain, error) {
req := h.newNetlinkRequest(unix.RTM_GETCHAIN, unix.NLM_F_DUMP)
index := int32(0)
Expand All @@ -78,9 +86,9 @@ func (h *Handle) ChainList(link Link, parent uint32) ([]Chain, error) {
}
req.AddData(msg)

msgs, err := req.Execute(unix.NETLINK_ROUTE, unix.RTM_NEWCHAIN)
if err != nil {
return nil, err
msgs, executeErr := req.Execute(unix.NETLINK_ROUTE, unix.RTM_NEWCHAIN)
if executeErr != nil && !errors.Is(executeErr, ErrDumpInterrupted) {
return nil, executeErr
}

var res []Chain
Expand Down Expand Up @@ -108,5 +116,5 @@ func (h *Handle) ChainList(link Link, parent uint32) ([]Chain, error) {
res = append(res, chain)
}

return res, nil
return res, executeErr
}
14 changes: 10 additions & 4 deletions class_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -201,14 +201,20 @@ func classPayload(req *nl.NetlinkRequest, class Class) error {

// ClassList gets a list of classes in the system.
// Equivalent to: `tc class show`.
//
// Generally returns nothing if link and parent are not specified.
// If the returned error is [ErrDumpInterrupted], results may be inconsistent
// or incomplete.
func ClassList(link Link, parent uint32) ([]Class, error) {
return pkgHandle.ClassList(link, parent)
}

// ClassList gets a list of classes in the system.
// Equivalent to: `tc class show`.
//
// Generally returns nothing if link and parent are not specified.
// If the returned error is [ErrDumpInterrupted], results may be inconsistent
// or incomplete.
func (h *Handle) ClassList(link Link, parent uint32) ([]Class, error) {
req := h.newNetlinkRequest(unix.RTM_GETTCLASS, unix.NLM_F_DUMP)
msg := &nl.TcMsg{
Expand All @@ -222,9 +228,9 @@ func (h *Handle) ClassList(link Link, parent uint32) ([]Class, error) {
}
req.AddData(msg)

msgs, err := req.Execute(unix.NETLINK_ROUTE, unix.RTM_NEWTCLASS)
if err != nil {
return nil, err
msgs, executeErr := req.Execute(unix.NETLINK_ROUTE, unix.RTM_NEWTCLASS)
if executeErr != nil && !errors.Is(executeErr, ErrDumpInterrupted) {
return nil, executeErr
}

var res []Class
Expand Down Expand Up @@ -295,7 +301,7 @@ func (h *Handle) ClassList(link Link, parent uint32) ([]Class, error) {
res = append(res, class)
}

return res, nil
return res, executeErr
}

func parseHtbClassData(class Class, data []syscall.NetlinkRouteAttr) (bool, error) {
Expand Down
30 changes: 21 additions & 9 deletions conntrack_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"errors"
"fmt"
"net"
"strings"
"time"

"github.com/vishvananda/netlink/nl"
Expand Down Expand Up @@ -44,6 +45,9 @@ type InetFamily uint8

// ConntrackTableList returns the flow list of a table of a specific family
// conntrack -L [table] [options] List conntrack or expectation table
//
// If the returned error is [ErrDumpInterrupted], results may be inconsistent
// or incomplete.
func ConntrackTableList(table ConntrackTableType, family InetFamily) ([]*ConntrackFlow, error) {
return pkgHandle.ConntrackTableList(table, family)
}
Expand Down Expand Up @@ -83,10 +87,13 @@ func ConntrackDeleteFilters(table ConntrackTableType, family InetFamily, filters

// ConntrackTableList returns the flow list of a table of a specific family using the netlink handle passed
// conntrack -L [table] [options] List conntrack or expectation table
//
// If the returned error is [ErrDumpInterrupted], results may be inconsistent
// or incomplete.
func (h *Handle) ConntrackTableList(table ConntrackTableType, family InetFamily) ([]*ConntrackFlow, error) {
res, err := h.dumpConntrackTable(table, family)
if err != nil {
return nil, err
res, executeErr := h.dumpConntrackTable(table, family)
if executeErr != nil && !errors.Is(executeErr, ErrDumpInterrupted) {
return nil, executeErr
}

// Deserialize all the flows
Expand All @@ -95,7 +102,7 @@ func (h *Handle) ConntrackTableList(table ConntrackTableType, family InetFamily)
result = append(result, parseRawData(dataRaw))
}

return result, nil
return result, executeErr
}

// ConntrackTableFlush flushes all the flows of a specified table using the netlink handle passed
Expand Down Expand Up @@ -158,21 +165,26 @@ func (h *Handle) ConntrackDeleteFilters(table ConntrackTableType, family InetFam
}

var matched uint
var errMsgs []string
for _, dataRaw := range res {
flow := parseRawData(dataRaw)
for _, filter := range filters {
if match := filter.MatchConntrackFlow(flow); match {
req2 := h.newConntrackRequest(table, family, nl.IPCTNL_MSG_CT_DELETE, unix.NLM_F_ACK)
// skip the first 4 byte that are the netfilter header, the newConntrackRequest is adding it already
req2.AddRawData(dataRaw[4:])
req2.Execute(unix.NETLINK_NETFILTER, 0)
matched++
// flow is already deleted, no need to match on other filters and continue to the next flow.
break
if _, err = req2.Execute(unix.NETLINK_NETFILTER, 0); err == nil {
matched++
// flow is already deleted, no need to match on other filters and continue to the next flow.
break
}
errMsgs = append(errMsgs, fmt.Sprintf("failed to delete conntrack flow '%s': %s", flow.String(), err.Error()))
}
}
}

if len(errMsgs) > 0 {
return matched, fmt.Errorf(strings.Join(errMsgs, "; "))
}
return matched, nil
}

Expand Down
40 changes: 28 additions & 12 deletions devlink_linux.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package netlink

import (
"errors"
"fmt"
"net"
"strings"
Expand Down Expand Up @@ -466,6 +467,8 @@ func (h *Handle) getEswitchAttrs(family *GenlFamily, dev *DevlinkDevice) {

// DevLinkGetDeviceList provides a pointer to devlink devices and nil error,
// otherwise returns an error code.
// If the returned error is [ErrDumpInterrupted], results may be inconsistent
// or incomplete.
func (h *Handle) DevLinkGetDeviceList() ([]*DevlinkDevice, error) {
f, err := h.GenlFamilyGet(nl.GENL_DEVLINK_NAME)
if err != nil {
Expand All @@ -478,9 +481,9 @@ func (h *Handle) DevLinkGetDeviceList() ([]*DevlinkDevice, error) {
req := h.newNetlinkRequest(int(f.ID),
unix.NLM_F_REQUEST|unix.NLM_F_ACK|unix.NLM_F_DUMP)
req.AddData(msg)
msgs, err := req.Execute(unix.NETLINK_GENERIC, 0)
if err != nil {
return nil, err
msgs, executeErr := req.Execute(unix.NETLINK_GENERIC, 0)
if executeErr != nil && !errors.Is(executeErr, ErrDumpInterrupted) {
return nil, executeErr
}
devices, err := parseDevLinkDeviceList(msgs)
if err != nil {
Expand All @@ -489,11 +492,14 @@ func (h *Handle) DevLinkGetDeviceList() ([]*DevlinkDevice, error) {
for _, d := range devices {
h.getEswitchAttrs(f, d)
}
return devices, nil
return devices, executeErr
}

// DevLinkGetDeviceList provides a pointer to devlink devices and nil error,
// otherwise returns an error code.
//
// If the returned error is [ErrDumpInterrupted], results may be inconsistent
// or incomplete.
func DevLinkGetDeviceList() ([]*DevlinkDevice, error) {
return pkgHandle.DevLinkGetDeviceList()
}
Expand Down Expand Up @@ -646,6 +652,8 @@ func parseDevLinkAllPortList(msgs [][]byte) ([]*DevlinkPort, error) {

// DevLinkGetPortList provides a pointer to devlink ports and nil error,
// otherwise returns an error code.
// If the returned error is [ErrDumpInterrupted], results may be inconsistent
// or incomplete.
func (h *Handle) DevLinkGetAllPortList() ([]*DevlinkPort, error) {
f, err := h.GenlFamilyGet(nl.GENL_DEVLINK_NAME)
if err != nil {
Expand All @@ -658,19 +666,21 @@ func (h *Handle) DevLinkGetAllPortList() ([]*DevlinkPort, error) {
req := h.newNetlinkRequest(int(f.ID),
unix.NLM_F_REQUEST|unix.NLM_F_ACK|unix.NLM_F_DUMP)
req.AddData(msg)
msgs, err := req.Execute(unix.NETLINK_GENERIC, 0)
if err != nil {
return nil, err
msgs, executeErr := req.Execute(unix.NETLINK_GENERIC, 0)
if executeErr != nil && !errors.Is(executeErr, ErrDumpInterrupted) {
return nil, executeErr
}
ports, err := parseDevLinkAllPortList(msgs)
if err != nil {
return nil, err
}
return ports, nil
return ports, executeErr
}

// DevLinkGetPortList provides a pointer to devlink ports and nil error,
// otherwise returns an error code.
// If the returned error is [ErrDumpInterrupted], results may be inconsistent
// or incomplete.
func DevLinkGetAllPortList() ([]*DevlinkPort, error) {
return pkgHandle.DevLinkGetAllPortList()
}
Expand Down Expand Up @@ -738,15 +748,18 @@ func (h *Handle) DevlinkGetDeviceResources(bus string, device string) (*DevlinkR

// DevlinkGetDeviceParams returns parameters for devlink device
// Equivalent to: `devlink dev param show <bus>/<device>`
//
// If the returned error is [ErrDumpInterrupted], results may be inconsistent
// or incomplete.
func (h *Handle) DevlinkGetDeviceParams(bus string, device string) ([]*DevlinkParam, error) {
_, req, err := h.createCmdReq(nl.DEVLINK_CMD_PARAM_GET, bus, device)
if err != nil {
return nil, err
}
req.Flags |= unix.NLM_F_DUMP
respmsg, err := req.Execute(unix.NETLINK_GENERIC, 0)
if err != nil {
return nil, err
respmsg, executeErr := req.Execute(unix.NETLINK_GENERIC, 0)
if executeErr != nil && !errors.Is(executeErr, ErrDumpInterrupted) {
return nil, executeErr
}
var params []*DevlinkParam
for _, m := range respmsg {
Expand All @@ -761,11 +774,14 @@ func (h *Handle) DevlinkGetDeviceParams(bus string, device string) ([]*DevlinkPa
params = append(params, p)
}

return params, nil
return params, executeErr
}

// DevlinkGetDeviceParams returns parameters for devlink device
// Equivalent to: `devlink dev param show <bus>/<device>`
//
// If the returned error is [ErrDumpInterrupted], results may be inconsistent
// or incomplete.
func DevlinkGetDeviceParams(bus string, device string) ([]*DevlinkParam, error) {
return pkgHandle.DevlinkGetDeviceParams(bus, device)
}
Expand Down
Loading

0 comments on commit 552d5d4

Please sign in to comment.