mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-08-06 00:06:09 +00:00
2003-09-24 sowmini.varadhan@sun.com
* zebra/kernel_socket.c: Fix up WRAPUP macro to deal with multiple address families in the absence of sa_len element in struct sockaddr. (ifm_read): Handle solaris 9 if_msghdr_t. Deal with interfaces which are incomplete, lookup on name rather than the placeholder interface index of -1.
This commit is contained in:
parent
9491975ef9
commit
3e95a0741f
@ -48,7 +48,13 @@ extern struct zebra_t zebrad;
|
||||
#ifdef HAVE_SA_LEN
|
||||
#define WRAPUP(X) ROUNDUP(((struct sockaddr *)(X))->sa_len)
|
||||
#else
|
||||
#define WRAPUP(X) ROUNDUP(sizeof (struct sockaddr))
|
||||
#define WRAPUP(X) \
|
||||
(((struct sockaddr *)(X))->sa_family == AF_INET ? \
|
||||
ROUNDUP(sizeof(struct sockaddr_in)):\
|
||||
(((struct sockaddr *)(X))->sa_family == AF_INET6 ? \
|
||||
ROUNDUP(sizeof(struct sockaddr_in6)) : \
|
||||
(((struct sockaddr *)(X))->sa_family == AF_LINK ? \
|
||||
ROUNDUP(sizeof(struct sockaddr_dl)) : sizeof(struct sockaddr))))
|
||||
#endif /* HAVE_SA_LEN */
|
||||
|
||||
/* Routing socket message types. */
|
||||
@ -201,15 +207,55 @@ ifan_read (struct if_announcemsghdr *ifan)
|
||||
int
|
||||
ifm_read (struct if_msghdr *ifm)
|
||||
{
|
||||
struct interface *ifp;
|
||||
struct interface *ifp = NULL;
|
||||
struct sockaddr_dl *sdl = NULL;
|
||||
char ifname[IFNAMSIZ];
|
||||
|
||||
#ifdef SUNOS_5
|
||||
int i;
|
||||
struct sockaddr *sa;
|
||||
u_char *cp = (u_char *)(ifm + 1);
|
||||
|
||||
/*
|
||||
* if_msghdr_t on 64 bit kernels in Solaris 9 and earlier versions
|
||||
* is 12 bytes larger than the 32 bit version, so make adjustment
|
||||
* here.
|
||||
*/
|
||||
sa = (struct sockaddr *)cp;
|
||||
if (sa->sa_family == AF_UNSPEC)
|
||||
cp = cp + 12;
|
||||
|
||||
for (i = 1; i != 0; i <<= 1)
|
||||
{
|
||||
if (i & ifm->ifm_addrs)
|
||||
{
|
||||
sa = (struct sockaddr *)cp;
|
||||
cp += WRAPUP(sa);
|
||||
if (i & RTA_IFP)
|
||||
{
|
||||
sdl = (struct sockaddr_dl *)sa;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
#else
|
||||
sdl = (struct sockaddr_dl *)(ifm + 1);
|
||||
#endif
|
||||
|
||||
/* Use sdl index. */
|
||||
ifp = if_lookup_by_index (ifm->ifm_index);
|
||||
/*
|
||||
* Check if ifp already exists. If the interface has already been specified
|
||||
* in the conf file, but is just getting created, we would have an
|
||||
* entry in the iflist with incomplete data (e.g., ifindex == -1),
|
||||
* so we lookup on name.
|
||||
*/
|
||||
if (sdl != NULL)
|
||||
{
|
||||
bcopy(sdl->sdl_data, ifname, sdl->sdl_nlen);
|
||||
ifname[sdl->sdl_nlen] = '\0';
|
||||
ifp = if_lookup_by_name (ifname);
|
||||
}
|
||||
|
||||
if (ifp == NULL)
|
||||
if ((ifp == NULL) || (ifp->ifindex == -1))
|
||||
{
|
||||
/* Check interface's address.*/
|
||||
if (! (ifm->ifm_addrs & RTA_IFP))
|
||||
@ -219,7 +265,8 @@ ifm_read (struct if_msghdr *ifm)
|
||||
return -1;
|
||||
}
|
||||
|
||||
ifp = if_create (sdl->sdl_data, sdl->sdl_nlen);
|
||||
if (ifp == NULL)
|
||||
ifp = if_create (sdl->sdl_data, sdl->sdl_nlen);
|
||||
|
||||
ifp->ifindex = ifm->ifm_index;
|
||||
ifp->flags = ifm->ifm_flags;
|
||||
|
Loading…
Reference in New Issue
Block a user