github.com/cilium/cilium@v1.16.2/bpf/tests/ipv6_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 6 #include <bpf/ctx/xdp.h> 7 8 #include "pktgen.h" 9 #include "node_config.h" 10 11 #include "lib/common.h" 12 #include "lib/ipv6.h" 13 #include "lib/maps.h" 14 15 PKTGEN("xdp", "ipv6_without_extension_header") 16 int ipv6_without_extension_header_pktgen(struct __ctx_buff *ctx) 17 { 18 struct pktgen builder; 19 struct tcphdr *l4; 20 21 pktgen__init(&builder, ctx); 22 23 l4 = pktgen__push_ipv6_tcp_packet(&builder, 24 (__u8 *)mac_one, (__u8 *)mac_two, 25 (__u8 *)v6_node_one, (__u8 *)v6_node_two, 26 tcp_src_one, tcp_svc_one); 27 if (!l4) 28 return TEST_ERROR; 29 30 pktgen__finish(&builder); 31 32 return 0; 33 } 34 35 SETUP("xdp", "ipv6_without_extension_header") 36 int ipv6_without_extension_header_setup(__maybe_unused struct __ctx_buff *ctx) 37 { 38 return 123; 39 } 40 41 CHECK("xdp", "ipv6_without_extension_header") 42 int ipv6_without_extension_header_check(struct __ctx_buff *ctx) 43 { 44 void *data, *data_end; 45 struct ethhdr *l2; 46 struct ipv6hdr *l3; 47 __u32 *status_code; 48 __u8 nexthdr; 49 50 test_init(); 51 52 data = ctx_data(ctx); 53 data_end = ctx_data_end(ctx); 54 55 if (data + sizeof(__u32) > data_end) 56 test_fatal("status code out of bounds"); 57 58 status_code = data; 59 assert(*status_code == 123); 60 61 xdp_adjust_head(ctx, 4); 62 63 data = ctx_data(ctx); 64 data_end = ctx_data_end(ctx); 65 66 l2 = data; 67 if ((void *)(l2 + 1) > data_end) 68 test_fatal("l2 out of bounds"); 69 70 assert(l2->h_proto == __bpf_htons(ETH_P_IPV6)); 71 72 l3 = (void *)l2 + ETH_HLEN; 73 if ((void *)(l3 + 1) > data_end) 74 test_fatal("l3 out of bounds"); 75 76 nexthdr = l3->nexthdr; 77 assert(ipv6_hdrlen(ctx, &nexthdr) > 0); 78 assert(nexthdr == IPPROTO_TCP); 79 80 test_finish(); 81 } 82 83 struct ipv6_authhdr { 84 struct ipv6_opt_hdr opt; 85 __u16 reserved; 86 int spi; 87 int seq; 88 char icv[]; 89 }; 90 91 PKTGEN("xdp", "ipv6_with_auth_hop_tcp") 92 int ipv6_with_hop_auth_tcp_pktgen(struct __ctx_buff *ctx) 93 { 94 struct pktgen builder; 95 struct tcphdr *l4; 96 struct ethhdr *l2; 97 struct ipv6hdr *l3; 98 struct ipv6_authhdr *authhdr; 99 struct ipv6_opt_hdr *l3_next; 100 101 pktgen__init(&builder, ctx); 102 103 l2 = pktgen__push_ethhdr(&builder); 104 if (!l2) 105 return TEST_ERROR; 106 107 ethhdr__set_macs(l2, (__u8 *)mac_one, (__u8 *)mac_two); 108 109 l3 = pktgen__push_default_ipv6hdr(&builder); 110 if (!l3) 111 return TEST_ERROR; 112 113 memcpy(&l3->saddr, (__u8 *)v6_node_one, sizeof(l3->saddr)); 114 memcpy(&l3->daddr, (__u8 *)v6_node_two, sizeof(l3->daddr)); 115 116 l3_next = pktgen__append_ipv6_extension_header(&builder, NEXTHDR_AUTH, 0); 117 if (!l3_next) 118 return TEST_ERROR; 119 120 authhdr = (struct ipv6_authhdr *)l3_next; 121 if ((void *) authhdr + sizeof(struct ipv6_authhdr) > ctx_data_end(ctx)) 122 return TEST_ERROR; 123 124 authhdr->spi = 0x222; 125 authhdr->seq = 1; 126 127 l3_next = pktgen__append_ipv6_extension_header(&builder, NEXTHDR_HOP, 0); 128 if (!l3_next) 129 return TEST_ERROR; 130 131 l4 = pktgen__push_default_tcphdr(&builder); 132 if (!l4) 133 return TEST_ERROR; 134 135 l4->source = tcp_src_one; 136 l4->dest = tcp_svc_one; 137 138 pktgen__finish(&builder); 139 140 return 0; 141 } 142 143 SETUP("xdp", "ipv6_with_auth_hop_tcp") 144 int ipv6_with_hop_auth_tcp_setup(__maybe_unused struct __ctx_buff *ctx) 145 { 146 return 1234; 147 } 148 149 CHECK("xdp", "ipv6_with_auth_hop_tcp") 150 int ipv6_with_hop_auth_tcp_check(struct __ctx_buff *ctx) 151 { 152 void *data, *data_end; 153 struct ethhdr *l2; 154 struct ipv6hdr *l3; 155 __u32 *status_code; 156 __u8 nexthdr; 157 158 test_init(); 159 160 data = ctx_data(ctx); 161 data_end = ctx_data_end(ctx); 162 163 if (data + sizeof(__u32) > data_end) 164 test_fatal("status code out of bounds"); 165 166 status_code = data; 167 assert(*status_code == 1234); 168 169 xdp_adjust_head(ctx, 4); 170 171 data = ctx_data(ctx); 172 data_end = ctx_data_end(ctx); 173 174 l2 = data; 175 if ((void *)(l2 + 1) > data_end) 176 test_fatal("l2 out of bounds"); 177 178 assert(l2->h_proto == __bpf_htons(ETH_P_IPV6)); 179 180 l3 = (void *)l2 + ETH_HLEN; 181 if ((void *)(l3 + 1) > data_end) 182 test_fatal("l3 out of bounds"); 183 184 nexthdr = l3->nexthdr; 185 assert(ipv6_hdrlen(ctx, &nexthdr) > 0); 186 assert(nexthdr == IPPROTO_TCP); 187 188 test_finish(); 189 } 190 191 CHECK("xdp", "ipv6") 192 int bpf_test(__maybe_unused struct xdp_md *ctx) 193 { 194 test_init(); 195 196 union v6addr v6; 197 198 TEST("test_ipv6_addr_clear_suffix", { 199 memset(&v6, 0xff, sizeof(v6)); 200 ipv6_addr_clear_suffix(&v6, 128); 201 assert(bpf_ntohl(v6.p1) == 0xffffffff); 202 assert(bpf_ntohl(v6.p2) == 0xffffffff); 203 assert(bpf_ntohl(v6.p3) == 0xffffffff); 204 assert(bpf_ntohl(v6.p4) == 0xffffffff); 205 206 memset(&v6, 0xff, sizeof(v6)); 207 ipv6_addr_clear_suffix(&v6, 127); 208 assert(bpf_ntohl(v6.p1) == 0xffffffff); 209 assert(bpf_ntohl(v6.p2) == 0xffffffff); 210 assert(bpf_ntohl(v6.p3) == 0xffffffff); 211 assert(bpf_ntohl(v6.p4) == 0xfffffffe); 212 213 memset(&v6, 0xff, sizeof(v6)); 214 ipv6_addr_clear_suffix(&v6, 95); 215 assert(bpf_ntohl(v6.p1) == 0xffffffff); 216 assert(bpf_ntohl(v6.p2) == 0xffffffff); 217 assert(bpf_ntohl(v6.p3) == 0xfffffffe); 218 assert(bpf_ntohl(v6.p4) == 0x00000000); 219 220 memset(&v6, 0xff, sizeof(v6)); 221 ipv6_addr_clear_suffix(&v6, 1); 222 assert(bpf_ntohl(v6.p1) == 0x80000000); 223 assert(bpf_ntohl(v6.p2) == 0x00000000); 224 assert(bpf_ntohl(v6.p3) == 0x00000000); 225 assert(bpf_ntohl(v6.p4) == 0x00000000); 226 227 memset(&v6, 0xff, sizeof(v6)); 228 ipv6_addr_clear_suffix(&v6, -1); 229 assert(bpf_ntohl(v6.p1) == 0x00000000); 230 assert(bpf_ntohl(v6.p2) == 0x00000000); 231 assert(bpf_ntohl(v6.p3) == 0x00000000); 232 assert(bpf_ntohl(v6.p4) == 0x00000000); 233 }); 234 235 test_finish(); 236 } 237 238 BPF_LICENSE("Dual BSD/GPL");