[Babel-users] Duplicating externals (was: not routing)

Michael Grant mgrant at grant.org
Mon Nov 9 23:04:06 UTC 2009


I spent the day with this patch and several things are wrong.  I ran
into a string of problems getting this to work, not all are the fault
of babel at all.

- The metric of 2048 is way too high.  It seems anything about 255, my
router just returns an icmp no-route-to-host packet.

- I was not successful in getting babel to create a default route with
this to the other router, even though babel-pinger has created the
default route to loopback.

- Linux's multiple routing tables are not cumulative, once a packet
matches a rule, that table is used, no other table is consulted.  You
cannot combine tables, as in, it does not match one table if a table
of lower priority doesn't match a route.  So one must fill the routes
of the new table with the routes of the main table and keep them in
sync.

- When I manipulated the routes manually, I had dns problems because
my router is using dnsmasq which, when the default route changed,
insisted on sending dns requests to a host on the wrong network.
Problem is dnsmasq related, again, almost certainly a config problem
on my part.  I should be using a real dns server.

- I saw situations when I did not have a default route but I was using
babel-pinger to send out dns pings out a certain interface, but even
though the packets were going out the correct interface, the router on
the other side would not arp for an address which it knew how to get
to.  I needed a static host route to get around this.

Aside from many of these little problems, getting this working seems
to be a fine balancing act  I keep playing "whack-a-mole" solving one
problem and creating another in a loop.  It seems very easy to create
something that is very delicate.  I am sure I can get this working if
I continue, however, it seems clear to me that if I do manage to get
this working, it's going to be very easy to break.

I think it's time for me to abandon this and try some other method to
make this work.  My next best idea to make this work is to create
tunnels to a machine on the net and run babel on this third machine.

Thanks for your help and the patches!  Hopefully this has not been a
total waste of time.

Michael

