#include "eigrpd/eigrp_const.h"
#include "eigrpd/eigrp_filter.h"
#include "eigrpd/eigrp_packet.h"
+#include "eigrpd/eigrp_interface.h"
/*
* Distribute-list update functions.
/*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;
{
uint16_t length = EIGRP_TLV_SEQ_BASE_LEN;
struct eigrp_interface *ei;
- struct listnode *node;
struct eigrp_neighbor *nbr;
size_t backup_end, size_end;
int found;
stream_putc(s, IPV4_MAX_BYTELEN);
found = 0;
- for (ALL_LIST_ELEMENTS_RO(eigrp->eiflist, node, ei)) {
+ 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(
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)
{
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;
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);
struct eigrp_route_descriptor *ne;
struct eigrp_metrics metric;
struct eigrp_interface *ei2;
- struct listnode *node, *nnode;
struct eigrp *eigrp;
if (ei == NULL)
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);
eigrp_if_down(ei);
- listnode_delete(ei->eigrp->eiflist, ei);
+ eigrp_interface_hash_del(&ei->eigrp->eifs, ei);
}
/* Simulate down/up on the interface. This is needed, for example, when
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;
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;
/* 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_ */
struct in_addr nbr_addr)
{
struct eigrp_interface *ei;
- struct listnode *node;
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 */
lookup.src = nbr_addr;
nbr = eigrp_nbr_hash_find(&ei->nbr_hash_head, &lookup);
int eigrp_nbr_count_get(struct eigrp *eigrp)
{
struct eigrp_interface *iface;
- struct listnode *node;
uint32_t counter;
counter = 0;
- for (ALL_LIST_ELEMENTS_RO(eigrp->eiflist, node, iface))
+ frr_each (eigrp_interface_hash, &eigrp->eifs, iface)
counter += eigrp_nbr_hash_count(&iface->nbr_hash_head);
return counter;
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;
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)) {
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;
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",
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;
}
counter = 0;
- for (ALL_LIST_ELEMENTS_RO(eigrp->eiflist, node, iface)) {
+ frr_each (eigrp_interface_hash, &eigrp->eifs, iface) {
eigrp_send_query(iface);
counter++;
}
{
struct interface *ifp;
struct eigrp_interface *ei, *ei2;
- struct listnode *node, *nnode;
struct route_map *rmap;
struct eigrp *e;
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;
uint8_t flags;
};
+PREDECL_HASH(eigrp_interface_hash);
+
struct eigrp {
vrf_id_t vrf_id;
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;
/*EIGRP interface structure*/
struct eigrp_interface {
+ struct eigrp_interface_hash_item eif_item;
+
struct eigrp_if_params params;
/*multicast group refcnts */
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);
}
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);
}
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)
const char *ifname, const char *detail)
{
struct eigrp_interface *ei;
- struct listnode *node;
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) {
frr_each (eigrp_nbr_hash, &ei->nbr_hash_head, nbr) {
if (detail || (nbr->state == EIGRP_NEIGHBOR_UP))
{
struct eigrp *eigrp;
struct eigrp_interface *ei;
- struct listnode *node;
struct eigrp_neighbor *nbr;
/* Check if eigrp process is enabled */
}
/* 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);
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();
{
struct eigrp_interface *ei;
struct eigrp_neighbor *nbr;
- struct listnode *node, *nnode;
- for (ALL_LIST_ELEMENTS(eigrp->eiflist, node, nnode, ei)) {
+ 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);
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);