Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add bypass subnets feature to ipoe #3

Open
wants to merge 6 commits into
base: 1.10
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions accel-pppd/accel-ppp.conf.5
Original file line number Diff line number Diff line change
Expand Up @@ -354,6 +354,9 @@ The
.B proxy-arp
parameter specifies whether accel-ppp should reply to arp requests.
.TP
.BI "bypass-net=" x.x.x.x/mask
Specifies networks to which packets will be bypassed and therefore automatically allowed without session creation.
.TP
.BI "local-net=" x.x.x.x/mask
Specifies networks from which packets will be treated as unclassified. You may specify multiple local-net options.
.TP
Expand Down
65 changes: 57 additions & 8 deletions accel-pppd/ctrl/ipoe/ipoe.c
Original file line number Diff line number Diff line change
Expand Up @@ -1250,7 +1250,7 @@ static struct ipoe_session *ipoe_session_create_dhcpv4(struct ipoe_serv *serv, s

ptr = ses->hwaddr;
sprintf(ses->ctrl.calling_station_id, "%02x:%02x:%02x:%02x:%02x:%02x",
ptr[0], ptr[1], ptr[2], ptr[3], ptr[4], ptr[5]);
ptr[0], ptr[1], ptr[2], ptr[3], ptr[4], ptr[5]);

ses->ses.ctrl = &ses->ctrl;
ses->ses.chan_name = ses->ctrl.calling_station_id;
Expand Down Expand Up @@ -1438,7 +1438,7 @@ static void ipoe_serv_disc_timer(struct triton_timer_t *t)
clock_gettime(CLOCK_MONOTONIC, &ts);

