From nobody Thu Apr 30 22:07:51 2026 X-Original-To: dev-commits-src-all@mlmmj.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mlmmj.nyi.freebsd.org (Postfix) with ESMTP id 4g67Zw1rBBz6cMbF for ; Thu, 30 Apr 2026 22:07:52 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "R13" (not verified)) by mx1.freebsd.org (Postfix) with ESMTPS id 4g67Zv5s3Vz3kKS for ; Thu, 30 Apr 2026 22:07:51 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1777586871; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=EiKi8xwvE2iD/e6JxoPUsAhRf8/vmCVjfWZuuRshrVA=; b=dA94HRPt9ggAd+er4OC22nByzdjH38kCsnQKAuHS4Dvu9yWSmz2KeL1T+Hw6ebrxQm6427 S/B/SyFwb+EiHTaYCgDjDxAd4AvLKe4ExzAenbwUzI1jSKfttOtgi5imG7hLl1ZgqwXbzz Yu2q/6lEkKPOSFW5V6Ho+bAON5iIFPn0O/pOWQj/fUrm2oRDYbbsUiWh6DNpBAjhyXrO29 uCmGeQVaRJSIwVfdd7YTUSnyoCly91gVt1FqfNRqQKa/pBiaUDPAlMWVEvTyAw3wr263yo TDvmjFFzTY1PwGzwPwwFu+a9R9/uQCI1GT0s87xCQ1MSxi/irZPs3SiAnixv/w== ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1777586871; a=rsa-sha256; cv=none; b=BfXdLkgwhKo0cPl4ISrIAatfQkvEFr6wHwaV3qavwrSernbbAKG97aoyzqFR9/4KWF81L3 /9nd2odjoawDnkPg/0UvoDl0hBcwRKqSgXTLEHYeX4Q9Sp4Fbt+0vO8qPdQrQcIF5Lv7ie Qwe6xKgiBOfe7cD5DlyVFdOGMUcqkujI5hpbN6IQr8aliFiWFU/A/wzd50dsNWLE4q+9/c KmpCCtTgC2PJUpse9aZRpTPGnWC7ywBfcjTJF83IHEq9Rp3aUxot3HjTerH+Su6gNXdsT8 qvbfnIH1Jq2mw4k7HHLNQV/bs88dm3m3LgDhZhpEXNJDj8L4facb3sFNHwEz1Q== ARC-Authentication-Results: i=1; mx1.freebsd.org; none ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1777586871; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=EiKi8xwvE2iD/e6JxoPUsAhRf8/vmCVjfWZuuRshrVA=; b=oSJ/T0cag/4kut6X9DibJUmhexy9evOK/sysijmglgQnJR9vhaeZnG/6ILz5PpWfi8Si4W SEdgVivtqiSF8g+Q/dAy1tXbeFsUHRFtKob9Oo/ZmuO4RgpOVucb100ulufpdiLAboMrzo +NoyHGNleHnR/glvbhljXPui9isTwLiAmRr5aRNzvN9ywon1gPcicm/20jwtQvW63T26qY MqzBaeVvo1sPXI+JS8eb6EUOrKcn/6uiRtsemJSuE+av6qs8MRtu3L8KfOeeq6GMI+77Gm 4khdeyLLmoiGnuMMA0j1R6bsCplYr7/6GJH7NEC1UwZavrheNRnVGL1uCDOi1w== Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) by mxrelay.nyi.freebsd.org (Postfix) with ESMTP id 4g67Zv5SH0zW0g for ; Thu, 30 Apr 2026 22:07:51 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from git (uid 1279) (envelope-from git@FreeBSD.org) id 1d184 by gitrepo.freebsd.org (DragonFly Mail Agent v0.13+ on gitrepo.freebsd.org); Thu, 30 Apr 2026 22:07:51 +0000 To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org From: Pouria Mousavizadeh Tehrani Subject: git: 23b8d16c6641 - main - tests/netlink: Add nexthop group tests for multipath List-Id: Commit messages for all branches of the src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-all List-Help: List-Post: List-Subscribe: List-Unsubscribe: X-BeenThere: dev-commits-src-all@freebsd.org Sender: owner-dev-commits-src-all@FreeBSD.org MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: pouria X-Git-Repository: src X-Git-Refname: refs/heads/main X-Git-Reftype: branch X-Git-Commit: 23b8d16c6641362833a8decdcb98b643006c3f5c Auto-Submitted: auto-generated Date: Thu, 30 Apr 2026 22:07:51 +0000 Message-Id: <69f3d2b7.1d184.1ddb9670@gitrepo.freebsd.org> The branch main has been updated by pouria: URL: https://cgit.FreeBSD.org/src/commit/?id=23b8d16c6641362833a8decdcb98b643006c3f5c commit 23b8d16c6641362833a8decdcb98b643006c3f5c Author: Pouria Mousavizadeh Tehrani AuthorDate: 2026-04-19 11:04:01 +0000 Commit: Pouria Mousavizadeh Tehrani CommitDate: 2026-04-30 22:06:20 +0000 tests/netlink: Add nexthop group tests for multipath Added tests: * Test for creating multiple routes. * Test for merge multiple nexthops into a single nexthop group. * Test for nexthop expirations from a nexthop group. Reviewed by: glebius Differential Revision: https://reviews.freebsd.org/D56190 --- tests/sys/netlink/Makefile | 1 + tests/sys/netlink/test_rtnl_route.c | 321 ++++++++++++++++++++++++++++++++++++ 2 files changed, 322 insertions(+) diff --git a/tests/sys/netlink/Makefile b/tests/sys/netlink/Makefile index 43b9db80ee63..89dba16c823c 100644 --- a/tests/sys/netlink/Makefile +++ b/tests/sys/netlink/Makefile @@ -6,6 +6,7 @@ TESTSDIR= ${TESTSBASE}/sys/netlink ATF_TESTS_C+= netlink_socket ATF_TESTS_C+= test_snl test_snl_generic ATF_TESTS_C+= test_rtnl_gre +ATF_TESTS_C+= test_rtnl_route ATF_TESTS_PYTEST += test_nl_core.py ATF_TESTS_PYTEST += test_rtnl_iface.py ATF_TESTS_PYTEST += test_rtnl_ifaddr.py diff --git a/tests/sys/netlink/test_rtnl_route.c b/tests/sys/netlink/test_rtnl_route.c new file mode 100644 index 000000000000..84d73db11cc7 --- /dev/null +++ b/tests/sys/netlink/test_rtnl_route.c @@ -0,0 +1,321 @@ +/* + * Copyright (c) 2026 Pouria Mousavizadeh Tehrani + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#include +#include +#include +#include +#include +#include + +#include +#include +#include "netlink/netlink_snl.h" +#include +#include +#include + +#include +#include + +#include + +static struct rtmsg * +prepare_rtm_by_dst(struct snl_writer *nw, char *dst) +{ + struct rtmsg *rtm; + struct in_addr in_dst; + + inet_pton(AF_INET, dst, &in_dst); + rtm = snl_reserve_msg_object(nw, struct rtmsg); + if (rtm == NULL) + return (NULL); + + rtm->rtm_family = AF_INET; + rtm->rtm_protocol = RTPROT_STATIC; + rtm->rtm_type = RTN_UNICAST; + rtm->rtm_dst_len = 24; + rtm->rtm_flags = RTF_GATEWAY; + snl_add_msg_attr_ip4(nw, RTA_DST, &in_dst); + + return (rtm); +} + +static void +cleanup_route_by_dst(struct snl_state *ss, struct snl_writer *nw, char *dst) +{ + struct nlmsghdr *hdr, *rx_hdr; + struct snl_errmsg_data e = {}; + + /* Delete route */ + snl_init_writer(ss, nw); + ATF_REQUIRE((hdr = snl_create_msg_request(nw, RTM_DELROUTE)) != NULL); + ATF_REQUIRE(prepare_rtm_by_dst(nw, dst) != NULL); + ATF_REQUIRE((hdr = snl_finalize_msg(nw)) != NULL); + ATF_REQUIRE(snl_send_message(ss, hdr)); + ATF_REQUIRE((rx_hdr = snl_read_reply(ss, hdr->nlmsg_seq)) != NULL); +} + +ATF_TC(rtnl_nhgrp); +ATF_TC_HEAD(rtnl_nhgrp, tc) +{ + atf_tc_set_md_var(tc, "descr", "test nexthop group using netlink"); + atf_tc_set_md_var(tc, "require.user", "root"); + atf_tc_set_md_var(tc, "require.kmods", "netlink"); +} + +ATF_TC_BODY(rtnl_nhgrp, tc) +{ + struct snl_state ss; + struct snl_writer nw; + struct nlmsghdr *hdr, *rx_hdr; + struct in_addr gw1, gw2; + struct snl_errmsg_data e = {}; + struct snl_parsed_route r = { .rtax_weight = RT_DEFAULT_WEIGHT }; + struct rtmsg *rtm; + struct rtnexthop *rtnh; + int off, off2; + + ATF_REQUIRE_MSG(snl_init(&ss, NETLINK_ROUTE), "snl_init() failed"); + + inet_pton(AF_INET, "127.0.0.1", &gw1); + inet_pton(AF_INET, "127.0.0.2", &gw2); + + /* Create new multipath route */ + snl_init_writer(&ss, &nw); + ATF_REQUIRE((hdr = snl_create_msg_request(&nw, RTM_NEWROUTE)) != NULL); + hdr->nlmsg_flags |= NLM_F_CREATE; + ATF_REQUIRE((rtm = prepare_rtm_by_dst(&nw, "192.0.2.0")) != NULL); + + off = snl_add_msg_attr_nested(&nw, RTA_MULTIPATH); + /* first nexthop */ + off2 = snl_get_msg_offset(&nw); + rtnh = snl_reserve_msg_object(&nw, struct rtnexthop); + rtnh->rtnh_flags = 0; + rtnh->rtnh_hops = 1; + rtnh->rtnh_ifindex = 0; + snl_add_msg_attr_ip4(&nw, RTA_GATEWAY, &gw1); + rtnh = snl_restore_msg_offset(&nw, off2, struct rtnexthop); + rtnh->rtnh_len = snl_get_msg_offset(&nw) - off2; + + /* second nexthop */ + off2 = snl_get_msg_offset(&nw); + rtnh = snl_reserve_msg_object(&nw, struct rtnexthop); + rtnh->rtnh_flags = 0; + rtnh->rtnh_hops = 1; + rtnh->rtnh_ifindex = 0; + snl_add_msg_attr_ip4(&nw, RTA_GATEWAY, &gw2); + rtnh = snl_restore_msg_offset(&nw, off2, struct rtnexthop); + rtnh->rtnh_len = snl_get_msg_offset(&nw) - off2; + + snl_end_attr_nested(&nw, off); + + ATF_REQUIRE((hdr = snl_finalize_msg(&nw)) != NULL); + ATF_REQUIRE(snl_send_message(&ss, hdr)); + ATF_REQUIRE((rx_hdr = snl_read_reply(&ss, hdr->nlmsg_seq)) != NULL); + ATF_REQUIRE(snl_parse_errmsg(&ss, rx_hdr, &e)); + ATF_REQUIRE_INTEQ(e.error, 0); + + /* Get route and check for its nexthop group */ + snl_init_writer(&ss, &nw); + ATF_REQUIRE((hdr = snl_create_msg_request(&nw, RTM_GETROUTE)) != NULL); + ATF_REQUIRE((rtm = prepare_rtm_by_dst(&nw, "192.0.2.0")) != NULL); + ATF_REQUIRE((hdr = snl_finalize_msg(&nw)) != NULL); + ATF_REQUIRE(snl_send_message(&ss, hdr)); + ATF_REQUIRE((rx_hdr = snl_read_reply(&ss, hdr->nlmsg_seq)) != NULL); + ATF_CHECK(snl_parse_nlmsg(&ss, rx_hdr, &snl_rtm_route_parser, &r)); + ATF_CHECK(r.rta_knh_id != 0); + ATF_CHECK_INTEQ(r.rta_multipath.num_nhops, 2); + + cleanup_route_by_dst(&ss, &nw, "192.0.2.0"); +} + +ATF_TC(rtnl_nhop_merge); +ATF_TC_HEAD(rtnl_nhop_merge, tc) +{ + atf_tc_set_md_var(tc, "descr", "test merge of two independent nexthop using netlink"); + atf_tc_set_md_var(tc, "require.user", "root"); + atf_tc_set_md_var(tc, "require.kmods", "netlink"); +} + +ATF_TC_BODY(rtnl_nhop_merge, tc) +{ + struct snl_state ss; + struct snl_writer nw; + struct nlmsghdr *hdr, *rx_hdr; + struct in_addr gw1, gw2; + struct snl_errmsg_data e = {}; + struct snl_parsed_route r = { .rtax_weight = RT_DEFAULT_WEIGHT }; + struct rtmsg *rtm; + struct rtnexthop *rtnh; + + ATF_REQUIRE_MSG(snl_init(&ss, NETLINK_ROUTE), "snl_init() failed"); + + inet_pton(AF_INET, "127.0.1.1", &gw1); + inet_pton(AF_INET, "127.0.1.2", &gw2); + + /* Create new route with single nhop */ + snl_init_writer(&ss, &nw); + ATF_REQUIRE((hdr = snl_create_msg_request(&nw, RTM_NEWROUTE)) != NULL); + hdr->nlmsg_flags |= NLM_F_CREATE; + ATF_REQUIRE((rtm = prepare_rtm_by_dst(&nw, "198.51.100.0")) != NULL); + snl_add_msg_attr_ip4(&nw, RTA_GATEWAY, &gw1); + ATF_REQUIRE((hdr = snl_finalize_msg(&nw)) != NULL); + ATF_REQUIRE(snl_send_message(&ss, hdr)); + ATF_REQUIRE((rx_hdr = snl_read_reply(&ss, hdr->nlmsg_seq)) != NULL); + ATF_REQUIRE(snl_parse_errmsg(&ss, rx_hdr, &e)); + ATF_REQUIRE_INTEQ(e.error, 0); + + /* Get route and verify it's NOT a nexthop group */ + snl_init_writer(&ss, &nw); + ATF_REQUIRE((hdr = snl_create_msg_request(&nw, RTM_GETROUTE)) != NULL); + ATF_REQUIRE((rtm = prepare_rtm_by_dst(&nw, "198.51.100.0")) != NULL); + ATF_REQUIRE((hdr = snl_finalize_msg(&nw)) != NULL); + ATF_REQUIRE(snl_send_message(&ss, hdr)); + ATF_REQUIRE((rx_hdr = snl_read_reply(&ss, hdr->nlmsg_seq)) != NULL); + ATF_CHECK(snl_parse_nlmsg(&ss, rx_hdr, &snl_rtm_route_parser, &r)); + ATF_CHECK(r.rta_knh_id != 0); + ATF_CHECK_INTEQ(r.rta_multipath.num_nhops, 0); + + /* Append anoher nhop */ + snl_init_writer(&ss, &nw); + ATF_REQUIRE((hdr = snl_create_msg_request(&nw, RTM_NEWROUTE)) != NULL); + hdr->nlmsg_flags |= NLM_F_APPEND; + ATF_REQUIRE((rtm = prepare_rtm_by_dst(&nw, "198.51.100.0")) != NULL); + snl_add_msg_attr_ip4(&nw, RTA_GATEWAY, &gw2); + ATF_REQUIRE((hdr = snl_finalize_msg(&nw)) != NULL); + ATF_REQUIRE(snl_send_message(&ss, hdr)); + ATF_REQUIRE((rx_hdr = snl_read_reply(&ss, hdr->nlmsg_seq)) != NULL); + ATF_REQUIRE(snl_parse_errmsg(&ss, rx_hdr, &e)); + ATF_REQUIRE_INTEQ(e.error, 0); + + /* Get route and verify it became a nexthop group */ + snl_init_writer(&ss, &nw); + ATF_REQUIRE((hdr = snl_create_msg_request(&nw, RTM_GETROUTE)) != NULL); + ATF_REQUIRE((rtm = prepare_rtm_by_dst(&nw, "198.51.100.0")) != NULL); + ATF_REQUIRE((hdr = snl_finalize_msg(&nw)) != NULL); + ATF_REQUIRE(snl_send_message(&ss, hdr)); + ATF_REQUIRE((rx_hdr = snl_read_reply(&ss, hdr->nlmsg_seq)) != NULL); + ATF_CHECK(snl_parse_nlmsg(&ss, rx_hdr, &snl_rtm_route_parser, &r)); + ATF_CHECK(r.rta_knh_id != 0); + ATF_CHECK_INTEQ(r.rta_multipath.num_nhops, 2); + + cleanup_route_by_dst(&ss, &nw, "198.51.100.0"); +} + +ATF_TC(rtnl_nhgrp_expire); +ATF_TC_HEAD(rtnl_nhgrp_expire, tc) +{ + atf_tc_set_md_var(tc, "descr", "test nhop expiration of a member inside nhgrp using netlink"); + atf_tc_set_md_var(tc, "require.user", "root"); + atf_tc_set_md_var(tc, "require.kmods", "netlink"); +} + +ATF_TC_BODY(rtnl_nhgrp_expire, tc) +{ + struct snl_state ss; + struct snl_writer nw; + struct nlmsghdr *hdr, *rx_hdr; + struct in_addr gw1, gw2, gw3; + struct snl_errmsg_data e = {}; + struct snl_parsed_route r = { .rtax_weight = RT_DEFAULT_WEIGHT }; + struct rtmsg *rtm; + struct rtnexthop *rtnh; + struct timespec ts; + int off, off2; + + ATF_REQUIRE_MSG(snl_init(&ss, NETLINK_ROUTE), "snl_init() failed"); + + inet_pton(AF_INET, "127.0.2.1", &gw1); + inet_pton(AF_INET, "127.0.2.2", &gw2); + inet_pton(AF_INET, "127.0.2.3", &gw3); + + /* create new multipath route */ + snl_init_writer(&ss, &nw); + ATF_REQUIRE((hdr = snl_create_msg_request(&nw, RTM_NEWROUTE)) != NULL); + hdr->nlmsg_flags |= NLM_F_CREATE; + ATF_REQUIRE((rtm = prepare_rtm_by_dst(&nw, "203.0.113.0")) != NULL); + + off = snl_add_msg_attr_nested(&nw, RTA_MULTIPATH); + /* first nexthop */ + off2 = snl_get_msg_offset(&nw); + rtnh = snl_reserve_msg_object(&nw, struct rtnexthop); + rtnh->rtnh_flags = 0; + rtnh->rtnh_hops = 1; + rtnh->rtnh_ifindex = 0; + snl_add_msg_attr_ip4(&nw, RTA_GATEWAY, &gw1); + rtnh = snl_restore_msg_offset(&nw, off2, struct rtnexthop); + rtnh->rtnh_len = snl_get_msg_offset(&nw) - off2; + + /* second nexthop */ + off2 = snl_get_msg_offset(&nw); + rtnh = snl_reserve_msg_object(&nw, struct rtnexthop); + rtnh->rtnh_flags = 0; + rtnh->rtnh_hops = 1; + rtnh->rtnh_ifindex = 0; + snl_add_msg_attr_ip4(&nw, RTA_GATEWAY, &gw2); + rtnh = snl_restore_msg_offset(&nw, off2, struct rtnexthop); + rtnh->rtnh_len = snl_get_msg_offset(&nw) - off2; + + snl_end_attr_nested(&nw, off); + + ATF_REQUIRE((hdr = snl_finalize_msg(&nw)) != NULL); + ATF_REQUIRE(snl_send_message(&ss, hdr)); + ATF_REQUIRE((rx_hdr = snl_read_reply(&ss, hdr->nlmsg_seq)) != NULL); + ATF_REQUIRE(snl_parse_errmsg(&ss, rx_hdr, &e)); + ATF_REQUIRE_INTEQ(e.error, 0); + + /* append anoher nhop with expiration time */ + snl_init_writer(&ss, &nw); + ATF_REQUIRE((hdr = snl_create_msg_request(&nw, RTM_NEWROUTE)) != NULL); + hdr->nlmsg_flags |= NLM_F_APPEND; + ATF_REQUIRE((rtm = prepare_rtm_by_dst(&nw, "203.0.113.0")) != NULL); + snl_add_msg_attr_ip4(&nw, RTA_GATEWAY, &gw3); + /* expire after 1 seconds */ + clock_gettime(CLOCK_REALTIME_FAST, &ts); + snl_add_msg_attr_u32(&nw, RTA_EXPIRES, ts.tv_sec + 1); + ATF_REQUIRE((hdr = snl_finalize_msg(&nw)) != NULL); + ATF_REQUIRE(snl_send_message(&ss, hdr)); + ATF_REQUIRE((rx_hdr = snl_read_reply(&ss, hdr->nlmsg_seq)) != NULL); + ATF_REQUIRE(snl_parse_errmsg(&ss, rx_hdr, &e)); + ATF_REQUIRE_INTEQ(e.error, 0); + + /* get route and check for number of nhops */ + snl_init_writer(&ss, &nw); + ATF_REQUIRE((hdr = snl_create_msg_request(&nw, RTM_GETROUTE)) != NULL); + ATF_REQUIRE((rtm = prepare_rtm_by_dst(&nw, "203.0.113.0")) != NULL); + ATF_REQUIRE((hdr = snl_finalize_msg(&nw)) != NULL); + ATF_REQUIRE(snl_send_message(&ss, hdr)); + ATF_REQUIRE((rx_hdr = snl_read_reply(&ss, hdr->nlmsg_seq)) != NULL); + ATF_CHECK(snl_parse_nlmsg(&ss, rx_hdr, &snl_rtm_route_parser, &r)); + ATF_CHECK(r.rta_knh_id != 0); + ATF_CHECK_INTEQ(r.rta_multipath.num_nhops, 3); + + /* wait for 2 seconds and try again */ + sleep(2); + + /* get route and check for number of nhops */ + snl_init_writer(&ss, &nw); + ATF_REQUIRE((hdr = snl_create_msg_request(&nw, RTM_GETROUTE)) != NULL); + ATF_REQUIRE((rtm = prepare_rtm_by_dst(&nw, "203.0.113.0")) != NULL); + ATF_REQUIRE((hdr = snl_finalize_msg(&nw)) != NULL); + ATF_REQUIRE(snl_send_message(&ss, hdr)); + ATF_REQUIRE((rx_hdr = snl_read_reply(&ss, hdr->nlmsg_seq)) != NULL); + ATF_CHECK(snl_parse_nlmsg(&ss, rx_hdr, &snl_rtm_route_parser, &r)); + ATF_CHECK_INTEQ(r.rta_multipath.num_nhops, 2); + + cleanup_route_by_dst(&ss, &nw, "203.0.113.0"); +} + + +ATF_TP_ADD_TCS(tp) +{ + ATF_TP_ADD_TC(tp, rtnl_nhgrp); + ATF_TP_ADD_TC(tp, rtnl_nhgrp_expire); + ATF_TP_ADD_TC(tp, rtnl_nhop_merge); + + return (atf_no_error()); +}