diff options
author | Renato Westphal <renato@cvs.openbsd.org> | 2015-10-21 03:52:13 +0000 |
---|---|---|
committer | Renato Westphal <renato@cvs.openbsd.org> | 2015-10-21 03:52:13 +0000 |
commit | a276edca3fd2a5e935de4b937501bf27e8d4da8f (patch) | |
tree | 50d5f5628ebdc7bfa4b8225f54ee96474d6b15c4 /usr.sbin/eigrpd/rde_dual.c | |
parent | 7782225b2926834dc635e6f72ac2a42468bc922d (diff) |
Add support for route summarization.
Working great but need more testing, especially with ipv6. For now
we don't validate if one configured summary is inside another or the
presence of duplicates. Will address these issues in a future commit.
Diffstat (limited to 'usr.sbin/eigrpd/rde_dual.c')
-rw-r--r-- | usr.sbin/eigrpd/rde_dual.c | 56 |
1 files changed, 44 insertions, 12 deletions
diff --git a/usr.sbin/eigrpd/rde_dual.c b/usr.sbin/eigrpd/rde_dual.c index ad7e32b584b..d9a6de14d9b 100644 --- a/usr.sbin/eigrpd/rde_dual.c +++ b/usr.sbin/eigrpd/rde_dual.c @@ -1,4 +1,4 @@ -/* $OpenBSD: rde_dual.c,v 1.6 2015/10/21 03:48:09 renato Exp $ */ +/* $OpenBSD: rde_dual.c,v 1.7 2015/10/21 03:52:12 renato Exp $ */ /* * Copyright (c) 2015 Renato Westphal <renato@openbsd.org> @@ -613,6 +613,10 @@ uninstall: void rt_set_successor(struct rt_node *rn, struct eigrp_route *successor) { + struct eigrp *eigrp = rn->eigrp; + struct eigrp_iface *ei; + struct summary_addr *summary; + if (successor == NULL) { rn->successor.nbr = NULL; rn->successor.type = 0; @@ -622,17 +626,22 @@ rt_set_successor(struct rt_node *rn, struct eigrp_route *successor) sizeof(rn->successor.metric)); memset(&rn->successor.emetric, 0, sizeof(rn->successor.emetric)); - return; + } else { + rn->successor.nbr = successor->nbr; + rn->successor.type = successor->type; + rn->successor.fdistance = successor->distance; + rn->successor.rdistance = successor->rdistance; + memcpy(&rn->successor.metric, &successor->metric, + sizeof(rn->successor.metric)); + memcpy(&rn->successor.emetric, &successor->emetric, + sizeof(rn->successor.emetric)); } - rn->successor.nbr = successor->nbr; - rn->successor.type = successor->type; - rn->successor.fdistance = successor->distance; - rn->successor.rdistance = successor->rdistance; - memcpy(&rn->successor.metric, &successor->metric, - sizeof(rn->successor.metric)); - memcpy(&rn->successor.emetric, &successor->emetric, - sizeof(rn->successor.emetric)); + TAILQ_FOREACH(ei, &eigrp->ei_list, e_entry) { + summary = rde_summary_check(ei, &rn->prefix, rn->prefixlen); + if (summary) + rt_summary_set(eigrp, summary, &rn->successor.metric); + } } struct eigrp_route * @@ -674,10 +683,32 @@ rt_get_successor_fc(struct rt_node *rn) return (successor); } +struct summary_addr * +rde_summary_check(struct eigrp_iface *ei, union eigrpd_addr *prefix, + uint8_t prefixlen) +{ + struct summary_addr *summary; + + TAILQ_FOREACH(summary, &ei->summary_list, entry) { + /* do not filter the summary itself */ + if (summary->prefixlen == prefixlen && + !eigrp_addrcmp(ei->eigrp->af, prefix, &summary->prefix)) + return (NULL); + + if (summary->prefixlen <= prefixlen && + !eigrp_prefixcmp(ei->eigrp->af, prefix, &summary->prefix, + summary->prefixlen)) + return (summary); + } + + return (NULL); +} + void rde_send_update(struct eigrp_iface *ei, struct rinfo *ri) { - if (ri->metric.hop_count >= ei->eigrp->maximum_hops) + if (ri->metric.hop_count >= ei->eigrp->maximum_hops || + rde_summary_check(ei, &ri->prefix, ri->prefixlen)) ri->metric.delay = EIGRP_INFINITE_METRIC; rde_imsg_compose_eigrpe(IMSG_SEND_MUPDATE, ei->ifaceid, 0, @@ -768,7 +799,8 @@ rde_send_reply(struct rde_nbr *nbr, struct rinfo *ri, int siareply) { int type; - if (ri->metric.hop_count >= nbr->eigrp->maximum_hops) + if (ri->metric.hop_count >= nbr->eigrp->maximum_hops || + rde_summary_check(nbr->ei, &ri->prefix, ri->prefixlen)) ri->metric.delay = EIGRP_INFINITE_METRIC; if (!siareply) |