github.com/zhuohuang-hust/src-cbuild@v0.0.0-20230105071821-c7aab3e7c840/mergeCode/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/Sirupsen/logrus"
    11  	"github.com/docker/libnetwork/datastore"
    12  	"github.com/docker/libnetwork/discoverapi"
    13  	"github.com/docker/libnetwork/driverapi"
    14  	"github.com/docker/libnetwork/idm"
    15  	"github.com/docker/libnetwork/netlabel"
    16  	"github.com/docker/libnetwork/types"
    17  )
    18  
    19  const (
    20  	networkType  = "overlay"
    21  	vxlanIDStart = 256
    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  	}
    54  
    55  	d := &driver{
    56  		networks: networkTable{},
    57  		config:   config,
    58  	}
    59  
    60  	d.vxlanIdm, err = idm.New(nil, "vxlan-id", vxlanIDStart, 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  	d.networks[id] = n
   128  	d.Unlock()
   129  
   130  	return opts, nil
   131  }
   132  
   133  func (d *driver) NetworkFree(id string) error {
   134  	if id == "" {
   135  		return fmt.Errorf("invalid network id passed while freeing overlay network")
   136  	}
   137  
   138  	d.Lock()
   139  	n, ok := d.networks[id]
   140  	d.Unlock()
   141  
   142  	if !ok {
   143  		return fmt.Errorf("overlay network with id %s not found", id)
   144  	}
   145  
   146  	// Release all vxlan IDs in one shot.
   147  	n.releaseVxlanID()
   148  
   149  	d.Lock()
   150  	delete(d.networks, id)
   151  	d.Unlock()
   152  
   153  	return nil
   154  }
   155  
   156  func (n *network) obtainVxlanID(s *subnet) error {
   157  	var (
   158  		err error
   159  		vni uint64
   160  	)
   161  
   162  	n.Lock()
   163  	vni = uint64(s.vni)
   164  	n.Unlock()
   165  
   166  	if vni == 0 {
   167  		vni, err = n.driver.vxlanIdm.GetID()
   168  		if err != nil {
   169  			return err
   170  		}
   171  
   172  		n.Lock()
   173  		s.vni = uint32(vni)
   174  		n.Unlock()
   175  		return nil
   176  	}
   177  
   178  	return n.driver.vxlanIdm.GetSpecificID(vni)
   179  }
   180  
   181  func (n *network) releaseVxlanID() {
   182  	n.Lock()
   183  	vnis := make([]uint32, 0, len(n.subnets))
   184  	for _, s := range n.subnets {
   185  		vnis = append(vnis, s.vni)
   186  		s.vni = 0
   187  	}
   188  	n.Unlock()
   189  
   190  	for _, vni := range vnis {
   191  		n.driver.vxlanIdm.Release(uint64(vni))
   192  	}
   193  }
   194  
   195  func (d *driver) CreateNetwork(id string, option map[string]interface{}, nInfo driverapi.NetworkInfo, ipV4Data, ipV6Data []driverapi.IPAMData) error {
   196  	return types.NotImplementedErrorf("not implemented")
   197  }
   198  
   199  func (d *driver) EventNotify(etype driverapi.EventType, nid, tableName, key string, value []byte) {
   200  }
   201  
   202  func (d *driver) DeleteNetwork(nid string) error {
   203  	return types.NotImplementedErrorf("not implemented")
   204  }
   205  
   206  func (d *driver) CreateEndpoint(nid, eid string, ifInfo driverapi.InterfaceInfo, epOptions map[string]interface{}) error {
   207  	return types.NotImplementedErrorf("not implemented")
   208  }
   209  
   210  func (d *driver) DeleteEndpoint(nid, eid string) error {
   211  	return types.NotImplementedErrorf("not implemented")
   212  }
   213  
   214  func (d *driver) EndpointOperInfo(nid, eid string) (map[string]interface{}, error) {
   215  	return nil, types.NotImplementedErrorf("not implemented")
   216  }
   217  
   218  // Join method is invoked when a Sandbox is attached to an endpoint.
   219  func (d *driver) Join(nid, eid string, sboxKey string, jinfo driverapi.JoinInfo, options map[string]interface{}) error {
   220  	return types.NotImplementedErrorf("not implemented")
   221  }
   222  
   223  // Leave method is invoked when a Sandbox detaches from an endpoint.
   224  func (d *driver) Leave(nid, eid string) error {
   225  	return types.NotImplementedErrorf("not implemented")
   226  }
   227  
   228  func (d *driver) Type() string {
   229  	return networkType
   230  }
   231  
   232  // DiscoverNew is a notification for a new discovery event, such as a new node joining a cluster
   233  func (d *driver) DiscoverNew(dType discoverapi.DiscoveryType, data interface{}) error {
   234  	return types.NotImplementedErrorf("not implemented")
   235  }
   236  
   237  // DiscoverDelete is a notification for a discovery delete event, such as a node leaving a cluster
   238  func (d *driver) DiscoverDelete(dType discoverapi.DiscoveryType, data interface{}) error {
   239  	return types.NotImplementedErrorf("not implemented")
   240  }
   241  
   242  func (d *driver) ProgramExternalConnectivity(nid, eid string, options map[string]interface{}) error {
   243  	return types.NotImplementedErrorf("not implemented")
   244  }
   245  
   246  func (d *driver) RevokeExternalConnectivity(nid, eid string) error {
   247  	return types.NotImplementedErrorf("not implemented")
   248  }