Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[WIP] Add manual reload functionality to mrouted for hotplugged network interfaces #63

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
90 changes: 85 additions & 5 deletions src/config.c
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
#include <ifaddrs.h>
#include "defs.h"

static TAILQ_HEAD(, uvif) cvifs = TAILQ_HEAD_INITIALIZER(cvifs);
static TAILQ_HEAD(, uvif) vifs = TAILQ_HEAD_INITIALIZER(vifs);

void config_set_ifflag(uint32_t flag)
Expand Down Expand Up @@ -127,6 +128,22 @@ struct uvif *config_init_tunnel(in_addr_t lcl_addr, in_addr_t rmt_addr, uint32_t
return uv;
}

/*
* Find index of an already installed vif.
*/
static vifi_t find_vifi(struct uvif *v)
{
struct uvif *uv;
vifi_t vifi;

UVIF_FOREACH(vifi, uv) {
if (strcmp(v->uv_name, uv->uv_name) == 0) {
return vifi;
}
}
return NO_VIF;
}

/*
* Ignore any kernel interface that is disabled, or connected to the
* same subnet as one already installed in the uvifs[] array.
Expand Down Expand Up @@ -183,6 +200,61 @@ static vifi_t check_vif(struct uvif *v)
return vifi;
}

static void reload_gone_vifs(void)
{
struct uvif *uv;
struct uvif *nuv;

int found;
TAILQ_FOREACH(uv, &cvifs, uv_link) {
found = 0;
TAILQ_FOREACH(nuv, &vifs, uv_link) {
if (uv->uv_ifindex == nuv->uv_ifindex) {
found = 1;
break;
}
}
if (!found) {
vifi_t vifi = find_vifi(uv);
if (vifi == NO_VIF) {
TAILQ_REMOVE(&vifs, uv, uv_link);
free(uv);
continue;
}
stop_vif(vifi);
uninstall_uvif(uv);
}
}
}

static void reload_new_vifs(void)
{
struct uvif *uv;
struct uvif *nuv;

int found;
TAILQ_FOREACH(nuv, &vifs, uv_link) {
found = 0;
TAILQ_FOREACH(uv, &cvifs, uv_link) {
if (uv->uv_ifindex == nuv->uv_ifindex) {
found = 1;
break;
}
}
if (!found) {
vifi_t vifi = check_vif(nuv);
if (vifi == NO_VIF || install_uvif(nuv)) {
TAILQ_REMOVE(&vifs, nuv, uv_link);
free(nuv);
continue;
}
init_installvif(nuv, vifi);
start_vif2(vifi);
}
}
}


void config_vifs_correlate(void)
{
struct listaddr *al, *al_tmp;
Expand All @@ -209,11 +281,19 @@ void config_vifs_correlate(void)
vifi, v->uv_rate_limit);
}

/*
* XXX: one future extension may be to keep this for adding/removing
* dynamic interfaces at runtime. Now we re-init and let SIGHUP
* rebuild it to recheck since we tear down all vifs anyway.
*/
TAILQ_FIRST(&cvifs) = TAILQ_FIRST(&vifs);
TAILQ_INIT(&vifs);
}


void config_vifs_from_reload()
{
config_vifs_from_kernel();
reload_gone_vifs();
reload_new_vifs();

TAILQ_INIT(&cvifs);
TAILQ_FIRST(&cvifs) = TAILQ_FIRST(&vifs);
TAILQ_INIT(&vifs);
}

Expand Down
8 changes: 8 additions & 0 deletions src/defs.h
Original file line number Diff line number Diff line change
Expand Up @@ -256,6 +256,8 @@ extern int mrt_table_id;
extern int debug_list(int, char *, size_t);
extern int debug_parse(char *);
extern void restart(void);
extern void reload_iface(void);
extern void reload_vifs(void);
extern char * scaletime(time_t);
extern int register_input_handler(int, ihfunc_t);
extern void deregister_input_handler(int);
Expand Down Expand Up @@ -311,17 +313,21 @@ extern void report_to_all_neighbors(int);
extern int report_next_chunk(void);
extern void add_vif_to_routes(vifi_t);
extern void delete_vif_from_routes(vifi_t);
extern void discard_vif_from_routes(vifi_t);
extern void add_neighbor_to_routes(vifi_t, uint32_t);
extern void delete_neighbor_from_routes(uint32_t, vifi_t, uint32_t);
extern void dump_routes(FILE *, int);

