summaryrefslogtreecommitdiff
path: root/accel-pppd/ctrl/pppoe/pppoe.c
diff options
context:
space:
mode:
Diffstat (limited to 'accel-pppd/ctrl/pppoe/pppoe.c')
-rw-r--r--accel-pppd/ctrl/pppoe/pppoe.c125
1 files changed, 72 insertions, 53 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);