Reorganize source tree to use single autotools instance
[vpp.git] / src / vnet / fib / fib_entry_src_adj.c
1 /*
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:
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 #include "fib_entry.h"
17 #include "fib_entry_src.h"
18 #include "fib_path_list.h"
19 #include "fib_table.h"
20 #include "fib_entry_cover.h"
21 #include "fib_attached_export.h"
22
23 /**
24  * Source initialisation Function 
25  */
26 static void
27 fib_entry_src_adj_init (fib_entry_src_t *src)
28 {
29     src->adj.fesa_cover = FIB_NODE_INDEX_INVALID;
30     src->adj.fesa_sibling = FIB_NODE_INDEX_INVALID;
31 }
32
33 static void
34 fib_entry_src_adj_path_swap (fib_entry_src_t *src,
35                              const fib_entry_t *entry,
36                              fib_path_list_flags_t pl_flags,
37                              const fib_route_path_t *paths)
38 {
39     src->fes_pl = fib_path_list_create(pl_flags, paths);
40 }
41
42 static void
43 fib_entry_src_adj_remove (fib_entry_src_t *src)
44 {
45     src->fes_pl = FIB_NODE_INDEX_INVALID;
46 }
47
48
49 /*
50  * Source activate. 
51  * Called when the source is teh new longer best source on the entry
52  */
53 static int
54 fib_entry_src_adj_activate (fib_entry_src_t *src,
55                             const fib_entry_t *fib_entry)
56 {
57     fib_entry_t *cover;
58
59     /*
60      * find the covering prefix. become a dependent thereof.
61      * there should always be a cover, though it may be the default route.
62      */
63     src->adj.fesa_cover = fib_table_get_less_specific(fib_entry->fe_fib_index,
64                                                       &fib_entry->fe_prefix);
65
66     ASSERT(FIB_NODE_INDEX_INVALID != src->adj.fesa_cover);
67     ASSERT(fib_entry_get_index(fib_entry) != src->adj.fesa_cover);
68
69     cover = fib_entry_get(src->adj.fesa_cover);
70
71     ASSERT(cover != fib_entry);
72
73     src->adj.fesa_sibling =
74         fib_entry_cover_track(cover,
75                               fib_entry_get_index(fib_entry));
76
77     /*
78      * if the ocver is attached then this adj source entry can install, 
79      * via the adj. otherwise install a drop.
80      * This prevents ARP/ND entries that on interface X that do not belong
81      * on X's subnet from being added to the FIB. To do so would allow
82      * nefarious gratuitous ARP requests from attracting traffic to the sender.
83      *
84      * and yes, I really do mean attached and not connected.
85      * this abomination;
86      *   ip route add 10.0.0.0/24 Eth0
87      * is attached. and we want adj-fibs to install on Eth0.
88      */
89     return (FIB_ENTRY_FLAG_ATTACHED & fib_entry_get_flags_i(cover));
90 }
91
92 /*
93  * Source Deactivate. 
94  * Called when the source is no longer best source on the entry
95  */
96 static void
97 fib_entry_src_adj_deactivate (fib_entry_src_t *src,
98                               const fib_entry_t *fib_entry)
99 {
100     fib_entry_t *cover;
101
102     /*
103      * remove the depednecy on the covering entry
104      */
105     ASSERT(FIB_NODE_INDEX_INVALID != src->adj.fesa_cover);
106     cover = fib_entry_get(src->adj.fesa_cover);
107
108     fib_entry_cover_untrack(cover, src->adj.fesa_sibling);
109
110     /*
111      * tell the cover this entry no longer needs exporting
112      */
113     fib_attached_export_covered_removed(cover, fib_entry_get_index(fib_entry));
114
115     src->adj.fesa_cover = FIB_NODE_INDEX_INVALID;
116 }
117
118 static u8*
119 fib_entry_src_adj_format (fib_entry_src_t *src,
120                          u8* s)
121 {
122     return (format(s, "cover:%d", src->adj.fesa_cover));
123 }
124
125 static void
126 fib_entry_src_adj_installed (fib_entry_src_t *src,
127                              const fib_entry_t *fib_entry)
128 {
129     /*
130      * The adj source now rules! poke our cover to get exported
131      */
132     fib_entry_t *cover;
133
134     ASSERT(FIB_NODE_INDEX_INVALID != src->adj.fesa_cover);
135     cover = fib_entry_get(src->adj.fesa_cover);
136
137     fib_attached_export_covered_added(cover,
138                                       fib_entry_get_index(fib_entry));
139 }
140
141 static fib_entry_src_cover_res_t
142 fib_entry_src_adj_cover_change (fib_entry_src_t *src,
143                                 const fib_entry_t *fib_entry)
144 {
145     fib_entry_src_cover_res_t res = {
146         .install = !0,
147         .bw_reason = FIB_NODE_BW_REASON_FLAG_NONE,
148     };
149
150     fib_entry_src_adj_deactivate(src, fib_entry);
151
152     res.install = fib_entry_src_adj_activate(src, fib_entry);
153
154     if (res.install) {
155         /*
156          * ADJ fib can install
157          */
158         res.bw_reason = FIB_NODE_BW_REASON_FLAG_EVALUATE;
159     }
160
161     return (res);
162 }
163
164 /*
165  * fib_entry_src_adj_cover_update
166  */
167 static fib_entry_src_cover_res_t
168 fib_entry_src_adj_cover_update (fib_entry_src_t *src,
169                                 const fib_entry_t *fib_entry)
170 {
171     /*
172      * the cover has updated, i.e. its forwarding or flags
173      * have changed. do'nt decativate/activate here, since this
174      * prefix is updated during the covers walk.
175      */
176     fib_entry_src_cover_res_t res = {
177         .install = !0,
178         .bw_reason = FIB_NODE_BW_REASON_FLAG_NONE,
179     };
180     fib_entry_t *cover;
181
182     ASSERT(FIB_NODE_INDEX_INVALID != src->adj.fesa_cover);
183
184     cover = fib_entry_get(src->adj.fesa_cover);
185
186     res.install = (FIB_ENTRY_FLAG_ATTACHED & fib_entry_get_flags_i(cover));
187
188     return (res);
189 }
190
191 const static fib_entry_src_vft_t adj_src_vft = {
192     .fesv_init = fib_entry_src_adj_init,
193     .fesv_path_swap = fib_entry_src_adj_path_swap,
194     .fesv_remove = fib_entry_src_adj_remove,
195     .fesv_activate = fib_entry_src_adj_activate,
196     .fesv_deactivate = fib_entry_src_adj_deactivate,
197     .fesv_format = fib_entry_src_adj_format,
198     .fesv_installed = fib_entry_src_adj_installed,
199     .fesv_cover_change = fib_entry_src_adj_cover_change,
200     .fesv_cover_update = fib_entry_src_adj_cover_update,
201 };
202
203 void
204 fib_entry_src_adj_register (void)
205 {
206     fib_entry_src_register(FIB_SOURCE_ADJ, &adj_src_vft);
207 }