mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-08-14 14:17:20 +00:00
zebra: Refactor kernel_rtm to be a bit smarter about how it handles options
The ADD/DELETE messages are the only ones we support, so leave early from the function, in other words don't check it every nexthop loop. Additionally nexthops only care about non recursive active flags. Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
This commit is contained in:
parent
08ea27d112
commit
86afd5292f
@ -135,6 +135,19 @@ static int kernel_rtm(int cmd, const struct prefix *p,
|
|||||||
if (IS_ZEBRA_DEBUG_RIB)
|
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
|
||||||
|
* in time.
|
||||||
|
*/
|
||||||
|
if (cmd != RTM_ADD && cmd != RTM_DELETE) {
|
||||||
|
if (IS_ZEBRA_DEBUG_KERNEL)
|
||||||
|
zlog_debug("%s: %s odd command %s for flags %d",
|
||||||
|
__func__, prefix_buf,
|
||||||
|
lookup_msg(rtm_type_str, cmd, NULL),
|
||||||
|
nexthop->flags);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
memset(&sin_dest, 0, sizeof(sin_dest));
|
memset(&sin_dest, 0, sizeof(sin_dest));
|
||||||
memset(&sin_gate, 0, sizeof(sin_gate));
|
memset(&sin_gate, 0, sizeof(sin_gate));
|
||||||
memset(&sin_mask, 0, sizeof(sin_mask));
|
memset(&sin_mask, 0, sizeof(sin_mask));
|
||||||
@ -164,19 +177,16 @@ static int kernel_rtm(int cmd, const struct prefix *p,
|
|||||||
|
|
||||||
/* Make gateway. */
|
/* Make gateway. */
|
||||||
for (ALL_NEXTHOPS_PTR(ng, nexthop)) {
|
for (ALL_NEXTHOPS_PTR(ng, nexthop)) {
|
||||||
if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_RECURSIVE))
|
/*
|
||||||
|
* We only want to use the actual good nexthops
|
||||||
|
*/
|
||||||
|
if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_RECURSIVE) ||
|
||||||
|
!CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
gate = 0;
|
gate = 0;
|
||||||
char gate_buf[INET_ADDRSTRLEN] = "NULL";
|
char gate_buf[INET_ADDRSTRLEN] = "NULL";
|
||||||
|
|
||||||
/*
|
|
||||||
* XXX We need to refrain from kernel operations in some cases,
|
|
||||||
* but this if statement seems overly cautious - what about
|
|
||||||
* other than ADD and DELETE?
|
|
||||||
*/
|
|
||||||
if ((cmd == RTM_ADD && NEXTHOP_IS_ACTIVE(nexthop->flags))
|
|
||||||
|| (cmd == RTM_DELETE)) {
|
|
||||||
switch (nexthop->type) {
|
switch (nexthop->type) {
|
||||||
case NEXTHOP_TYPE_IPV4:
|
case NEXTHOP_TYPE_IPV4:
|
||||||
case NEXTHOP_TYPE_IPV4_IFINDEX:
|
case NEXTHOP_TYPE_IPV4_IFINDEX:
|
||||||
@ -199,8 +209,7 @@ static int kernel_rtm(int cmd, const struct prefix *p,
|
|||||||
(a).s6_addr[3] = (i)&0xff; \
|
(a).s6_addr[3] = (i)&0xff; \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
if (IN6_IS_ADDR_LINKLOCAL(
|
if (IN6_IS_ADDR_LINKLOCAL(&sin_gate.sin6.sin6_addr))
|
||||||
&sin_gate.sin6.sin6_addr))
|
|
||||||
SET_IN6_LINKLOCAL_IFINDEX(
|
SET_IN6_LINKLOCAL_IFINDEX(
|
||||||
sin_gate.sin6.sin6_addr,
|
sin_gate.sin6.sin6_addr,
|
||||||
ifindex);
|
ifindex);
|
||||||
@ -216,8 +225,7 @@ static int kernel_rtm(int cmd, const struct prefix *p,
|
|||||||
switch (p->family) {
|
switch (p->family) {
|
||||||
case AFI_IP: {
|
case AFI_IP: {
|
||||||
struct in_addr loopback;
|
struct in_addr loopback;
|
||||||
loopback.s_addr =
|
loopback.s_addr = htonl(INADDR_LOOPBACK);
|
||||||
htonl(INADDR_LOOPBACK);
|
|
||||||
sin_gate.sin.sin_addr = loopback;
|
sin_gate.sin.sin_addr = loopback;
|
||||||
gate = 1;
|
gate = 1;
|
||||||
}
|
}
|
||||||
@ -260,8 +268,7 @@ static int kernel_rtm(int cmd, const struct prefix *p,
|
|||||||
|
|
||||||
#ifdef __OpenBSD__
|
#ifdef __OpenBSD__
|
||||||
if (nexthop->nh_label
|
if (nexthop->nh_label
|
||||||
&& !kernel_rtm_add_labels(nexthop->nh_label,
|
&& !kernel_rtm_add_labels(nexthop->nh_label, &smpls))
|
||||||
&smpls))
|
|
||||||
continue;
|
continue;
|
||||||
smplsp = (union sockunion *)&smpls;
|
smplsp = (union sockunion *)&smpls;
|
||||||
#endif
|
#endif
|
||||||
@ -271,8 +278,7 @@ static int kernel_rtm(int cmd, const struct prefix *p,
|
|||||||
|
|
||||||
if (IS_ZEBRA_DEBUG_KERNEL) {
|
if (IS_ZEBRA_DEBUG_KERNEL) {
|
||||||
if (!gate) {
|
if (!gate) {
|
||||||
zlog_debug(
|
zlog_debug("%s: %s: attention! gate not found for re",
|
||||||
"%s: %s: attention! gate not found for re",
|
|
||||||
__func__, prefix_buf);
|
__func__, prefix_buf);
|
||||||
} else
|
} else
|
||||||
inet_ntop(p->family == AFI_IP ? AF_INET
|
inet_ntop(p->family == AFI_IP ? AF_INET
|
||||||
@ -286,8 +292,7 @@ static int kernel_rtm(int cmd, const struct prefix *p,
|
|||||||
case ZEBRA_ERR_NOERROR:
|
case ZEBRA_ERR_NOERROR:
|
||||||
nexthop_num++;
|
nexthop_num++;
|
||||||
if (IS_ZEBRA_DEBUG_KERNEL)
|
if (IS_ZEBRA_DEBUG_KERNEL)
|
||||||
zlog_debug(
|
zlog_debug("%s: %s: successfully did NH %s",
|
||||||
"%s: %s: successfully did NH %s",
|
|
||||||
__func__, prefix_buf, gate_buf);
|
__func__, prefix_buf, gate_buf);
|
||||||
if (cmd == RTM_ADD)
|
if (cmd == RTM_ADD)
|
||||||
SET_FLAG(nexthop->flags, NEXTHOP_FLAG_FIB);
|
SET_FLAG(nexthop->flags, NEXTHOP_FLAG_FIB);
|
||||||
@ -296,35 +301,26 @@ static int kernel_rtm(int cmd, const struct prefix *p,
|
|||||||
/* The only valid case for this error is
|
/* The only valid case for this error is
|
||||||
* kernel's failure to install a multipath
|
* kernel's failure to install a multipath
|
||||||
* route, which is common for FreeBSD. This
|
* route, which is common for FreeBSD. This
|
||||||
* should be
|
* should be ignored silently, but logged as an error
|
||||||
* ignored silently, but logged as an error
|
|
||||||
* otherwise.
|
* otherwise.
|
||||||
*/
|
*/
|
||||||
case ZEBRA_ERR_RTEXIST:
|
case ZEBRA_ERR_RTEXIST:
|
||||||
if (cmd != RTM_ADD)
|
if (cmd != RTM_ADD)
|
||||||
flog_err(
|
flog_err(EC_LIB_SYSTEM_CALL,
|
||||||
EC_LIB_SYSTEM_CALL,
|
|
||||||
"%s: rtm_write() returned %d for command %d",
|
"%s: rtm_write() returned %d for command %d",
|
||||||
__func__, error, cmd);
|
__func__, error, cmd);
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
/* Note any unexpected status returns */
|
/* Note any unexpected status returns */
|
||||||
default:
|
default:
|
||||||
flog_err(
|
flog_err(EC_LIB_SYSTEM_CALL,
|
||||||
EC_LIB_SYSTEM_CALL,
|
|
||||||
"%s: %s: rtm_write() unexpectedly returned %d for command %s",
|
"%s: %s: rtm_write() unexpectedly returned %d for command %s",
|
||||||
__func__,
|
__func__,
|
||||||
prefix2str(p, prefix_buf,
|
prefix2str(p, prefix_buf,
|
||||||
sizeof(prefix_buf)),
|
sizeof(prefix_buf)),
|
||||||
error,
|
error, lookup_msg(rtm_type_str, cmd, NULL));
|
||||||
lookup_msg(rtm_type_str, cmd, NULL));
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} /* if (cmd and flags make sense) */
|
|
||||||
else if (IS_ZEBRA_DEBUG_KERNEL)
|
|
||||||
zlog_debug("%s: odd command %s for flags %d", __func__,
|
|
||||||
lookup_msg(rtm_type_str, cmd, NULL),
|
|
||||||
nexthop->flags);
|
|
||||||
} /* for (ALL_NEXTHOPS(...))*/
|
} /* for (ALL_NEXTHOPS(...))*/
|
||||||
|
|
||||||
/* If there was no useful nexthop, then complain. */
|
/* If there was no useful nexthop, then complain. */
|
||||||
|
Loading…
Reference in New Issue
Block a user