diff options
author | Kozlov Dmitry <xeb@mail.ru> | 2011-08-30 18:46:38 +0400 |
---|---|---|
committer | Kozlov Dmitry <xeb@mail.ru> | 2011-08-30 18:46:38 +0400 |
commit | 98cc654b0c508d63fd872dc5405d6d95e909e5ff (patch) | |
tree | 24023b6fa8c46368e97878c26757d54fbabd677a /accel-pppd/ipv6 | |
parent | eb9e138d811b437c284aaf0cf5ed4898bbff802d (diff) | |
download | accel-ppp-98cc654b0c508d63fd872dc5405d6d95e909e5ff.tar.gz accel-ppp-98cc654b0c508d63fd872dc5405d6d95e909e5ff.zip |
dhcpv6: rapid commit support
Diffstat (limited to 'accel-pppd/ipv6')
-rw-r--r-- | accel-pppd/ipv6/dhcpv6.c | 34 | ||||
-rw-r--r-- | accel-pppd/ipv6/dhcpv6.h | 1 | ||||
-rw-r--r-- | accel-pppd/ipv6/dhcpv6_packet.c | 2 |
3 files changed, 20 insertions, 17 deletions
diff --git a/accel-pppd/ipv6/dhcpv6.c b/accel-pppd/ipv6/dhcpv6.c index cf09b079..7b37599d 100644 --- a/accel-pppd/ipv6/dhcpv6.c +++ b/accel-pppd/ipv6/dhcpv6.c @@ -249,7 +249,7 @@ static void dhcpv6_send_reply(struct dhcpv6_packet *req, struct dhcpv6_pd *pd, i insert_status(reply, opt1, D6_STATUS_NoAddrsAvail); } else { - if (req->hdr->type == D6_REQUEST) + if (req->hdr->type == D6_REQUEST || req->rapid_commit) pd->addr_iaid = ia_na->iaid; f = 1; @@ -314,7 +314,7 @@ static void dhcpv6_send_reply(struct dhcpv6_packet *req, struct dhcpv6_pd *pd, i insert_status(reply, opt1, D6_STATUS_NoPrefixAvail); } else { - if (req->hdr->type == D6_REQUEST) { + if (req->hdr->type == D6_REQUEST || req->rapid_commit) { pd->dp_iaid = ia_na->iaid; if (!pd->dp_active) insert_dp_routes(req->ppp, pd); @@ -410,15 +410,17 @@ static void dhcpv6_recv_solicit(struct dhcpv6_packet *req) req->serverid = &conf_serverid; - if (!pd->clientid) { - pd->clientid = _malloc(sizeof(struct dhcpv6_opt_hdr) + ntohs(req->clientid->hdr.len)); - memcpy(pd->clientid, req->clientid, sizeof(struct dhcpv6_opt_hdr) + ntohs(req->clientid->hdr.len)); - } else if (pd->clientid->hdr.len != req->clientid->hdr.len || memcmp(pd->clientid, req->clientid, sizeof(struct dhcpv6_opt_hdr) + ntohs(req->clientid->hdr.len))) { - log_ppp_warn("dhcpv6: Client-ID option was changed\n"); - return; + if (req->rapid_commit) { + if (!pd->clientid) { + pd->clientid = _malloc(sizeof(struct dhcpv6_opt_hdr) + ntohs(req->clientid->hdr.len)); + memcpy(pd->clientid, req->clientid, sizeof(struct dhcpv6_opt_hdr) + ntohs(req->clientid->hdr.len)); + } else if (pd->clientid->hdr.len != req->clientid->hdr.len || memcmp(pd->clientid, req->clientid, sizeof(struct dhcpv6_opt_hdr) + ntohs(req->clientid->hdr.len))) { + log_ppp_error("dhcpv6: unmatched Client-ID option\n"); + return; + } } - dhcpv6_send_reply(req, pd, D6_ADVERTISE); + dhcpv6_send_reply(req, pd, req->rapid_commit ? D6_REPLY : D6_ADVERTISE); } static void dhcpv6_recv_request(struct dhcpv6_packet *req) @@ -438,14 +440,12 @@ static void dhcpv6_recv_request(struct dhcpv6_packet *req) return; } - if (req->hdr->type == D6_REQUEST) { - if (!pd->clientid) { - pd->clientid = _malloc(sizeof(struct dhcpv6_opt_hdr) + ntohs(req->clientid->hdr.len)); - memcpy(pd->clientid, req->clientid, sizeof(struct dhcpv6_opt_hdr) + ntohs(req->clientid->hdr.len)); - } else if (pd->clientid->hdr.len != req->clientid->hdr.len || memcmp(pd->clientid, req->clientid, sizeof(struct dhcpv6_opt_hdr) + ntohs(req->clientid->hdr.len))) { - log_ppp_warn("dhcpv6: unmatched Client-ID option\n"); - return; - } + if (!pd->clientid) { + pd->clientid = _malloc(sizeof(struct dhcpv6_opt_hdr) + ntohs(req->clientid->hdr.len)); + memcpy(pd->clientid, req->clientid, sizeof(struct dhcpv6_opt_hdr) + ntohs(req->clientid->hdr.len)); + } else if (pd->clientid->hdr.len != req->clientid->hdr.len || memcmp(pd->clientid, req->clientid, sizeof(struct dhcpv6_opt_hdr) + ntohs(req->clientid->hdr.len))) { + log_ppp_error("dhcpv6: unmatched Client-ID option\n"); + return; } dhcpv6_send_reply(req, pd, D6_REPLY); diff --git a/accel-pppd/ipv6/dhcpv6.h b/accel-pppd/ipv6/dhcpv6.h index 403d703e..d1c0267c 100644 --- a/accel-pppd/ipv6/dhcpv6.h +++ b/accel-pppd/ipv6/dhcpv6.h @@ -172,6 +172,7 @@ struct dhcpv6_packet struct dhcpv6_msg_hdr *hdr; struct dhcpv6_opt_clientid *clientid; struct dhcpv6_opt_serverid *serverid; + int rapid_commit:1; struct list_head opt_list; void *endptr; diff --git a/accel-pppd/ipv6/dhcpv6_packet.c b/accel-pppd/ipv6/dhcpv6_packet.c index fd2b0dd5..026b6afd 100644 --- a/accel-pppd/ipv6/dhcpv6_packet.c +++ b/accel-pppd/ipv6/dhcpv6_packet.c @@ -133,6 +133,8 @@ struct dhcpv6_packet *dhcpv6_packet_parse(const void *buf, size_t size) pkt->clientid = ptr; else if (opth->code == htons(D6_OPTION_SERVERID)) pkt->serverid = ptr; + else if (opth->code == htons(D6_OPTION_RAPID_COMMIT)) + pkt->rapid_commit = 1; ptr = parse_option(ptr, endptr, &pkt->opt_list); if (!ptr) { dhcpv6_packet_free(pkt); |