summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--accel-pppd/ctrl/pppoe/pppoe.c125
-rw-r--r--accel-pppd/ctrl/pppoe/vpppoe.c609
-rw-r--r--accel-pppd/ctrl/pppoe/vpppoe.h23
-rw-r--r--accel-pppd/include/ap_session.h4
-rw-r--r--accel-pppd/ppp/ppp.c37
-rw-r--r--accel-pppd/session.c11
6 files changed, 640 insertions, 169 deletions
diff --git a/accel-pppd/ctrl/pppoe/pppoe.c b/accel-pppd/ctrl/pppoe/pppoe.c
index 01330c6..25e38a7 100644
--- a/accel-pppd/ctrl/pppoe/pppoe.c
+++ b/accel-pppd/ctrl/pppoe/pppoe.c
@@ -232,14 +232,16 @@ int pppoe_terminate(struct ap_session *ses, int hard) {
struct ppp_t *ppp = container_of(ses, typeof(*ppp), ses);
struct pppoe_conn_t *conn = container_of(ppp, typeof(*conn), ppp);
- ret = vpppoe_lcp_tun_add_del(ses->vpp_sw_if_index, ses->ifname, 0);
- if (ret)
- log_warn("VPPPOE: Can't remove VPP lcp TUN pair at terminate: sw_if_index %d name %s\n", ses->vpp_sw_if_index, ses->ifname);
- else {
- ret = vpppoe_pppoe_session_add_del(conn->addr, &ses->ipv4->peer_addr, conn->sid, 0, NULL);
- if (ret)
- log_warn("VPPPOE: Can't remove session at terminate: %d %02x.%02x.%02x.%02x.%02x.%02x", conn->sid,
- conn->addr[0], conn->addr[1], conn->addr[2], conn->addr[3], conn->addr[4], conn->addr[5]);
+ if (ppp->is_non_dev_ppp)
+ {
+ if (ses->non_dev_ppp_fixup_status == 2) {
+ vpppoe_async_del_pppoe_interface(conn->addr, &ses->ipv4->peer_addr, conn->sid, ses->vpp_sw_if_index, ses->ifname);
+ } else if (ses->non_dev_ppp_fixup_status == 1) {
+ vpppoe_setup_pppoe_interface_ctx_t *callback_ctx = (vpppoe_setup_pppoe_interface_ctx_t *)ses->non_dev_ppp_fixup_priv;
+
+ __sync_or_and_fetch(&callback_ctx->remove_after, 1);
+ }
+
}
ret = ppp_terminate(ses, hard);
@@ -261,58 +263,41 @@ static void ppp_finished(struct ap_session *ses)
}
}
-int pppoe_create_non_dev_ppp_interface(struct ap_session *ses) {
+static void pppoe_async_vpppoe_session_created_cb(vpppoe_setup_pppoe_interface_ctx_t *callback_ctx) {
+ int ret;
+ struct ifreq ifr;
+ struct ap_session *ses = (struct ap_session *)callback_ctx->priv;
struct ppp_t *ppp = container_of(ses, typeof(*ppp), ses);
struct pppoe_conn_t *conn = container_of(ppp, typeof(*conn), ppp);
- uint32_t ifindex = -1;
- char name[16];
- struct ifreq ifr;
- int ret = 0;
- if (!ppp->ses.ipv4) {
- log_error("VPPPOE: VPP require IPv4 peer addr for session routine");
- return -1;
- }
-
- ret = vpppoe_pppoe_session_add_del(conn->addr, &ses->ipv4->peer_addr, conn->sid, 1, &ifindex);
- if (ret) {
- log_error("VPPPOE: Can't create VPP session: %d %02x.%02x.%02x.%02x.%02x.%02x", conn->sid,
- conn->addr[0], conn->addr[1], conn->addr[2], conn->addr[3], conn->addr[4], conn->addr[5]);
- return -1;
- }
-
- snprintf(name, 15, "vppp%d", ifindex);
-
- ret = vpppoe_lcp_tun_add_del(ifindex, name, 1);
- if (ret) {
- log_error("VPPPOE: Can't create VPP lcp TUN pair: sw_if_index %d name %s\n", ifindex, name);
- goto lsp_vpp_err;
- }
-
- ret = vpppoe_set_feature(ifindex, 0, "ip4-not-enabled", "ip4-unicast");
- if (ret) {
- log_error("VPPPOE: Can't set ip4 feature\n");
- goto post_vpp_err;
+ if (callback_ctx->err) {
+ ses->non_dev_ppp_fixup_status = 0;
+ ap_session_terminate(ses, TERM_NAS_ERROR, 0);
+ _free(callback_ctx);
+ return;
}
+
+ ses->non_dev_ppp_fixup_status = 2;
- if (!ppp->ses.ipv6) {
- ret = vpppoe_set_feature(ifindex, 0, "ip6-not-enabled", "ip6-unicast");
- if (ret) {
- log_error("VPPPOE: Can't set ip6 feature\n");
- goto post_vpp_err;
- }
+ if (__sync_and_and_fetch(&callback_ctx->remove_after, 1)) {
+ vpppoe_async_del_pppoe_interface(conn->addr, &ses->ipv4->peer_addr, conn->sid, ses->vpp_sw_if_index, ses->ifname);
+ _free(callback_ctx);
+ return;
}
- ses->vpp_sw_if_index = ifindex;
+ ses->vpp_sw_if_index = callback_ctx->ifindex;
- strncpy(ses->ifname, name, IFNAMSIZ - 1);
+ strncpy(ses->ifname, callback_ctx->ifname, IFNAMSIZ - 1);
memset(&ifr, 0, sizeof(ifr));
strncpy(ifr.ifr_name, ses->ifname, IFNAMSIZ - 1);
ret = net->sock_ioctl(SIOCGIFINDEX, &ifr);
if (ret) {
log_error("VPPPOE: Can't get host ifindex for the interface %s: %s\n", ifr.ifr_name, strerror(errno));
- goto post_vpp_err;
+ // ap_session_terminate(ses, TERM_NAS_ERROR, 0);
+ // free(callback_ctx);
+ return;
}
+
ses->ifindex = ifr.ifr_ifindex;
if (ppp->mtu) {
@@ -322,7 +307,9 @@ int pppoe_create_non_dev_ppp_interface(struct ap_session *ses) {
ret = net->sock_ioctl(SIOCSIFMTU, &ifr);
if (ret) {
log_error("VPPPOE: Can't setup MTU for interface %s value %d: %s\n", ifr.ifr_name, ifr.ifr_mtu, strerror(errno));
- goto post_vpp_err;
+ // ap_session_terminate(ses, TERM_NAS_ERROR, 0);
+ // free(callback_ctx);
+ return;
}
}
@@ -332,9 +319,39 @@ int pppoe_create_non_dev_ppp_interface(struct ap_session *ses) {
log_warn("VPPPOE: Can't setup route %d.%d.%d.%d/32 for interface %d: %s\n",
ses->ipv4->peer_addr >> 24 & 0xff, ses->ipv4->peer_addr >> 16 & 0xff, ses->ipv4->peer_addr >> 8 & 0xff, ses->ipv4->peer_addr & 0xff,
ses->ifindex, strerror(errno));
- goto post_vpp_err;
+ // ap_session_terminate(ses, TERM_NAS_ERROR, 0);
+ // free(callback_ctx);
+ return;
+ }
+
+ free(callback_ctx);
+ ap_session_activate(ses);
+}
+
+int pppoe_create_non_dev_ppp_interface(struct ap_session *ses) {
+ struct ppp_t *ppp = container_of(ses, typeof(*ppp), ses);
+ struct pppoe_conn_t *conn = container_of(ppp, typeof(*conn), ppp);
+ uint32_t ifindex = -1;
+ char name[16];
+ struct ifreq ifr;
+ int ret = 0;
+
+ if (!ppp->ses.ipv4) {
+ log_error("VPPPOE: VPP require IPv4 peer addr for session routine");
+ return -1;
}
+ ses->non_dev_ppp_fixup_status = 1;
+
+ vpppoe_setup_pppoe_interface_ctx_t *callback_ctx = _malloc(sizeof(*callback_ctx));
+ memset(callback_ctx, 0, sizeof(*callback_ctx));
+ callback_ctx->tctx = &conn->ctx;
+ callback_ctx->callback = pppoe_async_vpppoe_session_created_cb;
+ callback_ctx->priv = ses;
+ callback_ctx->remove_after = 0;
+ ses->non_dev_ppp_fixup_priv = callback_ctx;
+ vpppoe_async_add_pppoe_interface(conn->addr, &ses->ipv4->peer_addr, conn->sid, callback_ctx);
+
return 0;
post_vpp_err:
@@ -350,6 +367,7 @@ lsp_vpp_err:
}
ses->vpp_sw_if_index = -1;
+ ses->non_dev_ppp_fixup_status = 0;
return -1;
}
@@ -473,10 +491,6 @@ static struct pppoe_conn_t *allocate_channel(struct pppoe_serv_t *serv, const ui
conn->ctrl.ifname = serv->ifname;
conn->ctrl.mppe = conf_mppe;
- if (serv->is_non_dev_ppp) {
- conn->ctrl.non_dev_ppp_fixup = pppoe_create_non_dev_ppp_interface;
- }
-
if (ppp_max_payload > ETH_DATA_LEN - 8)
conn->ctrl.max_mtu = min(ppp_max_payload, serv->mtu - 8);
@@ -556,6 +570,11 @@ static struct pppoe_conn_t *allocate_channel(struct pppoe_serv_t *serv, const ui
if (conf_session_timeout)
conn->ppp.ses.session_timeout = conf_session_timeout;
+ if (serv->is_non_dev_ppp) {
+ conn->ppp.ses.non_dev_ppp_fixup = pppoe_create_non_dev_ppp_interface;
+ conn->ppp.ses.non_dev_ppp_fixup_status = 0;
+ }
+
triton_context_register(&conn->ctx, conn);
pthread_mutex_lock(&serv->lock);
@@ -2276,7 +2295,7 @@ static void pppoe_init(void)
int fd;
uint8_t *ptr;
- vpppoe_init();
+ // vpppoe_init();
ptr = malloc(SID_MAX/8);
memset(ptr, 0xff, SID_MAX/8);
diff --git a/accel-pppd/ctrl/pppoe/vpppoe.c b/accel-pppd/ctrl/pppoe/vpppoe.c
index 4dea5cd..c5fdcf7 100644
--- a/accel-pppd/ctrl/pppoe/vpppoe.c
+++ b/accel-pppd/ctrl/pppoe/vpppoe.c
@@ -6,6 +6,13 @@
#include <vapi/feature.api.vapi.h>
#include <linux/if_ether.h>
+#include <pthread.h>
+
+#include <memory.h>
+#include <stdio.h>
+
+#include "events.h"
+#include "triton.h"
#include "vpppoe.h"
@@ -15,172 +22,590 @@ DEFINE_VAPI_MSG_IDS_PPPOE_API_JSON
DEFINE_VAPI_MSG_IDS_LCP_API_JSON
DEFINE_VAPI_MSG_IDS_FEATURE_API_JSON
-static struct vpp_connect_t {
- vapi_ctx_t vapi;
- int rfcounter;
+static uint32_t sc_fallback_timer = 1000;
+
+/* rcbc - Reply CallBack Counter. Retry postponed calls if waiting less then sc_fallback_at_rcbc at curent time */
+static int sc_fallback_at_rcbc = 1024;
+static int sc_vpp_queue_size = 2048;
+
+static int sc_teardown_on_max_queue = 512;
+
+static int sc_non_lcp_mode = 0;
+
+static struct vpp_connect_t
+{
+ vapi_ctx_t vapi;
+ int rfcounter;
+
+ int rcbc;
+
+ pthread_mutex_t lock_vpp;
+
+ struct triton_context_t tctx;
+ struct triton_md_handler_t vapi_read_hnd;
+
+ struct triton_timer_t timer;
+
+ /* retry fallback lists */
+ uint32_t retry_del_count;
+ struct list_head retry_del_list;
} vpp_connect;
const char vpp_app_name[] = "accel-vpppoe";
+static int vpppoe_read_events(struct triton_md_handler_t *h);
+static void vpppoe_disconnect_from_vpp();
+static void vpppoe_timer(struct triton_timer_t *t);
+
+static void vpppoe_fallback_allocate_and_add_postponed_pppoe_del(uint8_t *client_mac, in_addr_t *client_ip, uint16_t session_id);
+
static void vpppoe_connect_to_vpp()
{
- vapi_error_e verr = vapi_ctx_alloc(&vpp_connect.vapi);
+ int fd = -1;
+ vapi_error_e verr = vapi_ctx_alloc(&vpp_connect.vapi);
- if (verr != VAPI_OK) {
- vpp_connect.vapi = NULL;
+ if (verr != VAPI_OK)
+ {
+ vpp_connect.vapi = NULL;
return;
}
- verr = vapi_connect_ex(vpp_connect.vapi, vpp_app_name, NULL, 32, 32, VAPI_MODE_BLOCKING, true, true);
+ verr = vapi_connect_ex(vpp_connect.vapi, vpp_app_name, NULL, sc_vpp_queue_size, sc_vpp_queue_size, VAPI_MODE_NONBLOCKING, true, true);
+ if (verr != VAPI_OK)
+ {
+ vapi_ctx_free(vpp_connect.vapi);
+ vpp_connect.vapi = NULL;
+ return;
+ }
- if (verr != VAPI_OK) {
- vapi_ctx_free(vpp_connect.vapi);
- vpp_connect.vapi = NULL;
+ verr = vapi_get_fd(vpp_connect.vapi, &fd);
+ if (verr != VAPI_OK)
+ {
+ vapi_disconnect_from_vpp(vpp_connect.vapi);
+ vapi_ctx_free(vpp_connect.vapi);
+ vpp_connect.vapi = NULL;
+ return;
}
+
+ memset(&vpp_connect.tctx, 0, sizeof(vpp_connect.tctx));
+ memset(&vpp_connect.vapi_read_hnd, 0, sizeof(vpp_connect.vapi_read_hnd));
+
+ vpp_connect.vapi_read_hnd.fd = fd;
+ vpp_connect.vapi_read_hnd.read = vpppoe_read_events;
+
+ // TODO: add options for triton ctx aka close and free
+
+ vpp_connect.timer.expire = vpppoe_timer;
+ vpp_connect.timer.period = sc_fallback_timer;
+
+ // TODO: add checks
+ triton_context_register(&vpp_connect.tctx, NULL);
+ triton_md_register_handler(&vpp_connect.tctx, &vpp_connect.vapi_read_hnd);
+ triton_md_enable_handler(&vpp_connect.vapi_read_hnd, MD_MODE_READ);
+ triton_timer_add(&vpp_connect.tctx, &vpp_connect.timer, 0);
+ triton_context_wakeup(&vpp_connect.tctx);
}
-static void vpppoe_disconnect_from_vpp()
+void vpppoe_disconnect_from_vpp()
{
- vapi_disconnect(vpp_connect.vapi);
- vapi_ctx_free(vpp_connect.vapi);
- vpp_connect.vapi = NULL;
-}
+ triton_timer_del(&vpp_connect.timer);
+ triton_md_unregister_handler(&vpp_connect.vapi_read_hnd, 0);
+ triton_context_unregister(&vpp_connect.tctx);
-void vpppoe_init() {
+ vapi_disconnect(vpp_connect.vapi);
+ vapi_ctx_free(vpp_connect.vapi);
vpp_connect.vapi = NULL;
- vpp_connect.rfcounter = 0;
-
- memset(&vpp_connect, 0, sizeof(vpp_connect));
}
void vpppoe_get()
{
int rfc = __sync_fetch_and_add(&vpp_connect.rfcounter, 1);
- if (!rfc)
- vpppoe_connect_to_vpp();
+ if (!rfc)
+ vpppoe_connect_to_vpp();
}
void vpppoe_put()
{
int rfc = __sync_sub_and_fetch(&vpp_connect.rfcounter, 1);
- if (!rfc)
- vpppoe_disconnect_from_vpp();
+ if (!rfc)
+ vpppoe_disconnect_from_vpp();
+}
+
+static vapi_error_e vpppoe_set_feature_callback(struct vapi_ctx_s *ctx,
+ void *callback_ctx,
+ vapi_error_e rv,
+ bool is_last,
+ vapi_payload_feature_enable_disable_reply *reply)
+{
+ if (is_last)
+ vpp_connect.rcbc -= 1;
+ return VAPI_OK;
}
-static vapi_error_e vpppoe_session_add_reply_callback(struct vapi_ctx_s *ctx,
- void *callback_ctx,
- vapi_error_e rv,
- bool is_last,
- vapi_payload_pppoe_add_del_session_reply *reply)
+int vpppoe_set_feature(uint32_t ifindex, int is_enabled, const char *feature, const char *arc)
{
- if (callback_ctx != NULL && reply != NULL) {
- uint32_t *sw = (uint32_t *)(callback_ctx);
- *sw = reply->sw_if_index;
- }
+ vapi_error_e err;
+ vapi_msg_feature_enable_disable *req = vapi_alloc_feature_enable_disable(vpp_connect.vapi);
+ if (req == NULL)
+ return -1;
- return VAPI_OK;
+ strncpy((char *)req->payload.feature_name, feature, 63);
+ strncpy((char *)req->payload.arc_name, arc, 63);
+ req->payload.sw_if_index = ifindex;
+ req->payload.enable = is_enabled;
+
+ pthread_mutex_lock(&vpp_connect.lock_vpp);
+ vpp_connect.rcbc += 1;
+ err = vapi_feature_enable_disable(vpp_connect.vapi, req, vpppoe_set_feature_callback, NULL);
+ pthread_mutex_unlock(&vpp_connect.lock_vpp);
+
+ return err;
}
-int vpppoe_pppoe_session_add_del(uint8_t *client_mac, in_addr_t *client_ip, uint16_t session_id, int is_add, uint32_t *out_ifindex)
+typedef struct vpppoe_add_pppoe_interface_cb_ctx_t
{
- vapi_msg_pppoe_add_del_session *req = vapi_alloc_pppoe_add_del_session(vpp_connect.vapi);
+ uint8_t client_mac[ETH_ALEN];
+ in_addr_t client_ip;
+ uint16_t session_id;
+ vpppoe_setup_pppoe_interface_ctx_t *callback_ctx;
+} vpppoe_add_pppoe_interface_cb_ctx_t;
+
+int vpppoe_async_add_pppoe_interface_with_callback(vpppoe_add_pppoe_interface_cb_ctx_t *vppoe_callback_ctx);
+static void vpppoe_a_add_lcp_pair_triton(vpppoe_add_pppoe_interface_cb_ctx_t *vpppoe_callback_ctx);
+
+static void vpppoe_a_setup_features_triton(vpppoe_setup_pppoe_interface_ctx_t *vpppoe_callback_ctx) {
+ vpppoe_set_feature(vpppoe_callback_ctx->ifindex, 0, "ip4-not-enabled", "ip4-unicast");
+ vpppoe_set_feature(vpppoe_callback_ctx->ifindex, 0, "ip6-not-enabled", "ip6-unicast");
+ triton_context_call(vpppoe_callback_ctx->tctx, (triton_event_func)vpppoe_callback_ctx->callback, vpppoe_callback_ctx);
+}
+
+static vapi_error_e vpppoe_a_lcp_callback(struct vapi_ctx_s *ctx,
+ void *callback_ctx,
+ vapi_error_e rv,
+ bool is_last,
+ vapi_payload_lcp_itf_pair_add_del_reply *reply)
+{
+
+ if (is_last)
+ vpp_connect.rcbc -= 1;
+
+ vpppoe_add_pppoe_interface_cb_ctx_t *vpppoe_callback_ctx = (vpppoe_add_pppoe_interface_cb_ctx_t *)callback_ctx;
+
+ if (callback_ctx != NULL && reply != NULL && rv == VAPI_OK)
+ {
+ triton_context_call(&vpp_connect.tctx, (triton_event_func)vpppoe_a_setup_features_triton, vpppoe_callback_ctx->callback_ctx);
+ free(vpppoe_callback_ctx);
+ } else {
+ fprintf(stderr, "\e[1;31m --| %s unexpected issue ctx %p reply %p rv %d rcbc %d\e[0m\n", __FUNCTION__, callback_ctx, reply, rv, vpp_connect.rcbc);
+ if (vpppoe_callback_ctx != NULL) {
+
+ fprintf(stderr, "\e[1;31m --| %s ISSUE during lcp creation sid %d rcbc %d\e[0m\n", __FUNCTION__, vpppoe_callback_ctx->session_id, vpp_connect.rcbc);
+
+ vpppoe_fallback_allocate_and_add_postponed_pppoe_del(vpppoe_callback_ctx->client_mac, &vpppoe_callback_ctx->client_ip, vpppoe_callback_ctx->session_id);
+
+ vpppoe_callback_ctx->callback_ctx->err = rv;
+ triton_context_call(vpppoe_callback_ctx->callback_ctx->tctx, (triton_event_func)vpppoe_callback_ctx->callback_ctx->callback, vpppoe_callback_ctx->callback_ctx);
+ free(vpppoe_callback_ctx);
+ }
+ }
+ return rv;
+}
+
+void vpppoe_a_add_lcp_pair_triton(vpppoe_add_pppoe_interface_cb_ctx_t *vpppoe_callback_ctx) {
+ vapi_error_e err;
+ vapi_msg_lcp_itf_pair_add_del *req = vapi_alloc_lcp_itf_pair_add_del(vpp_connect.vapi);
+
+ // TODO check logic
if (req == NULL)
+ {
+ fprintf(stderr, "\e[1;31m --| %s can't allocate lcp add request ifindex %d rcbc %d\e[0m\n", __FUNCTION__, vpppoe_callback_ctx->callback_ctx->ifindex, vpp_connect.rcbc);
+ return;
+ }
+
+ snprintf((char *)req->payload.host_if_name, 15, "vppp%d", vpppoe_callback_ctx->callback_ctx->ifindex);
+ strncpy(vpppoe_callback_ctx->callback_ctx->ifname, (char *)req->payload.host_if_name, 15);
+ // strncpy((char *)req->payload.host_if_name, host_if_name, 15);
+ req->payload.sw_if_index = vpppoe_callback_ctx->callback_ctx->ifindex;
+ req->payload.host_if_type = LCP_API_ITF_HOST_TUN;
+ req->payload.is_add = 1;
+
+ pthread_mutex_lock(&vpp_connect.lock_vpp);
+ vpp_connect.rcbc += 1;
+ err = vapi_lcp_itf_pair_add_del(vpp_connect.vapi, req, vpppoe_a_lcp_callback, vpppoe_callback_ctx);
+ pthread_mutex_unlock(&vpp_connect.lock_vpp);
+
+ if (err != VAPI_OK)
+ {
+ if (vpppoe_callback_ctx != NULL)
+ {
+ fprintf(stderr, "\e[1;31m --| %s can't send lcp pair creation request sid %d rcbc %d\e[0m\n", __FUNCTION__, vpppoe_callback_ctx->session_id, vpp_connect.rcbc);
+
+ vpppoe_fallback_allocate_and_add_postponed_pppoe_del(vpppoe_callback_ctx->client_mac, &vpppoe_callback_ctx->client_ip, vpppoe_callback_ctx->session_id);
+
+ vpppoe_callback_ctx->callback_ctx->err = err;
+ triton_context_call(vpppoe_callback_ctx->callback_ctx->tctx, (triton_event_func)vpppoe_callback_ctx->callback_ctx->callback, vpppoe_callback_ctx->callback_ctx);
+ free(vpppoe_callback_ctx);
+ }
+ }
+}
+
+static vapi_error_e vpppoe_a_session_add_reply_callback(struct vapi_ctx_s *ctx,
+ void *callback_ctx,
+ vapi_error_e rv,
+ bool is_last,
+ vapi_payload_pppoe_add_del_session_reply *reply)
+{
+
+ if (is_last)
+ vpp_connect.rcbc -= 1;
+
+ vpppoe_add_pppoe_interface_cb_ctx_t *vpppoe_callback_ctx = (vpppoe_add_pppoe_interface_cb_ctx_t *)callback_ctx;
+ if (callback_ctx != NULL && reply != NULL && rv == VAPI_OK)
+ {
+ vpppoe_callback_ctx->callback_ctx->ifindex = reply->sw_if_index;
+ if (sc_non_lcp_mode) {
+ triton_context_call(&vpp_connect.tctx, (triton_event_func)vpppoe_a_setup_features_triton, vpppoe_callback_ctx->callback_ctx);
+ free(vpppoe_callback_ctx);
+ } else {
+ triton_context_call(&vpp_connect.tctx, (triton_event_func)vpppoe_a_add_lcp_pair_triton, vpppoe_callback_ctx);
+ }
+ fprintf(stderr, "\e[1;32m --| %s add pppoe session ifindex %d rcbc %d \e[0m\n", __FUNCTION__, vpppoe_callback_ctx->callback_ctx->ifindex, vpp_connect.rcbc);
+ } else {
+ fprintf(stderr, "\e[1;31m --| %s unexpected issue ctx %p reply %p rv %d rcbc %d\e[0m\n", __FUNCTION__, callback_ctx, reply, rv, vpp_connect.rcbc);
+
+ if (vpppoe_callback_ctx != NULL) {
+
+ vpppoe_callback_ctx->callback_ctx->err = rv;
+ triton_context_call(vpppoe_callback_ctx->callback_ctx->tctx, (triton_event_func)vpppoe_callback_ctx->callback_ctx->callback, vpppoe_callback_ctx->callback_ctx);
+ free(vpppoe_callback_ctx);
+ }
+ }
+
+ return rv;
+}
+
+int vpppoe_async_add_pppoe_interface_with_callback(vpppoe_add_pppoe_interface_cb_ctx_t *vppoe_callback_ctx) {
+ vapi_error_e err;
+
+ vapi_msg_pppoe_add_del_session *req = vapi_alloc_pppoe_add_del_session(vpp_connect.vapi);
+ if (req == NULL) {
+ fprintf(stderr, "\e[1;31m --| %s can't allocate pppoe add request session %d rcbc %d\e[0m\n", __FUNCTION__, vppoe_callback_ctx->session_id, vpp_connect.rcbc);
+
return -1;
+ }
+
+ vppoe_callback_ctx->callback_ctx->err = 0;
+ vppoe_callback_ctx->callback_ctx->ifindex = 0;
req->payload.client_ip.af = ADDRESS_IP4;
- memcpy(req->payload.client_ip.un.ip4, client_ip, sizeof(*client_ip));
- memcpy(req->payload.client_mac, client_mac, ETH_ALEN);
+ memcpy(req->payload.client_ip.un.ip4, &vppoe_callback_ctx->client_ip, sizeof(vppoe_callback_ctx->client_ip));
+ memcpy(req->payload.client_mac, vppoe_callback_ctx->client_mac, ETH_ALEN);
- req->payload.is_add = is_add;
- req->payload.session_id = session_id;
+ req->payload.is_add = 1;
+ req->payload.session_id = vppoe_callback_ctx->session_id;
req->payload.disable_fib = 1;
- return vapi_pppoe_add_del_session(vpp_connect.vapi, req, vpppoe_session_add_reply_callback, out_ifindex);
+ pthread_mutex_lock(&vpp_connect.lock_vpp);
+ vpp_connect.rcbc += 1;
+ err = vapi_pppoe_add_del_session(vpp_connect.vapi, req, vpppoe_a_session_add_reply_callback, vppoe_callback_ctx);
+ pthread_mutex_unlock(&vpp_connect.lock_vpp);
+
+ if (err != VAPI_OK) {
+ if (vppoe_callback_ctx != NULL) {
+ fprintf(stderr, "\e[1;31m --| %s can't send pppoe creation request sid %d rcbc %d\e[0m\n", __FUNCTION__, vppoe_callback_ctx->session_id, vpp_connect.rcbc);
+ vppoe_callback_ctx->callback_ctx->err = err;
+ triton_context_call(vppoe_callback_ctx->callback_ctx->tctx, (triton_event_func)vppoe_callback_ctx->callback_ctx->callback, vppoe_callback_ctx->callback_ctx);
+ free(vppoe_callback_ctx);
+ }
+ }
+
+ return err;
}
-typedef struct {
+int vpppoe_async_add_pppoe_interface(uint8_t *client_mac, in_addr_t *client_ip, uint16_t session_id, vpppoe_setup_pppoe_interface_ctx_t *callback_ctx)
+{
+ if (vpp_connect.rcbc >= sc_teardown_on_max_queue) {
+ fprintf(stderr, "\e[1;31m --| %s TOO much request sid %d rcbc %d\e[0m\n", __FUNCTION__, session_id, vpp_connect.rcbc);
+ callback_ctx->err = -100;
+ triton_context_call(callback_ctx->tctx, (triton_event_func)callback_ctx->callback, callback_ctx);
+ return -100;
+ }
+
+ vpppoe_add_pppoe_interface_cb_ctx_t *vpppoe_callback_ctx = malloc(sizeof(*vpppoe_callback_ctx));
+ memset(vpppoe_callback_ctx, 0, sizeof(*vpppoe_callback_ctx));
+
+ memcpy(&vpppoe_callback_ctx->client_ip, client_ip, sizeof(*client_ip));
+ memcpy(vpppoe_callback_ctx->client_mac, client_mac, ETH_ALEN);
+ vpppoe_callback_ctx->session_id = session_id;
+ vpppoe_callback_ctx->callback_ctx = callback_ctx;
+
+ return vpppoe_async_add_pppoe_interface_with_callback(vpppoe_callback_ctx);
+}
+
+typedef struct vpppoe_del_pppoe_interface_cb_ctx_t
+{
+ uint8_t mac[ETH_ALEN];
+ in_addr_t client_ip;
+ uint16_t session_id;
uint32_t ifindex;
- char *name;
- size_t len;
-} vpppoe_ifname_by_ifindex_t;
-
-static vapi_error_e vpppoe_ifname_by_ifindex_reply_callback(struct vapi_ctx_s *ctx,
- void *callback_ctx,
- vapi_error_e rv,
- bool is_last,
- vapi_payload_sw_interface_details *reply)
-{
- if (reply && callback_ctx != NULL) {
- vpppoe_ifname_by_ifindex_t *ifname = (vpppoe_ifname_by_ifindex_t *)callback_ctx;
- if (ifname->ifindex == reply->sw_if_index) {
- size_t len = ifname->len > 63 ? 63 : ifname->len;
- strncpy(ifname->name, (const char *)reply->interface_name, len);
+ char ifname[16];
+
+ /* retry fallback */
+ uint32_t retrys;
+ struct list_head entry;
+ uint32_t retry_at; /* 0 - from lcp delete routine, 1 - from pppoe session delete routine */
+} vpppoe_del_pppoe_interface_cb_ctx_t;
+
+
+static void vpppoe_async_del_pppoe_interface_with_callback(vpppoe_del_pppoe_interface_cb_ctx_t *callback_ctx);
+static void vpppoe_a_del_session_triton(vpppoe_del_pppoe_interface_cb_ctx_t *vpppoe_callback_ctx);
+
+static void vpppoe_retry_del_later(vpppoe_del_pppoe_interface_cb_ctx_t *ctx) {
+ ctx->retrys += 1;
+ vpp_connect.retry_del_count += 1;
+ list_add_tail(&ctx->entry, &vpp_connect.retry_del_list);
+}
+
+void vpppoe_fallback_allocate_and_add_postponed_pppoe_del(uint8_t *client_mac, in_addr_t *client_ip, uint16_t session_id) {
+
+ vpppoe_del_pppoe_interface_cb_ctx_t *callback_ctx = malloc(sizeof(*callback_ctx));
+ memset(callback_ctx, 0, sizeof(*callback_ctx));
+ memcpy(&callback_ctx->mac, client_mac, ETH_ALEN);
+ memcpy(&callback_ctx->client_ip, client_ip, sizeof(*client_ip));
+ callback_ctx->session_id = session_id;
+
+ callback_ctx->retry_at = 1;
+ vpppoe_retry_del_later(callback_ctx);
+}
+
+static void vpppoe_launch_del_retrys(uint32_t count) {
+ if (vpp_connect.retry_del_count) {
+
+ uint32_t i = 0;
+ struct list_head *pos, *n;
+ vpppoe_del_pppoe_interface_cb_ctx_t *callback_ctx;
+
+ list_for_each_safe(pos, n, &vpp_connect.retry_del_list) {
+ callback_ctx = list_entry(pos, typeof(*callback_ctx), entry);
+
+ vpp_connect.retry_del_count -= 1;
+ list_del(&callback_ctx->entry);
+
+ fprintf(stderr, "\033[104m --| %s RETRY DEL %d ifname %16s rcbc %d retry %d\e[0m\n", __FUNCTION__, callback_ctx->ifindex, callback_ctx->ifname, vpp_connect.rcbc, vpp_connect.retry_del_count);
+
+ if (callback_ctx->retry_at == 0)
+ vpppoe_async_del_pppoe_interface_with_callback(callback_ctx);
+ else
+ vpppoe_a_del_session_triton(callback_ctx);
+
+ ++i;
+ if (i > count) {
+ break;
+ }
}
}
+}
+
+static vapi_error_e vpppoe_a_del_session_add_reply_callback(struct vapi_ctx_s *ctx,
+ void *callback_ctx,
+ vapi_error_e rv,
+ bool is_last,
+ vapi_payload_pppoe_add_del_session_reply *reply)
+{
+ if (is_last)
+ vpp_connect.rcbc -= 1;
+
+ vpppoe_del_pppoe_interface_cb_ctx_t *vpppoe_callback_ctx = (vpppoe_del_pppoe_interface_cb_ctx_t *)callback_ctx;
+ if (callback_ctx && rv == VAPI_OK) {
+ fprintf(stderr, "\e[1;33m --| %s del pppoe %p %p %d ifindex %d ifname %s rcbc %d \e[0m\n", __FUNCTION__, callback_ctx, reply, rv, vpppoe_callback_ctx->ifindex, vpppoe_callback_ctx->ifname, vpp_connect.rcbc);
+ free(vpppoe_callback_ctx);
+
+ } else {
+ fprintf(stderr, "\e[1;31m --| %s some issue in pppoe del - adding to the retry list - responce %d ifindex %d ifname %16s rcbc %d retrys %d\e[0m\n", __FUNCTION__, rv, vpppoe_callback_ctx->ifindex, vpppoe_callback_ctx->ifname, vpp_connect.rcbc, vpp_connect.retry_del_count);
+ vpppoe_callback_ctx->retry_at = 1;
+ vpppoe_retry_del_later(vpppoe_callback_ctx);
+
+ }
return VAPI_OK;
}
-int vpppoe_get_sw_ifname_by_index(uint32_t sw_ifindex, char *ifname, size_t len)
-{
- vpppoe_ifname_by_ifindex_t ctx;
+void vpppoe_a_del_session_triton(vpppoe_del_pppoe_interface_cb_ctx_t *vpppoe_callback_ctx) {
- ctx.ifindex = sw_ifindex;
- ctx.name = ifname;
- ctx.len = len;
+ vapi_error_e err;
- vapi_msg_sw_interface_dump *req = vapi_alloc_sw_interface_dump(vpp_connect.vapi, 0);
- if (req == NULL)
- return -1;
+ if (vpp_connect.rcbc >= sc_teardown_on_max_queue) {
+ fprintf(stderr, "\e[1;31m --| %s TOO much DEL LCP request - add to postpone list sid %d ifindex %d rcbc %d\e[0m\n", __FUNCTION__, vpppoe_callback_ctx->session_id, vpppoe_callback_ctx->ifindex, vpp_connect.rcbc);
+ vpppoe_callback_ctx->retry_at = 1;
+ vpppoe_retry_del_later(vpppoe_callback_ctx);
+ return;
+ }
- req->payload.sw_if_index = sw_ifindex;
+ vapi_msg_pppoe_add_del_session *req = vapi_alloc_pppoe_add_del_session(vpp_connect.vapi);
+ if (req == NULL) {
+ fprintf(stderr, "\e[1;31m --| %s can't allocate pppoe delete request ifindex %d ifname %16s rcbc %d\e[0m\n", __FUNCTION__, vpppoe_callback_ctx->ifindex, vpppoe_callback_ctx->ifname, vpp_connect.rcbc);
+ return;
+ }
- return vapi_sw_interface_dump(vpp_connect.vapi, req, vpppoe_ifname_by_ifindex_reply_callback, &ctx);
-}
+ req->payload.client_ip.af = ADDRESS_IP4;
+ memcpy(req->payload.client_ip.un.ip4, &vpppoe_callback_ctx->client_ip, sizeof(vpppoe_callback_ctx->client_ip));
+ memcpy(req->payload.client_mac, &vpppoe_callback_ctx->mac, ETH_ALEN);
+ req->payload.is_add = 0;
+ req->payload.session_id = vpppoe_callback_ctx->session_id;
+ // req->payload.disable_fib = 1;
-static vapi_error_e vpppoe_lsc_callback(struct vapi_ctx_s *ctx,
+
+ pthread_mutex_lock(&vpp_connect.lock_vpp);
+ vpp_connect.rcbc += 1;
+ err = vapi_pppoe_add_del_session(vpp_connect.vapi, req, vpppoe_a_del_session_add_reply_callback, vpppoe_callback_ctx);
+ pthread_mutex_unlock(&vpp_connect.lock_vpp);
+
+ if (err != VAPI_OK) {
+ fprintf(stderr, "\e[1;31m --| %s cant SEND pppoe del - adding to the retry list - responce %d ifindex %d ifname %16s rcbc %d retrys %d\e[0m\n", __FUNCTION__, err, vpppoe_callback_ctx->ifindex, vpppoe_callback_ctx->ifname, vpp_connect.rcbc, vpp_connect.retry_del_count);
+ vpppoe_callback_ctx->retry_at = 1;
+ vpppoe_retry_del_later(vpppoe_callback_ctx);
+ }
+}
+
+static vapi_error_e vpppoe_a_del_lcp_callback(struct vapi_ctx_s *ctx,
void *callback_ctx,
vapi_error_e rv,
bool is_last,
vapi_payload_lcp_itf_pair_add_del_reply *reply)
{
+
+ if (is_last)
+ vpp_connect.rcbc -= 1;
+
+ vpppoe_del_pppoe_interface_cb_ctx_t *vpppoe_callback_ctx = (vpppoe_del_pppoe_interface_cb_ctx_t *)callback_ctx;
+
+ if (callback_ctx != NULL && rv == VAPI_OK)
+ {
+ triton_context_call(&vpp_connect.tctx, (triton_event_func)vpppoe_a_del_session_triton, vpppoe_callback_ctx);
+
+ } else {
+ fprintf(stderr, "\e[1;31m --| %s unexpected issue ctx %p reply %p rv %d rcbc %d\e[0m\n", __FUNCTION__, callback_ctx, reply, rv, vpp_connect.rcbc);
+ if (vpppoe_callback_ctx != NULL) {
+ fprintf(stderr, "\e[1;31m --| %s some issue in lcp del - adding to the retry list - responce %d ifindex %d ifname %16s rcbc %d retrys %d\e[0m\n", __FUNCTION__, rv, vpppoe_callback_ctx->ifindex, vpppoe_callback_ctx->ifname, vpp_connect.rcbc, vpp_connect.retry_del_count);
+ vpppoe_callback_ctx->retry_at = 0;
+ vpppoe_retry_del_later(vpppoe_callback_ctx);
+
+ }
+ }
+
return VAPI_OK;
}
-int vpppoe_lcp_tun_add_del(uint32_t ifindex, const char *host_if_name, int is_add)
-{
- vapi_msg_lcp_itf_pair_add_del* req = vapi_alloc_lcp_itf_pair_add_del(vpp_connect.vapi);
+void vpppoe_async_del_pppoe_interface_with_callback(vpppoe_del_pppoe_interface_cb_ctx_t *callback_ctx) {
+
+ vapi_error_e err;
+
+ if (vpp_connect.rcbc >= sc_teardown_on_max_queue) {
+ fprintf(stderr, "\e[1;31m --| %s TOO much DEL request - add to postpone list sid %d ifindex %d rcbc %d\e[0m\n", __FUNCTION__, callback_ctx->session_id, callback_ctx->ifindex, vpp_connect.rcbc);
+ callback_ctx->retry_at = 0;
+ vpppoe_retry_del_later(callback_ctx);
+ return;
+ }
+
+ vapi_msg_lcp_itf_pair_add_del *req = vapi_alloc_lcp_itf_pair_add_del(vpp_connect.vapi);
+
if (req == NULL)
- return -1;
+ {
+ fprintf(stderr, "\e[1;31m --| %s can't allocate lcp delete request ifindex %d ifname %16s rcbc %d\e[0m\n", __FUNCTION__,
+ callback_ctx->ifindex, callback_ctx->ifname, vpp_connect.rcbc);
+ return;
+ }
- strncpy((char *)req->payload.host_if_name, host_if_name, 15);
- req->payload.sw_if_index = ifindex;
+ strncpy((char *)req->payload.host_if_name, callback_ctx->ifname, 15);
+ req->payload.sw_if_index = callback_ctx->ifindex;
req->payload.host_if_type = LCP_API_ITF_HOST_TUN;
- req->payload.is_add = is_add;
+ req->payload.is_add = 0;
+
+
+ pthread_mutex_lock(&vpp_connect.lock_vpp);
+ vpp_connect.rcbc += 1;
+ err = vapi_lcp_itf_pair_add_del(vpp_connect.vapi, req, vpppoe_a_del_lcp_callback, callback_ctx);
+ pthread_mutex_unlock(&vpp_connect.lock_vpp);
+
+ if (err != VAPI_OK) {
+ fprintf(stderr, "\e[1;31m --| %s cant SEND lcp del - adding to the retry list - responce %d ifindex %d ifname %16s rcbc %d retrys %d\e[0m\n", __FUNCTION__, err, callback_ctx->ifindex, callback_ctx->ifname, vpp_connect.rcbc, vpp_connect.retry_del_count);
+ callback_ctx->retry_at = 0;
+ vpppoe_retry_del_later(callback_ctx);
+ }
+}
+
+void vpppoe_async_del_pppoe_interface(uint8_t *client_mac, in_addr_t *client_ip, uint16_t session_id, uint32_t ifindex, char *ifname) {
+ vpppoe_del_pppoe_interface_cb_ctx_t *callback_ctx = malloc(sizeof(*callback_ctx));
+ memset(callback_ctx, 0, sizeof(*callback_ctx));
+ memcpy(&callback_ctx->mac, client_mac, ETH_ALEN);
+ memcpy(&callback_ctx->client_ip, client_ip, sizeof(*client_ip));
+ callback_ctx->session_id = session_id;
- return vapi_lcp_itf_pair_add_del(vpp_connect.vapi, req, vpppoe_lsc_callback, NULL);
+ callback_ctx->ifindex = ifindex;
+ strncpy((char *)&callback_ctx->ifname, ifname, 15);
+
+ if (sc_non_lcp_mode) {
+ vpppoe_a_del_session_triton(callback_ctx);
+ } else {
+ vpppoe_async_del_pppoe_interface_with_callback(callback_ctx);
+ }
}
-static vapi_error_e vpppoe_set_feature_callback(struct vapi_ctx_s *ctx,
- void *callback_ctx,
- vapi_error_e rv,
- bool is_last,
- vapi_payload_feature_enable_disable_reply *reply)
+
+/* NOTE DIRTY HACKS ALL AROUND! */
+int vpppoe_read_events(struct triton_md_handler_t *h)
{
- return VAPI_OK;
+ pthread_mutex_lock(&vpp_connect.lock_vpp);
+ vapi_dispatch(vpp_connect.vapi);
+ pthread_mutex_unlock(&vpp_connect.lock_vpp);
+
+ return 0;
}
-int vpppoe_set_feature(uint32_t ifindex, int is_enabled, const char *feature, const char *arc)
+void vpppoe_timer(struct triton_timer_t *t) {
+
+ if (vpp_connect.rcbc < sc_fallback_at_rcbc) {
+ vpppoe_launch_del_retrys(sc_teardown_on_max_queue);
+ }
+ /* HACK */
+ vpppoe_read_events(NULL);
+}
+
+static void vpppoe_load_config(void)
{
- vapi_msg_feature_enable_disable* req = vapi_alloc_feature_enable_disable(vpp_connect.vapi);
- if (req == NULL)
- return -1;
+ char *opt;
+
+ opt = conf_get_opt("vpp", "queue_size");
+ if (opt)
+ sc_vpp_queue_size = atoi(opt);
+
+ opt = conf_get_opt("vpp", "fallback_timer");
+ if (opt)
+ sc_fallback_timer = atoi(opt);
+
+ opt = conf_get_opt("vpp", "teardown_at_max_requests");
+ if (opt)
+ sc_fallback_at_rcbc = atoi(opt);
+
+ opt = conf_get_opt("vpp", "fallback_requests");
+ if (opt)
+ sc_teardown_on_max_queue = atoi(opt);
+
+ opt = conf_get_opt("vpp", "non_lcp_mode");
+ if (opt)
+ sc_non_lcp_mode = atoi(opt);
+}
- strncpy((char *)req->payload.feature_name, feature, 63);
- strncpy((char *)req->payload.arc_name, arc, 63);
- req->payload.sw_if_index = ifindex;
- req->payload.enable = is_enabled;
+static void vpppoe_init()
+{
+ memset(&vpp_connect, 0, sizeof(vpp_connect));
+ INIT_LIST_HEAD(&vpp_connect.retry_del_list);
+ pthread_mutex_init(&vpp_connect.lock_vpp, NULL);
+
+ vpppoe_load_config();
- return vapi_feature_enable_disable(vpp_connect.vapi, req, vpppoe_set_feature_callback, NULL);
+ triton_event_register_handler(EV_CONFIG_RELOAD, (triton_event_func)vpppoe_load_config);
}
+
+DEFINE_INIT(20, vpppoe_init); \ No newline at end of file
diff --git a/accel-pppd/ctrl/pppoe/vpppoe.h b/accel-pppd/ctrl/pppoe/vpppoe.h
index 5b41070..d56bd74 100644
--- a/accel-pppd/ctrl/pppoe/vpppoe.h
+++ b/accel-pppd/ctrl/pppoe/vpppoe.h
@@ -1,13 +1,26 @@
#ifndef VPPPOE_H
#define VPPPOE_H
-void vpppoe_init();
void vpppoe_get();
void vpppoe_put();
-int vpppoe_pppoe_session_add_del(uint8_t *client_mac, in_addr_t *client_ip, uint16_t session_id, int is_add, uint32_t *out_ifindex);
-int vpppoe_get_sw_ifname_by_index(uint32_t sw_ifindex, char *ifname, size_t len);
-int vpppoe_lcp_tun_add_del(uint32_t ifindex, const char *host_if_name, int is_add);
-int vpppoe_set_feature(uint32_t ifindex, int is_enabled, const char *feature, const char *arc);
+struct triton_context_t;
+
+typedef struct vpppoe_setup_pppoe_interface_ctx_t
+{
+ struct triton_context_t *tctx;
+ void (*callback)(struct vpppoe_setup_pppoe_interface_ctx_t *ctx);
+ void *priv;
+
+ int remove_after;
+
+ /* Output values */
+ int err; /* 0 - OK */
+ uint32_t ifindex;
+ char ifname[16];
+} vpppoe_setup_pppoe_interface_ctx_t;
+
+int vpppoe_async_add_pppoe_interface(uint8_t *client_mac, in_addr_t *client_ip, uint16_t session_id, vpppoe_setup_pppoe_interface_ctx_t *callback_ctx);
+void vpppoe_async_del_pppoe_interface(uint8_t *client_mac, in_addr_t *client_ip, uint16_t session_id, uint32_t ifindex, char *ifname);
#endif /* VPPPOE_H */ \ No newline at end of file
diff --git a/accel-pppd/include/ap_session.h b/accel-pppd/include/ap_session.h
index c032c3f..61da292 100644
--- a/accel-pppd/include/ap_session.h
+++ b/accel-pppd/include/ap_session.h
@@ -58,7 +58,6 @@ struct ap_ctrl {
void (*started)(struct ap_session*);
void (*finished)(struct ap_session *);
int (*terminate)(struct ap_session *, int hard);
- int (*non_dev_ppp_fixup)(struct ap_session*);
};
struct ap_private
@@ -122,6 +121,9 @@ struct ap_session
uint64_t acct_tx_bytes_i;
int acct_start;
+ int (*non_dev_ppp_fixup)(struct ap_session*);
+ int non_dev_ppp_fixup_status; /* 0 nondone, 1 processing, 2 done */
+ void *non_dev_ppp_fixup_priv;
uint32_t vpp_sw_if_index;
};
diff --git a/accel-pppd/ppp/ppp.c b/accel-pppd/ppp/ppp.c
index 1ee612b..8fda7c7 100644
--- a/accel-pppd/ppp/ppp.c
+++ b/accel-pppd/ppp/ppp.c
@@ -143,8 +143,12 @@ int __export establish_ppp(struct ppp_t *ppp)
return 0;
exit_close_chan:
- if (!ppp->is_non_dev_ppp)
+ if (!ppp->is_non_dev_ppp) {
close(ppp->chan_fd);
+ }
+
+ ppp->chan_fd = -1;
+ ppp->chan_hnd.fd = -1;
return -1;
}
@@ -242,7 +246,8 @@ exit:
static void destroy_ppp_channel(struct ppp_t *ppp)
{
- triton_md_unregister_handler(&ppp->chan_hnd, 1);
+ /* do not close chan_hnd.fd if its non-dev-ppp(chan_hnd.fd == ppp.fd) */
+ triton_md_unregister_handler(&ppp->chan_hnd, !ppp->is_non_dev_ppp);
close(ppp->fd);
ppp->fd = -1;
ppp->chan_fd = -1;
@@ -292,8 +297,10 @@ static void destablish_ppp(struct ppp_t *ppp)
return;
}
- if (ppp->is_non_dev_ppp)
+ if (ppp->is_non_dev_ppp) {
+ ppp->is_unit_read_enabled = 0;
goto skip;
+ }
if (conf_unit_cache) {
struct ifreq ifr;
@@ -561,18 +568,18 @@ cont:
}
}
- list_for_each_entry(ppp_h, &ppp->unit_handlers, entry) {
- if (ppp_h->proto == proto) {
- if (ppp->is_unit_read_enabled > 0) {
- ppp_h->recv(ppp_h);
- if (ppp->fd == -1) {
- ppp->ses.ctrl->finished(&ppp->ses);
- return 1;
- }
- }
- goto cont;
- }
- }
+ if (ppp->is_unit_read_enabled > 0) {
+ list_for_each_entry(ppp_h, &ppp->unit_handlers, entry) {
+ if (ppp_h->proto == proto) {
+ ppp_h->recv(ppp_h);
+ if (ppp->fd == -1) {
+ ppp->ses.ctrl->finished(&ppp->ses);
+ return 1;
+ }
+ goto cont;
+ }
+ }
+ }
lcp_send_proto_rej(ppp, proto);
log_ppp_warn("ppp_chan_and_unit_read: discarding unknown packet %x\n", proto);
diff --git a/accel-pppd/session.c b/accel-pppd/session.c
index 2f6a4bf..34b44cb 100644
--- a/accel-pppd/session.c
+++ b/accel-pppd/session.c
@@ -150,9 +150,14 @@ void __export ap_session_activate(struct ap_session *ses)
if (ap_shutdown)
return;
- if (ses->ctrl->non_dev_ppp_fixup != NULL)
- if (ses->ctrl->non_dev_ppp_fixup(ses))
- ap_session_terminate(ses, TERM_NAS_ERROR, 0);
+ if (ses->non_dev_ppp_fixup != NULL) {
+ if (!ses->non_dev_ppp_fixup_status) {
+ ses->non_dev_ppp_fixup(ses);
+ return;
+ } else if (ses->non_dev_ppp_fixup_status == 1) {
+ return;
+ }
+ }
ap_session_ifup(ses);