blob: a0fa3b49280cb46e46775820d6d7759af64e1829 [file] [log] [blame]
Ed Warnickecb9cada2015-12-08 15:45:58 -07001/*
AkshayaNadahallied4a2fd2016-08-09 13:38:04 +05302 * 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 */
15/*
16 * ip/ip6.h: ip6 main include file
17 *
18 * Copyright (c) 2008 Eliot Dresselhaus
19 *
20 * Permission is hereby granted, free of charge, to any person obtaining
21 * a copy of this software and associated documentation files (the
22 * "Software"), to deal in the Software without restriction, including
23 * without limitation the rights to use, copy, modify, merge, publish,
24 * distribute, sublicense, and/or sell copies of the Software, and to
25 * permit persons to whom the Software is furnished to do so, subject to
26 * the following conditions:
27 *
28 * The above copyright notice and this permission notice shall be
29 * included in all copies or substantial portions of the Software.
30 *
31 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
32 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
33 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
34 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
35 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
36 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
37 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
38 */
39
40#ifndef included_ip_ip6_h
41#define included_ip_ip6_h
42
Neale Rannse4031132020-10-26 13:00:06 +000043#include <stdbool.h>
44
John Lo1edfba92016-08-27 01:11:57 -040045#include <vlib/buffer.h>
Neale Rannse4031132020-10-26 13:00:06 +000046
Ed Warnickecb9cada2015-12-08 15:45:58 -070047#include <vnet/ip/ip6_packet.h>
Neale Rannscbe25aa2019-09-30 10:53:31 +000048#include <vnet/ip/ip46_address.h>
Ole Troan944f5482016-05-24 11:56:58 +020049#include <vnet/ip/ip6_hop_by_hop_packet.h>
Ed Warnickecb9cada2015-12-08 15:45:58 -070050#include <vnet/ip/lookup.h>
Neale Ranns59f71132020-04-08 12:19:38 +000051#include <vnet/ip/ip_interface.h>
Neale Rannse4031132020-10-26 13:00:06 +000052#include <vnet/ip/ip_flow_hash.h>
Ed Warnickecb9cada2015-12-08 15:45:58 -070053
Dave Barachd7cb1b52016-12-09 09:52:16 -050054typedef struct
55{
Ed Warnickecb9cada2015-12-08 15:45:58 -070056 ip6_address_t addr;
57 u32 dst_address_length;
58 u32 vrf_index;
59} ip6_fib_key_t;
60
Dave Barachd7cb1b52016-12-09 09:52:16 -050061typedef struct
62{
Dave Baracheb987d32018-05-03 08:26:39 -040063 /* required for pool_get_aligned. */
64 CLIB_CACHE_LINE_ALIGN_MARK (cacheline0);
65
Ed Warnickecb9cada2015-12-08 15:45:58 -070066 /* Table ID (hash key) for this FIB. */
67 u32 table_id;
68
69 /* Index into FIB vector. */
70 u32 index;
Ed Warnickecb9cada2015-12-08 15:45:58 -070071} ip6_fib_t;
72
Neale Ranns32e1c012016-11-22 17:07:28 +000073typedef struct ip6_mfib_t
74{
Neale Rannsae809832018-11-23 09:00:27 -080075 /* required for pool_get_aligned. */
76 CLIB_CACHE_LINE_ALIGN_MARK (cacheline0);
77
Neale Ranns32e1c012016-11-22 17:07:28 +000078 /* Table ID (hash key) for this FIB. */
79 u32 table_id;
80
81 /* Index into FIB vector. */
82 u32 index;
Neale Ranns32e1c012016-11-22 17:07:28 +000083} ip6_mfib_t;
84
Ed Warnickecb9cada2015-12-08 15:45:58 -070085struct ip6_main_t;
86
Ed Warnickecb9cada2015-12-08 15:45:58 -070087typedef void (ip6_add_del_interface_address_function_t)
88 (struct ip6_main_t * im,
89 uword opaque,
90 u32 sw_if_index,
91 ip6_address_t * address,
Dave Barachd7cb1b52016-12-09 09:52:16 -050092 u32 address_length, u32 if_address_index, u32 is_del);
Ed Warnickecb9cada2015-12-08 15:45:58 -070093
Dave Barachd7cb1b52016-12-09 09:52:16 -050094typedef struct
95{
96 ip6_add_del_interface_address_function_t *function;
Ed Warnickecb9cada2015-12-08 15:45:58 -070097 uword function_opaque;
98} ip6_add_del_interface_address_callback_t;
99
Neale Ranns15002542017-09-10 04:39:11 -0700100typedef void (ip6_table_bind_function_t)
101 (struct ip6_main_t * im,
102 uword opaque, u32 sw_if_index, u32 new_fib_index, u32 old_fib_index);
103
104typedef struct
105{
106 ip6_table_bind_function_t *function;
107 uword function_opaque;
108} ip6_table_bind_callback_t;
109
Dave Barachd7cb1b52016-12-09 09:52:16 -0500110typedef struct ip6_main_t
111{
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100112 ip_lookup_main_t lookup_main;
Dave Barach75fc8542016-10-11 16:16:02 -0400113
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100114 /* Pool of FIBs. */
Dave Barachd7cb1b52016-12-09 09:52:16 -0500115 struct fib_table_t_ *fibs;
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100116
Neale Rannsa3af3372017-03-28 03:49:52 -0700117 /* Pool of V6 FIBs. */
118 ip6_fib_t *v6_fibs;
119
Neale Ranns32e1c012016-11-22 17:07:28 +0000120 /** Vector of MFIBs. */
121 struct mfib_table_t_ *mfibs;
122
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100123 /* Network byte orders subnet mask for each prefix length */
Ed Warnickecb9cada2015-12-08 15:45:58 -0700124 ip6_address_t fib_masks[129];
125
126 /* Table index indexed by software interface. */
Dave Barachd7cb1b52016-12-09 09:52:16 -0500127 u32 *fib_index_by_sw_if_index;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700128
Neale Ranns32e1c012016-11-22 17:07:28 +0000129 /** Table index indexed by software interface. */
130 u32 *mfib_index_by_sw_if_index;
131
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100132 /* IP6 enabled count by software interface */
Dave Barachd7cb1b52016-12-09 09:52:16 -0500133 u8 *ip_enabled_by_sw_if_index;
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100134
Ed Warnickecb9cada2015-12-08 15:45:58 -0700135 /* Hash table mapping table id to fib index.
136 ID space is not necessarily dense; index space is dense. */
Dave Barachd7cb1b52016-12-09 09:52:16 -0500137 uword *fib_index_by_table_id;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700138
Neale Ranns32e1c012016-11-22 17:07:28 +0000139 /** Hash table mapping table id to multicast fib index.
140 ID space is not necessarily dense; index space is dense. */
141 uword *mfib_index_by_table_id;
142
Ed Warnickecb9cada2015-12-08 15:45:58 -0700143 /* Hash table mapping interface rewrite adjacency index by sw if index. */
Dave Barachd7cb1b52016-12-09 09:52:16 -0500144 uword *interface_route_adj_index_by_sw_if_index;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700145
146 /* Functions to call when interface address changes. */
Dave Barachd7cb1b52016-12-09 09:52:16 -0500147 ip6_add_del_interface_address_callback_t
148 * add_del_interface_address_callbacks;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700149
Neale Ranns15002542017-09-10 04:39:11 -0700150 /** Functions to call when interface to table biding changes. */
151 ip6_table_bind_callback_t *table_bind_callbacks;
152
Ed Warnickecb9cada2015-12-08 15:45:58 -0700153 /* Seed for Jenkins hash used to compute ip6 flow hash. */
154 u32 flow_hash_seed;
155
Dave Barachd7cb1b52016-12-09 09:52:16 -0500156 struct
157 {
Ed Warnickecb9cada2015-12-08 15:45:58 -0700158 /* TTL to use for host generated packets. */
159 u8 ttl;
160
161 u8 pad[3];
162 } host_config;
Ole Troan944f5482016-05-24 11:56:58 +0200163
164 /* HBH processing enabled? */
165 u8 hbh_enabled;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700166} ip6_main_t;
167
Dave Barach49433ad2018-08-08 17:59:03 -0400168#define ND_THROTTLE_BITS 512
169
Ed Warnickecb9cada2015-12-08 15:45:58 -0700170/* Global ip6 main structure. */
171extern ip6_main_t ip6_main;
172
173/* Global ip6 input node. Errors get attached to ip6 input node. */
174extern vlib_node_registration_t ip6_input_node;
175extern vlib_node_registration_t ip6_rewrite_node;
Neale Ranns32e1c012016-11-22 17:07:28 +0000176extern vlib_node_registration_t ip6_rewrite_mcast_node;
Pierre Pfister0febaf12016-06-08 12:23:21 +0100177extern vlib_node_registration_t ip6_rewrite_local_node;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700178extern vlib_node_registration_t ip6_discover_neighbor_node;
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100179extern vlib_node_registration_t ip6_glean_node;
180extern vlib_node_registration_t ip6_midchain_node;
Jawahar Santosh Gundapaneni62ad2aa2020-03-19 16:42:28 -0400181extern vlib_node_registration_t ip6_punt_node;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700182
Neale Rannsd91c1db2017-07-31 02:30:50 -0700183extern void ip6_forward_next_trace (vlib_main_t * vm,
184 vlib_node_runtime_t * node,
185 vlib_frame_t * frame,
186 vlib_rx_or_tx_t which_adj_index);
187
Ed Warnickecb9cada2015-12-08 15:45:58 -0700188always_inline uword
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100189ip6_destination_matches_route (const ip6_main_t * im,
190 const ip6_address_t * key,
Dave Barachd7cb1b52016-12-09 09:52:16 -0500191 const ip6_address_t * dest, uword dest_length)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700192{
193 int i;
194 for (i = 0; i < ARRAY_LEN (key->as_uword); i++)
195 {
Dave Barachd7cb1b52016-12-09 09:52:16 -0500196 if ((key->as_uword[i] ^ dest->as_uword[i]) & im->
197 fib_masks[dest_length].as_uword[i])
Ed Warnickecb9cada2015-12-08 15:45:58 -0700198 return 0;
199 }
200 return 1;
201}
202
203always_inline uword
204ip6_destination_matches_interface (ip6_main_t * im,
205 ip6_address_t * key,
206 ip_interface_address_t * ia)
207{
Dave Barachd7cb1b52016-12-09 09:52:16 -0500208 ip6_address_t *a = ip_interface_address_get_address (&im->lookup_main, ia);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700209 return ip6_destination_matches_route (im, key, a, ia->address_length);
210}
211
212/* As above but allows for unaligned destinations (e.g. works right from IP header of packet). */
213always_inline uword
214ip6_unaligned_destination_matches_route (ip6_main_t * im,
215 ip6_address_t * key,
216 ip6_address_t * dest,
217 uword dest_length)
218{
219 int i;
220 for (i = 0; i < ARRAY_LEN (key->as_uword); i++)
221 {
Dave Barachd7cb1b52016-12-09 09:52:16 -0500222 if ((clib_mem_unaligned (&key->as_uword[i], uword) ^ dest->as_uword[i])
223 & im->fib_masks[dest_length].as_uword[i])
Ed Warnickecb9cada2015-12-08 15:45:58 -0700224 return 0;
225 }
226 return 1;
227}
228
Ed Warnickecb9cada2015-12-08 15:45:58 -0700229/* Find interface address which matches destination. */
230always_inline ip6_address_t *
Dave Barachd7cb1b52016-12-09 09:52:16 -0500231ip6_interface_address_matching_destination (ip6_main_t * im,
Neale Rannscbe25aa2019-09-30 10:53:31 +0000232 const ip6_address_t * dst,
Dave Barachd7cb1b52016-12-09 09:52:16 -0500233 u32 sw_if_index,
234 ip_interface_address_t **
235 result_ia)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700236{
Dave Barachd7cb1b52016-12-09 09:52:16 -0500237 ip_lookup_main_t *lm = &im->lookup_main;
238 ip_interface_address_t *ia;
239 ip6_address_t *result = 0;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700240
Dave Barachd7cb1b52016-12-09 09:52:16 -0500241 /* *INDENT-OFF* */
Dave Barach75fc8542016-10-11 16:16:02 -0400242 foreach_ip_interface_address (lm, ia, sw_if_index,
Ed Warnickecb9cada2015-12-08 15:45:58 -0700243 1 /* honor unnumbered */,
244 ({
245 ip6_address_t * a = ip_interface_address_get_address (lm, ia);
246 if (ip6_destination_matches_route (im, dst, a, ia->address_length))
247 {
248 result = a;
249 break;
250 }
251 }));
Dave Barachd7cb1b52016-12-09 09:52:16 -0500252 /* *INDENT-ON* */
Ed Warnickecb9cada2015-12-08 15:45:58 -0700253 if (result_ia)
254 *result_ia = result ? ia : 0;
255 return result;
256}
257
Dave Barachd7cb1b52016-12-09 09:52:16 -0500258clib_error_t *ip6_add_del_interface_address (vlib_main_t * vm,
259 u32 sw_if_index,
260 ip6_address_t * address,
261 u32 address_length, u32 is_del);
262void ip6_sw_interface_enable_disable (u32 sw_if_index, u32 is_enable);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700263
Neale Ranns6cfc39c2017-02-14 01:44:25 -0800264/**
Paul Vinciguerrab5a575b2019-11-01 13:00:58 -0400265 * @brief get first IPv6 interface address
Neale Ranns6cfc39c2017-02-14 01:44:25 -0800266 */
267ip6_address_t *ip6_interface_first_address (ip6_main_t * im, u32 sw_if_index);
268
Ed Warnickecb9cada2015-12-08 15:45:58 -0700269int ip6_address_compare (ip6_address_t * a1, ip6_address_t * a2);
270
Ed Warnickecb9cada2015-12-08 15:45:58 -0700271uword
Ed Warnickecb9cada2015-12-08 15:45:58 -0700272ip6_udp_register_listener (vlib_main_t * vm,
Dave Barachd7cb1b52016-12-09 09:52:16 -0500273 u16 dst_port, u32 next_node_index);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700274
Dave Barachd7cb1b52016-12-09 09:52:16 -0500275u16 ip6_tcp_udp_icmp_compute_checksum (vlib_main_t * vm, vlib_buffer_t * p0,
276 ip6_header_t * ip0,
277 int *bogus_lengthp);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700278
279void ip6_register_protocol (u32 protocol, u32 node_index);
Neale Rannsb538dd82019-05-21 06:54:54 -0700280void ip6_unregister_protocol (u32 protocol);
Dave Barach90800962019-05-24 13:03:01 -0400281void ip6_local_hop_by_hop_register_protocol (u32 protocol, u32 node_index);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700282
283serialize_function_t serialize_vnet_ip6_main, unserialize_vnet_ip6_main;
284
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100285int vnet_set_ip6_flow_hash (u32 table_id,
286 flow_hash_config_t flow_hash_config);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700287
John Lo2b81eb82017-01-30 13:12:10 -0500288u8 *format_ip6_forward_next_trace (u8 * s, va_list * args);
289
290u32 ip6_tcp_udp_icmp_validate_checksum (vlib_main_t * vm, vlib_buffer_t * p0);
291
Neale Rannsd91c1db2017-07-31 02:30:50 -0700292void ip6_punt_policer_add_del (u8 is_add, u32 policer_index);
293void ip6_punt_redirect_add (u32 rx_sw_if_index,
294 u32 tx_sw_if_index, ip46_address_t * nh);
Neale Ranns92207752019-06-03 13:21:40 +0000295void ip6_punt_redirect_add_paths (u32 rx_sw_if_index,
296 fib_route_path_t * paths);
Neale Rannsd91c1db2017-07-31 02:30:50 -0700297void ip6_punt_redirect_del (u32 rx_sw_if_index);
298
Dave Barach75fc8542016-10-11 16:16:02 -0400299int vnet_set_ip6_classify_intfc (vlib_main_t * vm, u32 sw_if_index,
Dave Barachd7cb1b52016-12-09 09:52:16 -0500300 u32 table_index);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700301extern vlib_node_registration_t ip6_lookup_node;
302
Shwetha Bhandari78372a92017-01-18 12:43:54 +0530303u8 *format_ip6_hop_by_hop_ext_hdr (u8 * s, va_list * args);
Ole Troan944f5482016-05-24 11:56:58 +0200304/*
305 * Hop-by-Hop handling
306 */
Dave Barachd7cb1b52016-12-09 09:52:16 -0500307typedef struct
308{
Ole Troan944f5482016-05-24 11:56:58 +0200309 /* Array of function pointers to HBH option handling routines */
Dave Barachd7cb1b52016-12-09 09:52:16 -0500310 int (*options[256]) (vlib_buffer_t * b, ip6_header_t * ip,
311 ip6_hop_by_hop_option_t * opt);
312 u8 *(*trace[256]) (u8 * s, ip6_hop_by_hop_option_t * opt);
Shwethaa91cbe62016-08-08 15:51:04 +0100313 uword next_override;
Ole Troan944f5482016-05-24 11:56:58 +0200314} ip6_hop_by_hop_main_t;
315
316extern ip6_hop_by_hop_main_t ip6_hop_by_hop_main;
317
318int ip6_hbh_register_option (u8 option,
Dave Barachd7cb1b52016-12-09 09:52:16 -0500319 int options (vlib_buffer_t * b,
320 ip6_header_t * ip,
321 ip6_hop_by_hop_option_t * opt),
322 u8 * trace (u8 * s,
323 ip6_hop_by_hop_option_t * opt));
Ole Troan944f5482016-05-24 11:56:58 +0200324int ip6_hbh_unregister_option (u8 option);
Shwethaa91cbe62016-08-08 15:51:04 +0100325void ip6_hbh_set_next_override (uword next);
Ole Troan944f5482016-05-24 11:56:58 +0200326
Nick Zavaritsky27518c22020-02-27 15:54:58 +0000327always_inline u32
328vlib_buffer_get_ip6_fib_index (vlib_buffer_t * b)
329{
330 u32 fib_index, sw_if_index;
331 sw_if_index = vnet_buffer (b)->sw_if_index[VLIB_RX];
332 fib_index = vnet_buffer (b)->sw_if_index[VLIB_TX];
333 return (fib_index == (u32) ~ 0) ?
334 vec_elt (ip6_main.fib_index_by_sw_if_index, sw_if_index) : fib_index;
335}
Ed Warnickecb9cada2015-12-08 15:45:58 -0700336#endif /* included_ip_ip6_h */
Dave Barachd7cb1b52016-12-09 09:52:16 -0500337
338/*
339 * fd.io coding-style-patch-verification: ON
340 *
341 * Local Variables:
342 * eval: (c-set-style "gnu")
343 * End:
344 */