[solaris] Extra debug and cross-checks for kernel_socket, two Sol9 fixes.

2005-11-12 Alexander Gall <gall@switch.ch>

	* See [quagga-dev 1815]
	* kernel_socket.c: (rtm_write) Use SAROUNDUP when HAVE_SIN_LEN
	  is not available.
	* rt_socket.c: (kernel_rtm_ipv6(_multipath)) set family to
	  AF_INET6 on ipv6 routes.

2005-11-12 Paul Jakma <paul.jakma@sun.com>

	* kernel_socket.c: Add RTA_NAME_GET macro to extract name from
	  sockaddr_dl. Add some more RTF_ flags.
	* (ifan_read) Add some debug messages.
	* (ifm_read) Add more debug messages. More robust cross-checks
	  of index against name.
	  Fall back to by-name lookup if the index lookup fails, future
	  proofing more than anything else.
	  (ifam_read_mesg) Read RTA_IFP. Add debug messages.
	  (ifam_read) More debug. If there's an RTA_IFP and it isn't
	  the name of the interface, save it as the label.
	  (rtm_read_mesg) Read RTA_IFP.
	  (rtm_read) allow name to be retrieved.
	  (rtmsg_debug) expand on the debug message.
This commit is contained in:
paul 2005-11-12 22:55:10 +00:00
parent db29ae5fca
commit 6fe70d1b35
3 changed files with 177 additions and 93 deletions

View File

@ -1,3 +1,27 @@
2005-11-12 Alexander Gall <gall@switch.ch>
* See [quagga-dev 1815]
* kernel_socket.c: (rtm_write) Use SAROUNDUP when HAVE_SIN_LEN
is not available.
* rt_socket.c: (kernel_rtm_ipv6(_multipath)) set family to
AF_INET6 on ipv6 routes.
2005-11-12 Paul Jakma <paul.jakma@sun.com>
* kernel_socket.c: Add RTA_NAME_GET macro to extract name from
sockaddr_dl. Add some more RTF_ flags.
* (ifan_read) Add some debug messages.
* (ifm_read) Add more debug messages. More robust cross-checks
of index against name.
Fall back to by-name lookup if the index lookup fails, future
proofing more than anything else.
(ifam_read_mesg) Read RTA_IFP. Add debug messages.
(ifam_read) More debug. If there's an RTA_IFP and it isn't
the name of the interface, save it as the label.
(rtm_read_mesg) Read RTA_IFP.
(rtm_read) allow name to be retrieved.
(rtmsg_debug) expand on the debug message.
2005-11-11 Paul Jakma <paul.jakma@sun.com> 2005-11-11 Paul Jakma <paul.jakma@sun.com>
* kernel_socket.c: (ifm_read) arithmetic on void pointer * kernel_socket.c: (ifm_read) arithmetic on void pointer

View File

