提交 0614a5ed 编写于 作者: K Kozlov Dmitry

ipoe: add ipset support for l4 redirect

上级 b4962f81
......@@ -6,7 +6,7 @@ project(accel-ppp C)
include(cmake/cpack.cmake)
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -fvisibility=hidden -fno-strict-aliasing -D_GNU_SOURCE -fPIC")
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -fvisibility=hidden -fno-strict-aliasing -D_GNU_SOURCE -fPIC -rdynamic")
IF (NOT DEFINED LIB_SUFFIX)
EXECUTE_PROCESS(
......@@ -34,6 +34,7 @@ ELSE (EXISTS ${CMAKE_HOME_DIRECTORY}/.git AND NOT DEFINED IGNORE_GIT)
ENDIF (EXISTS ${CMAKE_HOME_DIRECTORY}/.git AND NOT DEFINED IGNORE_GIT)
ADD_DEFINITIONS(-DACCEL_PPP_VERSION="${ACCEL_PPP_VERSION}")
INCLUDE_DIRECTORIES(${CMAKE_CURRENT_BINARY_DIR})
if (NOT BUILD_DRIVER_ONLY)
if (MEMDEBUG)
......@@ -70,3 +71,5 @@ if (BUILD_IPOE_DRIVER)
add_subdirectory(drivers/ipoe)
endif (BUILD_IPOE_DRIVER)
CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/config.h.in ${CMAKE_CURRENT_BINARY_DIR}/config.h)
......@@ -45,6 +45,9 @@ IF (SHAPER)
ADD_SUBDIRECTORY(shaper)
ENDIF (SHAPER)
INCLUDE(CheckIncludeFile)
CHECK_INCLUDE_FILE("linux/netfilter/ipset/ip_set.h" HAVE_IPSET)
ADD_EXECUTABLE(accel-pppd
session.c
session_backup.c
......@@ -78,6 +81,7 @@ ADD_EXECUTABLE(accel-pppd
libnetlink/libnetlink.c
libnetlink/iputils.c
libnetlink/genl.c
libnetlink/ipset.c
pwdb.c
ipdb.c
......
......@@ -39,7 +39,8 @@ username=ifname
lease-time=600
max-lease-time=3600
#unit-cache=1000
l4-redirect-table=4
#l4-redirect-table=4
#l4-redirect-ipset=l4
#l4-redirect-on-reject=300
shared=0
ifcfg=1
......
......@@ -209,6 +209,9 @@ This should reduce kernel-level interface creation/deletion rate lack.
Specifies number of table. If L4-Redirect radius attribute is received and it's value is not 0 or '0' then accel-ppp will add following rule: ip rule add from client_ip table
.B n
.TP
.BI "l4-redirect-ipset=" name
Specifies name of ipset list. If L4-Redirect radius attribute is received and it's value is not 0 or '0' then accel-ppp will add client's ip to that ipset name.
.TP
.BI "l4-redirect-on-reject=" n
If specified then if radius rejects access 'ip rule add from ip_addr table l4-redirect-table' rule will be created for time
.B n
......
......@@ -29,6 +29,8 @@
#include "ipdb.h"
#include "iputils.h"
#include "ipset.h"
#include "connlimit.h"
#ifdef RADIUS
#include "radius.h"
......@@ -65,6 +67,8 @@ static int conf_attr_l4_redirect;
#endif
static int conf_l4_redirect_table;
static int conf_l4_redirect_on_reject;
static const char *conf_l4_redirect_ipset;
static const char *conf_relay;
#ifdef USE_LUA
......@@ -304,7 +308,12 @@ static void l4_redirect_list_add(in_addr_t addr, int ifindex)
n->timeout = ts.tv_sec + conf_l4_redirect_on_reject;
ipoe_nl_modify(ifindex, addr, 1, NULL, NULL);
iprule_add(addr, conf_l4_redirect_table);
if (conf_l4_redirect_table)
iprule_add(addr, conf_l4_redirect_table);
if (conf_l4_redirect_ipset)
ipset_add(conf_l4_redirect_ipset, addr);
pthread_rwlock_wrlock(&l4_list_lock);
......@@ -345,7 +354,12 @@ static void l4_redirect_list_timer(struct triton_timer_t *t)
if (ts.tv_sec > n->timeout) {
list_del(&n->entry);
pthread_rwlock_unlock(&l4_list_lock);
iprule_del(n->addr, conf_l4_redirect_table);
if (conf_l4_redirect_table)
iprule_del(n->addr, conf_l4_redirect_table);
if (conf_l4_redirect_ipset)
ipset_del(conf_l4_redirect_ipset, n->addr);
if (uc_size < conf_unit_cache && ipoe_nl_modify(n->ifindex, 0, 0, "", NULL)) {
uc = mempool_alloc(uc_pool);
......@@ -372,21 +386,30 @@ static void l4_redirect_list_timer(struct triton_timer_t *t)
static void ipoe_change_l4_redirect(struct ipoe_session *ses, int del)
{
in_addr_t addr;
if (conf_l4_redirect_table <= 0)
return;
if (ses->ses.ipv4)
addr = ses->ses.ipv4->addr;
else
addr = ses->yiaddr;
if (conf_l4_redirect_table) {
if (del) {
iprule_del(addr, conf_l4_redirect_table);
ses->l4_redirect_set = 0;
} else {
iprule_add(addr, conf_l4_redirect_table);
ses->l4_redirect_set = 1;
}
}
if (del) {
iprule_del(addr, conf_l4_redirect_table);
ses->l4_redirect_set = 0;
} else {
iprule_add(addr, conf_l4_redirect_table);
ses->l4_redirect_set = 1;
if (conf_l4_redirect_ipset) {
if (del) {
ipset_del(conf_l4_redirect_ipset, addr);
ses->l4_redirect_set = 0;
} else {
ipset_add(conf_l4_redirect_ipset, addr);
ses->l4_redirect_set = 1;
}
}
}
......@@ -1638,8 +1661,15 @@ static void l4_redirect_ctx_close(struct triton_context_t *ctx)
while (!list_empty(&l4_redirect_list)) {
n = list_entry(l4_redirect_list.next, typeof(*n), entry);
list_del(&n->entry);
iprule_del(n->addr, conf_l4_redirect_table);
if (conf_l4_redirect_table)
iprule_del(n->addr, conf_l4_redirect_table);
if (conf_l4_redirect_ipset)
ipset_del(conf_l4_redirect_ipset, n->addr);
ipoe_nl_delete(n->ifindex);
_free(n);
}
pthread_rwlock_unlock(&l4_list_lock);
......@@ -2279,10 +2309,12 @@ static void load_config(void)
conf_unit_cache = atoi(opt);
opt = conf_get_opt("ipoe", "l4-redirect-table");
if (opt)
if (opt && atoi(opt) > 0)
conf_l4_redirect_table = atoi(opt);
else
conf_l4_redirect_table = 1;
conf_l4_redirect_table = 0;
conf_l4_redirect_ipset = conf_get_opt("ipoe", "l4-redirect-ipset");
opt = conf_get_opt("ipoe", "l4-redirect-on-reject");
if (opt) {
......@@ -2408,6 +2440,9 @@ static void ipoe_init(void)
load_config();
if (conf_l4_redirect_ipset)
ipset_flush(conf_l4_redirect_ipset);
cli_register_simple_cmd2(show_stat_exec, NULL, 2, "show", "stat");
triton_event_register_handler(EV_CONFIG_RELOAD, (triton_event_func)load_config);
......
../libnetlink/ipset.h
\ No newline at end of file
#include "config.h"
#ifdef HAVE_IPSET
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <syslog.h>
#include <fcntl.h>
#include <pthread.h>
#include <net/if_arp.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <string.h>
#include <errno.h>
#include <time.h>
#include <sys/uio.h>
#include <linux/netfilter/nfnetlink.h>
#include <linux/netfilter/ipset/ip_set.h>
#include "triton.h"
#include "log.h"
#include "libnetlink.h"
#include "ipset.h"
#include "memdebug.h"
static int __ipset_cmd(const char *name, in_addr_t addr, int cmd, int flags)
{
struct rtnl_handle rth;
struct req {
struct nlmsghdr n;
struct nfgenmsg nf;
char buf[1024];
} req;
struct rtattr *tail1, *tail2;
uint8_t protocol = IPSET_PROTOCOL;
if (rtnl_open_byproto(&rth, 0, NETLINK_NETFILTER)) {
log_error("ipset: cannot open rtnetlink\n");
return -1;
}
memset(&req, 0, sizeof(req) - 1024);
req.n.nlmsg_len = NLMSG_LENGTH(sizeof(struct nfgenmsg));
req.n.nlmsg_flags = flags;
req.n.nlmsg_type = cmd | (NFNL_SUBSYS_IPSET << 8);
req.nf.nfgen_family = AF_INET;
req.nf.version = NFNETLINK_V0;
req.nf.res_id = 0;
addattr_l(&req.n, 1024, IPSET_ATTR_PROTOCOL, &protocol, 1);
addattr_l(&req.n, 1024, IPSET_ATTR_SETNAME, name, strlen(name) + 1);
tail1 = addattr_nest(&req.n, MAX_MSG, IPSET_ATTR_DATA | NLA_F_NESTED);
tail2 = addattr_nest(&req.n, MAX_MSG, IPSET_ATTR_IP | NLA_F_NESTED);
addattr32(&req.n, 1024, IPSET_ATTR_IPADDR_IPV4 | NLA_F_NET_BYTEORDER, addr);
addattr_nest_end(&req.n, tail2);
addattr_nest_end(&req.n, tail1);
if (rtnl_talk(&rth, &req.n, 0, 0, NULL, NULL, NULL, 0) < 0)
goto out_err;
rtnl_close(&rth);
return 0;
out_err:
rtnl_close(&rth);
return -1;
}
int __export ipset_add(const char *name, in_addr_t addr)
{
return __ipset_cmd(name, addr, IPSET_CMD_ADD, NLM_F_REQUEST | NLM_F_ACK | NLM_F_EXCL);
}
int __export ipset_del(const char *name, in_addr_t addr)
{
return __ipset_cmd(name, addr, IPSET_CMD_DEL, NLM_F_REQUEST | NLM_F_ACK);
}
int __export ipset_flush(const char *name)
{
struct rtnl_handle rth;
struct req {
struct nlmsghdr n;
struct nfgenmsg nf;
char buf[1024];
} req;
uint8_t protocol = IPSET_PROTOCOL;
if (rtnl_open_byproto(&rth, 0, NETLINK_NETFILTER)) {
log_error("ipset: cannot open rtnetlink\n");
return -1;
}
memset(&req, 0, sizeof(req) - 1024);
req.n.nlmsg_len = NLMSG_LENGTH(sizeof(struct nfgenmsg));
req.n.nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK;
req.n.nlmsg_type = IPSET_CMD_FLUSH | (NFNL_SUBSYS_IPSET << 8);
req.nf.nfgen_family = AF_INET;
req.nf.version = NFNETLINK_V0;
req.nf.res_id = 0;
addattr_l(&req.n, 1024, IPSET_ATTR_PROTOCOL, &protocol, 1);
addattr_l(&req.n, 1024, IPSET_ATTR_SETNAME, name, strlen(name) + 1);
if (rtnl_talk(&rth, &req.n, 0, 0, NULL, NULL, NULL, 0) < 0)
goto out_err;
rtnl_close(&rth);
return 0;
out_err:
rtnl_close(&rth);
return -1;
}
#else
#include <netinet/in.h>
#include "triton.h"
int __export ipset_add(const char *name, in_addr_t addr)
{
return -1;
}
int __export ipset_del(const char *name, in_addr_t addr)
{
return -1;
}
int __export ipset_flush(const char *name)
{
return -1;
}
#endif
#ifndef __IPSET_H
#define __IPSET_H
int ipset_add(const char *name, in_addr_t addr);
int ipset_del(const char *name, in_addr_t addr);
int ipset_flush(const char *name);
#endif
//#cmakedefine ACCEL_PPP_VERSION "${ACCEL_PPP_VERSION}"
//#cmakedefine RADIUS
#cmakedefine HAVE_IPSET
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册