summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHans Dedecker2021-01-09 20:17:48 +0000
committerHans Dedecker2021-01-20 20:03:10 +0000
commit64e1b4e78f65bd8ea41320be6ab732f6143955fe (patch)
tree4779dbc35876c1d5b0ed56bd9699e83676ff91e6
parentf16afb7e167e23718ae3d8573082a410b718ae4c (diff)
downloadodhcp6c-64e1b4e78f65bd8ea41320be6ab732f6143955fe.tar.gz
ra: fix routing loop on point to point linksopenwrt-19.07
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> (cherry picked from commit 53f07e90b7f1da6977143a488dd5cb73a33b233b)
-rw-r--r--src/ra.c11
1 files changed, 10 insertions, 1 deletions
diff --git a/src/ra.c b/src/ra.c
index 9fcdb31..6b76a77 100644
--- a/src/ra.c
+++ b/src/ra.c
@@ -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;
@@ -480,7 +488,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);