blob: fbda8687c3bebe3d83014ef04b77d4e50b987375 [file] [log] [blame]
Ed Warnickecb9cada2015-12-08 15:45:58 -07001/*
Florin Corase127a7e2016-02-18 22:20:01 +01002 * Copyright (c) 2016 Cisco and/or its affiliates.
Ed Warnickecb9cada2015-12-08 15:45:58 -07003 * 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 */
Florin Corasff0bf132016-09-05 19:30:35 +020015/**
16 * @file
17 * @brief Common utility functions for IPv4, IPv6 and L2 LISP-GPE tunnels.
18 *
19 */
Florin Corase127a7e2016-02-18 22:20:01 +010020
Ed Warnickecb9cada2015-12-08 15:45:58 -070021#include <vnet/lisp-gpe/lisp_gpe.h>
Neale Ranns5e575b12016-10-03 09:40:25 +010022#include <vnet/lisp-gpe/lisp_gpe_fwd_entry.h>
Neale Ranns0bfe5d82016-08-25 15:29:12 +010023#include <vnet/lisp-gpe/lisp_gpe_adjacency.h>
Neale Ranns5e575b12016-10-03 09:40:25 +010024#include <vnet/lisp-gpe/lisp_gpe_tenant.h>
Ed Warnickecb9cada2015-12-08 15:45:58 -070025
Florin Corasff0bf132016-09-05 19:30:35 +020026/** LISP-GPE global state */
Ed Warnickecb9cada2015-12-08 15:45:58 -070027lisp_gpe_main_t lisp_gpe_main;
28
Florin Coras1a1adc72016-07-22 01:45:30 +020029
Florin Corasff0bf132016-09-05 19:30:35 +020030/** CLI command to add/del forwarding entry. */
Ed Warnickecb9cada2015-12-08 15:45:58 -070031static clib_error_t *
Florin Corase127a7e2016-02-18 22:20:01 +010032lisp_gpe_add_del_fwd_entry_command_fn (vlib_main_t * vm,
Florin Coras220beac2016-08-16 23:04:00 +020033 unformat_input_t * input,
34 vlib_cli_command_t * cmd)
Ed Warnickecb9cada2015-12-08 15:45:58 -070035{
Florin Coras220beac2016-08-16 23:04:00 +020036 unformat_input_t _line_input, *line_input = &_line_input;
Ed Warnickecb9cada2015-12-08 15:45:58 -070037 u8 is_add = 1;
Florin Corasbb5c22f2016-08-02 02:31:03 +020038 ip_address_t lloc, rloc;
Florin Coras220beac2016-08-16 23:04:00 +020039 clib_error_t *error = 0;
40 gid_address_t _reid, *reid = &_reid, _leid, *leid = &_leid;
Florin Coras03c4f992016-07-19 15:27:58 +020041 u8 reid_set = 0, leid_set = 0, is_negative = 0, vrf_set = 0, vni_set = 0;
Florin Corasbb5c22f2016-08-02 02:31:03 +020042 u32 vni, vrf, action = ~0, p, w;
Florin Coras220beac2016-08-16 23:04:00 +020043 locator_pair_t pair, *pairs = 0;
Andrej Kozemcak8ebb2a12016-06-07 12:25:20 +020044 int rv;
Florin Corase127a7e2016-02-18 22:20:01 +010045
Ed Warnickecb9cada2015-12-08 15:45:58 -070046 /* Get a line of input. */
Florin Coras220beac2016-08-16 23:04:00 +020047 if (!unformat_user (input, unformat_line_input, line_input))
Ed Warnickecb9cada2015-12-08 15:45:58 -070048 return 0;
49
Florin Corase127a7e2016-02-18 22:20:01 +010050 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
51 {
52 if (unformat (line_input, "del"))
Florin Coras220beac2016-08-16 23:04:00 +020053 is_add = 0;
Florin Corase127a7e2016-02-18 22:20:01 +010054 else if (unformat (line_input, "add"))
Florin Coras220beac2016-08-16 23:04:00 +020055 is_add = 1;
56 else if (unformat (line_input, "leid %U", unformat_gid_address, leid))
57 {
58 leid_set = 1;
59 }
60 else if (unformat (line_input, "reid %U", unformat_gid_address, reid))
61 {
62 reid_set = 1;
63 }
Florin Coras03c4f992016-07-19 15:27:58 +020064 else if (unformat (line_input, "vni %u", &vni))
Florin Coras220beac2016-08-16 23:04:00 +020065 {
66 gid_address_vni (leid) = vni;
67 gid_address_vni (reid) = vni;
68 vni_set = 1;
69 }
Florin Coras03c4f992016-07-19 15:27:58 +020070 else if (unformat (line_input, "vrf %u", &vrf))
Florin Coras220beac2016-08-16 23:04:00 +020071 {
72 vrf_set = 1;
73 }
Neale Ranns5e575b12016-10-03 09:40:25 +010074 else if (unformat (line_input, "bd %u", &vrf))
75 {
76 vrf_set = 1;
77 }
Florin Coras03c4f992016-07-19 15:27:58 +020078 else if (unformat (line_input, "negative action %U",
Florin Coras220beac2016-08-16 23:04:00 +020079 unformat_negative_mapping_action, &action))
80 {
81 is_negative = 1;
82 }
Florin Corasbb5c22f2016-08-02 02:31:03 +020083 else if (unformat (line_input, "loc-pair %U %U p %d w %d",
Florin Coras220beac2016-08-16 23:04:00 +020084 unformat_ip_address, &lloc,
85 unformat_ip_address, &rloc, &p, &w))
86 {
87 pair.lcl_loc = lloc;
88 pair.rmt_loc = rloc;
89 pair.priority = p;
90 pair.weight = w;
91 vec_add1 (pairs, pair);
92 }
Florin Corase127a7e2016-02-18 22:20:01 +010093 else
Florin Coras220beac2016-08-16 23:04:00 +020094 {
95 error = unformat_parse_error (line_input);
96 goto done;
97 }
Florin Corase127a7e2016-02-18 22:20:01 +010098 }
Ed Warnickecb9cada2015-12-08 15:45:58 -070099 unformat_free (line_input);
100
Florin Coras03c4f992016-07-19 15:27:58 +0200101 if (!vni_set || !vrf_set)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700102 {
Florin Coras220beac2016-08-16 23:04:00 +0200103 error = clib_error_return (0, "vni and vrf must be set!");
Florin Corase127a7e2016-02-18 22:20:01 +0100104 goto done;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700105 }
106
Florin Coras03c4f992016-07-19 15:27:58 +0200107 if (!reid_set)
Florin Corase127a7e2016-02-18 22:20:01 +0100108 {
Florin Coras220beac2016-08-16 23:04:00 +0200109 error = clib_error_return (0, "remote eid must be set!");
Florin Corase127a7e2016-02-18 22:20:01 +0100110 goto done;
111 }
112
Florin Coras03c4f992016-07-19 15:27:58 +0200113 if (is_negative)
Florin Corase127a7e2016-02-18 22:20:01 +0100114 {
Florin Coras03c4f992016-07-19 15:27:58 +0200115 if (~0 == action)
Florin Coras220beac2016-08-16 23:04:00 +0200116 {
117 error = clib_error_return (0, "no action set for negative tunnel!");
118 goto done;
119 }
Florin Coras03c4f992016-07-19 15:27:58 +0200120 }
121 else
122 {
Florin Corasbb5c22f2016-08-02 02:31:03 +0200123 if (vec_len (pairs) == 0)
Florin Coras220beac2016-08-16 23:04:00 +0200124 {
125 error = clib_error_return (0, "expected ip4/ip6 locators.");
126 goto done;
127 }
Florin Corase127a7e2016-02-18 22:20:01 +0100128 }
129
Florin Coras03c4f992016-07-19 15:27:58 +0200130 if (!leid_set)
131 {
132 /* if leid not set, make sure it's the same AFI like reid */
Florin Coras220beac2016-08-16 23:04:00 +0200133 gid_address_type (leid) = gid_address_type (reid);
Florin Coras03c4f992016-07-19 15:27:58 +0200134 if (GID_ADDR_IP_PREFIX == gid_address_type (reid))
Florin Coras220beac2016-08-16 23:04:00 +0200135 gid_address_ip_version (leid) = gid_address_ip_version (reid);
Florin Coras03c4f992016-07-19 15:27:58 +0200136 }
137
138 /* add fwd entry */
Florin Coras220beac2016-08-16 23:04:00 +0200139 vnet_lisp_gpe_add_del_fwd_entry_args_t _a, *a = &_a;
140 memset (a, 0, sizeof (a[0]));
Florin Coras03c4f992016-07-19 15:27:58 +0200141
142 a->is_add = is_add;
Florin Coras82bf7cd2016-09-26 18:59:44 +0300143 a->is_negative = is_negative;
Florin Coras03c4f992016-07-19 15:27:58 +0200144 a->vni = vni;
145 a->table_id = vrf;
Florin Coras220beac2016-08-16 23:04:00 +0200146 gid_address_copy (&a->lcl_eid, leid);
147 gid_address_copy (&a->rmt_eid, reid);
Florin Corasbb5c22f2016-08-02 02:31:03 +0200148 a->locator_pairs = pairs;
Florin Coras03c4f992016-07-19 15:27:58 +0200149
150 rv = vnet_lisp_gpe_add_del_fwd_entry (a, 0);
151 if (0 != rv)
152 {
Florin Coras220beac2016-08-16 23:04:00 +0200153 error = clib_error_return (0, "failed to %s gpe tunnel!",
154 is_add ? "add" : "delete");
Florin Coras03c4f992016-07-19 15:27:58 +0200155 }
156
Florin Coras220beac2016-08-16 23:04:00 +0200157done:
158 vec_free (pairs);
Florin Corase127a7e2016-02-18 22:20:01 +0100159 return error;
160}
161
Florin Coras220beac2016-08-16 23:04:00 +0200162/* *INDENT-OFF* */
Florin Corased09a052016-05-06 14:22:40 +0200163VLIB_CLI_COMMAND (lisp_gpe_add_del_fwd_entry_command, static) = {
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100164 .path = "lisp gpe entry",
165 .short_help = "lisp gpe entry add/del vni <vni> vrf <vrf> [leid <leid>]"
Florin Corasff0bf132016-09-05 19:30:35 +0200166 "reid <reid> [loc-pair <lloc> <rloc> p <priority> w <weight>] "
167 "[negative action <action>]",
Florin Corase127a7e2016-02-18 22:20:01 +0100168 .function = lisp_gpe_add_del_fwd_entry_command_fn,
169};
Florin Coras220beac2016-08-16 23:04:00 +0200170/* *INDENT-ON* */
Florin Corase127a7e2016-02-18 22:20:01 +0100171
Florin Corasff0bf132016-09-05 19:30:35 +0200172/** Check if LISP-GPE is enabled. */
Andrej Kozemcaka9edd852016-05-02 12:14:33 +0200173u8
Florin Coras220beac2016-08-16 23:04:00 +0200174vnet_lisp_gpe_enable_disable_status (void)
Andrej Kozemcaka9edd852016-05-02 12:14:33 +0200175{
Florin Coras220beac2016-08-16 23:04:00 +0200176 lisp_gpe_main_t *lgm = &lisp_gpe_main;
Andrej Kozemcaka9edd852016-05-02 12:14:33 +0200177
178 return lgm->is_en;
179}
180
Florin Corasff0bf132016-09-05 19:30:35 +0200181/** Enable/disable LISP-GPE. */
Florin Coras577c3552016-04-21 00:45:40 +0200182clib_error_t *
183vnet_lisp_gpe_enable_disable (vnet_lisp_gpe_enable_disable_args_t * a)
Florin Corase127a7e2016-02-18 22:20:01 +0100184{
Florin Coras220beac2016-08-16 23:04:00 +0200185 lisp_gpe_main_t *lgm = &lisp_gpe_main;
Florin Corase127a7e2016-02-18 22:20:01 +0100186
Florin Coras577c3552016-04-21 00:45:40 +0200187 if (a->is_en)
Florin Corase127a7e2016-02-18 22:20:01 +0100188 {
Andrej Kozemcaka9edd852016-05-02 12:14:33 +0200189 lgm->is_en = 1;
Florin Corase127a7e2016-02-18 22:20:01 +0100190 }
191 else
192 {
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100193 /* remove all entries */
Neale Ranns5e575b12016-10-03 09:40:25 +0100194 vnet_lisp_gpe_fwd_entry_flush ();
Florin Coras577c3552016-04-21 00:45:40 +0200195
Florin Coras1a1adc72016-07-22 01:45:30 +0200196 /* disable all l3 ifaces */
Neale Ranns5e575b12016-10-03 09:40:25 +0100197 lisp_gpe_tenant_flush ();
Florin Coras220beac2016-08-16 23:04:00 +0200198
Andrej Kozemcaka9edd852016-05-02 12:14:33 +0200199 lgm->is_en = 0;
Florin Corase127a7e2016-02-18 22:20:01 +0100200 }
Florin Coras577c3552016-04-21 00:45:40 +0200201
202 return 0;
Florin Corase127a7e2016-02-18 22:20:01 +0100203}
204
Florin Corasff0bf132016-09-05 19:30:35 +0200205/** CLI command to enable/disable LISP-GPE. */
Florin Corase127a7e2016-02-18 22:20:01 +0100206static clib_error_t *
Florin Coras220beac2016-08-16 23:04:00 +0200207lisp_gpe_enable_disable_command_fn (vlib_main_t * vm,
208 unformat_input_t * input,
209 vlib_cli_command_t * cmd)
Florin Corase127a7e2016-02-18 22:20:01 +0100210{
Florin Coras220beac2016-08-16 23:04:00 +0200211 unformat_input_t _line_input, *line_input = &_line_input;
Florin Coras577c3552016-04-21 00:45:40 +0200212 u8 is_en = 1;
Florin Coras220beac2016-08-16 23:04:00 +0200213 vnet_lisp_gpe_enable_disable_args_t _a, *a = &_a;
Florin Corase127a7e2016-02-18 22:20:01 +0100214
215 /* Get a line of input. */
Florin Coras220beac2016-08-16 23:04:00 +0200216 if (!unformat_user (input, unformat_line_input, line_input))
Florin Corase127a7e2016-02-18 22:20:01 +0100217 return 0;
218
219 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
220 {
Florin Coras577c3552016-04-21 00:45:40 +0200221 if (unformat (line_input, "enable"))
Florin Coras220beac2016-08-16 23:04:00 +0200222 is_en = 1;
Florin Coras577c3552016-04-21 00:45:40 +0200223 else if (unformat (line_input, "disable"))
Florin Coras220beac2016-08-16 23:04:00 +0200224 is_en = 0;
Florin Corase127a7e2016-02-18 22:20:01 +0100225 else
Florin Coras220beac2016-08-16 23:04:00 +0200226 {
227 return clib_error_return (0, "parse error: '%U'",
228 format_unformat_error, line_input);
229 }
Florin Corase127a7e2016-02-18 22:20:01 +0100230 }
Florin Coras577c3552016-04-21 00:45:40 +0200231 a->is_en = is_en;
232 return vnet_lisp_gpe_enable_disable (a);
Florin Corase127a7e2016-02-18 22:20:01 +0100233}
234
Florin Coras220beac2016-08-16 23:04:00 +0200235/* *INDENT-OFF* */
Florin Coras577c3552016-04-21 00:45:40 +0200236VLIB_CLI_COMMAND (enable_disable_lisp_gpe_command, static) = {
237 .path = "lisp gpe",
238 .short_help = "lisp gpe [enable|disable]",
239 .function = lisp_gpe_enable_disable_command_fn,
Florin Corase127a7e2016-02-18 22:20:01 +0100240};
Florin Coras220beac2016-08-16 23:04:00 +0200241/* *INDENT-ON* */
Florin Corase127a7e2016-02-18 22:20:01 +0100242
Florin Corasff0bf132016-09-05 19:30:35 +0200243/** CLI command to show LISP-GPE interfaces. */
Filip Tehlar53f09e32016-05-19 14:25:44 +0200244static clib_error_t *
245lisp_show_iface_command_fn (vlib_main_t * vm,
Florin Coras220beac2016-08-16 23:04:00 +0200246 unformat_input_t * input,
247 vlib_cli_command_t * cmd)
Filip Tehlar53f09e32016-05-19 14:25:44 +0200248{
Florin Coras220beac2016-08-16 23:04:00 +0200249 lisp_gpe_main_t *lgm = &lisp_gpe_main;
250 hash_pair_t *p;
Filip Tehlar53f09e32016-05-19 14:25:44 +0200251
252 vlib_cli_output (vm, "%=10s%=12s", "vrf", "hw_if_index");
Florin Coras220beac2016-08-16 23:04:00 +0200253
254 /* *INDENT-OFF* */
Florin Coras1a1adc72016-07-22 01:45:30 +0200255 hash_foreach_pair (p, lgm->l3_ifaces.hw_if_index_by_dp_table, ({
Filip Tehlar53f09e32016-05-19 14:25:44 +0200256 vlib_cli_output (vm, "%=10d%=10d", p->key, p->value[0]);
257 }));
Florin Coras220beac2016-08-16 23:04:00 +0200258 /* *INDENT-ON* */
Florin Coras1a1adc72016-07-22 01:45:30 +0200259
260 if (0 != lgm->l2_ifaces.hw_if_index_by_dp_table)
261 {
262 vlib_cli_output (vm, "%=10s%=12s", "bd_id", "hw_if_index");
Florin Coras220beac2016-08-16 23:04:00 +0200263 /* *INDENT-OFF* */
Florin Coras1a1adc72016-07-22 01:45:30 +0200264 hash_foreach_pair (p, lgm->l2_ifaces.hw_if_index_by_dp_table, ({
265 vlib_cli_output (vm, "%=10d%=10d", p->key, p->value[0]);
266 }));
Florin Coras220beac2016-08-16 23:04:00 +0200267 /* *INDENT-ON* */
Florin Coras1a1adc72016-07-22 01:45:30 +0200268 }
Filip Tehlar53f09e32016-05-19 14:25:44 +0200269 return 0;
270}
271
Florin Coras220beac2016-08-16 23:04:00 +0200272/* *INDENT-OFF* */
Filip Tehlar53f09e32016-05-19 14:25:44 +0200273VLIB_CLI_COMMAND (lisp_show_iface_command) = {
274 .path = "show lisp gpe interface",
275 .short_help = "show lisp gpe interface",
276 .function = lisp_show_iface_command_fn,
277};
Florin Coras220beac2016-08-16 23:04:00 +0200278/* *INDENT-ON* */
Florin Coras1a1adc72016-07-22 01:45:30 +0200279
Florin Corasff0bf132016-09-05 19:30:35 +0200280/** Format LISP-GPE status. */
Florin Coras1a1adc72016-07-22 01:45:30 +0200281u8 *
282format_vnet_lisp_gpe_status (u8 * s, va_list * args)
283{
Florin Coras220beac2016-08-16 23:04:00 +0200284 lisp_gpe_main_t *lgm = &lisp_gpe_main;
Florin Coras1a1adc72016-07-22 01:45:30 +0200285 return format (s, "%s", lgm->is_en ? "enabled" : "disabled");
286}
287
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100288
Florin Corasff0bf132016-09-05 19:30:35 +0200289/** LISP-GPE init function. */
Florin Corase127a7e2016-02-18 22:20:01 +0100290clib_error_t *
Florin Coras220beac2016-08-16 23:04:00 +0200291lisp_gpe_init (vlib_main_t * vm)
Florin Corase127a7e2016-02-18 22:20:01 +0100292{
Florin Coras220beac2016-08-16 23:04:00 +0200293 lisp_gpe_main_t *lgm = &lisp_gpe_main;
294 clib_error_t *error = 0;
Florin Corase127a7e2016-02-18 22:20:01 +0100295
296 if ((error = vlib_call_init_function (vm, ip_main_init)))
297 return error;
298
299 if ((error = vlib_call_init_function (vm, ip4_lookup_init)))
300 return error;
301
Florin Coras220beac2016-08-16 23:04:00 +0200302 lgm->vnet_main = vnet_get_main ();
Florin Corase127a7e2016-02-18 22:20:01 +0100303 lgm->vlib_main = vm;
304 lgm->im4 = &ip4_main;
Florin Coras02655bd2016-04-26 00:17:24 +0200305 lgm->im6 = &ip6_main;
306 lgm->lm4 = &ip4_main.lookup_main;
307 lgm->lm6 = &ip6_main.lookup_main;
Florin Coras577c3552016-04-21 00:45:40 +0200308
Neale Ranns5e575b12016-10-03 09:40:25 +0100309 lgm->lisp_gpe_fwd_entries =
310 hash_create_mem (0, sizeof (lisp_gpe_fwd_entry_key_t), sizeof (uword));
Florin Coras1a1adc72016-07-22 01:45:30 +0200311
Florin Coras220beac2016-08-16 23:04:00 +0200312 udp_register_dst_port (vm, UDP_DST_PORT_lisp_gpe,
313 lisp_gpe_ip4_input_node.index, 1 /* is_ip4 */ );
Florin Coras02655bd2016-04-26 00:17:24 +0200314 udp_register_dst_port (vm, UDP_DST_PORT_lisp_gpe6,
Florin Coras220beac2016-08-16 23:04:00 +0200315 lisp_gpe_ip6_input_node.index, 0 /* is_ip4 */ );
Ed Warnickecb9cada2015-12-08 15:45:58 -0700316 return 0;
317}
318
Florin Coras220beac2016-08-16 23:04:00 +0200319VLIB_INIT_FUNCTION (lisp_gpe_init);
320
321/*
322 * fd.io coding-style-patch-verification: ON
323 *
324 * Local Variables:
325 * eval: (c-set-style "gnu")
326 * End:
327 */