I made a trivial patch for the case.

On Tue, Sep 20, 2022 at 6:23 PM Alexander Zubkov <gr...@qrator.net> wrote:
>
> Hi,
>
> Bird from master branch ignores the default preference set in channel
> for a kernel protocol, like that:
>
> protocol kernel {
>         learn yes;
>         ipv4 {
>                 preference 200;
>                 import all;
>                 export none;
>         };
> }
>
> Version 2.0.10 seems ok. I suppose the change was introduced with this commit:
>
> https://gitlab.nic.cz/labs/bird/-/commit/eb937358c087eaeb6f209660cc7ecfe6d6eff739
>
> It adds setting of the preference to the krt_learn_async() function.
> But as I understand when route is learned with netlink hook it is
> processed like this:
> nl_parse_route -> krt_got_route_async -> krt_learn_async
> But when it is learned from scan, it is processed like this:
> nl_parse_route -> krt_got_route -> krt_learn_scan
>
> And setting preference was not added to krt_learn_scan() function.
>
> I also saw that in my test - when I added a new route to the kernel
> while bird was running, it appeared in bird with correct preference.
> But some time after, the scan updated the route and it was replaced
> with the default preference.
commit 4a233ea65adf794e358e425a6cb9c4fde060b35c
Author: Alexander Zubkov <gr...@qrator.net>
Date:   Wed Sep 21 17:07:11 2022 +0200

    KRT: Fix setting default preference
    
    Changes in commit eb937358 boke setting of channel preference for alien
    routes learned during scan. The preference was set only for async routes.
    Move common attribute processing part of functions krt_learn_async() and
    krt_learn_async() to a separate function to have only one place for such
    changes.

diff --git a/sysdep/unix/krt.c b/sysdep/unix/krt.c
index c4a3a4a8..cb0f1d4f 100644
--- a/sysdep/unix/krt.c
+++ b/sysdep/unix/krt.c
@@ -318,6 +318,15 @@ krt_learn_announce_delete(struct krt_proto *p, net *n)
   rte_update(&p->p, n->n.addr, NULL);
 }
 
+static void
+krt_learn_alien_attr(struct channel *c, rte *e)
+{
+  ASSERT(!e->attrs->cached);
+  e->attrs->pref = c->preference;
+
+  e->attrs = rta_lookup(e->attrs);
+}
+
 /* Called when alien route is discovered during scan */
 static void
 krt_learn_scan(struct krt_proto *p, rte *e)
@@ -326,7 +335,7 @@ krt_learn_scan(struct krt_proto *p, rte *e)
   net *n = net_get(p->krt_table, n0->n.addr);
   rte *m, **mm;
 
-  e->attrs = rta_lookup(e->attrs);
+  krt_learn_alien_attr(p->p.main_channel, e);
 
   for(mm=&n->routes; m = *mm; mm=&m->next)
     if (krt_same_key(m, e))
@@ -438,10 +447,7 @@ krt_learn_async(struct krt_proto *p, rte *e, int new)
   net *n = net_get(p->krt_table, n0->n.addr);
   rte *g, **gg, *best, **bestp, *old_best;
 
-  ASSERT(!e->attrs->cached);
-  e->attrs->pref = p->p.main_channel->preference;
-
-  e->attrs = rta_lookup(e->attrs);
+  krt_learn_alien_attr(p->p.main_channel, e);
 
   old_best = n->routes;
   for(gg=&n->routes; g = *gg; gg = &g->next)

Reply via email to