github.com/cilium/cilium@v1.16.2/bpf/tests/ipv6_ndp_from_netdev_test.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/skb.h> 6 #include "pktgen.h" 7 #define ROUTER_IP 8 #define HOST_IP 9 #undef ROUTER_IP 10 #undef HOST_IP 11 12 #define ENABLE_IPV4 13 #define ENABLE_IPV6 14 #define SECCTX_FROM_IPCACHE 1 15 16 #include "bpf_host.c" 17 18 #include "lib/ipcache.h" 19 #include "lib/endpoint.h" 20 21 #define FROM_NETDEV 0 22 23 struct { 24 __uint(type, BPF_MAP_TYPE_PROG_ARRAY); 25 __uint(key_size, sizeof(__u32)); 26 __uint(max_entries, 1); 27 __array(values, int()); 28 } entry_call_map __section(".maps") = { 29 .values = { 30 [FROM_NETDEV] = &cil_from_netdev, 31 }, 32 }; 33 34 PKTGEN("tc", "01_ipv6_from_netdev_ns_for_pod") 35 int ipv6_from_netdev_ns_for_pod_pktgen(struct __ctx_buff *ctx) 36 { 37 struct pktgen builder; 38 struct icmp6hdr *l4; 39 void *data; 40 41 pktgen__init(&builder, ctx); 42 43 l4 = pktgen__push_ipv6_icmp6_packet(&builder, 44 (__u8 *)mac_one, (__u8 *)mac_two, 45 (__u8 *)v6_pod_one, (__u8 *)v6_pod_two, 46 ICMP6_NS_MSG_TYPE); 47 if (!l4) 48 return TEST_ERROR; 49 50 data = pktgen__push_data(&builder, (__u8 *)v6_pod_three, 16); 51 if (!data) 52 return TEST_ERROR; 53 54 __u8 options[] = {0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1}; 55 56 data = pktgen__push_data(&builder, (__u8 *)options, 8); 57 58 pktgen__finish(&builder); 59 return 0; 60 } 61 62 SETUP("tc", "01_ipv6_from_netdev_ns_for_pod") 63 int ipv6_from_netdev_ns_for_pod_setup(struct __ctx_buff *ctx) 64 { 65 endpoint_v6_add_entry((union v6addr *)v6_pod_three, 0, 0, 0, 0, 66 (__u8 *)mac_three, (__u8 *)mac_two); 67 tail_call_static(ctx, entry_call_map, FROM_NETDEV); 68 return TEST_ERROR; 69 } 70 71 CHECK("tc", "01_ipv6_from_netdev_ns_for_pod") 72 int ipv6_from_netdev_ns_for_pod_check(const struct __ctx_buff *ctx) 73 { 74 void *data; 75 void *data_end; 76 __u32 *status_code; 77 struct ethhdr *l2; 78 struct ipv6hdr *l3; 79 struct icmp6hdr *l4; 80 void *payload; 81 82 test_init(); 83 84 data = (void *)(long)ctx->data; 85 data_end = (void *)(long)ctx->data_end; 86 87 if (data + sizeof(*status_code) > data_end) 88 test_fatal("status code out of bounds"); 89 90 status_code = data; 91 printk("status_code: %d\n", *status_code); 92 assert(*status_code == CTX_ACT_REDIRECT); 93 94 l2 = data + sizeof(*status_code); 95 96 if ((void *)l2 + sizeof(struct ethhdr) > data_end) 97 test_fatal("l2 out of bounds"); 98 99 if (l2->h_proto != bpf_htons(ETH_P_IPV6)) 100 test_fatal("l2 proto hasn't been set to ETH_P_IP"); 101 102 union macaddr node_mac = THIS_INTERFACE_MAC; 103 104 if (memcmp(l2->h_source, (__u8 *)&node_mac.addr, ETH_ALEN) != 0) 105 test_fatal("src mac hasn't been set to node mac"); 106 107 if (memcmp(l2->h_dest, (__u8 *)mac_one, ETH_ALEN) != 0) 108 test_fatal("dest mac hasn't been set to source mac"); 109 110 l3 = (void *)l2 + sizeof(struct ethhdr); 111 112 if ((void *)l3 + sizeof(struct ipv6hdr) > data_end) 113 test_fatal("l3 out of bounds"); 114 115 union v6addr router_ip; 116 117 BPF_V6(router_ip, ROUTER_IP); 118 if (memcmp((__u8 *)&l3->saddr, (__u8 *)&router_ip, 16) != 0) 119 test_fatal("src IP hasn't been set to router IP"); 120 121 if (memcmp((__u8 *)&l3->daddr, (__u8 *)v6_pod_one, 16) != 0) 122 test_fatal("dest IP hasn't been set to source IP"); 123 124 l4 = (void *)l3 + sizeof(struct ipv6hdr); 125 126 if ((void *)l4 + sizeof(struct icmp6hdr) > data_end) 127 test_fatal("l4 out of bounds"); 128 129 if (l4->icmp6_type != ICMP6_NA_MSG_TYPE) 130 test_fatal("icmp6 type hasn't been set to ICMP6_NA_MSG_TYPE"); 131 132 payload = (void *)l4 + sizeof(struct icmp6hdr); 133 if ((void *)payload + 24 > data_end) 134 test_fatal("payload out of bounds"); 135 136 void *target = payload; 137 138 if (memcmp(target, (__u8 *)v6_pod_three, 16) != 0) 139 test_fatal("icmp6 payload target hasn't been set properly"); 140 141 void *target_lladdr = payload + 16 + 2; 142 143 if (memcmp(target_lladdr, (__u8 *)&node_mac.addr, ETH_ALEN) != 0) 144 test_fatal("icmp6 payload target_lladdr hasn't been set properly"); 145 146 test_finish(); 147 } 148 149 PKTGEN("tc", "02_ipv6_from_netdev_ns_for_node_ip") 150 int ipv6_from_netdev_ns_for_node_ip_pktgen(struct __ctx_buff *ctx) 151 { 152 struct pktgen builder; 153 struct icmp6hdr *l4; 154 void *data; 155 156 pktgen__init(&builder, ctx); 157 158 l4 = pktgen__push_ipv6_icmp6_packet(&builder, 159 (__u8 *)mac_one, (__u8 *)mac_two, 160 (__u8 *)v6_pod_one, (__u8 *)v6_pod_two, 161 ICMP6_NS_MSG_TYPE); 162 if (!l4) 163 return TEST_ERROR; 164 165 union v6addr node_ip; 166 167 BPF_V6(node_ip, HOST_IP); 168 data = pktgen__push_data(&builder, (__u8 *)&node_ip, 16); 169 if (!data) 170 return TEST_ERROR; 171 172 __u8 options[] = {0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1}; 173 174 data = pktgen__push_data(&builder, (__u8 *)options, 8); 175 176 pktgen__finish(&builder); 177 return 0; 178 } 179 180 SETUP("tc", "02_ipv6_from_netdev_ns_for_node_ip") 181 int ipv6_from_netdev_ns_for_node_ip_setup(struct __ctx_buff *ctx) 182 { 183 union v6addr node_ip; 184 185 BPF_V6(node_ip, HOST_IP); 186 endpoint_v6_add_entry((union v6addr *)&node_ip, 0, 0, ENDPOINT_F_HOST, 0, 187 (__u8 *)mac_three, (__u8 *)mac_two); 188 tail_call_static(ctx, entry_call_map, FROM_NETDEV); 189 return TEST_ERROR; 190 } 191 192 CHECK("tc", "02_ipv6_from_netdev_ns_for_node_ip") 193 int ipv6_from_netdev_ns_for_node_ip_check(const struct __ctx_buff *ctx) 194 { 195 void *data; 196 void *data_end; 197 __u32 *status_code; 198 struct ethhdr *l2; 199 struct ipv6hdr *l3; 200 struct icmp6hdr *l4; 201 void *payload; 202 203 test_init(); 204 205 data = (void *)(long)ctx->data; 206 data_end = (void *)(long)ctx->data_end; 207 208 if (data + sizeof(*status_code) > data_end) 209 test_fatal("status code out of bounds"); 210 211 status_code = data; 212 printk("status_code: %d\n", *status_code); 213 assert(*status_code == CTX_ACT_OK); 214 215 l2 = data + sizeof(*status_code); 216 if ((void *)l2 + sizeof(struct ethhdr) > data_end) 217 test_fatal("l2 out of bounds"); 218 219 if (l2->h_proto != bpf_htons(ETH_P_IPV6)) 220 test_fatal("l2 proto hasn't been set to ETH_P_IP"); 221 222 if (memcmp(l2->h_source, (__u8 *)mac_one, ETH_ALEN) != 0) 223 test_fatal("src mac hasn't been set to source ep's mac"); 224 225 if (memcmp(l2->h_dest, (__u8 *)mac_two, ETH_ALEN) != 0) 226 test_fatal("dest mac hasn't been set to dest ep's mac"); 227 228 l3 = (void *)l2 + sizeof(struct ethhdr); 229 230 if ((void *)l3 + sizeof(struct ipv6hdr) > data_end) 231 test_fatal("l3 out of bounds"); 232 233 if (memcmp((__u8 *)&l3->saddr, (__u8 *)v6_pod_one, 16) != 0) 234 test_fatal("src IP was changed"); 235 236 if (memcmp((__u8 *)&l3->daddr, (__u8 *)v6_pod_two, 16) != 0) 237 test_fatal("dest IP was changed"); 238 239 l4 = (void *)l3 + sizeof(struct ipv6hdr); 240 241 if ((void *)l4 + sizeof(struct icmp6hdr) > data_end) 242 test_fatal("l4 out of bounds"); 243 244 if (l4->icmp6_type != ICMP6_NS_MSG_TYPE) 245 test_fatal("icmp6 type was changed"); 246 247 payload = (void *)l4 + sizeof(struct icmp6hdr); 248 if ((void *)payload + 24 > data_end) 249 test_fatal("payload out of bounds"); 250 251 union v6addr node_ip; 252 253 BPF_V6(node_ip, HOST_IP); 254 if (memcmp(payload, (__u8 *)&node_ip, 16) != 0) 255 test_fatal("icmp6 payload target was changed"); 256 257 test_finish(); 258 }