]> git.proxmox.com Git - mirror_frr.git/blob - eigrpd/eigrp_filter.c
Merge pull request #435 from chiragshah6/pim_dev
[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
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 */
66 void
67 eigrp_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
189 ifp = if_lookup_by_name (dist->ifname, VRF_DEFAULT);
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 * Function called by prefix-list and access-list update
313 */
314 void
315 eigrp_distribute_update_interface (struct interface *ifp)
316 {
317 struct distribute *dist;
318
319 dist = distribute_lookup (ifp->name);
320 if (dist)
321 eigrp_distribute_update (dist);
322 }
323
324 /* Update all interface's distribute list.
325 * Function used in hook for prefix-list
326 */
327 void
328 eigrp_distribute_update_all (struct prefix_list *notused)
329 {
330 struct interface *ifp;
331 struct listnode *node, *nnode;
332
333 for (ALL_LIST_ELEMENTS (vrf_iflist(VRF_DEFAULT), node, nnode, ifp))
334 eigrp_distribute_update_interface (ifp);
335 }
336
337 /*
338 * Function used in hook for acces-list
339 */
340 void
341 eigrp_distribute_update_all_wrapper(struct access_list *notused)
342 {
343 eigrp_distribute_update_all(NULL);
344 }
345
346 /*
347 * @fn eigrp_distribute_timer_process
348 *
349 * @param[in] thread current execution thread timer is associated with
350 *
351 * @return int always returns 0
352 *
353 * @par
354 * Called when 10sec waiting time expire and
355 * executes Graceful restart for whole process
356 */
357 int
358 eigrp_distribute_timer_process (struct thread *thread)
359 {
360 struct eigrp *eigrp;
361
362 eigrp = THREAD_ARG(thread);
363 eigrp->t_distribute = NULL;
364
365 /* execute GR for whole process */
366 eigrp_update_send_process_GR(eigrp, EIGRP_GR_FILTER, NULL);
367
368 return 0;
369 }
370
371 /*
372 * @fn eigrp_distribute_timer_interface
373 *
374 * @param[in] thread current execution thread timer is associated with
375 *
376 * @return int always returns 0
377 *
378 * @par
379 * Called when 10sec waiting time expire and
380 * executes Graceful restart for interface
381 */
382 int
383 eigrp_distribute_timer_interface (struct thread *thread)
384 {
385 struct eigrp_interface *ei;
386
387 ei = THREAD_ARG(thread);
388 ei->t_distribute = NULL;
389
390 /* execute GR for interface */
391 eigrp_update_send_interface_GR(ei, EIGRP_GR_FILTER, NULL);
392
393 return 0;
394 }