Skip to content
Draft
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions src/common.h
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,10 @@
#define ROUNDUP4(a) (1 + (((a) - 1) | 3))
#define ROUNDUP8(a) (1 + (((a) - 1) | 7))

#ifndef FIELD_SIZEOF
#define FIELD_SIZEOF(t, f) sizeof(((t *)0)->f)
#endif

/* Some systems don't define timespec macros */
#ifndef timespecclear
#define timespecclear(tsp) (tsp)->tv_sec = (time_t)((tsp)->tv_nsec = 0L)
Expand Down
2 changes: 1 addition & 1 deletion src/dhcpcd.8.in
Original file line number Diff line number Diff line change
Expand Up @@ -651,7 +651,7 @@ of a randomly generated number.
.It Fl J , Fl Fl broadcast
Instructs the DHCP server to broadcast replies back to the client.
Normally this is only set for non-Ethernet interfaces,
such as FireWire and InfiniBand.
such as FireWire and InfiniBand, and on Linux-based systems for ipvlan as well.
In most instances,
.Nm
will set this automatically.
Expand Down
2 changes: 1 addition & 1 deletion src/dhcpcd.c
Original file line number Diff line number Diff line change
Expand Up @@ -470,7 +470,7 @@ configure_interface1(struct interface *ifp)

if (!(ifo->options & DHCPCD_IAID)) {
/*
* An IAID is for identifying a unqiue interface within
* An IAID is for identifying an unique interface within
* the client. It is 4 bytes long. Working out a default
* value is problematic.
*
Expand Down
44 changes: 44 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 @@ -309,12 +310,55 @@ if_init(struct interface *ifp)
return if_writepathuint(ifp->ctx, path, 1) == -1 ? -1 : 0;
}

/* Returns number of bytes written to driver, else 0 (error or indeterminate). */
static size_t
if_get_driver(struct interface *ifp, char *driver, const size_t driverlen)
{
struct ethtool_drvinfo drvinfo = { .cmd = ETHTOOL_GDRVINFO };
struct ifreq ifr = { .ifr_data = (void *)&drvinfo };

strlcpy(ifr.ifr_name, ifp->name, sizeof(ifr.ifr_name));
if (ioctl(ifp->ctx->pf_inet_fd, SIOCETHTOOL, &ifr) != 0) {
logerr("%s: SIOCETHTOOL ifname=%s", __func__, ifp->name);
return 0; /* 0 means error or indeterminate driver name */
}
return strlcpy(driver, drvinfo.driver, driverlen);
}

static bool
if_cmp_driver(struct interface *ifp, const char *driver)
{
char ifdriver[FIELD_SIZEOF(struct ethtool_drvinfo, driver)];
size_t n = if_get_driver(ifp, ifdriver, sizeof(ifdriver));

if (n == 0) {
logerr("%s: if_get_driver ifname=%s", __func__, ifp->name);
return false;
}
if (strncmp(ifdriver, driver, n) == 0)
return true;
return false;
}

static bool
if_ipvlan(struct interface *ifp)
{
if (if_cmp_driver(ifp, "ipvlan"))
return true;
return false;
}

int
if_conf(struct interface *ifp)
{
char path[sizeof(SYS_LAYER2) + IF_NAMESIZE];
int n;

/* Set broadcast flag for ipvlan interfaces.
* XXX: move this out to dhcpcd if needed on other platforms. */
if (if_ipvlan(ifp))
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