Skip to content

Commit 548cfea

Browse files
authored
Merge pull request ovn-kubernetes#5052 from crnithya/encapip_fix
Do not update EncapIP if it is configured
2 parents 1d1311c + 4281345 commit 548cfea

File tree

4 files changed

+60
-13
lines changed

4 files changed

+60
-13
lines changed

go-controller/pkg/config/config.go

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -228,9 +228,11 @@ type DefaultConfig struct {
228228
// EncapType value defines the encapsulation protocol to use to transmit packets between
229229
// hypervisors. By default the value is 'geneve'
230230
EncapType string `gcfg:"encap-type"`
231-
// The IP address of the encapsulation endpoint. If not specified, the IP address the
232-
// NodeName resolves to will be used
231+
// Configured IP address of the encapsulation endpoint.
233232
EncapIP string `gcfg:"encap-ip"`
233+
// Effective encap IP. It may be different from EncapIP if EncapIP meant to be
234+
// the node's primary IP which can be updated when node's primary IP changes.
235+
EffectiveEncapIP string
234236
// The UDP Port of the encapsulation endpoint. If not specified, the IP default port
235237
// of 6081 will be used
236238
EncapPort uint `gcfg:"encap-port"`

go-controller/pkg/node/default_node_network_controller.go

Lines changed: 52 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -270,32 +270,76 @@ func setOVSFlowTargets(node *kapi.Node) error {
270270
return nil
271271
}
272272

273+
// validateEncapIP returns false if there is an error or if the given IP is not known local IP address.
274+
func validateEncapIP(encapIP string) (bool, error) {
275+
links, err := netlink.LinkList()
276+
if err != nil {
277+
return false, fmt.Errorf("failed to get all the links on the node: %v", err)
278+
}
279+
for _, link := range links {
280+
addrs, err := util.GetFilteredInterfaceAddrs(link, config.IPv4Mode, config.IPv6Mode)
281+
if err != nil {
282+
return false, err
283+
}
284+
for _, addr := range addrs {
285+
if addr.IP.String() == encapIP {
286+
return true, nil
287+
}
288+
}
289+
}
290+
return false, nil
291+
}
292+
273293
func setupOVNNode(node *kapi.Node) error {
274294
var err error
275295

296+
nodePrimaryIP, err := util.GetNodePrimaryIP(node)
297+
if err != nil {
298+
return fmt.Errorf("failed to obtain local primary IP from node %q: %v", node.Name, err)
299+
}
300+
276301
encapIP := config.Default.EncapIP
277302
if encapIP == "" {
278-
encapIP, err = util.GetNodePrimaryIP(node)
279-
if err != nil {
280-
return fmt.Errorf("failed to obtain local IP from node %q: %v", node.Name, err)
281-
}
282-
config.Default.EncapIP = encapIP
303+
config.Default.EffectiveEncapIP = nodePrimaryIP
283304
} else {
284305
// OVN allows `external_ids:ovn-encap-ip` to be a list of IPs separated by comma.
306+
config.Default.EffectiveEncapIP = encapIP
285307
ovnEncapIps := strings.Split(encapIP, ",")
286308
for _, ovnEncapIp := range ovnEncapIps {
287309
if ip := net.ParseIP(strings.TrimSpace(ovnEncapIp)); ip == nil {
288310
return fmt.Errorf("invalid IP address %q in provided encap-ip setting %q", ovnEncapIp, encapIP)
289311
}
290312
}
313+
// if there are more than one encap IPs, it must be configured explicitly. otherwise:
314+
if len(ovnEncapIps) == 1 {
315+
encapIP = ovnEncapIps[0]
316+
if encapIP == nodePrimaryIP {
317+
// the current encap IP is node primary IP, unset config.Default.EncapIP to indicate it is
318+
// implicitly configured through the old external_ids:ovn-encap-ip value and needs to be updated
319+
// if node primary IP changes.
320+
config.Default.EncapIP = ""
321+
} else {
322+
// the encap IP may be incorrectly set or;
323+
// previous implicitly set with the old primary node IP through the old external_ids:ovn-encap-ip value,
324+
// that has changed when ovnkube-node is down.
325+
// validate it to see if it is still a valid local IP address.
326+
valid, err := validateEncapIP(encapIP)
327+
if err != nil {
328+
return fmt.Errorf("invalid encap IP %s: %v", encapIP, err)
329+
}
330+
if !valid {
331+
return fmt.Errorf("invalid encap IP %s: does not exist", encapIP)
332+
}
333+
}
334+
}
291335
}
292336

293337
setExternalIdsCmd := []string{
294338
"set",
295339
"Open_vSwitch",
296340
".",
297341
fmt.Sprintf("external_ids:ovn-encap-type=%s", config.Default.EncapType),
298-
fmt.Sprintf("external_ids:ovn-encap-ip=%s", encapIP),
342+
fmt.Sprintf("external_ids:ovn-encap-ip=%s", config.Default.EffectiveEncapIP),
299343
fmt.Sprintf("external_ids:ovn-remote-probe-interval=%d",
300344
config.Default.InactivityProbe),
301345
fmt.Sprintf("external_ids:ovn-openflow-probe-interval=%d",
@@ -1285,11 +1329,11 @@ func (nc *DefaultNodeNetworkController) WatchNamespaces() error {
12851329
// enough, it will return an error
12861330
func (nc *DefaultNodeNetworkController) validateVTEPInterfaceMTU() error {
12871331
// OVN allows `external_ids:ovn-encap-ip` to be a list of IPs separated by comma
1288-
ovnEncapIps := strings.Split(config.Default.EncapIP, ",")
1332+
ovnEncapIps := strings.Split(config.Default.EffectiveEncapIP, ",")
12891333
for _, ip := range ovnEncapIps {
12901334
ovnEncapIP := net.ParseIP(strings.TrimSpace(ip))
12911335
if ovnEncapIP == nil {
1292-
return fmt.Errorf("invalid IP address %q in provided encap-ip setting %q", ovnEncapIP, config.Default.EncapIP)
1336+
return fmt.Errorf("invalid IP address %q in provided encap-ip setting %q", ovnEncapIP, config.Default.EffectiveEncapIP)
12931337
}
12941338
interfaceName, mtu, err := util.GetIFNameAndMTUForAddress(ovnEncapIP)
12951339
if err != nil {

go-controller/pkg/node/default_node_network_controller_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ var _ = Describe("Node", func() {
7474
}
7575

7676
config.Default.MTU = configDefaultMTU
77-
config.Default.EncapIP = "10.1.0.40"
77+
config.Default.EffectiveEncapIP = "10.1.0.40"
7878

7979
})
8080

@@ -219,7 +219,7 @@ var _ = Describe("Node", func() {
219219
BeforeEach(func() {
220220
config.IPv4Mode = true
221221
config.IPv6Mode = false
222-
config.Default.EncapIP = "10.1.0.40,10.2.0.50"
222+
config.Default.EffectiveEncapIP = "10.1.0.40,10.2.0.50"
223223
netlinkOpsMock.On("LinkByIndex", 5).Return(netlinkLinkMock, nil)
224224
})
225225

go-controller/pkg/node/node_ip_handler_linux.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -255,7 +255,7 @@ func (c *addressManager) handleNodePrimaryAddrChange() {
255255
klog.Errorf("Address Manager failed to check node primary address change: %v", err)
256256
return
257257
}
258-
if nodePrimaryAddrChanged {
258+
if nodePrimaryAddrChanged && config.Default.EncapIP == "" {
259259
klog.Infof("Node primary address changed to %v. Updating OVN encap IP.", c.nodePrimaryAddr)
260260
updateOVNEncapIPAndReconnect(c.nodePrimaryAddr)
261261
}
@@ -519,6 +519,7 @@ func updateOVNEncapIPAndReconnect(newIP net.IP) {
519519
}
520520
}
521521

522+
config.Default.EffectiveEncapIP = newIP.String()
522523
confCmd := []string{
523524
"set",
524525
"Open_vSwitch",

0 commit comments

Comments
 (0)