diff --git a/include/node.h b/include/node.h
index 089010198..29ecc7592 100644
--- a/include/node.h
+++ b/include/node.h
@@ -38,6 +38,9 @@ enum node_type
  */
 struct node
 {
+	/** A system-wide unique id per node */
+	int id;
+
 	/** The socket descriptor */
 	int sd;
 
@@ -66,24 +69,6 @@ struct node
 	struct node *next;
 };
 
-/** Create a new node.
- *
- * Memory is allocated dynamically and has to be freed by node_destroy()
- *
- * @param n A pointer to the node structure.
- * @param name An acroynm which describes the node.
- * @param type The type of a node (server, simulator, workstation).
- * @param local The local address of this node.
- *	This is where to server is listening for the arrival of new messages.
- * @param remote The local address of this node.
- * 	This is where messages are sent to.
- * @return
- *  - 0 on success
- *  - otherwise on error occured
- */
-int node_create(struct node *n, const char *name, enum node_type type,
-	struct sockaddr_in local, struct sockaddr_in remote);
-
 /** Connect and bind the UDP socket of this node
  *
  * @param n A pointer to the node structure
diff --git a/include/path.h b/include/path.h
index 723c67904..d96e89850 100644
--- a/include/path.h
+++ b/include/path.h
@@ -51,17 +51,6 @@ struct path
 	struct path *next;
 };
 
-/** Setup a new path.
- *
- * @param p A pointer to the path structure
- * @param in The node we are receiving messages from
- * @param out The destination node
- * @return
- *  - 0 on success
- *  - otherwise an error occured
- */
-int path_create(struct path *p, struct node *in, struct node *out);
-
 /** Start a path.
  *
  * Start a new pthread for receiving/sending messages over this path.
diff --git a/src/cfg.c b/src/cfg.c
index c233c872f..5197bb8e9 100644
--- a/src/cfg.c
+++ b/src/cfg.c
@@ -12,6 +12,7 @@
 #include <grp.h>
 #include <pwd.h>
 
+#include "if.h"
 #include "cfg.h"
 #include "node.h"
 #include "path.h"
@@ -100,8 +101,6 @@ int config_parse_global(config_setting_t *cfg, struct settings *set)
 int config_parse_path(config_setting_t *cfg,
 	struct path **paths, struct node *nodes)
 {
-	struct path *path;
-	struct node *in, *out;
 	const char *in_str = NULL;
 	const char *out_str = NULL;
 	int enabled = 1;
@@ -111,6 +110,12 @@ int config_parse_path(config_setting_t *cfg,
 	config_setting_lookup_bool(cfg, "enabled", &enabled);
 	config_setting_lookup_bool(cfg, "reverse", &reverse);
 
+	struct path *path = (struct path *) malloc(sizeof(struct path));
+	if (!path)
+		error("Failed to allocate memory for path");
+	else
+		memset(path, 0, sizeof(struct path));
+
 	/* Required settings */
 	if (!config_setting_lookup_string(cfg, "in", &in_str))
 		cerror(cfg, "Missing input node for path");
