github.com/elfadel/cilium@v1.6.12/pkg/datapath/linux/node_linux_test.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  // +build privileged_tests
    16  
    17  package linux
    18  
    19  import (
    20  	"net"
    21  	"testing"
    22  
    23  	"github.com/cilium/cilium/pkg/cidr"
    24  	"github.com/cilium/cilium/pkg/datapath"
    25  	"github.com/cilium/cilium/pkg/datapath/fake"
    26  	"github.com/cilium/cilium/pkg/datapath/linux/route"
    27  	"github.com/cilium/cilium/pkg/maps/tunnel"
    28  	"github.com/cilium/cilium/pkg/mtu"
    29  	"github.com/cilium/cilium/pkg/node"
    30  	nodeaddressing "github.com/cilium/cilium/pkg/node/addressing"
    31  
    32  	"github.com/vishvananda/netlink"
    33  	"gopkg.in/check.v1"
    34  )
    35  
    36  func Test(t *testing.T) {
    37  	check.TestingT(t)
    38  }
    39  
    40  type linuxPrivilegedBaseTestSuite struct {
    41  	nodeAddressing datapath.NodeAddressing
    42  	mtuConfig      mtu.Configuration
    43  	enableIPv4     bool
    44  	enableIPv6     bool
    45  }
    46  
    47  type linuxPrivilegedIPv6OnlyTestSuite struct {
    48  	linuxPrivilegedBaseTestSuite
    49  }
    50  
    51  var _ = check.Suite(&linuxPrivilegedIPv6OnlyTestSuite{})
    52  
    53  type linuxPrivilegedIPv4OnlyTestSuite struct {
    54  	linuxPrivilegedBaseTestSuite
    55  }
    56  
    57  var _ = check.Suite(&linuxPrivilegedIPv4OnlyTestSuite{})
    58  
    59  type linuxPrivilegedIPv4AndIPv6TestSuite struct {
    60  	linuxPrivilegedBaseTestSuite
    61  }
    62  
    63  var _ = check.Suite(&linuxPrivilegedIPv4AndIPv6TestSuite{})
    64  
    65  const (
    66  	dummyHostDeviceName     = "dummy_host"
    67  	dummyExternalDeviceName = "dummy_external"
    68  )
    69  
    70  func (s *linuxPrivilegedBaseTestSuite) SetUpTest(c *check.C, addressing datapath.NodeAddressing, enableIPv6, enableIPv4 bool) {
    71  	s.nodeAddressing = addressing
    72  	s.mtuConfig = mtu.NewConfiguration(0, false, false, 1500)
    73  	s.enableIPv6 = enableIPv6
    74  	s.enableIPv4 = enableIPv4
    75  
    76  	removeDevice(dummyHostDeviceName)
    77  	removeDevice(dummyExternalDeviceName)
    78  
    79  	ips := make([]net.IP, 0)
    80  	if enableIPv6 {
    81  		ips = append(ips, s.nodeAddressing.IPv6().PrimaryExternal())
    82  	}
    83  	if enableIPv4 {
    84  		ips = append(ips, s.nodeAddressing.IPv4().PrimaryExternal())
    85  	}
    86  	err := setupDummyDevice(dummyExternalDeviceName, ips...)
    87  	c.Assert(err, check.IsNil)
    88  
    89  	if enableIPv4 {
    90  		err = setupDummyDevice(dummyHostDeviceName, s.nodeAddressing.IPv4().Router())
    91  	} else {
    92  		err = setupDummyDevice(dummyHostDeviceName)
    93  	}
    94  	c.Assert(err, check.IsNil)
    95  
    96  	tunnel.TunnelMap = tunnel.NewTunnelMap("test_cilium_tunnel_map")
    97  	_, err = tunnel.TunnelMap.OpenOrCreate()
    98  	c.Assert(err, check.IsNil)
    99  }
   100  
   101  func (s *linuxPrivilegedIPv6OnlyTestSuite) SetUpTest(c *check.C) {
   102  	addressing := fake.NewIPv6OnlyNodeAddressing()
   103  	s.linuxPrivilegedBaseTestSuite.SetUpTest(c, addressing, true, false)
   104  }
   105  
   106  func (s *linuxPrivilegedIPv4OnlyTestSuite) SetUpTest(c *check.C) {
   107  	addressing := fake.NewIPv4OnlyNodeAddressing()
   108  	s.linuxPrivilegedBaseTestSuite.SetUpTest(c, addressing, false, true)
   109  }
   110  
   111  func (s *linuxPrivilegedIPv4AndIPv6TestSuite) SetUpTest(c *check.C) {
   112  	addressing := fake.NewNodeAddressing()
   113  	s.linuxPrivilegedBaseTestSuite.SetUpTest(c, addressing, true, true)
   114  }
   115  
   116  func tearDownTest(c *check.C) {
   117  	removeDevice(dummyHostDeviceName)
   118  	removeDevice(dummyExternalDeviceName)
   119  	err := tunnel.TunnelMap.Unpin()
   120  	c.Assert(err, check.IsNil)
   121  }
   122  
   123  func (s *linuxPrivilegedIPv6OnlyTestSuite) TearDownTest(c *check.C) {
   124  	tearDownTest(c)
   125  }
   126  
   127  func (s *linuxPrivilegedIPv4OnlyTestSuite) TearDownTest(c *check.C) {
   128  	tearDownTest(c)
   129  }
   130  
   131  func (s *linuxPrivilegedIPv4AndIPv6TestSuite) TearDownTest(c *check.C) {
   132  	tearDownTest(c)
   133  }
   134  
   135  func setupDummyDevice(name string, ips ...net.IP) error {
   136  	dummy := &netlink.Dummy{
   137  		LinkAttrs: netlink.LinkAttrs{
   138  			Name: name,
   139  		},
   140  	}
   141  	if err := netlink.LinkAdd(dummy); err != nil {
   142  		return err
   143  	}
   144  
   145  	if err := netlink.LinkSetUp(dummy); err != nil {
   146  		removeDevice(name)
   147  		return err
   148  	}
   149  
   150  	for _, ip := range ips {
   151  		var ipnet *net.IPNet
   152  		if ip.To4() != nil {
   153  			ipnet = &net.IPNet{IP: ip, Mask: net.CIDRMask(32, 32)}
   154  		} else {
   155  			ipnet = &net.IPNet{IP: ip, Mask: net.CIDRMask(128, 128)}
   156  		}
   157  
   158  		addr := &netlink.Addr{IPNet: ipnet}
   159  		if err := netlink.AddrAdd(dummy, addr); err != nil {
   160  			removeDevice(name)
   161  			return err
   162  		}
   163  	}
   164  
   165  	return nil
   166  }
   167  
   168  func removeDevice(name string) {
   169  	l, err := netlink.LinkByName(name)
   170  	if err == nil {
   171  		netlink.LinkDel(l)
   172  	}
   173  }
   174  
   175  func (s *linuxPrivilegedBaseTestSuite) TestUpdateNodeRoute(c *check.C) {
   176  	ip4CIDR := cidr.MustParseCIDR("254.254.254.0/24")
   177  	c.Assert(ip4CIDR, check.Not(check.IsNil))
   178  
   179  	ip6CIDR := cidr.MustParseCIDR("cafe:cafe:cafe:cafe::/96")
   180  	c.Assert(ip6CIDR, check.Not(check.IsNil))
   181  
   182  	dpConfig := DatapathConfiguration{HostDevice: dummyHostDeviceName}
   183  
   184  	linuxNodeHandler := NewNodeHandler(dpConfig, s.nodeAddressing).(*linuxNodeHandler)
   185  	c.Assert(linuxNodeHandler, check.Not(check.IsNil))
   186  	nodeConfig := datapath.LocalNodeConfiguration{
   187  		EnableIPv4: s.enableIPv4,
   188  		EnableIPv6: s.enableIPv6,
   189  	}
   190  
   191  	err := linuxNodeHandler.NodeConfigurationChanged(nodeConfig)
   192  	c.Assert(err, check.IsNil)
   193  
   194  	if s.enableIPv4 {
   195  		// add & remove IPv4 node route
   196  		err = linuxNodeHandler.updateNodeRoute(ip4CIDR, true)
   197  		c.Assert(err, check.IsNil)
   198  
   199  		foundRoute, err := linuxNodeHandler.lookupNodeRoute(ip4CIDR)
   200  		c.Assert(err, check.IsNil)
   201  		c.Assert(foundRoute, check.Not(check.IsNil))
   202  
   203  		err = linuxNodeHandler.deleteNodeRoute(ip4CIDR)
   204  		c.Assert(err, check.IsNil)
   205  
   206  		foundRoute, err = linuxNodeHandler.lookupNodeRoute(ip4CIDR)
   207  		c.Assert(err, check.IsNil)
   208  		c.Assert(foundRoute, check.IsNil)
   209  	}
   210  
   211  	if s.enableIPv6 {
   212  		// add & remove IPv6 node route
   213  		err = linuxNodeHandler.updateNodeRoute(ip6CIDR, true)
   214  		c.Assert(err, check.IsNil)
   215  
   216  		foundRoute, err := linuxNodeHandler.lookupNodeRoute(ip6CIDR)
   217  		c.Assert(err, check.IsNil)
   218  		c.Assert(foundRoute, check.Not(check.IsNil))
   219  
   220  		err = linuxNodeHandler.deleteNodeRoute(ip6CIDR)
   221  		c.Assert(err, check.IsNil)
   222  
   223  		foundRoute, err = linuxNodeHandler.lookupNodeRoute(ip6CIDR)
   224  		c.Assert(err, check.IsNil)
   225  		c.Assert(foundRoute, check.IsNil)
   226  	}
   227  }
   228  
   229  func (s *linuxPrivilegedBaseTestSuite) TestSingleClusterPrefix(c *check.C) {
   230  	dpConfig := DatapathConfiguration{HostDevice: dummyHostDeviceName}
   231  
   232  	linuxNodeHandler := NewNodeHandler(dpConfig, s.nodeAddressing).(*linuxNodeHandler)
   233  	c.Assert(linuxNodeHandler, check.Not(check.IsNil))
   234  
   235  	// enable as per test definition
   236  	err := linuxNodeHandler.NodeConfigurationChanged(datapath.LocalNodeConfiguration{
   237  		UseSingleClusterRoute: true,
   238  		EnableIPv4:            s.enableIPv4,
   239  		EnableIPv6:            s.enableIPv6,
   240  	})
   241  	c.Assert(err, check.IsNil)
   242  
   243  	if s.enableIPv4 {
   244  		foundRoute, err := linuxNodeHandler.lookupNodeRoute(s.nodeAddressing.IPv4().AllocationCIDR())
   245  		c.Assert(err, check.IsNil)
   246  		c.Assert(foundRoute, check.Not(check.IsNil))
   247  	}
   248  
   249  	if s.enableIPv6 {
   250  		foundRoute, err := linuxNodeHandler.lookupNodeRoute(s.nodeAddressing.IPv6().AllocationCIDR())
   251  		c.Assert(err, check.IsNil)
   252  		c.Assert(foundRoute, check.Not(check.IsNil))
   253  	}
   254  
   255  	// disable ipv4, enable ipv6. addressing may not be available for IPv6
   256  	err = linuxNodeHandler.NodeConfigurationChanged(datapath.LocalNodeConfiguration{
   257  		UseSingleClusterRoute: true,
   258  		EnableIPv6:            true,
   259  	})
   260  	c.Assert(err, check.IsNil)
   261  
   262  	foundRoute, err := linuxNodeHandler.lookupNodeRoute(s.nodeAddressing.IPv4().AllocationCIDR())
   263  	c.Assert(err, check.IsNil)
   264  	c.Assert(foundRoute, check.IsNil)
   265  
   266  	if s.enableIPv6 {
   267  		foundRoute, err := linuxNodeHandler.lookupNodeRoute(s.nodeAddressing.IPv6().AllocationCIDR())
   268  		c.Assert(err, check.IsNil)
   269  		c.Assert(foundRoute, check.Not(check.IsNil))
   270  	}
   271  
   272  	// enable ipv4, enable ipv6, addressing may not be available
   273  	err = linuxNodeHandler.NodeConfigurationChanged(datapath.LocalNodeConfiguration{
   274  		UseSingleClusterRoute: true,
   275  		EnableIPv6:            true,
   276  		EnableIPv4:            true,
   277  	})
   278  	c.Assert(err, check.IsNil)
   279  
   280  	if s.enableIPv4 {
   281  		foundRoute, err := linuxNodeHandler.lookupNodeRoute(s.nodeAddressing.IPv4().AllocationCIDR())
   282  		c.Assert(err, check.IsNil)
   283  		c.Assert(foundRoute, check.Not(check.IsNil))
   284  	}
   285  
   286  	if s.enableIPv6 {
   287  		foundRoute, err := linuxNodeHandler.lookupNodeRoute(s.nodeAddressing.IPv6().AllocationCIDR())
   288  		c.Assert(err, check.IsNil)
   289  		c.Assert(foundRoute, check.Not(check.IsNil))
   290  	}
   291  }
   292  
   293  func (s *linuxPrivilegedBaseTestSuite) TestAuxiliaryPrefixes(c *check.C) {
   294  	net1 := cidr.MustParseCIDR("30.30.0.0/24")
   295  	net2 := cidr.MustParseCIDR("cafe:f00d::/112")
   296  
   297  	dpConfig := DatapathConfiguration{HostDevice: dummyHostDeviceName}
   298  	linuxNodeHandler := NewNodeHandler(dpConfig, s.nodeAddressing).(*linuxNodeHandler)
   299  	c.Assert(linuxNodeHandler, check.Not(check.IsNil))
   300  	nodeConfig := datapath.LocalNodeConfiguration{
   301  		EnableIPv4:        s.enableIPv4,
   302  		EnableIPv6:        s.enableIPv6,
   303  		AuxiliaryPrefixes: []*cidr.CIDR{net1, net2},
   304  	}
   305  
   306  	err := linuxNodeHandler.NodeConfigurationChanged(nodeConfig)
   307  	c.Assert(err, check.IsNil)
   308  
   309  	if s.enableIPv4 {
   310  		foundRoute, err := linuxNodeHandler.lookupNodeRoute(net1)
   311  		c.Assert(err, check.IsNil)
   312  		c.Assert(foundRoute, check.Not(check.IsNil))
   313  	}
   314  
   315  	if s.enableIPv6 {
   316  		foundRoute, err := linuxNodeHandler.lookupNodeRoute(net2)
   317  		c.Assert(err, check.IsNil)
   318  		c.Assert(foundRoute, check.Not(check.IsNil))
   319  	}
   320  
   321  	// remove aux prefix net2
   322  	err = linuxNodeHandler.NodeConfigurationChanged(datapath.LocalNodeConfiguration{
   323  		EnableIPv4:        s.enableIPv4,
   324  		EnableIPv6:        s.enableIPv6,
   325  		AuxiliaryPrefixes: []*cidr.CIDR{net1},
   326  	})
   327  	c.Assert(err, check.IsNil)
   328  
   329  	if s.enableIPv4 {
   330  		foundRoute, err := linuxNodeHandler.lookupNodeRoute(net1)
   331  		c.Assert(err, check.IsNil)
   332  		c.Assert(foundRoute, check.Not(check.IsNil))
   333  	}
   334  
   335  	if s.enableIPv6 {
   336  		foundRoute, err := linuxNodeHandler.lookupNodeRoute(net2)
   337  		c.Assert(err, check.IsNil)
   338  		c.Assert(foundRoute, check.IsNil)
   339  	}
   340  
   341  	// remove aux prefix net1, re-add net2
   342  	err = linuxNodeHandler.NodeConfigurationChanged(datapath.LocalNodeConfiguration{
   343  		EnableIPv4:        s.enableIPv4,
   344  		EnableIPv6:        s.enableIPv6,
   345  		AuxiliaryPrefixes: []*cidr.CIDR{net2},
   346  	})
   347  	c.Assert(err, check.IsNil)
   348  
   349  	if s.enableIPv4 {
   350  		foundRoute, err := linuxNodeHandler.lookupNodeRoute(net1)
   351  		c.Assert(err, check.IsNil)
   352  		c.Assert(foundRoute, check.IsNil)
   353  	}
   354  
   355  	if s.enableIPv6 {
   356  		foundRoute, err := linuxNodeHandler.lookupNodeRoute(net2)
   357  		c.Assert(err, check.IsNil)
   358  		c.Assert(foundRoute, check.Not(check.IsNil))
   359  	}
   360  }
   361  
   362  func (s *linuxPrivilegedBaseTestSuite) TestNodeUpdateEncapsulation(c *check.C) {
   363  	ip4Alloc1 := cidr.MustParseCIDR("5.5.5.0/24")
   364  	ip4Alloc2 := cidr.MustParseCIDR("6.6.6.0/24")
   365  	ip6Alloc1 := cidr.MustParseCIDR("2001:aaaa::/96")
   366  	ip6Alloc2 := cidr.MustParseCIDR("2001:bbbb::/96")
   367  
   368  	externalNodeIP1 := net.ParseIP("4.4.4.4")
   369  	externalNodeIP2 := net.ParseIP("8.8.8.8")
   370  
   371  	dpConfig := DatapathConfiguration{HostDevice: dummyHostDeviceName}
   372  	linuxNodeHandler := NewNodeHandler(dpConfig, s.nodeAddressing).(*linuxNodeHandler)
   373  	c.Assert(linuxNodeHandler, check.Not(check.IsNil))
   374  	nodeConfig := datapath.LocalNodeConfiguration{
   375  		EnableIPv4:          s.enableIPv4,
   376  		EnableIPv6:          s.enableIPv6,
   377  		EnableEncapsulation: true,
   378  	}
   379  
   380  	err := linuxNodeHandler.NodeConfigurationChanged(nodeConfig)
   381  	c.Assert(err, check.IsNil)
   382  
   383  	// nodev1: ip4Alloc1, ip6alloc1 => externalNodeIP1
   384  	nodev1 := node.Node{
   385  		Name: "node1",
   386  		IPAddresses: []node.Address{
   387  			{IP: externalNodeIP1, Type: nodeaddressing.NodeInternalIP},
   388  		},
   389  	}
   390  
   391  	if s.enableIPv4 {
   392  		nodev1.IPv4AllocCIDR = ip4Alloc1
   393  	}
   394  	if s.enableIPv6 {
   395  		nodev1.IPv6AllocCIDR = ip6Alloc1
   396  	}
   397  
   398  	err = linuxNodeHandler.NodeAdd(nodev1)
   399  	c.Assert(err, check.IsNil)
   400  
   401  	if s.enableIPv4 {
   402  		underlayIP, err := tunnel.TunnelMap.GetTunnelEndpoint(ip4Alloc1.IP)
   403  		c.Assert(err, check.IsNil)
   404  		c.Assert(underlayIP.Equal(externalNodeIP1), check.Equals, true)
   405  
   406  		foundRoute, err := linuxNodeHandler.lookupNodeRoute(ip4Alloc1)
   407  		c.Assert(err, check.IsNil)
   408  		c.Assert(foundRoute, check.Not(check.IsNil))
   409  	}
   410  
   411  	if s.enableIPv6 {
   412  		underlayIP, err := tunnel.TunnelMap.GetTunnelEndpoint(ip6Alloc1.IP)
   413  		c.Assert(err, check.IsNil)
   414  		c.Assert(underlayIP.Equal(externalNodeIP1), check.Equals, true)
   415  
   416  		foundRoute, err := linuxNodeHandler.lookupNodeRoute(ip6Alloc1)
   417  		c.Assert(err, check.IsNil)
   418  		c.Assert(foundRoute, check.Not(check.IsNil))
   419  	}
   420  
   421  	// nodev2: ip4Alloc1, ip6alloc1 => externalNodeIP2
   422  	nodev2 := node.Node{
   423  		Name: "node1",
   424  		IPAddresses: []node.Address{
   425  			{IP: externalNodeIP2, Type: nodeaddressing.NodeInternalIP},
   426  		},
   427  	}
   428  
   429  	if s.enableIPv4 {
   430  		nodev2.IPv4AllocCIDR = ip4Alloc1
   431  	}
   432  	if s.enableIPv6 {
   433  		nodev2.IPv6AllocCIDR = ip6Alloc1
   434  	}
   435  
   436  	err = linuxNodeHandler.NodeUpdate(nodev1, nodev2)
   437  	c.Assert(err, check.IsNil)
   438  
   439  	// alloc range v1 should map to underlay2
   440  	if s.enableIPv4 {
   441  		underlayIP, err := tunnel.TunnelMap.GetTunnelEndpoint(ip4Alloc1.IP)
   442  		c.Assert(err, check.IsNil)
   443  		c.Assert(underlayIP.Equal(externalNodeIP2), check.Equals, true)
   444  
   445  		foundRoute, err := linuxNodeHandler.lookupNodeRoute(ip4Alloc1)
   446  		c.Assert(err, check.IsNil)
   447  		c.Assert(foundRoute, check.Not(check.IsNil))
   448  	}
   449  
   450  	if s.enableIPv6 {
   451  		underlayIP, err := tunnel.TunnelMap.GetTunnelEndpoint(ip6Alloc1.IP)
   452  		c.Assert(err, check.IsNil)
   453  		c.Assert(underlayIP.Equal(externalNodeIP2), check.Equals, true)
   454  
   455  		foundRoute, err := linuxNodeHandler.lookupNodeRoute(ip6Alloc1)
   456  		c.Assert(err, check.IsNil)
   457  		c.Assert(foundRoute, check.Not(check.IsNil))
   458  	}
   459  
   460  	// nodev3: ip4Alloc2, ip6alloc2 => externalNodeIP1
   461  	nodev3 := node.Node{
   462  		Name: "node1",
   463  		IPAddresses: []node.Address{
   464  			{IP: externalNodeIP1, Type: nodeaddressing.NodeInternalIP},
   465  		},
   466  	}
   467  
   468  	if s.enableIPv4 {
   469  		nodev3.IPv4AllocCIDR = ip4Alloc2
   470  	}
   471  	if s.enableIPv6 {
   472  		nodev3.IPv6AllocCIDR = ip6Alloc2
   473  	}
   474  
   475  	err = linuxNodeHandler.NodeUpdate(nodev2, nodev3)
   476  	c.Assert(err, check.IsNil)
   477  
   478  	// alloc range v1 should fail
   479  	underlayIP, err := tunnel.TunnelMap.GetTunnelEndpoint(ip4Alloc1.IP)
   480  	c.Assert(err, check.Not(check.IsNil))
   481  
   482  	underlayIP, err = tunnel.TunnelMap.GetTunnelEndpoint(ip6Alloc1.IP)
   483  	c.Assert(err, check.Not(check.IsNil))
   484  
   485  	if s.enableIPv4 {
   486  		// alloc range v2 should map to underlay1
   487  		underlayIP, err := tunnel.TunnelMap.GetTunnelEndpoint(ip4Alloc2.IP)
   488  		c.Assert(err, check.IsNil)
   489  		c.Assert(underlayIP.Equal(externalNodeIP1), check.Equals, true)
   490  
   491  		// node routes for alloc1 ranges should be gone
   492  		foundRoute, err := linuxNodeHandler.lookupNodeRoute(ip4Alloc1)
   493  		c.Assert(err, check.IsNil)
   494  		c.Assert(foundRoute, check.IsNil)
   495  
   496  		// node routes for alloc2 ranges should have been installed
   497  		foundRoute, err = linuxNodeHandler.lookupNodeRoute(ip4Alloc2)
   498  		c.Assert(err, check.IsNil)
   499  		c.Assert(foundRoute, check.Not(check.IsNil))
   500  	}
   501  
   502  	if s.enableIPv6 {
   503  		// alloc range v2 should map to underlay1
   504  		underlayIP, err = tunnel.TunnelMap.GetTunnelEndpoint(ip6Alloc2.IP)
   505  		c.Assert(err, check.IsNil)
   506  		c.Assert(underlayIP.Equal(externalNodeIP1), check.Equals, true)
   507  
   508  		// node routes for alloc1 ranges should be gone
   509  		foundRoute, err := linuxNodeHandler.lookupNodeRoute(ip6Alloc1)
   510  		c.Assert(err, check.IsNil)
   511  		c.Assert(foundRoute, check.IsNil)
   512  
   513  		// node routes for alloc2 ranges should have been installed
   514  		foundRoute, err = linuxNodeHandler.lookupNodeRoute(ip6Alloc2)
   515  		c.Assert(err, check.IsNil)
   516  		c.Assert(foundRoute, check.Not(check.IsNil))
   517  	}
   518  
   519  	// nodev4: stop announcing CIDRs
   520  	nodev4 := node.Node{
   521  		Name: "node1",
   522  		IPAddresses: []node.Address{
   523  			{IP: externalNodeIP1, Type: nodeaddressing.NodeInternalIP},
   524  		},
   525  	}
   526  	err = linuxNodeHandler.NodeUpdate(nodev3, nodev4)
   527  	c.Assert(err, check.IsNil)
   528  
   529  	// alloc range v2 should fail
   530  	underlayIP, err = tunnel.TunnelMap.GetTunnelEndpoint(ip4Alloc2.IP)
   531  	c.Assert(err, check.Not(check.IsNil))
   532  
   533  	underlayIP, err = tunnel.TunnelMap.GetTunnelEndpoint(ip6Alloc2.IP)
   534  	c.Assert(err, check.Not(check.IsNil))
   535  
   536  	if s.enableIPv4 {
   537  		// node routes for alloc2 ranges should be gone
   538  		foundRoute, err := linuxNodeHandler.lookupNodeRoute(ip4Alloc2)
   539  		c.Assert(err, check.IsNil)
   540  		c.Assert(foundRoute, check.IsNil)
   541  	}
   542  
   543  	if s.enableIPv6 {
   544  		// node routes for alloc2 ranges should be gone
   545  		foundRoute, err := linuxNodeHandler.lookupNodeRoute(ip6Alloc2)
   546  		c.Assert(err, check.IsNil)
   547  		c.Assert(foundRoute, check.IsNil)
   548  	}
   549  
   550  	// nodev5: re-announce CIDRs
   551  	nodev5 := node.Node{
   552  		Name: "node1",
   553  		IPAddresses: []node.Address{
   554  			{IP: externalNodeIP1, Type: nodeaddressing.NodeInternalIP},
   555  		},
   556  	}
   557  
   558  	if s.enableIPv4 {
   559  		nodev5.IPv4AllocCIDR = ip4Alloc2
   560  	}
   561  	if s.enableIPv6 {
   562  		nodev5.IPv6AllocCIDR = ip6Alloc2
   563  	}
   564  
   565  	err = linuxNodeHandler.NodeUpdate(nodev4, nodev5)
   566  	c.Assert(err, check.IsNil)
   567  
   568  	if s.enableIPv4 {
   569  		// alloc range v2 should map to underlay1
   570  		underlayIP, err := tunnel.TunnelMap.GetTunnelEndpoint(ip4Alloc2.IP)
   571  		c.Assert(err, check.IsNil)
   572  		c.Assert(underlayIP.Equal(externalNodeIP1), check.Equals, true)
   573  
   574  		// node routes for alloc2 ranges should have been installed
   575  		foundRoute, err := linuxNodeHandler.lookupNodeRoute(ip4Alloc2)
   576  		c.Assert(err, check.IsNil)
   577  		c.Assert(foundRoute, check.Not(check.IsNil))
   578  	}
   579  
   580  	if s.enableIPv6 {
   581  		// alloc range v2 should map to underlay1
   582  		underlayIP, err := tunnel.TunnelMap.GetTunnelEndpoint(ip6Alloc2.IP)
   583  		c.Assert(err, check.IsNil)
   584  		c.Assert(underlayIP.Equal(externalNodeIP1), check.Equals, true)
   585  
   586  		// node routes for alloc2 ranges should have been installed
   587  		foundRoute, err := linuxNodeHandler.lookupNodeRoute(ip6Alloc2)
   588  		c.Assert(err, check.IsNil)
   589  		c.Assert(foundRoute, check.Not(check.IsNil))
   590  	}
   591  
   592  	// delete nodev5
   593  	err = linuxNodeHandler.NodeDelete(nodev5)
   594  	c.Assert(err, check.IsNil)
   595  
   596  	// alloc range v1 should fail
   597  	underlayIP, err = tunnel.TunnelMap.GetTunnelEndpoint(ip4Alloc1.IP)
   598  	c.Assert(err, check.Not(check.IsNil))
   599  
   600  	underlayIP, err = tunnel.TunnelMap.GetTunnelEndpoint(ip6Alloc1.IP)
   601  	c.Assert(err, check.Not(check.IsNil))
   602  
   603  	// alloc range v2 should fail
   604  	underlayIP, err = tunnel.TunnelMap.GetTunnelEndpoint(ip4Alloc2.IP)
   605  	c.Assert(err, check.Not(check.IsNil))
   606  
   607  	underlayIP, err = tunnel.TunnelMap.GetTunnelEndpoint(ip6Alloc2.IP)
   608  	c.Assert(err, check.Not(check.IsNil))
   609  
   610  	if s.enableIPv4 {
   611  		// node routes for alloc2 ranges should be gone
   612  		foundRoute, err := linuxNodeHandler.lookupNodeRoute(ip4Alloc2)
   613  		c.Assert(err, check.IsNil)
   614  		c.Assert(foundRoute, check.IsNil)
   615  	}
   616  
   617  	if s.enableIPv6 {
   618  		// node routes for alloc2 ranges should be gone
   619  		foundRoute, err := linuxNodeHandler.lookupNodeRoute(ip6Alloc2)
   620  		c.Assert(err, check.IsNil)
   621  		c.Assert(foundRoute, check.IsNil)
   622  	}
   623  }
   624  
   625  func (s *linuxPrivilegedBaseTestSuite) TestNodeUpdateDirectRouting(c *check.C) {
   626  	ip4Alloc1 := cidr.MustParseCIDR("5.5.5.0/24")
   627  	ip4Alloc2 := cidr.MustParseCIDR("6.6.6.0/24")
   628  
   629  	externalNode1IP4v1 := net.ParseIP("4.4.4.4")
   630  	externalNode1IP4v2 := net.ParseIP("4.4.4.5")
   631  
   632  	externalNode1Device := "dummy_node1"
   633  	removeDevice(externalNode1Device)
   634  	err := setupDummyDevice(externalNode1Device, externalNode1IP4v1, net.ParseIP("face::1"))
   635  	c.Assert(err, check.IsNil)
   636  	defer removeDevice(externalNode1Device)
   637  
   638  	externalNode2Device := "dummy_node2"
   639  	removeDevice(externalNode2Device)
   640  	err = setupDummyDevice(externalNode2Device, externalNode1IP4v2, net.ParseIP("face::2"))
   641  	c.Assert(err, check.IsNil)
   642  	defer removeDevice(externalNode2Device)
   643  
   644  	dpConfig := DatapathConfiguration{HostDevice: dummyHostDeviceName}
   645  	linuxNodeHandler := NewNodeHandler(dpConfig, s.nodeAddressing).(*linuxNodeHandler)
   646  	c.Assert(linuxNodeHandler, check.Not(check.IsNil))
   647  	nodeConfig := datapath.LocalNodeConfiguration{
   648  		EnableIPv4:              s.enableIPv4,
   649  		EnableIPv6:              s.enableIPv6,
   650  		EnableAutoDirectRouting: true,
   651  	}
   652  
   653  	err = linuxNodeHandler.NodeConfigurationChanged(nodeConfig)
   654  	c.Assert(err, check.IsNil)
   655  
   656  	// nodev1: ip4Alloc1 => externalNodeIP1
   657  	nodev1 := node.Node{
   658  		Name: "node1",
   659  		IPAddresses: []node.Address{
   660  			{IP: externalNode1IP4v1, Type: nodeaddressing.NodeInternalIP},
   661  		},
   662  		IPv4AllocCIDR: ip4Alloc1,
   663  	}
   664  	err = linuxNodeHandler.NodeAdd(nodev1)
   665  	c.Assert(err, check.IsNil)
   666  
   667  	foundRoutes, err := linuxNodeHandler.lookupDirectRoute(ip4Alloc1, externalNode1IP4v1)
   668  	c.Assert(err, check.IsNil)
   669  	if s.enableIPv4 {
   670  		c.Assert(len(foundRoutes), check.Equals, 1)
   671  	} else {
   672  		c.Assert(len(foundRoutes), check.Equals, 0)
   673  	}
   674  
   675  	// nodev2: ip4Alloc1 => externalNodeIP2
   676  	nodev2 := node.Node{
   677  		Name: "node1",
   678  		IPAddresses: []node.Address{
   679  			{IP: externalNode1IP4v2, Type: nodeaddressing.NodeInternalIP},
   680  		},
   681  		IPv4AllocCIDR: ip4Alloc1,
   682  	}
   683  	err = linuxNodeHandler.NodeUpdate(nodev1, nodev2)
   684  	c.Assert(err, check.IsNil)
   685  
   686  	foundRoutes, err = linuxNodeHandler.lookupDirectRoute(ip4Alloc1, externalNode1IP4v2)
   687  	c.Assert(err, check.IsNil)
   688  	if s.enableIPv4 {
   689  		c.Assert(len(foundRoutes), check.Equals, 1)
   690  	} else {
   691  		c.Assert(len(foundRoutes), check.Equals, 0)
   692  	}
   693  
   694  	// nodev3: ip4Alloc2 => externalNodeIP2
   695  	nodev3 := node.Node{
   696  		Name: "node1",
   697  		IPAddresses: []node.Address{
   698  			{IP: externalNode1IP4v2, Type: nodeaddressing.NodeInternalIP},
   699  		},
   700  		IPv4AllocCIDR: ip4Alloc2,
   701  	}
   702  	err = linuxNodeHandler.NodeUpdate(nodev2, nodev3)
   703  	c.Assert(err, check.IsNil)
   704  
   705  	// node routes for alloc1 ranges should be gone
   706  	foundRoutes, err = linuxNodeHandler.lookupDirectRoute(ip4Alloc1, externalNode1IP4v2)
   707  	c.Assert(err, check.IsNil)
   708  	c.Assert(len(foundRoutes), check.Equals, 0) // route should not exist regardless whether ipv4 is enabled or not
   709  
   710  	// node routes for alloc2 ranges should have been installed
   711  	foundRoutes, err = linuxNodeHandler.lookupDirectRoute(ip4Alloc2, externalNode1IP4v2)
   712  	c.Assert(err, check.IsNil)
   713  	if s.enableIPv4 {
   714  		c.Assert(len(foundRoutes), check.Equals, 1)
   715  	} else {
   716  		c.Assert(len(foundRoutes), check.Equals, 0)
   717  	}
   718  
   719  	// nodev4: no longer announce CIDR
   720  	nodev4 := node.Node{
   721  		Name: "node1",
   722  		IPAddresses: []node.Address{
   723  			{IP: externalNode1IP4v2, Type: nodeaddressing.NodeInternalIP},
   724  		},
   725  	}
   726  	err = linuxNodeHandler.NodeUpdate(nodev3, nodev4)
   727  	c.Assert(err, check.IsNil)
   728  
   729  	// node routes for alloc2 ranges should have been removed
   730  	foundRoutes, err = linuxNodeHandler.lookupDirectRoute(ip4Alloc2, externalNode1IP4v2)
   731  	c.Assert(err, check.IsNil)
   732  	c.Assert(len(foundRoutes), check.Equals, 0)
   733  
   734  	// nodev5: Re-announce CIDR
   735  	nodev5 := node.Node{
   736  		Name: "node1",
   737  		IPAddresses: []node.Address{
   738  			{IP: externalNode1IP4v2, Type: nodeaddressing.NodeInternalIP},
   739  		},
   740  		IPv4AllocCIDR: ip4Alloc2,
   741  	}
   742  	err = linuxNodeHandler.NodeUpdate(nodev4, nodev5)
   743  	c.Assert(err, check.IsNil)
   744  
   745  	// node routes for alloc2 ranges should have been removed
   746  	foundRoutes, err = linuxNodeHandler.lookupDirectRoute(ip4Alloc2, externalNode1IP4v2)
   747  	c.Assert(err, check.IsNil)
   748  	if s.enableIPv4 {
   749  		c.Assert(len(foundRoutes), check.Equals, 1)
   750  	} else {
   751  		c.Assert(len(foundRoutes), check.Equals, 0)
   752  	}
   753  
   754  	// delete nodev5
   755  	err = linuxNodeHandler.NodeDelete(nodev5)
   756  	c.Assert(err, check.IsNil)
   757  
   758  	// node routes for alloc2 ranges should be gone
   759  	foundRoutes, err = linuxNodeHandler.lookupDirectRoute(ip4Alloc2, externalNode1IP4v2)
   760  	c.Assert(err, check.IsNil)
   761  	c.Assert(len(foundRoutes), check.Equals, 0) // route should not exist regardless whether ipv4 is enabled or not
   762  }
   763  
   764  func (s *linuxPrivilegedBaseTestSuite) TestAgentRestartOptionChanges(c *check.C) {
   765  	ip4Alloc1 := cidr.MustParseCIDR("5.5.5.0/24")
   766  	ip6Alloc1 := cidr.MustParseCIDR("2001:aaaa::/96")
   767  	underlayIP := net.ParseIP("4.4.4.4")
   768  
   769  	dpConfig := DatapathConfiguration{HostDevice: dummyHostDeviceName}
   770  	linuxNodeHandler := NewNodeHandler(dpConfig, s.nodeAddressing).(*linuxNodeHandler)
   771  	c.Assert(linuxNodeHandler, check.Not(check.IsNil))
   772  	nodeConfig := datapath.LocalNodeConfiguration{
   773  		EnableIPv4:          s.enableIPv4,
   774  		EnableIPv6:          s.enableIPv6,
   775  		EnableEncapsulation: true,
   776  	}
   777  
   778  	err := linuxNodeHandler.NodeConfigurationChanged(nodeConfig)
   779  	c.Assert(err, check.IsNil)
   780  
   781  	nodev1 := node.Node{
   782  		Name: "node1",
   783  		IPAddresses: []node.Address{
   784  			{IP: underlayIP, Type: nodeaddressing.NodeInternalIP},
   785  		},
   786  	}
   787  
   788  	if s.enableIPv6 {
   789  		nodev1.IPv6AllocCIDR = ip6Alloc1
   790  	}
   791  
   792  	if s.enableIPv4 {
   793  		nodev1.IPv4AllocCIDR = ip4Alloc1
   794  	}
   795  
   796  	err = linuxNodeHandler.NodeAdd(nodev1)
   797  	c.Assert(err, check.IsNil)
   798  
   799  	// tunnel map entries must exist
   800  	if s.enableIPv4 {
   801  		_, err = tunnel.TunnelMap.GetTunnelEndpoint(ip4Alloc1.IP)
   802  		c.Assert(err, check.IsNil)
   803  	}
   804  	if s.enableIPv6 {
   805  		_, err = tunnel.TunnelMap.GetTunnelEndpoint(ip6Alloc1.IP)
   806  		c.Assert(err, check.IsNil)
   807  	}
   808  
   809  	// Simulate agent restart with address families disables
   810  	err = linuxNodeHandler.NodeConfigurationChanged(datapath.LocalNodeConfiguration{
   811  		EnableIPv6:          false,
   812  		EnableIPv4:          false,
   813  		EnableEncapsulation: true,
   814  	})
   815  	c.Assert(err, check.IsNil)
   816  
   817  	// Simulate initial node addition
   818  	err = linuxNodeHandler.NodeAdd(nodev1)
   819  	c.Assert(err, check.IsNil)
   820  
   821  	// tunnel map entries should have been removed
   822  	_, err = tunnel.TunnelMap.GetTunnelEndpoint(ip4Alloc1.IP)
   823  	c.Assert(err, check.Not(check.IsNil))
   824  	_, err = tunnel.TunnelMap.GetTunnelEndpoint(ip6Alloc1.IP)
   825  	c.Assert(err, check.Not(check.IsNil))
   826  
   827  	// Simulate agent restart with address families enabled again
   828  	err = linuxNodeHandler.NodeConfigurationChanged(datapath.LocalNodeConfiguration{
   829  		EnableIPv4:          s.enableIPv4,
   830  		EnableIPv6:          s.enableIPv6,
   831  		EnableEncapsulation: true,
   832  	})
   833  	c.Assert(err, check.IsNil)
   834  
   835  	// Simulate initial node addition
   836  	err = linuxNodeHandler.NodeAdd(nodev1)
   837  	c.Assert(err, check.IsNil)
   838  
   839  	// tunnel map entries must exist
   840  	if s.enableIPv4 {
   841  		_, err = tunnel.TunnelMap.GetTunnelEndpoint(ip4Alloc1.IP)
   842  		c.Assert(err, check.IsNil)
   843  	}
   844  	if s.enableIPv6 {
   845  		_, err = tunnel.TunnelMap.GetTunnelEndpoint(ip6Alloc1.IP)
   846  		c.Assert(err, check.IsNil)
   847  	}
   848  
   849  	err = linuxNodeHandler.NodeDelete(nodev1)
   850  	c.Assert(err, check.IsNil)
   851  }
   852  
   853  func insertFakeRoute(c *check.C, n *linuxNodeHandler, prefix *cidr.CIDR) {
   854  	nodeRoute, err := n.createNodeRoute(prefix)
   855  	c.Assert(err, check.IsNil)
   856  
   857  	nodeRoute.Device = dummyExternalDeviceName
   858  
   859  	_, err = route.Upsert(nodeRoute)
   860  	c.Assert(err, check.IsNil)
   861  }
   862  
   863  func lookupFakeRoute(c *check.C, n *linuxNodeHandler, prefix *cidr.CIDR) bool {
   864  	routeSpec, err := n.createNodeRoute(prefix)
   865  	c.Assert(err, check.IsNil)
   866  
   867  	routeSpec.Device = dummyExternalDeviceName
   868  	rt, err := route.Lookup(routeSpec)
   869  	c.Assert(err, check.IsNil)
   870  	return rt != nil
   871  }
   872  
   873  func (s *linuxPrivilegedBaseTestSuite) TestNodeValidationDirectRouting(c *check.C) {
   874  	ip4Alloc1 := cidr.MustParseCIDR("5.5.5.0/24")
   875  	ip6Alloc1 := cidr.MustParseCIDR("2001:aaaa::/96")
   876  	dpConfig := DatapathConfiguration{HostDevice: dummyHostDeviceName}
   877  	linuxNodeHandler := NewNodeHandler(dpConfig, s.nodeAddressing).(*linuxNodeHandler)
   878  	c.Assert(linuxNodeHandler, check.Not(check.IsNil))
   879  
   880  	if s.enableIPv4 {
   881  		insertFakeRoute(c, linuxNodeHandler, ip4Alloc1)
   882  	}
   883  
   884  	if s.enableIPv6 {
   885  		insertFakeRoute(c, linuxNodeHandler, ip6Alloc1)
   886  	}
   887  
   888  	err := linuxNodeHandler.NodeConfigurationChanged(datapath.LocalNodeConfiguration{
   889  		EnableEncapsulation: false,
   890  		EnableIPv4:          s.enableIPv4,
   891  		EnableIPv6:          s.enableIPv6,
   892  	})
   893  	c.Assert(err, check.IsNil)
   894  
   895  	nodev1 := node.Node{
   896  		Name:        "node1",
   897  		IPAddresses: []node.Address{},
   898  	}
   899  
   900  	if s.enableIPv4 {
   901  		nodev1.IPAddresses = append(nodev1.IPAddresses, node.Address{
   902  			IP:   s.nodeAddressing.IPv4().PrimaryExternal(),
   903  			Type: nodeaddressing.NodeInternalIP,
   904  		})
   905  		nodev1.IPv4AllocCIDR = ip4Alloc1
   906  	}
   907  
   908  	if s.enableIPv6 {
   909  		nodev1.IPAddresses = append(nodev1.IPAddresses, node.Address{
   910  			IP:   s.nodeAddressing.IPv6().PrimaryExternal(),
   911  			Type: nodeaddressing.NodeInternalIP,
   912  		})
   913  		nodev1.IPv6AllocCIDR = ip6Alloc1
   914  	}
   915  
   916  	err = linuxNodeHandler.NodeAdd(nodev1)
   917  	c.Assert(err, check.IsNil)
   918  
   919  	err = linuxNodeHandler.NodeValidateImplementation(nodev1)
   920  	c.Assert(err, check.IsNil)
   921  
   922  	if s.enableIPv4 {
   923  		c.Assert(lookupFakeRoute(c, linuxNodeHandler, ip4Alloc1), check.Equals, true)
   924  	}
   925  
   926  	if s.enableIPv6 {
   927  		c.Assert(lookupFakeRoute(c, linuxNodeHandler, ip6Alloc1), check.Equals, true)
   928  	}
   929  }
   930  
   931  func (s *linuxPrivilegedBaseTestSuite) benchmarkNodeUpdate(c *check.C, config datapath.LocalNodeConfiguration) {
   932  	ip4Alloc1 := cidr.MustParseCIDR("5.5.5.0/24")
   933  	ip4Alloc2 := cidr.MustParseCIDR("6.6.6.0/24")
   934  	ip6Alloc1 := cidr.MustParseCIDR("2001:aaaa::/96")
   935  	ip6Alloc2 := cidr.MustParseCIDR("2001:bbbb::/96")
   936  
   937  	dpConfig := DatapathConfiguration{HostDevice: dummyHostDeviceName}
   938  	linuxNodeHandler := NewNodeHandler(dpConfig, s.nodeAddressing).(*linuxNodeHandler)
   939  	c.Assert(linuxNodeHandler, check.Not(check.IsNil))
   940  
   941  	err := linuxNodeHandler.NodeConfigurationChanged(config)
   942  	c.Assert(err, check.IsNil)
   943  
   944  	nodev1 := node.Node{
   945  		Name:        "node1",
   946  		IPAddresses: []node.Address{},
   947  	}
   948  
   949  	if s.enableIPv4 {
   950  		nodev1.IPAddresses = append(nodev1.IPAddresses, node.Address{
   951  			IP:   s.nodeAddressing.IPv4().PrimaryExternal(),
   952  			Type: nodeaddressing.NodeInternalIP,
   953  		})
   954  		nodev1.IPv4AllocCIDR = ip4Alloc1
   955  	}
   956  
   957  	if s.enableIPv6 {
   958  		nodev1.IPAddresses = append(nodev1.IPAddresses, node.Address{
   959  			IP:   s.nodeAddressing.IPv6().PrimaryExternal(),
   960  			Type: nodeaddressing.NodeInternalIP,
   961  		})
   962  		nodev1.IPv6AllocCIDR = ip6Alloc1
   963  	}
   964  
   965  	nodev2 := node.Node{
   966  		Name:        "node1",
   967  		IPAddresses: []node.Address{},
   968  	}
   969  
   970  	if s.enableIPv4 {
   971  		nodev2.IPAddresses = append(nodev2.IPAddresses, node.Address{
   972  			IP:   s.nodeAddressing.IPv4().PrimaryExternal(),
   973  			Type: nodeaddressing.NodeInternalIP,
   974  		})
   975  		nodev2.IPv4AllocCIDR = ip4Alloc2
   976  	}
   977  
   978  	if s.enableIPv6 {
   979  		nodev2.IPAddresses = append(nodev2.IPAddresses, node.Address{
   980  			IP:   s.nodeAddressing.IPv6().PrimaryExternal(),
   981  			Type: nodeaddressing.NodeInternalIP,
   982  		})
   983  		nodev2.IPv6AllocCIDR = ip6Alloc2
   984  	}
   985  
   986  	err = linuxNodeHandler.NodeAdd(nodev1)
   987  	c.Assert(err, check.IsNil)
   988  
   989  	oldNode := nodev1
   990  	newNode := nodev2
   991  
   992  	c.ResetTimer()
   993  	for i := 0; i < c.N; i++ {
   994  		err = linuxNodeHandler.NodeUpdate(oldNode, newNode)
   995  		c.Assert(err, check.IsNil)
   996  
   997  		tmp := oldNode
   998  		oldNode = newNode
   999  		newNode = tmp
  1000  	}
  1001  	c.StopTimer()
  1002  
  1003  	err = linuxNodeHandler.NodeDelete(oldNode)
  1004  	c.Assert(err, check.IsNil)
  1005  }
  1006  
  1007  func (s *linuxPrivilegedBaseTestSuite) BenchmarkNodeUpdate(c *check.C) {
  1008  	s.benchmarkNodeUpdate(c, datapath.LocalNodeConfiguration{
  1009  		EnableIPv4: s.enableIPv4,
  1010  		EnableIPv6: s.enableIPv6,
  1011  	})
  1012  }
  1013  
  1014  func (s *linuxPrivilegedBaseTestSuite) BenchmarkNodeUpdateEncap(c *check.C) {
  1015  	s.benchmarkNodeUpdate(c, datapath.LocalNodeConfiguration{
  1016  		EnableIPv4:          s.enableIPv4,
  1017  		EnableIPv6:          s.enableIPv6,
  1018  		EnableEncapsulation: true,
  1019  	})
  1020  }
  1021  
  1022  func (s *linuxPrivilegedBaseTestSuite) BenchmarkNodeUpdateEncapSingleClusterRoute(c *check.C) {
  1023  	s.benchmarkNodeUpdate(c, datapath.LocalNodeConfiguration{
  1024  		EnableIPv4:            s.enableIPv4,
  1025  		EnableIPv6:            s.enableIPv6,
  1026  		EnableEncapsulation:   true,
  1027  		UseSingleClusterRoute: true,
  1028  	})
  1029  }
  1030  
  1031  func (s *linuxPrivilegedBaseTestSuite) BenchmarkNodeUpdateDirectRoute(c *check.C) {
  1032  	s.benchmarkNodeUpdate(c, datapath.LocalNodeConfiguration{
  1033  		EnableIPv4:              s.enableIPv4,
  1034  		EnableIPv6:              s.enableIPv6,
  1035  		EnableAutoDirectRouting: true,
  1036  	})
  1037  }
  1038  
  1039  func (s *linuxPrivilegedBaseTestSuite) benchmarkNodeUpdateNOP(c *check.C, config datapath.LocalNodeConfiguration) {
  1040  	ip4Alloc1 := cidr.MustParseCIDR("5.5.5.0/24")
  1041  	ip6Alloc1 := cidr.MustParseCIDR("2001:aaaa::/96")
  1042  
  1043  	dpConfig := DatapathConfiguration{HostDevice: dummyHostDeviceName}
  1044  	linuxNodeHandler := NewNodeHandler(dpConfig, s.nodeAddressing).(*linuxNodeHandler)
  1045  	c.Assert(linuxNodeHandler, check.Not(check.IsNil))
  1046  
  1047  	err := linuxNodeHandler.NodeConfigurationChanged(config)
  1048  	c.Assert(err, check.IsNil)
  1049  
  1050  	nodev1 := node.Node{
  1051  		Name:        "node1",
  1052  		IPAddresses: []node.Address{},
  1053  	}
  1054  
  1055  	if s.enableIPv4 {
  1056  		nodev1.IPAddresses = append(nodev1.IPAddresses, node.Address{
  1057  			IP:   s.nodeAddressing.IPv4().PrimaryExternal(),
  1058  			Type: nodeaddressing.NodeInternalIP,
  1059  		})
  1060  		nodev1.IPv4AllocCIDR = ip4Alloc1
  1061  	}
  1062  
  1063  	if s.enableIPv6 {
  1064  		nodev1.IPAddresses = append(nodev1.IPAddresses, node.Address{
  1065  			IP:   s.nodeAddressing.IPv6().PrimaryExternal(),
  1066  			Type: nodeaddressing.NodeInternalIP,
  1067  		})
  1068  		nodev1.IPv6AllocCIDR = ip6Alloc1
  1069  	}
  1070  
  1071  	err = linuxNodeHandler.NodeAdd(nodev1)
  1072  	c.Assert(err, check.IsNil)
  1073  
  1074  	c.ResetTimer()
  1075  	for i := 0; i < c.N; i++ {
  1076  		err = linuxNodeHandler.NodeUpdate(nodev1, nodev1)
  1077  		c.Assert(err, check.IsNil)
  1078  	}
  1079  	c.StopTimer()
  1080  
  1081  	err = linuxNodeHandler.NodeDelete(nodev1)
  1082  	c.Assert(err, check.IsNil)
  1083  }
  1084  
  1085  func (s *linuxPrivilegedBaseTestSuite) BenchmarkNoChangeNodeUpdate(c *check.C) {
  1086  	s.benchmarkNodeUpdateNOP(c, datapath.LocalNodeConfiguration{
  1087  		EnableIPv4: s.enableIPv4,
  1088  		EnableIPv6: s.enableIPv6,
  1089  	})
  1090  }
  1091  
  1092  func (s *linuxPrivilegedBaseTestSuite) BenchmarkNoChangeNodeUpdateEncapAll(c *check.C) {
  1093  	s.benchmarkNodeUpdateNOP(c, datapath.LocalNodeConfiguration{
  1094  		EnableIPv4:          s.enableIPv4,
  1095  		EnableIPv6:          s.enableIPv6,
  1096  		EnableEncapsulation: true,
  1097  	})
  1098  }
  1099  
  1100  func (s *linuxPrivilegedBaseTestSuite) BenchmarkNoChangeNodeUpdateDirectRouteAll(c *check.C) {
  1101  	s.benchmarkNodeUpdateNOP(c, datapath.LocalNodeConfiguration{
  1102  		EnableIPv4:              s.enableIPv4,
  1103  		EnableIPv6:              s.enableIPv6,
  1104  		EnableAutoDirectRouting: true,
  1105  	})
  1106  }
  1107  
  1108  func (s *linuxPrivilegedBaseTestSuite) benchmarkNodeValidateImplementation(c *check.C, config datapath.LocalNodeConfiguration) {
  1109  	ip4Alloc1 := cidr.MustParseCIDR("5.5.5.0/24")
  1110  	ip6Alloc1 := cidr.MustParseCIDR("2001:aaaa::/96")
  1111  
  1112  	dpConfig := DatapathConfiguration{HostDevice: dummyHostDeviceName}
  1113  	linuxNodeHandler := NewNodeHandler(dpConfig, s.nodeAddressing).(*linuxNodeHandler)
  1114  	c.Assert(linuxNodeHandler, check.Not(check.IsNil))
  1115  
  1116  	err := linuxNodeHandler.NodeConfigurationChanged(config)
  1117  	c.Assert(err, check.IsNil)
  1118  
  1119  	nodev1 := node.Node{
  1120  		Name:        "node1",
  1121  		IPAddresses: []node.Address{},
  1122  	}
  1123  
  1124  	if s.enableIPv4 {
  1125  		nodev1.IPAddresses = append(nodev1.IPAddresses, node.Address{
  1126  			IP:   s.nodeAddressing.IPv4().PrimaryExternal(),
  1127  			Type: nodeaddressing.NodeInternalIP,
  1128  		})
  1129  		nodev1.IPv4AllocCIDR = ip4Alloc1
  1130  	}
  1131  
  1132  	if s.enableIPv6 {
  1133  		nodev1.IPAddresses = append(nodev1.IPAddresses, node.Address{
  1134  			IP:   s.nodeAddressing.IPv6().PrimaryExternal(),
  1135  			Type: nodeaddressing.NodeInternalIP,
  1136  		})
  1137  		nodev1.IPv6AllocCIDR = ip6Alloc1
  1138  	}
  1139  
  1140  	err = linuxNodeHandler.NodeAdd(nodev1)
  1141  	c.Assert(err, check.IsNil)
  1142  
  1143  	c.ResetTimer()
  1144  	for i := 0; i < c.N; i++ {
  1145  		err = linuxNodeHandler.NodeValidateImplementation(nodev1)
  1146  		c.Assert(err, check.IsNil)
  1147  	}
  1148  	c.StopTimer()
  1149  
  1150  	err = linuxNodeHandler.NodeDelete(nodev1)
  1151  	c.Assert(err, check.IsNil)
  1152  }
  1153  
  1154  func (s *linuxPrivilegedBaseTestSuite) BenchmarkNodeValidateImplementation(c *check.C) {
  1155  	s.benchmarkNodeValidateImplementation(c, datapath.LocalNodeConfiguration{
  1156  		EnableIPv4: s.enableIPv4,
  1157  		EnableIPv6: s.enableIPv6,
  1158  	})
  1159  }
  1160  
  1161  func (s *linuxPrivilegedBaseTestSuite) BenchmarkNodeValidateImplementationEncap(c *check.C) {
  1162  	s.benchmarkNodeValidateImplementation(c, datapath.LocalNodeConfiguration{
  1163  		EnableIPv4:          s.enableIPv4,
  1164  		EnableIPv6:          s.enableIPv6,
  1165  		EnableEncapsulation: true,
  1166  	})
  1167  }
  1168  
  1169  func (s *linuxPrivilegedBaseTestSuite) BenchmarkNodeValidateImplementationEncapSingleCluster(c *check.C) {
  1170  	s.benchmarkNodeValidateImplementation(c, datapath.LocalNodeConfiguration{
  1171  		EnableIPv4:            s.enableIPv4,
  1172  		EnableIPv6:            s.enableIPv6,
  1173  		EnableEncapsulation:   true,
  1174  		UseSingleClusterRoute: true,
  1175  	})
  1176  }
  1177  
  1178  func (s *linuxPrivilegedBaseTestSuite) BenchmarkNodeValidateImplementationDirectRoute(c *check.C) {
  1179  	s.benchmarkNodeValidateImplementation(c, datapath.LocalNodeConfiguration{
  1180  		EnableIPv4:              s.enableIPv4,
  1181  		EnableIPv6:              s.enableIPv6,
  1182  		EnableAutoDirectRouting: true,
  1183  	})
  1184  }