Merge pull request #119 from ifupdown-ng/feature/explicit-guard

guard auto and explicitly configured interfaces from inappropriate deconfiguration
This commit is contained in:
Ariadne Conill 2020-10-21 07:15:03 -08:00 committed by GitHub
commit 90453f1412
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 52 additions and 13 deletions

View file

@ -182,7 +182,8 @@ list_state(struct lif_dict *state, struct match_options *opts)
if (listing_running) if (listing_running)
printf("%s\n", entry->key); printf("%s\n", entry->key);
else else
printf("%s=%s %zu\n", entry->key, rec->mapped_if, rec->refcount); printf("%s=%s %zu%s\n", entry->key, rec->mapped_if, rec->refcount,
rec->is_explicit ? " explicit" : "");
} }
} }

View file

@ -95,7 +95,7 @@ acquire_state_lock(const char *state_path, const char *lifname)
} }
bool bool
skip_interface(struct lif_interface *iface, const char *ifname) skip_interface(struct lif_interface *iface, const char *ifname, struct lif_dict *state, bool update_state)
{ {
if (iface->is_template) if (iface->is_template)
{ {
@ -123,16 +123,23 @@ skip_interface(struct lif_interface *iface, const char *ifname)
if (up && iface->refcount > 0) if (up && iface->refcount > 0)
{ {
if (exec_opts.verbose) if (exec_opts.verbose)
fprintf(stderr, "%s: skipping auto interface %s (already configured), use --force to force configuration\n", fprintf(stderr, "%s: skipping %sinterface %s (already configured), use --force to force configuration\n",
argv0, ifname); argv0, iface->is_auto ? "auto " : "", ifname);
if (update_state)
{
iface->is_explicit = true;
lif_state_upsert(state, ifname, iface);
}
return true; return true;
} }
if (!up && iface->refcount == 0) if (!up && iface->refcount == 0)
{ {
if (exec_opts.verbose) if (exec_opts.verbose)
fprintf(stderr, "%s: skipping auto interface %s (already deconfigured), use --force to force deconfiguration\n", fprintf(stderr, "%s: skipping %sinterface %s (already deconfigured), use --force to force deconfiguration\n",
argv0, ifname); argv0, iface->is_auto ? "auto " : "", ifname);
return true; return true;
} }
@ -140,7 +147,7 @@ skip_interface(struct lif_interface *iface, const char *ifname)
} }
bool bool
change_interface(struct lif_interface *iface, struct lif_dict *collection, struct lif_dict *state, const char *ifname) change_interface(struct lif_interface *iface, struct lif_dict *collection, struct lif_dict *state, const char *ifname, bool update_state)
{ {
int lockfd = acquire_state_lock(exec_opts.state_file, ifname); int lockfd = acquire_state_lock(exec_opts.state_file, ifname);
@ -150,7 +157,7 @@ change_interface(struct lif_interface *iface, struct lif_dict *collection, struc
return false; return false;
} }
if (skip_interface(iface, ifname)) if (skip_interface(iface, ifname, state, update_state))
{ {
if (lockfd != -1) if (lockfd != -1)
close(lockfd); close(lockfd);
@ -178,6 +185,12 @@ change_interface(struct lif_interface *iface, struct lif_dict *collection, struc
if (lockfd != -1) if (lockfd != -1)
close(lockfd); close(lockfd);
if (up && update_state)
{
iface->is_explicit = true;
lif_state_upsert(state, ifname, iface);
}
return true; return true;
} }
@ -202,7 +215,7 @@ change_auto_interfaces(struct lif_dict *collection, struct lif_dict *state, stru
fnmatch(opts->include_pattern, iface->ifname, 0)) fnmatch(opts->include_pattern, iface->ifname, 0))
continue; continue;
if (!change_interface(iface, collection, state, iface->ifname)) if (!change_interface(iface, collection, state, iface->ifname, false))
return false; return false;
} }
@ -313,7 +326,7 @@ ifupdown_main(int argc, char *argv[])
iface = entry->data; iface = entry->data;
} }
if (!change_interface(iface, &collection, &state, ifname)) if (!change_interface(iface, &collection, &state, ifname, true))
return update_state_file_and_exit(EXIT_FAILURE, &state); return update_state_file_and_exit(EXIT_FAILURE, &state);
} }

View file

@ -172,6 +172,9 @@ handle_auto(struct lif_interface_file_parse_state *state, char *token, char *buf
if (!state->cur_iface->is_template) if (!state->cur_iface->is_template)
state->cur_iface->is_auto = true; state->cur_iface->is_auto = true;
if (state->cur_iface->is_auto)
state->cur_iface->is_explicit = true;
return true; return true;
} }

View file

