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/fib/fib_entry_cover.h>
17 #include <vnet/fib/fib_entry_src.h>
18 #include <vnet/fib/fib_node_list.h>
21 fib_entry_cover_track (fib_entry_t* cover,
22 fib_node_index_t covered)
24 FIB_ENTRY_DBG(cover, "cover-track %d", covered);
26 ASSERT(fib_entry_get_index(cover) != covered);
28 if (FIB_NODE_INDEX_INVALID == cover->fe_covered)
30 cover->fe_covered = fib_node_list_create();
33 return (fib_node_list_push_front(cover->fe_covered,
34 0, FIB_NODE_TYPE_ENTRY,
39 fib_entry_cover_untrack (fib_entry_t* cover,
42 FIB_ENTRY_DBG(cover, "cover-untrack @ %d", tracked_index);
44 if (FIB_NODE_INDEX_INVALID == cover->fe_covered)
47 fib_node_list_remove(cover->fe_covered, tracked_index);
49 if (0 == fib_node_list_get_size(cover->fe_covered))
51 fib_node_list_destroy(&cover->fe_covered);
56 * Internal struct to hold user supplied paraneters for the cover walk
58 typedef struct fib_enty_cover_walk_ctx_t_ {
60 fib_entry_covered_walk_t walk;
62 } fib_enty_cover_walk_ctx_t;
65 fib_entry_cover_walk_node_ptr (fib_node_ptr_t *depend,
68 fib_enty_cover_walk_ctx_t *ctx = args;
70 ctx->walk(ctx->cover, depend->fnp_index, ctx->ctx);
77 fib_entry_cover_walk (fib_entry_t *cover,
78 fib_entry_covered_walk_t walk,
81 if (FIB_NODE_INDEX_INVALID != cover->fe_covered)
83 fib_enty_cover_walk_ctx_t ctx = {
89 fib_node_list_walk(cover->fe_covered,
90 fib_entry_cover_walk_node_ptr,
96 fib_entry_cover_get_size (fib_entry_t *cover)
98 if (FIB_NODE_INDEX_INVALID != cover->fe_covered)
99 return (fib_node_list_get_size(cover->fe_covered));
103 typedef struct fib_entry_cover_list_format_ctx_t_ {
105 } fib_entry_cover_list_format_ctx_t;
108 fib_entry_covered_list_format_one (fib_entry_t *cover,
109 fib_node_index_t covered,
112 fib_entry_cover_list_format_ctx_t * ctx = args;
114 ctx->s = format(ctx->s, "%d, ", covered);
121 fib_entry_cover_list_format (fib_entry_t *fib_entry,
124 fib_entry_cover_list_format_ctx_t ctx = {
128 fib_entry_cover_walk(fib_entry,
129 fib_entry_covered_list_format_one,
136 fib_entry_cover_change_one (fib_entry_t *cover,
137 fib_node_index_t covered,
140 fib_node_index_t new_cover;
143 * The 3 entries involved here are:
144 * cover - the least specific. It will cover both the others
145 * new_cover - the enty just inserted below the cover
146 * covered - the entry that was tracking the cover.
148 * The checks below are to determine if new_cover is a cover for covered.
150 new_cover = pointer_to_uword(args);
152 if (FIB_NODE_INDEX_INVALID == new_cover)
155 * nothing has been inserted, which implies the cover was removed.
156 * 'cover' is thus the new cover.
158 fib_entry_cover_changed(covered);
160 else if (new_cover != covered)
162 fib_prefix_t pfx_covered, pfx_new_cover;
164 fib_entry_get_prefix(covered, &pfx_covered);
165 fib_entry_get_prefix(new_cover, &pfx_new_cover);
167 if (fib_prefix_is_cover(&pfx_new_cover, &pfx_covered))
169 fib_entry_cover_changed(covered);
177 fib_entry_cover_change_notify (fib_node_index_t cover_index,
178 fib_node_index_t covered)
182 cover = fib_entry_get(cover_index);
184 fib_entry_cover_walk(cover,
185 fib_entry_cover_change_one,
186 uword_to_pointer(covered, void*));
190 fib_entry_cover_update_one (fib_entry_t *cover,
191 fib_node_index_t covered,
194 fib_entry_cover_updated(covered);
201 fib_entry_cover_update_notify (fib_entry_t *fib_entry)
203 fib_entry_cover_walk(fib_entry,
204 fib_entry_cover_update_one,