commit 7ec86efc4ed1c6a8e112e5afca6c5c310a34ef27
parent b939f76bbb2fc40c1996c1296b9e2febb2a98c6e
Author: Robin Bron <robin@finwo.nl>
Date: Sun, 26 Feb 2023 01:09:53 +0100
Data being transferred through the bond again
Diffstat:
9 files changed, 351 insertions(+), 256 deletions(-)
diff --git a/src/main.c b/src/main.c
@@ -22,8 +22,6 @@
#include "task/bond.h"
/* #include "socket.h" */
-#define RCVBUFSIZ 65536
-
static const char *const usage[] = {
__NAME " [options]",
NULL
@@ -118,223 +116,7 @@ static const char *const usage[] = {
/* pthread_mutex_unlock(&(iface->bond->mtx_rt)); */
/* } */
-/* void * thread_iface(void *arg) { */
-/* struct pmlag_iface *iface = (struct pmlag_iface *)arg; */
-
-/* // Open socket for the interface in the bond */
-/* iface->sockfd = sockraw_open(iface->name); */
-/* if (iface->sockfd < 0) { */
-/* pthread_exit(NULL); */
-/* return NULL; */
-/* } */
-
-/* // Reserve receive buffer, support 64k packets just in case */
-/* int buflen; */
-/* unsigned char *buffer = (unsigned char *) malloc(RCVBUFSIZ); */
-/* struct sockaddr saddr; */
-/* int saddr_len = sizeof(saddr); */
-
-/* // Get the interface's idx on the socket */
-/* iface->ifidx = iface_idx(iface->sockfd, iface->name); */
-
-/* /1* printf("Thread started for iface: %s->%s(%d)\n", iface->bond->name, iface->name, iface->sockfd); *1/ */
-
-/* // Wait for the bond thread to finish initializing */
-/* pthread_mutex_lock(&(iface->bond->mtx_rt)); */
-/* pthread_mutex_unlock(&(iface->bond->mtx_rt)); */
-
-/* // Find bond socket iface_idx */
-/* int send_len; */
-/* uint16_t proto; */
-/* uint16_t bcidx; */
-
-/* size_t rt_len; */
-
-/* while(1) { */
-
-/* // Zero out buffer, to prevent pollution, & receive packet {{{ */
-/* /1* memset(buffer, 0, RCVBUFSIZ); *1/ */
-/* buflen = recvfrom(iface->sockfd, buffer, RCVBUFSIZ, 0, &saddr, (socklen_t *)&saddr_len); */
-/* if (buflen < 0) { */
-/* perror("recvfrom"); */
-/* pthread_exit(NULL); */
-/* return NULL; */
-/* } */
-/* // }}} */
-
-/* printf("%.2x:%.2x:%.2x:%.2x:%.2x:%.2x < %.2x:%.2x:%.2x:%.2x:%.2x:%.2x, %.4x (%d)\n", */
-/* buffer[0],buffer[1],buffer[2],buffer[3],buffer[ 4],buffer[ 5], // DST */
-/* buffer[6],buffer[7],buffer[8],buffer[9],buffer[10],buffer[11], // SRC */
-/* ((unsigned int)((unsigned char)buffer[12]) << 8) + buffer[13], // PROTO */
-/* buflen */
-/* ); */
-
-/* // Update routing table if our custom protocol is seen */
-/* proto = ((uint16_t)((unsigned char)buffer[(ETH_ALEN*2)+0]) << 8) + buffer[(ETH_ALEN*2)+1]; */
-/* if (proto == 0x0666) { */
-/* bcidx = ((uint16_t)((unsigned char)buffer[(ETH_ALEN*2)+2]) << 8) + buffer[(ETH_ALEN*2)+3]; */
-/* iface_add_rt(iface, buffer+ETH_ALEN, bcidx); */
-/* continue; */
-/* } else { */
-/* iface_add_rt(iface, buffer+ETH_ALEN, 0); */
-/* } */
-
-/* /1* trim_rt(iface->bond, *1/ */
-/* rt_len = btree_count(iface->bond->rt); */
-/* printf("Current RT length: %ld\n", rt_len); */
-
-/* // Redirect packet to bond socket as-is */
-/* send_len = write(iface->bond->sockfd, buffer, buflen); */
-/* if (buflen != send_len) { */
-/* perror("write(bond)"); */
-/* /1* pthread_exit(NULL); *1/ */
-/* /1* return NULL; *1/ */
-/* } */
-
-/* } */
-
-/* pthread_exit(NULL); */
-/* return NULL; */
-/* } */
-
-/* void * thread_bond(void *arg) { */
-/* struct pmlag_bond *bond = (struct pmlag_bond *)arg; */
-/* /1* printf("Thread started for bond: %s\n", bond->name); *1/ */
-
-/* // Assign bond interface */
-/* unsigned char *mac = iface_mac(bond->interfaces->name); */
-/* bond->sockfd = tap_alloc(bond->name, mac); */
-/* printf("FREE LINE %d (%p)\n", __LINE__, mac); */
-/* free(mac); */
-/* if (bond->sockfd < 0) { */
-/* perror("Allocating bond interface"); */
-/* pthread_exit(NULL); */
-/* return NULL; */
-/* }; */
-
-/* // Lock this bond's routing table */
-/* pthread_mutex_lock(&(bond->mtx_rt)); */
-
-/* // Start thread for each interface of this bond */
-/* struct pmlag_iface *iface = bond->interfaces; */
-/* while(iface) { */
-/* if(pthread_create(&(iface->tid), NULL, thread_iface, iface)) { */
-/* perror("Starting iface thread"); */
-/* pthread_exit((void*)1); */
-/* return (void*)1; */
-/* } */
-/* iface = iface->next; */
-/* } */
-
-/* // Give iface threads time to run into the lock */
-/* /1* sleep(1); *1/ */
-/* // Free this bond's routing table */
-/* pthread_mutex_unlock(&(bond->mtx_rt)); */
-
-/* int buflen, send_len; */
-/* unsigned char *buffer = (unsigned char *) malloc(RCVBUFSIZ); */
-/* struct sockaddr_ll saddr_ll; */
-/* saddr_ll.sll_halen = ETH_ALEN; */
-
-/* struct pmlag_rt_entry *rt_entry; */
-/* int iface_list_len; */
-/* int iface_list_sel; */
-/* pmlag_iface_llist *iface_list_entry; */
-
-/* sleep(1); */
-
-/* while(1) { */
-/* /1* sleep(1); *1/ */
-
-/* buflen = read(bond->sockfd, buffer, RCVBUFSIZ); */
-/* if (buflen < 0) { */
-/* perror("read(bond)"); */
-/* pthread_exit(NULL); */
-/* return NULL; */
-/* } */
-
-/* /1* printf("\n"); *1/ */
-/* /1* printf("Got packet: %d bytes\n", buflen); *1/ */
-
-/* /1* printf("Ethernet header\n"); *1/ */
-/* printf("%.2x:%.2x:%.2x:%.2x:%.2x:%.2x > %.2x:%.2x:%.2x:%.2x:%.2x:%.2x, %.4x (%d)\n", */
-/* buffer[6],buffer[7],buffer[8],buffer[9],buffer[10],buffer[11], // SRC */
-/* buffer[0],buffer[1],buffer[2],buffer[3],buffer[ 4],buffer[ 5], // DST */
-/* ((unsigned int)((unsigned char)buffer[12]) << 8) + buffer[13], // PROTO */
-/* buflen */
-/* ); */
-
-/* // Insert destination MAC into saddr_ll */
-/* memcpy(saddr_ll.sll_addr, buffer, ETH_ALEN); */
-
-/* // Fetch entry from routing table */
-/* pthread_mutex_lock(&(bond->mtx_rt)); */
-/* rt_entry = btree_get(bond->rt, &(struct pmlag_rt_entry){ .mac = buffer }); */
-
-/* // Broadcast on ALL interfaces if no rt entry OR broadcast packet */
-/* if ((!rt_entry) || (memcmp(buffer, "\xFF\xFF\xFF\xFF\xFF\xFF", ETH_ALEN) == 0)) { */
-/* pthread_mutex_unlock(&(bond->mtx_rt)); */
-/* iface = bond->interfaces; */
-/* while(iface) { */
-/* saddr_ll.sll_ifindex = iface->ifidx; */
-/* send_len = sendto(iface->sockfd, buffer, buflen, 0, (const struct sockaddr*)&saddr_ll, sizeof(struct sockaddr_ll)); */
-/* if(send_len != buflen) { */
-/* perror("sendto"); */
-/* /1* pthread_exit(NULL); *1/ */
-/* /1* return NULL; *1/ */
-/* } */
-/* iface = iface->next; */
-/* } */
-/* continue; */
-/* } */
-
-/* // Fetch length of interface list */
-/* iface_list_len = 0; */
-/* iface_list_entry = rt_entry->interfaces; */
-/* while(iface_list_entry) { */
-/* iface_list_len++; */
-/* iface_list_entry = iface_list_entry->next; */
-/* } */
-
-/* // Select interface at random */
-/* iface_list_sel = rand() % iface_list_len; */
-/* iface_list_entry = rt_entry->interfaces; */
-/* while(iface_list_sel--) iface_list_entry = iface_list_entry->next; */
-/* iface = iface_list_entry->data; */
-
-/* // Unlock routing table */
-/* pthread_mutex_unlock(&(bond->mtx_rt)); */
-
-/* // Prepare saddr_ll for sendto */
-/* saddr_ll.sll_ifindex = iface->ifidx; */
-/* memcpy(saddr_ll.sll_addr, buffer, ETH_ALEN); */
-
-/* // Forward packet to iface as-is */
-/* send_len = sendto(iface->sockfd, buffer, buflen, 0, (const struct sockaddr*)&saddr_ll, sizeof(struct sockaddr_ll)); */
-/* if(send_len != buflen) { */
-/* perror("sendto"); */
-/* /1* pthread_exit(NULL); *1/ */
-/* /1* return NULL; *1/ */
-/* } */
-/* } */
-
-/* // Wait for iface threads to finish */
-/* iface = bond->interfaces; */
-/* while(iface) { */
-/* pthread_join(iface->tid, NULL); */
-/* iface = iface->next; */
-/* } */
-
-/* pthread_exit(NULL); */
-/* return NULL; */
-/* } */
-
-/* static int compare_rt_entries(const void *a, const void *b, void *udata) { */
-/* struct pmlag_rt_entry *ta = (struct pmlag_rt_entry*)a; */
-/* struct pmlag_rt_entry *tb = (struct pmlag_rt_entry*)b; */
-/* return memcmp(ta->mac, tb->mac, ETH_ALEN); */
-/* } */
int main(int argc, const char **argv) {
char *config_file="/etc/pmlag/pmlag.ini";
@@ -357,8 +139,6 @@ int main(int argc, const char **argv) {
);
argc = argparse_parse(&argparse, argc, argv);
- printf("config file: %s\n", config_file);
-
// Load configuration file
struct pmlag_configuration *config = config_load(config_file);
if (!config) {
@@ -369,15 +149,6 @@ int main(int argc, const char **argv) {
struct pmlag_bond *bond = config->bonds;
while(bond) {
- /* // Initialize routing table lock */
- /* if (pthread_mutex_init(&(bond->mtx_rt), NULL) != 0) { */
- /* perror("Initializing mutex for bond"); */
- /* return 1; */
- /* } */
-
- /* // Initialize routing table */
- /* bond->rt = btree_new(sizeof(void*), 0, compare_rt_entries, bond); */
-
// Start the bond's thread
if(pthread_create(&(bond->tid), NULL, task_bond_thread, bond)) {
perror("Starting bond thread");
diff --git a/src/task/bond.c b/src/task/bond.c
@@ -1,10 +1,203 @@
+#include <linux/if_ether.h>
+#include <linux/if_packet.h>
+#include <pthread.h>
#include <stdlib.h>
#include <stdio.h>
+#include <string.h>
+#include <sys/socket.h>
+#include <unistd.h>
+#include "tidwall/btree.h"
+#include "../util/config.h"
+#include "../util/routing-table.h"
+#include "../util/socket.h"
+#include "iface.h"
+int task_bond_onpacket(struct pmlag_bond *bond, unsigned char *buffer, size_t buflen) {
+ struct sockaddr_ll saddr_ll;
+ saddr_ll.sll_halen = ETH_ALEN;
+
+ // Debug: print eth header
+ printf("%.2x:%.2x:%.2x:%.2x:%.2x:%.2x > %.2x:%.2x:%.2x:%.2x:%.2x:%.2x, %.4x (%ld)\n",
+ buffer[6],buffer[7],buffer[8],buffer[9],buffer[10],buffer[11], // SRC
+ buffer[0],buffer[1],buffer[2],buffer[3],buffer[ 4],buffer[ 5], // DST
+ ((unsigned int)((unsigned char)buffer[12]) << 8) + buffer[13], // PROTO
+ buflen
+ );
+
+ // Send packet to the first available iface
+ struct pmlag_iface *iface = bond->interfaces->data;
+
+/* // Select interface at random */
+/* iface_list_sel = rand() % iface_list_len; */
+/* iface_list_entry = rt_entry->interfaces; */
+/* while(iface_list_sel--) iface_list_entry = iface_list_entry->next; */
+/* iface = iface_list_entry->data; */
+
+/* // Unlock routing table */
+/* pthread_mutex_unlock(&(bond->mtx_rt)); */
+
+ // Prepare saddr_ll for sendto
+ saddr_ll.sll_ifindex = iface->ifidx;
+ memcpy(saddr_ll.sll_addr, buffer, ETH_ALEN);
+
+ // Forward packet to iface as-is
+ size_t send_len = sendto(iface->sockfd, buffer, buflen, 0, (const struct sockaddr*)&saddr_ll, sizeof(struct sockaddr_ll));
+ if(send_len != buflen) {
+ perror("sendto");
+ return 1;
+ }
+
+ return 0;
+}
+
+// Responsible for init + calling task_bond_onpacket
void * task_bond_thread(void *arg) {
+ struct pmlag_bond *bond = arg;
+
+ // Initialize routing table lock
+ if (pthread_mutex_init(&(bond->mtx_rt), NULL) != 0) {
+ perror("Initializing mutex for bond");
+ pthread_exit(NULL);
+ return NULL;
+ }
+
+ // Initialize routing table
+ bond->rt = rt_init(bond);
+
+ // Assign bond interface
+ unsigned char *mac = iface_mac(bond->interfaces->data->name);
+ bond->sockfd = tap_alloc(bond->name, mac);
+ free(mac);
+ if (bond->sockfd < 0) {
+ perror("Allocating bond interface");
+ pthread_exit(NULL);
+ return NULL;
+ };
+
+ // Lock this bond's routing table
+ pthread_mutex_lock(&(bond->mtx_rt));
+
+ // Start thread for each interface of this bond
+ pmlag_iface_llist *iface_entry = bond->interfaces;
+ while(iface_entry) {
+ if(pthread_create(&(iface_entry->data->tid), NULL, task_iface_thread, iface_entry->data)) {
+ perror("Starting iface thread");
+ pthread_exit((void*)1);
+ return (void*)1;
+ }
+ iface_entry = iface_entry->next;
+ }
+
+ // Free this bond's routing table
+ pthread_mutex_unlock(&(bond->mtx_rt));
+
+ // Predefine things we'll re-use
+ size_t buflen;
+ unsigned char *buffer = (unsigned char *) malloc(RCVBUFSIZ);
+
+ // TODO: replace by waiting for the iface to finish initializing
+ sleep(1);
+
+ // This is our life now
+ while(1) {
+
+ // Wait for a packet to arrive
+ buflen = read(bond->sockfd, buffer, RCVBUFSIZ);
+ if (buflen < 0) {
+ perror("read(bond)");
+ pthread_exit(NULL);
+ return NULL;
+ }
+
+ // And let the more specific method handle the packet
+ if(task_bond_onpacket(bond, buffer, buflen)) {
+ pthread_exit(NULL);
+ return NULL;
+ }
+
+ }
+
+ // Wait for iface threads to finish
+ iface_entry = bond->interfaces;
+ while(iface_entry) {
+ pthread_join(iface_entry->data->tid, NULL);
+ iface_entry = iface_entry->next;
+ }
+
+ pthread_exit(NULL);
+ return NULL;
+}
+
+void * thread_bond_old(void *arg) {
+/* struct pmlag_rt_entry *rt_entry; */
+/* int iface_list_len; */
+/* int iface_list_sel; */
+/* pmlag_iface_llist *iface_list_entry; */
+
+/* sleep(1); */
+
+/* while(1) { */
+/* /1* sleep(1); *1/ */
+
+/* // Fetch entry from routing table */
+/* pthread_mutex_lock(&(bond->mtx_rt)); */
+/* rt_entry = btree_get(bond->rt, &(struct pmlag_rt_entry){ .mac = buffer }); */
+
+/* // Broadcast on ALL interfaces if no rt entry OR broadcast packet */
+/* if ((!rt_entry) || (memcmp(buffer, "\xFF\xFF\xFF\xFF\xFF\xFF", ETH_ALEN) == 0)) { */
+/* pthread_mutex_unlock(&(bond->mtx_rt)); */
+/* iface = bond->interfaces; */
+/* while(iface) { */
+/* saddr_ll.sll_ifindex = iface->ifidx; */
+/* send_len = sendto(iface->sockfd, buffer, buflen, 0, (const struct sockaddr*)&saddr_ll, sizeof(struct sockaddr_ll)); */
+/* if(send_len != buflen) { */
+/* perror("sendto"); */
+/* /1* pthread_exit(NULL); *1/ */
+/* /1* return NULL; *1/ */
+/* } */
+/* iface = iface->next; */
+/* } */
+/* continue; */
+/* } */
+
+/* // Fetch length of interface list */
+/* iface_list_len = 0; */
+/* iface_list_entry = rt_entry->interfaces; */
+/* while(iface_list_entry) { */
+/* iface_list_len++; */
+/* iface_list_entry = iface_list_entry->next; */
+/* } */
+
+/* // Select interface at random */
+/* iface_list_sel = rand() % iface_list_len; */
+/* iface_list_entry = rt_entry->interfaces; */
+/* while(iface_list_sel--) iface_list_entry = iface_list_entry->next; */
+/* iface = iface_list_entry->data; */
+
+/* // Unlock routing table */
+/* pthread_mutex_unlock(&(bond->mtx_rt)); */
+
+/* // Prepare saddr_ll for sendto */
+/* saddr_ll.sll_ifindex = iface->ifidx; */
+/* memcpy(saddr_ll.sll_addr, buffer, ETH_ALEN); */
+
+/* // Forward packet to iface as-is */
+/* send_len = sendto(iface->sockfd, buffer, buflen, 0, (const struct sockaddr*)&saddr_ll, sizeof(struct sockaddr_ll)); */
+/* if(send_len != buflen) { */
+/* perror("sendto"); */
+/* /1* pthread_exit(NULL); *1/ */
+/* /1* return NULL; *1/ */
+/* } */
+/* } */
- printf("Thread started!\n");
+ /* // Wait for iface threads to finish */
+ /* iface = bond->interfaces; */
+ /* while(iface) { */
+ /* pthread_join(iface->tid, NULL); */
+ /* iface = iface->next; */
+ /* } */
+ pthread_exit(NULL);
return NULL;
}
diff --git a/src/task/iface.c b/src/task/iface.c
@@ -0,0 +1,104 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/socket.h>
+#include <unistd.h>
+
+#include "../util/config.h"
+#include "../util/socket.h"
+
+void * task_iface_thread(void *arg) {
+ struct pmlag_iface *iface = arg;
+
+ // Open socket for the interface in the bond
+ iface->sockfd = sockraw_open(iface->name);
+ if (iface->sockfd < 0) {
+ pthread_exit(NULL);
+ return NULL;
+ }
+
+ // Get the interface's idx on the socket
+ iface->ifidx = iface_idx(iface->sockfd, iface->name);
+
+ // Reserve receive buffer, support 64k packets just in case
+ size_t buflen, send_len;
+ unsigned char *buffer = (unsigned char *) malloc(RCVBUFSIZ);
+ struct sockaddr saddr;
+ int saddr_len = sizeof(saddr);
+
+ // Wait for the bond thread to finish initializing
+ pthread_mutex_lock(&(iface->bond->mtx_rt));
+ pthread_mutex_unlock(&(iface->bond->mtx_rt));
+
+ printf("Thread started for iface %s\n", iface->name);
+
+ // This is our life now
+ while(1) {
+
+ // Zero out buffer, to prevent pollution, & receive packet
+ memset(buffer, 0, RCVBUFSIZ);
+ buflen = recvfrom(iface->sockfd, buffer, RCVBUFSIZ, 0, &saddr, (socklen_t *)&saddr_len);
+ if (buflen < 0) {
+ perror("recvfrom");
+ pthread_exit(NULL);
+ return NULL;
+ }
+
+ // Debug: print eth header
+ printf("%.2x:%.2x:%.2x:%.2x:%.2x:%.2x < %.2x:%.2x:%.2x:%.2x:%.2x:%.2x, %.4x (%ld)\n",
+ buffer[0],buffer[1],buffer[2],buffer[3],buffer[ 4],buffer[ 5], // DST
+ buffer[6],buffer[7],buffer[8],buffer[9],buffer[10],buffer[11], // SRC
+ ((unsigned int)((unsigned char)buffer[12]) << 8) + buffer[13], // PROTO
+ buflen
+ );
+
+ // Redirect packet to bond socket as-is
+ send_len = write(iface->bond->sockfd, buffer, buflen);
+ if (buflen != send_len) {
+ perror("write(bond)");
+ pthread_exit(NULL);
+ return NULL;
+ }
+
+ /* sleep(1); */
+ }
+
+ return NULL;
+}
+
+
+
+/* /1* printf("Thread started for iface: %s->%s(%d)\n", iface->bond->name, iface->name, iface->sockfd); *1/ */
+
+
+/* // Find bond socket iface_idx */
+/* int send_len; */
+/* uint16_t proto; */
+/* uint16_t bcidx; */
+
+/* size_t rt_len; */
+
+/* while(1) { */
+
+
+
+/* // Update routing table if our custom protocol is seen */
+/* proto = ((uint16_t)((unsigned char)buffer[(ETH_ALEN*2)+0]) << 8) + buffer[(ETH_ALEN*2)+1]; */
+/* if (proto == 0x0666) { */
+/* bcidx = ((uint16_t)((unsigned char)buffer[(ETH_ALEN*2)+2]) << 8) + buffer[(ETH_ALEN*2)+3]; */
+/* iface_add_rt(iface, buffer+ETH_ALEN, bcidx); */
+/* continue; */
+/* } else { */
+/* iface_add_rt(iface, buffer+ETH_ALEN, 0); */
+/* } */
+
+/* /1* trim_rt(iface->bond, *1/ */
+/* rt_len = btree_count(iface->bond->rt); */
+/* printf("Current RT length: %ld\n", rt_len); */
+
+
+/* } */
+
+/* pthread_exit(NULL); */
+/* return NULL; */
+/* } */
diff --git a/src/task/iface.h b/src/task/iface.h
@@ -1,7 +1,7 @@
#ifndef __PMLAG_TASK_IFACE_H__
#define __PMLAG_TASK_IFACE_H__
-
+void * task_iface_thread(void *arg);
#endif // __PMLAG_TASK_IFACE_H__
diff --git a/src/util/config.c b/src/util/config.c
@@ -31,7 +31,7 @@ static int config_load_handler(
}
// Get interface being configured
- struct pmlag_iface *iface = bond->interfaces;
+ pmlag_iface_llist *iface_entry = bond->interfaces;
if (0) {
// Intentionally empty
@@ -51,28 +51,25 @@ static int config_load_handler(
} else if (!strcmp(name, "interface")) {
// Select the right interface
- while(iface) {
- if (!strcmp(iface->name, value)) {
+ while(iface_entry) {
+ if (!strcmp(iface_entry->data->name, value)) {
break;
}
- iface = iface->next;
+ iface_entry = iface_entry->next;
}
// Create iface if not found
- if (!iface) {
- iface = calloc(1, sizeof(struct pmlag_iface));
- iface->next = bond->interfaces;
- iface->name = strdup(value);
- /* iface->weight = 10; */
- iface->bond = bond;
- bond->interfaces = iface;
+ if (!iface_entry) {
+ // Create the list entry
+ iface_entry = calloc(1, sizeof(pmlag_iface_llist));
+ iface_entry->next = bond->interfaces;
+ bond->interfaces = iface_entry;
+ // Create the iface
+ iface_entry->data = calloc(1, sizeof(struct pmlag_iface));
+ iface_entry->data->name = strdup(value);
+ iface_entry->data->bond = bond;
}
- /* } else if (!strcmp(name, "weight")) { */
- /* if (!iface) { */
- /* return 0; */
- /* } */
- /* iface->weight = atoi(value); */
} else {
// Unknown key
return 0;
diff --git a/src/util/config.h b/src/util/config.h
@@ -6,6 +6,8 @@
#include "tidwall/btree.h"
+#include "linked-list.h"
+
#ifdef __cplusplus
extern "C" {
#endif
@@ -15,12 +17,11 @@ extern "C" {
#define PMLAG_MODE_BROADCAST 2
#define PMLAG_MODE_BALANCED_RR 3
-#define LLIST(x) struct { void *next; x *data; }
+#define RCVBUFSIZ 65536
typedef LLIST(struct pmlag_iface) pmlag_iface_llist;
struct pmlag_iface {
- void *next; // linked-list next reference
char *name; // name of the interface this object represents
/* int weight; // weight of this interface within the bond */
int sockfd; // file descriptor for the iface raw socket
@@ -38,13 +39,7 @@ struct pmlag_bond {
pthread_t tid; // thread id where the bond interface listener recides in
pthread_mutex_t mtx_rt; // lock for the routing table of the bond
struct btree *rt; // pointer to the routing table
- struct pmlag_iface *interfaces; // linked-list of interfaces contained in the bond
-};
-
-struct pmlag_rt_entry {
- unsigned char *mac; // mac address of the remote entity
- uint16_t bcidx; // broadcast index last seen from the mac
- pmlag_iface_llist *interfaces; // list of pointers to interfaces
+ pmlag_iface_llist *interfaces; // linked-list of interfaces contained in the bond
};
struct pmlag_configuration {
diff --git a/src/util/linked-list.h b/src/util/linked-list.h
@@ -0,0 +1,6 @@
+#ifndef __PMLAG_UTIL_LL_H__
+#define __PMLAG_UTIL_LL_H__
+
+#define LLIST(x) struct { void *next; x *data; }
+
+#endif // __PMLAG_UTIL_LL_H__
diff --git a/src/util/routing-table.c b/src/util/routing-table.c
@@ -0,0 +1,15 @@
+#include <linux/if_ether.h>
+#include <string.h>
+
+#include "tidwall/btree.h"
+#include "routing-table.h"
+
+static int compare_rt_entries(const void *a, const void *b, void *udata) {
+ struct pmlag_rt_entry *ta = (struct pmlag_rt_entry*)a;
+ struct pmlag_rt_entry *tb = (struct pmlag_rt_entry*)b;
+ return memcmp(ta->mac, tb->mac, ETH_ALEN);
+}
+
+struct btree * rt_init(void *udata) {
+ return btree_new(sizeof(void*), 0, compare_rt_entries, udata);
+}
diff --git a/src/util/routing-table.h b/src/util/routing-table.h
@@ -0,0 +1,14 @@
+#ifndef __PMLAG_UTIL_RT_H__
+#define __PMLAG_UTIL_RT_H__
+
+#include "config.h"
+
+struct pmlag_rt_entry {
+ unsigned char *mac; // mac address of the remote entity
+ uint16_t bcidx; // broadcast index last seen from the mac
+ pmlag_iface_llist *interfaces; // list of pointers to interfaces
+};
+
+struct btree * rt_init(void *udata);
+
+#endif // __PMLAG_UTIL_RT_H__