blob: f8462a5cbffa2f326878c213150fef1e1fda1929 [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;
BenoƮt Ganne23c48962024-04-05 09:45:29 +020071
72 /**
73 * The hash table DB
74 */
75 uword *fib_entry_by_dst_address;
Ed Warnickecb9cada2015-12-08 15:45:58 -070076} ip6_fib_t;
77
Neale Ranns32e1c012016-11-22 17:07:28 +000078typedef struct ip6_mfib_t
79{
Neale Rannsae809832018-11-23 09:00:27 -080080 /* required for pool_get_aligned. */
81 CLIB_CACHE_LINE_ALIGN_MARK (cacheline0);
82
Neale Ranns32e1c012016-11-22 17:07:28 +000083 /* Table ID (hash key) for this FIB. */
84 u32 table_id;
85
86 /* Index into FIB vector. */
87 u32 index;
Neale Ranns32e1c012016-11-22 17:07:28 +000088} ip6_mfib_t;
89
Ed Warnickecb9cada2015-12-08 15:45:58 -070090struct ip6_main_t;
91
Ed Warnickecb9cada2015-12-08 15:45:58 -070092typedef void (ip6_add_del_interface_address_function_t)
93 (struct ip6_main_t * im,
94 uword opaque,
95 u32 sw_if_index,
96 ip6_address_t * address,
Dave Barachd7cb1b52016-12-09 09:52:16 -050097 u32 address_length, u32 if_address_index, u32 is_del);
Ed Warnickecb9cada2015-12-08 15:45:58 -070098
Dave Barachd7cb1b52016-12-09 09:52:16 -050099typedef struct
100{
101 ip6_add_del_interface_address_function_t *function;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700102 uword function_opaque;
103} ip6_add_del_interface_address_callback_t;
104
Neale Ranns15002542017-09-10 04:39:11 -0700105typedef void (ip6_table_bind_function_t)
106 (struct ip6_main_t * im,
107 uword opaque, u32 sw_if_index, u32 new_fib_index, u32 old_fib_index);
108
109typedef struct
110{
111 ip6_table_bind_function_t *function;
112 uword function_opaque;
113} ip6_table_bind_callback_t;
114
Dave Barachd7cb1b52016-12-09 09:52:16 -0500115typedef struct ip6_main_t
116{
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100117 ip_lookup_main_t lookup_main;
Dave Barach75fc8542016-10-11 16:16:02 -0400118
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100119 /* Pool of FIBs. */
Dave Barachd7cb1b52016-12-09 09:52:16 -0500120 struct fib_table_t_ *fibs;
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100121
Neale Rannsa3af3372017-03-28 03:49:52 -0700122 /* Pool of V6 FIBs. */
123 ip6_fib_t *v6_fibs;
124
Neale Ranns32e1c012016-11-22 17:07:28 +0000125 /** Vector of MFIBs. */
126 struct mfib_table_t_ *mfibs;
127
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100128 /* Network byte orders subnet mask for each prefix length */
Ed Warnickecb9cada2015-12-08 15:45:58 -0700129 ip6_address_t fib_masks[129];
130
131 /* Table index indexed by software interface. */
Dave Barachd7cb1b52016-12-09 09:52:16 -0500132 u32 *fib_index_by_sw_if_index;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700133
Neale Ranns32e1c012016-11-22 17:07:28 +0000134 /** Table index indexed by software interface. */
135 u32 *mfib_index_by_sw_if_index;
136
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100137 /* IP6 enabled count by software interface */
Dave Barachd7cb1b52016-12-09 09:52:16 -0500138 u8 *ip_enabled_by_sw_if_index;
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100139
Ed Warnickecb9cada2015-12-08 15:45:58 -0700140 /* Hash table mapping table id to fib index.
141 ID space is not necessarily dense; index space is dense. */
Dave Barachd7cb1b52016-12-09 09:52:16 -0500142 uword *fib_index_by_table_id;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700143
Neale Ranns32e1c012016-11-22 17:07:28 +0000144 /** Hash table mapping table id to multicast fib index.
145 ID space is not necessarily dense; index space is dense. */
146 uword *mfib_index_by_table_id;
147
Ed Warnickecb9cada2015-12-08 15:45:58 -0700148 /* Hash table mapping interface rewrite adjacency index by sw if index. */
Dave Barachd7cb1b52016-12-09 09:52:16 -0500149 uword *interface_route_adj_index_by_sw_if_index;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700150
151 /* Functions to call when interface address changes. */
Dave Barachd7cb1b52016-12-09 09:52:16 -0500152 ip6_add_del_interface_address_callback_t
153 * add_del_interface_address_callbacks;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700154
Neale Ranns15002542017-09-10 04:39:11 -0700155 /** Functions to call when interface to table biding changes. */
156 ip6_table_bind_callback_t *table_bind_callbacks;
157
Ed Warnickecb9cada2015-12-08 15:45:58 -0700158 /* Seed for Jenkins hash used to compute ip6 flow hash. */
159 u32 flow_hash_seed;
160
Dave Barachd7cb1b52016-12-09 09:52:16 -0500161 struct
162 {
Ed Warnickecb9cada2015-12-08 15:45:58 -0700163 /* TTL to use for host generated packets. */
164 u8 ttl;
165
166 u8 pad[3];
167 } host_config;
Ole Troan944f5482016-05-24 11:56:58 +0200168
169 /* HBH processing enabled? */
170 u8 hbh_enabled;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700171} ip6_main_t;
172
Dave Barach49433ad2018-08-08 17:59:03 -0400173#define ND_THROTTLE_BITS 512
174
Ed Warnickecb9cada2015-12-08 15:45:58 -0700175/* Global ip6 main structure. */
176extern ip6_main_t ip6_main;
177
178/* Global ip6 input node. Errors get attached to ip6 input node. */
179extern vlib_node_registration_t ip6_input_node;
180extern vlib_node_registration_t ip6_rewrite_node;
Neale Ranns32e1c012016-11-22 17:07:28 +0000181extern vlib_node_registration_t ip6_rewrite_mcast_node;
Pierre Pfister0febaf12016-06-08 12:23:21 +0100182extern vlib_node_registration_t ip6_rewrite_local_node;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700183extern vlib_node_registration_t ip6_discover_neighbor_node;
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100184extern vlib_node_registration_t ip6_glean_node;
185extern vlib_node_registration_t ip6_midchain_node;
Jawahar Santosh Gundapaneni62ad2aa2020-03-19 16:42:28 -0400186extern vlib_node_registration_t ip6_punt_node;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700187
Neale Rannsd91c1db2017-07-31 02:30:50 -0700188extern void ip6_forward_next_trace (vlib_main_t * vm,
189 vlib_node_runtime_t * node,
190 vlib_frame_t * frame,
191 vlib_rx_or_tx_t which_adj_index);
192
Ed Warnickecb9cada2015-12-08 15:45:58 -0700193always_inline uword
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100194ip6_destination_matches_route (const ip6_main_t * im,
195 const ip6_address_t * key,
Dave Barachd7cb1b52016-12-09 09:52:16 -0500196 const ip6_address_t * dest, uword dest_length)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700197{
198 int i;
199 for (i = 0; i < ARRAY_LEN (key->as_uword); i++)
200 {
Dave Barachd7cb1b52016-12-09 09:52:16 -0500201 if ((key->as_uword[i] ^ dest->as_uword[i]) & im->
202 fib_masks[dest_length].as_uword[i])
Ed Warnickecb9cada2015-12-08 15:45:58 -0700203 return 0;
204 }
205 return 1;
206}
207
208always_inline uword
209ip6_destination_matches_interface (ip6_main_t * im,
210 ip6_address_t * key,
211 ip_interface_address_t * ia)
212{
Dave Barachd7cb1b52016-12-09 09:52:16 -0500213 ip6_address_t *a = ip_interface_address_get_address (&im->lookup_main, ia);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700214 return ip6_destination_matches_route (im, key, a, ia->address_length);
215}
216
217/* As above but allows for unaligned destinations (e.g. works right from IP header of packet). */
218always_inline uword
219ip6_unaligned_destination_matches_route (ip6_main_t * im,
220 ip6_address_t * key,
221 ip6_address_t * dest,
222 uword dest_length)
223{
224 int i;
225 for (i = 0; i < ARRAY_LEN (key->as_uword); i++)
226 {
Dave Barachd7cb1b52016-12-09 09:52:16 -0500227 if ((clib_mem_unaligned (&key->as_uword[i], uword) ^ dest->as_uword[i])
228 & im->fib_masks[dest_length].as_uword[i])
Ed Warnickecb9cada2015-12-08 15:45:58 -0700229 return 0;
230 }
231 return 1;
232}
233
Ed Warnickecb9cada2015-12-08 15:45:58 -0700234/* Find interface address which matches destination. */
235always_inline ip6_address_t *
Dave Barachd7cb1b52016-12-09 09:52:16 -0500236ip6_interface_address_matching_destination (ip6_main_t * im,
Neale Rannscbe25aa2019-09-30 10:53:31 +0000237 const ip6_address_t * dst,
Dave Barachd7cb1b52016-12-09 09:52:16 -0500238 u32 sw_if_index,
239 ip_interface_address_t **
240 result_ia)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700241{
Dave Barachd7cb1b52016-12-09 09:52:16 -0500242 ip_lookup_main_t *lm = &im->lookup_main;
243 ip_interface_address_t *ia;
244 ip6_address_t *result = 0;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700245
Dave Barach75fc8542016-10-11 16:16:02 -0400246 foreach_ip_interface_address (lm, ia, sw_if_index,
Ed Warnickecb9cada2015-12-08 15:45:58 -0700247 1 /* honor unnumbered */,
248 ({
249 ip6_address_t * a = ip_interface_address_get_address (lm, ia);
250 if (ip6_destination_matches_route (im, dst, a, ia->address_length))
251 {
252 result = a;
253 break;
254 }
255 }));
256 if (result_ia)
257 *result_ia = result ? ia : 0;
258 return result;
259}
260
Dave Barachd7cb1b52016-12-09 09:52:16 -0500261clib_error_t *ip6_add_del_interface_address (vlib_main_t * vm,
262 u32 sw_if_index,
263 ip6_address_t * address,
264 u32 address_length, u32 is_del);
265void ip6_sw_interface_enable_disable (u32 sw_if_index, u32 is_enable);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700266
Neale Ranns6cfc39c2017-02-14 01:44:25 -0800267/**
Paul Vinciguerrab5a575b2019-11-01 13:00:58 -0400268 * @brief get first IPv6 interface address
Neale Ranns6cfc39c2017-02-14 01:44:25 -0800269 */
270ip6_address_t *ip6_interface_first_address (ip6_main_t * im, u32 sw_if_index);
271
Ed Warnickecb9cada2015-12-08 15:45:58 -0700272int ip6_address_compare (ip6_address_t * a1, ip6_address_t * a2);
273
Ed Warnickecb9cada2015-12-08 15:45:58 -0700274uword
Ed Warnickecb9cada2015-12-08 15:45:58 -0700275ip6_udp_register_listener (vlib_main_t * vm,
Dave Barachd7cb1b52016-12-09 09:52:16 -0500276 u16 dst_port, u32 next_node_index);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700277
Dave Barachd7cb1b52016-12-09 09:52:16 -0500278u16 ip6_tcp_udp_icmp_compute_checksum (vlib_main_t * vm, vlib_buffer_t * p0,
279 ip6_header_t * ip0,
280 int *bogus_lengthp);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700281
282void ip6_register_protocol (u32 protocol, u32 node_index);
Neale Rannsb538dd82019-05-21 06:54:54 -0700283void ip6_unregister_protocol (u32 protocol);
Dave Barach90800962019-05-24 13:03:01 -0400284void ip6_local_hop_by_hop_register_protocol (u32 protocol, u32 node_index);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700285
286serialize_function_t serialize_vnet_ip6_main, unserialize_vnet_ip6_main;
287
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);
Neale Ranns92207752019-06-03 13:21:40 +0000293void ip6_punt_redirect_add_paths (u32 rx_sw_if_index,
Nathan Skrzypczak2a1783f2021-08-10 15:05:29 +0200294 const fib_route_path_t *paths);
Neale Rannsd91c1db2017-07-31 02:30:50 -0700295void ip6_punt_redirect_del (u32 rx_sw_if_index);
296
Dave Barach75fc8542016-10-11 16:16:02 -0400297int vnet_set_ip6_classify_intfc (vlib_main_t * vm, u32 sw_if_index,
Dave Barachd7cb1b52016-12-09 09:52:16 -0500298 u32 table_index);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700299extern vlib_node_registration_t ip6_lookup_node;
300
Shwetha Bhandari78372a92017-01-18 12:43:54 +0530301u8 *format_ip6_hop_by_hop_ext_hdr (u8 * s, va_list * args);
Ole Troan944f5482016-05-24 11:56:58 +0200302/*
303 * Hop-by-Hop handling
304 */
Dave Barachd7cb1b52016-12-09 09:52:16 -0500305typedef struct
306{
Ole Troan944f5482016-05-24 11:56:58 +0200307 /* Array of function pointers to HBH option handling routines */
Dave Barachd7cb1b52016-12-09 09:52:16 -0500308 int (*options[256]) (vlib_buffer_t * b, ip6_header_t * ip,
309 ip6_hop_by_hop_option_t * opt);
310 u8 *(*trace[256]) (u8 * s, ip6_hop_by_hop_option_t * opt);
Shwethaa91cbe62016-08-08 15:51:04 +0100311 uword next_override;
Ole Troan944f5482016-05-24 11:56:58 +0200312} ip6_hop_by_hop_main_t;
313
314extern ip6_hop_by_hop_main_t ip6_hop_by_hop_main;
315
316int ip6_hbh_register_option (u8 option,
Dave Barachd7cb1b52016-12-09 09:52:16 -0500317 int options (vlib_buffer_t * b,
318 ip6_header_t * ip,
319 ip6_hop_by_hop_option_t * opt),
320 u8 * trace (u8 * s,
321 ip6_hop_by_hop_option_t * opt));
Ole Troan944f5482016-05-24 11:56:58 +0200322int ip6_hbh_unregister_option (u8 option);
Shwethaa91cbe62016-08-08 15:51:04 +0100323void ip6_hbh_set_next_override (uword next);
Ole Troan944f5482016-05-24 11:56:58 +0200324
Nick Zavaritsky27518c22020-02-27 15:54:58 +0000325always_inline u32
326vlib_buffer_get_ip6_fib_index (vlib_buffer_t * b)
327{
328 u32 fib_index, sw_if_index;
329 sw_if_index = vnet_buffer (b)->sw_if_index[VLIB_RX];
330 fib_index = vnet_buffer (b)->sw_if_index[VLIB_TX];
331 return (fib_index == (u32) ~ 0) ?
332 vec_elt (ip6_main.fib_index_by_sw_if_index, sw_if_index) : fib_index;
333}
Ed Warnickecb9cada2015-12-08 15:45:58 -0700334#endif /* included_ip_ip6_h */
Dave Barachd7cb1b52016-12-09 09:52:16 -0500335
336/*
337 * fd.io coding-style-patch-verification: ON
338 *
339 * Local Variables:
340 * eval: (c-set-style "gnu")
341 * End:
342 */