pmlag

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

commit 9988c8d87b5818154dd6e72b4304b1efd8a1477e
parent d88b4b5b223006c88f6835e00650a6b24cabdb95
Author: Yersa Nordman <yersa@finwo.nl>
Date:   Mon, 13 Mar 2023 23:40:04 +0100

Add support for random and chosen hwaddr on the bond

Diffstat:
Msrc/task/bond.c | 6+++---
Msrc/util/config.c | 32++++++++++++++++++++++++++++++++
Msrc/util/config.h | 1+
Mtest.ini | 23++++++-----------------
4 files changed, 42 insertions(+), 20 deletions(-)

diff --git a/src/task/bond.c b/src/task/bond.c @@ -76,9 +76,9 @@ void * task_bond_thread(void *arg) { 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); + /* unsigned char *mac = iface_mac(bond->interfaces->data->name); */ + bond->sockfd = tap_alloc(bond->name, bond->hwaddr); + /* free(mac); */ if (bond->sockfd < 0) { perror("Allocating bond interface"); pthread_exit(NULL); diff --git a/src/util/config.c b/src/util/config.c @@ -1,9 +1,11 @@ +#include <linux/if_ether.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include "benhoyt/inih.h" #include "config.h" +#include "socket.h" static int config_load_handler( void *user, @@ -48,6 +50,7 @@ static int config_load_handler( } else { return 0; } + } else if (!strcmp(name, "interface")) { // Select the right interface @@ -70,6 +73,35 @@ static int config_load_handler( iface_entry->data->bond = bond; } + } else if (!strcmp(name, "hwaddr")) { + + // Find iface with name == value + iface_entry = bond->interfaces; + while(iface_entry) { + if (!strcmp(iface_entry->data->name, value)) break; + iface_entry = iface_entry->next; + } + + if (iface_entry) { + // Got interface by that name = use it's hwaddr + bond->hwaddr = iface_mac(iface_entry->data->name); + } else if (!strcmp(value, "random")) { + // "random" = null, a.k.a. let the kernel generate a random mac + if (bond->hwaddr) free(bond->hwaddr); + bond->hwaddr = NULL; + } else { + // xx:xx:xx:xx:xx:xx + bond->hwaddr = (unsigned char *)malloc(6); // ETH_ALEN should be 6, but this is safer + sscanf(value, "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx", + &(bond->hwaddr[0]), + &(bond->hwaddr[1]), + &(bond->hwaddr[2]), + &(bond->hwaddr[3]), + &(bond->hwaddr[4]), + &(bond->hwaddr[5]) + ); + } + } else { // Unknown key return 0; diff --git a/src/util/config.h b/src/util/config.h @@ -39,6 +39,7 @@ 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 + unsigned char *hwaddr; // hwaddr to use for the interface (null = random) 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 diff --git a/test.ini b/test.ini @@ -2,21 +2,10 @@ ; eth0 = backup, eth1 = primary [bond0] +; interface=enp0s13f0u1c2 +; interface=enp0s20f0u3 interface=virbr1 -; interface=virbr2 -; interface=virbr6 -; interface=docker0 - -; ; broadcast everything on all interfaces -; [bond1] -; mode=broadcast -; interface=eth2 -; interface=eth3 - -; ; use both at the same time -; [bond2] -; mode=balanced-rr -; interface=eth4 -; weight=10 -; interface=eth5 -; weight=25 +interface=virbr2 +hwaddr=random +hwaddr=virbr1 +hwaddr=52:54:00:0B:97:66