github.com/cilium/cilium@v1.16.2/bpf/tests/mcast_tests.c (about)

     1  // SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
     2  /* Copyright Authors of Cilium */
     3  
     4  #include "bpf/ctx/skb.h"
     5  #include "node_config.h"
     6  #include "common.h"
     7  #include "lib/endian.h"
     8  #include "lib/common.h"
     9  #include "lib/eth.h"
    10  #include "pktgen.h"
    11  
    12  #define ENABLE_IPV4
    13  #define ENABLE_MULTICAST 1
    14  #define ENCAP_IFINDEX 1
    15  
    16  #include <linux/igmp.h>
    17  #include <linux/in.h>
    18  #include "../lib/mcast.h"
    19  
    20  static __always_inline int default_packet(struct __ctx_buff *ctx)
    21  {
    22  	struct pktgen builder;
    23  	struct ethhdr *eh;
    24  	struct iphdr *iph;
    25  
    26  	pktgen__init(&builder, ctx);
    27  
    28  	eh = pktgen__push_ethhdr(&builder);
    29  	if (!eh)
    30  		return TEST_ERROR;
    31  
    32  	iph = pktgen__push_default_iphdr(&builder);
    33  	if (!iph)
    34  		return TEST_ERROR;
    35  
    36  	pktgen__finish(&builder);
    37  
    38  	return 0;
    39  }
    40  
    41  static __always_inline int igmpv3_join_packet(struct __ctx_buff *ctx)
    42  {
    43  	struct pktgen builder;
    44  	struct ethhdr *eh;
    45  	struct iphdr *iph;
    46  	struct igmpv3_report *rep;
    47  
    48  	pktgen__init(&builder, ctx);
    49  
    50  	eh = pktgen__push_ethhdr(&builder);
    51  	if (!eh)
    52  		return TEST_ERROR;
    53  
    54  	iph = pktgen__push_default_iphdr(&builder);
    55  	if (!iph)
    56  		return TEST_ERROR;
    57  	iph->saddr = 0x1010101;/* 1.1.1.1 */
    58  	iph->daddr = 0x160000e0;/* 224.0.0.22 */
    59  	iph->protocol = IPPROTO_IGMP;
    60  
    61  	rep = pktgen__push_rawhdr(&builder, sizeof(struct igmpv3_report),
    62  				  PKT_LAYER_DATA);
    63  	if (!rep)
    64  		return TEST_ERROR;
    65  
    66  	rep->type = IGMPV3_HOST_MEMBERSHIP_REPORT;
    67  
    68  	pktgen__finish(&builder);
    69  
    70  	return 0;
    71  }
    72  
    73  CHECK("tc", "mcast_tests")
    74  int test1_check(struct __ctx_buff *ctx)
    75  {
    76  	test_init();
    77  
    78  	/* test we correctly identify igmp packets */
    79  	TEST("is_igmp", {
    80  		int ret;
    81  		struct iphdr *ip4;
    82  
    83  		ret = igmpv3_join_packet(ctx);
    84  		if (ret)
    85  			return ret;
    86  
    87  		void *data = (void *)(long)ctx->data;
    88  		void *data_end = (void *)(long)ctx->data_end;
    89  
    90  		if ((data + sizeof(struct ethhdr) + sizeof(struct iphdr)) > data_end)
    91  			test_fatal("ctx not big enough");
    92  
    93  		ip4 = data + sizeof(struct ethhdr);
    94  
    95  		if (mcast_ipv4_is_igmp(ip4) != 1)
    96  			test_fatal("expected true for ipv4 protocol %x", ip4->protocol);
    97  	});
    98  
    99  	/* test we do not incorrectly identify non igmp packets */
   100  	TEST("is_not_igmp", {
   101  		int ret;
   102  		struct iphdr *ip4;
   103  
   104  		ret = default_packet(ctx);
   105  		if (ret)
   106  			return ret;
   107  
   108  		void *data = (void *)(long)ctx->data;
   109  		void *data_end = (void *)(long)ctx->data_end;
   110  
   111  		if ((data + sizeof(struct ethhdr) + sizeof(struct iphdr)) > data_end)
   112  			test_fatal("ctx not big enough");
   113  
   114  		ip4 = data + sizeof(struct ethhdr);
   115  
   116  		if (mcast_ipv4_is_igmp(ip4) == 1)
   117  			test_fatal("expected false for ipv4 protocol %x", ip4->protocol);
   118  	});
   119  
   120  	/* test we extract the correct IGMP type */
   121  	TEST("igmp_type", {
   122  		int ret;
   123  		struct iphdr *ip4;
   124  		__s32 type = 0;
   125  
   126  		ret = igmpv3_join_packet(ctx);
   127  		if (ret)
   128  			return ret;
   129  
   130  		void *data = (void *)(long)ctx->data;
   131  		void *data_end = (void *)(long)ctx->data_end;
   132  
   133  		if ((data + sizeof(struct ethhdr) + sizeof(struct iphdr)) > data_end)
   134  			test_fatal("ctx not big enough");
   135  
   136  		ip4 = data + sizeof(struct ethhdr);
   137  
   138  		type = mcast_ipv4_igmp_type(ip4, data, data_end);
   139  		if (type != IGMPV3_HOST_MEMBERSHIP_REPORT)
   140  			test_fatal("expected 0x22, got %x", type);
   141  	});
   142  
   143  	test_finish();
   144  }