bridge.go 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525
  1. package bridge
  2. import (
  3. "net"
  4. "strings"
  5. "sync"
  6. "github.com/docker/libnetwork/driverapi"
  7. "github.com/docker/libnetwork/ipallocator"
  8. "github.com/docker/libnetwork/netutils"
  9. "github.com/docker/libnetwork/pkg/options"
  10. "github.com/docker/libnetwork/portmapper"
  11. "github.com/docker/libnetwork/sandbox"
  12. "github.com/docker/libnetwork/types"
  13. "github.com/vishvananda/netlink"
  14. )
  15. const (
  16. networkType = "bridge"
  17. vethPrefix = "veth"
  18. vethLen = 7
  19. containerVeth = "eth0"
  20. )
  21. var (
  22. ipAllocator *ipallocator.IPAllocator
  23. portMapper *portmapper.PortMapper
  24. )
  25. // Configuration info for the "bridge" driver.
  26. type Configuration struct {
  27. BridgeName string
  28. AddressIPv4 *net.IPNet
  29. FixedCIDR *net.IPNet
  30. FixedCIDRv6 *net.IPNet
  31. EnableIPv6 bool
  32. EnableIPTables bool
  33. EnableIPMasquerade bool
  34. EnableICC bool
  35. EnableIPForwarding bool
  36. AllowNonDefaultBridge bool
  37. Mtu int
  38. }
  39. // EndpointConfiguration represents the user specified configuration for the sandbox endpoint
  40. type EndpointConfiguration struct {
  41. MacAddress net.HardwareAddr
  42. }
  43. type bridgeEndpoint struct {
  44. id types.UUID
  45. port *sandbox.Interface
  46. config *EndpointConfiguration // User specified parameters
  47. }
  48. type bridgeNetwork struct {
  49. id types.UUID
  50. bridge *bridgeInterface // The bridge's L3 interface
  51. endpoints map[string]*bridgeEndpoint // key: sandbox id
  52. sync.Mutex
  53. }
  54. type driver struct {
  55. config *Configuration
  56. network *bridgeNetwork
  57. sync.Mutex
  58. }
  59. func init() {
  60. ipAllocator = ipallocator.New()
  61. portMapper = portmapper.New()
  62. }
  63. // New provides a new instance of bridge driver
  64. func New() (string, driverapi.Driver) {
  65. return networkType, &driver{}
  66. }
  67. func (n *bridgeNetwork) getEndpoint(eid types.UUID) (string, *bridgeEndpoint, error) {
  68. n.Lock()
  69. defer n.Unlock()
  70. if eid == "" {
  71. return "", nil, InvalidEndpointIDError(eid)
  72. }
  73. for sk, ep := range n.endpoints {
  74. if ep.id == eid {
  75. return sk, ep, nil
  76. }
  77. }
  78. return "", nil, nil
  79. }
  80. func (d *driver) Config(option interface{}) error {
  81. var config *Configuration
  82. d.Lock()
  83. defer d.Unlock()
  84. if d.config != nil {
  85. return ErrConfigExists
  86. }
  87. switch opt := option.(type) {
  88. case options.Generic:
  89. opaqueConfig, err := options.GenerateFromModel(opt, &Configuration{})
  90. if err != nil {
  91. return err
  92. }
  93. config = opaqueConfig.(*Configuration)
  94. case *Configuration:
  95. config = opt
  96. }
  97. d.config = config
  98. return nil
  99. }
  100. // Create a new network using bridge plugin
  101. func (d *driver) CreateNetwork(id types.UUID, option interface{}) error {
  102. var err error
  103. // Driver must be configured
  104. d.Lock()
  105. if d.config == nil {
  106. d.Unlock()
  107. return ErrInvalidConfig
  108. }
  109. config := d.config
  110. // Sanity checks
  111. if d.network != nil {
  112. d.Unlock()
  113. return ErrNetworkExists
  114. }
  115. // Create and set network handler in driver
  116. d.network = &bridgeNetwork{id: id, endpoints: make(map[string]*bridgeEndpoint)}
  117. d.Unlock()
  118. // On failure make sure to reset driver network handler to nil
  119. defer func() {
  120. if err != nil {
  121. d.Lock()
  122. d.network = nil
  123. d.Unlock()
  124. }
  125. }()
  126. // Create or retrieve the bridge L3 interface
  127. bridgeIface := newInterface(config)
  128. d.network.bridge = bridgeIface
  129. // Prepare the bridge setup configuration
  130. bridgeSetup := newBridgeSetup(config, bridgeIface)
  131. // If the bridge interface doesn't exist, we need to start the setup steps
  132. // by creating a new device and assigning it an IPv4 address.
  133. bridgeAlreadyExists := bridgeIface.exists()
  134. if !bridgeAlreadyExists {
  135. bridgeSetup.queueStep(setupDevice)
  136. bridgeSetup.queueStep(setupBridgeIPv4)
  137. }
  138. // Conditionnally queue setup steps depending on configuration values.
  139. for _, step := range []struct {
  140. Condition bool
  141. Fn setupStep
  142. }{
  143. // Enable IPv6 on the bridge if required. We do this even for a
  144. // previously existing bridge, as it may be here from a previous
  145. // installation where IPv6 wasn't supported yet and needs to be
  146. // assigned an IPv6 link-local address.
  147. {config.EnableIPv6, setupBridgeIPv6},
  148. // We ensure that the bridge has the expectedIPv4 and IPv6 addresses in
  149. // the case of a previously existing device.
  150. {bridgeAlreadyExists, setupVerifyAndReconcile},
  151. // Setup the bridge to allocate containers IPv4 addresses in the
  152. // specified subnet.
  153. {config.FixedCIDR != nil, setupFixedCIDRv4},
  154. // Setup the bridge to allocate containers global IPv6 addresses in the
  155. // specified subnet.
  156. {config.FixedCIDRv6 != nil, setupFixedCIDRv6},
  157. // Setup IPTables.
  158. {config.EnableIPTables, setupIPTables},
  159. // Setup IP forwarding.
  160. {config.EnableIPForwarding, setupIPForwarding},
  161. } {
  162. if step.Condition {
  163. bridgeSetup.queueStep(step.Fn)
  164. }
  165. }
  166. // Apply the prepared list of steps, and abort at the first error.
  167. bridgeSetup.queueStep(setupDeviceUp)
  168. if err = bridgeSetup.apply(); err != nil {
  169. return err
  170. }
  171. return nil
  172. }
  173. func (d *driver) DeleteNetwork(nid types.UUID) error {
  174. var err error
  175. // Get network handler and remove it from driver
  176. d.Lock()
  177. n := d.network
  178. d.network = nil
  179. d.Unlock()
  180. // On failure set network handler back in driver, but
  181. // only if is not already taken over by some other thread
  182. defer func() {
  183. if err != nil {
  184. d.Lock()
  185. if d.network == nil {
  186. d.network = n
  187. }
  188. d.Unlock()
  189. }
  190. }()
  191. // Sanity check
  192. if n == nil {
  193. err = driverapi.ErrNoNetwork
  194. return err
  195. }
  196. // Cannot remove network if endpoints are still present
  197. if len(n.endpoints) != 0 {
  198. err = ActiveEndpointsError(n.id)
  199. return err
  200. }
  201. // Programming
  202. err = netlink.LinkDel(n.bridge.Link)
  203. return err
  204. }
  205. func (d *driver) CreateEndpoint(nid, eid types.UUID, sboxKey string, epOptions interface{}) (*sandbox.Info, error) {
  206. var (
  207. ipv6Addr *net.IPNet
  208. err error
  209. )
  210. // Get the network handler and make sure it exists
  211. d.Lock()
  212. n := d.network
  213. config := d.config
  214. d.Unlock()
  215. if n == nil {
  216. return nil, driverapi.ErrNoNetwork
  217. }
  218. // Sanity check
  219. n.Lock()
  220. if n.id != nid {
  221. n.Unlock()
  222. return nil, InvalidNetworkIDError(nid)
  223. }
  224. n.Unlock()
  225. // Check if endpoint id is good and retrieve correspondent endpoint
  226. _, ep, err := n.getEndpoint(eid)
  227. if err != nil {
  228. return nil, err
  229. }
  230. // Endpoint with that id exists either on desired or other sandbox
  231. if ep != nil {
  232. return nil, driverapi.ErrEndpointExists
  233. }
  234. // Check if valid sandbox key
  235. if sboxKey == "" {
  236. return nil, InvalidSandboxIDError(sboxKey)
  237. }
  238. // Check if endpoint already exists for this sandbox
  239. n.Lock()
  240. if _, ok := n.endpoints[sboxKey]; ok {
  241. n.Unlock()
  242. return nil, driverapi.ErrEndpointExists
  243. }
  244. // Try to convert the options to endpoint configuration
  245. epConfig, err := parseEndpointOptions(epOptions)
  246. if err != nil {
  247. return nil, err
  248. }
  249. // Create and add the endpoint
  250. endpoint := &bridgeEndpoint{id: eid, config: epConfig}
  251. n.endpoints[sboxKey] = endpoint
  252. n.Unlock()
  253. // On failure make sure to remove the endpoint
  254. defer func() {
  255. if err != nil {
  256. n.Lock()
  257. delete(n.endpoints, sboxKey)
  258. n.Unlock()
  259. }
  260. }()
  261. // Generate a name for what will be the host side pipe interface
  262. name1, err := generateIfaceName()
  263. if err != nil {
  264. return nil, err
  265. }
  266. // Generate a name for what will be the sandbox side pipe interface
  267. name2, err := generateIfaceName()
  268. if err != nil {
  269. return nil, err
  270. }
  271. // Generate and add the interface pipe host <-> sandbox
  272. veth := &netlink.Veth{
  273. LinkAttrs: netlink.LinkAttrs{Name: name1, TxQLen: 0},
  274. PeerName: name2}
  275. if err = netlink.LinkAdd(veth); err != nil {
  276. return nil, err
  277. }
  278. // Get the host side pipe interface handler
  279. host, err := netlink.LinkByName(name1)
  280. if err != nil {
  281. return nil, err
  282. }
  283. defer func() {
  284. if err != nil {
  285. netlink.LinkDel(host)
  286. }
  287. }()
  288. // Get the sandbox side pipe interface handler
  289. sbox, err := netlink.LinkByName(name2)
  290. if err != nil {
  291. return nil, err
  292. }
  293. defer func() {
  294. if err != nil {
  295. netlink.LinkDel(sbox)
  296. }
  297. }()
  298. // Add user specified attributes
  299. if epConfig != nil && epConfig.MacAddress != nil {
  300. err = netlink.LinkSetHardwareAddr(sbox, epConfig.MacAddress)
  301. if err != nil {
  302. return nil, err
  303. }
  304. }
  305. // Add bridge inherited attributes to pipe interfaces
  306. if config.Mtu != 0 {
  307. err = netlink.LinkSetMTU(host, config.Mtu)
  308. if err != nil {
  309. return nil, err
  310. }
  311. err = netlink.LinkSetMTU(sbox, config.Mtu)
  312. if err != nil {
  313. return nil, err
  314. }
  315. }
  316. // Attach host side pipe interface into the bridge
  317. if err = netlink.LinkSetMaster(host,
  318. &netlink.Bridge{LinkAttrs: netlink.LinkAttrs{Name: config.BridgeName}}); err != nil {
  319. return nil, err
  320. }
  321. // v4 address for the sandbox side pipe interface
  322. ip4, err := ipAllocator.RequestIP(n.bridge.bridgeIPv4, nil)
  323. if err != nil {
  324. return nil, err
  325. }
  326. ipv4Addr := &net.IPNet{IP: ip4, Mask: n.bridge.bridgeIPv4.Mask}
  327. // v6 address for the sandbox side pipe interface
  328. if config.EnableIPv6 {
  329. ip6, err := ipAllocator.RequestIP(n.bridge.bridgeIPv6, nil)
  330. if err != nil {
  331. return nil, err
  332. }
  333. ipv6Addr = &net.IPNet{IP: ip6, Mask: n.bridge.bridgeIPv6.Mask}
  334. }
  335. // Store the sandbox side pipe interface
  336. // This is needed for cleanup on DeleteEndpoint()
  337. intf := &sandbox.Interface{}
  338. intf.SrcName = name2
  339. intf.DstName = containerVeth
  340. intf.Address = ipv4Addr
  341. // Update endpoint with the sandbox interface info
  342. endpoint.port = intf
  343. // Generate the sandbox info to return
  344. sinfo := &sandbox.Info{Interfaces: []*sandbox.Interface{intf}}
  345. sinfo.Gateway = n.bridge.bridgeIPv4.IP
  346. if config.EnableIPv6 {
  347. intf.AddressIPv6 = ipv6Addr
  348. sinfo.GatewayIPv6 = n.bridge.bridgeIPv6.IP
  349. }
  350. return sinfo, nil
  351. }
  352. func (d *driver) DeleteEndpoint(nid, eid types.UUID) error {
  353. var err error
  354. // Get the network handler and make sure it exists
  355. d.Lock()
  356. n := d.network
  357. config := d.config
  358. d.Unlock()
  359. if n == nil {
  360. return driverapi.ErrNoNetwork
  361. }
  362. // Sanity Check
  363. n.Lock()
  364. if n.id != nid {
  365. n.Unlock()
  366. return InvalidNetworkIDError(nid)
  367. }
  368. n.Unlock()
  369. // Check endpoint id and if an endpoint is actually there
  370. sboxKey, ep, err := n.getEndpoint(eid)
  371. if err != nil {
  372. return err
  373. }
  374. if ep == nil {
  375. return EndpointNotFoundError(eid)
  376. }
  377. // Remove it
  378. n.Lock()
  379. delete(n.endpoints, sboxKey)
  380. n.Unlock()
  381. // On failure make sure to set back ep in n.endpoints, but only
  382. // if it hasn't been taken over already by some other thread.
  383. defer func() {
  384. if err != nil {
  385. n.Lock()
  386. if _, ok := n.endpoints[sboxKey]; !ok {
  387. n.endpoints[sboxKey] = ep
  388. }
  389. n.Unlock()
  390. }
  391. }()
  392. // Release the v4 address allocated to this endpoint's sandbox interface
  393. err = ipAllocator.ReleaseIP(n.bridge.bridgeIPv4, ep.port.Address.IP)
  394. if err != nil {
  395. return err
  396. }
  397. // Release the v6 address allocated to this endpoint's sandbox interface
  398. if config.EnableIPv6 {
  399. err := ipAllocator.ReleaseIP(n.bridge.bridgeIPv6, ep.port.AddressIPv6.IP)
  400. if err != nil {
  401. return err
  402. }
  403. }
  404. // Try removal of link. Discard error: link pair might have
  405. // already been deleted by sandbox delete.
  406. link, err := netlink.LinkByName(ep.port.SrcName)
  407. if err == nil {
  408. netlink.LinkDel(link)
  409. }
  410. return nil
  411. }
  412. func parseEndpointOptions(epOptions interface{}) (*EndpointConfiguration, error) {
  413. if epOptions == nil {
  414. return nil, nil
  415. }
  416. switch opt := epOptions.(type) {
  417. case options.Generic:
  418. opaqueConfig, err := options.GenerateFromModel(opt, &EndpointConfiguration{})
  419. if err != nil {
  420. return nil, err
  421. }
  422. return opaqueConfig.(*EndpointConfiguration), nil
  423. case *EndpointConfiguration:
  424. return opt, nil
  425. default:
  426. return nil, ErrInvalidEndpointConfig
  427. }
  428. }
  429. // Generates a name to be used for a virtual ethernet
  430. // interface. The name is constructed by 'veth' appended
  431. // by a randomly generated hex value. (example: veth0f60e2c)
  432. func generateIfaceName() (string, error) {
  433. for i := 0; i < 3; i++ {
  434. name, err := netutils.GenerateRandomName(vethPrefix, vethLen)
  435. if err != nil {
  436. continue
  437. }
  438. if _, err := net.InterfaceByName(name); err != nil {
  439. if strings.Contains(err.Error(), "no such") {
  440. return name, nil
  441. }
  442. return "", err
  443. }
  444. }
  445. return "", ErrIfaceName
  446. }