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(ð->h_source, (__u8 *)mac_one, sizeof(mac_three)); 28 memcpy(ð->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 }