diff options
author | Dmitry Kozlov <xeb@mail.ru> | 2013-06-22 21:53:06 +0400 |
---|---|---|
committer | Dmitry Kozlov <xeb@mail.ru> | 2013-06-22 21:53:06 +0400 |
commit | b2d6202a84a377531a7d16a2a87b6e85b782c051 (patch) | |
tree | e0fc05297b7c7b7ca70629739ac09a38f573ca22 | |
parent | 81fce25dbbc103a0e0ebdd4ff586c00b0292d05e (diff) | |
download | accel-ppp-b2d6202a84a377531a7d16a2a87b6e85b782c051.tar.gz accel-ppp-b2d6202a84a377531a7d16a2a87b6e85b782c051.zip |
ipoe: introduced proxy-arp option
-rw-r--r-- | accel-pppd/accel-ppp.conf | 3 | ||||
-rw-r--r-- | accel-pppd/accel-ppp.conf.5 | 10 | ||||
-rw-r--r-- | accel-pppd/ctrl/ipoe/CMakeLists.txt | 1 | ||||
-rw-r--r-- | accel-pppd/ctrl/ipoe/ipoe.c | 45 | ||||
-rw-r--r-- | accel-pppd/ctrl/ipoe/ipoe.h | 20 |
5 files changed, 74 insertions, 5 deletions
diff --git a/accel-pppd/accel-ppp.conf b/accel-pppd/accel-ppp.conf index a3bc3db0..62ac2328 100644 --- a/accel-pppd/accel-ppp.conf +++ b/accel-pppd/accel-ppp.conf @@ -46,6 +46,9 @@ shared=0 ifcfg=1 mode=L2 start=dhcpv4 +#proxy-arp=0 +#nat=0 +#proto=100 #relay=10.10.10.10 #attr-dhcp-client-ip=DHCP-Client-IP-Address #attr-dhcp-router-ip=DHCP-Router-IP-Address diff --git a/accel-pppd/accel-ppp.conf.5 b/accel-pppd/accel-ppp.conf.5 index 269043eb..23970232 100644 --- a/accel-pppd/accel-ppp.conf.5 +++ b/accel-pppd/accel-ppp.conf.5 @@ -242,11 +242,17 @@ Specifies default value for per-interface .B relay parameter. .TP +.BI "proxy-arp=" n +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 "" [,range=x.x.x.x/mask][,ifcfg=0|1] .BI "" [,relay=x.x.x.x] .BI "" [,giaddr=x.x.x.x] .BI "" [,src=x.x.x.x] +.BI "" [,proxy-arp=0|1|2] .br Specifies interface to listen dhcp or unclassified packets. You may specify multiple .B interface @@ -297,6 +303,10 @@ parameter specifies relay agent IP address. The .B src parameter specifies ip address to use as source when adding route to client. +.br +The +.B proxy-arp +parameter specifies whether accel-ppp should reply to arp requests. .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. diff --git a/accel-pppd/ctrl/ipoe/CMakeLists.txt b/accel-pppd/ctrl/ipoe/CMakeLists.txt index ef53a4f2..16a60540 100644 --- a/accel-pppd/ctrl/ipoe/CMakeLists.txt +++ b/accel-pppd/ctrl/ipoe/CMakeLists.txt @@ -6,6 +6,7 @@ SET(sources dhcpv4_options.c ipoe_netlink.c backup.c + arp.c ) IF (LUA) diff --git a/accel-pppd/ctrl/ipoe/ipoe.c b/accel-pppd/ctrl/ipoe/ipoe.c index ce6a4cd0..5845f6ee 100644 --- a/accel-pppd/ctrl/ipoe/ipoe.c +++ b/accel-pppd/ctrl/ipoe/ipoe.c @@ -50,6 +50,7 @@ static int conf_mode = 0; static int conf_shared = 1; static int conf_ifcfg = 1; static int conf_nat = 0; +static int conf_arp = 0; static uint32_t conf_src; //static int conf_dhcpv6; @@ -149,7 +150,7 @@ static struct ipoe_session *ipoe_session_lookup(struct ipoe_serv *serv, struct d } list_for_each_entry(ses, &serv->sessions, entry) { - opt82_match = pack->relay_agent != NULL; + opt82_match = pack->relay_agent == NULL; if (opt82_match && agent_circuit_id && !ses->agent_circuit_id) opt82_match = 0; @@ -982,7 +983,7 @@ static void ipoe_ses_recv_dhcpv4(struct dhcpv4_serv *dhcpv4, struct dhcpv4_packe agent_remote_id = NULL; } - opt82_match = pack->relay_agent != NULL; + opt82_match = pack->relay_agent == NULL; if (opt82_match && agent_circuit_id && !ses->agent_circuit_id) opt82_match = 0; @@ -1476,6 +1477,9 @@ static void ipoe_serv_close(struct triton_context_t *ctx) dhcpv4_relay_free(serv->dhcpv4_relay, &serv->ctx); } + if (serv->arp) + arpd_stop(serv->arp); + triton_context_unregister(ctx); _free(serv->ifname); @@ -1571,6 +1575,8 @@ static void add_interface(const char *ifname, int ifindex, const char *opt) in_addr_t relay_addr = 0; in_addr_t giaddr = 0; in_addr_t opt_src = conf_src; + int opt_arp = conf_arp; + struct ifreq ifr; str0 = strchr(opt, ','); if (str0) { @@ -1623,6 +1629,8 @@ static void add_interface(const char *ifname, int ifindex, const char *opt) opt_nat = atoi(ptr1); } else if (strcmp(str, "src") == 0) { opt_src = inet_addr(ptr1); + } else if (strcmp(str, "proxy-arp") == 0) { + opt_arp = atoi(ptr1); } if (end) @@ -1674,12 +1682,19 @@ static void add_interface(const char *ifname, int ifindex, const char *opt) ipoe_serv_add_addr(serv, giaddr); serv->dhcpv4_relay = dhcpv4_relay_create(opt_relay, opt_giaddr, &serv->ctx, (triton_event_func)ipoe_recv_dhcpv4_relay); } + + if (serv->arp && !conf_arp) { + arpd_stop(serv->arp); + serv->arp = NULL; + } else if (!serv->arp && conf_arp) + serv->arp = arpd_start(serv); serv->opt_up = opt_up; serv->opt_mode = opt_mode; serv->opt_ifcfg = opt_ifcfg; serv->opt_nat = opt_nat; serv->opt_src = opt_src; + serv->opt_arp = opt_arp; if (str0) _free(str0); @@ -1687,6 +1702,14 @@ static void add_interface(const char *ifname, int ifindex, const char *opt) return; } + memset(&ifr, 0, sizeof(ifr)); + strcpy(ifr.ifr_name, ifname); + + if (ioctl(sock_fd, SIOCGIFHWADDR, &ifr)) { + log_error("ipoe: '%s': ioctl(SIOCGIFHWADDR): %s\n", ifname, strerror(errno)); + return; + } + serv = _malloc(sizeof(*serv)); memset(serv, 0, sizeof(*serv)); serv->ctx.close = ipoe_serv_close; @@ -1699,9 +1722,11 @@ static void add_interface(const char *ifname, int ifindex, const char *opt) serv->opt_ifcfg = opt_ifcfg; serv->opt_nat = opt_nat; serv->opt_src = opt_src; + serv->opt_arp = opt_arp; serv->active = 1; INIT_LIST_HEAD(&serv->sessions); INIT_LIST_HEAD(&serv->addr_list); + memcpy(serv->hwaddr, ifr.ifr_hwaddr.sa_data, ETH_ALEN); pthread_mutex_init(&serv->lock, NULL); triton_context_register(&serv->ctx, NULL); @@ -1718,6 +1743,9 @@ static void add_interface(const char *ifname, int ifindex, const char *opt) } } + if (serv->opt_arp) + serv->arp = arpd_start(serv); + triton_context_wakeup(&serv->ctx); list_add_tail(&serv->entry, &serv_list); @@ -1749,7 +1777,7 @@ static void load_interface(const char *opt) log_error("ipoe: '%s': ioctl(SIOCGIFINDEX): %s\n", ifr.ifr_name, strerror(errno)); return; } - + add_interface(ifr.ifr_name, ifr.ifr_ifindex, opt); } @@ -2051,6 +2079,17 @@ static void load_config(void) conf_src = inet_addr(opt); else conf_src = 0; + + opt = conf_get_opt("ipoe", "proxy-arp"); + if (opt) + conf_arp = atoi(opt); + else + conf_arp = 0; + + if (conf_arp < 0 || conf_arp > 2) { + log_error("ipoe: arp=%s: invalid value\n", opt); + conf_arp = 0; + } opt = conf_get_opt("ipoe", "mode"); if (opt) { diff --git a/accel-pppd/ctrl/ipoe/ipoe.h b/accel-pppd/ctrl/ipoe/ipoe.h index 1dd2db97..73855980 100644 --- a/accel-pppd/ctrl/ipoe/ipoe.h +++ b/accel-pppd/ctrl/ipoe/ipoe.h @@ -9,26 +9,35 @@ #include "ipdb.h" #include "dhcpv4.h" +#ifndef ETH_ALEN +#define ETH_ALEN 6 +#endif + +struct arp_serv; + struct ipoe_serv { struct list_head entry; struct triton_context_t ctx; char *ifname; int ifindex; - int active; + uint8_t hwaddr[ETH_ALEN]; struct list_head sessions; struct list_head addr_list; struct dhcpv4_serv *dhcpv4; struct dhcpv4_relay *dhcpv4_relay; + struct arp_serv *arp; pthread_mutex_t lock; int opt_mode; uint32_t opt_src; + int opt_arp; int opt_shared:1; int opt_dhcpv4:1; int opt_up:1; int opt_ifcfg:1; int opt_nat:1; int need_close:1; + int active:1; }; struct ipoe_session @@ -40,7 +49,7 @@ struct ipoe_session struct dhcpv4_serv *dhcpv4; struct ap_ctrl ctrl; struct ap_session ses; - uint8_t hwaddr[6]; + uint8_t hwaddr[ETH_ALEN]; struct dhcpv4_option *client_id; struct dhcpv4_option *relay_agent; uint8_t *agent_circuit_id; @@ -74,6 +83,11 @@ struct ipoe_session_info uint32_t peer_addr; }; +struct arp_serv { + struct triton_md_handler_t h; + struct ipoe_serv *ipoe; +}; + #ifdef USE_LUA int ipoe_lua_set_username(struct ipoe_session *, const char *func); #endif @@ -95,5 +109,7 @@ void ipoe_nl_delete(int ifindex); int ipoe_nl_modify(int ifindex, uint32_t peer_addr, uint32_t addr, const char *ifname, uint8_t *hwaddr); void ipoe_nl_get_sessions(struct list_head *list); +struct arp_serv *arpd_start(struct ipoe_serv *ipoe); +void arpd_stop(struct arp_serv *arp); #endif |