github.com/cilium/cilium@v1.16.2/pkg/datapath/linux/node_test.go (about)

     1  // SPDX-License-Identifier: Apache-2.0
     2  // Copyright Authors of Cilium
     3  
     4  package linux
     5  
     6  import (
     7  	"net"
     8  	"testing"
     9  
    10  	"github.com/cilium/hive/hivetest"
    11  	"github.com/stretchr/testify/assert"
    12  	"github.com/stretchr/testify/require"
    13  	"github.com/vishvananda/netlink"
    14  	"golang.org/x/sys/unix"
    15  
    16  	"github.com/cilium/cilium/pkg/cidr"
    17  	cmtypes "github.com/cilium/cilium/pkg/clustermesh/types"
    18  	fakeTypes "github.com/cilium/cilium/pkg/datapath/fake/types"
    19  	"github.com/cilium/cilium/pkg/datapath/linux/linux_defaults"
    20  	"github.com/cilium/cilium/pkg/datapath/linux/route"
    21  	datapath "github.com/cilium/cilium/pkg/datapath/types"
    22  	"github.com/cilium/cilium/pkg/mtu"
    23  	"github.com/cilium/cilium/pkg/testutils"
    24  	"github.com/cilium/cilium/pkg/testutils/netns"
    25  )
    26  
    27  var (
    28  	fakeNodeAddressing = fakeTypes.NewNodeAddressing()
    29  
    30  	nodeConfig = datapath.LocalNodeConfiguration{
    31  		NodeIPv4:            fakeNodeAddressing.IPv4().PrimaryExternal(),
    32  		NodeIPv6:            fakeNodeAddressing.IPv6().PrimaryExternal(),
    33  		CiliumInternalIPv4:  fakeNodeAddressing.IPv4().Router(),
    34  		CiliumInternalIPv6:  fakeNodeAddressing.IPv6().Router(),
    35  		DeviceMTU:           mtuConfig.GetDeviceMTU(),
    36  		RouteMTU:            mtuConfig.GetRouteMTU(),
    37  		RoutePostEncryptMTU: mtuConfig.GetRoutePostEncryptMTU(),
    38  	}
    39  	mtuConfig = mtu.NewConfiguration(0, false, false, false, false, 100, net.IP("1.1.1.1"), false)
    40  	nh        = linuxNodeHandler{
    41  		nodeConfig: nodeConfig,
    42  		datapathConfig: DatapathConfiguration{
    43  			HostDevice: "host_device",
    44  		},
    45  	}
    46  	cr1 = cidr.MustParseCIDR("10.1.0.0/16")
    47  )
    48  
    49  func TestTunnelCIDRUpdateRequired(t *testing.T) {
    50  	nilPrefixCluster := cmtypes.PrefixCluster{}
    51  	c1 := cmtypes.PrefixClusterFromCIDR(cidr.MustParseCIDR("10.1.0.0/16"))
    52  	c2 := cmtypes.PrefixClusterFromCIDR(cidr.MustParseCIDR("10.2.0.0/16"))
    53  	ip1 := net.ParseIP("1.1.1.1")
    54  	ip2 := net.ParseIP("2.2.2.2")
    55  
    56  	require.Equal(t, false, cidrNodeMappingUpdateRequired(nilPrefixCluster, nilPrefixCluster, ip1, ip1, 0, 0)) // disabled -> disabled
    57  	require.Equal(t, true, cidrNodeMappingUpdateRequired(nilPrefixCluster, c1, ip1, ip1, 0, 0))                // disabled -> c1
    58  	require.Equal(t, false, cidrNodeMappingUpdateRequired(c1, c1, ip1, ip1, 0, 0))                             // c1 -> c1
    59  	require.Equal(t, true, cidrNodeMappingUpdateRequired(c1, c1, ip1, ip2, 0, 0))                              // c1 -> c1 (changed host IP, cidrNodeMappingUpdateRequired(c1, c1, ip1, ip2, 0, 0))
    60  	require.Equal(t, true, cidrNodeMappingUpdateRequired(c1, c2, ip2, ip2, 0, 0))                              // c1 -> c2
    61  	require.Equal(t, false, cidrNodeMappingUpdateRequired(c2, nilPrefixCluster, ip2, ip2, 0, 0))               // c2 -> disabled
    62  	require.Equal(t, true, cidrNodeMappingUpdateRequired(c1, c1, ip1, ip1, 0, 1))                              // key upgrade 0 -> 1
    63  	require.Equal(t, true, cidrNodeMappingUpdateRequired(c1, c1, ip1, ip1, 1, 0))                              // key downgrade 1 -> 0
    64  
    65  	c1 = cmtypes.PrefixClusterFromCIDR(cidr.MustParseCIDR("f00d::a0a:0:0:0/96"))
    66  	c2 = cmtypes.PrefixClusterFromCIDR(cidr.MustParseCIDR("f00d::b0b:0:0:0/96"))
    67  	ip1 = net.ParseIP("cafe::1")
    68  	ip2 = net.ParseIP("cafe::2")
    69  
    70  	require.Equal(t, false, cidrNodeMappingUpdateRequired(nilPrefixCluster, nilPrefixCluster, ip1, ip1, 0, 0)) // disabled -> disabled
    71  	require.Equal(t, true, cidrNodeMappingUpdateRequired(nilPrefixCluster, c1, ip1, ip1, 0, 0))                // disabled -> c1
    72  	require.Equal(t, false, cidrNodeMappingUpdateRequired(c1, c1, ip1, ip1, 0, 0))                             // c1 -> c1
    73  	require.Equal(t, true, cidrNodeMappingUpdateRequired(c1, c1, ip1, ip2, 0, 0))                              // c1 -> c1 (changed host IP, cidrNodeMappingUpdateRequired(c1, c1, ip1, ip2, 0, 0))
    74  	require.Equal(t, true, cidrNodeMappingUpdateRequired(c1, c2, ip2, ip2, 0, 0))                              // c1 -> c2
    75  	require.Equal(t, false, cidrNodeMappingUpdateRequired(c2, nilPrefixCluster, ip2, ip2, 0, 0))               // c2 -> disabled
    76  	require.Equal(t, true, cidrNodeMappingUpdateRequired(c1, c1, ip1, ip1, 0, 1))                              // key upgrade 0 -> 1
    77  	require.Equal(t, true, cidrNodeMappingUpdateRequired(c1, c1, ip1, ip1, 1, 0))                              // key downgrade 1 -> 0
    78  }
    79  
    80  func TestCreateNodeRoute(t *testing.T) {
    81  	dpConfig := DatapathConfiguration{
    82  		HostDevice: "host_device",
    83  	}
    84  	log := hivetest.Logger(t)
    85  
    86  	nodeHandler := newNodeHandler(log, dpConfig, nil, new(mockEnqueuer))
    87  	nodeHandler.NodeConfigurationChanged(nodeConfig)
    88  
    89  	c1 := cidr.MustParseCIDR("10.10.0.0/16")
    90  	generatedRoute, err := nodeHandler.createNodeRouteSpec(c1, false)
    91  	require.NoError(t, err)
    92  	require.EqualValues(t, *c1.IPNet, generatedRoute.Prefix)
    93  	require.Equal(t, dpConfig.HostDevice, generatedRoute.Device)
    94  	require.EqualValues(t, fakeNodeAddressing.IPv4().Router(), *generatedRoute.Nexthop)
    95  	require.EqualValues(t, fakeNodeAddressing.IPv4().Router(), generatedRoute.Local)
    96  
    97  	c1 = cidr.MustParseCIDR("beef:beef::/48")
    98  	generatedRoute, err = nodeHandler.createNodeRouteSpec(c1, false)
    99  	require.NoError(t, err)
   100  	require.EqualValues(t, *c1.IPNet, generatedRoute.Prefix)
   101  	require.Equal(t, dpConfig.HostDevice, generatedRoute.Device)
   102  	require.Nil(t, generatedRoute.Nexthop)
   103  	require.EqualValues(t, fakeNodeAddressing.IPv6().Router(), generatedRoute.Local)
   104  }
   105  
   106  func TestCreateNodeRouteSpecMtu(t *testing.T) {
   107  	generatedRoute, err := nh.createNodeRouteSpec(cr1, false)
   108  
   109  	require.NoError(t, err)
   110  	require.NotEqual(t, 0, generatedRoute.MTU)
   111  
   112  	generatedRoute, err = nh.createNodeRouteSpec(cr1, true)
   113  
   114  	require.NoError(t, err)
   115  	require.Equal(t, 0, generatedRoute.MTU)
   116  }
   117  
   118  func TestStoreLoadNeighLinks(t *testing.T) {
   119  	tmpDir := t.TempDir()
   120  	devExpected := []string{"dev1"}
   121  	err := storeNeighLink(tmpDir, devExpected)
   122  	require.NoError(t, err)
   123  
   124  	devsActual, err := loadNeighLink(tmpDir)
   125  	require.NoError(t, err)
   126  	require.EqualValues(t, devsActual, devExpected)
   127  }
   128  
   129  func TestLocalRule(t *testing.T) {
   130  	testutils.PrivilegedTest(t)
   131  
   132  	ns := netns.NewNetNS(t)
   133  
   134  	test := func(t *testing.T) {
   135  		require.NoError(t, NodeEnsureLocalRoutingRule())
   136  
   137  		// Expect at least one rule in the netns, with the first entry at pref 100
   138  		// pointing at table 255.
   139  		rules, err := route.ListRules(netlink.FAMILY_V4, nil)
   140  		assert.NoError(t, err)
   141  		assert.GreaterOrEqual(t, len(rules), 1)
   142  		assert.Equal(t, rules[0].Priority, linux_defaults.RulePriorityLocalLookup)
   143  		assert.Equal(t, rules[0].Table, unix.RT_TABLE_LOCAL)
   144  
   145  		rules, err = route.ListRules(netlink.FAMILY_V6, nil)
   146  		assert.NoError(t, err)
   147  		assert.GreaterOrEqual(t, len(rules), 1)
   148  		assert.Equal(t, rules[0].Priority, linux_defaults.RulePriorityLocalLookup)
   149  		assert.Equal(t, rules[0].Table, unix.RT_TABLE_LOCAL)
   150  	}
   151  
   152  	ns.Do(func() error {
   153  		// Install rules the first time.
   154  		test(t)
   155  
   156  		// Ensure idempotency.
   157  		test(t)
   158  
   159  		return nil
   160  	})
   161  }