Skip to content

Commit d2141cd

Browse files
author
Santhosh Manohar
authored
Merge pull request #1433 from mrjana/overlay
Ensure purging neighbor cache for stale deletes
2 parents db01448 + 03f4406 commit d2141cd

File tree

3 files changed

+52
-38
lines changed

3 files changed

+52
-38
lines changed

drivers/overlay/peerdb.go

Lines changed: 23 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -168,14 +168,14 @@ func (d *driver) peerDbAdd(nid, eid string, peerIP net.IP, peerIPMask net.IPMask
168168
}
169169

170170
func (d *driver) peerDbDelete(nid, eid string, peerIP net.IP, peerIPMask net.IPMask,
171-
peerMac net.HardwareAddr, vtep net.IP) bool {
171+
peerMac net.HardwareAddr, vtep net.IP) peerEntry {
172172
peerDbWg.Wait()
173173

174174
d.peerDb.Lock()
175175
pMap, ok := d.peerDb.mp[nid]
176176
if !ok {
177177
d.peerDb.Unlock()
178-
return false
178+
return peerEntry{}
179179
}
180180
d.peerDb.Unlock()
181181

@@ -186,19 +186,20 @@ func (d *driver) peerDbDelete(nid, eid string, peerIP net.IP, peerIPMask net.IPM
186186

187187
pMap.Lock()
188188

189-
if pEntry, ok := pMap.mp[pKey.String()]; ok {
189+
pEntry, ok := pMap.mp[pKey.String()]
190+
if ok {
190191
// Mismatched endpoint ID(possibly outdated). Do not
191192
// delete peerdb
192193
if pEntry.eid != eid {
193194
pMap.Unlock()
194-
return false
195+
return pEntry
195196
}
196197
}
197198

198199
delete(pMap.mp, pKey.String())
199200
pMap.Unlock()
200201

201-
return true
202+
return pEntry
202203
}
203204

204205
func (d *driver) peerDbUpdateSandbox(nid string) {
@@ -312,10 +313,9 @@ func (d *driver) peerDelete(nid, eid string, peerIP net.IP, peerIPMask net.IPMas
312313
return err
313314
}
314315

316+
var pEntry peerEntry
315317
if updateDb {
316-
if !d.peerDbDelete(nid, eid, peerIP, peerIPMask, peerMac, vtep) {
317-
return nil
318-
}
318+
pEntry = d.peerDbDelete(nid, eid, peerIP, peerIPMask, peerMac, vtep)
319319
}
320320

321321
n := d.network(nid)
@@ -328,14 +328,24 @@ func (d *driver) peerDelete(nid, eid string, peerIP net.IP, peerIPMask net.IPMas
328328
return nil
329329
}
330330

331-
// Delete fdb entry to the bridge for the peer mac
332-
if err := sbox.DeleteNeighbor(vtep, peerMac); err != nil {
333-
return fmt.Errorf("could not delete fdb entry into the sandbox: %v", err)
331+
// Delete fdb entry to the bridge for the peer mac only if the
332+
// entry existed in local peerdb. If it is a stale delete
333+
// request, still call DeleteNeighbor but only to cleanup any
334+
// leftover sandbox neighbor cache and not actually delete the
335+
// kernel state.
336+
if (eid == pEntry.eid && vtep.Equal(pEntry.vtep)) ||
337+
(eid != pEntry.eid && !vtep.Equal(pEntry.vtep)) {
338+
if err := sbox.DeleteNeighbor(vtep, peerMac,
339+
eid == pEntry.eid && vtep.Equal(pEntry.vtep)); err != nil {
340+
return fmt.Errorf("could not delete fdb entry into the sandbox: %v", err)
341+
}
334342
}
335343

336344
// Delete neighbor entry for the peer IP
337-
if err := sbox.DeleteNeighbor(peerIP, peerMac); err != nil {
338-
return fmt.Errorf("could not delete neighbor entry into the sandbox: %v", err)
345+
if eid == pEntry.eid {
346+
if err := sbox.DeleteNeighbor(peerIP, peerMac, true); err != nil {
347+
return fmt.Errorf("could not delete neighbor entry into the sandbox: %v", err)
348+
}
339349
}
340350

341351
if err := d.checkEncryption(nid, vtep, 0, false, false); err != nil {

osl/neigh_linux.go

Lines changed: 28 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ func (n *networkNamespace) findNeighbor(dstIP net.IP, dstMac net.HardwareAddr) *
3232
return nil
3333
}
3434

35-
func (n *networkNamespace) DeleteNeighbor(dstIP net.IP, dstMac net.HardwareAddr) error {
35+
func (n *networkNamespace) DeleteNeighbor(dstIP net.IP, dstMac net.HardwareAddr, osDelete bool) error {
3636
var (
3737
iface netlink.Link
3838
err error
@@ -43,42 +43,46 @@ func (n *networkNamespace) DeleteNeighbor(dstIP net.IP, dstMac net.HardwareAddr)
4343
return fmt.Errorf("could not find the neighbor entry to delete")
4444
}
4545

46-
n.Lock()
47-
nlh := n.nlHandle
48-
n.Unlock()
46+
if osDelete {
47+
n.Lock()
48+
nlh := n.nlHandle
49+
n.Unlock()
4950

50-
if nh.linkDst != "" {
51-
iface, err = nlh.LinkByName(nh.linkDst)
52-
if err != nil {
53-
return fmt.Errorf("could not find interface with destination name %s: %v",
54-
nh.linkDst, err)
51+
if nh.linkDst != "" {
52+
iface, err = nlh.LinkByName(nh.linkDst)
53+
if err != nil {
54+
return fmt.Errorf("could not find interface with destination name %s: %v",
55+
nh.linkDst, err)
56+
}
5557
}
56-
}
5758

58-
nlnh := &netlink.Neigh{
59-
IP: dstIP,
60-
State: netlink.NUD_PERMANENT,
61-
Family: nh.family,
62-
}
59+
nlnh := &netlink.Neigh{
60+
IP: dstIP,
61+
State: netlink.NUD_PERMANENT,
62+
Family: nh.family,
63+
}
6364

64-
if nlnh.Family > 0 {
65-
nlnh.HardwareAddr = dstMac
66-
nlnh.Flags = netlink.NTF_SELF
67-
}
65+
if nlnh.Family > 0 {
66+
nlnh.HardwareAddr = dstMac
67+
nlnh.Flags = netlink.NTF_SELF
68+
}
6869

69-
if nh.linkDst != "" {
70-
nlnh.LinkIndex = iface.Attrs().Index
71-
}
70+
if nh.linkDst != "" {
71+
nlnh.LinkIndex = iface.Attrs().Index
72+
}
7273

73-
if err := nlh.NeighDel(nlnh); err != nil {
74-
return fmt.Errorf("could not delete neighbor entry: %v", err)
74+
if err := nlh.NeighDel(nlnh); err != nil {
75+
return fmt.Errorf("could not delete neighbor entry: %v", err)
76+
}
7577
}
7678

79+
n.Lock()
7780
for i, nh := range n.neighbors {
7881
if nh.dstIP.Equal(dstIP) && bytes.Equal(nh.dstMac, dstMac) {
7982
n.neighbors = append(n.neighbors[:i], n.neighbors[i+1:]...)
8083
}
8184
}
85+
n.Unlock()
8286

8387
return nil
8488
}

osl/sandbox.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ type Sandbox interface {
4242
AddNeighbor(dstIP net.IP, dstMac net.HardwareAddr, option ...NeighOption) error
4343

4444
// DeleteNeighbor deletes neighbor entry from the sandbox.
45-
DeleteNeighbor(dstIP net.IP, dstMac net.HardwareAddr) error
45+
DeleteNeighbor(dstIP net.IP, dstMac net.HardwareAddr, osDelete bool) error
4646

4747
// Returns an interface with methods to set neighbor options.
4848
NeighborOptions() NeighborOptionSetter

0 commit comments

Comments
 (0)