Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Initial multipath support #156

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
312 changes: 208 additions & 104 deletions gtests/net/packetdrill/config.c

Large diffs are not rendered by default.

27 changes: 6 additions & 21 deletions gtests/net/packetdrill/config.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
#include <unistd.h>
#include <getopt.h>
#include "ip_address.h"
#include "ip_prefix.h"
#include "path.h"
#include "script.h"

#define TUN_DRIVER_SPEED_CUR 0 /* don't change current speed */
Expand Down Expand Up @@ -97,26 +97,8 @@ struct config {
u16 live_bind_port; /* local port for bind() */
u16 live_connect_port; /* remote port for connect() */

struct ip_address live_bind_ip; /* address for bind() */
struct ip_address live_connect_ip; /* address for connect() */

struct ip_address live_local_ip; /* local interface IP */
struct ip_address live_local_linklocal_ip; /* IPv6 local link-local address */
struct ip_address live_remote_ip; /* remote interface IP */
struct ip_prefix live_remote_prefix; /* remote prefix under test */
struct ip_address live_gateway_ip; /* gateway interface IP */
struct ip_address live_gateway_linklocal_ip; /* IPv6 gateway link-local address */

char live_local_ip_string[ADDR_STR_LEN]; /* human-readable IP */
char live_local_linklocal_ip_string[ADDR_STR_LEN]; /* human-readable IP */
char live_remote_ip_string[ADDR_STR_LEN]; /* human-readable IP */
char live_remote_prefix_string[ADDR_STR_LEN]; /* <addr>/<prefixlen> */

char live_gateway_ip_string[ADDR_STR_LEN]; /* local gateway IP */
char live_gateway_linklocal_ip_string[ADDR_STR_LEN]; /* local gateway IP */
char live_netmask_ip_string[ADDR_STR_LEN]; /* local netmask */

int live_prefix_len; /* IPv4/IPv6 interface prefix len */
struct path *live_paths; /* the local/remote/gateway IPs for each path */
uint live_paths_cnt; /* numer of elements in live_path */

int tolerance_usecs; /* tolerance for time divergence */
int tcp_ts_tick_usecs; /* microseconds per TS val tick */
Expand Down Expand Up @@ -208,4 +190,7 @@ extern char **parse_command_line_options(int argc, char *argv[],
/* The parser calls this function to finalize processing of config info. */
extern void parse_and_finalize_config(struct invocation *invocation);

extern struct ip_address *paths_get_address(struct config *config, int addr_skip,
int address_family, enum paths_address_types address_type);

#endif /* __CONFIG_H__ */
12 changes: 1 addition & 11 deletions gtests/net/packetdrill/net_utils.c
Original file line number Diff line number Diff line change
Expand Up @@ -29,17 +29,7 @@
#include <unistd.h>

#include "logging.h"

static void verbose_system(const char *command)
{
int result;

DEBUGP("running: '%s'\n", command);
result = system(command);
DEBUGP("result: %d\n", result);
if (result != 0)
DEBUGP("error executing command '%s'\n", command);
}
#include "system.h"

/* Configure a local IPv4 address and netmask for the device */
static void net_add_ipv4_address(const char *dev_name,
Expand Down
114 changes: 56 additions & 58 deletions gtests/net/packetdrill/netdev.c
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@
#include "packet.h"
#include "packet_parser.h"
#include "packet_socket.h"
#include "system.h"
#include "tcp.h"
#include "tun.h"

Expand Down Expand Up @@ -92,23 +93,14 @@ static void cleanup_old_device(struct config *config,
{
#if defined(__NetBSD__)
char *cleanup_command = NULL;
#ifdef DEBUG
int result;
#endif

if ((config->tun_device == NULL) || config->persistent_tun_device) {
return;
}
asprintf(&cleanup_command,
"/sbin/ifconfig %s down delete > /dev/null 2>&1",
config->tun_device);
DEBUGP("running: '%s'\n", cleanup_command);
#ifdef DEBUG
result = system(cleanup_command);
#else
system(cleanup_command);
#endif
DEBUGP("result: %d\n", result);
verbose_system(cleanup_command);
free(cleanup_command);
#endif /* defined(__NetBSD__) */
}
Expand All @@ -119,9 +111,11 @@ static void cleanup_old_device(struct config *config,
static void check_remote_address(struct config *config,
struct local_netdev *netdev)
{
if (is_ip_local(&config->live_remote_ip)) {
die("error: live_remote_ip %s is not remote\n",
config->live_remote_ip_string);
for (uint i = 0; i < config->live_paths_cnt; i++) {
if (is_ip_local(&config->live_paths[i].remote_ip)) {
die("error: remote_ip %s of path %d is not remote\n",
config->live_paths[i].remote_ip_string, i);
}
}
}

Expand Down Expand Up @@ -166,8 +160,8 @@ static void create_device(struct config *config, struct local_netdev *netdev)
DEBUGP("utun index: '%d'\n", netdev->index);
if (config->mtu != TUN_DRIVER_DEFAULT_MTU) {
asprintf(&command, "ifconfig %s mtu %d", netdev->name, config->mtu);
if (system(command) < 0)
die("Error executing %s\n", command);
if(verbose_system(command) != STATUS_OK)
die("");
free(command);
}
}
Expand Down Expand Up @@ -199,7 +193,7 @@ static void create_device(struct config *config, struct local_netdev *netdev)
tun_fd = open(tun_path, O_RDWR);
#if defined(__FreeBSD__)
if ((tun_fd < 0) && (errno == ENOENT)) {
if (system("kldload -q if_tun") < 0) {
if (verbose_system("kldload -q if_tun") != STATUS_OK) {
die_perror("kldload -q if_tun");
}
tun_fd = open(tun_path, O_RDWR);
Expand Down Expand Up @@ -275,26 +269,26 @@ static void create_device(struct config *config, struct local_netdev *netdev)
char *command;
asprintf(&command, "ethtool -s %s speed %u autoneg off",
netdev->name, config->speed);
if (system(command) < 0)
die("Error executing %s\n", command);
if(verbose_system(command) != STATUS_OK)
die("");
free(command);

/* Need to bring interface down and up so the interface speed
* will be copied to the link_speed field. This field is
* used by TCP's cwnd bound. */
asprintf(&command, "ifconfig %s down; sleep 1; ifconfig %s up; "
"sleep 1", netdev->name, netdev->name);
if (system(command) < 0)
die("Error executing %s\n", command);
if(verbose_system(command) != STATUS_OK)
die("");
free(command);
}

if (config->mtu != TUN_DRIVER_DEFAULT_MTU) {
char *command;
asprintf(&command, "ifconfig %s mtu %d",
netdev->name, config->mtu);
if (system(command) < 0)
die("Error executing %s\n", command);
if(verbose_system(command) != STATUS_OK)
die("");
free(command);
}
#endif
Expand Down Expand Up @@ -350,39 +344,40 @@ static void route_traffic_to_device(struct config *config,
struct local_netdev *netdev)
{
char *route_command = NULL;

for (uint i = 0; i < config->live_paths_cnt; i++) {
struct path *path = &config->live_paths[i];

#if defined(linux)
asprintf(&route_command,
"ip route del %s > /dev/null 2>&1 ; "
"ip route add %s dev %s via %s > /dev/null 2>&1",
config->live_remote_prefix_string,
config->live_remote_prefix_string,
netdev->name,
config->live_gateway_ip_string);
#else
if (config->wire_protocol == AF_INET) {
asprintf(&route_command,
"route delete %s > /dev/null 2>&1 ; "
"route add %s %s > /dev/null",
config->live_remote_prefix_string,
config->live_remote_prefix_string,
config->live_gateway_ip_string);
} else if (config->wire_protocol == AF_INET6) {
asprintf(&route_command,
"route delete -inet6 %s > /dev/null 2>&1 ; "
"route add -inet6 %s %s > /dev/null",
config->live_remote_prefix_string,
config->live_remote_prefix_string,
config->live_gateway_ip_string);
} else {
assert(!"bad wire protocol");
}
"ip route del %s > /dev/null 2>&1 ; "
"ip route add %s dev %s via %s > /dev/null 2>&1",
path->remote_prefix_string,
path->remote_prefix_string,
netdev->name,
path->gateway_ip_string);
#else
if (config->wire_protocol == AF_INET) {
asprintf(&route_command,
"route delete %s > /dev/null 2>&1 ; "
"route add %s %s > /dev/null",
path->remote_prefix_string,
path->remote_prefix_string,
path->gateway_ip_string);
} else if (config->wire_protocol == AF_INET6) {
asprintf(&route_command,
"route delete -inet6 %s > /dev/null 2>&1 ; "
"route add -inet6 %s %s > /dev/null",
path->remote_prefix_string,
path->remote_prefix_string,
path->gateway_ip_string);
} else {
assert(!"bad wire protocol");
}
#endif /* defined(linux) */
int result = system(route_command);
if ((result == -1) || (WEXITSTATUS(result) != 0)) {
die("error executing route command '%s'\n",
route_command);
verbose_system(route_command);
free(route_command);
}
free(route_command);
}

struct netdev *local_netdev_new(struct config *config)
Expand All @@ -400,19 +395,22 @@ struct netdev *local_netdev_new(struct config *config)
bring_up_device(netdev);
#endif

net_setup_dev_address(netdev->name,
&config->live_local_ip,
config->live_prefix_len,
&config->live_local_linklocal_ip,
&config->live_gateway_ip);
for (uint i = 0; i < config->live_paths_cnt; i++) {
struct path *path = &config->live_paths[i];
net_setup_dev_address(netdev->name,
&path->local_ip,
path->prefix_len,
&path->local_linklocal_ip,
&path->gateway_ip);
}

route_traffic_to_device(config, netdev);
netdev->psock = packet_socket_new(netdev->name);
#if !defined(linux)
/* Make sure we only see packets from the machine under test. */
packet_socket_set_filter(netdev->psock,
NULL,
&config->live_local_ip); /* client IP */
config->live_paths, config->live_paths_cnt);
#endif /* !defined(linux) */

return (struct netdev *)netdev;
Expand All @@ -433,7 +431,7 @@ static void local_netdev_free(struct netdev *a_netdev)
asprintf(&cleanup_command,
"/sbin/ifconfig %s destroy > /dev/null 2>&1",
netdev->name);
system(cleanup_command);
verbose_system(cleanup_command);
free(cleanup_command);
}
#endif
Expand Down
5 changes: 5 additions & 0 deletions gtests/net/packetdrill/packet.c
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,8 @@ static struct packet *packet_copy_with_headroom(struct packet *old_packet,

packet->ip_bytes = old_packet->ip_bytes;
packet->direction = old_packet->direction;
packet->ip_src_index = old_packet->ip_src_index;
packet->ip_dst_index = old_packet->ip_dst_index;
packet->time_usecs = old_packet->time_usecs;
packet->flags = old_packet->flags;
packet->tos_chk = old_packet->tos_chk;
Expand Down Expand Up @@ -282,6 +284,9 @@ struct packet *packet_encapsulate(struct packet *outer, struct packet *inner)

packet->ip_bytes = outer->ip_bytes + inner->ip_bytes;

packet->ip_src_index = inner->ip_src_index;
packet->ip_dst_index = inner->ip_dst_index;

return packet;
}

Expand Down
2 changes: 2 additions & 0 deletions gtests/net/packetdrill/packet.h
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,8 @@ struct packet {
u32 buffer_bytes; /* bytes of space in data buffer */
u32 ip_bytes; /* bytes in outermost IP hdrs/payload */
enum direction_t direction; /* direction packet is traveling */
int ip_src_index;
int ip_dst_index;

/* Metadata about all the headers in the packet, including all
* layers of encapsulation, from outer to inner, starting from
Expand Down
3 changes: 2 additions & 1 deletion gtests/net/packetdrill/packet_socket.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
#include "ethernet.h"
#include "ip_address.h"
#include "packet.h"
#include "path.h"

struct packet_socket;

Expand All @@ -47,7 +48,7 @@ extern void packet_socket_free(struct packet_socket *packet_socket);
extern void packet_socket_set_filter(
struct packet_socket *psock,
const struct ether_addr *client_ether_addr,
const struct ip_address *client_live_ip);
const struct path *paths, uint paths_cnt);

/* Send the given packet using writev. Return STATUS_OK on success,
* or STATUS_ERR if writev returns an error.
Expand Down
Loading