diff options
Diffstat (limited to 'sbin/route')
| -rw-r--r-- | sbin/route/Makefile | 2 | ||||
| -rw-r--r-- | sbin/route/Makefile.depend | 1 | ||||
| -rw-r--r-- | sbin/route/keywords | 1 | ||||
| -rw-r--r-- | sbin/route/route.8 | 18 | ||||
| -rw-r--r-- | sbin/route/route.c | 53 | ||||
| -rw-r--r-- | sbin/route/route_netlink.c | 40 | ||||
| -rw-r--r-- | sbin/route/tests/Makefile | 9 | ||||
| -rw-r--r-- | sbin/route/tests/Makefile.depend | 10 | ||||
| -rw-r--r-- | sbin/route/tests/basic.sh | 58 |
9 files changed, 127 insertions, 65 deletions
diff --git a/sbin/route/Makefile b/sbin/route/Makefile index 7685a2fecd64..43b9c0d8d821 100644 --- a/sbin/route/Makefile +++ b/sbin/route/Makefile @@ -1,5 +1,3 @@ -# @(#)Makefile 8.1 (Berkeley) 6/5/93 - .include <src.opts.mk> PACKAGE=runtime diff --git a/sbin/route/Makefile.depend b/sbin/route/Makefile.depend index 344a5d0e9310..672ec75190c6 100644 --- a/sbin/route/Makefile.depend +++ b/sbin/route/Makefile.depend @@ -7,6 +7,7 @@ DIRDEPS = \ lib/${CSU_DIR} \ lib/libc \ lib/libcompiler_rt \ + lib/libjail \ .include <dirdeps.mk> diff --git a/sbin/route/keywords b/sbin/route/keywords index 496fb8b95e2e..cbd8799ffb6b 100644 --- a/sbin/route/keywords +++ b/sbin/route/keywords @@ -1,4 +1,3 @@ -# @(#)keywords 8.2 (Berkeley) 3/19/94 4 6 diff --git a/sbin/route/route.8 b/sbin/route/route.8 index 4eccd511f0cc..572781ef59c8 100644 --- a/sbin/route/route.8 +++ b/sbin/route/route.8 @@ -25,9 +25,7 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.\" @(#)route.8 8.3 (Berkeley) 3/19/94 -.\" -.Dd June 16, 2023 +.Dd November 12, 2024 .Dt ROUTE 8 .Os .Sh NAME @@ -554,17 +552,3 @@ The .Nm utility appeared in .Bx 4.2 . -.Sh BUGS -The first paragraph may have slightly exaggerated -.Xr routed 8 Ns 's -abilities. -.Pp -Currently, routes with the -.Dv RTF_BLACKHOLE -flag set need to have the gateway set to an instance of the -.Xr lo 4 -driver, using the -.Fl iface -option, for the flag to have any effect; unless IP fast forwarding -is enabled, in which case the meaning of the flag will always -be honored. diff --git a/sbin/route/route.c b/sbin/route/route.c index 3913bdc9e6af..f37d23d25c2c 100644 --- a/sbin/route/route.c +++ b/sbin/route/route.c @@ -29,19 +29,6 @@ * SUCH DAMAGE. */ -#ifndef lint -static const char copyright[] = -"@(#) Copyright (c) 1983, 1989, 1991, 1993\n\ - The Regents of the University of California. All rights reserved.\n"; -#endif /* not lint */ - -#ifndef lint -#if 0 -static char sccsid[] = "@(#)route.c 8.6 (Berkeley) 4/28/95"; -#endif -#endif /* not lint */ - -#include <sys/cdefs.h> #include <sys/param.h> #include <sys/file.h> #include <sys/socket.h> @@ -107,8 +94,8 @@ static u_long rtm_inits; static uid_t uid; static int defaultfib; static int numfibs; -static char domain[MAXHOSTNAMELEN + 1]; -static bool domain_initialized; +static char domain_storage[MAXHOSTNAMELEN + 1]; +static const char *domain; static char rt_line[NI_MAXHOST]; static char net_line[MAXHOSTNAMELEN + 1]; @@ -594,14 +581,16 @@ routename(struct sockaddr *sa) const char *cp; int n; - if (!domain_initialized) { - domain_initialized = true; - if (gethostname(domain, MAXHOSTNAMELEN) == 0 && - (cp = strchr(domain, '.'))) { - domain[MAXHOSTNAMELEN] = '\0'; - (void)strcpy(domain, cp + 1); - } else - domain[0] = '\0'; + if (domain == NULL) { + if (gethostname(domain_storage, + sizeof(domain_storage) - 1) == 0 && + (cp = strchr(domain_storage, '.')) != NULL) { + domain_storage[sizeof(domain_storage) - 1] = '\0'; + domain = cp + 1; + } else { + domain_storage[0] = '\0'; + domain = domain_storage; + } } /* If the address is zero-filled, use "default". */ @@ -1342,6 +1331,9 @@ getaddr(int idx, char *str, int nrflags) q = strchr(str,'/'); if (q != NULL && idx == RTAX_DST) { /* A.B.C.D/NUM */ + struct sockaddr_in *mask; + uint32_t mask_bits; + *q = '\0'; if (inet_aton(str, &sin->sin_addr) == 0) errx(EX_NOHOST, "bad address: %s", str); @@ -1351,6 +1343,20 @@ getaddr(int idx, char *str, int nrflags) errx(EX_NOHOST, "bad mask length: %s", q + 1); inet_makemask((struct sockaddr_in *)&so[RTAX_NETMASK],masklen); + + /* + * Check for bogus destination such as "10/8"; heuristic is + * that there are bits set in the host part, and no dot + * is present. + */ + mask = ((struct sockaddr_in *) &so[RTAX_NETMASK]); + mask_bits = ntohl(mask->sin_addr.s_addr); + if ((ntohl(sin->sin_addr.s_addr) & ~mask_bits) != 0 && + strchr(str, '.') == NULL) + errx(EX_NOHOST, + "malformed address, bits set after mask;" + " %s means %s", + str, inet_ntoa(sin->sin_addr)); return (0); } if (inet_aton(str, &sin->sin_addr) != 0) @@ -1657,6 +1663,7 @@ static const char *const msgtypes[] = { "RTM_DELMADDR: multicast group membership removed from iface", "RTM_IFANNOUNCE: interface arrival/departure", "RTM_IEEE80211: IEEE 802.11 wireless event", + "RTM_IPFWLOG: IPFW log", }; static const char metricnames[] = diff --git a/sbin/route/route_netlink.c b/sbin/route/route_netlink.c index 0dbd90151e10..ba22a2ec1e22 100644 --- a/sbin/route/route_netlink.c +++ b/sbin/route/route_netlink.c @@ -266,27 +266,32 @@ rtmsg_nl_int(struct nl_helper *h, int cmd, int rtm_flags, int fib, int rtm_addrs if (rt_metrics->rmx_weight > 0) snl_add_msg_attr_u32(&nw, NL_RTA_WEIGHT, rt_metrics->rmx_weight); - if (snl_finalize_msg(&nw) && snl_send_message(ss, hdr)) { + if ((hdr = snl_finalize_msg(&nw)) && snl_send_message(ss, hdr)) { struct snl_errmsg_data e = {}; hdr = snl_read_reply(ss, hdr->nlmsg_seq); if (nl_type == NL_RTM_GETROUTE) { - if (hdr->nlmsg_type == NL_RTM_NEWROUTE) + if (hdr->nlmsg_type == NL_RTM_NEWROUTE) { print_getmsg(h, hdr, dst); - else { - snl_parse_errmsg(ss, hdr, &e); - if (e.error == ESRCH) - warn("route has not been found"); - else - warn("message indicates error %d", e.error); + return (0); } - - return (0); } - if (snl_parse_errmsg(ss, hdr, &e)) + if (snl_parse_errmsg(ss, hdr, &e)) { + switch (e.error) { + case (ESRCH): + warnx("route has not been found"); + break; + default: + if (e.error == 0) + break; + warnc(e.error, "message indicates error"); + } + return (e.error); + } } + return (EINVAL); } @@ -314,7 +319,7 @@ get_ifdata(struct nl_helper *h, uint32_t ifindex, struct snl_parsed_link_simple struct ifinfomsg *ifmsg = snl_reserve_msg_object(&nw, struct ifinfomsg); if (ifmsg != NULL) ifmsg->ifi_index = ifindex; - if (!snl_finalize_msg(&nw) || !snl_send_message(ss, hdr)) + if (! (hdr = snl_finalize_msg(&nw)) || !snl_send_message(ss, hdr)) return; hdr = snl_read_reply(ss, hdr->nlmsg_seq); @@ -584,7 +589,7 @@ print_nlmsg_link(struct nl_helper *h, struct nlmsghdr *hdr, printf("iface#%u %s ", l.ifi_index, l.ifla_ifname); printf("admin %s ", (l.ifi_flags & IFF_UP) ? "UP" : "DOWN"); - if (l.ifla_operstate < NL_ARRAY_LEN(operstate)) + if (l.ifla_operstate < nitems(operstate)) printf("oper %s ", operstate[l.ifla_operstate]); if (l.ifla_mtu > 0) printf("mtu %u ", l.ifla_mtu); @@ -663,7 +668,7 @@ print_nlmsg_neigh(struct nl_helper *h, struct nlmsghdr *hdr, struct snl_parsed_link_simple link = {}; get_ifdata(h, attrs.nda_ifindex, &link); - for (unsigned int i = 0; i < NL_ARRAY_LEN(nudstate); i++) { + for (unsigned int i = 0; i < nitems(nudstate); i++) { if ((1 << i) & attrs.ndm_state) { printf("state %s ", nudstate[i]); break; @@ -733,6 +738,7 @@ print_nlmsg(struct nl_helper *h, struct nlmsghdr *hdr, struct snl_msg_info *cinf print_nlmsg_generic(h, hdr, cinfo); } + fflush(stdout); snl_clear_lb(&h->ss_cmd); } @@ -763,7 +769,7 @@ monitor_nl(int fib) socklen_t optlen = sizeof(optval); setsockopt(ss_event.fd, SOL_NETLINK, NETLINK_MSG_INFO, &optval, optlen); - for (unsigned int i = 0; i < NL_ARRAY_LEN(groups); i++) { + for (unsigned int i = 0; i < nitems(groups); i++) { int error; int optval = groups[i]; socklen_t optlen = sizeof(optval); @@ -817,7 +823,7 @@ flushroute_one(struct nl_helper *h, struct snl_parsed_route *r) snl_add_msg_attr_u32(&nw, RTA_TABLE, r->rta_table); snl_add_msg_attr_ip(&nw, RTA_DST, r->rta_dst); - if (!snl_finalize_msg(&nw) || !snl_send_message(ss, hdr)) + if (! (hdr = snl_finalize_msg(&nw)) || !snl_send_message(ss, hdr)) return (ENOMEM); if (!snl_read_reply_code(ss, hdr->nlmsg_seq, &e)) { @@ -864,7 +870,7 @@ flushroutes_fib_nl(int fib, int af) rtm->rtm_family = af; snl_add_msg_attr_u32(&nw, RTA_TABLE, fib); - if (!snl_finalize_msg(&nw) || !snl_send_message(&ss, hdr)) { + if (! (hdr = snl_finalize_msg(&nw)) || !snl_send_message(&ss, hdr)) { snl_free(&ss); return (EINVAL); } diff --git a/sbin/route/tests/Makefile b/sbin/route/tests/Makefile index 1ae964693ff4..9d634d7c48b8 100644 --- a/sbin/route/tests/Makefile +++ b/sbin/route/tests/Makefile @@ -1,10 +1,9 @@ - PACKAGE= tests -ATF_TESTS_SH+= \ - basic +ATF_TESTS_SH+= basic +# Tests reuse jail names and so cannot run in parallel. +TEST_METADATA.basic+= is_exclusive=true -${PACKAGE}FILES+= \ - utils.subr +${PACKAGE}FILES+= utils.subr .include <bsd.test.mk> diff --git a/sbin/route/tests/Makefile.depend b/sbin/route/tests/Makefile.depend new file mode 100644 index 000000000000..11aba52f82cf --- /dev/null +++ b/sbin/route/tests/Makefile.depend @@ -0,0 +1,10 @@ +# Autogenerated - do NOT edit! + +DIRDEPS = \ + + +.include <dirdeps.mk> + +.if ${DEP_RELDIR} == ${_DEP_RELDIR} +# local dependencies - needed for -jN in clean tree +.endif diff --git a/sbin/route/tests/basic.sh b/sbin/route/tests/basic.sh index bb432daa0793..2e2ab9dba97f 100644 --- a/sbin/route/tests/basic.sh +++ b/sbin/route/tests/basic.sh @@ -117,8 +117,66 @@ basic_v6_cleanup() vnet_cleanup } +atf_test_case "interface_route_v4" "cleanup" +interface_route_v4_head() +{ + atf_set descr 'add interface route for v4' + atf_set require.user root + atf_set require.progs jail jq +} + +interface_route_v4_body() +{ + epair=$(vnet_mkepair) + ifconfig ${epair}a up + vnet_mkjail alcatraz ${epair}b + + # add interface route + jexec alcatraz route add "192.0.2.1" -iface ${epair}b + gateway=$(check_route "alcatraz" "192.0.2.1") + + if [ -z "${gateway}" ]; then + atf_fail "Failed to add interface route." + fi +} + +interface_route_v4_cleanup() +{ + vnet_cleanup +} + +atf_test_case "interface_route_v6" "cleanup" +interface_route_v6_head() +{ + atf_set descr 'add interface route for v6' + atf_set require.user root + atf_set require.progs jail jq +} + +interface_route_v6_body() +{ + epair=$(vnet_mkepair) + ifconfig ${epair}a up + vnet_mkjail alcatraz ${epair}b + + # add interface route + jexec alcatraz route add -6 "2001:db8:cc4b::1" -iface ${epair}b + gateway=$(check_route "alcatraz" "2001:db8:cc4b::1") + + if [ -z "${gateway}" ]; then + atf_fail "Failed to add interface route." + fi +} + +interface_route_v6_cleanup() +{ + vnet_cleanup +} + atf_init_test_cases() { atf_add_test_case "basic_v4" atf_add_test_case "basic_v6" + atf_add_test_case "interface_route_v4" + atf_add_test_case "interface_route_v6" } |
