diff options
Diffstat (limited to 'zebra/kernel_socket.c')
| -rw-r--r-- | zebra/kernel_socket.c | 62 |
1 files changed, 25 insertions, 37 deletions
diff --git a/zebra/kernel_socket.c b/zebra/kernel_socket.c index 2b6caace8e..8fd0c96bd9 100644 --- a/zebra/kernel_socket.c +++ b/zebra/kernel_socket.c @@ -80,12 +80,6 @@ extern struct zebra_privs_t zserv_privs; #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. @@ -547,18 +541,6 @@ int ifm_read(struct if_msghdr *ifm) */ cp = (void *)(ifm + 1); -#ifdef SUNOS_5 - /* - * XXX This behavior should be narrowed to only the kernel versions - * for which the structures returned do not match the headers. - * - * if_msghdr_t on 64 bit kernels in Solaris 9 and earlier versions - * is 12 bytes larger than the 32 bit version. - */ - if (((struct sockaddr *)cp)->sa_family == AF_UNSPEC) - cp += 12; -#endif - /* Look up for RTA_IFP and skip others. */ for (maskbit = 1; maskbit; maskbit <<= 1) { if ((maskbit & ifm->ifm_addrs) == 0) @@ -946,23 +928,6 @@ int ifam_read(struct ifa_msghdr *ifam) /* Check interface flag for implicit up of the interface. */ if_refresh(ifp); -#ifdef SUNOS_5 - /* In addition to lacking IFANNOUNCE, on SUNOS IFF_UP is strange. - * See comments for SUNOS_5 in interface.c::if_flags_mangle. - * - * Here we take care of case where the real IFF_UP was previously - * unset (as kept in struct zebra_if.primary_state) and the mangled - * IFF_UP (ie IFF_UP set || listcount(connected) has now transitioned - * to unset due to the lost non-primary address having DELADDR'd. - * - * we must delete the interface, because in between here and next - * event for this interface-name the administrator could unplumb - * and replumb the interface. - */ - if (!if_is_up(ifp)) - if_delete_update(ifp); -#endif /* SUNOS_5 */ - return 0; } @@ -1375,13 +1340,27 @@ static int kernel_read(struct thread *thread) nbytes = read(sock, &buf, sizeof(buf)); - if (nbytes <= 0) { - if (nbytes < 0 && errno != EWOULDBLOCK && errno != EAGAIN) + if (nbytes < 0) { + if (errno == ENOBUFS) { + flog_err(EC_ZEBRA_RECVMSG_OVERRUN, + "routing socket overrun: %s", + safe_strerror(errno)); + /* + * In this case we are screwed. + * There is no good way to + * recover zebra at this point. + */ + exit(-1); + } + if (errno != EAGAIN && errno != EWOULDBLOCK) flog_err_sys(EC_LIB_SOCKET, "routing socket error: %s", safe_strerror(errno)); return 0; } + if (nbytes == 0) + return 0; + thread_add_read(zrouter.master, kernel_read, NULL, sock, NULL); if (IS_ZEBRA_DEBUG_KERNEL) @@ -1447,6 +1426,15 @@ static void routing_socket(struct zebra_ns *zns) return; } +#ifdef SO_RERROR + /* Allow reporting of route(4) buffer overflow errors */ + int n = 1; + + if (setsockopt(routing_sock, SOL_SOCKET, SO_RERROR, &n, sizeof(n)) < 0) + flog_err_sys(EC_LIB_SOCKET, + "Can't set SO_RERROR on routing socket"); +#endif + /* XXX: Socket should be NONBLOCK, however as we currently * discard failed writes, this will lead to inconsistencies. * For now, socket must be blocking. |
