summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDmitry Kozlov <xeb@mail.ru>2016-03-18 16:49:14 +0300
committerDmitry Kozlov <xeb@mail.ru>2016-03-18 16:49:18 +0300
commit550d631e9aad3ffac3ab4c2953021182ab2eb0c3 (patch)
treecfd9cafee968b65c4308bcf146b3fede166300aa
parent546e33e6f4d03f81341c0da91eac9fef8aa94f29 (diff)
downloadaccel-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.conf1
-rw-r--r--accel-pppd/accel-ppp.conf.56
-rw-r--r--accel-pppd/ctrl/ipoe/ipoe.c86
-rw-r--r--accel-pppd/ctrl/ipoe/ipoe.h1
-rw-r--r--accel-pppd/radius/serv.c2
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);