uint16_t hwtype; /* ARPHRD_ETHER for example */
unsigned char hwaddr[HWADDR_LEN];
uint8_t hwlen;
+ unsigned int mtu;
unsigned short vlanid;
unsigned int metric;
int carrier;
if ((ifp = if_findindex(ctx->ifaces, ifm->ifm_index)) == NULL)
return 0;
+ ifp->mtu = if_mtu(ifp);
link_state = if_carrier(ifp, &ifm->ifm_data);
dhcpcd_handlecarrier(ifp, link_state, (unsigned int)ifm->ifm_flags);
return 0;
struct interface *ifp = arg;
int r;
size_t len;
- struct rtattr *rta, *hwaddr;
+ struct rtattr *rta, *hwaddr, *mtu;
struct ifinfomsg *ifi;
char ifn[IF_NAMESIZE + 1];
rta = (void *)((char *)ifi + NLMSG_ALIGN(sizeof(*ifi)));
len = NLMSG_PAYLOAD(nlm, sizeof(*ifi));
*ifn = '\0';
- hwaddr = NULL;
+ hwaddr = mtu = NULL;
for (; RTA_OK(rta, len); rta = RTA_NEXT(rta, len)) {
switch (rta->rta_type) {
case IFLA_ADDRESS:
hwaddr = rta;
break;
+ case IFLA_MTU:
+ mtu = rta;
+ break;
}
}
return 0;
}
+ if (mtu != NULL)
+ ifp->mtu = *(unsigned int *)RTA_DATA(mtu);
+
/* Re-read hardware address and friends */
if (!(ifi->ifi_flags & IFF_UP)) {
void *hwa = hwaddr != NULL ? RTA_DATA(hwaddr) : NULL;
state = LINK_UP;
flags |= IFF_UP;
}
+ ifp->mtu = if_mtu(ifp);
dhcpcd_handlecarrier(ifp, state, flags);
return 0;
}
return 0;
}
+unsigned int
+if_mtu(struct interface *ifp)
+{
+ struct ifreq ifr = { .ifr_mtu = 0 };
+
+ strlcpy(ifr.ifr_name, ifp->name, sizeof(ifr.ifr_name));
+ if (ioctl(ifp->ctx->pf_inet_fd, SIOCGIFMTU, &ifr) == -1)
+ return 0;
+
+ return (unsigned int)ifr.ifr_mtu;
+}
+
bool
if_is_link_up(const struct interface *ifp)
{
}
}
+ ifp->mtu = if_mtu(ifp);
ifp->vlanid = if_vlanid(ifp);
#ifdef SIOCGIFPRIORITY
#define pioctl(ctx, req, data, len) ioctl((ctx)->pf_inet_fd, (req),(data),(len))
#endif
int if_setflag(struct interface *, short, short);
+unsigned int if_mtu(struct interface *);
#define if_up(ifp) if_setflag((ifp), (IFF_UP | IFF_RUNNING), 0)
#define if_down(ifp) if_setflag((ifp), 0, IFF_UP);
bool if_is_link_up(const struct interface *);
static bool
rt_cmp_misc(struct rt *nrt, struct rt *ort)
{
- /* MTU changed */
+#if defined(__FreeBSD__) || defined(__DragonFly__)
+ /* FreeBSD puts the interface MTU into the route MTU
+ * if the route does not define it's own. */
+ unsigned int nmtu, omtu;
+
+ nmtu = nrt->rt_mtu ? nrt->rt_mtu : nrt->rt_ifp->mtu;
+ omtu = ort->rt_mtu ? ort->rt_mtu : ort->rt_ifp->mtu;
+ if (omtu != nmtu)
+ return false;
+#else
if (ort->rt_mtu != nrt->rt_mtu)
return false;
+#endif
#ifdef HAVE_ROUTE_LIFETIME
uint32_t deviation;