diff options
Diffstat (limited to 'zebra/rt_socket.c')
-rw-r--r-- | zebra/rt_socket.c | 83 |
1 files changed, 60 insertions, 23 deletions
diff --git a/zebra/rt_socket.c b/zebra/rt_socket.c index b06c586a..e8668a1d 100644 --- a/zebra/rt_socket.c +++ b/zebra/rt_socket.c @@ -32,6 +32,7 @@ #include "zebra/debug.h" #include "zebra/rib.h" #include "zebra/rt.h" +#include "zebra/kernel_socket.h" extern struct zebra_privs_t zserv_privs; @@ -75,7 +76,10 @@ kernel_rtm_ipv4 (int cmd, struct prefix *p, struct rib *rib, int family) unsigned int ifindex = 0; int gate = 0; int error; + char prefix_buf[INET_ADDRSTRLEN]; + if (IS_ZEBRA_DEBUG_RIB) + inet_ntop (AF_INET, &p->u.prefix, prefix_buf, INET_ADDRSTRLEN); memset (&sin_dest, 0, sizeof (struct sockaddr_in)); sin_dest.sin_family = AF_INET; #ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN @@ -95,6 +99,7 @@ kernel_rtm_ipv4 (int cmd, struct prefix *p, struct rib *rib, int family) for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next) { gate = 0; + char gate_buf[INET_ADDRSTRLEN] = "NULL"; /* * XXX We need to refrain from kernel operations in some cases, @@ -161,29 +166,61 @@ kernel_rtm_ipv4 (int cmd, struct prefix *p, struct rib *rib, int family) rib->flags, rib->metric); -#if 0 - if (error) - { - zlog_info ("kernel_rtm_ipv4(): nexthop %d add error=%d.", - nexthop_num, error); - } -#endif - if (error == 0) - { - nexthop_num++; - if (cmd == RTM_ADD) - SET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB); - } - } - } - - /* If there is no useful nexthop then return. */ - if (nexthop_num == 0) - { - if (IS_ZEBRA_DEBUG_KERNEL) - zlog_debug ("kernel_rtm_ipv4(): No useful nexthop."); - return 0; - } + if (IS_ZEBRA_DEBUG_RIB) + { + if (!gate) + { + zlog_debug ("%s: %s/%d: attention! gate not found for rib %p", + __func__, prefix_buf, p->prefixlen, rib); + rib_dump (__func__, (struct prefix_ipv4 *)p, rib); + } + else + inet_ntop (AF_INET, &sin_gate.sin_addr, gate_buf, INET_ADDRSTRLEN); + } + + switch (error) + { + /* We only flag nexthops as being in FIB if rtm_write() did its work. */ + case ZEBRA_ERR_NOERROR: + nexthop_num++; + if (IS_ZEBRA_DEBUG_RIB) + zlog_debug ("%s: %s/%d: successfully did NH %s", + __func__, prefix_buf, p->prefixlen, gate_buf); + if (cmd == RTM_ADD) + SET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB); + break; + + /* The only valid case for this error is kernel's failure to install + * a multipath route, which is common for FreeBSD. This should be + * ignored silently, but logged as an error otherwise. + */ + case ZEBRA_ERR_RTEXIST: + if (cmd != RTM_ADD) + zlog_err ("%s: rtm_write() returned %d for command %d", + __func__, error, cmd); + continue; + break; + + /* Given that our NEXTHOP_FLAG_FIB matches real kernel FIB, it isn't + * normal to get any other messages in ANY case. + */ + case ZEBRA_ERR_RTNOEXIST: + case ZEBRA_ERR_RTUNREACH: + default: + zlog_err ("%s: %s/%d: rtm_write() unexpectedly returned %d for command %s", + __func__, prefix_buf, p->prefixlen, error, LOOKUP (rtm_type_str, cmd)); + break; + } + } /* if (cmd and flags make sense) */ + else + if (IS_ZEBRA_DEBUG_RIB) + zlog_debug ("%s: odd command %s for flags %d", + __func__, LOOKUP (rtm_type_str, cmd), nexthop->flags); + } /* for (nexthop = ... */ + + /* If there was no useful nexthop, then complain. */ + if (nexthop_num == 0 && IS_ZEBRA_DEBUG_KERNEL) + zlog_debug ("%s: No useful nexthops were found in RIB entry %p", __func__, rib); return 0; /*XXX*/ } |