diff options
| author | Hans Dedecker | 2021-01-09 20:17:48 +0000 |
|---|---|---|
| committer | Hans Dedecker | 2021-01-10 20:01:12 +0000 |
| commit | 53f07e90b7f1da6977143a488dd5cb73a33b233b (patch) | |
| tree | c7584811e9b43d078e83107eac195cb4cb4c68a5 | |
| parent | 2b6959dfe2095402e004b63d9aca9900c074abb6 (diff) | |
| download | odhcp6c-53f07e90b7f1da6977143a488dd5cb73a33b233b.tar.gz | |
ra: fix routing loop on point to point links
For point-to-point links (e.g. PPP) don't create a link prefix route
when receiving a prefix information option with the on-link flag set.
Point-to-point links are non shared media and as such a destination
IPv6 address cannot be on-link.
If a link prefix route points to a point-to-point link it can trigger
a routing loop if the destination IPv6 address belongs to the prefix.
If such a packet is received and not directed to a local IPv6 address
it will be routed to the point-to-point link due to the link prefix route;
the upstream ISP router will route the IPv6 packet back due to the assigned
prefix route creating a "ping pong" effect
Signed-off-by: Hans Dedecker <dedeckeh@gmail.com>
| -rw-r--r-- | src/ra.c | 11 |
1 files changed, 10 insertions, 1 deletions
@@ -51,6 +51,7 @@ #include "ra.h" static bool nocarrier = false; +static bool ptp_link = false; static int sock = -1, rtnl = -1; static int if_index = 0; @@ -89,6 +90,13 @@ int ra_init(const char *ifname, const struct in6_addr *ifid, memset(&ifr, 0, sizeof(ifr)); strncpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name) - 1); + if (ioctl(sock, SIOCGIFFLAGS, &ifr) < 0) + goto failure; + + ptp_link = !!(ifr.ifr_flags & IFF_POINTOPOINT); + + memset(&ifr, 0, sizeof(ifr)); + strncpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name) - 1); if (ioctl(sock, SIOCGIFINDEX, &ifr) < 0) goto failure; @@ -488,7 +496,8 @@ bool ra_process(void) || entry->valid < entry->preferred) continue; - if (pinfo->nd_opt_pi_flags_reserved & ND_OPT_PI_FLAG_ONLINK) + if ((pinfo->nd_opt_pi_flags_reserved & ND_OPT_PI_FLAG_ONLINK) && + !ptp_link) changed |= odhcp6c_update_entry(STATE_RA_ROUTE, entry, 7200, ra_holdoff_interval); |