summaryrefslogtreecommitdiff
path: root/accel-pppd/ctrl/ipoe/ipoe.c
diff options
context:
space:
mode:
authorDmitry Kozlov <xeb@mail.ru>2013-06-22 21:53:06 +0400
committerDmitry Kozlov <xeb@mail.ru>2013-06-22 21:53:06 +0400
commitb2d6202a84a377531a7d16a2a87b6e85b782c051 (patch)
treee0fc05297b7c7b7ca70629739ac09a38f573ca22 /accel-pppd/ctrl/ipoe/ipoe.c
parent81fce25dbbc103a0e0ebdd4ff586c00b0292d05e (diff)
downloadaccel-ppp-b2d6202a84a377531a7d16a2a87b6e85b782c051.tar.gz
accel-ppp-b2d6202a84a377531a7d16a2a87b6e85b782c051.zip
ipoe: introduced proxy-arp option
Diffstat (limited to 'accel-pppd/ctrl/ipoe/ipoe.c')
-rw-r--r--accel-pppd/ctrl/ipoe/ipoe.c45
1 files changed, 42 insertions, 3 deletions
diff --git a/accel-pppd/ctrl/ipoe/ipoe.c b/accel-pppd/ctrl/ipoe/ipoe.c
index ce6a4cd..5845f6e 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) {