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.
16 #include <vnet/lisp-gpe/lisp_gpe_adjacency.h>
17 #include <vnet/fib/fib_table.h>
18 #include <vnet/fib/fib_entry.h>
19 #include <vnet/fib/ip6_fib.h>
20 #include <vnet/fib/ip4_fib.h>
21 #include <vnet/dpo/lookup_dpo.h>
22 #include <vnet/dpo/load_balance.h>
25 * @brief Add route to IP4 or IP6 Destination FIB.
27 * Add a route to the destination FIB that results in the lookup
28 * in the SRC FIB. The SRC FIB is created is it does not yet exist.
30 * @param[in] dst_table_id Destination FIB Table-ID
31 * @param[in] dst_prefix Destination IP prefix.
32 * @param[out] src_fib_index The index/ID of the SRC FIB created.
35 ip_dst_fib_add_route (u32 dst_fib_index, const ip_prefix_t * dst_prefix)
37 fib_node_index_t src_fib_index;
38 fib_prefix_t dst_fib_prefix;
39 fib_node_index_t dst_fei;
41 ASSERT (NULL != dst_prefix);
43 ip_prefix_to_fib_prefix (dst_prefix, &dst_fib_prefix);
46 * lookup the destination prefix in the VRF table and retrieve the
47 * LISP associated data
49 dst_fei = fib_table_lookup_exact_match (dst_fib_index, &dst_fib_prefix);
52 * If the FIB entry is not present, or not LISP sourced, add it
54 if (dst_fei == FIB_NODE_INDEX_INVALID ||
55 NULL == fib_entry_get_source_data (dst_fei, FIB_SOURCE_LISP))
57 dpo_id_t src_lkup_dpo = DPO_NULL;
59 /* create a new src FIB. */
61 fib_table_create_and_lock (dst_fib_prefix.fp_proto,
62 "LISP-src for [%d,%U]",
64 format_fib_prefix, &dst_fib_prefix);
67 * create a data-path object to perform the source address lookup
70 lookup_dpo_add_or_lock_w_fib_index (src_fib_index,
71 (ip_prefix_version (dst_prefix) ==
74 LOOKUP_INPUT_SRC_ADDR,
75 LOOKUP_TABLE_FROM_CONFIG,
79 * add the entry to the destination FIB that uses the lookup DPO
81 dst_fei = fib_table_entry_special_dpo_add (dst_fib_index,
84 FIB_ENTRY_FLAG_EXCLUSIVE,
88 * the DPO is locked by the FIB entry, and we have no further
91 dpo_unlock (&src_lkup_dpo);
94 * save the SRC FIB index on the entry so we can retrieve it for
97 fib_entry_set_source_data (dst_fei, FIB_SOURCE_LISP, &src_fib_index);
102 * destination FIB entry already present
104 src_fib_index = *(u32 *) fib_entry_get_source_data (dst_fei,
108 return (src_fib_index);
112 * @brief Del route to IP4 or IP6 SD FIB.
114 * Remove routes from both destination and source FIBs.
116 * @param[in] src_fib_index The index/ID of the SRC FIB
117 * @param[in] src_prefix Source IP prefix.
118 * @param[in] dst_fib_index The index/ID of the DST FIB
119 * @param[in] dst_prefix Destination IP prefix.
122 ip_src_dst_fib_del_route (u32 src_fib_index,
123 const ip_prefix_t * src_prefix,
124 u32 dst_fib_index, const ip_prefix_t * dst_prefix)
126 fib_prefix_t dst_fib_prefix, src_fib_prefix;
128 ASSERT (NULL != dst_prefix);
129 ASSERT (NULL != src_prefix);
131 ip_prefix_to_fib_prefix (dst_prefix, &dst_fib_prefix);
132 ip_prefix_to_fib_prefix (src_prefix, &src_fib_prefix);
134 fib_table_entry_delete (src_fib_index, &src_fib_prefix, FIB_SOURCE_LISP);
136 if (0 == fib_table_get_num_entries (src_fib_index,
137 src_fib_prefix.fp_proto,
141 * there's nothing left, unlock the source FIB and the
144 fib_table_entry_special_remove (dst_fib_index,
145 &dst_fib_prefix, FIB_SOURCE_LISP);
146 fib_table_unlock (src_fib_index, src_fib_prefix.fp_proto);
151 * @brief Add route to IP4 or IP6 SRC FIB.
153 * Adds a route to in the LISP SRC FIB with the result of the route
154 * being the DPO passed.
156 * @param[in] src_fib_index The index/ID of the SRC FIB
157 * @param[in] src_prefix Source IP prefix.
158 * @param[in] src_dpo The DPO the route will link to.
161 ip_src_fib_add_route_w_dpo (u32 src_fib_index,
162 const ip_prefix_t * src_prefix,
163 const dpo_id_t * src_dpo)
165 fib_prefix_t src_fib_prefix;
167 ip_prefix_to_fib_prefix (src_prefix, &src_fib_prefix);
170 * add the entry into the source fib.
172 fib_node_index_t src_fei;
174 src_fei = fib_table_lookup_exact_match (src_fib_index, &src_fib_prefix);
176 if (FIB_NODE_INDEX_INVALID == src_fei ||
177 !fib_entry_is_sourced (src_fei, FIB_SOURCE_LISP))
179 fib_table_entry_special_dpo_add (src_fib_index,
182 FIB_ENTRY_FLAG_EXCLUSIVE, src_dpo);
187 ip_address_to_46 (const ip_address_t * addr,
188 ip46_address_t * a, fib_protocol_t * proto)
190 *proto = (IP4 == ip_addr_version (addr) ?
191 FIB_PROTOCOL_IP4 : FIB_PROTOCOL_IP6);
194 case FIB_PROTOCOL_IP4:
195 a->ip4 = addr->ip.v4;
197 case FIB_PROTOCOL_IP6:
198 a->ip6 = addr->ip.v6;
206 static fib_route_path_t *
207 ip_src_fib_mk_paths (const lisp_fwd_path_t * paths)
209 const lisp_gpe_adjacency_t *ladj;
210 fib_route_path_t *rpaths = NULL;
214 vec_validate (rpaths, vec_len (paths) - 1);
216 best_priority = paths[0].priority;
218 vec_foreach_index (ii, paths)
220 if (paths[0].priority != best_priority)
223 ladj = lisp_gpe_adjacency_get (paths[ii].lisp_adj);
225 ip_address_to_46 (&ladj->remote_rloc,
226 &rpaths[ii].frp_addr, &rpaths[ii].frp_proto);
228 rpaths[ii].frp_sw_if_index = ladj->sw_if_index;
229 rpaths[ii].frp_weight = (paths[ii].weight ? paths[ii].weight : 1);
230 rpaths[ii].frp_label = MPLS_LABEL_INVALID;
233 ASSERT (0 != vec_len (rpaths));
239 * @brief Add route to IP4 or IP6 SRC FIB.
241 * Adds a route to in the LISP SRC FIB for the tunnel.
243 * @param[in] src_fib_index The index/ID of the SRC FIB
244 * @param[in] src_prefix Source IP prefix.
245 * @param[in] paths The paths from which to construct the
249 ip_src_fib_add_route (u32 src_fib_index,
250 const ip_prefix_t * src_prefix,
251 const lisp_fwd_path_t * paths)
253 fib_prefix_t src_fib_prefix;
254 fib_route_path_t *rpaths;
256 ip_prefix_to_fib_prefix (src_prefix, &src_fib_prefix);
258 rpaths = ip_src_fib_mk_paths (paths);
260 fib_table_entry_update (src_fib_index,
262 FIB_SOURCE_LISP, FIB_ENTRY_FLAG_NONE, rpaths);
267 * fd.io coding-style-patch-verification: ON
270 * eval: (c-set-style "gnu")