interface_linux.go 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431
  1. package osl
  2. import (
  3. "fmt"
  4. "net"
  5. "sync"
  6. "syscall"
  7. "time"
  8. "github.com/docker/docker/libnetwork/ns"
  9. "github.com/docker/docker/libnetwork/types"
  10. "github.com/sirupsen/logrus"
  11. "github.com/vishvananda/netlink"
  12. "github.com/vishvananda/netns"
  13. )
  14. type nwIface struct {
  15. srcName string
  16. dstName string
  17. master string
  18. dstMaster string
  19. mac net.HardwareAddr
  20. address *net.IPNet
  21. addressIPv6 *net.IPNet
  22. llAddrs []*net.IPNet
  23. routes []*net.IPNet
  24. bridge bool
  25. ns *networkNamespace
  26. sync.Mutex
  27. }
  28. func (i *nwIface) SrcName() string {
  29. i.Lock()
  30. defer i.Unlock()
  31. return i.srcName
  32. }
  33. func (i *nwIface) DstName() string {
  34. i.Lock()
  35. defer i.Unlock()
  36. return i.dstName
  37. }
  38. func (i *nwIface) DstMaster() string {
  39. i.Lock()
  40. defer i.Unlock()
  41. return i.dstMaster
  42. }
  43. func (i *nwIface) Bridge() bool {
  44. i.Lock()
  45. defer i.Unlock()
  46. return i.bridge
  47. }
  48. func (i *nwIface) Master() string {
  49. i.Lock()
  50. defer i.Unlock()
  51. return i.master
  52. }
  53. func (i *nwIface) MacAddress() net.HardwareAddr {
  54. i.Lock()
  55. defer i.Unlock()
  56. return types.GetMacCopy(i.mac)
  57. }
  58. func (i *nwIface) Address() *net.IPNet {
  59. i.Lock()
  60. defer i.Unlock()
  61. return types.GetIPNetCopy(i.address)
  62. }
  63. func (i *nwIface) AddressIPv6() *net.IPNet {
  64. i.Lock()
  65. defer i.Unlock()
  66. return types.GetIPNetCopy(i.addressIPv6)
  67. }
  68. func (i *nwIface) LinkLocalAddresses() []*net.IPNet {
  69. i.Lock()
  70. defer i.Unlock()
  71. return i.llAddrs
  72. }
  73. func (i *nwIface) Routes() []*net.IPNet {
  74. i.Lock()
  75. defer i.Unlock()
  76. routes := make([]*net.IPNet, len(i.routes))
  77. for index, route := range i.routes {
  78. r := types.GetIPNetCopy(route)
  79. routes[index] = r
  80. }
  81. return routes
  82. }
  83. func (n *networkNamespace) Interfaces() []Interface {
  84. n.Lock()
  85. defer n.Unlock()
  86. ifaces := make([]Interface, len(n.iFaces))
  87. for i, iface := range n.iFaces {
  88. ifaces[i] = iface
  89. }
  90. return ifaces
  91. }
  92. func (i *nwIface) Remove() error {
  93. i.Lock()
  94. n := i.ns
  95. i.Unlock()
  96. n.Lock()
  97. isDefault := n.isDefault
  98. nlh := n.nlHandle
  99. n.Unlock()
  100. // Find the network interface identified by the DstName attribute.
  101. iface, err := nlh.LinkByName(i.DstName())
  102. if err != nil {
  103. return err
  104. }
  105. // Down the interface before configuring
  106. if err := nlh.LinkSetDown(iface); err != nil {
  107. return err
  108. }
  109. err = nlh.LinkSetName(iface, i.SrcName())
  110. if err != nil {
  111. logrus.Debugf("LinkSetName failed for interface %s: %v", i.SrcName(), err)
  112. return err
  113. }
  114. // if it is a bridge just delete it.
  115. if i.Bridge() {
  116. if err := nlh.LinkDel(iface); err != nil {
  117. return fmt.Errorf("failed deleting bridge %q: %v", i.SrcName(), err)
  118. }
  119. } else if !isDefault {
  120. // Move the network interface to caller namespace.
  121. if err := nlh.LinkSetNsFd(iface, ns.ParseHandlerInt()); err != nil {
  122. logrus.Debugf("LinkSetNsPid failed for interface %s: %v", i.SrcName(), err)
  123. return err
  124. }
  125. }
  126. n.Lock()
  127. for index, intf := range n.iFaces {
  128. if intf == i {
  129. n.iFaces = append(n.iFaces[:index], n.iFaces[index+1:]...)
  130. break
  131. }
  132. }
  133. n.Unlock()
  134. n.checkLoV6()
  135. return nil
  136. }
  137. // Returns the sandbox's side veth interface statistics
  138. func (i *nwIface) Statistics() (*types.InterfaceStatistics, error) {
  139. i.Lock()
  140. n := i.ns
  141. i.Unlock()
  142. l, err := n.nlHandle.LinkByName(i.DstName())
  143. if err != nil {
  144. return nil, fmt.Errorf("failed to retrieve the statistics for %s in netns %s: %v", i.DstName(), n.path, err)
  145. }
  146. stats := l.Attrs().Statistics
  147. if stats == nil {
  148. return nil, fmt.Errorf("no statistics were returned")
  149. }
  150. return &types.InterfaceStatistics{
  151. RxBytes: stats.RxBytes,
  152. TxBytes: stats.TxBytes,
  153. RxPackets: stats.RxPackets,
  154. TxPackets: stats.TxPackets,
  155. RxDropped: stats.RxDropped,
  156. TxDropped: stats.TxDropped,
  157. }, nil
  158. }
  159. func (n *networkNamespace) findDst(srcName string, isBridge bool) string {
  160. n.Lock()
  161. defer n.Unlock()
  162. for _, i := range n.iFaces {
  163. // The master should match the srcname of the interface and the
  164. // master interface should be of type bridge, if searching for a bridge type
  165. if i.SrcName() == srcName && (!isBridge || i.Bridge()) {
  166. return i.DstName()
  167. }
  168. }
  169. return ""
  170. }
  171. func (n *networkNamespace) AddInterface(srcName, dstPrefix string, options ...IfaceOption) error {
  172. i := &nwIface{srcName: srcName, dstName: dstPrefix, ns: n}
  173. i.processInterfaceOptions(options...)
  174. if i.master != "" {
  175. i.dstMaster = n.findDst(i.master, true)
  176. if i.dstMaster == "" {
  177. return fmt.Errorf("could not find an appropriate master %q for %q",
  178. i.master, i.srcName)
  179. }
  180. }
  181. n.Lock()
  182. if n.isDefault {
  183. i.dstName = i.srcName
  184. } else {
  185. i.dstName = fmt.Sprintf("%s%d", dstPrefix, n.nextIfIndex[dstPrefix])
  186. n.nextIfIndex[dstPrefix]++
  187. }
  188. path := n.path
  189. isDefault := n.isDefault
  190. nlh := n.nlHandle
  191. nlhHost := ns.NlHandle()
  192. n.Unlock()
  193. // If it is a bridge interface we have to create the bridge inside
  194. // the namespace so don't try to lookup the interface using srcName
  195. if i.bridge {
  196. link := &netlink.Bridge{
  197. LinkAttrs: netlink.LinkAttrs{
  198. Name: i.srcName,
  199. },
  200. }
  201. if err := nlh.LinkAdd(link); err != nil {
  202. return fmt.Errorf("failed to create bridge %q: %v", i.srcName, err)
  203. }
  204. } else {
  205. // Find the network interface identified by the SrcName attribute.
  206. iface, err := nlhHost.LinkByName(i.srcName)
  207. if err != nil {
  208. return fmt.Errorf("failed to get link by name %q: %v", i.srcName, err)
  209. }
  210. // Move the network interface to the destination
  211. // namespace only if the namespace is not a default
  212. // type
  213. if !isDefault {
  214. newNs, err := netns.GetFromPath(path)
  215. if err != nil {
  216. return fmt.Errorf("failed get network namespace %q: %v", path, err)
  217. }
  218. defer newNs.Close()
  219. if err := nlhHost.LinkSetNsFd(iface, int(newNs)); err != nil {
  220. return fmt.Errorf("failed to set namespace on link %q: %v", i.srcName, err)
  221. }
  222. }
  223. }
  224. // Find the network interface identified by the SrcName attribute.
  225. iface, err := nlh.LinkByName(i.srcName)
  226. if err != nil {
  227. return fmt.Errorf("failed to get link by name %q: %v", i.srcName, err)
  228. }
  229. // Down the interface before configuring
  230. if err := nlh.LinkSetDown(iface); err != nil {
  231. return fmt.Errorf("failed to set link down: %v", err)
  232. }
  233. // Configure the interface now this is moved in the proper namespace.
  234. if err := configureInterface(nlh, iface, i); err != nil {
  235. // If configuring the device fails move it back to the host namespace
  236. // and change the name back to the source name. This allows the caller
  237. // to properly cleanup the interface. Its important especially for
  238. // interfaces with global attributes, ex: vni id for vxlan interfaces.
  239. if nerr := nlh.LinkSetName(iface, i.SrcName()); nerr != nil {
  240. logrus.Errorf("renaming interface (%s->%s) failed, %v after config error %v", i.DstName(), i.SrcName(), nerr, err)
  241. }
  242. if nerr := nlh.LinkSetNsFd(iface, ns.ParseHandlerInt()); nerr != nil {
  243. logrus.Errorf("moving interface %s to host ns failed, %v, after config error %v", i.SrcName(), nerr, err)
  244. }
  245. return err
  246. }
  247. // Up the interface.
  248. cnt := 0
  249. for err = nlh.LinkSetUp(iface); err != nil && cnt < 3; cnt++ {
  250. logrus.Debugf("retrying link setup because of: %v", err)
  251. time.Sleep(10 * time.Millisecond)
  252. err = nlh.LinkSetUp(iface)
  253. }
  254. if err != nil {
  255. return fmt.Errorf("failed to set link up: %v", err)
  256. }
  257. // Set the routes on the interface. This can only be done when the interface is up.
  258. if err := setInterfaceRoutes(nlh, iface, i); err != nil {
  259. return fmt.Errorf("error setting interface %q routes to %q: %v", iface.Attrs().Name, i.Routes(), err)
  260. }
  261. n.Lock()
  262. n.iFaces = append(n.iFaces, i)
  263. n.Unlock()
  264. n.checkLoV6()
  265. return nil
  266. }
  267. func configureInterface(nlh *netlink.Handle, iface netlink.Link, i *nwIface) error {
  268. ifaceName := iface.Attrs().Name
  269. ifaceConfigurators := []struct {
  270. Fn func(*netlink.Handle, netlink.Link, *nwIface) error
  271. ErrMessage string
  272. }{
  273. {setInterfaceName, fmt.Sprintf("error renaming interface %q to %q", ifaceName, i.DstName())},
  274. {setInterfaceMAC, fmt.Sprintf("error setting interface %q MAC to %q", ifaceName, i.MacAddress())},
  275. {setInterfaceIP, fmt.Sprintf("error setting interface %q IP to %v", ifaceName, i.Address())},
  276. {setInterfaceIPv6, fmt.Sprintf("error setting interface %q IPv6 to %v", ifaceName, i.AddressIPv6())},
  277. {setInterfaceMaster, fmt.Sprintf("error setting interface %q master to %q", ifaceName, i.DstMaster())},
  278. {setInterfaceLinkLocalIPs, fmt.Sprintf("error setting interface %q link local IPs to %v", ifaceName, i.LinkLocalAddresses())},
  279. }
  280. for _, config := range ifaceConfigurators {
  281. if err := config.Fn(nlh, iface, i); err != nil {
  282. return fmt.Errorf("%s: %v", config.ErrMessage, err)
  283. }
  284. }
  285. return nil
  286. }
  287. func setInterfaceMaster(nlh *netlink.Handle, iface netlink.Link, i *nwIface) error {
  288. if i.DstMaster() == "" {
  289. return nil
  290. }
  291. return nlh.LinkSetMaster(iface, &netlink.Bridge{
  292. LinkAttrs: netlink.LinkAttrs{Name: i.DstMaster()}})
  293. }
  294. func setInterfaceMAC(nlh *netlink.Handle, iface netlink.Link, i *nwIface) error {
  295. if i.MacAddress() == nil {
  296. return nil
  297. }
  298. return nlh.LinkSetHardwareAddr(iface, i.MacAddress())
  299. }
  300. func setInterfaceIP(nlh *netlink.Handle, iface netlink.Link, i *nwIface) error {
  301. if i.Address() == nil {
  302. return nil
  303. }
  304. if err := checkRouteConflict(nlh, i.Address(), netlink.FAMILY_V4); err != nil {
  305. return err
  306. }
  307. ipAddr := &netlink.Addr{IPNet: i.Address(), Label: ""}
  308. return nlh.AddrAdd(iface, ipAddr)
  309. }
  310. func setInterfaceIPv6(nlh *netlink.Handle, iface netlink.Link, i *nwIface) error {
  311. if i.AddressIPv6() == nil {
  312. return nil
  313. }
  314. if err := checkRouteConflict(nlh, i.AddressIPv6(), netlink.FAMILY_V6); err != nil {
  315. return err
  316. }
  317. if err := setIPv6(i.ns.path, i.DstName(), true); err != nil {
  318. return fmt.Errorf("failed to enable ipv6: %v", err)
  319. }
  320. ipAddr := &netlink.Addr{IPNet: i.AddressIPv6(), Label: "", Flags: syscall.IFA_F_NODAD}
  321. return nlh.AddrAdd(iface, ipAddr)
  322. }
  323. func setInterfaceLinkLocalIPs(nlh *netlink.Handle, iface netlink.Link, i *nwIface) error {
  324. for _, llIP := range i.LinkLocalAddresses() {
  325. ipAddr := &netlink.Addr{IPNet: llIP}
  326. if err := nlh.AddrAdd(iface, ipAddr); err != nil {
  327. return err
  328. }
  329. }
  330. return nil
  331. }
  332. func setInterfaceName(nlh *netlink.Handle, iface netlink.Link, i *nwIface) error {
  333. return nlh.LinkSetName(iface, i.DstName())
  334. }
  335. func setInterfaceRoutes(nlh *netlink.Handle, iface netlink.Link, i *nwIface) error {
  336. for _, route := range i.Routes() {
  337. err := nlh.RouteAdd(&netlink.Route{
  338. Scope: netlink.SCOPE_LINK,
  339. LinkIndex: iface.Attrs().Index,
  340. Dst: route,
  341. })
  342. if err != nil {
  343. return err
  344. }
  345. }
  346. return nil
  347. }
  348. func checkRouteConflict(nlh *netlink.Handle, address *net.IPNet, family int) error {
  349. routes, err := nlh.RouteList(nil, family)
  350. if err != nil {
  351. return err
  352. }
  353. for _, route := range routes {
  354. if route.Dst != nil {
  355. if route.Dst.Contains(address.IP) || address.Contains(route.Dst.IP) {
  356. return fmt.Errorf("cannot program address %v in sandbox interface because it conflicts with existing route %s",
  357. address, route)
  358. }
  359. }
  360. }
  361. return nil
  362. }