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");