On Sat, Nov 7, 2009 at 18:47, Juliusz Chroboczek <jch at pps.jussieu.fr> wrote:
> Okay, I think that's the correct solution.
>
> Please try this patch, running Babel with ``-A''.
>
>                                        Juliusz
>
> Sat Nov  7 18:44:25 CET 2009  Juliusz Chroboczek <jch at pps.jussieu.fr>
>  * Document -A.
> Sat Nov  7 18:43:25 CET 2009  Juliusz Chroboczek <jch at pps.jussieu.fr>
>  * Implement -A.
> diff -rN -u old-babeld/babeld.c new-babeld/babeld.c
> --- old-babeld/babeld.c 2009-11-07 18:44:52.228760892 +0100
> +++ new-babeld/babeld.c 2009-11-07 18:44:52.228760892 +0100
> @@ -171,6 +171,11 @@
>             if(kernel_metric < 0 || kernel_metric > 0xFFFF)
>                 goto usage;
>             break;
> +        case 'A':
> +            allow_duplicates = atoi(optarg);
> +            if(allow_duplicates < 0 || allow_duplicates > 0xFFFF)
> +                goto usage;
> +            break;
>         case 'P':
>             parasitic = 1;
>             break;
> @@ -231,7 +236,6 @@
>         }
>     }
>
> -
>     if(!config_file) {
>         if(access("/etc/babeld.conf", F_OK) >= 0)
>             config_file = "/etc/babeld.conf";
> @@ -258,6 +262,12 @@
>         wired_hello_interval = 20000;
>     wired_hello_interval = MAX(wired_hello_interval, 5);
>
> +    if(parasitic && allow_duplicates >= 0) {
> +        /* Too difficult to get right. */
> +        fprintf(stderr, "Sorry, -P and -A are incompatible.\n");
> +        exit(1);
> +    }
> +
>     if(do_daemonise) {
>         if(logfile == NULL)
>             logfile = "/var/log/babeld.log";
> @@ -776,7 +786,7 @@
>             "                "
>             "[-h hello] [-H wired_hello] [-i idle_hello]\n"
>             "                "
> -            "[-k metric] [-s] [-P] [-l] [-w] [-d level] [-g port]\n"
> +            "[-k metric] [-A metric] [-s] [-P] [-l] [-w] [-d level] [-g port]\n"
>             "                "
>             "[-t table] [-T table] [-c file] [-C statement]\n"
>             "                "
> diff -rN -u old-babeld/babeld.man new-babeld/babeld.man
> --- old-babeld/babeld.man       2009-11-07 18:44:52.224764188 +0100
> +++ new-babeld/babeld.man       2009-11-07 18:44:52.232763395 +0100
> @@ -52,6 +52,12 @@
>  Specify the priority value used when installing routes into the kernel.
>  The default is 0.
>  .TP
> +.BI \-A " priority"
> +Allow duplicating external routes when their kernel priority is at least
> +.IR priority .
> +Do not use this option unless you know what you are doing, as it can cause
> +persistent route flapping.
> +.TP
>  .B \-l
>  Use IFF_RUNNING (carrier sense) when determining interface availability.
>  .TP
> diff -rN -u old-babeld/message.c new-babeld/message.c
> --- old-babeld/message.c        2009-11-07 18:44:52.228760892 +0100
> +++ new-babeld/message.c        2009-11-07 18:44:52.232763395 +0100
> @@ -878,16 +878,15 @@
>             }
>
>             xroute = find_xroute(b[i].prefix, b[i].plen);
> -            if(xroute) {
> +            route = find_installed_route(b[i].prefix, b[i].plen);
> +
> +            if(xroute && (!route || xroute->metric <= kernel_metric)) {
>                 really_send_update(net, myid,
>                                    xroute->prefix, xroute->plen,
>                                    myseqno, xroute->metric);
>                 last_prefix = xroute->prefix;
>                 last_plen = xroute->plen;
> -                continue;
> -            }
> -            route = find_installed_route(b[i].prefix, b[i].plen);
> -            if(route) {
> +            } else if(route) {
>                 seqno = route->seqno;
>                 metric = route->metric;
>                 if(metric < INFINITY)
> @@ -903,13 +902,12 @@
>                 update_source(route->src, seqno, metric);
>                 last_prefix = route->src->prefix;
>                 last_plen = route->src->plen;
> -                continue;
> +            } else {
> +            /* There's no route for this prefix.  This can happen shortly
> +               after an xroute has been retracted, so send a retraction. */
> +                really_send_update(net, myid, b[i].prefix, b[i].plen,
> +                                   myseqno, INFINITY);
>             }
> -            /* If we reach this point, there's no route for this prefix.
> -               This can happen after an xroute has been retracted, so send
> -               a retraction. */
> -            really_send_update(net, myid, b[i].prefix, b[i].plen,
> -                               myseqno, INFINITY);
>         }
>         schedule_flush_now(net);
>     done:
> @@ -1348,7 +1346,9 @@
>     struct neighbour *successor = NULL;
>
>     xroute = find_xroute(prefix, plen);
> -    if(xroute) {
> +    route = find_installed_route(prefix, plen);
> +
> +    if(xroute && (!route || xroute->metric <= kernel_metric)) {
>         if(hop_count > 0 && memcmp(id, myid, 8) == 0) {
>             if(seqno_compare(seqno, myseqno) > 0) {
>                 if(seqno_minus(seqno, myseqno) > 100) {
> @@ -1362,7 +1362,6 @@
>         return;
>     }
>
> -    route = find_installed_route(prefix, plen);
>     if(route &&
>        (memcmp(id, route->src->id, 8) != 0 ||
>         seqno_compare(seqno, route->seqno) <= 0)) {
> diff -rN -u old-babeld/route.c new-babeld/route.c
> --- old-babeld/route.c  2009-11-07 18:44:52.224764188 +0100
> +++ new-babeld/route.c  2009-11-07 18:44:52.232763395 +0100
> @@ -42,6 +42,7 @@
>  struct route *routes = NULL;
>  int numroutes = 0, maxroutes = 0;
>  int kernel_metric = 0;
> +int allow_duplicates = -1;
>
>  struct route *
>  find_route(const unsigned char *prefix, unsigned char plen,
> @@ -512,6 +513,7 @@
>  consider_route(struct route *route)
>  {
>     struct route *installed;
> +    struct xroute *xroute;
>
>     if(route->installed)
>         return;
> @@ -519,8 +521,9 @@
>     if(!route_feasible(route))
>         return;
>
> -    if(find_xroute(route->src->prefix, route->src->plen))
> -       return;
> +    xroute = find_xroute(route->src->prefix, route->src->plen);
> +    if(xroute && (allow_duplicates < 0 || xroute->metric >= allow_duplicates))
> +        return;
>
>     installed = find_installed_route(route->src->prefix, route->src->plen);
>
> diff -rN -u old-babeld/route.h new-babeld/route.h
> --- old-babeld/route.h  2009-11-07 18:44:52.224764188 +0100
> +++ new-babeld/route.h  2009-11-07 18:44:52.232763395 +0100
> @@ -34,7 +34,7 @@
>
>  extern struct route *routes;
>  extern int numroutes, maxroutes;
> -extern int kernel_metric;
> +extern int kernel_metric, allow_duplicates;
>
>  struct route *find_route(const unsigned char *prefix, unsigned char plen,
>                          struct neighbour *neigh, const unsigned char *nexthop);
> diff -rN -u old-babeld/xroute.c new-babeld/xroute.c
> --- old-babeld/xroute.c 2009-11-07 18:44:52.224764188 +0100
> +++ new-babeld/xroute.c 2009-11-07 18:44:52.236762195 +0100
> @@ -208,8 +208,11 @@
>             if(rc) {
>                 struct route *route;
>                 route = find_installed_route(routes[i].prefix, routes[i].plen);
> -                if(route)
> -                    uninstall_route(route);
> +                if(route) {
> +                    if(allow_duplicates < 0 ||
> +                       routes[i].metric < allow_duplicates)
> +                        uninstall_route(route);
> +                }
>                 change = 1;
>                 if(send_updates)
>                     send_update(NULL, 0, routes[i].prefix, routes[i].plen);
>
>
> _______________________________________________
> Babel-users mailing list
> Babel-users at lists.alioth.debian.org
> http://lists.alioth.debian.org/mailman/listinfo/babel-users
>
>



More information about the Babel-users mailing list