mirror of
https://github.com/FRRouting/frr.git
synced 2025-04-30 13:37:17 +02:00
Merge pull request #18482 from donaldsharp/eigrp_typesafe
Eigrp typesafe
This commit is contained in:
commit
38fd34f363
|
@ -81,11 +81,11 @@ static int config_write_debug(struct vty *vty)
|
|||
static int eigrp_neighbor_packet_queue_sum(struct eigrp_interface *ei)
|
||||
{
|
||||
struct eigrp_neighbor *nbr;
|
||||
struct listnode *node, *nnode;
|
||||
int sum;
|
||||
|
||||
sum = 0;
|
||||
|
||||
for (ALL_LIST_ELEMENTS(ei->nbrs, node, nnode, nbr)) {
|
||||
frr_each (eigrp_nbr_hash, &ei->nbr_hash_head, nbr) {
|
||||
sum += nbr->retrans_queue->count;
|
||||
}
|
||||
|
||||
|
@ -152,7 +152,7 @@ void show_ip_eigrp_interface_sub(struct vty *vty, struct eigrp *eigrp,
|
|||
vty_out(vty, "%-16s ", IF_NAME(ei));
|
||||
vty_out(vty, "%-11u", ei->params.bandwidth);
|
||||
vty_out(vty, "%-11u", ei->params.delay);
|
||||
vty_out(vty, "%-7u", ei->nbrs->count);
|
||||
vty_out(vty, "%-7zu", eigrp_nbr_hash_count(&ei->nbr_hash_head));
|
||||
vty_out(vty, "%u %c %-10u", 0, '/',
|
||||
eigrp_neighbor_packet_queue_sum(ei));
|
||||
vty_out(vty, "%-7u %-14u %-12u %-8u", 0, 0, 0, 0);
|
||||
|
@ -228,7 +228,7 @@ void show_ip_eigrp_prefix_descriptor(struct vty *vty,
|
|||
|
||||
vty_out(vty, "%-3c", (tn->state > 0) ? 'A' : 'P');
|
||||
|
||||
vty_out(vty, "%pFX, ", tn->destination);
|
||||
vty_out(vty, "%pFX, ", &tn->destination);
|
||||
vty_out(vty, "%u successors, ", (successors) ? successors->count : 0);
|
||||
vty_out(vty, "FD is %u, serno: %" PRIu64 " \n", tn->fdistance,
|
||||
tn->serno);
|
||||
|
|
|
@ -42,6 +42,7 @@
|
|||
#include "eigrpd/eigrp_const.h"
|
||||
#include "eigrpd/eigrp_filter.h"
|
||||
#include "eigrpd/eigrp_packet.h"
|
||||
#include "eigrpd/eigrp_interface.h"
|
||||
|
||||
/*
|
||||
* Distribute-list update functions.
|
||||
|
@ -126,10 +127,9 @@ void eigrp_distribute_update(struct distribute_ctx *ctx,
|
|||
|
||||
/*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)) {
|
||||
frr_each (eigrp_interface_hash, &e->eifs, ei2) {
|
||||
if (strcmp(ei2->ifp->name, ifp->name) == 0) {
|
||||
ei = ei2;
|
||||
break;
|
||||
|
|
|
@ -403,12 +403,10 @@ int eigrp_fsm_event(struct eigrp_fsm_action_message *msg)
|
|||
{
|
||||
enum eigrp_fsm_events event = eigrp_get_fsm_event(msg);
|
||||
|
||||
zlog_info(
|
||||
"EIGRP AS: %d State: %s Event: %s Network: %pI4 Packet Type: %s Reply RIJ Count: %d change: %s",
|
||||
msg->eigrp->AS, prefix_state2str(msg->prefix->state),
|
||||
fsm_state2str(event), &msg->prefix->destination->u.prefix4,
|
||||
packet_type2str(msg->packet_type), msg->prefix->rij->count,
|
||||
change2str(msg->change));
|
||||
zlog_info("EIGRP AS: %d State: %s Event: %s Network: %pFX Packet Type: %s Reply RIJ Count: %d change: %s",
|
||||
msg->eigrp->AS, prefix_state2str(msg->prefix->state), fsm_state2str(event),
|
||||
&msg->prefix->destination, packet_type2str(msg->packet_type),
|
||||
msg->prefix->rij->count, change2str(msg->change));
|
||||
(*(NSM[msg->prefix->state][event].func))(msg);
|
||||
|
||||
return 1;
|
||||
|
|
|
@ -496,7 +496,6 @@ static uint16_t eigrp_sequence_encode(struct eigrp *eigrp, struct stream *s)
|
|||
{
|
||||
uint16_t length = EIGRP_TLV_SEQ_BASE_LEN;
|
||||
struct eigrp_interface *ei;
|
||||
struct listnode *node, *node2, *nnode2;
|
||||
struct eigrp_neighbor *nbr;
|
||||
size_t backup_end, size_end;
|
||||
int found;
|
||||
|
@ -509,8 +508,8 @@ static uint16_t eigrp_sequence_encode(struct eigrp *eigrp, struct stream *s)
|
|||
stream_putc(s, IPV4_MAX_BYTELEN);
|
||||
|
||||
found = 0;
|
||||
for (ALL_LIST_ELEMENTS_RO(eigrp->eiflist, node, ei)) {
|
||||
for (ALL_LIST_ELEMENTS(ei->nbrs, node2, nnode2, nbr)) {
|
||||
frr_each (eigrp_interface_hash, &eigrp->eifs, ei) {
|
||||
frr_each (eigrp_nbr_hash, &ei->nbr_hash_head, nbr) {
|
||||
if (nbr->multicast_queue->count > 0) {
|
||||
length += (uint16_t)stream_put_ipv4(
|
||||
s, nbr->src.s_addr);
|
||||
|
|
|
@ -45,6 +45,16 @@
|
|||
|
||||
DEFINE_MTYPE_STATIC(EIGRPD, EIGRP_IF, "EIGRP interface");
|
||||
|
||||
int eigrp_interface_cmp(const struct eigrp_interface *a, const struct eigrp_interface *b)
|
||||
{
|
||||
return if_cmp_func(a->ifp, b->ifp);
|
||||
}
|
||||
|
||||
uint32_t eigrp_interface_hash(const struct eigrp_interface *ei)
|
||||
{
|
||||
return ei->ifp->ifindex;
|
||||
}
|
||||
|
||||
struct eigrp_interface *eigrp_if_new(struct eigrp *eigrp, struct interface *ifp,
|
||||
struct prefix *p)
|
||||
{
|
||||
|
@ -61,12 +71,12 @@ struct eigrp_interface *eigrp_if_new(struct eigrp *eigrp, struct interface *ifp,
|
|||
prefix_copy(&ei->address, p);
|
||||
|
||||
ifp->info = ei;
|
||||
listnode_add(eigrp->eiflist, ei);
|
||||
eigrp_interface_hash_add(&eigrp->eifs, ei);
|
||||
|
||||
ei->type = EIGRP_IFTYPE_BROADCAST;
|
||||
|
||||
/* Initialize neighbor list. */
|
||||
ei->nbrs = list_new();
|
||||
eigrp_nbr_hash_init(&ei->nbr_hash_head);
|
||||
|
||||
ei->crypt_seqnum = frr_sequence32_next();
|
||||
|
||||
|
@ -102,10 +112,10 @@ int eigrp_if_delete_hook(struct interface *ifp)
|
|||
if (!ei)
|
||||
return 0;
|
||||
|
||||
list_delete(&ei->nbrs);
|
||||
eigrp_nbr_hash_fini(&ei->nbr_hash_head);
|
||||
|
||||
eigrp = ei->eigrp;
|
||||
listnode_delete(eigrp->eiflist, ei);
|
||||
eigrp_interface_hash_del(&eigrp->eifs, ei);
|
||||
|
||||
eigrp_fifo_free(ei->obuf);
|
||||
|
||||
|
@ -238,7 +248,6 @@ int eigrp_if_up(struct eigrp_interface *ei)
|
|||
struct eigrp_route_descriptor *ne;
|
||||
struct eigrp_metrics metric;
|
||||
struct eigrp_interface *ei2;
|
||||
struct listnode *node, *nnode;
|
||||
struct eigrp *eigrp;
|
||||
|
||||
if (ei == NULL)
|
||||
|
@ -285,8 +294,7 @@ int eigrp_if_up(struct eigrp_interface *ei)
|
|||
if (pe == NULL) {
|
||||
pe = eigrp_prefix_descriptor_new();
|
||||
pe->serno = eigrp->serno;
|
||||
pe->destination = (struct prefix *)prefix_ipv4_new();
|
||||
prefix_copy(pe->destination, &dest_addr);
|
||||
prefix_copy(&pe->destination, &dest_addr);
|
||||
pe->af = AF_INET;
|
||||
pe->nt = EIGRP_TOPOLOGY_TYPE_CONNECTED;
|
||||
|
||||
|
@ -300,9 +308,8 @@ int eigrp_if_up(struct eigrp_interface *ei)
|
|||
|
||||
eigrp_route_descriptor_add(eigrp, pe, ne);
|
||||
|
||||
for (ALL_LIST_ELEMENTS(eigrp->eiflist, node, nnode, ei2)) {
|
||||
frr_each (eigrp_interface_hash, &eigrp->eifs, ei2)
|
||||
eigrp_update_send(ei2);
|
||||
}
|
||||
|
||||
pe->req_action &= ~EIGRP_FSM_NEED_UPDATE;
|
||||
listnode_delete(eigrp->topology_changes_internalIPV4, pe);
|
||||
|
@ -327,9 +334,6 @@ int eigrp_if_up(struct eigrp_interface *ei)
|
|||
|
||||
int eigrp_if_down(struct eigrp_interface *ei)
|
||||
{
|
||||
struct listnode *node, *nnode;
|
||||
struct eigrp_neighbor *nbr;
|
||||
|
||||
if (ei == NULL)
|
||||
return 0;
|
||||
|
||||
|
@ -340,9 +344,9 @@ int eigrp_if_down(struct eigrp_interface *ei)
|
|||
|
||||
/*Set infinite metrics to routes learned by this interface and start
|
||||
* query process*/
|
||||
for (ALL_LIST_ELEMENTS(ei->nbrs, node, nnode, nbr)) {
|
||||
eigrp_nbr_delete(nbr);
|
||||
}
|
||||
while (eigrp_nbr_hash_count(&ei->nbr_hash_head) > 0)
|
||||
eigrp_nbr_delete(eigrp_nbr_hash_first(&ei->nbr_hash_head));
|
||||
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
@ -436,8 +440,6 @@ void eigrp_if_free(struct eigrp_interface *ei, int source)
|
|||
pe);
|
||||
|
||||
eigrp_if_down(ei);
|
||||
|
||||
listnode_delete(ei->eigrp->eiflist, ei);
|
||||
}
|
||||
|
||||
/* Simulate down/up on the interface. This is needed, for example, when
|
||||
|
@ -457,10 +459,9 @@ struct eigrp_interface *eigrp_if_lookup_by_local_addr(struct eigrp *eigrp,
|
|||
struct interface *ifp,
|
||||
struct in_addr address)
|
||||
{
|
||||
struct listnode *node;
|
||||
struct eigrp_interface *ei;
|
||||
|
||||
for (ALL_LIST_ELEMENTS_RO(eigrp->eiflist, node, ei)) {
|
||||
frr_each (eigrp_interface_hash, &eigrp->eifs, ei) {
|
||||
if (ifp && ei->ifp != ifp)
|
||||
continue;
|
||||
|
||||
|
@ -486,10 +487,10 @@ struct eigrp_interface *eigrp_if_lookup_by_name(struct eigrp *eigrp,
|
|||
const char *if_name)
|
||||
{
|
||||
struct eigrp_interface *ei;
|
||||
struct listnode *node;
|
||||
|
||||
/* iterate over all eigrp interfaces */
|
||||
for (ALL_LIST_ELEMENTS_RO(eigrp->eiflist, node, ei)) {
|
||||
// XXX
|
||||
frr_each (eigrp_interface_hash, &eigrp->eifs, ei) {
|
||||
/* compare int name with eigrp interface's name */
|
||||
if (strcmp(ei->ifp->name, if_name) == 0) {
|
||||
return ei;
|
||||
|
|
|
@ -43,4 +43,10 @@ extern struct eigrp_interface *eigrp_if_lookup_by_name(struct eigrp *,
|
|||
/* Simulate down/up on the interface. */
|
||||
extern void eigrp_if_reset(struct interface *);
|
||||
|
||||
extern int eigrp_interface_cmp(const struct eigrp_interface *a, const struct eigrp_interface *b);
|
||||
extern uint32_t eigrp_interface_hash(const struct eigrp_interface *ei);
|
||||
|
||||
DECLARE_HASH(eigrp_interface_hash, struct eigrp_interface, eif_item, eigrp_interface_cmp,
|
||||
eigrp_interface_hash);
|
||||
|
||||
#endif /* ZEBRA_EIGRP_INTERFACE_H_ */
|
||||
|
|
|
@ -98,6 +98,7 @@ static void sigint(void)
|
|||
|
||||
keychain_terminate();
|
||||
|
||||
route_map_finish();
|
||||
eigrp_terminate();
|
||||
|
||||
exit(0);
|
||||
|
|
|
@ -41,6 +41,21 @@
|
|||
|
||||
DEFINE_MTYPE_STATIC(EIGRPD, EIGRP_NEIGHBOR, "EIGRP neighbor");
|
||||
|
||||
int eigrp_nbr_comp(const struct eigrp_neighbor *a, const struct eigrp_neighbor *b)
|
||||
{
|
||||
if (a->src.s_addr == b->src.s_addr)
|
||||
return 0;
|
||||
else if (a->src.s_addr < b->src.s_addr)
|
||||
return -1;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
uint32_t eigrp_nbr_hash(const struct eigrp_neighbor *a)
|
||||
{
|
||||
return a->src.s_addr;
|
||||
}
|
||||
|
||||
struct eigrp_neighbor *eigrp_nbr_new(struct eigrp_interface *ei)
|
||||
{
|
||||
struct eigrp_neighbor *nbr;
|
||||
|
@ -80,17 +95,18 @@ struct eigrp_neighbor *eigrp_nbr_get(struct eigrp_interface *ei,
|
|||
struct eigrp_header *eigrph,
|
||||
struct ip *iph)
|
||||
{
|
||||
struct eigrp_neighbor *nbr;
|
||||
struct listnode *node, *nnode;
|
||||
struct eigrp_neighbor lookup, *nbr;
|
||||
|
||||
for (ALL_LIST_ELEMENTS(ei->nbrs, node, nnode, nbr)) {
|
||||
if (iph->ip_src.s_addr == nbr->src.s_addr) {
|
||||
return nbr;
|
||||
}
|
||||
lookup.src = iph->ip_src;
|
||||
lookup.ei = ei;
|
||||
|
||||
nbr = eigrp_nbr_hash_find(&ei->nbr_hash_head, &lookup);
|
||||
if (nbr) {
|
||||
return nbr;
|
||||
}
|
||||
|
||||
nbr = eigrp_nbr_add(ei, eigrph, iph);
|
||||
listnode_add(ei->nbrs, nbr);
|
||||
eigrp_nbr_hash_add(&ei->nbr_hash_head, nbr);
|
||||
|
||||
return nbr;
|
||||
}
|
||||
|
@ -110,16 +126,12 @@ struct eigrp_neighbor *eigrp_nbr_get(struct eigrp_interface *ei,
|
|||
struct eigrp_neighbor *eigrp_nbr_lookup_by_addr(struct eigrp_interface *ei,
|
||||
struct in_addr *addr)
|
||||
{
|
||||
struct eigrp_neighbor *nbr;
|
||||
struct listnode *node, *nnode;
|
||||
struct eigrp_neighbor lookup, *nbr;
|
||||
|
||||
for (ALL_LIST_ELEMENTS(ei->nbrs, node, nnode, nbr)) {
|
||||
if (addr->s_addr == nbr->src.s_addr) {
|
||||
return nbr;
|
||||
}
|
||||
}
|
||||
lookup.src = *addr;
|
||||
nbr = eigrp_nbr_hash_find(&ei->nbr_hash_head, &lookup);
|
||||
|
||||
return NULL;
|
||||
return nbr;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -138,17 +150,15 @@ struct eigrp_neighbor *eigrp_nbr_lookup_by_addr_process(struct eigrp *eigrp,
|
|||
struct in_addr nbr_addr)
|
||||
{
|
||||
struct eigrp_interface *ei;
|
||||
struct listnode *node, *node2, *nnode2;
|
||||
struct eigrp_neighbor *nbr;
|
||||
struct eigrp_neighbor lookup, *nbr;
|
||||
|
||||
/* iterate over all eigrp interfaces */
|
||||
for (ALL_LIST_ELEMENTS_RO(eigrp->eiflist, node, ei)) {
|
||||
frr_each (eigrp_interface_hash, &eigrp->eifs, ei) {
|
||||
/* iterate over all neighbors on eigrp interface */
|
||||
for (ALL_LIST_ELEMENTS(ei->nbrs, node2, nnode2, nbr)) {
|
||||
/* compare if neighbor address is same as arg address */
|
||||
if (nbr->src.s_addr == nbr_addr.s_addr) {
|
||||
return nbr;
|
||||
}
|
||||
lookup.src = nbr_addr;
|
||||
nbr = eigrp_nbr_hash_find(&ei->nbr_hash_head, &lookup);
|
||||
if (nbr) {
|
||||
return nbr;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -170,7 +180,7 @@ void eigrp_nbr_delete(struct eigrp_neighbor *nbr)
|
|||
EVENT_OFF(nbr->t_holddown);
|
||||
|
||||
if (nbr->ei)
|
||||
listnode_delete(nbr->ei->nbrs, nbr);
|
||||
eigrp_nbr_hash_del(&nbr->ei->nbr_hash_head, nbr);
|
||||
XFREE(MTYPE_EIGRP_NEIGHBOR, nbr);
|
||||
}
|
||||
|
||||
|
@ -278,18 +288,12 @@ void eigrp_nbr_state_update(struct eigrp_neighbor *nbr)
|
|||
int eigrp_nbr_count_get(struct eigrp *eigrp)
|
||||
{
|
||||
struct eigrp_interface *iface;
|
||||
struct listnode *node, *node2, *nnode2;
|
||||
struct eigrp_neighbor *nbr;
|
||||
uint32_t counter;
|
||||
|
||||
counter = 0;
|
||||
for (ALL_LIST_ELEMENTS_RO(eigrp->eiflist, node, iface)) {
|
||||
for (ALL_LIST_ELEMENTS(iface->nbrs, node2, nnode2, nbr)) {
|
||||
if (nbr->state == EIGRP_NEIGHBOR_UP) {
|
||||
counter++;
|
||||
}
|
||||
}
|
||||
}
|
||||
frr_each (eigrp_interface_hash, &eigrp->eifs, iface)
|
||||
counter += eigrp_nbr_hash_count(&iface->nbr_hash_head);
|
||||
|
||||
return counter;
|
||||
}
|
||||
|
||||
|
|
|
@ -26,8 +26,6 @@ extern void eigrp_nbr_delete(struct eigrp_neighbor *neigh);
|
|||
|
||||
extern void holddown_timer_expired(struct event *thread);
|
||||
|
||||
extern int eigrp_neighborship_check(struct eigrp_neighbor *neigh,
|
||||
struct TLV_Parameter_Type *tlv);
|
||||
extern void eigrp_nbr_state_update(struct eigrp_neighbor *neigh);
|
||||
extern void eigrp_nbr_state_set(struct eigrp_neighbor *neigh, uint8_t state);
|
||||
extern uint8_t eigrp_nbr_state_get(struct eigrp_neighbor *neigh);
|
||||
|
@ -41,4 +39,9 @@ extern void eigrp_nbr_hard_restart(struct eigrp_neighbor *nbr, struct vty *vty);
|
|||
|
||||
extern int eigrp_nbr_split_horizon_check(struct eigrp_route_descriptor *ne,
|
||||
struct eigrp_interface *ei);
|
||||
|
||||
extern int eigrp_nbr_comp(const struct eigrp_neighbor *a, const struct eigrp_neighbor *b);
|
||||
extern uint32_t eigrp_nbr_hash(const struct eigrp_neighbor *a);
|
||||
|
||||
DECLARE_HASH(eigrp_nbr_hash, struct eigrp_neighbor, nbr_hash_item, eigrp_nbr_comp, eigrp_nbr_hash);
|
||||
#endif /* _ZEBRA_EIGRP_NEIGHBOR_H */
|
||||
|
|
|
@ -219,6 +219,21 @@ int eigrp_network_set(struct eigrp *eigrp, struct prefix *p)
|
|||
return 1;
|
||||
}
|
||||
|
||||
static void eigrp_network_delete_all(struct eigrp *eigrp, struct route_table *table)
|
||||
{
|
||||
struct route_node *rn;
|
||||
|
||||
for (rn = route_top(table); rn; rn = route_next(rn)) {
|
||||
prefix_free((struct prefix **)&rn->info);
|
||||
}
|
||||
}
|
||||
|
||||
void eigrp_network_free(struct eigrp *eigrp, struct route_table *table)
|
||||
{
|
||||
eigrp_network_delete_all(eigrp, table);
|
||||
route_table_finish(table);
|
||||
}
|
||||
|
||||
/* Check whether interface matches given network
|
||||
* returns: 1, true. 0, false
|
||||
*/
|
||||
|
@ -262,7 +277,6 @@ static void eigrp_network_run_interface(struct eigrp *eigrp, struct prefix *p,
|
|||
|
||||
void eigrp_if_update(struct interface *ifp)
|
||||
{
|
||||
struct listnode *node, *nnode;
|
||||
struct route_node *rn;
|
||||
struct eigrp *eigrp;
|
||||
|
||||
|
@ -270,7 +284,7 @@ void eigrp_if_update(struct interface *ifp)
|
|||
* In the event there are multiple eigrp autonymnous systems running,
|
||||
* we need to check eac one and add the interface as approperate
|
||||
*/
|
||||
for (ALL_LIST_ELEMENTS(eigrp_om->eigrp, node, nnode, eigrp)) {
|
||||
frr_each (eigrp_master_hash, &eigrp_om->eigrp, eigrp) {
|
||||
if (ifp->vrf->vrf_id != eigrp->vrf_id)
|
||||
continue;
|
||||
|
||||
|
@ -289,7 +303,6 @@ void eigrp_if_update(struct interface *ifp)
|
|||
int eigrp_network_unset(struct eigrp *eigrp, struct prefix *p)
|
||||
{
|
||||
struct route_node *rn;
|
||||
struct listnode *node, *nnode;
|
||||
struct eigrp_interface *ei;
|
||||
struct prefix *pref;
|
||||
|
||||
|
@ -307,7 +320,7 @@ int eigrp_network_unset(struct eigrp *eigrp, struct prefix *p)
|
|||
route_unlock_node(rn); /* initial reference */
|
||||
|
||||
/* Find interfaces that not configured already. */
|
||||
for (ALL_LIST_ELEMENTS(eigrp->eiflist, node, nnode, ei)) {
|
||||
frr_each (eigrp_interface_hash, &eigrp->eifs, ei) {
|
||||
bool found = false;
|
||||
|
||||
for (rn = route_top(eigrp->networks); rn; rn = route_next(rn)) {
|
||||
|
|
|
@ -19,6 +19,7 @@ extern int eigrp_sock_init(struct vrf *vrf);
|
|||
extern int eigrp_if_ipmulticast(struct eigrp *, struct prefix *, unsigned int);
|
||||
extern int eigrp_network_set(struct eigrp *eigrp, struct prefix *p);
|
||||
extern int eigrp_network_unset(struct eigrp *eigrp, struct prefix *p);
|
||||
extern void eigrp_network_free(struct eigrp *eigrp, struct route_table *table);
|
||||
|
||||
extern void eigrp_hello_timer(struct event *thread);
|
||||
extern void eigrp_if_update(struct interface *);
|
||||
|
|
|
@ -43,13 +43,11 @@ static void redistribute_get_metrics(const struct lyd_node *dnode,
|
|||
em->reliability = yang_dnode_get_uint32(dnode, "reliability");
|
||||
}
|
||||
|
||||
static struct eigrp_interface *eigrp_interface_lookup(const struct eigrp *eigrp,
|
||||
const char *ifname)
|
||||
static struct eigrp_interface *eigrp_interface_lookup(struct eigrp *eigrp, const char *ifname)
|
||||
{
|
||||
struct eigrp_interface *eif;
|
||||
struct listnode *ln;
|
||||
|
||||
for (ALL_LIST_ELEMENTS_RO(eigrp->eiflist, ln, eif)) {
|
||||
frr_each (eigrp_interface_hash, &eigrp->eifs, eif) {
|
||||
if (strcmp(ifname, eif->ifp->name))
|
||||
continue;
|
||||
|
||||
|
|
|
@ -532,8 +532,8 @@ void eigrp_read(struct event *thread)
|
|||
return;
|
||||
|
||||
/* Self-originated packet should be discarded silently. */
|
||||
if (eigrp_if_lookup_by_local_addr(eigrp, NULL, iph->ip_src)
|
||||
|| (IPV4_ADDR_SAME(&srcaddr, &ei->address.u.prefix4))) {
|
||||
if (eigrp_if_lookup_by_local_addr(eigrp, ifp, iph->ip_src) ||
|
||||
(IPV4_ADDR_SAME(&srcaddr, &ei->address.u.prefix4))) {
|
||||
if (IS_DEBUG_EIGRP_TRANSMIT(0, RECV))
|
||||
zlog_debug(
|
||||
"eigrp_read[%pI4]: Dropping self-originated packet",
|
||||
|
@ -1129,7 +1129,7 @@ uint16_t eigrp_add_internalTLV_to_stream(struct stream *s,
|
|||
uint16_t length;
|
||||
|
||||
stream_putw(s, EIGRP_TLV_IPv4_INT);
|
||||
switch (pe->destination->prefixlen) {
|
||||
switch (pe->destination.prefixlen) {
|
||||
case 0:
|
||||
case 1:
|
||||
case 2:
|
||||
|
@ -1176,8 +1176,8 @@ uint16_t eigrp_add_internalTLV_to_stream(struct stream *s,
|
|||
stream_putw(s, length);
|
||||
break;
|
||||
default:
|
||||
flog_err(EC_LIB_DEVELOPMENT, "%s: Unexpected prefix length: %d",
|
||||
__func__, pe->destination->prefixlen);
|
||||
flog_err(EC_LIB_DEVELOPMENT, "%s: Unexpected prefix length: %d", __func__,
|
||||
pe->destination.prefixlen);
|
||||
return 0;
|
||||
}
|
||||
stream_putl(s, 0x00000000);
|
||||
|
@ -1194,15 +1194,15 @@ uint16_t eigrp_add_internalTLV_to_stream(struct stream *s,
|
|||
stream_putc(s, pe->reported_metric.tag);
|
||||
stream_putc(s, pe->reported_metric.flags);
|
||||
|
||||
stream_putc(s, pe->destination->prefixlen);
|
||||
stream_putc(s, pe->destination.prefixlen);
|
||||
|
||||
stream_putc(s, (ntohl(pe->destination->u.prefix4.s_addr) >> 24) & 0xFF);
|
||||
if (pe->destination->prefixlen > 8)
|
||||
stream_putc(s, (ntohl(pe->destination->u.prefix4.s_addr) >> 16) & 0xFF);
|
||||
if (pe->destination->prefixlen > 16)
|
||||
stream_putc(s, (ntohl(pe->destination->u.prefix4.s_addr) >> 8) & 0xFF);
|
||||
if (pe->destination->prefixlen > 24)
|
||||
stream_putc(s, ntohl(pe->destination->u.prefix4.s_addr) & 0xFF);
|
||||
stream_putc(s, (ntohl(pe->destination.u.prefix4.s_addr) >> 24) & 0xFF);
|
||||
if (pe->destination.prefixlen > 8)
|
||||
stream_putc(s, (ntohl(pe->destination.u.prefix4.s_addr) >> 16) & 0xFF);
|
||||
if (pe->destination.prefixlen > 16)
|
||||
stream_putc(s, (ntohl(pe->destination.u.prefix4.s_addr) >> 8) & 0xFF);
|
||||
if (pe->destination.prefixlen > 24)
|
||||
stream_putc(s, ntohl(pe->destination.u.prefix4.s_addr) & 0xFF);
|
||||
|
||||
return length;
|
||||
}
|
||||
|
|
|
@ -41,7 +41,7 @@
|
|||
uint32_t eigrp_query_send_all(struct eigrp *eigrp)
|
||||
{
|
||||
struct eigrp_interface *iface;
|
||||
struct listnode *node, *node2, *nnode2;
|
||||
struct listnode *node2, *nnode2;
|
||||
struct eigrp_prefix_descriptor *pe;
|
||||
uint32_t counter;
|
||||
|
||||
|
@ -51,7 +51,7 @@ uint32_t eigrp_query_send_all(struct eigrp *eigrp)
|
|||
}
|
||||
|
||||
counter = 0;
|
||||
for (ALL_LIST_ELEMENTS_RO(eigrp->eiflist, node, iface)) {
|
||||
frr_each (eigrp_interface_hash, &eigrp->eifs, iface) {
|
||||
eigrp_send_query(iface);
|
||||
counter++;
|
||||
}
|
||||
|
@ -146,7 +146,7 @@ void eigrp_send_query(struct eigrp_interface *ei)
|
|||
{
|
||||
struct eigrp_packet *ep = NULL;
|
||||
uint16_t length = EIGRP_HEADER_LEN;
|
||||
struct listnode *node, *nnode, *node2, *nnode2;
|
||||
struct listnode *node, *nnode;
|
||||
struct eigrp_neighbor *nbr;
|
||||
struct eigrp_prefix_descriptor *pe;
|
||||
bool has_tlv = false;
|
||||
|
@ -177,7 +177,7 @@ void eigrp_send_query(struct eigrp_interface *ei)
|
|||
|
||||
length += eigrp_add_internalTLV_to_stream(ep->s, pe);
|
||||
has_tlv = true;
|
||||
for (ALL_LIST_ELEMENTS(ei->nbrs, node2, nnode2, nbr)) {
|
||||
frr_each (eigrp_nbr_hash, &ei->nbr_hash_head, nbr) {
|
||||
if (nbr->state == EIGRP_NEIGHBOR_UP)
|
||||
listnode_add(pe->rij, nbr);
|
||||
}
|
||||
|
@ -197,7 +197,7 @@ void eigrp_send_query(struct eigrp_interface *ei)
|
|||
ep->sequence_number = ei->eigrp->sequence_number;
|
||||
ei->eigrp->sequence_number++;
|
||||
|
||||
for (ALL_LIST_ELEMENTS(ei->nbrs, node2, nnode2, nbr)) {
|
||||
frr_each (eigrp_nbr_hash, &ei->nbr_hash_head, nbr) {
|
||||
struct eigrp_packet *dup;
|
||||
|
||||
if (nbr->state != EIGRP_NEIGHBOR_UP)
|
||||
|
@ -237,7 +237,7 @@ void eigrp_send_query(struct eigrp_interface *ei)
|
|||
ep->sequence_number = ei->eigrp->sequence_number;
|
||||
ei->eigrp->sequence_number++;
|
||||
|
||||
for (ALL_LIST_ELEMENTS(ei->nbrs, node2, nnode2, nbr)) {
|
||||
frr_each (eigrp_nbr_hash, &ei->nbr_hash_head, nbr) {
|
||||
struct eigrp_packet *dup;
|
||||
|
||||
if (nbr->state != EIGRP_NEIGHBOR_UP)
|
||||
|
|
|
@ -61,8 +61,7 @@ void eigrp_send_reply(struct eigrp_neighbor *nbr,
|
|||
sizeof(struct eigrp_prefix_descriptor));
|
||||
memcpy(pe2, pe, sizeof(struct eigrp_prefix_descriptor));
|
||||
|
||||
if (eigrp_update_prefix_apply(eigrp, ei, EIGRP_FILTER_OUT,
|
||||
pe2->destination)) {
|
||||
if (eigrp_update_prefix_apply(eigrp, ei, EIGRP_FILTER_OUT, &pe2->destination)) {
|
||||
zlog_info("REPLY SEND: Setting Metric to max");
|
||||
pe2->reported_metric.delay = EIGRP_MAX_METRIC;
|
||||
}
|
||||
|
|
|
@ -43,7 +43,6 @@ void eigrp_if_rmap_update(struct if_rmap *if_rmap)
|
|||
{
|
||||
struct interface *ifp;
|
||||
struct eigrp_interface *ei, *ei2;
|
||||
struct listnode *node, *nnode;
|
||||
struct route_map *rmap;
|
||||
struct eigrp *e;
|
||||
|
||||
|
@ -53,7 +52,7 @@ void eigrp_if_rmap_update(struct if_rmap *if_rmap)
|
|||
|
||||
ei = NULL;
|
||||
e = eigrp_lookup();
|
||||
for (ALL_LIST_ELEMENTS(e->eiflist, node, nnode, ei2)) {
|
||||
frr_each (eigrp_interface_hash, &e->eifs, ei2) {
|
||||
if (strcmp(ei2->ifp->name, ifp->name) == 0) {
|
||||
ei = ei2;
|
||||
break;
|
||||
|
|
|
@ -43,7 +43,11 @@ struct eigrp_extdata {
|
|||
uint8_t flags;
|
||||
};
|
||||
|
||||
PREDECL_HASH(eigrp_interface_hash);
|
||||
PREDECL_HASH(eigrp_master_hash);
|
||||
struct eigrp {
|
||||
struct eigrp_master_hash_item eigrp_item;
|
||||
|
||||
vrf_id_t vrf_id;
|
||||
|
||||
uint16_t AS; /* Autonomous system number */
|
||||
|
@ -59,7 +63,7 @@ struct eigrp {
|
|||
struct in_addr router_id; /* Configured automatically. */
|
||||
struct in_addr router_id_static; /* Configured manually. */
|
||||
|
||||
struct list *eiflist; /* eigrp interfaces */
|
||||
struct eigrp_interface_hash_head eifs;
|
||||
uint8_t passive_interface_default; /* passive-interface default */
|
||||
|
||||
int fd;
|
||||
|
@ -133,8 +137,12 @@ enum { MEMBER_ALLROUTERS = 0,
|
|||
MEMBER_MAX,
|
||||
};
|
||||
|
||||
PREDECL_HASH(eigrp_nbr_hash);
|
||||
|
||||
/*EIGRP interface structure*/
|
||||
struct eigrp_interface {
|
||||
struct eigrp_interface_hash_item eif_item;
|
||||
|
||||
struct eigrp_if_params params;
|
||||
|
||||
/*multicast group refcnts */
|
||||
|
@ -162,7 +170,7 @@ struct eigrp_interface {
|
|||
struct prefix address; /* Interface prefix */
|
||||
|
||||
/* Neighbor information. */
|
||||
struct list *nbrs; /* EIGRP Neighbor List */
|
||||
struct eigrp_nbr_hash_head nbr_hash_head;
|
||||
|
||||
/* Threads. */
|
||||
struct event *t_hello; /* timer */
|
||||
|
@ -208,6 +216,8 @@ enum Packet_part_type {
|
|||
|
||||
/* Neighbor Data Structure */
|
||||
struct eigrp_neighbor {
|
||||
struct eigrp_nbr_hash_item nbr_hash_item;
|
||||
|
||||
/* This neighbor's parent eigrp interface. */
|
||||
struct eigrp_interface *ei;
|
||||
|
||||
|
@ -437,7 +447,7 @@ struct eigrp_prefix_descriptor {
|
|||
uint8_t af; // address family
|
||||
uint8_t req_action; // required action
|
||||
|
||||
struct prefix *destination;
|
||||
struct prefix destination;
|
||||
|
||||
// If network type is REMOTE_EXTERNAL, pointer will have reference to
|
||||
// its external TLV
|
||||
|
|
|
@ -68,7 +68,6 @@ struct eigrp_prefix_descriptor *eigrp_prefix_descriptor_new(void)
|
|||
new->rij = list_new();
|
||||
new->entries->cmp = (int (*)(void *, void *))eigrp_route_descriptor_cmp;
|
||||
new->distance = new->fdistance = new->rdistance = EIGRP_MAX_METRIC;
|
||||
new->destination = NULL;
|
||||
|
||||
return new;
|
||||
}
|
||||
|
@ -120,12 +119,11 @@ void eigrp_prefix_descriptor_add(struct route_table *topology,
|
|||
{
|
||||
struct route_node *rn;
|
||||
|
||||
rn = route_node_get(topology, pe->destination);
|
||||
rn = route_node_get(topology, &pe->destination);
|
||||
if (rn->info) {
|
||||
if (IS_DEBUG_EIGRP_EVENT)
|
||||
zlog_debug(
|
||||
"%s: %pFX Should we have found this entry in the topo table?",
|
||||
__func__, pe->destination);
|
||||
zlog_debug("%s: %pFX Should we have found this entry in the topo table?",
|
||||
__func__, &pe->destination);
|
||||
route_unlock_node(rn);
|
||||
}
|
||||
|
||||
|
@ -147,8 +145,7 @@ void eigrp_route_descriptor_add(struct eigrp *eigrp,
|
|||
listnode_add_sort(node->entries, entry);
|
||||
entry->prefix = node;
|
||||
|
||||
eigrp_zebra_route_add(eigrp, node->destination,
|
||||
l, node->fdistance);
|
||||
eigrp_zebra_route_add(eigrp, &node->destination, l, node->fdistance);
|
||||
}
|
||||
|
||||
list_delete(&l);
|
||||
|
@ -168,7 +165,7 @@ void eigrp_prefix_descriptor_delete(struct eigrp *eigrp,
|
|||
if (!eigrp)
|
||||
return;
|
||||
|
||||
rn = route_node_lookup(table, pe->destination);
|
||||
rn = route_node_lookup(table, &pe->destination);
|
||||
if (!rn)
|
||||
return;
|
||||
|
||||
|
@ -182,8 +179,7 @@ void eigrp_prefix_descriptor_delete(struct eigrp *eigrp,
|
|||
eigrp_route_descriptor_delete(eigrp, pe, ne);
|
||||
list_delete(&pe->entries);
|
||||
list_delete(&pe->rij);
|
||||
eigrp_zebra_route_delete(eigrp, pe->destination);
|
||||
prefix_free(&pe->destination);
|
||||
eigrp_zebra_route_delete(eigrp, &pe->destination);
|
||||
|
||||
rn->info = NULL;
|
||||
route_unlock_node(rn); // Lookup above
|
||||
|
@ -200,7 +196,7 @@ void eigrp_route_descriptor_delete(struct eigrp *eigrp,
|
|||
{
|
||||
if (listnode_lookup(node->entries, entry) != NULL) {
|
||||
listnode_delete(node->entries, entry);
|
||||
eigrp_zebra_route_delete(eigrp, node->destination);
|
||||
eigrp_zebra_route_delete(eigrp, &node->destination);
|
||||
XFREE(MTYPE_EIGRP_ROUTE_DESCRIPTOR, entry);
|
||||
}
|
||||
}
|
||||
|
@ -462,14 +458,13 @@ void eigrp_update_routing_table(struct eigrp *eigrp,
|
|||
successors = eigrp_topology_get_successor_max(prefix, eigrp->max_paths);
|
||||
|
||||
if (successors) {
|
||||
eigrp_zebra_route_add(eigrp, prefix->destination, successors,
|
||||
prefix->fdistance);
|
||||
eigrp_zebra_route_add(eigrp, &prefix->destination, successors, prefix->fdistance);
|
||||
for (ALL_LIST_ELEMENTS_RO(successors, node, entry))
|
||||
entry->flags |= EIGRP_ROUTE_DESCRIPTOR_INTABLE_FLAG;
|
||||
|
||||
list_delete(&successors);
|
||||
} else {
|
||||
eigrp_zebra_route_delete(eigrp, prefix->destination);
|
||||
eigrp_zebra_route_delete(eigrp, &prefix->destination);
|
||||
for (ALL_LIST_ELEMENTS_RO(prefix->entries, node, entry))
|
||||
entry->flags &= ~EIGRP_ROUTE_DESCRIPTOR_INTABLE_FLAG;
|
||||
}
|
||||
|
|
|
@ -128,8 +128,7 @@ static void eigrp_update_receive_GR_ask(struct eigrp *eigrp,
|
|||
|
||||
/* iterate over all prefixes which weren't advertised by neighbor */
|
||||
for (ALL_LIST_ELEMENTS_RO(nbr_prefixes, node1, prefix)) {
|
||||
zlog_debug("GR receive: Neighbor not advertised %pFX",
|
||||
prefix->destination);
|
||||
zlog_debug("GR receive: Neighbor not advertised %pFX", &prefix->destination);
|
||||
|
||||
fsm_msg.metrics = prefix->reported_metric;
|
||||
/* set delay to MAX */
|
||||
|
@ -320,9 +319,7 @@ void eigrp_update_receive(struct eigrp *eigrp, struct ip *iph,
|
|||
/*Here comes topology information save*/
|
||||
pe = eigrp_prefix_descriptor_new();
|
||||
pe->serno = eigrp->serno;
|
||||
pe->destination =
|
||||
(struct prefix *)prefix_ipv4_new();
|
||||
prefix_copy(pe->destination, &dest_addr);
|
||||
prefix_copy(&pe->destination, &dest_addr);
|
||||
pe->af = AF_INET;
|
||||
pe->state = EIGRP_FSM_STATE_PASSIVE;
|
||||
pe->nt = EIGRP_TOPOLOGY_TYPE_REMOTE;
|
||||
|
@ -482,11 +479,10 @@ static void eigrp_update_place_on_nbr_queue(struct eigrp_neighbor *nbr,
|
|||
static void eigrp_update_send_to_all_nbrs(struct eigrp_interface *ei,
|
||||
struct eigrp_packet *ep)
|
||||
{
|
||||
struct listnode *node, *nnode;
|
||||
struct eigrp_neighbor *nbr;
|
||||
bool packet_sent = false;
|
||||
|
||||
for (ALL_LIST_ELEMENTS(ei->nbrs, node, nnode, nbr)) {
|
||||
frr_each (eigrp_nbr_hash, &ei->nbr_hash_head, nbr) {
|
||||
struct eigrp_packet *ep_dup;
|
||||
|
||||
if (nbr->state != EIGRP_NEIGHBOR_UP)
|
||||
|
@ -567,7 +563,7 @@ void eigrp_update_send_EOT(struct eigrp_neighbor *nbr)
|
|||
}
|
||||
}
|
||||
/* Get destination address from prefix */
|
||||
dest_addr = pe->destination;
|
||||
dest_addr = &pe->destination;
|
||||
|
||||
/* Check if any list fits */
|
||||
if (eigrp_update_prefix_apply(
|
||||
|
@ -595,7 +591,7 @@ void eigrp_update_send(struct eigrp_interface *ei)
|
|||
uint32_t seq_no = eigrp->sequence_number;
|
||||
uint16_t eigrp_mtu = EIGRP_PACKET_MTU(ei->ifp->mtu);
|
||||
|
||||
if (ei->nbrs->count == 0)
|
||||
if (eigrp_nbr_hash_count(&ei->nbr_hash_head) == 0)
|
||||
return;
|
||||
|
||||
uint16_t length = EIGRP_HEADER_LEN;
|
||||
|
@ -651,7 +647,7 @@ void eigrp_update_send(struct eigrp_interface *ei)
|
|||
has_tlv = 0;
|
||||
}
|
||||
/* Get destination address from prefix */
|
||||
dest_addr = pe->destination;
|
||||
dest_addr = &pe->destination;
|
||||
|
||||
if (eigrp_update_prefix_apply(eigrp, ei, EIGRP_FILTER_OUT,
|
||||
dest_addr)) {
|
||||
|
@ -694,10 +690,10 @@ void eigrp_update_send_all(struct eigrp *eigrp,
|
|||
struct eigrp_interface *exception)
|
||||
{
|
||||
struct eigrp_interface *iface;
|
||||
struct listnode *node, *node2, *nnode2;
|
||||
struct listnode *node2, *nnode2;
|
||||
struct eigrp_prefix_descriptor *pe;
|
||||
|
||||
for (ALL_LIST_ELEMENTS_RO(eigrp->eiflist, node, iface)) {
|
||||
frr_each (eigrp_interface_hash, &eigrp->eifs, iface) {
|
||||
if (iface != exception) {
|
||||
eigrp_update_send(iface);
|
||||
}
|
||||
|
@ -799,7 +795,7 @@ static void eigrp_update_send_GR_part(struct eigrp_neighbor *nbr)
|
|||
/*
|
||||
* Filtering
|
||||
*/
|
||||
dest_addr = pe->destination;
|
||||
dest_addr = &pe->destination;
|
||||
|
||||
if (eigrp_update_prefix_apply(eigrp, ei, EIGRP_FILTER_OUT,
|
||||
dest_addr)) {
|
||||
|
@ -1001,11 +997,10 @@ void eigrp_update_send_GR(struct eigrp_neighbor *nbr, enum GR_type gr_type,
|
|||
void eigrp_update_send_interface_GR(struct eigrp_interface *ei,
|
||||
enum GR_type gr_type, struct vty *vty)
|
||||
{
|
||||
struct listnode *node;
|
||||
struct eigrp_neighbor *nbr;
|
||||
|
||||
/* iterate over all neighbors on eigrp interface */
|
||||
for (ALL_LIST_ELEMENTS_RO(ei->nbrs, node, nbr)) {
|
||||
frr_each (eigrp_nbr_hash, &ei->nbr_hash_head, nbr) {
|
||||
/* send GR to neighbor */
|
||||
eigrp_update_send_GR(nbr, gr_type, vty);
|
||||
}
|
||||
|
@ -1027,11 +1022,10 @@ void eigrp_update_send_interface_GR(struct eigrp_interface *ei,
|
|||
void eigrp_update_send_process_GR(struct eigrp *eigrp, enum GR_type gr_type,
|
||||
struct vty *vty)
|
||||
{
|
||||
struct listnode *node;
|
||||
struct eigrp_interface *ei;
|
||||
|
||||
/* iterate over all eigrp interfaces */
|
||||
for (ALL_LIST_ELEMENTS_RO(eigrp->eiflist, node, ei)) {
|
||||
frr_each (eigrp_interface_hash, &eigrp->eifs, ei) {
|
||||
/* send GR to all neighbors on interface */
|
||||
eigrp_update_send_interface_GR(ei, gr_type, vty);
|
||||
}
|
||||
|
|
|
@ -195,12 +195,11 @@ static void eigrp_interface_helper(struct vty *vty, struct eigrp *eigrp,
|
|||
const char *ifname, const char *detail)
|
||||
{
|
||||
struct eigrp_interface *ei;
|
||||
struct listnode *node;
|
||||
|
||||
if (!ifname)
|
||||
show_ip_eigrp_interface_header(vty, eigrp);
|
||||
|
||||
for (ALL_LIST_ELEMENTS_RO(eigrp->eiflist, node, ei)) {
|
||||
frr_each (eigrp_interface_hash, &eigrp->eifs, ei) {
|
||||
if (!ifname || strcmp(ei->ifp->name, ifname) == 0) {
|
||||
show_ip_eigrp_interface_sub(vty, eigrp, ei);
|
||||
if (detail)
|
||||
|
@ -252,14 +251,13 @@ static void eigrp_neighbors_helper(struct vty *vty, struct eigrp *eigrp,
|
|||
const char *ifname, const char *detail)
|
||||
{
|
||||
struct eigrp_interface *ei;
|
||||
struct listnode *node, *node2, *nnode2;
|
||||
struct eigrp_neighbor *nbr;
|
||||
|
||||
show_ip_eigrp_neighbor_header(vty, eigrp);
|
||||
|
||||
for (ALL_LIST_ELEMENTS_RO(eigrp->eiflist, node, ei)) {
|
||||
frr_each (eigrp_interface_hash, &eigrp->eifs, ei) {
|
||||
if (!ifname || strcmp(ei->ifp->name, ifname) == 0) {
|
||||
for (ALL_LIST_ELEMENTS(ei->nbrs, node2, nnode2, nbr)) {
|
||||
frr_each (eigrp_nbr_hash, &ei->nbr_hash_head, nbr) {
|
||||
if (detail || (nbr->state == EIGRP_NEIGHBOR_UP))
|
||||
show_ip_eigrp_neighbor_sub(vty, nbr,
|
||||
!!detail);
|
||||
|
@ -320,7 +318,6 @@ DEFPY (clear_ip_eigrp_neighbors,
|
|||
{
|
||||
struct eigrp *eigrp;
|
||||
struct eigrp_interface *ei;
|
||||
struct listnode *node, *node2, *nnode2;
|
||||
struct eigrp_neighbor *nbr;
|
||||
|
||||
/* Check if eigrp process is enabled */
|
||||
|
@ -331,12 +328,12 @@ DEFPY (clear_ip_eigrp_neighbors,
|
|||
}
|
||||
|
||||
/* iterate over all eigrp interfaces */
|
||||
for (ALL_LIST_ELEMENTS_RO(eigrp->eiflist, node, ei)) {
|
||||
frr_each (eigrp_interface_hash, &eigrp->eifs, ei) {
|
||||
/* send Goodbye Hello */
|
||||
eigrp_hello_send(ei, EIGRP_HELLO_GRACEFUL_SHUTDOWN, NULL);
|
||||
|
||||
/* iterate over all neighbors on eigrp interface */
|
||||
for (ALL_LIST_ELEMENTS(ei->nbrs, node2, nnode2, nbr)) {
|
||||
frr_each (eigrp_nbr_hash, &ei->nbr_hash_head, nbr) {
|
||||
if (nbr->state != EIGRP_NEIGHBOR_DOWN) {
|
||||
zlog_debug(
|
||||
"Neighbor %pI4 (%s) is down: manually cleared",
|
||||
|
@ -376,7 +373,6 @@ DEFPY (clear_ip_eigrp_neighbors_int,
|
|||
{
|
||||
struct eigrp *eigrp;
|
||||
struct eigrp_interface *ei;
|
||||
struct listnode *node2, *nnode2;
|
||||
struct eigrp_neighbor *nbr;
|
||||
|
||||
/* Check if eigrp process is enabled */
|
||||
|
@ -397,7 +393,7 @@ DEFPY (clear_ip_eigrp_neighbors_int,
|
|||
eigrp_hello_send(ei, EIGRP_HELLO_GRACEFUL_SHUTDOWN, NULL);
|
||||
|
||||
/* iterate over all neighbors on eigrp interface */
|
||||
for (ALL_LIST_ELEMENTS(ei->nbrs, node2, nnode2, nbr)) {
|
||||
frr_each (eigrp_nbr_hash, &ei->nbr_hash_head, nbr) {
|
||||
if (nbr->state != EIGRP_NEIGHBOR_DOWN) {
|
||||
zlog_debug(
|
||||
"Neighbor %pI4 (%s) is down: manually cleared",
|
||||
|
|
|
@ -105,6 +105,11 @@ void eigrp_zebra_init(void)
|
|||
zclient->zebra_connected = eigrp_zebra_connected;
|
||||
}
|
||||
|
||||
void eigrp_zebra_stop(void)
|
||||
{
|
||||
zclient_stop(zclient);
|
||||
zclient_free(zclient);
|
||||
}
|
||||
|
||||
/* Zebra route add and delete treatment. */
|
||||
static int eigrp_zebra_read_route(ZAPI_CALLBACK_ARGS)
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
#include "vrf.h"
|
||||
|
||||
extern void eigrp_zebra_init(void);
|
||||
extern void eigrp_zebra_stop(void);
|
||||
|
||||
extern void eigrp_zebra_route_add(struct eigrp *eigrp, struct prefix *p,
|
||||
struct list *successors, uint32_t distance);
|
||||
|
|
|
@ -55,6 +55,15 @@ struct eigrp_master *eigrp_om;
|
|||
extern struct zclient *zclient;
|
||||
extern struct in_addr router_id_zebra;
|
||||
|
||||
int eigrp_master_hash_cmp(const struct eigrp *a, const struct eigrp *b)
|
||||
{
|
||||
return a->vrf_id - b->vrf_id;
|
||||
}
|
||||
|
||||
uint32_t eigrp_master_hash_hash(const struct eigrp *a)
|
||||
{
|
||||
return a->vrf_id;
|
||||
}
|
||||
|
||||
/*
|
||||
* void eigrp_router_id_update(struct eigrp *eigrp)
|
||||
|
@ -111,7 +120,7 @@ void eigrp_master_init(void)
|
|||
memset(&eigrp_master, 0, sizeof(eigrp_master));
|
||||
|
||||
eigrp_om = &eigrp_master;
|
||||
eigrp_om->eigrp = list_new();
|
||||
eigrp_master_hash_init(&eigrp_om->eigrp);
|
||||
|
||||
monotime(&tv);
|
||||
eigrp_om->start_time = tv.tv_sec;
|
||||
|
@ -139,7 +148,7 @@ static struct eigrp *eigrp_new(uint16_t as, vrf_id_t vrf_id)
|
|||
eigrp->k_values[5] = EIGRP_K6_DEFAULT;
|
||||
|
||||
/* init internal data structures */
|
||||
eigrp->eiflist = list_new();
|
||||
eigrp_interface_hash_init(&eigrp->eifs);
|
||||
eigrp->passive_interface_default = EIGRP_IF_ACTIVE;
|
||||
eigrp->networks = eigrp_topology_new();
|
||||
|
||||
|
@ -206,7 +215,7 @@ struct eigrp *eigrp_get(uint16_t as, vrf_id_t vrf_id)
|
|||
eigrp = eigrp_lookup(vrf_id);
|
||||
if (eigrp == NULL) {
|
||||
eigrp = eigrp_new(as, vrf_id);
|
||||
listnode_add(eigrp_om->eigrp, eigrp);
|
||||
eigrp_master_hash_add(&eigrp_om->eigrp, eigrp);
|
||||
}
|
||||
|
||||
return eigrp;
|
||||
|
@ -216,7 +225,6 @@ struct eigrp *eigrp_get(uint16_t as, vrf_id_t vrf_id)
|
|||
void eigrp_terminate(void)
|
||||
{
|
||||
struct eigrp *eigrp;
|
||||
struct listnode *node, *nnode;
|
||||
|
||||
/* shutdown already in progress */
|
||||
if (CHECK_FLAG(eigrp_om->options, EIGRP_MASTER_SHUTDOWN))
|
||||
|
@ -224,9 +232,16 @@ void eigrp_terminate(void)
|
|||
|
||||
SET_FLAG(eigrp_om->options, EIGRP_MASTER_SHUTDOWN);
|
||||
|
||||
for (ALL_LIST_ELEMENTS(eigrp_om->eigrp, node, nnode, eigrp))
|
||||
while (eigrp_master_hash_count(&eigrp_om->eigrp)) {
|
||||
eigrp = eigrp_master_hash_first(&eigrp_om->eigrp);
|
||||
eigrp_finish(eigrp);
|
||||
}
|
||||
|
||||
eigrp_master_hash_fini(&eigrp_om->eigrp);
|
||||
|
||||
eigrp_zebra_stop();
|
||||
|
||||
vrf_terminate();
|
||||
frr_fini();
|
||||
}
|
||||
|
||||
|
@ -234,16 +249,6 @@ void eigrp_finish(struct eigrp *eigrp)
|
|||
{
|
||||
eigrp_finish_final(eigrp);
|
||||
|
||||
/* eigrp being shut-down? If so, was this the last eigrp instance? */
|
||||
if (CHECK_FLAG(eigrp_om->options, EIGRP_MASTER_SHUTDOWN)
|
||||
&& (listcount(eigrp_om->eigrp) == 0)) {
|
||||
if (zclient) {
|
||||
zclient_stop(zclient);
|
||||
zclient_free(zclient);
|
||||
}
|
||||
exit(0);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -252,44 +257,48 @@ void eigrp_finish_final(struct eigrp *eigrp)
|
|||
{
|
||||
struct eigrp_interface *ei;
|
||||
struct eigrp_neighbor *nbr;
|
||||
struct listnode *node, *nnode, *node2, *nnode2;
|
||||
|
||||
for (ALL_LIST_ELEMENTS(eigrp->eiflist, node, nnode, ei)) {
|
||||
for (ALL_LIST_ELEMENTS(ei->nbrs, node2, nnode2, nbr))
|
||||
while (eigrp_interface_hash_count(&eigrp->eifs)) {
|
||||
ei = eigrp_interface_hash_first(&eigrp->eifs);
|
||||
while (eigrp_nbr_hash_count(&ei->nbr_hash_head)) {
|
||||
nbr = eigrp_nbr_hash_first(&ei->nbr_hash_head);
|
||||
eigrp_nbr_delete(nbr);
|
||||
eigrp_if_free(ei, INTERFACE_DOWN_BY_FINAL);
|
||||
}
|
||||
eigrp_if_delete_hook(ei->ifp);
|
||||
}
|
||||
|
||||
EVENT_OFF(eigrp->t_write);
|
||||
EVENT_OFF(eigrp->t_read);
|
||||
close(eigrp->fd);
|
||||
|
||||
list_delete(&eigrp->eiflist);
|
||||
eigrp_interface_hash_fini(&eigrp->eifs);
|
||||
list_delete(&eigrp->oi_write_q);
|
||||
|
||||
eigrp_topology_free(eigrp, eigrp->topology_table);
|
||||
eigrp_network_free(eigrp, eigrp->networks);
|
||||
|
||||
eigrp_nbr_delete(eigrp->neighbor_self);
|
||||
|
||||
list_delete(&eigrp->topology_changes_externalIPV4);
|
||||
list_delete(&eigrp->topology_changes_internalIPV4);
|
||||
|
||||
listnode_delete(eigrp_om->eigrp, eigrp);
|
||||
eigrp_master_hash_del(&eigrp_om->eigrp, eigrp);
|
||||
|
||||
stream_free(eigrp->ibuf);
|
||||
distribute_list_delete(&eigrp->distribute_ctx);
|
||||
|
||||
QOBJ_UNREG(eigrp);
|
||||
|
||||
XFREE(MTYPE_EIGRP_TOP, eigrp);
|
||||
}
|
||||
|
||||
/*Look for existing eigrp process*/
|
||||
struct eigrp *eigrp_lookup(vrf_id_t vrf_id)
|
||||
{
|
||||
struct eigrp *eigrp;
|
||||
struct listnode *node, *nnode;
|
||||
struct eigrp *eigrp, lookup;
|
||||
|
||||
for (ALL_LIST_ELEMENTS(eigrp_om->eigrp, node, nnode, eigrp))
|
||||
if (eigrp->vrf_id == vrf_id)
|
||||
return eigrp;
|
||||
lookup.vrf_id = vrf_id;
|
||||
eigrp = eigrp_master_hash_find(&eigrp_om->eigrp, &lookup);
|
||||
|
||||
return NULL;
|
||||
return eigrp;
|
||||
}
|
||||
|
|
|
@ -30,9 +30,11 @@ DECLARE_MGROUP(EIGRPD);
|
|||
#define EIGRP_TLV_MTR_VERSION 3 /* MTR TLVs with 32bit metric *Not Supported */
|
||||
#define EIGRP_TLV_SAF_VERSION 4 /* SAF TLVs with 64bit metric *Not Supported */
|
||||
|
||||
//PREDECL_HASH(eigrp_master_hash);
|
||||
|
||||
struct eigrp_master {
|
||||
/* EIGRP instance. */
|
||||
struct list *eigrp;
|
||||
struct eigrp_master_hash_head eigrp;
|
||||
|
||||
/* EIGRP thread master. */
|
||||
struct event_loop *master;
|
||||
|
@ -64,4 +66,10 @@ extern struct eigrp *eigrp_get(uint16_t as, vrf_id_t vrf_id);
|
|||
extern struct eigrp *eigrp_lookup(vrf_id_t vrf_id);
|
||||
extern void eigrp_router_id_update(struct eigrp *eigrp);
|
||||
|
||||
extern int eigrp_master_hash_cmp(const struct eigrp *a, const struct eigrp *b);
|
||||
extern uint32_t eigrp_master_hash_hash(const struct eigrp *a);
|
||||
|
||||
DECLARE_HASH(eigrp_master_hash, struct eigrp, eigrp_item, eigrp_master_hash_cmp,
|
||||
eigrp_master_hash_hash);
|
||||
|
||||
#endif /* _ZEBRA_EIGRPD_H */
|
||||
|
|
4
lib/if.c
4
lib/if.c
|
@ -44,7 +44,6 @@ static void if_set_name(struct interface *ifp, const char *name);
|
|||
static struct interface *if_lookup_by_ifindex(ifindex_t ifindex,
|
||||
vrf_id_t vrf_id);
|
||||
static struct interface *if_lookup_by_index_all_vrf(ifindex_t ifindex);
|
||||
static int if_cmp_func(const struct interface *, const struct interface *);
|
||||
static int if_cmp_index_func(const struct interface *ifp1,
|
||||
const struct interface *ifp2);
|
||||
RB_GENERATE(if_name_head, interface, name_entry, if_cmp_func);
|
||||
|
@ -136,8 +135,7 @@ int if_cmp_name_func(const char *p1, const char *p2)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int if_cmp_func(const struct interface *ifp1,
|
||||
const struct interface *ifp2)
|
||||
int if_cmp_func(const struct interface *ifp1, const struct interface *ifp2)
|
||||
{
|
||||
return if_cmp_name_func(ifp1->name, ifp2->name);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue