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
*dist
)
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;
74 /* if no interface address is present, set list to eigrp process struct
79 /* Check if distribute-list was set for process or interface */
81 /* access list IN for whole process */
82 if (dist
->list
[DISTRIBUTE_V4_IN
]) {
83 alist
= access_list_lookup(
84 AFI_IP
, dist
->list
[DISTRIBUTE_V4_IN
]);
86 e
->list
[EIGRP_FILTER_IN
] = alist
;
88 e
->list
[EIGRP_FILTER_IN
] = NULL
;
90 e
->list
[EIGRP_FILTER_IN
] = NULL
;
93 /* access list OUT for whole process */
94 if (dist
->list
[DISTRIBUTE_V4_OUT
]) {
95 alist
= access_list_lookup(
96 AFI_IP
, dist
->list
[DISTRIBUTE_V4_OUT
]);
98 e
->list
[EIGRP_FILTER_OUT
] = alist
;
100 e
->list
[EIGRP_FILTER_OUT
] = NULL
;
102 e
->list
[EIGRP_FILTER_OUT
] = NULL
;
105 /* PREFIX_LIST IN for process */
106 if (dist
->prefix
[DISTRIBUTE_V4_IN
]) {
107 plist
= prefix_list_lookup(
108 AFI_IP
, dist
->prefix
[DISTRIBUTE_V4_IN
]);
110 e
->prefix
[EIGRP_FILTER_IN
] = plist
;
112 e
->prefix
[EIGRP_FILTER_IN
] = NULL
;
114 e
->prefix
[EIGRP_FILTER_IN
] = NULL
;
116 /* PREFIX_LIST OUT for process */
117 if (dist
->prefix
[DISTRIBUTE_V4_OUT
]) {
118 plist
= prefix_list_lookup(
119 AFI_IP
, dist
->prefix
[DISTRIBUTE_V4_OUT
]);
121 e
->prefix
[EIGRP_FILTER_OUT
] = plist
;
124 e
->prefix
[EIGRP_FILTER_OUT
] = NULL
;
126 e
->prefix
[EIGRP_FILTER_OUT
] = NULL
;
128 // This is commented out, because the distribute.[ch] code
129 // changes looked poorly written from first glance
130 // commit was 133bdf2d
133 /* route-map IN for whole process */
134 if (dist
->route
[DISTRIBUTE_V4_IN
])
136 routemap
= route_map_lookup_by_name (dist
->route
[DISTRIBUTE_V4_IN
]);
138 e
->routemap
[EIGRP_FILTER_IN
] = routemap
;
140 e
->routemap
[EIGRP_FILTER_IN
] = NULL
;
144 e
->routemap
[EIGRP_FILTER_IN
] = NULL
;
147 /* route-map OUT for whole process */
148 if (dist
->route
[DISTRIBUTE_V4_OUT
])
150 routemap
= route_map_lookup_by_name (dist
->route
[DISTRIBUTE_V4_OUT
]);
152 e
->routemap
[EIGRP_FILTER_OUT
] = routemap
;
154 e
->routemap
[EIGRP_FILTER_OUT
] = NULL
;
158 e
->routemap
[EIGRP_FILTER_OUT
] = NULL
;
161 // TODO: check Graceful restart after 10sec
163 /* check if there is already GR scheduled */
164 if (e
->t_distribute
!= NULL
) {
165 /* if is, cancel schedule */
166 thread_cancel(e
->t_distribute
);
168 /* schedule Graceful restart for whole process in 10sec */
169 e
->t_distribute
= NULL
;
170 thread_add_timer(master
, eigrp_distribute_timer_process
, e
,
171 (10), &e
->t_distribute
);
176 ifp
= if_lookup_by_name(dist
->ifname
, VRF_DEFAULT
);
180 /*struct eigrp_if_info * info = ifp->info;
181 ei = info->eigrp_interface;*/
182 struct listnode
*node
, *nnode
;
183 struct eigrp_interface
*ei2
;
184 /* Find proper interface */
185 for (ALL_LIST_ELEMENTS(e
->eiflist
, node
, nnode
, ei2
)) {
186 if (strcmp(ei2
->ifp
->name
, ifp
->name
) == 0) {
193 /* Access-list for interface in */
194 if (dist
->list
[DISTRIBUTE_V4_IN
]) {
195 alist
= access_list_lookup(AFI_IP
,
196 dist
->list
[DISTRIBUTE_V4_IN
]);
198 ei
->list
[EIGRP_FILTER_IN
] = alist
;
200 ei
->list
[EIGRP_FILTER_IN
] = NULL
;
202 ei
->list
[EIGRP_FILTER_IN
] = NULL
;
205 /* Access-list for interface in */
206 if (dist
->list
[DISTRIBUTE_V4_OUT
]) {
207 alist
= access_list_lookup(AFI_IP
,
208 dist
->list
[DISTRIBUTE_V4_OUT
]);
210 ei
->list
[EIGRP_FILTER_OUT
] = alist
;
212 ei
->list
[EIGRP_FILTER_OUT
] = NULL
;
215 ei
->list
[EIGRP_FILTER_OUT
] = NULL
;
217 /* Prefix-list for interface in */
218 if (dist
->prefix
[DISTRIBUTE_V4_IN
]) {
219 plist
= prefix_list_lookup(AFI_IP
,
220 dist
->prefix
[DISTRIBUTE_V4_IN
]);
222 ei
->prefix
[EIGRP_FILTER_IN
] = plist
;
224 ei
->prefix
[EIGRP_FILTER_IN
] = NULL
;
226 ei
->prefix
[EIGRP_FILTER_IN
] = NULL
;
228 /* Prefix-list for interface out */
229 if (dist
->prefix
[DISTRIBUTE_V4_OUT
]) {
230 plist
= prefix_list_lookup(AFI_IP
,
231 dist
->prefix
[DISTRIBUTE_V4_OUT
]);
233 ei
->prefix
[EIGRP_FILTER_OUT
] = plist
;
235 ei
->prefix
[EIGRP_FILTER_OUT
] = NULL
;
237 ei
->prefix
[EIGRP_FILTER_OUT
] = NULL
;
240 /* route-map IN for whole process */
241 if (dist
->route
[DISTRIBUTE_V4_IN
])
243 zlog_info("<DEBUG ACL ALL in");
244 routemap
= route_map_lookup_by_name (dist
->route
[DISTRIBUTE_V4_IN
]);
246 ei
->routemap
[EIGRP_FILTER_IN
] = routemap
;
248 ei
->routemap
[EIGRP_FILTER_IN
] = NULL
;
252 ei
->routemap
[EIGRP_FILTER_IN
] = NULL
;
255 /* route-map OUT for whole process */
256 if (dist
->route
[DISTRIBUTE_V4_OUT
])
258 routemap
= route_map_lookup_by_name (dist
->route
[DISTRIBUTE_V4_OUT
]);
260 ei
->routemap
[EIGRP_FILTER_OUT
] = routemap
;
262 ei
->routemap
[EIGRP_FILTER_OUT
] = NULL
;
266 ei
->routemap
[EIGRP_FILTER_OUT
] = NULL
;
269 // TODO: check Graceful restart after 10sec
271 /* check if there is already GR scheduled */
272 if (ei
->t_distribute
!= NULL
) {
273 /* if is, cancel schedule */
274 thread_cancel(ei
->t_distribute
);
276 /* schedule Graceful restart for interface in 10sec */
277 e
->t_distribute
= NULL
;
278 thread_add_timer(master
, eigrp_distribute_timer_interface
, ei
, 10,
283 * Function called by prefix-list and access-list update
285 void eigrp_distribute_update_interface(struct interface
*ifp
)
287 struct distribute
*dist
;
289 dist
= distribute_lookup(ifp
->name
);
291 eigrp_distribute_update(dist
);
294 /* Update all interface's distribute list.
295 * Function used in hook for prefix-list
297 void eigrp_distribute_update_all(struct prefix_list
*notused
)
299 struct vrf
*vrf
= vrf_lookup_by_id(VRF_DEFAULT
);
300 struct interface
*ifp
;
302 FOR_ALL_INTERFACES (vrf
, ifp
)
303 eigrp_distribute_update_interface(ifp
);
307 * Function used in hook for acces-list
309 void eigrp_distribute_update_all_wrapper(struct access_list
*notused
)
311 eigrp_distribute_update_all(NULL
);
315 * @fn eigrp_distribute_timer_process
317 * @param[in] thread current execution thread timer is associated with
319 * @return int always returns 0
322 * Called when 10sec waiting time expire and
323 * executes Graceful restart for whole process
325 int eigrp_distribute_timer_process(struct thread
*thread
)
329 eigrp
= THREAD_ARG(thread
);
330 eigrp
->t_distribute
= NULL
;
332 /* execute GR for whole process */
333 eigrp_update_send_process_GR(eigrp
, EIGRP_GR_FILTER
, NULL
);
339 * @fn eigrp_distribute_timer_interface
341 * @param[in] thread current execution thread timer is associated with
343 * @return int always returns 0
346 * Called when 10sec waiting time expire and
347 * executes Graceful restart for interface
349 int eigrp_distribute_timer_interface(struct thread
*thread
)
351 struct eigrp_interface
*ei
;
353 ei
= THREAD_ARG(thread
);
354 ei
->t_distribute
= NULL
;
356 /* execute GR for interface */
357 eigrp_update_send_interface_GR(ei
, EIGRP_GR_FILTER
, NULL
);