mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-08-15 09:20:25 +00:00
Merge pull request #3641 from opensourcerouting/rsock-ipv6-fix
zebra: fix a few problems with routing socket
This commit is contained in:
commit
518515a1e3
@ -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);
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user