Subject: [babel] Unicast Hellos?

From: Juliusz Chroboczek <[email-masked]>
Date: Sun, 28 May 2017 23:31:02 +0200

Dear list,

As I may have mentioned before, we at Babel Towers are planning to work on
Stenberg-style security for Babel during the month of July.  While we can
start the work without unicast Hellos (Hellos will be unprotected, big
deal, and RTT estimation will break), it would of course be better if we
had a complete design for unicast Hellos so that we can implement both at
the same time.

We did discuss some of the issues about unicast Hellos back in Chicago,
and at the risk of boring my audience, please allow me to reiterate (my
understanding of) our conclusions:

  1. There are two natural ways of encoding unicast Hellos: by using the
     Reserved field of the existing Hello, or by defining a new TLV.  The
     latter has a more graceful failure mode in the presence of legacy
     implementations, the former seems more elegant to some.  Since we're
     already breaking compatibility with the Mandatory bit, I'm okay with
     either choice.  (There is also one unnatural way -- using a carefully
     crafted sub-TLV -- but I don't think we're going to do that.)

  2. There is some confusion about the meaning of Interval in the presence
     of unicast Hellos: does it carry a promise of sending another Hello
     of any type, or does it carry a promise of sending a Hello of the
     same type.  If the latter, then I can see a need for an interval-less
     Hello.  (Interval=0 is a reasonable way to encode that.)

  3. The majority opinion appears that Unicast Hellos carry a Seqno, just
     like multicast ones.  My proposal to make them Seqno-less was soundly
     trashed.

  4. Unicast Hellos require new link-quality estimation algorithms.  In
     the spirit of RFC 6126, I intend that said algorithms will not be
     normative -- implementation advice will be given in the relevant
     appendix to the spec.  I am volunteering to do some serious
     experimentation.

As mentioned in a previous mail, I'll be only marginally available until
9 June, but fairly active after that date.  I would be overwhelmed with
joy if people could write down and implement their proposals by that date.

-- Juliusz

---

From: Toke Høiland-Jørgensen <[email-masked]>
Date: Mon, 29 May 2017 13:06:04 +0200

Juliusz Chroboczek <[email-masked]> writes:

> As mentioned in a previous mail, I'll be only marginally available
> until 9 June, but fairly active after that date. I would be
> overwhelmed with joy if people could write down and implement their
> proposals by that date.

I've recently started hacking on Babel in Bird again. Unicast mode is
high on my list (right after getting dual-stack operation to work), but
no promises I'll get around to it before June 9th...

-Toke

---

From: Juliusz Chroboczek <[email-masked]>
Date: Mon, 29 May 2017 14:48:58 +0200

> (right after getting dual-stack operation to work)

Bird supports that nowadays?  Cool.

-- Juliusz

---

From: Toke Høiland-Jørgensen <[email-masked]>
Date: Mon, 29 May 2017 15:01:37 +0200

> Bird supports that nowadays?  Cool.

The 2.0-pre releases add support for this to the core (int-new branch of
the Bird git repo). I'm in the process of making the Babel protocol
support it as well...

-Toke

---

From: Justin Kilpatrick <[email-masked]>
Date: Tue, 30 May 2017 07:18:47 -0400

I was actually playing with unicast hellos this weekend. I'm pretty
happy with my implementation at this point so I'll try and package it
up and present it.

Out of curiosity do y'all use a VM based test environment? We've got a
netnamespace based one that's very fast and easy to use, but seems to
have some problems with route insertions.

On Mon, May 29, 2017 at 9:01 AM, Toke Høiland-Jørgensen <[email-masked]> wrote:
> _______________________________________________
> babel mailing list
> [email-masked]
> https://www.ietf.org/mailman/listinfo/babel

---

From: Toke Høiland-Jørgensen <[email-masked]>
Date: Tue, 30 May 2017 13:43:12 +0200

> happy with my implementation at this point so I'll try and package it

Cool! Please do share. Which approach did you take to encoding the
unicast hellos?

> have some problems with route insertions.

I have done both. These days, I tend to prefer network namespaces, but I
have not done complicated topologies. I don't suppose you can share your
setup scripts? Would be cool to have a "reference" test environment to
verify implementations...

-Toke

---

From: justin kilpatrick <[email-masked]>
Date: Tue, 30 May 2017 08:59:15 -0400

First off sorry for the email change, I try to keep to personal email
for personal projects but turns out I was only subbed to this mailing
list at work until today.

> Cool! Please do share. Which approach did you take to encoding the

I created a new TLV, specifically our goal is the verification of
route metrics so I've been trying to extend the hello/IHU mechanism
across multiple hops without being too invasive to the overall code.
So in this case I want to send a hello addressed to a non-neighbor,
I'm not totally sure if you have similar requirements as I'm not
familiar with what Stenberg style security implies, I have the closest
RFC I can find printed to read tonight.

Anyways back on subject, I created a new tlv and then piggybacked on
the existing unicast accumulate functions and a neighbor struct to
build a copy of a normal hello message, at the end I have a custom
flush_unicast() function that sets the destination address to a remote
address then flushes the unicast buffer so that we don't cause any
other confusion. I grab a sequence number and interval from the
interface struct in the neighbor struct I select.

You can see the code here, please excuse the mess and be kind if you
find any glaring flaws [0]

> verify implementations...

This is what we're using to test right now [1], I was actually running
into some problems with it not inserting routes into the namespace
routing table this weekend so chances are it need improvement. But it
is nice to have an instant standup test env.

[0] https://github.com/althea-mesh/babeld/blob/experiments/message.c#L1191
[1] https://github.com/sudomesh/network-lab

---

From: Toke Høiland-Jørgensen <[email-masked]>
Date: Tue, 30 May 2017 16:06:19 +0200