@@ -120,85 +125,93 @@ int config_parse_path(config_setting_t *cfg,
 
 	info("Loading path from '%s' to '%s'", in_str, out_str);
 
-	in = node_lookup_name(in_str, nodes);
-	if (!in)
+	path->in = node_lookup_name(in_str, nodes);
+	if (!path->in)
 		cerror(cfg, "Invalid input node '%s'");
 
-	out = node_lookup_name(out_str, nodes);
-	if (!out)
+	path->out = node_lookup_name(out_str, nodes);
+	if (!path->out)
 		cerror(cfg, "Invalid output node '%s'", out_str);
 
+	path->cfg = cfg;
+
 	if (enabled) {
-		path = (struct path *) malloc(sizeof(struct path));
-		if (!path)
-			error("Failed to allocate memory for path");
-
-		if (path_create(path, in, out))
-			cerror(cfg, "Failed to parse path");
-
-		path->cfg = cfg;
 		list_add(*paths, path);
 
 		if (reverse) {
-			path = (struct path *) malloc(sizeof(struct path));
-			if (!path)
+			struct path *path_rev = (struct path *) malloc(sizeof(struct path));
+			if (!path_rev)
 				error("Failed to allocate memory for path");
+			else
+				memcpy(path_rev, path, sizeof(struct path));
 
-			if (path_create(path, out, in))
-				cerror(cfg, "Failed to parse path");
-			path->cfg = cfg;
-			list_add(*paths, path);
+			path_rev->in = path->out; /* Swap in/out */
+			path_rev->out = path->in;
+				
+			list_add(*paths, path_rev);
 		}
 	}
-	else
+	else {
+		free(path);
 		warn("  Path is not enabled");
+	}
+
+	return 0;
 }
 
 int config_parse_node(config_setting_t *cfg, struct node **nodes)
 {
-	const char *name = NULL;
 	const char *type_str = NULL;
 	const char *remote_str = NULL;
 	const char *local_str = NULL;
 
 	struct node *node;
-	struct sockaddr_in local, remote;
-	enum node_type type;
-
-	/* Required settings */
-	name = config_setting_name(cfg);
-	if (!name)
-		cerror(cfg, "Missing node name");
-
-	if (!config_setting_lookup_string(cfg, "type", &type_str))
-		cerror(cfg, "Missing node type");
-
-	if (!config_setting_lookup_string(cfg, "remote", &remote_str))
-		cerror(cfg, "Missing node remote address");
-
-	if (!config_setting_lookup_string(cfg, "local", &local_str))
-		cerror(cfg, "Missing node local address");
-
-	type = node_lookup_type(type_str);
-	if (type == NODE_INVALID)
-		cerror(cfg, "Invalid node type '%s'", type);
-
-	info("Loading %s node '%s'", type_str, name);
-
-	if (resolve_addr(local_str, &local, 0))
-		cerror(cfg, "Failed to resolve local address '%s' of node '%s'", local_str, name);
-
-	if (resolve_addr(remote_str, &remote, 0))
-		cerror(cfg, "Failed to resolve remote address '%s' of node '%s'", remote_str, name);
 
+	/* Allocate memory */
 	node = (struct node *) malloc(sizeof(struct node));
 	if (!node)
 		error("Failed to allocate memory for node");
+	else
+		memset(node, 0, sizeof(struct node));
 
-	if (node_create(node, name, type, local, remote))
-		cerror(cfg, "Failed to parse node");
+	/* Required settings */
+	node->name = config_setting_name(cfg);
+	if (!node->name)
+		cerror(cfg, "Missing node name");
+
+	if (!config_setting_lookup_int(cfg, "id", &node->id))
+		cerror(cfg, "Missing id for node '%s'", node->name);
+
+	if (!config_setting_lookup_string(cfg, "type", &type_str))
+		cerror(cfg, "Missing type for node '%s'", node->name);
+
+	if (!config_setting_lookup_string(cfg, "remote", &remote_str))
+		cerror(cfg, "Missing remote address for node '%s'", node->name);
+
+	if (!config_setting_lookup_string(cfg, "local", &local_str))
+		cerror(cfg, "Missing local address for node '%s'", node->name);
+
+	node->type = node_lookup_type(type_str);
+	if (node->type == NODE_INVALID)
+		cerror(cfg, "Invalid type '%s' for node '%s'", type_str, node->name);
+
+	if (resolve_addr(local_str, &node->local, 0))
+		cerror(cfg, "Failed to resolve local address '%s' of node '%s'", local_str, node->name);
+
+	if (resolve_addr(remote_str, &node->remote, 0))
+		cerror(cfg, "Failed to resolve remote address '%s' of node '%s'", remote_str, node->name);
+
+	if (!config_setting_lookup_string(cfg, "interface", &node->ifname)) {
+		node->ifname = if_addrtoname((struct sockaddr*) &node->local);
+	}
+
+	node->cfg = cfg;
+	node->ifindex = if_nametoindex(node->ifname);
+	node->mark = node->ifindex + 8000;
 
 	list_add(*nodes, node);
 
-	node->cfg = cfg;
+	debug(3, "Loaded %s node '%s'", type_str, node->name);
+
+	return 0;
 }
