commit 5cd99d6705b6384753add53134b9b5cc1c465285
parent aa97a592dc57c4fb94155ad3384702990427d353
Author: Robin Bron <robin@finwo.nl>
Date: Thu, 9 Mar 2023 22:22:05 +0100
Start separate thread for announcements
Diffstat:
5 files changed, 75 insertions(+), 57 deletions(-)
diff --git a/src/main.c b/src/main.c
@@ -64,7 +64,7 @@ int main(int argc, const char **argv) {
while(bond) {
// Start the bond's thread
- if(pthread_create(&(bond->tid), NULL, task_bond_thread, bond)) {
+ if(pthread_create(&(bond->tid_bond), NULL, task_bond_thread, bond)) {
perror("Starting bond thread");
return 1;
}
@@ -72,61 +72,10 @@ int main(int argc, const char **argv) {
bond = bond->next;
}
- /* // Timer, keep broadcasting "I'm here" packets */
- /* struct pmlag_iface *iface; */
- /* struct sockaddr_ll saddr_ll; */
- /* saddr_ll.sll_halen = ETH_ALEN; */
- /* unsigned char *mac; */
- /* uint16_t ethtype = htons(0x0666); */
- /* int buflen = (ETH_ALEN*2) + 2 + 46; */
- /* unsigned char *buffer = calloc(1, buflen); */
- /* int send_len; */
- /* memset(buffer, 0xFF, ETH_ALEN); // DST = broadcast */
- /* memcpy(buffer+(ETH_ALEN*2), ðtype, sizeof(uint16_t)); // EtherType = 0x0666 = custom */
- /* while(1) { */
- /* bond = config->bonds; */
- /* while(bond) { */
- /* // Set source address in saddr_ll and packet */
- /* mac = iface_mac(bond->name); */
- /* memcpy(saddr_ll.sll_addr, mac, ETH_ALEN); */
- /* memcpy(buffer+ETH_ALEN, mac, ETH_ALEN); */
- /* printf("FREE LINE %d (%p)\n", __LINE__, mac); */
- /* free(mac); */
- /* // Set the bcidx */
- /* memcpy(buffer + (ETH_ALEN*2) + sizeof(uint16_t), &(bond->bcidx), sizeof(int16_t)); */
-
- /* /1* printf("Ethernet header\n"); *1/ */
- /* /1* printf("\nSending: %.2x:%.2x:%.2x:%.2x:%.2x:%.2x > %.2x:%.2x:%.2x:%.2x:%.2x:%.2x, %.4x (%d)\n\n", *1/ */
- /* /1* buffer[6],buffer[7],buffer[8],buffer[9],buffer[10],buffer[11], // SRC *1/ */
- /* /1* buffer[0],buffer[1],buffer[2],buffer[3],buffer[ 4],buffer[ 5], // DST *1/ */
- /* /1* ((unsigned int)((unsigned char)buffer[12]) << 8) + buffer[13], // PROTO *1/ */
- /* /1* buflen *1/ */
- /* /1* ); *1/ */
-
- /* // Output to all interfaces */
- /* iface = bond->interfaces; */
- /* while(iface) { */
- /* if (iface->sockfd) { */
- /* 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 < 0) { */
- /* perror("SENDTO"); */
- /* } */
- /* } */
- /* iface = iface->next; */
- /* } */
- /* bond->bcidx = htons((ntohs(bond->bcidx)+1)|1); */
- /* bond = bond->next; */
- /* } */
- /* /1* usleep(100000); // 100ms *1/ */
- /* sleep(1); */
- /* } */
-
-
// Wait for all bonds to finish
bond = config->bonds;
while(bond) {
- pthread_join(bond->tid, NULL);
+ pthread_join(bond->tid_bond, NULL);
bond = bond->next;
}
diff --git a/src/task/announce.c b/src/task/announce.c
@@ -0,0 +1,61 @@
+#include <linux/if_ether.h>
+#include <linux/if_packet.h>
+#include <netinet/in.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "../util/config.h"
+#include "../util/socket.h"
+#include "announce.h"
+
+void * task_announce_thread(void *arg) {
+ struct pmlag_bond *bond = arg;
+ struct sockaddr_ll saddr_ll;
+ saddr_ll.sll_halen = ETH_ALEN;
+ pmlag_iface_llist *iface_entry;
+
+ uint16_t ethtype = htons(0x0666);
+ size_t buflen = (ETH_ALEN*2) + sizeof(ethtype) + 46;
+ size_t sendlen;
+
+ unsigned char *mac = iface_mac(bond->name);
+ unsigned char *buffer = calloc(1, buflen);
+
+ // Prepare saddr_ll and buffer
+ memcpy(saddr_ll.sll_addr, mac, ETH_ALEN);
+ memset(buffer, 0xFF, ETH_ALEN); // Destination = Broadcast
+ memcpy(buffer+ETH_ALEN, mac, ETH_ALEN); // Source = bond
+ memcpy(buffer+(ETH_ALEN*2), ðtype, sizeof(uint16_t)); // EtherType = 0x0666 = custom
+
+ int16_t bcidx = htons(rand() | 1);
+
+ while(1) {
+ sleep(1);
+ iface_entry = bond->interfaces;
+
+ // Increment bcidx
+ bcidx = ntohs(bcidx);
+ bcidx = (bcidx+1) | 1;
+ bcidx = htons(bcidx);
+
+ // Store bcidx on buffer
+ memcpy(buffer + (ETH_ALEN*2) + sizeof(uint16_t), &bcidx, sizeof(int16_t));
+
+ // Send the buffer as-is over all ifaces
+ while(iface_entry) {
+ if (iface_entry->data->sockfd) {
+ saddr_ll.sll_ifindex = iface_entry->data->ifidx;
+ sendlen = sendto(iface_entry->data->sockfd, buffer, buflen, 0, (const struct sockaddr*)&saddr_ll, sizeof(struct sockaddr_ll));
+ if (sendlen < 0) {
+ perror("SENDTO");
+ }
+ }
+ iface_entry = iface_entry->next;
+ }
+ }
+
+ return NULL;
+}
diff --git a/src/task/announce.h b/src/task/announce.h
@@ -1,7 +1,6 @@
#ifndef __PMLAG_TASK_ANNOUNCE_H__
#define __PMLAG_TASK_ANNOUNCE_H__
-
-
+void * task_announce_thread(void *arg);
#endif // __PMLAG_TASK_ANNOUNCE_H__
diff --git a/src/task/bond.c b/src/task/bond.c
@@ -11,6 +11,8 @@
#include "../util/config.h"
#include "../util/routing-table.h"
#include "../util/socket.h"
+
+#include "announce.h"
#include "iface.h"
int task_bond_onpacket(struct pmlag_bond *bond, unsigned char *buffer, size_t buflen) {
@@ -97,6 +99,13 @@ void * task_bond_thread(void *arg) {
iface_entry = iface_entry->next;
}
+ // Start an announcement thread
+ if(pthread_create(&(bond->tid_announce), NULL, task_announce_thread, bond)) {
+ perror("Starting announce thread");
+ pthread_exit((void*)1);
+ return (void*)1;
+ }
+
// Free this bond's routing table
pthread_mutex_unlock(&(bond->mtx_rt));
diff --git a/src/util/config.h b/src/util/config.h
@@ -35,8 +35,8 @@ struct pmlag_bond {
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
- int16_t bcidx; // big-endian broadcast index for quickly detecting dead paths
- pthread_t tid; // thread id where the bond interface listener recides in
+ pthread_t tid_bond; // thread id where the bond interface listener recides in
+ pthread_t tid_announce; // thread id that'll output announces for the bond
pthread_mutex_t mtx_rt; // lock for the routing table of the bond
struct mindex_t *rt; // pointer to the routing table
pmlag_iface_llist *interfaces; // linked-list of interfaces contained in the bond