2 * EIGRP Filter Functions.
3 * Copyright (C) 2013-2015
16 * This file is part of GNU Zebra.
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
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.
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
44 #include "sockunion.h"
49 #include "distribute.h"
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"
63 * Distribute-list update functions.
65 void eigrp_distribute_update(struct distribute_ctx
*ctx
,
66 struct distribute
*dist
)
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;
75 /* if no interface address is present, set list to eigrp process struct
80 /* Check if distribute-list was set for process or interface */
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
]);
87 e
->list
[EIGRP_FILTER_IN
] = alist
;
89 e
->list
[EIGRP_FILTER_IN
] = NULL
;
91 e
->list
[EIGRP_FILTER_IN
] = NULL
;
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
]);
99 e
->list
[EIGRP_FILTER_OUT
] = alist
;
101 e
->list
[EIGRP_FILTER_OUT
] = NULL
;
103 e
->list
[EIGRP_FILTER_OUT
] = NULL
;
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
]);
111 e
->prefix
[EIGRP_FILTER_IN
] = plist
;
113 e
->prefix
[EIGRP_FILTER_IN
] = NULL
;
115 e
->prefix
[EIGRP_FILTER_IN
] = NULL
;
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
]);
122 e
->prefix
[EIGRP_FILTER_OUT
] = plist
;
125 e
->prefix
[EIGRP_FILTER_OUT
] = NULL
;
127 e
->prefix
[EIGRP_FILTER_OUT
] = NULL
;
129 // This is commented out, because the distribute.[ch] code
130 // changes looked poorly written from first glance
131 // commit was 133bdf2d
134 /* route-map IN for whole process */
135 if (dist
->route
[DISTRIBUTE_V4_IN
])
137 routemap
= route_map_lookup_by_name (dist
->route
[DISTRIBUTE_V4_IN
]);
139 e
->routemap
[EIGRP_FILTER_IN
] = routemap
;
141 e
->routemap
[EIGRP_FILTER_IN
] = NULL
;
145 e
->routemap
[EIGRP_FILTER_IN
] = NULL
;
148 /* route-map OUT for whole process */
149 if (dist
->route
[DISTRIBUTE_V4_OUT
])
151 routemap
= route_map_lookup_by_name (dist
->route
[DISTRIBUTE_V4_OUT
]);
153 e
->routemap
[EIGRP_FILTER_OUT
] = routemap
;
155 e
->routemap
[EIGRP_FILTER_OUT
] = NULL
;
159 e
->routemap
[EIGRP_FILTER_OUT
] = NULL
;
162 // TODO: check Graceful restart after 10sec
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
);
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
);
177 ifp
= if_lookup_by_name(dist
->ifname
, e
->vrf_id
);
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) {
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
]);
199 ei
->list
[EIGRP_FILTER_IN
] = alist
;
201 ei
->list
[EIGRP_FILTER_IN
] = NULL
;
203 ei
->list
[EIGRP_FILTER_IN
] = NULL
;
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
]);
211 ei
->list
[EIGRP_FILTER_OUT
] = alist
;
213 ei
->list
[EIGRP_FILTER_OUT
] = NULL
;
216 ei
->list
[EIGRP_FILTER_OUT
] = NULL
;
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
]);
223 ei
->prefix
[EIGRP_FILTER_IN
] = plist
;
225 ei
->prefix
[EIGRP_FILTER_IN
] = NULL
;
227 ei
->prefix
[EIGRP_FILTER_IN
] = NULL
;
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
]);
234 ei
->prefix
[EIGRP_FILTER_OUT
] = plist
;
236 ei
->prefix
[EIGRP_FILTER_OUT
] = NULL
;
238 ei
->prefix
[EIGRP_FILTER_OUT
] = NULL
;
241 /* route-map IN for whole process */
242 if (dist
->route
[DISTRIBUTE_V4_IN
])
244 zlog_info("<DEBUG ACL ALL in");
245 routemap
= route_map_lookup_by_name (dist
->route
[DISTRIBUTE_V4_IN
]);
247 ei
->routemap
[EIGRP_FILTER_IN
] = routemap
;
249 ei
->routemap
[EIGRP_FILTER_IN
] = NULL
;
253 ei
->routemap
[EIGRP_FILTER_IN
] = NULL
;
256 /* route-map OUT for whole process */
257 if (dist
->route
[DISTRIBUTE_V4_OUT
])
259 routemap
= route_map_lookup_by_name (dist
->route
[DISTRIBUTE_V4_OUT
]);
261 ei
->routemap
[EIGRP_FILTER_OUT
] = routemap
;
263 ei
->routemap
[EIGRP_FILTER_OUT
] = NULL
;
267 ei
->routemap
[EIGRP_FILTER_OUT
] = NULL
;
270 // TODO: check Graceful restart after 10sec
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
);
277 /* schedule Graceful restart for interface in 10sec */
278 e
->t_distribute
= NULL
;
279 thread_add_timer(master
, eigrp_distribute_timer_interface
, ei
, 10,
284 * Function called by prefix-list and access-list update
286 void eigrp_distribute_update_interface(struct interface
*ifp
)
288 struct distribute
*dist
;
291 eigrp
= eigrp_lookup();
294 dist
= distribute_lookup(eigrp
->distribute_ctx
, ifp
->name
);
296 eigrp_distribute_update(eigrp
->distribute_ctx
,
300 /* Update all interface's distribute list.
301 * Function used in hook for prefix-list
303 void eigrp_distribute_update_all(struct prefix_list
*notused
)
305 struct vrf
*vrf
= vrf_lookup_by_id(VRF_DEFAULT
);
306 struct interface
*ifp
;
308 FOR_ALL_INTERFACES (vrf
, ifp
)
309 eigrp_distribute_update_interface(ifp
);
313 * Function used in hook for acces-list
315 void eigrp_distribute_update_all_wrapper(struct access_list
*notused
)
317 eigrp_distribute_update_all(NULL
);
321 * @fn eigrp_distribute_timer_process
323 * @param[in] thread current execution thread timer is associated with
325 * @return int always returns 0
328 * Called when 10sec waiting time expire and
329 * executes Graceful restart for whole process
331 int eigrp_distribute_timer_process(struct thread
*thread
)
335 eigrp
= THREAD_ARG(thread
);
336 eigrp
->t_distribute
= NULL
;
338 /* execute GR for whole process */
339 eigrp_update_send_process_GR(eigrp
, EIGRP_GR_FILTER
, NULL
);
345 * @fn eigrp_distribute_timer_interface
347 * @param[in] thread current execution thread timer is associated with
349 * @return int always returns 0
352 * Called when 10sec waiting time expire and
353 * executes Graceful restart for interface
355 int eigrp_distribute_timer_interface(struct thread
*thread
)
357 struct eigrp_interface
*ei
;
359 ei
= THREAD_ARG(thread
);
360 ei
->t_distribute
= NULL
;
362 /* execute GR for interface */
363 eigrp_update_send_interface_GR(ei
, EIGRP_GR_FILTER
, NULL
);