瀏覽代碼

Split backend Init operation into New/Init and AddNetwork

To make things slightly easier for singleton backends, so that
initialization with static interface/address values is done
separately from handling a new network.
Dan Williams 9 年之前
父節點
當前提交
c1029314ad
共有 9 個文件被更改,包括 139 次插入111 次删除
  1. 13 10
      backend/alloc/alloc.go
  2. 16 16
      backend/awsvpc/awsvpc.go
  3. 15 3
      backend/common.go
  4. 12 12
      backend/gce/gce.go
  5. 17 13
      backend/hostgw/hostgw.go
  6. 26 26
      backend/udp/udp.go
  7. 26 21
      backend/vxlan/vxlan.go
  8. 8 5
      network/backend.go
  9. 6 5
      network/network.go

+ 13 - 10
backend/alloc/alloc.go

@@ -11,30 +11,33 @@ import (
 )
 
 type AllocBackend struct {
-	sm      subnet.Manager
-	network string
-	lease   *subnet.Lease
+	sm       subnet.Manager
+	publicIP ip.IP4
+	mtu      int
+	lease    *subnet.Lease
 }
 
-func New(sm subnet.Manager, network string, config *subnet.Config) backend.Backend {
-	return &AllocBackend{
+func New(sm subnet.Manager, extIface *net.Interface, extIaddr net.IP, extEaddr net.IP) (backend.Backend, error) {
+	be := AllocBackend{
 		sm:      sm,
-		network: network,
+		publicIP: ip.FromIP(extEaddr),
+		mtu:      extIface.MTU,
 	}
+	return &be, nil
 }
 
-func (m *AllocBackend) Init(ctx context.Context, extIface *net.Interface, extIaddr net.IP, extEaddr net.IP) (*backend.SubnetDef, error) {
+func (m *AllocBackend) RegisterNetwork(ctx context.Context, network string, config *subnet.Config) (*backend.SubnetDef, error) {
 	attrs := subnet.LeaseAttrs{
-		PublicIP: ip.FromIP(extEaddr),
+		PublicIP: m.publicIP,
 	}
 
-	l, err := m.sm.AcquireLease(ctx, m.network, &attrs)
+	l, err := m.sm.AcquireLease(ctx, network, &attrs)
 	switch err {
 	case nil:
 		m.lease = l
 		return &backend.SubnetDef{
 			Lease: l,
-			MTU:   extIface.MTU,
+			MTU:   m.mtu,
 		}, nil
 
 	case context.Canceled, context.DeadlineExceeded:

+ 16 - 16
backend/awsvpc/awsvpc.go

@@ -30,38 +30,38 @@ import (
 )
 
 type AwsVpcBackend struct {
-	sm      subnet.Manager
-	network string
-	config  *subnet.Config
-	cfg     struct {
-		RouteTableID string
+	sm       subnet.Manager
+	publicIP ip.IP4
+	mtu      int
+	cfg      struct {
+		 RouteTableID string
 	}
-	lease *subnet.Lease
+	lease    *subnet.Lease
 }
 
-func New(sm subnet.Manager, network string, config *subnet.Config) backend.Backend {
+func New(sm subnet.Manager, extIface *net.Interface, extIaddr net.IP, extEaddr net.IP) (backend.Backend, error) {
 	be := AwsVpcBackend{
 		sm:      sm,
-		network: network,
-		config:  config,
+		publicIP: ip.FromIP(extEaddr),
+		mtu:      extIface.MTU,
 	}
-	return &be
+	return &be, nil
 }
 
-func (m *AwsVpcBackend) Init(ctx context.Context, extIface *net.Interface, extIaddr net.IP, extEaddr net.IP) (*backend.SubnetDef, error) {
+func (m *AwsVpcBackend) RegisterNetwork(ctx context.Context, network string, config *subnet.Config) (*backend.SubnetDef, error) {
 	// Parse our configuration
-	if len(m.config.Backend) > 0 {
-		if err := json.Unmarshal(m.config.Backend, &m.cfg); err != nil {
+	if len(config.Backend) > 0 {
+		if err := json.Unmarshal(config.Backend, &m.cfg); err != nil {
 			return nil, fmt.Errorf("error decoding VPC backend config: %v", err)
 		}
 	}
 
 	// Acquire the lease form subnet manager
 	attrs := subnet.LeaseAttrs{
-		PublicIP: ip.FromIP(extEaddr),
+		PublicIP: m.publicIP,
 	}
 
-	l, err := m.sm.AcquireLease(ctx, m.network, &attrs)
+	l, err := m.sm.AcquireLease(ctx, network, &attrs)
 	switch err {
 	case nil:
 		m.lease = l
@@ -137,7 +137,7 @@ func (m *AwsVpcBackend) Init(ctx context.Context, extIface *net.Interface, extIa
 
 	return &backend.SubnetDef{
 		Lease: l,
-		MTU:   extIface.MTU,
+		MTU:   m.mtu,
 	}, nil
 }
 

+ 15 - 3
backend/common.go

@@ -15,8 +15,6 @@
 package backend
 
 import (
-	"net"
-
 	"github.com/coreos/flannel/Godeps/_workspace/src/golang.org/x/net/context"
 
 	"github.com/coreos/flannel/subnet"
@@ -27,7 +25,21 @@ type SubnetDef struct {
 	MTU   int
 }
 
+// Besides the entry points in the Backend interface, the backend's New()
+// function receives static network interface information (like internal and
+// external IP addresses, MTU, etc) which it should cache for later use if
+// needed.
+//
+// To implement a singleton backend which manages multiple networks, the
+// New() function should create the singleton backend object once, and return
+// that object on on further calls to New().  The backend is guaranteed that
+// the arguments passed via New() will not change across invocations.  Also,
+// since multiple RegisterNetwork() and Run() calls may be in-flight at any
+// given time for a singleton backend, it must protect these calls with a mutex.
 type Backend interface {
-	Init(ctx context.Context, extIface *net.Interface, extIaddr net.IP, extEaddr net.IP) (*SubnetDef, error)
+	// Called when the backend should create or begin managing a new network
+	RegisterNetwork(ctx context.Context, network string, config *subnet.Config) (*SubnetDef, error)
+	// Called after the backend's first network has been registered to
+	// allow the plugin to watch dynamic events
 	Run(ctx context.Context)
 }

+ 12 - 12
backend/gce/gce.go

@@ -59,31 +59,31 @@ var metadataEndpoint = "http://169.254.169.254/computeMetadata/v1"
 var replacer = strings.NewReplacer(".", "-", "/", "-")
 
 type GCEBackend struct {
-	network        string
-	project        string
 	sm             subnet.Manager
-	config         *subnet.Config
+	publicIP       ip.IP4
+	mtu            int
+	project        string
 	lease          *subnet.Lease
 	computeService *compute.Service
 	gceNetwork     *compute.Network
 	gceInstance    *compute.Instance
 }
 
-func New(sm subnet.Manager, network string, config *subnet.Config) backend.Backend {
+func New(sm subnet.Manager, extIface *net.Interface, extIaddr net.IP, extEaddr net.IP) (backend.Backend, error) {
 	gb := GCEBackend{
-		sm:      sm,
-		config:  config,
-		network: network,
+		sm:       sm,
+		publicIP: ip.FromIP(extEaddr),
+		mtu:      extIface.MTU,
 	}
-	return &gb
+	return &gb, nil
 }
 
-func (g *GCEBackend) Init(ctx context.Context, extIface *net.Interface, extIaddr net.IP, extEaddr net.IP) (*backend.SubnetDef, error) {
+func (g *GCEBackend) RegisterNetwork(ctx context.Context, network string, config *subnet.Config) (*backend.SubnetDef, error) {
 	attrs := subnet.LeaseAttrs{
-		PublicIP: ip.FromIP(extEaddr),
+		PublicIP: g.publicIP,
 	}
 
-	l, err := g.sm.AcquireLease(ctx, g.network, &attrs)
+	l, err := g.sm.AcquireLease(ctx, network, &attrs)
 	switch err {
 	case nil:
 		g.lease = l
@@ -154,7 +154,7 @@ func (g *GCEBackend) Init(ctx context.Context, extIface *net.Interface, extIaddr
 
 	return &backend.SubnetDef{
 		Lease: l,
-		MTU:   extIface.MTU,
+		MTU:   g.mtu,
 	}, nil
 }
 

+ 17 - 13
backend/hostgw/hostgw.go

@@ -35,31 +35,35 @@ const (
 
 type HostgwBackend struct {
 	sm       subnet.Manager
+	publicIP ip.IP4
 	network  string
 	lease    *subnet.Lease
 	extIface *net.Interface
 	extIaddr net.IP
+	mtu      int
 	rl       []netlink.Route
 }
 
-func New(sm subnet.Manager, network string, config *subnet.Config) backend.Backend {
+func New(sm subnet.Manager, extIface *net.Interface, extIaddr net.IP, extEaddr net.IP) (backend.Backend, error) {
+	if !extIaddr.Equal(extEaddr) {
+		return nil, fmt.Errorf("your PublicIP differs from interface IP, meaning that probably you're on a NAT, which is not supported by host-gw backend")
+	}
+
 	b := &HostgwBackend{
-		sm:      sm,
-		network: network,
+		sm:       sm,
+		publicIP: ip.FromIP(extEaddr),
+		mtu:      extIface.MTU,
+		extIface: extIface,
+		extIaddr: extIaddr,
 	}
-	return b
+	return b, nil
 }
 
-func (rb *HostgwBackend) Init(ctx context.Context, extIface *net.Interface, extIaddr net.IP, extEaddr net.IP) (*backend.SubnetDef, error) {
-	rb.extIface = extIface
-	rb.extIaddr = extIaddr
-
-	if !extIaddr.Equal(extEaddr) {
-		return nil, fmt.Errorf("your PublicIP differs from interface IP, meaning that probably you're on a NAT, which is not supported by host-gw backend")
-	}
+func (rb *HostgwBackend) RegisterNetwork(ctx context.Context, network string, config *subnet.Config) (*backend.SubnetDef, error) {
+	rb.network = network
 
 	attrs := subnet.LeaseAttrs{
-		PublicIP:    ip.FromIP(extIaddr),
+		PublicIP:    rb.publicIP,
 		BackendType: "host-gw",
 	}
 
@@ -79,7 +83,7 @@ func (rb *HostgwBackend) Init(ctx context.Context, extIface *net.Interface, extI
 
 	return &backend.SubnetDef{
 		Lease: l,
-		MTU:   extIface.MTU,
+		MTU:   rb.mtu,
 	}, nil
 }
 

+ 26 - 26
backend/udp/udp.go

@@ -37,42 +37,45 @@ const (
 )
 
 type UdpBackend struct {
-	sm      subnet.Manager
-	network string
-	config  *subnet.Config
-	cfg     struct {
-		Port int
-	}
-	lease  *subnet.Lease
-	ctl    *os.File
-	ctl2   *os.File
-	tun    *os.File
-	conn   *net.UDPConn
-	mtu    int
-	tunNet ip.IP4Net
+	sm       subnet.Manager
+	network  string
+	publicIP ip.IP4
+	cfg      struct {
+		 Port int
+	}
+	lease    *subnet.Lease
+	ctl      *os.File
+	ctl2     *os.File
+	tun      *os.File
+	conn     *net.UDPConn
+	mtu      int
+	tunNet   ip.IP4Net
 }
 
-func New(sm subnet.Manager, network string, config *subnet.Config) backend.Backend {
+func New(sm subnet.Manager, extIface *net.Interface, extIaddr net.IP, extEaddr net.IP) (backend.Backend, error) {
 	be := UdpBackend{
-		sm:      sm,
-		network: network,
-		config:  config,
+		sm:       sm,
+		publicIP: ip.FromIP(extEaddr),
+		// TUN MTU will be smaller b/c of encap (IP+UDP hdrs)
+		mtu:      extIface.MTU - encapOverhead,
 	}
 	be.cfg.Port = defaultPort
-	return &be
+	return &be, nil
 }
 
-func (m *UdpBackend) Init(ctx context.Context, extIface *net.Interface, extIaddr net.IP, extEaddr net.IP) (*backend.SubnetDef, error) {
+func (m *UdpBackend) RegisterNetwork(ctx context.Context, network string, config *subnet.Config) (*backend.SubnetDef, error) {
+	m.network = network
+
 	// Parse our configuration
-	if len(m.config.Backend) > 0 {
-		if err := json.Unmarshal(m.config.Backend, &m.cfg); err != nil {
+	if len(config.Backend) > 0 {
+		if err := json.Unmarshal(config.Backend, &m.cfg); err != nil {
 			return nil, fmt.Errorf("error decoding UDP backend config: %v", err)
 		}
 	}
 
 	// Acquire the lease form subnet manager
 	attrs := subnet.LeaseAttrs{
-		PublicIP: ip.FromIP(extEaddr),
+		PublicIP: m.publicIP,
 	}
 
 	l, err := m.sm.AcquireLease(ctx, m.network, &attrs)
@@ -91,12 +94,9 @@ func (m *UdpBackend) Init(ctx context.Context, extIface *net.Interface, extIaddr
 	// and not that of the individual host (e.g. /24)
 	m.tunNet = ip.IP4Net{
 		IP:        l.Subnet.IP,
-		PrefixLen: m.config.Network.PrefixLen,
+		PrefixLen: config.Network.PrefixLen,
 	}
 
-	// TUN MTU will be smaller b/c of encap (IP+UDP hdrs)
-	m.mtu = extIface.MTU - encapOverhead
-
 	if err = m.initTun(); err != nil {
 		return nil, err
 	}

+ 26 - 21
backend/vxlan/vxlan.go

@@ -36,27 +36,30 @@ const (
 )
 
 type VXLANBackend struct {
-	sm      subnet.Manager
-	network string
-	config  *subnet.Config
-	cfg     struct {
-		VNI  int
-		Port int
+	sm       subnet.Manager
+	network  string
+	cfg      struct {
+		 VNI  int
+		 Port int
 	}
-	lease *subnet.Lease
-	dev   *vxlanDevice
-	rts   routes
+	extIndex int
+	extIaddr net.IP
+	extEaddr net.IP
+	lease    *subnet.Lease
+	dev      *vxlanDevice
+	rts      routes
 }
 
-func New(sm subnet.Manager, network string, config *subnet.Config) backend.Backend {
+func New(sm subnet.Manager, extIface *net.Interface, extIaddr net.IP, extEaddr net.IP) (backend.Backend, error) {
 	vb := &VXLANBackend{
-		sm:      sm,
-		network: network,
-		config:  config,
+		sm:       sm,
+		extIndex: extIface.Index,
+		extIaddr: extIaddr,
+		extEaddr: extEaddr,
 	}
 	vb.cfg.VNI = defaultVNI
 
-	return vb
+	return vb, nil
 }
 
 func newSubnetAttrs(extEaddr net.IP, mac net.HardwareAddr) (*subnet.LeaseAttrs, error) {
@@ -72,10 +75,12 @@ func newSubnetAttrs(extEaddr net.IP, mac net.HardwareAddr) (*subnet.LeaseAttrs,
 	}, nil
 }
 
-func (vb *VXLANBackend) Init(ctx context.Context, extIface *net.Interface, extIaddr net.IP, extEaddr net.IP) (*backend.SubnetDef, error) {
+func (vb *VXLANBackend) RegisterNetwork(ctx context.Context, network string, config *subnet.Config) (*backend.SubnetDef, error) {
+	vb.network = network
+
 	// Parse our configuration
-	if len(vb.config.Backend) > 0 {
-		if err := json.Unmarshal(vb.config.Backend, &vb.cfg); err != nil {
+	if len(config.Backend) > 0 {
+		if err := json.Unmarshal(config.Backend, &vb.cfg); err != nil {
 			return nil, fmt.Errorf("error decoding VXLAN backend config: %v", err)
 		}
 	}
@@ -83,8 +88,8 @@ func (vb *VXLANBackend) Init(ctx context.Context, extIface *net.Interface, extIa
 	devAttrs := vxlanDeviceAttrs{
 		vni:       uint32(vb.cfg.VNI),
 		name:      fmt.Sprintf("flannel.%v", vb.cfg.VNI),
-		vtepIndex: extIface.Index,
-		vtepAddr:  extIaddr,
+		vtepIndex: vb.extIndex,
+		vtepAddr:  vb.extIaddr,
 		vtepPort:  vb.cfg.Port,
 	}
 
@@ -102,7 +107,7 @@ func (vb *VXLANBackend) Init(ctx context.Context, extIface *net.Interface, extIa
 		}
 	}
 
-	sa, err := newSubnetAttrs(extEaddr, vb.dev.MACAddr())
+	sa, err := newSubnetAttrs(vb.extEaddr, vb.dev.MACAddr())
 	if err != nil {
 		return nil, err
 	}
@@ -123,7 +128,7 @@ func (vb *VXLANBackend) Init(ctx context.Context, extIface *net.Interface, extIa
 	// and not that of the individual host (e.g. /24)
 	vxlanNet := ip.IP4Net{
 		IP:        l.Subnet.IP,
-		PrefixLen: vb.config.Network.PrefixLen,
+		PrefixLen: config.Network.PrefixLen,
 	}
 	if err = vb.dev.Configure(vxlanNet); err != nil {
 		return nil, err

+ 8 - 5
network/backend.go

@@ -2,6 +2,7 @@ package network
 
 import (
 	"fmt"
+	"net"
 	"strings"
 
 	"github.com/coreos/flannel/backend"
@@ -14,7 +15,9 @@ import (
 	"github.com/coreos/flannel/subnet"
 )
 
-var backendMap = map[string]func(sm subnet.Manager, network string, config *subnet.Config) backend.Backend {
+type beNewFunc func(sm subnet.Manager, extIface *net.Interface, extIaddr net.IP, extEaddr net.IP) (backend.Backend, error)
+
+var backendMap = map[string]beNewFunc {
 	"udp":     udp.New,
 	"alloc":   alloc.New,
 	"host-gw": hostgw.New,
@@ -23,11 +26,11 @@ var backendMap = map[string]func(sm subnet.Manager, network string, config *subn
 	"gce":     gce.New,
 }
 
-func newBackend(sm subnet.Manager, network string, config *subnet.Config) (backend.Backend, error) {
-	betype := strings.ToLower(config.BackendType)
+func newBackend(sm subnet.Manager, backendType string, extIface *net.Interface, extIaddr net.IP, extEaddr net.IP) (backend.Backend, error) {
+	betype := strings.ToLower(backendType)
 	befunc, ok := backendMap[betype]
 	if !ok {
-		return nil, fmt.Errorf("%v: '%v': unknown backend type", network, betype)
+		return nil, fmt.Errorf("unknown backend type")
 	}
-	return befunc(sm, network, config), nil
+	return befunc(sm, extIface, extIaddr, extEaddr)
 }

+ 6 - 5
network/network.go

@@ -57,9 +57,9 @@ func (n *Network) Init(ctx context.Context, iface *net.Interface, iaddr net.IP,
 		},
 
 		func() (err error) {
-			be, err = newBackend(n.sm, n.Name, n.Config)
+			be, err = newBackend(n.sm, n.Config.BackendType, iface, iaddr, eaddr)
 			if err != nil {
-				log.Error("Failed to create backend: ", err)
+				log.Errorf("Failed to create and initialize network %v (type %v): %v", n.Name, n.Config.BackendType, err)
 			} else {
 				n.be = be
 			}
@@ -67,11 +67,12 @@ func (n *Network) Init(ctx context.Context, iface *net.Interface, iaddr net.IP,
 		},
 
 		func() (err error) {
-			sn, err = be.Init(ctx, iface, iaddr, eaddr)
+			sn, err = be.RegisterNetwork(ctx, n.Name, n.Config)
 			if err != nil {
-				log.Errorf("Failed to initialize network %v (type %v): %v", n.Name, n.Config.BackendType, err)
+				log.Errorf("Failed register network %v (type %v): %v", n.Name, n.Config.BackendType, err)
+			} else {
+				n.lease = sn.Lease
 			}
-			n.lease = sn.Lease
 			return
 		},