Skip to content

Commit c004c74

Browse files
committed
converge cnat refactoring
This patch uses the new implementation of cnat where we use cnat session for every packet (not only translated ones).
1 parent 56264ec commit c004c74

File tree

16 files changed

+501
-175
lines changed

16 files changed

+501
-175
lines changed

calico-vpp-agent/cni/cni_pod_test.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,8 @@ var _ = Describe("Pod-related functionality of CNI", func() {
6060

6161
BeforeEach(func() {
6262
log = logrus.New()
63+
nodeIP4String := net.ParseIP("6.6.6.6")
64+
nodeIP6String := net.ParseIP("2001:db8::68")
6365
testutils.StartVPP()
6466
vpp, _ = testutils.ConfigureVPP(log)
6567
// setup connectivity server (functionality target of tests)
@@ -71,6 +73,7 @@ var _ = Describe("Pod-related functionality of CNI", func() {
7173
cniServer = cni.NewCNIServer(vpp, ipamStub, log.WithFields(logrus.Fields{"component": "cni"}))
7274
cniServer.SetFelixConfig(&felixconfig.Config{})
7375
cniServer.FetchBufferConfig()
76+
vpp.CnatSetSnatAddresses(nodeIP4String, nodeIP6String)
7477
})
7578

7679
Describe("Addition of the pod", func() {

calico-vpp-agent/cni/podinterface/common.go

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@ func (i *PodInterfaceDriverData) DoPodIfNatConfiguration(podSpec *model.LocalPod
107107
stack.Push(i.vpp.RemovePodInterface, swIfIndex)
108108
}
109109

110-
err = i.vpp.CnatEnableFeatures(swIfIndex)
110+
err = i.vpp.CnatEnableFeatures(swIfIndex, true)
111111
if err != nil {
112112
return errors.Wrapf(err, "error configuring nat on pod interface")
113113
}
@@ -131,6 +131,10 @@ func (i *PodInterfaceDriverData) DoPodInterfaceConfiguration(podSpec *model.Loca
131131
}
132132
}
133133

134+
err = i.vpp.EnableCnatSNATOnInterfaceVRF(swIfIndex)
135+
if err != nil {
136+
return errors.Wrapf(err, "error configuring cnat snat on pod VRF")
137+
}
134138
if !*ifSpec.IsL3 {
135139
/* L2 */
136140
err = i.vpp.SetPromiscOn(swIfIndex)

calico-vpp-agent/connectivity/connectivity_server.go

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,21 @@ func (s *ConnectivityServer) updateAllIPConnectivity() {
137137
}
138138
}
139139

140+
func (s *ConnectivityServer) configureRemoteNodeSnat(node *common.LocalNodeSpec, isAdd bool) {
141+
if node.IPv4Address != nil {
142+
err := s.vpp.CnatAddDelSnatPrefix(common.ToMaxLenCIDR(node.IPv4Address.IP), isAdd)
143+
if err != nil {
144+
s.log.Errorf("error configuring snat prefix for current node (%v): %v", node.IPv4Address.IP, err)
145+
}
146+
}
147+
if node.IPv6Address != nil {
148+
err := s.vpp.CnatAddDelSnatPrefix(common.ToMaxLenCIDR(node.IPv6Address.IP), isAdd)
149+
if err != nil {
150+
s.log.Errorf("error configuring snat prefix for current node (%v): %v", node.IPv6Address.IP, err)
151+
}
152+
}
153+
}
154+
140155
func (s *ConnectivityServer) ServeConnectivity(t *tomb.Tomb) error {
141156
/**
142157
* There might be leftover state in VPP in case we restarted
@@ -214,6 +229,7 @@ func (s *ConnectivityServer) ServeConnectivity(t *tomb.Tomb) error {
214229
delete(s.nodeByAddr, old.IPv6Address.IP.String())
215230
}
216231
}
232+
s.configureRemoteNodeSnat(old, false /* isAdd */)
217233
}
218234
if evt.New != nil {
219235
new, ok := evt.New.(*common.LocalNodeSpec)
@@ -227,6 +243,7 @@ func (s *ConnectivityServer) ServeConnectivity(t *tomb.Tomb) error {
227243
s.nodeByAddr[new.IPv6Address.IP.String()] = *new
228244
}
229245
}
246+
s.configureRemoteNodeSnat(new, true /* isAdd */)
230247
}
231248
case common.FelixConfChanged:
232249
old, ok := evt.Old.(*felixConfig.Config)

calico-vpp-agent/connectivity/ipip.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,7 @@ func (p *IpipProvider) AddConnectivity(cn *common.NodeConnectivity) error {
127127
return errors.Wrapf(err, "Error enabling gso for ipip interface")
128128
}
129129

130-
err = p.vpp.CnatEnableFeatures(swIfIndex)
130+
err = p.vpp.CnatEnableFeatures(swIfIndex, true)
131131
if err != nil {
132132
p.errorCleanup(tunnel)
133133
return errors.Wrapf(err, "Error enabling nat for ipip interface")

calico-vpp-agent/connectivity/ipsec.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -197,7 +197,7 @@ func (p *IpsecProvider) createIPSECTunnel(tunnel *IpsecTunnel, psk string, stack
197197
return errors.Wrapf(err, "Error enabling gso for ipip interface")
198198
}
199199

200-
err = p.vpp.CnatEnableFeatures(swIfIndex)
200+
err = p.vpp.CnatEnableFeatures(swIfIndex, true)
201201
if err != nil {
202202
return errors.Wrapf(err, "Error enabling nat for ipip interface")
203203
}

calico-vpp-agent/connectivity/vxlan.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -177,7 +177,7 @@ func (p *VXLanProvider) AddConnectivity(cn *common.NodeConnectivity) error {
177177
return errors.Wrapf(err, "Error enabling gso for vxlan interface")
178178
}
179179

180-
err = p.vpp.CnatEnableFeatures(swIfIndex)
180+
err = p.vpp.CnatEnableFeatures(swIfIndex, true)
181181
if err != nil {
182182
// TODO : delete tunnel
183183
return errors.Wrapf(err, "Error enabling nat for vxlan interface")

calico-vpp-agent/connectivity/wireguard.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -217,7 +217,7 @@ func (p *WireguardProvider) createWireguardTunnels() error {
217217
return errors.Wrapf(err, "Error enabling gso for wireguard interface")
218218
}
219219

220-
err = p.vpp.CnatEnableFeatures(swIfIndex)
220+
err = p.vpp.CnatEnableFeatures(swIfIndex, true)
221221
if err != nil {
222222
p.errorCleanup(tunnel)
223223
return errors.Wrapf(err, "Error enabling nat for wireguard interface")

calico-vpp-agent/felix/felix_server.go

Lines changed: 20 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1218,21 +1218,17 @@ func (s *Server) handleWireguardEndpointRemove(msg *proto.WireguardEndpointRemov
12181218
}
12191219

12201220
func (s *Server) onNodeUpdated(old *common.LocalNodeSpec, node *common.LocalNodeSpec) (err error) {
1221-
// This is used by the routing server to process Wireguard key updates
1222-
// As a result we only send an event when a node is updated, not when it is added or deleted
1223-
common.SendEvent(common.CalicoVppEvent{
1224-
Type: common.PeerNodeStateChanged,
1225-
Old: old,
1226-
New: node,
1227-
})
12281221
change := common.GetIPNetChangeType(old.IPv4Address, node.IPv4Address) | common.GetIPNetChangeType(old.IPv6Address, node.IPv6Address)
12291222
if change&(common.ChangeDeleted|common.ChangeUpdated) != 0 && node.Name == *config.NodeName {
12301223
// restart if our BGP config changed
12311224
return NodeWatcherRestartError{}
12321225
}
12331226
if change != common.ChangeSame {
1234-
s.configureRemoteNodeSnat(old, false /* isAdd */)
1235-
s.configureRemoteNodeSnat(node, true /* isAdd */)
1227+
common.SendEvent(common.CalicoVppEvent{
1228+
Type: common.PeerNodeStateChanged,
1229+
Old: old,
1230+
New: node,
1231+
})
12361232
}
12371233

12381234
return nil
@@ -1245,12 +1241,21 @@ func (s *Server) onNodeAdded(node *common.LocalNodeSpec) (err error) {
12451241
/* We found a BGP Spec that seems valid enough */
12461242
s.GotOurNodeBGPchan <- node
12471243
}
1244+
ip4 := net.IP{}
1245+
ip6 := net.IP{}
12481246
if node.IPv4Address != nil {
12491247
s.ip4 = &node.IPv4Address.IP
1248+
ip4 = node.IPv4Address.IP
12501249
}
12511250
if node.IPv6Address != nil {
12521251
s.ip6 = &node.IPv6Address.IP
1252+
ip6 = node.IPv6Address.IP
1253+
}
1254+
err = s.vpp.CnatSetSnatAddresses(ip4, ip6)
1255+
if err != nil {
1256+
s.log.Errorf("Failed to configure SNAT addresses %v", err)
12531257
}
1258+
12541259
err = s.createAllowFromHostPolicy()
12551260
if err != nil {
12561261
return errors.Wrap(err, "Error in creating AllowFromHostPolicy")
@@ -1265,26 +1270,10 @@ func (s *Server) onNodeAdded(node *common.LocalNodeSpec) (err error) {
12651270
Type: common.PeerNodeStateChanged,
12661271
New: node,
12671272
})
1268-
s.configureRemoteNodeSnat(node, true /* isAdd */)
12691273

12701274
return nil
12711275
}
12721276

1273-
func (s *Server) configureRemoteNodeSnat(node *common.LocalNodeSpec, isAdd bool) {
1274-
if node.IPv4Address != nil {
1275-
err := s.vpp.CnatAddDelSnatPrefix(common.ToMaxLenCIDR(node.IPv4Address.IP), isAdd)
1276-
if err != nil {
1277-
s.log.Errorf("error configuring snat prefix for current node (%v): %v", node.IPv4Address.IP, err)
1278-
}
1279-
}
1280-
if node.IPv6Address != nil {
1281-
err := s.vpp.CnatAddDelSnatPrefix(common.ToMaxLenCIDR(node.IPv6Address.IP), isAdd)
1282-
if err != nil {
1283-
s.log.Errorf("error configuring snat prefix for current node (%v): %v", node.IPv6Address.IP, err)
1284-
}
1285-
}
1286-
}
1287-
12881277
func (s *Server) onNodeDeleted(old *common.LocalNodeSpec, node *common.LocalNodeSpec) error {
12891278
common.SendEvent(common.CalicoVppEvent{
12901279
Type: common.PeerNodeStateChanged,
@@ -1295,7 +1284,6 @@ func (s *Server) onNodeDeleted(old *common.LocalNodeSpec, node *common.LocalNode
12951284
return NodeWatcherRestartError{}
12961285
}
12971286

1298-
s.configureRemoteNodeSnat(old, false /* isAdd */)
12991287
return nil
13001288
}
13011289

@@ -1318,8 +1306,8 @@ func (s *Server) handleIpamPoolUpdate(msg *proto.IPAMPoolUpdate, pending bool) (
13181306
if newIpamPool.GetCidr() != oldIpamPool.GetCidr() ||
13191307
newIpamPool.GetMasquerade() != oldIpamPool.GetMasquerade() {
13201308
var err, err2 error
1321-
err = s.addDelSnatPrefix(oldIpamPool, false /* isAdd */)
1322-
err2 = s.addDelSnatPrefix(newIpamPool, true /* isAdd */)
1309+
err = s.addDelSnatPrefixForIPPool(oldIpamPool, false /* isAdd */)
1310+
err2 = s.addDelSnatPrefixForIPPool(newIpamPool, true /* isAdd */)
13231311
if err != nil || err2 != nil {
13241312
return errors.Errorf("error updating snat prefix del:%s, add:%s", err, err2)
13251313
}
@@ -1333,7 +1321,7 @@ func (s *Server) handleIpamPoolUpdate(msg *proto.IPAMPoolUpdate, pending bool) (
13331321
s.log.Infof("Adding pool: %s, nat:%t", msg.GetId(), newIpamPool.GetMasquerade())
13341322
s.ippoolmap[msg.GetId()] = newIpamPool
13351323
s.log.Debugf("Pool %v Added, handler called", msg)
1336-
err = s.addDelSnatPrefix(newIpamPool, true /* isAdd */)
1324+
err = s.addDelSnatPrefixForIPPool(newIpamPool, true /* isAdd */)
13371325
if err != nil {
13381326
return errors.Wrap(err, "error handling ipam add")
13391327
}
@@ -1359,7 +1347,7 @@ func (s *Server) handleIpamPoolRemove(msg *proto.IPAMPoolRemove, pending bool) (
13591347
delete(s.ippoolmap, msg.GetId())
13601348
s.log.Infof("Deleting pool: %s", msg.GetId())
13611349
s.log.Debugf("Pool %s deleted, handler called", oldIpamPool.Cidr)
1362-
err = s.addDelSnatPrefix(oldIpamPool, false /* isAdd */)
1350+
err = s.addDelSnatPrefixForIPPool(oldIpamPool, false /* isAdd */)
13631351
if err != nil {
13641352
return errors.Wrap(err, "error handling ipam deletion")
13651353
}
@@ -1404,12 +1392,12 @@ func ipamPoolEquals(a *proto.IPAMPool, b *proto.IPAMPool) bool {
14041392
return true
14051393
}
14061394

1407-
// addDelSnatPrefix configures IP Pool prefixes so that we don't source-NAT the packets going
1395+
// addDelSnatPrefixForIPPool configures IP Pool prefixes so that we don't source-NAT the packets going
14081396
// to these addresses. All the IP Pools prefixes are configured that way so that pod <-> pod
14091397
// communications are never source-nated in the cluster
14101398
// Note(aloaugus) - I think the iptables dataplane behaves differently and uses the k8s level
14111399
// pod CIDR for this rather than the individual pool prefixes
1412-
func (s *Server) addDelSnatPrefix(pool *proto.IPAMPool, isAdd bool) (err error) {
1400+
func (s *Server) addDelSnatPrefixForIPPool(pool *proto.IPAMPool, isAdd bool) (err error) {
14131401
_, ipNet, err := net.ParseCIDR(pool.GetCidr())
14141402
if err != nil {
14151403
return errors.Wrapf(err, "Couldn't parse pool CIDR %s", pool.Cidr)

calico-vpp-agent/services/service_server.go

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -346,10 +346,6 @@ func objectID(meta *metav1.ObjectMeta) string {
346346
}
347347

348348
func (s *Server) configureSnat() (err error) {
349-
err = s.vpp.CnatSetSnatAddresses(s.getNodeIP(false /* isv6 */), s.getNodeIP(true /* isv6 */))
350-
if err != nil {
351-
s.log.Errorf("Failed to configure SNAT addresses %v", err)
352-
}
353349
nodeIP4, nodeIP6 := common.GetBGPSpecAddresses(s.nodeBGPSpec)
354350
if nodeIP6 != nil {
355351
err = s.vpp.CnatAddSnatPrefix(common.FullyQualified(*nodeIP6))
@@ -369,6 +365,23 @@ func (s *Server) configureSnat() (err error) {
369365
s.log.Errorf("Failed to Add Service CIDR %s %v", serviceCIDR, err)
370366
}
371367
}
368+
err = s.vpp.SetK8sSnatPolicy()
369+
if err != nil {
370+
return errors.Wrap(err, "Error configuring cnat source policy")
371+
}
372+
for _, uplink := range common.VppManagerInfo.UplinkStatuses {
373+
// register vpptap0
374+
err = s.vpp.RegisterPodInterface(uplink.TapSwIfIndex)
375+
if err != nil {
376+
return errors.Wrap(err, "error configuring vpptap0 as pod intf")
377+
}
378+
379+
err = s.vpp.RegisterHostInterface(uplink.TapSwIfIndex)
380+
if err != nil {
381+
return errors.Wrap(err, "error configuring vpptap0 as host intf")
382+
}
383+
}
384+
372385
return nil
373386
}
374387

@@ -515,11 +528,6 @@ func (s *Server) ServeService(t *tomb.Tomb) error {
515528
})
516529
}
517530

518-
err = s.vpp.CnatPurge()
519-
if err != nil {
520-
return err
521-
}
522-
523531
if *config.GetCalicoVppDebug().ServicesEnabled {
524532
s.t.Go(func() error { s.serviceInformer.Run(t.Dying()); return nil })
525533
s.t.Go(func() error { s.endpointslicesInformer.Run(t.Dying()); return nil })

vpp-manager/vpp_runner.go

Lines changed: 2 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -460,7 +460,7 @@ func (v *VppRunner) configureVppUplinkInterface(
460460
return errors.Wrap(err, "Error disabling ipv6 RA on uplink interface")
461461
}
462462

463-
err = v.vpp.CnatEnableFeatures(ifSpec.SwIfIndex)
463+
err = v.vpp.CnatEnableFeatures(ifSpec.SwIfIndex, true)
464464
if err != nil {
465465
return errors.Wrap(err, "Error configuring NAT on uplink interface")
466466
}
@@ -606,21 +606,11 @@ func (v *VppRunner) configureVppUplinkInterface(
606606
log.Errorf("Error SetInterfaceRxMode on vpptap0 %v", err)
607607
}
608608

609-
err = v.vpp.CnatEnableFeatures(tapSwIfIndex)
609+
err = v.vpp.CnatEnableFeatures(tapSwIfIndex, true)
610610
if err != nil {
611611
return errors.Wrap(err, "Error configuring NAT on vpptap0")
612612
}
613613

614-
err = v.vpp.RegisterPodInterface(tapSwIfIndex)
615-
if err != nil {
616-
return errors.Wrap(err, "error configuring vpptap0 as pod intf")
617-
}
618-
619-
err = v.vpp.RegisterHostInterface(tapSwIfIndex)
620-
if err != nil {
621-
return errors.Wrap(err, "error configuring vpptap0 as host intf")
622-
}
623-
624614
// Linux side tap setup
625615
link, err := netlink.LinkByName(ifSpec.InterfaceName)
626616
if err != nil {
@@ -659,11 +649,6 @@ func (v *VppRunner) doVppGlobalConfiguration() (err error) {
659649
return errors.Wrap(err, "Error creating static VRFs in VPP")
660650
}
661651

662-
err = v.vpp.SetK8sSnatPolicy()
663-
if err != nil {
664-
return errors.Wrap(err, "Error configuring cnat source policy")
665-
}
666-
667652
err = v.vpp.ConfigureNeighborsV4(&types.NeighborConfig{
668653
MaxNumber: *config.GetCalicoVppInitialConfig().IP4NeighborsMaxNumber,
669654
MaxAge: *config.GetCalicoVppInitialConfig().IP4NeighborsMaxAge,

0 commit comments

Comments
 (0)