interface_linux.go 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284
  1. package sandbox
  2. import (
  3. "fmt"
  4. "net"
  5. "sync"
  6. "github.com/docker/libnetwork/types"
  7. "github.com/vishvananda/netlink"
  8. )
  9. // IfaceOption is a function option type to set interface options
  10. type IfaceOption func(i *nwIface)
  11. type nwIface struct {
  12. srcName string
  13. dstName string
  14. address *net.IPNet
  15. addressIPv6 *net.IPNet
  16. routes []*net.IPNet
  17. ns *networkNamespace
  18. sync.Mutex
  19. }
  20. func (i *nwIface) SrcName() string {
  21. i.Lock()
  22. defer i.Unlock()
  23. return i.srcName
  24. }
  25. func (i *nwIface) DstName() string {
  26. i.Lock()
  27. defer i.Unlock()
  28. return i.dstName
  29. }
  30. func (i *nwIface) DstMaster() string {
  31. i.Lock()
  32. defer i.Unlock()
  33. return i.dstMaster
  34. }
  35. func (i *nwIface) Bridge() bool {
  36. i.Lock()
  37. defer i.Unlock()
  38. return i.bridge
  39. }
  40. func (i *nwIface) Master() string {
  41. i.Lock()
  42. defer i.Unlock()
  43. return i.master
  44. }
  45. func (i *nwIface) Address() *net.IPNet {
  46. i.Lock()
  47. defer i.Unlock()
  48. return types.GetIPNetCopy(i.address)
  49. }
  50. func (i *nwIface) AddressIPv6() *net.IPNet {
  51. i.Lock()
  52. defer i.Unlock()
  53. return types.GetIPNetCopy(i.addressIPv6)
  54. }
  55. func (i *nwIface) Routes() []*net.IPNet {
  56. i.Lock()
  57. defer i.Unlock()
  58. routes := make([]*net.IPNet, len(i.routes))
  59. for index, route := range i.routes {
  60. r := types.GetIPNetCopy(route)
  61. routes[index] = r
  62. }
  63. return routes
  64. }
  65. func (n *networkNamespace) Interfaces() []Interface {
  66. n.Lock()
  67. defer n.Unlock()
  68. ifaces := make([]Interface, len(n.iFaces))
  69. for i, iface := range n.iFaces {
  70. ifaces[i] = iface
  71. }
  72. return ifaces
  73. }
  74. func (i *nwIface) Remove() error {
  75. i.Lock()
  76. n := i.ns
  77. i.Unlock()
  78. n.Lock()
  79. path := n.path
  80. n.Unlock()
  81. return nsInvoke(path, func(nsFD int) error { return nil }, func(callerFD int) error {
  82. // Find the network inteerface identified by the DstName attribute.
  83. iface, err := netlink.LinkByName(i.DstName())
  84. if err != nil {
  85. return err
  86. }
  87. // Down the interface before configuring
  88. if err := netlink.LinkSetDown(iface); err != nil {
  89. return err
  90. }
  91. err = netlink.LinkSetName(iface, i.SrcName())
  92. if err != nil {
  93. fmt.Println("LinkSetName failed: ", err)
  94. return err
  95. }
  96. // if it is a bridge just delete it.
  97. if i.Bridge() {
  98. if err := netlink.LinkDel(iface); err != nil {
  99. return fmt.Errorf("failed deleting bridge %q: %v", i.SrcName(), err)
  100. }
  101. } else {
  102. // Move the network interface to caller namespace.
  103. if err := netlink.LinkSetNsFd(iface, callerFD); err != nil {
  104. fmt.Println("LinkSetNsPid failed: ", err)
  105. return err
  106. }
  107. }
  108. n.Lock()
  109. for index, intf := range n.iFaces {
  110. if intf == i {
  111. n.iFaces = append(n.iFaces[:index], n.iFaces[index+1:]...)
  112. break
  113. }
  114. }
  115. n.Unlock()
  116. return nil
  117. })
  118. }
  119. func (n *networkNamespace) findDstMaster(srcName string) string {
  120. n.Lock()
  121. defer n.Unlock()
  122. for _, i := range n.iFaces {
  123. // The master should match the srcname of the interface and the
  124. // master interface should be of type bridge.
  125. if i.SrcName() == srcName && i.Bridge() {
  126. return i.DstName()
  127. }
  128. }
  129. return ""
  130. }
  131. func (n *networkNamespace) AddInterface(srcName, dstPrefix string, options ...IfaceOption) error {
  132. i := &nwIface{srcName: srcName, dstName: dstPrefix, ns: n}
  133. i.processInterfaceOptions(options...)
  134. n.Lock()
  135. i.dstName = fmt.Sprintf("%s%d", i.dstName, n.nextIfIndex)
  136. n.nextIfIndex++
  137. path := n.path
  138. n.Unlock()
  139. return nsInvoke(path, func(nsFD int) error {
  140. // Find the network interface identified by the SrcName attribute.
  141. iface, err := netlink.LinkByName(i.srcName)
  142. if err != nil {
  143. return fmt.Errorf("failed to get link by name %q: %v", i.srcName, err)
  144. }
  145. // Move the network interface to the destination namespace.
  146. if err := netlink.LinkSetNsFd(iface, nsFD); err != nil {
  147. return fmt.Errorf("failed to set namespace on link %q: %v", i.srcName, err)
  148. }
  149. return nil
  150. }, func(callerFD int) error {
  151. // Find the network interface identified by the SrcName attribute.
  152. iface, err := netlink.LinkByName(i.srcName)
  153. if err != nil {
  154. return fmt.Errorf("failed to get link by name %q: %v", i.srcName, err)
  155. }
  156. // Down the interface before configuring
  157. if err := netlink.LinkSetDown(iface); err != nil {
  158. return fmt.Errorf("failed to set link down: %v", err)
  159. }
  160. // Configure the interface now this is moved in the proper namespace.
  161. if err := configureInterface(iface, i); err != nil {
  162. return err
  163. }
  164. // Up the interface.
  165. if err := netlink.LinkSetUp(iface); err != nil {
  166. return fmt.Errorf("failed to set link up: %v", err)
  167. }
  168. n.Lock()
  169. n.iFaces = append(n.iFaces, i)
  170. n.Unlock()
  171. return nil
  172. })
  173. }
  174. func configureInterface(iface netlink.Link, i *nwIface) error {
  175. ifaceName := iface.Attrs().Name
  176. ifaceConfigurators := []struct {
  177. Fn func(netlink.Link, *nwIface) error
  178. ErrMessage string
  179. }{
  180. {setInterfaceName, fmt.Sprintf("error renaming interface %q to %q", ifaceName, i.DstName())},
  181. {setInterfaceIP, fmt.Sprintf("error setting interface %q IP to %q", ifaceName, i.Address())},
  182. {setInterfaceIPv6, fmt.Sprintf("error setting interface %q IPv6 to %q", ifaceName, i.AddressIPv6())},
  183. {setInterfaceRoutes, fmt.Sprintf("error setting interface %q routes to %q", ifaceName, i.Routes())},
  184. {setInterfaceMaster, fmt.Sprintf("error setting interface %q master to %q", ifaceName, i.DstMaster())},
  185. }
  186. for _, config := range ifaceConfigurators {
  187. if err := config.Fn(iface, i); err != nil {
  188. return fmt.Errorf("%s: %v", config.ErrMessage, err)
  189. }
  190. }
  191. return nil
  192. }
  193. func setInterfaceMaster(iface netlink.Link, i *nwIface) error {
  194. if i.DstMaster() == "" {
  195. return nil
  196. }
  197. return netlink.LinkSetMaster(iface, &netlink.Bridge{
  198. LinkAttrs: netlink.LinkAttrs{Name: i.DstMaster()}})
  199. }
  200. func setInterfaceIP(iface netlink.Link, i *nwIface) error {
  201. if i.Address() == nil {
  202. return nil
  203. }
  204. ipAddr := &netlink.Addr{IPNet: i.Address(), Label: ""}
  205. return netlink.AddrAdd(iface, ipAddr)
  206. }
  207. func setInterfaceIPv6(iface netlink.Link, i *nwIface) error {
  208. if i.AddressIPv6() == nil {
  209. return nil
  210. }
  211. ipAddr := &netlink.Addr{IPNet: i.AddressIPv6(), Label: ""}
  212. return netlink.AddrAdd(iface, ipAddr)
  213. }
  214. func setInterfaceName(iface netlink.Link, i *nwIface) error {
  215. return netlink.LinkSetName(iface, i.DstName())
  216. }
  217. func setInterfaceRoutes(iface netlink.Link, i *nwIface) error {
  218. for _, route := range i.Routes() {
  219. err := netlink.RouteAdd(&netlink.Route{
  220. Scope: netlink.SCOPE_LINK,
  221. LinkIndex: iface.Attrs().Index,
  222. Dst: route,
  223. })
  224. if err != nil {
  225. return err
  226. }
  227. }
  228. return nil
  229. }