Hi,
When an ospf route already exists, ospf6d doesn't update the nexthop.
I have 6 routers (4 with openbsd 5.0, 2 with openbsd 4.9) running ospfd,
ospf6d and bgpd, routeur id is on lo1.
For some reason (see at end for a way to reproduce it), one of the router
(openbsd 5.0 one) have multiple ospf ipv6 routes still in fib (even if no more
ospf6d or bgpd process is running). For exemple:
root@core3: route -n get -inet6 XXXX:YYYY::a
route to: XXXX:YYYY::a
destination: XXXX:YYYY::a
gateway: fe80::5054:60ff:fe60:3a1%vlan216
interface: vlan216
if address: fe80::5054:60ff:fe60:348%vlan216
priority: 32 (ospf)
flags: <UP,GATEWAY,HOST,DONE>
use mtu expire
4200 0 0
XXXX:YYYY::a is the loopback address of another router (the gateway is
obviously wrong as I've killed ospf6d and bgpd on the referenced host).
when starting ospf6d, a new route for XXXX:YYYY::a is found but ospf6d
find the previous one and don't change the nexthop. And when killing
ospf6d it doesn't remove it.
If I "route delete -inet6 -host XXXX:YYYY::a
fe80::5054:60ff:fe60:3a1%vlan216", and restart ospf6d the problem disappear.
I've took a look at ospf6d/kroute.c and found this route is processed like
that:
kr_change(struct kroute *kroute)
{
struct kroute_node *kr;
int action = RTM_ADD;
kroute->rtlabel = rtlabel_tag2id(kroute->ext_tag);
if ((kr = kroute_find(&kroute->prefix, kroute->prefixlen)) !=
NULL) {
===> goes here
if (!(kr->r.flags & F_KERNEL))
action = RTM_CHANGE;
else { /* a non-ospf route already exists. not a problem */
===> goes here
if (!(kr->r.flags & F_BGPD_INSERTED)) {
===> goes here
do {
kr->r.flags |= F_OSPFD_INSERTED;
kr = kr->next;
} while (kr);
===> exit (nexthop is unchanged)
return (0);
}
This problem occurs when the prefix is announced by different
ospf peers with a different nexthop. Exemple:
When starting ospf6d a first route is added learned from one ospf6d peer:
root@core3: route -n get -inet6 XXXX:YYYY::8
route to: XXXX:YYYY::8
destination: XXXX:YYYY::8
gateway: fe80::5054:60ff:fe60:365%vlan222
interface: vlan222
if address: fe80::5054:60ff:fe60:345%vlan222
priority: 32 (ospf)
flags: <UP,GATEWAY,HOST,DONE>
use mtu expire
0 0 0
Next a second route is learned (gateway on fe80::5054:60ff:fe60:321%vlan213
which is the most direct route) but ospf6d doesn't update it.
Here some traces I've added in ospf6d:
MG kr_change: prefix XXXX:YYYY::8/128
MG send_rtmsg1: action 1, prefix XXXX:YYYY::8/128
MG send_rtmsg2: action 1, nexthop: fe80::5054:60ff:fe60:365
...
MG kr_change: prefix XXXX:YYYY::8/128
MG kr_change2: found prefix XXXX:YYYY::8/128
MG kr_change: prefix XXXX:YYYY::8/128 !FKERNEL
MG send_rtmsg1: action 3, prefix XXXX:YYYY::8/128
MG send_rtmsg2: action 3, nexthop: fe80::5054:60ff:fe60:321
send_rtmsg: action 1, prefix XXXX:YYYY::8/128: File exists
After killing ospf6d, (first/bad) route is still here:
root@core3:usr.sbin$ route -n get -inet6 XXXX:YYYY::8
route to: XXXX:YYYY::8
destination: XXXX:YYYY::8
gateway: fe80::5054:60ff:fe60:365%vlan222
interface: vlan222
if address: fe80::5054:60ff:fe60:345%vlan222
priority: 32 (ospf)
flags: <UP,GATEWAY,HOST,DONE>
use mtu expire
28 0 0
I've retried multiple times and when the 1st learned route is the good one
(via vlan213) the route is well deleted when killing ospf6d.
I've tried to compare with ospfd and found that the following chnage seems to
handle nexthop change case:
http://www.openbsd.org/cgi-bin/cvsweb/src/usr.sbin/ospfd/kroute.c.diff?r1=1.52;r2=1.53;f=h
May be common changes in ospfd weren't ported to ospf6d ?
Manuel