#if defined(HANDLE_NETLINK_FUZZING)
#include <stdio.h>
#include <string.h>
+#include "libfrr.h"
#endif /* HANDLE_NETLINK_FUZZING */
#ifdef HAVE_NETLINK
{RTM_NEWRULE, "RTM_NEWRULE"},
{RTM_DELRULE, "RTM_DELRULE"},
{RTM_GETRULE, "RTM_GETRULE"},
+ {RTM_NEWNEXTHOP, "RTM_NEWNEXTHOP"},
+ {RTM_DELNEXTHOP, "RTM_DELNEXTHOP"},
+ {RTM_GETNEXTHOP, "RTM_GETNEXTHOP"},
{0}};
static const struct message rtproto_str[] = {
}
/* Try force option (linux >= 2.6.14) and fall back to normal set */
- frr_elevate_privs(&zserv_privs) {
+ frr_with_privs(&zserv_privs) {
ret = setsockopt(nl->sock, SOL_SOCKET, SO_RCVBUFFORCE,
&nl_rcvbufsize,
sizeof(nl_rcvbufsize));
int sock;
int namelen;
- frr_elevate_privs(&zserv_privs) {
+ frr_with_privs(&zserv_privs) {
sock = ns_socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE, ns_id);
if (sock < 0) {
zlog_err("Can't open %s socket: %s", nl->name,
return netlink_neigh_change(h, ns_id);
case RTM_DELNEIGH:
return netlink_neigh_change(h, ns_id);
+ case RTM_GETNEIGH:
+ /*
+ * Kernel in some situations when it expects
+ * user space to resolve arp entries, we will
+ * receive this notification. As we don't
+ * need this notification and as that
+ * we don't want to spam the log file with
+ * below messages, just ignore.
+ */
+ if (IS_ZEBRA_DEBUG_KERNEL)
+ zlog_debug("Received RTM_GETNEIGH, ignoring");
+ break;
case RTM_NEWRULE:
return netlink_rule_change(h, ns_id, startup);
case RTM_DELRULE:
return netlink_rule_change(h, ns_id, startup);
+ case RTM_NEWNEXTHOP:
+ return netlink_nexthop_change(h, ns_id, startup);
+ case RTM_DELNEXTHOP:
+ return netlink_nexthop_change(h, ns_id, startup);
default:
/*
* If we have received this message then
FILE *f;
snprintf(fname, MAXPATHLEN, "%s/%s_%u", frr_vtydir, "netlink", counter);
- frr_elevate_privs(&zserv_privs) {
+ frr_with_privs(&zserv_privs) {
f = fopen(fname, "w");
}
if (f) {
FILE *f;
long file_bytes = -1;
- frr_elevate_privs(&zserv_privs) {
+ frr_with_privs(&zserv_privs) {
f = fopen(fname, "r");
}
if (f) {
struct rtattr *nest = NLMSG_TAIL(n);
addattr_l(n, maxlen, type, NULL, 0);
+ nest->rta_type |= NLA_F_NESTED;
return nest;
}
struct rtattr *nest = RTA_TAIL(rta);
rta_addattr_l(rta, maxlen, type, NULL, 0);
+ nest->rta_type |= NLA_F_NESTED;
return nest;
}
msg_type,
err->msg.nlmsg_seq,
err->msg.nlmsg_pid);
- } else
- flog_err(
- EC_ZEBRA_UNEXPECTED_MESSAGE,
- "%s error: %s, type=%s(%u), seq=%u, pid=%u",
- nl->name,
- safe_strerror(-errnum),
- nl_msg_type_to_str(msg_type),
- msg_type, err->msg.nlmsg_seq,
- err->msg.nlmsg_pid);
+ } else {
+ if ((msg_type != RTM_GETNEXTHOP)
+ || !startup)
+ flog_err(
+ EC_ZEBRA_UNEXPECTED_MESSAGE,
+ "%s error: %s, type=%s(%u), seq=%u, pid=%u",
+ nl->name,
+ safe_strerror(-errnum),
+ nl_msg_type_to_str(
+ msg_type),
+ msg_type,
+ err->msg.nlmsg_seq,
+ err->msg.nlmsg_pid);
+ }
return -1;
}
n->nlmsg_flags);
/* Send message to netlink interface. */
- frr_elevate_privs(&zserv_privs) {
+ frr_with_privs(&zserv_privs) {
status = sendmsg(nl->sock, &msg, 0);
save_errno = errno;
}
snl.nl_family = AF_NETLINK;
/* Raise capabilities and send message, then lower capabilities. */
- frr_elevate_privs(&zserv_privs) {
+ frr_with_privs(&zserv_privs) {
ret = sendto(nl->sock, (void *)n, n->nlmsg_len, 0,
(struct sockaddr *)&snl, sizeof snl);
}
netlink_socket (). */
void kernel_init(struct zebra_ns *zns)
{
- unsigned long groups;
+ uint32_t groups;
#if defined SOL_NETLINK
int one, ret;
#endif
RTMGRP_IPV6_IFADDR |
RTMGRP_IPV4_MROUTE |
RTMGRP_NEIGH |
- (1 << (RTNLGRP_IPV4_RULE - 1)) |
- (1 << (RTNLGRP_IPV6_RULE - 1));
+ ((uint32_t) 1 << (RTNLGRP_IPV4_RULE - 1)) |
+ ((uint32_t) 1 << (RTNLGRP_IPV6_RULE - 1)) |
+ ((uint32_t) 1 << (RTNLGRP_NEXTHOP - 1));
snprintf(zns->netlink.name, sizeof(zns->netlink.name),
"netlink-listen (NS %u)", zns->ns_id);