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 */