diff options
author | Claudio Jeker <claudio@cvs.openbsd.org> | 2009-10-05 08:20:27 +0000 |
---|---|---|
committer | Claudio Jeker <claudio@cvs.openbsd.org> | 2009-10-05 08:20:27 +0000 |
commit | 5e6ca13d17bb06f788768f818835f6420eff8a3d (patch) | |
tree | 3d46b77442efafab72cf3926b17e8938ca707076 | |
parent | 3dc1de0fadffb0117f49dc36fd559c9051df5ec5 (diff) |
Until now AS-ext LSA were always announced with the router as nexthop.
Change this so that the real nexthop is announced if the following
conditions are met:
- the nexthop is reachable via an OSPF enabled interface
- the interface is a broadcast or NBMA interface
It does not make sense to announce the nexthop of a point-to-point link
since the traffic has to go through this box anyway. This is closer to
what other systems implement.
-rw-r--r-- | usr.sbin/ospfd/rde.c | 52 |
1 files changed, 36 insertions, 16 deletions
diff --git a/usr.sbin/ospfd/rde.c b/usr.sbin/ospfd/rde.c index 4848b820076..88c1d7a4350 100644 --- a/usr.sbin/ospfd/rde.c +++ b/usr.sbin/ospfd/rde.c @@ -1,4 +1,4 @@ -/* $OpenBSD: rde.c,v 1.81 2009/06/06 07:31:26 eric Exp $ */ +/* $OpenBSD: rde.c,v 1.82 2009/10/05 08:20:26 claudio Exp $ */ /* * Copyright (c) 2004, 2005 Claudio Jeker <claudio@openbsd.org> @@ -56,6 +56,7 @@ int rde_req_list_exists(struct rde_nbr *, struct lsa_hdr *); void rde_req_list_del(struct rde_nbr *, struct lsa_hdr *); void rde_req_list_free(struct rde_nbr *); +struct iface *rde_asext_lookup(u_int32_t, int); struct lsa *rde_asext_get(struct rroute *); struct lsa *rde_asext_put(struct rroute *); @@ -1033,24 +1034,32 @@ rde_req_list_free(struct rde_nbr *nbr) /* * as-external LSA handling */ -struct lsa * -rde_asext_get(struct rroute *rr) +struct iface * +rde_asext_lookup(u_int32_t prefix, int plen) { struct area *area; struct iface *iface; - LIST_FOREACH(area, &rdeconf->area_list, entry) + LIST_FOREACH(area, &rdeconf->area_list, entry) { LIST_FOREACH(iface, &area->iface_list, entry) { if ((iface->addr.s_addr & iface->mask.s_addr) == - rr->kr.prefix.s_addr && iface->mask.s_addr == - prefixlen2mask(rr->kr.prefixlen)) { - /* already announced as (stub) net LSA */ - log_debug("rde_asext_get: %s/%d is net LSA", - inet_ntoa(rr->kr.prefix), rr->kr.prefixlen); - return (NULL); - } + (prefix & iface->mask.s_addr) && (plen == -1 || + iface->mask.s_addr == prefixlen2mask(plen))) + return (iface); } + } + return (NULL); +} +struct lsa * +rde_asext_get(struct rroute *rr) +{ + if (rde_asext_lookup(rr->kr.prefix.s_addr, rr->kr.prefixlen)) { + /* already announced as (stub) net LSA */ + log_debug("rde_asext_get: %s/%d is net LSA", + inet_ntoa(rr->kr.prefix), rr->kr.prefixlen); + return (NULL); + } /* update of seqnum is done by lsa_merge */ return (orig_asext_lsa(rr, DEFAULT_AGE)); } @@ -1138,6 +1147,7 @@ struct lsa * orig_asext_lsa(struct rroute *rr, u_int16_t age) { struct lsa *lsa; + struct iface *iface; u_int16_t len; len = sizeof(struct lsa_hdr) + sizeof(struct lsa_asext); @@ -1166,12 +1176,22 @@ orig_asext_lsa(struct rroute *rr, u_int16_t age) /* * nexthop -- on connected routes we are the nexthop, - * on all other cases we announce the true nexthop. - * XXX this is wrong as the true nexthop may be outside - * of the ospf cloud and so unreachable. For now we force - * all traffic to be directed to us. + * in other cases we may announce the true nexthop if the + * nexthop is reachable via an OSPF enabled interface but only + * broadcast & NBMA interfaces are considered in that case. + * It does not make sense to announce the nexthop of a point-to-point + * link since the traffic has to go through this box anyway. + * Some implementations actually check that there are multiple + * neighbors on the particular segment, we skip that check. */ - lsa->data.asext.fw_addr = 0; + iface = rde_asext_lookup(rr->kr.nexthop.s_addr, -1); + if (rr->kr.flags & F_CONNECTED) + lsa->data.asext.fw_addr = 0; + else if (iface && (iface->type == IF_TYPE_BROADCAST || + iface->type == IF_TYPE_NBMA)) + lsa->data.asext.fw_addr = rr->kr.nexthop.s_addr; + else + lsa->data.asext.fw_addr = 0; lsa->data.asext.metric = htonl(rr->metric); lsa->data.asext.ext_tag = htonl(rr->kr.ext_tag); |