@ -83,7 +83,7 @@ extern struct zebra_t zebrad;
int len = SAROUNDUP ((PNT)); \ int len = SAROUNDUP ((PNT)); \
if ( ((DEST) != NULL) && \ if ( ((DEST) != NULL) && \
af_check (((struct sockaddr *)(PNT))->sa_family)) \ af_check (((struct sockaddr *)(PNT))->sa_family)) \
memcpy ((caddr_t)(DEST), (PNT), len); \ memcpy ((DEST), (PNT), len); \
(PNT) += len; \ (PNT) += len; \
} }
#define RTA_ATTR_GET(DEST, RTA, RTMADDRS, PNT) \ #define RTA_ATTR_GET(DEST, RTA, RTMADDRS, PNT) \
@ -91,10 +91,31 @@ extern struct zebra_t zebrad;
{ \ { \
int len = SAROUNDUP ((PNT)); \ int len = SAROUNDUP ((PNT)); \
if ( ((DEST) != NULL) ) \ if ( ((DEST) != NULL) ) \
memcpy ((caddr_t)(DEST), (PNT), len); \ memcpy ((DEST), (PNT), len); \
(PNT) += len; \ (PNT) += len; \
} }
#define RTA_NAME_GET(DEST, RTA, RTMADDRS, PNT, LEN) \
if ((RTMADDRS) & (RTA)) \
{ \
int len = SAROUNDUP ((PNT)); \
struct sockaddr_dl *sdl = (struct sockaddr_dl *)(PNT); \
if (IS_ZEBRA_DEBUG_KERNEL) \
zlog_debug ("%s: RTA_SDL_GET nlen %d, alen %d", \
__func__, sdl->sdl_nlen, sdl->sdl_alen); \
if ( ((DEST) != NULL) && (sdl->sdl_family == AF_LINK) \
&& (sdl->sdl_nlen < IFNAMSIZ) && (sdl->sdl_nlen <= len) ) \
{ \
memcpy ((DEST), sdl->sdl_data, sdl->sdl_nlen); \
(DEST)[sdl->sdl_nlen] = '\0'; \
(LEN) = sdl->sdl_nlen; \
} \
(PNT) += len; \
} \
else \
{ \
(LEN) = 0; \
}
/* Routing socket message types. */ /* Routing socket message types. */
struct message rtm_type_str[] = struct message rtm_type_str[] =
{ {
@ -144,6 +165,9 @@ struct message rtm_flag_str[] =
{RTF_LLINFO, "LLINFO"}, {RTF_LLINFO, "LLINFO"},
{RTF_STATIC, "STATIC"}, {RTF_STATIC, "STATIC"},
{RTF_BLACKHOLE, "BLACKHOLE"}, {RTF_BLACKHOLE, "BLACKHOLE"},
#ifdef RTF_PRIVATE
{RTF_PRIVATE, "PRIVATE"},
#endif /* RTF_PRIVATE */
{RTF_PROTO1, "PROTO1"}, {RTF_PROTO1, "PROTO1"},
{RTF_PROTO2, "PROTO2"}, {RTF_PROTO2, "PROTO2"},
#ifdef RTF_PRCLONING #ifdef RTF_PRCLONING
@ -167,6 +191,12 @@ struct message rtm_flag_str[] =
#ifdef RTF_MULTICAST #ifdef RTF_MULTICAST
{RTF_MULTICAST, "MULTICAST"}, {RTF_MULTICAST, "MULTICAST"},
#endif /* RTF_MULTICAST */ #endif /* RTF_MULTICAST */
#ifdef RTF_MULTIRT
{RTF_MULTIRT, "MULTIRT"},
#endif /* RTF_MULTIRT */
#ifdef RTF_SETSRC
{RTF_SETSRC, "SETSRC"},
#endif /* RTF_SETSRC */
{0, NULL} {0, NULL}
}; };
@ -216,8 +246,18 @@ ifan_read (struct if_announcemsghdr *ifan)
struct interface *ifp; struct interface *ifp;
ifp = if_lookup_by_index (ifan->ifan_index); ifp = if_lookup_by_index (ifan->ifan_index);
if (ifp == NULL && ifan->ifan_what == IFAN_ARRIVAL)
if (ifp)
assert ( (ifp->ifindex == ifan->ifan_index)
|| (ifp->ifindex == IFINDEX_INTERNAL) );
if ( (ifp == NULL || (ifp->ifindex == IFINDEX_INTERNAL)
&& ifan->ifan_what == IFAN_ARRIVAL)
{ {
if (IS_ZEBRA_DEBUG_KERNEL)
zlog_debug ("%s: creating interface for ifindex %d, name %s",
__func__, ifan->ifan_index, ifan->ifan_name);
/* Create Interface */ /* Create Interface */
ifp = if_get_by_name_len(ifan->ifan_name, ifp = if_get_by_name_len(ifan->ifan_name,
strnlen(ifan->ifan_name, strnlen(ifan->ifan_name,
@ -234,7 +274,8 @@ ifan_read (struct if_announcemsghdr *ifan)
if_get_metric (ifp); if_get_metric (ifp);
if (IS_ZEBRA_DEBUG_KERNEL) if (IS_ZEBRA_DEBUG_KERNEL)
zlog_debug ("interface %s index %d", ifp->name, ifp->ifindex); zlog_debug ("%s: interface %s index %d",
__func__, ifan->ifan_name, ifan->ifan_index);
return 0; return 0;
} }
@ -249,9 +290,12 @@ int
ifm_read (struct if_msghdr *ifm) ifm_read (struct if_msghdr *ifm)
{ {
struct interface *ifp = NULL; struct interface *ifp = NULL;
struct sockaddr_dl *sdl = NULL; char ifname[IFNAMSIZ];
short ifnlen = 0;
caddr_t *cp; caddr_t *cp;
unsigned int i;
/* terminate ifname at head (for strnlen) and tail (for safety) */
ifname[IFNAMSIZ - 1] = '\0';
/* paranoia: sanity check structure */ /* paranoia: sanity check structure */
if (ifm->ifm_msglen < sizeof(struct if_msghdr)) if (ifm->ifm_msglen < sizeof(struct if_msghdr))
@ -279,68 +323,56 @@ ifm_read (struct if_msghdr *ifm)
cp = cp + 12; cp = cp + 12;
#endif #endif
RTA_ADDR_GET (NULL, RTA_DST, ifm->ifm_addrs, cp);
RTA_ADDR_GET (NULL, RTA_GATEWAY, ifm->ifm_addrs, cp);
RTA_ATTR_GET (NULL, RTA_NETMASK, ifm->ifm_addrs, cp);
RTA_ADDR_GET (NULL, RTA_GENMASK, ifm->ifm_addrs, cp);
RTA_NAME_GET (ifname, RTA_IFP, ifm->ifm_addrs, cp, ifnlen);
RTA_ADDR_GET (NULL, RTA_IFA, ifm->ifm_addrs, cp);
RTA_ADDR_GET (NULL, RTA_AUTHOR, ifm->ifm_addrs, cp);
RTA_ADDR_GET (NULL, RTA_BRD, ifm->ifm_addrs, cp);
if (IS_ZEBRA_DEBUG_KERNEL)
zlog_debug ("%s: sdl ifname %s", __func__, (ifnlen ? ifname : "(nil)"));
/* /*
* Check for each sockaddr in turn, advancing over it. After this * Look up on ifindex first, because ifindices are the primary handle for
* loop, sdl should point to a sockaddr_dl iff one was present. * interfaces across the user/kernel boundary, for most systems. (Some
* messages, such as up/down status changes on NetBSD, do not include a
* sockaddr_dl).
*/ */
for (i = 1; i != 0; i <<= 1) if ( (ifp = if_lookup_by_index (ifm->ifm_index)) != NULL )
{ {
if (i & ifm->ifm_addrs) /* we have an ifp, verify that the name matches as some systems,
* eg Solaris, have a 1:many association of ifindex:ifname
* if they dont match, we dont have the correct ifp and should
* set it back to NULL to let next check do lookup by name
*/
if (ifnlen && (strncmp (ifp->name, ifname, IFNAMSIZ) != 0) )
{ {
if (i == RTA_IFP) if (IS_ZEBRA_DEBUG_KERNEL)
{ zlog_debug ("%s: ifp name %s doesnt match sdl name %s",
sdl = (struct sockaddr_dl *)cp; __func__, ifp->name, ifname);
break; ifp = NULL;
}
/* XXX warning: pointer of type `void *' used in arithmetic */
cp += SAROUNDUP(cp);
} }
} }
/* Ensure that sdl, if present, is actually a sockaddr_dl. */
if (sdl != NULL && sdl->sdl_family != AF_LINK)
{
zlog_err ("ifm_read: sockaddr_dl bad AF %d\n",
sdl->sdl_family);
return -1;
}
/* /*
* Look up on ifindex first, because ifindices are the primary * If we dont have an ifp, try looking up by name. Particularly as some
* handle for interfaces across the user/kernel boundary. (Some * systems (Solaris) have a 1:many mapping of ifindex:ifname - the ifname
* messages, such as up/down status changes on NetBSD, do not * is therefore our unique handle to that interface.
* include a sockaddr_dl).
*/
ifp = if_lookup_by_index (ifm->ifm_index);
/*
* If lookup by index was unsuccessful and we have a name, try
* looking up by name. Interfaces specified in the configuration
* file for which the ifindex has not been determined will have
* ifindex == IFINDEX_INTERNAL, and such interfaces are found by this search,
* and then their ifindex values can be filled in.
*/
if (ifp == NULL && sdl != NULL)
{
/*
* paranoia: sanity check name length. nlen does not include
* trailing zero, but IFNAMSIZ max length does.
* *
* XXX Is this test correct? Should it be '>=' or '>'? And is it even * Interfaces specified in the configuration file for which the ifindex
* necessary now that we are using if_lookup_by_name_len? * has not been determined will have ifindex == IFINDEX_INTERNAL, and such
* interfaces are found by this search, and then their ifindex values can
* be filled in.
*/ */
if (sdl->sdl_nlen >= IFNAMSIZ) if ( (ifp == NULL) && ifnlen)
{ ifp = if_lookup_by_name (ifname);
zlog_err ("ifm_read: illegal sdl_nlen %d\n", sdl->sdl_nlen);
return -1;
}
ifp = if_lookup_by_name_len (sdl->sdl_data, sdl->sdl_nlen);
}
/* /*
* If ifp does not exist or has an invalid index (IFINDEX_INTERNAL), create or * If ifp still does not exist or has an invalid index (IFINDEX_INTERNAL),
* fill in an interface. * create or fill in an interface.
*/ */
if ((ifp == NULL) || (ifp->ifindex == IFINDEX_INTERNAL)) if ((ifp == NULL) || (ifp->ifindex == IFINDEX_INTERNAL))
{ {
@ -348,17 +380,25 @@ ifm_read (struct if_msghdr *ifm)
* To create or fill in an interface, a sockaddr_dl (via * To create or fill in an interface, a sockaddr_dl (via
* RTA_IFP) is required. * RTA_IFP) is required.
*/ */
if (sdl == NULL) if (!ifnlen)
{ {
zlog_warn ("Interface index %d (new) missing RTA_IFP sockaddr_dl\n", zlog_warn ("Interface index %d (new) missing ifname\n",
ifm->ifm_index); ifm->ifm_index);
return -1; return -1;
} }
if (ifp == NULL) if (ifp == NULL)
{
/* Interface that zebra was not previously aware of, so create. */ /* Interface that zebra was not previously aware of, so create. */
ifp = if_create (sdl->sdl_data, sdl->sdl_nlen); ifp = if_create (ifname, ifnlen);
if (IS_ZEBRA_DEBUG_KERNEL)
zlog_debug ("%s: creating ifp for ifindex %d",
__func__, ifm->ifm_index);
}
if (IS_ZEBRA_DEBUG_KERNEL)
zlog_debug ("%s: updated/created ifp, ifname %s, ifindex %d",
__func__, ifp->name, ifp->ifindex);
/* /*
* Fill in newly created interface structure, or larval * Fill in newly created interface structure, or larval
* structure with ifindex IFINDEX_INTERNAL. * structure with ifindex IFINDEX_INTERNAL.
@ -372,13 +412,6 @@ ifm_read (struct if_msghdr *ifm)
#endif /* __bsdi__ */ #endif /* __bsdi__ */
if_get_metric (ifp); if_get_metric (ifp);
/*
* XXX sockaddr_dl contents can be larger than the structure
* definition, so the user of the stored structure must be
* careful not to read off the end.
*/
memcpy (&ifp->sdl, sdl, sizeof (struct sockaddr_dl));
if_add_update (ifp); if_add_update (ifp);
} }
else else
@ -390,6 +423,14 @@ ifm_read (struct if_msghdr *ifm)
* but apparently do not trigger action.) * but apparently do not trigger action.)
*/ */
{ {
if (ifp->ifindex != ifm->ifm_index)
{
zlog_warn ("%s: index mismatch, ifname %s, ifp index %d, "
"ifm index %d",
__func__, ifp->name, ifp->ifindex, ifm->ifm_index);
return -1;
}
if (if_is_up (ifp)) if (if_is_up (ifp))
{ {
ifp->flags = ifm->ifm_flags; ifp->flags = ifm->ifm_flags;
@ -423,7 +464,8 @@ ifm_read (struct if_msghdr *ifm)
#endif /* HAVE_NET_RT_IFLIST */ #endif /* HAVE_NET_RT_IFLIST */
if (IS_ZEBRA_DEBUG_KERNEL) if (IS_ZEBRA_DEBUG_KERNEL)
zlog_debug ("interface %s index %d", ifp->name, ifp->ifindex); zlog_debug ("%s: interface %s index %d",
__func__, ifp->name, ifp->ifindex);
return 0; return 0;
} }
@ -433,7 +475,9 @@ void
ifam_read_mesg (struct ifa_msghdr *ifm, ifam_read_mesg (struct ifa_msghdr *ifm,
union sockunion *addr, union sockunion *addr,
union sockunion *mask, union sockunion *mask,
union sockunion *dest) union sockunion *brd,
char *ifname,
short *ifnlen)
{ {
caddr_t pnt, end; caddr_t pnt, end;
@ -450,10 +494,15 @@ ifam_read_mesg (struct ifa_msghdr *ifm,
RTA_ADDR_GET (NULL, RTA_GATEWAY, ifm->ifam_addrs, pnt); RTA_ADDR_GET (NULL, RTA_GATEWAY, ifm->ifam_addrs, pnt);
RTA_ATTR_GET (mask, RTA_NETMASK, ifm->ifam_addrs, pnt); RTA_ATTR_GET (mask, RTA_NETMASK, ifm->ifam_addrs, pnt);
RTA_ADDR_GET (NULL, RTA_GENMASK, ifm->ifam_addrs, pnt); RTA_ADDR_GET (NULL, RTA_GENMASK, ifm->ifam_addrs, pnt);
RTA_ADDR_GET (NULL, RTA_IFP, ifm->ifam_addrs, pnt); RTA_NAME_GET (ifname, RTA_IFP, ifm->ifam_addrs, pnt, *ifnlen);
RTA_ADDR_GET (addr, RTA_IFA, ifm->ifam_addrs, pnt); RTA_ADDR_GET (addr, RTA_IFA, ifm->ifam_addrs, pnt);
RTA_ADDR_GET (NULL, RTA_AUTHOR, ifm->ifam_addrs, pnt); RTA_ADDR_GET (NULL, RTA_AUTHOR, ifm->ifam_addrs, pnt);
RTA_ADDR_GET (dest, RTA_BRD, ifm->ifam_addrs, pnt); RTA_ADDR_GET (brd, RTA_BRD, ifm->ifam_addrs, pnt);
if (IS_ZEBRA_DEBUG_KERNEL)
zlog_debug ("%s: ifindex %d, ifname %s, ifam_addrs 0x%x",
__func__, ifm->ifam_index,
(ifnlen ? ifname : "(nil)"), ifm->ifam_addrs);
/* Assert read up end point matches to end point */ /* Assert read up end point matches to end point */
if (pnt != end) if (pnt != end)
@ -464,19 +513,26 @@ ifam_read_mesg (struct ifa_msghdr *ifm,
int int
ifam_read (struct ifa_msghdr *ifam) ifam_read (struct ifa_msghdr *ifam)
{ {
struct interface *ifp; struct interface *ifp = NULL;
union sockunion addr, mask, brd; union sockunion addr, mask, brd;
char ifname[INTERFACE_NAMSIZ];
short ifnlen = 0;
char isalias = 0;
/* Check does this interface exist or not. */ ifname[0] = ifname[INTERFACE_NAMSIZ - 1] = '\0';
ifp = if_lookup_by_index (ifam->ifam_index);
if (ifp == NULL) /* Allocate and read address information. */
ifam_read_mesg (ifam, &addr, &mask, &brd, ifname, &ifnlen);
if ((ifp = if_lookup_by_index(ifam->ifam_index)) == NULL)
{ {
zlog_warn ("no interface for index %d", ifam->ifam_index); zlog_warn ("%s: no interface for ifname %s, index %d",
__func__, ifname, ifam->ifam_index);
return -1; return -1;
} }
/* Allocate and read address information. */ if (ifnlen && strncmp (ifp->name, ifname, INTERFACE_NAMSIZ))
ifam_read_mesg (ifam, &addr, &mask, &brd); isalias = 1;
/* Check interface flag for implicit up of the interface. */ /* Check interface flag for implicit up of the interface. */
if_refresh (ifp); if_refresh (ifp);
@ -525,7 +581,9 @@ int
rtm_read_mesg (struct rt_msghdr *rtm, rtm_read_mesg (struct rt_msghdr *rtm,
union sockunion *dest, union sockunion *dest,
union sockunion *mask, union sockunion *mask,
union sockunion *gate) union sockunion *gate,
char *ifname,
short *ifnlen)
{ {
caddr_t pnt, end; caddr_t pnt, end;
@ -549,7 +607,7 @@ rtm_read_mesg (struct rt_msghdr *rtm,
RTA_ADDR_GET (gate, RTA_GATEWAY, rtm->rtm_addrs, pnt); RTA_ADDR_GET (gate, RTA_GATEWAY, rtm->rtm_addrs, pnt);
RTA_ATTR_GET (mask, RTA_NETMASK, rtm->rtm_addrs, pnt); RTA_ATTR_GET (mask, RTA_NETMASK, rtm->rtm_addrs, pnt);
RTA_ADDR_GET (NULL, RTA_GENMASK, rtm->rtm_addrs, pnt); RTA_ADDR_GET (NULL, RTA_GENMASK, rtm->rtm_addrs, pnt);
RTA_ADDR_GET (NULL, RTA_IFP, rtm->rtm_addrs, pnt); RTA_NAME_GET (ifname, RTA_IFP, rtm->rtm_addrs, pnt, *ifnlen);
RTA_ADDR_GET (NULL, RTA_IFA, rtm->rtm_addrs, pnt); RTA_ADDR_GET (NULL, RTA_IFA, rtm->rtm_addrs, pnt);
RTA_ADDR_GET (NULL, RTA_AUTHOR, rtm->rtm_addrs, pnt); RTA_ADDR_GET (NULL, RTA_AUTHOR, rtm->rtm_addrs, pnt);
RTA_ADDR_GET (NULL, RTA_BRD, rtm->rtm_addrs, pnt); RTA_ADDR_GET (NULL, RTA_BRD, rtm->rtm_addrs, pnt);
@ -572,6 +630,8 @@ rtm_read (struct rt_msghdr *rtm)
int flags; int flags;
u_char zebra_flags; u_char zebra_flags;
union sockunion dest, mask, gate; union sockunion dest, mask, gate;
char ifname[INTERFACE_NAMSIZ + 1];
short ifnlen = 0;
zebra_flags = 0; zebra_flags = 0;
@ -582,7 +642,7 @@ rtm_read (struct rt_msghdr *rtm)
/* Read destination and netmask and gateway from rtm message /* Read destination and netmask and gateway from rtm message
structure. */ structure. */
flags = rtm_read_mesg (rtm, &dest, &mask, &gate); flags = rtm_read_mesg (rtm, &dest, &mask, &gate, ifname, &ifnlen);
#ifdef RTF_CLONED /*bsdi, netbsd 1.6*/ #ifdef RTF_CLONED /*bsdi, netbsd 1.6*/
if (flags & RTF_CLONED) if (flags & RTF_CLONED)
@ -790,7 +850,7 @@ rtm_write (int message,
#define SOCKADDRSET(X,R) \ #define SOCKADDRSET(X,R) \
if (msg.rtm.rtm_addrs & (R)) \ if (msg.rtm.rtm_addrs & (R)) \
{ \ { \
int len = ROUNDUP (sizeof((X)->sa)); \ int len = SAROUNDUP (X); \
memcpy (pnt, (caddr_t)(X), len); \ memcpy (pnt, (caddr_t)(X), len); \
pnt += len; \ pnt += len; \
} }
@ -841,7 +901,7 @@ rtmsg_debug (struct rt_msghdr *rtm)
zlog_debug ("Kernel: Len: %d Type: %s", rtm->rtm_msglen, type); zlog_debug ("Kernel: Len: %d Type: %s", rtm->rtm_msglen, type);
rtm_flag_dump (rtm->rtm_flags); rtm_flag_dump (rtm->rtm_flags);
zlog_debug ("Kernel: message seq %d", rtm->rtm_seq); zlog_debug ("Kernel: message seq %d", rtm->rtm_seq);
zlog_debug ("Kernel: pid %d", rtm->rtm_pid); zlog_debug ("Kernel: pid %d, rtm_addrs 0x%x", rtm->rtm_pid, rtm->rtm_addrs);
} }
/* This is pretty gross, better suggestions welcome -- mhandler */ /* This is pretty gross, better suggestions welcome -- mhandler */

View File

@ -290,7 +290,7 @@ kernel_rtm_ipv6 (int message, struct prefix_ipv6 *dest,
else else
{ {
masklen2ip6 (dest->prefixlen, &sin_mask.sin6_addr); masklen2ip6 (dest->prefixlen, &sin_mask.sin6_addr);
sin_mask.sin6_family = AF_UNSPEC; sin_mask.sin6_family = AF_INET6;
#ifdef SIN6_LEN #ifdef SIN6_LEN
sin_mask.sin6_len = sin6_masklen (sin_mask.sin6_addr); sin_mask.sin6_len = sin6_masklen (sin_mask.sin6_addr);
#endif /* SIN6_LEN */ #endif /* SIN6_LEN */
@ -400,7 +400,7 @@ kernel_rtm_ipv6_multipath (int cmd, struct prefix *p, struct rib *rib,
else else
{ {
masklen2ip6 (p->prefixlen, &sin_mask.sin6_addr); masklen2ip6 (p->prefixlen, &sin_mask.sin6_addr);
sin_mask.sin6_family = AF_UNSPEC; sin_mask.sin6_family = AF_INET6;
#ifdef SIN6_LEN #ifdef SIN6_LEN
sin_mask.sin6_len = sin6_masklen (sin_mask.sin6_addr); sin_mask.sin6_len = sin6_masklen (sin_mask.sin6_addr);
#endif /* SIN6_LEN */ #endif /* SIN6_LEN */