diff options
author | Claudio Jeker <claudio@cvs.openbsd.org> | 2011-05-24 20:21:52 +0000 |
---|---|---|
committer | Claudio Jeker <claudio@cvs.openbsd.org> | 2011-05-24 20:21:52 +0000 |
commit | 84cded86709d8bc018a9101ce6a067d69b5aa936 (patch) | |
tree | 7f341f48d263ab93ea44ae81b63d6930f8ab3da4 | |
parent | 4665eb962644a8b44bfd4fa96783da6a7f001eff (diff) |
Fix nexthop calculation for directly connected P2P links. connected
may only be set on directly connected networks but not on router
nodes which are used by the P2P links. Fix for PR 6597. OK sthen@
-rw-r--r-- | usr.sbin/ospfd/rde_spf.c | 54 |
1 files changed, 29 insertions, 25 deletions
diff --git a/usr.sbin/ospfd/rde_spf.c b/usr.sbin/ospfd/rde_spf.c index 996e9fcaf26..aea7d4de426 100644 --- a/usr.sbin/ospfd/rde_spf.c +++ b/usr.sbin/ospfd/rde_spf.c @@ -1,4 +1,4 @@ -/* $OpenBSD: rde_spf.c,v 1.72 2011/05/09 12:24:41 claudio Exp $ */ +/* $OpenBSD: rde_spf.c,v 1.73 2011/05/24 20:21:51 claudio Exp $ */ /* * Copyright (c) 2005 Esben Norby <norby@openbsd.org> @@ -38,9 +38,9 @@ struct vertex *spf_root = NULL; void calc_nexthop(struct vertex *, struct vertex *, struct area *, struct lsa_rtr_link *); void rt_nexthop_clear(struct rt_node *); -void rt_nexthop_add(struct rt_node *, struct v_nexthead *, +void rt_nexthop_add(struct rt_node *, struct v_nexthead *, u_int8_t, struct in_addr); -void rt_update(struct in_addr, u_int8_t, struct v_nexthead *, +void rt_update(struct in_addr, u_int8_t, struct v_nexthead *, u_int8_t, u_int32_t, u_int32_t, struct in_addr, struct in_addr, enum path_type, enum dst_type, u_int8_t, u_int32_t); void rt_invalidate(struct area *); @@ -194,7 +194,8 @@ rt_calc(struct vertex *v, struct area *area, struct ospfd_conf *conf) adv_rtr.s_addr = htonl(v->adv_rtr); rt_update(addr, mask2prefixlen(rtr_link->data), - &v->nexthop, v->cost + ntohs(rtr_link->metric), 0, + &v->nexthop, v->type, + v->cost + ntohs(rtr_link->metric), 0, area->id, adv_rtr, PT_INTRA_AREA, DT_NET, v->lsa->data.rtr.flags, 0); } @@ -206,7 +207,7 @@ rt_calc(struct vertex *v, struct area *area, struct ospfd_conf *conf) addr.s_addr = htonl(v->ls_id); adv_rtr.s_addr = htonl(v->adv_rtr); - rt_update(addr, 32, &v->nexthop, v->cost, 0, area->id, + rt_update(addr, 32, &v->nexthop, v->type, v->cost, 0, area->id, adv_rtr, PT_INTRA_AREA, DT_RTR, v->lsa->data.rtr.flags, 0); break; case LSA_TYPE_NETWORK: @@ -216,8 +217,8 @@ rt_calc(struct vertex *v, struct area *area, struct ospfd_conf *conf) addr.s_addr = htonl(v->ls_id) & v->lsa->data.net.mask; adv_rtr.s_addr = htonl(v->adv_rtr); rt_update(addr, mask2prefixlen(v->lsa->data.net.mask), - &v->nexthop, v->cost, 0, area->id, adv_rtr, PT_INTRA_AREA, - DT_NET, 0, 0); + &v->nexthop, v->type, v->cost, 0, area->id, adv_rtr, + PT_INTRA_AREA, DT_NET, 0, 0); break; case LSA_TYPE_SUM_NETWORK: case LSA_TYPE_SUM_ROUTER: @@ -251,12 +252,12 @@ rt_calc(struct vertex *v, struct area *area, struct ospfd_conf *conf) if (v->type == LSA_TYPE_SUM_NETWORK) { addr.s_addr = htonl(v->ls_id) & v->lsa->data.sum.mask; rt_update(addr, mask2prefixlen(v->lsa->data.sum.mask), - &v->nexthop, v->cost, 0, area->id, adv_rtr, + &v->nexthop, v->type, v->cost, 0, area->id, adv_rtr, PT_INTER_AREA, DT_NET, 0, 0); } else { addr.s_addr = htonl(v->ls_id); - rt_update(addr, 32, &v->nexthop, v->cost, 0, area->id, - adv_rtr, PT_INTER_AREA, DT_RTR, + rt_update(addr, 32, &v->nexthop, v->type, v->cost, 0, + area->id, adv_rtr, PT_INTER_AREA, DT_RTR, v->lsa->data.rtr.flags, 0); } @@ -322,19 +323,20 @@ asext_calc(struct vertex *v) if (rn->invalid) continue; - if (rn->connected && r->d_type == DT_NET) { - if (v->lsa->data.asext.fw_addr != 0) - vertex_nexthop_add(v, NULL, - v->lsa->data.asext.fw_addr); - else - vertex_nexthop_add(v, NULL, - htonl(v->adv_rtr)); - } else + /* + * if a fw_addr is specified and the nexthop + * is directly connected then it is possible to + * send traffic directly to fw_addr. + */ + if (v->lsa->data.asext.fw_addr != 0 && rn->connected) + vertex_nexthop_add(v, NULL, + v->lsa->data.asext.fw_addr); + else vertex_nexthop_add(v, NULL, rn->nexthop.s_addr); } rt_update(addr, mask2prefixlen(v->lsa->data.asext.mask), - &v->nexthop, v->cost, cost2, a, adv_rtr, type, + &v->nexthop, v->type, v->cost, cost2, a, adv_rtr, type, DT_NET, 0, ntohl(v->lsa->data.asext.ext_tag)); break; default: @@ -729,7 +731,7 @@ rt_nexthop_clear(struct rt_node *r) } void -rt_nexthop_add(struct rt_node *r, struct v_nexthead *vnh, +rt_nexthop_add(struct rt_node *r, struct v_nexthead *vnh, u_int8_t type, struct in_addr adv_rtr) { struct v_nexthop *vn; @@ -742,7 +744,8 @@ rt_nexthop_add(struct rt_node *r, struct v_nexthead *vnh, continue; rn->adv_rtr.s_addr = adv_rtr.s_addr; - rn->connected = vn->prev == spf_root; + rn->connected = (type == LSA_TYPE_NETWORK && + vn->prev == spf_root); rn->invalid = 0; r->invalid = 0; @@ -758,7 +761,8 @@ rt_nexthop_add(struct rt_node *r, struct v_nexthead *vnh, rn->nexthop.s_addr = vn->nexthop.s_addr; rn->adv_rtr.s_addr = adv_rtr.s_addr; rn->uptime = now.tv_sec; - rn->connected = vn->prev == spf_root; + rn->connected = (type == LSA_TYPE_NETWORK && + vn->prev == spf_root); rn->invalid = 0; r->invalid = 0; @@ -837,7 +841,7 @@ rt_dump(struct in_addr area, pid_t pid, u_int8_t r_type) void rt_update(struct in_addr prefix, u_int8_t prefixlen, struct v_nexthead *vnh, - u_int32_t cost, u_int32_t cost2, struct in_addr area, + u_int8_t v_type, u_int32_t cost, u_int32_t cost2, struct in_addr area, struct in_addr adv_rtr, enum path_type p_type, enum dst_type d_type, u_int8_t flags, u_int32_t tag) { @@ -863,7 +867,7 @@ rt_update(struct in_addr prefix, u_int8_t prefixlen, struct v_nexthead *vnh, rte->flags = flags; rte->ext_tag = tag; - rt_nexthop_add(rte, vnh, adv_rtr); + rt_nexthop_add(rte, vnh, v_type, adv_rtr); rt_insert(rte); } else { @@ -923,7 +927,7 @@ rt_update(struct in_addr prefix, u_int8_t prefixlen, struct v_nexthead *vnh, } if (equal || better) - rt_nexthop_add(rte, vnh, adv_rtr); + rt_nexthop_add(rte, vnh, v_type, adv_rtr); } } |