#3 L2TPv2 LNS Support

+ Add result codes to CDN and STOPCCN
+ Fix attribute hiding
+ ...
This commit is contained in:
Christian Giese
2021-02-24 17:02:23 +01:00
parent 40d23ec4cd
commit d7f80e1b04
4 changed files with 89 additions and 3 deletions
+3 -3
View File
@@ -692,9 +692,9 @@ bbl_ctrl_li_flows(int fd, bbl_ctx_s *ctx, session_key_t *key __attribute__((unus
}
}
root = json_pack("{ss si so}",
"status", "ok",
"code", 200,
"li-flows", flows);
"status", "ok",
"code", 200,
"li-flows", flows);
if(root) {
result = json_dumpfd(root, fd, 0);
json_decref(root);
+25
View File
@@ -265,6 +265,9 @@ bbl_l2tp_tunnel_tx_job (timer_s *timer) {
l2tp_tunnel->stats.control_retry++;
interface->stats.l2tp_control_retry++;
if(q->retries > l2tp_tunnel->server->max_retry) {
l2tp_tunnel->result_code = 2;
l2tp_tunnel->error_code = 6;
l2tp_tunnel->error_message = "max retry";
bbl_l2tp_tunnel_update_state(l2tp_tunnel, BBL_L2TP_TUNNEL_SEND_STOPCCN);
bbl_l2tp_send(l2tp_tunnel, NULL, L2TP_MESSAGE_STOPCCN);
}
@@ -311,6 +314,9 @@ bbl_l2tp_tunnel_control_job (timer_s *timer) {
switch(l2tp_tunnel->state) {
case BBL_L2TP_TUNNEL_WAIT_CTR_CONN:
if(l2tp_tunnel->state_seconds > 30) {
l2tp_tunnel->result_code = 2;
l2tp_tunnel->error_code = 6;
l2tp_tunnel->error_message = "timeout";
bbl_l2tp_tunnel_update_state(l2tp_tunnel, BBL_L2TP_TUNNEL_SEND_STOPCCN);
bbl_l2tp_send(l2tp_tunnel, NULL, L2TP_MESSAGE_STOPCCN);
}
@@ -600,6 +606,9 @@ bbl_l2tp_sccrq_rx(bbl_ethernet_header_t *eth, bbl_l2tp_t *l2tp, bbl_interface_s
LOG(ERROR, "L2TP Error (%s) Missing challenge in SCCRQ from %s\n",
l2tp_tunnel->server->host_name,
format_ipv4_address(&l2tp_tunnel->peer_ip));
l2tp_tunnel->result_code = 2;
l2tp_tunnel->error_code = 6;
l2tp_tunnel->error_message = "missing challenge";
l2tp_tunnel->state = BBL_L2TP_TUNNEL_SEND_STOPCCN;
}
} else {
@@ -609,6 +618,9 @@ bbl_l2tp_sccrq_rx(bbl_ethernet_header_t *eth, bbl_l2tp_t *l2tp, bbl_interface_s
LOG(ERROR, "L2TP Error (%s) No secret found but challenge received in SCCRQ from %s\n",
l2tp_tunnel->server->host_name,
format_ipv4_address(&l2tp_tunnel->peer_ip));
l2tp_tunnel->result_code = 2;
l2tp_tunnel->error_code = 6;
l2tp_tunnel->error_message = "no challenge expected";
l2tp_tunnel->state = BBL_L2TP_TUNNEL_SEND_STOPCCN;
}
}
@@ -648,6 +660,9 @@ bbl_l2tp_scccn_rx(bbl_ethernet_header_t *eth, bbl_l2tp_t *l2tp, bbl_interface_s
l2tp_tunnel->server->host_name,
format_ipv4_address(&l2tp_tunnel->peer_ip));
bbl_l2tp_tunnel_update_state(l2tp_tunnel, BBL_L2TP_TUNNEL_SEND_STOPCCN);
l2tp_tunnel->result_code = 2;
l2tp_tunnel->error_code = 6;
l2tp_tunnel->error_message = "decode error";
return bbl_l2tp_send(l2tp_tunnel, NULL, L2TP_MESSAGE_STOPCCN);
}
/* Check challenge response ... */
@@ -663,6 +678,9 @@ bbl_l2tp_scccn_rx(bbl_ethernet_header_t *eth, bbl_l2tp_t *l2tp, bbl_interface_s
l2tp_tunnel->server->host_name,
format_ipv4_address(&l2tp_tunnel->peer_ip));
bbl_l2tp_tunnel_update_state(l2tp_tunnel, BBL_L2TP_TUNNEL_SEND_STOPCCN);
l2tp_tunnel->result_code = 2;
l2tp_tunnel->error_code = 6;
l2tp_tunnel->error_message = "challenge authentication failed";
return bbl_l2tp_send(l2tp_tunnel, NULL, L2TP_MESSAGE_STOPCCN);
}
} else {
@@ -670,6 +688,9 @@ bbl_l2tp_scccn_rx(bbl_ethernet_header_t *eth, bbl_l2tp_t *l2tp, bbl_interface_s
l2tp_tunnel->server->host_name,
format_ipv4_address(&l2tp_tunnel->peer_ip));
bbl_l2tp_tunnel_update_state(l2tp_tunnel, BBL_L2TP_TUNNEL_SEND_STOPCCN);
l2tp_tunnel->result_code = 2;
l2tp_tunnel->error_code = 6;
l2tp_tunnel->error_message = "missing challenge response";
return bbl_l2tp_send(l2tp_tunnel, NULL, L2TP_MESSAGE_STOPCCN);
}
}
@@ -759,6 +780,9 @@ bbl_l2tp_iccn_rx(bbl_ethernet_header_t *eth, bbl_l2tp_t *l2tp, bbl_interface_s *
}
if(!bbl_l2tp_avp_decode_session(l2tp, l2tp_tunnel, l2tp_session)) {
l2tp_session->result_code = 2;
l2tp_session->error_code = 6;
l2tp_session->error_message = "decode error";
bbl_l2tp_send(l2tp_tunnel, l2tp_session, L2TP_MESSAGE_CDN);
return bbl_l2tp_session_delete(l2tp_session);
}
@@ -1118,6 +1142,7 @@ bbl_l2tp_stop_all_tunnel(bbl_ctx_s *ctx) {
CIRCLEQ_FOREACH(l2tp_tunnel, &l2tp_server->tunnel_qhead, tunnel_qnode) {
if(l2tp_tunnel->state < BBL_L2TP_TUNNEL_SEND_STOPCCN) {
bbl_l2tp_tunnel_update_state(l2tp_tunnel, BBL_L2TP_TUNNEL_SEND_STOPCCN);
l2tp_tunnel->result_code = 6;
bbl_l2tp_send(l2tp_tunnel, NULL, L2TP_MESSAGE_STOPCCN);
}
}
+8
View File
@@ -163,6 +163,10 @@ typedef struct bbl_l2tp_tunnel_
uint16_t cwcount;
uint32_t send_timestamp;
uint16_t result_code;
uint16_t error_code;
char* error_message;
bool zlb;
bbl_l2tp_queue_t *zlb_qnode;
@@ -230,6 +234,10 @@ typedef struct bbl_l2tp_session_
uint8_t ipcp_state;
uint8_t ip6cp_state;
uint16_t result_code;
uint16_t error_code;
char* error_message;
/* The following members must be freed
* if session is destroyed! */
+53
View File
@@ -90,6 +90,41 @@ bbl_l2tp_avp_encode(uint8_t **_buf, uint16_t *len, bbl_l2tp_avp_t *avp) {
*_buf = buf;
}
static void
bbl_l2tp_avp_encode_result_code(uint8_t **_buf, uint16_t *len,
uint16_t result_code, uint16_t error_code,
char *error_message) {
uint8_t *avp_len_field;
uint16_t avp_len = L2TP_AVP_HDR_LEN;
uint8_t *buf = *_buf;
avp_len_field = buf;
BUMP_WRITE_BUFFER(buf, len, sizeof(uint16_t));
*(uint16_t*)buf = 0;
BUMP_WRITE_BUFFER(buf, len, sizeof(uint16_t));
*(uint16_t*)buf = htobe16(L2TP_AVP_RESULT_CODE);
BUMP_WRITE_BUFFER(buf, len, sizeof(uint16_t));
*(uint16_t*)buf = htobe16(result_code);
BUMP_WRITE_BUFFER(buf, len, sizeof(uint16_t));
avp_len += 2;
if(error_code) {
*(uint16_t*)buf = htobe16(error_code);
BUMP_WRITE_BUFFER(buf, len, sizeof(uint16_t));
avp_len += 2;
if(error_message) {
memcpy(buf, error_message, strlen(error_message));
BUMP_WRITE_BUFFER(buf, len, strlen(error_message));
avp_len += strlen(error_message);
}
}
avp_len |= L2TP_AVP_M_BIT_MASK;
*(uint16_t*)avp_len_field = htobe16(avp_len);
*_buf = buf;
}
/* bbl_l2tp_avp_unhide */
static bool
bbl_l2tp_avp_unhide(bbl_l2tp_tunnel_t *l2tp_tunnel, bbl_l2tp_avp_t *avp, uint8_t
@@ -329,6 +364,10 @@ bbl_l2tp_avp_decode_session(bbl_l2tp_t *l2tp, bbl_l2tp_tunnel_t *l2tp_tunnel, bb
l2tp_session->proxy_auth_response_len = avp.len;
}
break;
case L2TP_AVP_RANDOM_VECTOR:
random_vector = avp.value;
random_vector_len = avp.len;
break;
case L2TP_AVP_CONNECT_SPEED_UPDATE_ENABLE:
/* See RFC5515 */
l2tp_session->connect_speed_update_enabled = true;
@@ -515,6 +554,10 @@ bbl_l2tp_avp_decode_tunnel(bbl_l2tp_t *l2tp, bbl_l2tp_tunnel_t *l2tp_tunnel) {
memcpy(l2tp_tunnel->peer_challenge_response, avp.value, avp.len);
}
break;
case L2TP_AVP_RANDOM_VECTOR:
random_vector = avp.value;
random_vector_len = avp.len;
break;
default:
if(avp.m) {
LOG(L2TP, "L2TP Error (%s) Mandatory standard AVP with unknown type %u in %s from %s\n",
@@ -739,6 +782,11 @@ bbl_l2tp_avp_encode_attributes(bbl_l2tp_tunnel_t *l2tp_tunnel, bbl_l2tp_session_
avp.value_type = L2TP_AVP_VALUE_UINT16;
avp.value = (void*)(&l2tp_tunnel->tunnel_id);
bbl_l2tp_avp_encode(&buf, len, &avp);
/* Result Code */
bbl_l2tp_avp_encode_result_code(&buf, len,
l2tp_tunnel->result_code,
l2tp_tunnel->error_code,
l2tp_tunnel->error_message);
break;
case L2TP_MESSAGE_ICRP:
/* Assigned Session ID */
@@ -760,6 +808,11 @@ bbl_l2tp_avp_encode_attributes(bbl_l2tp_tunnel_t *l2tp_tunnel, bbl_l2tp_session_
avp.value_type = L2TP_AVP_VALUE_UINT16;
avp.value = (void*)(&l2tp_session->key.session_id);
bbl_l2tp_avp_encode(&buf, len, &avp);
/* Result Code */
bbl_l2tp_avp_encode_result_code(&buf, len,
l2tp_session->result_code,
l2tp_session->error_code,
l2tp_session->error_message);
}
break;
case L2TP_MESSAGE_CSURQ: