]> git.proxmox.com Git - mirror_frr.git/blob - eigrpd/eigrp_filter.c
Merge branch 'stable/3.0'
[mirror_frr.git] / eigrpd / eigrp_filter.c
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 along
29 * with this program; see the file COPYING; if not, write to the Free Software
30 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
31 */
32
33 #include <zebra.h>
34
35 #include "if.h"
36 #include "command.h"
37 #include "prefix.h"
38 #include "table.h"
39 #include "thread.h"
40 #include "memory.h"
41 #include "log.h"
42 #include "stream.h"
43 #include "filter.h"
44 #include "sockunion.h"
45 #include "sockopt.h"
46 #include "routemap.h"
47 #include "if_rmap.h"
48 #include "plist.h"
49 #include "distribute.h"
50 #include "md5.h"
51 #include "keychain.h"
52 #include "privs.h"
53 #include "vrf.h"
54
55 #include "eigrpd/eigrp_structs.h"
56 #include "eigrpd/eigrpd.h"
57 #include "eigrpd/eigrp_const.h"
58 #include "eigrpd/eigrp_filter.h"
59 #include "eigrpd/eigrp_packet.h"
60 #include "eigrpd/eigrp_memory.h"
61
62 /*
63 * Distribute-list update functions.
64 */
65 void
66 eigrp_distribute_update (struct distribute *dist)
67 {
68 struct interface *ifp;
69 struct eigrp_interface *ei = NULL;
70 struct access_list *alist;
71 struct prefix_list *plist;
72 //struct route_map *routemap;
73 struct eigrp *e;
74
75 /* if no interface address is present, set list to eigrp process struct */
76 e = eigrp_lookup();
77
78 /* Check if distribute-list was set for process or interface */
79 if (! dist->ifname)
80 {
81 /* access list IN for whole process */
82 if (dist->list[DISTRIBUTE_V4_IN])
83 {
84 alist = access_list_lookup (AFI_IP, dist->list[DISTRIBUTE_V4_IN]);
85 if (alist)
86 e->list[EIGRP_FILTER_IN] = alist;
87 else
88 e->list[EIGRP_FILTER_IN] = NULL;
89 }
90 else
91 {
92 e->list[EIGRP_FILTER_IN] = NULL;
93 }
94
95 /* access list OUT for whole process */
96 if (dist->list[DISTRIBUTE_V4_OUT])
97 {
98 alist = access_list_lookup (AFI_IP, dist->list[DISTRIBUTE_V4_OUT]);
99 if (alist)
100 e->list[EIGRP_FILTER_OUT] = alist;
101 else
102 e->list[EIGRP_FILTER_OUT] = NULL;
103 }
104 else
105 {
106 e->list[EIGRP_FILTER_OUT] = NULL;
107 }
108
109 /* PREFIX_LIST IN for process */
110 if (dist->prefix[DISTRIBUTE_V4_IN])
111 {
112 plist = prefix_list_lookup (AFI_IP, dist->prefix[DISTRIBUTE_V4_IN]);
113 if (plist)
114 {
115 e->prefix[EIGRP_FILTER_IN] = plist;
116 }
117 else
118 e->prefix[EIGRP_FILTER_IN] = NULL;
119 } else
120 e->prefix[EIGRP_FILTER_IN] = NULL;
121
122 /* PREFIX_LIST OUT for process */
123 if (dist->prefix[DISTRIBUTE_V4_OUT])
124 {
125 plist = prefix_list_lookup (AFI_IP, dist->prefix[DISTRIBUTE_V4_OUT]);
126 if (plist)
127 {
128 e->prefix[EIGRP_FILTER_OUT] = plist;
129
130 }
131 else
132 e->prefix[EIGRP_FILTER_OUT] = NULL;
133 }
134 else
135 e->prefix[EIGRP_FILTER_OUT] = NULL;
136
137 //This is commented out, because the distribute.[ch] code
138 //changes looked poorly written from first glance
139 //commit was 133bdf2d
140 //TODO: DBS
141 #if 0
142 /* route-map IN for whole process */
143 if (dist->route[DISTRIBUTE_V4_IN])
144 {
145 routemap = route_map_lookup_by_name (dist->route[DISTRIBUTE_V4_IN]);
146 if (routemap)
147 e->routemap[EIGRP_FILTER_IN] = routemap;
148 else
149 e->routemap[EIGRP_FILTER_IN] = NULL;
150 }
151 else
152 {
153 e->routemap[EIGRP_FILTER_IN] = NULL;
154 }
155
156 /* route-map OUT for whole process */
157 if (dist->route[DISTRIBUTE_V4_OUT])
158 {
159 routemap = route_map_lookup_by_name (dist->route[DISTRIBUTE_V4_OUT]);
160 if (routemap)
161 e->routemap[EIGRP_FILTER_OUT] = routemap;
162 else
163 e->routemap[EIGRP_FILTER_OUT] = NULL;
164 }
165 else
166 {
167 e->routemap[EIGRP_FILTER_OUT] = NULL;
168 }
169 #endif
170 //TODO: check Graceful restart after 10sec
171
172 /* check if there is already GR scheduled */
173 if(e->t_distribute != NULL)
174 {
175 /* if is, cancel schedule */
176 thread_cancel(e->t_distribute);
177 }
178 /* schedule Graceful restart for whole process in 10sec */
179 e->t_distribute = NULL;
180 thread_add_timer(master, eigrp_distribute_timer_process, e, (10),
181 &e->t_distribute);
182
183 return;
184 }
185
186 ifp = if_lookup_by_name (dist->ifname, VRF_DEFAULT);
187 if (ifp == NULL)
188 return;
189
190 /*struct eigrp_if_info * info = ifp->info;
191 ei = info->eigrp_interface;*/
192 struct listnode *node, *nnode;
193 struct eigrp_interface *ei2;
194 /* Find proper interface */
195 for (ALL_LIST_ELEMENTS (e->eiflist, node, nnode, ei2))
196 {
197 if(strcmp(ei2->ifp->name,ifp->name) == 0){
198 ei = ei2;
199 break;
200 }
201 }
202
203 /* Access-list for interface in */
204 if (dist->list[DISTRIBUTE_V4_IN])
205 {
206 alist = access_list_lookup (AFI_IP, dist->list[DISTRIBUTE_V4_IN]);
207 if (alist){
208 ei->list[EIGRP_FILTER_IN] = alist;
209 }
210 else
211 ei->list[EIGRP_FILTER_IN] = NULL;
212 }
213 else
214 {
215 ei->list[EIGRP_FILTER_IN] = NULL;
216 }
217
218 /* Access-list for interface in */
219 if (dist->list[DISTRIBUTE_V4_OUT])
220 {
221 alist = access_list_lookup (AFI_IP, dist->list[DISTRIBUTE_V4_OUT]);
222 if (alist)
223 ei->list[EIGRP_FILTER_OUT] = alist;
224 else
225 ei->list[EIGRP_FILTER_OUT] = NULL;
226
227 }
228 else
229 ei->list[EIGRP_FILTER_OUT] = NULL;
230
231 /* Prefix-list for interface in */
232 if (dist->prefix[DISTRIBUTE_V4_IN])
233 {
234 plist = prefix_list_lookup (AFI_IP, dist->prefix[DISTRIBUTE_V4_IN]);
235 if (plist)
236 ei->prefix[EIGRP_FILTER_IN] = plist;
237 else
238 ei->prefix[EIGRP_FILTER_IN] = NULL;
239 }
240 else
241 ei->prefix[EIGRP_FILTER_IN] = NULL;
242
243 /* Prefix-list for interface out */
244 if (dist->prefix[DISTRIBUTE_V4_OUT])
245 {
246 plist = prefix_list_lookup (AFI_IP, dist->prefix[DISTRIBUTE_V4_OUT]);
247 if (plist)
248 ei->prefix[EIGRP_FILTER_OUT] = plist;
249 else
250 ei->prefix[EIGRP_FILTER_OUT] = NULL;
251 }
252 else
253 ei->prefix[EIGRP_FILTER_OUT] = NULL;
254
255 #if 0
256 /* route-map IN for whole process */
257 if (dist->route[DISTRIBUTE_V4_IN])
258 {
259 zlog_info("<DEBUG ACL ALL in");
260 routemap = route_map_lookup_by_name (dist->route[DISTRIBUTE_V4_IN]);
261 if (routemap)
262 ei->routemap[EIGRP_FILTER_IN] = routemap;
263 else
264 ei->routemap[EIGRP_FILTER_IN] = NULL;
265 }
266 else
267 {
268 ei->routemap[EIGRP_FILTER_IN] = NULL;
269 }
270
271 /* route-map OUT for whole process */
272 if (dist->route[DISTRIBUTE_V4_OUT])
273 {
274 routemap = route_map_lookup_by_name (dist->route[DISTRIBUTE_V4_OUT]);
275 if (routemap)
276 ei->routemap[EIGRP_FILTER_OUT] = routemap;
277 else
278 ei->routemap[EIGRP_FILTER_OUT] = NULL;
279 }
280 else
281 {
282 ei->routemap[EIGRP_FILTER_OUT] = NULL;
283 }
284 #endif
285 //TODO: check Graceful restart after 10sec
286
287 /* check if there is already GR scheduled */
288 if(ei->t_distribute != NULL)
289 {
290 /* if is, cancel schedule */
291 thread_cancel(ei->t_distribute);
292 }
293 /* schedule Graceful restart for interface in 10sec */
294 e->t_distribute = NULL;
295 thread_add_timer(master, eigrp_distribute_timer_interface, ei, 10,
296 &e->t_distribute);
297 }
298
299 /*
300 * Function called by prefix-list and access-list update
301 */
302 void
303 eigrp_distribute_update_interface (struct interface *ifp)
304 {
305 struct distribute *dist;
306
307 dist = distribute_lookup (ifp->name);
308 if (dist)
309 eigrp_distribute_update (dist);
310 }
311
312 /* Update all interface's distribute list.
313 * Function used in hook for prefix-list
314 */
315 void
316 eigrp_distribute_update_all (struct prefix_list *notused)
317 {
318 struct interface *ifp;
319 struct listnode *node, *nnode;
320
321 for (ALL_LIST_ELEMENTS (vrf_iflist(VRF_DEFAULT), node, nnode, ifp))
322 eigrp_distribute_update_interface (ifp);
323 }
324
325 /*
326 * Function used in hook for acces-list
327 */
328 void
329 eigrp_distribute_update_all_wrapper(struct access_list *notused)
330 {
331 eigrp_distribute_update_all(NULL);
332 }
333
334 /*
335 * @fn eigrp_distribute_timer_process
336 *
337 * @param[in] thread current execution thread timer is associated with
338 *
339 * @return int always returns 0
340 *
341 * @par
342 * Called when 10sec waiting time expire and
343 * executes Graceful restart for whole process
344 */
345 int
346 eigrp_distribute_timer_process (struct thread *thread)
347 {
348 struct eigrp *eigrp;
349
350 eigrp = THREAD_ARG(thread);
351 eigrp->t_distribute = NULL;
352
353 /* execute GR for whole process */
354 eigrp_update_send_process_GR(eigrp, EIGRP_GR_FILTER, NULL);
355
356 return 0;
357 }
358
359 /*
360 * @fn eigrp_distribute_timer_interface
361 *
362 * @param[in] thread current execution thread timer is associated with
363 *
364 * @return int always returns 0
365 *
366 * @par
367 * Called when 10sec waiting time expire and
368 * executes Graceful restart for interface
369 */
370 int
371 eigrp_distribute_timer_interface (struct thread *thread)
372 {
373 struct eigrp_interface *ei;
374
375 ei = THREAD_ARG(thread);
376 ei->t_distribute = NULL;
377
378 /* execute GR for interface */
379 eigrp_update_send_interface_GR(ei, EIGRP_GR_FILTER, NULL);
380
381 return 0;
382 }