Skip to content

Commit

Permalink
Linux: set broadcast flag by default for ipvlan interfaces.
Browse files Browse the repository at this point in the history
resolves #32.
  • Loading branch information
ido committed Apr 23, 2021
1 parent 01748b3 commit 0716901
Showing 1 changed file with 47 additions and 0 deletions.
47 changes: 47 additions & 0 deletions src/if-linux.c
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@
#include <linux/if_vlan.h>
#include <linux/filter.h>
#include <linux/netlink.h>
#include <linux/ethtool.h> /* for ipvlan detection */
#include <linux/sockios.h>
#include <linux/rtnetlink.h>

Expand Down Expand Up @@ -315,6 +316,11 @@ if_conf(struct interface *ifp)
char path[sizeof(SYS_LAYER2) + IF_NAMESIZE];
int n;

/* Set broadcast flag for ipvlan interfaces. */
if (if_ipvlan(ifp->name)) {
ifp->options->options |= DHCPCD_BROADCAST;
}

/* Some qeth setups require the use of the broadcast flag. */
snprintf(path, sizeof(path), SYS_LAYER2, ifp->name);
n = check_proc_int(ifp->ctx, path);
Expand Down Expand Up @@ -347,6 +353,47 @@ if_tap(struct dhcpcd_ctx *ctx, const char *ifname)
return false;
return u & IFF_TAP;
}
i
/* @maxlen should be greater than or equal to 32; see ethtool_drvinfo. */
static int
if_get_driver(struct dhcpcd_ctx *cts, const char *ifname, char *driver, const size_t maxlen)
{
struct ifreq ifr;
struct ethtool_drvinfo drvinfo;
int fd, result;
if (!ifname || !*ifname)
return -1;

fd = socket(AF_INET, SOCK_STREAM, 0);
if (fd == -1) {
logerr("if_get_driver: failed socket creation: %s", strerror(errno));
return -1;

memset(&ifr, 0, sizeof(ifr));
strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
drvinfo.cmd = ETHTOOL_GDRVINFO;
ifr.ifr_data = (void *)&drvinfo;
if (ioctl(fd, SIOCETHTOOL, &ifr) < 0) {
const int err = errno;
logerr("if_get_driver: failed ethtool ioctl on interface %s: %s",
ifname, strerror(errno));
result = close(fd);
return -1;
}
return strlcpy(driver, drvinfo.driver,
MIN(sizeof(drvinfo.driver), maxlen));
}

static bool
if_ipvlan(struct dhcpcd_ctx *ctx, const char *ifname)
{
char driver[32]; /* sizeof(ethtool_drvinfo.driver) = 32 */
if (if_get_driver(ctx, ifname, driver, sizeof(driver)) < 0) {
logerr("if_ipvlan: failed to get driver name %s.", ifname);
return false;a
}
return (strncmp(driver, "ipvlan", sizeof(driver)) == 0);
}

bool
if_ignore(struct dhcpcd_ctx *ctx, const char *ifname)
Expand Down

0 comments on commit 0716901

Please sign in to comment.