2017-03-09 05:07:46 +01:00
|
|
|
/*
|
|
|
|
* 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.
|
|
|
|
*
|
2017-05-13 10:25:29 +02:00
|
|
|
* 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
|
2017-03-09 05:07:46 +01:00
|
|
|
*/
|
|
|
|
|
|
|
|
#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)
|
|
|
|
{
|
2017-04-08 20:44:58 +02:00
|
|
|
/* 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;
|
|
|
|
|
|
|
|
//This is commented out, because the distribute.[ch] code
|
|
|
|
//changes looked poorly written from first glance
|
|
|
|
//commit was 133bdf2d
|
|
|
|
//TODO: DBS
|
2017-03-09 05:07:46 +01:00
|
|
|
#if 0
|
2017-04-08 20:44:58 +02:00
|
|
|
/* 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;
|
|
|
|
}
|
2017-03-09 05:07:46 +01:00
|
|
|
#endif
|
2017-04-08 20:44:58 +02:00
|
|
|
//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 */
|
2017-05-09 23:09:52 +02:00
|
|
|
e->t_distribute = NULL;
|
|
|
|
thread_add_timer(master, eigrp_distribute_timer_process, e, (10),
|
|
|
|
&e->t_distribute);
|
2017-04-08 20:44:58 +02:00
|
|
|
|
|
|
|
return;
|
2017-03-09 05:07:46 +01:00
|
|
|
}
|
|
|
|
|
2017-04-06 03:01:31 +02:00
|
|
|
ifp = if_lookup_by_name (dist->ifname, VRF_DEFAULT);
|
2017-03-09 05:07:46 +01:00
|
|
|
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))
|
|
|
|
{
|
2017-04-08 20:44:58 +02:00
|
|
|
if(strcmp(ei2->ifp->name,ifp->name) == 0){
|
|
|
|
ei = ei2;
|
|
|
|
break;
|
|
|
|
}
|
2017-03-09 05:07:46 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/* 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
|
2017-04-08 20:44:58 +02:00
|
|
|
ei->list[EIGRP_FILTER_IN] = NULL;
|
2017-03-09 05:07:46 +01:00
|
|
|
}
|
|
|
|
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)
|
2017-04-08 20:44:58 +02:00
|
|
|
ei->list[EIGRP_FILTER_OUT] = alist;
|
2017-03-09 05:07:46 +01:00
|
|
|
else
|
2017-04-08 20:44:58 +02:00
|
|
|
ei->list[EIGRP_FILTER_OUT] = NULL;
|
2017-03-09 05:07:46 +01:00
|
|
|
|
|
|
|
}
|
|
|
|
else
|
2017-05-16 00:48:54 +02:00
|
|
|
ei->list[EIGRP_FILTER_OUT] = NULL;
|
2017-03-09 05:07:46 +01:00
|
|
|
|
|
|
|
/* Prefix-list for interface in */
|
|
|
|
if (dist->prefix[DISTRIBUTE_V4_IN])
|
|
|
|
{
|
|
|
|
plist = prefix_list_lookup (AFI_IP, dist->prefix[DISTRIBUTE_V4_IN]);
|
|
|
|
if (plist)
|
2017-04-08 20:44:58 +02:00
|
|
|
ei->prefix[EIGRP_FILTER_IN] = plist;
|
2017-03-09 05:07:46 +01:00
|
|
|
else
|
2017-04-08 20:44:58 +02:00
|
|
|
ei->prefix[EIGRP_FILTER_IN] = NULL;
|
2017-03-09 05:07:46 +01:00
|
|
|
}
|
|
|
|
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)
|
2017-04-08 20:44:58 +02:00
|
|
|
ei->prefix[EIGRP_FILTER_OUT] = plist;
|
2017-03-09 05:07:46 +01:00
|
|
|
else
|
2017-04-08 20:44:58 +02:00
|
|
|
ei->prefix[EIGRP_FILTER_OUT] = NULL;
|
2017-03-09 05:07:46 +01:00
|
|
|
}
|
|
|
|
else
|
|
|
|
ei->prefix[EIGRP_FILTER_OUT] = NULL;
|
|
|
|
|
|
|
|
#if 0
|
|
|
|
/* route-map IN for whole process */
|
|
|
|
if (dist->route[DISTRIBUTE_V4_IN])
|
2017-04-08 20:44:58 +02:00
|
|
|
{
|
|
|
|
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;
|
|
|
|
}
|
2017-03-09 05:07:46 +01:00
|
|
|
else
|
2017-04-08 20:44:58 +02:00
|
|
|
{
|
|
|
|
ei->routemap[EIGRP_FILTER_IN] = NULL;
|
|
|
|
}
|
2017-03-09 05:07:46 +01:00
|
|
|
|
|
|
|
/* route-map OUT for whole process */
|
|
|
|
if (dist->route[DISTRIBUTE_V4_OUT])
|
2017-04-08 20:44:58 +02:00
|
|
|
{
|
|
|
|
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;
|
|
|
|
}
|
2017-03-09 05:07:46 +01:00
|
|
|
else
|
2017-04-08 20:44:58 +02:00
|
|
|
{
|
|
|
|
ei->routemap[EIGRP_FILTER_OUT] = NULL;
|
|
|
|
}
|
2017-03-09 05:07:46 +01:00
|
|
|
#endif
|
|
|
|
//TODO: check Graceful restart after 10sec
|
|
|
|
|
|
|
|
/* check if there is already GR scheduled */
|
|
|
|
if(ei->t_distribute != NULL)
|
2017-04-08 20:44:58 +02:00
|
|
|
{
|
|
|
|
/* if is, cancel schedule */
|
|
|
|
thread_cancel(ei->t_distribute);
|
|
|
|
}
|
2017-03-09 05:07:46 +01:00
|
|
|
/* schedule Graceful restart for interface in 10sec */
|
2017-05-09 23:09:52 +02:00
|
|
|
e->t_distribute = NULL;
|
|
|
|
thread_add_timer(master, eigrp_distribute_timer_interface, ei, 10,
|
|
|
|
&e->t_distribute);
|
2017-03-09 05:07:46 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* 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)
|
|
|
|
{
|
2017-04-08 20:44:58 +02:00
|
|
|
eigrp_distribute_update_all(NULL);
|
2017-03-09 05:07:46 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* @fn eigrp_distribute_timer_process
|
|
|
|
*
|
2017-04-08 20:44:58 +02:00
|
|
|
* @param[in] thread current execution thread timer is associated with
|
2017-03-09 05:07:46 +01:00
|
|
|
*
|
2017-04-08 20:44:58 +02:00
|
|
|
* @return int always returns 0
|
2017-03-09 05:07:46 +01:00
|
|
|
*
|
|
|
|
* @par
|
|
|
|
* Called when 10sec waiting time expire and
|
|
|
|
* executes Graceful restart for whole process
|
|
|
|
*/
|
|
|
|
int
|
|
|
|
eigrp_distribute_timer_process (struct thread *thread)
|
|
|
|
{
|
2017-04-08 20:44:58 +02:00
|
|
|
struct eigrp *eigrp;
|
2017-03-09 05:07:46 +01:00
|
|
|
|
2017-04-08 20:44:58 +02:00
|
|
|
eigrp = THREAD_ARG(thread);
|
|
|
|
eigrp->t_distribute = NULL;
|
2017-03-09 05:07:46 +01:00
|
|
|
|
2017-04-08 20:44:58 +02:00
|
|
|
/* execute GR for whole process */
|
|
|
|
eigrp_update_send_process_GR(eigrp, EIGRP_GR_FILTER, NULL);
|
2017-03-09 05:07:46 +01:00
|
|
|
|
2017-04-08 20:44:58 +02:00
|
|
|
return 0;
|
2017-03-09 05:07:46 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* @fn eigrp_distribute_timer_interface
|
|
|
|
*
|
2017-04-08 20:44:58 +02:00
|
|
|
* @param[in] thread current execution thread timer is associated with
|
2017-03-09 05:07:46 +01:00
|
|
|
*
|
2017-04-08 20:44:58 +02:00
|
|
|
* @return int always returns 0
|
2017-03-09 05:07:46 +01:00
|
|
|
*
|
|
|
|
* @par
|
|
|
|
* Called when 10sec waiting time expire and
|
|
|
|
* executes Graceful restart for interface
|
|
|
|
*/
|
|
|
|
int
|
|
|
|
eigrp_distribute_timer_interface (struct thread *thread)
|
|
|
|
{
|
2017-04-08 20:44:58 +02:00
|
|
|
struct eigrp_interface *ei;
|
2017-03-09 05:07:46 +01:00
|
|
|
|
2017-04-08 20:44:58 +02:00
|
|
|
ei = THREAD_ARG(thread);
|
|
|
|
ei->t_distribute = NULL;
|
2017-03-09 05:07:46 +01:00
|
|
|
|
2017-04-08 20:44:58 +02:00
|
|
|
/* execute GR for interface */
|
|
|
|
eigrp_update_send_interface_GR(ei, EIGRP_GR_FILTER, NULL);
|
2017-03-09 05:07:46 +01:00
|
|
|
|
2017-04-08 20:44:58 +02:00
|
|
|
return 0;
|
2017-03-09 05:07:46 +01:00
|
|
|
}
|