Skip to content

Commit 5476c7b

Browse files
kvapsclaude
andcommitted
refactor(encapsulation): rename LocalIP to CNICompatibilityIP
Rename the encapsulation interface method and all related struct fields and annotation keys from Cilium-specific names to generic CNI compatibility names, as requested in review. Changes: - LocalIP() -> CNICompatibilityIP() returning *net.IPNet - CiliumInternalIP -> CNICompatibilityIP in Node struct - ciliumInternalIPs -> cniCompatibilityIPs in segment struct - kilo.squat.ai/cilium-internal-ip -> kilo.squat.ai/cni-compatibility-ip - Add comments for ignored errors and IPv4 filter in cilium.go Co-Authored-By: Claude <noreply@anthropic.com> Signed-off-by: Andrei Kvapil <kvapss@gmail.com>
1 parent 97f10c9 commit 5476c7b

11 files changed

Lines changed: 74 additions & 61 deletions

File tree

pkg/encapsulation/cilium.go

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -58,28 +58,33 @@ func (c *cilium) CleanUp() error {
5858
// Gw returns the correct gateway IP associated with the given node.
5959
// It returns the Cilium internal IP so that the IPIP outer packets are routed
6060
// through Cilium's VxLAN overlay rather than the host network.
61-
func (c *cilium) Gw(_, _, ciliumIP net.IP, subnet *net.IPNet) net.IP {
62-
if ciliumIP != nil {
63-
return ciliumIP
61+
func (c *cilium) Gw(_, _, cniIP net.IP, subnet *net.IPNet) net.IP {
62+
if cniIP != nil {
63+
return cniIP
6464
}
6565
return subnet.IP
6666
}
6767

68-
// LocalIP returns the IP address of the cilium_host interface.
68+
// CNICompatibilityIP returns the IP address of the cilium_host interface.
6969
// This IP is advertised to other nodes so they can route IPIP outer
7070
// packets through Cilium's overlay.
71-
func (c *cilium) LocalIP() net.IP {
71+
func (c *cilium) CNICompatibilityIP() *net.IPNet {
7272
iface, err := net.InterfaceByName(ciliumHostIface)
7373
if err != nil {
74+
// cilium_host does not exist; Cilium may not be running.
7475
return nil
7576
}
7677
addrs, err := iface.Addrs()
7778
if err != nil {
79+
// Unable to list addresses; safe to skip since the
80+
// CNI compatibility IP is only used for optimization.
7881
return nil
7982
}
8083
for _, a := range addrs {
84+
// IPIP tunnels use IPv4 encapsulation, so only IPv4
85+
// addresses are usable as the outer header source/destination.
8186
if ipNet, ok := a.(*net.IPNet); ok && ipNet.IP.To4() != nil {
82-
return ipNet.IP
87+
return ipNet
8388
}
8489
}
8590
return nil

pkg/encapsulation/encapsulation.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -49,9 +49,9 @@ type Encapsulator interface {
4949
Gw(net.IP, net.IP, net.IP, *net.IPNet) net.IP
5050
Index() int
5151
Init(int) error
52-
// LocalIP returns the local overlay IP that should be advertised
53-
// to other nodes. For Cilium, this is the IP of the cilium_host interface.
54-
LocalIP() net.IP
52+
// CNICompatibilityIP returns the local overlay IP that should be
53+
// advertised to other nodes for CNI-compatible routing.
54+
CNICompatibilityIP() *net.IPNet
5555
Rules([]*net.IPNet) iptables.RuleSet
5656
Set(*net.IPNet) error
5757
Strategy() Strategy

pkg/encapsulation/flannel.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,8 +54,8 @@ func (f *flannel) Gw(_, _, _ net.IP, subnet *net.IPNet) net.IP {
5454
return subnet.IP
5555
}
5656

57-
// LocalIP is a no-op for Flannel.
58-
func (f *flannel) LocalIP() net.IP {
57+
// CNICompatibilityIP is a no-op for Flannel.
58+
func (f *flannel) CNICompatibilityIP() *net.IPNet {
5959
return nil
6060
}
6161

pkg/encapsulation/ipip.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,8 +45,8 @@ func (i *ipip) Gw(_, internal, _ net.IP, _ *net.IPNet) net.IP {
4545
return internal
4646
}
4747

48-
// LocalIP is a no-op for IPIP.
49-
func (i *ipip) LocalIP() net.IP {
48+
// CNICompatibilityIP is a no-op for IPIP.
49+
func (i *ipip) CNICompatibilityIP() *net.IPNet {
5050
return nil
5151
}
5252

pkg/encapsulation/noop.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,8 @@ func (n Noop) Gw(_, _, _ net.IP, _ *net.IPNet) net.IP {
3333
return nil
3434
}
3535

36-
// LocalIP will also do nothing.
37-
func (n Noop) LocalIP() net.IP {
36+
// CNICompatibilityIP will also do nothing.
37+
func (n Noop) CNICompatibilityIP() *net.IPNet {
3838
return nil
3939
}
4040

pkg/k8s/backend.go

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ const (
6363
discoveredEndpointsKey = "kilo.squat.ai/discovered-endpoints"
6464
allowedLocationIPsKey = "kilo.squat.ai/allowed-location-ips"
6565
granularityKey = "kilo.squat.ai/granularity"
66-
ciliumInternalIPAnnotationKey = "kilo.squat.ai/cilium-internal-ip"
66+
cniCompatibilityIPAnnotationKey = "kilo.squat.ai/cni-compatibility-ip"
6767
// RegionLabelKey is the key for the well-known Kubernetes topology region label.
6868
RegionLabelKey = "topology.kubernetes.io/region"
6969
jsonPatchSlash = "~1"
@@ -242,10 +242,10 @@ func (nb *nodeBackend) Set(ctx context.Context, name string, node *mesh.Node) er
242242
n.ObjectMeta.Annotations[discoveredEndpointsKey] = string(discoveredEndpoints)
243243
}
244244
n.ObjectMeta.Annotations[granularityKey] = string(node.Granularity)
245-
if node.CiliumInternalIP != nil {
246-
n.ObjectMeta.Annotations[ciliumInternalIPAnnotationKey] = node.CiliumInternalIP.String()
245+
if node.CNICompatibilityIP != nil {
246+
n.ObjectMeta.Annotations[cniCompatibilityIPAnnotationKey] = node.CNICompatibilityIP.String()
247247
} else {
248-
n.ObjectMeta.Annotations[ciliumInternalIPAnnotationKey] = ""
248+
n.ObjectMeta.Annotations[cniCompatibilityIPAnnotationKey] = ""
249249
}
250250
oldData, err := json.Marshal(old)
251251
if err != nil {
@@ -348,10 +348,10 @@ func translateNode(node *v1.Node, topologyLabel string) *mesh.Node {
348348
// TODO log some error or warning.
349349
key, _ := wgtypes.ParseKey(node.ObjectMeta.Annotations[keyAnnotationKey])
350350

351-
// Parse the Cilium internal IP if present.
352-
var ciliumInternalIP net.IP
353-
if cipStr, ok := node.ObjectMeta.Annotations[ciliumInternalIPAnnotationKey]; ok && cipStr != "" {
354-
ciliumInternalIP = net.ParseIP(cipStr)
351+
// Parse the CNI compatibility IP if present.
352+
var cniCompatibilityIP *net.IPNet
353+
if cipStr, ok := node.ObjectMeta.Annotations[cniCompatibilityIPAnnotationKey]; ok && cipStr != "" {
354+
cniCompatibilityIP = normalizeIP(cipStr)
355355
}
356356

357357
return &mesh.Node{
@@ -364,7 +364,7 @@ func translateNode(node *v1.Node, topologyLabel string) *mesh.Node {
364364
Endpoint: endpoint,
365365
NoInternalIP: noInternalIP,
366366
InternalIP: internalIP,
367-
CiliumInternalIP: ciliumInternalIP,
367+
CNICompatibilityIP: cniCompatibilityIP,
368368
Key: key,
369369
LastSeen: lastSeen,
370370
Leader: leader,

pkg/mesh/backend.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ type Node struct {
6161
Key wgtypes.Key
6262
NoInternalIP bool
6363
InternalIP *net.IPNet
64-
CiliumInternalIP net.IP
64+
CNICompatibilityIP *net.IPNet
6565
// LastSeen is a Unix time for the last time
6666
// the node confirmed it was live.
6767
LastSeen int64

pkg/mesh/mesh.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -412,7 +412,7 @@ func (m *Mesh) handleLocal(ctx context.Context, n *Node) {
412412
Key: m.pub,
413413
NoInternalIP: n.NoInternalIP,
414414
InternalIP: n.InternalIP,
415-
CiliumInternalIP: m.enc.LocalIP(),
415+
CNICompatibilityIP: m.enc.CNICompatibilityIP(),
416416
LastSeen: time.Now().Unix(),
417417
Leader: n.Leader,
418418
Location: n.Location,
@@ -700,7 +700,7 @@ func nodesAreEqual(a, b *Node) bool {
700700
return a.Key.String() == b.Key.String() &&
701701
ipNetsEqual(a.WireGuardIP, b.WireGuardIP) &&
702702
ipNetsEqual(a.InternalIP, b.InternalIP) &&
703-
a.CiliumInternalIP.Equal(b.CiliumInternalIP) &&
703+
ipNetsEqual(a.CNICompatibilityIP, b.CNICompatibilityIP) &&
704704
a.Leader == b.Leader &&
705705
a.Location == b.Location &&
706706
a.Name == b.Name &&

pkg/mesh/routes.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ func (t *Topology) Routes(kiloIfaceName string, kiloIface, privIface, tunlIface
4040
var gw net.IP
4141
for _, segment := range t.segments {
4242
if segment.location == t.location {
43-
gw = enc.Gw(t.updateEndpoint(segment.endpoint, segment.key, &segment.persistentKeepalive).IP(), segment.privateIPs[segment.leader], segment.ciliumInternalIPs[segment.leader], segment.cidrs[segment.leader])
43+
gw = enc.Gw(t.updateEndpoint(segment.endpoint, segment.key, &segment.persistentKeepalive).IP(), segment.privateIPs[segment.leader], ipFromIPNet(segment.cniCompatibilityIPs[segment.leader]), segment.cidrs[segment.leader])
4444
break
4545
}
4646
}
@@ -61,7 +61,7 @@ func (t *Topology) Routes(kiloIfaceName string, kiloIface, privIface, tunlIface
6161
if segment.privateIPs[i].Equal(t.privateIP.IP) {
6262
continue
6363
}
64-
nodeGw := enc.Gw(nil, segment.privateIPs[i], segment.ciliumInternalIPs[i], segment.cidrs[i])
64+
nodeGw := enc.Gw(nil, segment.privateIPs[i], ipFromIPNet(segment.cniCompatibilityIPs[i]), segment.cidrs[i])
6565
routes = append(routes, encapsulateRoute(&netlink.Route{
6666
Dst: segment.cidrs[i],
6767
Flags: int(netlink.FLAG_ONLINK),
@@ -156,7 +156,7 @@ func (t *Topology) Routes(kiloIfaceName string, kiloIface, privIface, tunlIface
156156
if segment.privateIPs[i].Equal(t.privateIP.IP) {
157157
continue
158158
}
159-
nodeGw := enc.Gw(nil, segment.privateIPs[i], segment.ciliumInternalIPs[i], segment.cidrs[i])
159+
nodeGw := enc.Gw(nil, segment.privateIPs[i], ipFromIPNet(segment.cniCompatibilityIPs[i]), segment.cidrs[i])
160160
routes = append(routes, encapsulateRoute(&netlink.Route{
161161
Dst: segment.cidrs[i],
162162
Flags: int(netlink.FLAG_ONLINK),
@@ -202,7 +202,7 @@ func (t *Topology) Routes(kiloIfaceName string, kiloIface, privIface, tunlIface
202202
if segment.privateIPs[i].Equal(t.privateIP.IP) {
203203
continue
204204
}
205-
nodeGw := enc.Gw(nil, segment.privateIPs[i], segment.ciliumInternalIPs[i], segment.cidrs[i])
205+
nodeGw := enc.Gw(nil, segment.privateIPs[i], ipFromIPNet(segment.cniCompatibilityIPs[i]), segment.cidrs[i])
206206
if nodeGw != nil && !nodeGw.Equal(segment.privateIPs[i]) {
207207
routes = append(routes, &netlink.Route{
208208
Dst: oneAddressCIDR(segment.privateIPs[i]),

pkg/mesh/topology.go

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -86,8 +86,8 @@ type segment struct {
8686
leader int
8787
// privateIPs is a slice of private IPs of all peers in the segment.
8888
privateIPs []net.IP
89-
// ciliumInternalIPs is a slice of Cilium internal IPs of all peers in the segment.
90-
ciliumInternalIPs []net.IP
89+
// cniCompatibilityIPs is a slice of CNI compatibility IPs of all peers in the segment.
90+
cniCompatibilityIPs []*net.IPNet
9191
// wireGuardIP is the allocated IP address of the WireGuard
9292
// interface on the leader of the segment.
9393
wireGuardIP net.IP
@@ -157,7 +157,7 @@ func NewTopology(nodes map[string]*Node, peers map[string]*Peer, granularity Gra
157157
var cidrs []*net.IPNet
158158
var hostnames []string
159159
var privateIPs []net.IP
160-
var ciliumInternalIPs []net.IP
160+
var cniCompatibilityIPs []*net.IPNet
161161
for _, node := range topoMap[location] {
162162
// Allowed IPs should include:
163163
// - the node's allocated subnet
@@ -177,7 +177,7 @@ func NewTopology(nodes map[string]*Node, peers map[string]*Peer, granularity Gra
177177
allowedIPs = append(allowedIPs, *oneAddressCIDR(node.InternalIP.IP))
178178
privateIPs = append(privateIPs, node.InternalIP.IP)
179179
}
180-
ciliumInternalIPs = append(ciliumInternalIPs, node.CiliumInternalIP)
180+
cniCompatibilityIPs = append(cniCompatibilityIPs, node.CNICompatibilityIP)
181181
cidrs = append(cidrs, node.Subnet)
182182
hostnames = append(hostnames, node.Name)
183183
}
@@ -195,7 +195,7 @@ func NewTopology(nodes map[string]*Node, peers map[string]*Peer, granularity Gra
195195
hostnames: hostnames,
196196
leader: leader,
197197
privateIPs: privateIPs,
198-
ciliumInternalIPs: ciliumInternalIPs,
198+
cniCompatibilityIPs: cniCompatibilityIPs,
199199
allowedLocationIPs: allowedLocationIPs,
200200
})
201201
level.Debug(t.logger).Log("msg", "generated segment", "location", location, "allowedIPs", allowedIPs, "endpoint", topoMap[location][leader].Endpoint, "cidrs", cidrs, "hostnames", hostnames, "leader", leader, "privateIPs", privateIPs, "allowedLocationIPs", allowedLocationIPs)
@@ -419,6 +419,14 @@ func oneAddressCIDR(ip net.IP) *net.IPNet {
419419
return &net.IPNet{IP: ip, Mask: net.CIDRMask(len(ip)*8, len(ip)*8)}
420420
}
421421

422+
// ipFromIPNet extracts the IP from a *net.IPNet, returning nil if the IPNet is nil.
423+
func ipFromIPNet(n *net.IPNet) net.IP {
424+
if n == nil {
425+
return nil
426+
}
427+
return n.IP
428+
}
429+
422430
// findLeader selects a leader for the nodes in a segment;
423431
// it will select the first node that says it should lead
424432
// or the first node in the segment if none have volunteered,

0 commit comments

Comments
 (0)