mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-08-07 23:58:44 +00:00
[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:
parent
db29ae5fca
commit
6fe70d1b35
@ -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
|
||||||
|
@ -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 */
|
||||||
|
@ -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 */
|
||||||
|
Loading…
Reference in New Issue
Block a user