diff options
Diffstat (limited to 'eigrpd/eigrp_filter.c')
| -rw-r--r-- | eigrpd/eigrp_filter.c | 395 |
1 files changed, 395 insertions, 0 deletions
diff --git a/eigrpd/eigrp_filter.c b/eigrpd/eigrp_filter.c new file mode 100644 index 0000000000..aaac379d9b --- /dev/null +++ b/eigrpd/eigrp_filter.c @@ -0,0 +1,395 @@ +/* + * EIGRP Filter Functions. + * Copyright (C) 2013-2015 + * Authors: + * Donnie Savage + * Jan Janovic + * Matej Perina + * Peter Orsag + * Peter Paluch + * Frantisek Gazo + * Tomas Hvorkovy + * Martin Kontsek + * Lukas Koribsky + * + * + * This file is part of GNU Zebra. + * + * GNU Zebra is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2, or (at your option) any + * later version. + * + * GNU Zebra is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Zebra; see the file COPYING. If not, write to the Free + * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + */ + +#include <zebra.h> + +#include "if.h" +#include "command.h" +#include "prefix.h" +#include "table.h" +#include "thread.h" +#include "memory.h" +#include "log.h" +#include "stream.h" +#include "filter.h" +#include "sockunion.h" +#include "sockopt.h" +#include "routemap.h" +#include "if_rmap.h" +#include "plist.h" +#include "distribute.h" +#include "md5.h" +#include "keychain.h" +#include "privs.h" +#include "vrf.h" + +#include "eigrpd/eigrp_structs.h" +#include "eigrpd/eigrpd.h" +#include "eigrpd/eigrp_const.h" +#include "eigrpd/eigrp_filter.h" +#include "eigrpd/eigrp_packet.h" +#include "eigrpd/eigrp_memory.h" + +/* + * Distribute-list update functions. + */ +void +eigrp_distribute_update (struct distribute *dist) +{ + struct interface *ifp; + struct eigrp_interface *ei = NULL; + struct access_list *alist; + struct prefix_list *plist; + //struct route_map *routemap; + struct eigrp *e; + + /* if no interface address is present, set list to eigrp process struct */ + e = eigrp_lookup(); + + /* Check if distribute-list was set for process or interface */ + if (! dist->ifname) + { + /* access list IN for whole process */ + if (dist->list[DISTRIBUTE_V4_IN]) + { + alist = access_list_lookup (AFI_IP, dist->list[DISTRIBUTE_V4_IN]); + zlog_info("<DEBUG DISTRIBUTE ACL IN FOUND: %s",alist->name); + if (alist) + e->list[EIGRP_FILTER_IN] = alist; + else + e->list[EIGRP_FILTER_IN] = NULL; + } + else + { + e->list[EIGRP_FILTER_IN] = NULL; + } + + /* access list OUT for whole process */ + if (dist->list[DISTRIBUTE_V4_OUT]) + { + zlog_info("<DEBUG DISTRIBUTE ACL OUT FOUND: %s",dist->list[DISTRIBUTE_V4_OUT]); + alist = access_list_lookup (AFI_IP, dist->list[DISTRIBUTE_V4_OUT]); + if (alist) + e->list[EIGRP_FILTER_OUT] = alist; + else + e->list[EIGRP_FILTER_OUT] = NULL; + } + else + { + e->list[EIGRP_FILTER_OUT] = NULL; + } + + /* PREFIX_LIST IN for process */ + if (dist->prefix[DISTRIBUTE_V4_IN]) + { + zlog_info("<DEBUG DISTRIBUTE PREFIX IN FOUND: %s",dist->prefix[DISTRIBUTE_V4_IN]); + plist = prefix_list_lookup (AFI_IP, dist->prefix[DISTRIBUTE_V4_IN]); + if (plist) + { + e->prefix[EIGRP_FILTER_IN] = plist; + } + else + e->prefix[EIGRP_FILTER_IN] = NULL; + } else + e->prefix[EIGRP_FILTER_IN] = NULL; + + /* PREFIX_LIST OUT for process */ + if (dist->prefix[DISTRIBUTE_V4_OUT]) + { + zlog_info("<DEBUG DISTRIBUTE PREFIX OUT FOUND: %s",dist->prefix[DISTRIBUTE_V4_OUT]); + plist = prefix_list_lookup (AFI_IP, dist->prefix[DISTRIBUTE_V4_OUT]); + if (plist) + { + e->prefix[EIGRP_FILTER_OUT] = plist; + + } + else + e->prefix[EIGRP_FILTER_OUT] = NULL; + } + else + e->prefix[EIGRP_FILTER_OUT] = NULL; + + //This is commented out, because the distribute.[ch] code + //changes looked poorly written from first glance + //commit was 133bdf2d + //TODO: DBS +#if 0 + /* route-map IN for whole process */ + if (dist->route[DISTRIBUTE_V4_IN]) + { + routemap = route_map_lookup_by_name (dist->route[DISTRIBUTE_V4_IN]); + if (routemap) + e->routemap[EIGRP_FILTER_IN] = routemap; + else + e->routemap[EIGRP_FILTER_IN] = NULL; + } + else + { + e->routemap[EIGRP_FILTER_IN] = NULL; + } + + /* route-map OUT for whole process */ + if (dist->route[DISTRIBUTE_V4_OUT]) + { + routemap = route_map_lookup_by_name (dist->route[DISTRIBUTE_V4_OUT]); + if (routemap) + e->routemap[EIGRP_FILTER_OUT] = routemap; + else + e->routemap[EIGRP_FILTER_OUT] = NULL; + } + else + { + e->routemap[EIGRP_FILTER_OUT] = NULL; + } +#endif + //TODO: check Graceful restart after 10sec + + /* check if there is already GR scheduled */ + if(e->t_distribute != NULL) + { + /* if is, cancel schedule */ + thread_cancel(e->t_distribute); + } + /* schedule Graceful restart for whole process in 10sec */ + e->t_distribute = thread_add_timer(master, eigrp_distribute_timer_process, e,(10)); + + return; + } + + ifp = if_lookup_by_name (dist->ifname); + if (ifp == NULL) + return; + + zlog_info("<DEBUG ACL 2"); + + /*struct eigrp_if_info * info = ifp->info; + ei = info->eigrp_interface;*/ + struct listnode *node, *nnode; + struct eigrp_interface *ei2; + /* Find proper interface */ + for (ALL_LIST_ELEMENTS (e->eiflist, node, nnode, ei2)) + { + if(strcmp(ei2->ifp->name,ifp->name) == 0){ + ei = ei2; + break; + } + } + + if(ei == NULL) + { + zlog_info("Not Found eigrp interface %s",ifp->name); + } + + /* Access-list for interface in */ + if (dist->list[DISTRIBUTE_V4_IN]) + { + zlog_info("<DEBUG ACL in"); + alist = access_list_lookup (AFI_IP, dist->list[DISTRIBUTE_V4_IN]); + if (alist){ + ei->list[EIGRP_FILTER_IN] = alist; + } + else + ei->list[EIGRP_FILTER_IN] = NULL; + } + else + { + ei->list[EIGRP_FILTER_IN] = NULL; + } + + /* Access-list for interface in */ + if (dist->list[DISTRIBUTE_V4_OUT]) + { + alist = access_list_lookup (AFI_IP, dist->list[DISTRIBUTE_V4_OUT]); + if (alist) + ei->list[EIGRP_FILTER_OUT] = alist; + else + ei->list[EIGRP_FILTER_OUT] = NULL; + + } + else + { + ei->list[EIGRP_FILTER_OUT] = NULL; + zlog_info("<DEBUG ACL out else"); + } + + /* Prefix-list for interface in */ + if (dist->prefix[DISTRIBUTE_V4_IN]) + { + plist = prefix_list_lookup (AFI_IP, dist->prefix[DISTRIBUTE_V4_IN]); + if (plist) + ei->prefix[EIGRP_FILTER_IN] = plist; + else + ei->prefix[EIGRP_FILTER_IN] = NULL; + } + else + ei->prefix[EIGRP_FILTER_IN] = NULL; + + /* Prefix-list for interface out */ + if (dist->prefix[DISTRIBUTE_V4_OUT]) + { + plist = prefix_list_lookup (AFI_IP, dist->prefix[DISTRIBUTE_V4_OUT]); + if (plist) + ei->prefix[EIGRP_FILTER_OUT] = plist; + else + ei->prefix[EIGRP_FILTER_OUT] = NULL; + } + else + ei->prefix[EIGRP_FILTER_OUT] = NULL; + +#if 0 + /* route-map IN for whole process */ + if (dist->route[DISTRIBUTE_V4_IN]) + { + zlog_info("<DEBUG ACL ALL in"); + routemap = route_map_lookup_by_name (dist->route[DISTRIBUTE_V4_IN]); + if (routemap) + ei->routemap[EIGRP_FILTER_IN] = routemap; + else + ei->routemap[EIGRP_FILTER_IN] = NULL; + } + else + { + ei->routemap[EIGRP_FILTER_IN] = NULL; + } + + /* route-map OUT for whole process */ + if (dist->route[DISTRIBUTE_V4_OUT]) + { + routemap = route_map_lookup_by_name (dist->route[DISTRIBUTE_V4_OUT]); + if (routemap) + ei->routemap[EIGRP_FILTER_OUT] = routemap; + else + ei->routemap[EIGRP_FILTER_OUT] = NULL; + } + else + { + ei->routemap[EIGRP_FILTER_OUT] = NULL; + } +#endif + //TODO: check Graceful restart after 10sec + + /* check if there is already GR scheduled */ + if(ei->t_distribute != NULL) + { + /* if is, cancel schedule */ + thread_cancel(ei->t_distribute); + } + /* schedule Graceful restart for interface in 10sec */ + e->t_distribute = thread_add_timer(master, eigrp_distribute_timer_interface, ei,(10)); + +} + +/* + * Function called by prefix-list and access-list update + */ +void +eigrp_distribute_update_interface (struct interface *ifp) +{ + struct distribute *dist; + + dist = distribute_lookup (ifp->name); + if (dist) + eigrp_distribute_update (dist); +} + +/* Update all interface's distribute list. + * Function used in hook for prefix-list + */ +void +eigrp_distribute_update_all (struct prefix_list *notused) +{ + struct interface *ifp; + struct listnode *node, *nnode; + + for (ALL_LIST_ELEMENTS (vrf_iflist(VRF_DEFAULT), node, nnode, ifp)) + eigrp_distribute_update_interface (ifp); +} + +/* + * Function used in hook for acces-list + */ +void +eigrp_distribute_update_all_wrapper(struct access_list *notused) +{ + eigrp_distribute_update_all(NULL); +} + +/* + * @fn eigrp_distribute_timer_process + * + * @param[in] thread current execution thread timer is associated with + * + * @return int always returns 0 + * + * @par + * Called when 10sec waiting time expire and + * executes Graceful restart for whole process + */ +int +eigrp_distribute_timer_process (struct thread *thread) +{ + struct eigrp *eigrp; + + eigrp = THREAD_ARG(thread); + eigrp->t_distribute = NULL; + + /* execute GR for whole process */ + eigrp_update_send_process_GR(eigrp, EIGRP_GR_FILTER, NULL); + + return 0; +} + +/* + * @fn eigrp_distribute_timer_interface + * + * @param[in] thread current execution thread timer is associated with + * + * @return int always returns 0 + * + * @par + * Called when 10sec waiting time expire and + * executes Graceful restart for interface + */ +int +eigrp_distribute_timer_interface (struct thread *thread) +{ + struct eigrp_interface *ei; + + ei = THREAD_ARG(thread); + ei->t_distribute = NULL; + + /* execute GR for interface */ + eigrp_update_send_interface_GR(ei, EIGRP_GR_FILTER, NULL); + + return 0; +} |
