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 }