Merge pull request #38 from ifupdown-ng/bugfix/vlan-complex
vlan and assorted fixes
This commit is contained in:
commit
3997b6a952
8 changed files with 86 additions and 28 deletions
|
@ -29,12 +29,14 @@ is_vlan() {
|
||||||
}
|
}
|
||||||
|
|
||||||
case "$PHASE" in
|
case "$PHASE" in
|
||||||
up|down)
|
pre-up|post-down)
|
||||||
|
UP_DOWN="${PHASE##*-}"
|
||||||
|
|
||||||
if is_vlan; then
|
if is_vlan; then
|
||||||
ADD_DEL="add"
|
ADD_DEL="add"
|
||||||
[ "$PHASE" = "down" ] && ADD_DEL="delete"
|
[ "$UP_DOWN" = "down" ] && ADD_DEL="delete"
|
||||||
|
|
||||||
if [ -e /sys/class/net/$IFACE ]; then
|
if [ "$UP_DOWN" = "up" -a -e /sys/class/net/$IFACE ]; then
|
||||||
exit 0
|
exit 0
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
@ -43,16 +45,19 @@ up|down)
|
||||||
echo "Device $IF_VLAN_RAW_DEVICE for $IFACE does not exist"
|
echo "Device $IF_VLAN_RAW_DEVICE for $IFACE does not exist"
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
fi
|
|
||||||
|
|
||||||
if ! [ -d /proc/net/vlan ]; then
|
if ! [ -d /proc/net/vlan ]; then
|
||||||
echo "Loading 8021q kernel module for VLAN support"
|
echo "Loading 8021q kernel module for VLAN support"
|
||||||
${MOCK} modprobe 8021q
|
${MOCK} modprobe 8021q
|
||||||
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
${MOCK} ip link $ADD_DEL link "$IF_VLAN_RAW_DEVICE" name "$IFACE" type vlan id "$IF_VLAN_ID"
|
${MOCK} ip link $ADD_DEL link "$IF_VLAN_RAW_DEVICE" name "$IFACE" type vlan id "$IF_VLAN_ID"
|
||||||
|
[ "$UP_DOWN" = "down" ] && exit 0
|
||||||
|
|
||||||
|
${MOCK} ip link set $UP_DOWN dev $IFACE $IF_LINK_OPTIONS
|
||||||
else
|
else
|
||||||
${MOCK} ip link set $PHASE dev $IFACE $IF_LINK_OPTIONS
|
${MOCK} ip link set $UP_DOWN dev $IFACE $IF_LINK_OPTIONS
|
||||||
fi
|
fi
|
||||||
;;
|
;;
|
||||||
depend)
|
depend)
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
|
|
||||||
|
[ -z "$IF_METRIC" ] && IF_METRIC="1"
|
||||||
[ -n "$IF_VRF_TABLE" ] && VRF_TABLE="table $IF_VRF_TABLE"
|
[ -n "$IF_VRF_TABLE" ] && VRF_TABLE="table $IF_VRF_TABLE"
|
||||||
[ -n "$IF_METRIC" ] && METRIC="metric $IF_METRIC"
|
[ -n "$IF_METRIC" ] && METRIC="metric $IF_METRIC"
|
||||||
|
|
||||||
|
|
|
@ -35,6 +35,9 @@ struct lif_dict_entry {
|
||||||
#define LIF_DICT_FOREACH_SAFE(iter, iter_next, dict) \
|
#define LIF_DICT_FOREACH_SAFE(iter, iter_next, dict) \
|
||||||
LIF_LIST_FOREACH_SAFE((iter), (iter_next), (dict)->list.head)
|
LIF_LIST_FOREACH_SAFE((iter), (iter_next), (dict)->list.head)
|
||||||
|
|
||||||
|
#define LIF_DICT_FOREACH_REVERSE(iter, dict) \
|
||||||
|
LIF_LIST_FOREACH_REVERSE((iter), (dict)->list.tail)
|
||||||
|
|
||||||
typedef int (*lif_dict_cmp_t)(const void *, const void *);
|
typedef int (*lif_dict_cmp_t)(const void *, const void *);
|
||||||
|
|
||||||
extern void lif_dict_init(struct lif_dict *dict);
|
extern void lif_dict_init(struct lif_dict *dict);
|
||||||
|
|
|
@ -43,21 +43,33 @@ handle_commands_for_phase(const struct lif_execute_opts *opts, char *const envp[
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline bool
|
||||||
|
handle_single_executor_for_phase(const struct lif_dict_entry *entry, const struct lif_execute_opts *opts, char *const envp[])
|
||||||
|
{
|
||||||
|
if (strcmp(entry->key, "use"))
|
||||||
|
return true;
|
||||||
|
|
||||||
|
const char *cmd = entry->data;
|
||||||
|
if (!lif_maybe_run_executor(opts, envp, cmd))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
handle_executors_for_phase(const struct lif_execute_opts *opts, char *const envp[], struct lif_interface *iface)
|
handle_executors_for_phase(const struct lif_execute_opts *opts, char *const envp[], struct lif_interface *iface, bool up)
|
||||||
{
|
{
|
||||||
struct lif_node *iter;
|
struct lif_node *iter;
|
||||||
|
|
||||||
LIF_DICT_FOREACH(iter, &iface->vars)
|
if (up)
|
||||||
{
|
{
|
||||||
struct lif_dict_entry *entry = iter->data;
|
LIF_DICT_FOREACH(iter, &iface->vars)
|
||||||
|
handle_single_executor_for_phase(iter->data, opts, envp);
|
||||||
if (strcmp(entry->key, "use"))
|
}
|
||||||
continue;
|
else
|
||||||
|
{
|
||||||
const char *cmd = entry->data;
|
LIF_DICT_FOREACH_REVERSE(iter, &iface->vars)
|
||||||
if (!lif_maybe_run_executor(opts, envp, cmd))
|
handle_single_executor_for_phase(iter->data, opts, envp);
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -219,7 +231,7 @@ lif_lifecycle_run_phase(const struct lif_execute_opts *opts, struct lif_interfac
|
||||||
|
|
||||||
build_environment(&envp, opts, iface, lifname, phase, up ? "start" : "stop");
|
build_environment(&envp, opts, iface, lifname, phase, up ? "start" : "stop");
|
||||||
|
|
||||||
if (!handle_executors_for_phase(opts, envp, iface))
|
if (!handle_executors_for_phase(opts, envp, iface, up))
|
||||||
goto handle_error;
|
goto handle_error;
|
||||||
|
|
||||||
if (!handle_commands_for_phase(opts, envp, iface, phase))
|
if (!handle_commands_for_phase(opts, envp, iface, phase))
|
||||||
|
@ -255,7 +267,11 @@ handle_dependents(const struct lif_execute_opts *opts, struct lif_interface *par
|
||||||
|
|
||||||
/* already up or down, skip */
|
/* already up or down, skip */
|
||||||
if (up == iface->is_up)
|
if (up == iface->is_up)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "ifupdown: skipping dependent interface %s (of %s)\n",
|
||||||
|
iface->ifname, parent->ifname);
|
||||||
continue;
|
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",
|
||||||
|
|
|
@ -42,4 +42,7 @@ extern void lif_node_delete(struct lif_node *node, struct lif_list *list);
|
||||||
#define LIF_LIST_FOREACH_SAFE(iter, iter_next, head) \
|
#define LIF_LIST_FOREACH_SAFE(iter, iter_next, head) \
|
||||||
for ((iter) = (head), (iter_next) = (iter)->next; (iter) != NULL; (iter) = (iter_next), (iter_next) = (iter) != NULL ? (iter)->next : NULL)
|
for ((iter) = (head), (iter_next) = (iter)->next; (iter) != NULL; (iter) = (iter_next), (iter_next) = (iter) != NULL ? (iter)->next : NULL)
|
||||||
|
|
||||||
|
#define LIF_LIST_FOREACH_REVERSE(iter, tail) \
|
||||||
|
for ((iter) = (tail); (iter) != NULL; (iter) = (iter)->prev)
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
18
tests/fixtures/vlan-complex.interfaces
vendored
Normal file
18
tests/fixtures/vlan-complex.interfaces
vendored
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
# From Alpine issue #11885.
|
||||||
|
iface lo inet loopback
|
||||||
|
|
||||||
|
auto eth0
|
||||||
|
iface eth0
|
||||||
|
address 1.2.3.4/24
|
||||||
|
address abcd:ef12:3456:3::4/64
|
||||||
|
mtu 8000
|
||||||
|
|
||||||
|
auto servers
|
||||||
|
iface servers
|
||||||
|
address 1.2.10.4/24
|
||||||
|
gateway 1.2.10.1
|
||||||
|
address abcd:ef12:3456:10::4/64
|
||||||
|
gateway abcd:ef12:3456:10::1
|
||||||
|
mtu 8000
|
||||||
|
vlan-raw-device eth0
|
||||||
|
vlan_id 5
|
|
@ -32,7 +32,8 @@ tests_init \
|
||||||
tunnel_ifupdown2_rewrite \
|
tunnel_ifupdown2_rewrite \
|
||||||
gre_dependency \
|
gre_dependency \
|
||||||
vlan_explicit_learned_dependency \
|
vlan_explicit_learned_dependency \
|
||||||
vlan_guessed_learned_dependency
|
vlan_guessed_learned_dependency \
|
||||||
|
vlan_complex_learned_dependency
|
||||||
|
|
||||||
noargs_body() {
|
noargs_body() {
|
||||||
atf_check -s exit:1 -e ignore ifquery -S/dev/null
|
atf_check -s exit:1 -e ignore ifquery -S/dev/null
|
||||||
|
@ -206,3 +207,14 @@ vlan_guessed_learned_dependency_body() {
|
||||||
-o match:"use vlan" \
|
-o match:"use vlan" \
|
||||||
ifquery -E $EXECUTORS_LINUX -i $FIXTURES/vlan.interfaces eth0.8
|
ifquery -E $EXECUTORS_LINUX -i $FIXTURES/vlan.interfaces eth0.8
|
||||||
}
|
}
|
||||||
|
|
||||||
|
vlan_complex_learned_dependency_body() {
|
||||||
|
atf_check -s exit:0 -o match:"requires eth0" \
|
||||||
|
-o match:"use vlan" \
|
||||||
|
-o match:"address 1.2.10.4/24" \
|
||||||
|
-o match:"gateway 1.2.10.1" \
|
||||||
|
-o match:"address abcd:ef12:3456:10::4/64" \
|
||||||
|
-o match:"gateway abcd:ef12:3456:10::1" \
|
||||||
|
-o match:"vlan-raw-device eth0" \
|
||||||
|
ifquery -E $EXECUTORS_LINUX -i $FIXTURES/vlan-complex.interfaces servers
|
||||||
|
}
|
||||||
|
|
|
@ -15,51 +15,51 @@ tests_init \
|
||||||
vlan_guessed_depend
|
vlan_guessed_depend
|
||||||
|
|
||||||
up_body() {
|
up_body() {
|
||||||
export IFACE=lo PHASE=up MOCK=echo
|
export IFACE=lo PHASE=pre-up MOCK=echo
|
||||||
atf_check -s exit:0 -o match:'ip link set up dev lo' \
|
atf_check -s exit:0 -o match:'ip link set up dev lo' \
|
||||||
${EXECUTOR}
|
${EXECUTOR}
|
||||||
}
|
}
|
||||||
|
|
||||||
down_body() {
|
down_body() {
|
||||||
export IFACE=lo PHASE=down MOCK=echo
|
export IFACE=lo PHASE=post-down MOCK=echo
|
||||||
atf_check -s exit:0 -o match:'ip link set down dev lo' \
|
atf_check -s exit:0 -o match:'ip link set down dev lo' \
|
||||||
${EXECUTOR}
|
${EXECUTOR}
|
||||||
}
|
}
|
||||||
|
|
||||||
mtu_body() {
|
mtu_body() {
|
||||||
export IFACE=eth0 PHASE=up MOCK=echo IF_MTU=1492
|
export IFACE=eth0 PHASE=pre-up MOCK=echo IF_MTU=1492
|
||||||
atf_check -s exit:0 -o match:'ip link set up dev eth0 mtu 1492' \
|
atf_check -s exit:0 -o match:'ip link set up dev eth0 mtu 1492' \
|
||||||
${EXECUTOR}
|
${EXECUTOR}
|
||||||
}
|
}
|
||||||
|
|
||||||
vlan_explicit_up_body() {
|
vlan_explicit_up_body() {
|
||||||
export IFACE=servers PHASE=up MOCK=echo \
|
export IFACE=servers PHASE=pre-up MOCK=echo \
|
||||||
IF_VLAN_RAW_DEVICE="eth0" IF_VLAN_ID="123"
|
IF_VLAN_RAW_DEVICE="eth0" IF_VLAN_ID="123"
|
||||||
atf_check -s exit:0 -o match:'ip link add link eth0 name servers type vlan id 123' \
|
atf_check -s exit:0 -o match:'ip link add link eth0 name servers type vlan id 123' \
|
||||||
${EXECUTOR}
|
${EXECUTOR}
|
||||||
}
|
}
|
||||||
|
|
||||||
vlan_explicit_down_body() {
|
vlan_explicit_down_body() {
|
||||||
export IFACE=servers PHASE=down MOCK=echo \
|
export IFACE=servers PHASE=post-down MOCK=echo \
|
||||||
IF_VLAN_RAW_DEVICE="eth0" IF_VLAN_ID="123"
|
IF_VLAN_RAW_DEVICE="eth0" IF_VLAN_ID="123"
|
||||||
atf_check -s exit:0 -o match:'ip link delete link eth0 name servers type vlan id 123' \
|
atf_check -s exit:0 -o match:'ip link delete link eth0 name servers type vlan id 123' \
|
||||||
${EXECUTOR}
|
${EXECUTOR}
|
||||||
}
|
}
|
||||||
|
|
||||||
vlan_guessed_up_body() {
|
vlan_guessed_up_body() {
|
||||||
export IFACE=eth0.8 PHASE=up MOCK=echo
|
export IFACE=eth0.8 PHASE=pre-up MOCK=echo
|
||||||
atf_check -s exit:0 -o match:'ip link add link eth0 name eth0.8 type vlan id 8' \
|
atf_check -s exit:0 -o match:'ip link add link eth0 name eth0.8 type vlan id 8' \
|
||||||
${EXECUTOR}
|
${EXECUTOR}
|
||||||
}
|
}
|
||||||
|
|
||||||
vlan_guessed_down_body() {
|
vlan_guessed_down_body() {
|
||||||
export IFACE=eth0.8 PHASE=down MOCK=echo
|
export IFACE=eth0.8 PHASE=post-down MOCK=echo
|
||||||
atf_check -s exit:0 -o match:'ip link delete link eth0 name eth0.8 type vlan id 8' \
|
atf_check -s exit:0 -o match:'ip link delete link eth0 name eth0.8 type vlan id 8' \
|
||||||
${EXECUTOR}
|
${EXECUTOR}
|
||||||
}
|
}
|
||||||
|
|
||||||
vlan_explicit_depend_body() {
|
vlan_explicit_depend_body() {
|
||||||
export IFACE=servers PHASE=up MOCK=echo \
|
export IFACE=servers PHASE=pre-up MOCK=echo \
|
||||||
IF_VLAN_RAW_DEVICE="eth0" IF_VLAN_ID="123"
|
IF_VLAN_RAW_DEVICE="eth0" IF_VLAN_ID="123"
|
||||||
atf_check -s exit:0 -o match:'eth0' \
|
atf_check -s exit:0 -o match:'eth0' \
|
||||||
${EXECUTOR}
|
${EXECUTOR}
|
||||||
|
|
Loading…
Reference in a new issue