summaryrefslogtreecommitdiffstats
path: root/if.c
diff options
context:
space:
mode:
authorRoy Marples <roy@marples.name>2015-08-06 13:07:15 +0000
committerRoy Marples <roy@marples.name>2015-08-06 13:07:15 +0000
commit57498a08215a09b2f4427d8e38f2358faa1a71bf (patch)
tree3f89b3ba7712db2d92da5e2218905753a3758c83 /if.c
parent288ba63cd92dae0632c2c0dab98c05ce1fedb688 (diff)
downloaddhcpcd-57498a08215a09b2f4427d8e38f2358faa1a71bf.tar.xz
Open sockets once instead of open/close each for each ioctl.
Diffstat (limited to 'if.c')
-rw-r--r--if.c99
1 files changed, 45 insertions, 54 deletions
diff --git a/if.c b/if.c
index 056f9997..2823d8ea 100644
--- a/if.c
+++ b/if.c
@@ -71,11 +71,6 @@
#include "ipv4ll.h"
#include "ipv6nd.h"
-#ifdef __QNX__
-/* QNX carries defines for, but does not actually support PF_LINK */
-#undef IFLR_ACTIVE
-#endif
-
void
if_free(struct interface *ifp)
{
@@ -93,28 +88,50 @@ if_free(struct interface *ifp)
}
int
-if_carrier(struct interface *iface)
+if_opensockets(struct dhcpcd_ctx *ctx)
+{
+
+ if ((ctx->link_fd = if_openlinksocket()) == -1)
+ return -1;
+
+ ctx->pf_inet_fd = xsocket(PF_INET, SOCK_DGRAM, 0, O_CLOEXEC);
+ if (ctx->pf_inet_fd == -1)
+ return -1;
+
+#if defined(INET6) && defined(BSD)
+ ctx->pf_inet6_fd = xsocket(PF_INET6, SOCK_DGRAM, 0, O_CLOEXEC);
+ if (ctx->pf_inet6_fd == -1)
+ return -1;
+#endif
+
+#ifdef IFLR_ACTIVE
+ ctx->pf_link_fd = xsocket(PF_LINK, SOCK_DGRAM, 0, O_CLOEXEC);
+ if (ctx->pf_link_fd == -1)
+ return -1;
+#endif
+
+ return 0;
+}
+
+int
+if_carrier(struct interface *ifp)
{
- int s, r;
+ int r;
struct ifreq ifr;
#ifdef SIOCGIFMEDIA
struct ifmediareq ifmr;
#endif
- if ((s = xsocket(PF_INET, SOCK_DGRAM, 0, O_CLOEXEC)) == -1)
- return LINK_UNKNOWN;
memset(&ifr, 0, sizeof(ifr));
- strlcpy(ifr.ifr_name, iface->name, sizeof(ifr.ifr_name));
- if (ioctl(s, SIOCGIFFLAGS, &ifr) == -1) {
- close(s);
+ strlcpy(ifr.ifr_name, ifp->name, sizeof(ifr.ifr_name));
+ if (ioctl(ifp->ctx->pf_inet_fd, SIOCGIFFLAGS, &ifr) == -1)
return LINK_UNKNOWN;
- }
- iface->flags = (unsigned int)ifr.ifr_flags;
+ ifp->flags = (unsigned int)ifr.ifr_flags;
#ifdef SIOCGIFMEDIA
memset(&ifmr, 0, sizeof(ifmr));
- strlcpy(ifmr.ifm_name, iface->name, sizeof(ifmr.ifm_name));
- if (ioctl(s, SIOCGIFMEDIA, &ifmr) != -1 &&
+ strlcpy(ifmr.ifm_name, ifp->name, sizeof(ifmr.ifm_name));
+ if (ioctl(ifp->ctx->pf_inet_fd, SIOCGIFMEDIA, &ifmr) != -1 &&
ifmr.ifm_status & IFM_AVALID)
r = (ifmr.ifm_status & IFM_ACTIVE) ? LINK_UP : LINK_DOWN;
else
@@ -122,7 +139,6 @@ if_carrier(struct interface *iface)
#else
r = ifr.ifr_flags & IFF_RUNNING ? LINK_UP : LINK_DOWN;
#endif
- close(s);
return r;
}
@@ -130,24 +146,21 @@ int
if_setflag(struct interface *ifp, short flag)
{
struct ifreq ifr;
- int s, r;
+ int r;
- if ((s = xsocket(PF_INET, SOCK_DGRAM, 0, O_CLOEXEC)) == -1)
- return -1;
memset(&ifr, 0, sizeof(ifr));
strlcpy(ifr.ifr_name, ifp->name, sizeof(ifr.ifr_name));
r = -1;
- if (ioctl(s, SIOCGIFFLAGS, &ifr) == 0) {
+ if (ioctl(ifp->ctx->pf_inet_fd, SIOCGIFFLAGS, &ifr) == 0) {
if (flag == 0 || (ifr.ifr_flags & flag) == flag)
r = 0;
else {
ifr.ifr_flags |= flag;
- if (ioctl(s, SIOCSIFFLAGS, &ifr) == 0)
+ if (ioctl(ifp->ctx->pf_inet_fd, SIOCSIFFLAGS, &ifr) ==0)
r = 0;
}
ifp->flags = (unsigned int)ifr.ifr_flags;
}
- close(s);
return r;
}
@@ -239,24 +252,12 @@ if_discover(struct dhcpcd_ctx *ctx, int argc, char * const *argv)
const struct sockaddr_dl *sdl;
#ifdef SIOCGIFPRIORITY
struct ifreq ifr;
- int s_inet;
#endif
#ifdef IFLR_ACTIVE
struct if_laddrreq iflr;
- int s_link;
#endif
-#ifdef SIOCGIFPRIORITY
- if ((s_inet = xsocket(PF_INET, SOCK_DGRAM, 0, O_CLOEXEC)) == -1)
- return NULL;
-#endif
#ifdef IFLR_ACTIVE
- if ((s_link = xsocket(PF_LINK, SOCK_DGRAM, 0, O_CLOEXEC)) == -1) {
-#ifdef SIOCGIFPRIORITY
- close(s_inet);
-#endif
- return NULL;
- }
memset(&iflr, 0, sizeof(iflr));
#endif
#elif AF_PACKET
@@ -341,7 +342,7 @@ if_discover(struct dhcpcd_ctx *ctx, int argc, char * const *argv)
continue;
}
- if (if_vimaster(p) == 1) {
+ if (if_vimaster(ctx, p) == 1) {
logger(ctx, argc ? LOG_ERR : LOG_DEBUG,
"%s: is a Virtual Interface Master, skipping", p);
continue;
@@ -374,7 +375,7 @@ if_discover(struct dhcpcd_ctx *ctx, int argc, char * const *argv)
MIN(ifa->ifa_addr->sa_len, sizeof(iflr.addr)));
iflr.flags = IFLR_PREFIX;
iflr.prefixlen = (unsigned int)sdl->sdl_alen * NBBY;
- if (ioctl(s_link, SIOCGLIFADDR, &iflr) == -1 ||
+ if (ioctl(ctx->pf_link_fd, SIOCGLIFADDR, &iflr) == -1 ||
!(iflr.flags & IFLR_ACTIVE))
{
if_free(ifp);
@@ -503,8 +504,8 @@ if_discover(struct dhcpcd_ctx *ctx, int argc, char * const *argv)
}
/* Ensure that the MTU is big enough for DHCP */
- if (if_getmtu(ifp->name) < MTU_MIN &&
- if_setmtu(ifp->name, MTU_MIN) == -1)
+ if (if_getmtu(ifp) < MTU_MIN &&
+ if_setmtu(ifp, MTU_MIN) == -1)
{
logger(ifp->ctx, LOG_ERR, "%s: set_mtu: %m", p);
if_free(ifp);
@@ -515,7 +516,7 @@ if_discover(struct dhcpcd_ctx *ctx, int argc, char * const *argv)
/* Respect the interface priority */
memset(&ifr, 0, sizeof(ifr));
strlcpy(ifr.ifr_name, ifp->name, sizeof(ifr.ifr_name));
- if (ioctl(s_inet, SIOCGIFPRIORITY, &ifr) == 0)
+ if (ioctl(ctx->pf_inet_fd, SIOCGIFPRIORITY, &ifr) == 0)
ifp->metric = ifr.ifr_metric;
#else
/* We reserve the 100 range for virtual interfaces, if and when
@@ -533,13 +534,6 @@ if_discover(struct dhcpcd_ctx *ctx, int argc, char * const *argv)
if_learnaddrs1(ctx, ifs, ifaddrs);
freeifaddrs(ifaddrs);
-#ifdef SIOCGIFPRIORITY
- close(s_inet);
-#endif
-#ifdef IFLR_ACTIVE
- close(s_link);
-#endif
-
return ifs;
}
@@ -579,18 +573,15 @@ if_findindex(struct if_head *ifaces, unsigned int idx)
}
int
-if_domtu(const char *ifname, short int mtu)
+if_domtu(const struct interface *ifp, short int mtu)
{
- int s, r;
+ int r;
struct ifreq ifr;
- if ((s = xsocket(PF_INET, SOCK_DGRAM, 0, O_CLOEXEC)) == -1)
- return -1;
memset(&ifr, 0, sizeof(ifr));
- strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
+ strlcpy(ifr.ifr_name, ifp->name, sizeof(ifr.ifr_name));
ifr.ifr_mtu = mtu;
- r = ioctl(s, mtu ? SIOCSIFMTU : SIOCGIFMTU, &ifr);
- close(s);
+ r = ioctl(ifp->ctx->pf_inet_fd, mtu ? SIOCSIFMTU : SIOCGIFMTU, &ifr);
if (r == -1)
return -1;
return ifr.ifr_mtu;