version 1.1.1.3, 2013/07/21 23:54:41
|
version 1.1.1.4, 2016/11/02 10:09:10
|
Line 20
|
Line 20
|
*/ |
*/ |
|
|
#include <zebra.h> |
#include <zebra.h> |
|
#include <net/if_types.h> |
|
|
#include "if.h" |
#include "if.h" |
#include "prefix.h" |
#include "prefix.h" |
Line 32
|
Line 33
|
#include "table.h" |
#include "table.h" |
#include "rib.h" |
#include "rib.h" |
#include "privs.h" |
#include "privs.h" |
|
#include "vrf.h" |
|
|
#include "zebra/interface.h" |
#include "zebra/interface.h" |
#include "zebra/zserv.h" |
#include "zebra/zserv.h" |
#include "zebra/debug.h" |
#include "zebra/debug.h" |
#include "zebra/kernel_socket.h" |
#include "zebra/kernel_socket.h" |
|
#include "zebra/rib.h" |
|
|
extern struct zebra_privs_t zserv_privs; |
extern struct zebra_privs_t zserv_privs; |
extern struct zebra_t zebrad; |
extern struct zebra_t zebrad; |
|
|
/* |
/* |
* Given a sockaddr length, round it up to include pad bytes following | * Historically, the BSD routing socket has aligned data following a |
* it. Assumes the kernel pads to sizeof(long). | * 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 | * Alignment of zero-sized sockaddrs is nonsensical, but historically |
* length anyway (< sizeof (struct sockaddr)), so this shouldn't | * BSD defines RT_ROUNDUP(0) to be the alignment interval (rather than |
* matter. | * 0). We follow this practice without questioning it, but it is a |
* On OS X, both 32, 64bit syatems align on 4 byte boundary | * bug if quagga calls ROUNDUP with 0. |
*/ |
*/ |
|
|
|
/* |
|
* Because of these varying conventions, the only sane approach is for |
|
* the <net/route.h> 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__ |
#ifdef __APPLE__ |
#define ROUNDUP(a) \ | #define ROUNDUP_TYPE int |
((a) > 0 ? (1 + (((a) - 1) | (sizeof(int) - 1))) : sizeof(int)) | |
#else |
#else |
#define ROUNDUP(a) \ | #define ROUNDUP_TYPE long |
((a) > 0 ? (1 + (((a) - 1) | (sizeof(long) - 1))) : sizeof(long)) | |
#endif |
#endif |
|
|
|
#define ROUNDUP(a) \ |
|
((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 |
* Given a pointer (sockaddr or void *), return the number of bytes |
* taken up by the sockaddr and any padding needed for alignment. |
* taken up by the sockaddr and any padding needed for alignment. |
Line 84 extern struct zebra_t zebrad;
|
Line 129 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 */ |
|
|
|
#endif /* !SA_SIZE */ |
|
|
/* |
/* |
* We use a call to an inline function to copy (PNT) to (DEST) |
* 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 |
* 1. Calculating the length of the copy requires an #ifdef to determine |
Line 91 extern struct zebra_t zebrad;
|
Line 138 extern struct zebra_t zebrad;
|
* 2. So the compiler doesn't complain when DEST is NULL, which is only true |
* 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 |
* when we are skipping the copy and incrementing to the next SA |
*/ |
*/ |
static void inline | static inline void |
rta_copy (union sockunion *dest, caddr_t src) { |
rta_copy (union sockunion *dest, caddr_t src) { |
int len; |
int len; |
|
if (!dest) |
|
return; |
#ifdef HAVE_STRUCT_SOCKADDR_SA_LEN |
#ifdef HAVE_STRUCT_SOCKADDR_SA_LEN |
len = (((struct sockaddr *)src)->sa_len > sizeof (*dest)) ? |
len = (((struct sockaddr *)src)->sa_len > sizeof (*dest)) ? |
sizeof (*dest) : ((struct sockaddr *)src)->sa_len ; |
sizeof (*dest) : ((struct sockaddr *)src)->sa_len ; |
Line 108 rta_copy (union sockunion *dest, caddr_t src) {
|
Line 157 rta_copy (union sockunion *dest, caddr_t src) {
|
if ((RTMADDRS) & (RTA)) \ |
if ((RTMADDRS) & (RTA)) \ |
{ \ |
{ \ |
int len = SAROUNDUP ((PNT)); \ |
int len = SAROUNDUP ((PNT)); \ |
if ( ((DEST) != NULL) && \ | if (af_check (((struct sockaddr *)(PNT))->sa_family)) \ |
af_check (((struct sockaddr *)(PNT))->sa_family)) \ | |
rta_copy((DEST), (PNT)); \ |
rta_copy((DEST), (PNT)); \ |
(PNT) += len; \ |
(PNT) += len; \ |
} |
} |
Line 117 rta_copy (union sockunion *dest, caddr_t src) {
|
Line 165 rta_copy (union sockunion *dest, caddr_t src) {
|
if ((RTMADDRS) & (RTA)) \ |
if ((RTMADDRS) & (RTA)) \ |
{ \ |
{ \ |
int len = SAROUNDUP ((PNT)); \ |
int len = SAROUNDUP ((PNT)); \ |
if ((DEST) != NULL) \ | rta_copy((DEST), (PNT)); \ |
rta_copy((DEST), (PNT)); \ | |
(PNT) += len; \ |
(PNT) += len; \ |
} |
} |
|
|
Line 196 static const struct message rtm_flag_str[] =
|
Line 243 static const struct message rtm_flag_str[] =
|
{RTF_CLONING, "CLONING"}, |
{RTF_CLONING, "CLONING"}, |
#endif /* RTF_CLONING */ |
#endif /* RTF_CLONING */ |
{RTF_XRESOLVE, "XRESOLVE"}, |
{RTF_XRESOLVE, "XRESOLVE"}, |
|
#ifdef RTF_LLINFO |
{RTF_LLINFO, "LLINFO"}, |
{RTF_LLINFO, "LLINFO"}, |
|
#endif /* RTF_LLINFO */ |
{RTF_STATIC, "STATIC"}, |
{RTF_STATIC, "STATIC"}, |
{RTF_BLACKHOLE, "BLACKHOLE"}, |
{RTF_BLACKHOLE, "BLACKHOLE"}, |
#ifdef RTF_PRIVATE |
#ifdef RTF_PRIVATE |
Line 241 int routing_sock = -1;
|
Line 290 int routing_sock = -1;
|
/* #define DEBUG */ |
/* #define DEBUG */ |
|
|
/* Supported address family check. */ |
/* Supported address family check. */ |
static int inline | static inline int |
af_check (int family) |
af_check (int family) |
{ |
{ |
if (family == AF_INET) |
if (family == AF_INET) |
Line 252 af_check (int family)
|
Line 301 af_check (int family)
|
#endif /* HAVE_IPV6 */ |
#endif /* HAVE_IPV6 */ |
return 0; |
return 0; |
} |
} |
| |
/* Dump routing table flag for debug purpose. */ |
/* Dump routing table flag for debug purpose. */ |
static void |
static void |
rtm_flag_dump (int flag) |
rtm_flag_dump (int flag) |
Line 299 ifan_read (struct if_announcemsghdr *ifan)
|
Line 348 ifan_read (struct if_announcemsghdr *ifan)
|
sizeof(ifan->ifan_name))); |
sizeof(ifan->ifan_name))); |
ifp->ifindex = ifan->ifan_index; |
ifp->ifindex = ifan->ifan_index; |
|
|
|
if_get_metric (ifp); |
if_add_update (ifp); |
if_add_update (ifp); |
} |
} |
else if (ifp != NULL && ifan->ifan_what == IFAN_DEPARTURE) |
else if (ifp != NULL && ifan->ifan_what == IFAN_DEPARTURE) |
Line 329 bsd_linkdetect_translate (struct if_msghdr *ifm)
|
Line 379 bsd_linkdetect_translate (struct if_msghdr *ifm)
|
} |
} |
#endif /* HAVE_BSD_IFI_LINK_STATE */ |
#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 |
* Handle struct if_msghdr obtained from reading routing socket or |
* sysctl (from interface_list). There may or may not be sockaddrs |
* sysctl (from interface_list). There may or may not be sockaddrs |
Line 485 ifm_read (struct if_msghdr *ifm)
|
Line 558 ifm_read (struct if_msghdr *ifm)
|
* is fine here. |
* is fine here. |
* a nonzero ifnlen from RTA_NAME_GET() means sdl is valid |
* a nonzero ifnlen from RTA_NAME_GET() means sdl is valid |
*/ |
*/ |
|
ifp->ll_type = ZEBRA_LLT_UNKNOWN; |
|
ifp->hw_addr_len = 0; |
if (ifnlen) |
if (ifnlen) |
{ | { |
#ifdef HAVE_STRUCT_SOCKADDR_DL_SDL_LEN |
#ifdef HAVE_STRUCT_SOCKADDR_DL_SDL_LEN |
memcpy (&ifp->sdl, sdl, sdl->sdl_len); | memcpy (&((struct zebra_if *)ifp->info)->sdl, sdl, sdl->sdl_len); |
#else |
#else |
memcpy (&ifp->sdl, sdl, sizeof (struct sockaddr_dl)); | memcpy (&((struct zebra_if *)ifp->info)->sdl, sdl, sizeof (struct sockaddr_dl)); |
#endif /* HAVE_STRUCT_SOCKADDR_DL_SDL_LEN */ |
#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); |
if_add_update (ifp); |
} |
} |
else |
else |
Line 556 ifm_read (struct if_msghdr *ifm)
|
Line 638 ifm_read (struct if_msghdr *ifm)
|
|
|
return 0; |
return 0; |
} |
} |
| |
/* Address read from struct ifa_msghdr. */ |
/* Address read from struct ifa_msghdr. */ |
static void |
static void |
ifam_read_mesg (struct ifa_msghdr *ifm, |
ifam_read_mesg (struct ifa_msghdr *ifm, |
Line 592 ifam_read_mesg (struct ifa_msghdr *ifm,
|
Line 674 ifam_read_mesg (struct ifa_msghdr *ifm,
|
|
|
if (IS_ZEBRA_DEBUG_KERNEL) |
if (IS_ZEBRA_DEBUG_KERNEL) |
{ |
{ |
switch (sockunion_family(addr)) | int family = sockunion_family(addr); |
| switch (family) |
{ |
{ |
case AF_INET: |
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 |
#ifdef HAVE_IPV6 |
case AF_INET6: |
case AF_INET6: |
|
#endif |
{ |
{ |
char buf[4][INET6_ADDRSTRLEN]; |
char buf[4][INET6_ADDRSTRLEN]; |
zlog_debug ("%s: ifindex %d, ifname %s, ifam_addrs 0x%x, " |
zlog_debug ("%s: ifindex %d, ifname %s, ifam_addrs 0x%x, " |
"ifam_flags 0x%x, addr %s/%d broad %s dst %s " |
"ifam_flags 0x%x, addr %s/%d broad %s dst %s " |
"gateway %s", |
"gateway %s", |
__func__, ifm->ifam_index, | __func__, ifm->ifam_index, |
(ifnlen ? ifname : "(nil)"), ifm->ifam_addrs, |
(ifnlen ? ifname : "(nil)"), ifm->ifam_addrs, |
ifm->ifam_flags, |
ifm->ifam_flags, |
inet_ntop(AF_INET6,&addr->sin6.sin6_addr, | inet_ntop(family,&addr->sin.sin_addr, |
buf[0],sizeof(buf[0])), |
buf[0],sizeof(buf[0])), |
ip6_masklen(mask->sin6.sin6_addr), | ip_masklen(mask->sin.sin_addr), |
inet_ntop(AF_INET6,&brd->sin6.sin6_addr, | inet_ntop(family,&brd->sin.sin_addr, |
buf[1],sizeof(buf[1])), |
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])), |
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]))); |
buf[3],sizeof(buf[3]))); |
} |
} |
break; |
break; |
#endif /* HAVE_IPV6 */ |
|
default: |
default: |
zlog_debug ("%s: ifindex %d, ifname %s, ifam_addrs 0x%x", |
zlog_debug ("%s: ifindex %d, ifname %s, ifam_addrs 0x%x", |
__func__, ifm->ifam_index, |
__func__, ifm->ifam_index, |
Line 709 ifam_read (struct ifa_msghdr *ifam)
|
Line 773 ifam_read (struct ifa_msghdr *ifam)
|
/* Unset interface index from link-local address when IPv6 stack |
/* Unset interface index from link-local address when IPv6 stack |
is KAME. */ |
is KAME. */ |
if (IN6_IS_ADDR_LINKLOCAL (&addr.sin6.sin6_addr)) |
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) |
if (ifam->ifam_type == RTM_NEWADDR) |
connected_add_ipv6 (ifp, flags, &addr.sin6.sin6_addr, |
connected_add_ipv6 (ifp, flags, &addr.sin6.sin6_addr, |
Line 750 ifam_read (struct ifa_msghdr *ifam)
|
Line 816 ifam_read (struct ifa_msghdr *ifam)
|
|
|
return 0; |
return 0; |
} |
} |
| |
/* Interface function for reading kernel routing table information. */ |
/* Interface function for reading kernel routing table information. */ |
static int |
static int |
rtm_read_mesg (struct rt_msghdr *rtm, |
rtm_read_mesg (struct rt_msghdr *rtm, |
Line 828 rtm_read (struct rt_msghdr *rtm)
|
Line 894 rtm_read (struct rt_msghdr *rtm)
|
return; |
return; |
#endif |
#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; |
return; |
|
|
/* This is connected route. */ |
/* This is connected route. */ |
Line 865 rtm_read (struct rt_msghdr *rtm)
|
Line 931 rtm_read (struct rt_msghdr *rtm)
|
*/ |
*/ |
if (rtm->rtm_type != RTM_GET && rtm->rtm_pid == pid) |
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; |
int ret; |
if (! IS_ZEBRA_DEBUG_RIB) |
if (! IS_ZEBRA_DEBUG_RIB) |
return; |
return; |
ret = rib_lookup_ipv4_route (&p, &gate); | ret = rib_lookup_ipv4_route (&p, &gate, VRF_DEFAULT); |
inet_ntop (AF_INET, &p.prefix, buf, INET_ADDRSTRLEN); | prefix2str (&p, buf, sizeof(buf)); |
switch (rtm->rtm_type) |
switch (rtm->rtm_type) |
{ |
{ |
case RTM_ADD: |
case RTM_ADD: |
Line 881 rtm_read (struct rt_msghdr *rtm)
|
Line 947 rtm_read (struct rt_msghdr *rtm)
|
switch (ret) |
switch (ret) |
{ |
{ |
case ZEBRA_RIB_NOTFOUND: |
case ZEBRA_RIB_NOTFOUND: |
zlog_debug ("%s: %s %s/%d: desync: RR isn't yet in RIB, while already in FIB", | 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, p.prefixlen); | __func__, lookup (rtm_type_str, rtm->rtm_type), buf); |
break; |
break; |
case ZEBRA_RIB_FOUND_CONNECTED: |
case ZEBRA_RIB_FOUND_CONNECTED: |
case ZEBRA_RIB_FOUND_NOGATE: |
case ZEBRA_RIB_FOUND_NOGATE: |
inet_ntop (AF_INET, &gate.sin.sin_addr, gate_buf, INET_ADDRSTRLEN); |
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)", | 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, p.prefixlen, gate_buf); | __func__, lookup (rtm_type_str, rtm->rtm_type), buf, gate_buf); |
break; |
break; |
case ZEBRA_RIB_FOUND_EXACT: /* RIB RR == FIB RR */ |
case ZEBRA_RIB_FOUND_EXACT: /* RIB RR == FIB RR */ |
zlog_debug ("%s: %s %s/%d: done Ok", | zlog_debug ("%s: %s %s: done Ok", |
__func__, lookup (rtm_type_str, rtm->rtm_type), buf, p.prefixlen); | __func__, lookup (rtm_type_str, rtm->rtm_type), buf); |
rib_lookup_and_dump (&p); |
rib_lookup_and_dump (&p); |
return; |
return; |
break; |
break; |
Line 904 rtm_read (struct rt_msghdr *rtm)
|
Line 970 rtm_read (struct rt_msghdr *rtm)
|
switch (ret) |
switch (ret) |
{ |
{ |
case ZEBRA_RIB_FOUND_EXACT: |
case ZEBRA_RIB_FOUND_EXACT: |
zlog_debug ("%s: %s %s/%d: desync: RR is still in RIB, while already not in FIB", | 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, p.prefixlen); | __func__, lookup (rtm_type_str, rtm->rtm_type), buf); |
rib_lookup_and_dump (&p); |
rib_lookup_and_dump (&p); |
break; |
break; |
case ZEBRA_RIB_FOUND_CONNECTED: |
case ZEBRA_RIB_FOUND_CONNECTED: |
case ZEBRA_RIB_FOUND_NOGATE: |
case ZEBRA_RIB_FOUND_NOGATE: |
zlog_debug ("%s: %s %s/%d: desync: RR is still in RIB, plus gate differs", | zlog_debug ("%s: %s %s: desync: RR is still in RIB, plus gate differs", |
__func__, lookup (rtm_type_str, rtm->rtm_type), buf, p.prefixlen); | __func__, lookup (rtm_type_str, rtm->rtm_type), buf); |
rib_lookup_and_dump (&p); |
rib_lookup_and_dump (&p); |
break; |
break; |
case ZEBRA_RIB_NOTFOUND: /* RIB RR == FIB RR */ |
case ZEBRA_RIB_NOTFOUND: /* RIB RR == FIB RR */ |
zlog_debug ("%s: %s %s/%d: done Ok", | zlog_debug ("%s: %s %s: done Ok", |
__func__, lookup (rtm_type_str, rtm->rtm_type), buf, p.prefixlen); | __func__, lookup (rtm_type_str, rtm->rtm_type), buf); |
rib_lookup_and_dump (&p); |
rib_lookup_and_dump (&p); |
return; |
return; |
break; |
break; |
} |
} |
break; |
break; |
default: |
default: |
zlog_debug ("%s: %s/%d: warning: loopback RTM of type %s received", | zlog_debug ("%s: %s: warning: loopback RTM of type %s received", |
__func__, buf, p.prefixlen, lookup (rtm_type_str, rtm->rtm_type)); | __func__, buf, lookup (rtm_type_str, rtm->rtm_type)); |
} |
} |
return; |
return; |
} |
} |
Line 934 rtm_read (struct rt_msghdr *rtm)
|
Line 1000 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, SAFI_UNICAST); | NULL, 0, VRF_DEFAULT, 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, |
&p, &gate.sin.sin_addr, NULL, 0, 0, 0, 0, SAFI_UNICAST); | NULL, 0, VRF_DEFAULT, 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, |
&p, &gate.sin.sin_addr, 0, 0, SAFI_UNICAST); | &gate.sin.sin_addr, 0, VRF_DEFAULT, SAFI_UNICAST); |
} |
} |
#ifdef HAVE_IPV6 |
#ifdef HAVE_IPV6 |
if (dest.sa.sa_family == AF_INET6) |
if (dest.sa.sa_family == AF_INET6) |
Line 954 rtm_read (struct rt_msghdr *rtm)
|
Line 1020 rtm_read (struct rt_msghdr *rtm)
|
if (rtm->rtm_type != RTM_GET && rtm->rtm_pid == pid) |
if (rtm->rtm_type != RTM_GET && rtm->rtm_pid == pid) |
return; |
return; |
struct prefix_ipv6 p; |
struct prefix_ipv6 p; |
unsigned int ifindex = 0; | ifindex_t ifindex = 0; |
|
|
p.family = AF_INET6; |
p.family = AF_INET6; |
p.prefix = dest.sin6.sin6_addr; |
p.prefix = dest.sin6.sin6_addr; |
Line 976 rtm_read (struct rt_msghdr *rtm)
|
Line 1042 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, SAFI_UNICAST); | NULL, 0, VRF_DEFAULT, 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, |
&p, &gate.sin6.sin6_addr, ifindex, 0, 0, 0, SAFI_UNICAST); | ifindex, VRF_DEFAULT, RT_TABLE_MAIN, 0, 0, 0, SAFI_UNICAST); |
else |
else |
rib_delete_ipv6 (ZEBRA_ROUTE_KERNEL, zebra_flags, | rib_delete_ipv6 (ZEBRA_ROUTE_KERNEL, zebra_flags, &p, |
&p, &gate.sin6.sin6_addr, ifindex, 0, SAFI_UNICAST); | &gate.sin6.sin6_addr, ifindex, |
| VRF_DEFAULT, SAFI_UNICAST); |
} |
} |
#endif /* HAVE_IPV6 */ |
#endif /* HAVE_IPV6 */ |
} |
} |
Line 1038 rtm_write (int message,
|
Line 1105 rtm_write (int message,
|
|
|
ifp = if_lookup_by_index (index); |
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; |
msg.rtm.rtm_flags |= RTF_GATEWAY; |
|
|
/* When RTF_CLONING is unavailable on BSD, should we set some |
/* When RTF_CLONING is unavailable on BSD, should we set some |
* other flag instead? |
* other flag instead? |
*/ |
*/ |
#ifdef RTF_CLONING |
#ifdef RTF_CLONING |
if (! gate && message == RTM_ADD && ifp && | if (! gate && (message == RTM_ADD || message == RTM_CHANGE) && ifp && |
(ifp->flags & IFF_POINTOPOINT) == 0) |
(ifp->flags & IFF_POINTOPOINT) == 0) |
msg.rtm.rtm_flags |= RTF_CLONING; |
msg.rtm.rtm_flags |= RTF_CLONING; |
#endif /* RTF_CLONING */ |
#endif /* RTF_CLONING */ |
Line 1065 rtm_write (int message,
|
Line 1132 rtm_write (int message,
|
__func__, dest_buf, mask_buf, index); |
__func__, dest_buf, mask_buf, index); |
return -1; |
return -1; |
} |
} |
gate = (union sockunion *) & ifp->sdl; | gate = (union sockunion *) &((struct zebra_if *)ifp->info)->sdl; |
} |
} |
|
|
if (mask) |
if (mask) |
msg.rtm.rtm_addrs |= RTA_NETMASK; |
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; |
msg.rtm.rtm_flags |= RTF_HOST; |
|
|
/* Tagging route with flags */ |
/* Tagging route with flags */ |
Line 1083 rtm_write (int message,
|
Line 1150 rtm_write (int message,
|
msg.rtm.rtm_flags |= RTF_REJECT; |
msg.rtm.rtm_flags |= RTF_REJECT; |
|
|
|
|
#ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN |
|
#define SOCKADDRSET(X,R) \ |
#define SOCKADDRSET(X,R) \ |
if (msg.rtm.rtm_addrs & (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); \ |
int len = SAROUNDUP (X); \ |
memcpy (pnt, (caddr_t)(X), len); \ |
memcpy (pnt, (caddr_t)(X), len); \ |
pnt += len; \ |
pnt += len; \ |
} |
} |
#endif /* HAVE_STRUCT_SOCKADDR_IN_SIN_LEN */ |
|
|
|
pnt = (caddr_t) msg.buf; |
pnt = (caddr_t) msg.buf; |
|
|
Line 1127 rtm_write (int message,
|
Line 1184 rtm_write (int message,
|
return ZEBRA_ERR_NOERROR; |
return ZEBRA_ERR_NOERROR; |
} |
} |
|
|
| |
#include "thread.h" |
#include "thread.h" |
#include "zebra/zserv.h" |
#include "zebra/zserv.h" |
|
|
Line 1138 rtmsg_debug (struct rt_msghdr *rtm)
|
Line 1195 rtmsg_debug (struct rt_msghdr *rtm)
|
zlog_debug ("Kernel: Len: %d Type: %s", rtm->rtm_msglen, lookup (rtm_type_str, rtm->rtm_type)); |
zlog_debug ("Kernel: Len: %d Type: %s", rtm->rtm_msglen, lookup (rtm_type_str, rtm->rtm_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_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 */ |
/* This is pretty gross, better suggestions welcome -- mhandler */ |
Line 1260 kernel_read (struct thread *thread)
|
Line 1318 kernel_read (struct thread *thread)
|
|
|
/* Make routing socket. */ |
/* Make routing socket. */ |
static void |
static void |
routing_socket (void) | routing_socket (struct zebra_vrf *zvrf) |
{ |
{ |
|
if (zvrf->vrf_id != VRF_DEFAULT) |
|
return; |
|
|
if ( zserv_privs.change (ZPRIVS_RAISE) ) |
if ( zserv_privs.change (ZPRIVS_RAISE) ) |
zlog_err ("routing_socket: Can't raise privileges"); |
zlog_err ("routing_socket: Can't raise privileges"); |
|
|
Line 1292 routing_socket (void)
|
Line 1353 routing_socket (void)
|
/* Exported interface function. This function simply calls |
/* Exported interface function. This function simply calls |
routing_socket (). */ |
routing_socket (). */ |
void |
void |
kernel_init (void) | kernel_init (struct zebra_vrf *zvrf) |
{ |
{ |
routing_socket (); | routing_socket (zvrf); |
| } |
| |
| void |
| kernel_terminate (struct zebra_vrf *zvrf) |
| { |
| return; |
} |
} |