interface_linux.go 7.0 KB

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