summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRoy Marples <roy@marples.name>2012-11-14 10:20:12 +0000
committerRoy Marples <roy@marples.name>2012-11-14 10:20:12 +0000
commit9a6b22681aaa56e3140f10b6f1ec0589322083bb (patch)
tree8c5ecea4489838d4d4711eaa8a5c5560b7f0c49e
parentc42cbb3c3b54b31598b0f19e8d8d6882c85c5f8d (diff)
downloaddhcpcd-9a6b22681aaa56e3140f10b6f1ec0589322083bb.tar.xz
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.
-rw-r--r--dhcpcd.h10
-rw-r--r--ipv6rs.c44
-rw-r--r--ipv6rs.h9
3 files changed, 45 insertions, 18 deletions
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 *);