summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorRoy Marples <roy@marples.name>2020-04-20 14:11:00 +0100
committerRoy Marples <roy@marples.name>2020-04-20 14:11:00 +0100
commit097c471bfccdda2b3b7e8a05ce42379c38f85d89 (patch)
tree6a66044186e96f17ef38f6e2ef7ee57fbfe75ecd /src
parentbc4ceca2596b046eb734597552a7426f7042f1d3 (diff)
downloaddhcpcd-097c471bfccdda2b3b7e8a05ce42379c38f85d89.tar.xz
if: ensure interface flags persist when setting a flag
Otherwise we stupidly drop IFF_MULTICAST on Linux.
Diffstat (limited to 'src')
-rw-r--r--src/if.c14
1 files changed, 6 insertions, 8 deletions
diff --git a/src/if.c b/src/if.c
index 51e05571..f73dfc7e 100644
--- a/src/if.c
+++ b/src/if.c
@@ -161,19 +161,17 @@ int
if_setflag(struct interface *ifp, short setflag, short unsetflag)
{
struct ifreq ifr = { .ifr_flags = 0 };
- short f;
+ short oflags;
- if (if_getflags(ifp) == -1)
+ strlcpy(ifr.ifr_name, ifp->name, sizeof(ifr.ifr_name));
+ if (ioctl(ifp->ctx->pf_inet_fd, SIOCGIFFLAGS, &ifr) == -1)
return -1;
- f = (short)ifp->flags;
- if ((f & setflag) == setflag && (f & unsetflag) == 0)
- return 0;
-
- strlcpy(ifr.ifr_name, ifp->name, sizeof(ifr.ifr_name));
+ oflags = ifr.ifr_flags;
ifr.ifr_flags |= setflag;
ifr.ifr_flags &= (short)~unsetflag;
- if (if_ioctl(ifp->ctx, SIOCSIFFLAGS, &ifr, sizeof(ifr)) == -1)
+ if (ifr.ifr_flags != oflags &&
+ if_ioctl(ifp->ctx, SIOCSIFFLAGS, &ifr, sizeof(ifr)) == -1)
return -1;
ifp->flags = (unsigned int)ifr.ifr_flags;