while (!list_empty(&serv->disc_list)) {
d = list_entry(serv->disc_list.next, typeof(*d), entry);
d = list_entry(serv->disc_list.next, typeof(*d), entry);

delay = (ts.tv_sec - d->ts.tv_sec) * 1000 + (ts.tv_nsec - d->ts.tv_nsec) / 1000000;
offer_delay = get_offer_delay();
Expand Down Expand Up @@ -2469,7 +2469,7 @@ static void add_interface(const char *ifname, int ifindex, const char *opt, int
if (strcmp(ptr1, "ifname") == 0)
opt_username = USERNAME_IFNAME;
#ifdef USE_LUA
else if (strlen(ptr1) > 4 && memcmp(ptr1, "lua:", 4) == 0) {
else if (strlen(ptr1) > 4 && memcmp(ptr1, "lua:", 4) == 0) {
opt_username = USERNAME_LUA;
opt_lua_username_func = _strdup(ptr1 + 4);
}
Expand Down Expand Up @@ -2539,7 +2539,7 @@ static void add_interface(const char *ifname, int ifindex, const char *opt, int
}

if (serv->dhcpv4_relay &&
(serv->dhcpv4_relay->addr != relay_addr || serv->dhcpv4_relay->giaddr != opt_giaddr)) {
(serv->dhcpv4_relay->addr != relay_addr || serv->dhcpv4_relay->giaddr != opt_giaddr)) {
if (serv->opt_ifcfg)
ipoe_serv_del_addr(serv, serv->dhcpv4_relay->giaddr, 0);
dhcpv4_relay_free(serv->dhcpv4_relay, &serv->ctx);
Expand Down Expand Up @@ -2768,7 +2768,7 @@ static void load_interfaces(struct conf_sect_t *sect)
ipoe_nl_delete_interfaces();

list_for_each_entry(serv, &serv_list, entry)
serv->active = 0;
serv->active = 0;

list_for_each_entry(opt, &sect->items, entry) {
if (strcmp(opt->name, "interface"))
Expand Down Expand Up @@ -2823,6 +2823,39 @@ static void parse_local_net(const char *opt)
log_error("ipoe: failed to parse 'local-net=%s'\n", opt);
}

static void parse_bypass_net(const char *opt)
{
const char *ptr;
char str[17];
in_addr_t addr;
int mask;
char *endptr;

ptr = strchr(opt, '/');
if (ptr) {
memcpy(str, opt, ptr - opt);
str[ptr - opt] = 0;
addr = inet_addr(str);
if (addr == INADDR_NONE)
goto out_err;
mask = strtoul(ptr + 1, &endptr, 10);
if (mask > 32)
goto out_err;
} else {
addr = inet_addr(opt);
if (addr == INADDR_NONE)
goto out_err;
mask = 24;
}

ipoe_nl_add_bypass_net(addr, mask);

return;

out_err:
log_error("ipoe: failed to parse 'bypass-net=%s'\n", opt);
}

static void load_local_nets(struct conf_sect_t *sect)
{
struct conf_option_t *opt;
Expand All @@ -2838,6 +2871,21 @@ static void load_local_nets(struct conf_sect_t *sect)
}
}

static void load_bypass_nets(struct conf_sect_t *sect)
{
struct conf_option_t *opt;

ipoe_nl_delete_bypass_nets();

list_for_each_entry(opt, &sect->items, entry) {
if (strcmp(opt->name, "bypass-net"))
continue;
if (!opt->val)
continue;
parse_bypass_net(opt->val);
}
}

static void load_gw_addr(struct conf_sect_t *sect)
{
struct conf_option_t *opt;
Expand Down Expand Up @@ -3193,7 +3241,7 @@ static void load_config(void)
if (strcmp(opt, "ifname") == 0)
conf_username = USERNAME_IFNAME;
#ifdef USE_LUA
else if (strlen(opt) > 4 && memcmp(opt, "lua:", 4) == 0) {
else if (strlen(opt) > 4 && memcmp(opt, "lua:", 4) == 0) {
conf_username = USERNAME_LUA;
conf_lua_username_func = opt + 4;
}
Expand Down Expand Up @@ -3438,16 +3486,17 @@ static void load_config(void)

load_interfaces(s);
load_local_nets(s);
load_bypass_nets(s);
load_vlan_mon(s);
load_gw_addr(s);
}

static struct triton_context_t l4_redirect_ctx = {
.close = l4_redirect_ctx_close,
.close = l4_redirect_ctx_close,
};

static struct triton_timer_t l4_redirect_timer = {
.expire = l4_redirect_list_timer,
.expire = l4_redirect_list_timer,
};

static void ipoe_init(void)
Expand Down
2 changes: 2 additions & 0 deletions accel-pppd/ctrl/ipoe/ipoe.h
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,8 @@ struct ipoe_serv *ipoe_find_serv(const char *ifname);

void ipoe_nl_add_net(uint32_t addr, int mask);
void ipoe_nl_delete_nets(void);
void ipoe_nl_add_bypass_net(uint32_t addr, int mask);
void ipoe_nl_delete_bypass_nets(void);
void ipoe_nl_add_interface(int ifindex);
void ipoe_nl_delete_interfaces(void);
int ipoe_nl_create(uint32_t peer_addr, uint32_t addr, const char *ifname, uint8_t *hwaddr);
Expand Down
69 changes: 62 additions & 7 deletions accel-pppd/ctrl/ipoe/ipoe_netlink.c
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ void ipoe_nl_add_net(uint32_t addr, int mask)
ghdr = NLMSG_DATA(&req.n);
ghdr->cmd = IPOE_CMD_ADD_NET;

mask = ((1 << mask) - 1) << (32 - mask);
mask = (0xffffffff) << (32 - mask);

addattr32(nlh, 1024, IPOE_ATTR_ADDR, addr);
addattr32(nlh, 1024, IPOE_ATTR_MASK, mask);
Expand All @@ -84,6 +84,61 @@ void ipoe_nl_add_net(uint32_t addr, int mask)
log_error("ipoe: nl_add_net: error talking to kernel\n");
}

void ipoe_nl_delete_bypass_nets(void)
{
struct nlmsghdr *nlh;
struct genlmsghdr *ghdr;
struct {
struct nlmsghdr n;
char buf[1024];
} req;

if (rth.fd == -1)
return;

nlh = &req.n;
nlh->nlmsg_len = NLMSG_LENGTH(GENL_HDRLEN);
nlh->nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK;
nlh->nlmsg_type = ipoe_genl_id;

ghdr = NLMSG_DATA(&req.n);
ghdr->cmd = IPOE_CMD_DEL_BYPASS_NET;

addattr32(nlh, 1024, IPOE_ATTR_ADDR, 0);

if (rtnl_talk(&rth, nlh, 0, 0, nlh, NULL, NULL, 0) < 0 )
log_error("ipoe: nl_del_net: error talking to kernel\n");
}

void ipoe_nl_add_bypass_net(uint32_t addr, int mask)
{
struct nlmsghdr *nlh;
struct genlmsghdr *ghdr;
struct {
struct nlmsghdr n;
char buf[1024];
} req;

if (rth.fd == -1)
return;

nlh = &req.n;
nlh->nlmsg_len = NLMSG_LENGTH(GENL_HDRLEN);
nlh->nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK;
nlh->nlmsg_type = ipoe_genl_id;

ghdr = NLMSG_DATA(&req.n);
ghdr->cmd = IPOE_CMD_ADD_BYPASS_NET;

mask = (0xffffffff) << (32 - mask);

addattr32(nlh, 1024, IPOE_ATTR_ADDR, addr);
addattr32(nlh, 1024, IPOE_ATTR_MASK, mask);

if (rtnl_talk(&rth, nlh, 0, 0, nlh, NULL, NULL, 0) < 0 )
log_error("ipoe: nl_add_bypass_net: error talking to kernel\n");
}

int ipoe_nl_add_exclude(uint32_t addr, int mask)
{
struct rtnl_handle rth;
Expand Down Expand Up @@ -632,10 +687,10 @@ static int ipoe_mc_read(struct triton_md_handler_t *h)
struct sockaddr_nl nladdr;
struct iovec iov;
struct msghdr msg = {
.msg_name = &nladdr,
.msg_namelen = sizeof(nladdr),
.msg_iov = &iov,
.msg_iovlen = 1,
.msg_name = &nladdr,
.msg_namelen = sizeof(nladdr),
.msg_iov = &iov,
.msg_iovlen = 1,
};
char buf[8192];

Expand Down Expand Up @@ -713,11 +768,11 @@ static void ipoe_mc_close(struct triton_context_t *ctx)
}

static struct triton_context_t mc_ctx = {
.close = ipoe_mc_close,
.close = ipoe_mc_close,
};

static struct triton_md_handler_t mc_hnd = {
.read = ipoe_mc_read,
.read = ipoe_mc_read,
};

static void init(void)
Expand Down
2 changes: 1 addition & 1 deletion accel-pppd/ctrl/pptp/pptp.c
Original file line number Diff line number Diff line change
Expand Up @@ -646,7 +646,7 @@ static int pptp_connect(struct triton_md_handler_t *h)
log_info2("pptp: new connection from %s\n", inet_ntoa(addr.sin_addr));

if (iprange_client_check(addr.sin_addr.s_addr)) {
log_warn("pptp: IP is out of client-ip-range, droping connection...\n");
log_warn("pptp: IP %s is out of client-ip-range, droping connection...\n", inet_ntoa(addr.sin_addr));
close(sock);
continue;
}
Expand Down
Loading