From cd3efc65190abffcaf02a6aeb5cd6489c797a245 Mon Sep 17 00:00:00 2001 From: Jing Chen Date: Fri, 21 Jun 2024 23:52:33 -0700 Subject: [PATCH] Support IFLA_ADDRESS which changes a device's hardware address. PiperOrigin-RevId: 645611089 --- pkg/sentry/socket/netstack/stack.go | 26 +++++++++++++++++++------- pkg/tcpip/stack/stack.go | 13 +++++++++++++ 2 files changed, 32 insertions(+), 7 deletions(-) diff --git a/pkg/sentry/socket/netstack/stack.go b/pkg/sentry/socket/netstack/stack.go index ddf238e5f..3f9f15571 100644 --- a/pkg/sentry/socket/netstack/stack.go +++ b/pkg/sentry/socket/netstack/stack.go @@ -136,6 +136,7 @@ func (s *Stack) SetInterface(ctx context.Context, msg *nlmsg.Message) *syserr.Er } case linux.IFLA_MASTER: case linux.IFLA_LINKINFO: + case linux.IFLA_ADDRESS: default: ctx.Warningf("unexpected attribute: %x", attr) return syserr.ErrNotSupported @@ -169,13 +170,24 @@ func (s *Stack) SetInterface(ctx context.Context, msg *nlmsg.Message) *syserr.Er } func (s *Stack) setLink(id tcpip.NICID, linkAttrs map[uint16]nlmsg.BytesView) *syserr.Error { - if v, ok := linkAttrs[linux.IFLA_MASTER]; ok { - master, ok := v.Uint32() - if !ok { - return syserr.ErrInvalidArgument - } - if master != 0 { - if err := s.Stack.SetNICCoordinator(id, tcpip.NICID(master)); err != nil { + for t, v := range linkAttrs { + switch t { + case linux.IFLA_MASTER: + master, ok := v.Uint32() + if !ok { + return syserr.ErrInvalidArgument + } + if master != 0 { + if err := s.Stack.SetNICCoordinator(id, tcpip.NICID(master)); err != nil { + return syserr.TranslateNetstackError(err) + } + } + case linux.IFLA_ADDRESS: + addr, err := tcpip.ParseMACAddress(v.String()) + if err != nil { + return syserr.ErrInvalidArgument + } + if err := s.Stack.SetNICAddress(id, addr); err != nil { return syserr.TranslateNetstackError(err) } } diff --git a/pkg/tcpip/stack/stack.go b/pkg/tcpip/stack/stack.go index 824a691cd..0b2bf516e 100644 --- a/pkg/tcpip/stack/stack.go +++ b/pkg/tcpip/stack/stack.go @@ -1025,6 +1025,19 @@ func (s *Stack) SetNICCoordinator(id tcpip.NICID, mid tcpip.NICID) tcpip.Error { return nil } +// SetNICAddress sets the hardware address which is identified by the nic ID. +func (s *Stack) SetNICAddress(id tcpip.NICID, addr tcpip.LinkAddress) tcpip.Error { + s.mu.Lock() + defer s.mu.Unlock() + + nic, ok := s.nics[id] + if !ok { + return &tcpip.ErrUnknownNICID{} + } + nic.NetworkLinkEndpoint.SetLinkAddress(addr) + return nil +} + // NICInfo captures the name and addresses assigned to a NIC. type NICInfo struct { Name string