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.c163
1 files changed, 67 insertions, 96 deletions
diff --git a/zebra/rt_socket.c b/zebra/rt_socket.c
index 29e9bf82f0..f25259f300 100644
--- a/zebra/rt_socket.c
+++ b/zebra/rt_socket.c
@@ -44,30 +44,6 @@
extern struct zebra_privs_t zserv_privs;
-#ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
-/* Adjust netmask socket length. Return value is a adjusted sin_len
- value. */
-static int sin_masklen(struct in_addr mask)
-{
- char *p, *lim;
- int len;
- struct sockaddr_in sin;
-
- if (mask.s_addr == 0)
- return sizeof(long);
-
- sin.sin_addr = mask;
- len = sizeof(struct sockaddr_in);
-
- lim = (char *)&sin.sin_addr;
- p = lim + sizeof(sin.sin_addr);
-
- while (*--p == 0 && p >= lim)
- len--;
- return len;
-}
-#endif /* HAVE_STRUCT_SOCKADDR_IN_SIN_LEN */
-
#ifdef __OpenBSD__
static int kernel_rtm_add_labels(struct mpls_label_stack *nh_label,
struct sockaddr_mpls *smpls)
@@ -89,30 +65,6 @@ static int kernel_rtm_add_labels(struct mpls_label_stack *nh_label,
}
#endif
-#ifdef SIN6_LEN
-/* Calculate sin6_len value for netmask socket value. */
-static int sin6_masklen(struct in6_addr mask)
-{
- struct sockaddr_in6 sin6;
- char *p, *lim;
- int len;
-
- if (IN6_IS_ADDR_UNSPECIFIED(&mask))
- return sizeof(long);
-
- sin6.sin6_addr = mask;
- len = sizeof(struct sockaddr_in6);
-
- lim = (char *)&sin6.sin6_addr;
- p = lim + sizeof(sin6.sin6_addr);
-
- while (*--p == 0 && p >= lim)
- len--;
-
- return len;
-}
-#endif /* SIN6_LEN */
-
/* Interface between zebra message and rtm message. */
static int kernel_rtm(int cmd, const struct prefix *p,
const struct nexthop_group *ng, uint32_t metric)
@@ -128,11 +80,11 @@ static int kernel_rtm(int cmd, const struct prefix *p,
ifindex_t ifindex = 0;
bool gate = false;
int error;
+ char gate_buf[INET6_BUFSIZ];
char prefix_buf[PREFIX_STRLEN];
enum blackhole_type bh_type = BLACKHOLE_UNSPEC;
- if (IS_ZEBRA_DEBUG_RIB)
- prefix2str(p, prefix_buf, sizeof(prefix_buf));
+ prefix2str(p, prefix_buf, sizeof(prefix_buf));
/*
* We only have the ability to ADD or DELETE at this point
@@ -140,10 +92,9 @@ static int kernel_rtm(int cmd, const struct prefix *p,
*/
if (cmd != RTM_ADD && cmd != RTM_DELETE) {
if (IS_ZEBRA_DEBUG_KERNEL)
- zlog_debug("%s: %s odd command %s for flags %d",
+ zlog_debug("%s: %s odd command %s",
__func__, prefix_buf,
- lookup_msg(rtm_type_str, cmd, NULL),
- nexthop->flags);
+ lookup_msg(rtm_type_str, cmd, NULL));
return 0;
}
@@ -154,23 +105,21 @@ static int kernel_rtm(int cmd, const struct prefix *p,
switch (p->family) {
case AF_INET:
sin_dest.sin.sin_family = AF_INET;
-#ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
- sin_dest.sin.sin_len = sizeof(sin_dest);
- sin_gate.sin.sin_len = sizeof(sin_gate);
-#endif /* HAVE_STRUCT_SOCKADDR_IN_SIN_LEN */
sin_dest.sin.sin_addr = p->u.prefix4;
sin_gate.sin.sin_family = AF_INET;
+#ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
+ sin_dest.sin.sin_len = sizeof(struct sockaddr_in);
+ sin_gate.sin.sin_len = sizeof(struct sockaddr_in);
+#endif /* HAVE_STRUCT_SOCKADDR_SA_LEN */
break;
case AF_INET6:
sin_dest.sin6.sin6_family = AF_INET6;
-#ifdef SIN6_LEN
- sin_dest.sin6.sin6_len = sizeof(sin_dest);
-#endif /* SIN6_LEN */
sin_dest.sin6.sin6_addr = p->u.prefix6;
sin_gate.sin6.sin6_family = AF_INET6;
-#ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
- sin_gate.sin6.sin6_len = sizeof(sin_gate);
-#endif /* HAVE_STRUCT_SOCKADDR_IN_SIN_LEN */
+#ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
+ sin_dest.sin6.sin6_len = sizeof(struct sockaddr_in6);
+ sin_gate.sin6.sin6_len = sizeof(struct sockaddr_in6);
+#endif /* HAVE_STRUCT_SOCKADDR_SA_LEN */
break;
}
@@ -185,13 +134,16 @@ static int kernel_rtm(int cmd, const struct prefix *p,
smplsp = NULL;
gate = false;
- char gate_buf[INET_ADDRSTRLEN] = "NULL";
+ snprintf(gate_buf, sizeof(gate_buf), "NULL");
switch (nexthop->type) {
case NEXTHOP_TYPE_IPV4:
case NEXTHOP_TYPE_IPV4_IFINDEX:
sin_gate.sin.sin_addr = nexthop->gate.ipv4;
sin_gate.sin.sin_family = AF_INET;
+#ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
+ sin_gate.sin.sin_len = sizeof(struct sockaddr_in);
+#endif /* HAVE_STRUCT_SOCKADDR_SA_LEN */
ifindex = nexthop->ifindex;
gate = true;
break;
@@ -199,6 +151,9 @@ static int kernel_rtm(int cmd, const struct prefix *p,
case NEXTHOP_TYPE_IPV6_IFINDEX:
sin_gate.sin6.sin6_addr = nexthop->gate.ipv6;
sin_gate.sin6.sin6_family = AF_INET6;
+#ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
+ sin_gate.sin6.sin6_len = sizeof(struct sockaddr_in6);
+#endif /* HAVE_STRUCT_SOCKADDR_SA_LEN */
ifindex = nexthop->ifindex;
/* Under kame set interface index to link local address */
#ifdef KAME
@@ -227,6 +182,10 @@ static int kernel_rtm(int cmd, const struct prefix *p,
struct in_addr loopback;
loopback.s_addr = htonl(INADDR_LOOPBACK);
sin_gate.sin.sin_addr = loopback;
+#ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
+ sin_gate.sin.sin_len =
+ sizeof(struct sockaddr_in);
+#endif /* HAVE_STRUCT_SOCKADDR_SA_LEN */
gate = true;
}
break;
@@ -239,26 +198,26 @@ static int kernel_rtm(int cmd, const struct prefix *p,
case AF_INET:
masklen2ip(p->prefixlen, &sin_mask.sin.sin_addr);
sin_mask.sin.sin_family = AF_INET;
-#ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
- sin_mask.sin.sin_len = sin_masklen(
- sin_mask.sin.sin_addr);
-#endif /* HAVE_STRUCT_SOCKADDR_IN_SIN_LEN */
+#ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
+ sin_mask.sin.sin_len = sizeof(struct sockaddr_in);
+#endif /* HAVE_STRUCT_SOCKADDR_SA_LEN */
break;
case AF_INET6:
masklen2ip6(p->prefixlen, &sin_mask.sin6.sin6_addr);
sin_mask.sin6.sin6_family = AF_INET6;
-#ifdef SIN6_LEN
- sin_mask.sin6.sin6_len = sin6_masklen(
- sin_mask.sin6.sin6_addr);
-#endif /* SIN6_LEN */
+#ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
+ sin_mask.sin6.sin6_len = sizeof(struct sockaddr_in6);
+#endif /* HAVE_STRUCT_SOCKADDR_SA_LEN */
break;
}
#ifdef __OpenBSD__
- if (nexthop->nh_label
- && !kernel_rtm_add_labels(nexthop->nh_label, &smpls))
- continue;
- smplsp = (union sockunion *)&smpls;
+ if (nexthop->nh_label) {
+ if (kernel_rtm_add_labels(nexthop->nh_label,
+ &smpls) != 0)
+ continue;
+ smplsp = (union sockunion *)&smpls;
+ }
#endif
error = rtm_write(cmd, &sin_dest, &sin_mask,
gate ? &sin_gate : NULL, smplsp,
@@ -266,13 +225,29 @@ static int kernel_rtm(int cmd, const struct prefix *p,
if (IS_ZEBRA_DEBUG_KERNEL) {
if (!gate) {
- zlog_debug("%s: %s: attention! gate not found for re",
- __func__, prefix_buf);
- } else
- inet_ntop(p->family == AFI_IP ? AF_INET
- : AF_INET6,
- &sin_gate.sin.sin_addr,
- gate_buf, INET_ADDRSTRLEN);
+ zlog_debug(
+ "%s: %s: attention! gate not found for re",
+ __func__, prefix_buf);
+ } else {
+ switch (p->family) {
+ case AFI_IP:
+ inet_ntop(AF_INET,
+ &sin_gate.sin.sin_addr,
+ gate_buf, sizeof(gate_buf));
+ break;
+
+ case AFI_IP6:
+ inet_ntop(AF_INET6,
+ &sin_gate.sin6.sin6_addr,
+ gate_buf, sizeof(gate_buf));
+ break;
+
+ default:
+ snprintf(gate_buf, sizeof(gate_buf),
+ "(invalid-af)");
+ break;
+ }
+ }
}
switch (error) {
/* We only flag nexthops as being in FIB if
@@ -301,12 +276,11 @@ static int kernel_rtm(int cmd, const struct prefix *p,
/* Note any unexpected status returns */
default:
- flog_err(EC_LIB_SYSTEM_CALL,
- "%s: %s: rtm_write() unexpectedly returned %d for command %s",
- __func__,
- prefix2str(p, prefix_buf,
- sizeof(prefix_buf)),
- error, lookup_msg(rtm_type_str, cmd, NULL));
+ flog_err(
+ EC_LIB_SYSTEM_CALL,
+ "%s: %s: rtm_write() unexpectedly returned %d for command %s",
+ __func__, prefix_buf, error,
+ lookup_msg(rtm_type_str, cmd, NULL));
break;
}
} /* for (ALL_NEXTHOPS(...))*/
@@ -314,9 +288,9 @@ static int kernel_rtm(int cmd, const struct prefix *p,
/* If there was no useful nexthop, then complain. */
if (nexthop_num == 0) {
if (IS_ZEBRA_DEBUG_KERNEL)
- zlog_debug("%s: No useful nexthops were found in RIB prefix %s",
- __func__, prefix2str(p, prefix_buf,
- sizeof(prefix_buf)));
+ zlog_debug(
+ "%s: No useful nexthops were found in RIB prefix %s",
+ __func__, prefix_buf);
return 1;
}
@@ -333,8 +307,7 @@ enum zebra_dplane_result kernel_route_update(struct zebra_dplane_ctx *ctx)
if (dplane_ctx_get_src(ctx) != NULL) {
zlog_err("route add: IPv6 sourcedest routes unsupported!");
- res = ZEBRA_DPLANE_REQUEST_FAILURE;
- goto done;
+ return ZEBRA_DPLANE_REQUEST_FAILURE;
}
frr_elevate_privs(&zserv_privs) {
@@ -366,8 +339,6 @@ enum zebra_dplane_result kernel_route_update(struct zebra_dplane_ctx *ctx)
}
} /* Elevated privs */
-done:
-
return res;
}