commit 9a91e5e7fdb368d3eded4723714aba5ec3a1ea83
parent b08118b433d37df4258dc3364bf3d842f81101f0
Author: Yersa Nordman <yersa@finwo.nl>
Date: Wed, 11 Oct 2023 00:22:03 +0200
Initialize tap and routing-table
Diffstat:
6 files changed, 124 insertions(+), 68 deletions(-)
diff --git a/src/main.c b/src/main.c
@@ -8,6 +8,7 @@
#include "cofyc/argparse.h"
#include "util/config.h"
+#include "util/routing-table.h"
#include "util/socket.h"
static const char *const usage[] = {
@@ -25,6 +26,7 @@ int main(int argc, const char **argv) {
char *config_file="/etc/pmlag/pmlag.ini";
struct epoll_event *epev;
int epfd;
+ struct pmlag_bond *bond;
struct pmlag_iface *iface;
// Seed random
@@ -88,9 +90,24 @@ int main(int argc, const char **argv) {
for( b = 0 ; b < config->bond_count ; b++ ) {
// (re)open bond tap
+ bond = config->bond[b];
+ if (!bond->sockfd) {
+ bond->sockfd = tap_alloc(bond->name, bond->hwaddr);
+ if (bond->sockfd < 0) {
+ perror("tap_alloc");
+ bond->sockfd = 0;
+ continue;
+ }
+ printf("Opened tap for %s\n", bond->name);
+ }
+
+ // (re)initialize routing table
+ if (!bond->rt) {
+ bond->rt = rt_init(bond);
+ }
for( i = 0 ; i < config->bond[b]->iface_count ; i++ ) {
- iface = config->bond[b]->iface[i];
+ iface = bond->iface[i];
// (re)open interface socket
if (!iface->sockfd) {
diff --git a/src/util/config.h b/src/util/config.h
@@ -6,33 +6,21 @@
#define PMLAG_ENTITY_TYPE_BOND 2
struct pmlag_iface {
- PMLAG_ENTITY_TYPE type;
- char *name;
- struct pmlag_bond *bond;
- int sockfd;
+ PMLAG_ENTITY_TYPE type;
+ char *name;
+ struct pmlag_bond *bond;
+ int sockfd;
struct epoll_event *epev;
- /* /1* int weight; // weight of this interface within the bond *1/ */
- /* int sockfd; // file descriptor for the iface raw socket */
- /* int ifidx; // index of the interface within the 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 {
- PMLAG_ENTITY_TYPE type;
- char *name;
+ PMLAG_ENTITY_TYPE type;
+ char *name;
struct pmlag_iface **iface;
int iface_count;
- unsigned char *hwaddr; // hwaddr to use for the interface (null = random)
-
-/* int mode; // which mode to run pmlag in for this bond */
-/* int sockfd; // file descriptor for the bond socket interface */
-/* 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 */
-/* int iface_cnt; // track the number of interfaces in this bond */
+ int sockfd;
+ unsigned char *hwaddr; // hwaddr to use for the interface (null = random)
+ struct mindex_t *rt;
};
struct pmlag_configuration {
diff --git a/src/util/routing-table.c b/src/util/routing-table.c
@@ -1,39 +1,31 @@
-/* #include <linux/if_ether.h> */
+#include <linux/if_ether.h>
/* #include <stdio.h> */
/* #include <stdlib.h> */
-/* #include <string.h> */
-
-/* #include "config.h" */
-/* #include "finwo/mindex.h" */
-/* #include "routing-table.h" */
-
-/* static int rt_compare(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; */
-/* int result; */
-
-/* // Same pointer = match */
-/* if (a == b) return 0; */
-
-/* // Check for ETH_ALEN, unrolled memcmp */
-/* if (( result = ((int)ta->mac[0] - (int)tb->mac[0]) )) return result; */
-/* if (( result = ((int)ta->mac[1] - (int)tb->mac[1]) )) return result; */
-/* if (( result = ((int)ta->mac[2] - (int)tb->mac[2]) )) return result; */
-/* if (( result = ((int)ta->mac[3] - (int)tb->mac[3]) )) return result; */
-/* if (( result = ((int)ta->mac[4] - (int)tb->mac[4]) )) return result; */
-/* return (int)ta->mac[5] - (int)tb->mac[5]; */
-/* } */
-
-/* static void rt_purge(const void *item, void *udata) { */
-/* struct pmlag_rt_entry *rt_entry = (struct pmlag_rt_entry *)item; */
-/* free(rt_entry->interfaces); */
-/* free(rt_entry->mac); */
-/* free(rt_entry); */
-/* } */
-
-/* struct mindex_t * rt_init(void *udata) { */
-/* return mindex_init(rt_compare, rt_purge, udata); */
-/* } */
+#include <string.h>
+
+#include "finwo/mindex.h"
+
+#include "config.h"
+#include "routing-table.h"
+
+static int rt_compare(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;
+ if (a == b) return 0;
+ return memcmp(ta->mac, tb->mac, ETH_ALEN);
+}
+
+static void rt_purge(void *item, void *udata) {
+ struct pmlag_rt_entry *rt_entry = (struct pmlag_rt_entry *)item;
+ if (!rt_entry) return;
+ if (rt_entry->iface) free(rt_entry->iface);
+ if (rt_entry->mac) free(rt_entry->mac);
+ free(rt_entry);
+}
+
+struct mindex_t * rt_init(void *udata) {
+ return mindex_init(rt_compare, rt_purge, udata);
+}
/* int rt_upsert( */
/* struct mindex_t *rt, */
diff --git a/src/util/routing-table.h b/src/util/routing-table.h
@@ -1,18 +1,18 @@
-/* #ifndef __PMLAG_UTIL_RT_H__ */
-/* #define __PMLAG_UTIL_RT_H__ */
+#ifndef __PMLAG_UTIL_RT_H__
+#define __PMLAG_UTIL_RT_H__
-/* #include "config.h" */
+#include "config.h"
-/* #include "finwo/mindex.h" */
+#include "finwo/mindex.h"
-/* struct pmlag_rt_entry { */
-/* unsigned char *mac; // mac address of the remote entity */
-/* int16_t bcidx; // broadcast index last seen from the mac */
-/* int16_t iface_cnt; // amount of interfaces this mac is available on */
-/* struct pmlag_iface **interfaces; // list of pointers to interfaces */
-/* }; */
+struct pmlag_rt_entry {
+ unsigned char *mac; // mac address of the remote entity
+ int16_t bcidx; // broadcast index last seen from the mac
+ struct pmlag_iface **iface;
+ int iface_count;
+};
-/* struct mindex_t * rt_init(void *udata); */
+struct mindex_t * rt_init(void *udata);
/* int rt_upsert( */
/* struct mindex_t *rt, */
@@ -28,4 +28,4 @@
/* unsigned char *mac */
/* ); */
-/* #endif // __PMLAG_UTIL_RT_H__ */
+#endif // __PMLAG_UTIL_RT_H__
diff --git a/src/util/socket.c b/src/util/socket.c
@@ -96,3 +96,61 @@ int sockraw_open(char * ifname) {
// Return the prepared socket
return sockfd;
}
+
+int tap_alloc(char * ifname, unsigned char * mac) {
+ struct ifreq ifr;
+ int fd, err;
+
+ if( (fd = open("/dev/net/tun", O_RDWR)) < 0 ) {
+ perror("Open tun");
+ return -1;
+ }
+
+ // Bring up the interface
+ memset(&ifr, 0, sizeof(ifr));
+ ifr.ifr_flags = IFF_TAP | IFF_MULTI_QUEUE | IFF_NO_PI;
+ if( *ifname ) {
+ strncpy(ifr.ifr_name, ifname, IFNAMSIZ);
+ }
+ if( (err = ioctl(fd, TUNSETIFF, (void *) &ifr)) < 0 ){
+ perror("Open tun");
+ close(fd);
+ return err;
+ }
+ strcpy(ifname, ifr.ifr_name);
+
+ // Set the interface's mac address
+ if ( mac ) {
+ // TODO: random, copied or specific mac address pulled from ini
+ memset(&ifr, 0, sizeof(ifr));
+ strcpy(ifr.ifr_name, ifname);
+ ifr.ifr_hwaddr.sa_family = ARPHRD_ETHER;
+ memcpy(ifr.ifr_hwaddr.sa_data, mac, ETH_ALEN);
+ if ((err = if_ioctl(SIOCSIFHWADDR, &ifr)) < 0) {
+ perror("Set if hwaddr");
+ close(fd);
+ return err;
+ }
+ }
+
+ // Fetch the current flags
+ memset(&ifr, 0, sizeof(ifr));
+ strcpy(ifr.ifr_name, ifname);
+ if (if_ioctl(SIOCGIFFLAGS, &ifr) < 0) {
+ perror("failed to get the interface flags");
+ close(fd);
+ return err;
+ }
+
+ // Bring up the interface
+ if (!(ifr.ifr_flags & IFF_UP)) {
+ ifr.ifr_flags |= IFF_UP;
+ if (if_ioctl(SIOCSIFFLAGS, &ifr) < 0) {
+ perror("failed to get the interface flags");
+ close(fd);
+ return err;
+ }
+ }
+
+ return fd;
+}
diff --git a/src/util/socket.h b/src/util/socket.h
@@ -2,6 +2,7 @@
#define __PMLAG_UTIL_SOCKET_H__
unsigned char * iface_mac(char * ifname);
+int tap_alloc(char * ifname, unsigned char * mac);
int sockraw_open(char * ifname);
#endif // __PMLAG_UTIL_SOCKET_H__