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.
66 eigrp_distribute_update (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 */
78 /* Check if distribute-list was set for process or interface */
81 /* access list IN for whole process */
82 if (dist
->list
[DISTRIBUTE_V4_IN
])
84 alist
= access_list_lookup (AFI_IP
, dist
->list
[DISTRIBUTE_V4_IN
]);
86 e
->list
[EIGRP_FILTER_IN
] = alist
;
88 e
->list
[EIGRP_FILTER_IN
] = NULL
;
92 e
->list
[EIGRP_FILTER_IN
] = NULL
;
95 /* access list OUT for whole process */
96 if (dist
->list
[DISTRIBUTE_V4_OUT
])
98 alist
= access_list_lookup (AFI_IP
, dist
->list
[DISTRIBUTE_V4_OUT
]);
100 e
->list
[EIGRP_FILTER_OUT
] = alist
;
102 e
->list
[EIGRP_FILTER_OUT
] = NULL
;
106 e
->list
[EIGRP_FILTER_OUT
] = NULL
;
109 /* PREFIX_LIST IN for process */
110 if (dist
->prefix
[DISTRIBUTE_V4_IN
])
112 plist
= prefix_list_lookup (AFI_IP
, dist
->prefix
[DISTRIBUTE_V4_IN
]);
115 e
->prefix
[EIGRP_FILTER_IN
] = plist
;
118 e
->prefix
[EIGRP_FILTER_IN
] = NULL
;
120 e
->prefix
[EIGRP_FILTER_IN
] = NULL
;
122 /* PREFIX_LIST OUT for process */
123 if (dist
->prefix
[DISTRIBUTE_V4_OUT
])
125 plist
= prefix_list_lookup (AFI_IP
, dist
->prefix
[DISTRIBUTE_V4_OUT
]);
128 e
->prefix
[EIGRP_FILTER_OUT
] = plist
;
132 e
->prefix
[EIGRP_FILTER_OUT
] = NULL
;
135 e
->prefix
[EIGRP_FILTER_OUT
] = NULL
;
137 //This is commented out, because the distribute.[ch] code
138 //changes looked poorly written from first glance
139 //commit was 133bdf2d
142 /* route-map IN for whole process */
143 if (dist
->route
[DISTRIBUTE_V4_IN
])
145 routemap
= route_map_lookup_by_name (dist
->route
[DISTRIBUTE_V4_IN
]);
147 e
->routemap
[EIGRP_FILTER_IN
] = routemap
;
149 e
->routemap
[EIGRP_FILTER_IN
] = NULL
;
153 e
->routemap
[EIGRP_FILTER_IN
] = NULL
;
156 /* route-map OUT for whole process */
157 if (dist
->route
[DISTRIBUTE_V4_OUT
])
159 routemap
= route_map_lookup_by_name (dist
->route
[DISTRIBUTE_V4_OUT
]);
161 e
->routemap
[EIGRP_FILTER_OUT
] = routemap
;
163 e
->routemap
[EIGRP_FILTER_OUT
] = NULL
;
167 e
->routemap
[EIGRP_FILTER_OUT
] = NULL
;
170 //TODO: check Graceful restart after 10sec
172 /* check if there is already GR scheduled */
173 if(e
->t_distribute
!= NULL
)
175 /* if is, cancel schedule */
176 thread_cancel(e
->t_distribute
);
178 /* schedule Graceful restart for whole process in 10sec */
179 e
->t_distribute
= NULL
;
180 thread_add_timer(master
, eigrp_distribute_timer_process
, e
, (10),
186 ifp
= if_lookup_by_name (dist
->ifname
, VRF_DEFAULT
);
190 /*struct eigrp_if_info * info = ifp->info;
191 ei = info->eigrp_interface;*/
192 struct listnode
*node
, *nnode
;
193 struct eigrp_interface
*ei2
;
194 /* Find proper interface */
195 for (ALL_LIST_ELEMENTS (e
->eiflist
, node
, nnode
, ei2
))
197 if(strcmp(ei2
->ifp
->name
,ifp
->name
) == 0){
203 /* Access-list for interface in */
204 if (dist
->list
[DISTRIBUTE_V4_IN
])
206 alist
= access_list_lookup (AFI_IP
, dist
->list
[DISTRIBUTE_V4_IN
]);
208 ei
->list
[EIGRP_FILTER_IN
] = alist
;
211 ei
->list
[EIGRP_FILTER_IN
] = NULL
;
215 ei
->list
[EIGRP_FILTER_IN
] = NULL
;
218 /* Access-list for interface in */
219 if (dist
->list
[DISTRIBUTE_V4_OUT
])
221 alist
= access_list_lookup (AFI_IP
, dist
->list
[DISTRIBUTE_V4_OUT
]);
223 ei
->list
[EIGRP_FILTER_OUT
] = alist
;
225 ei
->list
[EIGRP_FILTER_OUT
] = NULL
;
229 ei
->list
[EIGRP_FILTER_OUT
] = NULL
;
231 /* Prefix-list for interface in */
232 if (dist
->prefix
[DISTRIBUTE_V4_IN
])
234 plist
= prefix_list_lookup (AFI_IP
, dist
->prefix
[DISTRIBUTE_V4_IN
]);
236 ei
->prefix
[EIGRP_FILTER_IN
] = plist
;
238 ei
->prefix
[EIGRP_FILTER_IN
] = NULL
;
241 ei
->prefix
[EIGRP_FILTER_IN
] = NULL
;
243 /* Prefix-list for interface out */
244 if (dist
->prefix
[DISTRIBUTE_V4_OUT
])
246 plist
= prefix_list_lookup (AFI_IP
, dist
->prefix
[DISTRIBUTE_V4_OUT
]);
248 ei
->prefix
[EIGRP_FILTER_OUT
] = plist
;
250 ei
->prefix
[EIGRP_FILTER_OUT
] = NULL
;
253 ei
->prefix
[EIGRP_FILTER_OUT
] = NULL
;
256 /* route-map IN for whole process */
257 if (dist
->route
[DISTRIBUTE_V4_IN
])
259 zlog_info("<DEBUG ACL ALL in");
260 routemap
= route_map_lookup_by_name (dist
->route
[DISTRIBUTE_V4_IN
]);
262 ei
->routemap
[EIGRP_FILTER_IN
] = routemap
;
264 ei
->routemap
[EIGRP_FILTER_IN
] = NULL
;
268 ei
->routemap
[EIGRP_FILTER_IN
] = NULL
;
271 /* route-map OUT for whole process */
272 if (dist
->route
[DISTRIBUTE_V4_OUT
])
274 routemap
= route_map_lookup_by_name (dist
->route
[DISTRIBUTE_V4_OUT
]);
276 ei
->routemap
[EIGRP_FILTER_OUT
] = routemap
;
278 ei
->routemap
[EIGRP_FILTER_OUT
] = NULL
;
282 ei
->routemap
[EIGRP_FILTER_OUT
] = NULL
;
285 //TODO: check Graceful restart after 10sec
287 /* check if there is already GR scheduled */
288 if(ei
->t_distribute
!= NULL
)
290 /* if is, cancel schedule */
291 thread_cancel(ei
->t_distribute
);
293 /* schedule Graceful restart for interface in 10sec */
294 e
->t_distribute
= NULL
;
295 thread_add_timer(master
, eigrp_distribute_timer_interface
, ei
, 10,
300 * Function called by prefix-list and access-list update
303 eigrp_distribute_update_interface (struct interface
*ifp
)
305 struct distribute
*dist
;
307 dist
= distribute_lookup (ifp
->name
);
309 eigrp_distribute_update (dist
);
312 /* Update all interface's distribute list.
313 * Function used in hook for prefix-list
316 eigrp_distribute_update_all (struct prefix_list
*notused
)
318 struct interface
*ifp
;
319 struct listnode
*node
, *nnode
;
321 for (ALL_LIST_ELEMENTS (vrf_iflist(VRF_DEFAULT
), node
, nnode
, ifp
))
322 eigrp_distribute_update_interface (ifp
);
326 * Function used in hook for acces-list
329 eigrp_distribute_update_all_wrapper(struct access_list
*notused
)
331 eigrp_distribute_update_all(NULL
);
335 * @fn eigrp_distribute_timer_process
337 * @param[in] thread current execution thread timer is associated with
339 * @return int always returns 0
342 * Called when 10sec waiting time expire and
343 * executes Graceful restart for whole process
346 eigrp_distribute_timer_process (struct thread
*thread
)
350 eigrp
= THREAD_ARG(thread
);
351 eigrp
->t_distribute
= NULL
;
353 /* execute GR for whole process */
354 eigrp_update_send_process_GR(eigrp
, EIGRP_GR_FILTER
, NULL
);
360 * @fn eigrp_distribute_timer_interface
362 * @param[in] thread current execution thread timer is associated with
364 * @return int always returns 0
367 * Called when 10sec waiting time expire and
368 * executes Graceful restart for interface
371 eigrp_distribute_timer_interface (struct thread
*thread
)
373 struct eigrp_interface
*ei
;
375 ei
= THREAD_ARG(thread
);
376 ei
->t_distribute
= NULL
;
378 /* execute GR for interface */
379 eigrp_update_send_interface_GR(ei
, EIGRP_GR_FILTER
, NULL
);