network.go 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755
  1. package docker
  2. import (
  3. "encoding/binary"
  4. "errors"
  5. "fmt"
  6. "github.com/dotcloud/docker/utils"
  7. "log"
  8. "net"
  9. "os/exec"
  10. "strconv"
  11. "strings"
  12. "sync"
  13. )
  14. var NetworkBridgeIface string
  15. const (
  16. DefaultNetworkBridge = "docker0"
  17. DisableNetworkBridge = "none"
  18. portRangeStart = 49153
  19. portRangeEnd = 65535
  20. )
  21. // Calculates the first and last IP addresses in an IPNet
  22. func networkRange(network *net.IPNet) (net.IP, net.IP) {
  23. netIP := network.IP.To4()
  24. firstIP := netIP.Mask(network.Mask)
  25. lastIP := net.IPv4(0, 0, 0, 0).To4()
  26. for i := 0; i < len(lastIP); i++ {
  27. lastIP[i] = netIP[i] | ^network.Mask[i]
  28. }
  29. return firstIP, lastIP
  30. }
  31. // Detects overlap between one IPNet and another
  32. func networkOverlaps(netX *net.IPNet, netY *net.IPNet) bool {
  33. firstIP, _ := networkRange(netX)
  34. if netY.Contains(firstIP) {
  35. return true
  36. }
  37. firstIP, _ = networkRange(netY)
  38. if netX.Contains(firstIP) {
  39. return true
  40. }
  41. return false
  42. }
  43. // Converts a 4 bytes IP into a 32 bit integer
  44. func ipToInt(ip net.IP) int32 {
  45. return int32(binary.BigEndian.Uint32(ip.To4()))
  46. }
  47. // Converts 32 bit integer into a 4 bytes IP address
  48. func intToIP(n int32) net.IP {
  49. b := make([]byte, 4)
  50. binary.BigEndian.PutUint32(b, uint32(n))
  51. return net.IP(b)
  52. }
  53. // Given a netmask, calculates the number of available hosts
  54. func networkSize(mask net.IPMask) int32 {
  55. m := net.IPv4Mask(0, 0, 0, 0)
  56. for i := 0; i < net.IPv4len; i++ {
  57. m[i] = ^mask[i]
  58. }
  59. return int32(binary.BigEndian.Uint32(m)) + 1
  60. }
  61. //Wrapper around the ip command
  62. func ip(args ...string) (string, error) {
  63. path, err := exec.LookPath("ip")
  64. if err != nil {
  65. return "", fmt.Errorf("command not found: ip")
  66. }
  67. output, err := exec.Command(path, args...).CombinedOutput()
  68. if err != nil {
  69. return "", fmt.Errorf("ip failed: ip %v", strings.Join(args, " "))
  70. }
  71. return string(output), nil
  72. }
  73. // Wrapper around the iptables command
  74. func iptables(args ...string) error {
  75. path, err := exec.LookPath("iptables")
  76. if err != nil {
  77. return fmt.Errorf("command not found: iptables")
  78. }
  79. if err := exec.Command(path, args...).Run(); err != nil {
  80. return fmt.Errorf("iptables failed: iptables %v", strings.Join(args, " "))
  81. }
  82. return nil
  83. }
  84. func checkRouteOverlaps(routes string, dockerNetwork *net.IPNet) error {
  85. utils.Debugf("Routes:\n\n%s", routes)
  86. for _, line := range strings.Split(routes, "\n") {
  87. if strings.Trim(line, "\r\n\t ") == "" || strings.Contains(line, "default") {
  88. continue
  89. }
  90. _, network, err := net.ParseCIDR(strings.Split(line, " ")[0])
  91. if err != nil {
  92. // is this a mask-less IP address?
  93. if ip := net.ParseIP(strings.Split(line, " ")[0]); ip == nil {
  94. // fail only if it's neither a network nor a mask-less IP address
  95. return fmt.Errorf("Unexpected ip route output: %s (%s)", err, line)
  96. } else {
  97. _, network, err = net.ParseCIDR(ip.String() + "/32")
  98. if err != nil {
  99. return err
  100. }
  101. }
  102. }
  103. if err == nil && network != nil {
  104. if networkOverlaps(dockerNetwork, network) {
  105. return fmt.Errorf("Network %s is already routed: '%s'", dockerNetwork, line)
  106. }
  107. }
  108. }
  109. return nil
  110. }
  111. // CreateBridgeIface creates a network bridge interface on the host system with the name `ifaceName`,
  112. // and attempts to configure it with an address which doesn't conflict with any other interface on the host.
  113. // If it can't find an address which doesn't conflict, it will return an error.
  114. func CreateBridgeIface(ifaceName string) error {
  115. addrs := []string{
  116. // Here we don't follow the convention of using the 1st IP of the range for the gateway.
  117. // This is to use the same gateway IPs as the /24 ranges, which predate the /16 ranges.
  118. // In theory this shouldn't matter - in practice there's bound to be a few scripts relying
  119. // on the internal addressing or other stupid things like that.
  120. // The shouldn't, but hey, let's not break them unless we really have to.
  121. "172.17.42.1/16", // Don't use 172.16.0.0/16, it conflicts with EC2 DNS 172.16.0.23
  122. "10.0.42.1/16", // Don't even try using the entire /8, that's too intrusive
  123. "10.1.42.1/16",
  124. "10.42.42.1/16",
  125. "172.16.42.1/24",
  126. "172.16.43.1/24",
  127. "172.16.44.1/24",
  128. "10.0.42.1/24",
  129. "10.0.43.1/24",
  130. "192.168.42.1/24",
  131. "192.168.43.1/24",
  132. "192.168.44.1/24",
  133. }
  134. var ifaceAddr string
  135. for _, addr := range addrs {
  136. _, dockerNetwork, err := net.ParseCIDR(addr)
  137. if err != nil {
  138. return err
  139. }
  140. routes, err := ip("route")
  141. if err != nil {
  142. return err
  143. }
  144. if err := checkRouteOverlaps(routes, dockerNetwork); err == nil {
  145. ifaceAddr = addr
  146. break
  147. } else {
  148. utils.Debugf("%s: %s", addr, err)
  149. }
  150. }
  151. if ifaceAddr == "" {
  152. return fmt.Errorf("Could not find a free IP address range for interface '%s'. Please configure its address manually and run 'docker -b %s'", ifaceName, ifaceName)
  153. }
  154. utils.Debugf("Creating bridge %s with network %s", ifaceName, ifaceAddr)
  155. if output, err := ip("link", "add", ifaceName, "type", "bridge"); err != nil {
  156. return fmt.Errorf("Error creating bridge: %s (output: %s)", err, output)
  157. }
  158. if output, err := ip("addr", "add", ifaceAddr, "dev", ifaceName); err != nil {
  159. return fmt.Errorf("Unable to add private network: %s (%s)", err, output)
  160. }
  161. if output, err := ip("link", "set", ifaceName, "up"); err != nil {
  162. return fmt.Errorf("Unable to start network bridge: %s (%s)", err, output)
  163. }
  164. if err := iptables("-t", "nat", "-A", "POSTROUTING", "-s", ifaceAddr,
  165. "!", "-d", ifaceAddr, "-j", "MASQUERADE"); err != nil {
  166. return fmt.Errorf("Unable to enable network bridge NAT: %s", err)
  167. }
  168. return nil
  169. }
  170. // Return the IPv4 address of a network interface
  171. func getIfaceAddr(name string) (net.Addr, error) {
  172. iface, err := net.InterfaceByName(name)
  173. if err != nil {
  174. return nil, err
  175. }
  176. addrs, err := iface.Addrs()
  177. if err != nil {
  178. return nil, err
  179. }
  180. var addrs4 []net.Addr
  181. for _, addr := range addrs {
  182. ip := (addr.(*net.IPNet)).IP
  183. if ip4 := ip.To4(); len(ip4) == net.IPv4len {
  184. addrs4 = append(addrs4, addr)
  185. }
  186. }
  187. switch {
  188. case len(addrs4) == 0:
  189. return nil, fmt.Errorf("Interface %v has no IP addresses", name)
  190. case len(addrs4) > 1:
  191. fmt.Printf("Interface %v has more than 1 IPv4 address. Defaulting to using %v\n",
  192. name, (addrs4[0].(*net.IPNet)).IP)
  193. }
  194. return addrs4[0], nil
  195. }
  196. // Port mapper takes care of mapping external ports to containers by setting
  197. // up iptables rules.
  198. // It keeps track of all mappings and is able to unmap at will
  199. type PortMapper struct {
  200. tcpMapping map[int]*net.TCPAddr
  201. tcpProxies map[int]Proxy
  202. udpMapping map[int]*net.UDPAddr
  203. udpProxies map[int]Proxy
  204. }
  205. func (mapper *PortMapper) cleanup() error {
  206. // Ignore errors - This could mean the chains were never set up
  207. iptables("-t", "nat", "-D", "PREROUTING", "-m", "addrtype", "--dst-type", "LOCAL", "-j", "DOCKER")
  208. iptables("-t", "nat", "-D", "OUTPUT", "-m", "addrtype", "--dst-type", "LOCAL", "!", "--dst", "127.0.0.0/8", "-j", "DOCKER")
  209. iptables("-t", "nat", "-D", "OUTPUT", "-m", "addrtype", "--dst-type", "LOCAL", "-j", "DOCKER") // Created in versions <= 0.1.6
  210. // Also cleanup rules created by older versions, or -X might fail.
  211. iptables("-t", "nat", "-D", "PREROUTING", "-j", "DOCKER")
  212. iptables("-t", "nat", "-D", "OUTPUT", "-j", "DOCKER")
  213. iptables("-t", "nat", "-F", "DOCKER")
  214. iptables("-t", "nat", "-X", "DOCKER")
  215. mapper.tcpMapping = make(map[int]*net.TCPAddr)
  216. mapper.tcpProxies = make(map[int]Proxy)
  217. mapper.udpMapping = make(map[int]*net.UDPAddr)
  218. mapper.udpProxies = make(map[int]Proxy)
  219. return nil
  220. }
  221. func (mapper *PortMapper) setup() error {
  222. if err := iptables("-t", "nat", "-N", "DOCKER"); err != nil {
  223. return fmt.Errorf("Failed to create DOCKER chain: %s", err)
  224. }
  225. if err := iptables("-t", "nat", "-A", "PREROUTING", "-m", "addrtype", "--dst-type", "LOCAL", "-j", "DOCKER"); err != nil {
  226. return fmt.Errorf("Failed to inject docker in PREROUTING chain: %s", err)
  227. }
  228. if err := iptables("-t", "nat", "-A", "OUTPUT", "-m", "addrtype", "--dst-type", "LOCAL", "!", "--dst", "127.0.0.0/8", "-j", "DOCKER"); err != nil {
  229. return fmt.Errorf("Failed to inject docker in OUTPUT chain: %s", err)
  230. }
  231. return nil
  232. }
  233. func (mapper *PortMapper) iptablesForward(rule string, port int, proto string, dest_addr string, dest_port int) error {
  234. return iptables("-t", "nat", rule, "DOCKER", "-p", proto, "--dport", strconv.Itoa(port),
  235. "!", "-i", NetworkBridgeIface,
  236. "-j", "DNAT", "--to-destination", net.JoinHostPort(dest_addr, strconv.Itoa(dest_port)))
  237. }
  238. func (mapper *PortMapper) Map(port int, backendAddr net.Addr) error {
  239. if _, isTCP := backendAddr.(*net.TCPAddr); isTCP {
  240. backendPort := backendAddr.(*net.TCPAddr).Port
  241. backendIP := backendAddr.(*net.TCPAddr).IP
  242. if err := mapper.iptablesForward("-A", port, "tcp", backendIP.String(), backendPort); err != nil {
  243. return err
  244. }
  245. mapper.tcpMapping[port] = backendAddr.(*net.TCPAddr)
  246. proxy, err := NewProxy(&net.TCPAddr{IP: net.IPv4(0, 0, 0, 0), Port: port}, backendAddr)
  247. if err != nil {
  248. mapper.Unmap(port, "tcp")
  249. return err
  250. }
  251. mapper.tcpProxies[port] = proxy
  252. go proxy.Run()
  253. } else {
  254. backendPort := backendAddr.(*net.UDPAddr).Port
  255. backendIP := backendAddr.(*net.UDPAddr).IP
  256. if err := mapper.iptablesForward("-A", port, "udp", backendIP.String(), backendPort); err != nil {
  257. return err
  258. }
  259. mapper.udpMapping[port] = backendAddr.(*net.UDPAddr)
  260. proxy, err := NewProxy(&net.UDPAddr{IP: net.IPv4(0, 0, 0, 0), Port: port}, backendAddr)
  261. if err != nil {
  262. mapper.Unmap(port, "udp")
  263. return err
  264. }
  265. mapper.udpProxies[port] = proxy
  266. go proxy.Run()
  267. }
  268. return nil
  269. }
  270. func (mapper *PortMapper) Unmap(port int, proto string) error {
  271. if proto == "tcp" {
  272. backendAddr, ok := mapper.tcpMapping[port]
  273. if !ok {
  274. return fmt.Errorf("Port tcp/%v is not mapped", port)
  275. }
  276. if proxy, exists := mapper.tcpProxies[port]; exists {
  277. proxy.Close()
  278. delete(mapper.tcpProxies, port)
  279. }
  280. if err := mapper.iptablesForward("-D", port, proto, backendAddr.IP.String(), backendAddr.Port); err != nil {
  281. return err
  282. }
  283. delete(mapper.tcpMapping, port)
  284. } else {
  285. backendAddr, ok := mapper.udpMapping[port]
  286. if !ok {
  287. return fmt.Errorf("Port udp/%v is not mapped", port)
  288. }
  289. if proxy, exists := mapper.udpProxies[port]; exists {
  290. proxy.Close()
  291. delete(mapper.udpProxies, port)
  292. }
  293. if err := mapper.iptablesForward("-D", port, proto, backendAddr.IP.String(), backendAddr.Port); err != nil {
  294. return err
  295. }
  296. delete(mapper.udpMapping, port)
  297. }
  298. return nil
  299. }
  300. func newPortMapper() (*PortMapper, error) {
  301. mapper := &PortMapper{}
  302. if err := mapper.cleanup(); err != nil {
  303. return nil, err
  304. }
  305. if err := mapper.setup(); err != nil {
  306. return nil, err
  307. }
  308. return mapper, nil
  309. }
  310. // Port allocator: Automatically allocate and release networking ports
  311. type PortAllocator struct {
  312. sync.Mutex
  313. inUse map[int]struct{}
  314. fountain chan int
  315. quit chan bool
  316. }
  317. func (alloc *PortAllocator) runFountain() {
  318. for {
  319. for port := portRangeStart; port < portRangeEnd; port++ {
  320. select {
  321. case alloc.fountain <- port:
  322. case quit := <-alloc.quit:
  323. if quit {
  324. return
  325. }
  326. }
  327. }
  328. }
  329. }
  330. // FIXME: Release can no longer fail, change its prototype to reflect that.
  331. func (alloc *PortAllocator) Release(port int) error {
  332. utils.Debugf("Releasing %d", port)
  333. alloc.Lock()
  334. delete(alloc.inUse, port)
  335. alloc.Unlock()
  336. return nil
  337. }
  338. func (alloc *PortAllocator) Acquire(port int) (int, error) {
  339. utils.Debugf("Acquiring %d", port)
  340. if port == 0 {
  341. // Allocate a port from the fountain
  342. for port := range alloc.fountain {
  343. if _, err := alloc.Acquire(port); err == nil {
  344. return port, nil
  345. }
  346. }
  347. return -1, fmt.Errorf("Port generator ended unexpectedly")
  348. }
  349. alloc.Lock()
  350. defer alloc.Unlock()
  351. if _, inUse := alloc.inUse[port]; inUse {
  352. return -1, fmt.Errorf("Port already in use: %d", port)
  353. }
  354. alloc.inUse[port] = struct{}{}
  355. return port, nil
  356. }
  357. func (alloc *PortAllocator) Close() error {
  358. alloc.quit <- true
  359. close(alloc.quit)
  360. close(alloc.fountain)
  361. return nil
  362. }
  363. func newPortAllocator() (*PortAllocator, error) {
  364. allocator := &PortAllocator{
  365. inUse: make(map[int]struct{}),
  366. fountain: make(chan int),
  367. quit: make(chan bool),
  368. }
  369. go allocator.runFountain()
  370. return allocator, nil
  371. }
  372. // IP allocator: Automatically allocate and release networking ports
  373. type IPAllocator struct {
  374. network *net.IPNet
  375. queueAlloc chan allocatedIP
  376. queueReleased chan net.IP
  377. inUse map[int32]struct{}
  378. quit chan bool
  379. }
  380. type allocatedIP struct {
  381. ip net.IP
  382. err error
  383. }
  384. func (alloc *IPAllocator) run() {
  385. firstIP, _ := networkRange(alloc.network)
  386. ipNum := ipToInt(firstIP)
  387. ownIP := ipToInt(alloc.network.IP)
  388. size := networkSize(alloc.network.Mask)
  389. pos := int32(1)
  390. max := size - 2 // -1 for the broadcast address, -1 for the gateway address
  391. for {
  392. var (
  393. newNum int32
  394. inUse bool
  395. )
  396. // Find first unused IP, give up after one whole round
  397. for attempt := int32(0); attempt < max; attempt++ {
  398. newNum = ipNum + pos
  399. pos = pos%max + 1
  400. // The network's IP is never okay to use
  401. if newNum == ownIP {
  402. continue
  403. }
  404. if _, inUse = alloc.inUse[newNum]; !inUse {
  405. // We found an unused IP
  406. break
  407. }
  408. }
  409. ip := allocatedIP{ip: intToIP(newNum)}
  410. if inUse {
  411. ip.err = errors.New("No unallocated IP available")
  412. }
  413. select {
  414. case quit := <-alloc.quit:
  415. if quit {
  416. return
  417. }
  418. case alloc.queueAlloc <- ip:
  419. alloc.inUse[newNum] = struct{}{}
  420. case released := <-alloc.queueReleased:
  421. r := ipToInt(released)
  422. delete(alloc.inUse, r)
  423. if inUse {
  424. // If we couldn't allocate a new IP, the released one
  425. // will be the only free one now, so instantly use it
  426. // next time
  427. pos = r - ipNum
  428. } else {
  429. // Use same IP as last time
  430. if pos == 1 {
  431. pos = max
  432. } else {
  433. pos--
  434. }
  435. }
  436. }
  437. }
  438. }
  439. func (alloc *IPAllocator) Acquire() (net.IP, error) {
  440. ip := <-alloc.queueAlloc
  441. return ip.ip, ip.err
  442. }
  443. func (alloc *IPAllocator) Release(ip net.IP) {
  444. alloc.queueReleased <- ip
  445. }
  446. func (alloc *IPAllocator) Close() error {
  447. alloc.quit <- true
  448. close(alloc.quit)
  449. close(alloc.queueAlloc)
  450. close(alloc.queueReleased)
  451. return nil
  452. }
  453. func newIPAllocator(network *net.IPNet) *IPAllocator {
  454. alloc := &IPAllocator{
  455. network: network,
  456. queueAlloc: make(chan allocatedIP),
  457. queueReleased: make(chan net.IP),
  458. inUse: make(map[int32]struct{}),
  459. quit: make(chan bool),
  460. }
  461. go alloc.run()
  462. return alloc
  463. }
  464. // Network interface represents the networking stack of a container
  465. type NetworkInterface struct {
  466. IPNet net.IPNet
  467. Gateway net.IP
  468. manager *NetworkManager
  469. extPorts []*Nat
  470. disabled bool
  471. }
  472. // Allocate an external TCP port and map it to the interface
  473. func (iface *NetworkInterface) AllocatePort(spec string) (*Nat, error) {
  474. if iface.disabled {
  475. return nil, fmt.Errorf("Trying to allocate port for interface %v, which is disabled", iface) // FIXME
  476. }
  477. nat, err := parseNat(spec)
  478. if err != nil {
  479. return nil, err
  480. }
  481. if nat.Proto == "tcp" {
  482. extPort, err := iface.manager.tcpPortAllocator.Acquire(nat.Frontend)
  483. if err != nil {
  484. return nil, err
  485. }
  486. backend := &net.TCPAddr{IP: iface.IPNet.IP, Port: nat.Backend}
  487. if err := iface.manager.portMapper.Map(extPort, backend); err != nil {
  488. iface.manager.tcpPortAllocator.Release(extPort)
  489. return nil, err
  490. }
  491. nat.Frontend = extPort
  492. } else {
  493. extPort, err := iface.manager.udpPortAllocator.Acquire(nat.Frontend)
  494. if err != nil {
  495. return nil, err
  496. }
  497. backend := &net.UDPAddr{IP: iface.IPNet.IP, Port: nat.Backend}
  498. if err := iface.manager.portMapper.Map(extPort, backend); err != nil {
  499. iface.manager.udpPortAllocator.Release(extPort)
  500. return nil, err
  501. }
  502. nat.Frontend = extPort
  503. }
  504. iface.extPorts = append(iface.extPorts, nat)
  505. return nat, nil
  506. }
  507. type Nat struct {
  508. Proto string
  509. Frontend int
  510. Backend int
  511. }
  512. func parseNat(spec string) (*Nat, error) {
  513. var nat Nat
  514. if strings.Contains(spec, "/") {
  515. specParts := strings.Split(spec, "/")
  516. if len(specParts) != 2 {
  517. return nil, fmt.Errorf("Invalid port format.")
  518. }
  519. proto := specParts[1]
  520. spec = specParts[0]
  521. if proto != "tcp" && proto != "udp" {
  522. return nil, fmt.Errorf("Invalid port format: unknown protocol %v.", proto)
  523. }
  524. nat.Proto = proto
  525. } else {
  526. nat.Proto = "tcp"
  527. }
  528. if strings.Contains(spec, ":") {
  529. specParts := strings.Split(spec, ":")
  530. if len(specParts) != 2 {
  531. return nil, fmt.Errorf("Invalid port format.")
  532. }
  533. // If spec starts with ':', external and internal ports must be the same.
  534. // This might fail if the requested external port is not available.
  535. var sameFrontend bool
  536. if len(specParts[0]) == 0 {
  537. sameFrontend = true
  538. } else {
  539. front, err := strconv.ParseUint(specParts[0], 10, 16)
  540. if err != nil {
  541. return nil, err
  542. }
  543. nat.Frontend = int(front)
  544. }
  545. back, err := strconv.ParseUint(specParts[1], 10, 16)
  546. if err != nil {
  547. return nil, err
  548. }
  549. nat.Backend = int(back)
  550. if sameFrontend {
  551. nat.Frontend = nat.Backend
  552. }
  553. } else {
  554. port, err := strconv.ParseUint(spec, 10, 16)
  555. if err != nil {
  556. return nil, err
  557. }
  558. nat.Backend = int(port)
  559. }
  560. return &nat, nil
  561. }
  562. // Release: Network cleanup - release all resources
  563. func (iface *NetworkInterface) Release() {
  564. if iface.disabled {
  565. return
  566. }
  567. for _, nat := range iface.extPorts {
  568. utils.Debugf("Unmaping %v/%v", nat.Proto, nat.Frontend)
  569. if err := iface.manager.portMapper.Unmap(nat.Frontend, nat.Proto); err != nil {
  570. log.Printf("Unable to unmap port %v/%v: %v", nat.Proto, nat.Frontend, err)
  571. }
  572. if nat.Proto == "tcp" {
  573. if err := iface.manager.tcpPortAllocator.Release(nat.Frontend); err != nil {
  574. log.Printf("Unable to release port tcp/%v: %v", nat.Frontend, err)
  575. }
  576. } else if err := iface.manager.udpPortAllocator.Release(nat.Frontend); err != nil {
  577. log.Printf("Unable to release port udp/%v: %v", nat.Frontend, err)
  578. }
  579. }
  580. iface.manager.ipAllocator.Release(iface.IPNet.IP)
  581. }
  582. // Network Manager manages a set of network interfaces
  583. // Only *one* manager per host machine should be used
  584. type NetworkManager struct {
  585. bridgeIface string
  586. bridgeNetwork *net.IPNet
  587. ipAllocator *IPAllocator
  588. tcpPortAllocator *PortAllocator
  589. udpPortAllocator *PortAllocator
  590. portMapper *PortMapper
  591. disabled bool
  592. }
  593. // Allocate a network interface
  594. func (manager *NetworkManager) Allocate() (*NetworkInterface, error) {
  595. if manager.disabled {
  596. return &NetworkInterface{disabled: true}, nil
  597. }
  598. var ip net.IP
  599. var err error
  600. ip, err = manager.ipAllocator.Acquire()
  601. if err != nil {
  602. return nil, err
  603. }
  604. // avoid duplicate IP
  605. ipNum := ipToInt(ip)
  606. firstIP := manager.ipAllocator.network.IP.To4().Mask(manager.ipAllocator.network.Mask)
  607. firstIPNum := ipToInt(firstIP) + 1
  608. if firstIPNum == ipNum {
  609. ip, err = manager.ipAllocator.Acquire()
  610. if err != nil {
  611. return nil, err
  612. }
  613. }
  614. iface := &NetworkInterface{
  615. IPNet: net.IPNet{IP: ip, Mask: manager.bridgeNetwork.Mask},
  616. Gateway: manager.bridgeNetwork.IP,
  617. manager: manager,
  618. }
  619. return iface, nil
  620. }
  621. func (manager *NetworkManager) Close() error {
  622. err1 := manager.tcpPortAllocator.Close()
  623. err2 := manager.udpPortAllocator.Close()
  624. err3 := manager.ipAllocator.Close()
  625. if err1 != nil {
  626. return err1
  627. }
  628. if err2 != nil {
  629. return err2
  630. }
  631. return err3
  632. }
  633. func newNetworkManager(bridgeIface string) (*NetworkManager, error) {
  634. if bridgeIface == DisableNetworkBridge {
  635. manager := &NetworkManager{
  636. disabled: true,
  637. }
  638. return manager, nil
  639. }
  640. addr, err := getIfaceAddr(bridgeIface)
  641. if err != nil {
  642. // If the iface is not found, try to create it
  643. if err := CreateBridgeIface(bridgeIface); err != nil {
  644. return nil, err
  645. }
  646. addr, err = getIfaceAddr(bridgeIface)
  647. if err != nil {
  648. return nil, err
  649. }
  650. }
  651. network := addr.(*net.IPNet)
  652. ipAllocator := newIPAllocator(network)
  653. tcpPortAllocator, err := newPortAllocator()
  654. if err != nil {
  655. return nil, err
  656. }
  657. udpPortAllocator, err := newPortAllocator()
  658. if err != nil {
  659. return nil, err
  660. }
  661. portMapper, err := newPortMapper()
  662. if err != nil {
  663. return nil, err
  664. }
  665. manager := &NetworkManager{
  666. bridgeIface: bridgeIface,
  667. bridgeNetwork: network,
  668. ipAllocator: ipAllocator,
  669. tcpPortAllocator: tcpPortAllocator,
  670. udpPortAllocator: udpPortAllocator,
  671. portMapper: portMapper,
  672. }
  673. return manager, nil
  674. }