Compare commits

..

No commits in common. "main" and "ifupdown-ng-0.11.2" have entirely different histories.

31 changed files with 81 additions and 516 deletions

View file

@ -1,5 +1,4 @@
Copyright (c) 2020-2021 Ariadne Conill <ariadne@dereferenced.org>
Copyright (c) 2020-2021 Maximilian Wilhelm <max@sdn.clinic>
Copyright (c) 2020 Ariadne Conill <ariadne@dereferenced.org>
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above

View file

@ -4,7 +4,7 @@ LIBBSD_CFLAGS =
LIBBSD_LIBS =
PACKAGE_NAME := ifupdown-ng
PACKAGE_VERSION := 0.11.3
PACKAGE_VERSION := 0.11.2
PACKAGE_BUGREPORT := https://github.com/ifupdown-ng/ifupdown-ng/issues/new
@ -14,8 +14,7 @@ CONFIG_FILE := /etc/network/ifupdown-ng.conf
EXECUTOR_PATH := /usr/libexec/ifupdown-ng
CFLAGS ?= -ggdb3 -Os
CFLAGS += -Wall -Wextra -Werror
CFLAGS += -Wmissing-declarations -Wmissing-prototypes -Wcast-align -Wpointer-arith -Wreturn-type
CFLAGS += -Wall -Wextra
CFLAGS += ${LIBBSD_CFLAGS}
CPPFLAGS = -I.
CPPFLAGS += -DINTERFACES_FILE=\"${INTERFACES_FILE}\"
@ -120,8 +119,6 @@ EXECUTOR_SCRIPTS ?= ${EXECUTOR_SCRIPTS_CORE} ${EXECUTOR_SCRIPTS_OPT}
EXECUTOR_SCRIPTS_STUB ?=
EXECUTOR_SCRIPTS_NATIVE ?=
TARGET_LIBS = ${LIBIFUPDOWN_LIB}
LIBS += ${TARGET_LIBS} ${LIBBSD_LIBS}
@ -156,9 +153,6 @@ install: all
for i in ${EXECUTOR_SCRIPTS_STUB}; do \
install -D -m755 executor-scripts/stub/$$i ${DESTDIR}${EXECUTOR_PATH}/$$i; \
done
for i in ${EXECUTOR_SCRIPTS_NATIVE}; do \
install -D -m755 executor-scripts/${LAYOUT}-native/$$i ${DESTDIR}${EXECUTOR_PATH}/$$i; \
done
install -D -m644 dist/ifupdown-ng.conf.example ${DESTDIR}${CONFIG_FILE}.example
.scd.1 .scd.2 .scd.3 .scd.4 .scd.5 .scd.6 .scd.7 .scd.8:
@ -173,7 +167,6 @@ MANPAGES_5 = \
doc/interfaces-bridge.5 \
doc/interfaces-forward.5 \
doc/interfaces-ppp.5 \
doc/interfaces-tunnel.5 \
doc/interfaces-vrf.5 \
doc/interfaces-vxlan.5 \
doc/interfaces-wifi.5 \

View file

@ -39,11 +39,11 @@ On glibc systems, you must install `libbsd-dev` or equivalent and additionally d
make LIBBSD_CFLAGS="$(pkg-config --cflags libbsd-overlay)" LIBBSD_LIBS="$(pkg-config --cflags --libs libbsd-overlay)"
make install
To run the tests, do `make check`. Running the checks requires `kyua` (`apk add kyua` / `apt install kyua`).
To run the tests, do `make check`. Running the checks requires `kyua` (`apk add kyua`, not packaged for Debian).
To build the documentation, do `make docs` and `make install_docs`. Building
the documentation requires scdoc (`apk add scdoc` / `apt install scdoc`).
## Discussion
Discuss ifupdown-ng on IRC: irc.oftc.net #ifupdown-ng
Discuss ifupdown-ng on IRC: irc.as7007.net #ifupdown-ng

View file

