Skip to content

Commit ab2d7cd

Browse files
committed
For route MTU comparison allow zero MTU to match interface MTU
Because some OS put the interface MTU into the route MTU if the route does not define its own.
1 parent b1a52d8 commit ab2d7cd

File tree

7 files changed

+36
-3
lines changed

7 files changed

+36
-3
lines changed

src/dhcpcd.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@ struct interface {
8080
uint16_t hwtype; /* ARPHRD_ETHER for example */
8181
unsigned char hwaddr[HWADDR_LEN];
8282
uint8_t hwlen;
83+
unsigned int mtu;
8384
unsigned short vlanid;
8485
unsigned int metric;
8586
int carrier;

src/if-bsd.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1252,6 +1252,7 @@ if_ifinfo(struct dhcpcd_ctx *ctx, const struct if_msghdr *ifm)
12521252
if ((ifp = if_findindex(ctx->ifaces, ifm->ifm_index)) == NULL)
12531253
return 0;
12541254

1255+
ifp->mtu = if_mtu(ifp);
12551256
link_state = if_carrier(ifp, &ifm->ifm_data);
12561257
dhcpcd_handlecarrier(ifp, link_state, (unsigned int)ifm->ifm_flags);
12571258
return 0;

src/if-linux.c

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1053,7 +1053,7 @@ link_netlink(struct dhcpcd_ctx *ctx, void *arg, struct nlmsghdr *nlm)
10531053
struct interface *ifp = arg;
10541054
int r;
10551055
size_t len;
1056-
struct rtattr *rta, *hwaddr;
1056+
struct rtattr *rta, *hwaddr, *mtu;
10571057
struct ifinfomsg *ifi;
10581058
char ifn[IF_NAMESIZE + 1];
10591059

@@ -1082,7 +1082,7 @@ link_netlink(struct dhcpcd_ctx *ctx, void *arg, struct nlmsghdr *nlm)
10821082
rta = (void *)((char *)ifi + NLMSG_ALIGN(sizeof(*ifi)));
10831083
len = NLMSG_PAYLOAD(nlm, sizeof(*ifi));
10841084
*ifn = '\0';
1085-
hwaddr = NULL;
1085+
hwaddr = mtu = NULL;
10861086

10871087
for (; RTA_OK(rta, len); rta = RTA_NEXT(rta, len)) {
10881088
switch (rta->rta_type) {
@@ -1098,6 +1098,9 @@ link_netlink(struct dhcpcd_ctx *ctx, void *arg, struct nlmsghdr *nlm)
10981098
case IFLA_ADDRESS:
10991099
hwaddr = rta;
11001100
break;
1101+
case IFLA_MTU:
1102+
mtu = rta;
1103+
break;
11011104
}
11021105
}
11031106

@@ -1139,6 +1142,9 @@ link_netlink(struct dhcpcd_ctx *ctx, void *arg, struct nlmsghdr *nlm)
11391142
return 0;
11401143
}
11411144

1145+
if (mtu != NULL)
1146+
ifp->mtu = *(unsigned int *)RTA_DATA(mtu);
1147+
11421148
/* Re-read hardware address and friends */
11431149
if (!(ifi->ifi_flags & IFF_UP)) {
11441150
void *hwa = hwaddr != NULL ? RTA_DATA(hwaddr) : NULL;

src/if-sun.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1059,6 +1059,7 @@ if_ifinfo(struct dhcpcd_ctx *ctx, const struct if_msghdr *ifm)
10591059
state = LINK_UP;
10601060
flags |= IFF_UP;
10611061
}
1062+
ifp->mtu = if_mtu(ifp);
10621063
dhcpcd_handlecarrier(ifp, state, flags);
10631064
return 0;
10641065
}

src/if.c

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -182,6 +182,18 @@ if_setflag(struct interface *ifp, short setflag, short unsetflag)
182182
return 0;
183183
}
184184

185+
unsigned int
186+
if_mtu(struct interface *ifp)
187+
{
188+
struct ifreq ifr = { .ifr_mtu = 0 };
189+
190+
strlcpy(ifr.ifr_name, ifp->name, sizeof(ifr.ifr_name));
191+
if (ioctl(ifp->ctx->pf_inet_fd, SIOCGIFMTU, &ifr) == -1)
192+
return 0;
193+
194+
return (unsigned int)ifr.ifr_mtu;
195+
}
196+
185197
bool
186198
if_is_link_up(const struct interface *ifp)
187199
{
@@ -685,6 +697,7 @@ if_discover(struct dhcpcd_ctx *ctx, struct ifaddrs **ifaddrs,
685697
}
686698
}
687699

700+
ifp->mtu = if_mtu(ifp);
688701
ifp->vlanid = if_vlanid(ifp);
689702

690703
#ifdef SIOCGIFPRIORITY

src/if.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,7 @@ int if_ioctl(struct dhcpcd_ctx *, ioctl_request_t, void *, size_t);
163163
#define pioctl(ctx, req, data, len) ioctl((ctx)->pf_inet_fd, (req),(data),(len))
164164
#endif
165165
int if_setflag(struct interface *, short, short);
166+
unsigned int if_mtu(struct interface *);
166167
#define if_up(ifp) if_setflag((ifp), (IFF_UP | IFF_RUNNING), 0)
167168
#define if_down(ifp) if_setflag((ifp), 0, IFF_UP);
168169
bool if_is_link_up(const struct interface *);

src/route.c

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -506,9 +506,19 @@ rt_recvrt(int cmd, const struct rt *rt, pid_t pid)
506506
static bool
507507
rt_cmp_misc(struct rt *nrt, struct rt *ort)
508508
{
509-
/* MTU changed */
509+
#if defined(__FreeBSD__) || defined(__DragonFly__)
510+
/* FreeBSD puts the interface MTU into the route MTU
511+
* if the route does not define it's own. */
512+
unsigned int nmtu, omtu;
513+
514+
nmtu = nrt->rt_mtu ? nrt->rt_mtu : nrt->rt_ifp->mtu;
515+
omtu = ort->rt_mtu ? ort->rt_mtu : ort->rt_ifp->mtu;
516+
if (omtu != nmtu)
517+
return false;
518+
#else
510519
if (ort->rt_mtu != nrt->rt_mtu)
511520
return false;
521+
#endif
512522

513523
#ifdef HAVE_ROUTE_LIFETIME
514524
uint32_t deviation;

0 commit comments

Comments
 (0)