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