@@ -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+
273293func 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
12861330func (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 {
0 commit comments