github.com/cilium/cilium@v1.16.2/bpf/lib/proxy_hairpin.h (about) 1 /* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */ 2 /* Copyright Authors of Cilium */ 3 4 #pragma once 5 6 #include "common.h" 7 #include "utils.h" 8 #include "ipv6.h" 9 #include "ipv4.h" 10 #include "eth.h" 11 #include "dbg.h" 12 #include "trace.h" 13 #include "csum.h" 14 #include "l4.h" 15 16 #if defined(HOST_IFINDEX_MAC) && defined(HOST_IFINDEX) 17 18 /** Redirect to the proxy by hairpinning the packet out the incoming 19 * interface. 20 * 21 * @arg ctx Packet 22 * @arg ip4 Pointer to IPv4 header. NULL for IPv6 packet. 23 * @arg proxy_port Proxy port 24 */ 25 static __always_inline int 26 ctx_redirect_to_proxy_hairpin(struct __ctx_buff *ctx, struct iphdr *ip4, 27 __be16 proxy_port) 28 { 29 #if defined(ENABLE_IPV4) || defined(ENABLE_IPV6) 30 union macaddr host_mac = HOST_IFINDEX_MAC; 31 union macaddr router_mac = THIS_INTERFACE_MAC; 32 #endif 33 int ret = 0; 34 35 ctx_store_meta(ctx, CB_PROXY_MAGIC, 36 MARK_MAGIC_TO_PROXY | (proxy_port << 16)); 37 bpf_barrier(); /* verifier workaround */ 38 39 if (!ip4) { 40 #ifdef ENABLE_IPV6 41 ret = ipv6_l3(ctx, ETH_HLEN, (__u8 *)&router_mac, (__u8 *)&host_mac, 42 METRIC_EGRESS); 43 #endif 44 } else { 45 #ifdef ENABLE_IPV4 46 ret = ipv4_l3(ctx, ETH_HLEN, (__u8 *)&router_mac, (__u8 *)&host_mac, 47 ip4); 48 #endif 49 } 50 if (IS_ERR(ret)) 51 return ret; 52 53 cilium_dbg_capture(ctx, DBG_CAPTURE_PROXY_PRE, proxy_port); 54 55 /* Note that the actual __ctx_buff preparation for submitting the 56 * packet to the proxy will occur in a subsequent program via 57 * ctx_redirect_to_proxy_first(). 58 */ 59 60 return ctx_redirect(ctx, HOST_IFINDEX, 0); 61 } 62 63 #ifdef ENABLE_IPV4 64 static __always_inline int 65 ctx_redirect_to_proxy_hairpin_ipv4(struct __ctx_buff *ctx, struct iphdr *ip4, 66 __be16 proxy_port) 67 { 68 return ctx_redirect_to_proxy_hairpin(ctx, ip4, proxy_port); 69 } 70 #endif 71 72 #ifdef ENABLE_IPV6 73 static __always_inline int 74 ctx_redirect_to_proxy_hairpin_ipv6(struct __ctx_buff *ctx, __be16 proxy_port) 75 { 76 return ctx_redirect_to_proxy_hairpin(ctx, NULL, proxy_port); 77 } 78 #endif 79 80 #endif /* HOST_IFINDEX_MAC && HOST_IFINDEX */