summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--accel-pppd/ctrl/ipoe/ipoe.c54
-rw-r--r--accel-pppd/ctrl/ipoe/ipoe_netlink.c8
-rw-r--r--accel-pppd/ifcfg.c3
-rw-r--r--drivers/ipoe/ipoe.c7
4 files changed, 57 insertions, 15 deletions
diff --git a/accel-pppd/ctrl/ipoe/ipoe.c b/accel-pppd/ctrl/ipoe/ipoe.c
index a24ce94..bfe65fb 100644
--- a/accel-pppd/ctrl/ipoe/ipoe.c
+++ b/accel-pppd/ctrl/ipoe/ipoe.c
@@ -46,6 +46,7 @@ static int conf_mode = 0;
static int conf_shared = 1;
//static int conf_dhcpv6;
static int conf_username;
+static int conf_unit_cache;
#ifdef USE_LUA
static const char *conf_lua_username_func;
@@ -71,6 +72,17 @@ struct iplink_arg
const char *opt;
};
+struct unit_cache
+{
+ struct list_head entry;
+ int ifindex;
+};
+
+static pthread_mutex_t uc_lock = PTHREAD_MUTEX_INITIALIZER;
+static LIST_HEAD(uc_list);
+static int uc_size;
+static mempool_t uc_pool;
+
static void ipoe_session_finished(struct ap_session *s);
static void ipoe_drop_sessions(struct ipoe_serv *serv, struct ipoe_session *skip);
static void ipoe_serv_close(struct triton_context_t *ctx);
@@ -163,15 +175,27 @@ static void ipoe_session_start(struct ipoe_session *ses)
int r;
char *passwd;
struct ifreq ifr;
+ struct unit_cache *uc;
if (ses->serv->opt_shared == 0)
strncpy(ses->ses.ifname, ses->serv->ifname, AP_IFNAME_LEN);
else if (ses->ifindex == -1) {
- ses->ifindex = ipoe_nl_create(0, 0, ses->dhcpv4_request ? ses->serv->ifname : NULL, ses->hwaddr);
- if (ses->ifindex == -1) {
- log_ppp_error("ipoe: failed to create interface\n");
- ipoe_session_finished(&ses->ses);
- return;
+ pthread_mutex_lock(&uc_lock);
+ if (!list_empty(&uc_list)) {
+ uc = list_entry(uc_list.next, typeof(*uc), entry);
+ ses->ifindex = uc->ifindex;
+ list_del(&uc->entry);
+ --uc_size;
+ pthread_mutex_unlock(&uc_lock);
+ mempool_free(uc);
+ } else {
+ pthread_mutex_unlock(&uc_lock);
+ ses->ifindex = ipoe_nl_create(0, 0, ses->serv->opt_mode == MODE_L2 ? ses->serv->ifname : NULL, ses->hwaddr);
+ if (ses->ifindex == -1) {
+ log_ppp_error("ipoe: failed to create interface\n");
+ ipoe_session_finished(&ses->ses);
+ return;
+ }
}
memset(&ifr, 0, sizeof(ifr));
@@ -296,6 +320,8 @@ static void ipoe_session_started(struct ap_session *s)
static void ipoe_session_free(struct ipoe_session *ses)
{
+ struct unit_cache *uc;
+
if (ses->timer.tpd)
triton_timer_del(&ses->timer);
@@ -313,8 +339,17 @@ static void ipoe_session_free(struct ipoe_session *ses)
if (ses->data)
_free(ses->data);
- if (ses->ifindex != -1)
- ipoe_nl_delete(ses->ifindex);
+ if (ses->ifindex != -1) {
+ if (uc_size < conf_unit_cache && ipoe_nl_modify(ses->ifindex, 0, 0, "", NULL)) {
+ uc = mempool_alloc(uc_pool);
+ uc->ifindex = ses->ifindex;
+ pthread_mutex_lock(&uc_lock);
+ list_add_tail(&uc->entry, &uc_list);
+ ++uc_size;
+ pthread_mutex_unlock(&uc_lock);
+ } else
+ ipoe_nl_delete(ses->ifindex);
+ }
mempool_free(ses);
}
@@ -1047,6 +1082,10 @@ static void load_config(void)
if (opt)
conf_lease_timeout = atoi(opt);
+ opt = conf_get_opt("ipoe", "unit-cache");
+ if (opt)
+ conf_unit_cache = atoi(opt);
+
opt = conf_get_opt("ipoe", "shared");
if (opt)
conf_shared = atoi(opt);
@@ -1086,6 +1125,7 @@ static void load_config(void)
static void ipoe_init(void)
{
ses_pool = mempool_create(sizeof(struct ipoe_session));
+ uc_pool = mempool_create(sizeof(struct unit_cache));
load_config();
diff --git a/accel-pppd/ctrl/ipoe/ipoe_netlink.c b/accel-pppd/ctrl/ipoe/ipoe_netlink.c
index 74db52d..b92ec92 100644
--- a/accel-pppd/ctrl/ipoe/ipoe_netlink.c
+++ b/accel-pppd/ctrl/ipoe/ipoe_netlink.c
@@ -194,12 +194,8 @@ int ipoe_nl_modify(int ifindex, uint32_t peer_addr, uint32_t addr, const char *i
ghdr->cmd = IPOE_CMD_MODIFY;
addattr32(nlh, 1024, IPOE_ATTR_IFINDEX, ifindex);
-
- if (peer_addr)
- addattr32(nlh, 1024, IPOE_ATTR_PEER_ADDR, peer_addr);
-
- if (addr)
- addattr32(nlh, 1024, IPOE_ATTR_ADDR, addr);
+ addattr32(nlh, 1024, IPOE_ATTR_PEER_ADDR, peer_addr);
+ addattr32(nlh, 1024, IPOE_ATTR_ADDR, addr);
if (hwaddr) {
memcpy(u.hwaddr, hwaddr, 6);
diff --git a/accel-pppd/ifcfg.c b/accel-pppd/ifcfg.c
index 7399a60..0b4927b 100644
--- a/accel-pppd/ifcfg.c
+++ b/accel-pppd/ifcfg.c
@@ -185,8 +185,7 @@ void __export ap_session_ifdown(struct ap_session *ses)
memset(&ifr, 0, sizeof(ifr));
strcpy(ifr.ifr_name, ses->ifname);
- if (ses->ctrl->type != CTRL_TYPE_IPOE)
- ioctl(sock_fd, SIOCSIFFLAGS, &ifr);
+ ioctl(sock_fd, SIOCSIFFLAGS, &ifr);
if (ses->ipv4) {
memset(&addr, 0, sizeof(addr));
diff --git a/drivers/ipoe/ipoe.c b/drivers/ipoe/ipoe.c
index d5f52b3..18f0f70 100644
--- a/drivers/ipoe/ipoe.c
+++ b/drivers/ipoe/ipoe.c
@@ -1202,6 +1202,13 @@ static int ipoe_nl_cmd_modify(struct sk_buff *skb, struct genl_info *info)
old_dev = ses->link_dev;
ses->link_dev = link_dev;
+
+ if (link_dev) {
+ ses->dev->features = link_dev->features;
+ memcpy(dev->dev_addr, link_dev->dev_addr, ETH_ALEN);
+ memcpy(dev->broadcast, link_dev->broadcast, ETH_ALEN);
+ }
+
if (old_dev)
dev_put(old_dev);
}