> So in this case I want to send a hello addressed to a non-neighbor,

Ah, right, so this is supposed to be in addition to the normal hello
mechanism?

> RFC I can find printed to read tonight.

This is basically just (as I understand it) a common moniker for
security mechanisms that only work over unicast (such as DTLS and IPSEC
that need separate keys for each pair of hosts communicating). So in
order to work with this, Hellos need to either be unicast, or they will
not be protected.

My motivation for having a unicast hello is slightly different: I want
to be able to run Babel on links that either do not support multicast at
all (such as the Wireguard VPN), or have poorer performance for
multicast traffic (such as WiFi).

Both of these use cases requires a replacement for multicast hellos, but
I was not envisioning them being multihop.

> is nice to have an instant standup test env.

Ah, that's really neat. I was thinking I'd set up an evaluation scenario
in Core (https://www.nrl.navy.mil/itd/ncs/products/core), but this looks
way more manageable. I'll take it for a spin later and see if I get any
errors (have not noticed anything on my single-namespace tests so far).

-Toke

---

From: justin kilpatrick <[email-masked]>
Date: Tue, 30 May 2017 10:27:02 -0400

> Ah, right, so this is supposed to be in addition to the normal hello

In our case yes, we need some of the same security properties to make
sure this packet can go multiple hops and be secure on the other end.
So that's a good place to share effort. We may end up having to modify
some of the metric calculation code too so that we can compute roughly
equal numbers by communicating directly with a remote node as the
network should produce by the 'normal' method of route distribution.

We want to verify some but not all remote routes and use that to rank
neighbors by how many of their routes are trustworthy. A sort of local
reputation system that we outline here [0].

> I was not envisioning them being multihop.

If you don't need multihop functionality you can just remove the
custom flush function. The normal unicast flush function will just
send the packet to the neighbor address.

[0] http://altheamesh.com/documents/whitepaper.pdf

---

From: Toke Høiland-Jørgensen <[email-masked]>
Date: Tue, 30 May 2017 16:50:38 +0200

> reputation system that we outline here [0].

Right, I see. I assume you'll need some kind of end-to-end verification
in this case, as you're basically trying to protect against malicious
transit nodes (that could just alter the multi-hop hello/IHUs); how are
you going to do that?

Also, from reading the description it was not clear to me exactly what a
"destination" is? If a gateway advertises a prefix (say
2001:db8:100::/64), which address is a node supposed to send its
multi-hop hello to?

> send the packet to the neighbor address.

I'm developing an independent implementation of Babel (in the Bird
routing daemon), so I try not to look at the babeld code; and so I
didn't read your code. But from the white paper, it seems your unicast
hello is something separate from the unicast version of the normal hello
that we have been discussing. I.e., they should have separate TLV
numbers, no?

-Toke

---

From: justin kilpatrick <[email-masked]>
Date: Tue, 30 May 2017 11:14:00 -0400

> 2001:db8:100::/64), which address is a node supposed to send its

In our case we want to reach the person advertising that prefix, we
really don't care what their exact address is.
In the ideal world we could send packets to Babel node id's but we're
settling on an assumption that if we send
this packet to a destination in the advertised prefix it will be
'eaten' by the babel node on the other end and responded
to correctly. Which probably isn't great networking design.

> that we have been discussing. I.e., they should have separate TLV

That's easy enough, we already identify it as a multhop hello in it's TLV.

Anyways I think we're starting to diverge from the subject of this
thread and should take further conversations on this topic off list or
to a different on list thread.

- Justin

---

From: Toke Høiland-Jørgensen <[email-masked]>
Date: Tue, 30 May 2017 17:32:05 +0200

justin kilpatrick <[email-masked]> writes:

> really don't care what their exact address is. In the ideal world we
> could send packets to Babel node id's but we're settling on an
> assumption that if we send this packet to a destination in the
> advertised prefix it will be 'eaten' by the babel node on the other
> end and responded to correctly. Which probably isn't great networking
> design.

Ah, I see. So "magic", basically ;)

> That's easy enough, we already identify it as a multhop hello in it's

Yup, just wanted to be sure we were on the same page, and that I should
not try to interoperate with your implementation when I get around to
doing unicast hellos...

> to a different on list thread.

Yeah, having a separate discussion on multi-hop metrics might be useful
at some point :)

-Toke

---

From: Juliusz Chroboczek <[email-masked]>
Date: Tue, 30 May 2017 18:49:18 +0200

> [0] https://github.com/althea-mesh/babeld/blob/experiments/message.c#L1191

I don't see how that code can possibly work.  It passes a router-id in the
address parameter, which is later stuck into the sin_addr field of
a sockaddr_in6.  It also reuses a neighbour's unicast buffer without
flushing it first, which may cause TLVs to be sent to the wrong address.

-- Juliusz

---

From: justin kilpatrick <[email-masked]>
Date: Tue, 30 May 2017 13:45:43 -0400

> flushing it first, which may cause TLVs to be sent to the wrong address.

It's toy code, I did get it working using the neighbor address and was
playing around with looking at router ID's and debugging why routes
where not getting inserted into the netns routing tables when I
stopped for the day with no intent to publish it. Probably should have
cleaned it up before I linked it here.

I do see your point on the buffering logic though, there's no way it
could go multiple hops because I'm not seeing the address right, I
would need to do so in flushbuf not after the bucket check. As for the
bad caching safety trying to trace that now I'm not sure I agree with
you, start unicast runs flush_unicast and I use the
flush_unicast_remote function to close things out properly. Now I
should probably run flush_unicast instead of flushbuff at the start of
the hello function but I don't see where we actually end up with TLV's
in the wrong buffer?

I've never done anything involving networking outside of Python and
Java so it's possible I'm missing something really obvious.