From: Roy Marples Date: Tue, 19 Feb 2013 13:37:42 +0000 (+0000) Subject: Use a TAILQ macro for our interface list. X-Git-Tag: v5.99.6~53 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=4b0cbc89742e6eb28580231da2f1ca8597613794;p=thirdparty%2Fdhcpcd.git Use a TAILQ macro for our interface list. --- diff --git a/dhcp.c b/dhcp.c index deabd773..a7042e7e 100644 --- a/dhcp.c +++ b/dhcp.c @@ -2441,9 +2441,14 @@ dhcp_dump(const char *ifname) struct interface *ifp; struct dhcp_state *state; - ifaces = ifp = calloc(1, sizeof(*ifp)); + ifaces = malloc(sizeof(*ifaces)); + if (ifaces == NULL) + goto eexit; + TAILQ_INIT(ifaces); + ifp = calloc(1, sizeof(*ifp)); if (ifp == NULL) goto eexit; + TAILQ_INSERT_HEAD(ifaces, ifp, next); ifp->if_data[IF_DATA_DHCP] = state = calloc(1, sizeof(*state)); if (state == NULL) goto eexit; diff --git a/dhcp6.c b/dhcp6.c index 46e2265f..ef0fe584 100644 --- a/dhcp6.c +++ b/dhcp6.c @@ -920,7 +920,7 @@ dhcp6_addrexists(const struct ipv6_addr *a) const struct dhcp6_state *state; const struct ipv6_addr *ap; - for (ifp = ifaces; ifp; ifp = ifp->next) { + TAILQ_FOREACH(ifp, ifaces, next) { state = D6_CSTATE(ifp); if (state == NULL) continue; @@ -1195,9 +1195,10 @@ dhcp6_handledata(_unused void *arg) return; } - for (ifp = ifaces; ifp; ifp = ifp->next) + TAILQ_FOREACH(ifp, ifaces, next) { if (ifp->index == (unsigned int)pkt.ipi6_ifindex) break; + } if (ifp == NULL) { syslog(LOG_ERR, "DHCPv6 reply for unexpected interface from %s", sfrom); @@ -1545,9 +1546,12 @@ dhcp6_freedrop(struct interface *ifp, int drop, const char *reason) /* If we don't have any more DHCP6 enabled interfaces, * close the global socket */ - for (ifp = ifaces; ifp; ifp = ifp->next) - if (D6_STATE(ifp)) - break; + if (ifaces) { + TAILQ_FOREACH(ifp, ifaces, next) { + if (D6_STATE(ifp)) + break; + } + } if (ifp == NULL && sock != -1) { close(sock); eloop_event_delete(sock); diff --git a/dhcpcd.c b/dhcpcd.c index a305803d..440f4e4a 100644 --- a/dhcpcd.c +++ b/dhcpcd.c @@ -73,9 +73,9 @@ const char copyright[] = "Copyright (c) 2006-2013 Roy Marples"; #define RELEASE_DELAY_S 0 #define RELEASE_DELAY_NS 10000000 +struct if_head *ifaces; char vendor[VENDORCLASSID_MAX_LEN]; int pidfd = -1; -struct interface *ifaces = NULL; struct if_options *if_options = NULL; int ifac = 0; char **ifav = NULL; @@ -135,16 +135,16 @@ static void cleanup(void) { #ifdef DEBUG_MEMORY - struct interface *iface; + struct interface *ifp; int i; free_options(if_options); - while (ifaces) { - iface = ifaces; - ifaces = iface->next; - free_interface(iface); + while ((ifp = TAILQ_FIRST(ifaces))) { + TAILQ_REMOVE(ifaces, ifp, next); + free_interface(ifp); } + free(ifaces); for (i = 0; i < ifac; i++) free(ifav[i]); @@ -256,37 +256,28 @@ struct interface * find_interface(const char *ifname) { struct interface *ifp; - - for (ifp = ifaces; ifp; ifp = ifp->next) + + TAILQ_FOREACH(ifp, ifaces, next) { if (strcmp(ifp->name, ifname) == 0) return ifp; + } return NULL; } static void -stop_interface(struct interface *iface) +stop_interface(struct interface *ifp) { - struct interface *ifp, *ifl = NULL; - syslog(LOG_INFO, "%s: removing interface", iface->name); + syslog(LOG_INFO, "%s: removing interface", ifp->name); // Remove the interface from our list - for (ifp = ifaces; ifp; ifp = ifp->next) { - if (ifp == iface) - break; - ifl = ifp; - } - if (ifl) - ifl->next = ifp->next; - else - ifaces = ifp->next; - - dhcp6_drop(iface, NULL); - ipv6rs_drop(iface); -// if (strcmp(iface->state->reason, "RELEASE") != 0) - dhcp_drop(iface, "STOP"); - dhcp_close(iface); - eloop_timeout_delete(NULL, iface); + TAILQ_REMOVE(ifaces, ifp, next); + dhcp6_drop(ifp, NULL); + ipv6rs_drop(ifp); +// if (strcmp(ifp->state->reason, "RELEASE") != 0) + dhcp_drop(ifp, "STOP"); + dhcp_close(ifp); + eloop_timeout_delete(NULL, ifp); free_interface(ifp); if (!(options & (DHCPCD_MASTER | DHCPCD_TEST))) exit(EXIT_FAILURE); @@ -380,10 +371,8 @@ handle_carrier(int action, int flags, const char *ifname) if (!(options & DHCPCD_LINK)) return; - for (ifp = ifaces; ifp; ifp = ifp->next) - if (strcmp(ifp->name, ifname) == 0) - break; - if (!ifp) { + ifp = find_interface(ifname); + if (ifp == NULL) { if (options & DHCPCD_LINK) handle_interface(1, ifname); return; @@ -487,7 +476,6 @@ init_state(struct interface *ifp, int argc, char **argv) syslog(LOG_ERR, "ipv6_init: %m"); } - if (!(options & DHCPCD_TEST)) script_runreason(ifp, "PREINIT"); @@ -514,7 +502,8 @@ init_state(struct interface *ifp, int argc, char **argv) void handle_interface(int action, const char *ifname) { - struct interface *ifs, *ifp, *ifn, *ifl = NULL; + struct if_head *ifs; + struct interface *ifp, *ifn, *ifl = NULL; const char * const argv[] = { ifname }; int i; @@ -535,30 +524,31 @@ handle_interface(int action, const char *ifname) } ifs = discover_interfaces(-1, UNCONST(argv)); - for (ifp = ifs; ifp; ifp = ifp->next) { + TAILQ_FOREACH_SAFE(ifp, ifs, next, ifn) { if (strcmp(ifp->name, ifname) != 0) continue; /* Check if we already have the interface */ - for (ifn = ifaces; ifn; ifn = ifn->next) { - if (strcmp(ifn->name, ifp->name) == 0) - break; - ifl = ifn; - } - if (ifn) { + ifl = find_interface(ifp->name); + if (ifl) { /* The flags and hwaddr could have changed */ - ifn->flags = ifp->flags; - ifn->hwlen = ifp->hwlen; + ifl->flags = ifp->flags; + ifl->hwlen = ifp->hwlen; if (ifp->hwlen != 0) - memcpy(ifn->hwaddr, ifp->hwaddr, ifn->hwlen); + memcpy(ifl->hwaddr, ifp->hwaddr, ifl->hwlen); } else { - if (ifl) - ifl->next = ifp; - else - ifaces = ifp; + TAILQ_REMOVE(ifs, ifp, next); + TAILQ_INSERT_TAIL(ifaces, ifp, next); } init_state(ifp, 0, NULL); start_interface(ifp); } + + /* Free our discovered list */ + while ((ifp = TAILQ_FIRST(ifs))) { + TAILQ_REMOVE(ifs, ifp, next); + free_interface(ifp); + } + free(ifs); } #ifdef RTM_CHGADDR @@ -569,7 +559,7 @@ handle_hwaddr(const char *ifname, unsigned char *hwaddr, size_t hwlen) struct if_options *ifo; struct dhcp_state *state; - for (ifp = ifaces; ifp; ifp = ifp->next) + TAILQ_FOREACH(ifp, ifaces, next) { if (strcmp(ifp->name, ifname) == 0 && ifp->hwlen <= hwlen) { state = D_STATE(ifp); if (state == NULL) @@ -598,6 +588,7 @@ handle_hwaddr(const char *ifname, unsigned char *hwaddr, size_t hwlen) start_interface(ifp); } } + } free(hwaddr); } #endif @@ -616,19 +607,16 @@ if_reboot(struct interface *ifp, int argc, char **argv) static void reconf_reboot(int action, int argc, char **argv, int oi) { - struct interface *ifl, *ifn, *ifp, *ifs, *ift; + struct if_head *ifs; + struct interface *ifn, *ifp; ifs = discover_interfaces(argc - oi, argv + oi); if (ifs == NULL) return; - for (ifp = ifs; ifp && (ift = ifp->next, 1); ifp = ift) { - ifl = NULL; - for (ifn = ifaces; ifn; ifn = ifn->next) { - if (strcmp(ifn->name, ifp->name) == 0) - break; - ifl = ifn; - } + while ((ifp = TAILQ_FIRST(ifs))) { + TAILQ_REMOVE(ifs, ifp, next); + ifn = find_interface(ifp->name); if (ifn) { if (action) if_reboot(ifn, argc, argv); @@ -636,15 +624,12 @@ reconf_reboot(int action, int argc, char **argv, int oi) ipv4_applyaddr(ifn); free_interface(ifp); } else { - ifp->next = NULL; + TAILQ_INSERT_TAIL(ifaces, ifp, next); init_state(ifp, argc, argv); start_interface(ifp); - if (ifl) - ifl->next = ifp; - else - ifaces = ifp; } } + free(ifs); sort_interfaces(); } @@ -704,8 +689,9 @@ handle_signal(int sig) break; case SIGUSR1: syslog(LOG_INFO, "received SIGUSR, reconfiguring"); - for (ifp = ifaces; ifp; ifp = ifp->next) + TAILQ_FOREACH(ifp, ifaces, next) { ipv4_applyaddr(ifp); + } return; case SIGPIPE: syslog(LOG_WARNING, "received SIGPIPE"); @@ -723,10 +709,7 @@ handle_signal(int sig) /* As drop_dhcp could re-arrange the order, we do it like this. */ for (;;) { /* Be sane and drop the last config first */ - for (ifp = ifaces; ifp; ifp = ifp->next) { - if (ifp->next == NULL) - break; - } + ifp = TAILQ_LAST(ifaces, if_head); if (ifp == NULL) break; if (ifp->carrier != LINK_DOWN && @@ -776,7 +759,7 @@ handle_args(struct fd_list *fd, int argc, char **argv) } else if (strcmp(*argv, "--getinterfaces") == 0) { len = 0; if (argc == 1) { - for (ifp = ifaces; ifp; ifp = ifp->next) { + TAILQ_FOREACH(ifp, ifaces, next) { len++; if (D6_STATE_RUNNING(ifp)) len++; @@ -786,13 +769,14 @@ handle_args(struct fd_list *fd, int argc, char **argv) len = write(fd->fd, &len, sizeof(len)); if (len != sizeof(len)) return -1; - for (ifp = ifaces; ifp; ifp = ifp->next) + TAILQ_FOREACH(ifp, ifaces, next) { send_interface(fd->fd, ifp); + } return 0; } opt = 0; while (argv[++opt] != NULL) { - for (ifp = ifaces; ifp; ifp = ifp->next) + TAILQ_FOREACH(ifp, ifaces, next) { if (strcmp(argv[opt], ifp->name) == 0) { len++; if (D6_STATE_RUNNING(ifp)) @@ -800,15 +784,17 @@ handle_args(struct fd_list *fd, int argc, char **argv) if (ipv6rs_has_ra(ifp)) len++; } + } } len = write(fd->fd, &len, sizeof(len)); if (len != sizeof(len)) return -1; opt = 0; while (argv[++opt] != NULL) { - for (ifp = ifaces; ifp; ifp = ifp->next) + TAILQ_FOREACH(ifp, ifaces, next) { if (strcmp(argv[opt], ifp->name) == 0) send_interface(fd->fd, ifp); + } } return 0; } else if (strcmp(*argv, "--listen") == 0) { @@ -863,10 +849,7 @@ handle_args(struct fd_list *fd, int argc, char **argv) if (do_release || do_exit) { for (oi = optind; oi < argc; oi++) { - for (ifp = ifaces; ifp; ifp = ifp->next) - if (strcmp(ifp->name, argv[oi]) == 0) - break; - if (!ifp) + if ((ifp = find_interface(argv[oi])) == NULL) continue; if (do_release) ifp->options->options |= DHCPCD_RELEASE; @@ -885,7 +868,7 @@ handle_args(struct fd_list *fd, int argc, char **argv) int main(int argc, char **argv) { - struct interface *iface; + struct interface *ifp; uint16_t family = 0; int opt, oi = 0, sig = 0, i, control_fd; size_t len; @@ -1158,14 +1141,11 @@ main(int argc, char **argv) ifaces = discover_interfaces(ifc, ifv); for (i = 0; i < ifc; i++) { - for (iface = ifaces; iface; iface = iface->next) - if (strcmp(iface->name, ifv[i]) == 0) - break; - if (!iface) + if (find_interface(ifv[i]) == NULL) syslog(LOG_ERR, "%s: interface not found or invalid", ifv[i]); } - if (!ifaces) { + if (ifaces == NULL) { if (ifc == 0) syslog(LOG_ERR, "no valid interfaces found"); else @@ -1181,9 +1161,9 @@ main(int argc, char **argv) daemonise(); opt = 0; - for (iface = ifaces; iface; iface = iface->next) { - init_state(iface, argc, argv); - if (iface->carrier != LINK_DOWN) + TAILQ_FOREACH(ifp, ifaces, next) { + init_state(ifp, argc, argv); + if (ifp->carrier != LINK_DOWN) opt = 1; } @@ -1198,9 +1178,9 @@ main(int argc, char **argv) ts.tv_sec = 1; ts.tv_nsec = 0; nanosleep(&ts, NULL); - for (iface = ifaces; iface; iface = iface->next) { - handle_carrier(0, 0, iface->name); - if (iface->carrier != LINK_DOWN) { + TAILQ_FOREACH(ifp, ifaces, next) { + handle_carrier(0, 0, ifp->name); + if (ifp->carrier != LINK_DOWN) { opt = 1; break; } @@ -1208,8 +1188,8 @@ main(int argc, char **argv) } if (options & DHCPCD_MASTER) i = if_options->timeout; - else if (ifaces) - i = ifaces->options->timeout; + else if ((ifp = TAILQ_FIRST(ifaces))) + i = ifp->options->timeout; else i = 0; if (opt == 0 && @@ -1228,8 +1208,9 @@ main(int argc, char **argv) if_options = NULL; sort_interfaces(); - for (iface = ifaces; iface; iface = iface->next) - eloop_timeout_add_sec(0, start_interface, iface); + TAILQ_FOREACH(ifp, ifaces, next) { + eloop_timeout_add_sec(0, start_interface, ifp); + } eloop_start(&dhcpcd_sigset); exit(EXIT_SUCCESS); diff --git a/dhcpcd.h b/dhcpcd.h index c734360c..09c19254 100644 --- a/dhcpcd.h +++ b/dhcpcd.h @@ -28,6 +28,7 @@ #ifndef DHCPCD_H #define DHCPCD_H +#include #include #include @@ -51,6 +52,7 @@ #define IF_DATA_MAX 3 struct interface { + TAILQ_ENTRY(interface) next; char name[IF_NAMESIZE]; unsigned int index; int flags; @@ -65,8 +67,8 @@ struct interface { char profile[PROFILE_LEN]; struct if_options *options; void *if_data[IF_DATA_MAX]; - struct interface *next; }; +extern TAILQ_HEAD(if_head, interface) *ifaces; extern char vendor[VENDORCLASSID_MAX_LEN]; extern sigset_t dhcpcd_sigset; @@ -76,7 +78,6 @@ extern char **ifav; extern int ifdc; extern char **ifdv; extern struct if_options *if_options; -extern struct interface *ifaces; pid_t daemonise(void); struct interface *find_interface(const char *); diff --git a/if-pref.c b/if-pref.c index 7b7fed84..3d024a60 100644 --- a/if-pref.c +++ b/if-pref.c @@ -79,33 +79,27 @@ ifcmp(const struct interface *si, const struct interface *ti) void sort_interfaces(void) { - struct interface *sorted, *ifp, *ifn, *ift; + struct if_head sorted; + struct interface *ifp, *ift; - if (!ifaces || !ifaces->next) + if (ifaces == NULL || + (ifp = TAILQ_FIRST(ifaces)) == NULL || + TAILQ_NEXT(ifp, next) == NULL) return; - sorted = ifaces; - ifaces = ifaces->next; - sorted->next = NULL; - for (ifp = ifaces; ifp && (ifn = ifp->next, 1); ifp = ifn) { - /* Are we the new head? */ - if (ifcmp(ifp, sorted) == -1) { - ifp->next = sorted; - sorted = ifp; - continue; - } - /* Do we fit in the middle? */ - for (ift = sorted; ift->next; ift = ift->next) { - if (ifcmp(ifp, ift->next) == -1) { - ifp->next = ift->next; - ift->next = ifp; + + TAILQ_INIT(&sorted); + TAILQ_REMOVE(ifaces, ifp, next); + TAILQ_INSERT_HEAD(&sorted, ifp, next); + while ((ifp = TAILQ_FIRST(ifaces))) { + TAILQ_REMOVE(ifaces, ifp, next); + TAILQ_FOREACH(ift, &sorted, next) { + if (ifcmp(ifp, ift) == -1) { + TAILQ_INSERT_BEFORE(ift, ifp, next); break; } } - /* We must be at the end */ - if (!ift->next) { - ift->next = ifp; - ifp->next = NULL; - } + if (ift == NULL) + TAILQ_INSERT_TAIL(&sorted, ifp, next); } - ifaces = sorted; + TAILQ_CONCAT(ifaces, &sorted, next); } diff --git a/ipv4.c b/ipv4.c index f9e43d14..ed4b11af 100644 --- a/ipv4.c +++ b/ipv4.c @@ -469,7 +469,7 @@ ipv4_buildroutes(void) struct interface *ifp; const struct dhcp_state *state; - for (ifp = ifaces; ifp; ifp = ifp->next) { + TAILQ_FOREACH(ifp, ifaces, next) { state = D_CSTATE(ifp); if (state == NULL || state->new == NULL) continue; @@ -632,9 +632,10 @@ ipv4_handleifa(int type, const char *ifname, if (addr->s_addr == INADDR_ANY) return; - for (ifp = ifaces; ifp; ifp = ifp->next) + TAILQ_FOREACH(ifp, ifaces, next) { if (strcmp(ifp->name, ifname) == 0) break; + } if (ifp == NULL) return; diff --git a/ipv6.c b/ipv6.c index e7282ba6..4d5505f3 100644 --- a/ipv6.c +++ b/ipv6.c @@ -479,7 +479,7 @@ ipv6_buildroutes(void) return; TAILQ_INIT(&dnr); - for (ifp = ifaces; ifp; ifp = ifp->next) { + TAILQ_FOREACH(ifp, ifaces, next) { d6_state = D6_CSTATE(ifp); if (d6_state && d6_state->state == DH6S_BOUND) { TAILQ_FOREACH(addr, &d6_state->addrs, next) { diff --git a/ipv6ns.c b/ipv6ns.c index c98a2cfa..a0021640 100644 --- a/ipv6ns.c +++ b/ipv6ns.c @@ -319,9 +319,10 @@ ipv6ns_handledata(_unused void *arg) return; } - for (ifp = ifaces; ifp; ifp = ifp->next) + TAILQ_FOREACH(ifp, ifaces, next) { if (ifp->index == (unsigned int)pkt.ipi6_ifindex) break; + } if (ifp == NULL) { #ifdef DEBUG_NS syslog(LOG_DEBUG, "NA for unexpected interface from %s", sfrom); diff --git a/ipv6rs.c b/ipv6rs.c index 783e56c4..59d20afe 100644 --- a/ipv6rs.c +++ b/ipv6rs.c @@ -473,9 +473,10 @@ ipv6rs_handledata(_unused void *arg) return; } - for (ifp = ifaces; ifp; ifp = ifp->next) + TAILQ_FOREACH(ifp, ifaces, next) { if (ifp->index == (unsigned int)pkt.ipi6_ifindex) break; + } if (ifp == NULL) { #ifdef DEBUG_RS syslog(LOG_DEBUG, "RA for unexpected interface from %s", sfrom); diff --git a/net.c b/net.c index 028dd9fa..5245554a 100644 --- a/net.c +++ b/net.c @@ -199,13 +199,14 @@ up_interface(struct interface *iface) return retval; } -struct interface * +struct if_head * discover_interfaces(int argc, char * const *argv) { struct ifaddrs *ifaddrs, *ifa; char *p; int i, sdl_type; - struct interface *ifp, *ifs, *ifl; + struct if_head *ifs; + struct interface *ifp; #ifdef __linux__ char ifn[IF_NAMESIZE]; #endif @@ -227,7 +228,11 @@ discover_interfaces(int argc, char * const *argv) if (getifaddrs(&ifaddrs) == -1) return NULL; - ifs = ifl = NULL; + ifs = malloc(sizeof(*ifs)); + if (ifs == NULL) + return NULL; + TAILQ_INIT(ifs); + for (ifa = ifaddrs; ifa; ifa = ifa->ifa_next) { if (ifa->ifa_addr != NULL) { #ifdef AF_LINK @@ -241,9 +246,10 @@ discover_interfaces(int argc, char * const *argv) /* It's possible for an interface to have >1 AF_LINK. * For our purposes, we use the first one. */ - for (ifp = ifs; ifp; ifp = ifp->next) + TAILQ_FOREACH(ifp, ifs, next) { if (strcmp(ifp->name, ifa->ifa_name) == 0) break; + } if (ifp) continue; if (argc > 0) { @@ -409,11 +415,7 @@ discover_interfaces(int argc, char * const *argv) ifp->metric += 100; } - if (ifl) - ifl->next = ifp; - else - ifs = ifp; - ifl = ifp; + TAILQ_INSERT_TAIL(ifs, ifp, next); } freeifaddrs(ifaddrs); diff --git a/net.h b/net.h index ca789525..9f832fbf 100644 --- a/net.h +++ b/net.h @@ -97,7 +97,7 @@ char *hwaddr_ntoa(const unsigned char *, size_t); size_t hwaddr_aton(unsigned char *, const char *); int getifssid(const char *, char *); -struct interface *discover_interfaces(int, char * const *); +struct if_head *discover_interfaces(int, char * const *); void free_interface(struct interface *); int do_mtu(const char *, short int); #define get_mtu(iface) do_mtu(iface, 0) diff --git a/script.c b/script.c index 867f8c0f..5f9005ee 100644 --- a/script.c +++ b/script.c @@ -259,14 +259,15 @@ make_env(const struct interface *ifp, const char *reason, char ***argv) EMALLOC(6, e); snprintf(env[6], e, "ifmtu=%d", get_mtu(ifp->name)); l = e = strlen("interface_order="); - for (ifp2 = ifaces; ifp2; ifp2 = ifp2->next) + TAILQ_FOREACH(ifp2, ifaces, next) { e += strlen(ifp2->name) + 1; + } EMALLOC(7, e); p = env[7]; strlcpy(p, "interface_order=", e); e -= l; p += l; - for (ifp2 = ifaces; ifp2; ifp2 = ifp2->next) { + TAILQ_FOREACH(ifp2, ifaces, next) { l = strlcpy(p, ifp2->name, e); p += l; e -= l;