github.com/datadog/cilium@v1.6.12/bpf/lib/eps.h (about)

     1  /*
     2   *  Copyright (C) 2017-2018 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  #ifndef __LIB_EPS_H_
    19  #define __LIB_EPS_H_
    20  
    21  #include <linux/ip.h>
    22  #include <linux/ipv6.h>
    23  
    24  #include "maps.h"
    25  
    26  static __always_inline struct endpoint_info *
    27  lookup_ip6_endpoint(struct ipv6hdr *ip6)
    28  {
    29  	struct endpoint_key key = {};
    30  
    31  	key.ip6 = *((union v6addr *) &ip6->daddr);
    32  	key.family = ENDPOINT_KEY_IPV6;
    33  
    34  	return map_lookup_elem(&ENDPOINTS_MAP, &key);
    35  }
    36  
    37  static __always_inline struct endpoint_info *
    38  __lookup_ip4_endpoint(uint32_t ip)
    39  {
    40  	struct endpoint_key key = {};
    41  
    42  	key.ip4 = ip;
    43  	key.family = ENDPOINT_KEY_IPV4;
    44  
    45  	return map_lookup_elem(&ENDPOINTS_MAP, &key);
    46  }
    47  
    48  static __always_inline struct endpoint_info *
    49  lookup_ip4_endpoint(struct iphdr *ip4)
    50  {
    51  	return __lookup_ip4_endpoint(ip4->daddr);
    52  }
    53  
    54  #ifdef SOCKMAP
    55  static __always_inline void *
    56  lookup_ip4_endpoint_policy_map(uint32_t ip)
    57  {
    58  	struct endpoint_key key = {};
    59  
    60  	key.ip4 = ip;
    61  	key.family = ENDPOINT_KEY_IPV4;
    62  
    63  	return map_lookup_elem(&EP_POLICY_MAP, &key);
    64  }
    65  #endif
    66  
    67  /* IPCACHE_STATIC_PREFIX gets sizeof non-IP, non-prefix part of ipcache_key */
    68  #define IPCACHE_STATIC_PREFIX							\
    69  	(8 * (sizeof(struct ipcache_key) - sizeof(struct bpf_lpm_trie_key)	\
    70  	      - sizeof(union v6addr)))
    71  #define IPCACHE_PREFIX_LEN(PREFIX) (IPCACHE_STATIC_PREFIX + PREFIX)
    72  
    73  #define V6_CACHE_KEY_LEN (sizeof(union v6addr)*8)
    74  
    75  static __always_inline struct remote_endpoint_info *
    76  ipcache_lookup6(struct bpf_elf_map *map, union v6addr *addr, __u32 prefix)
    77  {
    78  	struct ipcache_key key = {
    79  		.lpm_key = { IPCACHE_PREFIX_LEN(prefix) },
    80  		.family = ENDPOINT_KEY_IPV6,
    81  		.ip6 = *addr,
    82  	};
    83  	ipv6_addr_clear_suffix(&key.ip6, prefix);
    84  	return map_lookup_elem(map, &key);
    85  }
    86  
    87  #define V4_CACHE_KEY_LEN (sizeof(__u32)*8)
    88  
    89  static __always_inline struct remote_endpoint_info *
    90  ipcache_lookup4(struct bpf_elf_map *map, __be32 addr, __u32 prefix)
    91  {
    92  	struct ipcache_key key = {
    93  		.lpm_key = { IPCACHE_PREFIX_LEN(prefix) },
    94  		.family = ENDPOINT_KEY_IPV4,
    95  		.ip4 = addr,
    96  	};
    97  	key.ip4 &= GET_PREFIX(prefix);
    98  	return map_lookup_elem(map, &key);
    99  }
   100  
   101  #ifndef HAVE_LPM_MAP_TYPE
   102  /* Define a function with the following NAME which iterates through PREFIXES
   103   * (a list of integers ordered from high to low representing prefix length),
   104   * performing a lookup in MAP using LOOKUP_FN to find a provided IP of type
   105   * IPTYPE. */
   106  #define LPM_LOOKUP_FN(NAME, IPTYPE, PREFIXES, MAP, LOOKUP_FN)		\
   107  static __always_inline struct remote_endpoint_info *NAME(IPTYPE addr) \
   108  {									\
   109  	int prefixes[] = { PREFIXES };					\
   110  	const int size = (sizeof(prefixes) / sizeof(prefixes[0]));	\
   111  	struct remote_endpoint_info *info;				\
   112  	int i;								\
   113  									\
   114  _Pragma("unroll")							\
   115  	for (i = 0; i < size; i++) {					\
   116  		info = LOOKUP_FN(&MAP, addr, prefixes[i]);		\
   117  		if (info != NULL)					\
   118  			return info;					\
   119  	}								\
   120  									\
   121  	return NULL;							\
   122  }
   123  #ifdef IPCACHE6_PREFIXES
   124  LPM_LOOKUP_FN(lookup_ip6_remote_endpoint, union v6addr *, IPCACHE6_PREFIXES,
   125  	      IPCACHE_MAP, ipcache_lookup6)
   126  #endif
   127  #ifdef IPCACHE4_PREFIXES
   128  LPM_LOOKUP_FN(lookup_ip4_remote_endpoint, __be32, IPCACHE4_PREFIXES,
   129  	      IPCACHE_MAP, ipcache_lookup4)
   130  #endif
   131  #undef LPM_LOOKUP_FN
   132  #else /* HAVE_LPM_MAP_TYPE */
   133  #define lookup_ip6_remote_endpoint(addr) \
   134  	ipcache_lookup6(&IPCACHE_MAP, addr, V6_CACHE_KEY_LEN)
   135  #define lookup_ip4_remote_endpoint(addr) \
   136  	ipcache_lookup4(&IPCACHE_MAP, addr, V4_CACHE_KEY_LEN)
   137  #endif /* HAVE_LPM_MAP_TYPE */
   138  
   139  enum ep_cfg_flag {
   140  	EP_F_SKIP_POLICY_INGRESS = 1<<0,
   141  	EP_F_SKIP_POLICY_EGRESS = 1<<1,
   142  };
   143  
   144  #ifdef CONFIG_MAP
   145  static __always_inline struct ep_config *
   146  lookup_ep_config(void)
   147  {
   148  	__u32 key = 0;
   149  	return map_lookup_elem(&CONFIG_MAP, &key);
   150  }
   151  #endif /* CONFIG_MAP */
   152  
   153  #endif /* __LIB_EPS_H_ */