Re: ospf6d problem when a route already exists with a different nexthop

2012-09-29 Thread Manuel Guesdon
Sorry, here is the patch:

diff -u ospf6d.uptodate/kroute.c ospf6d.patch1/kroute.c
--- ospf6d.uptodate/kroute.cThu Sep 20 15:25:33 2012
+++ ospf6d.patch1/kroute.c  Thu Sep 27 18:01:37 2012
@@ -59,6 +59,8 @@
 intkr_redist_eval(struct kroute *, struct rroute *);
 void   kr_redistribute(struct kroute_node *);
 intkroute_compare(struct kroute_node *, struct kroute_node *);
+intkr_change_fib(struct kroute_node *, struct kroute *, int, int);
+intkr_delete_fib(struct kroute_node *);
 
 struct kroute_node *kroute_find(const struct in6_addr *, u_int8_t);
 struct kroute_node *kroute_matchgw(struct kroute_node *,
@@ -140,18 +142,102 @@
 }
 
 int
-kr_change(struct kroute *kroute)
+kr_change_fib(struct kroute_node *kr, struct kroute *kroute, int krcount,
+int action)
 {
+   int  i;
+   struct kroute_node  *kn, *nkn;
+
+   if (action == RTM_ADD) {
+   /*
+* First remove all stale multipath routes.
+* This step must be skipped when the action is RTM_CHANGE
+* because it is already a single path route that will be
+* changed.
+*/
+   for (kn = kr; kn != NULL; kn = nkn) {
+   for (i = 0; i  krcount; i++) {
+   if 
(IN6_ARE_ADDR_EQUAL(kn-r.nexthop,kroute[i].nexthop))
+   break;
+   }
+   nkn = kn-next;
+   if (i == krcount)
+   /* stale route */
+   if (kr_delete_fib(kn) == -1)
+   log_warnx(kr_delete_fib failed);
+   log_debug(kr_update_fib: before: %s%s,
+   log_in6addr(kn-r.nexthop),
+   i == krcount ?  (deleted) : );
+   }
+   }
+
+   /*
+* now add or change the route
+*/
+   for (i = 0; i  krcount; i++) {
+   /* nexthop within 127/8 - ignore silently */
+   if (kr  IN6_IS_ADDR_LOOPBACK(kr-r.nexthop))
+   continue;
+
+   if (action == RTM_ADD  kr) {
+   for (kn = kr; kn != NULL; kn = kn-next) {
+   if 
(IN6_ARE_ADDR_EQUAL(kn-r.nexthop,kroute[i].nexthop))
+   break;
+   }
+
+   log_debug(kr_update_fib: after : %s%s,
+log_in6addr(kroute[i].nexthop),
+kn == NULL ?  (added) : );
+
+   if (kn != NULL)
+   /* nexthop already present, skip it */
+   continue;
+   } else
+   /* modify first entry */
+   kn = kr;
+
+   /* send update */
+   if (send_rtmsg(kr_state.fd, action, kroute[i]) == -1)
+   return (-1);
+
+   /* create new entry unless we are changing the first entry */
+   if (action == RTM_ADD)
+   if ((kn = calloc(1, sizeof(*kn))) == NULL)
+   fatal(NULL);
+
+   kn-r.prefix = kroute[i].prefix;
+   kn-r.prefixlen = kroute[i].prefixlen;
+   kn-r.nexthop = kroute[i].nexthop;
+   kn-r.scope = kroute[i].scope;
+   kn-r.flags = kroute[i].flags | F_OSPFD_INSERTED;
+   kn-r.ext_tag = kroute[i].ext_tag;
+   rtlabel_unref(kn-r.rtlabel);   /* for RTM_CHANGE */
+   kn-r.rtlabel = kroute[i].rtlabel;
+   if (action == RTM_ADD) {
+   if (kroute_insert(kn) == -1) {
+   log_debug(kr_update_fib: cannot insert %s,
+   log_in6addr(kn-r.nexthop));
+   free(kn);
+   }
+   }
+   action = RTM_ADD;
+   }
+   return  (0);
+}
+
+int
+kr_change(struct kroute *kroute, int krcount)
+{
struct kroute_node  *kr;
int  action = RTM_ADD;
 
kroute-rtlabel = rtlabel_tag2id(kroute-ext_tag);
 
-   if ((kr = kroute_find(kroute-prefix, kroute-prefixlen)) !=
-   NULL) {
-   if (!(kr-r.flags  F_KERNEL))
-   action = RTM_CHANGE;
-   else {  /* a non-ospf route already exists. not a problem */
+   kr = kroute_find(kroute-prefix, kroute-prefixlen);
+
+   if (kr != NULL) {
+   if (kr-r.flags  F_KERNEL) {
+   /* a non-ospf route already exists. not a problem */
if (!(kr-r.flags  F_BGPD_INSERTED)) {
do {
kr-r.flags |= F_OSPFD_INSERTED;
@@ -170,79 +256,43 @@
 * - 

Re: ospf6d problem when a route already exists with a different nexthop

2012-09-27 Thread Manuel Guesdon
On Thu, 20 Sep 2012 18:00:26 +0200
Claudio Jeker cje...@diehard.n-r-g.com wrote:

| On Thu, Sep 20, 2012 at 05:19:53PM +0200, Manuel Guesdon wrote:
|  Hi,
|  
|  After checking cvs tree, it seems that ospf6d isn't following changes done 
in
|  ospfd. 
|  
|  Is someone working on updating ospf6d to add changes done in ospfd ? (or 
may
|  be it's not the best way to do ?).
|  
|  If it's a good idea to do it, I can try. Do you have some advice ? Should I
|  try to apply a big diff between ospfd initial (i.e. 2007 version) and 
current
|  state ? Or is there a way to retrieve each patch made to ospfd between 2007
|  and now ?
|  
|  A last question: ospf6d initial version was created by copying and 
modifying
|  ospfd files; I presume it was done this way instead of having same code 
with
|  #ifdef mecanism for good reasons. After 5 years of evolution, does these
|  reasons still appear beoing valid (I just ask, I haven't sufficient 
knowledge
|  to give an answer).
|  
| 
| OSPFv2 and OSPFv3 are similar but still to different to have a common
| source. We try to sync parts between the two daemons from time to time but
| in some parts the behaviour is to different so that syncing is almost
| impossible.

OK.

| I may sound like a broken record but we accept diffs. So if you think
| there are commits in ospfd that need to be synced over we will have a look
| at them.

Here is a patch adapted from ospfd patch of Tue Sep 25 11:25:41 2007
UTC (the one of version 1.52 of kroute.c):

Last missing piece in the equal cost multipath support for ospfd.
Send all possible nexthops to the parent process and correctly sync
the RIB, FIB and kernel routing table. Based on initial work by pyr@.
OK pyr@ norby@
PS: don't forget that you need to enable multipath support via a sysctl


It seems to solve my problem but not perfectly. 
When starting ospf6d with the best link between 2 hosts down, fib contains
2 other routes comme from 2 other hosts (these 2 routes have equal cost).
When the link came UP, these 2 routes are removed and replaced by the best
route; that's alright.
Next when the link goes down, the 2 alternative routes are well added in fib
but the precedent best route is still in the fib (I see it with  route -n -v
show |grep TargetIP). May be an important point: TargetIP is an IPv6 on lo1.

I can't find why; if you have any idea... I have a test network so I can make
test easily...


Manuel


-- 
Cordialement,

Manuel Guesdon

--
__
Manuel Guesdon - OXYMIUM

[demime 1.01d removed an attachment of type application/octet-stream which had 
a name of ospf6d-patch1]



Re: ospf6d problem when a route already exists with a different nexthop

2012-09-20 Thread Manuel Guesdon
Hi,

After checking cvs tree, it seems that ospf6d isn't following changes done in
ospfd. 

Is someone working on updating ospf6d to add changes done in ospfd ? (or may
be it's not the best way to do ?).

If it's a good idea to do it, I can try. Do you have some advice ? Should I
try to apply a big diff between ospfd initial (i.e. 2007 version) and current
state ? Or is there a way to retrieve each patch made to ospfd between 2007
and now ?

A last question: ospf6d initial version was created by copying and modifying
ospfd files; I presume it was done this way instead of having same code with
#ifdef mecanism for good reasons. After 5 years of evolution, does these
reasons still appear beoing valid (I just ask, I haven't sufficient knowledge
to give an answer).


Manuel


On Sun, 9 Sep 2012 17:14:42 +0200
Manuel Guesdon ml+openbsd.m...@oxymium.net wrote:

| 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 :::a
|route to: :::a
| destination: :::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   mtuexpire
| 4200 0 0
| 
| :::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 :::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 :::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 :::8
|route to: :::8
| destination: :::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   mtuexpire
|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 :::8/128
| MG send_rtmsg1: action 1, prefix :::8/128
| MG send_rtmsg2: action 1, nexthop: fe80::5054:60ff:fe60:365
| ...
| MG kr_change:  prefix :::8/128
| MG kr_change2: found prefix :::8/128
| MG kr_change:  prefix :::8/128 !FKERNEL
| MG send_rtmsg1: action 3, prefix :::8/128
| MG send_rtmsg2: action 3, nexthop: fe80::5054:60ff:fe60:321
| send_rtmsg: action 1, prefix :::8/128: File exists
| 
| 
| After killing ospf6d, (first/bad) route is still here:
| root@core3:usr.sbin$ route -n get -inet6 :::8
|route to: :::8
| destination: :::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   mtuexpire
|   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:
|  

Re: ospf6d problem when a route already exists with a different nexthop

2012-09-20 Thread Claudio Jeker
On Thu, Sep 20, 2012 at 05:19:53PM +0200, Manuel Guesdon wrote:
 Hi,
 
 After checking cvs tree, it seems that ospf6d isn't following changes done in
 ospfd. 
 
 Is someone working on updating ospf6d to add changes done in ospfd ? (or may
 be it's not the best way to do ?).
 
 If it's a good idea to do it, I can try. Do you have some advice ? Should I
 try to apply a big diff between ospfd initial (i.e. 2007 version) and current
 state ? Or is there a way to retrieve each patch made to ospfd between 2007
 and now ?
 
 A last question: ospf6d initial version was created by copying and modifying
 ospfd files; I presume it was done this way instead of having same code with
 #ifdef mecanism for good reasons. After 5 years of evolution, does these
 reasons still appear beoing valid (I just ask, I haven't sufficient knowledge
 to give an answer).
 

OSPFv2 and OSPFv3 are similar but still to different to have a common
source. We try to sync parts between the two daemons from time to time but
in some parts the behaviour is to different so that syncing is almost
impossible.

I may sound like a broken record but we accept diffs. So if you think
there are commits in ospfd that need to be synced over we will have a look
at them.
-- 
:wq Claudio



ospf6d problem when a route already exists with a different nexthop

2012-09-09 Thread Manuel Guesdon
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 :::a
   route to: :::a
destination: :::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   mtuexpire
4200 0 0

:::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 :::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 :::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 :::8
   route to: :::8
destination: :::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   mtuexpire
   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 :::8/128
MG send_rtmsg1: action 1, prefix :::8/128
MG send_rtmsg2: action 1, nexthop: fe80::5054:60ff:fe60:365
...
MG kr_change:  prefix :::8/128
MG kr_change2: found prefix :::8/128
MG kr_change:  prefix :::8/128 !FKERNEL
MG send_rtmsg1: action 3, prefix :::8/128
MG send_rtmsg2: action 3, nexthop: fe80::5054:60ff:fe60:321
send_rtmsg: action 1, prefix :::8/128: File exists


After killing ospf6d, (first/bad) route is still here:
root@core3:usr.sbin$ route -n get -inet6 :::8
   route to: :::8
destination: :::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   mtuexpire
  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