github.com/rawahars/moby@v24.0.4+incompatible/libnetwork/drivers/overlay/ovmanager/ovmanager.go (about)

     1  package ovmanager
     2  
     3  import (
     4  	"fmt"
     5  	"net"
     6  	"strconv"
     7  	"strings"
     8  	"sync"
     9  
    10  	"github.com/docker/docker/libnetwork/datastore"
    11  	"github.com/docker/docker/libnetwork/discoverapi"
    12  	"github.com/docker/docker/libnetwork/driverapi"
    13  	"github.com/docker/docker/libnetwork/idm"
    14  	"github.com/docker/docker/libnetwork/netlabel"
    15  	"github.com/docker/docker/libnetwork/types"
    16  	"github.com/sirupsen/logrus"
    17  )
    18  
    19  const (
    20  	networkType  = "overlay"
    21  	vxlanIDStart = 4096
    22  	vxlanIDEnd   = (1 << 24) - 1
    23  )
    24  
    25  type networkTable map[string]*network
    26  
    27  type driver struct {
    28  	config   map[string]interface{}
    29  	networks networkTable
    30  	vxlanIdm *idm.Idm
    31  	sync.Mutex
    32  }
    33  
    34  type subnet struct {
    35  	subnetIP *net.IPNet
    36  	gwIP     *net.IPNet
    37  	vni      uint32
    38  }
    39  
    40  type network struct {
    41  	id      string
    42  	driver  *driver
    43  	subnets []*subnet
    44  	sync.Mutex
    45  }
    46  
    47  // Init registers a new instance of the overlay driver.
    48  //
    49  // Deprecated: use [Register].
    50  func Init(dc driverapi.DriverCallback, config map[string]interface{}) error {
    51  	return Register(dc, config)
    52  }
    53  
    54  // Register registers a new instance of the overlay driver.
    55  func Register(r driverapi.DriverCallback, config map[string]interface{}) error {
    56  	var err error
    57  	c := driverapi.Capability{
    58  		DataScope:         datastore.GlobalScope,
    59  		ConnectivityScope: datastore.GlobalScope,
    60  	}
    61  
    62  	d := &driver{
    63  		networks: networkTable{},
    64  		config:   config,
    65  	}
    66  
    67  	d.vxlanIdm, err = idm.New(nil, "vxlan-id", 0, vxlanIDEnd)
    68  	if err != nil {
    69  		return fmt.Errorf("failed to initialize vxlan id manager: %v", err)
    70  	}
    71  
    72  	return r.RegisterDriver(networkType, d, c)
    73  }
    74  
    75  func (d *driver) NetworkAllocate(id string, option map[string]string, ipV4Data, ipV6Data []driverapi.IPAMData) (map[string]string, error) {
    76  	if id == "" {
    77  		return nil, fmt.Errorf("invalid network id for overlay network")
    78  	}
    79  
    80  	if ipV4Data == nil {
    81  		return nil, fmt.Errorf("empty ipv4 data passed during overlay network creation")
    82  	}
    83  
    84  	n := &network{
    85  		id:      id,
    86  		driver:  d,
    87  		subnets: []*subnet{},
    88  	}
    89  
    90  	opts := make(map[string]string)
    91  	vxlanIDList := make([]uint32, 0, len(ipV4Data))
    92  	for key, val := range option {
    93  		if key == netlabel.OverlayVxlanIDList {
    94  			logrus.Debugf("overlay network option: %s", val)
    95  			valStrList := strings.Split(val, ",")
    96  			for _, idStr := range valStrList {
    97  				vni, err := strconv.Atoi(idStr)
    98  				if err != nil {
    99  					return nil, fmt.Errorf("invalid vxlan id value %q passed", idStr)
   100  				}
   101  
   102  				vxlanIDList = append(vxlanIDList, uint32(vni))
   103  			}
   104  		} else {
   105  			opts[key] = val
   106  		}
   107  	}
   108  
   109  	for i, ipd := range ipV4Data {
   110  		s := &subnet{
   111  			subnetIP: ipd.Pool,
   112  			gwIP:     ipd.Gateway,
   113  		}
   114  
   115  		if len(vxlanIDList) > i {
   116  			s.vni = vxlanIDList[i]
   117  		}
   118  
   119  		if err := n.obtainVxlanID(s); err != nil {
   120  			n.releaseVxlanID()
   121  			return nil, fmt.Errorf("could not obtain vxlan id for pool %s: %v", s.subnetIP, err)
   122  		}
   123  
   124  		n.subnets = append(n.subnets, s)
   125  	}
   126  
   127  	val := strconv.FormatUint(uint64(n.subnets[0].vni), 10)
   128  	for _, s := range n.subnets[1:] {
   129  		val = val + "," + strconv.FormatUint(uint64(s.vni), 10)
   130  	}
   131  	opts[netlabel.OverlayVxlanIDList] = val
   132  
   133  	d.Lock()
   134  	defer d.Unlock()
   135  	if _, ok := d.networks[id]; ok {
   136  		n.releaseVxlanID()
   137  		return nil, fmt.Errorf("network %s already exists", id)
   138  	}
   139  	d.networks[id] = n
   140  
   141  	return opts, nil
   142  }
   143  
   144  func (d *driver) NetworkFree(id string) error {
   145  	if id == "" {
   146  		return fmt.Errorf("invalid network id passed while freeing overlay network")
   147  	}
   148  
   149  	d.Lock()
   150  	defer d.Unlock()
   151  	n, ok := d.networks[id]
   152  
   153  	if !ok {
   154  		return fmt.Errorf("overlay network with id %s not found", id)
   155  	}
   156  
   157  	// Release all vxlan IDs in one shot.
   158  	n.releaseVxlanID()
   159  
   160  	delete(d.networks, id)
   161  
   162  	return nil
   163  }
   164  
   165  func (n *network) obtainVxlanID(s *subnet) error {
   166  	var (
   167  		err error
   168  		vni uint64
   169  	)
   170  
   171  	n.Lock()
   172  	vni = uint64(s.vni)
   173  	n.Unlock()
   174  
   175  	if vni == 0 {
   176  		vni, err = n.driver.vxlanIdm.GetIDInRange(vxlanIDStart, vxlanIDEnd, true)
   177  		if err != nil {
   178  			return err
   179  		}
   180  
   181  		n.Lock()
   182  		s.vni = uint32(vni)
   183  		n.Unlock()
   184  		return nil
   185  	}
   186  
   187  	return n.driver.vxlanIdm.GetSpecificID(vni)
   188  }
   189  
   190  func (n *network) releaseVxlanID() {
   191  	n.Lock()
   192  	vnis := make([]uint32, 0, len(n.subnets))
   193  	for _, s := range n.subnets {
   194  		vnis = append(vnis, s.vni)
   195  		s.vni = 0
   196  	}
   197  	n.Unlock()
   198  
   199  	for _, vni := range vnis {
   200  		n.driver.vxlanIdm.Release(uint64(vni))
   201  	}
   202  }
   203  
   204  func (d *driver) CreateNetwork(id string, option map[string]interface{}, nInfo driverapi.NetworkInfo, ipV4Data, ipV6Data []driverapi.IPAMData) error {
   205  	return types.NotImplementedErrorf("not implemented")
   206  }
   207  
   208  func (d *driver) EventNotify(etype driverapi.EventType, nid, tableName, key string, value []byte) {
   209  }
   210  
   211  func (d *driver) DecodeTableEntry(tablename string, key string, value []byte) (string, map[string]string) {
   212  	return "", nil
   213  }
   214  
   215  func (d *driver) DeleteNetwork(nid string) error {
   216  	return types.NotImplementedErrorf("not implemented")
   217  }
   218  
   219  func (d *driver) CreateEndpoint(nid, eid string, ifInfo driverapi.InterfaceInfo, epOptions map[string]interface{}) error {
   220  	return types.NotImplementedErrorf("not implemented")
   221  }
   222  
   223  func (d *driver) DeleteEndpoint(nid, eid string) error {
   224  	return types.NotImplementedErrorf("not implemented")
   225  }
   226  
   227  func (d *driver) EndpointOperInfo(nid, eid string) (map[string]interface{}, error) {
   228  	return nil, types.NotImplementedErrorf("not implemented")
   229  }
   230  
   231  // Join method is invoked when a Sandbox is attached to an endpoint.
   232  func (d *driver) Join(nid, eid string, sboxKey string, jinfo driverapi.JoinInfo, options map[string]interface{}) error {
   233  	return types.NotImplementedErrorf("not implemented")
   234  }
   235  
   236  // Leave method is invoked when a Sandbox detaches from an endpoint.
   237  func (d *driver) Leave(nid, eid string) error {
   238  	return types.NotImplementedErrorf("not implemented")
   239  }
   240  
   241  func (d *driver) Type() string {
   242  	return networkType
   243  }
   244  
   245  func (d *driver) IsBuiltIn() bool {
   246  	return true
   247  }
   248  
   249  // DiscoverNew is a notification for a new discovery event, such as a new node joining a cluster
   250  func (d *driver) DiscoverNew(dType discoverapi.DiscoveryType, data interface{}) error {
   251  	return types.NotImplementedErrorf("not implemented")
   252  }
   253  
   254  // DiscoverDelete is a notification for a discovery delete event, such as a node leaving a cluster
   255  func (d *driver) DiscoverDelete(dType discoverapi.DiscoveryType, data interface{}) error {
   256  	return types.NotImplementedErrorf("not implemented")
   257  }
   258  
   259  func (d *driver) ProgramExternalConnectivity(nid, eid string, options map[string]interface{}) error {
   260  	return types.NotImplementedErrorf("not implemented")
   261  }
   262  
   263  func (d *driver) RevokeExternalConnectivity(nid, eid string) error {
   264  	return types.NotImplementedErrorf("not implemented")
   265  }