summaryrefslogtreecommitdiff
path: root/accel-pppd/ctrl
diff options
context:
space:
mode:
Diffstat (limited to 'accel-pppd/ctrl')
-rw-r--r--accel-pppd/ctrl/ipoe/dhcpv4.c21
-rw-r--r--accel-pppd/ctrl/ipoe/ipoe.c87
-rw-r--r--accel-pppd/ctrl/ipoe/ipoe.h1
-rw-r--r--accel-pppd/ctrl/ipoe/lua.c48
4 files changed, 139 insertions, 18 deletions
diff --git a/accel-pppd/ctrl/ipoe/dhcpv4.c b/accel-pppd/ctrl/ipoe/dhcpv4.c
index 94d39175..6d0d1c9c 100644
--- a/accel-pppd/ctrl/ipoe/dhcpv4.c
+++ b/accel-pppd/ctrl/ipoe/dhcpv4.c
@@ -692,6 +692,17 @@ int dhcpv4_packet_add_opt(struct dhcpv4_packet *pack, int type, const void *data
return 0;
}
+static inline int dhcpv4_packet_add_opt_u8(struct dhcpv4_packet *pack, int type, uint8_t val)
+{
+ return dhcpv4_packet_add_opt(pack, type, &val, 1);
+}
+
+static inline int dhcpv4_packet_add_opt_u32(struct dhcpv4_packet *pack, int type, uint32_t val)
+{
+ val = htonl(val);
+ 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)
{
struct dhcpv4_packet *pack;
@@ -720,19 +731,17 @@ int dhcpv4_send_reply(int msg_type, struct dhcpv4_serv *serv, struct dhcpv4_pack
pack->hdr->siaddr = 0;
pack->hdr->giaddr = req->hdr->giaddr;
- if (dhcpv4_packet_add_opt(pack, 53, &msg_type, 1))
+ if (dhcpv4_packet_add_opt_u8(pack, 53, msg_type))
goto out_err;
if (dhcpv4_packet_add_opt(pack, 54, &siaddr, 4))
goto out_err;
- val = ntohl(lease_time);
- if (dhcpv4_packet_add_opt(pack, 51, &val, 4))
+ if (dhcpv4_packet_add_opt_u32(pack, 51, lease_time))
goto out_err;
- val = ntohl(renew_time);
- if (val > 0){
- if (dhcpv4_packet_add_opt(pack, 58, &val, 4))
+ if (renew_time) {
+ if (dhcpv4_packet_add_opt_u32(pack, 58, renew_time))
goto out_err;
}
diff --git a/accel-pppd/ctrl/ipoe/ipoe.c b/accel-pppd/ctrl/ipoe/ipoe.c
index 14bda1f5..05a9ff53 100644
--- a/accel-pppd/ctrl/ipoe/ipoe.c
+++ b/accel-pppd/ctrl/ipoe/ipoe.c
@@ -367,7 +367,7 @@ static char *ipoe_session_get_username(struct ipoe_session *ses)
if (!ses->dhcpv4_request)
return _strdup(ses->ctrl.calling_station_id);
- return _strdup(ses->ses.ifname);
+ return _strdup(ses->serv->ifname);
}
static void l4_redirect_list_add(in_addr_t addr)
@@ -610,8 +610,6 @@ static void ipoe_session_start(struct ipoe_session *ses)
assert(!ses->ses.username);
- strncpy(ses->ses.ifname, ses->serv->ifname, AP_IFNAME_LEN);
-
username = ipoe_session_get_username(ses);
if (!username) {
@@ -958,7 +956,7 @@ static void __ipoe_session_activate(struct ipoe_session *ses)
ses->timer.expire = ipoe_session_timeout;
ses->timer.period = 0;
- ses->timer.expire_tv.tv_sec = conf_lease_timeout ? conf_lease_timeout : ses->lease_time;
+ ses->timer.expire_tv.tv_sec = ses->lease_time;
if (ses->timer.tpd)
triton_timer_mod(&ses->timer, 0);
}
@@ -1202,7 +1200,9 @@ static struct ipoe_session *ipoe_session_create_dhcpv4(struct ipoe_serv *serv, s
ses->serv = serv;
ses->dhcpv4_request = pack;
- strncpy(ses->ses.ifname, serv->ifname, AP_IFNAME_LEN);
+
+ if (!serv->opt_shared)
+ strncpy(ses->ses.ifname, serv->ifname, AP_IFNAME_LEN);
ses->xid = pack->hdr->xid;
memcpy(ses->hwaddr, pack->hdr->chaddr, 6);
@@ -1815,6 +1815,9 @@ static struct ipoe_session *ipoe_session_create_up(struct ipoe_serv *serv, struc
ses->yiaddr = iph->saddr;
ses->UP = 1;
+ if (!serv->opt_shared)
+ strncpy(ses->ses.ifname, serv->ifname, AP_IFNAME_LEN);
+
ses->ctrl.called_station_id = _strdup(serv->ifname);
if (conf_calling_sid == SID_MAC) {
@@ -1920,6 +1923,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;
if (ev->ses->ctrl->type != CTRL_TYPE_IPOE)
return;
@@ -1949,17 +1953,26 @@ static void ev_radius_access_accept(struct ev_radius_t *ev)
ses->l4_redirect = 1;
} else if (attr->val.integer != 0)
ses->l4_redirect = 1;
- } else if (attr->attr->id == conf_attr_dhcp_lease_time)
+ } else if (attr->attr->id == conf_attr_dhcp_lease_time) {
ses->lease_time = attr->val.integer;
- else if (attr->attr->id == conf_attr_dhcp_renew_time)
+ lease_time_set = 1;
+ } else if (attr->attr->id == conf_attr_dhcp_renew_time) {
ses->renew_time = attr->val.integer;
- else if (attr->attr->id == conf_attr_l4_redirect_table)
+ renew_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) {
if (attr->attr->type == ATTR_TYPE_STRING)
ses->l4_redirect_ipset = _strdup(attr->val.string);
}
}
+
+ if (lease_time_set && !renew_time_set)
+ 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;
+ }
}
static void ev_radius_coa(struct ev_radius_t *ev)
@@ -1967,6 +1980,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;
+ int lease_time_set = 0, renew_time_set = 0;
if (ev->ses->ctrl->type != CTRL_TYPE_IPOE)
return;
@@ -1982,11 +1996,13 @@ static void ev_radius_coa(struct ev_radius_t *ev)
} else if (strcmp(attr->attr->name, "Framed-IP-Address") == 0) {
if (ses->ses.ipv4 && ses->ses.ipv4->peer_addr != attr->val.ipaddr)
ipoe_change_addr(ses, attr->val.ipaddr);
- } else if (attr->attr->id == conf_attr_dhcp_lease_time)
+ } else if (attr->attr->id == conf_attr_dhcp_lease_time) {
ses->lease_time = attr->val.integer;
- else if (attr->attr->id == conf_attr_dhcp_renew_time)
+ lease_time_set = 1;
+ } else if (attr->attr->id == conf_attr_dhcp_renew_time) {
ses->renew_time = attr->val.integer;
- else if (attr->attr->id == conf_attr_l4_redirect_table)
+ renew_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) {
if (attr->attr->type == ATTR_TYPE_STRING) {
@@ -1998,6 +2014,13 @@ static void ev_radius_coa(struct ev_radius_t *ev)
}
}
+ if (lease_time_set && !renew_time_set)
+ 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;
+ }
+
//if (l4_redirect && !ses->l4_redirect) || (!l4_redirect && ses->l4_redirect))
if (l4_redirect != ses->l4_redirect && ev->ses->state == AP_STATE_ACTIVE)
ipoe_change_l4_redirect(ses, l4_redirect);
@@ -2158,6 +2181,19 @@ static int show_stat_exec(const char *cmd, char * const *fields, int fields_cnt,
return CLI_CMD_OK;
}
+static void print_session_type(struct ap_session *s, char *buf)
+{
+ if (s->ctrl->type == CTRL_TYPE_IPOE) {
+ struct ipoe_session *ses = container_of(s, typeof(*ses), ses);
+
+ if (ses->UP)
+ strcpy(buf, "up");
+ else
+ strcpy(buf, "dhcp");
+ } else
+ *buf = 0;
+}
+
void __export ipoe_get_stat(unsigned int **starting, unsigned int **active)
{
*starting = &stat_starting;
@@ -2245,7 +2281,13 @@ void ipoe_vlan_mon_notify(int ifindex, int vid)
svid = iplink_vlan_get_vid(ifindex);
- if (make_vlan_name(conf_vlan_name, ifr.ifr_name, svid, vid, ifname)) {
+#ifdef USE_LUA
+ if (!memcmp(conf_vlan_name, "lua:", 4))
+ r = ipoe_lua_make_vlan_name(conf_vlan_name + 4, parent, svid, cvid, name);
+ else
+#endif
+ r = make_vlan_name(conf_vlan_name, ifr.ifr_name, svid, vid, ifname);
+ if (r) {
log_error("ipoe: vlan-mon: %s.%i: interface name is too long\n", ifr.ifr_name, vid);
return;
}
@@ -2604,6 +2646,7 @@ static void load_interface(const char *opt)
{
const char *ptr;
struct ifreq ifr;
+ struct ipoe_serv *serv;
for (ptr = opt; *ptr && *ptr != ','; ptr++);
@@ -2613,6 +2656,16 @@ static void load_interface(const char *opt)
memcpy(ifr.ifr_name, opt, ptr - opt);
ifr.ifr_name[ptr - opt] = 0;
+ list_for_each_entry(serv, &serv_list, entry) {
+ if (serv->active)
+ continue;
+
+ if (!strcmp(serv->ifname, ifr.ifr_name)) {
+ add_interface(serv->ifname, serv->ifindex, opt, 0, 0);
+ return;
+ }
+ }
+
if (ioctl(sock_fd, SIOCGIFINDEX, &ifr)) {
log_error("ipoe: '%s': ioctl(SIOCGIFINDEX): %s\n", ifr.ifr_name, strerror(errno));
return;
@@ -2639,6 +2692,7 @@ static void load_interface_re(const char *opt)
const char *ptr;
int pcre_offset;
struct iplink_arg arg;
+ struct ipoe_serv *serv;
for (ptr = opt; *ptr && *ptr != ','; ptr++);
@@ -2658,6 +2712,14 @@ static void load_interface_re(const char *opt)
iplink_list((iplink_list_func)__load_interface_re, &arg);
+ list_for_each_entry(serv, &serv_list, entry) {
+ if (serv->active)
+ continue;
+
+ if (pcre_exec(re, NULL, serv->ifname, strlen(serv->ifname), 0, 0, NULL, 0) >= 0)
+ add_interface(serv->ifname, serv->ifindex, opt, 0, 0);
+ }
+
pcre_free(re);
_free(pattern);
}
@@ -3324,6 +3386,7 @@ static void ipoe_init(void)
ipset_flush(conf_l4_redirect_ipset);
cli_register_simple_cmd2(show_stat_exec, NULL, 2, "show", "stat");
+ cli_show_ses_register("ipoe-type", "IPoE session type", print_session_type);
triton_event_register_handler(EV_CONFIG_RELOAD, (triton_event_func)load_config);
diff --git a/accel-pppd/ctrl/ipoe/ipoe.h b/accel-pppd/ctrl/ipoe/ipoe.h
index 224b9e91..cd1993df 100644
--- a/accel-pppd/ctrl/ipoe/ipoe.h
+++ b/accel-pppd/ctrl/ipoe/ipoe.h
@@ -108,6 +108,7 @@ struct ipoe_session_info {
#ifdef USE_LUA
char *ipoe_lua_get_username(struct ipoe_session *, const char *func);
+int ipoe_lua_make_vlan_name(const char *func, const char *parent, int svid, int cvid, char *name);
#endif
struct iphdr;
diff --git a/accel-pppd/ctrl/ipoe/lua.c b/accel-pppd/ctrl/ipoe/lua.c
index 84da9d12..b27b1f26 100644
--- a/accel-pppd/ctrl/ipoe/lua.c
+++ b/accel-pppd/ctrl/ipoe/lua.c
@@ -2,6 +2,7 @@
#include <stdio.h>
#include <string.h>
#include <pthread.h>
+#include <net/if.h>
/* Include the Lua API header files. */
#include <lua.h>
@@ -268,6 +269,53 @@ out:
return r;
}
+int ipoe_lua_make_vlan_name(const char *func, const char *parent, int svid, int cvid, char *name)
+{
+ int r = -1;
+ const char *res;
+
+ if (file_error && serial == __serial)
+ return -1;
+
+ if (L && serial != __serial) {
+ lua_close(L);
+ init_lua();
+ } else if (!L)
+ init_lua();
+
+ if (!L)
+ return -1;
+
+ lua_getglobal(L, func);
+ lua_pushstring(L, parent);
+ lua_pushinteger(L, svid);
+ lua_pushinteger(L, cvid);
+
+ if (lua_pcall(L, 3, 1, 0)) {
+ log_ppp_error("ipoe: lua: %s\n", lua_tostring(L, -1));
+ lua_pop(L, 1);
+ goto out;
+ }
+
+ if (!lua_isstring(L, -1)) {
+ log_ppp_error("ipoe: lua: function '%s' must return a string\n", func);
+ goto out;
+ }
+
+ res = lua_tostring(L, -1);
+
+ if (strlen(res) >= IFNAMSIZ)
+ goto out;
+
+ strcpy(name, res);
+ r = 0;
+
+out:
+ lua_settop(L, 0);
+
+ return r;
+}
+
static void load_config()
{
conf_filename = conf_get_opt("ipoe", "lua-file");