@ -17,8 +17,7 @@
#include <limits.h>
#include <stdio.h>
#include <string.h>
#include "cmd/multicall.h"
#include "cmd/ifctrstat-linux.h"
#include "multicall.h"
struct counter_desc {
const char *name;
@ -42,7 +41,7 @@ counter_compare(const void *key, const void *candidate)
return strcasecmp((const char *)key, ((struct counter_desc *)candidate)->name);
}
const char *
char *
read_counter(const char *interface, const char *counter)
{
FILE *fp;

View file

@ -1,22 +0,0 @@
/*
* cmd/ifctrstat-linux.c
* Purpose: Implement ifctrstat system-specific routines for Linux
*
* Copyright (c) 2021 Maximilian Wilhelm <max@sdn.clinic>
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* This software is provided 'as is' and without any warranty, express or
* implied. In no event shall the authors be liable for any damages arising
* from the use of this software.
*/
#ifndef IFUPDOWN_IFCTRSTAT_LINUX__H__GUARD
#define IFUPDOWN_IFCTRSTAT_LINUX__H__GUARD
extern const char * read_counter(const char *interface, const char *counter);
#endif

View file

@ -20,11 +20,12 @@
#include <string.h>
#include "libifupdown/libifupdown.h"
#include "cmd/multicall.h"
#include "cmd/ifctrstat-linux.h"
extern struct counter_desc { const char *name; const void *data; } avail_counters[];
extern int avail_counters_count;
extern const char *read_counter(const char *interface, const char *counter);
static bool show_label = true;
static bool
@ -95,7 +96,7 @@ ifctrstat_set_nolabel(const char *opt_arg)
show_label = false;
}
static int
int
ifctrstat_main(int argc, char *argv[])
{
if (optind >= argc)

View file

@ -131,7 +131,7 @@ pp_impl_cmp(const void *a, const void *b)
return strcmp(key, impl->name);
}
static int
int
ifparse_main(int argc, char *argv[])
{
struct lif_dict state = {};

View file

@ -22,7 +22,7 @@
#include "cmd/multicall.h"
#include "cmd/pretty-print-iface.h"
static void
void
print_interface_dot(struct lif_dict *collection, struct lif_interface *iface, struct lif_interface *parent)
{
if (!lif_lifecycle_query_dependents(&exec_opts, iface, iface->ifname))
@ -57,7 +57,7 @@ print_interface_dot(struct lif_dict *collection, struct lif_interface *iface, st
}
}
static void
void
print_interface_property(struct lif_interface *iface, const char *property)
{
struct lif_node *iter;
@ -83,7 +83,7 @@ print_interface_property(struct lif_interface *iface, const char *property)
}
}
static void
void
list_interfaces(struct lif_dict *collection, struct match_options *opts)
{
struct lif_node *iter;
@ -126,7 +126,7 @@ list_interfaces(struct lif_dict *collection, struct match_options *opts)
static bool listing = false, listing_stat = false, listing_running = false;
static bool allow_undefined = false;
static void
void
list_state(struct lif_dict *state, struct match_options *opts)
{
struct lif_node *iter;
@ -217,7 +217,7 @@ static struct if_option_group local_option_group = {
.group = local_options
};
static int
int
ifquery_main(int argc, char *argv[])
{
struct lif_dict state = {};

View file

@ -27,7 +27,7 @@
static bool up;
static bool
bool
is_ifdown()
{
if (strstr(argv0, "ifdown") != NULL)
@ -36,7 +36,7 @@ is_ifdown()
return false;
}
static int
int
acquire_state_lock(const char *state_path, const char *lifname)
{
if (exec_opts.mock || exec_opts.no_lock)
@ -94,7 +94,7 @@ acquire_state_lock(const char *state_path, const char *lifname)
return fd;
}
static bool
bool
skip_interface(struct lif_interface *iface, const char *ifname, struct lif_dict *state, bool update_state)
{
if (iface->is_template)
@ -146,7 +146,7 @@ skip_interface(struct lif_interface *iface, const char *ifname, struct lif_dict
return false;
}
static bool
bool
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);
@ -194,7 +194,7 @@ change_interface(struct lif_interface *iface, struct lif_dict *collection, struc
return true;
}
static bool
bool
change_auto_interfaces(struct lif_dict *collection, struct lif_dict *state, struct match_options *opts)
{
struct lif_node *iter;
@ -222,7 +222,7 @@ change_auto_interfaces(struct lif_dict *collection, struct lif_dict *state, stru
return true;
}
static int
int
update_state_file_and_exit(int rc, struct lif_dict *state)
{
if (exec_opts.mock)
@ -243,7 +243,7 @@ update_state_file_and_exit(int rc, struct lif_dict *state)
return rc;
}
static int
int
ifupdown_main(int argc, char *argv[])
{
up = !is_ifdown();

View file

@ -21,13 +21,10 @@
#include <getopt.h>
#include "cmd/multicall.h"
#define DEFAULT_TIMEOUT 300
struct lif_execute_opts exec_opts = {
.interfaces_file = INTERFACES_FILE,
.executor_path = EXECUTOR_PATH,
.state_file = STATE_FILE,
.timeout = DEFAULT_TIMEOUT,
.state_file = STATE_FILE
};
static void
@ -77,14 +74,6 @@ set_force(const char *opt_arg)
exec_opts.force = true;
}
static void
set_timeout(const char *opt_arg)
{
exec_opts.timeout = atoi(opt_arg);
if (exec_opts.timeout < 0)
exec_opts.timeout = DEFAULT_TIMEOUT;
}
static struct if_option exec_options[] = {
{'f', "force", NULL, "force (de)configuration", false, set_force},
{'i', "interfaces", "interfaces FILE", "use FILE for interface definitions", true, set_interfaces_file},
@ -93,7 +82,6 @@ static struct if_option exec_options[] = {
{'v', "verbose", NULL, "show what commands are being run", false, set_verbose},
{'E', "executor-path", "executor-path PATH", "use PATH for executor directory", true, set_executor_path},
{'S', "state-file", "state-file FILE", "use FILE for state", true, set_state_file},
{'T', "timeout", "timeout TIMEOUT", "wait TIMEOUT seconds for executors to complete", true, set_timeout},
};
struct if_option_group exec_option_group = {

View file

@ -39,7 +39,7 @@ set_include_pattern(const char *opt_arg)
static void
set_exclude_pattern(const char *opt_arg)
{
match_opts.exclude_pattern = opt_arg;
match_opts.include_pattern = opt_arg;
}
static struct if_option match_options[] = {

View file

@ -62,7 +62,7 @@ struct if_applet *applet_table[] = {
&ifupdown_applet,
};
static int
int
applet_cmp(const void *a, const void *b)
{
const char *key = a;
@ -101,7 +101,7 @@ main(int argc, char *argv[])
return self_applet->main(argc, argv);
}
static int
int
multicall_main(int argc, char *argv[])
{
if (argc < 2)

View file

@ -272,4 +272,4 @@ used for an interface, use the ifquery(8) command.
If you have further questions about how to use ifupdown-ng to
configure a specific scenario, drop by the
[ifupdown-ng IRC channel](irc://irc.oftc.net/#ifupdown-ng).
[ifupdown-ng IRC channel](irc://irc.as7007.net/#ifupdown-ng).

View file

@ -45,10 +45,6 @@ configured in the configuration database.
*-S, --state-file* _FILE_
Use _FILE_ as the state database.
*-T, --timeout* _TIMEOUT_
Wait up to _TIMEOUT_ seconds for executors to complete before
raising an error.
*-V, --version*
Print the ifupdown-ng version and exit.

View file

@ -43,10 +43,6 @@ stanzas between different formats.
*-S, --state-file* _FILE_
Use _FILE_ as the state database.
*-T, --timeout* _TIMEOUT_
Wait up to _TIMEOUT_ seconds for executors to complete before
raising an error.
*-V, --version*
Print the ifupdown-ng version and exit.

View file

@ -62,10 +62,6 @@ configuration file to the current format.
*-S, --state-file* _FILE_
Use _FILE_ as the state database.
*-T, --timeout* _TIMEOUT_
Wait up to _TIMEOUT_ seconds for executors to complete before
raising an error.
*-V, --version*
Print the ifupdown-ng version and exit.

View file

@ -48,10 +48,6 @@ configured in the configuration database.
*-S, --state-file* _FILE_
Use _FILE_ as the state database.
*-T, --timeout* _TIMEOUT_
Wait up to _TIMEOUT_ seconds for executors to complete before
raising an error.
*-V, --version*
Print the ifupdown-ng version and exit.

View file

@ -1,161 +0,0 @@
interfaces-tunnel(5)
# NAME
*interfaces-tunnel* - Tunnel extensions for the interfaces(5) file format
# DESCRIPTION
The following options set up tunneling interfaces with ifupdown-ng.
# TUNNEL-RELATED OPTIONS
A tunnel interface must have a mode, remote IP and a local IP or device
set, all other options are optional.
*tunnel-mode* _mode_
Denotes the mode for this tunnel. Basically all tunnel modes supported
by Linux / iproute2 are supported as well. This includes but is not
limited to _gre_/_gretap_, _ip6gre_/_ip6gretap_, _ipip_/_ip6ip_/_sit_.
*tunnel-local* _IP_
Denotes the IP address used as the local tunnel endpoint. According
to the _tunnel-mode_ an IPv4 or IPv6 address has to be given.
For compatiblity to ifupdown1 _local_ is an alias for this option.
*tunnel-local-dev* _interface_
When the local IP address the tunnel should be established from isn't
static and therefore might change (e.g. configured by DHCP or PPP) it
might be desireable to just use the address configured on _interface_.
When _tunnel-local-dev_ is given instead of _tunnel-local_ ifupdown-ng
will try to determine the IP address set on the given _interface_ with
respect to the address family required to set up a tunnel of the given
_mode_ and use this to set up the tunnel.
*tunnel-remote* _IP_
Denotes the IP address used as the remote tunnel endpoint. According
to the _tunnel-mode_ an IPv4 or IPv6 address has to be given.
For compatiblity to ifupdown1 _endpoint_ is an alias for this option.
*tunnel-physdev* _interface_
Denotes the _interface_ the encapsulated packets should be sent out by.
This comes in handy when using VRFs to denote that the local tunnel
endpoint should be terminated in VRF _interface_ or the VRF associated
with _interface_.
Note: Depending on the _mode_ of the tunnel either the VRF interface
or the real underlay interface may have to given as _interface_.
*tunnel-ttl* _ttl_
Denotes the TTL value to use in outgoing packets. _ttl_ is a number in the
range 1 - 255 whereas 0 is a special value meaning that packets inherit the
TTL value. The default for IPv4 tunnels is to inherit the TTL, for IPv6
tunnels it's 64. For compatiblity to ifupdown1 _ttl_ is an alias for this option.
# IPIP/SIT-RELATED OPTIONS
*tunnel-encap* _encap_
Denotes the type of secondary UDP encapsulation to use for this tunnel
if any. Supported _encap_ values are _fou_, _gue_, and _none_.
_fou_ indicates Foo-Over-UDP, _gue_ indicates Generic UDP Encapsulation.
# GRE-RELATED OPTIONS
*tunnel-encap* _encap_
Denotes the type of secondary UDP encapsulation to use for this tunnel
if any. Supported _encap_ values are _fou_, _gue_, and _none_.
_fou_ indicates Foo-Over-UDP, _gue_ indicates Generic UDP Encapsulation.
*tunnel-key* _key_
Denotes the_key to used for keyed GRE to allow multiple tunnels between
the same two endpoints. _key_ is either a number or an IPv4 address-
like dotted quad. The key parameter specifies the same key to use in both
directions. The _tunnel-ikey_ and _tunnel-okey_ parameters specify different
keys for input and output. For compatiblity to ifupdown1 _key_ is an alias
for this option.
*tunnel-hoplimit* _ttl_
Denotes the Hop Limit value to use in outgoing packets for _ip6gre_/_ip6gretap_
tunnels.
*tunnel-ignore-df* _bool_
Denotes wether to enable/disable IPv4 DF suppression on this tunnel. Normally
datagrams that exceed the MTU will be fragmented; the presence of the DF flag
inhibits this, resulting instead in an ICMP Unreachable (Fragmentation Required)
message. Enabling this attribute causes the DF flag to be ignored.
*tunnel-ikey* _key_
Denotes the key to used for keyed GRE for packets received. See _tunnel-key_
for details.
*tunnel-okey* _key_
Denotes the key to used for keyed GRE for packets sent out. See _tunnel-key_
for details.
*tunnel-pmtudisc* _bool_
Denotes wether to enable/disable Path MTU Discovery on this tunnel. It is
enabled by default. Note that a fixed ttl is incompatible with this option:
tunneling with a fixed ttl always makes pmtu discovery.
*tunnel-tos* _tos_
Denotes the TOS value to use in outgoing packets.
# EXAMPLES
A simple GRE tunnel
```
auto gre0
iface gre0
tunnel-mode gre
tunnel-remote 198.51.100.1
tunnel-local 203.0.113.2
#
address 192.0.2.42/24
address 2001:db8::42/64
```
A GRE tunnel where the local IP is learned from _eth0_
```
auto gre1
iface gre1
tunnel-mode gre
tunnel-remote 198.51.100.1
tunnel-local-dev eth0
#
address 192.0.2.42/24
address 2001:db8::42/64
```
A GRE tunnel which transfers encapasulated packets via _eth0_ which is part
of a VRF.
```
auto eth0
iface eth0
address 203.0.113.2/24
gateway 203.0.113.1
vrf vrf_external
auto tun-vrf
iface tun-vrf
tunnel-mode gre
tunnel-remote 198.51.100.1
tunnel-local 203.0.113.2
tunnel-physdev eth0
#
address 192.0.2.42/24
address 2001:db8::42/64
auto vrf_external
iface vrf_external
vrf-table 1023
```
# AUTHORS
Maximilian Wilhelm <max@sdn.clinic>

View file

@ -32,33 +32,26 @@ other options are optional.
*vxlan-physdev* _interface_
Specifies the physical ("underlay") device to use for tunnel
endpoint communication. This is required for setups using
multicast.
endpoint communication.
*vxlan-local-ip* _address_
Specifies the source IP address to use in outgoing packets.
For compatiblity with ifupdown2 _vxlan-local-tunnelip_ is an
alias for this parameter.
*vxlan-peer-ips* _list of IP addresses_
Specifies the unicast destination IP address(es) to use in outgoing
*vxlan-remote-ip* _address_
Specifies the unicast destination IP address to use in outgoing
packets when the destination link layer address is not known in
the VXLAN device forwarding database. This option can be used to
form Point-to-Point as well as Point-to-Multipoint VXLAN tunnels/
overlays depending on how many peer IPs are given. If more than one
IP address is given a Point-to-Multipoint overlay is being set up
and ingress / head-end replication will be used by the Linux Kernel.
This option cannot be used together with _vxlan-peer-group_ option.
For compatiblity with ifupdown2 _vxlan-remoteip_ is an alias for this option
and for compatibility with previos versions of ifupdown-ng _vxlan-remote-ip_
is an alias for this option, too.
the VXLAN device forwarding database. This parameter cannot be
specified with the _vxlan-remote-group_ parameter.
For compatiblity with ifupdown2 _vxlan-remoteip_ is an alias for
this parameter.
*vxlan-peer-group* _multicast group_
Specifies the multicast group address to join, requires _vxlan-phsydev_
to be set as well. This parameter cannot be specified in combination
with the _vxlan-peer-ips_ parameter. For compatibility with ifupdown2
_vxlan-svcnodeip_ is an alias for this option and for compatibility
with previos version of ifupdown-ng _vxlan-remote-group_ is an alias, too.
*vxlan-remote-group* _multicast group_
Specifies the multicast group IP address to join. This parameter
cannot be specified with the _vxlan-remote-ip_ parameter.
For compatibility with ifupdown2 _vxlan-svcnodeip_ is an alias for
this parameter.
*vxlan-learning* _on/off_
Specifies if unknown source link layer addresses and IP addresses
@ -86,46 +79,22 @@ iface vx_v1001_padcty
mtu 1560
```
The same works just fine with IPv6 in the underlay:
```
auto vx_v1400_padcty
iface vx_v1400_padcty
vxlan-id 917505
vxlan-physdev vlan1400
vxlan-peer-group ff42:1400::1
#
hwaddress f2:00:0d:01:14:00
mtu 1560
```
Note that the underlay must have an MTU of at least 1610 to
carry the encapsulated packets of the two VTEPs above.
carry the encapsulated packets.
A VTEP with one peer (unicast point-to-point configuration):
A VTEP with one peer (point-to-point configuration):
```
auto vx_ptp1
iface vx_ptp1
vxlan-id 2342
vxlan-local-ip 192.0.2.42
vxlan-peer-ips 198.51.100.23
vxlan-remote-ip 198.51.100.23
#
hwaddress f2:00:c1:01:10:01
```
A VTEP with multiple peers (unicast point-to-multipoint with ingress / head-end replication):
```
auto vx_her
iface vx_her
vxlan-id 1337
vxlan-local-ip 2001:db8:1::1
vxlan-peer-ips 2001:db8:2::23 2001:db8:3::42 2001:db8:4::84
```
# AUTHORS
Maximilian Wilhelm <max@sdn.clinic>

View file

@ -18,15 +18,6 @@ allow to set up Wireguard VPN tunnels.
used. In the latter case _use wireguard_ has to be explicitly
set to the interface configuration.
Be aware that the given configuration file will be loaded using
*wg setconf* and not with *wg-quick*. The file format for both
tools isn't compatible so you have to make sure you provide a
valid configuration file for the *wg* tool. If you already have
a configuration file for *wg-quick* you can set up the tunnel
manually once and then dump the configuration using *wg showconf*
and save this to _path_.
# EXAMPLES
A Wireguard VPN tunnel with explicit configuration file specified

View file

@ -11,7 +11,7 @@ interfaces are configured. The file is processed by *ifquery*(8),
*ifup*(8) and *ifdown*(8) to introspect and change system state.
In most cases, syntax from legacy implementations is supported as
well, but that syntax is not discussed in detail here.
well, but that syntax is not discussed here.
# FILE SYNTAX
@ -24,8 +24,6 @@ value combination that is related to an *object*. Triples which
are not associated with an *object* are considered to be part
of the root of the configuration tree.
All keywords are case-sensitive and are expected to be lower-case.
The following is a simple example of a stanza:
```
@ -66,11 +64,11 @@ the system will only respond to certain keywords by default:
*address* _address_
Associates an IPv4 or IPv6 address in CIDR notation with
the parent interface. If an IP address without a prefix
length is given a given _netmask_ attribute is used if present.
If neither a prefix length nor a _netmask_ are given a /24 or /64
prefix length is presumed for IPv4 / IPv6 as of compatibility
reasons to classic ifupdown.
the parent interface.
*gateway* _address_
Associates an IPv4 or IPv6 address with the parent interface
for use as a default route (gateway).
*netmask* _netmask_
Associates a fallback netmask with the parent interface for
@ -85,11 +83,6 @@ the system will only respond to certain keywords by default:
For compatiblity with ifupdown and ifupdown2, _pointopoint_ is
an alias for this parameter.
*gateway* _address_
Associates an IPv4 or IPv6 address with the parent interface
for use as a default route (gateway). This usually is given
once for IPv4 and once for IPv6 (in a Dual-Stack setup).
*link-type* _link-type_
Denotes the link-type of the interface. When set to _dummy_,
the interface is created as a virtual dummy interfaces.
@ -178,8 +171,7 @@ most common executors are:
*tunnel*
The interface is a tunnel. Configuration of tunnels
requires the *tunnel* package to be installed on Alpine
Linux.
requires the *tunnel* package to be installed.
*vrf*
The interface is a VRF. Configuration of VRFs requires
@ -250,7 +242,6 @@ iface eth0
*interfaces-forward*(5)
*interfaces-mpls*(5)
*interfaces-ppp*(5)
*interfaces-tunnel*(5)
*interfaces-vrf*(5)
*interfaces-vxlan*(5)
*interfaces-wifi*(5)

View file

@ -2,27 +2,20 @@
# Based on alpine's tunnel configuration script.
# Copyright (c) 2017 Kaarle Ritvanen
# Copyright (c) 2020 Ariadne Conill (extended for ifupdown-ng)
# Copyright (c) 2021 Maximilian Wilhelm (make sure mode/type is 1st parameter, add more options)
# Copyright (c) 2021 Maximilian Wilhelm (make sure mode/type is 1st parameter)
[ -z "$IF_TUNNEL_LOCAL" -a -z "$IF_TUNNEL_LOCAL_DEV" ] && exit 1
[ -z "$IF_TUNNEL_LOCAL" ] && exit 1
[ -z "$IF_TUNNEL_REMOTE" ] && exit 1
[ -z "$IF_TUNNEL_MODE" ] && exit 1
[ -n "$VERBOSE" ] && set -x
yesno() {
case "$1" in
yes|1) echo 1 ;;
*) echo 0 ;;
esac
}
# Figure out address familiy
FAMILY="4"
FAMILY="-4"
case "$IF_TUNNEL_MODE" in
vti6|ipip6|ip6*)
FAMILY="6"
FAMILY="-6"
;;
esac
@ -48,58 +41,6 @@ case "${IF_TUNNEL_MODE}" in
esac
# If 'tunnel-local <IP>' was not given but 'tunnel-local-dev <iface>' is given try
# to figure out the IP of the underlay device (wrt the address family used for this
# tunnel) and use this to set up the tunnel
if [ ${PHASE} = "create" -a ! "${IF_TUNNEL_LOCAL}" -a "${IF_TUNNEL_LOCAL_DEV}" ]; then
if [ "${FAMILY}" = "4" ]; then
ip=$(ip -4 -brief addr show dev "${IF_TUNNEL_LOCAL_DEV}" 2>/dev/null | awk '{ print $3 }' | cut -d/ -f1)
# For IPv6 we try to use a non-temporary address (-> privacy extensions)
else
# Get all IPv6 addres configured on $IF_TUNNEL_LOCAL_DEV which are not
# temporary (due to privacy extensions). We do not filter for "mgmtaddr"
# "scope global" etc. as we don't want to make further assumptions on
# whether a user wants to use a link local address configured to this interface.
#
# The assumption that a temporary address configured by PE isn't suited
# to terminate a tunnel should hold in nearly all setups, I hope.
ip=$(ip -6 addr show dev "${IF_TUNNEL_LOCAL_DEV}" -temporary | grep inet6 | head -n1 | awk '{ print $2 }' | cut -d/ -f1)
fi
if [ ! "${ip}" ]; then
echo "Unable to determine the IPv${FAMILIY} address of tunnel-local-dev ${IF_TUNNEL_LOCAL_DEV}!"
exit 1
fi
unset IF_TUNNEL_LOCAL_DEV
export IF_TUNNEL_LOCAL="${ip}"
fi
# Handle boolean switches
MORE_PARAMS=""
if [ "${IF_TUNNEL_IGNORE_DF}" ]; then
if $(yesno "${IF_TUNNEL_IGNORE_DF}"); then
MORE_PARAMS="ignore-df"
else
MORE_PARAMS="noignore-df"
fi
unset IF_TUNNEL_IGNORE_DF
fi
if [ "${IF_TUNNEL_PMTUDISC}" ]; then
if $(yesno "${IF_TUNNEL_PMTUDISC}"); then
MORE_PARAMS="pmtudisc"
else
MORE_PARAMS="nopmtudisc"
fi
unset IF_TUNNEL_PMTUDISC
fi
# Mangle residual IF_TUNNEL_* params into single string
PARAMS=$(set | sed -E '
s/^IF_TUNNEL_([A-Z0-9_]+)=(.+)/\1\n\2/
@ -117,12 +58,12 @@ PARAMS=$(set | sed -E '
case "$PHASE" in
create)
${MOCK} eval ip -$FAMILY $OBJECT add $IFACE $TYPE_KW $TUNNEL_MODE $PARAMS $MORE_PARAMS
${MOCK} eval ip $FAMILY $OBJECT add $IFACE $TYPE_KW $TUNNEL_MODE $PARAMS
;;
destroy)
${MOCK} ip -$FAMILY $OBJECT del $IFACE
${MOCK} ip $FAMILY $OBJECT del $IFACE
;;
depend)
echo "${IF_TUNNEL_DEV}" "${IF_TUNNEL_LOCAL_DEV}"
echo "$IF_TUNNEL_DEV"
;;
esac

View file

@ -10,8 +10,8 @@
# IF_VXLAN_ID The VXLAN Network Identifier (VNI)
# IF_VXLAN_PHYSDEV Specifies the physical device to use for tunnel endpoint communication
# IF_VXLAN_LOCAL_IP Specifies the source IP address to use in outgoing packets
# IF_VXLAN_PEER_IPS Space separated list of IPs of the remote VTEP endpoint (for ptp/ptmp mode with ingress replication)
# IF_VXLAN_PEER_GROUP Multicast group to use for this VNI (for ptmp mode with multicast)
# IF_VXLAN_REMOTE_IP IP of the remote VTEP endpoint (for ptp mode)
# IF_VXLAN_REMOTE_GROUP Multicast group to use for this VNI (for ptmp mode)
# IF_VXLAN_LEARNING Wether to activate MAC learning on this instance (on/off)
# IF_VXLAN_AGEING Specifies the lifetime in seconds of FDB entries learnt by the kernel
# IF_VXLAN_DSTPORT UDP destination port to communicate to the remote VXLAN tunnel endpoint (default 4789)
@ -36,27 +36,17 @@ case "$PHASE" in
fi
# Input validation
if [ "${IF_VXLAN_PEER_IPS}" -a "${IF_VXLAN_PEER_GROUP}" ]; then
echo "Error on ${IFACE} (vxlan): Only one of 'vxlan-peer-ips' and 'vxlan-peer-group' can be used!" >&2
if [ "${IF_VXLAN_REMOTE_IP}" -a "${IF_VXLAN_REMOTE_GROUP}" ]; then
echo "Error on ${IFACE} (vxlan): Only one of 'remote' and 'group' can be given!" >&2
exit 1
fi
# Check if we should operate in unicast ptp or ptmp mode
if [ "${IF_VXLAN_PEER_IPS}" ]; then
# If it's only one thing which looks like an IPv4/IPv6 address we assume it's ptp
if echo "${IF_VXLAN_PEER_IPS}" | grep -q '^[[:space:]]*[[:xdigit:].:]\+[[:space:]]*$'; then
UCAST_MODE="ptp"
else
UCAST_MODE="ptmp"
fi
fi
# Gather arguments
ARGS=""
[ "${IF_VXLAN_PHYSDEV}" ] && ARGS="${ARGS} dev ${IF_VXLAN_PHYSDEV}"
[ "${IF_VXLAN_LOCAL_IP}" ] && ARGS="${ARGS} local ${IF_VXLAN_LOCAL_IP}"
[ "${UCAST_MODE}" = "ptp" ] && ARGS="${ARGS} remote ${IF_VXLAN_PEER_IPS}"
[ "${IF_VXLAN_PEER_GROUP}" ] && ARGS="${ARGS} group ${IF_VXLAN_PEER_GROUP}"
[ "${IF_VXLAN_REMOTE_IP}" ] && ARGS="${ARGS} remote ${IF_VXLAN_REMOTE_IP}"
[ "${IF_VXLAN_REMOTE_GROUP}" ] && ARGS="${ARGS} group ${IF_VXLAN_REMOTE_GROUP}"
[ "${IF_VXLAN_AGEING}" ] && ARGS="${ARGS} ageing ${IF_VXLAN_AGEING}"
# Linux uses non-standard default port - WTF?
@ -77,13 +67,6 @@ case "$PHASE" in
esac
${MOCK} ip link add "${IFACE}" type vxlan id "${IF_VXLAN_ID}" ${ARGS}
# Set up FDB entries for peer VTEPs
if [ "${UCAST_MODE}" = "ptmp" ]; then
for peer in ${IF_VXLAN_PEER_IPS}; do
${MOCK} bridge fdb append 00:00:00:00:00:00 dev "${IFACE}" dst "${peer}" self permanent
done
fi
;;
destroy)

View file

@ -79,7 +79,7 @@ stop_wpa_supplicant() {
[ -z "$IF_WIFI_CONFIG_PATH" ] && rm -- "$WIFI_CONFIG_PATH"
# If there is no PIDFILE, there is nothing we can do
[ ! -f "$PIDFILE" ] && return
[ ! -d "$PIDFILE" ] && return
pid=$(cat "$PIDFILE")
rm -- "$PIDFILE"

View file

@ -16,7 +16,6 @@
#include <stdbool.h>
#include <stdio.h>
#include <string.h>
#include "libifupdown/compat.h"
#include "libifupdown/config-file.h"
#include "libifupdown/dict.h"
#include "libifupdown/interface.h"
@ -103,7 +102,7 @@ compat_ifupdown2_bridge_ports_inherit_vlans(struct lif_dict *collection)
return true;
}
bool
extern bool
lif_compat_apply(struct lif_dict *collection)
{
if (lif_config.compat_ifupdown2_bridge_ports_inherit_vlans &&

View file

@ -17,7 +17,6 @@
#define LIBIFUPDOWN__COMPAT_H
#include "libifupdown/config-file.h"
#include "libifupdown/dict.h"
extern bool lif_compat_apply (struct lif_dict *collection);

View file

@ -30,86 +30,6 @@
#define SHELL "/bin/sh"
#if defined(__linux__)
# include <sys/syscall.h>
#endif
/* POSIX compatible fallback using waitpid(2) and usleep(3) */
static inline bool
lif_process_monitor_busyloop(pid_t child, int timeout_sec, int *status)
{
int ticks = 0;
while (ticks < timeout_sec * 20)
{
/* Ugly hack: most executors finish very quickly,
* so give them a chance to finish before sleeping.
*/
usleep(50);
if (waitpid(child, status, WNOHANG) == child)
return true;
usleep(49950);
ticks++;
}
return false;
}
#if defined(__linux__) && defined(__NR_pidfd_open)
/* TODO: remove this wrapper once musl and glibc gain pidfd_open() directly. */
static inline int
lif_pidfd_open(pid_t pid, unsigned int flags)
{
return syscall(__NR_pidfd_open, pid, flags);
}
static inline bool
lif_process_monitor_procdesc(pid_t child, int timeout_sec, int *status)
{
int pidfd = lif_pidfd_open(child, 0);
/* pidfd_open() not available, fall back to busyloop */
if (pidfd == -1 && errno == ENOSYS)
return lif_process_monitor_busyloop(child, timeout_sec, status);
struct pollfd pfd = {
.fd = pidfd,
.events = POLLIN,
};
if (poll(&pfd, 1, timeout_sec * 1000) < 1)
return false;
waitpid(child, status, 0);
close(pidfd);
return true;
}
#endif
static inline bool
lif_process_monitor(const char *cmdbuf, pid_t child, int timeout_sec)
{
int status;
#if defined(__linux__) && defined(__NR_pidfd_open)
if (lif_process_monitor_procdesc(child, timeout_sec, &status))
return WIFEXITED(status) && WEXITSTATUS(status) == 0;
#else
if (lif_process_monitor_busyloop(child, timeout_sec, &status))
return WIFEXITED(status) && WEXITSTATUS(status) == 0;
#endif
fprintf(stderr, "execution of '%s': timeout after %d seconds\n", cmdbuf, timeout_sec);
kill(child, SIGKILL);
waitpid(child, &status, 0);
return false;
}
bool
lif_execute_fmt(const struct lif_execute_opts *opts, char *const envp[], const char *fmt, ...)
{
@ -135,7 +55,10 @@ lif_execute_fmt(const struct lif_execute_opts *opts, char *const envp[], const c
return false;
}
return lif_process_monitor(cmdbuf, child, opts->timeout);
int status;
waitpid(child, &status, 0);
return WIFEXITED(status) && WEXITSTATUS(status) == 0;
}
bool
@ -195,8 +118,11 @@ lif_execute_fmt_with_result(const struct lif_execute_opts *opts, char *buf, size
return false;
}
int status;
no_result:
return lif_process_monitor(cmdbuf, child, opts->timeout);
waitpid(child, &status, 0);
return WIFEXITED(status) && WEXITSTATUS(status) == 0;
}
bool

View file

@ -27,7 +27,6 @@ struct lif_execute_opts {
const char *executor_path;
const char *interfaces_file;
const char *state_file;
int timeout;
};
extern bool lif_execute_fmt(const struct lif_execute_opts *opts, char *const envp[], const char *fmt, ...);

View file

@ -100,10 +100,8 @@ static const struct remap_token tokens[] = {
{"vendor", "dhcp-vendor"}, /* legacy ifupdown */
{"vrf", "vrf-member"}, /* ifupdown2 */
{"vxlan-local-tunnelip", "vxlan-local-ip"}, /* ifupdown2 */
{"vxlan-remote-group", "vxlan-peer-group"}, /* ifupdown-ng */
{"vxlan-remoteip", "vxlan-peer-ips"}, /* ifupdown2 */
{"vxlan-remote-ip", "vxlan-peer-ips"}, /* ifupdown-ng */
{"vxlan-svcnodeip", "vxlan-peer-group"}, /* ifupdown2 */
{"vxlan-remoteip", "vxlan-remote-ip"}, /* ifupdown2 */
{"vxlan-svcnodeip", "vxlan-remote-group"}, /* ifupdown2 */
};
static int

View file

@ -94,8 +94,7 @@ query_dependents_from_executors(const struct lif_execute_opts *opts, char *const
struct lif_execute_opts exec_opts = {
.verbose = opts->verbose,
.executor_path = opts->executor_path,
.interfaces_file = opts->interfaces_file,
.timeout = opts->timeout,
.interfaces_file = opts->interfaces_file
};
if (strcmp(entry->key, "use"))
@ -115,7 +114,7 @@ query_dependents_from_executors(const struct lif_execute_opts *opts, char *const
return true;
}
static bool
bool
append_to_buffer(char **buffer, size_t *buffer_len, char **end, const char *value)
{
size_t value_len = strlen (value);

View file

@ -5,8 +5,7 @@ EXECUTOR="$(atf_get_srcdir)/../../executor-scripts/linux/vxlan"
tests_init \
create_simple \
create_ucast_ptp \
create_ucast_ptmp \
create_ucast \
create_mcast \
create_physdev \
create_dstport \
@ -19,24 +18,14 @@ create_simple_body() {
${EXECUTOR}
}
create_ucast_ptp_body() {
export IFACE=vx_foo PHASE=create MOCK=echo IF_VXLAN_ID=2342 IF_VXLAN_PEER_IPS=192.2.0.42
create_ucast_body() {
export IFACE=vx_foo PHASE=create MOCK=echo IF_VXLAN_ID=2342 IF_VXLAN_REMOTE_IP=192.2.0.42
atf_check -s exit:0 -o match:'ip link add vx_foo type vxlan id 2342 remote 192.2.0.42' \
${EXECUTOR}
}
create_ucast_ptmp_body() {
export IFACE=vx_foo PHASE=create MOCK=echo IF_VXLAN_ID=2342 IF_VXLAN_PEER_IPS="10.0.0.1 10.0.0.2 10.0.0.3"
atf_check -s exit:0 \
-o match:'ip link add vx_foo type vxlan id 2342 dstport 4789' \
-o match:'bridge fdb append 00:00:00:00:00:00 dev vx_foo dst 10.0.0.1 self permanent' \
-o match:'bridge fdb append 00:00:00:00:00:00 dev vx_foo dst 10.0.0.2 self permanent' \
-o match:'bridge fdb append 00:00:00:00:00:00 dev vx_foo dst 10.0.0.3 self permanent' \
${EXECUTOR}
}
create_mcast_body() {
export IFACE=vx_foo PHASE=create MOCK=echo IF_VXLAN_ID=2342 IF_VXLAN_PEER_GROUP=225.0.8.15
export IFACE=vx_foo PHASE=create MOCK=echo IF_VXLAN_ID=2342 IF_VXLAN_REMOTE_GROUP=225.0.8.15
atf_check -s exit:0 -o match:'ip link add vx_foo type vxlan id 2342 group 225.0.8.15' \
${EXECUTOR}
}