Skip to content

Commit

Permalink
Add interface state (admin and oper) to intf package. (#42)
Browse files Browse the repository at this point in the history
* Add an interface state manipulator to accessor.
  • Loading branch information
robshakir authored Nov 30, 2023
1 parent f39af32 commit 866a06a
Show file tree
Hide file tree
Showing 15 changed files with 152 additions and 25 deletions.
2 changes: 1 addition & 1 deletion cmd/magna/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ import (
"google.golang.org/grpc/credentials"
"google.golang.org/grpc/credentials/insecure"
"google.golang.org/grpc/reflection"
"k8s.io/klog"
"k8s.io/klog/v2"

gpb "github.com/openconfig/gnmi/proto/gnmi"
)
Expand Down
2 changes: 1 addition & 1 deletion flows/common/common.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import (
"github.com/google/gopacket/pcap"
"github.com/open-traffic-generator/snappi/gosnappi/otg"
"github.com/openconfig/magna/lwotg"
"k8s.io/klog"
"k8s.io/klog/v2"
)

var (
Expand Down
2 changes: 1 addition & 1 deletion flows/common/counter.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import (
"github.com/openconfig/magna/otgyang"
tcommon "github.com/openconfig/magna/telemetry/common"
"github.com/openconfig/ygot/ygot"
"k8s.io/klog"
"k8s.io/klog/v2"
)

var (
Expand Down
2 changes: 1 addition & 1 deletion flows/ip/ip.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import (
"github.com/openconfig/magna/flows/common"
"github.com/openconfig/magna/lwotg"
"github.com/openconfig/magna/lwotgtelem/gnmit"
"k8s.io/klog"
"k8s.io/klog/v2"
)

// New returns a new IP flow generator, consisting of:
Expand Down
2 changes: 1 addition & 1 deletion flows/mpls/mpls.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ import (
"github.com/openconfig/magna/flows/common"
"github.com/openconfig/magna/lwotg"
"github.com/openconfig/magna/lwotgtelem/gnmit"
"k8s.io/klog"
"k8s.io/klog/v2"
)

const (
Expand Down
1 change: 0 additions & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ require (
github.com/vishvananda/netlink v1.1.1-0.20210330154013-f5de75959ad5
google.golang.org/grpc v1.58.3
google.golang.org/protobuf v1.31.0
k8s.io/klog v1.0.0
k8s.io/klog/v2 v2.90.1
)

Expand Down
3 changes: 0 additions & 3 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -858,7 +858,6 @@ github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2
github.com/go-latex/latex v0.0.0-20210118124228-b3d85cf34e07/go.mod h1:CO1AlKB2CSIqUrmQPqA0gdRIlnLEY0gK5JGjh37zN5U=
github.com/go-latex/latex v0.0.0-20210823091927-c0d11ff05a81/go.mod h1:SX0U8uGpxhq9o2S/CELCSUxEWWAuoCUcVCQWv7G2OCk=
github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=
github.com/go-logr/logr v0.1.0/go.mod h1:ixOQHD9gLJUVQQ2ZOR7zLEifBX6tGkNJF4QyIY7sIas=
github.com/go-logr/logr v1.2.0/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
github.com/go-logr/logr v1.2.3 h1:2DntVwHkVopvECVRSlL5PSo9eG+cAkDCuckLubN+rq0=
github.com/go-logr/logr v1.2.3/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
Expand Down Expand Up @@ -2012,8 +2011,6 @@ k8s.io/apimachinery v0.26.3 h1:dQx6PNETJ7nODU3XPtrwkfuubs6w7sX0M8n61zHIV/k=
k8s.io/apimachinery v0.26.3/go.mod h1:ats7nN1LExKHvJ9TmwootT00Yz05MuYqPXEXaVeOy5I=
k8s.io/client-go v0.26.3 h1:k1UY+KXfkxV2ScEL3gilKcF7761xkYsSD6BC9szIu8s=
k8s.io/client-go v0.26.3/go.mod h1:ZPNu9lm8/dbRIPAgteN30RSXea6vrCpFvq+MateTUuQ=
k8s.io/klog v1.0.0 h1:Pt+yjF5aB1xDSVbau4VsWe+dQNzA0qv1LlXdC2dF6Q8=
k8s.io/klog v1.0.0/go.mod h1:4Bi6QPql/J/LkTDqv7R/cd3hPo4k2DG6Ptcz060Ez5I=
k8s.io/klog/v2 v2.90.1 h1:m4bYOKall2MmOiRaR1J+We67Do7vm9KiQVlT96lnHUw=
k8s.io/klog/v2 v2.90.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0=
k8s.io/kube-openapi v0.0.0-20230308215209-15aac26d736a h1:gmovKNur38vgoWfGtP5QOGNOA7ki4n6qNYoFAgMlNvg=
Expand Down
41 changes: 41 additions & 0 deletions integration/intf_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -86,3 +86,44 @@ func TestInterfaces(t *testing.T) {

t.Logf("Got interfaces: %v", ints)
}

func TestInterfaceState(t *testing.T) {
name := "dummy0"
dummy := &netlink.Dummy{
LinkAttrs: netlink.LinkAttrs{
Name: name,
},
}

if err := netlink.LinkAdd(dummy); err != nil {
t.Fatalf("cannot add dummy link, %v", err)
}

dummyState := func() intf.IntState {
l, err := intf.InterfaceByName(name)
if err != nil {
t.Errorf("unable to get dummy link, %v", err)
}
return l.AdminState
}

if err := intf.InterfaceState(name, intf.InterfaceDown); err != nil {
t.Errorf("cannot shut down dummy link, %v", err)
}

if got, want := dummyState(), intf.InterfaceDown; got != want {
t.Errorf("interface was not operationally down, got: %v, want: %v", got, want)
}

if err := intf.InterfaceState(name, intf.InterfaceUp); err != nil {
t.Errorf("cannot enable dummy link, %v", err)
}

if got, want := dummyState(), intf.InterfaceUp; got != want {
t.Errorf("interface was not restored to its previous state, got: %v, want: %v", got, want)
}

if err := netlink.LinkDel(dummy); err != nil {
t.Fatalf("cannot delete dummy link, %v", err)
}
}
76 changes: 66 additions & 10 deletions intf/accessor_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import (
"net"

"github.com/vishvananda/netlink"
"k8s.io/klog"
"k8s.io/klog/v2"
)

const (
Expand All @@ -44,6 +44,31 @@ func init() {
// system.
type netlinkAccessor struct{}

// intOperState maps a netlink operational link state to an intf internal
// representation.
func intOperState(n netlink.LinkOperState) IntState {
operStateMap := map[netlink.LinkOperState]IntState{
netlink.OperUp: InterfaceUp,
netlink.OperDown: InterfaceDown,
}

if _, ok := operStateMap[n]; !ok {
return InterfaceStateUnknown
}

return operStateMap[n]
}

// intAdminState maps an interface's flags to the administrative state of
// the interface. The flags are defined in the net package
// (see https://cs.opensource.google/go/go/+/refs/tags/go1.21.4:src/net/interface.go;l=39).
func intAdminState(n net.Flags) IntState {
if n&1 != 0 {
return InterfaceUp
}
return InterfaceDown
}

// Interface retrieves the interface named from the underlying system
// through making a netlink call.
func (n netlinkAccessor) Interface(name string) (*Interface, error) {
Expand All @@ -54,9 +79,11 @@ func (n netlinkAccessor) Interface(name string) (*Interface, error) {

attrs := link.Attrs()
return &Interface{
Index: attrs.Index,
Name: attrs.Name,
MAC: attrs.HardwareAddr,
Index: attrs.Index,
Name: attrs.Name,
MAC: attrs.HardwareAddr,
AdminState: intAdminState(attrs.Flags),
OperState: intOperState(attrs.OperState),
}, nil
}

Expand All @@ -72,9 +99,11 @@ func (n netlinkAccessor) Interfaces() ([]*Interface, error) {
for _, i := range ints {
attrs := i.Attrs()
intfs = append(intfs, &Interface{
Index: attrs.Index,
Name: attrs.Name,
MAC: attrs.HardwareAddr,
Index: attrs.Index,
Name: attrs.Name,
MAC: attrs.HardwareAddr,
AdminState: intAdminState(attrs.Flags),
OperState: intOperState(attrs.OperState),
})
}
return intfs, nil
Expand All @@ -87,9 +116,11 @@ func interfaceByIndex(idx int) (*Interface, error) {
return nil, fmt.Errorf("cannot find link by index %d", idx)
}
return &Interface{
Index: idx,
Name: link.Attrs().Name,
MAC: link.Attrs().HardwareAddr,
Index: idx,
Name: link.Attrs().Name,
MAC: link.Attrs().HardwareAddr,
AdminState: intAdminState(link.Attrs().Flags),
OperState: intOperState(link.Attrs().OperState),
}, nil
}

Expand Down Expand Up @@ -190,3 +221,28 @@ func (n netlinkAccessor) ARPSubscribe(updates chan ARPUpdate, done chan struct{}

return nil
}

// InterfaceState changes the state of an interface on the underlying system.
// The interface is looked up by the name specified, and is set to the state
// specified by state. It returns an error if the interface cannot be found or
// the system cannot complete the specified operation.
func (n netlinkAccessor) InterfaceState(name string, state IntState) error {
l, err := netlink.LinkByName(name)
if err != nil {
return fmt.Errorf("cannot get link, %w", err)
}

switch state {
case InterfaceDown:
if err := netlink.LinkSetDown(l); err != nil {
return fmt.Errorf("cannot shut down link, %w", err)
}
case InterfaceUp:
if err := netlink.LinkSetUp(l); err != nil {
return fmt.Errorf("cannot enable link, %w", err)
}
default:
return fmt.Errorf("unknown operation: %d", state)
}
return nil
}
32 changes: 32 additions & 0 deletions intf/intf.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,10 @@ type Interface struct {
Name string
// MAC is the MAC address of the interface.
MAC net.HardwareAddr
// OperState is the operational status of the interface.
OperState IntState
// AdminState is the administrative state of the interface.
AdminState IntState
}

// String is the string representation of an interface that can be read by humans.
Expand Down Expand Up @@ -92,6 +96,8 @@ type NetworkAccessor interface {
// that writes updates to the updates channel, and can be cancelled by sending a
// message to the done channel.
ARPSubscribe(updates chan ARPUpdate, done chan struct{}) error
// InterfaceState manipulates the state of the interface specified by name.
InterfaceState(name string, state IntState) error
}

// unimplementedAccessor is an accessor interface that returns unimplemented
Expand Down Expand Up @@ -128,6 +134,12 @@ func (u unimplementedAccessor) ARPSubscribe(_ chan ARPUpdate, _ chan struct{}) e
return fmt.Errorf("unimplemented ARPSubscribe method")
}

// InterfaceState returns unimplemented when asked to manipulate an interface
// state.
func (u unimplementedAccessor) InterfaceState(_ string, _ IntState) error {
return fmt.Errorf("unimplemented InterfaceState method")
}

// accessor is the implementation of the network accessor that should be used. It
// should be set by init() [which may be a platform-specific initiation].
var accessor NetworkAccessor
Expand Down Expand Up @@ -230,3 +242,23 @@ func ARPSubscribe(updates chan ARPUpdate, done chan struct{}) error {
func Interfaces() ([]*Interface, error) {
return accessor.Interfaces()
}

// IntState sets enumerated state values that an interface
// can use.
type IntState int64

const (
InterfaceStateUnknown IntState = iota
// InterfaceUp sets a link to administratively and operationally
// up.
InterfaceUp
// InterfaceDown sets a link to administratively and operationally
// down.
InterfaceDown
)

// InterfaceState changes the administrative state of an interface
// on the local system.
func InterfaceState(name string, state IntState) error {
return accessor.InterfaceState(name, state)
}
2 changes: 1 addition & 1 deletion lwotg/flows.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import (
"github.com/open-traffic-generator/snappi/gosnappi/otg"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/status"
"k8s.io/klog"
"k8s.io/klog/v2"
)

type TXRXWrapper struct {
Expand Down
2 changes: 1 addition & 1 deletion lwotg/lwotg.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import (
"github.com/openconfig/magna/intf"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/status"
"k8s.io/klog"
"k8s.io/klog/v2"
)

// Hint is <group, key, value> tuple that can be handed to modules of the
Expand Down
2 changes: 1 addition & 1 deletion lwotgtelem/lwotgtelem.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import (

"github.com/openconfig/magna/lwotg"
"github.com/openconfig/magna/lwotgtelem/gnmit"
"k8s.io/klog"
"k8s.io/klog/v2"
)

// HintMap is a structured set of hints that are supplied by the server, it
Expand Down
6 changes: 4 additions & 2 deletions mirrorsrv/mirror.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,12 @@ import (
"github.com/google/gopacket"
"github.com/google/gopacket/layers"
"github.com/google/gopacket/pcap"
mpb "github.com/openconfig/magna/proto/mirror"

"google.golang.org/grpc/codes"
"google.golang.org/grpc/status"
"k8s.io/klog"
"k8s.io/klog/v2"

mpb "github.com/openconfig/magna/proto/mirror"
)

type Server struct {
Expand Down
2 changes: 1 addition & 1 deletion telemetry/arp/arp.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import (
"github.com/openconfig/magna/otgyang"
"github.com/openconfig/magna/telemetry/common"
"github.com/openconfig/ygot/ygot"
"k8s.io/klog"
"k8s.io/klog/v2"

gpb "github.com/openconfig/gnmi/proto/gnmi"
)
Expand Down

0 comments on commit 866a06a

Please sign in to comment.