eigrpd: Refactor access/prefix list applications

There was allot of code cut-n-pasting to
apply the prefix/access lists.  Refactor
to simplify code.

Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
This commit is contained in:
Donald Sharp 2017-08-26 09:15:58 -04:00
parent 3a45a729a3
commit 71b52ef23a
4 changed files with 76 additions and 233 deletions

View File

@ -83,6 +83,10 @@ extern int eigrp_hello_timer(struct thread *);
/* /*
* These externs are found in eigrp_update.c * These externs are found in eigrp_update.c
*/ */
extern bool eigrp_update_prefix_apply(struct eigrp *eigrp,
struct eigrp_interface *ei,
int in,
struct prefix *prefix);
extern void eigrp_update_send(struct eigrp_interface *); extern void eigrp_update_send(struct eigrp_interface *);
extern void eigrp_update_receive(struct eigrp *, struct ip *, extern void eigrp_update_receive(struct eigrp *, struct ip *,
struct eigrp_header *, struct stream *, struct eigrp_header *, struct stream *,

View File

@ -64,43 +64,20 @@ void eigrp_send_reply(struct eigrp_neighbor *nbr, struct eigrp_prefix_entry *pe)
{ {
struct eigrp_packet *ep; struct eigrp_packet *ep;
u_int16_t length = EIGRP_HEADER_LEN; u_int16_t length = EIGRP_HEADER_LEN;
struct eigrp_interface *ei = nbr->ei;
struct access_list *alist; struct eigrp *eigrp = ei->eigrp;
struct prefix_list *plist;
struct access_list *alist_i;
struct prefix_list *plist_i;
struct eigrp *e;
struct eigrp_prefix_entry *pe2; struct eigrp_prefix_entry *pe2;
// TODO: Work in progress // TODO: Work in progress
/* Filtering */ /* Filtering */
/* get list from eigrp process */ /* get list from eigrp process */
e = eigrp_lookup();
pe2 = XCALLOC(MTYPE_EIGRP_PREFIX_ENTRY, pe2 = XCALLOC(MTYPE_EIGRP_PREFIX_ENTRY,
sizeof(struct eigrp_prefix_entry)); sizeof(struct eigrp_prefix_entry));
memcpy(pe2, pe, sizeof(struct eigrp_prefix_entry)); memcpy(pe2, pe, sizeof(struct eigrp_prefix_entry));
/* Get access-lists and prefix-lists from process and interface */
alist = e->list[EIGRP_FILTER_OUT];
plist = e->prefix[EIGRP_FILTER_OUT];
alist_i = nbr->ei->list[EIGRP_FILTER_OUT];
plist_i = nbr->ei->prefix[EIGRP_FILTER_OUT];
/* Check if any list fits */ if (eigrp_update_prefix_apply(eigrp, ei,
if ((alist EIGRP_FILTER_OUT,
&& access_list_apply(alist, pe2->destination) pe2->destination)) {
== FILTER_DENY)
|| (plist
&& prefix_list_apply(plist,
pe2->destination)
== PREFIX_DENY)
|| (alist_i
&& access_list_apply(alist_i,
pe2->destination)
== FILTER_DENY)
|| (plist_i
&& prefix_list_apply(plist_i,
pe2->destination)
== PREFIX_DENY)) {
zlog_info("REPLY SEND: Setting Metric to max"); zlog_info("REPLY SEND: Setting Metric to max");
pe2->reported_metric.delay = EIGRP_MAX_METRIC; pe2->reported_metric.delay = EIGRP_MAX_METRIC;
@ -110,34 +87,34 @@ void eigrp_send_reply(struct eigrp_neighbor *nbr, struct eigrp_prefix_entry *pe)
* End of filtering * End of filtering
*/ */
ep = eigrp_packet_new(nbr->ei->ifp->mtu, nbr); ep = eigrp_packet_new(ei->ifp->mtu, nbr);
/* Prepare EIGRP INIT UPDATE header */ /* Prepare EIGRP INIT UPDATE header */
eigrp_packet_header_init(EIGRP_OPC_REPLY, e, ep->s, 0, eigrp_packet_header_init(EIGRP_OPC_REPLY, eigrp, ep->s, 0,
nbr->ei->eigrp->sequence_number, 0); eigrp->sequence_number, 0);
// encode Authentication TLV, if needed // encode Authentication TLV, if needed
if ((IF_DEF_PARAMS(nbr->ei->ifp)->auth_type == EIGRP_AUTH_TYPE_MD5) if ((IF_DEF_PARAMS(ei->ifp)->auth_type == EIGRP_AUTH_TYPE_MD5)
&& (IF_DEF_PARAMS(nbr->ei->ifp)->auth_keychain != NULL)) { && (IF_DEF_PARAMS(ei->ifp)->auth_keychain != NULL)) {
length += eigrp_add_authTLV_MD5_to_stream(ep->s, nbr->ei); length += eigrp_add_authTLV_MD5_to_stream(ep->s, ei);
} }
length += eigrp_add_internalTLV_to_stream(ep->s, pe2); length += eigrp_add_internalTLV_to_stream(ep->s, pe2);
if ((IF_DEF_PARAMS(nbr->ei->ifp)->auth_type == EIGRP_AUTH_TYPE_MD5) if ((IF_DEF_PARAMS(ei->ifp)->auth_type == EIGRP_AUTH_TYPE_MD5)
&& (IF_DEF_PARAMS(nbr->ei->ifp)->auth_keychain != NULL)) { && (IF_DEF_PARAMS(ei->ifp)->auth_keychain != NULL)) {
eigrp_make_md5_digest(nbr->ei, ep->s, EIGRP_AUTH_UPDATE_FLAG); eigrp_make_md5_digest(ei, ep->s, EIGRP_AUTH_UPDATE_FLAG);
} }
/* EIGRP Checksum */ /* EIGRP Checksum */
eigrp_packet_checksum(nbr->ei, ep->s, length); eigrp_packet_checksum(ei, ep->s, length);
ep->length = length; ep->length = length;
ep->dst.s_addr = nbr->src.s_addr; ep->dst.s_addr = nbr->src.s_addr;
/*This ack number we await from neighbor*/ /*This ack number we await from neighbor*/
ep->sequence_number = nbr->ei->eigrp->sequence_number; ep->sequence_number = eigrp->sequence_number;
/*Put packet to retransmission queue*/ /*Put packet to retransmission queue*/
eigrp_fifo_push(nbr->retrans_queue, ep); eigrp_fifo_push(nbr->retrans_queue, ep);
@ -157,12 +134,6 @@ void eigrp_reply_receive(struct eigrp *eigrp, struct ip *iph,
struct eigrp_neighbor *nbr; struct eigrp_neighbor *nbr;
struct TLV_IPv4_Internal_type *tlv; struct TLV_IPv4_Internal_type *tlv;
struct access_list *alist;
struct prefix_list *plist;
struct access_list *alist_i;
struct prefix_list *plist_i;
struct eigrp *e;
u_int16_t type; u_int16_t type;
/* increment statistics. */ /* increment statistics. */
@ -200,35 +171,9 @@ void eigrp_reply_receive(struct eigrp *eigrp, struct ip *iph,
struct eigrp_neighbor_entry *entry = struct eigrp_neighbor_entry *entry =
eigrp_prefix_entry_lookup(dest->entries, nbr); eigrp_prefix_entry_lookup(dest->entries, nbr);
/* if (eigrp_update_prefix_apply(eigrp, ei,
* Filtering EIGRP_FILTER_IN,
*/ &dest_addr)) {
// TODO: Work in progress
/* get list from eigrp process */
e = eigrp_lookup();
/* Get access-lists and prefix-lists from process and
* interface */
alist = e->list[EIGRP_FILTER_IN];
plist = e->prefix[EIGRP_FILTER_IN];
alist_i = ei->list[EIGRP_FILTER_IN];
plist_i = ei->prefix[EIGRP_FILTER_IN];
/* Check if any list fits */
if ((alist
&& access_list_apply(alist,
(struct prefix *)&dest_addr)
== FILTER_DENY)
|| (plist
&& prefix_list_apply(
plist, (struct prefix *)&dest_addr)
== PREFIX_DENY)
|| (alist_i
&& access_list_apply(
alist_i, (struct prefix *)&dest_addr)
== FILTER_DENY)
|| (plist_i
&& prefix_list_apply(
plist_i, (struct prefix *)&dest_addr)
== PREFIX_DENY)) {
tlv->metric.delay = EIGRP_MAX_METRIC; tlv->metric.delay = EIGRP_MAX_METRIC;
} }
/* /*

View File

@ -8,6 +8,12 @@
#ifndef EIGRPD_EIGRP_ROUTEMAP_H_ #ifndef EIGRPD_EIGRP_ROUTEMAP_H_
#define EIGRPD_EIGRP_ROUTEMAP_H_ #define EIGRPD_EIGRP_ROUTEMAP_H_
#include "if_rmap.h"
extern bool eigrp_routemap_prefix_apply(struct eigrp *eigrp,
struct eigrp_interface *ei,
int in,
struct prefix *prefix);
extern void eigrp_route_map_update(const char *); extern void eigrp_route_map_update(const char *);
extern void eigrp_route_map_init(); extern void eigrp_route_map_init();
extern void eigrp_if_rmap_update(struct if_rmap *); extern void eigrp_if_rmap_update(struct if_rmap *);

View File

@ -63,6 +63,32 @@
#include "eigrpd/eigrp_network.h" #include "eigrpd/eigrp_network.h"
#include "eigrpd/eigrp_memory.h" #include "eigrpd/eigrp_memory.h"
bool eigrp_update_prefix_apply(struct eigrp *eigrp,
struct eigrp_interface *ei,
int in, struct prefix *prefix)
{
struct access_list *alist;
struct prefix_list *plist;
alist = eigrp->list[in];
if (alist && access_list_apply(alist, prefix) == FILTER_DENY)
return true;
plist = eigrp->prefix[in];
if (plist && prefix_list_apply(plist, prefix) == PREFIX_DENY)
return true;
alist = ei->list[in];
if (alist && access_list_apply(alist, prefix) == FILTER_DENY)
return true;
plist = ei->prefix[in];
if (plist && prefix_list_apply(plist, prefix) == PREFIX_DENY)
return true;
return false;
}
/** /**
* @fn remove_received_prefix_gr * @fn remove_received_prefix_gr
* *
@ -155,8 +181,6 @@ void eigrp_update_receive(struct eigrp *eigrp, struct ip *iph,
u_int16_t type; u_int16_t type;
u_int16_t length; u_int16_t length;
u_char same; u_char same;
struct access_list *alist;
struct prefix_list *plist;
struct prefix dest_addr; struct prefix dest_addr;
u_char graceful_restart; u_char graceful_restart;
u_char graceful_restart_final; u_char graceful_restart_final;
@ -327,66 +351,10 @@ void eigrp_update_receive(struct eigrp *eigrp, struct ip *iph,
/* /*
* Filtering * Filtering
*/ */
/* if (eigrp_update_prefix_apply(eigrp, ei,
* Check if there is any access-list on EIGRP_FILTER_IN,
* interface (IN direction) &dest_addr))
* and set distance to max ne->reported_metric.delay = EIGRP_MAX_METRIC;
*/
alist = eigrp->list[EIGRP_FILTER_IN];
/* Check if access-list fits */
if (alist
&& access_list_apply(alist,
&dest_addr)
== FILTER_DENY) {
/* If yes, set reported metric to Max */
ne->reported_metric.delay =
EIGRP_MAX_METRIC;
} else {
ne->distance =
eigrp_calculate_total_metrics(
eigrp, ne);
}
plist = eigrp->prefix[EIGRP_FILTER_IN];
/* Check if prefix-list fits */
if (plist
&& prefix_list_apply(plist,
&dest_addr)
== PREFIX_DENY) {
/* If yes, set reported metric to Max */
ne->reported_metric.delay =
EIGRP_MAX_METRIC;
}
/*Get access-list from current interface */
alist = ei->list[EIGRP_FILTER_IN];
/* Check if access-list fits */
if (alist
&& access_list_apply(alist,
&dest_addr)
== FILTER_DENY) {
/* If yes, set reported metric to Max */
ne->reported_metric.delay =
EIGRP_MAX_METRIC;
}
plist = ei->prefix[EIGRP_FILTER_IN];
/* Check if prefix-list fits */
if (plist
&& prefix_list_apply(plist,
&dest_addr)
== PREFIX_DENY) {
/* If yes, set reported metric to Max */
ne->reported_metric.delay =
EIGRP_MAX_METRIC;
}
/*
* End of filtering
*/
ne->distance = eigrp_calculate_total_metrics( ne->distance = eigrp_calculate_total_metrics(
eigrp, ne); eigrp, ne);
@ -560,10 +528,6 @@ void eigrp_update_send_EOT(struct eigrp_neighbor *nbr)
struct eigrp_neighbor_entry *te; struct eigrp_neighbor_entry *te;
struct eigrp_prefix_entry *pe; struct eigrp_prefix_entry *pe;
struct listnode *node, *node2, *nnode, *nnode2; struct listnode *node, *node2, *nnode, *nnode2;
struct access_list *alist;
struct prefix_list *plist;
struct access_list *alist_i;
struct prefix_list *plist_i;
struct eigrp_interface *ei = nbr->ei; struct eigrp_interface *ei = nbr->ei;
struct eigrp *eigrp = ei->eigrp; struct eigrp *eigrp = ei->eigrp;
struct prefix *dest_addr; struct prefix *dest_addr;
@ -606,28 +570,12 @@ void eigrp_update_send_EOT(struct eigrp_neighbor *nbr)
/* Get destination address from prefix */ /* Get destination address from prefix */
dest_addr = pe->destination; dest_addr = pe->destination;
/*
* Filtering
*/
//TODO: Work in progress
/* Get access-lists and prefix-lists from process and interface */
alist = eigrp->list[EIGRP_FILTER_OUT];
plist = eigrp->prefix[EIGRP_FILTER_OUT];
alist_i = ei->list[EIGRP_FILTER_OUT];
plist_i = ei->prefix[EIGRP_FILTER_OUT];
/* Check if any list fits */ /* Check if any list fits */
if ((alist if (eigrp_update_prefix_apply(eigrp, ei,
&& access_list_apply (alist, EIGRP_FILTER_OUT,
dest_addr) == FILTER_DENY)|| dest_addr))
(plist && prefix_list_apply (plist,
dest_addr) == PREFIX_DENY)||
(alist_i && access_list_apply (alist_i,
dest_addr) == FILTER_DENY)||
(plist_i && prefix_list_apply (plist_i,
dest_addr) == PREFIX_DENY)) {
continue; continue;
} else { else {
length += eigrp_add_internalTLV_to_stream(ep->s, pe); length += eigrp_add_internalTLV_to_stream(ep->s, pe);
} }
} }
@ -643,10 +591,6 @@ void eigrp_update_send(struct eigrp_interface *ei)
struct listnode *node, *nnode; struct listnode *node, *nnode;
struct eigrp_prefix_entry *pe; struct eigrp_prefix_entry *pe;
u_char has_tlv; u_char has_tlv;
struct access_list *alist;
struct prefix_list *plist;
struct access_list *alist_i;
struct prefix_list *plist_i;
struct eigrp *eigrp = ei->eigrp; struct eigrp *eigrp = ei->eigrp;
struct prefix *dest_addr; struct prefix *dest_addr;
u_int32_t seq_no = eigrp->sequence_number; u_int32_t seq_no = eigrp->sequence_number;
@ -708,33 +652,9 @@ void eigrp_update_send(struct eigrp_interface *ei)
/* Get destination address from prefix */ /* Get destination address from prefix */
dest_addr = pe->destination; dest_addr = pe->destination;
/* if (eigrp_update_prefix_apply(eigrp, ei,
* Filtering EIGRP_FILTER_OUT,
*/ dest_addr)) {
/* Get access-lists and prefix-lists from process and
* interface */
alist = eigrp->list[EIGRP_FILTER_OUT];
plist = eigrp->prefix[EIGRP_FILTER_OUT];
alist_i = ei->list[EIGRP_FILTER_OUT];
plist_i = ei->prefix[EIGRP_FILTER_OUT];
/* Check if any list fits */
if ((alist
&& access_list_apply(alist,
dest_addr)
== FILTER_DENY)
|| (plist
&& prefix_list_apply(plist,
dest_addr)
== PREFIX_DENY)
|| (alist_i
&& access_list_apply(alist_i,
dest_addr)
== FILTER_DENY)
|| (plist_i
&& prefix_list_apply(plist_i,
dest_addr)
== PREFIX_DENY)) {
// pe->reported_metric.delay = EIGRP_MAX_METRIC; // pe->reported_metric.delay = EIGRP_MAX_METRIC;
continue; continue;
} else { } else {
@ -818,8 +738,6 @@ static void eigrp_update_send_GR_part(struct eigrp_neighbor *nbr)
struct prefix *dest_addr; struct prefix *dest_addr;
struct eigrp_interface *ei = nbr->ei; struct eigrp_interface *ei = nbr->ei;
struct eigrp *eigrp = ei->eigrp; struct eigrp *eigrp = ei->eigrp;
struct access_list *alist, *alist_i;
struct prefix_list *plist, *plist_i;
struct list *prefixes; struct list *prefixes;
u_int32_t flags; u_int32_t flags;
unsigned int send_prefixes; unsigned int send_prefixes;
@ -879,26 +797,10 @@ static void eigrp_update_send_GR_part(struct eigrp_neighbor *nbr)
* Filtering * Filtering
*/ */
dest_addr = pe->destination; dest_addr = pe->destination;
/* Get access-lists and prefix-lists from process and interface
*/
alist = eigrp->list[EIGRP_FILTER_OUT];
plist = eigrp->prefix[EIGRP_FILTER_OUT];
alist_i = ei->list[EIGRP_FILTER_OUT];
plist_i = ei->prefix[EIGRP_FILTER_OUT];
/* Check if any list fits */ if (eigrp_update_prefix_apply(eigrp, ei,
if ((alist EIGRP_FILTER_OUT,
&& access_list_apply(alist, dest_addr) dest_addr)) {
== FILTER_DENY)
|| (plist
&& prefix_list_apply(plist, dest_addr)
== PREFIX_DENY)
|| (alist_i
&& access_list_apply(alist_i, dest_addr)
== FILTER_DENY)
|| (plist_i
&& prefix_list_apply(plist_i, dest_addr)
== PREFIX_DENY)) {
/* do not send filtered route */ /* do not send filtered route */
zlog_info("Filtered prefix %s won't be sent out.", zlog_info("Filtered prefix %s won't be sent out.",
inet_ntoa(dest_addr->u.prefix4)); inet_ntoa(dest_addr->u.prefix4));
@ -908,24 +810,13 @@ static void eigrp_update_send_GR_part(struct eigrp_neighbor *nbr)
send_prefixes++; send_prefixes++;
} }
alist = eigrp->list[EIGRP_FILTER_IN]; /*
plist = eigrp->prefix[EIGRP_FILTER_IN]; * This makes no sense, Filter out then filter in???
alist_i = ei->list[EIGRP_FILTER_IN]; * Look into this more - DBS
plist_i = ei->prefix[EIGRP_FILTER_IN]; */
if (eigrp_update_prefix_apply(eigrp, ei,
/* Check if any list fits */ EIGRP_FILTER_IN,
if ((alist dest_addr)) {
&& access_list_apply(alist, dest_addr)
== FILTER_DENY)
|| (plist
&& prefix_list_apply(plist, dest_addr)
== PREFIX_DENY)
|| (alist_i
&& access_list_apply(alist_i, dest_addr)
== FILTER_DENY)
|| (plist_i
&& prefix_list_apply(plist_i, dest_addr)
== PREFIX_DENY)) {
/* do not send filtered route */ /* do not send filtered route */
zlog_info("Filtered prefix %s will be removed.", zlog_info("Filtered prefix %s will be removed.",
inet_ntoa(dest_addr->u.prefix4)); inet_ntoa(dest_addr->u.prefix4));
@ -949,9 +840,6 @@ static void eigrp_update_send_GR_part(struct eigrp_neighbor *nbr)
/* send message to FSM */ /* send message to FSM */
eigrp_fsm_event(&fsm_msg); eigrp_fsm_event(&fsm_msg);
} }
/*
* End of filtering
*/
/* NULL the pointer */ /* NULL the pointer */
dest_addr = NULL; dest_addr = NULL;