github.com/elfadel/cilium@v1.6.12/pkg/datapath/linux/node.go (about)

     1  // Copyright 2018-2019 Authors of Cilium
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  package linux
    16  
    17  import (
    18  	"fmt"
    19  	"net"
    20  	"os"
    21  	"syscall"
    22  
    23  	"github.com/cilium/cilium/pkg/cidr"
    24  	"github.com/cilium/cilium/pkg/datapath"
    25  	"github.com/cilium/cilium/pkg/datapath/linux/ipsec"
    26  	"github.com/cilium/cilium/pkg/datapath/linux/linux_defaults"
    27  	"github.com/cilium/cilium/pkg/datapath/linux/route"
    28  	"github.com/cilium/cilium/pkg/lock"
    29  	"github.com/cilium/cilium/pkg/logging/logfields"
    30  	"github.com/cilium/cilium/pkg/maps/tunnel"
    31  	"github.com/cilium/cilium/pkg/node"
    32  	"github.com/cilium/cilium/pkg/option"
    33  
    34  	"github.com/cilium/arping"
    35  	"github.com/sirupsen/logrus"
    36  	"github.com/vishvananda/netlink"
    37  )
    38  
    39  var (
    40  	wildcardIPv4 = "0.0.0.0"
    41  	wildcardIPv6 = "0::0"
    42  )
    43  
    44  type linuxNodeHandler struct {
    45  	mutex                lock.Mutex
    46  	isInitialized        bool
    47  	nodeConfig           datapath.LocalNodeConfiguration
    48  	nodeAddressing       datapath.NodeAddressing
    49  	datapathConfig       DatapathConfiguration
    50  	nodes                map[node.Identity]*node.Node
    51  	enableNeighDiscovery bool
    52  	neighByNode          map[node.Identity]*netlink.Neigh
    53  }
    54  
    55  // NewNodeHandler returns a new node handler to handle node events and
    56  // implement the implications in the Linux datapath
    57  func NewNodeHandler(datapathConfig DatapathConfiguration, nodeAddressing datapath.NodeAddressing) datapath.NodeHandler {
    58  	return &linuxNodeHandler{
    59  		nodeAddressing: nodeAddressing,
    60  		datapathConfig: datapathConfig,
    61  		nodes:          map[node.Identity]*node.Node{},
    62  		neighByNode:    map[node.Identity]*netlink.Neigh{},
    63  	}
    64  }
    65  
    66  // updateTunnelMapping is called when a node update is received while running
    67  // with encapsulation mode enabled. The CIDR and IP of both the old and new
    68  // node are provided as context. The caller expects the tunnel mapping in the
    69  // datapath to be updated.
    70  func updateTunnelMapping(oldCIDR, newCIDR *cidr.CIDR, oldIP, newIP net.IP, firstAddition, encapEnabled bool, oldEncryptKey, newEncryptKey uint8) {
    71  	if !encapEnabled {
    72  		// When the protocol family is disabled, the initial node addition will
    73  		// trigger a deletion to clean up leftover entries. The deletion happens
    74  		// in quiet mode as we don't know whether it exists or not
    75  		if newCIDR != nil && firstAddition {
    76  			deleteTunnelMapping(newCIDR, true)
    77  		}
    78  
    79  		return
    80  	}
    81  
    82  	if cidrNodeMappingUpdateRequired(oldCIDR, newCIDR, oldIP, newIP, oldEncryptKey, newEncryptKey) {
    83  		log.WithFields(logrus.Fields{
    84  			logfields.IPAddr: newIP,
    85  			"allocCIDR":      newCIDR,
    86  		}).Debug("Updating tunnel map entry")
    87  
    88  		if err := tunnel.TunnelMap.SetTunnelEndpoint(newEncryptKey, newCIDR.IP, newIP); err != nil {
    89  			log.WithError(err).WithFields(logrus.Fields{
    90  				"allocCIDR": newCIDR,
    91  			}).Error("bpf: Unable to update in tunnel endpoint map")
    92  		}
    93  	}
    94  
    95  	// Determine whether an old tunnel mapping must be cleaned up. The
    96  	// below switch lists all conditions in which case the oldCIDR must be
    97  	// removed from the tunnel mapping
    98  	switch {
    99  	// CIDR no longer announced
   100  	case newCIDR == nil && oldCIDR != nil:
   101  		fallthrough
   102  	// Node allocation CIDR has changed
   103  	case oldCIDR != nil && newCIDR != nil && !oldCIDR.IP.Equal(newCIDR.IP):
   104  		deleteTunnelMapping(oldCIDR, false)
   105  	}
   106  }
   107  
   108  // cidrNodeMappingUpdateRequired returns true if the change from an old node
   109  // CIDR and node IP to a new node CIDR and node IP requires to insert/update
   110  // the new node CIDR.
   111  func cidrNodeMappingUpdateRequired(oldCIDR, newCIDR *cidr.CIDR, oldIP, newIP net.IP, oldKey, newKey uint8) bool {
   112  	// No CIDR provided
   113  	if newCIDR == nil {
   114  		return false
   115  	}
   116  	// Newly announced CIDR
   117  	if oldCIDR == nil {
   118  		return true
   119  	}
   120  
   121  	// Change in node IP
   122  	if !oldIP.Equal(newIP) {
   123  		return true
   124  	}
   125  
   126  	if newKey != oldKey {
   127  		return true
   128  	}
   129  
   130  	// CIDR changed
   131  	return !oldCIDR.IP.Equal(newCIDR.IP)
   132  }
   133  
   134  func deleteTunnelMapping(oldCIDR *cidr.CIDR, quietMode bool) {
   135  	if oldCIDR == nil {
   136  		return
   137  	}
   138  
   139  	log.WithField("allocCIDR", oldCIDR).Debug("Deleting tunnel map entry")
   140  
   141  	if err := tunnel.TunnelMap.DeleteTunnelEndpoint(oldCIDR.IP); err != nil {
   142  		if !quietMode {
   143  			log.WithError(err).WithFields(logrus.Fields{
   144  				"allocCIDR": oldCIDR,
   145  			}).Error("Unable to delete in tunnel endpoint map")
   146  		}
   147  	}
   148  }
   149  
   150  func createDirectRouteSpec(CIDR *cidr.CIDR, nodeIP net.IP) (routeSpec *netlink.Route, err error) {
   151  	var routes []netlink.Route
   152  
   153  	routeSpec = &netlink.Route{
   154  		Dst: CIDR.IPNet,
   155  		Gw:  nodeIP,
   156  	}
   157  
   158  	routes, err = netlink.RouteGet(nodeIP)
   159  	if err != nil {
   160  		err = fmt.Errorf("unable to lookup route for node %s: %s", nodeIP, err)
   161  		return
   162  	}
   163  
   164  	if len(routes) == 0 {
   165  		err = fmt.Errorf("no route found to destination %s", nodeIP.String())
   166  		return
   167  	}
   168  
   169  	if routes[0].Gw != nil && !routes[0].Gw.IsUnspecified() && !routes[0].Gw.Equal(nodeIP) {
   170  		err = fmt.Errorf("route to destination %s contains gateway %s, must be directly reachable",
   171  			nodeIP, routes[0].Gw.String())
   172  		return
   173  	}
   174  
   175  	linkIndex := routes[0].LinkIndex
   176  
   177  	// Special treatment if the route points to the loopback, lookup the
   178  	// local route and use that ifindex
   179  	if linkIndex == 1 {
   180  		family := netlink.FAMILY_V4
   181  		dst := &net.IPNet{IP: nodeIP, Mask: net.CIDRMask(32, 32)}
   182  		if nodeIP.To4() == nil {
   183  			family = netlink.FAMILY_V6
   184  			dst.Mask = net.CIDRMask(128, 128)
   185  		}
   186  
   187  		filter := &netlink.Route{
   188  			Table: 255, // local table
   189  			Dst:   dst,
   190  		}
   191  
   192  		routes, err = netlink.RouteListFiltered(family, filter, netlink.RT_FILTER_DST|netlink.RT_FILTER_TABLE)
   193  		if err != nil {
   194  			err = fmt.Errorf("unable to find local route for destination %s: %s", nodeIP, err)
   195  			return
   196  		}
   197  
   198  		if len(routes) == 0 {
   199  			err = fmt.Errorf("unable to find local route for destination %s which is routed over loopback", nodeIP)
   200  			return
   201  		}
   202  
   203  		linkIndex = routes[0].LinkIndex
   204  	}
   205  
   206  	routeSpec.LinkIndex = linkIndex
   207  
   208  	return
   209  }
   210  
   211  func installDirectRoute(CIDR *cidr.CIDR, nodeIP net.IP) (routeSpec *netlink.Route, err error) {
   212  	routeSpec, err = createDirectRouteSpec(CIDR, nodeIP)
   213  	if err != nil {
   214  		return
   215  	}
   216  
   217  	err = netlink.RouteReplace(routeSpec)
   218  	return
   219  }
   220  
   221  func (n *linuxNodeHandler) lookupDirectRoute(CIDR *cidr.CIDR, nodeIP net.IP) ([]netlink.Route, error) {
   222  	routeSpec, err := createDirectRouteSpec(CIDR, nodeIP)
   223  	if err != nil {
   224  		return nil, err
   225  	}
   226  
   227  	family := netlink.FAMILY_V4
   228  	if nodeIP.To4() == nil {
   229  		family = netlink.FAMILY_V6
   230  	}
   231  	return netlink.RouteListFiltered(family, routeSpec, netlink.RT_FILTER_DST|netlink.RT_FILTER_GW|netlink.RT_FILTER_OIF)
   232  }
   233  
   234  func (n *linuxNodeHandler) updateDirectRoute(oldCIDR, newCIDR *cidr.CIDR, oldIP, newIP net.IP, firstAddition, directRouteEnabled bool) error {
   235  	if !directRouteEnabled {
   236  		// When the protocol family is disabled, the initial node addition will
   237  		// trigger a deletion to clean up leftover entries. The deletion happens
   238  		// in quiet mode as we don't know whether it exists or not
   239  		if newCIDR != nil && firstAddition {
   240  			n.deleteDirectRoute(newCIDR, newIP)
   241  		}
   242  		return nil
   243  	}
   244  
   245  	if cidrNodeMappingUpdateRequired(oldCIDR, newCIDR, oldIP, newIP, 0, 0) {
   246  		log.WithFields(logrus.Fields{
   247  			logfields.IPAddr: newIP,
   248  			"allocCIDR":      newCIDR,
   249  		}).Debug("Updating direct route")
   250  
   251  		if routeSpec, err := installDirectRoute(newCIDR, newIP); err != nil {
   252  			log.WithError(err).Warningf("Unable to install direct node route %s", routeSpec.String())
   253  			return err
   254  		}
   255  	}
   256  
   257  	// Determine whether an old route must be deleted. The below switch
   258  	// lists all conditions in which case the route derived from oldCIDR
   259  	// and oldIP must be deleted.
   260  	switch {
   261  	// CIDR no longer announced
   262  	case newCIDR == nil && oldCIDR != nil:
   263  		fallthrough
   264  	// node IP has changed
   265  	case !oldIP.Equal(newIP):
   266  		fallthrough
   267  	// Node allocation CIDR has changed
   268  	case oldCIDR != nil && newCIDR != nil && !oldCIDR.IP.Equal(newCIDR.IP):
   269  		n.deleteDirectRoute(oldCIDR, oldIP)
   270  	}
   271  
   272  	return nil
   273  }
   274  
   275  func (n *linuxNodeHandler) deleteDirectRoute(CIDR *cidr.CIDR, nodeIP net.IP) {
   276  	if CIDR == nil {
   277  		return
   278  	}
   279  
   280  	family := netlink.FAMILY_V4
   281  	if CIDR.IP.To4() == nil {
   282  		family = netlink.FAMILY_V6
   283  	}
   284  
   285  	filter := &netlink.Route{
   286  		Dst: CIDR.IPNet,
   287  		Gw:  nodeIP,
   288  	}
   289  
   290  	routes, err := netlink.RouteListFiltered(family, filter, netlink.RT_FILTER_DST|netlink.RT_FILTER_GW)
   291  	if err != nil {
   292  		log.WithError(err).Error("Unable to list direct routes")
   293  		return
   294  	}
   295  
   296  	for _, rt := range routes {
   297  		if err := netlink.RouteDel(&rt); err != nil {
   298  			log.WithError(err).Warningf("Unable to delete direct node route %s", rt.String())
   299  		}
   300  	}
   301  }
   302  
   303  // createNodeRoute creates a route that points the specified prefix to the host
   304  // device via the router IP
   305  //
   306  // Example:
   307  // 10.10.0.0/24 via 10.10.0.1 dev cilium_host src 10.10.0.1
   308  // f00d::a0a:0:0:0/112 via f00d::a0a:0:0:1 dev cilium_host src fd04::11 metric 1024 pref medium
   309  //
   310  func (n *linuxNodeHandler) createNodeRoute(prefix *cidr.CIDR) (route.Route, error) {
   311  	var local, nexthop net.IP
   312  	if prefix.IP.To4() != nil {
   313  		if n.nodeAddressing.IPv4() == nil {
   314  			return route.Route{}, fmt.Errorf("IPv4 addressing unavailable")
   315  		}
   316  
   317  		if n.nodeAddressing.IPv4().Router() == nil {
   318  			return route.Route{}, fmt.Errorf("IPv4 router address unavailable")
   319  		}
   320  
   321  		nexthop = n.nodeAddressing.IPv4().Router()
   322  		local = nexthop
   323  	} else {
   324  		if n.nodeAddressing.IPv6() == nil {
   325  			return route.Route{}, fmt.Errorf("IPv6 addressing unavailable")
   326  		}
   327  
   328  		if n.nodeAddressing.IPv6().Router() == nil {
   329  			return route.Route{}, fmt.Errorf("IPv6 router address unavailable")
   330  		}
   331  
   332  		if n.nodeAddressing.IPv6().PrimaryExternal() == nil {
   333  			return route.Route{}, fmt.Errorf("External IPv6 address unavailable")
   334  		}
   335  
   336  		nexthop = n.nodeAddressing.IPv6().Router()
   337  		local = n.nodeAddressing.IPv6().PrimaryExternal()
   338  	}
   339  
   340  	// The default routing table accounts for encryption overhead for encrypt-node traffic
   341  	return route.Route{
   342  		Nexthop: &nexthop,
   343  		Local:   local,
   344  		Device:  n.datapathConfig.HostDevice,
   345  		Prefix:  *prefix.IPNet,
   346  		MTU:     n.nodeConfig.MtuConfig.GetRouteMTU(),
   347  	}, nil
   348  }
   349  
   350  func (n *linuxNodeHandler) lookupNodeRoute(prefix *cidr.CIDR) (*route.Route, error) {
   351  	if prefix == nil {
   352  		return nil, nil
   353  	}
   354  
   355  	routeSpec, err := n.createNodeRoute(prefix)
   356  	if err != nil {
   357  		return nil, err
   358  	}
   359  
   360  	return route.Lookup(routeSpec)
   361  }
   362  
   363  func (n *linuxNodeHandler) updateNodeRoute(prefix *cidr.CIDR, addressFamilyEnabled bool) error {
   364  	if prefix == nil || !addressFamilyEnabled {
   365  		return nil
   366  	}
   367  
   368  	nodeRoute, err := n.createNodeRoute(prefix)
   369  	if err != nil {
   370  		return err
   371  	}
   372  	if _, err := route.Upsert(nodeRoute); err != nil {
   373  		log.WithError(err).WithFields(nodeRoute.LogFields()).Warning("Unable to update route")
   374  		return err
   375  	}
   376  
   377  	return nil
   378  }
   379  
   380  func (n *linuxNodeHandler) deleteNodeRoute(prefix *cidr.CIDR) error {
   381  	if prefix == nil {
   382  		return nil
   383  	}
   384  
   385  	nodeRoute, err := n.createNodeRoute(prefix)
   386  	if err != nil {
   387  		return err
   388  	}
   389  	if err := route.Delete(nodeRoute); err != nil {
   390  		log.WithError(err).WithFields(nodeRoute.LogFields()).Warning("Unable to delete route")
   391  		return err
   392  	}
   393  
   394  	return nil
   395  }
   396  
   397  func (n *linuxNodeHandler) familyEnabled(c *cidr.CIDR) bool {
   398  	return (c.IP.To4() != nil && n.nodeConfig.EnableIPv4) || (c.IP.To4() == nil && n.nodeConfig.EnableIPv6)
   399  }
   400  
   401  func (n *linuxNodeHandler) updateOrRemoveNodeRoutes(old, new []*cidr.CIDR) {
   402  	addedAuxRoutes, removedAuxRoutes := cidr.DiffCIDRLists(old, new)
   403  	for _, prefix := range addedAuxRoutes {
   404  		if prefix != nil {
   405  			n.updateNodeRoute(prefix, n.familyEnabled(prefix))
   406  		}
   407  	}
   408  	for _, prefix := range removedAuxRoutes {
   409  		if rt, _ := n.lookupNodeRoute(prefix); rt != nil {
   410  			n.deleteNodeRoute(prefix)
   411  		}
   412  	}
   413  }
   414  
   415  func (n *linuxNodeHandler) NodeAdd(newNode node.Node) error {
   416  	n.mutex.Lock()
   417  	defer n.mutex.Unlock()
   418  
   419  	n.nodes[newNode.Identity()] = &newNode
   420  
   421  	if n.isInitialized {
   422  		return n.nodeUpdate(nil, &newNode, true)
   423  	}
   424  
   425  	return nil
   426  }
   427  
   428  func (n *linuxNodeHandler) NodeUpdate(oldNode, newNode node.Node) error {
   429  	n.mutex.Lock()
   430  	defer n.mutex.Unlock()
   431  
   432  	n.nodes[newNode.Identity()] = &newNode
   433  
   434  	if n.isInitialized {
   435  		return n.nodeUpdate(&oldNode, &newNode, false)
   436  	}
   437  
   438  	return nil
   439  }
   440  
   441  func upsertIPsecLog(err error, spec string, loc, rem *net.IPNet, spi uint8) {
   442  	scopedLog := log.WithFields(logrus.Fields{
   443  		logfields.Reason: spec,
   444  		"local-ip":       loc,
   445  		"remote-ip":      rem,
   446  		"spi":            spi,
   447  	})
   448  	if err != nil {
   449  		scopedLog.WithError(err).Error("IPsec enable failed")
   450  	} else {
   451  		scopedLog.Debug("IPsec enable succeeded")
   452  	}
   453  }
   454  
   455  func (n *linuxNodeHandler) enableSubnetIPsec(v4CIDR, v6CIDR []*net.IPNet) {
   456  	var spi uint8
   457  	var err error
   458  
   459  	n.replaceHostRules()
   460  
   461  	for _, cidr := range v4CIDR {
   462  		ipsecIPv4Wildcard := &net.IPNet{IP: net.ParseIP(wildcardIPv4), Mask: net.IPv4Mask(0, 0, 0, 0)}
   463  
   464  		n.replaceNodeIPSecInRoute(cidr)
   465  
   466  		n.replaceNodeIPSecOutRoute(cidr)
   467  		spi, err = ipsec.UpsertIPsecEndpoint(ipsecIPv4Wildcard, cidr, ipsec.IPSecDirOut, true)
   468  		upsertIPsecLog(err, "CNI Out IPv4", ipsecIPv4Wildcard, cidr, spi)
   469  
   470  		n.replaceNodeExternalIPSecOutRoute(cidr)
   471  	}
   472  
   473  	for _, cidr := range v6CIDR {
   474  		ipsecIPv6Wildcard := &net.IPNet{IP: net.ParseIP(wildcardIPv6), Mask: net.CIDRMask(0, 0)}
   475  
   476  		n.replaceNodeIPSecInRoute(cidr)
   477  
   478  		n.replaceNodeIPSecOutRoute(cidr)
   479  		spi, err := ipsec.UpsertIPsecEndpoint(ipsecIPv6Wildcard, cidr, ipsec.IPSecDirOut, true)
   480  		upsertIPsecLog(err, "CNI Out IPv6", cidr, ipsecIPv6Wildcard, spi)
   481  
   482  		n.replaceNodeExternalIPSecOutRoute(cidr)
   483  	}
   484  }
   485  
   486  func (n *linuxNodeHandler) encryptNode(newNode *node.Node) {
   487  	var spi uint8
   488  	var err error
   489  
   490  	if n.nodeConfig.EnableIPv4 && n.nodeConfig.EncryptNode {
   491  		internalIPv4 := n.nodeAddressing.IPv4().PrimaryExternal()
   492  		exactMask := net.IPv4Mask(255, 255, 255, 255)
   493  		ipsecLocal := &net.IPNet{IP: internalIPv4, Mask: exactMask}
   494  		if newNode.IsLocal() {
   495  			ipsecIPv4Wildcard := &net.IPNet{IP: net.ParseIP(wildcardIPv4), Mask: net.IPv4Mask(0, 0, 0, 0)}
   496  			n.replaceNodeIPSecInRoute(ipsecLocal)
   497  			spi, err = ipsec.UpsertIPsecEndpoint(ipsecLocal, ipsecIPv4Wildcard, ipsec.IPSecDirIn, true)
   498  			upsertIPsecLog(err, "EncryptNode local IPv4", ipsecLocal, ipsecIPv4Wildcard, spi)
   499  		} else {
   500  			if remoteIPv4 := newNode.GetNodeIP(false); remoteIPv4 != nil {
   501  				ipsecRemote := &net.IPNet{IP: remoteIPv4, Mask: exactMask}
   502  				n.replaceNodeExternalIPSecOutRoute(ipsecRemote)
   503  				spi, err = ipsec.UpsertIPsecEndpoint(ipsecLocal, ipsecRemote, ipsec.IPSecDirOutNode, true)
   504  				upsertIPsecLog(err, "EncryptNode IPv4", ipsecLocal, ipsecRemote, spi)
   505  			}
   506  			remoteIPv4 := newNode.GetCiliumInternalIP(false)
   507  			if remoteIPv4 != nil && !n.subnetEncryption() {
   508  				mask := newNode.IPv4AllocCIDR.Mask
   509  				ipsecRemoteRoute := &net.IPNet{IP: remoteIPv4.Mask(mask), Mask: mask}
   510  				ipsecRemote := &net.IPNet{IP: remoteIPv4, Mask: mask}
   511  				ipsecWildcard := &net.IPNet{IP: net.ParseIP(wildcardIPv4), Mask: net.IPv4Mask(0, 0, 0, 0)}
   512  
   513  				n.replaceNodeExternalIPSecOutRoute(ipsecRemoteRoute)
   514  				if remoteIPv4T := newNode.GetNodeIP(false); remoteIPv4T != nil {
   515  					ipsecRemoteT := &net.IPNet{IP: remoteIPv4T, Mask: exactMask}
   516  					err = ipsec.UpsertIPsecEndpointPolicy(ipsecWildcard, ipsecRemote, ipsecLocal, ipsecRemoteT, ipsec.IPSecDirOutNode)
   517  				}
   518  				upsertIPsecLog(err, "EncryptNode Cilium IPv4", ipsecWildcard, ipsecRemote, spi)
   519  			}
   520  		}
   521  	}
   522  
   523  	if n.nodeConfig.EnableIPv6 && n.nodeConfig.EncryptNode {
   524  		internalIPv6 := n.nodeAddressing.IPv6().PrimaryExternal()
   525  		exactMask := net.CIDRMask(128, 128)
   526  		ipsecLocal := &net.IPNet{IP: internalIPv6, Mask: exactMask}
   527  		if newNode.IsLocal() {
   528  			ipsecIPv6Wildcard := &net.IPNet{IP: net.ParseIP(wildcardIPv6), Mask: net.CIDRMask(0, 0)}
   529  			n.replaceNodeIPSecInRoute(ipsecLocal)
   530  			spi, err = ipsec.UpsertIPsecEndpoint(ipsecLocal, ipsecIPv6Wildcard, ipsec.IPSecDirIn, true)
   531  			upsertIPsecLog(err, "EncryptNode local IPv6", ipsecLocal, ipsecIPv6Wildcard, spi)
   532  		} else {
   533  			if remoteIPv6 := newNode.GetNodeIP(true); remoteIPv6 != nil {
   534  				ipsecRemote := &net.IPNet{IP: remoteIPv6, Mask: exactMask}
   535  				n.replaceNodeExternalIPSecOutRoute(ipsecRemote)
   536  				spi, err = ipsec.UpsertIPsecEndpoint(ipsecLocal, ipsecRemote, ipsec.IPSecDirOut, true)
   537  				upsertIPsecLog(err, "EncryptNode IPv6", ipsecLocal, ipsecRemote, spi)
   538  			}
   539  			remoteIPv6 := newNode.GetCiliumInternalIP(true)
   540  			if remoteIPv6 != nil && !n.subnetEncryption() {
   541  				mask := newNode.IPv6AllocCIDR.Mask
   542  				ipsecRemoteRoute := &net.IPNet{IP: remoteIPv6.Mask(mask), Mask: mask}
   543  				ipsecRemote := &net.IPNet{IP: remoteIPv6, Mask: mask}
   544  				ipsecWildcard := &net.IPNet{IP: net.ParseIP(wildcardIPv6), Mask: net.CIDRMask(0, 0)}
   545  
   546  				n.replaceNodeExternalIPSecOutRoute(ipsecRemoteRoute)
   547  				if remoteIPv6T := newNode.GetNodeIP(true); remoteIPv6T != nil {
   548  					ipsecRemoteT := &net.IPNet{IP: remoteIPv6T, Mask: exactMask}
   549  					err = ipsec.UpsertIPsecEndpointPolicy(ipsecWildcard, ipsecRemote, ipsecLocal, ipsecRemoteT, ipsec.IPSecDirOutNode)
   550  				}
   551  				upsertIPsecLog(err, "EncryptNode Cilium IPv6", ipsecWildcard, ipsecRemote, spi)
   552  			}
   553  		}
   554  	}
   555  
   556  }
   557  
   558  func neighborLog(spec, iface string, err error, ip *net.IP, hwAddr *net.HardwareAddr, link int) {
   559  	scopedLog := log.WithFields(logrus.Fields{
   560  		logfields.Reason: spec,
   561  		"Interface":      iface,
   562  		logfields.IPAddr: ip,
   563  		"HardwareAddr":   hwAddr,
   564  		"LinkIndex":      link,
   565  	})
   566  
   567  	if err != nil {
   568  		scopedLog.WithError(err).Error("insertNeighbor failed")
   569  	} else {
   570  		scopedLog.Debug("insertNeighbor")
   571  	}
   572  }
   573  
   574  func (n *linuxNodeHandler) insertNeighbor(newNode *node.Node, ifaceName string) {
   575  	if newNode.IsLocal() {
   576  		return
   577  	}
   578  
   579  	ciliumIPv4 := newNode.GetNodeIP(false)
   580  	var hwAddr net.HardwareAddr
   581  	link := 0
   582  
   583  	iface, err := net.InterfaceByName(ifaceName)
   584  	if err != nil {
   585  		neighborLog("insertNeightbor InterfaceByName", ifaceName, err, &ciliumIPv4, &hwAddr, link)
   586  		return
   587  	}
   588  
   589  	_, err = arping.FindIPInNetworkFromIface(ciliumIPv4, *iface)
   590  	if err != nil {
   591  		neighborLog("insertNeightbor IP not L2 reachable", ifaceName, nil, &ciliumIPv4, &hwAddr, link)
   592  		return
   593  	}
   594  
   595  	linkAttr, err := netlink.LinkByName(ifaceName)
   596  	if err != nil {
   597  		neighborLog("insertNeightbor LinkByName", ifaceName, err, &ciliumIPv4, &hwAddr, link)
   598  		return
   599  	}
   600  	link = linkAttr.Attrs().Index
   601  
   602  	if hwAddr, _, err := arping.PingOverIface(ciliumIPv4, *iface); err == nil {
   603  		neigh := netlink.Neigh{
   604  			LinkIndex:    link,
   605  			IP:           ciliumIPv4,
   606  			HardwareAddr: hwAddr,
   607  			State:        netlink.NUD_PERMANENT,
   608  		}
   609  		err := netlink.NeighSet(&neigh)
   610  		neighborLog("insertNeighbor NeighSet", ifaceName, err, &ciliumIPv4, &hwAddr, link)
   611  		if err == nil {
   612  			n.neighByNode[newNode.Identity()] = &neigh
   613  		}
   614  	} else {
   615  		neighborLog("insertNeighbor arping failed", ifaceName, err, &ciliumIPv4, &hwAddr, link)
   616  	}
   617  }
   618  
   619  func (n *linuxNodeHandler) deleteNeighbor(oldNode *node.Node) {
   620  	neigh, ok := n.neighByNode[oldNode.Identity()]
   621  	if !ok {
   622  		return
   623  	}
   624  
   625  	if err := netlink.NeighDel(neigh); err != nil {
   626  		log.WithFields(logrus.Fields{
   627  			logfields.IPAddr: neigh.IP,
   628  			"HardwareAddr":   neigh.HardwareAddr,
   629  			"LinkIndex":      neigh.LinkIndex,
   630  		}).WithError(err).Warn("Failed to remove neighbor entry")
   631  	}
   632  }
   633  
   634  func (n *linuxNodeHandler) enableIPsec(newNode *node.Node) {
   635  	var spi uint8
   636  	var err error
   637  
   638  	if newNode.IsLocal() {
   639  		n.replaceHostRules()
   640  	}
   641  
   642  	if n.nodeConfig.EnableIPv4 && newNode.IPv4AllocCIDR != nil {
   643  		new4Net := &net.IPNet{IP: newNode.IPv4AllocCIDR.IP, Mask: newNode.IPv4AllocCIDR.Mask}
   644  		if newNode.IsLocal() {
   645  			n.replaceNodeIPSecInRoute(new4Net)
   646  			ciliumInternalIPv4 := newNode.GetCiliumInternalIP(false)
   647  			if ciliumInternalIPv4 != nil {
   648  				ipsecLocal := &net.IPNet{IP: ciliumInternalIPv4, Mask: n.nodeAddressing.IPv4().AllocationCIDR().Mask}
   649  				ipsecIPv4Wildcard := &net.IPNet{IP: net.ParseIP(wildcardIPv4), Mask: net.IPv4Mask(0, 0, 0, 0)}
   650  				spi, err = ipsec.UpsertIPsecEndpoint(ipsecLocal, ipsecIPv4Wildcard, ipsec.IPSecDirIn, n.nodeConfig.EncryptNode)
   651  				upsertIPsecLog(err, "local IPv4", ipsecLocal, ipsecIPv4Wildcard, spi)
   652  			}
   653  		} else {
   654  			if ciliumInternalIPv4 := newNode.GetCiliumInternalIP(false); ciliumInternalIPv4 != nil {
   655  				ipsecLocal := &net.IPNet{IP: n.nodeAddressing.IPv4().Router(), Mask: n.nodeAddressing.IPv4().AllocationCIDR().Mask}
   656  				ipsecRemote := &net.IPNet{IP: ciliumInternalIPv4, Mask: newNode.IPv4AllocCIDR.Mask}
   657  				n.replaceNodeIPSecOutRoute(new4Net)
   658  				spi, err = ipsec.UpsertIPsecEndpoint(ipsecLocal, ipsecRemote, ipsec.IPSecDirOut, n.nodeConfig.EncryptNode)
   659  				upsertIPsecLog(err, "IPv4", ipsecLocal, ipsecRemote, spi)
   660  			}
   661  		}
   662  	}
   663  
   664  	if n.nodeConfig.EnableIPv6 && newNode.IPv6AllocCIDR != nil {
   665  		new6Net := &net.IPNet{IP: newNode.IPv6AllocCIDR.IP, Mask: newNode.IPv6AllocCIDR.Mask}
   666  		if newNode.IsLocal() {
   667  			n.replaceNodeIPSecInRoute(new6Net)
   668  			ciliumInternalIPv6 := newNode.GetCiliumInternalIP(true)
   669  			if ciliumInternalIPv6 != nil {
   670  				ipsecLocal := &net.IPNet{IP: ciliumInternalIPv6, Mask: n.nodeAddressing.IPv6().AllocationCIDR().Mask}
   671  				ipsecIPv6Wildcard := &net.IPNet{IP: net.ParseIP(wildcardIPv6), Mask: net.CIDRMask(0, 0)}
   672  				spi, err = ipsec.UpsertIPsecEndpoint(ipsecLocal, ipsecIPv6Wildcard, ipsec.IPSecDirIn, n.nodeConfig.EncryptNode)
   673  				upsertIPsecLog(err, "local IPv6", ipsecLocal, ipsecIPv6Wildcard, spi)
   674  			}
   675  		} else {
   676  			if ciliumInternalIPv6 := newNode.GetCiliumInternalIP(true); ciliumInternalIPv6 != nil {
   677  				ipsecLocalWildcard := &net.IPNet{IP: net.ParseIP(wildcardIPv6), Mask: net.CIDRMask(0, 0)}
   678  				ipsecRemote := &net.IPNet{IP: ciliumInternalIPv6, Mask: newNode.IPv6AllocCIDR.Mask}
   679  				n.replaceNodeIPSecOutRoute(new6Net)
   680  				spi, err := ipsec.UpsertIPsecEndpoint(ipsecLocalWildcard, ipsecRemote, ipsec.IPSecDirOut, n.nodeConfig.EncryptNode)
   681  				upsertIPsecLog(err, "IPv6", ipsecLocalWildcard, ipsecRemote, spi)
   682  			}
   683  		}
   684  	}
   685  }
   686  
   687  func (n *linuxNodeHandler) subnetEncryption() bool {
   688  	return len(n.nodeConfig.IPv4PodSubnets) > 0 || len(n.nodeConfig.IPv6PodSubnets) > 0
   689  }
   690  
   691  func (n *linuxNodeHandler) nodeUpdate(oldNode, newNode *node.Node, firstAddition bool) error {
   692  	var (
   693  		oldIP4Cidr, oldIP6Cidr *cidr.CIDR
   694  		oldIP4, oldIP6         net.IP
   695  		newIP4                 = newNode.GetNodeIP(false)
   696  		newIP6                 = newNode.GetNodeIP(true)
   697  		oldKey, newKey         uint8
   698  	)
   699  
   700  	if oldNode != nil {
   701  		oldIP4Cidr = oldNode.IPv4AllocCIDR
   702  		oldIP6Cidr = oldNode.IPv6AllocCIDR
   703  		oldIP4 = oldNode.GetNodeIP(false)
   704  		oldIP6 = oldNode.GetNodeIP(true)
   705  		oldKey = oldNode.EncryptionKey
   706  	}
   707  
   708  	if n.nodeConfig.EnableIPSec && !n.subnetEncryption() {
   709  		n.enableIPsec(newNode)
   710  		newKey = newNode.EncryptionKey
   711  	}
   712  
   713  	if n.enableNeighDiscovery {
   714  		var ifaceName string
   715  		if option.Config.EnableNodePort {
   716  			ifaceName = option.Config.Device
   717  		} else {
   718  			ifaceName = option.Config.EncryptInterface
   719  		}
   720  		n.insertNeighbor(newNode, ifaceName)
   721  	}
   722  
   723  	if n.nodeConfig.EnableIPSec {
   724  		n.encryptNode(newNode)
   725  	}
   726  
   727  	if newNode.IsLocal() {
   728  		if n.nodeConfig.EnableLocalNodeRoute {
   729  			n.updateOrRemoveNodeRoutes([]*cidr.CIDR{oldIP4Cidr}, []*cidr.CIDR{newNode.IPv4AllocCIDR})
   730  			n.updateOrRemoveNodeRoutes([]*cidr.CIDR{oldIP6Cidr}, []*cidr.CIDR{newNode.IPv6AllocCIDR})
   731  		}
   732  		if n.subnetEncryption() {
   733  			n.enableSubnetIPsec(n.nodeConfig.IPv4PodSubnets, n.nodeConfig.IPv6PodSubnets)
   734  		}
   735  		return nil
   736  	}
   737  
   738  	if n.nodeConfig.EnableAutoDirectRouting {
   739  		n.updateDirectRoute(oldIP4Cidr, newNode.IPv4AllocCIDR, oldIP4, newIP4, firstAddition, n.nodeConfig.EnableIPv4)
   740  		n.updateDirectRoute(oldIP6Cidr, newNode.IPv6AllocCIDR, oldIP6, newIP6, firstAddition, n.nodeConfig.EnableIPv6)
   741  		return nil
   742  	}
   743  
   744  	if n.nodeConfig.EnableEncapsulation {
   745  		// Update the tunnel mapping of the node. In case the
   746  		// node has changed its CIDR range, a new entry in the
   747  		// map is created and the old entry is removed.
   748  		updateTunnelMapping(oldIP4Cidr, newNode.IPv4AllocCIDR, oldIP4, newIP4, firstAddition, n.nodeConfig.EnableIPv4, oldKey, newKey)
   749  		// Not a typo, the IPv4 host IP is used to build the IPv6 overlay
   750  		updateTunnelMapping(oldIP6Cidr, newNode.IPv6AllocCIDR, oldIP4, newIP4, firstAddition, n.nodeConfig.EnableIPv6, oldKey, newKey)
   751  
   752  		if !n.nodeConfig.UseSingleClusterRoute {
   753  			n.updateOrRemoveNodeRoutes([]*cidr.CIDR{oldIP4Cidr}, []*cidr.CIDR{newNode.IPv4AllocCIDR})
   754  			n.updateOrRemoveNodeRoutes([]*cidr.CIDR{oldIP6Cidr}, []*cidr.CIDR{newNode.IPv6AllocCIDR})
   755  		}
   756  
   757  		return nil
   758  	} else if firstAddition {
   759  		// When encapsulation is disabled, then the initial node addition
   760  		// triggers a removal of eventual old tunnel map entries.
   761  		deleteTunnelMapping(newNode.IPv4AllocCIDR, true)
   762  		deleteTunnelMapping(newNode.IPv6AllocCIDR, true)
   763  
   764  		if rt, _ := n.lookupNodeRoute(newNode.IPv4AllocCIDR); rt != nil {
   765  			n.deleteNodeRoute(newNode.IPv4AllocCIDR)
   766  		}
   767  		if rt, _ := n.lookupNodeRoute(newNode.IPv6AllocCIDR); rt != nil {
   768  			n.deleteNodeRoute(newNode.IPv6AllocCIDR)
   769  		}
   770  	}
   771  
   772  	return nil
   773  }
   774  
   775  func (n *linuxNodeHandler) NodeDelete(oldNode node.Node) error {
   776  	n.mutex.Lock()
   777  	defer n.mutex.Unlock()
   778  
   779  	nodeIdentity := oldNode.Identity()
   780  	if oldCachedNode, nodeExists := n.nodes[nodeIdentity]; nodeExists {
   781  		delete(n.nodes, nodeIdentity)
   782  
   783  		if n.isInitialized {
   784  			return n.nodeDelete(oldCachedNode)
   785  		}
   786  	}
   787  
   788  	return nil
   789  }
   790  
   791  func (n *linuxNodeHandler) nodeDelete(oldNode *node.Node) error {
   792  	if oldNode.IsLocal() {
   793  		return nil
   794  	}
   795  
   796  	oldIP4 := oldNode.GetNodeIP(false)
   797  	oldIP6 := oldNode.GetNodeIP(true)
   798  
   799  	if n.nodeConfig.EnableAutoDirectRouting {
   800  		n.deleteDirectRoute(oldNode.IPv4AllocCIDR, oldIP4)
   801  		n.deleteDirectRoute(oldNode.IPv6AllocCIDR, oldIP6)
   802  	}
   803  
   804  	if n.nodeConfig.EnableEncapsulation {
   805  		deleteTunnelMapping(oldNode.IPv4AllocCIDR, false)
   806  		deleteTunnelMapping(oldNode.IPv6AllocCIDR, false)
   807  
   808  		if !n.nodeConfig.UseSingleClusterRoute {
   809  			n.deleteNodeRoute(oldNode.IPv4AllocCIDR)
   810  			n.deleteNodeRoute(oldNode.IPv6AllocCIDR)
   811  		}
   812  	}
   813  
   814  	if n.enableNeighDiscovery {
   815  		n.deleteNeighbor(oldNode)
   816  	}
   817  
   818  	if n.nodeConfig.EnableIPSec {
   819  		n.deleteIPsec(oldNode)
   820  	}
   821  
   822  	return nil
   823  }
   824  
   825  func (n *linuxNodeHandler) updateOrRemoveClusterRoute(addressing datapath.NodeAddressingFamily, addressFamilyEnabled bool) {
   826  	allocCIDR := addressing.AllocationCIDR()
   827  	if addressFamilyEnabled {
   828  		n.updateNodeRoute(allocCIDR, addressFamilyEnabled)
   829  	} else if rt, _ := n.lookupNodeRoute(allocCIDR); rt != nil {
   830  		n.deleteNodeRoute(allocCIDR)
   831  	}
   832  }
   833  
   834  func (n *linuxNodeHandler) replaceHostRules() error {
   835  	rule := route.Rule{
   836  		Priority: 1,
   837  		Mask:     linux_defaults.RouteMarkMask,
   838  		Table:    linux_defaults.RouteTableIPSec,
   839  	}
   840  
   841  	if n.nodeConfig.EnableIPv4 {
   842  		rule.Mark = linux_defaults.RouteMarkDecrypt
   843  		if err := route.ReplaceRule(rule); err != nil {
   844  			log.WithError(err).Error("Replace IPv4 route decrypt rule failed")
   845  			return err
   846  		}
   847  		rule.Mark = linux_defaults.RouteMarkEncrypt
   848  		if err := route.ReplaceRule(rule); err != nil {
   849  			log.WithError(err).Error("Replace IPv4 route encrypt rule failed")
   850  			return err
   851  		}
   852  	}
   853  
   854  	if n.nodeConfig.EnableIPv6 {
   855  		rule.Mark = linux_defaults.RouteMarkDecrypt
   856  		if err := route.ReplaceRuleIPv6(rule); err != nil {
   857  			log.WithError(err).Error("Replace IPv6 route decrypt rule failed")
   858  			return err
   859  		}
   860  		rule.Mark = linux_defaults.RouteMarkEncrypt
   861  		if err := route.ReplaceRuleIPv6(rule); err != nil {
   862  			log.WithError(err).Error("Replace IPv6 route ecrypt rule failed")
   863  			return err
   864  		}
   865  	}
   866  
   867  	return nil
   868  }
   869  
   870  func (n *linuxNodeHandler) removeEncryptRules() error {
   871  	rule := route.Rule{
   872  		Priority: 1,
   873  		Mask:     linux_defaults.RouteMarkMask,
   874  		Table:    linux_defaults.RouteTableIPSec,
   875  	}
   876  
   877  	rule.Mark = linux_defaults.RouteMarkDecrypt
   878  	if err := route.DeleteRule(rule); err != nil {
   879  		if !os.IsNotExist(err) {
   880  			return fmt.Errorf("Delete previous IPv4 decrypt rule failed: %s", err)
   881  		}
   882  	}
   883  
   884  	rule.Mark = linux_defaults.RouteMarkEncrypt
   885  	if err := route.DeleteRule(rule); err != nil {
   886  		if !os.IsNotExist(err) {
   887  			return fmt.Errorf("Delete previousa IPv4 encrypt rule failed: %s", err)
   888  		}
   889  	}
   890  
   891  	rule.Mark = linux_defaults.RouteMarkDecrypt
   892  	if err := route.DeleteRuleIPv6(rule); err != nil {
   893  		if !os.IsNotExist(err) && err != syscall.EAFNOSUPPORT {
   894  			return fmt.Errorf("Delete previous IPv6 decrypt rule failed: %s", err)
   895  		}
   896  	}
   897  
   898  	rule.Mark = linux_defaults.RouteMarkEncrypt
   899  	if err := route.DeleteRuleIPv6(rule); err != nil {
   900  		if !os.IsNotExist(err) && err != syscall.EAFNOSUPPORT {
   901  			return fmt.Errorf("Delete previous IPv6 encrypt rule failed: %s", err)
   902  		}
   903  	}
   904  	return nil
   905  }
   906  
   907  func (n *linuxNodeHandler) createNodeIPSecInRoute(ip *net.IPNet) route.Route {
   908  	var device string
   909  
   910  	if option.Config.Tunnel == option.TunnelDisabled {
   911  		device = n.datapathConfig.EncryptInterface
   912  	} else {
   913  		device = linux_defaults.TunnelDeviceName
   914  	}
   915  	return route.Route{
   916  		Nexthop: nil,
   917  		Device:  device,
   918  		Prefix:  *ip,
   919  		Table:   linux_defaults.RouteTableIPSec,
   920  		Proto:   linux_defaults.RouteProtocolIPSec,
   921  		Type:    route.RTN_LOCAL,
   922  	}
   923  }
   924  
   925  func (n *linuxNodeHandler) createNodeIPSecOutRoute(ip *net.IPNet) route.Route {
   926  	return route.Route{
   927  		Nexthop: nil,
   928  		Device:  n.datapathConfig.HostDevice,
   929  		Prefix:  *ip,
   930  		Table:   linux_defaults.RouteTableIPSec,
   931  	}
   932  }
   933  
   934  func (n *linuxNodeHandler) createNodeExternalIPSecOutRoute(ip *net.IPNet, dflt bool) route.Route {
   935  	var tbl int
   936  	var dev string
   937  	var mtu int
   938  
   939  	if dflt {
   940  		dev = n.datapathConfig.HostDevice
   941  		mtu = n.nodeConfig.MtuConfig.GetRouteMTU()
   942  	} else {
   943  		tbl = linux_defaults.RouteTableIPSec
   944  		dev = n.datapathConfig.HostDevice
   945  	}
   946  
   947  	// The default routing table accounts for encryption overhead for encrypt-node traffic
   948  	return route.Route{
   949  		Device: dev,
   950  		Prefix: *ip,
   951  		Table:  tbl,
   952  		Proto:  route.EncryptRouteProtocol,
   953  		MTU:    mtu,
   954  	}
   955  }
   956  
   957  // replaceNodeIPSecOutRoute replace the out IPSec route in the host routing table
   958  // with the new route. If no route exists the route is installed on the host.
   959  func (n *linuxNodeHandler) replaceNodeIPSecOutRoute(ip *net.IPNet) {
   960  	if ip == nil {
   961  		return
   962  	}
   963  
   964  	if ip.IP.To4() != nil {
   965  		if !n.nodeConfig.EnableIPv4 {
   966  			return
   967  		}
   968  	} else {
   969  		if !n.nodeConfig.EnableIPv6 {
   970  			return
   971  		}
   972  	}
   973  
   974  	_, err := route.Upsert(n.createNodeIPSecOutRoute(ip))
   975  	if err != nil {
   976  		log.WithError(err).Error("Unable to replace the IPSec route OUT the host routing table")
   977  	}
   978  }
   979  
   980  // replaceNodeExternalIPSecOutRoute replace the out IPSec route in the host routing table
   981  // with the new route. If no route exists the route is installed on the host.
   982  func (n *linuxNodeHandler) replaceNodeExternalIPSecOutRoute(ip *net.IPNet) {
   983  	if ip == nil {
   984  		return
   985  	}
   986  
   987  	if ip.IP.To4() != nil {
   988  		if !n.nodeConfig.EnableIPv4 {
   989  			return
   990  		}
   991  	} else {
   992  		if !n.nodeConfig.EnableIPv6 {
   993  			return
   994  		}
   995  	}
   996  
   997  	_, err := route.Upsert(n.createNodeExternalIPSecOutRoute(ip, true))
   998  	if err != nil {
   999  		log.WithError(err).Error("Unable to replace the IPSec route OUT the default routing table")
  1000  	}
  1001  	_, err = route.Upsert(n.createNodeExternalIPSecOutRoute(ip, false))
  1002  	if err != nil {
  1003  		log.WithError(err).Error("Unable to replace the IPSec route OUT the host routing table")
  1004  	}
  1005  }
  1006  
  1007  func (n *linuxNodeHandler) deleteNodeIPSecOutRoute(ip *net.IPNet) {
  1008  	if ip == nil {
  1009  		return
  1010  	}
  1011  
  1012  	if ip.IP.To4() != nil {
  1013  		if !n.nodeConfig.EnableIPv4 {
  1014  			return
  1015  		}
  1016  	} else {
  1017  		if !n.nodeConfig.EnableIPv6 {
  1018  			return
  1019  		}
  1020  	}
  1021  
  1022  	if err := route.Delete(n.createNodeIPSecOutRoute(ip)); err != nil {
  1023  		log.WithError(err).Error("Unable to delete the IPsec route OUT from the host routing table")
  1024  	}
  1025  }
  1026  
  1027  func (n *linuxNodeHandler) deleteNodeExternalIPSecOutRoute(ip *net.IPNet) {
  1028  	if ip == nil {
  1029  		return
  1030  	}
  1031  
  1032  	if ip.IP.To4() != nil {
  1033  		if !n.nodeConfig.EnableIPv4 {
  1034  			return
  1035  		}
  1036  	} else {
  1037  		if !n.nodeConfig.EnableIPv6 {
  1038  			return
  1039  		}
  1040  	}
  1041  
  1042  	if err := route.Delete(n.createNodeExternalIPSecOutRoute(ip, true)); err != nil {
  1043  		log.WithError(err).Error("Unable to delete the IPsec route External OUT from the ipsec routing table")
  1044  	}
  1045  
  1046  	if err := route.Delete(n.createNodeExternalIPSecOutRoute(ip, false)); err != nil {
  1047  		log.WithError(err).Error("Unable to delete the IPsec route External OUT from the host routing table")
  1048  	}
  1049  }
  1050  
  1051  // replaceNodeIPSecoInRoute replace the in IPSec routes in the host routing table
  1052  // with the new route. If no route exists the route is installed on the host.
  1053  func (n *linuxNodeHandler) replaceNodeIPSecInRoute(ip *net.IPNet) {
  1054  	if ip == nil {
  1055  		return
  1056  	}
  1057  
  1058  	if ip.IP.To4() != nil {
  1059  		if !n.nodeConfig.EnableIPv4 {
  1060  			return
  1061  		}
  1062  	} else {
  1063  		if !n.nodeConfig.EnableIPv6 {
  1064  			return
  1065  		}
  1066  	}
  1067  
  1068  	_, err := route.Upsert(n.createNodeIPSecInRoute(ip))
  1069  	if err != nil {
  1070  		log.WithError(err).Error("Unable to replace the IPSec route IN the host routing table")
  1071  	}
  1072  }
  1073  
  1074  func (n *linuxNodeHandler) deleteIPsec(oldNode *node.Node) {
  1075  	if n.nodeConfig.EnableIPv4 && oldNode.IPv4AllocCIDR != nil {
  1076  		ciliumInternalIPv4 := oldNode.GetCiliumInternalIP(false)
  1077  		old4Net := &net.IPNet{IP: ciliumInternalIPv4, Mask: oldNode.IPv4AllocCIDR.Mask}
  1078  		old4RouteNet := &net.IPNet{IP: oldNode.IPv4AllocCIDR.IP, Mask: oldNode.IPv4AllocCIDR.Mask}
  1079  		n.deleteNodeIPSecOutRoute(old4RouteNet)
  1080  		ipsec.DeleteIPsecEndpoint(old4Net)
  1081  		if n.nodeConfig.EncryptNode {
  1082  			if remoteIPv4 := oldNode.GetNodeIP(false); remoteIPv4 != nil {
  1083  				exactMask := net.IPv4Mask(255, 255, 255, 255)
  1084  				ipsecRemote := &net.IPNet{IP: remoteIPv4, Mask: exactMask}
  1085  				n.deleteNodeExternalIPSecOutRoute(ipsecRemote)
  1086  			}
  1087  		}
  1088  	}
  1089  
  1090  	if n.nodeConfig.EnableIPv6 && oldNode.IPv6AllocCIDR != nil {
  1091  		ciliumInternalIPv6 := oldNode.GetCiliumInternalIP(true)
  1092  		old6Net := &net.IPNet{IP: ciliumInternalIPv6, Mask: oldNode.IPv6AllocCIDR.Mask}
  1093  		old6RouteNet := &net.IPNet{IP: oldNode.IPv6AllocCIDR.IP, Mask: oldNode.IPv6AllocCIDR.Mask}
  1094  		n.deleteNodeIPSecOutRoute(old6RouteNet)
  1095  		ipsec.DeleteIPsecEndpoint(old6Net)
  1096  		if n.nodeConfig.EncryptNode {
  1097  			if remoteIPv6 := oldNode.GetNodeIP(true); remoteIPv6 != nil {
  1098  				exactMask := net.CIDRMask(128, 128)
  1099  				ipsecRemote := &net.IPNet{IP: remoteIPv6, Mask: exactMask}
  1100  				n.deleteNodeExternalIPSecOutRoute(ipsecRemote)
  1101  			}
  1102  		}
  1103  	}
  1104  }
  1105  
  1106  // NodeConfigurationChanged is called when the LocalNodeConfiguration has changed
  1107  func (n *linuxNodeHandler) NodeConfigurationChanged(newConfig datapath.LocalNodeConfiguration) error {
  1108  	n.mutex.Lock()
  1109  	defer n.mutex.Unlock()
  1110  
  1111  	prevConfig := n.nodeConfig
  1112  	n.nodeConfig = newConfig
  1113  
  1114  	n.enableNeighDiscovery = n.nodeConfig.EnableIPv4 &&
  1115  		(option.Config.EnableNodePort ||
  1116  			(n.nodeConfig.EnableIPSec && option.Config.Tunnel == option.TunnelDisabled))
  1117  
  1118  	n.updateOrRemoveNodeRoutes(prevConfig.AuxiliaryPrefixes, newConfig.AuxiliaryPrefixes)
  1119  
  1120  	if newConfig.EnableIPSec {
  1121  		if err := n.replaceHostRules(); err != nil {
  1122  			log.WithError(err).Warning("Cannot replace Host rules")
  1123  		}
  1124  	} else {
  1125  		err := n.removeEncryptRules()
  1126  		if err != nil {
  1127  			log.WithError(err).Warning("Cannot cleanup previous encryption rule state.")
  1128  		}
  1129  	}
  1130  
  1131  	if newConfig.UseSingleClusterRoute {
  1132  		n.updateOrRemoveClusterRoute(n.nodeAddressing.IPv4(), newConfig.EnableIPv4)
  1133  		n.updateOrRemoveClusterRoute(n.nodeAddressing.IPv6(), newConfig.EnableIPv6)
  1134  	} else if prevConfig.UseSingleClusterRoute {
  1135  		// single cluster route has been disabled, remove route
  1136  		n.deleteNodeRoute(n.nodeAddressing.IPv4().AllocationCIDR())
  1137  		n.deleteNodeRoute(n.nodeAddressing.IPv6().AllocationCIDR())
  1138  	}
  1139  
  1140  	if !n.isInitialized {
  1141  		n.isInitialized = true
  1142  		if !n.nodeConfig.UseSingleClusterRoute {
  1143  			for _, unlinkedNode := range n.nodes {
  1144  				n.nodeUpdate(nil, unlinkedNode, true)
  1145  			}
  1146  		}
  1147  	}
  1148  
  1149  	return nil
  1150  }
  1151  
  1152  // NodeValidateImplementation is called to validate the implementation of the
  1153  // node in the datapath
  1154  func (n *linuxNodeHandler) NodeValidateImplementation(nodeToValidate node.Node) error {
  1155  	return n.nodeUpdate(nil, &nodeToValidate, false)
  1156  }
  1157  
  1158  // NodeDeviceNameWithDefaultRoute returns the node's device name which
  1159  // handles the default route in the current namespace
  1160  func NodeDeviceNameWithDefaultRoute() (string, error) {
  1161  	link, err := route.NodeDeviceWithDefaultRoute()
  1162  	if err != nil {
  1163  		return "", err
  1164  	}
  1165  	return link.Attrs().Name, nil
  1166  }