[Swan-dev] quagga/nhrp integration to libreswan

Timo Teras timo.teras at iki.fi
Tue Apr 5 20:19:54 UTC 2016

On Tue, 5 Apr 2016 15:50:28 -0400 (EDT)
Paul Wouters <paul at nohats.ca> wrote:

> On Tue, 5 Apr 2016, Timo Teras wrote:
> > 1. Initiate IKE+CHILD SA of specific connection to specific host.
> > That is nhrp provides the connection name, and left/right
> > IP-addresses (roughly equivalent of kernel sent acquire).
> >
> > 2. Terminate all SAs given the connection name, and IP-addresses.  
> That can be done with whack (see below)

Right. Yes, it's mostly there after quick glance.

> > 3. Get information of IKE SA authentications (preferably including
> > the DER certificate if using x509). This information is sent to
> > optional nhrp triggers for authentication (e.g. to verify gre
> > ip-addresses against the certificate before allowing their
> > registration).  
> That is something we will have to add. Can you explain in a little
> more details what you need.

Basically nhrpd tracks each logical link established. Currently it's
based on the public IP pair.

The initial boot strap is that the spoke node registers to hub.
Effectively what happens is:

1. spoke establishes IPsec SA with hub
2. spoke sends nhrp registration request "I want GRE IP a.b.c.d to
come to me"
3. hub first verifies that IPsec SA is established (that CHILD_SA
exists) and then accepts nhrp message for processing
4. hub then processes registration, and verifies that the IP-address
can be registered. this can also trigger hooks to e.g. automatically
configure BGP session + filters against the GRE IP.
5. hub updates GRE IP <-> public IP bindings in it's cache
6. hub sends reply back registration ack

This is the original DMVPN architecture based on the NHRP (RFC 2332).

There's also newer FlexVPN where some of this happens implicitly based
on additional IKEv2 payload exchanges, but I'm not yet attempting to
implement that. Step #1 is DMVPN. But this is to keep in mind that
later on I might need much more payload data from the IKE_SA
negotation in this IKE_SA hook.

So the hooks I'd need is that on hub: after step #1, IKE would tell nhrp
the IKE_SA authentication credentials (certificate); and
inform that valid child_sa exists.

Additionally if support for multiple spokes behind same NAT device (and
thus public IP) is added. There would need to be some systemwide unique
id through kernel, ike and nhrp that allows separating which logical
connection we are talking to. But this is a longer term problem to
solve too.

> > 4. Get information of CHILD SAs. The idea is that nhrp can then
> > flush all nhrp mappings when last CHILD SA expires (or is killed by
> > DPD).  
> so we have ipsec whack --trafficstatus but I guess you want a listing
> of "conn-name source/mask <-> dest/mask" ? If there are many like you
> suggest, would you want to ask pluto based on a conn name or a prefix?

I would probably want through connection name. In dmvpn the
traffic selector is basically "Transport mode, GRE". IPsec+GRE is used
purely as transit tunnel mechanism. BGP, OSPF or other routing protocol
is run inside to figure out what traffic should go where. NHRP
complements this by 1) keeping the GRE IP<->public IP bindings and 2)
assisting the routing protocol to create shortcut routes to bypass hub
nodes when possible (however, it's the routing protocol that
maintains the routes and decision where traffic is flowing. e.g. on
BGP withdrawal all nhrp shortcuts are immediately flushed).

Basically I'd like to maintain one socket between nhrp and pluto. I can
then send command such as:
 "Enumerate, and send updates for all IKE_SA and CHILD_SA with
 connection name 'foo'"

And then I'd hope to get first a full dump, and later a push style
notification of any notable additions/deletions/changes. I do not need
to track traffic counts, idle times or so. I basically need to track if
"valid CHILD_SA exists" and "what is the IKE_SA authentication data".

> > So I'm wondering if there would be interest to get a more stable
> > api to control libreswan supporting (at least) the above three
> > features. Ideally, it'd be single unix socket connection that is
> > event based (asynchronous) and accepts initiate/terminate requests
> > and provides the ike/child sa notifications (+ sa db
> > synchronization on connect in case nhrpd is restarted).  
> Whack in the end is also a simple socket, and you could implement
> whack in your app so you can just use a socket. But perhaps we need
> to give you a separate socket so there is no risk of accidentally
> blocking.

Yes. That would be ideal. I would hope that:

a) whack is stable and would have at least some backwards
compatibility so that app does not need to updated too often when a
some minor new feature is added to whack. Currently it seems to be very
sensitive to the rpc structure.

b) it would require only one socket connection. now whack connects for
each initiate request, and pluto terminates the status socket when
done. so events could be sent over the same socket (thus avoiding
reconnecting / requiring simultaneous connects).

This would also help because of the way shortcuts are established.
Normally when two spoke nodes start to talk to each other, the traffic
is first relayed through the serving hub node. However, the hub will
then send nhrp traffic indication to both asking them to establish
direct tunnel. They can end up initiating IKE_SA simultaneously to each
other, so passing all events through one socket helps up to avoid race

> Thanks for reaching out to us, and let's keep the conversation going
> to make this work with libreswan.

Thanks for the positive response! Will do!


More information about the Swan-dev mailing list