diff options
author | Gleb Smirnoff <glebius@FreeBSD.org> | 2024-02-20 18:31:05 +0000 |
---|---|---|
committer | Gleb Smirnoff <glebius@FreeBSD.org> | 2024-02-20 18:31:05 +0000 |
commit | 6a3e87e1306d5058d63f7552a25ed6376422f658 (patch) | |
tree | 90c248c145e83f7ec99955a7333c2e36be875924 | |
parent | 9dd5023e955dac6bf1d4372d1b611a85f8b6f508 (diff) | |
download | src-6a3e87e1306d5058d63f7552a25ed6376422f658.tar.gz src-6a3e87e1306d5058d63f7552a25ed6376422f658.zip |
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
-rw-r--r-- | usr.sbin/arp/arp_netlink.c | 8 |
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) ? \ + NUD_PERMANENT : NUD_NONE; 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; } |