Skip to content

Commit 15f8dc4

Browse files
author
Santhosh Manohar
committed
Merge pull request #1145 from mrjana/overlay
Make overlay driver work without a kv store
2 parents f8fe886 + a997502 commit 15f8dc4

5 files changed

Lines changed: 116 additions & 47 deletions

File tree

drivers/overlay/joinleave.go

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package overlay
33
import (
44
"fmt"
55
"net"
6+
"strings"
67

78
log "github.com/Sirupsen/logrus"
89
"github.com/docker/libnetwork/driverapi"
@@ -104,11 +105,55 @@ func (d *driver) Join(nid, eid string, sboxKey string, jinfo driverapi.JoinInfo,
104105

105106
d.peerDbAdd(nid, eid, ep.addr.IP, ep.addr.Mask, ep.mac,
106107
net.ParseIP(d.bindAddress), true)
108+
109+
if err := jinfo.AddTableEntry(ovPeerTable, eid, []byte(fmt.Sprintf("%s,%s,%s", ep.addr, ep.mac, d.bindAddress))); err != nil {
110+
log.Errorf("overlay: Failed adding table entry to joininfo: %v", err)
111+
}
112+
107113
d.pushLocalEndpointEvent("join", nid, eid)
108114

109115
return nil
110116
}
111117

118+
func (d *driver) EventNotify(etype driverapi.EventType, nid, tableName, key string, value []byte) {
119+
if tableName != ovPeerTable {
120+
log.Errorf("Unexpected table notification for table %s received", tableName)
121+
return
122+
}
123+
124+
eid := key
125+
values := strings.Split(string(value), ",")
126+
if len(values) < 3 {
127+
log.Errorf("Invalid value %s received through event notify", string(value))
128+
return
129+
}
130+
131+
addr, err := types.ParseCIDR(values[0])
132+
if err != nil {
133+
log.Errorf("Invalid peer IP %s received in event notify", values[0])
134+
return
135+
}
136+
137+
mac, err := net.ParseMAC(values[1])
138+
if err != nil {
139+
log.Errorf("Invalid mac %s received in event notify", values[1])
140+
return
141+
}
142+
143+
vtep := net.ParseIP(values[2])
144+
if vtep == nil {
145+
log.Errorf("Invalid VTEP %s received in event notify", values[2])
146+
return
147+
}
148+
149+
if etype == driverapi.Delete {
150+
d.peerDelete(nid, eid, addr.IP, addr.Mask, mac, vtep, true)
151+
return
152+
}
153+
154+
d.peerAdd(nid, eid, addr.IP, addr.Mask, mac, vtep, true)
155+
}
156+
112157
// Leave method is invoked when a Sandbox detaches from an endpoint.
113158
func (d *driver) Leave(nid, eid string) error {
114159
if err := validateID(nid, eid); err != nil {

drivers/overlay/ov_network.go

Lines changed: 68 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,15 @@ import (
66
"net"
77
"os"
88
"path/filepath"
9+
"strconv"
910
"strings"
1011
"sync"
1112
"syscall"
1213

1314
"github.com/Sirupsen/logrus"
1415
"github.com/docker/libnetwork/datastore"
1516
"github.com/docker/libnetwork/driverapi"
17+
"github.com/docker/libnetwork/netlabel"
1618
"github.com/docker/libnetwork/netutils"
1719
"github.com/docker/libnetwork/osl"
1820
"github.com/docker/libnetwork/resolvconf"
@@ -67,9 +69,6 @@ func (d *driver) NetworkFree(id string) error {
6769
return types.NotImplementedErrorf("not implemented")
6870
}
6971

70-
func (d *driver) EventNotify(etype driverapi.EventType, nid, tableName, key string, value []byte) {
71-
}
72-
7372
func (d *driver) CreateNetwork(id string, option map[string]interface{}, nInfo driverapi.NetworkInfo, ipV4Data, ipV6Data []driverapi.IPAMData) error {
7473
if id == "" {
7574
return fmt.Errorf("invalid network id")
@@ -92,21 +91,54 @@ func (d *driver) CreateNetwork(id string, option map[string]interface{}, nInfo d
9291
subnets: []*subnet{},
9392
}
9493

95-
for _, ipd := range ipV4Data {
94+
vnis := make([]uint32, 0, len(ipV4Data))
95+
if gval, ok := option[netlabel.GenericData]; ok {
96+
optMap := gval.(map[string]string)
97+
if val, ok := optMap[netlabel.OverlayVxlanIDList]; ok {
98+
logrus.Debugf("overlay: Received vxlan IDs: %s", val)
99+
vniStrings := strings.Split(val, ",")
100+
for _, vniStr := range vniStrings {
101+
vni, err := strconv.Atoi(vniStr)
102+
if err != nil {
103+
return fmt.Errorf("invalid vxlan id value %q passed", vniStr)
104+
}
105+
106+
vnis = append(vnis, uint32(vni))
107+
}
108+
}
109+
}
110+
111+
// If we are getting vnis from libnetwork, either we get for
112+
// all subnets or none.
113+
if len(vnis) != 0 && len(vnis) < len(ipV4Data) {
114+
return fmt.Errorf("insufficient vnis(%d) passed to overlay", len(vnis))
115+
}
116+
117+
for i, ipd := range ipV4Data {
96118
s := &subnet{
97119
subnetIP: ipd.Pool,
98120
gwIP: ipd.Gateway,
99121
once: &sync.Once{},
100122
}
123+
124+
if len(vnis) != 0 {
125+
s.vni = vnis[i]
126+
}
127+
101128
n.subnets = append(n.subnets, s)
102129
}
103130

104131
if err := n.writeToStore(); err != nil {
105132
return fmt.Errorf("failed to update data store for network %v: %v", n.id, err)
106133
}
107134

108-
d.addNetwork(n)
135+
if nInfo != nil {
136+
if err := nInfo.TableEventRegister(ovPeerTable); err != nil {
137+
return err
138+
}
139+
}
109140

141+
d.addNetwork(n)
110142
return nil
111143
}
112144

@@ -255,11 +287,21 @@ func setHostMode() {
255287
}
256288

257289
func (n *network) generateVxlanName(s *subnet) string {
258-
return "vx-" + fmt.Sprintf("%06x", n.vxlanID(s)) + "-" + n.id[:5]
290+
id := n.id
291+
if len(n.id) > 5 {
292+
id = n.id[:5]
293+
}
294+
295+
return "vx-" + fmt.Sprintf("%06x", n.vxlanID(s)) + "-" + id
259296
}
260297

261298
func (n *network) generateBridgeName(s *subnet) string {
262-
return "ov-" + fmt.Sprintf("%06x", n.vxlanID(s)) + "-" + n.id[:5]
299+
id := n.id
300+
if len(n.id) > 5 {
301+
id = n.id[:5]
302+
}
303+
304+
return "ov-" + fmt.Sprintf("%06x", n.vxlanID(s)) + "-" + id
263305
}
264306

265307
func isOverlap(nw *net.IPNet) bool {
@@ -587,32 +629,38 @@ func (n *network) DataScope() string {
587629
}
588630

589631
func (n *network) writeToStore() error {
632+
if n.driver.store == nil {
633+
return nil
634+
}
635+
590636
return n.driver.store.PutObjectAtomic(n)
591637
}
592638

593639
func (n *network) releaseVxlanID() error {
594-
if n.driver.store == nil {
595-
return fmt.Errorf("no datastore configured. cannot release vxlan id")
596-
}
597-
598640
if len(n.subnets) == 0 {
599641
return nil
600642
}
601643

602-
if err := n.driver.store.DeleteObjectAtomic(n); err != nil {
603-
if err == datastore.ErrKeyModified || err == datastore.ErrKeyNotFound {
604-
// In both the above cases we can safely assume that the key has been removed by some other
605-
// instance and so simply get out of here
606-
return nil
607-
}
644+
if n.driver.store != nil {
645+
if err := n.driver.store.DeleteObjectAtomic(n); err != nil {
646+
if err == datastore.ErrKeyModified || err == datastore.ErrKeyNotFound {
647+
// In both the above cases we can safely assume that the key has been removed by some other
648+
// instance and so simply get out of here
649+
return nil
650+
}
608651

609-
return fmt.Errorf("failed to delete network to vxlan id map: %v", err)
652+
return fmt.Errorf("failed to delete network to vxlan id map: %v", err)
653+
}
610654
}
611655

612656
for _, s := range n.subnets {
613-
n.driver.vxlanIdm.Release(uint64(n.vxlanID(s)))
657+
if n.driver.vxlanIdm != nil {
658+
n.driver.vxlanIdm.Release(uint64(n.vxlanID(s)))
659+
}
660+
614661
n.setVxlanID(s, 0)
615662
}
663+
616664
return nil
617665
}
618666

@@ -623,7 +671,7 @@ func (n *network) obtainVxlanID(s *subnet) error {
623671
}
624672

625673
if n.driver.store == nil {
626-
return fmt.Errorf("no datastore configured. cannot obtain vxlan id")
674+
return fmt.Errorf("no valid vxlan id and no datastore configured, cannot obtain vxlan id")
627675
}
628676

629677
for {

drivers/overlay/overlay.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ func Fini(drv driverapi.Driver) {
8888

8989
func (d *driver) configure() error {
9090
if d.store == nil {
91-
return types.NoServiceErrorf("datastore is not available")
91+
return nil
9292
}
9393

9494
if d.vxlanIdm == nil {

drivers/overlay/overlay_test.go

Lines changed: 0 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@ import (
88
"github.com/docker/libnetwork/discoverapi"
99
"github.com/docker/libnetwork/driverapi"
1010
_ "github.com/docker/libnetwork/testutils"
11-
"github.com/docker/libnetwork/types"
1211
)
1312

1413
type driverTester struct {
@@ -24,14 +23,6 @@ func setupDriver(t *testing.T) *driverTester {
2423
t.Fatal(err)
2524
}
2625

27-
err := dt.d.configure()
28-
if err == nil {
29-
t.Fatalf("Failed to detect nil store")
30-
}
31-
if _, ok := err.(types.NoServiceError); !ok {
32-
t.Fatalf("Unexpected error type: %v", err)
33-
}
34-
3526
iface, err := net.InterfaceByName("eth0")
3627
if err != nil {
3728
t.Fatal(err)
@@ -93,23 +84,6 @@ func TestOverlayFiniWithoutConfig(t *testing.T) {
9384
cleanupDriver(t, dt)
9485
}
9586

96-
func TestOverlayNilConfig(t *testing.T) {
97-
dt := &driverTester{t: t}
98-
if err := Init(dt, nil); err != nil {
99-
t.Fatal(err)
100-
}
101-
102-
err := dt.d.configure()
103-
if err == nil {
104-
t.Fatalf("Failed to detect nil store")
105-
}
106-
if _, ok := err.(types.NoServiceError); !ok {
107-
t.Fatalf("Unexpected error type: %v", err)
108-
}
109-
110-
cleanupDriver(t, dt)
111-
}
112-
11387
func TestOverlayConfig(t *testing.T) {
11488
dt := setupDriver(t)
11589

drivers/overlay/peerdb.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ import (
77
"syscall"
88
)
99

10+
const ovPeerTable = "overlay_peer_table"
11+
1012
type peerKey struct {
1113
peerIP net.IP
1214
peerMac net.HardwareAddr

0 commit comments

Comments
 (0)