diff options
Diffstat (limited to 'sysdep')
-rw-r--r-- | sysdep/linux/krt-scan.c | 2 | ||||
-rw-r--r-- | sysdep/linux/netlink/netlink.c | 12 | ||||
-rw-r--r-- | sysdep/unix/krt-iface.c | 11 |
3 files changed, 22 insertions, 3 deletions
diff --git a/sysdep/linux/krt-scan.c b/sysdep/linux/krt-scan.c index 42f92877..b7fc1295 100644 --- a/sysdep/linux/krt-scan.c +++ b/sysdep/linux/krt-scan.c @@ -100,7 +100,7 @@ krt_parse_entry(byte *ent, struct krt_proto *p) if (flags & RTF_GATEWAY) { neighbor *ng = neigh_find(&p->p, &gw, 0); - if (ng) + if (ng && ng->scope) a.iface = ng->iface; else /* FIXME: Remove this warning? Handle it somehow... */ diff --git a/sysdep/linux/netlink/netlink.c b/sysdep/linux/netlink/netlink.c index 70abdd73..1c9d9778 100644 --- a/sysdep/linux/netlink/netlink.c +++ b/sysdep/linux/netlink/netlink.c @@ -321,6 +321,7 @@ nl_parse_addr(struct nlmsghdr *h) int new = h->nlmsg_type == RTM_NEWADDR; struct ifa ifa; struct iface *ifi; + int scope; if (!(i = nl_checkin(h, sizeof(*i))) || !nl_parse_attrs(IFA_RTA(i), a, sizeof(a))) return; @@ -355,6 +356,7 @@ nl_parse_addr(struct nlmsghdr *h) ifa.iface = ifi; if (i->ifa_flags & IFA_F_SECONDARY) ifa.flags |= IA_SECONDARY; + /* IFA_LOCAL can be unset for IPv6 interfaces */ memcpy(&ifa.ip, RTA_DATA(a[IFA_LOCAL] ? : a[IFA_ADDRESS]), sizeof(ifa.ip)); ipa_ntoh(ifa.ip); @@ -389,6 +391,14 @@ nl_parse_addr(struct nlmsghdr *h) ifa.prefix = ipa_and(ifa.ip, netmask); } + scope = ipa_classify(ifa.ip); + if (scope < 0) + { + log(L_ERR "KIF: Invalid interface address %I", ifa.ip); + return; + } + ifa.scope = scope & IADDR_SCOPE_MASK; + DBG("KIF: IF%d(%s): %s IPA %I, flg %x, net %I/%d, brd %I, opp %I\n", ifi->index, ifi->name, new ? "added" : "removed", @@ -664,7 +674,7 @@ nl_parse_route(struct nlmsghdr *h, int scan) memcpy(&ra.gw, RTA_DATA(a[RTA_GATEWAY]), sizeof(ra.gw)); ipa_ntoh(ra.gw); ng = neigh_find(&p->p, &ra.gw, 0); - if (ng) + if (ng && ng->scope) ra.iface = ng->iface; else /* FIXME: Remove this warning? Handle it somehow... */ diff --git a/sysdep/unix/krt-iface.c b/sysdep/unix/krt-iface.c index bd4a40a7..ddd70e99 100644 --- a/sysdep/unix/krt-iface.c +++ b/sysdep/unix/krt-iface.c @@ -35,7 +35,7 @@ scan_ifs(struct ifreq *r, int cnt) char *err, *colon; unsigned fl; ip_addr netmask; - int l; + int l, scope; if_start_update(); for (cnt /= sizeof(struct ifreq); cnt; cnt--, r++) @@ -115,6 +115,14 @@ scan_ifs(struct ifreq *r, int cnt) ) i.flags |= IF_MULTICAST; + scope = ipa_classify(a.ip); + if (scope < 0) + { + log(L_ERR "%s: Invalid address", i.name); + goto bad; + } + a.scope = scope & IADDR_SCOPE_MASK; + if (a.pxlen < 32) { a.brd = ipa_or(a.prefix, ipa_not(ipa_mkmask(a.pxlen))); @@ -132,6 +140,7 @@ scan_ifs(struct ifreq *r, int cnt) } else a.brd = a.opposite; + a.scope = SCOPE_UNIVERSE; if (ioctl(if_scan_sock, SIOCGIFMTU, r) < 0) { err = "SIOCGIFMTU"; goto faulty; } |