pmlag

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

commit ff55f9fe87c2a61ef33aeb7ec141b2da8807df58
parent 1fa26882ee286c25e28d47482b498519f76d27bd
Author: Yersa Nordman <yersa@finwo.nl>
Date:   Thu, 12 Oct 2023 00:04:14 +0200

Handled passing packets from bond to iface

Diffstat:
Msrc/main.c | 29+++++++++++++++++++++++++++--
Msrc/util/routing-table.c | 31+++++++++++++------------------
Msrc/util/routing-table.h | 8++++----
3 files changed, 44 insertions(+), 24 deletions(-)

diff --git a/src/main.c b/src/main.c @@ -35,9 +35,34 @@ int64_t millis() { } void handle_packet_bond(struct pmlag_bond *bond) { - int send_len, buflen; + int i, send_len, buflen; + struct sockaddr_ll saddr_ll; buflen = read(bond->sockfd, rcvbuf, RCVBUFSIZ); - printf("Got %d bytes on %s\n", buflen, bond->name); + + // Get interface to send the packet from + struct pmlag_iface *iface = (memcmp(rcvbuf, "\xFF\xFF\xFF\xFF\xFF\xFF", ETH_ALEN) == 0) + ? NULL + : rt_find(bond->rt, &(bond->mtx_rt), rcvbuf); + + // Prepare saddr_ll mac address + memcpy(saddr_ll.sll_addr, bond->hwaddr, ETH_ALEN); + + // Broadcast on ALL interfaces if no rt entry OR broadcast packet + if (!iface) { + for( i = 0 ; i < bond->iface_count ; i++ ) { + saddr_ll.sll_ifindex = bond->iface[i]->ifidx; + if (sendto(bond->iface[i]->sockfd, rcvbuf, buflen, 0, (const struct sockaddr*)&saddr_ll, sizeof(struct sockaddr_ll)) != buflen) { + perror("sendto"); + } + } + return; + } + + // Forward packet to iface as-is + saddr_ll.sll_ifindex = iface->ifidx; + if (sendto(iface->sockfd, rcvbuf, buflen, 0, (const struct sockaddr*)&saddr_ll, sizeof(struct sockaddr_ll)) != buflen) { + perror("sendto"); + } } void handle_packet_iface(struct pmlag_iface *iface) { diff --git a/src/util/routing-table.c b/src/util/routing-table.c @@ -80,23 +80,18 @@ int rt_upsert( return 0; } -/* struct pmlag_iface * rt_find( */ -/* struct mindex_t *rt, */ -/* pthread_mutex_t *mtx, */ -/* unsigned char *mac */ -/* ) { */ -/* struct pmlag_rt_entry *rt_entry; */ +struct pmlag_iface * rt_find( + struct mindex_t *rt, + pthread_mutex_t *mtx, + unsigned char *mac +) { + struct pmlag_rt_entry *rt_entry; -/* // Attempt to fetch the rt entry */ -/* pthread_mutex_lock(mtx); */ -/* rt_entry = mindex_get(rt, &((struct pmlag_rt_entry){ .mac = mac })); */ -/* if (!rt_entry) { */ -/* pthread_mutex_unlock(mtx); */ -/* return NULL; */ -/* } */ + // Attempt to fetch the rt entry + rt_entry = mindex_get(rt, &((struct pmlag_rt_entry){ .mac = mac })); + if (!rt_entry) return NULL; -/* // Unlock the routing table again */ -/* struct pmlag_iface *iface = rt_entry->interfaces[rand() % rt_entry->iface_cnt]; */ -/* pthread_mutex_unlock(mtx); */ -/* return iface; */ -/* } */ + // Unlock the routing table again + struct pmlag_iface *iface = rt_entry->interfaces[rand() % rt_entry->iface_cnt]; + return iface; +} diff --git a/src/util/routing-table.h b/src/util/routing-table.h @@ -23,9 +23,9 @@ int rt_upsert( int16_t bcidx ); -/* struct pmlag_iface * rt_find( */ -/* struct mindex_t *rt, */ -/* unsigned char *mac */ -/* ); */ +struct pmlag_iface * rt_find( + struct mindex_t *rt, + unsigned char *mac +); #endif // __PMLAG_UTIL_RT_H__