github.com/cilium/cilium@v1.16.2/bpf/tests/skip_lb_xlate_socket_lb.c (about)

     1  // SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
     2  /* Copyright Authors of Cilium */
     3  
     4  #include "common.h"
     5  #include <bpf/ctx/unspec.h>
     6  #include <bpf/api.h>
     7  #include "pktgen.h"
     8  
     9  #define ENABLE_IPV4 1
    10  #define ENABLE_IPV6 1
    11  #undef ENABLE_HEALTH_CHECK
    12  #define ENABLE_LOCAL_REDIRECT_POLICY 1
    13  
    14  #define HAVE_NETNS_COOKIE 1
    15  
    16  #define BACKEND_PORT 7000
    17  #define NETNS_COOKIE 5000
    18  #define NETNS_COOKIE2 5001
    19  #define HOST_NETNS_COOKIE 0
    20  #define DST_PORT 6000
    21  #define V6_BACKEND1 v6_pod_one
    22  #define V6_SVC_ONE v6_node_one
    23  #define V6_SVC_TWO v6_node_two
    24  
    25  #define get_netns_cookie(ctx) test_get_netns_cookie(ctx)
    26  /* Set netns_cookie based on the source ip in the addr. While this field isn't
    27   * populated in real CGROUP_SOCK_ADDR hooks, we use it only for testing to
    28   * mock netns_cookies for different source pods.
    29   */
    30  static __always_inline
    31  int test_get_netns_cookie(__maybe_unused const struct bpf_sock_addr *addr)
    32  {
    33  	struct bpf_sock *sk = addr->sk;
    34  
    35  	if (!sk)
    36  		return 0;
    37  	if (sk->src_ip4 == v4_pod_one ||
    38  	    (sk->src_ip6[0] == bpf_htonl(0xfd040000) &&
    39  	     sk->src_ip6[1] == 0 &&
    40  	     sk->src_ip6[2] == 0 &&
    41  	     sk->src_ip6[3] == bpf_htonl(1)))
    42  		return NETNS_COOKIE;
    43  	else
    44  		return NETNS_COOKIE2;
    45  }
    46  
    47  #include "bpf_sock.c"
    48  #include "lib/common.h"
    49  #include "lib/ipcache.h"
    50  #include "lib/lb.h"
    51  
    52  CHECK("xdp", "sock4_xlate_fwd")
    53  int test_sock4_xlate_fwd_skip_lb(__maybe_unused struct xdp_md *ctx)
    54  {
    55  	int ret;
    56  	__u16 revnat_id = 1;
    57  	__u16 revnat_id2 = 2;
    58  	struct bpf_sock sk = {
    59  		.src_ip4 = v4_pod_one
    60  	};
    61  	struct bpf_sock_addr addr = {
    62  		.user_port = tcp_svc_one,
    63  		.protocol = IPPROTO_TCP,
    64  		.sk = &sk,
    65  	};
    66  	struct skip_lb4_key key = {
    67  		.netns_cookie = NETNS_COOKIE,
    68  		.address = v4_svc_one,
    69  		.port = tcp_svc_one,
    70  	};
    71  	__u8 val = 0;
    72  
    73  	lb_v4_add_service_with_flags(v4_svc_one, tcp_svc_one, 1, revnat_id,
    74  				     0, SVC_FLAG_LOCALREDIRECT);
    75  	lb_v4_add_service_with_flags(v4_svc_two, tcp_svc_two, 1, revnat_id2,
    76  				     0, SVC_FLAG_LOCALREDIRECT);
    77  	lb_v4_add_backend(v4_svc_one, tcp_svc_one, 1, 124,
    78  			  v4_pod_one, tcp_dst_one, IPPROTO_TCP, 0);
    79  	lb_v4_add_backend(v4_svc_two, tcp_svc_two, 1, 124,
    80  			  v4_pod_one, tcp_dst_one, IPPROTO_TCP, 0);
    81  	ret = map_update_elem(&LB4_SKIP_MAP, &key, &val, BPF_ANY);
    82  	/* Needed to avoid sock4_skip_xlate */
    83  	ipcache_v4_add_entry(v4_pod_one, 0, 112233, 0, 0);
    84  
    85  	test_init();
    86  
    87  	/* Skip LB xlate when pod_one is connecting to v4_svc_one:tcp_svc_one. */
    88  	addr.user_ip4 = v4_svc_one,
    89  	addr.user_port = tcp_svc_one,
    90  	ret = __sock4_xlate_fwd(&addr, &addr, false);
    91  	test_log("ret: %d", ret);
    92  	test_log("pod_one [%lx] -> svc_one [%lx]", addr.sk->src_ip4, addr.user_ip4);
    93  	assert(addr.user_ip4 == v4_svc_one);
    94  	assert(addr.user_port == tcp_svc_one);
    95  	assert(ret == -ENXIO);
    96  
    97  	/* LB xlate happens when pod_one is connecting to v4_svc_two:tcp_svc_two. */
    98  	addr.user_ip4 = v4_svc_two;
    99  	addr.user_port = tcp_svc_two;
   100  	ret = __sock4_xlate_fwd(&addr, &addr, false);
   101  	test_log("ret: %d", ret);
   102  	test_log("pod_one [%lx] -> svc_two [%lx]", addr.sk->src_ip4, addr.user_ip4);
   103  	assert(addr.user_ip4 == v4_pod_one);
   104  	assert(addr.user_port == tcp_dst_one);
   105  	assert(ret == 0);
   106  
   107  	/* LB xlate happens when pod_two is connecting to v4_svc_one:tcp_svc_one. */
   108  	addr.sk->src_ip4 = v4_pod_two;
   109  	addr.user_ip4 = v4_svc_one;
   110  	addr.user_port = tcp_svc_one;
   111  	ret = __sock4_xlate_fwd(&addr, &addr, false);
   112  	test_log("ret: %d", ret);
   113  	test_log("pod_two [%lx] -> svc_one [%lx]", addr.sk->src_ip4, addr.user_ip4);
   114  	assert(addr.user_ip4 == v4_pod_one);
   115  	assert(addr.user_port == tcp_dst_one);
   116  	assert(ret == 0);
   117  
   118  	test_finish();
   119  }
   120  
   121  CHECK("xdp", "sock6_xlate_fwd")
   122  int test_sock6_xlate_fwd_skip_lb(__maybe_unused struct xdp_md *ctx)
   123  {
   124  	int ret;
   125  	__u16 revnat_id = 1;
   126  	__u16 revnat_id2 = 2;
   127  	union v6addr frontend_ip1 = {};
   128  	union v6addr frontend_ip2 = {};
   129  
   130  	struct bpf_sock sk = {};
   131  	struct bpf_sock_addr addr = {
   132  		.user_port = tcp_svc_one,
   133  		.protocol = IPPROTO_TCP,
   134  		.sk = &sk,
   135  	};
   136  	struct skip_lb6_key key = {
   137  		.netns_cookie = NETNS_COOKIE,
   138  		.port = tcp_svc_one,
   139  	};
   140  	__u8 val = 0;
   141  
   142  	memcpy(frontend_ip1.addr, (void *)V6_SVC_ONE, 16);
   143  	memcpy(frontend_ip2.addr, (void *)V6_SVC_TWO, 16);
   144  	lb_v6_add_service_with_flags(&frontend_ip1, tcp_svc_one, 1, revnat_id,
   145  				     0, SVC_FLAG_LOCALREDIRECT);
   146  	lb_v6_add_service_with_flags(&frontend_ip2, tcp_svc_two, 1, revnat_id2,
   147  				     0, SVC_FLAG_LOCALREDIRECT);
   148  	lb_v6_add_backend(&frontend_ip1, tcp_svc_one, 1, 124,
   149  			  (union v6addr *)V6_BACKEND1, tcp_dst_one, IPPROTO_TCP, 0);
   150  	lb_v6_add_backend(&frontend_ip2, tcp_svc_two, 1, 124,
   151  			  (union v6addr *)V6_BACKEND1, tcp_dst_one, IPPROTO_TCP, 0);
   152  	memcpy(&key.address, (void *)V6_SVC_ONE, 16);
   153  	ret = map_update_elem(&LB6_SKIP_MAP, &key, &val, BPF_ANY);
   154  	/* Needed to avoid sock6_skip_xlate */
   155  	ipcache_v6_add_entry((union v6addr *)V6_BACKEND1, 0, 112233, 0, 0);
   156  
   157  	test_init();
   158  
   159  	/* Skip LB xlate when pod_one is connecting to V6_SVC_ONE:tcp_svc_one. */
   160  	addr.sk->src_ip6[0] = bpf_htonl(0xfd040000);
   161  	addr.sk->src_ip6[1] = 0;
   162  	addr.sk->src_ip6[2] = 0;
   163  	addr.sk->src_ip6[3] = bpf_htonl(1);
   164  	memcpy(addr.user_ip6, (void *)V6_SVC_ONE, 16);
   165  	addr.user_port = tcp_svc_one;
   166  	ret = __sock6_xlate_fwd(&addr, false);
   167  	test_log("ret: %d", ret);
   168  	test_log("pod_one [%lx] -> svc_one [%lx]", addr.sk->src_ip6[0], addr.user_ip6[0]);
   169  	assert(addr.user_ip6[0] == bpf_htonl(0xfd050000));
   170  	assert(addr.user_ip6[1] == 0);
   171  	assert(addr.user_ip6[2] == 0);
   172  	assert(addr.user_ip6[3] == bpf_htonl(1));
   173  	assert(addr.user_port == tcp_svc_one);
   174  	assert(ret == -ENXIO);
   175  
   176  	/* LB xlate happens when pod_one is connecting to V6_SVC_TWO:tcp_svc_two. */
   177  	addr.sk->src_ip6[0] = bpf_htonl(0xfd040000);
   178  	addr.sk->src_ip6[1] = 0;
   179  	addr.sk->src_ip6[2] = 0;
   180  	addr.sk->src_ip6[3] = bpf_htonl(1);
   181  	memcpy(addr.user_ip6, (void *)V6_SVC_TWO, 16);
   182  	addr.user_port = tcp_svc_two;
   183  	ret = __sock6_xlate_fwd(&addr, false);
   184  	test_log("ret: %d", ret);
   185  	test_log("pod_one [%lx] -> svc_two [%lx]", addr.sk->src_ip6[0], addr.user_ip6[0]);
   186  	assert(addr.user_ip6[0] == bpf_htonl(0xfd040000));
   187  	assert(addr.user_ip6[1] == 0);
   188  	assert(addr.user_ip6[2] == 0);
   189  	assert(addr.user_ip6[3] == bpf_htonl(1));
   190  	assert(addr.user_port == tcp_dst_one);
   191  	assert(ret == 0);
   192  
   193  	/* LB xlate happens when pod_two is connecting to v4_svc_one:tcp_svc_one. */
   194  	addr.sk->src_ip6[0] = bpf_htonl(0xfd040000);
   195  	addr.sk->src_ip6[1] = 0;
   196  	addr.sk->src_ip6[2] = 0;
   197  	addr.sk->src_ip6[3] = bpf_htonl(2);
   198  	memcpy(addr.user_ip6, (void *)V6_SVC_ONE, 16);
   199  	addr.user_port = tcp_svc_one;
   200  	ret = __sock6_xlate_fwd(&addr, false);
   201  	test_log("ret: %d", ret);
   202  	test_log("pod_two [%lx] -> svc_one [%lx]", addr.sk->src_ip6[0], addr.user_ip6[0]);
   203  	assert(addr.user_ip6[0] == bpf_htonl(0xfd040000));
   204  	assert(addr.user_ip6[1] == 0);
   205  	assert(addr.user_ip6[2] == 0);
   206  	assert(addr.user_ip6[3] == bpf_htonl(1));
   207  	assert(addr.user_port == tcp_dst_one);
   208  	assert(ret == 0);
   209  
   210  	test_finish();
   211  }