summaryrefslogtreecommitdiff
path: root/usr.sbin/eigrpd/rde_dual.c
diff options
context:
space:
mode:
authorRenato Westphal <renato@cvs.openbsd.org>2015-10-21 03:52:13 +0000
committerRenato Westphal <renato@cvs.openbsd.org>2015-10-21 03:52:13 +0000
commita276edca3fd2a5e935de4b937501bf27e8d4da8f (patch)
tree50d5f5628ebdc7bfa4b8225f54ee96474d6b15c4 /usr.sbin/eigrpd/rde_dual.c
parent7782225b2926834dc635e6f72ac2a42468bc922d (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.c56
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)