Merge pull request #100 from BarbarossaTM/chore/addresses-and-gateways-env
Expose all adresses and gateways as environment variables
This commit is contained in:
commit
5b6cb5a128
4 changed files with 92 additions and 28 deletions
|
@ -2,12 +2,13 @@
|
|||
|
||||
set -e
|
||||
|
||||
[ -z "$VERBOSE" ] || set -x
|
||||
[ -z "${VERBOSE}" ] || set -x
|
||||
|
||||
[ -z "${IF_METRIC}" ] && IF_METRIC="1"
|
||||
[ -n "${IF_VRF_TABLE}" ] && VRF_TABLE="table ${IF_VRF_TABLE}"
|
||||
[ -n "${IF_VRF_MEMBER}" ] && VRF_TABLE="vrf ${IF_VRF_MEMBER}"
|
||||
[ -n "${IF_METRIC}" ] && METRIC="metric ${IF_METRIC}"
|
||||
|
||||
[ -z "$IF_METRIC" ] && IF_METRIC="1"
|
||||
[ -n "$IF_VRF_TABLE" ] && VRF_TABLE="table $IF_VRF_TABLE"
|
||||
[ -n "$IF_VRF_MEMBER" ] && VRF_TABLE="vrf $IF_VRF_MEMBER"
|
||||
[ -n "$IF_METRIC" ] && METRIC="metric $IF_METRIC"
|
||||
|
||||
addr_family() {
|
||||
if [ "$1" != "${1#*[0-9].[0-9]}" ]; then
|
||||
|
@ -20,22 +21,31 @@ addr_family() {
|
|||
}
|
||||
|
||||
configure_addresses() {
|
||||
for i in $(ifquery -p address -i $INTERFACES_FILE $IFACE); do
|
||||
addrfam=$(addr_family $i)
|
||||
for addr in ${IF_ADDRESSES}; do
|
||||
addrfam=$(addr_family ${addr})
|
||||
if [ "${IF_POINT_TO_POINT}" -a "${addrfam}" = "-4" ]; then
|
||||
PEER="peer ${IF_POINT_TO_POINT}"
|
||||
else
|
||||
PEER=""
|
||||
fi
|
||||
|
||||
${MOCK} ip $addrfam addr $1 $i $PEER dev $IFACE
|
||||
if [ -z "${MOCK}" -a "${1}" = "del" ]; then
|
||||
# When having multiple addresses set from the same prefix they might/will(?) be configured
|
||||
# as 'secondary' and implicitly removed when removing the non-secondary address. This
|
||||
# leads ip complaining about not being able to remove the secondaries as they are already
|
||||
# gone. So we ignore errors while deconfiguring addresses as they liked occur when removing
|
||||
# a vanish address anyway.
|
||||
${MOCK} ip "${addrfam}" addr "${1}" "${addr}" ${PEER} dev "${IFACE}" 2>/dev/null
|
||||
else
|
||||
${MOCK} ip "${addrfam}" addr "${1}" "${addr}" ${PEER} dev "${IFACE}"
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
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 $VRF_TABLE $METRIC dev $IFACE
|
||||
for gw in ${IF_GATEWAYS}; do
|
||||
addrfam=$(addr_family ${gw})
|
||||
${MOCK} ip "${addrfam}" route "${1}" default via "${gw}" ${VRF_TABLE} ${METRIC} dev "${IFACE}"
|
||||
done
|
||||
}
|
||||
|
||||
|
|
|
@ -28,6 +28,8 @@
|
|||
#include "libifupdown/tokenize.h"
|
||||
#include "libifupdown/config-file.h"
|
||||
|
||||
#define BUFFER_LEN 4096
|
||||
|
||||
static bool
|
||||
handle_commands_for_phase(const struct lif_execute_opts *opts, char *const envp[], const struct lif_interface *iface, const char *phase)
|
||||
{
|
||||
|
@ -112,6 +114,34 @@ query_dependents_from_executors(const struct lif_execute_opts *opts, char *const
|
|||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
append_to_buffer(char **buffer, size_t *buffer_len, char **end, const char *value)
|
||||
{
|
||||
size_t value_len = strlen (value);
|
||||
|
||||
/* Make sure there is enough room to add the value to the buffer */
|
||||
if (*buffer_len < strlen (*buffer) + value_len + 2)
|
||||
{
|
||||
*buffer = realloc (*buffer, *buffer_len * 2);
|
||||
if (*buffer == NULL)
|
||||
/* XXX Here be dragons */
|
||||
return false;
|
||||
|
||||
*buffer_len = *buffer_len * 2;
|
||||
}
|
||||
|
||||
/* Append value to buffer */
|
||||
size_t printed = snprintf (*end, value_len + 2, "%s ", value);
|
||||
if (printed < value_len + 1)
|
||||
/* Here be dragons */
|
||||
return false;
|
||||
|
||||
/* Move end pointer to last printed byte */
|
||||
*end += printed;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void
|
||||
build_environment(char **envp[], const struct lif_execute_opts *opts, const struct lif_interface *iface, const char *lifname, const char *phase, const char *mode)
|
||||
{
|
||||
|
@ -132,21 +162,35 @@ build_environment(char **envp[], const struct lif_execute_opts *opts, const stru
|
|||
const struct lif_node *iter;
|
||||
bool did_address = false, did_gateway = false;
|
||||
|
||||
/* Allocate a buffer for all possible addresses, if any */
|
||||
char *addresses = calloc (BUFFER_LEN, 1);
|
||||
size_t addresses_size = BUFFER_LEN;
|
||||
char *addresses_end = addresses;
|
||||
|
||||
/* Allocate a buffer for all possible gateways, if any */
|
||||
char *gateways = calloc (BUFFER_LEN, 1);
|
||||
size_t gateways_size = BUFFER_LEN;
|
||||
char *gateways_end = gateways;
|
||||
|
||||
LIF_DICT_FOREACH(iter, &iface->vars)
|
||||
{
|
||||
const struct lif_dict_entry *entry = iter->data;
|
||||
|
||||
if (!strcmp(entry->key, "address"))
|
||||
{
|
||||
if (did_address)
|
||||
continue;
|
||||
|
||||
struct lif_address *addr = entry->data;
|
||||
char addrbuf[4096];
|
||||
|
||||
if (!lif_address_unparse(addr, addrbuf, sizeof addrbuf, true))
|
||||
continue;
|
||||
|
||||
/* Append address to buffer */
|
||||
append_to_buffer(&addresses, &addresses_size, &addresses_end, addrbuf);
|
||||
|
||||
/* Only print IF_ADDRESS once */
|
||||
if (did_address)
|
||||
continue;
|
||||
|
||||
lif_environment_push(envp, "IF_ADDRESS", addrbuf);
|
||||
did_address = true;
|
||||
|
||||
|
@ -154,6 +198,9 @@ build_environment(char **envp[], const struct lif_execute_opts *opts, const stru
|
|||
}
|
||||
else if (!strcmp(entry->key, "gateway"))
|
||||
{
|
||||
/* Append address to buffer */
|
||||
append_to_buffer(&gateways, &gateways_size, &gateways_end, entry->data);
|
||||
|
||||
if (did_gateway)
|
||||
continue;
|
||||
|
||||
|
@ -179,6 +226,15 @@ build_environment(char **envp[], const struct lif_execute_opts *opts, const stru
|
|||
|
||||
lif_environment_push(envp, envkey, (const char *) entry->data);
|
||||
}
|
||||
|
||||
if (addresses != NULL)
|
||||
lif_environment_push(envp, "IF_ADDRESSES", addresses);
|
||||
if (gateways != NULL)
|
||||
lif_environment_push(envp, "IF_GATEWAYS", gateways);
|
||||
|
||||
/* Clean up */
|
||||
free (addresses);
|
||||
free (gateways);
|
||||
}
|
||||
|
||||
bool
|
||||
|
|
|
@ -23,7 +23,8 @@ lif_common_version(void)
|
|||
{
|
||||
printf("%s %s\n", PACKAGE_NAME, PACKAGE_VERSION);
|
||||
|
||||
printf("\nCopyright (c) 2020 Ariadne Conill <ariadne@dereferenced.org>\n\n");
|
||||
printf("\nCopyright (c) 2020 Ariadne Conill <ariadne@dereferenced.org>\n");
|
||||
printf("\nCopyright (c) 2020 Maximilian Wilhelm <max@sdn.clinic>\n\n");
|
||||
|
||||
printf("Permission to use, copy, modify, and/or distribute this software for any\n");
|
||||
printf("purpose with or without fee is hereby granted, provided that the above\n");
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
|
||||
. $(atf_get_srcdir)/../test_env.sh
|
||||
EXECUTOR="$(atf_get_srcdir)/../../executor-scripts/linux/static"
|
||||
FIXTURES="$(atf_get_srcdir)/../fixtures"
|
||||
|
||||
tests_init \
|
||||
up \
|
||||
|
@ -14,7 +13,8 @@ tests_init \
|
|||
metric_down
|
||||
|
||||
up_body() {
|
||||
export IFACE=eth0 PHASE=up MOCK=echo INTERFACES_FILE="$FIXTURES/static-eth0.interfaces"
|
||||
export IFACE=eth0 PHASE=up MOCK=echo IF_ADDRESSES="203.0.113.2/24 2001:db8:1000:2::2/64" \
|
||||
IF_GATEWAYS="203.0.113.1 2001:db8:1000:2::1"
|
||||
atf_check -s exit:0 \
|
||||
-o match:'addr add 203.0.113.2/24 dev eth0' \
|
||||
-o match:'addr add 2001:db8:1000:2::2/64 dev eth0' \
|
||||
|
@ -24,8 +24,8 @@ up_body() {
|
|||
}
|
||||
|
||||
up_ptp_body() {
|
||||
export IFACE=eth0 PHASE=up MOCK=echo INTERFACES_FILE="$FIXTURES/static-eth0-ptp.interfaces" \
|
||||
IF_POINT_TO_POINT="192.0.2.1"
|
||||
export IFACE=eth0 PHASE=up MOCK=echo IF_ADDRESSES="203.0.113.2/32 2001:db8:1000:2::2/64" \
|
||||
IF_GATEWAYS="192.0.2.1 2001:db8:1000:2::1" IF_POINT_TO_POINT="192.0.2.1"
|
||||
atf_check -s exit:0 \
|
||||
-o match:'addr add 203.0.113.2/32 peer 192.0.2.1 dev eth0' \
|
||||
-o match:'route add default via 192.0.2.1 metric 1 dev eth0' \
|
||||
|
@ -35,7 +35,8 @@ up_ptp_body() {
|
|||
}
|
||||
|
||||
down_body() {
|
||||
export IFACE=eth0 PHASE=down MOCK=echo INTERFACES_FILE="$FIXTURES/static-eth0.interfaces"
|
||||
export IFACE=eth0 PHASE=down MOCK=echo IF_ADDRESSES="203.0.113.2/24 2001:db8:1000:2::2/64" \
|
||||
IF_GATEWAYS="203.0.113.1 2001:db8:1000:2::1"
|
||||
atf_check -s exit:0 \
|
||||
-o match:'addr del 203.0.113.2/24 dev eth0' \
|
||||
-o match:'addr del 2001:db8:1000:2::2/64 dev eth0' \
|
||||
|
@ -45,32 +46,28 @@ down_body() {
|
|||
}
|
||||
|
||||
vrf_up_body() {
|
||||
export IFACE=vrf-red PHASE=up MOCK=echo INTERFACES_FILE="$FIXTURES/vrf.interfaces" \
|
||||
IF_VRF_TABLE=1
|
||||
export IFACE=vrf-red PHASE=up MOCK=echo IF_GATEWAYS=203.0.113.2 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
|
||||
export IFACE=vrf-red PHASE=down MOCK=echo IF_GATEWAYS=203.0.113.2 IF_VRF_TABLE=1
|
||||
atf_check -s exit:0 \
|
||||
-o match:'route del default via 203.0.113.2 table 1' \
|
||||
${EXECUTOR}
|
||||
}
|
||||
|
||||
metric_up_body() {
|
||||
export IFACE=vrf-red PHASE=up MOCK=echo INTERFACES_FILE="$FIXTURES/vrf.interfaces" \
|
||||
IF_VRF_TABLE=1 IF_METRIC=20
|
||||
export IFACE=vrf-red PHASE=up MOCK=echo IF_GATEWAYS=203.0.113.2 IF_VRF_TABLE=1 IF_METRIC=20
|
||||
atf_check -s exit:0 \
|
||||
-o match:'route add default via 203.0.113.2 table 1 metric 20' \
|
||||
${EXECUTOR}
|
||||
}
|
||||
|
||||
metric_down_body() {
|
||||
export IFACE=vrf-red PHASE=down MOCK=echo INTERFACES_FILE="$FIXTURES/vrf.interfaces" \
|
||||
IF_VRF_TABLE=1 IF_METRIC=20
|
||||
export IFACE=vrf-red PHASE=down MOCK=echo IF_GATEWAYS=203.0.113.2 IF_VRF_TABLE=1 IF_METRIC=20
|
||||
atf_check -s exit:0 \
|
||||
-o match:'route del default via 203.0.113.2 table 1 metric 20' \
|
||||
${EXECUTOR}
|
||||
|
|
Loading…
Reference in a new issue