/* vif.c */
extern void init_vifs(void);
extern void start_vif2(vifi_t);
extern void stop_vif(vifi_t);
extern void blaster_alloc(struct uvif *);
extern void blaster_free(struct uvif *);
extern void zero_vif(struct uvif *, int);
extern void init_installvifs(void);
extern int install_uvif(struct uvif *);
extern int uninstall_uvif(struct uvif *);
extern void check_vif_state(void);
extern void send_on_vif(struct uvif *, uint32_t, int, size_t);
extern struct uvif *find_uvif(vifi_t);
Expand Down Expand Up @@ -357,6 +363,7 @@ extern struct uvif *config_find_ifaddr(in_addr_t addr);
extern struct uvif *config_init_tunnel(in_addr_t lcl_addr, in_addr_t rmt_addr, uint32_t flags);
extern void config_vifs_correlate(void);
extern void config_vifs_from_kernel(void);
extern void config_vifs_from_reload(void);

/* cfparse.y */
extern void config_vifs_from_file(void);
Expand Down Expand Up @@ -452,6 +459,7 @@ extern int pidfile(const char *basename);
#define IPC_SHOW_MFC_CMD 21
#define IPC_SHOW_NEIGH_CMD 22
#define IPC_SHOW_ROUTES_CMD 23
#define IPC_RELOAD_IFACE_CMD 30
#define IPC_SHOW_COMPAT_CMD 250
#define IPC_EOF_CMD 254
#define IPC_ERR_CMD 255
Expand Down
4 changes: 4 additions & 0 deletions src/ipc.c
Original file line number Diff line number Diff line change
Expand Up @@ -618,6 +618,10 @@ static void ipc_handle(int sd)
restart();
break;

case IPC_RELOAD_IFACE_CMD:
reload_iface();
break;

case IPC_DEBUG_CMD:
ipc_generic(client, &msg, do_debug, &msg);
break;
Expand Down
18 changes: 17 additions & 1 deletion src/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -504,7 +504,7 @@ int main(int argc, char *argv[])
}

logit(LOG_NOTICE, 0, "%s exiting", versionstring);
free(pfd);
free(pfd);
cleanup();

return 0;
Expand Down Expand Up @@ -803,6 +803,22 @@ void restart(void)
timer_set(TIMER_INTERVAL, timer, NULL);
}

/*
* Reload ifaces
*/
void reload_iface(void)
{
FILE *fp = NULL;
char *s = NULL;

s = strdup (" reload ifaces");
if (s == NULL)
logit(LOG_ERR, 0, "out of memory");

reload_vifs();
}


#define SCALETIMEBUFLEN 27
char *scaletime(time_t t)
{
Expand Down
18 changes: 12 additions & 6 deletions src/mroutectl.c
Original file line number Diff line number Diff line change
Expand Up @@ -320,6 +320,7 @@ static int usage(int rc)
" kill Kill running mrouted, like SIGTERM\n"
" log [? | none | LEVEL] Set log level: none, err, notice*, info, debug\n"
" restart Restart mrouted and reload .conf file, like SIGHUP\n"
" reload ifaces Reload listening interfaces\n"
" show version Show version, and uptime (-d), of running mrouted\n"
" show status Show status summary, default\n"
" show compat Show status, compat mode, previously `mrouted -r`\n"
Expand Down Expand Up @@ -416,13 +417,18 @@ int main(int argc, char *argv[])
{ "version", NULL, NULL, IPC_VERSION_CMD },
{ NULL, NULL, NULL, 0 }
};
struct cmd reload[] = {
{ "ifaces", NULL, NULL, IPC_RELOAD_IFACE_CMD },
{ NULL, NULL, NULL, 0 }
};
struct cmd command[] = {
{ "debug", NULL, set_debug, 0 },
{ "help", NULL, help, 0 },
{ "kill", NULL, NULL, IPC_KILL_CMD },
{ "log", NULL, set_loglevel, 0 },
{ "restart", NULL, NULL, IPC_RESTART_CMD },
{ "show", show, show_status, 0 },
{ "debug", NULL, set_debug, 0 },
{ "help", NULL, help, 0 },
{ "kill", NULL, NULL, IPC_KILL_CMD },
{ "log", NULL, set_loglevel, 0 },
{ "restart", NULL, NULL, IPC_RESTART_CMD },
{ "show", show, show_status, 0 },
{ "reload", reload, NULL, 0 },
{ NULL, NULL, NULL, 0 }
};
int c;
Expand Down
12 changes: 11 additions & 1 deletion src/route.c
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,17 @@ void delete_vif_from_routes(vifi_t vifi)
}


void discard_vif_from_routes(vifi_t vifi)
{
struct rtentry *r, *tmp;

TAILQ_FOREACH_SAFE(r, &rtable, rt_link, tmp) {
if (r->rt_parent == vifi || VIFM_ISSET(vifi, r->rt_children))
discard_route(r);
}
}


/*
* A new neighbor has come up. If we're flooding on the neighbor's
* vif, mark that neighbor as subordinate for all routes whose parent
Expand Down Expand Up @@ -325,7 +336,6 @@ static void create_route(uint32_t origin, uint32_t mask)
++nroutes;
}


/*
* Discard the routing table entry following the one to which 'rt' points.
* [.|prev|.]--->[.|rt|.]<---[.|next|.]
Expand Down
Loading