FD.io VPP  v18.10-32-g1161dda
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 <vnet/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 (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 {
151  lisp_gpe_tunnel_key_t key = {
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  {
163  pool_get (lisp_gpe_tunnel_pool, lgt);
164  memset (lgt, 0, sizeof (*lgt));
165 
166  lgt->key = clib_mem_alloc (sizeof (*lgt->key));
167  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);
205  pool_put (lisp_gpe_tunnel_pool, lgt);
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  {
251  lgt = lisp_gpe_tunnel_get_i (index);
252  vlib_cli_output (vm, "%U", format_lisp_gpe_tunnel, lgt);
253  }
254  else
255  {
256  /* *INDENT-OFF* */
257  pool_foreach (lgt, lisp_gpe_tunnel_pool,
258  ({
259  vlib_cli_output (vm, "%U", format_lisp_gpe_tunnel, lgt);
260  }));
261  /* *INDENT-ON* */
262  }
263 
264  return 0;
265 }
266 
267 /* *INDENT-OFF* */
268 VLIB_CLI_COMMAND (show_lisp_gpe_tunnel_command, static) =
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  */
const lisp_gpe_tunnel_t * lisp_gpe_tunnel_get(index_t lgti)
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.
Recursive resolution source.
Definition: fib_entry.h:125
ip4_address_t src_address
Definition: ip4_packet.h:169
#define NULL
Definition: clib.h:57
index_t lisp_gpe_tunnel_find_or_create_and_lock(const locator_pair_t *pair, u32 rloc_fib_index)
void ip_address_to_fib_prefix(const ip_address_t *addr, fib_prefix_t *prefix)
convert from a LISP address to a FIB prefix
Definition: control.c:146
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:41
u8 * format_lisp_gpe_tunnel(u8 *s, va_list *args)
Format LISP-GPE tunnel.
#define hash_set_mem(h, key, value)
Definition: hash.h:275
u8 * format(u8 *s, const char *fmt,...)
Definition: format.c:419
#define vec_validate_aligned(V, I, A)
Make sure vector is long enough for given index (no header, specified alignment)
Definition: vec.h:448
#define pool_get(P, E)
Allocate an object E from a pool P (unspecified alignment).
Definition: pool.h:228
ip6_address_t src_address
Definition: ip6_packet.h:378
unsigned char u8
Definition: types.h:56
A Key for a tunnel.
memset(h->entries, 0, sizeof(h->entries[0])*entries)
fib_node_index_t fib_entry_index
the FIB entry through which the remote rloc is reachable s
#define pool_foreach(VAR, POOL, BODY)
Iterate through pool.
Definition: pool.h:443
lisp_gpe_tunnel_t * lisp_gpe_tunnel_get_i(index_t lgti)
#define VLIB_INIT_FUNCTION(x)
Definition: init.h:163
ip4_address_t dst_address
Definition: ip4_packet.h:169
void lisp_gpe_tunnel_unlock(index_t lgti)
Aggregrate type for a prefix.
Definition: fib_types.h:203
unsigned int u32
Definition: types.h:88
enum gpe_encap_mode_e gpe_encap_mode_t
#define ip_addr_version(_a)
Definition: lisp_types.h:56
Common utility functions for IPv4, IPv6 and L2 LISP-GPE adjacencys.
Definition: fib_entry.h:275
static clib_error_t * lisp_gpe_tunnel_module_init(vlib_main_t *vm)
#define hash_create_mem(elts, key_bytes, value_bytes)
Definition: hash.h:661
void ip_address_copy_addr(void *dst, const ip_address_t *src)
Definition: lisp_types.c:886
#define pool_elt_at_index(p, i)
Returns pointer to element at given index.
Definition: pool.h:464
#define hash_unset_mem(h, key)
Definition: hash.h:291
Common utility functions for IPv4, IPv6 and L2 LISP-GPE tunnels.
struct _unformat_input_t unformat_input_t
#define pool_put(P, E)
Free an object E in pool P.
Definition: pool.h:274
ip_address_t lcl_loc
Definition: lisp_types.h:384
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 &#39;special&#39; entry to the FIB.
Definition: fib_table.c:388
static lisp_gpe_tunnel_t * lisp_gpe_tunnel_pool
Pool of all LISP tunnels.
vlib_main_t * vm
Definition: buffer.c:294
LISP-GPE header.
u32 locks
number of reference counting locks
lisp_gpe_tunnel_key_t * key
RLOC pair and rloc fib_index.
#define VLIB_CLI_COMMAND(x,...)
Definition: cli.h:155
gpe_encap_mode_t vnet_gpe_get_encap_mode(void)
Definition: lisp_gpe.c:631
u8 * format_ip_address(u8 *s, va_list *args)
Definition: lisp_types.c:144
static void clib_mem_free(void *p)
Definition: mem.h:205
static void * clib_mem_alloc(uword size)
Definition: mem.h:132
static uword * lisp_gpe_tunnel_db
a DB of all tunnels
u32 ip_version_traffic_class_and_flow_label
Definition: ip6_packet.h:365
A LISP GPE Adjacency.
u64 uword
Definition: types.h:112
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_types.h:37
#define hash_get_mem(h, key)
Definition: hash.h:269
ip_address_t rmt_loc
Definition: lisp_types.h:385
static lisp_gpe_tunnel_t * lisp_gpe_tunnel_db_find(const lisp_gpe_tunnel_key_t *key)
u8 ip_version_and_header_length
Definition: ip4_packet.h:137
lisp_gpe_next_protocol_e
#define CLIB_CACHE_LINE_BYTES
Definition: cache.h:59
void vlib_cli_output(vlib_main_t *vm, char *fmt,...)
Definition: cli.c:725
u8 flags
LISP header fields in HOST byte order.
static u16 ip4_header_checksum(ip4_header_t *i)
Definition: ip4_packet.h:246
A LISP GPE Tunnel.
LISP-GPE definitions.
uword unformat(unformat_input_t *i, const char *fmt,...)
Definition: unformat.c:972
ip6_address_t dst_address
Definition: ip6_packet.h:378
static uword pool_elts(void *v)
Number of active elements in a pool.
Definition: pool.h:128