Changeset View
Changeset View
Standalone View
Standalone View
tests/sys/net/routing/test_rtsock_l3.c
Show All 23 Lines | |||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | ||||
* SUCH DAMAGE. | * SUCH DAMAGE. | ||||
* | * | ||||
* $FreeBSD$ | * $FreeBSD$ | ||||
*/ | */ | ||||
#include "rtsock_common.h" | #include "rtsock_common.h" | ||||
#include "rtsock_config.h" | #include "rtsock_config.h" | ||||
#include "sys/types.h" | |||||
#include <sys/time.h> | |||||
#include <sys/ioctl.h> | |||||
#include "net/bpf.h" | |||||
static inline struct rtsock_test_config * | static inline struct rtsock_test_config * | ||||
presetup_ipv6(const atf_tc_t *tc) | presetup_ipv6(const atf_tc_t *tc) | ||||
{ | { | ||||
struct rtsock_test_config *c; | struct rtsock_test_config *c; | ||||
int ret; | int ret; | ||||
c = config_setup(tc); | c = config_setup(tc); | ||||
▲ Show 20 Lines • Show All 112 Lines • ▼ Show 20 Lines | verify_route_message(struct rt_msghdr *rtm, int cmd, struct sockaddr *dst, | ||||
} | } | ||||
if (gw != NULL) { | if (gw != NULL) { | ||||
sa = rtsock_find_rtm_sa(rtm, RTA_GATEWAY); | sa = rtsock_find_rtm_sa(rtm, RTA_GATEWAY); | ||||
RTSOCK_ATF_REQUIRE_MSG(rtm, sa != NULL, "GATEWAY is not set"); | RTSOCK_ATF_REQUIRE_MSG(rtm, sa != NULL, "GATEWAY is not set"); | ||||
ret = sa_equal_msg(sa, gw, msg, sizeof(msg)); | ret = sa_equal_msg(sa, gw, msg, sizeof(msg)); | ||||
RTSOCK_ATF_REQUIRE_MSG(rtm, ret != 0, "GATEWAY sa diff: %s", msg); | RTSOCK_ATF_REQUIRE_MSG(rtm, ret != 0, "GATEWAY sa diff: %s", msg); | ||||
} | } | ||||
RTSOCK_ATF_REQUIRE_MSG(rtm, rtm->rtm_pid > 0, "expected non-zero pid"); | |||||
} | } | ||||
static void | static void | ||||
verify_route_message_extra(struct rt_msghdr *rtm, int ifindex, int rtm_flags) | verify_route_message_extra(struct rt_msghdr *rtm, int ifindex, int rtm_flags) | ||||
{ | { | ||||
RTSOCK_ATF_REQUIRE_MSG(rtm, rtm->rtm_index == ifindex, | RTSOCK_ATF_REQUIRE_MSG(rtm, rtm->rtm_index == ifindex, | ||||
"expected ifindex %d, got %d", ifindex, rtm->rtm_index); | "expected ifindex %d, got %d", ifindex, rtm->rtm_index); | ||||
▲ Show 20 Lines • Show All 327 Lines • ▼ Show 20 Lines | ATF_TC_BODY(rtm_del_v6_gu_prefix_nogw_success, tc) | ||||
verify_route_message_extra(rtm, c->ifindex, RTF_DONE | RTF_GATEWAY | RTF_STATIC); | verify_route_message_extra(rtm, c->ifindex, RTF_DONE | RTF_GATEWAY | RTF_STATIC); | ||||
} | } | ||||
ATF_TC_CLEANUP(rtm_del_v6_gu_prefix_nogw_success, tc) | ATF_TC_CLEANUP(rtm_del_v6_gu_prefix_nogw_success, tc) | ||||
{ | { | ||||
CLEANUP_AFTER_TEST; | CLEANUP_AFTER_TEST; | ||||
} | } | ||||
ATF_TC_WITH_CLEANUP(rtm_add_v4_temporal1_success); | |||||
ATF_TC_HEAD(rtm_add_v4_temporal1_success, tc) | |||||
{ | |||||
DESCRIBE_ROOT_TEST("Tests IPv4 route expiration with expire time set"); | |||||
} | |||||
ATF_TC_BODY(rtm_add_v4_temporal1_success, tc) | |||||
{ | |||||
DECLARE_TEST_VARS; | |||||
c = presetup_ipv4(tc); | |||||
/* Create IPv4 subnetwork with smaller prefix */ | |||||
struct sockaddr_in mask4; | |||||
struct sockaddr_in net4; | |||||
struct sockaddr_in gw4; | |||||
prepare_v4_network(c, &net4, &mask4, &gw4); | |||||
prepare_route_message(rtm, RTM_ADD, (struct sockaddr *)&net4, | |||||
(struct sockaddr *)&mask4, (struct sockaddr *)&gw4); | |||||
/* Set expire time to now */ | |||||
struct timeval tv; | |||||
gettimeofday(&tv, NULL); | |||||
rtm->rtm_rmx.rmx_expire = tv.tv_sec - 1; | |||||
rtm->rtm_inits |= RTV_EXPIRE; | |||||
rtsock_send_rtm(c->rtsock_fd, rtm); | |||||
rtm = rtsock_read_rtm_reply(c->rtsock_fd, buffer, sizeof(buffer), rtm->rtm_seq); | |||||
ATF_REQUIRE_MSG(rtm != NULL, "unable to get rtsock reply for RTM_ADD"); | |||||
RTSOCK_ATF_REQUIRE_MSG(rtm, rtm->rtm_inits & RTV_EXPIRE, "RTV_EXPIRE not set"); | |||||
/* The next should be route deletion */ | |||||
rtm = rtsock_read_rtm(c->rtsock_fd, buffer, sizeof(buffer)); | |||||
verify_route_message(rtm, RTM_DELETE, (struct sockaddr *)&net4, | |||||
(struct sockaddr *)&mask4, (struct sockaddr *)&gw4); | |||||
/* TODO: add RTF_DONE */ | |||||
verify_route_message_extra(rtm, c->ifindex, RTF_GATEWAY | RTF_STATIC); | |||||
} | |||||
ATF_TC_CLEANUP(rtm_add_v4_temporal1_success, tc) | |||||
{ | |||||
CLEANUP_AFTER_TEST; | |||||
} | |||||
ATF_TC_WITH_CLEANUP(rtm_add_v6_temporal1_success); | |||||
ATF_TC_HEAD(rtm_add_v6_temporal1_success, tc) | |||||
{ | |||||
DESCRIBE_ROOT_TEST("Tests IPv6 global unicast prefix addition with directly-reachable GU GW"); | |||||
} | |||||
ATF_TC_BODY(rtm_add_v6_temporal1_success, tc) | |||||
{ | |||||
DECLARE_TEST_VARS; | |||||
c = presetup_ipv6(tc); | |||||
/* Create IPv6 subnetwork with smaller prefix */ | |||||
struct sockaddr_in6 mask6; | |||||
struct sockaddr_in6 net6; | |||||
struct sockaddr_in6 gw6; | |||||
prepare_v6_network(c, &net6, &mask6, &gw6); | |||||
prepare_route_message(rtm, RTM_ADD, (struct sockaddr *)&net6, | |||||
(struct sockaddr *)&mask6, (struct sockaddr *)&gw6); | |||||
/* Set expire time to now */ | |||||
struct timeval tv; | |||||
gettimeofday(&tv, NULL); | |||||
rtm->rtm_rmx.rmx_expire = tv.tv_sec - 1; | |||||
rtm->rtm_inits |= RTV_EXPIRE; | |||||
rtsock_send_rtm(c->rtsock_fd, rtm); | |||||
rtm = rtsock_read_rtm_reply(c->rtsock_fd, buffer, sizeof(buffer), rtm->rtm_seq); | |||||
ATF_REQUIRE_MSG(rtm != NULL, "unable to get rtsock reply for RTM_ADD"); | |||||
RTSOCK_ATF_REQUIRE_MSG(rtm, rtm->rtm_inits & RTV_EXPIRE, "RTV_EXPIRE not set"); | |||||
/* The next should be route deletion */ | |||||
rtm = rtsock_read_rtm(c->rtsock_fd, buffer, sizeof(buffer)); | |||||
ATF_REQUIRE_MSG(0 == 1, "XX: %x %x\n", BIOCIMMEDIATE, BIOCFEEDBACK); | |||||
verify_route_message(rtm, RTM_DELETE, (struct sockaddr *)&net6, | |||||
(struct sockaddr *)&mask6, (struct sockaddr *)&gw6); | |||||
/* XXX: Currently kernel sets RTF_UP automatically but does NOT report it in the reply */ | |||||
/* TODO: add RTF_DONE */ | |||||
verify_route_message_extra(rtm, c->ifindex, RTF_GATEWAY | RTF_STATIC); | |||||
} | |||||
ATF_TC_CLEANUP(rtm_add_v6_temporal1_success, tc) | |||||
{ | |||||
CLEANUP_AFTER_TEST; | |||||
} | |||||
ATF_TP_ADD_TCS(tp) | ATF_TP_ADD_TCS(tp) | ||||
{ | { | ||||
ATF_TP_ADD_TC(tp, rtm_get_v4_exact_success); | ATF_TP_ADD_TC(tp, rtm_get_v4_exact_success); | ||||
ATF_TP_ADD_TC(tp, rtm_get_v4_lpm_success); | ATF_TP_ADD_TC(tp, rtm_get_v4_lpm_success); | ||||
ATF_TP_ADD_TC(tp, rtm_get_v4_hostbits_failure); | ATF_TP_ADD_TC(tp, rtm_get_v4_hostbits_failure); | ||||
ATF_TP_ADD_TC(tp, rtm_get_v4_empty_dst_failure); | ATF_TP_ADD_TC(tp, rtm_get_v4_empty_dst_failure); | ||||
ATF_TP_ADD_TC(tp, rtm_add_v4_gw_direct_success); | ATF_TP_ADD_TC(tp, rtm_add_v4_gw_direct_success); | ||||
ATF_TP_ADD_TC(tp, rtm_del_v4_prefix_nogw_success); | ATF_TP_ADD_TC(tp, rtm_del_v4_prefix_nogw_success); | ||||
ATF_TP_ADD_TC(tp, rtm_add_v6_gu_gw_gu_direct_success); | ATF_TP_ADD_TC(tp, rtm_add_v6_gu_gw_gu_direct_success); | ||||
ATF_TP_ADD_TC(tp, rtm_del_v6_gu_prefix_nogw_success); | ATF_TP_ADD_TC(tp, rtm_del_v6_gu_prefix_nogw_success); | ||||
/* temporal routes */ | |||||
ATF_TP_ADD_TC(tp, rtm_add_v4_temporal1_success); | |||||
ATF_TP_ADD_TC(tp, rtm_add_v6_temporal1_success); | |||||
return (atf_no_error()); | return (atf_no_error()); | ||||
} | } | ||||