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  }