[Babel-users] time, syscall, etc.

Juliusz Chroboczek jch at pps.jussieu.fr
Fri Jul 15 18:25:02 UTC 2011


> util.c, timeval_min, ~110:
> I was happy: there is a comment: 
> but it seems that {0, x} represents infinity, and not {0, 0}, or I think:
> 	if(s->tv_sec == 0)
> should be
> 	if(s->tv_sec == 0 && s->tv_usec == 0)
> no ?

Well, {0, x} for x /= 0 should never appear.  But yes.

> babel.c, main loop, around 550:
> if(kernel_socket < 0) kernel_setup_socket(1);
> Previously, we consider that a bad kernel_socket was sufficient to
> stop the program. Hum, I don't think the socket is possibly <0 at this
> point.

The kernel_socket descriptor is used for providing asynchronous
notifications from the kernel: if select detects that it's ready for
input, it will call kernel_routes_callback, it will call the various
check_* functions (check kernel_routes_callback, which is something of
a misnomer).

Now having asynchronous notification is cool, but not necessary: if
a kernel_something doesn't want to implement it, it doesn't, and babeld
will poll the kernel periodically -- see line 645 in babeld.c.  However,
as you justly note, both kernel_somethings in the current version of
babeld support asynchronous notifications.

(If you check the quagga sources, you will see that they have three
implementations of a kernel routing table interface -- rt_netlink,
rt_socket, just like in Babel, but also rt_ioctl.  THe latter doesn't
implement async notifications.)

> Same remark for the local_socket and local_server_socket.

Eh?  local_socket/local_server_socket are -1 unless you run babeld
with -g.

> Is FD_ZERO a non-raming* syscall?

It's not a system call, it's a very simple macro.  It's basically

  #define FD_ZERO(p) *p = 0

> It seems necessary to do a gettime(&now); only after select (in the
> other case we don't have wait anything).

It doesn't matter much -- we almost always go through select.

Please do not try to micro-optimise unless you have some profiling
results.  Keeping the code reasonably simple is just as important as
keeping it fast.  (And if you really want to optimise, there's some
pretty low-hanging fruit it route.c.)

> babel.c, somewhere near 590-610:
> if(errno != EAGAIN && errno != EINTR) {
>     perror("recv");
>     sleep(1);
> }
> Euhm… why blocking the entire rest of the program just because of
> a EAGAIN ? Don't we would sleep (if necessary) at the "select" ?

Read the code again.

> And finaly, what is the "*unicast*" things (like "unicast_neighbour",
> "flush_unicast") ?

Usually, Babel works over multicast.  However, there are a few messages
that are sent over unicast, such as some kind of requests.  When we want
to send a message over unicast, we buffer it in unicast_buffer, and
store the destination in unicast_neighbour.  See start_unicast_message,
which is the unicast analogue of start_message.

(Why do we do that?  First, jitter.  Second, usually we have multiple
unicast messages in quick succession for the same neighbour, for example
requests for both IPv4 and IPv6 addresses, bufferring allows sending
them in a sincle frame.)

-- Juliusz



More information about the Babel-users mailing list