FD.io VPP  v17.04.2-2-ga8f93f8
Vector Packet Processing
lisp_gpe.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 
21 #include <vnet/lisp-gpe/lisp_gpe.h>
25 
26 /** LISP-GPE global state */
28 
29 
30 /** CLI command to add/del forwarding entry. */
31 static clib_error_t *
33  unformat_input_t * input,
34  vlib_cli_command_t * cmd)
35 {
36  unformat_input_t _line_input, *line_input = &_line_input;
37  u8 is_add = 1;
38  ip_address_t lloc, rloc;
39  clib_error_t *error = 0;
40  gid_address_t _reid, *reid = &_reid, _leid, *leid = &_leid;
41  u8 reid_set = 0, leid_set = 0, is_negative = 0, dp_table_set = 0,
42  vni_set = 0;
43  u32 vni = 0, dp_table = 0, action = ~0, w;
44  locator_pair_t pair, *pairs = 0;
45  int rv;
46 
47  memset (leid, 0, sizeof (*leid));
48  memset (reid, 0, sizeof (*reid));
49 
50  /* Get a line of input. */
51  if (!unformat_user (input, unformat_line_input, line_input))
52  return 0;
53 
54  while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
55  {
56  if (unformat (line_input, "del"))
57  is_add = 0;
58  else if (unformat (line_input, "add"))
59  is_add = 1;
60  else if (unformat (line_input, "leid %U", unformat_gid_address, leid))
61  {
62  leid_set = 1;
63  }
64  else if (unformat (line_input, "reid %U", unformat_gid_address, reid))
65  {
66  reid_set = 1;
67  }
68  else if (unformat (line_input, "vni %u", &vni))
69  {
70  gid_address_vni (leid) = vni;
71  gid_address_vni (reid) = vni;
72  vni_set = 1;
73  }
74  else if (unformat (line_input, "vrf %u", &dp_table))
75  {
76  dp_table_set = 1;
77  }
78  else if (unformat (line_input, "bd %u", &dp_table))
79  {
80  dp_table_set = 1;
81  }
82  else if (unformat (line_input, "negative action %U",
84  {
85  is_negative = 1;
86  }
87  else if (unformat (line_input, "loc-pair %U %U w %d",
88  unformat_ip_address, &lloc,
89  unformat_ip_address, &rloc, &w))
90  {
91  pair.lcl_loc = lloc;
92  pair.rmt_loc = rloc;
93  pair.weight = w;
94  pair.priority = 0;
95  vec_add1 (pairs, pair);
96  }
97  else
98  {
99  error = unformat_parse_error (line_input);
100  vlib_cli_output (vm, "parse error: '%U'",
101  format_unformat_error, line_input);
102  goto done;
103  }
104  }
105 
106  if (!reid_set)
107  {
108  vlib_cli_output (vm, "remote eid must be set!");
109  goto done;
110  }
111 
112  if (gid_address_type (reid) != GID_ADDR_NSH && (!vni_set || !dp_table_set))
113  {
114  vlib_cli_output (vm, "vni and vrf/bd must be set!");
115  goto done;
116  }
117 
118  if (is_negative)
119  {
120  if (~0 == action)
121  {
122  vlib_cli_output (vm, "no action set for negative tunnel!");
123  goto done;
124  }
125  }
126  else
127  {
128  if (vec_len (pairs) == 0)
129  {
130  vlib_cli_output (vm, "expected ip4/ip6 locators");
131  goto done;
132  }
133  }
134 
135  if (!leid_set)
136  {
137  /* if leid not set, make sure it's the same AFI like reid */
138  gid_address_type (leid) = gid_address_type (reid);
139  if (GID_ADDR_IP_PREFIX == gid_address_type (reid))
141  }
142 
143  /* add fwd entry */
145  memset (a, 0, sizeof (a[0]));
146 
147  a->is_add = is_add;
148  a->is_negative = is_negative;
149  a->vni = vni;
150  a->table_id = dp_table;
151  gid_address_copy (&a->lcl_eid, leid);
152  gid_address_copy (&a->rmt_eid, reid);
153  a->locator_pairs = pairs;
154  a->action = action;
155 
157  if (0 != rv)
158  {
159  vlib_cli_output (vm, "failed to %s gpe tunnel!",
160  is_add ? "add" : "delete");
161  }
162 
163 done:
164  unformat_free (line_input);
165  vec_free (pairs);
166  return error;
167 }
168 
169 /* *INDENT-OFF* */
170 VLIB_CLI_COMMAND (lisp_gpe_add_del_fwd_entry_command, static) = {
171  .path = "gpe entry",
172  .short_help = "gpe entry add/del vni <vni> vrf/bd <id> [leid <leid>]"
173  "reid <reid> [loc-pair <lloc> <rloc> w <weight>] "
174  "[negative action <action>]",
176 };
177 /* *INDENT-ON* */
178 
179 /** Check if LISP-GPE is enabled. */
180 u8
182 {
184 
185  return lgm->is_en;
186 }
187 
188 /** Enable/disable LISP-GPE. */
189 clib_error_t *
191 {
193 
194  if (a->is_en)
195  {
196  lgm->is_en = 1;
197  }
198  else
199  {
200  /* remove all entries */
202 
203  /* disable all l3 ifaces */
205 
206  lgm->is_en = 0;
207  }
208 
209  return 0;
210 }
211 
212 /** Set GPE encapsulation mode. */
213 int
215 {
217 
218  if (mode >= GPE_ENCAP_COUNT)
219  return VNET_API_ERROR_INVALID_GPE_MODE;
220 
221  if (pool_elts (lgm->lisp_fwd_entry_pool) != 0)
222  return VNET_API_ERROR_LISP_GPE_ENTRIES_PRESENT;
223 
224  lgm->encap_mode = mode;
225  return 0;
226 }
227 
228 /** CLI command to set GPE encap */
229 static clib_error_t *
231  unformat_input_t * input,
232  vlib_cli_command_t * cmd)
233 {
234  unformat_input_t _line_input, *line_input = &_line_input;
236  vnet_api_error_t rv;
237 
238  /* Get a line of input. */
239  if (!unformat_user (input, unformat_line_input, line_input))
240  return 0;
241 
242  while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
243  {
244  if (unformat (line_input, "lisp"))
245  mode = GPE_ENCAP_LISP;
246  else if (unformat (line_input, "vxlan"))
247  mode = GPE_ENCAP_VXLAN;
248  else
249  {
250  return clib_error_return (0, "parse error: '%U'",
251  format_unformat_error, line_input);
252  }
253  }
254  rv = vnet_gpe_set_encap_mode (mode);
255  if (rv)
256  {
257  return clib_error_return (0,
258  "Error: invalid mode or GPE entries are present!");
259  }
260 
261  return 0;
262 }
263 
264 /* *INDENT-OFF* */
265 VLIB_CLI_COMMAND (gpe_set_encap_mode_command, static) = {
266  .path = "gpe encap",
267  .short_help = "gpe encap [lisp|vxlan]",
268  .function = gpe_set_encap_mode_command_fn,
269 };
270 /* *INDENT-ON* */
271 
272 /** Format GPE encap mode. */
273 u8 *
274 format_vnet_gpe_encap_mode (u8 * s, va_list * args)
275 {
277 
278  switch (lgm->encap_mode)
279  {
280  case GPE_ENCAP_LISP:
281  return format (s, "lisp");
282  case GPE_ENCAP_VXLAN:
283  return format (s, "vxlan");
284  default:
285  return 0;
286  }
287  return 0;
288 }
289 
290 /** CLI command to show GPE encap */
291 static clib_error_t *
293  unformat_input_t * input,
294  vlib_cli_command_t * cmd)
295 {
296  vlib_cli_output (vm, "encap mode: %U", format_vnet_gpe_encap_mode);
297  return 0;
298 }
299 
300 /* *INDENT-OFF* */
301 VLIB_CLI_COMMAND (gpe_show_encap_mode_command, static) = {
302  .path = "show gpe encap",
303  .short_help = "show GPE encapulation mode",
304  .function = gpe_show_encap_mode_command_fn,
305 };
306 /* *INDENT-ON* */
307 
308 /** CLI command to enable/disable LISP-GPE. */
309 static clib_error_t *
311  unformat_input_t * input,
312  vlib_cli_command_t * cmd)
313 {
314  unformat_input_t _line_input, *line_input = &_line_input;
315  u8 is_en = 1;
317  clib_error_t *error = NULL;
318 
319  /* Get a line of input. */
320  if (!unformat_user (input, unformat_line_input, line_input))
321  return 0;
322 
323  while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
324  {
325  if (unformat (line_input, "enable"))
326  is_en = 1;
327  else if (unformat (line_input, "disable"))
328  is_en = 0;
329  else
330  {
331  error = clib_error_return (0, "parse error: '%U'",
332  format_unformat_error, line_input);
333  goto done;
334  }
335  }
336  a->is_en = is_en;
337  error = vnet_lisp_gpe_enable_disable (a);
338 
339 done:
340  unformat_free (line_input);
341 
342  return error;
343 }
344 
345 /* *INDENT-OFF* */
346 VLIB_CLI_COMMAND (enable_disable_lisp_gpe_command, static) = {
347  .path = "gpe",
348  .short_help = "gpe [enable|disable]",
350 };
351 /* *INDENT-ON* */
352 
353 /** CLI command to show LISP-GPE interfaces. */
354 static clib_error_t *
356  unformat_input_t * input,
357  vlib_cli_command_t * cmd)
358 {
360  hash_pair_t *p;
361 
362  vlib_cli_output (vm, "%=10s%=12s", "vrf", "hw_if_index");
363 
364  /* *INDENT-OFF* */
366  vlib_cli_output (vm, "%=10d%=10d", p->key, p->value[0]);
367  }));
368  /* *INDENT-ON* */
369 
370  if (0 != lgm->l2_ifaces.hw_if_index_by_dp_table)
371  {
372  vlib_cli_output (vm, "%=10s%=12s", "bd_id", "hw_if_index");
373  /* *INDENT-OFF* */
375  vlib_cli_output (vm, "%=10d%=10d", p->key, p->value[0]);
376  }));
377  /* *INDENT-ON* */
378  }
379  return 0;
380 }
381 
382 /* *INDENT-OFF* */
383 VLIB_CLI_COMMAND (lisp_show_iface_command) = {
384  .path = "show gpe interface",
385  .short_help = "show gpe interface",
386  .function = lisp_show_iface_command_fn,
387 };
388 /* *INDENT-ON* */
389 
390 /** Format LISP-GPE status. */
391 u8 *
392 format_vnet_lisp_gpe_status (u8 * s, va_list * args)
393 {
395  return format (s, "%s", lgm->is_en ? "enabled" : "disabled");
396 }
397 
398 /** LISP-GPE init function. */
399 clib_error_t *
401 {
403  clib_error_t *error = 0;
404 
405  if ((error = vlib_call_init_function (vm, ip_main_init)))
406  return error;
407 
408  if ((error = vlib_call_init_function (vm, ip4_lookup_init)))
409  return error;
410 
411  lgm->vnet_main = vnet_get_main ();
412  lgm->vlib_main = vm;
413  lgm->im4 = &ip4_main;
414  lgm->im6 = &ip6_main;
415  lgm->lm4 = &ip4_main.lookup_main;
416  lgm->lm6 = &ip6_main.lookup_main;
417  lgm->encap_mode = GPE_ENCAP_LISP;
418 
419  lgm->lisp_gpe_fwd_entries =
420  hash_create_mem (0, sizeof (lisp_gpe_fwd_entry_key_t), sizeof (uword));
421 
422  udp_register_dst_port (vm, UDP_DST_PORT_lisp_gpe,
423  lisp_gpe_ip4_input_node.index, 1 /* is_ip4 */ );
424  udp_register_dst_port (vm, UDP_DST_PORT_lisp_gpe6,
425  lisp_gpe_ip6_input_node.index, 0 /* is_ip4 */ );
426 
428  hash_create_mem (0, sizeof (lisp_stats_key_t), sizeof (uword));
429  memset (&lgm->counters, 0, sizeof (lgm->counters));
430  lgm->counters.name = "LISP counters";
431 
432  return 0;
433 }
434 
437 {
439  return lgm->encap_mode;
440 }
441 
443 
444 /*
445  * fd.io coding-style-patch-verification: ON
446  *
447  * Local Variables:
448  * eval: (c-set-style "gnu")
449  * End:
450  */
#define gid_address_ip_version(_a)
Definition: lisp_types.h:245
vnet_api_error_t
Definition: api_errno.h:109
vlib_node_registration_t lisp_gpe_ip4_input_node
(constructor) VLIB_REGISTER_NODE (lisp_gpe_ip4_input_node)
Definition: decap.c:461
#define gid_address_type(_a)
Definition: lisp_types.h:241
a
Definition: bitmap.h:516
u8 vnet_lisp_gpe_enable_disable_status(void)
Check if LISP-GPE is enabled.
Definition: lisp_gpe.c:181
vnet_main_t * vnet_get_main(void)
Definition: misc.c:46
void vnet_lisp_gpe_fwd_entry_flush(void)
Flush all the forwrding entries.
clib_error_t * vnet_lisp_gpe_enable_disable(vnet_lisp_gpe_enable_disable_args_t *a)
Enable/disable LISP-GPE.
Definition: lisp_gpe.c:190
#define NULL
Definition: clib.h:55
LISP-GPE global state.
Definition: lisp_gpe.h:118
uword unformat_ip_address(unformat_input_t *input, va_list *args)
Definition: lisp_types.c:147
#define vec_add1(V, E)
Add 1 element to end of vector (unspecified alignment).
Definition: vec.h:522
LISP-GPE definitions.
uword unformat_user(unformat_input_t *input, unformat_function_t *func,...)
Definition: unformat.c:982
ip_lookup_main_t lookup_main
Definition: ip4.h:109
u8 * format(u8 *s, const char *fmt,...)
Definition: format.c:418
vlib_main_t * vlib_main
convenience
Definition: lisp_gpe.h:167
uword unformat_negative_mapping_action(unformat_input_t *input, va_list *args)
Definition: lisp_types.c:362
ip6_main_t * im6
Definition: lisp_gpe.h:170
#define VLIB_INIT_FUNCTION(x)
Definition: init.h:111
static clib_error_t * gpe_set_encap_mode_command_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
CLI command to set GPE encap.
Definition: lisp_gpe.c:230
vlib_combined_counter_main_t counters
Definition: lisp_gpe.h:164
LISP-GPE fwd entry key.
u8 is_add
Definition: lisp_gpe.h:226
#define clib_error_return(e, args...)
Definition: error.h:111
uword * lisp_gpe_fwd_entries
DB of all forwarding entries.
Definition: lisp_gpe.h:124
#define vlib_call_init_function(vm, x)
Definition: init.h:162
enum gpe_encap_mode_e gpe_encap_mode_t
Definition: lisp_gpe.h:222
Common utility functions for IPv4, IPv6 and L2 LISP-GPE adjacencys.
unformat_function_t unformat_line_input
Definition: format.h:281
vlib_node_registration_t lisp_gpe_ip6_input_node
(constructor) VLIB_REGISTER_NODE (lisp_gpe_ip6_input_node)
Definition: decap.c:483
#define hash_create_mem(elts, key_bytes, value_bytes)
Definition: hash.h:637
u32 table_id
table (vrf) id
Definition: lisp_gpe.h:259
struct _unformat_input_t unformat_input_t
uword unformat_gid_address(unformat_input_t *input, va_list *args)
Definition: lisp_types.c:321
ip_address_t lcl_loc
Definition: lisp_types.h:353
u8 is_negative
type of mapping
Definition: lisp_gpe.h:229
u32 vni
VNI/tenant id in HOST byte order.
Definition: lisp_gpe.h:253
clib_error_t * ip_main_init(vlib_main_t *vm)
Definition: ip_init.c:45
#define UNFORMAT_END_OF_INPUT
Definition: format.h:143
vlib_main_t * vm
Definition: buffer.c:276
#define vec_free(V)
Free vector&#39;s memory (no header).
Definition: vec.h:340
static clib_error_t * lisp_show_iface_command_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
CLI command to show LISP-GPE interfaces.
Definition: lisp_gpe.c:355
tunnel_lookup_t l2_ifaces
Definition: lisp_gpe.h:146
vnet_main_t * vnet_main
Definition: lisp_gpe.h:168
void lisp_gpe_tenant_flush(void)
Flush/delete ALL the tenants.
lisp_gpe_main_t lisp_gpe_main
LISP-GPE global state.
Definition: lisp_gpe.c:27
#define VLIB_CLI_COMMAND(x,...)
Definition: cli.h:154
int vnet_lisp_gpe_add_del_fwd_entry(vnet_lisp_gpe_add_del_fwd_entry_args_t *a, u32 *hw_if_indexp)
Forwarding entry create/remove dispatcher.
struct _gid_address_t gid_address_t
u8 * format_vnet_lisp_gpe_status(u8 *s, va_list *args)
Format LISP-GPE status.
Definition: lisp_gpe.c:392
gpe_encap_mode_t vnet_gpe_get_encap_mode(void)
Definition: lisp_gpe.c:436
unsigned int u32
Definition: types.h:88
ip6_main_t ip6_main
Definition: ip6_forward.c:2846
ip_lookup_main_t lookup_main
Definition: ip6.h:151
clib_error_t * lisp_gpe_init(vlib_main_t *vm)
LISP-GPE init function.
Definition: lisp_gpe.c:400
gpe_encap_mode_t encap_mode
Definition: lisp_gpe.h:160
uword * hw_if_index_by_dp_table
Lookup lisp-gpe interfaces by dp table (eg.
Definition: lisp_gpe.h:84
int vnet_gpe_set_encap_mode(gpe_encap_mode_t mode)
Set GPE encapsulation mode.
Definition: lisp_gpe.c:214
gid_address_t rmt_eid
remote eid
Definition: lisp_gpe.h:238
clib_error_t * ip4_lookup_init(vlib_main_t *vm)
Definition: ip4_forward.c:1120
u64 uword
Definition: types.h:112
#define unformat_parse_error(input)
Definition: format.h:267
static clib_error_t * gpe_show_encap_mode_command_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
CLI command to show GPE encap.
Definition: lisp_gpe.c:292
negative_fwd_actions_e action
action for negative mappings
Definition: lisp_gpe.h:232
#define gid_address_vni(_a)
Definition: lisp_types.h:249
struct lisp_gpe_fwd_entry_t_ * lisp_fwd_entry_pool
A Pool of all LISP forwarding entries.
Definition: lisp_gpe.h:129
static clib_error_t * lisp_gpe_enable_disable_command_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
CLI command to enable/disable LISP-GPE.
Definition: lisp_gpe.c:310
ip_lookup_main_t * lm4
Definition: lisp_gpe.h:171
#define vec_len(v)
Number of elements in vector (rvalue-only, NULL tolerant)
unsigned char u8
Definition: types.h:56
tunnel_lookup_t l3_ifaces
Definition: lisp_gpe.h:138
ip4_main_t * im4
Definition: lisp_gpe.h:169
#define hash_foreach_pair(p, v, body)
Iterate over hash pairs.
Definition: hash.h:349
static void unformat_free(unformat_input_t *i)
Definition: format.h:161
locator_pair_t * locator_pairs
vector of locator pairs
Definition: lisp_gpe.h:241
char * name
The counter collection&#39;s name.
Definition: counter.h:185
void gid_address_copy(gid_address_t *dst, gid_address_t *src)
Definition: lisp_types.c:1399
u8 * format_unformat_error(u8 *s, va_list *va)
Definition: unformat.c:91
ip4_main_t ip4_main
Global ip4 main structure.
Definition: ip4_forward.c:1117
ip_address_t rmt_loc
Definition: lisp_types.h:354
void udp_register_dst_port(vlib_main_t *vm, udp_dst_port_t dst_port, u32 node_index, u8 is_ip4)
Definition: udp_local.c:488
uword * lisp_stats_index_by_key
Definition: lisp_gpe.h:163
ip_lookup_main_t * lm6
Definition: lisp_gpe.h:172
u8 * format_vnet_gpe_encap_mode(u8 *s, va_list *args)
Format GPE encap mode.
Definition: lisp_gpe.c:274
gid_address_t lcl_eid
local eid
Definition: lisp_gpe.h:235
void vlib_cli_output(vlib_main_t *vm, char *fmt,...)
Definition: cli.c:577
LISP-GPE definitions.
uword unformat(unformat_input_t *i, const char *fmt,...)
Definition: unformat.c:971
static uword unformat_check_input(unformat_input_t *i)
Definition: format.h:169
static clib_error_t * lisp_gpe_add_del_fwd_entry_command_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
CLI command to add/del forwarding entry.
Definition: lisp_gpe.c:32
static uword pool_elts(void *v)
Number of active elements in a pool.
Definition: pool.h:109