FD.io VPP  v17.01-9-ge7dcee4
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;
53 
54  if (IP4 == ip_addr_version (&lgt->key->lcl))
55  {
56  ip4_udp_lisp_gpe_header_t *h0;
57  ip4_header_t *ip0;
58 
59  len = sizeof (*h0);
60 
62 
63  h0 = (ip4_udp_lisp_gpe_header_t *) rw;
64 
65  /* Fixed portion of the (outer) ip4 header */
66  ip0 = &h0->ip4;
67  ip0->ip_version_and_header_length = 0x45;
68  ip0->ttl = 254;
69  ip0->protocol = IP_PROTOCOL_UDP;
70 
71  /* we fix up the ip4 header length and checksum after-the-fact */
72  ip_address_copy_addr (&ip0->src_address, &lgt->key->lcl);
73  ip_address_copy_addr (&ip0->dst_address, &lgt->key->rmt);
74  ip0->checksum = ip4_header_checksum (ip0);
75 
76  /* UDP header, randomize src port on something, maybe? */
77  h0->udp.src_port = clib_host_to_net_u16 (4341);
78  h0->udp.dst_port = clib_host_to_net_u16 (UDP_DST_PORT_lisp_gpe);
79 
80  /* LISP-gpe header */
81  lisp0 = &h0->lisp;
82  }
83  else
84  {
85  ip6_udp_lisp_gpe_header_t *h0;
86  ip6_header_t *ip0;
87 
88  len = sizeof (*h0);
89 
91 
92  h0 = (ip6_udp_lisp_gpe_header_t *) rw;
93 
94  /* Fixed portion of the (outer) ip6 header */
95  ip0 = &h0->ip6;
97  clib_host_to_net_u32 (0x6 << 28);
98  ip0->hop_limit = 254;
99  ip0->protocol = IP_PROTOCOL_UDP;
100 
101  /* we fix up the ip6 header length after-the-fact */
102  ip_address_copy_addr (&ip0->src_address, &lgt->key->lcl);
103  ip_address_copy_addr (&ip0->dst_address, &lgt->key->rmt);
104 
105  /* UDP header, randomize src port on something, maybe? */
106  h0->udp.src_port = clib_host_to_net_u16 (4341);
107  h0->udp.dst_port = clib_host_to_net_u16 (UDP_DST_PORT_lisp_gpe);
108 
109  /* LISP-gpe header */
110  lisp0 = &h0->lisp;
111  }
112 
113  lisp0->flags = ladj->flags;
114  lisp0->ver_res = 0;
115  lisp0->res = 0;
116  lisp0->next_protocol = payload_proto;
117  lisp0->iid = clib_host_to_net_u32 (ladj->vni) >> 8; /* first 24 bits only */
118 
119  return (rw);
120 }
121 
122 static lisp_gpe_tunnel_t *
124 {
125  uword *p;
126 
127  p = hash_get_mem (lisp_gpe_tunnel_db, (void *) key);
128 
129  if (NULL != p)
130  {
131  return (pool_elt_at_index (lisp_gpe_tunnel_pool, p[0]));
132  }
133  return (NULL);
134 }
135 
138 {
139  return (pool_elt_at_index (lisp_gpe_tunnel_pool, lgti));
140 }
141 
142 index_t
144  u32 rloc_fib_index)
145 {
146  lisp_gpe_tunnel_key_t key = {
147  .lcl = pair->lcl_loc,
148  .rmt = pair->rmt_loc,
149  .fib_index = rloc_fib_index,
150  };
151  lisp_gpe_tunnel_t *lgt;
152  fib_prefix_t pfx;
153 
154  lgt = lisp_gpe_tunnel_db_find (&key);
155 
156  if (NULL == lgt)
157  {
158  pool_get (lisp_gpe_tunnel_pool, lgt);
159  memset (lgt, 0, sizeof (*lgt));
160 
161  lgt->key = clib_mem_alloc (sizeof (*lgt->key));
162  memset (lgt->key, 0, sizeof (*lgt->key));
163 
164  lgt->key->rmt = pair->rmt_loc;
165  lgt->key->lcl = pair->lcl_loc;
166  lgt->key->fib_index = rloc_fib_index;
167 
168  /*
169  * source the FIB entry for the RLOC so we can track its forwarding
170  * chain
171  */
172  ip_address_to_fib_prefix (&lgt->key->rmt, &pfx);
173 
174  lgt->fib_entry_index = fib_table_entry_special_add (rloc_fib_index,
175  &pfx,
179 
181  (lgt - lisp_gpe_tunnel_pool));
182  }
183 
184  lgt->locks++;
185 
186  return (lgt - lisp_gpe_tunnel_pool);
187 }
188 
189 void
191 {
192  lisp_gpe_tunnel_t *lgt;
193 
194  lgt = lisp_gpe_tunnel_get_i (lgti);
195  lgt->locks--;
196 
197  if (0 == lgt->locks)
198  {
200  clib_mem_free (lgt->key);
201  pool_put (lisp_gpe_tunnel_pool, lgt);
202  }
203 }
204 
205 const lisp_gpe_tunnel_t *
207 {
208  return (lisp_gpe_tunnel_get_i (lgti));
209 }
210 
211 /** Format LISP-GPE tunnel. */
212 u8 *
213 format_lisp_gpe_tunnel (u8 * s, va_list * args)
214 {
215  lisp_gpe_tunnel_t *lgt = va_arg (*args, lisp_gpe_tunnel_t *);
216 
217  s = format (s, "tunnel %d\n", lgt - lisp_gpe_tunnel_pool);
218  s = format (s, " fib-index: %d, locks:%d \n",
219  lgt->key->fib_index, lgt->locks);
220  s = format (s, " lisp ver 0\n");
221 
222  s = format (s, " locator-pair:\n");
223  s = format (s, " local: %U remote: %U\n",
224  format_ip_address, &lgt->key->lcl,
225  format_ip_address, &lgt->key->rmt);
226  s = format (s, " RLOC FIB entry: %d\n", lgt->fib_entry_index);
227 
228  return s;
229 }
230 
231 /**
232  * CLI command to show LISP-GPE tunnels.
233  */
234 static clib_error_t *
236  unformat_input_t * input,
237  vlib_cli_command_t * cmd)
238 {
239  lisp_gpe_tunnel_t *lgt;
240  index_t index;
241 
242  if (pool_elts (lisp_gpe_tunnel_pool) == 0)
243  vlib_cli_output (vm, "No lisp-gpe tunnels configured...");
244 
245  if (unformat (input, "%d", &index))
246  {
247  lgt = lisp_gpe_tunnel_get_i (index);
248  vlib_cli_output (vm, "%U", format_lisp_gpe_tunnel, lgt);
249  }
250  else
251  {
252  /* *INDENT-OFF* */
253  pool_foreach (lgt, lisp_gpe_tunnel_pool,
254  ({
255  vlib_cli_output (vm, "%U", format_lisp_gpe_tunnel, lgt);
256  }));
257  /* *INDENT-ON* */
258  }
259 
260  return 0;
261 }
262 
263 /* *INDENT-OFF* */
264 VLIB_CLI_COMMAND (show_lisp_gpe_tunnel_command, static) =
265 {
266  .path = "show lisp gpe tunnel",
268 };
269 /* *INDENT-ON* */
270 
271 static clib_error_t *
273 {
275  sizeof (lisp_gpe_tunnel_key_t),
276  sizeof (uword));
277 
278  return (NULL);
279 }
280 
282 
283 /*
284  * fd.io coding-style-patch-verification: ON
285  *
286  * Local Variables:
287  * eval: (c-set-style "gnu")
288  * End:
289  */
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:105
uword unformat(unformat_input_t *i, char *fmt,...)
Definition: unformat.c:966
ip4_address_t src_address
Definition: ip4_packet.h:163
#define NULL
Definition: clib.h:55
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:138
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:274
#define vec_validate_aligned(V, I, A)
Make sure vector is long enough for given index (no header, specified alignment)
Definition: vec.h:407
#define pool_get(P, E)
Allocate an object E from a pool P (unspecified alignment).
Definition: pool.h:200
ip6_address_t src_address
Definition: ip6_packet.h:337
A Key for a tunnel.
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:348
lisp_gpe_tunnel_t * lisp_gpe_tunnel_get_i(index_t lgti)
#define VLIB_INIT_FUNCTION(x)
Definition: init.h:111
ip4_address_t dst_address
Definition: ip4_packet.h:163
void lisp_gpe_tunnel_unlock(index_t lgti)
Aggregrate type for a prefix.
Definition: fib_types.h:145
#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:216
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:637
void ip_address_copy_addr(void *dst, const ip_address_t *src)
Definition: lisp_types.c:766
#define ADJ_INDEX_INVALID
Invalid ADJ index - used when no adj is known likewise blazoned capitals INVALID speak volumes where ...
Definition: adj_types.h:36
#define pool_elt_at_index(p, i)
Returns pointer to element at given index.
Definition: pool.h:369
#define hash_unset_mem(h, key)
Definition: hash.h:280
Common utility functions for IPv4, IPv6 and L2 LISP-GPE tunnels.
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, adj_index_t adj_index)
Add a &#39;special&#39; entry to the FIB that links to the adj passed A special entry is an entry that the FI...
Definition: fib_table.c:369
#define pool_put(P, E)
Free an object E in pool P.
Definition: pool.h:214
ip_address_t lcl_loc
Definition: lisp_types.h:334
void vlib_cli_output(vlib_main_t *vm, char *fmt,...)
Definition: cli.c:576
static lisp_gpe_tunnel_t * lisp_gpe_tunnel_pool
Pool of all LISP tunnels.
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:154
unsigned int u32
Definition: types.h:88
u8 * format_ip_address(u8 *s, va_list *args)
Definition: lisp_types.c:127
static void clib_mem_free(void *p)
Definition: mem.h:176
static void * clib_mem_alloc(uword size)
Definition: mem.h:109
static uword * lisp_gpe_tunnel_db
a DB of all tunnels
u64 uword
Definition: types.h:112
u32 ip_version_traffic_class_and_flow_label
Definition: ip6_packet.h:324
A LISP GPE Adjacency.
unsigned char u8
Definition: types.h:56
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:268
u8 * format(u8 *s, const char *fmt,...)
Definition: format.c:418
ip_address_t rmt_loc
Definition: lisp_types.h:335
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:131
struct _unformat_input_t unformat_input_t
lisp_gpe_next_protocol_e
#define CLIB_CACHE_LINE_BYTES
Definition: cache.h:67
u8 flags
LISP header fields in HOST byte order.
static u16 ip4_header_checksum(ip4_header_t *i)
Definition: ip4_packet.h:238
A LISP GPE Tunnel.
LISP-GPE definitions.
ip6_address_t dst_address
Definition: ip6_packet.h:337
static uword pool_elts(void *v)
Number of active elements in a pool.
Definition: pool.h:109