2023-02-08 13:17:09 +01:00
|
|
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
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
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <zebra.h>
|
|
|
|
|
|
|
|
#include "if.h"
|
|
|
|
#include "command.h"
|
|
|
|
#include "prefix.h"
|
|
|
|
#include "table.h"
|
2023-03-07 20:22:48 +01:00
|
|
|
#include "frrevent.h"
|
2017-03-09 05:07:46 +01:00
|
|
|
#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.
|
|
|
|
*/
|
lib, rip, ripng, babel, eigrp: add ctx pointer to distribute api
a distribute_ctx context pointer is returned after initialisation to the
calling daemon. this context pointer will be further used to do
discussion with distribute service. Today, there is no specific problem
with old api, since the pointer is the same in all the memory process.
but the pointer will be different if we have multiple instances. Right
now, this is not the case, but if that happens, that work will be used
for that.
distribute-list initialisation is split in two. the vty initialisation
is done at global level, while the context initialisation is done for
each routing daemon instance.
babel daemon is being equipped with a routing returning the main babel
instance.
also, a delete routine is available when the daemon routing instance is
suppressed.
a list of contexts is used inside distribute_list. This will permit
distribute_list utility to handle in the same daemon to handle more than
one context. This will be very useful in the vrf context.
Signed-off-by: Philippe Guibert <philippe.guibert@6wind.com>
2018-12-04 15:45:57 +01:00
|
|
|
void eigrp_distribute_update(struct distribute_ctx *ctx,
|
|
|
|
struct distribute *dist)
|
2017-03-09 05:07:46 +01:00
|
|
|
{
|
2019-06-15 21:20:11 +02:00
|
|
|
struct eigrp *e = eigrp_lookup(ctx->vrf->vrf_id);
|
2017-03-09 05:07:46 +01:00
|
|
|
struct interface *ifp;
|
|
|
|
struct eigrp_interface *ei = NULL;
|
|
|
|
struct access_list *alist;
|
|
|
|
struct prefix_list *plist;
|
|
|
|
// struct route_map *routemap;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2017-03-09 05:07:46 +01:00
|
|
|
/* if no interface address is present, set list to eigrp process struct
|
|
|
|
*/
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2017-03-09 05:07:46 +01:00
|
|
|
/* 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;
|
|
|
|
}
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2017-04-08 20:44:58 +02:00
|
|
|
/* 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;
|
|
|
|
}
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2017-04-08 20:44:58 +02:00
|
|
|
/* 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;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2017-04-08 20:44:58 +02:00
|
|
|
/* 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;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2017-04-08 20:44:58 +02:00
|
|
|
} else
|
|
|
|
e->prefix[EIGRP_FILTER_OUT] = NULL;
|
|
|
|
} else
|
|
|
|
e->prefix[EIGRP_FILTER_OUT] = NULL;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2017-04-08 20:44:58 +02:00
|
|
|
// TODO: check Graceful restart after 10sec
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2020-07-17 23:09:51 +02:00
|
|
|
/* cancel GR scheduled */
|
2022-12-10 15:08:37 +01:00
|
|
|
event_cancel(&(e->t_distribute));
|
2020-07-06 18:55:03 +02:00
|
|
|
|
2017-04-08 20:44:58 +02:00
|
|
|
/* schedule Graceful restart for whole process in 10sec */
|
2022-05-20 20:19:08 +02:00
|
|
|
event_add_timer(master, eigrp_distribute_timer_process, e, (10),
|
|
|
|
&e->t_distribute);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2017-04-08 20:44:58 +02:00
|
|
|
return;
|
2017-03-09 05:07:46 +01:00
|
|
|
}
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2019-04-13 01:49:11 +02:00
|
|
|
ifp = if_lookup_by_name(dist->ifname, e->vrf_id);
|
2017-03-09 05:07:46 +01:00
|
|
|
if (ifp == NULL)
|
|
|
|
return;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2017-03-09 05:07:46 +01:00
|
|
|
/*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
|
|
|
}
|
2017-07-17 14:03:14 +02:00
|
|
|
}
|
2017-10-09 00:12:01 +02:00
|
|
|
assert(ei != NULL);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
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;
|
|
|
|
}
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2017-03-09 05:07:46 +01:00
|
|
|
/* 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-07-17 14:03:14 +02:00
|
|
|
|
2017-03-09 05:07:46 +01:00
|
|
|
} else
|
2017-05-16 00:48:54 +02:00
|
|
|
ei->list[EIGRP_FILTER_OUT] = NULL;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
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;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2017-03-09 05:07:46 +01:00
|
|
|
/* 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;
|
|
|
|
|
|
|
|
// TODO: check Graceful restart after 10sec
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2020-07-17 23:09:51 +02:00
|
|
|
/* Cancel GR scheduled */
|
2022-12-10 15:08:37 +01:00
|
|
|
event_cancel(&(ei->t_distribute));
|
2017-03-09 05:07:46 +01:00
|
|
|
/* schedule Graceful restart for interface in 10sec */
|
2022-05-20 20:19:08 +02:00
|
|
|
event_add_timer(master, eigrp_distribute_timer_interface, ei, 10,
|
|
|
|
&ei->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;
|
lib, rip, ripng, babel, eigrp: add ctx pointer to distribute api
a distribute_ctx context pointer is returned after initialisation to the
calling daemon. this context pointer will be further used to do
discussion with distribute service. Today, there is no specific problem
with old api, since the pointer is the same in all the memory process.
but the pointer will be different if we have multiple instances. Right
now, this is not the case, but if that happens, that work will be used
for that.
distribute-list initialisation is split in two. the vty initialisation
is done at global level, while the context initialisation is done for
each routing daemon instance.
babel daemon is being equipped with a routing returning the main babel
instance.
also, a delete routine is available when the daemon routing instance is
suppressed.
a list of contexts is used inside distribute_list. This will permit
distribute_list utility to handle in the same daemon to handle more than
one context. This will be very useful in the vrf context.
Signed-off-by: Philippe Guibert <philippe.guibert@6wind.com>
2018-12-04 15:45:57 +01:00
|
|
|
struct eigrp *eigrp;
|
2017-03-09 05:07:46 +01:00
|
|
|
|
2021-10-22 00:17:40 +02:00
|
|
|
eigrp = eigrp_lookup(ifp->vrf->vrf_id);
|
lib, rip, ripng, babel, eigrp: add ctx pointer to distribute api
a distribute_ctx context pointer is returned after initialisation to the
calling daemon. this context pointer will be further used to do
discussion with distribute service. Today, there is no specific problem
with old api, since the pointer is the same in all the memory process.
but the pointer will be different if we have multiple instances. Right
now, this is not the case, but if that happens, that work will be used
for that.
distribute-list initialisation is split in two. the vty initialisation
is done at global level, while the context initialisation is done for
each routing daemon instance.
babel daemon is being equipped with a routing returning the main babel
instance.
also, a delete routine is available when the daemon routing instance is
suppressed.
a list of contexts is used inside distribute_list. This will permit
distribute_list utility to handle in the same daemon to handle more than
one context. This will be very useful in the vrf context.
Signed-off-by: Philippe Guibert <philippe.guibert@6wind.com>
2018-12-04 15:45:57 +01:00
|
|
|
if (!eigrp)
|
|
|
|
return;
|
|
|
|
dist = distribute_lookup(eigrp->distribute_ctx, ifp->name);
|
2017-03-09 05:07:46 +01:00
|
|
|
if (dist)
|
lib, rip, ripng, babel, eigrp: add ctx pointer to distribute api
a distribute_ctx context pointer is returned after initialisation to the
calling daemon. this context pointer will be further used to do
discussion with distribute service. Today, there is no specific problem
with old api, since the pointer is the same in all the memory process.
but the pointer will be different if we have multiple instances. Right
now, this is not the case, but if that happens, that work will be used
for that.
distribute-list initialisation is split in two. the vty initialisation
is done at global level, while the context initialisation is done for
each routing daemon instance.
babel daemon is being equipped with a routing returning the main babel
instance.
also, a delete routine is available when the daemon routing instance is
suppressed.
a list of contexts is used inside distribute_list. This will permit
distribute_list utility to handle in the same daemon to handle more than
one context. This will be very useful in the vrf context.
Signed-off-by: Philippe Guibert <philippe.guibert@6wind.com>
2018-12-04 15:45:57 +01:00
|
|
|
eigrp_distribute_update(eigrp->distribute_ctx,
|
|
|
|
dist);
|
2017-03-09 05:07:46 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Update all interface's distribute list.
|
|
|
|
* Function used in hook for prefix-list
|
|
|
|
*/
|
|
|
|
void eigrp_distribute_update_all(struct prefix_list *notused)
|
|
|
|
{
|
2019-06-15 21:20:11 +02:00
|
|
|
struct vrf *vrf;
|
2017-03-09 05:07:46 +01:00
|
|
|
struct interface *ifp;
|
|
|
|
|
2019-06-15 21:20:11 +02:00
|
|
|
RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
|
|
|
|
FOR_ALL_INTERFACES (vrf, ifp)
|
|
|
|
eigrp_distribute_update_interface(ifp);
|
|
|
|
}
|
2017-03-09 05:07:46 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* 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
|
|
|
*
|
2022-02-23 01:04:25 +01:00
|
|
|
* @return void
|
2017-03-09 05:07:46 +01:00
|
|
|
*
|
|
|
|
* @par
|
|
|
|
* Called when 10sec waiting time expire and
|
|
|
|
* executes Graceful restart for whole process
|
|
|
|
*/
|
2022-03-01 22:18:12 +01:00
|
|
|
void eigrp_distribute_timer_process(struct event *thread)
|
2017-03-09 05:07:46 +01:00
|
|
|
{
|
2017-04-08 20:44:58 +02:00
|
|
|
struct eigrp *eigrp;
|
2017-03-09 05:07:46 +01:00
|
|
|
|
2022-12-25 16:26:52 +01:00
|
|
|
eigrp = EVENT_ARG(thread);
|
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
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* @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
|
|
|
*
|
2022-02-23 01:04:25 +01:00
|
|
|
* @return void
|
2017-03-09 05:07:46 +01:00
|
|
|
*
|
|
|
|
* @par
|
|
|
|
* Called when 10sec waiting time expire and
|
|
|
|
* executes Graceful restart for interface
|
|
|
|
*/
|
2022-03-01 22:18:12 +01:00
|
|
|
void eigrp_distribute_timer_interface(struct event *thread)
|
2017-03-09 05:07:46 +01:00
|
|
|
{
|
2017-04-08 20:44:58 +02:00
|
|
|
struct eigrp_interface *ei;
|
2017-03-09 05:07:46 +01:00
|
|
|
|
2022-12-25 16:26:52 +01:00
|
|
|
ei = EVENT_ARG(thread);
|
2017-04-08 20:44:58 +02:00
|
|
|
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
|
|
|
}
|