1

Using https://godoc.org/github.com/vishvananda/netlink, I'm trying to access the table ID of a link that has been set as a slave to a VRF. If I add the link and then get it, I can see that the Slave field of netlink.LinkAttrs is set; printing it using "%+v" it prints as {Table:2}, which is correct. But I can't figure out how to access the Table field.

In LinkAttrs, Slave appears as a field (included interface):

type LinkAttrs struct {
    ...
    Slave SlaveType
}

SlaveType is an interface:

type LinkSlave interface {
    SlaveType() string
}

The value of link.Attrs().Slave.SlaveType() is "vrf", implying that the struct that implements SlaveType and is assigned to Slave is possibly the netlink.Vrf type, but that type doesn't implement SlaveType. So, of course, trying to type-assert fails:

vrf, ok := link.Slave.(netlink.Vrf) // or .*(netlink.Vrf)

as "impossible assertion", which is what I expect since Vrf doesn't implement SlaveType.

I can't find any type that does other than BondSlave, which has many more fields (and no Table field.)

The only struct with a Table field is

type Vrf struct {
    LinkAttrs
    Table uint32
}

So, I'm at a loss on how to access the Table field.

Example, which I run using sudo -E --preserve-env=PATH bash -c "go test":

package main

import (
    "fmt"
    "testing"

    "github.com/vishvananda/netlink"
    "github.com/stretchr/testify/require"
)

var vrfConfig = &netlink.Vrf{
    LinkAttrs: netlink.LinkAttrs{
        Name:  "vrf1"},
    Table: 2,
}

var link1Config = &netlink.Gretap{
    LinkAttrs: netlink.LinkAttrs{
        Name:      "link1"},
    Remote: []byte{1, 1, 1, 1},
}

func TestSlave(t *testing.T) {
    err := netlink.LinkAdd(vrfConfig)
    require.NoError(t, err)

    err = netlink.LinkAdd(link1Config)
    require.NoError(t, err)

    err = netlink.LinkSetMaster(link1Config, vrfConfig)
    require.NoError(t, err)

    links, err := netlink.LinkList()
    require.NoError(t, err)

    for _, link := range links {
        if link.Attrs().Name == "link1" {
            fmt.Printf("Slave: %+v\n", link.Attrs().Slave)
        }
    }
}

(See https://goplay.tools/snippet/mHaMt9jRs9_m , but of course it returns a permission error.)

Clean up using

sudo ip link delete vrf1; sudo ip link delete link1
Jeff Learman
  • 2,914
  • 1
  • 22
  • 31

0 Answers0