FD.io VPP  v21.06-3-gbb25fbf28
Vector Packet Processing
lisp_gpe_tunnel.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2016 Cisco and/or its affiliates.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at:
6  *
7  * http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 /**
16  * @file
17  * @brief Common utility functions for IPv4, IPv6 and L2 LISP-GPE tunnels.
18  *
19  */
20 #include <lisp/lisp-gpe/lisp_gpe.h>
23 
24 #include <vnet/fib/fib_table.h>
25 
26 /**
27  * @brief Pool of all LISP tunnels
28  */
30 
31 /**
32  * @brief a DB of all tunnels
33  */
35 
36 /**
37  * @brief Compute IP-UDP-GPE sub-tunnel encap/rewrite header.
38  *
39  * @param[in] t Parent of the sub-tunnel.
40  * @param[in] st Sub-tunnel.
41  * @param[in] lp Local and remote locators used in the encap header.
42  *
43  * @return 0 on success.
44  */
45 u8 *
47  const lisp_gpe_adjacency_t * ladj,
48  lisp_gpe_next_protocol_e payload_proto)
49 {
50  lisp_gpe_header_t *lisp0;
51  u8 *rw = 0;
52  int len;
54 
55  if (AF_IP4 == ip_addr_version (&lgt->key->lcl))
56  {
57  ip4_udp_lisp_gpe_header_t *h0;
58  ip4_header_t *ip0;
59 
60  len = sizeof (*h0);
61 
63 
64  h0 = (ip4_udp_lisp_gpe_header_t *) rw;
65 
66  /* Fixed portion of the (outer) ip4 header */
67  ip0 = &h0->ip4;
68  ip0->ip_version_and_header_length = 0x45;
69  ip0->ttl = 254;
70  ip0->protocol = IP_PROTOCOL_UDP;
71 
72  /* we fix up the ip4 header length and checksum after-the-fact */
73  ip_address_copy_addr (&ip0->src_address, &lgt->key->lcl);
74  ip_address_copy_addr (&ip0->dst_address, &lgt->key->rmt);
75  ip0->checksum = ip4_header_checksum (ip0);
76 
77  /* UDP header, randomize src port on something, maybe? */
78  h0->udp.src_port = clib_host_to_net_u16 (4341);
79  h0->udp.dst_port = clib_host_to_net_u16 (UDP_DST_PORT_lisp_gpe);
80 
81  /* LISP-gpe header */
82  lisp0 = &h0->lisp;
83  }
84  else
85  {
86  ip6_udp_lisp_gpe_header_t *h0;
87  ip6_header_t *ip0;
88 
89  len = sizeof (*h0);
90 
92 
93  h0 = (ip6_udp_lisp_gpe_header_t *) rw;
94 
95  /* Fixed portion of the (outer) ip6 header */
96  ip0 = &h0->ip6;
98  clib_host_to_net_u32 (0x6 << 28);
99  ip0->hop_limit = 254;
100  ip0->protocol = IP_PROTOCOL_UDP;
101 
102  /* we fix up the ip6 header length after-the-fact */
103  ip_address_copy_addr (&ip0->src_address, &lgt->key->lcl);
104  ip_address_copy_addr (&ip0->dst_address, &lgt->key->rmt);
105 
106  /* UDP header, randomize src port on something, maybe? */
107  h0->udp.src_port = clib_host_to_net_u16 (4341);
108  h0->udp.dst_port = clib_host_to_net_u16 (UDP_DST_PORT_lisp_gpe);
109 
110  /* LISP-gpe header */
111  lisp0 = &h0->lisp;
112  }
113 
114  lisp0->flags = ladj->flags;
115  if (GPE_ENCAP_VXLAN == encap_mode)
116  /* unset P flag */
117  lisp0->flags &= ~LISP_GPE_FLAGS_P;
118 
119  lisp0->ver_res = 0;
120  lisp0->res = 0;
121  lisp0->next_protocol = payload_proto;
122  lisp0->iid = clib_host_to_net_u32 (ladj->vni) >> 8; /* first 24 bits only */
123 
124  return (rw);
125 }
126 
127 static lisp_gpe_tunnel_t *
129 {
130  uword *p;
131 
132  p = hash_get_mem (lisp_gpe_tunnel_db, (void *) key);
133 
134  if (NULL != p)
135  {
136  return (pool_elt_at_index (lisp_gpe_tunnel_pool, p[0]));
137  }
138  return (NULL);
139 }
140 
143 {
144  return (pool_elt_at_index (lisp_gpe_tunnel_pool, lgti));
145 }
146 
147 index_t
149  u32 rloc_fib_index)
150 {
152  .lcl = pair->lcl_loc,
153  .rmt = pair->rmt_loc,
154  .fib_index = rloc_fib_index,
155  };
156  lisp_gpe_tunnel_t *lgt;
157  fib_prefix_t pfx;
158 
159  lgt = lisp_gpe_tunnel_db_find (&key);
160 
161  if (NULL == lgt)
162  {
164  clib_memset (lgt, 0, sizeof (*lgt));
165 
166  lgt->key = clib_mem_alloc (sizeof (*lgt->key));
167  clib_memset (lgt->key, 0, sizeof (*lgt->key));
168 
169  lgt->key->rmt = pair->rmt_loc;
170  lgt->key->lcl = pair->lcl_loc;
171  lgt->key->fib_index = rloc_fib_index;
172 
173  /*
174  * source the FIB entry for the RLOC so we can track its forwarding
175  * chain
176  */
177  ip_address_to_fib_prefix (&lgt->key->rmt, &pfx);
178 
179  lgt->fib_entry_index = fib_table_entry_special_add (rloc_fib_index,
180  &pfx,
183 
185  (lgt - lisp_gpe_tunnel_pool));
186  }
187 
188  lgt->locks++;
189 
190  return (lgt - lisp_gpe_tunnel_pool);
191 }
192 
193 void
195 {
196  lisp_gpe_tunnel_t *lgt;
197 
198  lgt = lisp_gpe_tunnel_get_i (lgti);
199  lgt->locks--;
200 
201  if (0 == lgt->locks)
202  {
204  clib_mem_free (lgt->key);
206  }
207 }
208 
209 const lisp_gpe_tunnel_t *
211 {
212  return (lisp_gpe_tunnel_get_i (lgti));
213 }
214 
215 /** Format LISP-GPE tunnel. */
216 u8 *
217 format_lisp_gpe_tunnel (u8 * s, va_list * args)
218 {
219  lisp_gpe_tunnel_t *lgt = va_arg (*args, lisp_gpe_tunnel_t *);
220 
221  s = format (s, "tunnel %d\n", lgt - lisp_gpe_tunnel_pool);
222  s = format (s, " fib-index: %d, locks:%d \n",
223  lgt->key->fib_index, lgt->locks);
224  s = format (s, " lisp ver 0\n");
225 
226  s = format (s, " locator-pair:\n");
227  s = format (s, " local: %U remote: %U\n",
228  format_ip_address, &lgt->key->lcl,
229  format_ip_address, &lgt->key->rmt);
230  s = format (s, " RLOC FIB entry: %d\n", lgt->fib_entry_index);
231 
232  return s;
233 }
234 
235 /**
236  * CLI command to show LISP-GPE tunnels.
237  */
238 static clib_error_t *
240  unformat_input_t * input,
241  vlib_cli_command_t * cmd)
242 {
243  lisp_gpe_tunnel_t *lgt;
244  index_t index;
245 
246  if (pool_elts (lisp_gpe_tunnel_pool) == 0)
247  vlib_cli_output (vm, "No lisp-gpe tunnels configured...");
248 
249  if (unformat (input, "%d", &index))
250  {
253  }
254  else
255  {
256  /* *INDENT-OFF* */
258  {
260  }
261  /* *INDENT-ON* */
262  }
263 
264  return 0;
265 }
266 
267 /* *INDENT-OFF* */
269 {
270  .path = "show gpe tunnel",
272 };
273 /* *INDENT-ON* */
274 
275 static clib_error_t *
277 {
279  sizeof (lisp_gpe_tunnel_key_t),
280  sizeof (uword));
281 
282  return (NULL);
283 }
284 
286 
287 /*
288  * fd.io coding-style-patch-verification: ON
289  *
290  * Local Variables:
291  * eval: (c-set-style "gnu")
292  * End:
293  */
lisp_gpe_tunnel_find_or_create_and_lock
index_t lisp_gpe_tunnel_find_or_create_and_lock(const locator_pair_t *pair, u32 rloc_fib_index)
Definition: lisp_gpe_tunnel.c:148
pool_elt_at_index
#define pool_elt_at_index(p, i)
Returns pointer to element at given index.
Definition: pool.h:553
lisp_gpe_next_protocol_e
lisp_gpe_next_protocol_e
Definition: lisp_gpe_packet.h:132
ip6_header_t::protocol
u8 protocol
Definition: ip6_packet.h:304
clib_mem_free
static void clib_mem_free(void *p)
Definition: mem.h:311
ip6_header_t::hop_limit
u8 hop_limit
Definition: ip6_packet.h:307
lisp_gpe_header_t::flags
u8 flags
Definition: lisp_gpe_packet.h:102
vlib_cli_command_t::path
char * path
Definition: cli.h:96
gpe_encap_mode_t
enum gpe_encap_mode_e gpe_encap_mode_t
fib_table.h
ip_address_to_fib_prefix
void ip_address_to_fib_prefix(const ip_address_t *addr, fib_prefix_t *prefix)
convert from a IP address to a FIB prefix
Definition: ip_types.c:270
pool_put
#define pool_put(P, E)
Free an object E in pool P.
Definition: pool.h:305
vm
vlib_main_t * vm
X-connect all packets from the HOST to the PHY.
Definition: nat44_ei.c:3047
AF_IP4
@ AF_IP4
Definition: ip_types.h:23
GPE_ENCAP_VXLAN
@ GPE_ENCAP_VXLAN
Definition: lisp_gpe.h:114
unformat_input_t
struct _unformat_input_t unformat_input_t
ip4_header_t
Definition: ip4_packet.h:87
lisp_gpe.h
LISP-GPE definitions.
key
typedef key
Definition: ipsec_types.api:88
unformat
uword unformat(unformat_input_t *i, const char *fmt,...)
Definition: unformat.c:978
ip_addr_version
#define ip_addr_version(_a)
Definition: ip_types.h:93
pool_foreach
#define pool_foreach(VAR, POOL)
Iterate through pool.
Definition: pool.h:534
ip_address_copy_addr
void ip_address_copy_addr(void *dst, const ip_address_t *src)
Definition: ip_types.c:164
lisp_gpe_tunnel_get_i
lisp_gpe_tunnel_t * lisp_gpe_tunnel_get_i(index_t lgti)
Definition: lisp_gpe_tunnel.c:142
len
u8 len
Definition: ip_types.api:103
locator_pair::rmt_loc
ip_address_t rmt_loc
Definition: lisp_types.h:330
vec_validate_aligned
#define vec_validate_aligned(V, I, A)
Make sure vector is long enough for given index (no header, specified alignment)
Definition: vec.h:534
FIB_ENTRY_FLAG_NONE
@ FIB_ENTRY_FLAG_NONE
Definition: fib_entry.h:112
lisp_gpe_tunnel_t_::fib_entry_index
fib_node_index_t fib_entry_index
the FIB entry through which the remote rloc is reachable s
Definition: lisp_gpe_tunnel.h:63
index_t
u32 index_t
A Data-Path Object is an object that represents actions that are applied to packets are they are swit...
Definition: dpo.h:43
format_ip_address
u8 * format_ip_address(u8 *s, va_list *args)
Definition: ip_types.c:21
uword
u64 uword
Definition: types.h:112
hash_create_mem
#define hash_create_mem(elts, key_bytes, value_bytes)
Definition: hash.h:660
locator_pair::lcl_loc
ip_address_t lcl_loc
Definition: lisp_types.h:329
hash_set_mem
#define hash_set_mem(h, key, value)
Definition: hash.h:275
lisp_gpe_tunnel_get
const lisp_gpe_tunnel_t * lisp_gpe_tunnel_get(index_t lgti)
Definition: lisp_gpe_tunnel.c:210
ip6_header_t::dst_address
ip6_address_t dst_address
Definition: ip6_packet.h:310
lisp_gpe_header_t::next_protocol
u8 next_protocol
Definition: lisp_gpe_packet.h:105
show_lisp_gpe_tunnel_command_fn
static clib_error_t * show_lisp_gpe_tunnel_command_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
CLI command to show LISP-GPE tunnels.
Definition: lisp_gpe_tunnel.c:239
pool_get
#define pool_get(P, E)
Allocate an object E from a pool P (unspecified alignment).
Definition: pool.h:255
VLIB_CLI_COMMAND
#define VLIB_CLI_COMMAND(x,...)
Definition: cli.h:163
ip4_header_t::checksum
u16 checksum
Definition: ip4_packet.h:118
lisp_gpe_tunnel_key_t_::rmt
ip_address_t rmt
Definition: lisp_gpe_tunnel.h:37
CLIB_CACHE_LINE_BYTES
#define CLIB_CACHE_LINE_BYTES
Definition: cache.h:59
vlib_cli_output
void vlib_cli_output(vlib_main_t *vm, char *fmt,...)
Definition: cli.c:716
lisp_gpe_tunnel.h
Common utility functions for IPv4, IPv6 and L2 LISP-GPE tunnels.
ip4_header_t::dst_address
ip4_address_t dst_address
Definition: ip4_packet.h:125
locator_pair
Definition: lisp_types.h:326
lisp_gpe_tunnel_key_t_::fib_index
u32 fib_index
Definition: lisp_gpe_tunnel.h:39
index
u32 index
Definition: flow_types.api:221
ip4_header_t::src_address
ip4_address_t src_address
Definition: ip4_packet.h:125
hash_get_mem
#define hash_get_mem(h, key)
Definition: hash.h:269
format
description fragment has unexpected format
Definition: map.api:433
lisp_gpe_tunnel_db
static uword * lisp_gpe_tunnel_db
a DB of all tunnels
Definition: lisp_gpe_tunnel.c:34
u32
unsigned int u32
Definition: types.h:88
VLIB_INIT_FUNCTION
#define VLIB_INIT_FUNCTION(x)
Definition: init.h:172
lisp_gpe_tunnel_t_::key
lisp_gpe_tunnel_key_t * key
RLOC pair and rloc fib_index.
Definition: lisp_gpe_tunnel.h:53
lisp_gpe_header_t
LISP-GPE header.
Definition: lisp_gpe_packet.h:100
ip4_header_t::ttl
u8 ttl
Definition: ip4_packet.h:112
show_lisp_gpe_tunnel_command
static vlib_cli_command_t show_lisp_gpe_tunnel_command
(constructor) VLIB_CLI_COMMAND (show_lisp_gpe_tunnel_command)
Definition: lisp_gpe_tunnel.c:268
lisp_gpe_header_t::iid
u32 iid
Definition: lisp_gpe_packet.h:106
lisp_gpe_header_t::res
u8 res
Definition: lisp_gpe_packet.h:104
lisp_gpe_adjacency_t_
A LISP GPE Adjacency.
Definition: lisp_gpe_adjacency.h:43
pool_elts
static uword pool_elts(void *v)
Number of active elements in a pool.
Definition: pool.h:127
lisp_gpe_tunnel_key_t_::lcl
ip_address_t lcl
Definition: lisp_gpe_tunnel.h:38
ip6_header_t
Definition: ip6_packet.h:294
lisp_gpe_tunnel_build_rewrite
u8 * lisp_gpe_tunnel_build_rewrite(const lisp_gpe_tunnel_t *lgt, const lisp_gpe_adjacency_t *ladj, lisp_gpe_next_protocol_e payload_proto)
Compute IP-UDP-GPE sub-tunnel encap/rewrite header.
Definition: lisp_gpe_tunnel.c:46
lisp_gpe_adjacency_t_::flags
u8 flags
LISP header fields in HOST byte order.
Definition: lisp_gpe_adjacency.h:92
ip6_header_t::src_address
ip6_address_t src_address
Definition: ip6_packet.h:310
clib_memset
clib_memset(h->entries, 0, sizeof(h->entries[0]) *entries)
vlib_main_t
Definition: main.h:102
ip4_header_t::ip_version_and_header_length
u8 ip_version_and_header_length
Definition: ip4_packet.h:93
lisp_gpe_tunnel_t_::locks
u32 locks
number of reference counting locks
Definition: lisp_gpe_tunnel.h:58
lisp_gpe_adjacency.h
Common utility functions for IPv4, IPv6 and L2 LISP-GPE adjacencys.
vnet_gpe_get_encap_mode
gpe_encap_mode_t vnet_gpe_get_encap_mode(void)
Definition: lisp_gpe.c:631
u8
unsigned char u8
Definition: types.h:56
clib_error_t
Definition: clib_error.h:21
hash_unset_mem
#define hash_unset_mem(h, key)
Definition: hash.h:291
ip4_header_checksum
static u16 ip4_header_checksum(ip4_header_t *i)
Definition: ip4_packet.h:314
vlib_init_function_t
clib_error_t *() vlib_init_function_t(struct vlib_main_t *vm)
Definition: init.h:51
lisp_gpe_tunnel_t_
A LISP GPE Tunnel.
Definition: lisp_gpe_tunnel.h:48
lisp_gpe_tunnel_unlock
void lisp_gpe_tunnel_unlock(index_t lgti)
Definition: lisp_gpe_tunnel.c:194
lisp_gpe_tunnel_pool
static lisp_gpe_tunnel_t * lisp_gpe_tunnel_pool
Pool of all LISP tunnels.
Definition: lisp_gpe_tunnel.c:29
FIB_SOURCE_RR
@ FIB_SOURCE_RR
Recursive resolution source.
Definition: fib_source.h:122
fib_table_entry_special_add
fib_node_index_t fib_table_entry_special_add(u32 fib_index, const fib_prefix_t *prefix, fib_source_t source, fib_entry_flag_t flags)
Add a 'special' entry to the FIB.
Definition: fib_table.c:405
format_lisp_gpe_tunnel
u8 * format_lisp_gpe_tunnel(u8 *s, va_list *args)
Format LISP-GPE tunnel.
Definition: lisp_gpe_tunnel.c:217
lisp_gpe_tunnel_module_init
static clib_error_t * lisp_gpe_tunnel_module_init(vlib_main_t *vm)
Definition: lisp_gpe_tunnel.c:276
vlib_cli_command_t
Definition: cli.h:92
lisp_gpe_header_t::ver_res
u8 ver_res
Definition: lisp_gpe_packet.h:103
clib_mem_alloc
static void * clib_mem_alloc(uword size)
Definition: mem.h:253
ip6_header_t::ip_version_traffic_class_and_flow_label
u32 ip_version_traffic_class_and_flow_label
Definition: ip6_packet.h:297
fib_prefix_t_
Aggregate type for a prefix.
Definition: fib_types.h:202
ip4_header_t::protocol
u8 protocol
Definition: ip4_packet.h:115
lisp_gpe_adjacency_t_::vni
u32 vni
The VNI.
Definition: lisp_gpe_adjacency.h:58
lisp_gpe_tunnel_db_find
static lisp_gpe_tunnel_t * lisp_gpe_tunnel_db_find(const lisp_gpe_tunnel_key_t *key)
Definition: lisp_gpe_tunnel.c:128
lisp_gpe_tunnel_key_t_
A Key for a tunnel.
Definition: lisp_gpe_tunnel.h:35