diff options
author | Dmitry Kozlov <xeb@mail.ru> | 2014-07-17 14:16:54 +0400 |
---|---|---|
committer | Dmitry Kozlov <xeb@mail.ru> | 2014-07-17 14:17:38 +0400 |
commit | 35149a848e169a7717d30537b54770e513a34679 (patch) | |
tree | 841b68098b52bb1ef8aefd6fb41dd2e3d7446740 /accel-pppd/ctrl | |
parent | 953a944839db2dd4cf4eef5ef9cd94e4ba08e4d8 (diff) | |
download | accel-ppp-35149a848e169a7717d30537b54770e513a34679.tar.gz accel-ppp-35149a848e169a7717d30537b54770e513a34679.zip |
ipoe: fixed passing packets in 'redirect on reject' mode
Diffstat (limited to 'accel-pppd/ctrl')
-rw-r--r-- | accel-pppd/ctrl/ipoe/ipoe.c | 39 | ||||
-rw-r--r-- | accel-pppd/ctrl/ipoe/ipoe.h | 2 | ||||
-rw-r--r-- | accel-pppd/ctrl/ipoe/ipoe_netlink.c | 72 |
3 files changed, 82 insertions, 31 deletions
diff --git a/accel-pppd/ctrl/ipoe/ipoe.c b/accel-pppd/ctrl/ipoe/ipoe.c index ec241ea8..134aec8c 100644 --- a/accel-pppd/ctrl/ipoe/ipoe.c +++ b/accel-pppd/ctrl/ipoe/ipoe.c @@ -68,7 +68,6 @@ struct unit_cache { struct l4_redirect { struct list_head entry; - int ifindex; in_addr_t addr; time_t timeout; }; @@ -339,7 +338,7 @@ static char *ipoe_session_get_username(struct ipoe_session *ses) return _strdup(ses->ses.ifname); } -static void l4_redirect_list_add(in_addr_t addr, int ifindex) +static void l4_redirect_list_add(in_addr_t addr) { struct l4_redirect *n = _malloc(sizeof(*n)); struct timespec ts; @@ -351,10 +350,9 @@ static void l4_redirect_list_add(in_addr_t addr, int ifindex) memset(n, 0, sizeof(*n)); n->addr = addr; - n->ifindex = ifindex; n->timeout = ts.tv_sec + conf_l4_redirect_on_reject; - ipoe_nl_modify(ifindex, addr, 1, NULL, NULL); + ipoe_nl_add_exclude(addr, 32); if (conf_l4_redirect_table) iprule_add(addr, conf_l4_redirect_table); @@ -391,7 +389,6 @@ static void l4_redirect_list_timer(struct triton_timer_t *t) { struct l4_redirect *n; struct timespec ts; - struct unit_cache *uc; clock_gettime(CLOCK_MONOTONIC, &ts); @@ -407,16 +404,8 @@ static void l4_redirect_list_timer(struct triton_timer_t *t) 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); - uc->ifindex = n->ifindex; - pthread_mutex_lock(&uc_lock); - list_add_tail(&uc->entry, &uc_list); - ++uc_size; - pthread_mutex_unlock(&uc_lock); - } else - ipoe_nl_delete(n->ifindex); + + ipoe_nl_del_exclude(n->addr); _free(n); pthread_rwlock_wrlock(&l4_list_lock); @@ -555,10 +544,8 @@ static void ipoe_session_start(struct ipoe_session *ses) pthread_rwlock_unlock(&ses_lock); if (conf_ppp_verbose) log_ppp_warn("authentication failed\n"); - if (conf_l4_redirect_on_reject && !ses->dhcpv4_request && ses->ifindex != -1) { - l4_redirect_list_add(ses->yiaddr, ses->ifindex); - ses->ifindex = -1; - } + if (conf_l4_redirect_on_reject && !ses->dhcpv4_request) + l4_redirect_list_add(ses->yiaddr); ap_session_terminate(&ses->ses, TERM_AUTH_ERROR, 0); return; } @@ -1836,7 +1823,7 @@ static void l4_redirect_ctx_close(struct triton_context_t *ctx) if (conf_l4_redirect_ipset) ipset_del(conf_l4_redirect_ipset, n->addr); - ipoe_nl_delete(n->ifindex); + ipoe_nl_del_exclude(n->addr); _free(n); } @@ -2437,17 +2424,7 @@ static void parse_local_net(const char *opt) mask = 24; } - if (mask == 32) - mask = 0xffffffff; - else - mask = (1 << (32-mask)) - 1; - - addr = ntohl(addr); - mask = ~mask; - - //printf("%x/%x %x\n", htonl(addr), ~mask, htonl(addr)&(~mask)); - - ipoe_nl_add_net(addr & mask, mask); + ipoe_nl_add_net(addr, mask); return; diff --git a/accel-pppd/ctrl/ipoe/ipoe.h b/accel-pppd/ctrl/ipoe/ipoe.h index b3a346f3..e50d7221 100644 --- a/accel-pppd/ctrl/ipoe/ipoe.h +++ b/accel-pppd/ctrl/ipoe/ipoe.h @@ -122,6 +122,8 @@ void ipoe_nl_get_sessions(struct list_head *list); int ipoe_nl_add_vlan_mon(int ifindex, long *mask, int len); int ipoe_nl_add_vlan_mon_vid(int ifindex, int vid); int ipoe_nl_del_vlan_mon(int ifindex); +int ipoe_nl_add_exclude(uint32_t addr, int mask); +void ipoe_nl_del_exclude(uint32_t addr); struct arp_serv *arpd_start(struct ipoe_serv *ipoe); void arpd_stop(struct arp_serv *arp); diff --git a/accel-pppd/ctrl/ipoe/ipoe_netlink.c b/accel-pppd/ctrl/ipoe/ipoe_netlink.c index e4d1d024..7643961a 100644 --- a/accel-pppd/ctrl/ipoe/ipoe_netlink.c +++ b/accel-pppd/ctrl/ipoe/ipoe_netlink.c @@ -74,6 +74,8 @@ 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); addattr32(nlh, 1024, IPOE_ATTR_ADDR, addr); addattr32(nlh, 1024, IPOE_ATTR_MASK, mask); @@ -82,6 +84,74 @@ void ipoe_nl_add_net(uint32_t addr, int mask) log_error("ipoe: nl_add_net: error talking to kernel\n"); } +int ipoe_nl_add_exclude(uint32_t addr, int mask) +{ + struct rtnl_handle rth; + struct nlmsghdr *nlh; + struct genlmsghdr *ghdr; + struct { + struct nlmsghdr n; + char buf[1024]; + } req; + int ret = 0; + + if (rtnl_open_byproto(&rth, 0, NETLINK_GENERIC)) { + log_ppp_error("ipoe: cannot open generic netlink socket\n"); + return -1; + } + + 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_EXCLUDE; + + + addattr32(nlh, 1024, IPOE_ATTR_ADDR, addr); + + if (rtnl_talk(&rth, nlh, 0, 0, nlh, NULL, NULL, 0) < 0 ) { + log_ppp_error("ipoe: nl_add_net: error talking to kernel\n"); + ret = -1; + } + + rtnl_close(&rth); + + return ret; +} + +void ipoe_nl_del_exclude(uint32_t addr) +{ + struct rtnl_handle rth; + struct nlmsghdr *nlh; + struct genlmsghdr *ghdr; + struct { + struct nlmsghdr n; + char buf[1024]; + } req; + + if (rtnl_open_byproto(&rth, 0, NETLINK_GENERIC)) { + log_ppp_error("ipoe: cannot open generic netlink socket\n"); + 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_EXCLUDE; + + addattr32(nlh, 1024, IPOE_ATTR_ADDR, addr); + + if (rtnl_talk(&rth, nlh, 0, 0, nlh, NULL, NULL, 0) < 0 ) + log_ppp_error("ipoe: nl_add_net: error talking to kernel\n"); + + rtnl_close(&rth); +} + void ipoe_nl_delete_interfaces(void) { struct nlmsghdr *nlh; @@ -673,6 +743,8 @@ static void init(void) triton_md_register_handler(&mc_ctx, &mc_hnd); triton_md_enable_handler(&mc_hnd, MD_MODE_READ); triton_context_wakeup(&mc_ctx); + + ipoe_nl_del_exclude(0); } DEFINE_INIT(19, init); |