summaryrefslogtreecommitdiff
path: root/accel-pppd/ipv6
diff options
context:
space:
mode:
authorKozlov Dmitry <xeb@mail.ru>2011-08-30 18:46:38 +0400
committerKozlov Dmitry <xeb@mail.ru>2011-08-30 18:46:38 +0400
commit98cc654b0c508d63fd872dc5405d6d95e909e5ff (patch)
tree24023b6fa8c46368e97878c26757d54fbabd677a /accel-pppd/ipv6
parenteb9e138d811b437c284aaf0cf5ed4898bbff802d (diff)
downloadaccel-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.c34
-rw-r--r--accel-pppd/ipv6/dhcpv6.h1
-rw-r--r--accel-pppd/ipv6/dhcpv6_packet.c2
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);