summaryrefslogtreecommitdiff
path: root/accel-pppd
diff options
context:
space:
mode:
authorVladislav Grishenko <themiron@mail.ru>2020-04-30 06:33:41 +0500
committerVladislav Grishenko <themiron@mail.ru>2020-04-30 06:33:41 +0500
commit90778881d9aba076344412b7769e103f36541273 (patch)
tree5c594c52665dc338c73eb8d9543de7cfc3b0e97d /accel-pppd
parente5c2be0ad9d725beaa2f34d1d3ffb66b4abafeac (diff)
downloadaccel-ppp-90778881d9aba076344412b7769e103f36541273.tar.gz
accel-ppp-90778881d9aba076344412b7769e103f36541273.zip
ipoe: dhcp: add rebind-time support
Diffstat (limited to 'accel-pppd')
-rw-r--r--accel-pppd/accel-ppp.conf5
-rw-r--r--accel-pppd/accel-ppp.conf.53
-rw-r--r--accel-pppd/ctrl/ipoe/dhcpv4.c13
-rw-r--r--accel-pppd/ctrl/ipoe/dhcpv4.h4
-rw-r--r--accel-pppd/ctrl/ipoe/ipoe.c102
-rw-r--r--accel-pppd/ctrl/ipoe/ipoe.h1
6 files changed, 101 insertions, 27 deletions
diff --git a/accel-pppd/accel-ppp.conf b/accel-pppd/accel-ppp.conf
index 290a19c..7302a34 100644
--- a/accel-pppd/accel-ppp.conf
+++ b/accel-pppd/accel-ppp.conf
@@ -143,7 +143,8 @@ verbose=1
username=ifname
#password=username
lease-time=600
-renew-time=300
+#renew-time=300
+#rebind-time=525
max-lease-time=3600
#unit-cache=1000
#l4-redirect-table=4
@@ -166,6 +167,8 @@ start=dhcpv4
#attr-dhcp-router-ip=DHCP-Router-IP-Address
#attr-dhcp-mask=DHCP-Mask
#attr-dhcp-lease-time=DHCP-Lease-Time
+#attr-dhcp-renew-time=DHCP-Renewal-Time
+#attr-dhcp-rebind-time=DHCP-Rebinding-Time
#attr-dhcp-opt82=DHCP-Option82
#attr-dhcp-opt82-remote-id=DHCP-Agent-Remote-Id
#attr-dhcp-opt82-circuit-id=DHCP-Agent-Circuit-Id
diff --git a/accel-pppd/accel-ppp.conf.5 b/accel-pppd/accel-ppp.conf.5
index af85d04..0854d6f 100644
--- a/accel-pppd/accel-ppp.conf.5
+++ b/accel-pppd/accel-ppp.conf.5
@@ -281,6 +281,9 @@ Specifies lease time in seconds to be sent to dhcp client.
.BI "renew-time=" n
Specifies lease renew time (option 58) in seconds to be sent to dhcp client.
.TP
+.BI "rebind-time=" n
+Specifies lease rebind time (option 59) in seconds to be sent to dhcp client.
+.TP
.BI "max-lease-time=" n
Specifies max lease time in seconds, after this time session will be terminated if client won't renew it.
.TP
diff --git a/accel-pppd/ctrl/ipoe/dhcpv4.c b/accel-pppd/ctrl/ipoe/dhcpv4.c
index 557e58a..cdb21a9 100644
--- a/accel-pppd/ctrl/ipoe/dhcpv4.c
+++ b/accel-pppd/ctrl/ipoe/dhcpv4.c
@@ -709,7 +709,9 @@ static inline int dhcpv4_packet_add_opt_u32(struct dhcpv4_packet *pack, int type
return dhcpv4_packet_add_opt(pack, type, &val, 4);
}
-int dhcpv4_send_reply(int msg_type, struct dhcpv4_serv *serv, struct dhcpv4_packet *req, uint32_t yiaddr, uint32_t siaddr, uint32_t router, uint32_t mask, int lease_time, int renew_time, struct dhcpv4_packet *relay)
+int dhcpv4_send_reply(int msg_type, struct dhcpv4_serv *serv, struct dhcpv4_packet *req,
+ uint32_t yiaddr, uint32_t siaddr, uint32_t router, uint32_t mask,
+ int lease_time, int renew_time, int rebind_time, struct dhcpv4_packet *relay)
{
struct dhcpv4_packet *pack;
struct dhcpv4_option *opt;
@@ -744,10 +746,11 @@ int dhcpv4_send_reply(int msg_type, struct dhcpv4_serv *serv, struct dhcpv4_pack
if (dhcpv4_packet_add_opt_u32(pack, 51, lease_time))
goto out_err;
- if (renew_time) {
- if (dhcpv4_packet_add_opt_u32(pack, 58, renew_time))
- goto out_err;
- }
+ if (renew_time && dhcpv4_packet_add_opt_u32(pack, 58, renew_time))
+ goto out_err;
+
+ if (rebind_time && dhcpv4_packet_add_opt_u32(pack, 59, rebind_time))
+ goto out_err;
if (router && dhcpv4_packet_add_opt(pack, 3, &router, 4))
goto out_err;
diff --git a/accel-pppd/ctrl/ipoe/dhcpv4.h b/accel-pppd/ctrl/ipoe/dhcpv4.h
index 3e90cc3..24b9d61 100644
--- a/accel-pppd/ctrl/ipoe/dhcpv4.h
+++ b/accel-pppd/ctrl/ipoe/dhcpv4.h
@@ -117,7 +117,9 @@ int dhcpv4_relay_send_release(struct dhcpv4_relay *relay, uint8_t *chaddr, uint3
struct dhcpv4_option *client_id, struct dhcpv4_option *relay_agent,
const char *agent_circuit_id, const char *agent_remote_id);
-int dhcpv4_send_reply(int msg_type, struct dhcpv4_serv *serv, struct dhcpv4_packet *req, uint32_t yiaddr, uint32_t siaddr, uint32_t router, uint32_t mask, int lease_time, int renew_time, struct dhcpv4_packet *relay_reply);
+int dhcpv4_send_reply(int msg_type, struct dhcpv4_serv *serv, struct dhcpv4_packet *req,
+ uint32_t yiaddr, uint32_t siaddr, uint32_t router, uint32_t mask,
+ int lease_time, int renew_time, int rebind_time, struct dhcpv4_packet *relay_reply);
int dhcpv4_send_nak(struct dhcpv4_serv *serv, struct dhcpv4_packet *req);
void dhcpv4_send_notify(struct dhcpv4_serv *serv, struct dhcpv4_packet *req, unsigned int weight);
diff --git a/accel-pppd/ctrl/ipoe/ipoe.c b/accel-pppd/ctrl/ipoe/ipoe.c
index 87261cb..a4fa151 100644
--- a/accel-pppd/ctrl/ipoe/ipoe.c
+++ b/accel-pppd/ctrl/ipoe/ipoe.c
@@ -49,6 +49,8 @@
#define MODE_L2 2
#define MODE_L3 3
+#define LEASE_TIME 600
+
struct iplink_arg {
pcre *re;
const char *opt;
@@ -135,6 +137,7 @@ static int conf_attr_dhcp_router_ip;
static int conf_attr_dhcp_mask;
static int conf_attr_dhcp_lease_time;
static int conf_attr_dhcp_renew_time;
+static int conf_attr_dhcp_rebind_time;
static int conf_attr_l4_redirect;
static int conf_attr_l4_redirect_table;
static int conf_attr_l4_redirect_ipset;
@@ -162,9 +165,10 @@ static int conf_relay_timeout = 3;
static int conf_relay_retransmit = 3;
static LIST_HEAD(conf_gw_addr);
static int conf_netmask = 24;
-static int conf_lease_time = 600;
-static int conf_lease_timeout = 660;
-static int conf_renew_time = 300;
+static int conf_lease_time = LEASE_TIME;
+static int conf_lease_timeout = LEASE_TIME + LEASE_TIME/10;
+static int conf_renew_time = LEASE_TIME/2;
+static int conf_rebind_time = LEASE_TIME/2 + LEASE_TIME/4 + LEASE_TIME/8;
static int conf_verbose;
static const char *conf_agent_remote_id;
static int conf_proto;
@@ -880,7 +884,8 @@ static void __ipoe_session_start(struct ipoe_session *ses)
if (ses->ses.ipv4 && !ses->ses.ipv4->addr)
ses->ses.ipv4->addr = ses->siaddr;
- dhcpv4_send_reply(DHCPOFFER, ses->serv->dhcpv4, ses->dhcpv4_request, ses->yiaddr, ses->siaddr, ses->router, ses->mask, ses->lease_time, ses->renew_time, ses->dhcpv4_relay_reply);
+ dhcpv4_send_reply(DHCPOFFER, ses->serv->dhcpv4, ses->dhcpv4_request, ses->yiaddr, ses->siaddr, ses->router, ses->mask,
+ ses->lease_time, ses->renew_time, ses->rebind_time, ses->dhcpv4_relay_reply);
dhcpv4_packet_free(ses->dhcpv4_request);
ses->dhcpv4_request = NULL;
@@ -1018,7 +1023,8 @@ static void __ipoe_session_activate(struct ipoe_session *ses)
if (ses->dhcpv4_request) {
if (ses->ses.state == AP_STATE_ACTIVE)
- dhcpv4_send_reply(DHCPACK, ses->dhcpv4 ?: ses->serv->dhcpv4, ses->dhcpv4_request, ses->yiaddr, ses->siaddr, ses->router, ses->mask, ses->lease_time, ses->renew_time, ses->dhcpv4_relay_reply);
+ dhcpv4_send_reply(DHCPACK, ses->dhcpv4 ?: ses->serv->dhcpv4, ses->dhcpv4_request, ses->yiaddr, ses->siaddr, ses->router, ses->mask,
+ ses->lease_time, ses->renew_time, ses->rebind_time, ses->dhcpv4_relay_reply);
else
dhcpv4_send_nak(ses->serv->dhcpv4, ses->dhcpv4_request);
@@ -1073,7 +1079,8 @@ static void ipoe_session_keepalive(struct dhcpv4_packet *pack)
}
if (ses->ses.state == AP_STATE_ACTIVE) {
- dhcpv4_send_reply(DHCPACK, ses->dhcpv4 ?: ses->serv->dhcpv4, ses->dhcpv4_request, ses->yiaddr, ses->siaddr, ses->router, ses->mask, ses->lease_time, ses->renew_time, ses->dhcpv4_relay_reply);
+ dhcpv4_send_reply(DHCPACK, ses->dhcpv4 ?: ses->serv->dhcpv4, ses->dhcpv4_request, ses->yiaddr, ses->siaddr, ses->router, ses->mask,
+ ses->lease_time, ses->renew_time, ses->rebind_time, ses->dhcpv4_relay_reply);
} else
dhcpv4_send_nak(ses->dhcpv4 ?: ses->serv->dhcpv4, ses->dhcpv4_request);
@@ -1472,7 +1479,8 @@ static void ipoe_ses_recv_dhcpv4(struct dhcpv4_serv *dhcpv4, struct dhcpv4_packe
dhcpv4_packet_ref(pack);
ipoe_session_keepalive(pack);
} else
- dhcpv4_send_reply(DHCPOFFER, dhcpv4, pack, ses->yiaddr, ses->siaddr, ses->router, ses->mask, ses->lease_time, ses->renew_time, ses->dhcpv4_relay_reply);
+ dhcpv4_send_reply(DHCPOFFER, dhcpv4, pack, ses->yiaddr, ses->siaddr, ses->router, ses->mask,
+ ses->lease_time, ses->renew_time, ses->rebind_time, ses->dhcpv4_relay_reply);
}
} else if (pack->msg_type == DHCPREQUEST) {
ses->xid = pack->hdr->xid;
@@ -1507,7 +1515,8 @@ static void ipoe_ses_recv_dhcpv4_discover(struct dhcpv4_packet *pack)
}
if (ses->yiaddr)
- dhcpv4_send_reply(DHCPOFFER, ses->dhcpv4 ?: ses->serv->dhcpv4, pack, ses->yiaddr, ses->siaddr, ses->router, ses->mask, ses->lease_time, ses->renew_time, ses->dhcpv4_relay_reply);
+ dhcpv4_send_reply(DHCPOFFER, ses->dhcpv4 ?: ses->serv->dhcpv4, pack, ses->yiaddr, ses->siaddr, ses->router, ses->mask,
+ ses->lease_time, ses->renew_time, ses->rebind_time, ses->dhcpv4_relay_reply);
dhcpv4_packet_free(pack);
}
@@ -1954,6 +1963,10 @@ static void ipoe_ses_recv_dhcpv4_relay(struct dhcpv4_packet *pack)
if (opt)
ses->renew_time = ntohl(*(uint32_t *)opt->data);
+ opt = dhcpv4_packet_find_opt(pack, 59);
+ if (opt)
+ ses->rebind_time = ntohl(*(uint32_t *)opt->data);
+
opt = dhcpv4_packet_find_opt(pack, 1);
if (opt)
ses->mask = parse_dhcpv4_mask(ntohl(*(uint32_t *)opt->data));
@@ -1975,12 +1988,14 @@ static void ipoe_ses_recv_dhcpv4_relay(struct dhcpv4_packet *pack)
__ipoe_session_start(ses);
} else
- dhcpv4_send_reply(DHCPOFFER, ses->dhcpv4 ?: ses->serv->dhcpv4, ses->dhcpv4_request, ses->yiaddr, ses->siaddr, ses->router, ses->mask, ses->lease_time, ses->renew_time, ses->dhcpv4_relay_reply);
+ dhcpv4_send_reply(DHCPOFFER, ses->dhcpv4 ?: ses->serv->dhcpv4, ses->dhcpv4_request, ses->yiaddr, ses->siaddr, ses->router, ses->mask,
+ ses->lease_time, ses->renew_time, ses->rebind_time, ses->dhcpv4_relay_reply);
} else if (pack->msg_type == DHCPACK) {
if (ses->ses.state == AP_STATE_STARTING)
__ipoe_session_activate(ses);
else
- dhcpv4_send_reply(DHCPACK, ses->dhcpv4 ?: ses->serv->dhcpv4, ses->dhcpv4_request, ses->yiaddr, ses->siaddr, ses->router, ses->mask, ses->lease_time, ses->renew_time, ses->dhcpv4_relay_reply);
+ dhcpv4_send_reply(DHCPACK, ses->dhcpv4 ?: ses->serv->dhcpv4, ses->dhcpv4_request, ses->yiaddr, ses->siaddr, ses->router, ses->mask,
+ ses->lease_time, ses->renew_time, ses->rebind_time, ses->dhcpv4_relay_reply);
} else if (pack->msg_type == DHCPNAK) {
dhcpv4_send_nak(ses->dhcpv4 ?: ses->serv->dhcpv4, ses->dhcpv4_request);
@@ -2178,6 +2193,7 @@ struct ipoe_session *ipoe_session_alloc(const char *ifname)
ses->lease_time = conf_lease_time;
ses->renew_time = conf_renew_time;
+ ses->rebind_time = conf_rebind_time;
return ses;
}
@@ -2273,7 +2289,7 @@ static void ev_radius_access_accept(struct ev_radius_t *ev)
{
struct ipoe_session *ses = container_of(ev->ses, typeof(*ses), ses);
struct rad_attr_t *attr;
- int lease_time_set = 0, renew_time_set = 0, has_dhcp = 0;
+ int lease_time_set = 0, renew_time_set = 0, rebind_time_set = 0, has_dhcp = 0;
in_addr_t server_id = 0;
if (ev->ses->ctrl->type != CTRL_TYPE_IPOE)
@@ -2306,6 +2322,10 @@ static void ev_radius_access_accept(struct ev_radius_t *ev)
ses->renew_time = attr->val.integer;
renew_time_set = 1;
break;
+ case DHCP_Rebinding_Time:
+ ses->rebind_time = attr->val.integer;
+ rebind_time_set = 1;
+ break;
case DHCP_DHCP_Server_Identifier:
server_id = attr->val.ipaddr;
break;
@@ -2336,9 +2356,12 @@ static void ev_radius_access_accept(struct ev_radius_t *ev)
} else if (attr->attr->id == conf_attr_dhcp_lease_time) {
ses->lease_time = attr->val.integer;
lease_time_set = 1;
- } else if (attr->attr->id == conf_attr_dhcp_renew_time) {
+ } else if (attr->attr->id == conf_attr_dhcp_renew_time) {
ses->renew_time = attr->val.integer;
renew_time_set = 1;
+ } else if (attr->attr->id == conf_attr_dhcp_rebind_time) {
+ ses->rebind_time = attr->val.integer;
+ rebind_time_set = 1;
} else if (attr->attr->id == conf_attr_l4_redirect_table)
ses->l4_redirect_table = attr->val.integer;
else if (attr->attr->id == conf_attr_l4_redirect_ipset) {
@@ -2348,10 +2371,23 @@ static void ev_radius_access_accept(struct ev_radius_t *ev)
}
if (lease_time_set && !renew_time_set)
- ses->renew_time = ses->lease_time / 2;
+ ses->renew_time = ses->lease_time/2;
else if (renew_time_set && ses->renew_time > ses->lease_time) {
log_ppp_warn("ipoe: overriding renew time\n");
- ses->renew_time = ses->lease_time / 2;
+ ses->renew_time = ses->lease_time/2;
+ }
+
+ if (lease_time_set && !rebind_time_set)
+ ses->rebind_time = ses->lease_time/2 + ses->lease_time/4 + ses->lease_time/8;
+ else if (rebind_time_set && ses->rebind_time > ses->lease_time) {
+ log_ppp_warn("ipoe: overriding rebind time\n");
+ ses->rebind_time = ses->lease_time/2 + ses->lease_time/4 + ses->lease_time/8;
+ }
+
+ if (ses->renew_time && ses->rebind_time && ses->renew_time > ses->rebind_time) {
+ if (renew_time_set)
+ log_ppp_warn("ipoe: overriding renew time\n");
+ ses->renew_time = ses->rebind_time*4/7;
}
if (!ses->siaddr)
@@ -2366,7 +2402,7 @@ static void ev_radius_coa(struct ev_radius_t *ev)
struct ipoe_session *ses = container_of(ev->ses, typeof(*ses), ses);
struct rad_attr_t *attr;
int l4_redirect = -1;
- int lease_time_set = 0, renew_time_set = 0;
+ int lease_time_set = 0, renew_time_set = 0, rebind_time_set = 0;
char *ipset = NULL;
if (ev->ses->ctrl->type != CTRL_TYPE_IPOE)
@@ -2394,6 +2430,9 @@ static void ev_radius_coa(struct ev_radius_t *ev)
} else if (attr->attr->id == conf_attr_dhcp_renew_time) {
ses->renew_time = attr->val.integer;
renew_time_set = 1;
+ } else if (attr->attr->id == conf_attr_dhcp_rebind_time) {
+ ses->rebind_time = attr->val.integer;
+ rebind_time_set = 1;
} else if (attr->attr->id == conf_attr_l4_redirect_table)
ses->l4_redirect_table = attr->val.integer;
else if (attr->attr->id == conf_attr_l4_redirect_ipset) {
@@ -2405,10 +2444,23 @@ static void ev_radius_coa(struct ev_radius_t *ev)
}
if (lease_time_set && !renew_time_set)
- ses->renew_time = ses->lease_time / 2;
+ ses->renew_time = ses->lease_time/2;
else if (renew_time_set && ses->renew_time > ses->lease_time) {
log_ppp_warn("ipoe: overriding renew time\n");
- ses->renew_time = ses->lease_time / 2;
+ ses->renew_time = ses->lease_time/2;
+ }
+
+ if (lease_time_set && !rebind_time_set)
+ ses->rebind_time = ses->lease_time/2 + ses->lease_time/4 + ses->lease_time/8;
+ else if (rebind_time_set && ses->rebind_time > ses->lease_time) {
+ log_ppp_warn("ipoe: overriding rebind time\n");
+ ses->rebind_time = ses->lease_time/2 + ses->lease_time/4 + ses->lease_time/8;
+ }
+
+ if (ses->renew_time && ses->rebind_time && ses->renew_time > ses->rebind_time) {
+ if (renew_time_set)
+ log_ppp_warn("ipoe: overriding renew time\n");
+ ses->renew_time = ses->rebind_time*4/7;
}
if (l4_redirect >= 0 && ev->ses->state == AP_STATE_ACTIVE) {
@@ -3401,6 +3453,7 @@ static void load_radius_attrs(void)
parse_conf_rad_attr("attr-dhcp-mask", &conf_attr_dhcp_mask);
parse_conf_rad_attr("attr-dhcp-lease-time", &conf_attr_dhcp_lease_time);
parse_conf_rad_attr("attr-dhcp-renew-time", &conf_attr_dhcp_renew_time);
+ parse_conf_rad_attr("attr-dhcp-rebind-time", &conf_attr_dhcp_rebind_time);
parse_conf_rad_attr("attr-l4-redirect", &conf_attr_l4_redirect);
parse_conf_rad_attr("attr-l4-redirect-table", &conf_attr_l4_redirect_table);
parse_conf_rad_attr("attr-l4-redirect-ipset", &conf_attr_l4_redirect_ipset);
@@ -3765,19 +3818,28 @@ static void load_config(void)
if (opt)
conf_lease_time = atoi(opt);
else
- conf_lease_time = 600;
+ conf_lease_time = LEASE_TIME;
opt = conf_get_opt("ipoe", "renew-time");
if (opt)
conf_renew_time = atoi(opt);
- else
+ if (!opt || conf_renew_time > conf_lease_time)
conf_renew_time = conf_lease_time/2;
+ opt = conf_get_opt("ipoe", "rebind-time");
+ if (opt)
+ conf_rebind_time = atoi(opt);
+ if (!opt || conf_rebind_time > conf_lease_time)
+ conf_rebind_time = conf_lease_time/2 + conf_lease_time/4 + conf_lease_time/8;
+
+ if (conf_renew_time && conf_rebind_time && conf_renew_time > conf_rebind_time)
+ conf_renew_time = conf_rebind_time*4/7;
+
opt = conf_get_opt("ipoe", "max-lease-time");
if (opt)
conf_lease_timeout = atoi(opt);
else
- conf_lease_timeout = conf_lease_time;
+ conf_lease_timeout = conf_lease_time + conf_lease_time/10;
opt = conf_get_opt("ipoe", "unit-cache");
if (opt)
diff --git a/accel-pppd/ctrl/ipoe/ipoe.h b/accel-pppd/ctrl/ipoe/ipoe.h
index 0be99ea..7c585a2 100644
--- a/accel-pppd/ctrl/ipoe/ipoe.h
+++ b/accel-pppd/ctrl/ipoe/ipoe.h
@@ -97,6 +97,7 @@ struct ipoe_session {
int mask;
int lease_time;
int renew_time;
+ int rebind_time;
uint8_t *data;
struct dhcpv4_packet *dhcpv4_request;
struct dhcpv4_packet *dhcpv4_relay_reply;