commit 38f6a4ec1c2888f48ff98df7fb52846c8ffef1d7
parent 0a1cd68d615a5c6064b6de949845a37f3bdefaa1
Author: Yersa Nordman <yersa@finwo.nl>
Date: Mon, 13 Feb 2023 21:41:21 +0100
Open file descriptors before starting bond/iface threads
Diffstat:
3 files changed, 124 insertions(+), 80 deletions(-)
diff --git a/src/main.c b/src/main.c
@@ -29,66 +29,68 @@ static const char *const usage[] = {
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;
- }
+ /* // 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);
+ /* // 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); */
printf("Thread started for iface: %s->%s(%d)\n", iface->bond->name, iface->name, iface->sockfd);
- // Wait for the bond thread to finish initializing
- pthread_mutex_lock(&(iface->bond->mtx_rt));
- pthread_mutex_unlock(&(iface->bond->mtx_rt));
+ /* // 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) {
- pthread_exit(NULL);
- return NULL;
- }
+ /* // Bail if the bond's socket could not be opened */
+ /* if (!iface->bond->sockfd) { */
+ /* pthread_exit(NULL); */
+ /* return NULL; */
+ /* } */
- // Find bond socket iface_idx
- int send_len;
+ /* // Find bond socket iface_idx */
+ /* int send_len; */
- while(1) {
+ /* 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;
- }
+ /* // 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; */
+ /* } */
- // TODO: track received proto=0x0666 packet to update routing table
+ /* // TODO: track received proto=0x0666 packet to update routing table */
- /* printf("\n"); */
- /* printf("Got packet: %d bytes\n", buflen); */
- /* printf("\n"); */
+ /* printf("\n"); */
+ /* printf("Got packet: %d bytes\n", buflen); */
+ /* printf("\n"); */
- /* printf("Ethernet header\n"); */
- /* printf("\t|- DST %.2X-%.2X-%.2X-%.2X-%.2X-%.2X\n",buffer[0],buffer[1],buffer[2],buffer[3],buffer[ 4],buffer[ 5]); */
- /* printf("\t|- SRC %.2X-%.2X-%.2X-%.2X-%.2X-%.2X\n",buffer[6],buffer[7],buffer[8],buffer[9],buffer[10],buffer[11]); */
- /* printf("\t|- PROTO %.4X\n", ((int)((char)buffer[12]) << 8) + buffer[13]); */
+ /* printf("Ethernet header\n"); */
+ /* printf("\t|- DST %.2X-%.2X-%.2X-%.2X-%.2X-%.2X\n",buffer[0],buffer[1],buffer[2],buffer[3],buffer[ 4],buffer[ 5]); */
+ /* printf("\t|- SRC %.2X-%.2X-%.2X-%.2X-%.2X-%.2X\n",buffer[6],buffer[7],buffer[8],buffer[9],buffer[10],buffer[11]); */
+ /* printf("\t|- PROTO %.4X\n", ((int)((char)buffer[12]) << 8) + buffer[13]); */
+ /* printf("\n"); */
- // 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;
- }
- }
+ /* // Redirect packet to bond socket as-is */
+ /* printf("Bond iface: %d\n\n", iface->bond->sockfd); */
+ /* send_len = write(iface->bond->sockfd, buffer, buflen); */
+ /* if (buflen != send_len) { */
+ /* perror("write(bond)"); */
+ /* pthread_exit(NULL); */
+ /* return NULL; */
+ /* } */
+ /* } */
- sleep(3);
+ /* sleep(3); */
pthread_exit(NULL);
return NULL;
}
@@ -97,37 +99,37 @@ 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));
+ /* // 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;
- }
+ /* // Initialize the bond interface */
+ /* bond->sockfd = tap_alloc(bond->name); */
- // Take mac address of last iface
- bond->sockfd = tap_alloc(bond->name);
+ /* // 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; */
+ /* } */
- // Free this bond's routing table
- pthread_mutex_unlock(&(bond->mtx_rt));
+ /* // 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)
- // hint: include sequence id, so tracking can react quickly (seq dist > 1)
+ /* // 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) */
+ /* // hint: include sequence id, so tracking can react quickly (seq dist > 1) */
- // Wait for iface threads to finish
- iface = bond->interfaces;
- while(iface) {
- pthread_join(iface->tid, NULL);
- iface = iface->next;
- }
+ /* // Wait for iface threads to finish */
+ /* iface = bond->interfaces; */
+ /* while(iface) { */
+ /* pthread_join(iface->tid, NULL); */
+ /* iface = iface->next; */
+ /* } */
pthread_exit(NULL);
return NULL;
@@ -160,19 +162,51 @@ int main(int argc, const char **argv) {
return 1;
}
- // For each bond of config->bonds
+ // Initialize interfaces for all configured bonds
struct pmlag_bond *bond = config->bonds;
+ struct pmlag_iface *iface;
while(bond) {
- // Initialize it's routing table lock
+
+ bond->sockfd = tap_alloc(bond->name);
+ if (bond->sockfd < 0) return 3;
+
+ iface = bond->interfaces;
+ while(iface) {
+ iface->sockfd = sockraw_open(iface->name);
+ if (iface->sockfd < 0) return 2;
+ iface = iface->next;
+ }
+
+ bond = bond->next;
+ }
+
+
+ // For each bond of config->bonds
+ 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;
}
- // And start it's thread
+
+ // Start the bond's thread
if(pthread_create(&(bond->tid), NULL, thread_bond, bond)) {
perror("Starting bond thread");
return 1;
}
+
+ // Start a thread for each interface
+ iface = bond->interfaces;
+ while(iface) {
+ if(pthread_create(&(iface->tid), NULL, thread_iface, iface)) {
+ perror("Starting iface thread");
+ return 1;
+ }
+ iface = iface->next;
+ }
+
bond = bond->next;
}
@@ -180,9 +214,18 @@ int main(int argc, const char **argv) {
bond = config->bonds;
while(bond) {
pthread_join(bond->tid, NULL);
+ iface = bond->interfaces;
+ while(iface) {
+ pthread_join(iface->tid, NULL);
+ iface = iface->next;
+ }
bond = bond->next;
}
+
+
+
+
/* int sockfd = sockraw_open(INTERFACE); */
/* if (sockfd < 0) { */
/* return 1; */
diff --git a/src/socket.c b/src/socket.c
@@ -77,12 +77,13 @@ int tap_alloc(char * ifname) {
*/
ifr.ifr_flags = IFF_TAP | IFF_NO_PI;
if( *ifname ) {
- strncpy(ifr.ifr_name, ifname, IFNAMSIZ);
+ strncpy(ifr.ifr_name, ifname, IFNAMSIZ);
}
if( (err = ioctl(fd, TUNSETIFF, (void *) &ifr)) < 0 ){
- close(fd);
- return err;
+ perror("Open tun");
+ close(fd);
+ return err;
}
strcpy(ifname, ifr.ifr_name);
diff --git a/test.ini b/test.ini
@@ -3,7 +3,7 @@
; eth0 = backup, eth1 = primary
[bond0]
mode=active-backup
-interface=docker0
+interface=enp0s13f0u1c2
weight=10
; ; broadcast everything on all interfaces