link.go 1.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980
  1. package bridge
  2. import (
  3. "fmt"
  4. "net"
  5. log "github.com/Sirupsen/logrus"
  6. "github.com/docker/libnetwork/netutils"
  7. "github.com/docker/libnetwork/pkg/iptables"
  8. )
  9. type link struct {
  10. parentIP string
  11. childIP string
  12. ports []netutils.TransportPort
  13. bridge string
  14. }
  15. func (l *link) String() string {
  16. return fmt.Sprintf("%s <-> %s [%v] on %s", l.parentIP, l.childIP, l.ports, l.bridge)
  17. }
  18. func newLink(parentIP, childIP string, ports []netutils.TransportPort, bridge string) *link {
  19. return &link{
  20. childIP: childIP,
  21. parentIP: parentIP,
  22. ports: ports,
  23. bridge: bridge,
  24. }
  25. }
  26. func (l *link) Enable() error {
  27. // -A == iptables append flag
  28. return linkContainers("-A", l.parentIP, l.childIP, l.ports, l.bridge, false)
  29. }
  30. func (l *link) Disable() {
  31. // -D == iptables delete flag
  32. err := linkContainers("-D", l.parentIP, l.childIP, l.ports, l.bridge, true)
  33. if err != nil {
  34. log.Errorf("Error removing IPTables rules for a link %s due to %s", l.String(), err.Error())
  35. }
  36. // Return proper error once we move to use a proper iptables package
  37. // that returns typed errors
  38. }
  39. func linkContainers(action, parentIP, childIP string, ports []netutils.TransportPort, bridge string,
  40. ignoreErrors bool) error {
  41. var nfAction iptables.Action
  42. switch action {
  43. case "-A":
  44. nfAction = iptables.Append
  45. case "-I":
  46. nfAction = iptables.Insert
  47. case "-D":
  48. nfAction = iptables.Delete
  49. default:
  50. return invalidIPTablesCfgError(action)
  51. }
  52. ip1 := net.ParseIP(parentIP)
  53. if ip1 == nil {
  54. return InvalidLinkIPAddrError(parentIP)
  55. }
  56. ip2 := net.ParseIP(childIP)
  57. if ip2 == nil {
  58. return InvalidLinkIPAddrError(childIP)
  59. }
  60. chain := iptables.Chain{Name: DockerChain, Bridge: bridge}
  61. for _, port := range ports {
  62. err := chain.Link(nfAction, ip1, ip2, int(port.Port), port.Proto.String())
  63. if !ignoreErrors && err != nil {
  64. return err
  65. }
  66. }
  67. return nil
  68. }