summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/config.c9
-rw-r--r--src/iface.c47
2 files changed, 52 insertions, 4 deletions
diff --git a/src/config.c b/src/config.c
index 1ac9e81..7aa046d 100644
--- a/src/config.c
+++ b/src/config.c
@@ -102,6 +102,15 @@ bool fastd_config_ifname(fastd_peer_t *peer, const char *ifname) {
if (strchr(ifname, '/'))
return false;
+ const char *percent = strchr(ifname, '%');
+ if (percent) {
+ if (strrchr(ifname, '%') != percent)
+ return false; /* Multiple patterns */
+
+ if (percent[1] != 'n' && percent[1] != 'k')
+ return false;
+ }
+
char **name = peer ? &peer->ifname : &conf.ifname;
free(*name);
diff --git a/src/iface.c b/src/iface.c
index 6cad96d..e471c89 100644
--- a/src/iface.c
+++ b/src/iface.c
@@ -464,18 +464,57 @@ void fastd_iface_write(fastd_iface_t *iface, fastd_buffer_t buffer) {
/** Opens a new TUN/TAP interface, optionally associated with a specific peer */
fastd_iface_t * fastd_iface_open(fastd_peer_t *peer) {
- fastd_iface_t *iface = fastd_new(fastd_iface_t);
- iface->peer = peer;
-
const char *ifname = conf.ifname;
+ char ifnamebuf[IFNAMSIZ];
if (peer) {
if (peer->ifname)
ifname = peer->ifname;
- else if (!fastd_config_single_iface())
+ else if (!fastd_config_single_iface() && !(ifname && strchr(ifname, '%')))
ifname = NULL;
}
+ const char *percent = ifname ? strchr(ifname, '%') : NULL;
+ if (percent) {
+ if (peer) {
+ char prefix[percent - ifname + 1];
+ memcpy(prefix, ifname, percent - ifname);
+ prefix[percent - ifname] = 0;
+
+ ifname = NULL;
+
+ switch (percent[1]) {
+ case 'n':
+ if (peer->name) {
+ snprintf(ifnamebuf, sizeof(ifnamebuf), "%s%s%s", prefix, peer->name, percent+2);
+ ifname = ifnamebuf;
+ }
+
+ break;
+
+ case 'k':
+ {
+ char buf[17];
+ if (conf.protocol->describe_peer(peer, buf, sizeof(buf))) {
+ snprintf(ifnamebuf, sizeof(ifnamebuf), "%s%s%s", prefix, buf, percent+2);
+ ifname = ifnamebuf;
+ }
+ }
+ break;
+
+ default:
+ exit_bug("fastd_iface_open: invalid interface pattern");
+ }
+ }
+ else {
+ pr_error("Invalid TUN/TAP device name: `%%n' and `%%k' patterns can't be used in TAP mode");
+ return NULL;
+ }
+ }
+
+ fastd_iface_t *iface = fastd_new(fastd_iface_t);
+ iface->peer = peer;
+
pr_debug("initializing TUN/TAP device...");
open_iface(iface, ifname);