This diff solves the issue of PR6597 for me and should be commited.
If nobody screams I will commit it tomorrow evening.
--
:wq Claudio
Index: usr.sbin/ospfd/rde_spf.c
===================================================================
RCS file: /cvs/src/usr.sbin/ospfd/rde_spf.c,v
retrieving revision 1.72
diff -u -p -r1.72 rde_spf.c
--- usr.sbin/ospfd/rde_spf.c 9 May 2011 12:24:41 -0000 1.72
+++ usr.sbin/ospfd/rde_spf.c 20 May 2011 10:25:04 -0000
@@ -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 *a
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 *a
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 *a
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 *a
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
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
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,
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_
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_
}
if (equal || better)
- rt_nexthop_add(rte, vnh, adv_rtr);
+ rt_nexthop_add(rte, vnh, v_type, adv_rtr);
}
}