github.com/moby/docker@v26.1.3+incompatible/libnetwork/drivers/overlay/overlay.go (about)

     1  //go:build linux
     2  
     3  package overlay
     4  
     5  //go:generate protoc -I=. -I=../../../vendor/ --gogofaster_out=import_path=github.com/docker/docker/libnetwork/drivers/overlay:. overlay.proto
     6  
     7  import (
     8  	"context"
     9  	"fmt"
    10  	"net"
    11  	"sync"
    12  
    13  	"github.com/containerd/log"
    14  	"github.com/docker/docker/libnetwork/discoverapi"
    15  	"github.com/docker/docker/libnetwork/driverapi"
    16  	"github.com/docker/docker/libnetwork/scope"
    17  )
    18  
    19  const (
    20  	NetworkType  = "overlay"
    21  	vethPrefix   = "veth"
    22  	vethLen      = len(vethPrefix) + 7
    23  	vxlanEncap   = 50
    24  	secureOption = "encrypted"
    25  )
    26  
    27  // overlay driver must implement the discover-API.
    28  var _ discoverapi.Discover = (*driver)(nil)
    29  
    30  type driver struct {
    31  	bindAddress, advertiseAddress net.IP
    32  
    33  	config        map[string]interface{}
    34  	peerDb        peerNetworkMap
    35  	secMap        *encrMap
    36  	networks      networkTable
    37  	initOS        sync.Once
    38  	localJoinOnce sync.Once
    39  	keys          []*key
    40  	peerOpMu      sync.Mutex
    41  	sync.Mutex
    42  }
    43  
    44  // Register registers a new instance of the overlay driver.
    45  func Register(r driverapi.Registerer, config map[string]interface{}) error {
    46  	d := &driver{
    47  		networks: networkTable{},
    48  		peerDb: peerNetworkMap{
    49  			mp: map[string]*peerMap{},
    50  		},
    51  		secMap: &encrMap{nodes: map[string][]*spi{}},
    52  		config: config,
    53  	}
    54  	return r.RegisterDriver(NetworkType, d, driverapi.Capability{
    55  		DataScope:         scope.Global,
    56  		ConnectivityScope: scope.Global,
    57  	})
    58  }
    59  
    60  func (d *driver) configure() error {
    61  	// Apply OS specific kernel configs if needed
    62  	d.initOS.Do(applyOStweaks)
    63  
    64  	return nil
    65  }
    66  
    67  func (d *driver) Type() string {
    68  	return NetworkType
    69  }
    70  
    71  func (d *driver) IsBuiltIn() bool {
    72  	return true
    73  }
    74  
    75  // isIPv6Transport reports whether the outer Layer-3 transport for VXLAN datagrams is IPv6.
    76  func (d *driver) isIPv6Transport() (bool, error) {
    77  	// Infer whether remote peers' virtual tunnel endpoints will be IPv4 or IPv6
    78  	// from the address family of our own advertise address. This is a
    79  	// reasonable inference to make as Linux VXLAN links do not support
    80  	// mixed-address-family remote peers.
    81  	if d.advertiseAddress == nil {
    82  		return false, fmt.Errorf("overlay: cannot determine address family of transport: the local data-plane address is not currently known")
    83  	}
    84  	return d.advertiseAddress.To4() == nil, nil
    85  }
    86  
    87  func (d *driver) nodeJoin(data discoverapi.NodeDiscoveryData) error {
    88  	if data.Self {
    89  		advAddr, bindAddr := net.ParseIP(data.Address), net.ParseIP(data.BindAddress)
    90  		if advAddr == nil {
    91  			return fmt.Errorf("invalid discovery data")
    92  		}
    93  		d.Lock()
    94  		d.advertiseAddress = advAddr
    95  		d.bindAddress = bindAddr
    96  		d.Unlock()
    97  
    98  		// If containers are already running on this network update the
    99  		// advertise address in the peerDB
   100  		d.localJoinOnce.Do(func() {
   101  			d.peerDBUpdateSelf()
   102  		})
   103  	}
   104  	return nil
   105  }
   106  
   107  // DiscoverNew is a notification for a new discovery event, such as a new node joining a cluster
   108  func (d *driver) DiscoverNew(dType discoverapi.DiscoveryType, data interface{}) error {
   109  	switch dType {
   110  	case discoverapi.NodeDiscovery:
   111  		nodeData, ok := data.(discoverapi.NodeDiscoveryData)
   112  		if !ok {
   113  			return fmt.Errorf("invalid discovery data type: %T", data)
   114  		}
   115  		return d.nodeJoin(nodeData)
   116  	case discoverapi.EncryptionKeysConfig:
   117  		encrData, ok := data.(discoverapi.DriverEncryptionConfig)
   118  		if !ok {
   119  			return fmt.Errorf("invalid encryption key notification data")
   120  		}
   121  		keys := make([]*key, 0, len(encrData.Keys))
   122  		for i := 0; i < len(encrData.Keys); i++ {
   123  			k := &key{
   124  				value: encrData.Keys[i],
   125  				tag:   uint32(encrData.Tags[i]),
   126  			}
   127  			keys = append(keys, k)
   128  		}
   129  		if err := d.setKeys(keys); err != nil {
   130  			log.G(context.TODO()).Warn(err)
   131  		}
   132  	case discoverapi.EncryptionKeysUpdate:
   133  		var newKey, delKey, priKey *key
   134  		encrData, ok := data.(discoverapi.DriverEncryptionUpdate)
   135  		if !ok {
   136  			return fmt.Errorf("invalid encryption key notification data")
   137  		}
   138  		if encrData.Key != nil {
   139  			newKey = &key{
   140  				value: encrData.Key,
   141  				tag:   uint32(encrData.Tag),
   142  			}
   143  		}
   144  		if encrData.Primary != nil {
   145  			priKey = &key{
   146  				value: encrData.Primary,
   147  				tag:   uint32(encrData.PrimaryTag),
   148  			}
   149  		}
   150  		if encrData.Prune != nil {
   151  			delKey = &key{
   152  				value: encrData.Prune,
   153  				tag:   uint32(encrData.PruneTag),
   154  			}
   155  		}
   156  		if err := d.updateKeys(newKey, priKey, delKey); err != nil {
   157  			return err
   158  		}
   159  	default:
   160  	}
   161  	return nil
   162  }
   163  
   164  // DiscoverDelete is a notification for a discovery delete event, such as a node leaving a cluster
   165  func (d *driver) DiscoverDelete(dType discoverapi.DiscoveryType, data interface{}) error {
   166  	return nil
   167  }