diff options
authorGleb Smirnoff <glebius@FreeBSD.org>2024-02-20 18:31:05 +0000
committerGleb Smirnoff <glebius@FreeBSD.org>2024-02-25 18:03:17 +0000
commit1e74fc950419f2b2482d313fc664cc03aa46f13c (patch)
parentff9794844f86d6c30b82cc29ec3f175f449b2e94 (diff)
arp: fix arp -s/-S
When setting a permanent ARP entry, the route(4) would use rtm->rtm_rmx.rmx_expire == 0 as a flag for installing a static entry, but netlink(4) is looking for explicit NTF_STICKY flag in the request. The arp(8) utility was adopted to use netlink(4) by default, but it has lots of route-era guts internally. Specifically there is global variable 'opts' that shares configuration for both protocols, and it is still initialized with route(4) specific RTF_xxx flags. In set_nl() these flags are translated to netlink(4) parameters. However, RTF_STATIC is a flag that is never set by default, so attempt to use it as a proxy flag manifesting -s/-S results in losing it. Use zero opts.expire_time as a manifest of -s/-S operation. This is a minimal fix. A better one would be to fully get rid of route(4) legacy. The change also corrects the logic to set NUD_PERMANENT flag for consistency. This flag is ignored by our kernel (now). Reviewed by: melifaro, tuexen, emaste PR: 277063 Fixes: 6ad73dbf65048b0950a1ba6ff25607f6708c8954 Differential Revision: https://reviews.freebsd.org/D43983 (cherry picked from commit 6a3e87e1306d5058d63f7552a25ed6376422f658)
1 files changed, 3 insertions, 5 deletions
diff --git a/usr.sbin/arp/arp_netlink.c b/usr.sbin/arp/arp_netlink.c
index d78f380af04b..8644f3722aed 100644
--- a/usr.sbin/arp/arp_netlink.c
+++ b/usr.sbin/arp/arp_netlink.c
@@ -390,9 +390,6 @@ set_nl(uint32_t ifindex, struct sockaddr_in *dst, struct sockaddr_dl *sdl, char
return (0);
- if (opts.expire_time != 0)
- opts.flags &= ~RTF_STATIC;
snl_init_writer(&ss, &nw);
struct nlmsghdr *hdr = snl_create_msg_request(&nw, RTM_NEWNEIGH);
hdr->nlmsg_flags |= NLM_F_CREATE | NLM_F_REPLACE;
@@ -402,11 +399,12 @@ set_nl(uint32_t ifindex, struct sockaddr_in *dst, struct sockaddr_dl *sdl, char
ndmsg->ndm_family = AF_INET;
ndmsg->ndm_ifindex = ifindex;
- ndmsg->ndm_state = (opts.flags & RTF_STATIC) ? NUD_PERMANENT : NUD_NONE;
+ ndmsg->ndm_state = (opts.expire_time == 0) ? \
if (opts.flags & RTF_ANNOUNCE)
nl_flags |= NTF_PROXY;
- if (opts.flags & RTF_STATIC)
+ if (opts.expire_time == 0)
nl_flags |= NTF_STICKY;
ndmsg->ndm_flags = nl_flags;