diff options
Diffstat (limited to 'eigrpd/eigrp_interface.c')
| -rw-r--r-- | eigrpd/eigrp_interface.c | 264 |
1 files changed, 54 insertions, 210 deletions
diff --git a/eigrpd/eigrp_interface.c b/eigrpd/eigrp_interface.c index f2512eadad..b8f7cf0441 100644 --- a/eigrpd/eigrp_interface.c +++ b/eigrpd/eigrp_interface.c @@ -55,41 +55,22 @@ #include "eigrpd/eigrp_memory.h" #include "eigrpd/eigrp_fsm.h" -static void eigrp_delete_from_if(struct interface *, struct eigrp_interface *); - -static void eigrp_add_to_if(struct interface *ifp, struct eigrp_interface *ei) -{ - struct route_node *rn; - struct prefix p; - - p = *ei->address; - p.prefixlen = IPV4_MAX_PREFIXLEN; - - rn = route_node_get(IF_OIFS(ifp), &p); - /* rn->info should either be NULL or equal to this ei - * as route_node_get may return an existing node - */ - assert(!rn->info || rn->info == ei); - rn->info = ei; -} - struct eigrp_interface *eigrp_if_new(struct eigrp *eigrp, struct interface *ifp, struct prefix *p) { - struct eigrp_interface *ei; + struct eigrp_interface *ei = ifp->info; int i; - if ((ei = eigrp_if_table_lookup(ifp, p)) == NULL) { - ei = XCALLOC(MTYPE_EIGRP_IF, sizeof(struct eigrp_interface)); - memset(ei, 0, sizeof(struct eigrp_interface)); - } else + if (ei) return ei; + ei = XCALLOC(MTYPE_EIGRP_IF, sizeof(struct eigrp_interface)); + /* Set zebra interface pointer. */ ei->ifp = ifp; ei->address = p; - eigrp_add_to_if(ifp, ei); + ifp->info = ei; listnode_add(eigrp->eiflist, ei); ei->type = EIGRP_IFTYPE_BROADCAST; @@ -106,39 +87,32 @@ struct eigrp_interface *eigrp_if_new(struct eigrp *eigrp, struct interface *ifp, ei->routemap[i] = NULL; } - return ei; -} - -/* lookup ei for specified prefix/ifp */ -struct eigrp_interface *eigrp_if_table_lookup(struct interface *ifp, - struct prefix *prefix) -{ - struct prefix p; - struct route_node *rn; - struct eigrp_interface *rninfo = NULL; - - p = *prefix; - p.prefixlen = IPV4_MAX_PREFIXLEN; + ei->eigrp = eigrp; - /* route_node_get implicitly locks */ - if ((rn = route_node_lookup(IF_OIFS(ifp), &p))) { - rninfo = (struct eigrp_interface *)rn->info; - route_unlock_node(rn); - } + ei->params.v_hello = EIGRP_HELLO_INTERVAL_DEFAULT; + ei->params.v_wait = EIGRP_HOLD_INTERVAL_DEFAULT; + ei->params.bandwidth = EIGRP_BANDWIDTH_DEFAULT; + ei->params.delay = EIGRP_DELAY_DEFAULT; + ei->params.reliability = EIGRP_RELIABILITY_DEFAULT; + ei->params.load = EIGRP_LOAD_DEFAULT; + ei->params.auth_type = EIGRP_AUTH_TYPE_NONE; + ei->params.auth_keychain = NULL; - return rninfo; + return ei; } int eigrp_if_delete_hook(struct interface *ifp) { - struct route_node *rn; + struct eigrp_interface *ei = ifp->info; + struct eigrp *eigrp; - route_table_finish(IF_OIFS(ifp)); + if (!ei) + return 0; + + list_delete(ei->nbrs); - for (rn = route_top(IF_OIFS_PARAMS(ifp)); rn; rn = route_next(rn)) - if (rn->info) - eigrp_del_if_params(rn->info); - route_table_finish(IF_OIFS_PARAMS(ifp)); + eigrp = ei->eigrp; + listnode_delete(eigrp->eiflist, ei); XFREE(MTYPE_EIGRP_IF_INFO, ifp->info); ifp->info = NULL; @@ -151,95 +125,16 @@ struct list *eigrp_iflist; void eigrp_if_init() { /* Initialize Zebra interface data structure. */ - hook_register_prio(if_add, 0, eigrp_if_new_hook); + //hook_register_prio(if_add, 0, eigrp_if_new); hook_register_prio(if_del, 0, eigrp_if_delete_hook); } -int eigrp_if_new_hook(struct interface *ifp) -{ - int rc = 0; - - ifp->info = XCALLOC(MTYPE_EIGRP_IF_INFO, sizeof(struct eigrp_if_info)); - - IF_OIFS(ifp) = route_table_init(); - IF_OIFS_PARAMS(ifp) = route_table_init(); - - IF_DEF_PARAMS(ifp) = eigrp_new_if_params(); - - SET_IF_PARAM(IF_DEF_PARAMS(ifp), v_hello); - IF_DEF_PARAMS(ifp)->v_hello = (u_int32_t)EIGRP_HELLO_INTERVAL_DEFAULT; - - SET_IF_PARAM(IF_DEF_PARAMS(ifp), v_wait); - IF_DEF_PARAMS(ifp)->v_wait = (u_int16_t)EIGRP_HOLD_INTERVAL_DEFAULT; - - SET_IF_PARAM(IF_DEF_PARAMS(ifp), bandwidth); - IF_DEF_PARAMS(ifp)->bandwidth = (u_int32_t)EIGRP_BANDWIDTH_DEFAULT; - - SET_IF_PARAM(IF_DEF_PARAMS(ifp), delay); - IF_DEF_PARAMS(ifp)->delay = (u_int32_t)EIGRP_DELAY_DEFAULT; - - SET_IF_PARAM(IF_DEF_PARAMS(ifp), reliability); - IF_DEF_PARAMS(ifp)->reliability = (u_char)EIGRP_RELIABILITY_DEFAULT; - SET_IF_PARAM(IF_DEF_PARAMS(ifp), load); - IF_DEF_PARAMS(ifp)->load = (u_char)EIGRP_LOAD_DEFAULT; - - SET_IF_PARAM(IF_DEF_PARAMS(ifp), auth_type); - IF_DEF_PARAMS(ifp)->auth_type = EIGRP_AUTH_TYPE_NONE; - - SET_IF_PARAM(IF_DEF_PARAMS(ifp), auth_keychain); - IF_DEF_PARAMS(ifp)->auth_keychain = NULL; - - return rc; -} - -struct eigrp_if_params *eigrp_new_if_params(void) -{ - struct eigrp_if_params *eip; - - eip = XCALLOC(MTYPE_EIGRP_IF_PARAMS, sizeof(struct eigrp_if_params)); - if (!eip) - return NULL; - - UNSET_IF_PARAM(eip, passive_interface); - UNSET_IF_PARAM(eip, v_hello); - UNSET_IF_PARAM(eip, v_wait); - UNSET_IF_PARAM(eip, bandwidth); - UNSET_IF_PARAM(eip, delay); - UNSET_IF_PARAM(eip, reliability); - UNSET_IF_PARAM(eip, load); - UNSET_IF_PARAM(eip, auth_keychain); - UNSET_IF_PARAM(eip, auth_type); - - return eip; -} void eigrp_del_if_params(struct eigrp_if_params *eip) { if (eip->auth_keychain) free(eip->auth_keychain); - - XFREE(MTYPE_EIGRP_IF_PARAMS, eip); -} - -struct eigrp_if_params *eigrp_lookup_if_params(struct interface *ifp, - struct in_addr addr) -{ - struct prefix p; - struct route_node *rn; - - p.family = AF_INET; - p.prefixlen = IPV4_MAX_PREFIXLEN; - p.u.prefix4 = addr; - - rn = route_node_lookup(IF_OIFS_PARAMS(ifp), &p); - - if (rn) { - route_unlock_node(rn); - return rn->info; - } - - return NULL; } int eigrp_if_up(struct eigrp_interface *ei) @@ -266,10 +161,10 @@ int eigrp_if_up(struct eigrp_interface *ei) /*Prepare metrics*/ metric.bandwidth = - eigrp_bandwidth_to_scaled(EIGRP_IF_PARAM(ei, bandwidth)); - metric.delay = eigrp_delay_to_scaled(EIGRP_IF_PARAM(ei, delay)); - metric.load = EIGRP_IF_PARAM(ei, load); - metric.reliability = EIGRP_IF_PARAM(ei, reliability); + eigrp_bandwidth_to_scaled(ei->params.bandwidth); + metric.delay = eigrp_delay_to_scaled(ei->params.delay); + metric.load = ei->params.load; + metric.reliability = ei->params.reliability; metric.mtu[0] = 0xDC; metric.mtu[1] = 0x05; metric.mtu[2] = 0x00; @@ -387,33 +282,43 @@ void eigrp_if_stream_unset(struct eigrp_interface *ei) } } +bool eigrp_if_is_passive(struct eigrp_interface *ei) +{ + if (ei->params.passive_interface == EIGRP_IF_ACTIVE) + return false; + + if (ei->eigrp->passive_interface_default == EIGRP_IF_ACTIVE) + return false; + + return true; +} + void eigrp_if_set_multicast(struct eigrp_interface *ei) { - if ((EIGRP_IF_PASSIVE_STATUS(ei) == EIGRP_IF_ACTIVE)) { + if (!eigrp_if_is_passive(ei)) { /* The interface should belong to the EIGRP-all-routers group. */ - if (!EI_MEMBER_CHECK(ei, MEMBER_ALLROUTERS) + if (!ei->member_allrouters && (eigrp_if_add_allspfrouters(ei->eigrp, ei->address, ei->ifp->ifindex) >= 0)) /* Set the flag only if the system call to join * succeeded. */ - EI_MEMBER_JOINED(ei, MEMBER_ALLROUTERS); + ei->member_allrouters = true; } else { /* The interface should NOT belong to the EIGRP-all-routers * group. */ - if (EI_MEMBER_CHECK(ei, MEMBER_ALLROUTERS)) { + if (ei->member_allrouters) { /* Only actually drop if this is the last reference */ - if (EI_MEMBER_COUNT(ei, MEMBER_ALLROUTERS) == 1) - eigrp_if_drop_allspfrouters(ei->eigrp, - ei->address, - ei->ifp->ifindex); + eigrp_if_drop_allspfrouters(ei->eigrp, + ei->address, + ei->ifp->ifindex); /* Unset the flag regardless of whether the system call to leave the group succeeded, since it's much safer to assume that we are not a member. */ - EI_MEMBER_LEFT(ei, MEMBER_ALLROUTERS); + ei->member_allrouters = false; } } } @@ -428,7 +333,8 @@ u_char eigrp_default_iftype(struct interface *ifp) return EIGRP_IFTYPE_BROADCAST; } -void eigrp_if_free(struct eigrp_interface *ei, int source) +void eigrp_if_free(struct eigrp_interface *ei, + int source) { struct prefix dest_addr; struct eigrp_prefix_entry *pe; @@ -449,47 +355,20 @@ void eigrp_if_free(struct eigrp_interface *ei, int source) eigrp_if_down(ei); list_delete(ei->nbrs); - eigrp_delete_from_if(ei->ifp, ei); listnode_delete(ei->eigrp->eiflist, ei); - - thread_cancel_event(master, ei); - - memset(ei, 0, sizeof(*ei)); - XFREE(MTYPE_EIGRP_IF, ei); -} - -static void eigrp_delete_from_if(struct interface *ifp, - struct eigrp_interface *ei) -{ - struct route_node *rn; - struct prefix p; - - p = *ei->address; - p.prefixlen = IPV4_MAX_PREFIXLEN; - - rn = route_node_lookup(IF_OIFS(ei->ifp), &p); - assert(rn); - assert(rn->info); - rn->info = NULL; - route_unlock_node(rn); - route_unlock_node(rn); } /* Simulate down/up on the interface. This is needed, for example, when the MTU changes. */ void eigrp_if_reset(struct interface *ifp) { - struct route_node *rn; + struct eigrp_interface *ei = ifp->info; - for (rn = route_top(IF_OIFS(ifp)); rn; rn = route_next(rn)) { - struct eigrp_interface *ei; + if (!ei) + return; - if ((ei = rn->info) == NULL) - continue; - - eigrp_if_down(ei); - eigrp_if_up(ei); - } + eigrp_if_down(ei); + eigrp_if_up(ei); } struct eigrp_interface *eigrp_if_lookup_by_local_addr(struct eigrp *eigrp, @@ -538,41 +417,6 @@ struct eigrp_interface *eigrp_if_lookup_by_name(struct eigrp *eigrp, return NULL; } -/* determine receiving interface by ifp and source address */ -struct eigrp_interface *eigrp_if_lookup_recv_if(struct eigrp *eigrp, - struct in_addr src, - struct interface *ifp) -{ - struct route_node *rn; - struct prefix addr; - struct eigrp_interface *ei, *match; - - addr.family = AF_INET; - addr.u.prefix4 = src; - addr.prefixlen = IPV4_MAX_BITLEN; - - match = NULL; - - for (rn = route_top(IF_OIFS(ifp)); rn; rn = route_next(rn)) { - ei = rn->info; - - if (!ei) /* oi can be NULL for PtP aliases */ - continue; - - if (if_is_loopback(ei->ifp)) - continue; - - if (prefix_match(CONNECTED_PREFIX(ei->connected), - &addr)) { - if ((match == NULL) || (match->address->prefixlen - < ei->address->prefixlen)) - match = ei; - } - } - - return match; -} - u_int32_t eigrp_bandwidth_to_scaled(u_int32_t bandwidth) { uint64_t temp_bandwidth = (256ull * 10000000) / bandwidth; |
