diff options
author | Dmitry Kozlov <xeb@mail.ru> | 2016-03-18 16:49:14 +0300 |
---|---|---|
committer | Dmitry Kozlov <xeb@mail.ru> | 2016-03-18 16:49:18 +0300 |
commit | 550d631e9aad3ffac3ab4c2953021182ab2eb0c3 (patch) | |
tree | cfd9cafee968b65c4308bcf146b3fede166300aa | |
parent | 546e33e6f4d03f81341c0da91eac9fef8aa94f29 (diff) | |
download | accel-ppp-550d631e9aad3ffac3ab4c2953021182ab2eb0c3.tar.gz accel-ppp-550d631e9aad3ffac3ab4c2953021182ab2eb0c3.zip |
ipoe: implemented new option "start=auto"
If start=auto is specified then accel-pppd automatically starts session with username = interface name on shared=0 interfaces.
Use it with conjuction vlan_mon. So any packet may start session.
-rw-r--r-- | accel-pppd/accel-ppp.conf | 1 | ||||
-rw-r--r-- | accel-pppd/accel-ppp.conf.5 | 6 | ||||
-rw-r--r-- | accel-pppd/ctrl/ipoe/ipoe.c | 86 | ||||
-rw-r--r-- | accel-pppd/ctrl/ipoe/ipoe.h | 1 | ||||
-rw-r--r-- | accel-pppd/radius/serv.c | 2 |
5 files changed, 79 insertions, 17 deletions
diff --git a/accel-pppd/accel-ppp.conf b/accel-pppd/accel-ppp.conf index 6b6352e..2b11613 100644 --- a/accel-pppd/accel-ppp.conf +++ b/accel-pppd/accel-ppp.conf @@ -117,6 +117,7 @@ shared=0 ifcfg=1 mode=L2 start=dhcpv4 +#start=UP #ip-unnumbered=1 #proxy-arp=0 #nat=0 diff --git a/accel-pppd/accel-ppp.conf.5 b/accel-pppd/accel-ppp.conf.5 index 648fd24..eefbe6b 100644 --- a/accel-pppd/accel-ppp.conf.5 +++ b/accel-pppd/accel-ppp.conf.5 @@ -272,7 +272,7 @@ Specifies default value for per-interface .B mode parameter. .TP -.BI "start=" dhcpv4|up +.BI "start=" dhcpv4|up|auto Specifies default value for per-interface .B start parameter. @@ -292,7 +292,7 @@ Specifies default value for per-interface .B proxy-arp parameter. .TP -.BI "interface=" [re:]name[,mode=L2|L3][,shared=0|1][,start=dhcpv4|up] +.BI "interface=" [re:]name[,mode=L2|L3][,shared=0|1][,start=dhcpv4|up|auto] .BI "" [,range=x.x.x.x/mask][,ifcfg=0|1] .BI "" [,relay=x.x.x.x] .BI "" [,giaddr=x.x.x.x] @@ -328,6 +328,8 @@ The .B start parameter specifies which way session starts (up - unclassified packet). .br +auto - means automatically start session with username = interface name. Use it with conjuction vlan_mon. +.br The .B range parameter specifies local range of ip address to give to dhcp clients. First IP in range is router IP. diff --git a/accel-pppd/ctrl/ipoe/ipoe.c b/accel-pppd/ctrl/ipoe/ipoe.c index 06ca52f..7fe3967 100644 --- a/accel-pppd/ctrl/ipoe/ipoe.c +++ b/accel-pppd/ctrl/ipoe/ipoe.c @@ -100,6 +100,7 @@ enum {SID_MAC, SID_IP}; static int conf_dhcpv4 = 1; static int conf_up; +static int conf_auto; static int conf_mode; static int conf_shared = 1; static int conf_ifcfg = 1; @@ -197,6 +198,7 @@ static int get_offer_delay(); static void __ipoe_session_start(struct ipoe_session *ses); static int ipoe_rad_send_auth_request(struct rad_plugin_t *rad, struct rad_packet_t *pack); static int ipoe_rad_send_acct_request(struct rad_plugin_t *rad, struct rad_packet_t *pack); +static void ipoe_session_create_auto(struct ipoe_serv *serv); static void ipoe_ctx_switch(struct triton_context_t *ctx, void *arg) { @@ -689,15 +691,21 @@ static void find_gw_addr(struct ipoe_session *ses) static void __ipoe_session_start(struct ipoe_session *ses) { - if (!ses->yiaddr) { + if (!ses->yiaddr && ses->serv->dhcpv4) { dhcpv4_get_ip(ses->serv->dhcpv4, &ses->yiaddr, &ses->router, &ses->mask); if (ses->yiaddr) ses->dhcp_addr = 1; } - if (!ses->yiaddr && !ses->serv->opt_nat) + if (!ses->yiaddr && (ses->UP || !ses->serv->opt_nat)) { ses->ses.ipv4 = ipdb_get_ipv4(&ses->ses); + if (ses->UP && !ses->ses.ipv4) { + log_ppp_error("ipoe: no address specified\n"); + ap_session_terminate(&ses->ses, TERM_NAS_REQUEST, 1); + } + } + if (ses->ses.ipv4) { if (!ses->mask) ses->mask = ses->ses.ipv4->mask; @@ -997,10 +1005,10 @@ static void ipoe_session_free(struct ipoe_session *ses) if (ses->dhcpv4_relay_reply) dhcpv4_packet_free(ses->dhcpv4_relay_reply); - if (ses->ctrl.called_station_id) + if (ses->ctrl.called_station_id && ses->ctrl.called_station_id != ses->ses.ifname) _free(ses->ctrl.called_station_id); - if (ses->ctrl.calling_station_id) + if (ses->ctrl.calling_station_id && ses->ctrl.calling_station_id != ses->ses.ifname) _free(ses->ctrl.calling_station_id); if (ses->l4_redirect_ipset) @@ -1782,8 +1790,6 @@ static struct ipoe_session *ipoe_session_create_up(struct ipoe_serv *serv, struc triton_context_register(&ses->ctx, &ses->ses); - triton_context_wakeup(&ses->ctx); - list_add_tail(&ses->entry, &serv->sessions); if (serv->timer.tpd) @@ -1791,9 +1797,45 @@ static struct ipoe_session *ipoe_session_create_up(struct ipoe_serv *serv, struc triton_context_call(&ses->ctx, (triton_event_func)ipoe_session_start, ses); + triton_context_wakeup(&ses->ctx); + return ses; } +static void ipoe_session_create_auto(struct ipoe_serv *serv) +{ + struct ipoe_session *ses; + + if (ap_shutdown) + return; + + ses = ipoe_session_alloc(); + if (!ses) + return; + + ses->serv = serv; + ses->UP = 1; + + strncpy(ses->ses.ifname, serv->ifname, AP_IFNAME_LEN); + ses->ctrl.called_station_id = ses->ses.ifname; + ses->ctrl.calling_station_id = ses->ses.ifname; + ses->username = _strdup(serv->ifname); + ses->ses.chan_name = ses->ctrl.calling_station_id; + + if (conf_ip_pool) + ses->ses.ipv4_pool_name = _strdup(conf_ip_pool); + + ses->ctrl.dont_ifcfg = 1; + + triton_context_register(&ses->ctx, &ses->ses); + + list_add_tail(&ses->entry, &serv->sessions); + + triton_context_call(&ses->ctx, (triton_event_func)ipoe_session_start, ses); + + triton_context_wakeup(&ses->ctx); +} + struct ipoe_session *ipoe_session_alloc(void) { struct ipoe_session *ses; @@ -2020,7 +2062,7 @@ static void ipoe_serv_release(struct ipoe_serv *serv) } pthread_mutex_unlock(&serv->lock); - if (serv->vid && !serv->need_close && !ap_shutdown) { + if (serv->vid && !serv->need_close && !ap_shutdown && !serv->opt_auto) { if (serv->timer.tpd) triton_timer_mod(&serv->timer, 0); else @@ -2064,7 +2106,8 @@ static void ipoe_serv_release(struct ipoe_serv *serv) if (serv->timer.tpd) triton_timer_del(&serv->timer); - ipoe_nl_del_interface(serv->ifindex); + if (!serv->opt_auto) + ipoe_nl_del_interface(serv->ifindex); if (serv->vid) { log_info2("ipoe: remove vlan %s\n", serv->ifname); @@ -2350,6 +2393,7 @@ static void add_interface(const char *ifname, int ifindex, const char *opt, int int opt_nat = conf_nat; int opt_username = conf_username; int opt_ipv6 = conf_ipv6; + int opt_auto = conf_auto; #ifdef USE_LUA char *opt_lua_username_func = NULL; #endif @@ -2388,6 +2432,8 @@ static void add_interface(const char *ifname, int ifindex, const char *opt, int opt_up = 1; else if (!strcmp(ptr1, "dhcpv4")) opt_dhcpv4 = 1; + else if (!strcmp(ptr1, "auto")) + opt_auto = 1; else goto parse_err; } else if (strcmp(str, "shared") == 0) { @@ -2499,7 +2545,10 @@ static void add_interface(const char *ifname, int ifindex, const char *opt, int } else if (!serv->arp && conf_arp) serv->arp = arpd_start(serv); + opt_auto &= !opt_shared; + serv->opt_up = opt_up; + serv->opt_auto = opt_auto; serv->opt_mode = opt_mode; serv->opt_ifcfg = opt_ifcfg; serv->opt_nat = opt_nat; @@ -2527,10 +2576,12 @@ static void add_interface(const char *ifname, int ifindex, const char *opt, int } pthread_mutex_unlock(&serv_lock); - if (opt_up) - ipoe_nl_add_interface(ifindex, opt_mode); - else - ipoe_nl_add_interface(ifindex, 0); + if (!opt_auto) { + if (opt_up) + ipoe_nl_add_interface(ifindex, opt_mode); + else + ipoe_nl_add_interface(ifindex, 0); + } opt = strchr(opt, ','); if (opt) @@ -2570,6 +2621,7 @@ static void add_interface(const char *ifname, int ifindex, const char *opt, int serv->opt_shared = opt_shared; serv->opt_dhcpv4 = opt_dhcpv4; serv->opt_up = opt_up; + serv->opt_auto = opt_auto; serv->opt_mode = opt_mode; serv->opt_ifcfg = opt_ifcfg; serv->opt_nat = opt_nat; @@ -2609,12 +2661,15 @@ static void add_interface(const char *ifname, int ifindex, const char *opt, int triton_timer_add(&serv->ctx, &serv->timer, 0); } - triton_context_wakeup(&serv->ctx); + if (serv->opt_auto && !serv->opt_shared) + triton_context_call(&serv->ctx, (triton_event_func)ipoe_session_create_auto, serv); pthread_mutex_lock(&serv_lock); list_add_tail(&serv->entry, &serv_list); pthread_mutex_unlock(&serv_lock); + triton_context_wakeup(&serv->ctx); + if (str0) _free(str0); @@ -2730,7 +2785,8 @@ static void load_interfaces(struct conf_sect_t *sect) list_for_each_entry(serv, &serv_list, entry) { if (!serv->active) { - ipoe_nl_del_interface(serv->ifindex); + if (!serv->opt_auto) + ipoe_nl_del_interface(serv->ifindex); ipoe_drop_sessions(serv, NULL); serv->need_close = 1; triton_context_call(&serv->ctx, (triton_event_func)ipoe_serv_release, serv); @@ -3287,6 +3343,8 @@ static void load_config(void) conf_dhcpv4 = 1; else if (!strcmp(opt1->val, "up")) conf_up = 1; + else if (!strcmp(opt1->val, "auto")) + conf_auto = 1; } if (!conf_dhcpv4 && !conf_up) diff --git a/accel-pppd/ctrl/ipoe/ipoe.h b/accel-pppd/ctrl/ipoe/ipoe.h index 825ffca..0cf14ea 100644 --- a/accel-pppd/ctrl/ipoe/ipoe.h +++ b/accel-pppd/ctrl/ipoe/ipoe.h @@ -46,6 +46,7 @@ struct ipoe_serv { int opt_shared:1; int opt_dhcpv4:1; int opt_up:1; + int opt_auto:1; int opt_ifcfg:1; int opt_nat:1; int opt_ipv6:1; diff --git a/accel-pppd/radius/serv.c b/accel-pppd/radius/serv.c index c66cc28..4313a38 100644 --- a/accel-pppd/radius/serv.c +++ b/accel-pppd/radius/serv.c @@ -177,7 +177,7 @@ int rad_server_req_enter(struct rad_req_t *req) { struct timespec ts; - if (req->serv->need_free || req->serv->starting) + if (req->serv->need_free) return -1; clock_gettime(CLOCK_MONOTONIC, &ts); |