From: Roy Marples Date: Wed, 14 Nov 2012 10:20:12 +0000 (+0000) Subject: Move the RS state into a struct in a generic data array. X-Git-Tag: v5.6.3~17 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=9a6b22681aaa56e3140f10b6f1ec0589322083bb;p=thirdparty%2Fdhcpcd.git Move the RS state into a struct in a generic data array. We should move the DHCP code there, but more importantly allows DHCP6 to slot in later. --- diff --git a/dhcpcd.h b/dhcpcd.h index 1f229522..c0147baa 100644 --- a/dhcpcd.h +++ b/dhcpcd.h @@ -60,6 +60,11 @@ enum DHS { #define LINK_UNKNOWN 0 #define LINK_DOWN -1 +#define IF_DATA_DHCP 0 +#define IF_DATA_IPV6RS 1 +#define IF_DATA_DHCP6 2 +#define IF_DATA_MAX 3 + struct if_state { enum DHS state; char profile[PROFILE_LEN]; @@ -85,6 +90,7 @@ struct if_state { struct interface { char name[IF_NAMESIZE]; struct if_state *state; + void *if_data[IF_DATA_MAX]; unsigned int index; int flags; @@ -111,10 +117,6 @@ struct interface { unsigned char *clientid; - unsigned char *rs; - size_t rslen; - int rsprobes; - struct interface *next; }; diff --git a/ipv6rs.c b/ipv6rs.c index 31a52309..f7f3aaa8 100644 --- a/ipv6rs.c +++ b/ipv6rs.c @@ -186,20 +186,22 @@ ipv6rs_open(void) static int ipv6rs_makeprobe(struct interface *ifp) { + struct rs_state *state; struct nd_router_solicit *rs; struct nd_opt_hdr *nd; - free(ifp->rs); - ifp->rslen = sizeof(*rs) + ROUNDUP8(ifp->hwlen + 2); - ifp->rs = xzalloc(ifp->rslen); - if (ifp->rs == NULL) + state = RS_STATE(ifp); + free(state->rs); + state->rslen = sizeof(*rs) + ROUNDUP8(ifp->hwlen + 2); + state->rs = xzalloc(state->rslen); + if (state->rs == NULL) return -1; - rs = (struct nd_router_solicit *)(void *)ifp->rs; + rs = (struct nd_router_solicit *)(void *)state->rs; rs->nd_rs_type = ND_ROUTER_SOLICIT; rs->nd_rs_code = 0; rs->nd_rs_cksum = 0; rs->nd_rs_reserved = 0; - nd = (struct nd_opt_hdr *)(ifp->rs + sizeof(*rs)); + nd = (struct nd_opt_hdr *)(state->rs + sizeof(*rs)); nd->nd_opt_type = ND_OPT_SOURCE_LINKADDR; nd->nd_opt_len = (ROUNDUP8(ifp->hwlen + 2)) >> 3; memcpy(nd + 1, ifp->hwaddr, ifp->hwlen); @@ -210,6 +212,7 @@ static void ipv6rs_sendprobe(void *arg) { struct interface *ifp = arg; + struct rs_state *state; struct sockaddr_in6 dst; struct cmsghdr *cm; struct in6_pktinfo pi; @@ -218,10 +221,10 @@ ipv6rs_sendprobe(void *arg) dst = allrouters; //dst.sin6_scope_id = ifp->linkid; - ipv6rs_makeprobe(ifp); + state = RS_STATE(ifp); sndhdr.msg_name = (caddr_t)&dst; - sndhdr.msg_iov[0].iov_base = ifp->rs; - sndhdr.msg_iov[0].iov_len = ifp->rslen; + sndhdr.msg_iov[0].iov_base = state->rs; + sndhdr.msg_iov[0].iov_len = state->rslen; /* Set the outbound interface */ cm = CMSG_FIRSTHDR(&sndhdr); @@ -243,7 +246,7 @@ ipv6rs_sendprobe(void *arg) if (sendmsg(sock, &sndhdr, 0) == -1) syslog(LOG_ERR, "%s: sendmsg: %m", ifp->name); - if (ifp->rsprobes++ < MAX_RTR_SOLICITATIONS) + if (state->rsprobes++ < MAX_RTR_SOLICITATIONS) add_timeout_sec(RTR_SOLICITATION_INTERVAL, ipv6rs_sendprobe, ifp); else @@ -315,11 +318,16 @@ void ipv6rs_freedrop_ra(struct ra *rap, int drop) ssize_t ipv6rs_free(struct interface *ifp) { + struct rs_state *state; struct ra *rap, *ran; ssize_t n; - free(ifp->rs); - ifp->rs = NULL; + state = RS_STATE(ifp); + if (state) { + free(state->rs); + free(state); + ifp->if_data[IF_DATA_IPV6RS] = NULL; + } n = 0; TAILQ_FOREACH_SAFE(rap, &ipv6_routers, next, ran) { if (rap->iface == ifp) { @@ -333,6 +341,7 @@ ipv6rs_free(struct interface *ifp) static int rtpref(struct ra *rap) { + switch (rap->flags & ND_RA_FLAG_RTPREF_MASK) { case ND_RA_FLAG_RTPREF_HIGH: return (RTPREF_HIGH); @@ -879,16 +888,23 @@ ipv6rs_expire(void *arg) int ipv6rs_start(struct interface *ifp) { + struct rs_state *state; delete_timeout(NULL, ifp); + state = RS_STATE(ifp); + if (state == NULL) { + ifp->if_data[IF_DATA_IPV6RS] = xzalloc(sizeof(*state)); + state = RS_STATE(ifp); + } + /* Always make a new probe as the underlying hardware * address could have changed. */ ipv6rs_makeprobe(ifp); - if (ifp->rs == NULL) + if (state->rs == NULL) return -1; - ifp->rsprobes = 0; + state->rsprobes = 0; ipv6rs_sendprobe(ifp); return 0; } diff --git a/ipv6rs.h b/ipv6rs.h index ef8b4068..157c5438 100644 --- a/ipv6rs.h +++ b/ipv6rs.h @@ -67,6 +67,15 @@ struct ra { extern TAILQ_HEAD(rahead, ra) ipv6_routers; + +struct rs_state { + unsigned char *rs; + size_t rslen; + int rsprobes; +}; + +#define RS_STATE(a) ((struct rs_state *)(ifp)->if_data[IF_DATA_IPV6RS]) + int ipv6rs_open(void); void ipv6rs_handledata(void *); int ipv6rs_start(struct interface *);