diff options
Diffstat (limited to 'accel-pppd/ctrl')
-rw-r--r-- | accel-pppd/ctrl/ipoe/dhcpv4.c | 21 | ||||
-rw-r--r-- | accel-pppd/ctrl/ipoe/ipoe.c | 87 | ||||
-rw-r--r-- | accel-pppd/ctrl/ipoe/ipoe.h | 1 | ||||
-rw-r--r-- | accel-pppd/ctrl/ipoe/lua.c | 48 |
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"); |