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