pmlag

Poor man's link aggregation
git clone git://git.finwo.net/app/pmlag
Log | Files | Refs | README | LICENSE

commit 0a1cd68d615a5c6064b6de949845a37f3bdefaa1
parent 5851fbeb8f3648f336c77c47eb8c371b696bd567
Author: Robin Bron <robin@finwo.nl>
Date:   Sun, 12 Feb 2023 23:58:44 +0100

Use mutex instead of sleep to let iface threads wait for the tap to exist

Diffstat:
Msrc/config.h | 25+++++++++++++------------
Msrc/main.c | 18++++++++++++++----
2 files changed, 27 insertions(+), 16 deletions(-)

diff --git a/src/config.h b/src/config.h @@ -13,21 +13,22 @@ extern "C" { #define PMLAG_MODE_BALANCED_RR 3 struct pmlag_iface { - void *next; - char *name; - int weight; - int sockfd; - pthread_t tid; - struct pmlag_bond *bond; + 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 + pthread_t tid; // thread id where the iface listener recides in + struct pmlag_bond *bond; // reference to the bond this iface belongs to }; struct pmlag_bond { - void *next; - char *name; - int mode; - int sockfd; - pthread_t tid; - struct pmlag_iface *interfaces; + void *next; // linked-list next reference + char *name; // name of the bond interface + int mode; // which mode to run pmlag in for this bond + int sockfd; // file descriptor for the bond socket interface + 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 pmlag_iface *interfaces; // linked-list of interfaces contained in the bond }; struct pmlag_configuration { diff --git a/src/main.c b/src/main.c @@ -44,9 +44,9 @@ void * thread_iface(void *arg) { printf("Thread started for iface: %s->%s(%d)\n", iface->bond->name, iface->name, iface->sockfd); - // Allow some time for all threads to register their sockets - // TODO: use a mutex from main thread for this to not have idle-time? - sleep(1); + // Wait for the bond thread to finish initializing + pthread_mutex_lock(&(iface->bond->mtx_rt)); + pthread_mutex_unlock(&(iface->bond->mtx_rt)); // Bail if the bond's socket could not be opened if (!iface->bond->sockfd) { @@ -97,7 +97,8 @@ void * thread_bond(void *arg) { struct pmlag_bond *bond = (struct pmlag_bond *)arg; printf("Thread started for bond: %s\n", bond->name); - + // 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; @@ -113,6 +114,9 @@ void * thread_bond(void *arg) { // Take mac address of last iface bond->sockfd = tap_alloc(bond->name); + // Free this bond's routing table + pthread_mutex_unlock(&(bond->mtx_rt)); + // TODO: blocked listen on bond, send through routing table to other ifaces // TODO: send broadcasts to all interfaces // TODO: timer to broadcast announce our presence to ifaces (vrrp-ish) @@ -159,6 +163,12 @@ int main(int argc, const char **argv) { // For each bond of config->bonds struct pmlag_bond *bond = config->bonds; while(bond) { + // Initialize it's routing table lock + if (pthread_mutex_init(&(bond->mtx_rt), NULL) != 0) { + perror("Initializing mutex for bond"); + return 1; + } + // And start it's thread if(pthread_create(&(bond->tid), NULL, thread_bond, bond)) { perror("Starting bond thread"); return 1;