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:
7 * http://www.apache.org/licenses/LICENSE-2.0
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.
17 * @brief Common utility functions for IPv4, IPv6 and L2 LISP-GPE tunnels.
21 #include <vnet/lisp-gpe/lisp_gpe.h>
22 #include <vnet/lisp-gpe/lisp_gpe_adjacency.h>
23 #include <vnet/adj/adj_midchain.h>
24 #include <vnet/fib/fib_table.h>
25 #include <vnet/fib/fib_entry.h>
26 #include <vnet/fib/fib_path_list.h>
27 #include <vnet/dpo/drop_dpo.h>
28 #include <vnet/dpo/load_balance.h>
30 /** LISP-GPE global state */
31 lisp_gpe_main_t lisp_gpe_main;
34 * @brief A Pool of all LISP forwarding entries
36 static lisp_fwd_entry_t *lisp_fwd_entry_pool;
39 * DB of all forwarding entries. The Key is:{l-EID,r-EID,vni}
40 * where the EID encodes L2 or L3
42 static uword *lisp_gpe_fwd_entries;
45 create_fib_entries (lisp_fwd_entry_t * lfe)
49 dproto = (ip_prefix_version (&lfe->key->rmt.ippref) == IP4 ?
50 FIB_PROTOCOL_IP4 : FIB_PROTOCOL_IP6);
52 lfe->src_fib_index = ip_dst_fib_add_route (lfe->eid_fib_index,
53 &lfe->key->rmt.ippref);
55 if (LISP_FWD_ENTRY_TYPE_NEGATIVE == lfe->type)
57 dpo_id_t dpo = DPO_NULL;
62 /* TODO update timers? */
63 case LISP_FORWARD_NATIVE:
64 /* TODO check if route/next-hop for eid exists in fib and add
65 * more specific for the eid with the next-hop found */
66 case LISP_SEND_MAP_REQUEST:
67 /* insert tunnel that always sends map-request */
68 dpo_set (&dpo, DPO_LISP_CP, 0, dproto);
71 /* for drop fwd entries, just add route, no need to add encap tunnel */
72 dpo_copy (&dpo, drop_dpo_get (dproto));
75 ip_src_fib_add_route_w_dpo (lfe->src_fib_index,
76 &lfe->key->lcl.ippref, &dpo);
81 ip_src_fib_add_route (lfe->src_fib_index,
82 &lfe->key->lcl.ippref, lfe->paths);
87 delete_fib_entries (lisp_fwd_entry_t * lfe)
89 ip_src_dst_fib_del_route (lfe->src_fib_index,
90 &lfe->key->lcl.ippref,
91 lfe->eid_fib_index, &lfe->key->rmt.ippref);
95 gid_to_dp_address (gid_address_t * g, dp_address_t * d)
97 switch (gid_address_type (g))
99 case GID_ADDR_IP_PREFIX:
100 case GID_ADDR_SRC_DST:
101 ip_prefix_copy (&d->ippref, &gid_address_ippref (g));
102 d->type = FID_ADDR_IP_PREF;
106 mac_copy (&d->mac, &gid_address_mac (g));
107 d->type = FID_ADDR_MAC;
112 static lisp_fwd_entry_t *
113 find_fwd_entry (lisp_gpe_main_t * lgm,
114 vnet_lisp_gpe_add_del_fwd_entry_args_t * a,
115 lisp_gpe_fwd_entry_key_t * key)
119 memset (key, 0, sizeof (*key));
121 if (GID_ADDR_IP_PREFIX == gid_address_type (&a->rmt_eid))
124 * the ip version of the source is not set to ip6 when the
125 * source is all zeros. force it.
127 ip_prefix_version (&gid_address_ippref (&a->lcl_eid)) =
128 ip_prefix_version (&gid_address_ippref (&a->rmt_eid));
131 gid_to_dp_address (&a->rmt_eid, &key->rmt);
132 gid_to_dp_address (&a->lcl_eid, &key->lcl);
135 p = hash_get_mem (lisp_gpe_fwd_entries, key);
139 return (pool_elt_at_index (lisp_fwd_entry_pool, p[0]));
145 lisp_gpe_fwd_entry_path_sort (void *a1, void *a2)
147 lisp_fwd_path_t *p1 = a1, *p2 = a2;
149 return (p1->priority - p2->priority);
153 * @brief Add/Delete LISP IP forwarding entry.
155 * creation of forwarding entries for IP LISP overlay:
157 * @param[in] lgm Reference to @ref lisp_gpe_main_t.
158 * @param[in] a Parameters for building the forwarding entry.
160 * @return 0 on success.
163 add_ip_fwd_entry (lisp_gpe_main_t * lgm,
164 vnet_lisp_gpe_add_del_fwd_entry_args_t * a)
166 lisp_gpe_fwd_entry_key_t key;
167 lisp_fwd_entry_t *lfe;
168 fib_protocol_t fproto;
170 lfe = find_fwd_entry (lgm, a, &key);
173 /* don't support updates */
174 return VNET_API_ERROR_INVALID_VALUE;
176 pool_get (lisp_fwd_entry_pool, lfe);
177 memset (lfe, 0, sizeof (*lfe));
178 lfe->key = clib_mem_alloc (sizeof (key));
179 memcpy (lfe->key, &key, sizeof (key));
181 hash_set_mem (lisp_gpe_fwd_entries, lfe->key, lfe - lisp_fwd_entry_pool);
183 fproto = (IP4 == ip_prefix_version (&fid_addr_ippref (&lfe->key->rmt)) ?
184 FIB_PROTOCOL_IP4 : FIB_PROTOCOL_IP6);
186 lfe->type = (a->is_negative ?
187 LISP_FWD_ENTRY_TYPE_NEGATIVE : LISP_FWD_ENTRY_TYPE_NORMAL);
188 lfe->eid_table_id = a->table_id;
189 lfe->eid_fib_index = fib_table_find_or_create_and_lock (fproto,
192 if (LISP_FWD_ENTRY_TYPE_NEGATIVE != lfe->type)
194 lisp_fwd_path_t *path;
197 vec_validate (lfe->paths, vec_len (a->locator_pairs) - 1);
199 vec_foreach_index (index, a->locator_pairs)
201 path = &lfe->paths[index];
203 path->priority = a->locator_pairs[index].priority;
204 path->weight = a->locator_pairs[index].weight;
207 lisp_gpe_adjacency_find_or_create_and_lock (&a->locator_pairs
212 vec_sort_with_function (lfe->paths, lisp_gpe_fwd_entry_path_sort);
215 create_fib_entries (lfe);
221 del_ip_fwd_entry_i (lisp_fwd_entry_t * lfe)
223 lisp_fwd_path_t *path;
224 fib_protocol_t fproto;
226 vec_foreach (path, lfe->paths)
228 lisp_gpe_adjacency_unlock (path->lisp_adj);
231 delete_fib_entries (lfe);
233 fproto = (IP4 == ip_prefix_version (&fid_addr_ippref (&lfe->key->rmt)) ?
234 FIB_PROTOCOL_IP4 : FIB_PROTOCOL_IP6);
235 fib_table_unlock (lfe->eid_fib_index, fproto);
237 hash_unset_mem (lisp_gpe_fwd_entries, lfe->key);
238 clib_mem_free (lfe->key);
239 pool_put (lisp_fwd_entry_pool, lfe);
243 * @brief Add/Delete LISP IP forwarding entry.
245 * removal of forwarding entries for IP LISP overlay:
247 * @param[in] lgm Reference to @ref lisp_gpe_main_t.
248 * @param[in] a Parameters for building the forwarding entry.
250 * @return 0 on success.
253 del_ip_fwd_entry (lisp_gpe_main_t * lgm,
254 vnet_lisp_gpe_add_del_fwd_entry_args_t * a)
256 lisp_gpe_fwd_entry_key_t key;
257 lisp_fwd_entry_t *lfe;
259 lfe = find_fwd_entry (lgm, a, &key);
263 return VNET_API_ERROR_INVALID_VALUE;
265 del_ip_fwd_entry_i (lfe);
271 make_mac_fib_key (BVT (clib_bihash_kv) * kv, u16 bd_index, u8 src_mac[6],
274 kv->key[0] = (((u64) bd_index) << 48) | mac_to_u64 (dst_mac);
275 kv->key[1] = mac_to_u64 (src_mac);
280 * @brief Lookup L2 SD FIB entry
282 * Does a vni + dest + source lookup in the L2 LISP FIB. If the lookup fails
283 * it tries a second time with source set to 0 (i.e., a simple dest lookup).
285 * @param[in] lgm Reference to @ref lisp_gpe_main_t.
286 * @param[in] bd_index Bridge domain index.
287 * @param[in] src_mac Source mac address.
288 * @param[in] dst_mac Destination mac address.
290 * @return index of mapping matching the lookup key.
293 lisp_l2_fib_lookup (lisp_gpe_main_t * lgm, u16 bd_index, u8 src_mac[6],
297 BVT (clib_bihash_kv) kv, value;
299 make_mac_fib_key (&kv, bd_index, src_mac, dst_mac);
300 rv = BV (clib_bihash_search_inline_2) (&lgm->l2_fib, &kv, &value);
302 /* no match, try with src 0, catch all for dst */
306 rv = BV (clib_bihash_search_inline_2) (&lgm->l2_fib, &kv, &value);
311 return lisp_gpe_main.l2_lb_miss;
315 * @brief Add/del L2 SD FIB entry
317 * Inserts value in L2 FIB keyed by vni + dest + source. If entry is
318 * overwritten the associated value is returned.
320 * @param[in] lgm Reference to @ref lisp_gpe_main_t.
321 * @param[in] bd_index Bridge domain index.
322 * @param[in] src_mac Source mac address.
323 * @param[in] dst_mac Destination mac address.
324 * @param[in] val Value to add.
325 * @param[in] is_add Add/del flag.
327 * @return ~0 or value of overwritten entry.
330 lisp_l2_fib_add_del_entry (lisp_gpe_main_t * lgm, u16 bd_index, u8 src_mac[6],
331 u8 dst_mac[6], u32 val, u8 is_add)
333 BVT (clib_bihash_kv) kv, value;
336 make_mac_fib_key (&kv, bd_index, src_mac, dst_mac);
338 if (BV (clib_bihash_search) (&lgm->l2_fib, &kv, &value) == 0)
339 old_val = value.value;
342 BV (clib_bihash_add_del) (&lgm->l2_fib, &kv, 0 /* is_add */ );
346 BV (clib_bihash_add_del) (&lgm->l2_fib, &kv, 1 /* is_add */ );
352 l2_fib_init (lisp_gpe_main_t * lgm)
354 BV (clib_bihash_init) (&lgm->l2_fib, "l2 fib",
355 1 << max_log2 (L2_FIB_DEFAULT_HASH_NUM_BUCKETS),
356 L2_FIB_DEFAULT_HASH_MEMORY_SIZE);
359 * the result from a 'miss' in a L2 Table
361 lgm->l2_lb_miss = load_balance_create (1, DPO_PROTO_IP4, 0);
362 load_balance_set_bucket (lgm->l2_lb_miss, 0, drop_dpo_get (DPO_PROTO_IP4));
366 * @brief Add/Delete LISP L2 forwarding entry.
368 * Coordinates the creation/removal of forwarding entries for L2 LISP overlay:
369 * creates lisp-gpe tunnel and injects new entry in Source/Dest L2 FIB.
371 * @param[in] lgm Reference to @ref lisp_gpe_main_t.
372 * @param[in] a Parameters for building the forwarding entry.
374 * @return 0 on success.
377 add_del_l2_fwd_entry (lisp_gpe_main_t * lgm,
378 vnet_lisp_gpe_add_del_fwd_entry_args_t * a)
380 /* lisp_gpe_fwd_entry_key_t key; */
381 /* lisp_fwd_entry_t *lfe; */
382 /* fib_protocol_t fproto; */
383 /* uword *bd_indexp; */
385 /* bd_indexp = hash_get (bdm->bd_index_by_bd_id, a->bd_id); */
386 /* if (!bd_indexp) */
388 /* clib_warning ("bridge domain %d doesn't exist", a->bd_id); */
392 /* lfe = find_fwd_entry(lgm, a, &key); */
394 /* if (NULL != lfe) */
395 /* /\* don't support updates *\/ */
396 /* return VNET_API_ERROR_INVALID_VALUE; */
400 /* fib_node_index_t old_path_list; */
401 /* bd_main_t *bdm = &bd_main; */
402 /* fib_route_path_t *rpaths; */
403 /* lisp_gpe_tunnel_t *t; */
404 /* const dpo_id_t *dpo; */
407 /* /\* create tunnel *\/ */
408 /* rv = add_del_ip_tunnel (a, 1 /\* is_l2 *\/ , &tun_index, NULL); */
412 /* bd_indexp = hash_get (bdm->bd_index_by_bd_id, a->bd_id); */
413 /* if (!bd_indexp) */
415 /* clib_warning ("bridge domain %d doesn't exist", a->bd_id); */
419 /* t = pool_elt_at_index (lgm->tunnels, tun_index); */
420 /* old_path_list = t->l2_path_list; */
422 /* if (LISP_NO_ACTION == t->action) */
424 /* rpaths = lisp_gpe_mk_paths_for_sub_tunnels (t); */
426 /* t->l2_path_list = fib_path_list_create (FIB_PATH_LIST_FLAG_NONE, */
429 /* vec_free (rpaths); */
430 /* fib_path_list_lock (t->l2_path_list); */
432 /* dpo = fib_path_list_contribute_forwarding (t->l2_path_list, */
433 /* FIB_FORW_CHAIN_TYPE_UNICAST_IP); */
434 /* lbi = dpo->dpoi_index; */
436 /* else if (LISP_SEND_MAP_REQUEST == t->action) */
438 /* lbi = lgm->l2_lb_cp_lkup; */
442 /* lbi = lgm->l2_lb_miss; */
444 /* fib_path_list_unlock (old_path_list); */
446 /* /\* add entry to l2 lisp fib *\/ */
447 /* lisp_l2_fib_add_del_entry (lgm, bd_indexp[0], gid_address_mac (&a->lcl_eid), */
448 /* gid_address_mac (&a->rmt_eid), lbi, a->is_add); */
453 * @brief Forwarding entry create/remove dispatcher.
455 * Calls l2 or l3 forwarding entry add/del function based on input data.
457 * @param[in] a Forwarding entry parameters.
458 * @param[out] hw_if_indexp NOT USED
460 * @return 0 on success.
463 vnet_lisp_gpe_add_del_fwd_entry (vnet_lisp_gpe_add_del_fwd_entry_args_t * a,
466 lisp_gpe_main_t *lgm = &lisp_gpe_main;
469 if (vnet_lisp_gpe_enable_disable_status () == 0)
471 clib_warning ("LISP is disabled!");
472 return VNET_API_ERROR_LISP_DISABLED;
475 type = gid_address_type (&a->rmt_eid);
478 case GID_ADDR_IP_PREFIX:
480 return add_ip_fwd_entry (lgm, a);
482 return del_ip_fwd_entry (lgm, a);
485 return add_del_l2_fwd_entry (lgm, a);
487 clib_warning ("Forwarding entries for type %d not supported!", type);
492 /** CLI command to add/del forwarding entry. */
493 static clib_error_t *
494 lisp_gpe_add_del_fwd_entry_command_fn (vlib_main_t * vm,
495 unformat_input_t * input,
496 vlib_cli_command_t * cmd)
498 unformat_input_t _line_input, *line_input = &_line_input;
500 ip_address_t lloc, rloc;
501 clib_error_t *error = 0;
502 gid_address_t _reid, *reid = &_reid, _leid, *leid = &_leid;
503 u8 reid_set = 0, leid_set = 0, is_negative = 0, vrf_set = 0, vni_set = 0;
504 u32 vni, vrf, action = ~0, p, w;
505 locator_pair_t pair, *pairs = 0;
508 /* Get a line of input. */
509 if (!unformat_user (input, unformat_line_input, line_input))
512 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
514 if (unformat (line_input, "del"))
516 else if (unformat (line_input, "add"))
518 else if (unformat (line_input, "leid %U", unformat_gid_address, leid))
522 else if (unformat (line_input, "reid %U", unformat_gid_address, reid))
526 else if (unformat (line_input, "vni %u", &vni))
528 gid_address_vni (leid) = vni;
529 gid_address_vni (reid) = vni;
532 else if (unformat (line_input, "vrf %u", &vrf))
536 else if (unformat (line_input, "negative action %U",
537 unformat_negative_mapping_action, &action))
541 else if (unformat (line_input, "loc-pair %U %U p %d w %d",
542 unformat_ip_address, &lloc,
543 unformat_ip_address, &rloc, &p, &w))
549 vec_add1 (pairs, pair);
553 error = unformat_parse_error (line_input);
557 unformat_free (line_input);
559 if (!vni_set || !vrf_set)
561 error = clib_error_return (0, "vni and vrf must be set!");
567 error = clib_error_return (0, "remote eid must be set!");
575 error = clib_error_return (0, "no action set for negative tunnel!");
581 if (vec_len (pairs) == 0)
583 error = clib_error_return (0, "expected ip4/ip6 locators.");
590 /* if leid not set, make sure it's the same AFI like reid */
591 gid_address_type (leid) = gid_address_type (reid);
592 if (GID_ADDR_IP_PREFIX == gid_address_type (reid))
593 gid_address_ip_version (leid) = gid_address_ip_version (reid);
597 vnet_lisp_gpe_add_del_fwd_entry_args_t _a, *a = &_a;
598 memset (a, 0, sizeof (a[0]));
603 gid_address_copy (&a->lcl_eid, leid);
604 gid_address_copy (&a->rmt_eid, reid);
605 a->locator_pairs = pairs;
607 rv = vnet_lisp_gpe_add_del_fwd_entry (a, 0);
610 error = clib_error_return (0, "failed to %s gpe tunnel!",
611 is_add ? "add" : "delete");
620 VLIB_CLI_COMMAND (lisp_gpe_add_del_fwd_entry_command, static) = {
621 .path = "lisp gpe entry",
622 .short_help = "lisp gpe entry add/del vni <vni> vrf <vrf> [leid <leid>]"
623 "reid <reid> [loc-pair <lloc> <rloc> p <priority> w <weight>] "
624 "[negative action <action>]",
625 .function = lisp_gpe_add_del_fwd_entry_command_fn,
630 format_lisp_fwd_path (u8 * s, va_list ap)
632 lisp_fwd_path_t *lfp = va_arg (ap, lisp_fwd_path_t *);
634 s = format (s, "pirority:%d weight:%d ", lfp->priority, lfp->weight);
635 s = format (s, "adj:[%U]\n",
636 format_lisp_gpe_adjacency,
637 lisp_gpe_adjacency_get (lfp->lisp_adj),
638 LISP_GPE_ADJ_FORMAT_FLAG_NONE);
644 format_lisp_gpe_fwd_entry (u8 * s, va_list ap)
646 lisp_fwd_entry_t *lfe = va_arg (ap, lisp_fwd_entry_t *);
648 s = format (s, "VNI:%d VRF:%d EID: %U -> %U",
649 lfe->key->vni, lfe->eid_table_id,
650 format_fid_address, &lfe->key->lcl,
651 format_fid_address, &lfe->key->rmt);
652 if (LISP_FWD_ENTRY_TYPE_NEGATIVE == lfe->type)
654 s = format (s, "\n Negative - action:%U",
655 format_negative_mapping_action, lfe->action);
659 lisp_fwd_path_t *path;
661 s = format (s, "\n via:");
662 vec_foreach (path, lfe->paths)
664 s = format (s, "\n %U", format_lisp_fwd_path, path);
671 static clib_error_t *
672 lisp_gpe_fwd_entry_show (vlib_main_t * vm,
673 unformat_input_t * input, vlib_cli_command_t * cmd)
675 lisp_fwd_entry_t *lfe;
678 pool_foreach (lfe, lisp_fwd_entry_pool,
680 vlib_cli_output (vm, "%U", format_lisp_gpe_fwd_entry, lfe);
688 VLIB_CLI_COMMAND (lisp_gpe_fwd_entry_show_command, static) = {
689 .path = "show lisp gpe entry",
690 .short_help = "show lisp gpe entry vni <vni> vrf <vrf> [leid <leid>] reid <reid>",
691 .function = lisp_gpe_fwd_entry_show,
695 /** Check if LISP-GPE is enabled. */
697 vnet_lisp_gpe_enable_disable_status (void)
699 lisp_gpe_main_t *lgm = &lisp_gpe_main;
704 /** Enable/disable LISP-GPE. */
706 vnet_lisp_gpe_enable_disable (vnet_lisp_gpe_enable_disable_args_t * a)
708 lisp_gpe_main_t *lgm = &lisp_gpe_main;
716 CLIB_UNUSED (uword * val);
718 u32 *dp_tables = 0, *dp_table;
719 vnet_lisp_gpe_add_del_iface_args_t _ai, *ai = &_ai;
720 lisp_fwd_entry_t *lfe;
722 /* remove all entries */
724 pool_foreach (lfe, lisp_fwd_entry_pool,
726 del_ip_fwd_entry_i (lfe);
730 /* disable all l3 ifaces */
733 hash_foreach_pair(p, lgm->l3_ifaces.hw_if_index_by_dp_table, ({
734 vec_add1(dp_tables, p->key);
738 vec_foreach (dp_table, dp_tables)
741 ai->table_id = dp_table[0];
744 /* disables interface and removes defaults */
745 vnet_lisp_gpe_add_del_iface (ai, 0);
748 /* disable all l2 ifaces */
749 _vec_len (dp_tables) = 0;
752 hash_foreach_pair(p, lgm->l2_ifaces.hw_if_index_by_dp_table, ({
753 vec_add1(dp_tables, p->key);
757 vec_foreach (dp_table, dp_tables)
760 ai->bd_id = dp_table[0];
763 /* disables interface and removes defaults */
764 vnet_lisp_gpe_add_del_iface (ai, 0);
767 vec_free (dp_tables);
774 /** CLI command to enable/disable LISP-GPE. */
775 static clib_error_t *
776 lisp_gpe_enable_disable_command_fn (vlib_main_t * vm,
777 unformat_input_t * input,
778 vlib_cli_command_t * cmd)
780 unformat_input_t _line_input, *line_input = &_line_input;
782 vnet_lisp_gpe_enable_disable_args_t _a, *a = &_a;
784 /* Get a line of input. */
785 if (!unformat_user (input, unformat_line_input, line_input))
788 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
790 if (unformat (line_input, "enable"))
792 else if (unformat (line_input, "disable"))
796 return clib_error_return (0, "parse error: '%U'",
797 format_unformat_error, line_input);
801 return vnet_lisp_gpe_enable_disable (a);
805 VLIB_CLI_COMMAND (enable_disable_lisp_gpe_command, static) = {
807 .short_help = "lisp gpe [enable|disable]",
808 .function = lisp_gpe_enable_disable_command_fn,
812 /** CLI command to show LISP-GPE interfaces. */
813 static clib_error_t *
814 lisp_show_iface_command_fn (vlib_main_t * vm,
815 unformat_input_t * input,
816 vlib_cli_command_t * cmd)
818 lisp_gpe_main_t *lgm = &lisp_gpe_main;
821 vlib_cli_output (vm, "%=10s%=12s", "vrf", "hw_if_index");
824 hash_foreach_pair (p, lgm->l3_ifaces.hw_if_index_by_dp_table, ({
825 vlib_cli_output (vm, "%=10d%=10d", p->key, p->value[0]);
829 if (0 != lgm->l2_ifaces.hw_if_index_by_dp_table)
831 vlib_cli_output (vm, "%=10s%=12s", "bd_id", "hw_if_index");
833 hash_foreach_pair (p, lgm->l2_ifaces.hw_if_index_by_dp_table, ({
834 vlib_cli_output (vm, "%=10d%=10d", p->key, p->value[0]);
842 VLIB_CLI_COMMAND (lisp_show_iface_command) = {
843 .path = "show lisp gpe interface",
844 .short_help = "show lisp gpe interface",
845 .function = lisp_show_iface_command_fn,
849 /** Format LISP-GPE status. */
851 format_vnet_lisp_gpe_status (u8 * s, va_list * args)
853 lisp_gpe_main_t *lgm = &lisp_gpe_main;
854 return format (s, "%s", lgm->is_en ? "enabled" : "disabled");
858 /** LISP-GPE init function. */
860 lisp_gpe_init (vlib_main_t * vm)
862 lisp_gpe_main_t *lgm = &lisp_gpe_main;
863 clib_error_t *error = 0;
865 if ((error = vlib_call_init_function (vm, ip_main_init)))
868 if ((error = vlib_call_init_function (vm, ip4_lookup_init)))
871 lgm->vnet_main = vnet_get_main ();
873 lgm->im4 = &ip4_main;
874 lgm->im6 = &ip6_main;
875 lgm->lm4 = &ip4_main.lookup_main;
876 lgm->lm6 = &ip6_main.lookup_main;
878 lisp_gpe_fwd_entries = hash_create_mem (0,
879 sizeof (lisp_gpe_fwd_entry_key_t),
884 udp_register_dst_port (vm, UDP_DST_PORT_lisp_gpe,
885 lisp_gpe_ip4_input_node.index, 1 /* is_ip4 */ );
886 udp_register_dst_port (vm, UDP_DST_PORT_lisp_gpe6,
887 lisp_gpe_ip6_input_node.index, 0 /* is_ip4 */ );
891 VLIB_INIT_FUNCTION (lisp_gpe_init);
894 * fd.io coding-style-patch-verification: ON
897 * eval: (c-set-style "gnu")