From 6cde57e27446716f77ccd6112eaae914bc29ebe2 Mon Sep 17 00:00:00 2001 From: Vincent JARDIN Date: Fri, 2 Aug 2024 00:35:38 +0200 Subject: [PATCH 1/3] llc: llc-VERSION to be used on Ubuntu 24.04 Hint for llvm-18 package from Ubuntu 24.04 --- README.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/README.md b/README.md index 77d375f..afc7f52 100644 --- a/README.md +++ b/README.md @@ -22,6 +22,14 @@ gcc is the default compiled. Should you prefer the usage of clang, then use: CC=clang make -j $(nproc) ``` +If you are missing the `llc` llvm tool, maybe it missing from your `PATH` or it +has been renamed `llc-N`, for example `llc-18` on Ubuntu 24.04. + +If you are facing such issue, you can compile using: +``` +LLC=llc-18 make -j $(nproc) +``` + # Basic Run Define your own `gtp-guard.conf` settings in order to enable its vty over TCP. From 8b36c477e9c479ea928a5196e4be041d8d354954 Mon Sep 17 00:00:00 2001 From: Vincent JARDIN Date: Fri, 2 Aug 2024 00:36:34 +0200 Subject: [PATCH 2/3] gcc.ebpf: prepare an full gcc compilation ebpf is properly supported by gcc ; let's fix warning on pointers that gcc is facing. This commit will prepare the compilation of gtp-guard using gcc only. The main benefit is for embedded targets so we avoid having two toolchains: gcc and clang. Please, note that having CLANG=gcc and LLC=gcc won't be enough since there are some missing modifications required with src/bpf/Makefile so it can support both gcc and clang toolchains. --- src/bpf/gtp_fwd.c | 32 ++++++++++++------------ src/bpf/gtp_mirror.c | 4 +-- src/bpf/gtp_route.c | 58 ++++++++++++++++++++++---------------------- 3 files changed, 47 insertions(+), 47 deletions(-) diff --git a/src/bpf/gtp_fwd.c b/src/bpf/gtp_fwd.c index eea89a6..600132d 100644 --- a/src/bpf/gtp_fwd.c +++ b/src/bpf/gtp_fwd.c @@ -147,7 +147,7 @@ gtpu_ipencap(struct parse_pkt *pkt, struct gtp_iptnl_rule *iptnl_rule) int headroom, use_vlan = 0, offset = 0; iph = data + pkt->l3_offset; - if (iph + 1 > data_end) + if (iph + 1 > (typeof(iph))data_end) return XDP_DROP; payload_len = bpf_ntohs(iph->tot_len); @@ -165,7 +165,7 @@ gtpu_ipencap(struct parse_pkt *pkt, struct gtp_iptnl_rule *iptnl_rule) data = (void *) (long) ctx->data; data_end = (void *) (long) ctx->data_end; new_eth = data; - if (new_eth + 1 > data_end) + if (new_eth + 1 > (typeof(new_eth))data_end) return XDP_DROP; new_eth->h_proto = bpf_htons(ETH_P_IP); @@ -173,7 +173,7 @@ gtpu_ipencap(struct parse_pkt *pkt, struct gtp_iptnl_rule *iptnl_rule) new_eth->h_proto = bpf_htons(ETH_P_8021Q); vlanh = data + sizeof(*new_eth); - if (vlanh + 1 > data_end) + if (vlanh + 1 > (typeof(vlanh))data_end) return XDP_DROP; vlanh->h_vlan_encapsulated_proto = bpf_htons(ETH_P_IP); vlanh->hvlan_TCI = bpf_htons(iptnl_rule->encap_vlan_id); @@ -181,7 +181,7 @@ gtpu_ipencap(struct parse_pkt *pkt, struct gtp_iptnl_rule *iptnl_rule) } iph = data + sizeof(*new_eth) + offset; - if (iph + 1 > data_end) + if (iph + 1 > (typeof(iph))data_end) return XDP_DROP; /* Fill Encap header */ @@ -293,7 +293,7 @@ gtpu_ipip_decap(struct parse_pkt *pkt, struct gtp_iptnl_rule *iptnl_rule, struct data_end = (void *) (long) ctx->data_end; new_eth = data; - if (new_eth + 1 > data_end) + if (new_eth + 1 > (typeof(new_eth))data_end) return XDP_DROP; new_eth->h_proto = bpf_htons(ETH_P_8021Q); @@ -303,7 +303,7 @@ gtpu_ipip_decap(struct parse_pkt *pkt, struct gtp_iptnl_rule *iptnl_rule, struct if ((iptnl_rule->flags & IPTNL_FL_TAG_VLAN) && pkt->vlan_id != 0) { vlanh = data + offset; - if (vlanh + 1 > data_end) + if (vlanh + 1 > (typeof(vlanh))data_end) return XDP_DROP; vlanh->h_vlan_encapsulated_proto = bpf_htons(ETH_P_IP); vlanh->hvlan_TCI = bpf_htons(iptnl_rule->decap_vlan_id); @@ -311,7 +311,7 @@ gtpu_ipip_decap(struct parse_pkt *pkt, struct gtp_iptnl_rule *iptnl_rule, struct } iph = data + offset; - if (iph + 1 > data_end) + if (iph + 1 > (typeof(iph))data_end) return XDP_DROP; /* Fragmentation handling */ @@ -327,13 +327,13 @@ gtpu_ipip_decap(struct parse_pkt *pkt, struct gtp_iptnl_rule *iptnl_rule, struct offset += sizeof(struct iphdr); udph = data + offset; - if (udph + 1 > data_end) + if (udph + 1 > (typeof(udph))data_end) return XDP_DROP; /* Perform xlat if needed */ offset += sizeof(struct udphdr); gtph = data + offset; - if (gtph + 1 > data_end) + if (gtph + 1 > (typeof(gtph))data_end) return XDP_DROP; if (iptnl_rule->flags & IPTNL_FL_TRANSPARENT_EGRESS_ENCAP) { @@ -366,12 +366,12 @@ gtpu_ipip_traffic_selector(struct parse_pkt *pkt) __u16 frag_off = 0, ipfl = 0; iph_outer = data + offset; - if (iph_outer + 1 > data_end) + if (iph_outer + 1 > (typeof(iph_outer))data_end) return XDP_PASS; offset += sizeof(struct iphdr); iph_inner = data + offset; - if (iph_inner + 1 > data_end) + if (iph_inner + 1 > (typeof(iph_inner))data_end) return XDP_PASS; /* A bit more complicated here since we need to @@ -402,7 +402,7 @@ gtpu_ipip_traffic_selector(struct parse_pkt *pkt) offset += sizeof(struct iphdr); udph = data + offset; - if (udph + 1 > data_end) + if (udph + 1 > (typeof(udph))data_end) return XDP_DROP; /* Only allow GTP-U decap !!! */ @@ -412,7 +412,7 @@ gtpu_ipip_traffic_selector(struct parse_pkt *pkt) /* Perform xlat if needed */ offset += sizeof(struct udphdr); gtph = data + offset; - if (gtph + 1 > data_end) + if (gtph + 1 > (typeof(gtph))data_end) return XDP_DROP; /* Punt into netstack GTP-U echo request */ @@ -577,7 +577,7 @@ gtpu_traffic_selector(struct parse_pkt *pkt) ethh = data; iph = data + pkt->l3_offset; - if (iph + 1 > data_end) + if (iph + 1 > (typeof(iph))data_end) return XDP_PASS; if (iph->protocol == IPPROTO_IPIP) @@ -602,7 +602,7 @@ gtpu_traffic_selector(struct parse_pkt *pkt) } udph = data + offset + sizeof(struct iphdr); - if (udph + 1 > data_end) + if (udph + 1 > (typeof(udph))data_end) return XDP_DROP; if (udph->dest != bpf_htons(GTPU_PORT)) @@ -610,7 +610,7 @@ gtpu_traffic_selector(struct parse_pkt *pkt) offset += sizeof(struct iphdr); gtph = data + offset + sizeof(struct udphdr); - if (gtph + 1 > data_end) + if (gtph + 1 > (typeof(gtph))data_end) return XDP_DROP; /* That is a nice feature of XDP here: diff --git a/src/bpf/gtp_mirror.c b/src/bpf/gtp_mirror.c index bdb8298..0dc9153 100644 --- a/src/bpf/gtp_mirror.c +++ b/src/bpf/gtp_mirror.c @@ -63,7 +63,7 @@ int tc_gtp_mirror(struct __sk_buff *skb) return TC_ACT_OK; iph = data + offset; - if (iph + 1 > data_end) + if (iph + 1 > (typeof(iph))data_end) return TC_ACT_OK; /* First match destination address */ @@ -77,7 +77,7 @@ int tc_gtp_mirror(struct __sk_buff *skb) offset += sizeof(struct iphdr); udph = data + offset; - if (udph + 1 > data_end) + if (udph + 1 > (typeof(udph))data_end) return TC_ACT_OK; if (!(udph->dest == rule->port || udph->source == rule->port)) diff --git a/src/bpf/gtp_route.c b/src/bpf/gtp_route.c index 5e38d7b..cabd4a3 100644 --- a/src/bpf/gtp_route.c +++ b/src/bpf/gtp_route.c @@ -178,14 +178,14 @@ gtp_route_ipip_encap(struct parse_pkt *pkt, struct gtp_rt_rule *rt_rule) data_end = (void *) (long) ctx->data_end; new_eth = data; - if (new_eth + 1 > data_end) + if (new_eth + 1 > (typeof(new_eth))data_end) return XDP_DROP; new_eth->h_proto = bpf_htons(ETH_P_IP); if (iptnl_rule->flags & IPTNL_FL_TAG_VLAN) { new_eth->h_proto = bpf_htons(ETH_P_8021Q); vlanh = data + offset; - if (vlanh + 1 > data_end) + if (vlanh + 1 > (typeof(vlanh))data_end) return XDP_DROP; vlanh->h_vlan_encapsulated_proto = bpf_htons(ETH_P_IP); vlanh->hvlan_TCI = bpf_htons(iptnl_rule->encap_vlan_id); @@ -194,12 +194,12 @@ gtp_route_ipip_encap(struct parse_pkt *pkt, struct gtp_rt_rule *rt_rule) /* IPIP Encapsulation header */ iph = data + offset; - if (iph + 1 > data_end) + if (iph + 1 > (typeof(iph))data_end) return XDP_DROP; offset += sizeof(struct iphdr); iph_inner = data + offset; - if (iph_inner + 1 > data_end) + if (iph_inner + 1 > (typeof(iph_inner))data_end) return XDP_DROP; payload_len = bpf_ntohs(iph_inner->tot_len); gtp_route_stats_update(rt_rule, bpf_ntohs(iph_inner->tot_len)); @@ -246,12 +246,12 @@ gtp_route_ipip_decap(struct parse_pkt *pkt) __u32 csum = 0; iph_outer = data + offset; - if (iph_outer + 1 > data_end) + if (iph_outer + 1 > (typeof(iph_outer))data_end) return XDP_PASS; offset += sizeof(struct iphdr); iph_inner = data + offset; - if (iph_inner + 1 > data_end) + if (iph_inner + 1 > (typeof(iph_inner))data_end) return XDP_PASS; payload_len = bpf_ntohs(iph_inner->tot_len); @@ -285,7 +285,7 @@ gtp_route_ipip_decap(struct parse_pkt *pkt) data = (void *) (long) ctx->data; data_end = (void *) (long) ctx->data_end; new_eth = data; - if (new_eth + 1 > data_end) + if (new_eth + 1 > (typeof(new_eth))data_end) return XDP_DROP; offset = sizeof(struct ethhdr); @@ -294,7 +294,7 @@ gtp_route_ipip_decap(struct parse_pkt *pkt) new_eth->h_proto = bpf_htons(ETH_P_8021Q); vlanh = data + sizeof(*new_eth); - if (vlanh + 1 > data_end) + if (vlanh + 1 > (typeof(vlanh))data_end) return XDP_DROP; vlanh->h_vlan_encapsulated_proto = bpf_htons(ETH_P_IP); vlanh->hvlan_TCI = bpf_htons(iptnl_rule->decap_vlan_id); @@ -303,7 +303,7 @@ gtp_route_ipip_decap(struct parse_pkt *pkt) /* Build GTP-U IP Header */ iph = data + offset; - if (iph + 1 > data_end) + if (iph + 1 > (typeof(iph))data_end) return XDP_DROP; iph->version = 4; iph->ihl = sizeof(*iph) >> 2; @@ -322,7 +322,7 @@ gtp_route_ipip_decap(struct parse_pkt *pkt) /* Build GTP-U UDP Header */ udph = data + offset; - if (udph + 1 > data_end) + if (udph + 1 > (typeof(udph))data_end) return XDP_DROP; udph->dest = bpf_htons(GTPU_PORT); udph->source= bpf_htons(65000); @@ -333,7 +333,7 @@ gtp_route_ipip_decap(struct parse_pkt *pkt) /* Build GTP-U GTP Header */ gtph = data + offset; - if (gtph + 1 > data_end) + if (gtph + 1 > (typeof(gtph))data_end) return XDP_DROP; gtph->flags = GTPU_FLAGS; /* GTP Release 99 + GTP */ gtph->type = GTPU_TPDU; @@ -414,7 +414,7 @@ gtp_route_ppp_encap(struct parse_pkt *pkt, struct gtp_rt_rule *rt_rule, __u16 le int headroom, payload_len; ethh = data; - if (ethh + 1 > data_end) + if (ethh + 1 > (typeof(ethh))data_end) return XDP_PASS; /* In direct-tx mode we are enabling mac learning */ @@ -442,7 +442,7 @@ gtp_route_ppp_encap(struct parse_pkt *pkt, struct gtp_rt_rule *rt_rule, __u16 le /* Phase 3 : Layer2 */ ethh = data; - if (ethh + 1 > data_end) + if (ethh + 1 > (typeof(ethh))data_end) return XDP_DROP; __builtin_memcpy(ethh->h_dest, rt_rule->h_dst, ETH_ALEN); __builtin_memcpy(ethh->h_source, rt_rule->h_src, ETH_ALEN); @@ -451,7 +451,7 @@ gtp_route_ppp_encap(struct parse_pkt *pkt, struct gtp_rt_rule *rt_rule, __u16 le if (rt_rule->vlan_id != 0) { ethh->h_proto = bpf_htons(ETH_P_8021Q); vlanh = data + offset; - if (vlanh + 1 > data_end) + if (vlanh + 1 > (typeof(vlanh))data_end) return XDP_DROP; vlanh->h_vlan_encapsulated_proto = bpf_htons(ETH_P_PPP_SES); vlanh->hvlan_TCI = bpf_htons(rt_rule->vlan_id); @@ -460,7 +460,7 @@ gtp_route_ppp_encap(struct parse_pkt *pkt, struct gtp_rt_rule *rt_rule, __u16 le /* Phase 4 : PPPoE */ pppoeh = data + offset; - if (pppoeh + 1 > data_end) + if (pppoeh + 1 > (typeof(pppoeh))data_end) return XDP_DROP; pppoeh->vertype = PPPOE_VERTYPE; pppoeh->code = PPPOE_CODE_SESSION; @@ -469,13 +469,13 @@ gtp_route_ppp_encap(struct parse_pkt *pkt, struct gtp_rt_rule *rt_rule, __u16 le /* Phase 5 : PPP */ ppph = data + offset; - if (ppph + 1 > data_end) + if (ppph + 1 > (typeof(ppph))data_end) return XDP_DROP; offset += 2; /* Phase 6 : Complete PPPoE & PPP header according to L3 */ iph = data + offset; - if (iph + 1 > data_end) + if (iph + 1 > (typeof(iph))data_end) return XDP_DROP; if (iph->version == 4) { @@ -483,7 +483,7 @@ gtp_route_ppp_encap(struct parse_pkt *pkt, struct gtp_rt_rule *rt_rule, __u16 le } else if (iph->version == 6) { *ppph = bpf_htons(PPP_IPV6); ipv6h = data + offset; - if (ipv6h + 1 > data_end) + if (ipv6h + 1 > (typeof(ipv6h))data_end) return XDP_DROP; } else return XDP_DROP; /* only IPv4 & IPv6 */ @@ -524,17 +524,17 @@ gtp_route_ppp_decap(struct parse_pkt *pkt) int headroom; ethh = data; - if (ethh + 1 > data_end) + if (ethh + 1 > (typeof(ethh))data_end) return XDP_PASS; pppoeh = data + offset; - if (pppoeh + 1 > data_end) + if (pppoeh + 1 > (typeof(pppoeh))data_end) return XDP_PASS; payload_len = bpf_ntohs(pppoeh->plen) - 2; offset += sizeof(*pppoeh); ppph = data + offset; - if (ppph + 1 > data_end) + if (ppph + 1 > (typeof(ppph))data_end) return XDP_PASS; /* Only handle IPv4 and IPv6. Punt Control Protocol */ @@ -564,7 +564,7 @@ gtp_route_ppp_decap(struct parse_pkt *pkt) data = (void *) (long) ctx->data; data_end = (void *) (long) ctx->data_end; ethh = data; - if (ethh + 1 > data_end) + if (ethh + 1 > (typeof(ethh))data_end) return XDP_DROP; offset = sizeof(*ethh); ethh->h_proto = bpf_htons(ETH_P_IP); @@ -572,7 +572,7 @@ gtp_route_ppp_decap(struct parse_pkt *pkt) ethh->h_proto = bpf_htons(ETH_P_8021Q); vlanh = data + offset; - if (vlanh + 1 > data_end) + if (vlanh + 1 > (typeof(vlanh))data_end) return XDP_DROP; vlanh->h_vlan_encapsulated_proto = bpf_htons(ETH_P_IP); vlanh->hvlan_TCI = bpf_htons(rt_rule->vlan_id); @@ -581,7 +581,7 @@ gtp_route_ppp_decap(struct parse_pkt *pkt) /* Phase 2 : Layer3 */ iph = data + offset; - if (iph + 1 > data_end) + if (iph + 1 > (typeof(iph))data_end) return XDP_DROP; iph->version = 4; iph->ihl = sizeof(*iph) >> 2; @@ -600,7 +600,7 @@ gtp_route_ppp_decap(struct parse_pkt *pkt) /* Phase 3 : Layer4 */ udph = data + offset; - if (udph + 1 > data_end) + if (udph + 1 > (typeof(udph))data_end) return XDP_DROP; udph->source = bpf_htons(GTPU_PORT); udph->dest = bpf_htons(GTPU_PORT); @@ -618,7 +618,7 @@ gtp_route_ppp_decap(struct parse_pkt *pkt) /* Phase 4 : GTP-U */ gtph = data + offset; - if (gtph + 1 > data_end) + if (gtph + 1 > (typeof(gtph))data_end) return XDP_DROP; gtph->flags = GTPU_FLAGS; /* GTP Release 99 + GTP */ gtph->type = GTPU_TPDU; @@ -721,7 +721,7 @@ gtp_route_traffic_selector(struct parse_pkt *pkt) return gtp_route_ppp_decap(pkt); iph = data + pkt->l3_offset; - if (iph + 1 > data_end) + if (iph + 1 > (typeof(iph))data_end) return XDP_PASS; if (iph->protocol == IPPROTO_IPIP) @@ -732,7 +732,7 @@ gtp_route_traffic_selector(struct parse_pkt *pkt) return XDP_PASS; udph = data + offset + sizeof(struct iphdr); - if (udph + 1 > data_end) + if (udph + 1 > (typeof(udph))data_end) return XDP_DROP; if (udph->dest != bpf_htons(GTPU_PORT)) @@ -740,7 +740,7 @@ gtp_route_traffic_selector(struct parse_pkt *pkt) offset += sizeof(struct iphdr); gtph = data + offset + sizeof(struct udphdr); - if (gtph + 1 > data_end) + if (gtph + 1 > (typeof(gtph))data_end) return XDP_DROP; /* UDP Traffic to GTP-U UDP port : Egress lookup */ From d84e43d1585fc4c2cc0c04898a3b381a20ddbd7e Mon Sep 17 00:00:00 2001 From: Vincent Jardin Date: Fri, 2 Aug 2024 01:05:11 +0200 Subject: [PATCH 3/3] ci: fix missing artifact bpf(s) have been moved to bin/ since the commit 68948003512e1c2cb1723d25d4353853763933a7 --- .github/workflows/actions-compile.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/actions-compile.yml b/.github/workflows/actions-compile.yml index 1bfe2b3..51514cd 100644 --- a/.github/workflows/actions-compile.yml +++ b/.github/workflows/actions-compile.yml @@ -34,6 +34,7 @@ jobs: path : | bin/gtp-guard src/bpf/*.bpf + bin/*.bpf test/ build-gtping: name: Build gtping