diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-28 09:53:30 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-28 09:53:30 +0000 |
commit | 2c7cac91ed6e7db0f6937923d2b57f97dbdbc337 (patch) | |
tree | c05dc0f8e6aa3accc84e3e5cffc933ed94941383 /eigrpd/eigrp_filter.c | |
parent | Initial commit. (diff) | |
download | frr-2c7cac91ed6e7db0f6937923d2b57f97dbdbc337.tar.xz frr-2c7cac91ed6e7db0f6937923d2b57f97dbdbc337.zip |
Adding upstream version 8.4.4.upstream/8.4.4upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'eigrpd/eigrp_filter.c')
-rw-r--r-- | eigrpd/eigrp_filter.c | 290 |
1 files changed, 290 insertions, 0 deletions
diff --git a/eigrpd/eigrp_filter.c b/eigrpd/eigrp_filter.c new file mode 100644 index 0000000..8d50ed6 --- /dev/null +++ b/eigrpd/eigrp_filter.c @@ -0,0 +1,290 @@ +/* + * 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 this program; see the file COPYING; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 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" + +/* + * Distribute-list update functions. + */ +void eigrp_distribute_update(struct distribute_ctx *ctx, + struct distribute *dist) +{ + struct eigrp *e = eigrp_lookup(ctx->vrf->vrf_id); + struct interface *ifp; + struct eigrp_interface *ei = NULL; + struct access_list *alist; + struct prefix_list *plist; + // struct route_map *routemap; + + /* if no interface address is present, set list to eigrp process struct + */ + + /* 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]); + 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]) { + 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]) { + 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]) { + 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; + + // TODO: check Graceful restart after 10sec + + /* cancel GR scheduled */ + thread_cancel(&(e->t_distribute)); + + /* schedule Graceful restart for whole process in 10sec */ + thread_add_timer(master, eigrp_distribute_timer_process, e, + (10), &e->t_distribute); + + return; + } + + ifp = if_lookup_by_name(dist->ifname, e->vrf_id); + if (ifp == NULL) + return; + + /*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; + } + } + assert(ei != NULL); + + /* Access-list for interface in */ + if (dist->list[DISTRIBUTE_V4_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; + + /* 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; + + // TODO: check Graceful restart after 10sec + + /* Cancel GR scheduled */ + thread_cancel(&(ei->t_distribute)); + /* schedule Graceful restart for interface in 10sec */ + thread_add_timer(master, eigrp_distribute_timer_interface, ei, 10, + &ei->t_distribute); +} + +/* + * Function called by prefix-list and access-list update + */ +void eigrp_distribute_update_interface(struct interface *ifp) +{ + struct distribute *dist; + struct eigrp *eigrp; + + eigrp = eigrp_lookup(ifp->vrf->vrf_id); + if (!eigrp) + return; + dist = distribute_lookup(eigrp->distribute_ctx, ifp->name); + if (dist) + eigrp_distribute_update(eigrp->distribute_ctx, + dist); +} + +/* Update all interface's distribute list. + * Function used in hook for prefix-list + */ +void eigrp_distribute_update_all(struct prefix_list *notused) +{ + struct vrf *vrf; + struct interface *ifp; + + RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) { + FOR_ALL_INTERFACES (vrf, 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 void + * + * @par + * Called when 10sec waiting time expire and + * executes Graceful restart for whole process + */ +void eigrp_distribute_timer_process(struct thread *thread) +{ + struct eigrp *eigrp; + + eigrp = THREAD_ARG(thread); + + /* execute GR for whole process */ + eigrp_update_send_process_GR(eigrp, EIGRP_GR_FILTER, NULL); +} + +/* + * @fn eigrp_distribute_timer_interface + * + * @param[in] thread current execution thread timer is associated with + * + * @return void + * + * @par + * Called when 10sec waiting time expire and + * executes Graceful restart for interface + */ +void 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); +} |