Git Product home page Git Product logo

ndprbrd's Introduction

Build Status

ndprbrd - NDP Routing Bridge Daemon.

The development has moved to https://github.com/DarthGandalf/ndprbrd

Disclaimer: This is not an official Google product.

This daemon has a very specific purpose: to give the same IPv6 prefix /64 to several network interfaces using radvd without creating L2 bridge and without need to configure DHCPv6. It's designed to be used together with ndppd for case if ISP gives single /64 without delegating a bigger prefix to your router.

Deprecation notice

On 2017-08-07 this functionality was merged into ndppd itself. However, there are several caveats:

  • If ndppd crashes for whatever reason, routes which it adds are never deleted. If this risk is unacceptable for you, use ndprbrd until this issue is fixed.
  • There was no new release of ndppd yet, so your favorite distro may have a version which doesn't support it. In that case you need to either still use ndprbrd, or build ndppd from git master.

An example ndppd config with this functionality enabled:

proxy eth0 {
  autowire yes
  rule 2001:db8:1:2::/64 {
    iface eth1
  }
  rule 2001:db8:1:2::/64 {
    iface eth2
  }
}
proxy eth1 {
  autowire yes
  rule 2001:db8:1:2::/64 {
    iface eth0
  }
  rule 2001:db8:1:2::/64 {
    iface eth2
  }
}
proxy eth2 {
  autowire yes
  rule 2001:db8:1:2::/64 {
    iface eth0
  }
  rule 2001:db8:1:2::/64 {
    iface eth1
  }
}

If new ndppd is enough for you, you can stop reading now.

How to use ndprbrd

Below are 2 sample setups - the simple one which doesn't need ndprbrd, and the more complicated one which makes use of it. The simple setup sets the base for the more complicated one.

Setup which does not need ndprbrd

+-------------------+
|        ISP        |
|  radvd announces  |
| 2001:db8:1:2::/64 |
+---------+---------+
          |
          |
          | eth0
          | addr 2001:db8:1:2::42
          | default route via link-local address
          | ndppd answers to NDP solicitations, so ISP thinks that the whole 2001:db8:1:2::/64 is here
   +------+------+
   |  My router  |
   +------+------+
          | eth1
          | radvd announces 2001:db8:1:2::/64
          | route to 2001:db8:1:2::/64
          |
          |
       +--+--+
       | LAN |
       +-----+
  • A packet comes from internet to 2001:db8:1:2::33
  • ISP sends NDP neigbor solicitation to the wire
  • ndppd sees it, and replies to it
    • depending on whether auto or static is used, ndppd behaves slightly differently, but I don't want to go to such details. Both modes work.
  • Router sends solicitation to LAN, gets response (neighbor advertisement), sends packets to there, and everyone is happy.

Setup with makes use of ndprbrd

+-------------------+
|        ISP        |
|  radvd announces  |
| 2001:db8:1:2::/64 |
+---------+---------+
          |
          |
          | eth0
          | addr 2001:db8:1:2::42
          | default route via link-local address
          | ndppd answers to NDP solicitations, so ISP thinks that the whole 2001:db8:1:2::/64 is here
   +------+------+
   |             |
   |             | eth2                                 +-------+
   |  My router  +--------------------------------------+ LAN-2 |
   |             | radvd announces 2001:db8:1:2::/64    +-------+
   |             |
   +------+------+
          | eth1
          | radvd announces 2001:db8:1:2::/64
          |
          |
      +---+---+
      | LAN-1 |
      +-------+

A packet already reached Router due to the same setup of eth0 as before, now it tries to reach an address 2001:db8:1:2::33. But which of two LANs contain this address? They both use the same prefix! Having route 2001:db8:1:2::/64 on both eth1 and eth2 won't work, as such routes will collide, and kernel will send packets to only one of interfaces.

This is where ndprbrd comes to rescue. It has 2 modes, using TAP interface (the recommended mode), and not using it.

                       | eth0
                 +-----+-----+
