Add routing tests verifying basic RTM_CHANGE functionality.
MFC after: 2 weeks Differential Revision: https://reviews.freebsd.org/D24239
This commit is contained in:
parent
130d950caf
commit
272bd6985f
@ -71,6 +71,8 @@ void rtsock_update_rtm_len(struct rt_msghdr *rtm);
|
||||
void rtsock_validate_message(char *buffer, ssize_t len);
|
||||
void rtsock_add_rtm_sa(struct rt_msghdr *rtm, int addr_type, struct sockaddr *sa);
|
||||
|
||||
void file_append_line(char *fname, char *text);
|
||||
|
||||
static int _rtm_seq = 42;
|
||||
|
||||
|
||||
@ -151,34 +153,43 @@ _enforce_cloner_loaded(char *cloner_name)
|
||||
return (1);
|
||||
}
|
||||
|
||||
static int
|
||||
iface_create_cloned(char *ifname_ptr)
|
||||
static char *
|
||||
iface_create(char *ifname_orig)
|
||||
{
|
||||
struct ifreq ifr;
|
||||
int s;
|
||||
char prefix[IFNAMSIZ];
|
||||
char prefix[IFNAMSIZ], ifname[IFNAMSIZ], *result;
|
||||
|
||||
char *src, *dst;
|
||||
for (src = ifname_ptr, dst = prefix; *src && isalpha(*src); src++)
|
||||
for (src = ifname_orig, dst = prefix; *src && isalpha(*src); src++)
|
||||
*dst++ = *src;
|
||||
*dst = '\0';
|
||||
|
||||
if (_enforce_cloner_loaded(prefix) == 0)
|
||||
return (0);
|
||||
return (NULL);
|
||||
|
||||
memset(&ifr, 0, sizeof(struct ifreq));
|
||||
|
||||
s = socket(AF_LOCAL, SOCK_DGRAM, 0);
|
||||
strlcpy(ifr.ifr_name, ifname_ptr, sizeof(ifr.ifr_name));
|
||||
strlcpy(ifr.ifr_name, ifname_orig, sizeof(ifr.ifr_name));
|
||||
|
||||
RLOG("creating iface %s %s", prefix, ifr.ifr_name);
|
||||
if (ioctl(s, SIOCIFCREATE2, &ifr) < 0)
|
||||
err(1, "SIOCIFCREATE2");
|
||||
|
||||
strlcpy(ifname_ptr, ifr.ifr_name, IFNAMSIZ);
|
||||
RLOG("created interface %s", ifname_ptr);
|
||||
strlcpy(ifname, ifr.ifr_name, IFNAMSIZ);
|
||||
RLOG("created interface %s", ifname);
|
||||
|
||||
return (1);
|
||||
result = strdup(ifname);
|
||||
|
||||
file_append_line(IFACES_FNAME, ifname);
|
||||
if (strstr(ifname, "epair") == ifname) {
|
||||
/* call returned epairXXXa, need to add epairXXXb */
|
||||
ifname[strlen(ifname) - 1] = 'b';
|
||||
file_append_line(IFACES_FNAME, ifname);
|
||||
}
|
||||
|
||||
return (result);
|
||||
}
|
||||
|
||||
static int
|
||||
@ -357,16 +368,19 @@ vnet_wait_interface(char *vnet_name, char *ifname)
|
||||
}
|
||||
|
||||
void
|
||||
vnet_switch(char *vnet_name, char *ifname)
|
||||
vnet_switch(char *vnet_name, char **ifnames, int count)
|
||||
{
|
||||
char buf[512], cmd[512], *line;
|
||||
FILE *fp;
|
||||
int jid, ret;
|
||||
int jid, len, ret;
|
||||
|
||||
RLOG("switching to vnet %s with interface %s", vnet_name, ifname);
|
||||
snprintf(cmd, sizeof(cmd),
|
||||
"/usr/sbin/jail -i -c name=%s persist vnet vnet.interface=%s",
|
||||
vnet_name, ifname);
|
||||
RLOG("switching to vnet %s with interface(s) %s", vnet_name, ifnames[0]);
|
||||
len = snprintf(cmd, sizeof(cmd),
|
||||
"/usr/sbin/jail -i -c name=%s persist vnet", vnet_name);
|
||||
for (int i = 0; i < count && len < sizeof(cmd); i++) {
|
||||
len += snprintf(&cmd[len], sizeof(cmd) - len,
|
||||
" vnet.interface=%s", ifnames[i]);
|
||||
}
|
||||
RLOG("jail cmd: \"%s\"\n", cmd);
|
||||
|
||||
fp = popen(cmd, "r");
|
||||
@ -384,8 +398,11 @@ vnet_switch(char *vnet_name, char *ifname)
|
||||
file_append_line(JAILS_FNAME, vnet_name);
|
||||
|
||||
/* Wait while interface appearsh inside vnet */
|
||||
if (!vnet_wait_interface(vnet_name, ifname)) {
|
||||
atf_tc_fail("unable to move interface %s to jail %s", ifname, vnet_name);
|
||||
for (int i = 0; i < count; i++) {
|
||||
if (vnet_wait_interface(vnet_name, ifnames[i]))
|
||||
continue;
|
||||
atf_tc_fail("unable to move interface %s to jail %s",
|
||||
ifnames[i], vnet_name);
|
||||
}
|
||||
|
||||
if (jail_attach(jid) == -1) {
|
||||
@ -396,6 +413,15 @@ vnet_switch(char *vnet_name, char *ifname)
|
||||
RLOG("attached to the jail");
|
||||
}
|
||||
|
||||
void
|
||||
vnet_switch_one(char *vnet_name, char *ifname)
|
||||
{
|
||||
char *ifnames[1];
|
||||
|
||||
ifnames[0] = ifname;
|
||||
vnet_switch(vnet_name, ifnames, 1);
|
||||
}
|
||||
|
||||
|
||||
#define SA_F_IGNORE_IFNAME 0x01
|
||||
#define SA_F_IGNORE_IFTYPE 0x02
|
||||
@ -699,15 +725,19 @@ struct rt_msghdr *
|
||||
rtsock_read_rtm_reply(int fd, char *buffer, size_t buflen, int seq)
|
||||
{
|
||||
struct rt_msghdr *rtm;
|
||||
int found = 0;
|
||||
|
||||
while (true) {
|
||||
rtm = rtsock_read_rtm(fd, buffer, buflen);
|
||||
if (rtm->rtm_pid != getpid())
|
||||
continue;
|
||||
if (rtm->rtm_seq != seq)
|
||||
continue;
|
||||
|
||||
return (rtm);
|
||||
if (rtm->rtm_pid == getpid() && rtm->rtm_seq == seq)
|
||||
found = 1;
|
||||
if (found)
|
||||
RLOG("--- MATCHED RTSOCK MESSAGE ---");
|
||||
else
|
||||
RLOG("--- SKIPPED RTSOCK MESSAGE ---");
|
||||
rtsock_print_rtm(rtm);
|
||||
if (found)
|
||||
return (rtm);
|
||||
}
|
||||
|
||||
/* NOTREACHED */
|
||||
|
@ -32,6 +32,10 @@
|
||||
|
||||
#include "params.h"
|
||||
|
||||
struct rtsock_config_options {
|
||||
int num_interfaces; /* number of interfaces to create */
|
||||
};
|
||||
|
||||
struct rtsock_test_config {
|
||||
int ifindex;
|
||||
char net4_str[INET_ADDRSTRLEN];
|
||||
@ -48,30 +52,29 @@ struct rtsock_test_config {
|
||||
int plen6;
|
||||
char *remote_lladdr;
|
||||
char *ifname;
|
||||
char **ifnames;
|
||||
bool autocreated_interface;
|
||||
int rtsock_fd;
|
||||
int num_interfaces;
|
||||
};
|
||||
|
||||
struct rtsock_test_config *
|
||||
config_setup_base(const atf_tc_t *tc)
|
||||
{
|
||||
struct rtsock_test_config *c;
|
||||
|
||||
c = calloc(1, sizeof(struct rtsock_test_config));
|
||||
c->rtsock_fd = -1;
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
struct rtsock_test_config *
|
||||
config_setup(const atf_tc_t *tc)
|
||||
config_setup(const atf_tc_t *tc, struct rtsock_config_options *co)
|
||||
{
|
||||
struct rtsock_config_options default_co;
|
||||
struct rtsock_test_config *c;
|
||||
char buf[64], *s;
|
||||
const char *key;
|
||||
int mask;
|
||||
|
||||
c = config_setup_base(tc);
|
||||
if (co == NULL) {
|
||||
bzero(&default_co, sizeof(default_co));
|
||||
co = &default_co;
|
||||
co->num_interfaces = 1;
|
||||
}
|
||||
|
||||
c = calloc(1, sizeof(struct rtsock_test_config));
|
||||
c->rtsock_fd = -1;
|
||||
|
||||
key = atf_tc_get_config_var_wd(tc, "rtsock.v4prefix", "192.0.2.0/24");
|
||||
strlcpy(buf, key, sizeof(buf));
|
||||
@ -123,27 +126,17 @@ config_setup(const atf_tc_t *tc)
|
||||
inet_ntop(AF_INET6, &c->net6.sin6_addr, c->net6_str, INET6_ADDRSTRLEN);
|
||||
inet_ntop(AF_INET6, &c->addr6.sin6_addr, c->addr6_str, INET6_ADDRSTRLEN);
|
||||
|
||||
c->ifname = strdup("epair");
|
||||
c->autocreated_interface = true;
|
||||
if (co->num_interfaces > 0) {
|
||||
c->ifnames = calloc(co->num_interfaces, sizeof(char *));
|
||||
for (int i = 0; i < co->num_interfaces; i++)
|
||||
c->ifnames[i] = iface_create("epair");
|
||||
|
||||
if (c->autocreated_interface && (if_nametoindex(c->ifname) == 0))
|
||||
{
|
||||
/* create our own interface */
|
||||
char new_ifname[IFNAMSIZ];
|
||||
strlcpy(new_ifname, c->ifname, sizeof(new_ifname));
|
||||
int ret = iface_create_cloned(new_ifname);
|
||||
ATF_REQUIRE_MSG(ret != 0, "%s interface creation failed: %s", new_ifname,
|
||||
strerror(errno));
|
||||
c->ifname = strdup(new_ifname);
|
||||
file_append_line(IFACES_FNAME, new_ifname);
|
||||
if (strstr(new_ifname, "epair") == new_ifname) {
|
||||
/* call returned epairXXXa, need to add epairXXXb */
|
||||
new_ifname[strlen(new_ifname) - 1] = 'b';
|
||||
file_append_line(IFACES_FNAME, new_ifname);
|
||||
}
|
||||
c->ifname = c->ifnames[0];
|
||||
c->ifindex = if_nametoindex(c->ifname);
|
||||
ATF_REQUIRE_MSG(c->ifindex != 0, "interface %s not found",
|
||||
c->ifname);
|
||||
}
|
||||
c->ifindex = if_nametoindex(c->ifname);
|
||||
ATF_REQUIRE_MSG(c->ifindex != 0, "inteface %s not found", c->ifname);
|
||||
c->num_interfaces = co->num_interfaces;
|
||||
|
||||
c->remote_lladdr = strdup(atf_tc_get_config_var_wd(tc,
|
||||
"rtsock.remote_lladdr", "00:00:5E:00:53:42"));
|
||||
|
@ -43,7 +43,7 @@ jump_vnet(struct rtsock_test_config *c, const atf_tc_t *tc)
|
||||
snprintf(vnet_name, sizeof(vnet_name), "vt-%s", atf_tc_get_ident(tc));
|
||||
RLOG("jumping to %s", vnet_name);
|
||||
|
||||
vnet_switch(vnet_name, c->ifname);
|
||||
vnet_switch(vnet_name, c->ifnames, c->num_interfaces);
|
||||
|
||||
/* Update ifindex cache */
|
||||
c->ifindex = if_nametoindex(c->ifname);
|
||||
@ -55,7 +55,7 @@ presetup_ipv6_iface(const atf_tc_t *tc)
|
||||
struct rtsock_test_config *c;
|
||||
int ret;
|
||||
|
||||
c = config_setup(tc);
|
||||
c = config_setup(tc, NULL);
|
||||
|
||||
jump_vnet(c, tc);
|
||||
|
||||
@ -89,7 +89,7 @@ presetup_ipv4_iface(const atf_tc_t *tc)
|
||||
struct rtsock_test_config *c;
|
||||
int ret;
|
||||
|
||||
c = config_setup(tc);
|
||||
c = config_setup(tc, NULL);
|
||||
|
||||
jump_vnet(c, tc);
|
||||
|
||||
@ -353,8 +353,12 @@ ATF_TC_HEAD(rtm_get_v4_empty_dst_failure, tc)
|
||||
ATF_TC_BODY(rtm_get_v4_empty_dst_failure, tc)
|
||||
{
|
||||
DECLARE_TEST_VARS;
|
||||
struct rtsock_config_options co;
|
||||
|
||||
c = config_setup_base(tc);
|
||||
bzero(&co, sizeof(co));
|
||||
co.num_interfaces = 0;
|
||||
|
||||
c = config_setup(tc,&co);
|
||||
c->rtsock_fd = rtsock_setup_socket();
|
||||
|
||||
rtsock_prepare_route_message(rtm, RTM_GET, NULL,
|
||||
@ -486,6 +490,133 @@ ATF_TC_CLEANUP(rtm_del_v4_prefix_nogw_success, tc)
|
||||
CLEANUP_AFTER_TEST;
|
||||
}
|
||||
|
||||
RTM_DECLARE_ROOT_TEST(rtm_change_v4_gw_success,
|
||||
"Tests IPv4 gateway change");
|
||||
|
||||
ATF_TC_BODY(rtm_change_v4_gw_success, tc)
|
||||
{
|
||||
DECLARE_TEST_VARS;
|
||||
struct rtsock_config_options co;
|
||||
|
||||
bzero(&co, sizeof(co));
|
||||
co.num_interfaces = 2;
|
||||
|
||||
c = config_setup(tc, &co);
|
||||
jump_vnet(c, tc);
|
||||
|
||||
ret = iface_turn_up(c->ifnames[0]);
|
||||
ATF_REQUIRE_MSG(ret == 0, "Unable to turn up %s", c->ifnames[0]);
|
||||
ret = iface_turn_up(c->ifnames[1]);
|
||||
ATF_REQUIRE_MSG(ret == 0, "Unable to turn up %s", c->ifnames[1]);
|
||||
|
||||
ret = iface_setup_addr(c->ifnames[0], c->addr4_str, c->plen4);
|
||||
ATF_REQUIRE_MSG(ret == 0, "ifconfig failed");
|
||||
|
||||
/* Use 198.51.100.0/24 "TEST-NET-2" for the second interface */
|
||||
ret = iface_setup_addr(c->ifnames[1], "198.51.100.1", 24);
|
||||
ATF_REQUIRE_MSG(ret == 0, "ifconfig failed");
|
||||
|
||||
c->rtsock_fd = rtsock_setup_socket();
|
||||
|
||||
/* 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);
|
||||
|
||||
rtsock_send_rtm(c->rtsock_fd, rtm);
|
||||
rtm = rtsock_read_rtm_reply(c->rtsock_fd, buffer, sizeof(buffer), rtm->rtm_seq);
|
||||
|
||||
verify_route_message(rtm, RTM_ADD, (struct sockaddr *)&net4,
|
||||
(struct sockaddr *)&mask4, (struct sockaddr *)&gw4);
|
||||
|
||||
/* Change gateway to the one on desiding on the other interface */
|
||||
inet_pton(AF_INET, "198.51.100.2", &gw4.sin_addr.s_addr);
|
||||
prepare_route_message(rtm, RTM_CHANGE, (struct sockaddr *)&net4,
|
||||
(struct sockaddr *)&mask4, (struct sockaddr *)&gw4);
|
||||
rtsock_send_rtm(c->rtsock_fd, rtm);
|
||||
|
||||
rtm = rtsock_read_rtm_reply(c->rtsock_fd, buffer, sizeof(buffer), rtm->rtm_seq);
|
||||
|
||||
verify_route_message(rtm, RTM_CHANGE, (struct sockaddr *)&net4,
|
||||
(struct sockaddr *)&mask4, (struct sockaddr *)&gw4);
|
||||
|
||||
verify_route_message_extra(rtm, if_nametoindex(c->ifnames[1]),
|
||||
RTF_DONE | RTF_GATEWAY | RTF_STATIC);
|
||||
|
||||
/* Verify the change has actually taken place */
|
||||
prepare_route_message(rtm, RTM_GET, (struct sockaddr *)&net4,
|
||||
(struct sockaddr *)&mask4, NULL);
|
||||
|
||||
rtsock_send_rtm(c->rtsock_fd, rtm);
|
||||
|
||||
/*
|
||||
* RTM_GET: len 200, pid: 3894, seq 44, errno 0, flags: <UP,GATEWAY,DONE,STATIC>
|
||||
* sockaddrs: 0x7 <DST,GATEWAY,NETMASK>
|
||||
* af=inet len=16 addr=192.0.2.0 hd={x10, x02, x00{2}, xC0, x00, x02, x00{9}}
|
||||
* af=inet len=16 addr=198.51.100.2 hd={x10, x02, x00{2}, xC6, x33, x64, x02, x00{8}}
|
||||
* af=inet len=16 addr=255.255.255.128 hd={x10, x02, xFF, xFF, xFF, xFF, xFF, x80, x00{8}}
|
||||
*/
|
||||
|
||||
rtm = rtsock_read_rtm_reply(c->rtsock_fd, buffer, sizeof(buffer), rtm->rtm_seq);
|
||||
verify_route_message_extra(rtm, if_nametoindex(c->ifnames[1]),
|
||||
RTF_UP | RTF_DONE | RTF_GATEWAY | RTF_STATIC);
|
||||
|
||||
}
|
||||
|
||||
RTM_DECLARE_ROOT_TEST(rtm_change_v4_mtu_success,
|
||||
"Tests IPv4 path mtu change");
|
||||
|
||||
ATF_TC_BODY(rtm_change_v4_mtu_success, tc)
|
||||
{
|
||||
DECLARE_TEST_VARS;
|
||||
|
||||
unsigned long test_mtu = 1442;
|
||||
|
||||
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);
|
||||
|
||||
rtsock_send_rtm(c->rtsock_fd, rtm);
|
||||
rtm = rtsock_read_rtm_reply(c->rtsock_fd, buffer, sizeof(buffer), rtm->rtm_seq);
|
||||
|
||||
/* Change MTU */
|
||||
prepare_route_message(rtm, RTM_CHANGE, (struct sockaddr *)&net4,
|
||||
(struct sockaddr *)&mask4, NULL);
|
||||
rtm->rtm_inits |= RTV_MTU;
|
||||
rtm->rtm_rmx.rmx_mtu = test_mtu;
|
||||
|
||||
rtsock_send_rtm(c->rtsock_fd, rtm);
|
||||
rtm = rtsock_read_rtm_reply(c->rtsock_fd, buffer, sizeof(buffer), rtm->rtm_seq);
|
||||
|
||||
verify_route_message(rtm, RTM_CHANGE, (struct sockaddr *)&net4,
|
||||
(struct sockaddr *)&mask4, NULL);
|
||||
|
||||
RTSOCK_ATF_REQUIRE_MSG(rtm, rtm->rtm_rmx.rmx_mtu == test_mtu,
|
||||
"expected mtu: %lu, got %lu", test_mtu, rtm->rtm_rmx.rmx_mtu);
|
||||
|
||||
/* Verify the change has actually taken place */
|
||||
prepare_route_message(rtm, RTM_GET, (struct sockaddr *)&net4,
|
||||
(struct sockaddr *)&mask4, NULL);
|
||||
|
||||
rtsock_send_rtm(c->rtsock_fd, rtm);
|
||||
rtm = rtsock_read_rtm_reply(c->rtsock_fd, buffer, sizeof(buffer), rtm->rtm_seq);
|
||||
|
||||
RTSOCK_ATF_REQUIRE_MSG(rtm, rtm->rtm_rmx.rmx_mtu == test_mtu,
|
||||
"expected mtu: %lu, got %lu", test_mtu, rtm->rtm_rmx.rmx_mtu);
|
||||
}
|
||||
|
||||
|
||||
ATF_TC_WITH_CLEANUP(rtm_add_v6_gu_gw_gu_direct_success);
|
||||
ATF_TC_HEAD(rtm_add_v6_gu_gw_gu_direct_success, tc)
|
||||
{
|
||||
@ -578,6 +709,136 @@ ATF_TC_CLEANUP(rtm_del_v6_gu_prefix_nogw_success, tc)
|
||||
CLEANUP_AFTER_TEST;
|
||||
}
|
||||
|
||||
RTM_DECLARE_ROOT_TEST(rtm_change_v6_gw_success,
|
||||
"Tests IPv6 gateway change");
|
||||
|
||||
ATF_TC_BODY(rtm_change_v6_gw_success, tc)
|
||||
{
|
||||
DECLARE_TEST_VARS;
|
||||
struct rtsock_config_options co;
|
||||
|
||||
bzero(&co, sizeof(co));
|
||||
co.num_interfaces = 2;
|
||||
|
||||
c = config_setup(tc, &co);
|
||||
jump_vnet(c, tc);
|
||||
|
||||
ret = iface_turn_up(c->ifnames[0]);
|
||||
ATF_REQUIRE_MSG(ret == 0, "Unable to turn up %s", c->ifnames[0]);
|
||||
ret = iface_turn_up(c->ifnames[1]);
|
||||
ATF_REQUIRE_MSG(ret == 0, "Unable to turn up %s", c->ifnames[1]);
|
||||
|
||||
ret = iface_enable_ipv6(c->ifnames[0]);
|
||||
ATF_REQUIRE_MSG(ret == 0, "Unable to enable IPv6 on %s", c->ifnames[0]);
|
||||
ret = iface_enable_ipv6(c->ifnames[1]);
|
||||
ATF_REQUIRE_MSG(ret == 0, "Unable to enable IPv6 on %s", c->ifnames[1]);
|
||||
|
||||
ret = iface_setup_addr(c->ifnames[0], c->addr6_str, c->plen6);
|
||||
ATF_REQUIRE_MSG(ret == 0, "ifconfig failed");
|
||||
|
||||
ret = iface_setup_addr(c->ifnames[1], "2001:DB8:4242::1", 64);
|
||||
ATF_REQUIRE_MSG(ret == 0, "ifconfig failed");
|
||||
|
||||
c->rtsock_fd = rtsock_setup_socket();
|
||||
|
||||
/* 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);
|
||||
|
||||
rtsock_send_rtm(c->rtsock_fd, rtm);
|
||||
rtm = rtsock_read_rtm_reply(c->rtsock_fd, buffer, sizeof(buffer), rtm->rtm_seq);
|
||||
|
||||
verify_route_message(rtm, RTM_ADD, (struct sockaddr *)&net6,
|
||||
(struct sockaddr *)&mask6, (struct sockaddr *)&gw6);
|
||||
|
||||
/* Change gateway to the one on residing on the other interface */
|
||||
inet_pton(AF_INET6, "2001:DB8:4242::4242", &gw6.sin6_addr);
|
||||
prepare_route_message(rtm, RTM_CHANGE, (struct sockaddr *)&net6,
|
||||
(struct sockaddr *)&mask6, (struct sockaddr *)&gw6);
|
||||
rtsock_send_rtm(c->rtsock_fd, rtm);
|
||||
|
||||
rtm = rtsock_read_rtm_reply(c->rtsock_fd, buffer, sizeof(buffer), rtm->rtm_seq);
|
||||
|
||||
verify_route_message(rtm, RTM_CHANGE, (struct sockaddr *)&net6,
|
||||
(struct sockaddr *)&mask6, (struct sockaddr *)&gw6);
|
||||
|
||||
verify_route_message_extra(rtm, if_nametoindex(c->ifnames[1]),
|
||||
RTF_DONE | RTF_GATEWAY | RTF_STATIC);
|
||||
|
||||
/* Verify the change has actually taken place */
|
||||
prepare_route_message(rtm, RTM_GET, (struct sockaddr *)&net6,
|
||||
(struct sockaddr *)&mask6, NULL);
|
||||
|
||||
rtsock_send_rtm(c->rtsock_fd, rtm);
|
||||
|
||||
/*
|
||||
* RTM_GET: len 248, pid: 2268, seq 44, errno 0, flags: <UP,GATEWAY,DONE,STATIC>
|
||||
* sockaddrs: 0x7 <DST,GATEWAY,NETMASK>
|
||||
* af=inet6 len=28 addr=2001:db8:: hd={x1C, x1C, x00{6}, x20, x01, x0D, xB8, x00{16}}
|
||||
* af=inet6 len=28 addr=2001:db8:4242::4242 hd={x1C, x1C, x00{6}, x20, x01, x0D, xB8, x42, x42, x00{8}, x42, x42, x00{4}}
|
||||
* af=inet6 len=28 addr=ffff:ffff:8000:: hd={x1C, x1C, xFF, xFF, xFF, xFF, xFF, xFF, xFF, xFF, xFF, xFF, x80, x00{15}}
|
||||
*/
|
||||
|
||||
rtm = rtsock_read_rtm_reply(c->rtsock_fd, buffer, sizeof(buffer), rtm->rtm_seq);
|
||||
verify_route_message_extra(rtm, if_nametoindex(c->ifnames[1]),
|
||||
RTF_UP | RTF_DONE | RTF_GATEWAY | RTF_STATIC);
|
||||
}
|
||||
|
||||
RTM_DECLARE_ROOT_TEST(rtm_change_v6_mtu_success,
|
||||
"Tests IPv6 path mtu change");
|
||||
|
||||
ATF_TC_BODY(rtm_change_v6_mtu_success, tc)
|
||||
{
|
||||
DECLARE_TEST_VARS;
|
||||
|
||||
unsigned long test_mtu = 1442;
|
||||
|
||||
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);
|
||||
|
||||
/* Send route add */
|
||||
rtsock_send_rtm(c->rtsock_fd, rtm);
|
||||
rtm = rtsock_read_rtm_reply(c->rtsock_fd, buffer, sizeof(buffer), rtm->rtm_seq);
|
||||
|
||||
/* Change MTU */
|
||||
prepare_route_message(rtm, RTM_CHANGE, (struct sockaddr *)&net6,
|
||||
(struct sockaddr *)&mask6, NULL);
|
||||
rtm->rtm_inits |= RTV_MTU;
|
||||
rtm->rtm_rmx.rmx_mtu = test_mtu;
|
||||
|
||||
rtsock_send_rtm(c->rtsock_fd, rtm);
|
||||
rtm = rtsock_read_rtm_reply(c->rtsock_fd, buffer, sizeof(buffer), rtm->rtm_seq);
|
||||
|
||||
verify_route_message(rtm, RTM_CHANGE, (struct sockaddr *)&net6,
|
||||
(struct sockaddr *)&mask6, NULL);
|
||||
|
||||
RTSOCK_ATF_REQUIRE_MSG(rtm, rtm->rtm_rmx.rmx_mtu == test_mtu,
|
||||
"expected mtu: %lu, got %lu", test_mtu, rtm->rtm_rmx.rmx_mtu);
|
||||
|
||||
/* Verify the change has actually taken place */
|
||||
prepare_route_message(rtm, RTM_GET, (struct sockaddr *)&net6,
|
||||
(struct sockaddr *)&mask6, NULL);
|
||||
|
||||
rtsock_send_rtm(c->rtsock_fd, rtm);
|
||||
rtm = rtsock_read_rtm_reply(c->rtsock_fd, buffer, sizeof(buffer), rtm->rtm_seq);
|
||||
|
||||
RTSOCK_ATF_REQUIRE_MSG(rtm, rtm->rtm_rmx.rmx_mtu == test_mtu,
|
||||
"expected mtu: %lu, got %lu", test_mtu, rtm->rtm_rmx.rmx_mtu);
|
||||
}
|
||||
|
||||
ATF_TC_WITH_CLEANUP(rtm_add_v4_temporal1_success);
|
||||
ATF_TC_HEAD(rtm_add_v4_temporal1_success, tc)
|
||||
{
|
||||
@ -1012,6 +1273,10 @@ ATF_TP_ADD_TCS(tp)
|
||||
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_del_v6_gu_prefix_nogw_success);
|
||||
ATF_TP_ADD_TC(tp, rtm_change_v4_gw_success);
|
||||
ATF_TP_ADD_TC(tp, rtm_change_v4_mtu_success);
|
||||
ATF_TP_ADD_TC(tp, rtm_change_v6_gw_success);
|
||||
ATF_TP_ADD_TC(tp, rtm_change_v6_mtu_success);
|
||||
/* ifaddr tests */
|
||||
ATF_TP_ADD_TC(tp, rtm_add_v6_gu_ifa_hostroute_success);
|
||||
ATF_TP_ADD_TC(tp, rtm_add_v6_gu_ifa_prefixroute_success);
|
||||
|
@ -38,7 +38,7 @@ jump_vnet(struct rtsock_test_config *c, const atf_tc_t *tc)
|
||||
snprintf(vnet_name, sizeof(vnet_name), "vt-%s", atf_tc_get_ident(tc));
|
||||
RLOG("jumping to %s", vnet_name);
|
||||
|
||||
vnet_switch(vnet_name, c->ifname);
|
||||
vnet_switch_one(vnet_name, c->ifname);
|
||||
|
||||
/* Update ifindex cache */
|
||||
c->ifindex = if_nametoindex(c->ifname);
|
||||
@ -50,7 +50,7 @@ presetup_ipv6(const atf_tc_t *tc)
|
||||
struct rtsock_test_config *c;
|
||||
int ret;
|
||||
|
||||
c = config_setup(tc);
|
||||
c = config_setup(tc, NULL);
|
||||
|
||||
jump_vnet(c, tc);
|
||||
|
||||
@ -70,7 +70,7 @@ presetup_ipv4(const atf_tc_t *tc)
|
||||
struct rtsock_test_config *c;
|
||||
int ret;
|
||||
|
||||
c = config_setup(tc);
|
||||
c = config_setup(tc, NULL);
|
||||
|
||||
jump_vnet(c, tc);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user