github.com/cilium/cilium@v1.16.2/bpf/tests/vxlan_helpers_tests.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  
     8  #define TUNNEL_PROTOCOL TUNNEL_PROTOCOL_VXLAN
     9  #define TUNNEL_PORT 8472
    10  #define TUNNEL_PORT_BAD 0
    11  #define VXLAN_VNI 0xDEADBE
    12  #define VXLAN_VNI_NEW 0xCAFEBE
    13  #define UDP_CHECK 0xDEAD
    14  
    15  #include "node_config.h"
    16  #include "lib/common.h"
    17  #include "lib/vxlan.h"
    18  
    19  /* this had to be used instead of the pktgen__push methods since these methods
    20   * use layer accounting and will fail when pushing an ipv4 header past its
    21   * assumed layer
    22   */
    23  static __always_inline void
    24  mk_data(const __u8 *buff) {
    25  	struct ethhdr *eth = (struct ethhdr *)buff;
    26  
    27  	memcpy(&eth->h_source, (__u8 *)mac_one, sizeof(mac_three));
    28  	memcpy(&eth->h_dest, (__u8 *)mac_one, sizeof(mac_four));
    29  	eth->h_proto = ETH_P_IP;
    30  
    31  	struct iphdr *ipv4 = (struct iphdr *)(buff + sizeof(struct ethhdr));
    32  
    33  	ipv4->saddr = v4_pod_one;
    34  	ipv4->daddr = v4_pod_two;
    35  }
    36  
    37  static __always_inline int
    38  mk_packet(struct __ctx_buff *ctx) {
    39  	struct pktgen builder;
    40  	struct udphdr *l4;
    41  	struct vxlanhdr *vx;
    42  	/* data is encap'd ipv4 packet, we don't care about l4 */
    43  	__u8 encap_data[sizeof(struct ethhdr) + sizeof(struct iphdr)];
    44  	void *data;
    45  
    46  	pktgen__init(&builder, ctx);
    47  
    48  	l4 = pktgen__push_ipv4_udp_packet(&builder,
    49  					  (__u8 *)mac_one,
    50  					  (__u8 *)mac_two,
    51  					  v4_node_one,
    52  					  v4_node_two,
    53  					  666,
    54  					  bpf_htons(TUNNEL_PORT));
    55  	if (!l4)
    56  		return TEST_ERROR;
    57  
    58  	l4->check = UDP_CHECK;
    59  
    60  	vx = pktgen__push_default_vxlanhdr(&builder);
    61  	if (!vx)
    62  		return TEST_ERROR;
    63  
    64  	vx->vx_vni = bpf_htonl(VXLAN_VNI << 8);
    65  
    66  	mk_data(encap_data);
    67  
    68  	data = pktgen__push_data(&builder, encap_data, sizeof(encap_data));
    69  	if (!data)
    70  		return TEST_ERROR;
    71  
    72  	pktgen__finish(&builder);
    73  
    74  	return 0;
    75  }
    76  
    77  PKTGEN("tc", "vxlan_get_vni_success")
    78  static __always_inline int
    79  pktgen_vxlan_mock_check3(struct __ctx_buff *ctx) {
    80  	return mk_packet(ctx);
    81  }
    82  
    83  CHECK("tc", "vxlan_get_vni_success")
    84  int check3(struct __ctx_buff *ctx)
    85  {
    86  	test_init();
    87  
    88  	void *data, *data_end = NULL;
    89  	struct iphdr *ipv4 = NULL;
    90  
    91  	assert(revalidate_data(ctx, &data, &data_end, &ipv4));
    92  	assert(vxlan_get_vni(data, data_end, ipv4) == VXLAN_VNI);
    93  
    94  	test_finish();
    95  }
    96  
    97  PKTGEN("tc", "vxlan_get_inner_ipv4_success")
    98  static __always_inline int
    99  pktgen_vxlan_mock_check4(struct __ctx_buff *ctx) {
   100  	return mk_packet(ctx);
   101  }
   102  
   103  CHECK("tc", "vxlan_get_inner_ipv4_success")
   104  int check4(struct __ctx_buff *ctx)
   105  {
   106  	test_init();
   107  
   108  	void *data, *data_end = NULL;
   109  	struct iphdr *ipv4 = NULL;
   110  	struct iphdr *inner_ipv4 = NULL;
   111  
   112  	assert(revalidate_data(ctx, &data, &data_end, &ipv4));
   113  	assert(vxlan_get_inner_ipv4(data, data_end, ipv4, &inner_ipv4));
   114  
   115  	assert(inner_ipv4->saddr == v4_pod_one);
   116  	assert(inner_ipv4->daddr == v4_pod_two);
   117  
   118  	test_finish();
   119  }
   120  
   121  PKTGEN("tc", "vxlan_rewrite_vni_success")
   122  static __always_inline int
   123  pktgen_vxlan_mock_check5(struct __ctx_buff *ctx) {
   124  	return mk_packet(ctx);
   125  }
   126  
   127  CHECK("tc", "vxlan_rewrite_vni_success")
   128  int check5(struct __ctx_buff *ctx)
   129  {
   130  	test_init();
   131  
   132  	void *data, *data_end = NULL;
   133  	struct iphdr *ipv4 = NULL;
   134  	struct udphdr *udp = NULL;
   135  	__u32 vni = 0;
   136  
   137  	assert(revalidate_data(ctx, &data, &data_end, &ipv4));
   138  
   139  	assert(vxlan_rewrite_vni(ctx, data, data_end, ipv4,
   140  				 VXLAN_VNI_NEW));
   141  
   142  	/* packet data was touched so revalidate */
   143  	assert(revalidate_data(ctx, &data, &data_end, &ipv4));
   144  
   145  	vni = vxlan_get_vni(data, data_end, ipv4);
   146  	assert(vni == VXLAN_VNI_NEW);
   147  
   148  	/* assert udp checksum was updated */
   149  	udp = (struct udphdr *)(data + sizeof(struct ethhdr) + (ipv4->ihl * 4));
   150  	assert(udp->check != UDP_CHECK);
   151  
   152  	test_finish();
   153  }