Skip to content

Commit c7b9370

Browse files
committed
libn/d/overlay: extract hashable address types
The macAddr and ipmac types are generally useful within libnetwork. Move them to a dedicated package and overhaul the API to be more like that of the net/netip package. Update the overlay driver to utilize these types, adapting to the new API. Signed-off-by: Cory Snider <[email protected]>
1 parent 844023f commit c7b9370

8 files changed

Lines changed: 188 additions & 111 deletions

File tree

daemon/libnetwork/drivers/overlay/joinleave.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,12 @@ import (
66
"context"
77
"errors"
88
"fmt"
9-
"net"
109
"net/netip"
1110
"syscall"
1211

1312
"github.com/containerd/log"
1413
"github.com/docker/docker/daemon/libnetwork/driverapi"
14+
"github.com/docker/docker/daemon/libnetwork/internal/hashable"
1515
"github.com/docker/docker/daemon/libnetwork/internal/netiputil"
1616
"github.com/docker/docker/daemon/libnetwork/netlabel"
1717
"github.com/docker/docker/daemon/libnetwork/ns"
@@ -104,7 +104,7 @@ func (d *driver) Join(ctx context.Context, nid, eid string, sboxKey string, jinf
104104
return err
105105
}
106106

107-
if err = nlh.LinkSetHardwareAddr(veth, ep.mac); err != nil {
107+
if err = nlh.LinkSetHardwareAddr(veth, ep.mac.AsSlice()); err != nil {
108108
return fmt.Errorf("could not set mac address (%v) to the container interface: %v", ep.mac, err)
109109
}
110110

@@ -187,7 +187,7 @@ func (d *driver) EventNotify(etype driverapi.EventType, nid, tableName, key stri
187187
return
188188
}
189189

190-
mac, err := net.ParseMAC(peer.EndpointMAC)
190+
mac, err := hashable.ParseMAC(peer.EndpointMAC)
191191
if err != nil {
192192
log.G(context.TODO()).WithError(err).Errorf("Invalid mac %s received in event notify", peer.EndpointMAC)
193193
return

daemon/libnetwork/drivers/overlay/ov_endpoint.go

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,11 @@ import (
66
"context"
77
"errors"
88
"fmt"
9-
"net"
109
"net/netip"
1110

1211
"github.com/containerd/log"
1312
"github.com/docker/docker/daemon/libnetwork/driverapi"
13+
"github.com/docker/docker/daemon/libnetwork/internal/hashable"
1414
"github.com/docker/docker/daemon/libnetwork/internal/netiputil"
1515
"github.com/docker/docker/daemon/libnetwork/netutils"
1616
"github.com/docker/docker/daemon/libnetwork/ns"
@@ -22,7 +22,7 @@ type endpoint struct {
2222
id string
2323
nid string
2424
ifName string
25-
mac net.HardwareAddr
25+
mac hashable.MACAddr
2626
addr netip.Prefix
2727
}
2828

@@ -48,7 +48,6 @@ func (d *driver) CreateEndpoint(_ context.Context, nid, eid string, ifInfo drive
4848
ep := &endpoint{
4949
id: eid,
5050
nid: n.id,
51-
mac: ifInfo.MacAddress(),
5251
}
5352
var ok bool
5453
ep.addr, ok = netiputil.ToPrefix(ifInfo.Address())
@@ -60,9 +59,19 @@ func (d *driver) CreateEndpoint(_ context.Context, nid, eid string, ifInfo drive
6059
return fmt.Errorf("no matching subnet for IP %q in network %q", ep.addr, nid)
6160
}
6261

63-
if ep.mac == nil {
64-
ep.mac = netutils.GenerateMACFromIP(ep.addr.Addr().AsSlice())
65-
if err := ifInfo.SetMacAddress(ep.mac); err != nil {
62+
if ifmac := ifInfo.MacAddress(); ifmac != nil {
63+
var ok bool
64+
ep.mac, ok = hashable.MACAddrFromSlice(ifInfo.MacAddress())
65+
if !ok {
66+
return fmt.Errorf("invalid MAC address %q assigned to endpoint: unexpected length", ifmac)
67+
}
68+
} else {
69+
var ok bool
70+
ep.mac, ok = hashable.MACAddrFromSlice(netutils.GenerateMACFromIP(ep.addr.Addr().AsSlice()))
71+
if !ok {
72+
panic("GenerateMACFromIP returned a HardwareAddress that is not a MAC-48")
73+
}
74+
if err := ifInfo.SetMacAddress(ep.mac.AsSlice()); err != nil {
6675
return err
6776
}
6877
}

daemon/libnetwork/drivers/overlay/ov_network.go

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ import (
1919
"github.com/docker/docker/daemon/libnetwork/driverapi"
2020
"github.com/docker/docker/daemon/libnetwork/drivers/overlay/overlayutils"
2121
"github.com/docker/docker/daemon/libnetwork/internal/countmap"
22+
"github.com/docker/docker/daemon/libnetwork/internal/hashable"
2223
"github.com/docker/docker/daemon/libnetwork/internal/netiputil"
2324
"github.com/docker/docker/daemon/libnetwork/netlabel"
2425
"github.com/docker/docker/daemon/libnetwork/ns"
@@ -65,7 +66,7 @@ type network struct {
6566
endpoints endpointTable
6667
joinCnt int
6768
// Ref count of VXLAN Forwarding Database entries programmed into the kernel
68-
fdbCnt countmap.Map[ipmac]
69+
fdbCnt countmap.Map[hashable.IPMAC]
6970
sboxInit bool
7071
initEpoch int
7172
initErr error
@@ -110,7 +111,7 @@ func (d *driver) CreateNetwork(ctx context.Context, id string, option map[string
110111
driver: d,
111112
endpoints: endpointTable{},
112113
subnets: []*subnet{},
113-
fdbCnt: countmap.Map[ipmac]{},
114+
fdbCnt: countmap.Map[hashable.IPMAC]{},
114115
}
115116

116117
vnis := make([]uint32, 0, len(ipV4Data))
@@ -607,7 +608,7 @@ func (n *network) initSandbox() error {
607608

608609
// this is needed to let the peerAdd configure the sandbox
609610
n.sbox = sbox
610-
n.fdbCnt = countmap.Map[ipmac]{}
611+
n.fdbCnt = countmap.Map[hashable.IPMAC]{}
611612

612613
return nil
613614
}

daemon/libnetwork/drivers/overlay/peerdb.go

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,11 @@ import (
77
"context"
88
"errors"
99
"fmt"
10-
"net"
1110
"net/netip"
1211
"syscall"
1312

1413
"github.com/containerd/log"
14+
"github.com/docker/docker/daemon/libnetwork/internal/hashable"
1515
"github.com/docker/docker/daemon/libnetwork/internal/setmatrix"
1616
"github.com/docker/docker/daemon/libnetwork/osl"
1717
)
@@ -20,7 +20,7 @@ const ovPeerTable = "overlay_peer_table"
2020

2121
type peerEntry struct {
2222
eid string
23-
mac macAddr
23+
mac hashable.MACAddr
2424
vtep netip.Addr
2525
}
2626

@@ -49,10 +49,10 @@ func (pm *peerMap) Get(peerIP netip.Prefix) (peerEntry, bool) {
4949
return c[0], true
5050
}
5151

52-
func (pm *peerMap) Add(eid string, peerIP netip.Prefix, peerMac net.HardwareAddr, vtep netip.Addr) (bool, int) {
52+
func (pm *peerMap) Add(eid string, peerIP netip.Prefix, peerMac hashable.MACAddr, vtep netip.Addr) (bool, int) {
5353
pEntry := peerEntry{
5454
eid: eid,
55-
mac: macAddrOf(peerMac),
55+
mac: peerMac,
5656
vtep: vtep,
5757
}
5858
b, i := pm.mp.Insert(peerIP, pEntry)
@@ -64,10 +64,10 @@ func (pm *peerMap) Add(eid string, peerIP netip.Prefix, peerMac net.HardwareAddr
6464
return b, i
6565
}
6666

67-
func (pm *peerMap) Delete(eid string, peerIP netip.Prefix, peerMac net.HardwareAddr, vtep netip.Addr) (bool, int) {
67+
func (pm *peerMap) Delete(eid string, peerIP netip.Prefix, peerMac hashable.MACAddr, vtep netip.Addr) (bool, int) {
6868
pEntry := peerEntry{
6969
eid: eid,
70-
mac: macAddrOf(peerMac),
70+
mac: peerMac,
7171
vtep: vtep,
7272
}
7373

@@ -94,7 +94,7 @@ func (n *network) initSandboxPeerDB() error {
9494
var errs []error
9595
n.peerdb.Walk(func(peerIP netip.Prefix, pEntry peerEntry) {
9696
if !pEntry.isLocal() {
97-
if err := n.addNeighbor(peerIP, pEntry.mac.HardwareAddr(), pEntry.vtep); err != nil {
97+
if err := n.addNeighbor(peerIP, pEntry.mac, pEntry.vtep); err != nil {
9898
errs = append(errs, fmt.Errorf("failed to add neighbor entries for %s: %w", peerIP, err))
9999
}
100100
}
@@ -105,7 +105,7 @@ func (n *network) initSandboxPeerDB() error {
105105
// peerAdd adds a new entry to the peer database.
106106
//
107107
// Local peers are signified by an invalid vtep (i.e. netip.Addr{}).
108-
func (n *network) peerAdd(eid string, peerIP netip.Prefix, peerMac net.HardwareAddr, vtep netip.Addr) error {
108+
func (n *network) peerAdd(eid string, peerIP netip.Prefix, peerMac hashable.MACAddr, vtep netip.Addr) error {
109109
if eid == "" {
110110
return errors.New("invalid endpoint id")
111111
}
@@ -130,7 +130,7 @@ func (n *network) peerAdd(eid string, peerIP netip.Prefix, peerMac net.HardwareA
130130
}
131131

132132
// addNeighbor programs the kernel so the given peer is reachable through the VXLAN tunnel.
133-
func (n *network) addNeighbor(peerIP netip.Prefix, peerMac net.HardwareAddr, vtep netip.Addr) error {
133+
func (n *network) addNeighbor(peerIP netip.Prefix, peerMac hashable.MACAddr, vtep netip.Addr) error {
134134
if n.sbox == nil {
135135
// We are hitting this case for all the events that are arriving before that the sandbox
136136
// is being created. The peer got already added into the database and the sandbox init will
@@ -154,13 +154,13 @@ func (n *network) addNeighbor(peerIP netip.Prefix, peerMac net.HardwareAddr, vte
154154
}
155155

156156
// Add neighbor entry for the peer IP
157-
if err := n.sbox.AddNeighbor(peerIP.Addr().AsSlice(), peerMac, osl.WithLinkName(s.vxlanName)); err != nil {
157+
if err := n.sbox.AddNeighbor(peerIP.Addr().AsSlice(), peerMac.AsSlice(), osl.WithLinkName(s.vxlanName)); err != nil {
158158
return fmt.Errorf("could not add neighbor entry into the sandbox: %w", err)
159159
}
160160

161161
// Add fdb entry to the bridge for the peer mac
162-
if n.fdbCnt.Add(ipmacOf(vtep, peerMac), 1) == 1 {
163-
if err := n.sbox.AddNeighbor(vtep.AsSlice(), peerMac, osl.WithLinkName(s.vxlanName), osl.WithFamily(syscall.AF_BRIDGE)); err != nil {
162+
if n.fdbCnt.Add(hashable.IPMACFrom(vtep, peerMac), 1) == 1 {
163+
if err := n.sbox.AddNeighbor(vtep.AsSlice(), peerMac.AsSlice(), osl.WithLinkName(s.vxlanName), osl.WithFamily(syscall.AF_BRIDGE)); err != nil {
164164
return fmt.Errorf("could not add fdb entry into the sandbox: %w", err)
165165
}
166166
}
@@ -171,7 +171,7 @@ func (n *network) addNeighbor(peerIP netip.Prefix, peerMac net.HardwareAddr, vte
171171
// peerDelete removes an entry from the peer database.
172172
//
173173
// Local peers are signified by an invalid vtep (i.e. netip.Addr{}).
174-
func (n *network) peerDelete(eid string, peerIP netip.Prefix, peerMac net.HardwareAddr, vtep netip.Addr) error {
174+
func (n *network) peerDelete(eid string, peerIP netip.Prefix, peerMac hashable.MACAddr, vtep netip.Addr) error {
175175
if eid == "" {
176176
return errors.New("invalid endpoint id")
177177
}
@@ -207,7 +207,7 @@ func (n *network) peerDelete(eid string, peerIP netip.Prefix, peerMac net.Hardwa
207207
if !ok {
208208
return fmt.Errorf("peerDelete: unable to restore a configuration: no entry for %v found in the database", peerIP)
209209
}
210-
err := n.addNeighbor(peerIP, peerEntry.mac.HardwareAddr(), peerEntry.vtep)
210+
err := n.addNeighbor(peerIP, peerEntry.mac, peerEntry.vtep)
211211
if err != nil {
212212
return fmt.Errorf("peer delete operation failed: %w", err)
213213
}
@@ -217,7 +217,7 @@ func (n *network) peerDelete(eid string, peerIP netip.Prefix, peerMac net.Hardwa
217217

218218
// deleteNeighbor removes programming from the kernel for the given peer to be
219219
// reachable through the VXLAN tunnel. It is the inverse of [driver.addNeighbor].
220-
func (n *network) deleteNeighbor(peerIP netip.Prefix, peerMac net.HardwareAddr, vtep netip.Addr) error {
220+
func (n *network) deleteNeighbor(peerIP netip.Prefix, peerMac hashable.MACAddr, vtep netip.Addr) error {
221221
if n.sbox == nil {
222222
return nil
223223
}
@@ -233,14 +233,14 @@ func (n *network) deleteNeighbor(peerIP netip.Prefix, peerMac net.HardwareAddr,
233233
return fmt.Errorf("could not find the subnet %q in network %q", peerIP.String(), n.id)
234234
}
235235
// Remove fdb entry to the bridge for the peer mac
236-
if n.fdbCnt.Add(ipmacOf(vtep, peerMac), -1) == 0 {
237-
if err := n.sbox.DeleteNeighbor(vtep.AsSlice(), peerMac, osl.WithLinkName(s.vxlanName), osl.WithFamily(syscall.AF_BRIDGE)); err != nil {
236+
if n.fdbCnt.Add(hashable.IPMACFrom(vtep, peerMac), -1) == 0 {
237+
if err := n.sbox.DeleteNeighbor(vtep.AsSlice(), peerMac.AsSlice(), osl.WithLinkName(s.vxlanName), osl.WithFamily(syscall.AF_BRIDGE)); err != nil {
238238
return fmt.Errorf("could not delete fdb entry in the sandbox: %w", err)
239239
}
240240
}
241241

242242
// Delete neighbor entry for the peer IP
243-
if err := n.sbox.DeleteNeighbor(peerIP.Addr().AsSlice(), peerMac, osl.WithLinkName(s.vxlanName)); err != nil {
243+
if err := n.sbox.DeleteNeighbor(peerIP.Addr().AsSlice(), peerMac.AsSlice(), osl.WithLinkName(s.vxlanName)); err != nil {
244244
return fmt.Errorf("could not delete neighbor entry in the sandbox:%v", err)
245245
}
246246

daemon/libnetwork/drivers/overlay/types.go

Lines changed: 0 additions & 52 deletions
This file was deleted.

daemon/libnetwork/drivers/overlay/types_test.go

Lines changed: 0 additions & 29 deletions
This file was deleted.

0 commit comments

Comments
 (0)