github.com/Prakhar-Agarwal-byte/moby@v0.0.0-20231027092010-a14e3e8ab87e/libnetwork/drivers/overlay/ovmanager/ovmanager.go (about)

     1  package ovmanager
     2  
     3  import (
     4  	"context"
     5  	"fmt"
     6  	"net"
     7  	"strconv"
     8  	"sync"
     9  
    10  	"github.com/containerd/log"
    11  	"github.com/Prakhar-Agarwal-byte/moby/libnetwork/bitmap"
    12  	"github.com/Prakhar-Agarwal-byte/moby/libnetwork/driverapi"
    13  	"github.com/Prakhar-Agarwal-byte/moby/libnetwork/drivers/overlay/overlayutils"
    14  	"github.com/Prakhar-Agarwal-byte/moby/libnetwork/netlabel"
    15  	"github.com/Prakhar-Agarwal-byte/moby/libnetwork/scope"
    16  	"github.com/Prakhar-Agarwal-byte/moby/libnetwork/types"
    17  )
    18  
    19  const (
    20  	networkType = "overlay"
    21  	// The lowest VNI value to auto-assign. Windows does not support VXLAN IDs
    22  	// which overlap the range of 802.1Q VLAN IDs [0, 4095].
    23  	vxlanIDStart = 4096
    24  	// The largest VNI value permitted by RFC 7348.
    25  	vxlanIDEnd = (1 << 24) - 1
    26  )
    27  
    28  type networkTable map[string]*network
    29  
    30  type driver struct {
    31  	mu       sync.Mutex
    32  	networks networkTable
    33  	vxlanIdm *bitmap.Bitmap
    34  }
    35  
    36  type subnet struct {
    37  	subnetIP *net.IPNet
    38  	gwIP     *net.IPNet
    39  	vni      uint32
    40  }
    41  
    42  type network struct {
    43  	id      string
    44  	driver  *driver
    45  	subnets []*subnet
    46  }
    47  
    48  // Register registers a new instance of the overlay driver.
    49  func Register(r driverapi.Registerer) error {
    50  	return r.RegisterDriver(networkType, newDriver(), driverapi.Capability{
    51  		DataScope:         scope.Global,
    52  		ConnectivityScope: scope.Global,
    53  	})
    54  }
    55  
    56  func newDriver() *driver {
    57  	return &driver{
    58  		networks: networkTable{},
    59  		vxlanIdm: bitmap.New(vxlanIDEnd + 1), // The full range of valid vxlan IDs: [0, 2^24).
    60  	}
    61  }
    62  
    63  func (d *driver) NetworkAllocate(id string, option map[string]string, ipV4Data, ipV6Data []driverapi.IPAMData) (map[string]string, error) {
    64  	if id == "" {
    65  		return nil, fmt.Errorf("invalid network id for overlay network")
    66  	}
    67  
    68  	if ipV4Data == nil {
    69  		return nil, fmt.Errorf("empty ipv4 data passed during overlay network creation")
    70  	}
    71  
    72  	n := &network{
    73  		id:      id,
    74  		driver:  d,
    75  		subnets: []*subnet{},
    76  	}
    77  
    78  	opts := make(map[string]string)
    79  	vxlanIDList := make([]uint32, 0, len(ipV4Data))
    80  	for key, val := range option {
    81  		if key == netlabel.OverlayVxlanIDList {
    82  			log.G(context.TODO()).Debugf("overlay network option: %s", val)
    83  			var err error
    84  			vxlanIDList, err = overlayutils.AppendVNIList(vxlanIDList, val)
    85  			if err != nil {
    86  				return nil, err
    87  			}
    88  		} else {
    89  			opts[key] = val
    90  		}
    91  	}
    92  
    93  	d.mu.Lock()
    94  	defer d.mu.Unlock()
    95  	for i, ipd := range ipV4Data {
    96  		s := &subnet{
    97  			subnetIP: ipd.Pool,
    98  			gwIP:     ipd.Gateway,
    99  		}
   100  
   101  		if len(vxlanIDList) > i { // The VNI for this subnet was specified in the network options.
   102  			s.vni = vxlanIDList[i]
   103  			err := d.vxlanIdm.Set(uint64(s.vni)) // Mark VNI as in-use.
   104  			if err != nil {
   105  				// The VNI is already in use by another subnet/network.
   106  				n.releaseVxlanID()
   107  				return nil, fmt.Errorf("could not assign vxlan id %v to pool %s: %v", s.vni, s.subnetIP, err)
   108  			}
   109  		} else {
   110  			// Allocate an available VNI for the subnet, outside the range of 802.1Q VLAN IDs.
   111  			vni, err := d.vxlanIdm.SetAnyInRange(vxlanIDStart, vxlanIDEnd, true)
   112  			if err != nil {
   113  				n.releaseVxlanID()
   114  				return nil, fmt.Errorf("could not obtain vxlan id for pool %s: %v", s.subnetIP, err)
   115  			}
   116  			s.vni = uint32(vni)
   117  		}
   118  
   119  		n.subnets = append(n.subnets, s)
   120  	}
   121  
   122  	val := strconv.FormatUint(uint64(n.subnets[0].vni), 10)
   123  	for _, s := range n.subnets[1:] {
   124  		val = val + "," + strconv.FormatUint(uint64(s.vni), 10)
   125  	}
   126  	opts[netlabel.OverlayVxlanIDList] = val
   127  
   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.mu.Lock()
   143  	defer d.mu.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) releaseVxlanID() {
   159  	for _, s := range n.subnets {
   160  		n.driver.vxlanIdm.Unset(uint64(s.vni))
   161  		s.vni = 0
   162  	}
   163  }
   164  
   165  func (d *driver) CreateNetwork(id string, option map[string]interface{}, nInfo driverapi.NetworkInfo, ipV4Data, ipV6Data []driverapi.IPAMData) error {
   166  	return types.NotImplementedErrorf("not implemented")
   167  }
   168  
   169  func (d *driver) EventNotify(etype driverapi.EventType, nid, tableName, key string, value []byte) {
   170  }
   171  
   172  func (d *driver) DecodeTableEntry(tablename string, key string, value []byte) (string, map[string]string) {
   173  	return "", nil
   174  }
   175  
   176  func (d *driver) DeleteNetwork(nid string) error {
   177  	return types.NotImplementedErrorf("not implemented")
   178  }
   179  
   180  func (d *driver) CreateEndpoint(nid, eid string, ifInfo driverapi.InterfaceInfo, epOptions map[string]interface{}) error {
   181  	return types.NotImplementedErrorf("not implemented")
   182  }
   183  
   184  func (d *driver) DeleteEndpoint(nid, eid string) error {
   185  	return types.NotImplementedErrorf("not implemented")
   186  }
   187  
   188  func (d *driver) EndpointOperInfo(nid, eid string) (map[string]interface{}, error) {
   189  	return nil, types.NotImplementedErrorf("not implemented")
   190  }
   191  
   192  // Join method is invoked when a Sandbox is attached to an endpoint.
   193  func (d *driver) Join(nid, eid string, sboxKey string, jinfo driverapi.JoinInfo, options map[string]interface{}) error {
   194  	return types.NotImplementedErrorf("not implemented")
   195  }
   196  
   197  // Leave method is invoked when a Sandbox detaches from an endpoint.
   198  func (d *driver) Leave(nid, eid string) error {
   199  	return types.NotImplementedErrorf("not implemented")
   200  }
   201  
   202  func (d *driver) Type() string {
   203  	return networkType
   204  }
   205  
   206  func (d *driver) IsBuiltIn() bool {
   207  	return true
   208  }
   209  
   210  func (d *driver) ProgramExternalConnectivity(nid, eid string, options map[string]interface{}) error {
   211  	return types.NotImplementedErrorf("not implemented")
   212  }
   213  
   214  func (d *driver) RevokeExternalConnectivity(nid, eid string) error {
   215  	return types.NotImplementedErrorf("not implemented")
   216  }