diff options
Diffstat (limited to 'src/vnet/ip/ip4_mtrie.h')
-rw-r--r-- | src/vnet/ip/ip4_mtrie.h | 188 |
1 files changed, 188 insertions, 0 deletions
diff --git a/src/vnet/ip/ip4_mtrie.h b/src/vnet/ip/ip4_mtrie.h new file mode 100644 index 00000000000..c0afc2cf842 --- /dev/null +++ b/src/vnet/ip/ip4_mtrie.h @@ -0,0 +1,188 @@ +/* + * Copyright (c) 2015 Cisco and/or its affiliates. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * ip/ip4_fib.h: ip4 mtrie fib + * + * Copyright (c) 2012 Eliot Dresselhaus + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifndef included_ip_ip4_fib_h +#define included_ip_ip4_fib_h + +#include <vppinfra/cache.h> +#include <vppinfra/vector.h> +#include <vnet/ip/lookup.h> +#include <vnet/ip/ip4_packet.h> /* for ip4_address_t */ + +/* ip4 fib leafs: 4 ply 8-8-8-8 mtrie. + 1 + 2*adj_index for terminal leaves. + 0 + 2*next_ply_index for non-terminals. + 1 => empty (adjacency index of zero is special miss adjacency). */ +typedef u32 ip4_fib_mtrie_leaf_t; + +#define IP4_FIB_MTRIE_LEAF_EMPTY (1 + 2*0) +#define IP4_FIB_MTRIE_LEAF_ROOT (0 + 2*0) + +always_inline u32 +ip4_fib_mtrie_leaf_is_empty (ip4_fib_mtrie_leaf_t n) +{ + return n == IP4_FIB_MTRIE_LEAF_EMPTY; +} + +always_inline u32 +ip4_fib_mtrie_leaf_is_non_empty (ip4_fib_mtrie_leaf_t n) +{ + return n != IP4_FIB_MTRIE_LEAF_EMPTY; +} + +always_inline u32 +ip4_fib_mtrie_leaf_is_terminal (ip4_fib_mtrie_leaf_t n) +{ + return n & 1; +} + +always_inline u32 +ip4_fib_mtrie_leaf_get_adj_index (ip4_fib_mtrie_leaf_t n) +{ + ASSERT (ip4_fib_mtrie_leaf_is_terminal (n)); + return n >> 1; +} + +always_inline ip4_fib_mtrie_leaf_t +ip4_fib_mtrie_leaf_set_adj_index (u32 adj_index) +{ + ip4_fib_mtrie_leaf_t l; + l = 1 + 2 * adj_index; + ASSERT (ip4_fib_mtrie_leaf_get_adj_index (l) == adj_index); + return l; +} + +always_inline u32 +ip4_fib_mtrie_leaf_is_next_ply (ip4_fib_mtrie_leaf_t n) +{ + return (n & 1) == 0; +} + +always_inline u32 +ip4_fib_mtrie_leaf_get_next_ply_index (ip4_fib_mtrie_leaf_t n) +{ + ASSERT (ip4_fib_mtrie_leaf_is_next_ply (n)); + return n >> 1; +} + +always_inline ip4_fib_mtrie_leaf_t +ip4_fib_mtrie_leaf_set_next_ply_index (u32 i) +{ + ip4_fib_mtrie_leaf_t l; + l = 0 + 2 * i; + ASSERT (ip4_fib_mtrie_leaf_get_next_ply_index (l) == i); + return l; +} + +/* One ply of the 4 ply mtrie fib. */ +typedef struct +{ + union + { + ip4_fib_mtrie_leaf_t leaves[256]; + +#ifdef CLIB_HAVE_VEC128 + u32x4 leaves_as_u32x4[256 / 4]; +#endif + }; + + /* Prefix length for terminal leaves. */ + u8 dst_address_bits_of_leaves[256]; + + /* Number of non-empty leafs (whether terminal or not). */ + i32 n_non_empty_leafs; + + /* Pad to cache line boundary. */ + u8 pad[CLIB_CACHE_LINE_BYTES - 1 * sizeof (i32)]; +} +ip4_fib_mtrie_ply_t; + +STATIC_ASSERT (0 == sizeof (ip4_fib_mtrie_ply_t) % CLIB_CACHE_LINE_BYTES, + "IP4 Mtrie ply cache line"); + +typedef struct +{ + /* Pool of plies. Index zero is root ply. */ + ip4_fib_mtrie_ply_t *ply_pool; + + /* Special case leaf for default route 0.0.0.0/0. */ + ip4_fib_mtrie_leaf_t default_leaf; +} ip4_fib_mtrie_t; + +void ip4_fib_mtrie_init (ip4_fib_mtrie_t * m); + +struct ip4_fib_t; + +void ip4_fib_mtrie_add_del_route (struct ip4_fib_t *f, + ip4_address_t dst_address, + u32 dst_address_length, + u32 adj_index, u32 is_del); + +/* Returns adjacency index. */ +u32 ip4_mtrie_lookup_address (ip4_fib_mtrie_t * m, ip4_address_t dst); + +format_function_t format_ip4_fib_mtrie; + +/* Lookup step. Processes 1 byte of 4 byte ip4 address. */ +always_inline ip4_fib_mtrie_leaf_t +ip4_fib_mtrie_lookup_step (ip4_fib_mtrie_t * m, + ip4_fib_mtrie_leaf_t current_leaf, + const ip4_address_t * dst_address, + u32 dst_address_byte_index) +{ + ip4_fib_mtrie_leaf_t next_leaf; + ip4_fib_mtrie_ply_t *ply; + uword current_is_terminal = ip4_fib_mtrie_leaf_is_terminal (current_leaf); + + ply = m->ply_pool + (current_is_terminal ? 0 : (current_leaf >> 1)); + next_leaf = ply->leaves[dst_address->as_u8[dst_address_byte_index]]; + next_leaf = current_is_terminal ? current_leaf : next_leaf; + + return next_leaf; +} + +#endif /* included_ip_ip4_fib_h */ + +/* + * fd.io coding-style-patch-verification: ON + * + * Local Variables: + * eval: (c-set-style "gnu") + * End: + */ |