github.com/cilium/cilium@v1.16.2/bpf/tests/xdp_nodeport_lb4_nat_backend.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 6 #include <bpf/ctx/xdp.h> 7 #include "pktgen.h" 8 9 /* Set ETH_HLEN to 14 to indicate that the packet has a 14 byte ethernet header */ 10 #define ETH_HLEN 14 11 12 /* Enable code paths under test */ 13 #define ENABLE_IPV4 14 #define ENABLE_NODEPORT 15 #define ENABLE_NODEPORT_ACCELERATION 16 17 #define DISABLE_LOOPBACK_LB 18 19 /* Skip ingress policy checks, not needed to validate hairpin flow */ 20 #define USE_BPF_PROG_FOR_INGRESS_POLICY 21 #undef FORCE_LOCAL_POLICY_EVAL_AT_SOURCE 22 23 #define CLIENT_IP v4_ext_one 24 #define CLIENT_PORT __bpf_htons(111) 25 26 #define FRONTEND_IP v4_svc_one 27 #define FRONTEND_PORT tcp_svc_one 28 29 #define LB_IP v4_node_one 30 #define LB_PORT __bpf_htons(222) 31 32 #define BACKEND_IP v4_pod_one 33 #define BACKEND_PORT __bpf_htons(8080) 34 35 #include <bpf_xdp.c> 36 37 #include "lib/endpoint.h" 38 #include "lib/ipcache.h" 39 #include "lib/lb.h" 40 41 static volatile const __u8 *client_mac = mac_one; 42 static volatile const __u8 *lb_mac = mac_two; 43 44 #define FROM_XDP 0 45 46 struct { 47 __uint(type, BPF_MAP_TYPE_PROG_ARRAY); 48 __uint(key_size, sizeof(__u32)); 49 __uint(max_entries, 1); 50 __array(values, int()); 51 } entry_call_map __section(".maps") = { 52 .values = { 53 [FROM_XDP] = &cil_xdp_entry, 54 }, 55 }; 56 57 /* Test that a remote LB 58 * - doesn't touch a NATed request, 59 * - passes it up from XDP to TC 60 */ 61 PKTGEN("xdp", "xdp_nodeport_nat_backend") 62 int nodeport_nat_backend_pktgen(struct __ctx_buff *ctx) 63 { 64 struct pktgen builder; 65 struct tcphdr *l4; 66 void *data; 67 68 /* Init packet builder */ 69 pktgen__init(&builder, ctx); 70 71 l4 = pktgen__push_ipv4_tcp_packet(&builder, 72 (__u8 *)client_mac, (__u8 *)lb_mac, 73 LB_IP, BACKEND_IP, 74 LB_PORT, BACKEND_PORT); 75 if (!l4) 76 return TEST_ERROR; 77 78 data = pktgen__push_data(&builder, default_data, sizeof(default_data)); 79 if (!data) 80 return TEST_ERROR; 81 82 /* Calc lengths, set protocol fields and calc checksums */ 83 pktgen__finish(&builder); 84 85 return 0; 86 } 87 88 SETUP("xdp", "xdp_nodeport_nat_backend") 89 int nodeport_nat_backend_setup(struct __ctx_buff *ctx) 90 { 91 lb_v4_add_service(FRONTEND_IP, FRONTEND_PORT, 1, 1); 92 lb_v4_add_backend(FRONTEND_IP, FRONTEND_PORT, 1, 124, 93 BACKEND_IP, BACKEND_PORT, IPPROTO_TCP, 0); 94 95 /* add local backend */ 96 endpoint_v4_add_entry(BACKEND_IP, 0, 0, 0, 0, NULL, NULL); 97 98 ipcache_v4_add_entry(BACKEND_IP, 0, 112233, 0, 0); 99 100 /* Jump into the entrypoint */ 101 tail_call_static(ctx, entry_call_map, FROM_XDP); 102 /* Fail if we didn't jump */ 103 return TEST_ERROR; 104 } 105 106 CHECK("xdp", "xdp_nodeport_nat_backend") 107 int nodeport_nat_backend_check(__maybe_unused const struct __ctx_buff *ctx) 108 { 109 void *data, *data_end; 110 __u32 *status_code; 111 struct tcphdr *l4; 112 struct ethhdr *l2; 113 struct iphdr *l3; 114 __u32 *meta; 115 116 test_init(); 117 118 data = (void *)(long)ctx_data(ctx); 119 data_end = (void *)(long)ctx->data_end; 120 121 status_code = data; 122 if (data + sizeof(__u32) > data_end) 123 test_fatal("status code out of bounds"); 124 125 meta = (void *)status_code + sizeof(__u32); 126 if ((void *)meta + sizeof(__u32) > data_end) 127 test_fatal("meta out of bounds"); 128 129 l2 = (void *)meta + sizeof(__u32); 130 if ((void *)l2 + sizeof(struct ethhdr) > data_end) 131 test_fatal("l2 out of bounds"); 132 133 l3 = (void *)l2 + sizeof(struct ethhdr); 134 if ((void *)l3 + sizeof(struct iphdr) > data_end) 135 test_fatal("l3 out of bounds"); 136 137 l4 = (void *)l3 + sizeof(struct iphdr); 138 if ((void *)l4 + sizeof(struct tcphdr) > data_end) 139 test_fatal("l4 out of bounds"); 140 141 assert(*status_code == CTX_ACT_OK); 142 143 assert((*meta & XFER_PKT_NO_SVC) == XFER_PKT_NO_SVC); 144 145 if (memcmp(l2->h_source, (__u8 *)client_mac, ETH_ALEN) != 0) 146 test_fatal("src MAC is not the client MAC") 147 if (memcmp(l2->h_dest, (__u8 *)lb_mac, ETH_ALEN) != 0) 148 test_fatal("dst MAC is not the LB MAC") 149 150 if (l3->saddr != LB_IP) 151 test_fatal("src IP has changed"); 152 153 if (l3->daddr != BACKEND_IP) 154 test_fatal("dst IP has changed"); 155 156 if (l3->check != bpf_htons(0xa612)) 157 test_fatal("L3 checksum is invalid: %d", bpf_htons(l3->check)); 158 159 if (l4->source != LB_PORT) 160 test_fatal("src port has changed"); 161 162 if (l4->dest != BACKEND_PORT) 163 test_fatal("dst port has changed"); 164 165 test_finish(); 166 }