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…
	
	Add table
		Add a link
		
	
		Reference in a new issue