Skip to content

Commit

Permalink
add netstack_iface_copy_byidx() #12
Browse files Browse the repository at this point in the history
  • Loading branch information
dankamongmen committed Nov 1, 2019
1 parent c701ef6 commit 582f6ab
Show file tree
Hide file tree
Showing 2 changed files with 46 additions and 2 deletions.
9 changes: 9 additions & 0 deletions include/netstack.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ typedef struct netstack_iface {
// rtabuf by attr type. NULL if that attr wasn't in the message.
const struct rtattr* rta_indexed[__IFLA_MAX];
bool unknown_attrs; // are there attrs >= __IFLA_MAX?
struct netstack_iface* hnext; // next in the idx-hashed table ns->iface_slots
} netstack_iface;

static inline const struct rtattr *
Expand Down Expand Up @@ -276,11 +277,19 @@ typedef struct netstack_opts {
struct netstack* netstack_create(const netstack_opts* opts);
int netstack_destroy(struct netstack* ns);

// Copy out a netstack iface for arbitrary use in the client. This is a
// heavyweight copy, and must be freed using netstack_iface_destroy().
netstack_iface* netstack_iface_copy_byname(const struct netstack* ns, const char* name);
netstack_iface* netstack_iface_copy_byidx(const struct netstack* ns, int idx);

int netstack_print_iface(const netstack_iface* ni, FILE* out);
int netstack_print_addr(const netstack_addr* na, FILE* out);
int netstack_print_route(const netstack_route* nr, FILE* out);
int netstack_print_neigh(const netstack_neigh* nn, FILE* out);

// Free up a netstack_iface copied by netstack_iface_copy().
void netstack_iface_destroy(netstack_iface* ni);

#ifdef __cplusplus
}
#endif
Expand Down
39 changes: 37 additions & 2 deletions src/lib/netstack.c
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@
#include <linux/rtnetlink.h>
#include "netstack.h"

// Naive hash. Interface numbers are assigned successively, so there ought
// generally not be clashes with a linear mod map.
#define IFACE_HASH_SLOTS 256

typedef struct netstack {
struct nl_sock* nl; // netlink connection abstraction from libnl
pthread_t rxtid;
Expand All @@ -29,6 +33,7 @@ typedef struct netstack {
pthread_mutex_t txlock;
atomic_bool clear_to_send;
netstack_opts opts; // copied wholesale in netstack_create()
netstack_iface* iface_hash[IFACE_HASH_SLOTS];
} netstack;

// Sits on blocking nl_recvmsgs()
Expand Down Expand Up @@ -373,7 +378,7 @@ create_neigh(const struct rtattr* rtas, int rlen){
static inline void*
vcreate_neigh(const struct rtattr* rtas, int rlen){ return create_neigh(rtas, rlen); }

static void free_iface(netstack_iface* ni){
void netstack_iface_destroy(netstack_iface* ni){
if(ni){
free(ni->rtabuf);
free(ni);
Expand Down Expand Up @@ -401,7 +406,7 @@ static void free_neigh(netstack_neigh* nn){
}
}

static inline void vfree_iface(void* vni){ free_iface(vni); }
static inline void vfree_iface(void* vni){ netstack_iface_destroy(vni); }
static inline void vfree_addr(void* va){ free_addr(va); }
static inline void vfree_route(void* vr){ free_route(vr); }
static inline void vfree_neigh(void* vn){ free_neigh(vn); }
Expand Down Expand Up @@ -604,6 +609,7 @@ netstack_init(netstack* ns, const netstack_opts* opts){
ns->queueidx = sizeof(dumpmsgs) / sizeof(*dumpmsgs);
ns->dequeueidx = 0;
ns->clear_to_send = true;
memset(&ns->iface_hash, 0, sizeof(ns->iface_hash));
if((ns->nl = nl_socket_alloc()) == NULL){
return -1;
}
Expand Down Expand Up @@ -700,3 +706,32 @@ int netstack_destroy(netstack* ns){
}
return ret;
}

netstack_iface* netstack_iface_copy_byname(const netstack* ns, const char* name){
netstack_iface* ni;
(void)ns; (void)name; ni = NULL; // FIXME
return ni;
}

static inline netstack_iface*
netstack_iface_byidx(const netstack* ns, int idx){
if(idx < 0){
return NULL;
}
int hidx = idx % (sizeof(ns->iface_hash) / sizeof(*ns->iface_hash));
netstack_iface* ni = ns->iface_hash[hidx];
while(ni){
if(ni->ifi.ifi_index == idx){
break;
}
ni = ni->hnext;
}
return ni;
}

netstack_iface* netstack_iface_copy_byidx(const netstack* ns, int idx){
netstack_iface* ni = netstack_iface_byidx(ns, idx);
netstack_iface* ret = create_iface(ni->rtabuf, ni->rtabuflen);
// FIXME populate new indices
return ret;
}

0 comments on commit 582f6ab

Please sign in to comment.