summaryrefslogtreecommitdiff
path: root/zebra/rt_socket.c
diff options
context:
space:
mode:
Diffstat (limited to 'zebra/rt_socket.c')
-rw-r--r--zebra/rt_socket.c83
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*/
}