diff options
author | Ondrej Zajicek (work) <santiago@crfreenet.org> | 2022-01-05 18:46:41 +0100 |
---|---|---|
committer | Ondrej Zajicek (work) <santiago@crfreenet.org> | 2022-01-05 18:46:41 +0100 |
commit | 77d032c71f62e44293a10ccc22f8c157442df179 (patch) | |
tree | f10464bef726a3dcbd131e3d78d6b306cfd41a87 /sysdep/linux/netlink.c | |
parent | 29dda184e56ce3a1ec72db4612198f6b3ba84e82 (diff) |
Netlink: Improve multipath parsing errors
Function nl_parse_multipath() should handle errors internally.
Diffstat (limited to 'sysdep/linux/netlink.c')
-rw-r--r-- | sysdep/linux/netlink.c | 41 |
1 files changed, 25 insertions, 16 deletions
diff --git a/sysdep/linux/netlink.c b/sysdep/linux/netlink.c index fdf3f2db..1293df4d 100644 --- a/sysdep/linux/netlink.c +++ b/sysdep/linux/netlink.c @@ -681,7 +681,7 @@ nl_add_multipath(struct nlmsghdr *h, uint bufsize, struct nexthop *nh, int af, e } static struct nexthop * -nl_parse_multipath(struct nl_parse_state *s, struct krt_proto *p, struct rtattr *ra, int af) +nl_parse_multipath(struct nl_parse_state *s, struct krt_proto *p, const net_addr *n, struct rtattr *ra, int af) { struct rtattr *a[BIRD_RTA_MAX]; struct rtnexthop *nh = RTA_DATA(ra); @@ -695,7 +695,7 @@ nl_parse_multipath(struct nl_parse_state *s, struct krt_proto *p, struct rtattr { /* Use RTNH_OK(nh,len) ?? */ if ((len < sizeof(*nh)) || (len < nh->rtnh_len)) - return NULL; + goto err; if (nh->rtnh_flags & RTNH_F_DEAD) goto next; @@ -706,7 +706,10 @@ nl_parse_multipath(struct nl_parse_state *s, struct krt_proto *p, struct rtattr rv->weight = nh->rtnh_hops; rv->iface = if_find_by_index(nh->rtnh_ifindex); if (!rv->iface) - return NULL; + { + log(L_ERR "KRT: Received route %N with unknown ifindex %u", n, nh->rtnh_ifindex); + return NULL; + } /* Nonexistent RTNH_PAYLOAD ?? */ nl_attr_len = nh->rtnh_len - RTNH_LENGTH(0); @@ -714,18 +717,18 @@ nl_parse_multipath(struct nl_parse_state *s, struct krt_proto *p, struct rtattr { case AF_INET: if (!nl_parse_attrs(RTNH_DATA(nh), nexthop_attr_want4, a, sizeof(a))) - return NULL; + goto err; break; case AF_INET6: if (!nl_parse_attrs(RTNH_DATA(nh), nexthop_attr_want6, a, sizeof(a))) - return NULL; + goto err; break; #ifdef HAVE_MPLS_KERNEL case AF_MPLS: if (!nl_parse_attrs(RTNH_DATA(nh), nexthop_attr_want_mpls, a, sizeof(a))) - return NULL; + goto err; if (a[RTA_NEWDST]) rv->labels = rta_get_mpls(a[RTA_NEWDST], rv->label); @@ -734,7 +737,7 @@ nl_parse_multipath(struct nl_parse_state *s, struct krt_proto *p, struct rtattr #endif default: - return NULL; + goto err; } if (a[RTA_GATEWAY]) @@ -757,14 +760,19 @@ nl_parse_multipath(struct nl_parse_state *s, struct krt_proto *p, struct rtattr nbr = neigh_find(&p->p, rv->gw, rv->iface, (rv->flags & RNF_ONLINK) ? NEF_ONLINK : 0); if (!nbr || (nbr->scope == SCOPE_HOST)) - return NULL; + { + log(L_ERR "KRT: Received route %N with strange next-hop %I", n, rv->gw); + return NULL; + } } #ifdef HAVE_MPLS_KERNEL if (a[RTA_ENCAP] && a[RTA_ENCAP_TYPE]) { - if (rta_get_u16(a[RTA_ENCAP_TYPE]) != LWTUNNEL_ENCAP_MPLS) { - log(L_WARN "KRT: Unknown encapsulation method %d in multipath", rta_get_u16(a[RTA_ENCAP_TYPE])); + if (rta_get_u16(a[RTA_ENCAP_TYPE]) != LWTUNNEL_ENCAP_MPLS) + { + log(L_WARN "KRT: Received route %N with unknown encapsulation method %d", + n, rta_get_u16(a[RTA_ENCAP_TYPE])); return NULL; } @@ -785,6 +793,10 @@ nl_parse_multipath(struct nl_parse_state *s, struct krt_proto *p, struct rtattr first = nexthop_sort(first); return first; + +err: + log(L_ERR "KRT: Received strange multipath route %N", n); + return NULL; } static void @@ -1675,19 +1687,16 @@ nl_parse_route(struct nl_parse_state *s, struct nlmsghdr *h) if (a[RTA_MULTIPATH]) { - struct nexthop *nh = nl_parse_multipath(s, p, a[RTA_MULTIPATH], i->rtm_family); + struct nexthop *nh = nl_parse_multipath(s, p, n, a[RTA_MULTIPATH], i->rtm_family); if (!nh) - { - log(L_ERR "KRT: Received strange multipath route %N", net->n.addr); - return; - } + SKIP("strange RTA_MULTIPATH\n"); nexthop_link(ra, nh); break; } if (i->rtm_flags & RTNH_F_DEAD) - return; + SKIP("ignore RTNH_F_DEAD\n"); ra->nh.iface = if_find_by_index(oif); if (!ra->nh.iface) |