From 4bcb9b082607fa3a1d0c9c377df9a1fe7b48f2b0 Mon Sep 17 00:00:00 2001 From: Vladislav Grishenko Date: Wed, 31 Jan 2018 22:59:41 +0500 Subject: ppp: fix mtu/mru negotiation in preallocate/unit-cache modes --- accel-pppd/ppp/lcp_opt_mru.c | 6 +----- accel-pppd/ppp/ppp.c | 49 +++++++++++++++++++++++++++++++++----------- 2 files changed, 38 insertions(+), 17 deletions(-) diff --git a/accel-pppd/ppp/lcp_opt_mru.c b/accel-pppd/ppp/lcp_opt_mru.c index 2f321fb6..ac4ce7fb 100644 --- a/accel-pppd/ppp/lcp_opt_mru.c +++ b/accel-pppd/ppp/lcp_opt_mru.c @@ -66,7 +66,7 @@ static struct lcp_option_t *mru_init(struct ppp_lcp_t *lcp) mru_opt->opt.id = CI_MRU; mru_opt->opt.len = 4; - lcp->ppp->mru = mru_opt->mru; + lcp->ppp->mru = PPP_MTU; lcp->ppp->mtu = mru_opt->mtu; return &mru_opt->opt; @@ -128,10 +128,6 @@ static int mru_recv_conf_ack(struct ppp_lcp_t *lcp, struct lcp_option_t *opt, ui { struct mru_option_t *mru_opt = container_of(opt, typeof(*mru_opt), opt); - if (net->ppp_ioctl(lcp->ppp->chan_fd, PPPIOCSMRU, &mru_opt->mru) && - errno != EIO && errno != ENOTTY) - log_ppp_error("lcp:mru: failed to set channel MRU: %s\n", strerror(errno)); - lcp->ppp->mru = mru_opt->mru; return 0; diff --git a/accel-pppd/ppp/ppp.c b/accel-pppd/ppp/ppp.c index 053d3b17..0606f3fd 100644 --- a/accel-pppd/ppp/ppp.c +++ b/accel-pppd/ppp/ppp.c @@ -62,6 +62,7 @@ static int ppp_unit_read(struct triton_md_handler_t*); static void init_layers(struct ppp_t *); static void _free_layers(struct ppp_t *); static void start_first_layer(struct ppp_t *); +static int setup_ppp_mru(struct ppp_t *ppp); void __export ppp_init(struct ppp_t *ppp) { @@ -138,8 +139,11 @@ int __export connect_ppp_channel(struct ppp_t *ppp) struct pppunit_cache *uc = NULL; struct ifreq ifr; - if (ppp->unit_fd != -1) + if (ppp->unit_fd != -1) { + if (setup_ppp_mru(ppp)) + goto exit_close_unit; return 0; + } if (uc_size) { pthread_mutex_lock(&uc_lock); @@ -184,24 +188,16 @@ int __export connect_ppp_channel(struct ppp_t *ppp) log_ppp_info1("connect: %s <--> %s(%s)\n", ppp->ses.ifname, ppp->ses.ctrl->name, ppp->ses.chan_name); - ifr.ifr_mtu = ppp->mtu; + memset(&ifr, 0, sizeof(ifr)); strcpy(ifr.ifr_name, ppp->ses.ifname); - if (ppp->mtu && net->sock_ioctl(SIOCSIFMTU, &ifr)) { - log_ppp_error("failed to set MTU: %s\n", strerror(errno)); - goto exit_close_unit; - } - - if (ppp->mru && net->ppp_ioctl(ppp->unit_fd, PPPIOCSMRU, &ppp->mru)) { - log_ppp_error("failed to set MRU: %s\n", strerror(errno)); - goto exit_close_unit; - } - if (net->sock_ioctl(SIOCGIFINDEX, &ifr)) { log_ppp_error("ioctl(SIOCGIFINDEX): %s\n", strerror(errno)); goto exit_close_unit; } ppp->ses.ifindex = ifr.ifr_ifindex; + setup_ppp_mru(ppp); + ap_session_set_ifindex(&ppp->ses); ppp->unit_hnd.fd = ppp->unit_fd; @@ -234,6 +230,35 @@ static void destroy_ppp_channel(struct ppp_t *ppp) mempool_free(ppp->buf); } +static int setup_ppp_mru(struct ppp_t *ppp) +{ + struct ifreq ifr; + + if (ppp->mtu) { + memset(&ifr, 0, sizeof(ifr)); + strcpy(ifr.ifr_name, ppp->ses.ifname); + ifr.ifr_mtu = ppp->mtu; + if (net->sock_ioctl(SIOCSIFMTU, &ifr)) { + log_ppp_error("failed to set MTU: %s\n", strerror(errno)); + return -1; + } + } + + if (ppp->mru) { + if (net->ppp_ioctl(ppp->unit_fd, PPPIOCSMRU, &ppp->mru)) { + log_ppp_error("failed to set unit MRU: %s\n", strerror(errno)); + return -1; + } + if (net->ppp_ioctl(ppp->chan_fd, PPPIOCSMRU, &ppp->mru) && + errno != EIO && errno != ENOTTY) { + log_ppp_error("lcp:mru: failed to set channel MRU: %s\n", strerror(errno)); + return -1; + } + } + + return 0; +} + static void destablish_ppp(struct ppp_t *ppp) { struct pppunit_cache *uc = NULL; -- cgit v1.2.3 From 2e4477498304db90061df3d387728e26a9232a5d Mon Sep 17 00:00:00 2001 From: Vladislav Grishenko Date: Thu, 8 Feb 2018 19:12:01 +0500 Subject: ipv6: dhcpv6: fix PD linklocal route for ipoe clients peer linklocal address can't be negotiated in ipoe mode unlike ppp, so route may lead to nowhere with non-working PD routing as result. so, instead of guessing peer link-local address, use dhcpv6 client src address as the gateway. since dhcpv6 clients are onlink and there's no dhcpv6 relay support (yet), dhcpv6 source would be exactly final linklocal address, no matter ppp or ipoe is in use. fine tune commit abaa43a307fa7a790dd34034c5fd8013dbd0488c --- accel-pppd/ipv6/dhcpv6.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/accel-pppd/ipv6/dhcpv6.c b/accel-pppd/ipv6/dhcpv6.c index 22273428..84d36caa 100644 --- a/accel-pppd/ipv6/dhcpv6.c +++ b/accel-pppd/ipv6/dhcpv6.c @@ -167,7 +167,7 @@ static void ev_ses_finished(struct ap_session *ses) _free(pd); } -static void insert_dp_routes(struct ap_session *ses, struct dhcpv6_pd *pd) +static void insert_dp_routes(struct ap_session *ses, struct dhcpv6_pd *pd, struct in6_addr *addr) { struct ipv6db_addr_t *p; struct in6_rtmsg rt6; @@ -179,10 +179,9 @@ static void insert_dp_routes(struct ap_session *ses, struct dhcpv6_pd *pd) rt6.rtmsg_ifindex = ses->ifindex; rt6.rtmsg_flags = RTF_UP; - if (conf_route_via_gw) { + if (conf_route_via_gw && addr && !IN6_IS_ADDR_UNSPECIFIED(addr)) { rt6.rtmsg_flags |= RTF_GATEWAY; - rt6.rtmsg_gateway.s6_addr32[0] = htonl(0xfe800000); - memcpy(rt6.rtmsg_gateway.s6_addr + 8, &ses->ipv6->peer_intf_id, 8); + memcpy(&rt6.rtmsg_gateway, addr, sizeof(rt6.rtmsg_gateway)); } list_for_each_entry(p, &ses->ipv6_dp->prefix_list, entry) { @@ -372,7 +371,7 @@ static void dhcpv6_send_reply(struct dhcpv6_packet *req, struct dhcpv6_pd *pd, i if (req->hdr->type == D6_REQUEST || req->rapid_commit) { pd->dp_iaid = ia_na->iaid; if (!pd->dp_active) - insert_dp_routes(ses, pd); + insert_dp_routes(ses, pd, &req->addr.sin6_addr); } f2 = 1; -- cgit v1.2.3 From 4fc2be2b3b2a7c8af8cf667e2c4a87e03d95c9e4 Mon Sep 17 00:00:00 2001 From: Vladislav Grishenko Date: Thu, 8 Feb 2018 19:24:05 +0500 Subject: pptp: add the ppp-max-mtu option to match l2tp & sstp --- accel-pppd/accel-ppp.conf.5 | 4 ++++ accel-pppd/ctrl/pptp/pptp.c | 9 ++++++++- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/accel-pppd/accel-ppp.conf.5 b/accel-pppd/accel-ppp.conf.5 index 56b8bee9..5bf7282d 100644 --- a/accel-pppd/accel-ppp.conf.5 +++ b/accel-pppd/accel-ppp.conf.5 @@ -475,6 +475,10 @@ Timeout waiting reply from client in seconds (default 5). If this option is given ppp interface will be renamed using .B ifname as a template, i.e pptp%d => pptp0. +.TP +.BI "ppp-max-mtu=" n +Set the maximun MTU value that can be negociated for PPP over PPTP +sessions. Default value is 1436. .SH [pppoe] .br Configuration of PPPoE module. diff --git a/accel-pppd/ctrl/pptp/pptp.c b/accel-pppd/ctrl/pptp/pptp.c index 88b3759a..7ca4b77a 100644 --- a/accel-pppd/ctrl/pptp/pptp.c +++ b/accel-pppd/ctrl/pptp/pptp.c @@ -55,6 +55,7 @@ struct pptp_conn_t struct ppp_t ppp; }; +static int conf_ppp_max_mtu = PPTP_MAX_MTU; static int conf_timeout = 5; static int conf_echo_interval = 0; static int conf_echo_failure = 3; @@ -688,7 +689,7 @@ static int pptp_connect(struct triton_md_handler_t *h) conn->ctrl.started = ppp_started; conn->ctrl.finished = ppp_finished; conn->ctrl.terminate = ppp_terminate; - conn->ctrl.max_mtu = PPTP_MAX_MTU; + conn->ctrl.max_mtu = conf_ppp_max_mtu; conn->ctrl.type = CTRL_TYPE_PPTP; conn->ctrl.ppp = 1; conn->ctrl.name = "pptp"; @@ -770,6 +771,12 @@ static void load_config(void) if (opt && atoi(opt) >= 0) conf_verbose = atoi(opt) > 0; + opt = conf_get_opt("pptp", "ppp-max-mtu"); + if (opt && atoi(opt) > 0) + conf_ppp_max_mtu = atoi(opt); + else + conf_ppp_max_mtu = PPTP_MAX_MTU; + conf_mppe = MPPE_UNSET; opt = conf_get_opt("pptp", "mppe"); if (opt) { -- cgit v1.2.3