precondition: s.linkLock is held. If dstNs is not nil, dstNs.Stack.linkMu is also held.
(ctx context.Context, id tcpip.NICID, linkAttrs map[uint16]nlmsg.BytesView, dstNs *inet.Namespace)
| 321 | // precondition: s.linkLock is held. If dstNs is not nil, dstNs.Stack.linkMu is |
| 322 | // also held. |
| 323 | func (s *Stack) setLinkLocked(ctx context.Context, id tcpip.NICID, linkAttrs map[uint16]nlmsg.BytesView, dstNs *inet.Namespace) *syserr.Error { |
| 324 | src := s |
| 325 | changed := false |
| 326 | nicInfo, ok := src.Stack.SingleNICInfo(id) |
| 327 | if !ok { |
| 328 | return syserr.ErrUnknownNICID |
| 329 | } |
| 330 | |
| 331 | dst := src |
| 332 | if dstNs != nil { |
| 333 | dst = dstNs.Stack().(*Stack) |
| 334 | } |
| 335 | if dst != src { |
| 336 | var err tcpip.Error |
| 337 | oldID := id |
| 338 | id, err = src.Stack.SetNICStack(id, dst.Stack) |
| 339 | if err != nil { |
| 340 | return syserr.TranslateNetstackError(err) |
| 341 | } |
| 342 | |
| 343 | src.sendDeleteEvent(ctx, oldID, nicInfo) // inform about exit from old ns |
| 344 | changed = true // inform about entry into new ns |
| 345 | |
| 346 | nicInfo, ok = dst.Stack.SingleNICInfo(id) |
| 347 | if !ok { |
| 348 | // Because we hold dst.linkMu, this should never happen. |
| 349 | ctx.Warningf("Newly rehomed NIC %d not found in new stack %p", id, dst.Stack) |
| 350 | return syserr.ErrUnknownNICID |
| 351 | } |
| 352 | src = dst |
| 353 | |
| 354 | // TODO (b/465141970): Once we support IFLA_LINK_NETNSID, we need to call sendChangeEvent on |
| 355 | // the peer interface if this interface is part of a veth pair. |
| 356 | } |
| 357 | |
| 358 | for t, v := range linkAttrs { |
| 359 | switch t { |
| 360 | case linux.IFLA_MASTER: |
| 361 | master, ok := v.Uint32() |
| 362 | if !ok { |
| 363 | return syserr.ErrInvalidArgument |
| 364 | } |
| 365 | if mid, ok := src.Stack.GetNICCoordinatorID(id); ok && mid == tcpip.NICID(master) { |
| 366 | continue |
| 367 | } |
| 368 | if master != 0 { |
| 369 | if err := src.Stack.SetNICCoordinator(id, tcpip.NICID(master)); err != nil { |
| 370 | return syserr.TranslateNetstackError(err) |
| 371 | } |
| 372 | changed = true |
| 373 | } |
| 374 | case linux.IFLA_ADDRESS: |
| 375 | if len(v) != tcpip.LinkAddressSize { |
| 376 | return syserr.ErrInvalidArgument |
| 377 | } |
| 378 | addr := tcpip.LinkAddress(v) |
| 379 | if nicInfo.LinkAddress == addr { |
| 380 | continue |
no test coverage detected