[PATCH v2 2/2] Add the Babel protocol.

Juliusz Chroboczek jch at pps.univ-paris-diderot.fr
Sat Jan 16 22:43:19 CET 2016


Nice.

> +		tx length <number>;

Please don't make this configurable, it only breaks interoperability.
Section 4 of RFC 6126 is very clear about the maximum size of a Babel
packet:

   It MUST NOT send packets larger than the attached interface's MTU
   (adjusted for lower-layer headers) or 512 octets, whichever is larger,
   but not exceeding 2^16 - 1 adjusted for lower-layer headers.

> +		rx buffer <number>;

In the same section, it says

   Every Babel speaker MUST be able to receive packets that are as large
   as any attached interface's MTU (adjusted for lower-layer headers) or
   512 octets, whichever is larger.

> +      <tag>hello interval <m/num/</tag>
> +      Interval at which periodic "hello" messages are sent on this interface,
> +      in seconds. Default: 20 seconds for wired interfaces, 4 seconds for wireless. 

Note that recent versions of babeld use 4s in all cases by default.  20s
turned out to be too long for our users.

> +      These options specify the ToS/DiffServ/Traffic class/Priority of the
> +      outgoing RIP packets.

RIP?

> +/* Is one number larger than another mod 65535? Since diff_mod64k is always >=
> +   0, just use a simple cutoff value to determine if the difference is small
> +   enough that one is really larger. Since these comparisons are only made for
> +   values that should not differ by more than a few numbers, this should be
> +   safe. */
> +static inline u16 ge_mod64k(u16 a, u16 b)
> +{
> +  return ((u16) a-b) < 0xfff0;
> +}

The comment is obsolete -- it applies to the previous version.

> +static struct babel_source *
> +babel_find_source(struct babel_entry *e, u64 router_id)
> +{
> +  struct babel_source *s;
> +  WALK_LIST(s, e->sources)
> +    if (s->router_id == router_id)
> +      return s;
> +  return NULL;
> +}

We've recently found out that in large networks, a large amount of CPU
time (40%) in babeld was taken by walking the source table -- I recommend
using a more efficient data structure here.  (Source creation/flushing is
rare, but searching for a source is very common.)

> +static void
> +babel_iface_timer(timer *t)
> +{

The triggered update logic here is not obvious to me.  Perhaps a comment
is suitable?

> +static void
> +babel_iface_update_buffers(struct babel_iface *ifa)
> +{
> +  if (!ifa->sk)
> +    return;
> +
> +  uint rbsize = ifa->cf->rx_buffer ?: ifa->iface->mtu;
> +  uint tbsize = ifa->cf->tx_length ?: ifa->iface->mtu;

Shouldn't you be accounting for IPv6 and UDP headers, at least for tbsize?

> +static enum parse_result
> +babel_read_ihu(struct babel_pkt_tlv_header *hdr,
> +               union babel_tlv *tlv,
> +               struct babel_parse_state *state)

[...]

> +  // We handle link-local IPs. In every other case, the addr field will be 0 but
> +  // validation will succeed. The handler takes care of these cases.

Hmm.  Well, ok.

> +static enum parse_result
> +babel_read_next_hop(struct babel_pkt_tlv_header *hdr,
> +                    union babel_tlv *tlv,
> +                    struct babel_parse_state *state)

AE 2 is perfectly legal in NH TLVs.  (Babeld only ever sends AE 3, but
non-LL NHs are perfectly legal.)  See Section 4.4.8 of RFC 6126.

> +void
> +babel_send_unicast(union babel_tlv *tlv, struct babel_iface *ifa, ip_addr dest)

Note that buffering unicasts can be useful in case you're forwarding
multiple requests to the same neighbour.  (I babeld, we buffer at most one
unicast packet per interface -- per-neighbour queueing is probably
overkill.)

> +  /* A router_id may be 0, so we need a separate variable to track whether we
> +     have seen a router_id */

Interesting observation.  This suggests making 0 router-id forbidden (and
all-1 too, for good measure).

> /* We use multithreading */
> #undef USE_PTHREADS

Wrong comment?

-- Juliusz


More information about the Bird-users mailing list