+-------+   eth1 |           | eth2   +-------+
| LAN-1 +--------+ My router +--------+ LAN-2 |
+-------+     ^  |           |     ^  +-------+
              |  +-----+-----+     |
              |        | ndprbrd0  |
              |        | route to 2001:db8:1:2::/64
              |        | accepts NDP solicitations only, and sends them to both LANs
              |        |           |
              +--------+-----------+

When Router tries to send a packet, it sends neighbor solicitation to ndprbrd0, and ndprbrd resends it to all interfaces which it's configured to use. Let's say LAN-1 replies with neighbor advertisement. Then ndprbrd sees it, and adds a static route to the advertised address 2001:db8:1:2::33 to interface eth1. From this point all packets to that address will go directly to eth1, and not to eth2, and not even to ndprbrd0.

If at some point later advertisements about 2001:db8:1:2::33 stopped coming from eth1, the static route is removed after a timeout (10 minutes by default). Then, if a new packet comes to that address, all LANs will be used to discover it again.

Only absence of traffic will trigger such timeout, because with traffic the neighbor solicitations are still sent from time to time. The solicitation will go directly to eth1 because of the static route, the machine will reply, and ndprbrd will see it and reset the timer.

                                   | eth0
route to 2001:db8:1:2:33/128       |
route to 2001:db8:1:2:77/128 +-----+-----+ route to 2001:db8:1:2::55/128
        +-------+       eth1 |           | eth2       +-------+
        | LAN-1 +------------+ My router +------------+ LAN-2 |
        +-------+         ^  |           |      ^     +-------+
                          |  +-----+-----+      |
                          |        | ndprbrd0   |
                          |        | route to 2001:db8:1:2::/64
                          |        | accepts NDP solicitations only, and sends them to both LANs
                          |        |            |
                          +--------+------------+

There is one more missing step: what happens when a machine in LAN-1 tries to send something to LAN-2? The answer is ndppd again: instead of listening only on eth0 ndppd should listen also on eth1 and eth2.

Note about firewall setup: forwarding from eth0 to ndprbrd0 should be accepted. Otherwise, kernel won't generate NDP solicitations to ndprbrd0. (TODO: this statement is true for static configuration of ndppd on eth0. Probably auto doesn't require this, but I didn't check)

The mode without TAP interface (not recommended)

If Linux is compiled without TUN/TAP interface support, another mode is available. In this mode, ndprbrd every second switches the route to 2001:db8:1:2::/64 from one interface to another. So when the neighbor solicitation is sent, there is a chance that it's sent to the correct LAN, in which case ndprbrd will see the neighbor advertisement, and add the route for that address.

Note that when an address is discovered in some LAN, due to the timeout mechanism described above, that address will continue working until it disappears from that LAN for 10 minutes. However, several first packets are likely to be dropped. In TAP mode they are still likely to be dropped, but number of first packets dropped is smaller in TAP mode.

Usage

./ndprbrd --interface=eth1 --interface=eth2 --prefix=2001:db8:1:2::/64

To change name of TAP interface, use --tun=foo. To use the mode without TAP interface, use --pendulum.

Sample config of ndppd:

proxy eth0 {
  rule 2001:db8:1:2::/64 {
    auto
  }
}
proxy eth1 {
  rule 2001:db8:1:2::/64 {
    auto
  }
}
proxy eth2 {
  rule 2001:db8:1:2::/64 {
    auto
  }
}

Note that eth0 (interface connected to ISP) is in ndppd, but not in ndprbrd.

Also note that routers don't usually accept RA themselves, so you might need to specify the default route yourself (or try to set accept_ra to 2).

Dependencies

  • Linux
  • Compiler with C++11 support:
    • GCC 4.9+
    • Clang 3.5 with libstdc++ 4.9
    • Earlier Clang and Clang with libc++ are not tested

