github.com/datadog/cilium@v1.6.12/bpf/sockops/bpf_sockops.h (about)

     1  /*
     2   *  Copyright (C) 2018-2019 Authors of Cilium
     3   *
     4   *  This program is free software; you can redistribute it and/or modify
     5   *  it under the terms of the GNU General Public License as published by
     6   *  the Free Software Foundation; either version 2 of the License, or
     7   *  (at your option) any later version.
     8   *
     9   *  This program is distributed in the hope that it will be useful,
    10   *  but WITHOUT ANY WARRANTY; without even the implied warranty of
    11   *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    12   *  GNU General Public License for more details.
    13   *
    14   *  You should have received a copy of the GNU General Public License
    15   *  along with this program; if not, write to the Free Software
    16   *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
    17   */
    18  
    19  #include "sockops_config.h"
    20  
    21  /* Structure representing an L7 sock */
    22  struct sock_key {
    23  	union {
    24  		struct {
    25  			__u32		sip4;
    26  			__u32		pad1;
    27  			__u32		pad2;
    28  			__u32		pad3;
    29  		};
    30  		union v6addr	sip6;
    31  	};
    32  	union {
    33  		struct {
    34  			__u32		dip4;
    35  			__u32		pad4;
    36  			__u32		pad5;
    37  			__u32		pad6;
    38  		};
    39  		union v6addr	dip6;
    40  	};
    41  	__u8 family;
    42  	__u8 pad7;
    43  	__u16 pad8;
    44  	__u32 sport;
    45  	__u32 dport;
    46  } __attribute__((packed));
    47  
    48  struct bpf_elf_map __section_maps SOCK_OPS_MAP = {
    49  	.type           = BPF_MAP_TYPE_SOCKHASH,
    50  	.size_key       = sizeof(struct sock_key),
    51  	.size_value     = sizeof(int),
    52  	.pinning        = PIN_GLOBAL_NS,
    53  	.max_elem       = SOCKOPS_MAP_SIZE,
    54  };
    55  
    56  static __always_inline void sk_extract4_key(struct bpf_sock_ops *ops,
    57  					    struct sock_key *key)
    58  {
    59  	key->dip4 = ops->remote_ip4;
    60  	key->sip4 = ops->local_ip4;
    61  	key->family = ENDPOINT_KEY_IPV4;
    62  
    63  	key->sport = (bpf_ntohl(ops->local_port) >> 16);
    64  	/* clang-7.1 or higher seems to think it can do a 16-bit read here
    65  	 * which unfortunately most kernels (as of October 2019) do not
    66  	 * support, which leads to verifier failures. Insert a READ_ONCE
    67  	 * to make sure that a 32-bit read followed by shift is generated. */
    68  	key->dport = READ_ONCE(ops->remote_port) >> 16;
    69  }
    70  
    71  static __always_inline void sk_msg_extract4_key(struct sk_msg_md *msg,
    72  						struct sock_key *key)
    73  {
    74  	key->dip4 = msg->remote_ip4;
    75  	key->sip4 = msg->local_ip4;
    76  	key->family = ENDPOINT_KEY_IPV4;
    77  
    78  	key->sport = (bpf_ntohl(msg->local_port) >> 16);
    79  	/* clang-7.1 or higher seems to think it can do a 16-bit read here
    80  	 * which unfortunately most kernels (as of October 2019) do not
    81  	 * support, which leads to verifier failures. Insert a READ_ONCE
    82  	 * to make sure that a 32-bit read followed by shift is generated. */
    83  	key->dport = READ_ONCE(msg->remote_port) >> 16;
    84  }
    85  
    86  static __always_inline void sk_lb4_key_v2(struct lb4_key_v2 *lb4,
    87  					  struct sock_key *key)
    88  {
    89  	/* SK MSG is always egress, so use daddr */
    90  	lb4->address = key->dip4;
    91  	lb4->dport = key->dport;
    92  }
    93  
    94  static __always_inline bool redirect_to_proxy(int verdict)
    95  {
    96  	return verdict > 0;
    97  }