Merge pull request #3641 from opensourcerouting/rsock-ipv6-fix

zebra: fix a few problems with routing socket
This commit is contained in:
Donald Sharp 2019-01-22 08:57:16 -05:00 committed by GitHub
commit 518515a1e3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 26 additions and 68 deletions

View File

@ -274,7 +274,7 @@ size_t _rta_get(caddr_t sap, void *destp, size_t destlen, bool checkaf)
if (sa->sa_family == AF_LINK) { if (sa->sa_family == AF_LINK) {
sdl = (struct sockaddr_dl *)sa; sdl = (struct sockaddr_dl *)sa;
if (sdl->sdl_index == 0 || sdl->sdl_nlen == 0) if (sdl->sdl_index == 0 || sdl->sdl_nlen == 0)
copylen = sizeof(*sdl) - sizeof(sdl->sdl_data); copylen = destlen;
} }
if (copylen > destlen) { if (copylen > destlen) {
@ -994,7 +994,7 @@ static int rtm_read_mesg(struct rt_msghdr *rtm, union sockunion *dest,
pnt += rta_get(pnt, gate, sizeof(*gate)); pnt += rta_get(pnt, gate, sizeof(*gate));
break; break;
case RTA_NETMASK: case RTA_NETMASK:
pnt += rta_get(pnt, mask, sizeof(*mask)); pnt += rta_getattr(pnt, mask, sizeof(*mask));
break; break;
case RTA_IFP: case RTA_IFP:
pnt += rta_getsdlname(pnt, ifname, ifnlen); pnt += rta_getsdlname(pnt, ifname, ifnlen);

View File

@ -44,30 +44,6 @@
extern struct zebra_privs_t zserv_privs; extern struct zebra_privs_t zserv_privs;
#ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
/* Adjust netmask socket length. Return value is a adjusted sin_len
value. */
static int sin_masklen(struct in_addr mask)
{
char *p, *lim;
int len;
struct sockaddr_in sin;
if (mask.s_addr == 0)
return sizeof(long);
sin.sin_addr = mask;
len = sizeof(struct sockaddr_in);
lim = (char *)&sin.sin_addr;
p = lim + sizeof(sin.sin_addr);
while (*--p == 0 && p >= lim)
len--;
return len;
}
#endif /* HAVE_STRUCT_SOCKADDR_IN_SIN_LEN */
#ifdef __OpenBSD__ #ifdef __OpenBSD__
static int kernel_rtm_add_labels(struct mpls_label_stack *nh_label, static int kernel_rtm_add_labels(struct mpls_label_stack *nh_label,
struct sockaddr_mpls *smpls) struct sockaddr_mpls *smpls)
@ -89,30 +65,6 @@ static int kernel_rtm_add_labels(struct mpls_label_stack *nh_label,
} }
#endif #endif
#ifdef SIN6_LEN
/* Calculate sin6_len value for netmask socket value. */
static int sin6_masklen(struct in6_addr mask)
{
struct sockaddr_in6 sin6;
char *p, *lim;
int len;
if (IN6_IS_ADDR_UNSPECIFIED(&mask))
return sizeof(long);
sin6.sin6_addr = mask;
len = sizeof(struct sockaddr_in6);
lim = (char *)&sin6.sin6_addr;
p = lim + sizeof(sin6.sin6_addr);
while (*--p == 0 && p >= lim)
len--;
return len;
}
#endif /* SIN6_LEN */
/* Interface between zebra message and rtm message. */ /* Interface between zebra message and rtm message. */
static int kernel_rtm(int cmd, const struct prefix *p, static int kernel_rtm(int cmd, const struct prefix *p,
const struct nexthop_group *ng, uint32_t metric) const struct nexthop_group *ng, uint32_t metric)
@ -155,23 +107,21 @@ static int kernel_rtm(int cmd, const struct prefix *p,
switch (p->family) { switch (p->family) {
case AF_INET: case AF_INET:
sin_dest.sin.sin_family = AF_INET; sin_dest.sin.sin_family = AF_INET;
#ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
sin_dest.sin.sin_len = sizeof(sin_dest);
sin_gate.sin.sin_len = sizeof(sin_gate);
#endif /* HAVE_STRUCT_SOCKADDR_IN_SIN_LEN */
sin_dest.sin.sin_addr = p->u.prefix4; sin_dest.sin.sin_addr = p->u.prefix4;
sin_gate.sin.sin_family = AF_INET; sin_gate.sin.sin_family = AF_INET;
#ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
sin_dest.sin.sin_len = sizeof(struct sockaddr_in);
sin_gate.sin.sin_len = sizeof(struct sockaddr_in);
#endif /* HAVE_STRUCT_SOCKADDR_SA_LEN */
break; break;
case AF_INET6: case AF_INET6:
sin_dest.sin6.sin6_family = AF_INET6; sin_dest.sin6.sin6_family = AF_INET6;
#ifdef SIN6_LEN
sin_dest.sin6.sin6_len = sizeof(sin_dest);
#endif /* SIN6_LEN */
sin_dest.sin6.sin6_addr = p->u.prefix6; sin_dest.sin6.sin6_addr = p->u.prefix6;
sin_gate.sin6.sin6_family = AF_INET6; sin_gate.sin6.sin6_family = AF_INET6;
#ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN #ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
sin_gate.sin6.sin6_len = sizeof(sin_gate); sin_dest.sin6.sin6_len = sizeof(struct sockaddr_in6);
#endif /* HAVE_STRUCT_SOCKADDR_IN_SIN_LEN */ sin_gate.sin6.sin6_len = sizeof(struct sockaddr_in6);
#endif /* HAVE_STRUCT_SOCKADDR_SA_LEN */
break; break;
} }
@ -193,6 +143,9 @@ static int kernel_rtm(int cmd, const struct prefix *p,
case NEXTHOP_TYPE_IPV4_IFINDEX: case NEXTHOP_TYPE_IPV4_IFINDEX:
sin_gate.sin.sin_addr = nexthop->gate.ipv4; sin_gate.sin.sin_addr = nexthop->gate.ipv4;
sin_gate.sin.sin_family = AF_INET; sin_gate.sin.sin_family = AF_INET;
#ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
sin_gate.sin.sin_len = sizeof(struct sockaddr_in);
#endif /* HAVE_STRUCT_SOCKADDR_SA_LEN */
ifindex = nexthop->ifindex; ifindex = nexthop->ifindex;
gate = true; gate = true;
break; break;
@ -200,6 +153,9 @@ static int kernel_rtm(int cmd, const struct prefix *p,
case NEXTHOP_TYPE_IPV6_IFINDEX: case NEXTHOP_TYPE_IPV6_IFINDEX:
sin_gate.sin6.sin6_addr = nexthop->gate.ipv6; sin_gate.sin6.sin6_addr = nexthop->gate.ipv6;
sin_gate.sin6.sin6_family = AF_INET6; sin_gate.sin6.sin6_family = AF_INET6;
#ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
sin_gate.sin6.sin6_len = sizeof(struct sockaddr_in6);
#endif /* HAVE_STRUCT_SOCKADDR_SA_LEN */
ifindex = nexthop->ifindex; ifindex = nexthop->ifindex;
/* Under kame set interface index to link local address */ /* Under kame set interface index to link local address */
#ifdef KAME #ifdef KAME
@ -228,6 +184,10 @@ static int kernel_rtm(int cmd, const struct prefix *p,
struct in_addr loopback; struct in_addr loopback;
loopback.s_addr = htonl(INADDR_LOOPBACK); loopback.s_addr = htonl(INADDR_LOOPBACK);
sin_gate.sin.sin_addr = loopback; sin_gate.sin.sin_addr = loopback;
#ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
sin_gate.sin.sin_len =
sizeof(struct sockaddr_in);
#endif /* HAVE_STRUCT_SOCKADDR_SA_LEN */
gate = true; gate = true;
} }
break; break;
@ -240,18 +200,16 @@ static int kernel_rtm(int cmd, const struct prefix *p,
case AF_INET: case AF_INET:
masklen2ip(p->prefixlen, &sin_mask.sin.sin_addr); masklen2ip(p->prefixlen, &sin_mask.sin.sin_addr);
sin_mask.sin.sin_family = AF_INET; sin_mask.sin.sin_family = AF_INET;
#ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN #ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
sin_mask.sin.sin_len = sin_masklen( sin_mask.sin.sin_len = sizeof(struct sockaddr_in);
sin_mask.sin.sin_addr); #endif /* HAVE_STRUCT_SOCKADDR_SA_LEN */
#endif /* HAVE_STRUCT_SOCKADDR_IN_SIN_LEN */
break; break;
case AF_INET6: case AF_INET6:
masklen2ip6(p->prefixlen, &sin_mask.sin6.sin6_addr); masklen2ip6(p->prefixlen, &sin_mask.sin6.sin6_addr);
sin_mask.sin6.sin6_family = AF_INET6; sin_mask.sin6.sin6_family = AF_INET6;
#ifdef SIN6_LEN #ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
sin_mask.sin6.sin6_len = sin6_masklen( sin_mask.sin6.sin6_len = sizeof(struct sockaddr_in6);
sin_mask.sin6.sin6_addr); #endif /* HAVE_STRUCT_SOCKADDR_SA_LEN */
#endif /* SIN6_LEN */
break; break;
} }