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