Alternatives

  • Switch ISP to one that gives more than /64 :-)
  • Give different parts of /64 to LAN-1 and LAN-2, but that breaks SLAAC, so
    • Configure a static address for every host,
    • Or use DHCPv6
  • Bridge all networks together, which means that IPv4 will also be in a single subnet

ndprbrd's People

Contributors

darthgandalf avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

ndprbrd's Issues

Client switches network

Hi,

First of all, great idea and great software!
However, I think there two bugs.

1. On my Linux gateway the routes are never deleted, when running ndprbrd interactively in the shell I see messages like "deleting XXX:XXX:XXX from brX" but when issuing "ip -6 route" this route is still there. I have changed the expiration to 10s and the routes are still there, even if the client is disconnected. So old and stale routes are stacking up, also leading to the next problem. (moved to #9)

  1. If switching the above client, let's say from one wifi connection to another (same gateway, different interfaces) this old route is still left while a new is added out on the current interface. The effect is there is two routes to the same client, because the old route never seem to get deleted. Example:

2001:2002:5ae1:XXX:3 dev br2 proto 100 metric 1024 mtu 1500 advmss 1440 hoplimit 0 (old route)
2001:2002:5ae1::XXX:3 dev br1 proto 100 metric 1024 mtu 1500 advmss 1440 hoplimit 0

The best thing would be if ndprbrd could keep track on which existing routes exist, and say if above client rapidly switches wifi connection it sees a new NS from br1, and compares it to the current routing table and then sees the same client on br2 and therefore removes that routes automatically. I guess the idea is that routes to clients without any NS-traffic will be expired after 10 min as default, but that would also mean if a client switches to another network interface on the same gateway it'll have to wait 10 min before it gets any IPv6 network access...

Merging features into ndppd

Hi

I found your use case very useful and appreciate the efforts you put into this as it certainly saved me heaps of time.

After some effort I found that the functionality while still effective as a separate daemon may be a bit easier to maintain if merged with the original NDP proxy daemon - hence I forked the ndppd project and added the ability to automatically create routes in the project ndppd.

It's still a fork but I thought you may be interested in it, if so please take a look and let me know.
https://github.com/john-sharratt/ndppd

The pull request I've made in the NDPPD project is here:
DanielAdolfsson/ndppd#30

Kind Regards
John

Slow discovery

Tests show that it takes 30-60 sec for a connection to establish.

Investigate why, and how to make it faster.

Problem with route deletion

From #8 by @dulemis

On my Linux gateway the routes are never deleted, when running ndprbrd interactively in the shell I see messages like "deleting XXX:XXX:XXX from brX" but when issuing "ip -6 route" this route is still there. I have changed the expiration to 10s and the routes are still there, even if the client is disconnected. So old and stale routes are stacking up, also leading to the next problem.

Support policy based routing

Currently ip route command is called without specifying table, so the table defaults to main.
It assumes that this table is used, but it may be otherwise in ip rule show.
A possible solution would be to accept the table name (number) as an optional command line argument, and let system administrator to ensure this table is used in the routing policies.

Rewrite to C++

Currently this requires python, which is unlikely to get on a usual router.

Support not only Linux

e.g. FreeBSD

These features of Linux are currently dependent upon:

  • ip command to manage routes
  • /dev/net/tun; however, the pendulum mode doesn't require it
  • probably I missed something else

Drop Qt dependency

Qt is not as heavy dependency as python (#1), but still pretty heavy for a router.

Specific features of Qt used, and possible alternatives:

  • QCommandLineParser: getopt_long
  • QHostAddress: getaddrinfo with AI_NUMERICHOST
    • isInSubnet: comparison of first 8 bytes using memcmp
  • QNetworkInterface: ioctl with SIOCGIFINDEX (man 7 netdevice)
  • QSocketNotifier and QTimer: either select/poll/epoll/libevent, or threads with blocking reads
  • QProcess: fork? Probably talking to kernel directly to update routes would be more difficult than to call ip command

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.