--- embedaddon/quagga/zebra/kernel_socket.c 2012/02/21 17:26:11 1.1 +++ embedaddon/quagga/zebra/kernel_socket.c 2016/11/02 10:09:10 1.1.1.4 @@ -20,6 +20,7 @@ */ #include +#include #include "if.h" #include "prefix.h" @@ -32,26 +33,76 @@ #include "table.h" #include "rib.h" #include "privs.h" +#include "vrf.h" #include "zebra/interface.h" #include "zebra/zserv.h" #include "zebra/debug.h" #include "zebra/kernel_socket.h" +#include "zebra/rib.h" extern struct zebra_privs_t zserv_privs; extern struct zebra_t zebrad; /* - * Given a sockaddr length, round it up to include pad bytes following - * it. Assumes the kernel pads to sizeof(long). + * Historically, the BSD routing socket has aligned data following a + * struct sockaddr to sizeof(long), which was 4 bytes on some + * platforms, and 8 bytes on others. NetBSD 6 changed the routing + * socket to align to sizeof(uint64_t), which is 8 bytes. OS X + * appears to align to sizeof(int), which is 4 bytes. * - * XXX: why is ROUNDUP(0) sizeof(long)? 0 is an illegal sockaddr - * length anyway (< sizeof (struct sockaddr)), so this shouldn't - * matter. + * Alignment of zero-sized sockaddrs is nonsensical, but historically + * BSD defines RT_ROUNDUP(0) to be the alignment interval (rather than + * 0). We follow this practice without questioning it, but it is a + * bug if quagga calls ROUNDUP with 0. */ + +/* + * Because of these varying conventions, the only sane approach is for + * the header to define some flavor of ROUNDUP macro. + */ + +#if defined(SA_SIZE) +/* SAROUNDUP is the only thing we need, and SA_SIZE provides that */ +#define SAROUNDUP(a) SA_SIZE(a) +#else /* !SA_SIZE */ + +#if defined(RT_ROUNDUP) +#define ROUNDUP(a) RT_ROUNDUP(a) +#endif /* defined(RT_ROUNDUP) */ + +#if defined(SUNOS_5) +/* Solaris has struct sockaddr_in[6] definitions at 16 / 32 bytes size, + * so the whole concept doesn't really apply. */ +#define ROUNDUP(a) (a) +#endif + +/* + * If ROUNDUP has not yet been defined in terms of platform-provided + * defines, attempt to cope with heuristics. + */ +#if !defined(ROUNDUP) + +/* + * It's a bug for a platform not to define rounding/alignment for + * sockaddrs on the routing socket. This warning really is + * intentional, to provoke filing bug reports with operating systems + * that don't define RT_ROUNDUP or equivalent. + */ +#warning "net/route.h does not define RT_ROUNDUP; making unwarranted assumptions!" + +/* OS X (Xcode as of 2014-12) is known not to define RT_ROUNDUP */ +#ifdef __APPLE__ +#define ROUNDUP_TYPE int +#else +#define ROUNDUP_TYPE long +#endif + #define ROUNDUP(a) \ - ((a) > 0 ? (1 + (((a) - 1) | (sizeof(long) - 1))) : sizeof(long)) + ((a) > 0 ? (1 + (((a) - 1) | (sizeof(ROUNDUP_TYPE) - 1))) : sizeof(ROUNDUP_TYPE)) +#endif /* defined(ROUNDUP) */ + /* * Given a pointer (sockaddr or void *), return the number of bytes * taken up by the sockaddr and any padding needed for alignment. @@ -78,28 +129,43 @@ extern struct zebra_t zebrad; ROUNDUP(sizeof(struct sockaddr_dl)) : sizeof(struct sockaddr))) #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, - * complaining that memcpy is being passed a NULL value, despite the fact - * the if (NULL) makes it impossible. +#endif /* !SA_SIZE */ + +/* + * We use a call to an inline function to copy (PNT) to (DEST) + * 1. Calculating the length of the copy requires an #ifdef to determine + * 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 inline void +rta_copy (union sockunion *dest, caddr_t src) { + int len; + if (!dest) + return; +#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) \ if ((RTMADDRS) & (RTA)) \ { \ - void *pdest = (DEST); \ int len = SAROUNDUP ((PNT)); \ - if ( ((DEST) != NULL) && \ - af_check (((struct sockaddr *)(PNT))->sa_family)) \ - memcpy (pdest, (PNT), len); \ + if (af_check (((struct sockaddr *)(PNT))->sa_family)) \ + rta_copy((DEST), (PNT)); \ (PNT) += len; \ } #define RTA_ATTR_GET(DEST, RTA, RTMADDRS, PNT) \ if ((RTMADDRS) & (RTA)) \ { \ - void *pdest = (DEST); \ int len = SAROUNDUP ((PNT)); \ - if ((DEST) != NULL) \ - memcpy (pdest, (PNT), len); \ + rta_copy((DEST), (PNT)); \ (PNT) += len; \ } @@ -177,7 +243,9 @@ static const struct message rtm_flag_str[] = {RTF_CLONING, "CLONING"}, #endif /* RTF_CLONING */ {RTF_XRESOLVE, "XRESOLVE"}, +#ifdef RTF_LLINFO {RTF_LLINFO, "LLINFO"}, +#endif /* RTF_LLINFO */ {RTF_STATIC, "STATIC"}, {RTF_BLACKHOLE, "BLACKHOLE"}, #ifdef RTF_PRIVATE @@ -222,7 +290,7 @@ int routing_sock = -1; /* #define DEBUG */ /* Supported address family check. */ -static int inline +static inline int af_check (int family) { if (family == AF_INET) @@ -233,7 +301,7 @@ af_check (int family) #endif /* HAVE_IPV6 */ return 0; } - + /* Dump routing table flag for debug purpose. */ static void rtm_flag_dump (int flag) @@ -280,6 +348,7 @@ ifan_read (struct if_announcemsghdr *ifan) sizeof(ifan->ifan_name))); ifp->ifindex = ifan->ifan_index; + if_get_metric (ifp); if_add_update (ifp); } else if (ifp != NULL && ifan->ifan_what == IFAN_DEPARTURE) @@ -297,7 +366,7 @@ ifan_read (struct if_announcemsghdr *ifan) } #endif /* RTM_IFANNOUNCE */ -#ifdef HAVE_BSD_LINK_DETECT +#ifdef HAVE_BSD_IFI_LINK_STATE /* BSD link detect translation */ static void bsd_linkdetect_translate (struct if_msghdr *ifm) @@ -308,8 +377,31 @@ bsd_linkdetect_translate (struct if_msghdr *ifm) else UNSET_FLAG(ifm->ifm_flags, IFF_RUNNING); } -#endif /* HAVE_BSD_LINK_DETECT */ +#endif /* HAVE_BSD_IFI_LINK_STATE */ +static enum zebra_link_type +sdl_to_zebra_link_type (unsigned int sdlt) +{ + switch (sdlt) + { + case IFT_ETHER: return ZEBRA_LLT_ETHER; + case IFT_X25: return ZEBRA_LLT_X25; + case IFT_FDDI: return ZEBRA_LLT_FDDI; + case IFT_PPP: return ZEBRA_LLT_PPP; + case IFT_LOOP: return ZEBRA_LLT_LOOPBACK; + case IFT_SLIP: return ZEBRA_LLT_SLIP; + case IFT_ARCNET: return ZEBRA_LLT_ARCNET; + case IFT_ATM: return ZEBRA_LLT_ATM; + case IFT_LOCALTALK: return ZEBRA_LLT_LOCALTLK; + case IFT_HIPPI: return ZEBRA_LLT_HIPPI; +#ifdef IFT_IEEE1394 + case IFT_IEEE1394: return ZEBRA_LLT_IEEE1394; +#endif + + default: return ZEBRA_LLT_UNKNOWN; + } +} + /* * Handle struct if_msghdr obtained from reading routing socket or * sysctl (from interface_list). There may or may not be sockaddrs @@ -319,9 +411,10 @@ int ifm_read (struct if_msghdr *ifm) { struct interface *ifp = NULL; + struct sockaddr_dl *sdl; char ifname[IFNAMSIZ]; short ifnlen = 0; - caddr_t *cp; + caddr_t cp; /* terminate ifname at head (for strnlen) and tail (for safety) */ ifname[IFNAMSIZ - 1] = '\0'; @@ -356,6 +449,7 @@ ifm_read (struct if_msghdr *ifm) 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); + sdl = (struct sockaddr_dl *)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); @@ -442,9 +536,9 @@ ifm_read (struct if_msghdr *ifm) */ 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); -#endif /* HAVE_BSD_LINK_DETECT */ +#endif /* HAVE_BSD_IFI_LINK_STATE */ if_flags_update (ifp, ifm->ifm_flags); #if defined(__bsdi__) @@ -454,6 +548,34 @@ ifm_read (struct if_msghdr *ifm) #endif /* __bsdi__ */ 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 + */ + ifp->ll_type = ZEBRA_LLT_UNKNOWN; + ifp->hw_addr_len = 0; + if (ifnlen) + { +#ifdef HAVE_STRUCT_SOCKADDR_DL_SDL_LEN + memcpy (&((struct zebra_if *)ifp->info)->sdl, sdl, sdl->sdl_len); +#else + memcpy (&((struct zebra_if *)ifp->info)->sdl, sdl, sizeof (struct sockaddr_dl)); +#endif /* HAVE_STRUCT_SOCKADDR_DL_SDL_LEN */ + + ifp->ll_type = sdl_to_zebra_link_type (sdl->sdl_type); + if (sdl->sdl_alen <= sizeof(ifp->hw_addr)) + { + memcpy (ifp->hw_addr, LLADDR(sdl), sdl->sdl_alen); + ifp->hw_addr_len = sdl->sdl_alen; + } + } + if_add_update (ifp); } else @@ -473,9 +595,9 @@ ifm_read (struct if_msghdr *ifm) 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); -#endif /* HAVE_BSD_LINK_DETECT */ +#endif /* HAVE_BSD_IFI_LINK_STATE */ /* update flags and handle operative->inoperative transition, if any */ if_flags_update (ifp, ifm->ifm_flags); @@ -516,7 +638,7 @@ ifm_read (struct if_msghdr *ifm) return 0; } - + /* Address read from struct ifa_msghdr. */ static void ifam_read_mesg (struct ifa_msghdr *ifm, @@ -552,50 +674,32 @@ ifam_read_mesg (struct ifa_msghdr *ifm, if (IS_ZEBRA_DEBUG_KERNEL) { - switch (sockunion_family(addr)) + int family = sockunion_family(addr); + switch (family) { case AF_INET: - { - char buf[4][INET_ADDRSTRLEN]; - zlog_debug ("%s: ifindex %d, ifname %s, ifam_addrs 0x%x, " - "ifam_flags 0x%x, addr %s/%d broad %s dst %s " - "gateway %s", - __func__, ifm->ifam_index, - (ifnlen ? ifname : "(nil)"), ifm->ifam_addrs, - ifm->ifam_flags, - inet_ntop(AF_INET,&addr->sin.sin_addr, - buf[0],sizeof(buf[0])), - ip_masklen(mask->sin.sin_addr), - inet_ntop(AF_INET,&brd->sin.sin_addr, - buf[1],sizeof(buf[1])), - inet_ntop(AF_INET,&dst.sin.sin_addr, - buf[2],sizeof(buf[2])), - inet_ntop(AF_INET,&gateway.sin.sin_addr, - buf[3],sizeof(buf[3]))); - } - break; #ifdef HAVE_IPV6 case AF_INET6: +#endif { char buf[4][INET6_ADDRSTRLEN]; zlog_debug ("%s: ifindex %d, ifname %s, ifam_addrs 0x%x, " "ifam_flags 0x%x, addr %s/%d broad %s dst %s " "gateway %s", - __func__, ifm->ifam_index, + __func__, ifm->ifam_index, (ifnlen ? ifname : "(nil)"), ifm->ifam_addrs, ifm->ifam_flags, - inet_ntop(AF_INET6,&addr->sin6.sin6_addr, + inet_ntop(family,&addr->sin.sin_addr, buf[0],sizeof(buf[0])), - ip6_masklen(mask->sin6.sin6_addr), - inet_ntop(AF_INET6,&brd->sin6.sin6_addr, + ip_masklen(mask->sin.sin_addr), + inet_ntop(family,&brd->sin.sin_addr, buf[1],sizeof(buf[1])), - inet_ntop(AF_INET6,&dst.sin6.sin6_addr, + inet_ntop(family,&dst.sin.sin_addr, buf[2],sizeof(buf[2])), - inet_ntop(AF_INET6,&gateway.sin6.sin6_addr, + inet_ntop(family,&gateway.sin.sin_addr, buf[3],sizeof(buf[3]))); } break; -#endif /* HAVE_IPV6 */ default: zlog_debug ("%s: ifindex %d, ifname %s, ifam_addrs 0x%x", __func__, ifm->ifam_index, @@ -606,7 +710,7 @@ ifam_read_mesg (struct ifa_msghdr *ifm, /* Assert read up end point matches to end point */ 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. */ @@ -669,7 +773,9 @@ ifam_read (struct ifa_msghdr *ifam) /* Unset interface index from link-local address when IPv6 stack is KAME. */ if (IN6_IS_ADDR_LINKLOCAL (&addr.sin6.sin6_addr)) - SET_IN6_LINKLOCAL_IFINDEX (addr.sin6.sin6_addr, 0); + { + SET_IN6_LINKLOCAL_IFINDEX (addr.sin6.sin6_addr, 0); + } if (ifam->ifam_type == RTM_NEWADDR) connected_add_ipv6 (ifp, flags, &addr.sin6.sin6_addr, @@ -710,7 +816,7 @@ ifam_read (struct ifa_msghdr *ifam) return 0; } - + /* Interface function for reading kernel routing table information. */ static int rtm_read_mesg (struct rt_msghdr *rtm, @@ -754,7 +860,7 @@ rtm_read_mesg (struct rt_msghdr *rtm, /* Assert read up to the end of pointer. */ 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; } @@ -788,7 +894,7 @@ rtm_read (struct rt_msghdr *rtm) return; #endif - if ((rtm->rtm_type == RTM_ADD) && ! (flags & RTF_UP)) + if ((rtm->rtm_type == RTM_ADD || rtm->rtm_type == RTM_CHANGE) && ! (flags & RTF_UP)) return; /* This is connected route. */ @@ -825,12 +931,12 @@ rtm_read (struct rt_msghdr *rtm) */ if (rtm->rtm_type != RTM_GET && rtm->rtm_pid == pid) { - char buf[INET_ADDRSTRLEN], gate_buf[INET_ADDRSTRLEN]; + char buf[PREFIX_STRLEN], gate_buf[INET_ADDRSTRLEN]; int ret; if (! IS_ZEBRA_DEBUG_RIB) return; - ret = rib_lookup_ipv4_route (&p, &gate); - inet_ntop (AF_INET, &p.prefix, buf, INET_ADDRSTRLEN); + ret = rib_lookup_ipv4_route (&p, &gate, VRF_DEFAULT); + prefix2str (&p, buf, sizeof(buf)); switch (rtm->rtm_type) { case RTM_ADD: @@ -841,18 +947,18 @@ rtm_read (struct rt_msghdr *rtm) switch (ret) { case ZEBRA_RIB_NOTFOUND: - zlog_debug ("%s: %s %s/%d: desync: RR isn't yet in RIB, while already in FIB", - __func__, lookup (rtm_type_str, rtm->rtm_type), buf, p.prefixlen); + zlog_debug ("%s: %s %s: desync: RR isn't yet in RIB, while already in FIB", + __func__, lookup (rtm_type_str, rtm->rtm_type), buf); break; case ZEBRA_RIB_FOUND_CONNECTED: case ZEBRA_RIB_FOUND_NOGATE: inet_ntop (AF_INET, &gate.sin.sin_addr, gate_buf, INET_ADDRSTRLEN); - zlog_debug ("%s: %s %s/%d: desync: RR is in RIB, but gate differs (ours is %s)", - __func__, lookup (rtm_type_str, rtm->rtm_type), buf, p.prefixlen, gate_buf); + zlog_debug ("%s: %s %s: desync: RR is in RIB, but gate differs (ours is %s)", + __func__, lookup (rtm_type_str, rtm->rtm_type), buf, gate_buf); break; case ZEBRA_RIB_FOUND_EXACT: /* RIB RR == FIB RR */ - zlog_debug ("%s: %s %s/%d: done Ok", - __func__, lookup (rtm_type_str, rtm->rtm_type), buf, p.prefixlen); + zlog_debug ("%s: %s %s: done Ok", + __func__, lookup (rtm_type_str, rtm->rtm_type), buf); rib_lookup_and_dump (&p); return; break; @@ -864,27 +970,27 @@ rtm_read (struct rt_msghdr *rtm) switch (ret) { case ZEBRA_RIB_FOUND_EXACT: - zlog_debug ("%s: %s %s/%d: desync: RR is still in RIB, while already not in FIB", - __func__, lookup (rtm_type_str, rtm->rtm_type), buf, p.prefixlen); + zlog_debug ("%s: %s %s: desync: RR is still in RIB, while already not in FIB", + __func__, lookup (rtm_type_str, rtm->rtm_type), buf); rib_lookup_and_dump (&p); break; case ZEBRA_RIB_FOUND_CONNECTED: case ZEBRA_RIB_FOUND_NOGATE: - zlog_debug ("%s: %s %s/%d: desync: RR is still in RIB, plus gate differs", - __func__, lookup (rtm_type_str, rtm->rtm_type), buf, p.prefixlen); + zlog_debug ("%s: %s %s: desync: RR is still in RIB, plus gate differs", + __func__, lookup (rtm_type_str, rtm->rtm_type), buf); rib_lookup_and_dump (&p); break; case ZEBRA_RIB_NOTFOUND: /* RIB RR == FIB RR */ - zlog_debug ("%s: %s %s/%d: done Ok", - __func__, lookup (rtm_type_str, rtm->rtm_type), buf, p.prefixlen); + zlog_debug ("%s: %s %s: done Ok", + __func__, lookup (rtm_type_str, rtm->rtm_type), buf); rib_lookup_and_dump (&p); return; break; } break; default: - zlog_debug ("%s: %s/%d: warning: loopback RTM of type %s received", - __func__, buf, p.prefixlen, lookup (rtm_type_str, rtm->rtm_type)); + zlog_debug ("%s: %s: warning: loopback RTM of type %s received", + __func__, buf, lookup (rtm_type_str, rtm->rtm_type)); } return; } @@ -894,16 +1000,16 @@ rtm_read (struct rt_msghdr *rtm) */ if (rtm->rtm_type == RTM_CHANGE) rib_delete_ipv4 (ZEBRA_ROUTE_KERNEL, zebra_flags, &p, - NULL, 0, 0); + NULL, 0, VRF_DEFAULT, SAFI_UNICAST); if (rtm->rtm_type == RTM_GET || rtm->rtm_type == RTM_ADD || rtm->rtm_type == RTM_CHANGE) - rib_add_ipv4 (ZEBRA_ROUTE_KERNEL, zebra_flags, - &p, &gate.sin.sin_addr, NULL, 0, 0, 0, 0); + rib_add_ipv4 (ZEBRA_ROUTE_KERNEL, zebra_flags, &p, &gate.sin.sin_addr, + NULL, 0, VRF_DEFAULT, 0, 0, 0, 0, SAFI_UNICAST); else - rib_delete_ipv4 (ZEBRA_ROUTE_KERNEL, zebra_flags, - &p, &gate.sin.sin_addr, 0, 0); + rib_delete_ipv4 (ZEBRA_ROUTE_KERNEL, zebra_flags, &p, + &gate.sin.sin_addr, 0, VRF_DEFAULT, SAFI_UNICAST); } #ifdef HAVE_IPV6 if (dest.sa.sa_family == AF_INET6) @@ -914,7 +1020,7 @@ rtm_read (struct rt_msghdr *rtm) if (rtm->rtm_type != RTM_GET && rtm->rtm_pid == pid) return; struct prefix_ipv6 p; - unsigned int ifindex = 0; + ifindex_t ifindex = 0; p.family = AF_INET6; p.prefix = dest.sin6.sin6_addr; @@ -936,16 +1042,17 @@ rtm_read (struct rt_msghdr *rtm) */ if (rtm->rtm_type == RTM_CHANGE) rib_delete_ipv6 (ZEBRA_ROUTE_KERNEL, zebra_flags, &p, - NULL, 0, 0); + NULL, 0, VRF_DEFAULT, SAFI_UNICAST); if (rtm->rtm_type == RTM_GET || rtm->rtm_type == RTM_ADD || rtm->rtm_type == RTM_CHANGE) - rib_add_ipv6 (ZEBRA_ROUTE_KERNEL, zebra_flags, - &p, &gate.sin6.sin6_addr, ifindex, 0, 0, 0); + rib_add_ipv6 (ZEBRA_ROUTE_KERNEL, zebra_flags, &p, &gate.sin6.sin6_addr, + ifindex, VRF_DEFAULT, RT_TABLE_MAIN, 0, 0, 0, SAFI_UNICAST); else - rib_delete_ipv6 (ZEBRA_ROUTE_KERNEL, zebra_flags, - &p, &gate.sin6.sin6_addr, ifindex, 0); + rib_delete_ipv6 (ZEBRA_ROUTE_KERNEL, zebra_flags, &p, + &gate.sin6.sin6_addr, ifindex, + VRF_DEFAULT, SAFI_UNICAST); } #endif /* HAVE_IPV6 */ } @@ -998,14 +1105,14 @@ rtm_write (int message, ifp = if_lookup_by_index (index); - if (gate && message == RTM_ADD) + if (gate && (message == RTM_ADD || message == RTM_CHANGE)) msg.rtm.rtm_flags |= RTF_GATEWAY; /* When RTF_CLONING is unavailable on BSD, should we set some * other flag instead? */ #ifdef RTF_CLONING - if (! gate && message == RTM_ADD && ifp && + if (! gate && (message == RTM_ADD || message == RTM_CHANGE) && ifp && (ifp->flags & IFF_POINTOPOINT) == 0) msg.rtm.rtm_flags |= RTF_CLONING; #endif /* RTF_CLONING */ @@ -1025,12 +1132,12 @@ rtm_write (int message, __func__, dest_buf, mask_buf, index); return -1; } - gate = (union sockunion *) & ifp->sdl; + gate = (union sockunion *) &((struct zebra_if *)ifp->info)->sdl; } if (mask) msg.rtm.rtm_addrs |= RTA_NETMASK; - else if (message == RTM_ADD) + else if (message == RTM_ADD || message == RTM_CHANGE) msg.rtm.rtm_flags |= RTF_HOST; /* Tagging route with flags */ @@ -1043,23 +1150,13 @@ rtm_write (int message, msg.rtm.rtm_flags |= RTF_REJECT; -#ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN #define SOCKADDRSET(X,R) \ if (msg.rtm.rtm_addrs & (R)) \ { \ - int len = ROUNDUP ((X)->sa.sa_len); \ - memcpy (pnt, (caddr_t)(X), len); \ - pnt += len; \ - } -#else -#define SOCKADDRSET(X,R) \ - if (msg.rtm.rtm_addrs & (R)) \ - { \ int len = SAROUNDUP (X); \ memcpy (pnt, (caddr_t)(X), len); \ pnt += len; \ } -#endif /* HAVE_STRUCT_SOCKADDR_IN_SIN_LEN */ pnt = (caddr_t) msg.buf; @@ -1087,7 +1184,7 @@ rtm_write (int message, return ZEBRA_ERR_NOERROR; } - + #include "thread.h" #include "zebra/zserv.h" @@ -1098,7 +1195,8 @@ rtmsg_debug (struct rt_msghdr *rtm) zlog_debug ("Kernel: Len: %d Type: %s", rtm->rtm_msglen, lookup (rtm_type_str, rtm->rtm_type)); rtm_flag_dump (rtm->rtm_flags); zlog_debug ("Kernel: message seq %d", rtm->rtm_seq); - zlog_debug ("Kernel: pid %d, rtm_addrs 0x%x", rtm->rtm_pid, rtm->rtm_addrs); + zlog_debug ("Kernel: pid %lld, rtm_addrs 0x%x", + (long long)rtm->rtm_pid, rtm->rtm_addrs); } /* This is pretty gross, better suggestions welcome -- mhandler */ @@ -1220,8 +1318,11 @@ kernel_read (struct thread *thread) /* Make routing socket. */ static void -routing_socket (void) +routing_socket (struct zebra_vrf *zvrf) { + if (zvrf->vrf_id != VRF_DEFAULT) + return; + if ( zserv_privs.change (ZPRIVS_RAISE) ) zlog_err ("routing_socket: Can't raise privileges"); @@ -1252,7 +1353,13 @@ routing_socket (void) /* Exported interface function. This function simply calls routing_socket (). */ void -kernel_init (void) +kernel_init (struct zebra_vrf *zvrf) { - routing_socket (); + routing_socket (zvrf); +} + +void +kernel_terminate (struct zebra_vrf *zvrf) +{ + return; }