]> git.proxmox.com Git - mirror_frr.git/blame - eigrpd/eigrp_filter.c
eigrpd: Only install up to eigrp->max_paths into rib.
[mirror_frr.git] / eigrpd / eigrp_filter.c
CommitLineData
7f57883e
DS
1/*
2 * EIGRP Filter Functions.
3 * Copyright (C) 2013-2015
4 * Authors:
5 * Donnie Savage
6 * Jan Janovic
7 * Matej Perina
8 * Peter Orsag
9 * Peter Paluch
10 * Frantisek Gazo
11 * Tomas Hvorkovy
12 * Martin Kontsek
13 * Lukas Koribsky
14 *
15 *
16 * This file is part of GNU Zebra.
17 *
18 * GNU Zebra is free software; you can redistribute it and/or modify it
19 * under the terms of the GNU General Public License as published by the
20 * Free Software Foundation; either version 2, or (at your option) any
21 * later version.
22 *
23 * GNU Zebra is distributed in the hope that it will be useful, but
24 * WITHOUT ANY WARRANTY; without even the implied warranty of
25 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
26 * General Public License for more details.
27 *
28 * You should have received a copy of the GNU General Public License
29 * along with GNU Zebra; see the file COPYING. If not, write to the Free
30 * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
31 * 02111-1307, USA.
32 */
33
34#include <zebra.h>
35
36#include "if.h"
37#include "command.h"
38#include "prefix.h"
39#include "table.h"
40#include "thread.h"
41#include "memory.h"
42#include "log.h"
43#include "stream.h"
44#include "filter.h"
45#include "sockunion.h"
46#include "sockopt.h"
47#include "routemap.h"
48#include "if_rmap.h"
49#include "plist.h"
50#include "distribute.h"
51#include "md5.h"
52#include "keychain.h"
53#include "privs.h"
54#include "vrf.h"
55
56#include "eigrpd/eigrp_structs.h"
57#include "eigrpd/eigrpd.h"
58#include "eigrpd/eigrp_const.h"
59#include "eigrpd/eigrp_filter.h"
60#include "eigrpd/eigrp_packet.h"
61#include "eigrpd/eigrp_memory.h"
62
63/*
64 * Distribute-list update functions.
65 */
66void
67eigrp_distribute_update (struct distribute *dist)
68{
69 struct interface *ifp;
70 struct eigrp_interface *ei = NULL;
71 struct access_list *alist;
72 struct prefix_list *plist;
73 //struct route_map *routemap;
74 struct eigrp *e;
75
76 /* if no interface address is present, set list to eigrp process struct */
77 e = eigrp_lookup();
78
79 /* Check if distribute-list was set for process or interface */
80 if (! dist->ifname)
81 {
82 /* access list IN for whole process */
83 if (dist->list[DISTRIBUTE_V4_IN])
84 {
85 alist = access_list_lookup (AFI_IP, dist->list[DISTRIBUTE_V4_IN]);
86 zlog_info("<DEBUG DISTRIBUTE ACL IN FOUND: %s",alist->name);
87 if (alist)
88 e->list[EIGRP_FILTER_IN] = alist;
89 else
90 e->list[EIGRP_FILTER_IN] = NULL;
91 }
92 else
93 {
94 e->list[EIGRP_FILTER_IN] = NULL;
95 }
96
97 /* access list OUT for whole process */
98 if (dist->list[DISTRIBUTE_V4_OUT])
99 {
100 zlog_info("<DEBUG DISTRIBUTE ACL OUT FOUND: %s",dist->list[DISTRIBUTE_V4_OUT]);
101 alist = access_list_lookup (AFI_IP, dist->list[DISTRIBUTE_V4_OUT]);
102 if (alist)
103 e->list[EIGRP_FILTER_OUT] = alist;
104 else
105 e->list[EIGRP_FILTER_OUT] = NULL;
106 }
107 else
108 {
109 e->list[EIGRP_FILTER_OUT] = NULL;
110 }
111
112 /* PREFIX_LIST IN for process */
113 if (dist->prefix[DISTRIBUTE_V4_IN])
114 {
115 zlog_info("<DEBUG DISTRIBUTE PREFIX IN FOUND: %s",dist->prefix[DISTRIBUTE_V4_IN]);
116 plist = prefix_list_lookup (AFI_IP, dist->prefix[DISTRIBUTE_V4_IN]);
117 if (plist)
118 {
119 e->prefix[EIGRP_FILTER_IN] = plist;
120 }
121 else
122 e->prefix[EIGRP_FILTER_IN] = NULL;
123 } else
124 e->prefix[EIGRP_FILTER_IN] = NULL;
125
126 /* PREFIX_LIST OUT for process */
127 if (dist->prefix[DISTRIBUTE_V4_OUT])
128 {
129 zlog_info("<DEBUG DISTRIBUTE PREFIX OUT FOUND: %s",dist->prefix[DISTRIBUTE_V4_OUT]);
130 plist = prefix_list_lookup (AFI_IP, dist->prefix[DISTRIBUTE_V4_OUT]);
131 if (plist)
132 {
133 e->prefix[EIGRP_FILTER_OUT] = plist;
134
135 }
136 else
137 e->prefix[EIGRP_FILTER_OUT] = NULL;
138 }
139 else
140 e->prefix[EIGRP_FILTER_OUT] = NULL;
141
142 //This is commented out, because the distribute.[ch] code
143 //changes looked poorly written from first glance
144 //commit was 133bdf2d
145 //TODO: DBS
146#if 0
147 /* route-map IN for whole process */
148 if (dist->route[DISTRIBUTE_V4_IN])
149 {
150 routemap = route_map_lookup_by_name (dist->route[DISTRIBUTE_V4_IN]);
151 if (routemap)
152 e->routemap[EIGRP_FILTER_IN] = routemap;
153 else
154 e->routemap[EIGRP_FILTER_IN] = NULL;
155 }
156 else
157 {
158 e->routemap[EIGRP_FILTER_IN] = NULL;
159 }
160
161 /* route-map OUT for whole process */
162 if (dist->route[DISTRIBUTE_V4_OUT])
163 {
164 routemap = route_map_lookup_by_name (dist->route[DISTRIBUTE_V4_OUT]);
165 if (routemap)
166 e->routemap[EIGRP_FILTER_OUT] = routemap;
167 else
168 e->routemap[EIGRP_FILTER_OUT] = NULL;
169 }
170 else
171 {
172 e->routemap[EIGRP_FILTER_OUT] = NULL;
173 }
174#endif
175 //TODO: check Graceful restart after 10sec
176
177 /* check if there is already GR scheduled */
178 if(e->t_distribute != NULL)
179 {
180 /* if is, cancel schedule */
181 thread_cancel(e->t_distribute);
182 }
183 /* schedule Graceful restart for whole process in 10sec */
184 e->t_distribute = thread_add_timer(master, eigrp_distribute_timer_process, e,(10));
185
186 return;
187 }
188
ca975a87 189 ifp = if_lookup_by_name (dist->ifname, VRF_DEFAULT);
7f57883e
DS
190 if (ifp == NULL)
191 return;
192
193 zlog_info("<DEBUG ACL 2");
194
195 /*struct eigrp_if_info * info = ifp->info;
196 ei = info->eigrp_interface;*/
197 struct listnode *node, *nnode;
198 struct eigrp_interface *ei2;
199 /* Find proper interface */
200 for (ALL_LIST_ELEMENTS (e->eiflist, node, nnode, ei2))
201 {
202 if(strcmp(ei2->ifp->name,ifp->name) == 0){
203 ei = ei2;
204 break;
205 }
206 }
207
208 if(ei == NULL)
209 {
210 zlog_info("Not Found eigrp interface %s",ifp->name);
211 }
212
213 /* Access-list for interface in */
214 if (dist->list[DISTRIBUTE_V4_IN])
215 {
216 zlog_info("<DEBUG ACL in");
217 alist = access_list_lookup (AFI_IP, dist->list[DISTRIBUTE_V4_IN]);
218 if (alist){
219 ei->list[EIGRP_FILTER_IN] = alist;
220 }
221 else
222 ei->list[EIGRP_FILTER_IN] = NULL;
223 }
224 else
225 {
226 ei->list[EIGRP_FILTER_IN] = NULL;
227 }
228
229 /* Access-list for interface in */
230 if (dist->list[DISTRIBUTE_V4_OUT])
231 {
232 alist = access_list_lookup (AFI_IP, dist->list[DISTRIBUTE_V4_OUT]);
233 if (alist)
234 ei->list[EIGRP_FILTER_OUT] = alist;
235 else
236 ei->list[EIGRP_FILTER_OUT] = NULL;
237
238 }
239 else
240 {
241 ei->list[EIGRP_FILTER_OUT] = NULL;
242 zlog_info("<DEBUG ACL out else");
243 }
244
245 /* Prefix-list for interface in */
246 if (dist->prefix[DISTRIBUTE_V4_IN])
247 {
248 plist = prefix_list_lookup (AFI_IP, dist->prefix[DISTRIBUTE_V4_IN]);
249 if (plist)
250 ei->prefix[EIGRP_FILTER_IN] = plist;
251 else
252 ei->prefix[EIGRP_FILTER_IN] = NULL;
253 }
254 else
255 ei->prefix[EIGRP_FILTER_IN] = NULL;
256
257 /* Prefix-list for interface out */
258 if (dist->prefix[DISTRIBUTE_V4_OUT])
259 {
260 plist = prefix_list_lookup (AFI_IP, dist->prefix[DISTRIBUTE_V4_OUT]);
261 if (plist)
262 ei->prefix[EIGRP_FILTER_OUT] = plist;
263 else
264 ei->prefix[EIGRP_FILTER_OUT] = NULL;
265 }
266 else
267 ei->prefix[EIGRP_FILTER_OUT] = NULL;
268
269#if 0
270 /* route-map IN for whole process */
271 if (dist->route[DISTRIBUTE_V4_IN])
272 {
273 zlog_info("<DEBUG ACL ALL in");
274 routemap = route_map_lookup_by_name (dist->route[DISTRIBUTE_V4_IN]);
275 if (routemap)
276 ei->routemap[EIGRP_FILTER_IN] = routemap;
277 else
278 ei->routemap[EIGRP_FILTER_IN] = NULL;
279 }
280 else
281 {
282 ei->routemap[EIGRP_FILTER_IN] = NULL;
283 }
284
285 /* route-map OUT for whole process */
286 if (dist->route[DISTRIBUTE_V4_OUT])
287 {
288 routemap = route_map_lookup_by_name (dist->route[DISTRIBUTE_V4_OUT]);
289 if (routemap)
290 ei->routemap[EIGRP_FILTER_OUT] = routemap;
291 else
292 ei->routemap[EIGRP_FILTER_OUT] = NULL;
293 }
294 else
295 {
296 ei->routemap[EIGRP_FILTER_OUT] = NULL;
297 }
298#endif
299 //TODO: check Graceful restart after 10sec
300
301 /* check if there is already GR scheduled */
302 if(ei->t_distribute != NULL)
303 {
304 /* if is, cancel schedule */
305 thread_cancel(ei->t_distribute);
306 }
307 /* schedule Graceful restart for interface in 10sec */
308 e->t_distribute = thread_add_timer(master, eigrp_distribute_timer_interface, ei,(10));
309
310}
311
312/*
313 * Function called by prefix-list and access-list update
314 */
315void
316eigrp_distribute_update_interface (struct interface *ifp)
317{
318 struct distribute *dist;
319
320 dist = distribute_lookup (ifp->name);
321 if (dist)
322 eigrp_distribute_update (dist);
323}
324
325/* Update all interface's distribute list.
326 * Function used in hook for prefix-list
327 */
328void
329eigrp_distribute_update_all (struct prefix_list *notused)
330{
331 struct interface *ifp;
332 struct listnode *node, *nnode;
333
334 for (ALL_LIST_ELEMENTS (vrf_iflist(VRF_DEFAULT), node, nnode, ifp))
335 eigrp_distribute_update_interface (ifp);
336}
337
338/*
339 * Function used in hook for acces-list
340 */
341void
342eigrp_distribute_update_all_wrapper(struct access_list *notused)
343{
344 eigrp_distribute_update_all(NULL);
345}
346
347/*
348 * @fn eigrp_distribute_timer_process
349 *
350 * @param[in] thread current execution thread timer is associated with
351 *
352 * @return int always returns 0
353 *
354 * @par
355 * Called when 10sec waiting time expire and
356 * executes Graceful restart for whole process
357 */
358int
359eigrp_distribute_timer_process (struct thread *thread)
360{
361 struct eigrp *eigrp;
362
363 eigrp = THREAD_ARG(thread);
364 eigrp->t_distribute = NULL;
365
366 /* execute GR for whole process */
367 eigrp_update_send_process_GR(eigrp, EIGRP_GR_FILTER, NULL);
368
369 return 0;
370}
371
372/*
373 * @fn eigrp_distribute_timer_interface
374 *
375 * @param[in] thread current execution thread timer is associated with
376 *
377 * @return int always returns 0
378 *
379 * @par
380 * Called when 10sec waiting time expire and
381 * executes Graceful restart for interface
382 */
383int
384eigrp_distribute_timer_interface (struct thread *thread)
385{
386 struct eigrp_interface *ei;
387
388 ei = THREAD_ARG(thread);
389 ei->t_distribute = NULL;
390
391 /* execute GR for interface */
392 eigrp_update_send_interface_GR(ei, EIGRP_GR_FILTER, NULL);
393
394 return 0;
395}