diff --git a/src/node.c b/src/node.c
index 9253d9a50..71ac296f3 100644
--- a/src/node.c
+++ b/src/node.c
@@ -21,22 +21,6 @@
 #include "node.h"
 #include "if.h"
 
-int node_create(struct node *n, const char *name, enum node_type type,
-	struct sockaddr_in local, struct sockaddr_in remote)
-{
-	n->name = name;
-	n->type = type;
-
-	n->local = local;
-	n->remote = remote;
-
-	/* We use to local address to determine the outgoing interface */
-	//n->ifname = if_addrtoname((struct sockaddr*) &local);
-	//n->ifindex = if_nametoindex(n->ifname);
-
-	return 0;
-}
-
 int node_connect(struct node *n)
 {
 	/* Create socket */
diff --git a/src/path.c b/src/path.c
index 861da62c7..e1023a282 100644
--- a/src/path.c
+++ b/src/path.c
@@ -13,21 +13,6 @@
 #include "utils.h"
 #include "path.h"
 
-int path_create(struct path *p, struct node *in, struct node *out)
-{
-	/* Reset counters */
-	p->received = 0;
-	p->delayed = 0;
-	p->duplicated = 0;
-
-	p->hook = NULL;
-
-	p->in = in;
-	p->out = out;
-
-	return 0;
-}
-
 /**
  * @brief This is the main thread function per path
  */
diff --git a/src/receive.c b/src/receive.c
index 779d92871..048ba9f65 100644
--- a/src/receive.c
+++ b/src/receive.c
@@ -30,6 +30,10 @@ void quit(int sig, siginfo_t *si, void *ptr)
 
 int main(int argc, char *argv[])
 {
+	struct node n;
+	struct msg m;
+
+	memset(&n, 0, sizeof(struct node));
  	struct sockaddr_in sa;
 
 	if (argc != 2) {
@@ -40,8 +44,6 @@ int main(int argc, char *argv[])
 		exit(EXIT_FAILURE);
 	}
 
-	const char *local_str = argv[1];
-
 	/* Setup signals */
 	struct sigaction sa_quit = {
 		.sa_flags = SA_SIGINFO,
@@ -53,21 +55,14 @@ int main(int argc, char *argv[])
 	sigaction(SIGINT, &sa_quit, NULL);
 
 	/* Resolve addresses */
-	struct sockaddr_in local;
- 	struct sockaddr_in remote;
-
-	if (resolve_addr(local_str, &local, 0))
-		error("Failed to resolve remote address: %s", local_str);
+	if (resolve_addr(argv[1], &n.local, 0))
+		error("Failed to resolve local address: %s", argv[1]);
 
 	/* Print header */
 	fprintf(stderr, "# %-6s %-8s %-12s\n", "dev_id", "seq_no", "data");
 
-	/* Create node */
-	struct node n;
-	node_create(&n, NULL, NODE_SERVER, local, remote);
 	node_connect(&n);
 
-	struct msg m;
 	while (1) {
 		msg_recv(&m, &n);
 		msg_fprint(stdout, &m);
diff --git a/src/send.c b/src/send.c
index 277a234a6..0b6e6f9b8 100644
--- a/src/send.c
+++ b/src/send.c
@@ -42,9 +42,12 @@ int main(int argc, char *argv[])
 		exit(EXIT_FAILURE);
 	}
 
-	int values = atoi(argv[1]);
-	const char *remote_str = argv[2];
-	const char *local_str = argv[3];
+	struct node n;
+	struct msg m = {
+		.length = atoi(argv[1]) * sizeof(double)
+	};
+
+	memset(&n, 0, sizeof(struct node));
 
 	/* Setup signals */
 	struct sigaction sa_quit = {
@@ -57,28 +60,19 @@ int main(int argc, char *argv[])
 	sigaction(SIGINT, &sa_quit, NULL);
 
 	/* Resolve addresses */
- 	struct sockaddr_in local;
-	struct sockaddr_in remote;
+	if (resolve_addr(argv[2], &n.remote, 0))
+		error("Failed to resolve remote address: %s", argv[2]);
 
-	if (argc == 4 && resolve_addr(remote_str, &remote, 0))
-		error("Failed to resolve local address: %s", local_str);
+	if (argc == 4 && resolve_addr(argv[3], &n.local, 0))
+		error("Failed to resolve local address: %s", argv[3]);
 	else {
-		local.sin_family = AF_INET;
-		local.sin_addr.s_addr = INADDR_ANY;
-		local.sin_port = 0;
+		n.local.sin_family = AF_INET;
+		n.local.sin_addr.s_addr = INADDR_ANY;
+		n.local.sin_port = 0;
 	}
 
-	if (resolve_addr(remote_str, &remote, 0))
-		error("Failed to resolve remote address: %s", remote_str);
-
-	/* Create node */
-	struct node n;
-	node_create(&n, NULL, NODE_SERVER, local, remote);
 	node_connect(&n);
 
-	struct msg m;
-	m.length = values * sizeof(double);
-
 	while (!feof(stdin)) {
 		msg_fscan(stdin, &m);
 		msg_send(&m, &n);
diff --git a/src/test.c b/src/test.c
index 386dbd5bf..1d306de96 100644
--- a/src/test.c
+++ b/src/test.c
@@ -27,6 +27,10 @@ void quit(int sig, siginfo_t *si, void *ptr)
 
 int main(int argc, char *argv[])
 {
+	struct node n;
+
+	memset(&n, 0, sizeof(struct node));
+
 	if (argc != 4) {
 		printf("Usage: %s TEST LOCAL REMOTE\n", argv[0]);
 		printf("  TEST     has to be 'latency' for now\n");
@@ -37,10 +41,6 @@ int main(int argc, char *argv[])
 		exit(EXIT_FAILURE);
 	}
 
-	const char *test = argv[1];
-	const char *local_str = argv[2];
-	const char *remote_str = argv[3];
-
 	/* Setup signals */
 	struct sigaction sa_quit = {
 		.sa_flags = SA_SIGINFO,
@@ -52,24 +52,18 @@ int main(int argc, char *argv[])
 	sigaction(SIGINT, &sa_quit, NULL);
 
 	/* Resolve addresses */
-	struct sockaddr_in local;
- 	struct sockaddr_in remote;
+	if (resolve_addr(argv[2], &n.local, 0))
+		error("Failed to resolve local address: %s", argv[2]);
 
-	if (resolve_addr(local_str, &local, 0))
-		error("Failed to resolve local address: %s", local_str);
+	if (resolve_addr(argv[3], &n.remote, 0))
+		error("Failed to resolve remote address: %s", argv[3]);
 
-	if (resolve_addr(remote_str, &remote, 0))
-		error("Failed to resolve remote address: %s", remote_str);
-
-	/* Create node */
-	struct node n;
-	node_create(&n, NULL, NODE_SERVER, local, remote);
 	node_connect(&n);
 
 	debug(1, "We listen at %s:%u", inet_ntoa(n.local.sin_addr), ntohs(n.local.sin_port));
 	debug(1, "We sent to %s:%u", inet_ntoa(n.remote.sin_addr), ntohs(n.remote.sin_port));
 
-	if (!strcmp(test, "latency")) {
+	if (!strcmp(argv[1], "latency")) {
 		struct msg m2, m1 = {
 			.device = 99,
 			.sequence = 0