diff --git a/executor-scripts/linux/static b/executor-scripts/linux/static index d7e3ee3..e14ca6b 100755 --- a/executor-scripts/linux/static +++ b/executor-scripts/linux/static @@ -1,5 +1,8 @@ #!/bin/sh +VRF_TABLE="" +[ -n "$IF_VRF_TABLE" ] && VRF_TABLE="table $IF_VRF_TABLE" + addr_family() { if [ "$1" != "${1#*[0-9].[0-9]}" ]; then echo "-4" @@ -20,7 +23,7 @@ configure_addresses() { configure_gateways() { for i in $(ifquery -p gateway -i $INTERFACES_FILE $IFACE); do addrfam=$(addr_family $i) - ${MOCK} ip $addrfam route $1 default via $i + ${MOCK} ip $addrfam route $1 default via $i $VRF_TABLE done } diff --git a/libifupdown/interface-file.c b/libifupdown/interface-file.c index 674cecd..1f2d19d 100644 --- a/libifupdown/interface-file.c +++ b/libifupdown/interface-file.c @@ -123,14 +123,9 @@ lif_interface_file_parse(struct lif_dict *collection, const char *filename) while (*token) { if (!strcmp(token, "dhcp")) - { - cur_iface->is_dhcp = true; - lif_dict_add(&cur_iface->vars, "use", strdup("dhcp")); - } + lif_interface_use_executor(cur_iface, "dhcp"); else if (!strcmp(token, "ppp")) - { - lif_dict_add(&cur_iface->vars, "use", strdup("ppp")); - } + lif_interface_use_executor(cur_iface, "ppp"); else if (!strcmp(token, "inherits")) { token = lif_next_token(&bufp); @@ -162,21 +157,12 @@ lif_interface_file_parse(struct lif_dict *collection, const char *filename) } /* pass requires as compatibility env vars to appropriate executors (bridge, bond) */ - if (!strcmp(executor, "dhcp")) - cur_iface->is_dhcp = true; - else if (!strcmp(executor, "bridge")) + if (!strcmp(executor, "bridge")) cur_iface->is_bridge = true; else if (!strcmp(executor, "bond")) cur_iface->is_bond = true; - else if (!strcmp(executor, "static")) - { - cur_iface->is_static = true; - continue; - } - else if (!strcmp(executor, "link")) - continue; - lif_dict_add(&cur_iface->vars, token, strdup(executor)); + lif_interface_use_executor(cur_iface, executor); } else if (!strcmp(token, "inherit")) { @@ -206,6 +192,19 @@ lif_interface_file_parse(struct lif_dict *collection, const char *filename) lif_interface_address_add(cur_iface, addr); } + else if (!strcmp(token, "gateway")) + { + char *addr = lif_next_token(&bufp); + + if (cur_iface == NULL) + { + fprintf(stderr, "%s: gateway '%s' without interface\n", filename, addr); + goto parse_error; + } + + lif_interface_use_executor(cur_iface, "static"); + lif_dict_add(&cur_iface->vars, token, strdup(addr)); + } else if (cur_iface != NULL) { token = maybe_remap_token(token); @@ -214,17 +213,15 @@ lif_interface_file_parse(struct lif_dict *collection, const char *filename) /* Check if token looks like - and assume is an addon */ char *word_end = strchr(token, '-'); - if (word_end) + if (word_end != NULL) { /* Copy word1 to not mangle *token */ char *addon = strndup(token, word_end - token); - if (lif_dict_add_once(&cur_iface->vars, "use", addon, (lif_dict_cmp_t) strcmp) == NULL) - free(addon); + lif_interface_use_executor(cur_iface, addon); + free(addon); /* pass requires as compatibility env vars to appropriate executors (bridge, bond) */ - if (!strcmp(addon, "dhcp")) - cur_iface->is_dhcp = true; - else if (!strcmp(addon, "bridge")) + if (!strcmp(addon, "bridge")) cur_iface->is_bridge = true; else if (!strcmp(addon, "bond")) cur_iface->is_bond = true; diff --git a/libifupdown/interface.c b/libifupdown/interface.c index 8841c13..fe9acea 100644 --- a/libifupdown/interface.c +++ b/libifupdown/interface.c @@ -63,10 +63,7 @@ lif_interface_init(struct lif_interface *interface, const char *ifname) interface->ifname = strdup(ifname); - if (strchr(ifname, '.') == NULL) - lif_dict_add(&interface->vars, "use", strdup("link")); - else - lif_dict_add(&interface->vars, "use", strdup("vlan")); + lif_interface_use_executor(interface, strchr(ifname, '.') == NULL ? "link" : "vlan"); } bool @@ -80,11 +77,7 @@ lif_interface_address_add(struct lif_interface *interface, const char *address) return false; } - if (!interface->is_static) - { - lif_dict_add(&interface->vars, "use", strdup("static")); - interface->is_static = true; - } + lif_interface_use_executor(interface, "static"); lif_dict_add(&interface->vars, "address", addr); @@ -137,6 +130,15 @@ lif_interface_fini(struct lif_interface *interface) free(interface->ifname); } +void +lif_interface_use_executor(struct lif_interface *interface, const char *executor) +{ + char *exec_addon = strdup(executor); + + if (lif_dict_add_once(&interface->vars, "use", exec_addon, (lif_dict_cmp_t) strcmp) == NULL) + free(exec_addon); +} + void lif_interface_collection_init(struct lif_dict *collection) { @@ -147,7 +149,7 @@ lif_interface_collection_init(struct lif_dict *collection) /* always enable loopback interface as part of a collection */ if_lo = lif_interface_collection_find(collection, "lo"); if_lo->is_auto = true; - lif_dict_add(&if_lo->vars, "use", strdup("loopback")); + lif_interface_use_executor(if_lo, "loopback"); } void @@ -228,8 +230,6 @@ lif_interface_collection_inherit(struct lif_interface *interface, struct lif_dic return false; lif_dict_add(&interface->vars, "inherit", strdup(ifname)); - interface->is_static = parent->is_static; - interface->is_dhcp = parent->is_dhcp; interface->is_bond = parent->is_bond; interface->is_bridge = parent->is_bridge; diff --git a/libifupdown/interface.h b/libifupdown/interface.h index 045f848..3f2c287 100644 --- a/libifupdown/interface.h +++ b/libifupdown/interface.h @@ -47,11 +47,9 @@ extern bool lif_address_unparse(const struct lif_address *address, char *buf, si struct lif_interface { char *ifname; - bool is_dhcp; bool is_auto; bool is_bridge; bool is_bond; - bool is_static; struct lif_dict vars; @@ -68,6 +66,7 @@ extern void lif_interface_init(struct lif_interface *interface, const char *ifna extern bool lif_interface_address_add(struct lif_interface *interface, const char *address); extern void lif_interface_address_delete(struct lif_interface *interface, const char *address); extern void lif_interface_fini(struct lif_interface *interface); +extern void lif_interface_use_executor(struct lif_interface *interface, const char *executor); extern void lif_interface_collection_init(struct lif_dict *collection); extern void lif_interface_collection_fini(struct lif_dict *collection); diff --git a/libifupdown/lifecycle.c b/libifupdown/lifecycle.c index dc31474..d2a32e3 100644 --- a/libifupdown/lifecycle.c +++ b/libifupdown/lifecycle.c @@ -104,10 +104,7 @@ build_environment(char **envp[], const struct lif_execute_opts *opts, struct lif lif_environment_push(envp, "IFACE", lifname); lif_environment_push(envp, "PHASE", phase); lif_environment_push(envp, "MODE", mode); - - /* try to provide $METHOD for ifupdown1 scripts if we can */ - if (iface->is_dhcp) - lif_environment_push(envp, "METHOD", "dhcp"); + lif_environment_push(envp, "METHOD", "none"); if (opts->verbose) lif_environment_push(envp, "VERBOSE", "1"); diff --git a/tests/fixtures/vrf.interfaces b/tests/fixtures/vrf.interfaces index bfcf11b..fc40df2 100644 --- a/tests/fixtures/vrf.interfaces +++ b/tests/fixtures/vrf.interfaces @@ -1,5 +1,6 @@ iface vrf-red vrf-table 1 + gateway 203.0.113.2 auto eth0 iface eth0 diff --git a/tests/ifquery_test b/tests/ifquery_test index 3c4361e..a53c22c 100755 --- a/tests/ifquery_test +++ b/tests/ifquery_test @@ -22,6 +22,7 @@ tests_init \ vrf_dependency \ vrf_ifupdown2_rewrite \ vrf_ifupdown2_dependency \ + vrf_implicit_static_gateway \ ppp_dependency \ ppp_legacy_rewrite \ tunnel_dependency \ @@ -139,6 +140,11 @@ vrf_ifupdown2_dependency_body() { ifquery -E $EXECUTORS_LINUX -i $FIXTURES/vrf-ifupdown2.interfaces eth0 } +vrf_implicit_static_gateway_body() { + atf_check -s exit:0 -o match:"use static" \ + ifquery -E $EXECUTORS_LINUX -i $FIXTURES/vrf.interfaces vrf-red +} + ppp_dependency_body() { atf_check -s exit:0 -o match:"requires eth0" \ ifquery -E $EXECUTORS_LINUX -i $FIXTURES/ppp.interfaces ppp0 diff --git a/tests/linux/static_test b/tests/linux/static_test index a07ea8e..79bf820 100755 --- a/tests/linux/static_test +++ b/tests/linux/static_test @@ -4,7 +4,7 @@ EXECUTOR="$(atf_get_srcdir)/../../executor-scripts/linux/static" FIXTURES="$(atf_get_srcdir)/../fixtures" -tests_init up down +tests_init up down vrf_up vrf_down up_body() { export IFACE=eth0 PHASE=up MOCK=echo INTERFACES_FILE="$FIXTURES/static-eth0.interfaces" @@ -25,3 +25,19 @@ down_body() { -o match:'route del default via 2001:db8:1000:2::1' \ ${EXECUTOR} } + +vrf_up_body() { + export IFACE=vrf-red PHASE=up MOCK=echo INTERFACES_FILE="$FIXTURES/vrf.interfaces" \ + IF_VRF_TABLE=1 + atf_check -s exit:0 \ + -o match:'route add default via 203.0.113.2 table 1' \ + ${EXECUTOR} +} + +vrf_down_body() { + export IFACE=vrf-red PHASE=down MOCK=echo INTERFACES_FILE="$FIXTURES/vrf.interfaces" \ + IF_VRF_TABLE=1 + atf_check -s exit:0 \ + -o match:'route del default via 203.0.113.2 table 1' \ + ${EXECUTOR} +}