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
29 * along with GNU Zebra; see the file COPYING. If not, write to the Free
30 * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
45 #include "sockunion.h"
50 #include "distribute.h"
56 #include "eigrpd/eigrp_structs.h"
57 #include "eigrpd/eigrpd.h"
58 #include "eigrpd/eigrp_const.h"
59 #include "eigrpd/eigrp_filter.h"
60 #include "eigrpd/eigrp_packet.h"
61 #include "eigrpd/eigrp_memory.h"
64 * Distribute-list update functions.
67 eigrp_distribute_update (struct distribute
*dist
)
69 struct interface
*ifp
;
70 struct eigrp_interface
*ei
= NULL
;
71 struct access_list
*alist
;
72 struct prefix_list
*plist
;
73 //struct route_map *routemap;
76 /* if no interface address is present, set list to eigrp process struct */
79 /* Check if distribute-list was set for process or interface */
82 /* access list IN for whole process */
83 if (dist
->list
[DISTRIBUTE_V4_IN
])
85 alist
= access_list_lookup (AFI_IP
, dist
->list
[DISTRIBUTE_V4_IN
]);
86 zlog_info("<DEBUG DISTRIBUTE ACL IN FOUND: %s",alist
->name
);
88 e
->list
[EIGRP_FILTER_IN
] = alist
;
90 e
->list
[EIGRP_FILTER_IN
] = NULL
;
94 e
->list
[EIGRP_FILTER_IN
] = NULL
;
97 /* access list OUT for whole process */
98 if (dist
->list
[DISTRIBUTE_V4_OUT
])
100 zlog_info("<DEBUG DISTRIBUTE ACL OUT FOUND: %s",dist
->list
[DISTRIBUTE_V4_OUT
]);
101 alist
= access_list_lookup (AFI_IP
, dist
->list
[DISTRIBUTE_V4_OUT
]);
103 e
->list
[EIGRP_FILTER_OUT
] = alist
;
105 e
->list
[EIGRP_FILTER_OUT
] = NULL
;
109 e
->list
[EIGRP_FILTER_OUT
] = NULL
;
112 /* PREFIX_LIST IN for process */
113 if (dist
->prefix
[DISTRIBUTE_V4_IN
])
115 zlog_info("<DEBUG DISTRIBUTE PREFIX IN FOUND: %s",dist
->prefix
[DISTRIBUTE_V4_IN
]);
116 plist
= prefix_list_lookup (AFI_IP
, dist
->prefix
[DISTRIBUTE_V4_IN
]);
119 e
->prefix
[EIGRP_FILTER_IN
] = plist
;
122 e
->prefix
[EIGRP_FILTER_IN
] = NULL
;
124 e
->prefix
[EIGRP_FILTER_IN
] = NULL
;
126 /* PREFIX_LIST OUT for process */
127 if (dist
->prefix
[DISTRIBUTE_V4_OUT
])
129 zlog_info("<DEBUG DISTRIBUTE PREFIX OUT FOUND: %s",dist
->prefix
[DISTRIBUTE_V4_OUT
]);
130 plist
= prefix_list_lookup (AFI_IP
, dist
->prefix
[DISTRIBUTE_V4_OUT
]);
133 e
->prefix
[EIGRP_FILTER_OUT
] = plist
;
137 e
->prefix
[EIGRP_FILTER_OUT
] = NULL
;
140 e
->prefix
[EIGRP_FILTER_OUT
] = NULL
;
142 //This is commented out, because the distribute.[ch] code
143 //changes looked poorly written from first glance
144 //commit was 133bdf2d
147 /* route-map IN for whole process */
148 if (dist
->route
[DISTRIBUTE_V4_IN
])
150 routemap
= route_map_lookup_by_name (dist
->route
[DISTRIBUTE_V4_IN
]);
152 e
->routemap
[EIGRP_FILTER_IN
] = routemap
;
154 e
->routemap
[EIGRP_FILTER_IN
] = NULL
;
158 e
->routemap
[EIGRP_FILTER_IN
] = NULL
;
161 /* route-map OUT for whole process */
162 if (dist
->route
[DISTRIBUTE_V4_OUT
])
164 routemap
= route_map_lookup_by_name (dist
->route
[DISTRIBUTE_V4_OUT
]);
166 e
->routemap
[EIGRP_FILTER_OUT
] = routemap
;
168 e
->routemap
[EIGRP_FILTER_OUT
] = NULL
;
172 e
->routemap
[EIGRP_FILTER_OUT
] = NULL
;
175 //TODO: check Graceful restart after 10sec
177 /* check if there is already GR scheduled */
178 if(e
->t_distribute
!= NULL
)
180 /* if is, cancel schedule */
181 thread_cancel(e
->t_distribute
);
183 /* schedule Graceful restart for whole process in 10sec */
184 e
->t_distribute
= thread_add_timer(master
, eigrp_distribute_timer_process
, e
,(10));
189 ifp
= if_lookup_by_name (dist
->ifname
);
193 zlog_info("<DEBUG ACL 2");
195 /*struct eigrp_if_info * info = ifp->info;
196 ei = info->eigrp_interface;*/
197 struct listnode
*node
, *nnode
;
198 struct eigrp_interface
*ei2
;
199 /* Find proper interface */
200 for (ALL_LIST_ELEMENTS (e
->eiflist
, node
, nnode
, ei2
))
202 if(strcmp(ei2
->ifp
->name
,ifp
->name
) == 0){
210 zlog_info("Not Found eigrp interface %s",ifp
->name
);
213 /* Access-list for interface in */
214 if (dist
->list
[DISTRIBUTE_V4_IN
])
216 zlog_info("<DEBUG ACL in");
217 alist
= access_list_lookup (AFI_IP
, dist
->list
[DISTRIBUTE_V4_IN
]);
219 ei
->list
[EIGRP_FILTER_IN
] = alist
;
222 ei
->list
[EIGRP_FILTER_IN
] = NULL
;
226 ei
->list
[EIGRP_FILTER_IN
] = NULL
;
229 /* Access-list for interface in */
230 if (dist
->list
[DISTRIBUTE_V4_OUT
])
232 alist
= access_list_lookup (AFI_IP
, dist
->list
[DISTRIBUTE_V4_OUT
]);
234 ei
->list
[EIGRP_FILTER_OUT
] = alist
;
236 ei
->list
[EIGRP_FILTER_OUT
] = NULL
;
241 ei
->list
[EIGRP_FILTER_OUT
] = NULL
;
242 zlog_info("<DEBUG ACL out else");
245 /* Prefix-list for interface in */
246 if (dist
->prefix
[DISTRIBUTE_V4_IN
])
248 plist
= prefix_list_lookup (AFI_IP
, dist
->prefix
[DISTRIBUTE_V4_IN
]);
250 ei
->prefix
[EIGRP_FILTER_IN
] = plist
;
252 ei
->prefix
[EIGRP_FILTER_IN
] = NULL
;
255 ei
->prefix
[EIGRP_FILTER_IN
] = NULL
;
257 /* Prefix-list for interface out */
258 if (dist
->prefix
[DISTRIBUTE_V4_OUT
])
260 plist
= prefix_list_lookup (AFI_IP
, dist
->prefix
[DISTRIBUTE_V4_OUT
]);
262 ei
->prefix
[EIGRP_FILTER_OUT
] = plist
;
264 ei
->prefix
[EIGRP_FILTER_OUT
] = NULL
;
267 ei
->prefix
[EIGRP_FILTER_OUT
] = NULL
;
270 /* route-map IN for whole process */
271 if (dist
->route
[DISTRIBUTE_V4_IN
])
273 zlog_info("<DEBUG ACL ALL in");
274 routemap
= route_map_lookup_by_name (dist
->route
[DISTRIBUTE_V4_IN
]);
276 ei
->routemap
[EIGRP_FILTER_IN
] = routemap
;
278 ei
->routemap
[EIGRP_FILTER_IN
] = NULL
;
282 ei
->routemap
[EIGRP_FILTER_IN
] = NULL
;
285 /* route-map OUT for whole process */
286 if (dist
->route
[DISTRIBUTE_V4_OUT
])
288 routemap
= route_map_lookup_by_name (dist
->route
[DISTRIBUTE_V4_OUT
]);
290 ei
->routemap
[EIGRP_FILTER_OUT
] = routemap
;
292 ei
->routemap
[EIGRP_FILTER_OUT
] = NULL
;
296 ei
->routemap
[EIGRP_FILTER_OUT
] = NULL
;
299 //TODO: check Graceful restart after 10sec
301 /* check if there is already GR scheduled */
302 if(ei
->t_distribute
!= NULL
)
304 /* if is, cancel schedule */
305 thread_cancel(ei
->t_distribute
);
307 /* schedule Graceful restart for interface in 10sec */
308 e
->t_distribute
= thread_add_timer(master
, eigrp_distribute_timer_interface
, ei
,(10));
313 * Function called by prefix-list and access-list update
316 eigrp_distribute_update_interface (struct interface
*ifp
)
318 struct distribute
*dist
;
320 dist
= distribute_lookup (ifp
->name
);
322 eigrp_distribute_update (dist
);
325 /* Update all interface's distribute list.
326 * Function used in hook for prefix-list
329 eigrp_distribute_update_all (struct prefix_list
*notused
)
331 struct interface
*ifp
;
332 struct listnode
*node
, *nnode
;
334 for (ALL_LIST_ELEMENTS (vrf_iflist(VRF_DEFAULT
), node
, nnode
, ifp
))
335 eigrp_distribute_update_interface (ifp
);
339 * Function used in hook for acces-list
342 eigrp_distribute_update_all_wrapper(struct access_list
*notused
)
344 eigrp_distribute_update_all(NULL
);
348 * @fn eigrp_distribute_timer_process
350 * @param[in] thread current execution thread timer is associated with
352 * @return int always returns 0
355 * Called when 10sec waiting time expire and
356 * executes Graceful restart for whole process
359 eigrp_distribute_timer_process (struct thread
*thread
)
363 eigrp
= THREAD_ARG(thread
);
364 eigrp
->t_distribute
= NULL
;
366 /* execute GR for whole process */
367 eigrp_update_send_process_GR(eigrp
, EIGRP_GR_FILTER
, NULL
);
373 * @fn eigrp_distribute_timer_interface
375 * @param[in] thread current execution thread timer is associated with
377 * @return int always returns 0
380 * Called when 10sec waiting time expire and
381 * executes Graceful restart for interface
384 eigrp_distribute_timer_interface (struct thread
*thread
)
386 struct eigrp_interface
*ei
;
388 ei
= THREAD_ARG(thread
);
389 ei
->t_distribute
= NULL
;
391 /* execute GR for interface */
392 eigrp_update_send_interface_GR(ei
, EIGRP_GR_FILTER
, NULL
);