diff options
author | whitespace / reindent <invalid@invalid.invalid> | 2017-07-17 14:03:14 +0200 |
---|---|---|
committer | whitespace / reindent <invalid@invalid.invalid> | 2017-07-17 14:04:07 +0200 |
commit | d62a17aedeb0eebdba98238874bb13d62c48dbf9 (patch) | |
tree | 3b319b1d61c8b85b4d1f06adf8b844bb8a9b5107 /eigrpd/eigrp_network.c | |
parent | *: add indent control files (diff) | |
download | frr-d62a17aedeb0eebdba98238874bb13d62c48dbf9.tar.xz frr-d62a17aedeb0eebdba98238874bb13d62c48dbf9.zip |
*: reindentreindent-master-after
indent.py `git ls-files | pcregrep '\.[ch]$' | pcregrep -v '^(ldpd|babeld|nhrpd)/'`
Signed-off-by: David Lamparter <equinox@opensourcerouting.org>
Diffstat (limited to 'eigrpd/eigrp_network.c')
-rw-r--r-- | eigrpd/eigrp_network.c | 697 |
1 files changed, 345 insertions, 352 deletions
diff --git a/eigrpd/eigrp_network.c b/eigrpd/eigrp_network.c index 74cb6de18..80610e04a 100644 --- a/eigrpd/eigrp_network.c +++ b/eigrpd/eigrp_network.c @@ -49,412 +49,405 @@ extern struct zebra_privs_t eigrpd_privs; #include "eigrpd/eigrp_vty.h" #include "eigrpd/eigrp_network.h" -static int -eigrp_network_match_iface(const struct connected *, const struct prefix *); -static void -eigrp_network_run_interface(struct eigrp *, struct prefix *, struct interface *); +static int eigrp_network_match_iface(const struct connected *, + const struct prefix *); +static void eigrp_network_run_interface(struct eigrp *, struct prefix *, + struct interface *); -int -eigrp_sock_init(void) +int eigrp_sock_init(void) { - int eigrp_sock; - int ret, hincl = 1; - - if (eigrpd_privs.change(ZPRIVS_RAISE)) - zlog_err("eigrp_sock_init: could not raise privs, %s", - safe_strerror(errno)); - - eigrp_sock = socket(AF_INET, SOCK_RAW, IPPROTO_EIGRPIGP); - if (eigrp_sock < 0) - { - int save_errno = errno; - if (eigrpd_privs.change(ZPRIVS_LOWER)) - zlog_err("eigrp_sock_init: could not lower privs, %s", - safe_strerror(errno)); - zlog_err("eigrp_read_sock_init: socket: %s", safe_strerror(save_errno)); - exit(1); - } + int eigrp_sock; + int ret, hincl = 1; + + if (eigrpd_privs.change(ZPRIVS_RAISE)) + zlog_err("eigrp_sock_init: could not raise privs, %s", + safe_strerror(errno)); + + eigrp_sock = socket(AF_INET, SOCK_RAW, IPPROTO_EIGRPIGP); + if (eigrp_sock < 0) { + int save_errno = errno; + if (eigrpd_privs.change(ZPRIVS_LOWER)) + zlog_err("eigrp_sock_init: could not lower privs, %s", + safe_strerror(errno)); + zlog_err("eigrp_read_sock_init: socket: %s", + safe_strerror(save_errno)); + exit(1); + } #ifdef IP_HDRINCL - /* we will include IP header with packet */ - ret = setsockopt(eigrp_sock, IPPROTO_IP, IP_HDRINCL, &hincl, sizeof(hincl)); - if (ret < 0) - { - int save_errno = errno; - if (eigrpd_privs.change(ZPRIVS_LOWER)) - zlog_err("eigrp_sock_init: could not lower privs, %s", - safe_strerror(errno)); - zlog_warn("Can't set IP_HDRINCL option for fd %d: %s", eigrp_sock, - safe_strerror(save_errno)); - - } -#elif defined (IPTOS_PREC_INTERNETCONTROL) + /* we will include IP header with packet */ + ret = setsockopt(eigrp_sock, IPPROTO_IP, IP_HDRINCL, &hincl, + sizeof(hincl)); + if (ret < 0) { + int save_errno = errno; + if (eigrpd_privs.change(ZPRIVS_LOWER)) + zlog_err("eigrp_sock_init: could not lower privs, %s", + safe_strerror(errno)); + zlog_warn("Can't set IP_HDRINCL option for fd %d: %s", + eigrp_sock, safe_strerror(save_errno)); + } +#elif defined(IPTOS_PREC_INTERNETCONTROL) #warning "IP_HDRINCL not available on this system" #warning "using IPTOS_PREC_INTERNETCONTROL" - ret = setsockopt_ipv4_tos (eigrp_sock, IPTOS_PREC_INTERNETCONTROL); - if (ret < 0) - { - int save_errno = errno; - if ( eigrpd_privs.change (ZPRIVS_LOWER) ) - zlog_err ("eigrpd_sock_init: could not lower privs, %s", - safe_strerror (errno) ); - zlog_warn ("can't set sockopt IP_TOS %d to socket %d: %s", - tos, eigrp_sock, safe_strerror (save_errno)); - close (eigrp_sock); /* Prevent sd leak. */ - return ret; - } + ret = setsockopt_ipv4_tos(eigrp_sock, IPTOS_PREC_INTERNETCONTROL); + if (ret < 0) { + int save_errno = errno; + if (eigrpd_privs.change(ZPRIVS_LOWER)) + zlog_err("eigrpd_sock_init: could not lower privs, %s", + safe_strerror(errno)); + zlog_warn("can't set sockopt IP_TOS %d to socket %d: %s", tos, + eigrp_sock, safe_strerror(save_errno)); + close(eigrp_sock); /* Prevent sd leak. */ + return ret; + } #else /* !IPTOS_PREC_INTERNETCONTROL */ #warning "IP_HDRINCL not available, nor is IPTOS_PREC_INTERNETCONTROL" - zlog_warn ("IP_HDRINCL option not available"); + zlog_warn("IP_HDRINCL option not available"); #endif /* IP_HDRINCL */ - ret = setsockopt_ifindex(AF_INET, eigrp_sock, 1); + ret = setsockopt_ifindex(AF_INET, eigrp_sock, 1); - if (ret < 0) - zlog_warn("Can't set pktinfo option for fd %d", eigrp_sock); + if (ret < 0) + zlog_warn("Can't set pktinfo option for fd %d", eigrp_sock); - if (eigrpd_privs.change(ZPRIVS_LOWER)) - { - zlog_err("eigrp_sock_init: could not lower privs, %s", - safe_strerror(errno)); - } + if (eigrpd_privs.change(ZPRIVS_LOWER)) { + zlog_err("eigrp_sock_init: could not lower privs, %s", + safe_strerror(errno)); + } - return eigrp_sock; + return eigrp_sock; } -void -eigrp_adjust_sndbuflen(struct eigrp * eigrp, unsigned int buflen) +void eigrp_adjust_sndbuflen(struct eigrp *eigrp, unsigned int buflen) { - int newbuflen; - /* Check if any work has to be done at all. */ - if (eigrp->maxsndbuflen >= buflen) - return; - if (eigrpd_privs.change(ZPRIVS_RAISE)) - zlog_err("%s: could not raise privs, %s", __func__, safe_strerror(errno)); - - /* Now we try to set SO_SNDBUF to what our caller has requested - * (the MTU of a newly added interface). However, if the OS has - * truncated the actual buffer size to somewhat less size, try - * to detect it and update our records appropriately. The OS - * may allocate more buffer space, than requested, this isn't - * a error. - */ - setsockopt_so_sendbuf(eigrp->fd, buflen); - newbuflen = getsockopt_so_sendbuf(eigrp->fd); - if (newbuflen < 0 || newbuflen < (int) buflen) - zlog_warn("%s: tried to set SO_SNDBUF to %u, but got %d", __func__, buflen, - newbuflen); - if (newbuflen >= 0) - eigrp->maxsndbuflen = (unsigned int) newbuflen; - else - zlog_warn("%s: failed to get SO_SNDBUF", __func__); - if (eigrpd_privs.change(ZPRIVS_LOWER)) - zlog_err("%s: could not lower privs, %s", __func__, safe_strerror(errno)); + int newbuflen; + /* Check if any work has to be done at all. */ + if (eigrp->maxsndbuflen >= buflen) + return; + if (eigrpd_privs.change(ZPRIVS_RAISE)) + zlog_err("%s: could not raise privs, %s", __func__, + safe_strerror(errno)); + + /* Now we try to set SO_SNDBUF to what our caller has requested + * (the MTU of a newly added interface). However, if the OS has + * truncated the actual buffer size to somewhat less size, try + * to detect it and update our records appropriately. The OS + * may allocate more buffer space, than requested, this isn't + * a error. + */ + setsockopt_so_sendbuf(eigrp->fd, buflen); + newbuflen = getsockopt_so_sendbuf(eigrp->fd); + if (newbuflen < 0 || newbuflen < (int)buflen) + zlog_warn("%s: tried to set SO_SNDBUF to %u, but got %d", + __func__, buflen, newbuflen); + if (newbuflen >= 0) + eigrp->maxsndbuflen = (unsigned int)newbuflen; + else + zlog_warn("%s: failed to get SO_SNDBUF", __func__); + if (eigrpd_privs.change(ZPRIVS_LOWER)) + zlog_err("%s: could not lower privs, %s", __func__, + safe_strerror(errno)); } -int -eigrp_if_ipmulticast(struct eigrp *top, struct prefix *p, unsigned int ifindex) +int eigrp_if_ipmulticast(struct eigrp *top, struct prefix *p, + unsigned int ifindex) { - u_char val; - int ret, len; - - val = 0; - len = sizeof(val); - - /* Prevent receiving self-origined multicast packets. */ - ret = setsockopt(top->fd, IPPROTO_IP, IP_MULTICAST_LOOP, (void *) &val, len); - if (ret < 0) - zlog_warn("can't setsockopt IP_MULTICAST_LOOP (0) for fd %d: %s", top->fd, - safe_strerror(errno)); - - /* Explicitly set multicast ttl to 1 -- endo. */ - val = 1; - ret = setsockopt(top->fd, IPPROTO_IP, IP_MULTICAST_TTL, (void *) &val, len); - if (ret < 0) - zlog_warn("can't setsockopt IP_MULTICAST_TTL (1) for fd %d: %s", top->fd, - safe_strerror(errno)); - - ret = setsockopt_ipv4_multicast_if(top->fd, p->u.prefix4, ifindex); - if (ret < 0) - zlog_warn("can't setsockopt IP_MULTICAST_IF (fd %d, addr %s, " - "ifindex %u): %s", top->fd, inet_ntoa(p->u.prefix4), ifindex, - safe_strerror(errno)); - - return ret; + u_char val; + int ret, len; + + val = 0; + len = sizeof(val); + + /* Prevent receiving self-origined multicast packets. */ + ret = setsockopt(top->fd, IPPROTO_IP, IP_MULTICAST_LOOP, (void *)&val, + len); + if (ret < 0) + zlog_warn( + "can't setsockopt IP_MULTICAST_LOOP (0) for fd %d: %s", + top->fd, safe_strerror(errno)); + + /* Explicitly set multicast ttl to 1 -- endo. */ + val = 1; + ret = setsockopt(top->fd, IPPROTO_IP, IP_MULTICAST_TTL, (void *)&val, + len); + if (ret < 0) + zlog_warn("can't setsockopt IP_MULTICAST_TTL (1) for fd %d: %s", + top->fd, safe_strerror(errno)); + + ret = setsockopt_ipv4_multicast_if(top->fd, p->u.prefix4, ifindex); + if (ret < 0) + zlog_warn( + "can't setsockopt IP_MULTICAST_IF (fd %d, addr %s, " + "ifindex %u): %s", + top->fd, inet_ntoa(p->u.prefix4), ifindex, + safe_strerror(errno)); + + return ret; } /* Join to the EIGRP multicast group. */ -int -eigrp_if_add_allspfrouters(struct eigrp *top, struct prefix *p, - unsigned int ifindex) +int eigrp_if_add_allspfrouters(struct eigrp *top, struct prefix *p, + unsigned int ifindex) { - int ret; - - ret = setsockopt_ipv4_multicast(top->fd, IP_ADD_MEMBERSHIP, p->u.prefix4, - htonl(EIGRP_MULTICAST_ADDRESS), ifindex); - if (ret < 0) - zlog_warn("can't setsockopt IP_ADD_MEMBERSHIP (fd %d, addr %s, " - "ifindex %u, AllSPFRouters): %s; perhaps a kernel limit " - "on # of multicast group memberships has been exceeded?", top->fd, - inet_ntoa(p->u.prefix4), ifindex, safe_strerror(errno)); - else - zlog_debug("interface %s [%u] join EIGRP Multicast group.", - inet_ntoa(p->u.prefix4), ifindex); - - return ret; + int ret; + + ret = setsockopt_ipv4_multicast( + top->fd, IP_ADD_MEMBERSHIP, p->u.prefix4, + htonl(EIGRP_MULTICAST_ADDRESS), ifindex); + if (ret < 0) + zlog_warn( + "can't setsockopt IP_ADD_MEMBERSHIP (fd %d, addr %s, " + "ifindex %u, AllSPFRouters): %s; perhaps a kernel limit " + "on # of multicast group memberships has been exceeded?", + top->fd, inet_ntoa(p->u.prefix4), ifindex, + safe_strerror(errno)); + else + zlog_debug("interface %s [%u] join EIGRP Multicast group.", + inet_ntoa(p->u.prefix4), ifindex); + + return ret; } -int -eigrp_if_drop_allspfrouters(struct eigrp *top, struct prefix *p, - unsigned int ifindex) +int eigrp_if_drop_allspfrouters(struct eigrp *top, struct prefix *p, + unsigned int ifindex) { - int ret; - - ret = setsockopt_ipv4_multicast(top->fd, IP_DROP_MEMBERSHIP, p->u.prefix4, - htonl(EIGRP_MULTICAST_ADDRESS), ifindex); - if (ret < 0) - zlog_warn("can't setsockopt IP_DROP_MEMBERSHIP (fd %d, addr %s, " - "ifindex %u, AllSPFRouters): %s", top->fd, inet_ntoa(p->u.prefix4), - ifindex, safe_strerror(errno)); - else - zlog_debug("interface %s [%u] leave EIGRP Multicast group.", - inet_ntoa(p->u.prefix4), ifindex); - - return ret; + int ret; + + ret = setsockopt_ipv4_multicast( + top->fd, IP_DROP_MEMBERSHIP, p->u.prefix4, + htonl(EIGRP_MULTICAST_ADDRESS), ifindex); + if (ret < 0) + zlog_warn( + "can't setsockopt IP_DROP_MEMBERSHIP (fd %d, addr %s, " + "ifindex %u, AllSPFRouters): %s", + top->fd, inet_ntoa(p->u.prefix4), ifindex, + safe_strerror(errno)); + else + zlog_debug("interface %s [%u] leave EIGRP Multicast group.", + inet_ntoa(p->u.prefix4), ifindex); + + return ret; } -int -eigrp_network_set(struct eigrp *eigrp, struct prefix_ipv4 *p) +int eigrp_network_set(struct eigrp *eigrp, struct prefix_ipv4 *p) { - struct route_node *rn; - struct interface *ifp; - struct listnode *node; - - rn = route_node_get(eigrp->networks, (struct prefix *) p); - if (rn->info) - { - /* There is already same network statement. */ - route_unlock_node(rn); - return 0; - } - - struct prefix_ipv4 *pref = prefix_ipv4_new(); - PREFIX_COPY_IPV4(pref,p); - rn->info = (void *) pref; - - /* Schedule Router ID Update. */ - if (eigrp->router_id == 0) - eigrp_router_id_update(eigrp); - /* Run network config now. */ - /* Get target interface. */ - for (ALL_LIST_ELEMENTS_RO(vrf_iflist(VRF_DEFAULT), node, ifp)) - { - zlog_debug("Setting up %s", ifp->name); - eigrp_network_run_interface(eigrp, (struct prefix *) p, ifp); - } - return 1; + struct route_node *rn; + struct interface *ifp; + struct listnode *node; + + rn = route_node_get(eigrp->networks, (struct prefix *)p); + if (rn->info) { + /* There is already same network statement. */ + route_unlock_node(rn); + return 0; + } + + struct prefix_ipv4 *pref = prefix_ipv4_new(); + PREFIX_COPY_IPV4(pref, p); + rn->info = (void *)pref; + + /* Schedule Router ID Update. */ + if (eigrp->router_id == 0) + eigrp_router_id_update(eigrp); + /* Run network config now. */ + /* Get target interface. */ + for (ALL_LIST_ELEMENTS_RO(vrf_iflist(VRF_DEFAULT), node, ifp)) { + zlog_debug("Setting up %s", ifp->name); + eigrp_network_run_interface(eigrp, (struct prefix *)p, ifp); + } + return 1; } /* Check whether interface matches given network * returns: 1, true. 0, false */ -static int -eigrp_network_match_iface(const struct connected *co, const struct prefix *net) +static int eigrp_network_match_iface(const struct connected *co, + const struct prefix *net) { - /* new approach: more elegant and conceptually clean */ - return prefix_match_network_statement(net, CONNECTED_PREFIX (co)); + /* new approach: more elegant and conceptually clean */ + return prefix_match_network_statement(net, CONNECTED_PREFIX(co)); } -static void -eigrp_network_run_interface(struct eigrp *eigrp, struct prefix *p, - struct interface *ifp) +static void eigrp_network_run_interface(struct eigrp *eigrp, struct prefix *p, + struct interface *ifp) { - struct listnode *cnode; - struct connected *co; - - /* if interface prefix is match specified prefix, - then create socket and join multicast group. */ - for (ALL_LIST_ELEMENTS_RO(ifp->connected, cnode, co)) - { - - if (CHECK_FLAG (co->flags,ZEBRA_IFA_SECONDARY)) - continue; - - if (p->family == co->address->family - && !eigrp_if_table_lookup(ifp, co->address) - && eigrp_network_match_iface(co, p)) - { - struct eigrp_interface *ei; - - ei = eigrp_if_new(eigrp, ifp, co->address); - ei->connected = co; - - ei->params = eigrp_lookup_if_params(ifp, ei->address->u.prefix4); - - /* Relate eigrp interface to eigrp instance. */ - ei->eigrp = eigrp; - - /* update network type as interface flag */ - /* If network type is specified previously, - skip network type setting. */ - ei->type = IF_DEF_PARAMS (ifp)->type; - - /* if router_id is not configured, dont bring up - * interfaces. - * eigrp_router_id_update() will call eigrp_if_update - * whenever r-id is configured instead. - */ - if (if_is_operative(ifp)) - eigrp_if_up(ei); - } - } + struct listnode *cnode; + struct connected *co; + + /* if interface prefix is match specified prefix, + then create socket and join multicast group. */ + for (ALL_LIST_ELEMENTS_RO(ifp->connected, cnode, co)) { + + if (CHECK_FLAG(co->flags, ZEBRA_IFA_SECONDARY)) + continue; + + if (p->family == co->address->family + && !eigrp_if_table_lookup(ifp, co->address) + && eigrp_network_match_iface(co, p)) { + struct eigrp_interface *ei; + + ei = eigrp_if_new(eigrp, ifp, co->address); + ei->connected = co; + + ei->params = eigrp_lookup_if_params( + ifp, ei->address->u.prefix4); + + /* Relate eigrp interface to eigrp instance. */ + ei->eigrp = eigrp; + + /* update network type as interface flag */ + /* If network type is specified previously, + skip network type setting. */ + ei->type = IF_DEF_PARAMS(ifp)->type; + + /* if router_id is not configured, dont bring up + * interfaces. + * eigrp_router_id_update() will call eigrp_if_update + * whenever r-id is configured instead. + */ + if (if_is_operative(ifp)) + eigrp_if_up(ei); + } + } } -void -eigrp_if_update(struct interface *ifp) +void eigrp_if_update(struct interface *ifp) { - struct listnode *node, *nnode; - struct route_node *rn; - struct eigrp *eigrp; - - /* - * 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)) - { - /* EIGRP must be on and Router-ID must be configured. */ - if (!eigrp || eigrp->router_id == 0) - continue; - - /* Run each network for this interface. */ - for (rn = route_top(eigrp->networks); rn; rn = route_next(rn)) - if (rn->info != NULL) - { - eigrp_network_run_interface(eigrp, &rn->p, ifp); - } - } + struct listnode *node, *nnode; + struct route_node *rn; + struct eigrp *eigrp; + + /* + * 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)) { + /* EIGRP must be on and Router-ID must be configured. */ + if (!eigrp || eigrp->router_id == 0) + continue; + + /* Run each network for this interface. */ + for (rn = route_top(eigrp->networks); rn; rn = route_next(rn)) + if (rn->info != NULL) { + eigrp_network_run_interface(eigrp, &rn->p, ifp); + } + } } -int -eigrp_network_unset(struct eigrp *eigrp, struct prefix_ipv4 *p) +int eigrp_network_unset(struct eigrp *eigrp, struct prefix_ipv4 *p) { - struct route_node *rn; - struct listnode *node, *nnode; - struct eigrp_interface *ei; - struct prefix *pref; - - rn = route_node_lookup(eigrp->networks, (struct prefix *) p); - if (rn == NULL) - return 0; - - pref = rn->info; - route_unlock_node (rn); - - if (!IPV4_ADDR_SAME (&pref->u.prefix4, &p->prefix)) - return 0; - - prefix_ipv4_free(rn->info); - rn->info = NULL; - route_unlock_node(rn); /* initial reference */ - - /* Find interfaces that not configured already. */ - for (ALL_LIST_ELEMENTS(eigrp->eiflist, node, nnode, ei)) - { - int found = 0; - struct connected *co = ei->connected; - - for (rn = route_top(eigrp->networks); rn; rn = route_next(rn)) - { - if (rn->info == NULL) - continue; - - if (eigrp_network_match_iface(co, &rn->p)) - { - found = 1; - route_unlock_node(rn); - break; - } - } - - if (found == 0) - { - eigrp_if_free(ei, INTERFACE_DOWN_BY_VTY); - } - } - - return 1; + struct route_node *rn; + struct listnode *node, *nnode; + struct eigrp_interface *ei; + struct prefix *pref; + + rn = route_node_lookup(eigrp->networks, (struct prefix *)p); + if (rn == NULL) + return 0; + + pref = rn->info; + route_unlock_node(rn); + + if (!IPV4_ADDR_SAME(&pref->u.prefix4, &p->prefix)) + return 0; + + prefix_ipv4_free(rn->info); + rn->info = NULL; + route_unlock_node(rn); /* initial reference */ + + /* Find interfaces that not configured already. */ + for (ALL_LIST_ELEMENTS(eigrp->eiflist, node, nnode, ei)) { + int found = 0; + struct connected *co = ei->connected; + + for (rn = route_top(eigrp->networks); rn; rn = route_next(rn)) { + if (rn->info == NULL) + continue; + + if (eigrp_network_match_iface(co, &rn->p)) { + found = 1; + route_unlock_node(rn); + break; + } + } + + if (found == 0) { + eigrp_if_free(ei, INTERFACE_DOWN_BY_VTY); + } + } + + return 1; } -u_int32_t -eigrp_calculate_metrics(struct eigrp *eigrp, struct eigrp_metrics metric) +u_int32_t eigrp_calculate_metrics(struct eigrp *eigrp, + struct eigrp_metrics metric) { - uint64_t temp_metric; - temp_metric = 0; - - if(metric.delay == EIGRP_MAX_METRIC) - return EIGRP_MAX_METRIC; - - // EIGRP Metric = {K1*BW+[(K2*BW)/(256-load)]+(K3*delay)}*{K5/(reliability+K4)} - - if (eigrp->k_values[0]) - temp_metric += (eigrp->k_values[0] * metric.bandwith); - if (eigrp->k_values[1]) - temp_metric += ((eigrp->k_values[1] * metric.bandwith) - / (256 - metric.load)); - if (eigrp->k_values[2]) - temp_metric += (eigrp->k_values[2] * metric.delay); - if (eigrp->k_values[3] && !eigrp->k_values[4]) - temp_metric *= eigrp->k_values[3]; - if (!eigrp->k_values[3] && eigrp->k_values[4]) - temp_metric *= (eigrp->k_values[4] / metric.reliability); - if (eigrp->k_values[3] && eigrp->k_values[4]) - temp_metric *= ((eigrp->k_values[4] / metric.reliability) - + eigrp->k_values[3]); - - if (temp_metric <= EIGRP_MAX_METRIC) - return (u_int32_t) temp_metric; - else - return EIGRP_MAX_METRIC; + uint64_t temp_metric; + temp_metric = 0; + + if (metric.delay == EIGRP_MAX_METRIC) + return EIGRP_MAX_METRIC; + + // EIGRP Metric = + // {K1*BW+[(K2*BW)/(256-load)]+(K3*delay)}*{K5/(reliability+K4)} + + if (eigrp->k_values[0]) + temp_metric += (eigrp->k_values[0] * metric.bandwith); + if (eigrp->k_values[1]) + temp_metric += ((eigrp->k_values[1] * metric.bandwith) + / (256 - metric.load)); + if (eigrp->k_values[2]) + temp_metric += (eigrp->k_values[2] * metric.delay); + if (eigrp->k_values[3] && !eigrp->k_values[4]) + temp_metric *= eigrp->k_values[3]; + if (!eigrp->k_values[3] && eigrp->k_values[4]) + temp_metric *= (eigrp->k_values[4] / metric.reliability); + if (eigrp->k_values[3] && eigrp->k_values[4]) + temp_metric *= ((eigrp->k_values[4] / metric.reliability) + + eigrp->k_values[3]); + + if (temp_metric <= EIGRP_MAX_METRIC) + return (u_int32_t)temp_metric; + else + return EIGRP_MAX_METRIC; } -u_int32_t -eigrp_calculate_total_metrics(struct eigrp *eigrp, - struct eigrp_neighbor_entry *entry) +u_int32_t eigrp_calculate_total_metrics(struct eigrp *eigrp, + struct eigrp_neighbor_entry *entry) { - entry->total_metric = entry->reported_metric; - uint64_t temp_delay = (uint64_t) entry->total_metric.delay - + (uint64_t) eigrp_delay_to_scaled (EIGRP_IF_PARAM (entry->ei, delay)); - entry->total_metric.delay = - temp_delay > EIGRP_MAX_METRIC ? EIGRP_MAX_METRIC : (u_int32_t) temp_delay; - - u_int32_t bw = eigrp_bandwidth_to_scaled (EIGRP_IF_PARAM (entry->ei,bandwidth)); - entry->total_metric.bandwith = - entry->total_metric.bandwith > bw ? bw : entry->total_metric.bandwith; - - return eigrp_calculate_metrics(eigrp, entry->total_metric); + entry->total_metric = entry->reported_metric; + uint64_t temp_delay = (uint64_t)entry->total_metric.delay + + (uint64_t)eigrp_delay_to_scaled( + EIGRP_IF_PARAM(entry->ei, delay)); + entry->total_metric.delay = temp_delay > EIGRP_MAX_METRIC + ? EIGRP_MAX_METRIC + : (u_int32_t)temp_delay; + + u_int32_t bw = + eigrp_bandwidth_to_scaled(EIGRP_IF_PARAM(entry->ei, bandwidth)); + entry->total_metric.bandwith = entry->total_metric.bandwith > bw + ? bw + : entry->total_metric.bandwith; + + return eigrp_calculate_metrics(eigrp, entry->total_metric); } -u_char -eigrp_metrics_is_same(struct eigrp_metrics metric1, - struct eigrp_metrics metric2) +u_char eigrp_metrics_is_same(struct eigrp_metrics metric1, + struct eigrp_metrics metric2) { - if ((metric1.bandwith == metric2.bandwith) - && (metric1.delay == metric2.delay) - && (metric1.hop_count == metric2.hop_count) - && (metric1.load == metric2.load) - && (metric1.reliability == metric2.reliability) - && (metric1.mtu[0] == metric2.mtu[0]) - && (metric1.mtu[1] == metric2.mtu[1]) - && (metric1.mtu[2] == metric2.mtu[2])) - return 1; - - return 0; // if different + if ((metric1.bandwith == metric2.bandwith) + && (metric1.delay == metric2.delay) + && (metric1.hop_count == metric2.hop_count) + && (metric1.load == metric2.load) + && (metric1.reliability == metric2.reliability) + && (metric1.mtu[0] == metric2.mtu[0]) + && (metric1.mtu[1] == metric2.mtu[1]) + && (metric1.mtu[2] == metric2.mtu[2])) + return 1; + + return 0; // if different } -void -eigrp_external_routes_refresh (struct eigrp *eigrp, int type) +void eigrp_external_routes_refresh(struct eigrp *eigrp, int type) { - } - |