github.com/Prakhar-Agarwal-byte/moby@v0.0.0-20231027092010-a14e3e8ab87e/libnetwork/drivers/bridge/link.go (about) 1 //go:build linux 2 3 package bridge 4 5 import ( 6 "context" 7 "fmt" 8 "net" 9 10 "github.com/containerd/log" 11 "github.com/Prakhar-Agarwal-byte/moby/libnetwork/iptables" 12 "github.com/Prakhar-Agarwal-byte/moby/libnetwork/types" 13 ) 14 15 type link struct { 16 parentIP net.IP 17 childIP net.IP 18 ports []types.TransportPort 19 bridge string 20 } 21 22 func (l *link) String() string { 23 return fmt.Sprintf("%s <-> %s [%v] on %s", l.parentIP, l.childIP, l.ports, l.bridge) 24 } 25 26 func newLink(parentIP, childIP net.IP, ports []types.TransportPort, bridge string) (*link, error) { 27 if parentIP == nil { 28 return nil, fmt.Errorf("cannot link to a container with an empty parent IP address") 29 } 30 if childIP == nil { 31 return nil, fmt.Errorf("cannot link to a container with an empty child IP address") 32 } 33 34 return &link{ 35 childIP: childIP, 36 parentIP: parentIP, 37 ports: ports, 38 bridge: bridge, 39 }, nil 40 } 41 42 func (l *link) Enable() error { 43 linkFunction := func() error { 44 return linkContainers(iptables.Append, l.parentIP, l.childIP, l.ports, l.bridge, false) 45 } 46 if err := linkFunction(); err != nil { 47 return err 48 } 49 50 iptables.OnReloaded(func() { _ = linkFunction() }) 51 return nil 52 } 53 54 func (l *link) Disable() { 55 if err := linkContainers(iptables.Delete, l.parentIP, l.childIP, l.ports, l.bridge, true); err != nil { 56 // @TODO: Return error once we have the iptables package return typed errors. 57 log.G(context.TODO()).WithError(err).Errorf("Error removing IPTables rules for link: %s", l.String()) 58 } 59 } 60 61 func linkContainers(action iptables.Action, parentIP, childIP net.IP, ports []types.TransportPort, bridge string, ignoreErrors bool) error { 62 if parentIP == nil { 63 return fmt.Errorf("cannot link to a container with an empty parent IP address") 64 } 65 if childIP == nil { 66 return fmt.Errorf("cannot link to a container with an empty child IP address") 67 } 68 69 chain := iptables.ChainInfo{Name: DockerChain} 70 for _, port := range ports { 71 err := chain.Link(action, parentIP, childIP, int(port.Port), port.Proto.String(), bridge) 72 if !ignoreErrors && err != nil { 73 return err 74 } 75 } 76 return nil 77 }