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