summaryrefslogtreecommitdiff
path: root/accel-pppd/ctrl/ipoe/ipoe.c
diff options
context:
space:
mode:
Diffstat (limited to 'accel-pppd/ctrl/ipoe/ipoe.c')
-rw-r--r--accel-pppd/ctrl/ipoe/ipoe.c58
1 files changed, 48 insertions, 10 deletions
diff --git a/accel-pppd/ctrl/ipoe/ipoe.c b/accel-pppd/ctrl/ipoe/ipoe.c
index b6ca46c4..4a4f95d4 100644
--- a/accel-pppd/ctrl/ipoe/ipoe.c
+++ b/accel-pppd/ctrl/ipoe/ipoe.c
@@ -173,6 +173,7 @@ static int conf_renew_time = LEASE_TIME/2;
static int conf_rebind_time = LEASE_TIME/2 + LEASE_TIME/4 + LEASE_TIME/8;
static int conf_verbose;
static const char *conf_agent_remote_id;
+static const char *conf_link_selection;
static int conf_proto;
static LIST_HEAD(conf_offer_delay);
static const char *conf_vlan_name;
@@ -258,6 +259,7 @@ static struct ipoe_session *ipoe_session_lookup(struct ipoe_serv *serv, struct d
uint8_t *agent_circuit_id = NULL;
uint8_t *agent_remote_id = NULL;
+ uint8_t *link_selection = NULL;
int opt82_match;
if (opt82_ses)
@@ -274,9 +276,10 @@ static struct ipoe_session *ipoe_session_lookup(struct ipoe_serv *serv, struct d
return ses;
}
- if (!conf_check_mac_change || (pack->relay_agent && dhcpv4_parse_opt82(pack->relay_agent, &agent_circuit_id, &agent_remote_id))) {
+ if (!conf_check_mac_change || (pack->relay_agent && dhcpv4_parse_opt82(pack->relay_agent, &agent_circuit_id, &agent_remote_id, &link_selection))) {
agent_circuit_id = NULL;
agent_remote_id = NULL;
+ link_selection = NULL;
}
list_for_each_entry(ses, &serv->sessions, entry) {
@@ -288,12 +291,18 @@ static struct ipoe_session *ipoe_session_lookup(struct ipoe_serv *serv, struct d
if (opt82_match && agent_remote_id && !ses->agent_remote_id)
opt82_match = 0;
+ if (opt82_match && link_selection && !ses->link_selection)
+ opt82_match = 0;
+
if (opt82_match && !agent_circuit_id && ses->agent_circuit_id)
opt82_match = 0;
if (opt82_match && !agent_remote_id && ses->agent_remote_id)
opt82_match = 0;
+ if (opt82_match && !link_selection && ses->link_selection)
+ opt82_match = 0;
+
if (opt82_match && agent_circuit_id) {
if (*agent_circuit_id != *ses->agent_circuit_id)
opt82_match = 0;
@@ -310,6 +319,14 @@ static struct ipoe_session *ipoe_session_lookup(struct ipoe_serv *serv, struct d
opt82_match = 0;
}
+ if (opt82_match && link_selection) {
+ if (*link_selection != *ses->link_selection)
+ opt82_match = 0;
+
+ if (memcmp(link_selection + 1, ses->link_selection + 1, *link_selection))
+ opt82_match = 0;
+ }
+
if (opt82_match && opt82_ses)
*opt82_ses = ses;
@@ -350,12 +367,18 @@ static struct ipoe_session *ipoe_session_lookup(struct ipoe_serv *serv, struct d
if (opt82_match && agent_remote_id && !ses->agent_remote_id)
continue;
+ if (opt82_match && link_selection && !ses->link_selection)
+ continue;
+
if (opt82_match && !agent_circuit_id && ses->agent_circuit_id)
continue;
if (opt82_match && !agent_remote_id && ses->agent_remote_id)
continue;
+ if (opt82_match && !link_selection && ses->link_selection)
+ continue;
+
if (opt82_match && agent_circuit_id) {
if (*agent_circuit_id != *ses->agent_circuit_id)
continue;
@@ -372,6 +395,14 @@ static struct ipoe_session *ipoe_session_lookup(struct ipoe_serv *serv, struct d
continue;
}
+ if (opt82_match && link_selection) {
+ if (*link_selection != *ses->link_selection)
+ continue;
+
+ if (memcmp(link_selection + 1, ses->link_selection + 1, *link_selection))
+ continue;
+ }
+
*opt82_ses = ses;
break;
}
@@ -417,7 +448,7 @@ static void ipoe_relay_timeout(struct triton_timer_t *t)
ap_session_terminate(&ses->ses, TERM_LOST_CARRIER, 1);
} else
- dhcpv4_relay_send(ses->serv->dhcpv4_relay, ses->dhcpv4_request, ses->relay_server_id, ses->serv->ifname, conf_agent_remote_id);
+ dhcpv4_relay_send(ses->serv->dhcpv4_relay, ses->dhcpv4_request, ses->relay_server_id, ses->serv->ifname, conf_agent_remote_id, conf_link_selection);
}
@@ -684,7 +715,7 @@ cont:
ap_session_set_ifindex(&ses->ses);
if (ses->dhcpv4_request && ses->serv->dhcpv4_relay) {
- dhcpv4_relay_send(ses->serv->dhcpv4_relay, ses->dhcpv4_request, ses->relay_server_id, ses->serv->ifname, conf_agent_remote_id);
+ dhcpv4_relay_send(ses->serv->dhcpv4_relay, ses->dhcpv4_request, ses->relay_server_id, ses->serv->ifname, conf_agent_remote_id, conf_link_selection);
ses->timer.expire = ipoe_relay_timeout;
ses->timer.period = conf_relay_timeout * 1000;
@@ -1077,7 +1108,7 @@ static void ipoe_session_activate(struct dhcpv4_packet *pack)
ses->dhcpv4_request = pack;
if (ses->serv->dhcpv4_relay)
- dhcpv4_relay_send(ses->serv->dhcpv4_relay, ses->dhcpv4_request, ses->relay_server_id, ses->serv->ifname, conf_agent_remote_id);
+ dhcpv4_relay_send(ses->serv->dhcpv4_relay, ses->dhcpv4_request, ses->relay_server_id, ses->serv->ifname, conf_agent_remote_id, conf_link_selection);
else
__ipoe_session_activate(ses);
}
@@ -1097,7 +1128,7 @@ static void ipoe_session_keepalive(struct dhcpv4_packet *pack)
ses->xid = ses->dhcpv4_request->hdr->xid;
if (/*ses->ses.state == AP_STATE_ACTIVE &&*/ ses->serv->dhcpv4_relay) {
- dhcpv4_relay_send(ses->serv->dhcpv4_relay, ses->dhcpv4_request, ses->relay_server_id, ses->serv->ifname, conf_agent_remote_id);
+ dhcpv4_relay_send(ses->serv->dhcpv4_relay, ses->dhcpv4_request, ses->relay_server_id, ses->serv->ifname, conf_agent_remote_id, conf_link_selection);
return;
}
@@ -1121,7 +1152,7 @@ static void ipoe_session_decline(struct dhcpv4_packet *pack)
}
if (pack->msg_type == DHCPDECLINE && ses->serv->dhcpv4_relay)
- dhcpv4_relay_send(ses->serv->dhcpv4_relay, pack, 0, ses->serv->ifname, conf_agent_remote_id);
+ dhcpv4_relay_send(ses->serv->dhcpv4_relay, pack, 0, ses->serv->ifname, conf_agent_remote_id, conf_link_selection);
dhcpv4_packet_free(pack);
@@ -1233,7 +1264,7 @@ static void ipoe_session_finished(struct ap_session *s)
dhcpv4_put_ip(ses->serv->dhcpv4, ses->yiaddr);
if (ses->relay_addr && ses->serv->dhcpv4_relay)
- dhcpv4_relay_send_release(ses->serv->dhcpv4_relay, ses->hwaddr, ses->xid, ses->yiaddr, ses->client_id, ses->relay_agent, ses->serv->ifname, conf_agent_remote_id);
+ dhcpv4_relay_send_release(ses->serv->dhcpv4_relay, ses->hwaddr, ses->xid, ses->yiaddr, ses->client_id, ses->relay_agent, ses->serv->ifname, conf_agent_remote_id, conf_link_selection);
if (ses->dhcpv4)
dhcpv4_free(ses->dhcpv4);
@@ -1382,7 +1413,7 @@ static struct ipoe_session *ipoe_session_create_dhcpv4(struct ipoe_serv *serv, s
ses->relay_agent->data = (uint8_t *)(ses->relay_agent + 1);
memcpy(ses->relay_agent->data, pack->relay_agent->data, pack->relay_agent->len);
ptr += sizeof(struct dhcpv4_option) + pack->relay_agent->len;
- if (dhcpv4_parse_opt82(ses->relay_agent, &ses->agent_circuit_id, &ses->agent_remote_id))
+ if (dhcpv4_parse_opt82(ses->relay_agent, &ses->agent_circuit_id, &ses->agent_remote_id, &ses->link_selection))
ses->relay_agent = NULL;
}
@@ -1440,6 +1471,7 @@ static void ipoe_ses_recv_dhcpv4(struct dhcpv4_serv *dhcpv4, struct dhcpv4_packe
int opt82_match;
uint8_t *agent_circuit_id = NULL;
uint8_t *agent_remote_id = NULL;
+ uint8_t *link_selection = NULL;
if (conf_verbose) {
log_ppp_info2("recv ");
@@ -1453,9 +1485,10 @@ static void ipoe_ses_recv_dhcpv4(struct dhcpv4_serv *dhcpv4, struct dhcpv4_packe
return;
}
- if (pack->relay_agent && dhcpv4_parse_opt82(pack->relay_agent, &agent_circuit_id, &agent_remote_id)) {
+ if (pack->relay_agent && dhcpv4_parse_opt82(pack->relay_agent, &agent_circuit_id, &agent_remote_id, &link_selection)) {
agent_circuit_id = NULL;
agent_remote_id = NULL;
+ link_selection = NULL;
}
opt82_match = pack->relay_agent != NULL;
@@ -1515,7 +1548,7 @@ static void ipoe_ses_recv_dhcpv4(struct dhcpv4_serv *dhcpv4, struct dhcpv4_packe
if (pack->server_id == ses->siaddr)
dhcpv4_send_nak(dhcpv4, pack, "Wrong session");
else if (ses->serv->dhcpv4_relay)
- dhcpv4_relay_send(ses->serv->dhcpv4_relay, pack, 0, ses->serv->ifname, conf_agent_remote_id);
+ dhcpv4_relay_send(ses->serv->dhcpv4_relay, pack, 0, ses->serv->ifname, conf_agent_remote_id, conf_link_selection);
triton_context_call(ses->ctrl.ctx, (triton_event_func)__ipoe_session_terminate, &ses->ses);
} else {
@@ -3802,6 +3835,7 @@ static void load_config(void)
const char *opt;
struct conf_sect_t *s = conf_get_section("ipoe");
struct conf_option_t *opt1;
+ struct in_addr dummy;
if (!s)
return;
@@ -3969,6 +4003,10 @@ static void load_config(void)
else
conf_agent_remote_id = NULL;
+ opt = conf_get_opt("ipoe", "link-selection");
+ if (opt && inet_pton(AF_INET, opt, &dummy) > 0)
+ conf_link_selection = opt;
+
opt = conf_get_opt("ipoe", "ipv6");
if (opt)
conf_ipv6 = atoi(opt);