From 2c77247bd03e0efe2d34176590c4041133c4977e Mon Sep 17 00:00:00 2001 From: Roy Marples Date: Fri, 30 Mar 2012 09:37:21 +0000 Subject: [PATCH] Interface index should persist and be unique for the interface lifetime. As such, store it at discover and stop using if_nametoindex(3). --- dhcpcd.c | 2 +- dhcpcd.h | 3 ++- if-linux.c | 14 ++-------- ipv6rs.c | 4 +-- lpf.c | 10 ++----- net.c | 76 +++++++++++++++++++----------------------------------- net.h | 1 - 7 files changed, 36 insertions(+), 74 deletions(-) diff --git a/dhcpcd.c b/dhcpcd.c index d46e88a9..8ad52c4f 100644 --- a/dhcpcd.c +++ b/dhcpcd.c @@ -822,7 +822,7 @@ configure_interface1(struct interface *iface) memset(iface->clientid + 2 + ifl, 0, 4 - ifl); } else { - ifl = htonl(if_nametoindex(iface->name)); + ifl = htonl(iface->index); memcpy(iface->clientid + 2, &ifl, 4); } } else if (len == 0) { diff --git a/dhcpcd.h b/dhcpcd.h index fbb96003..642aed06 100644 --- a/dhcpcd.h +++ b/dhcpcd.h @@ -1,6 +1,6 @@ /* * dhcpcd - DHCP client daemon - * Copyright (c) 2006-2011 Roy Marples + * Copyright (c) 2006-2012 Roy Marples * All rights reserved * Redistribution and use in source and binary forms, with or without @@ -110,6 +110,7 @@ struct interface { char name[IF_NAMESIZE]; struct if_state *state; + unsigned int index; int flags; sa_family_t family; unsigned char hwaddr[HWADDR_LEN]; diff --git a/if-linux.c b/if-linux.c index f4ab7fca..40b4836d 100644 --- a/if-linux.c +++ b/if-linux.c @@ -505,11 +505,7 @@ if_address(const struct interface *iface, nlm->hdr.nlmsg_type = RTM_NEWADDR; } else nlm->hdr.nlmsg_type = RTM_DELADDR; - if (!(nlm->ifa.ifa_index = if_nametoindex(iface->name))) { - free(nlm); - errno = ENODEV; - return -1; - } + nlm->ifa.ifa_index = iface->index; nlm->ifa.ifa_family = AF_INET; nlm->ifa.ifa_prefixlen = inet_ntocidr(*netmask); /* This creates the aliased interface */ @@ -531,14 +527,8 @@ int if_route(const struct rt *rt, int action) { struct nlmr *nlm; - unsigned int ifindex; int retval = 0; - if (!(ifindex = if_nametoindex(rt->iface->name))) { - errno = ENODEV; - return -1; - } - nlm = xzalloc(sizeof(*nlm)); nlm->hdr.nlmsg_len = NLMSG_LENGTH(sizeof(struct rtmsg)); nlm->hdr.nlmsg_type = RTM_NEWROUTE; @@ -585,7 +575,7 @@ if_route(const struct rt *rt, int action) add_attr_l(&nlm->hdr, sizeof(*nlm), RTA_GATEWAY, &rt->gate.s_addr, sizeof(rt->gate.s_addr)); - add_attr_32(&nlm->hdr, sizeof(*nlm), RTA_OIF, ifindex); + add_attr_32(&nlm->hdr, sizeof(*nlm), RTA_OIF, rt->iface->index); add_attr_32(&nlm->hdr, sizeof(*nlm), RTA_PRIORITY, rt->metric); if (send_netlink(&nlm->hdr) == -1) diff --git a/ipv6rs.c b/ipv6rs.c index df969340..92aeebaa 100644 --- a/ipv6rs.c +++ b/ipv6rs.c @@ -208,7 +208,7 @@ ipv6rs_sendprobe(void *arg) cm->cmsg_type = IPV6_PKTINFO; cm->cmsg_len = CMSG_LEN(sizeof(pi)); memset(&pi, 0, sizeof(pi)); - pi.ipi6_ifindex = if_nametoindex(ifp->name); + pi.ipi6_ifindex = ifp->index; memcpy(CMSG_DATA(cm), &pi, sizeof(pi)); /* Hop limit */ @@ -344,7 +344,7 @@ ipv6rs_handledata(_unused void *arg) } for (ifp = ifaces; ifp; ifp = ifp->next) - if (if_nametoindex(ifp->name) == (unsigned int)pkt.ipi6_ifindex) + if (ifp->index == pkt.ipi6_ifindex) break; if (ifp == NULL) { syslog(LOG_ERR,"received RA for unexpected interface from %s", diff --git a/lpf.c b/lpf.c index 853d0a32..cb9b2051 100644 --- a/lpf.c +++ b/lpf.c @@ -86,10 +86,7 @@ open_socket(struct interface *iface, int protocol) memset(&su, 0, sizeof(su)); su.sll.sll_family = PF_PACKET; su.sll.sll_protocol = htons(protocol); - if (!(su.sll.sll_ifindex = if_nametoindex(iface->name))) { - errno = ENOENT; - goto eexit; - } + su.sll.sll_ifindex = iface->index; /* Install the DHCP filter */ memset(&pf, 0, sizeof(pf)); if (protocol == ETHERTYPE_ARP) { @@ -142,10 +139,7 @@ send_raw_packet(const struct interface *iface, int protocol, memset(&su, 0, sizeof(su)); su.sll.sll_family = AF_PACKET; su.sll.sll_protocol = htons(protocol); - if (!(su.sll.sll_ifindex = if_nametoindex(iface->name))) { - errno = ENOENT; - return -1; - } + su.sll.sll_ifindex = iface->index; su.sll.sll_hatype = htons(iface->family); su.sll.sll_halen = iface->hwlen; if (iface->family == ARPHRD_INFINIBAND) diff --git a/net.c b/net.c index 7bb43a01..701023d9 100644 --- a/net.c +++ b/net.c @@ -182,53 +182,6 @@ hwaddr_aton(unsigned char *buffer, const char *addr) return len; } -struct interface * -init_interface(const char *ifname) -{ - struct ifreq ifr; - struct interface *iface = NULL; - - memset(&ifr, 0, sizeof(ifr)); - strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name)); - if (ioctl(socket_afnet, SIOCGIFFLAGS, &ifr) == -1) - goto eexit; - - iface = xzalloc(sizeof(*iface)); - strlcpy(iface->name, ifname, sizeof(iface->name)); - iface->flags = ifr.ifr_flags; - /* We reserve the 100 range for virtual interfaces, if and when - * we can work them out. */ - iface->metric = 200 + if_nametoindex(iface->name); - if (getifssid(ifname, iface->ssid) != -1) { - iface->wireless = 1; - iface->metric += 100; - } - - if (ioctl(socket_afnet, SIOCGIFMTU, &ifr) == -1) - goto eexit; - /* Ensure that the MTU is big enough for DHCP */ - if (ifr.ifr_mtu < MTU_MIN) { - ifr.ifr_mtu = MTU_MIN; - strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name)); - if (ioctl(socket_afnet, SIOCSIFMTU, &ifr) == -1) - goto eexit; - } - - snprintf(iface->leasefile, sizeof(iface->leasefile), - LEASEFILE, ifname); - /* 0 is a valid fd, so init to -1 */ - iface->raw_fd = -1; - iface->udp_fd = -1; - iface->arp_fd = -1; - goto exit; - -eexit: - free(iface); - iface = NULL; -exit: - return iface; -} - void free_interface(struct interface *iface) { @@ -396,8 +349,10 @@ discover_interfaces(int argc, char * const *argv) continue; p = ifa->ifa_name; } - if ((ifp = init_interface(p)) == NULL) - continue; + + ifp = xzalloc(sizeof(*ifp)); + strlcpy(ifp->name, p, sizeof(ifp->name)); + ifp->flags = ifa->ifa_flags; /* Bring the interface up if not already */ if (!(ifp->flags & IFF_UP) @@ -439,6 +394,7 @@ discover_interfaces(int argc, char * const *argv) } #endif + ifp->index = sdl->sdl_index; sdl_type = sdl->sdl_type; switch(sdl->sdl_type) { case IFT_BRIDGE: /* FALLTHROUGH */ @@ -463,6 +419,7 @@ discover_interfaces(int argc, char * const *argv) memcpy(ifp->hwaddr, CLLADDR(sdl), ifp->hwlen); #elif AF_PACKET sll = (const struct sockaddr_ll *)(void *)ifa->ifa_addr; + ifp->index = sll->sll_index; ifp->family = sdl_type = sll->sll_hatype; ifp->hwlen = sll->sll_halen; if (ifp->hwlen != 0) @@ -500,6 +457,27 @@ discover_interfaces(int argc, char * const *argv) continue; } + /* Ensure that the MTU is big enough for DHCP */ + if (get_mtu(ifp->name) < MTU_MIN && + set_mtu(ifp->name, MTU_MIN) == -1) + { + syslog(LOG_ERR, "%s: set_mtu: %m", p); + free_interface(ifp); + continue; + } + + /* We reserve the 100 range for virtual interfaces, if and when + * we can work them out. */ + ifp->metric = 200 + ifp->index; + if (getifssid(ifp->name, ifp->ssid) != -1) { + ifp->wireless = 1; + ifp->metric += 100; + } + snprintf(ifp->leasefile, sizeof(ifp->leasefile), + LEASEFILE, ifp->name); + /* 0 is a valid fd, so init to -1 */ + ifp->raw_fd = ifp->udp_fd = ifp->arp_fd = -1; + if (ifl) ifl->next = ifp; else diff --git a/net.h b/net.h index f1817983..5fbab78b 100644 --- a/net.h +++ b/net.h @@ -96,7 +96,6 @@ char *hwaddr_ntoa(const unsigned char *, size_t); size_t hwaddr_aton(unsigned char *, const char *); int getifssid(const char *, char *); -struct interface *init_interface(const char *); struct interface *discover_interfaces(int, char * const *); void free_interface(struct interface *); int do_mtu(const char *, short int); -- 2.47.2