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