version 1.1.1.1, 2012/02/21 17:26:11
|
version 1.1.1.3, 2013/07/21 23:54:41
|
Line 48 extern struct zebra_t zebrad;
|
Line 48 extern struct zebra_t zebrad;
|
* XXX: why is ROUNDUP(0) sizeof(long)? 0 is an illegal sockaddr |
* XXX: why is ROUNDUP(0) sizeof(long)? 0 is an illegal sockaddr |
* length anyway (< sizeof (struct sockaddr)), so this shouldn't |
* length anyway (< sizeof (struct sockaddr)), so this shouldn't |
* matter. |
* matter. |
|
* On OS X, both 32, 64bit syatems align on 4 byte boundary |
*/ |
*/ |
|
#ifdef __APPLE__ |
#define ROUNDUP(a) \ |
#define ROUNDUP(a) \ |
|
((a) > 0 ? (1 + (((a) - 1) | (sizeof(int) - 1))) : sizeof(int)) |
|
#else |
|
#define ROUNDUP(a) \ |
((a) > 0 ? (1 + (((a) - 1) | (sizeof(long) - 1))) : sizeof(long)) |
((a) > 0 ? (1 + (((a) - 1) | (sizeof(long) - 1))) : sizeof(long)) |
|
#endif |
|
|
/* |
/* |
* Given a pointer (sockaddr or void *), return the number of bytes |
* Given a pointer (sockaddr or void *), return the number of bytes |
Line 78 extern struct zebra_t zebrad;
|
Line 84 extern struct zebra_t zebrad;
|
ROUNDUP(sizeof(struct sockaddr_dl)) : sizeof(struct sockaddr))) |
ROUNDUP(sizeof(struct sockaddr_dl)) : sizeof(struct sockaddr))) |
#endif /* HAVE_STRUCT_SOCKADDR_SA_LEN */ |
#endif /* HAVE_STRUCT_SOCKADDR_SA_LEN */ |
|
|
/* We use an additional pointer in following, pdest, rather than (DEST) | /* |
* directly, because gcc will warn if the macro is expanded and DEST is NULL, | * We use a call to an inline function to copy (PNT) to (DEST) |
* complaining that memcpy is being passed a NULL value, despite the fact | * 1. Calculating the length of the copy requires an #ifdef to determine |
* the if (NULL) makes it impossible. | * if sa_len is a field and can't be used directly inside a #define |
| * 2. So the compiler doesn't complain when DEST is NULL, which is only true |
| * when we are skipping the copy and incrementing to the next SA |
*/ |
*/ |
|
static void inline |
|
rta_copy (union sockunion *dest, caddr_t src) { |
|
int len; |
|
#ifdef HAVE_STRUCT_SOCKADDR_SA_LEN |
|
len = (((struct sockaddr *)src)->sa_len > sizeof (*dest)) ? |
|
sizeof (*dest) : ((struct sockaddr *)src)->sa_len ; |
|
#else |
|
len = (SAROUNDUP (src) > sizeof (*dest)) ? |
|
sizeof (*dest) : SAROUNDUP (src) ; |
|
#endif |
|
memcpy (dest, src, len); |
|
} |
|
|
#define RTA_ADDR_GET(DEST, RTA, RTMADDRS, PNT) \ |
#define RTA_ADDR_GET(DEST, RTA, RTMADDRS, PNT) \ |
if ((RTMADDRS) & (RTA)) \ |
if ((RTMADDRS) & (RTA)) \ |
{ \ |
{ \ |
void *pdest = (DEST); \ |
|
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 (pdest, (PNT), len); \ | rta_copy((DEST), (PNT)); \ |
(PNT) += len; \ |
(PNT) += len; \ |
} |
} |
#define RTA_ATTR_GET(DEST, RTA, RTMADDRS, PNT) \ |
#define RTA_ATTR_GET(DEST, RTA, RTMADDRS, PNT) \ |
if ((RTMADDRS) & (RTA)) \ |
if ((RTMADDRS) & (RTA)) \ |
{ \ |
{ \ |
void *pdest = (DEST); \ |
|
int len = SAROUNDUP ((PNT)); \ |
int len = SAROUNDUP ((PNT)); \ |
if ((DEST) != NULL) \ |
if ((DEST) != NULL) \ |
memcpy (pdest, (PNT), len); \ | rta_copy((DEST), (PNT)); \ |
(PNT) += len; \ |
(PNT) += len; \ |
} |
} |
|
|
Line 297 ifan_read (struct if_announcemsghdr *ifan)
|
Line 316 ifan_read (struct if_announcemsghdr *ifan)
|
} |
} |
#endif /* RTM_IFANNOUNCE */ |
#endif /* RTM_IFANNOUNCE */ |
|
|
#ifdef HAVE_BSD_LINK_DETECT | #ifdef HAVE_BSD_IFI_LINK_STATE |
/* BSD link detect translation */ |
/* BSD link detect translation */ |
static void |
static void |
bsd_linkdetect_translate (struct if_msghdr *ifm) |
bsd_linkdetect_translate (struct if_msghdr *ifm) |
Line 308 bsd_linkdetect_translate (struct if_msghdr *ifm)
|
Line 327 bsd_linkdetect_translate (struct if_msghdr *ifm)
|
else |
else |
UNSET_FLAG(ifm->ifm_flags, IFF_RUNNING); |
UNSET_FLAG(ifm->ifm_flags, IFF_RUNNING); |
} |
} |
#endif /* HAVE_BSD_LINK_DETECT */ | #endif /* HAVE_BSD_IFI_LINK_STATE */ |
|
|
/* |
/* |
* Handle struct if_msghdr obtained from reading routing socket or |
* Handle struct if_msghdr obtained from reading routing socket or |
Line 319 int
|
Line 338 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; |
char ifname[IFNAMSIZ]; |
char ifname[IFNAMSIZ]; |
short ifnlen = 0; |
short ifnlen = 0; |
caddr_t *cp; | caddr_t cp; |
|
|
/* terminate ifname at head (for strnlen) and tail (for safety) */ |
/* terminate ifname at head (for strnlen) and tail (for safety) */ |
ifname[IFNAMSIZ - 1] = '\0'; |
ifname[IFNAMSIZ - 1] = '\0'; |
Line 356 ifm_read (struct if_msghdr *ifm)
|
Line 376 ifm_read (struct if_msghdr *ifm)
|
RTA_ADDR_GET (NULL, RTA_GATEWAY, 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_ATTR_GET (NULL, RTA_NETMASK, ifm->ifm_addrs, cp); |
RTA_ADDR_GET (NULL, RTA_GENMASK, ifm->ifm_addrs, cp); |
RTA_ADDR_GET (NULL, RTA_GENMASK, ifm->ifm_addrs, cp); |
|
sdl = (struct sockaddr_dl *)cp; |
RTA_NAME_GET (ifname, RTA_IFP, ifm->ifm_addrs, cp, ifnlen); |
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_IFA, ifm->ifm_addrs, cp); |
RTA_ADDR_GET (NULL, RTA_AUTHOR, ifm->ifm_addrs, cp); |
RTA_ADDR_GET (NULL, RTA_AUTHOR, ifm->ifm_addrs, cp); |
Line 442 ifm_read (struct if_msghdr *ifm)
|
Line 463 ifm_read (struct if_msghdr *ifm)
|
*/ |
*/ |
ifp->ifindex = ifm->ifm_index; |
ifp->ifindex = ifm->ifm_index; |
|
|
#ifdef HAVE_BSD_LINK_DETECT /* translate BSD kernel msg for link-state */ | #ifdef HAVE_BSD_IFI_LINK_STATE /* translate BSD kernel msg for link-state */ |
bsd_linkdetect_translate(ifm); |
bsd_linkdetect_translate(ifm); |
#endif /* HAVE_BSD_LINK_DETECT */ | #endif /* HAVE_BSD_IFI_LINK_STATE */ |
|
|
if_flags_update (ifp, ifm->ifm_flags); |
if_flags_update (ifp, ifm->ifm_flags); |
#if defined(__bsdi__) |
#if defined(__bsdi__) |
Line 454 ifm_read (struct if_msghdr *ifm)
|
Line 475 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. There are 2 big families here: |
|
* - BSD has sdl_len + sdl_data[16] + overruns sdl_data |
|
* we MUST use sdl_len here or we'll truncate data. |
|
* - Solaris has no sdl_len, but sdl_data[244] |
|
* presumably, it's not going to run past that, so sizeof() |
|
* is fine here. |
|
* a nonzero ifnlen from RTA_NAME_GET() means sdl is valid |
|
*/ |
|
if (ifnlen) |
|
{ |
|
#ifdef HAVE_STRUCT_SOCKADDR_DL_SDL_LEN |
|
memcpy (&ifp->sdl, sdl, sdl->sdl_len); |
|
#else |
|
memcpy (&ifp->sdl, sdl, sizeof (struct sockaddr_dl)); |
|
#endif /* HAVE_STRUCT_SOCKADDR_DL_SDL_LEN */ |
|
} |
|
|
if_add_update (ifp); |
if_add_update (ifp); |
} |
} |
else |
else |
Line 473 ifm_read (struct if_msghdr *ifm)
|
Line 513 ifm_read (struct if_msghdr *ifm)
|
return -1; |
return -1; |
} |
} |
|
|
#ifdef HAVE_BSD_LINK_DETECT /* translate BSD kernel msg for link-state */ | #ifdef HAVE_BSD_IFI_LINK_STATE /* translate BSD kernel msg for link-state */ |
bsd_linkdetect_translate(ifm); |
bsd_linkdetect_translate(ifm); |
#endif /* HAVE_BSD_LINK_DETECT */ | #endif /* HAVE_BSD_IFI_LINK_STATE */ |
|
|
/* update flags and handle operative->inoperative transition, if any */ |
/* update flags and handle operative->inoperative transition, if any */ |
if_flags_update (ifp, ifm->ifm_flags); |
if_flags_update (ifp, ifm->ifm_flags); |
Line 606 ifam_read_mesg (struct ifa_msghdr *ifm,
|
Line 646 ifam_read_mesg (struct ifa_msghdr *ifm,
|
|
|
/* Assert read up end point matches to end point */ |
/* Assert read up end point matches to end point */ |
if (pnt != end) |
if (pnt != end) |
zlog_warn ("ifam_read() does't read all socket data"); | zlog_warn ("ifam_read() doesn't read all socket data"); |
} |
} |
|
|
/* Interface's address information get. */ |
/* Interface's address information get. */ |
Line 754 rtm_read_mesg (struct rt_msghdr *rtm,
|
Line 794 rtm_read_mesg (struct rt_msghdr *rtm,
|
|
|
/* Assert read up to the end of pointer. */ |
/* Assert read up to the end of pointer. */ |
if (pnt != end) |
if (pnt != end) |
zlog (NULL, LOG_WARNING, "rtm_read() does't read all socket data."); | zlog (NULL, LOG_WARNING, "rtm_read() doesn't read all socket data."); |
|
|
return rtm->rtm_flags; |
return rtm->rtm_flags; |
} |
} |
Line 894 rtm_read (struct rt_msghdr *rtm)
|
Line 934 rtm_read (struct rt_msghdr *rtm)
|
*/ |
*/ |
if (rtm->rtm_type == RTM_CHANGE) |
if (rtm->rtm_type == RTM_CHANGE) |
rib_delete_ipv4 (ZEBRA_ROUTE_KERNEL, zebra_flags, &p, |
rib_delete_ipv4 (ZEBRA_ROUTE_KERNEL, zebra_flags, &p, |
NULL, 0, 0); | NULL, 0, 0, SAFI_UNICAST); |
|
|
if (rtm->rtm_type == RTM_GET |
if (rtm->rtm_type == RTM_GET |
|| rtm->rtm_type == RTM_ADD |
|| rtm->rtm_type == RTM_ADD |
|| rtm->rtm_type == RTM_CHANGE) |
|| rtm->rtm_type == RTM_CHANGE) |
rib_add_ipv4 (ZEBRA_ROUTE_KERNEL, zebra_flags, |
rib_add_ipv4 (ZEBRA_ROUTE_KERNEL, zebra_flags, |
&p, &gate.sin.sin_addr, NULL, 0, 0, 0, 0); | &p, &gate.sin.sin_addr, NULL, 0, 0, 0, 0, SAFI_UNICAST); |
else |
else |
rib_delete_ipv4 (ZEBRA_ROUTE_KERNEL, zebra_flags, |
rib_delete_ipv4 (ZEBRA_ROUTE_KERNEL, zebra_flags, |
&p, &gate.sin.sin_addr, 0, 0); | &p, &gate.sin.sin_addr, 0, 0, SAFI_UNICAST); |
} |
} |
#ifdef HAVE_IPV6 |
#ifdef HAVE_IPV6 |
if (dest.sa.sa_family == AF_INET6) |
if (dest.sa.sa_family == AF_INET6) |
Line 936 rtm_read (struct rt_msghdr *rtm)
|
Line 976 rtm_read (struct rt_msghdr *rtm)
|
*/ |
*/ |
if (rtm->rtm_type == RTM_CHANGE) |
if (rtm->rtm_type == RTM_CHANGE) |
rib_delete_ipv6 (ZEBRA_ROUTE_KERNEL, zebra_flags, &p, |
rib_delete_ipv6 (ZEBRA_ROUTE_KERNEL, zebra_flags, &p, |
NULL, 0, 0); | NULL, 0, 0, SAFI_UNICAST); |
|
|
if (rtm->rtm_type == RTM_GET |
if (rtm->rtm_type == RTM_GET |
|| rtm->rtm_type == RTM_ADD |
|| rtm->rtm_type == RTM_ADD |
|| rtm->rtm_type == RTM_CHANGE) |
|| rtm->rtm_type == RTM_CHANGE) |
rib_add_ipv6 (ZEBRA_ROUTE_KERNEL, zebra_flags, |
rib_add_ipv6 (ZEBRA_ROUTE_KERNEL, zebra_flags, |
&p, &gate.sin6.sin6_addr, ifindex, 0, 0, 0); | &p, &gate.sin6.sin6_addr, ifindex, 0, 0, 0, SAFI_UNICAST); |
else |
else |
rib_delete_ipv6 (ZEBRA_ROUTE_KERNEL, zebra_flags, |
rib_delete_ipv6 (ZEBRA_ROUTE_KERNEL, zebra_flags, |
&p, &gate.sin6.sin6_addr, ifindex, 0); | &p, &gate.sin6.sin6_addr, ifindex, 0, SAFI_UNICAST); |
} |
} |
#endif /* HAVE_IPV6 */ |
#endif /* HAVE_IPV6 */ |
} |
} |