@ -223,6 +223,7 @@ lif_interface_collection_init(struct lif_dict *collection)
/* always enable loopback interface as part of a collection */ /* always enable loopback interface as part of a collection */
if_lo = lif_interface_collection_find(collection, "lo"); if_lo = lif_interface_collection_find(collection, "lo");
if_lo->is_auto = true; if_lo->is_auto = true;
if_lo->is_explicit = true;
lif_interface_use_executor(if_lo, "loopback"); lif_interface_use_executor(if_lo, "loopback");
} }

View file

@ -50,6 +50,7 @@ struct lif_interface {
bool is_bond; bool is_bond;
bool is_template; bool is_template;
bool is_pending; bool is_pending;
bool is_explicit;
bool has_config_error; /* error found in interface configuration */ bool has_config_error; /* error found in interface configuration */

View file

@ -396,6 +396,15 @@ handle_dependents(const struct lif_execute_opts *opts, struct lif_interface *par
continue; continue;
} }
if (!up && iface->is_explicit)
{
if (opts->verbose)
fprintf(stderr, "ifupdown: skipping dependent interface %s (of %s) -- interface is marked as explicitly configured\n",
iface->ifname, parent->ifname);
continue;
}
if (opts->verbose) if (opts->verbose)
fprintf(stderr, "ifupdown: changing state of dependent interface %s (of %s) to %s\n", fprintf(stderr, "ifupdown: changing state of dependent interface %s (of %s) to %s\n",
iface->ifname, parent->ifname, up ? "up" : "down"); iface->ifname, parent->ifname, up ? "up" : "down");

View file

@ -29,8 +29,13 @@ lif_state_read(struct lif_dict *state, FILE *fd)
char *bufp = linebuf; char *bufp = linebuf;
char *ifname = lif_next_token(&bufp); char *ifname = lif_next_token(&bufp);
char *refcount = lif_next_token(&bufp); char *refcount = lif_next_token(&bufp);
char *explicit = lif_next_token(&bufp);
size_t rc = 1; size_t rc = 1;
char *equals_p = strchr(linebuf, '='); char *equals_p = strchr(linebuf, '=');
bool is_explicit = false;
if (*explicit && !strcmp(explicit, "explicit"))
is_explicit = true;
if (*refcount) if (*refcount)
{ {
@ -42,12 +47,12 @@ lif_state_read(struct lif_dict *state, FILE *fd)
if (equals_p == NULL) if (equals_p == NULL)
{ {
lif_state_upsert(state, ifname, &(struct lif_interface){ .ifname = ifname, .refcount = rc }); lif_state_upsert(state, ifname, &(struct lif_interface){ .ifname = ifname, .refcount = rc, .is_explicit = is_explicit });
continue; continue;
} }
*equals_p++ = '\0'; *equals_p++ = '\0';
lif_state_upsert(state, ifname, &(struct lif_interface){ .ifname = equals_p, .refcount = rc }); lif_state_upsert(state, ifname, &(struct lif_interface){ .ifname = equals_p, .refcount = rc, .is_explicit = is_explicit });
} }
return true; return true;
@ -99,6 +104,7 @@ lif_state_upsert(struct lif_dict *state, const char *ifname, struct lif_interfac
rec->mapped_if = strdup(iface->ifname); rec->mapped_if = strdup(iface->ifname);
rec->refcount = iface->refcount; rec->refcount = iface->refcount;
rec->is_explicit = iface->is_explicit;
lif_dict_add(state, ifname, rec); lif_dict_add(state, ifname, rec);
} }
@ -128,7 +134,8 @@ lif_state_write(const struct lif_dict *state, FILE *f)
struct lif_dict_entry *entry = iter->data; struct lif_dict_entry *entry = iter->data;
struct lif_state_record *rec = entry->data; struct lif_state_record *rec = entry->data;
fprintf(f, "%s=%s %zu\n", entry->key, rec->mapped_if, rec->refcount); fprintf(f, "%s=%s %zu%s\n", entry->key, rec->mapped_if, rec->refcount,
rec->is_explicit ? " explicit" : "");
} }
} }
@ -175,6 +182,7 @@ lif_state_sync(struct lif_dict *state, struct lif_dict *if_collection)
struct lif_interface *iface = lif_interface_collection_find(if_collection, rec->mapped_if); struct lif_interface *iface = lif_interface_collection_find(if_collection, rec->mapped_if);
iface->refcount = rec->refcount; iface->refcount = rec->refcount;
iface->is_explicit = rec->is_explicit;
} }
return true; return true;

View file

@ -17,11 +17,14 @@
#define LIBIFUPDOWN_STATE_H__GUARD #define LIBIFUPDOWN_STATE_H__GUARD
#include <stdio.h> #include <stdio.h>
#include <stdbool.h>
#include "libifupdown/interface.h" #include "libifupdown/interface.h"
struct lif_state_record { struct lif_state_record {
char *mapped_if; char *mapped_if;
size_t refcount; size_t refcount;
bool is_explicit;
}; };
extern bool lif_state_read(struct lif_dict *state, FILE *f); extern bool lif_state_read(struct lif_dict *state, FILE *f);