summaryrefslogtreecommitdiff
path: root/accel-pppd
diff options
context:
space:
mode:
authorDmitry Kozlov <xeb@mail.ru>2016-03-18 23:15:20 +0300
committerDmitry Kozlov <xeb@mail.ru>2016-03-18 23:15:20 +0300
commitaa4ed7b9c637b70dc42a180b918fb4adb3e32d74 (patch)
tree4e8454f4c751db0619faa2e6333d6b90aa841158 /accel-pppd
parent53eaf7555a5f3f0b60854acf7933484c98ada917 (diff)
downloadaccel-ppp-aa4ed7b9c637b70dc42a180b918fb4adb3e32d74.tar.gz
accel-ppp-aa4ed7b9c637b70dc42a180b918fb4adb3e32d74.zip
ipoe: implemented starting UP session by arp request
Diffstat (limited to 'accel-pppd')
-rw-r--r--accel-pppd/ctrl/ipoe/arp.c12
-rw-r--r--accel-pppd/ctrl/ipoe/ipoe.c20
-rw-r--r--accel-pppd/ctrl/ipoe/ipoe.h14
-rw-r--r--accel-pppd/ctrl/ipoe/ipoe_netlink.c18
4 files changed, 38 insertions, 26 deletions
diff --git a/accel-pppd/ctrl/ipoe/arp.c b/accel-pppd/ctrl/ipoe/arp.c
index 9699624..2bf5a95 100644
--- a/accel-pppd/ctrl/ipoe/arp.c
+++ b/accel-pppd/ctrl/ipoe/arp.c
@@ -26,18 +26,6 @@
#include "memdebug.h"
-struct _arphdr {
- __be16 ar_hrd;
- __be16 ar_pro;
- __u8 ar_hln;
- __u8 ar_pln;
- __be16 ar_op;
- __u8 ar_sha[ETH_ALEN];
- __be32 ar_spa;
- __u8 ar_tha[ETH_ALEN];
- __be32 ar_tpa;
-} __packed;
-
struct arp_node {
struct rb_node node;
struct ipoe_serv *ipoe;
diff --git a/accel-pppd/ctrl/ipoe/ipoe.c b/accel-pppd/ctrl/ipoe/ipoe.c
index 514e787..e6f142a 100644
--- a/accel-pppd/ctrl/ipoe/ipoe.c
+++ b/accel-pppd/ctrl/ipoe/ipoe.c
@@ -1748,15 +1748,16 @@ static void ipoe_recv_dhcpv4_relay(struct dhcpv4_packet *pack)
}
-static struct ipoe_session *ipoe_session_create_up(struct ipoe_serv *serv, struct ethhdr *eth, struct iphdr *iph)
+static struct ipoe_session *ipoe_session_create_up(struct ipoe_serv *serv, struct ethhdr *eth, struct iphdr *iph, struct _arphdr *arph)
{
struct ipoe_session *ses;
- uint8_t *hwaddr = eth->h_source;
+ uint8_t *hwaddr = arph ? arph->ar_sha : eth->h_source;
+ in_addr_t saddr = arph ? arph->ar_spa : iph->saddr;
if (ap_shutdown)
return NULL;
- if (l4_redirect_list_check(iph->saddr))
+ if (l4_redirect_list_check(saddr))
return NULL;
ses = ipoe_session_alloc();
@@ -1764,8 +1765,8 @@ static struct ipoe_session *ipoe_session_create_up(struct ipoe_serv *serv, struc
return NULL;
ses->serv = serv;
- memcpy(ses->hwaddr, eth->h_source, 6);
- ses->yiaddr = iph->saddr;
+ memcpy(ses->hwaddr, hwaddr, ETH_ALEN);
+ ses->yiaddr = saddr;
ses->UP = 1;
if (!serv->opt_shared)
@@ -1779,7 +1780,7 @@ static struct ipoe_session *ipoe_session_create_up(struct ipoe_serv *serv, struc
hwaddr[0], hwaddr[1], hwaddr[2], hwaddr[3], hwaddr[4], hwaddr[5]);
} else {
ses->ctrl.calling_station_id = _malloc(17);
- u_inet_ntoa(iph->saddr, ses->ctrl.calling_station_id);
+ u_inet_ntoa(saddr, ses->ctrl.calling_station_id);
}
if (ses->serv->opt_username == USERNAME_IFNAME)
@@ -1881,10 +1882,11 @@ struct ipoe_session *ipoe_session_alloc(void)
return ses;
}
-void ipoe_recv_up(int ifindex, struct ethhdr *eth, struct iphdr *iph)
+void ipoe_recv_up(int ifindex, struct ethhdr *eth, struct iphdr *iph, struct _arphdr *arph)
{
struct ipoe_serv *serv;
struct ipoe_session *ses;
+ in_addr_t saddr = arph ? arph->ar_spa : iph->saddr;
pthread_mutex_lock(&serv_lock);
list_for_each_entry(serv, &serv_list, entry) {
@@ -1904,14 +1906,14 @@ void ipoe_recv_up(int ifindex, struct ethhdr *eth, struct iphdr *iph)
}
list_for_each_entry(ses, &serv->sessions, entry) {
- if (ses->yiaddr == iph->saddr) {
+ if (ses->yiaddr == saddr) {
pthread_mutex_unlock(&serv->lock);
pthread_mutex_unlock(&serv_lock);
return;
}
}
- ipoe_session_create_up(serv, eth, iph);
+ ipoe_session_create_up(serv, eth, iph, arph);
pthread_mutex_unlock(&serv->lock);
diff --git a/accel-pppd/ctrl/ipoe/ipoe.h b/accel-pppd/ctrl/ipoe/ipoe.h
index 0cf14ea..52b3c8d 100644
--- a/accel-pppd/ctrl/ipoe/ipoe.h
+++ b/accel-pppd/ctrl/ipoe/ipoe.h
@@ -106,6 +106,18 @@ struct ipoe_session_info {
uint32_t peer_addr;
};
+struct _arphdr {
+ __be16 ar_hrd;
+ __be16 ar_pro;
+ __u8 ar_hln;
+ __u8 ar_pln;
+ __be16 ar_op;
+ __u8 ar_sha[ETH_ALEN];
+ __be32 ar_spa;
+ __u8 ar_tha[ETH_ALEN];
+ __be32 ar_tpa;
+} __packed;
+
#ifdef USE_LUA
char *ipoe_lua_get_username(struct ipoe_session *, const char *func);
int ipoe_lua_make_vlan_name(const char *func, const char *parent, int svid, int cvid, char *name);
@@ -114,7 +126,7 @@ int ipoe_lua_make_vlan_name(const char *func, const char *parent, int svid, int
struct iphdr;
struct ethhdr;
-void ipoe_recv_up(int ifindex, struct ethhdr *eth, struct iphdr *iph);
+void ipoe_recv_up(int ifindex, struct ethhdr *eth, struct iphdr *iph, struct _arphdr *arph);
struct ipoe_session *ipoe_session_alloc(void);
diff --git a/accel-pppd/ctrl/ipoe/ipoe_netlink.c b/accel-pppd/ctrl/ipoe/ipoe_netlink.c
index 9372a94..8ed4d91 100644
--- a/accel-pppd/ctrl/ipoe/ipoe_netlink.c
+++ b/accel-pppd/ctrl/ipoe/ipoe_netlink.c
@@ -467,6 +467,7 @@ static void ipoe_up_handler(const struct sockaddr_nl *addr, struct nlmsghdr *h)
int ifindex;
struct iphdr *iph;
struct ethhdr *eth;
+ struct _arphdr *arph;
len -= NLMSG_LENGTH(GENL_HDRLEN);
@@ -484,14 +485,23 @@ static void ipoe_up_handler(const struct sockaddr_nl *addr, struct nlmsghdr *h)
parse_rtattr_nested(tb2, IPOE_ATTR_MAX, tb[i]);
- if (!tb2[IPOE_ATTR_ETH_HDR] || !tb2[IPOE_ATTR_IP_HDR] || !tb2[IPOE_ATTR_IFINDEX])
+ if (!tb2[IPOE_ATTR_IFINDEX])
continue;
ifindex = *(uint32_t *)(RTA_DATA(tb2[IPOE_ATTR_IFINDEX]));
- iph = (struct iphdr *)(RTA_DATA(tb2[IPOE_ATTR_IP_HDR]));
- eth = (struct ethhdr *)(RTA_DATA(tb2[IPOE_ATTR_ETH_HDR]));
- ipoe_recv_up(ifindex, eth, iph);
+ if (tb2[IPOE_ATTR_ARP_HDR]) {
+ arph = (struct _arphdr *)(RTA_DATA(tb2[IPOE_ATTR_ARP_HDR]));
+ iph = NULL;
+ eth = NULL;
+ } else if (tb2[IPOE_ATTR_ETH_HDR] && !tb2[IPOE_ATTR_IP_HDR]) {
+ iph = (struct iphdr *)(RTA_DATA(tb2[IPOE_ATTR_IP_HDR]));
+ eth = (struct ethhdr *)(RTA_DATA(tb2[IPOE_ATTR_ETH_HDR]));
+ arph = NULL;
+ } else
+ continue;
+
+ ipoe_recv_up(ifindex, eth, iph, arph);
}
}