handle_linux.go 2.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586
  1. package netlink
  2. import (
  3. "sync/atomic"
  4. "syscall"
  5. "github.com/vishvananda/netlink/nl"
  6. "github.com/vishvananda/netns"
  7. )
  8. // Empty handle used by the netlink package methods
  9. var pkgHandle = &Handle{}
  10. // Handle is an handle for the netlink requests
  11. // on a specific network namespace. All the requests
  12. // share the same netlink socket, which gets released
  13. // when the handle is deleted.
  14. type Handle struct {
  15. seq uint32
  16. routeSocket *nl.NetlinkSocket
  17. xfrmSocket *nl.NetlinkSocket
  18. lookupByDump bool
  19. }
  20. // NewHandle returns a netlink handle on the current network namespace.
  21. func NewHandle() (*Handle, error) {
  22. return newHandle(netns.None(), netns.None())
  23. }
  24. // NewHandle returns a netlink handle on the network namespace
  25. // specified by ns. If ns=netns.None(), current network namespace
  26. // will be assumed
  27. func NewHandleAt(ns netns.NsHandle) (*Handle, error) {
  28. return newHandle(ns, netns.None())
  29. }
  30. // NewHandleAtFrom works as NewHandle but allows client to specify the
  31. // new and the origin netns Handle.
  32. func NewHandleAtFrom(newNs, curNs netns.NsHandle) (*Handle, error) {
  33. return newHandle(newNs, curNs)
  34. }
  35. func newHandle(newNs, curNs netns.NsHandle) (*Handle, error) {
  36. var (
  37. err error
  38. rSocket *nl.NetlinkSocket
  39. xSocket *nl.NetlinkSocket
  40. )
  41. rSocket, err = nl.GetNetlinkSocketAt(newNs, curNs, syscall.NETLINK_ROUTE)
  42. if err != nil {
  43. return nil, err
  44. }
  45. xSocket, err = nl.GetNetlinkSocketAt(newNs, curNs, syscall.NETLINK_XFRM)
  46. if err != nil {
  47. return nil, err
  48. }
  49. return &Handle{routeSocket: rSocket, xfrmSocket: xSocket}, nil
  50. }
  51. // Delete releases the resources allocated to this handle
  52. func (h *Handle) Delete() {
  53. if h.routeSocket != nil {
  54. h.routeSocket.Close()
  55. }
  56. if h.xfrmSocket != nil {
  57. h.xfrmSocket.Close()
  58. }
  59. h.routeSocket, h.xfrmSocket = nil, nil
  60. }
  61. func (h *Handle) newNetlinkRequest(proto, flags int) *nl.NetlinkRequest {
  62. // Do this so that package API still use nl package variable nextSeqNr
  63. if h.routeSocket == nil {
  64. return nl.NewNetlinkRequest(proto, flags)
  65. }
  66. return &nl.NetlinkRequest{
  67. NlMsghdr: syscall.NlMsghdr{
  68. Len: uint32(syscall.SizeofNlMsghdr),
  69. Type: uint16(proto),
  70. Flags: syscall.NLM_F_REQUEST | uint16(flags),
  71. Seq: atomic.AddUint32(&h.seq, 1),
  72. },
  73. RouteSocket: h.routeSocket,
  74. XfmrSocket: h.xfrmSocket,
  75. }
  76. }