Initial commit
Some checks failed
Build Kernel / Build all affected Kernels (push) Has been cancelled
Build all core packages / Build all core packages for selected target (push) Has been cancelled
Build and Push prebuilt tools container / Build and Push all prebuilt containers (push) Has been cancelled
Build Toolchains / Build Toolchains for each target (push) Has been cancelled
Build host tools / Build host tools for linux and macos based systems (push) Has been cancelled
Coverity scan build / Coverity x86/64 build (push) Has been cancelled

This commit is contained in:
domenico
2025-06-24 12:51:15 +02:00
commit 27c9d80f51
10493 changed files with 1885777 additions and 0 deletions

View File

@@ -0,0 +1,24 @@
configure: Allow overriding uname results
In a cross compile setting it makes no sense to rely on the "uname" values
reported by the build host system. This patch allows overriding the
"uname -r", "uname -s" and "uname -m" results with the "UNAME_R", "UNAME_S"
and "UNAME_M" environment variables.
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
--- a/configure
+++ b/configure
@@ -10,9 +10,9 @@ CROSS_COMPILE=
CC=cc
CFLAGS=
-system=`uname -s`
-release=`uname -r`
-arch=`uname -m`
+system=${UNAME_S:-`uname -s`}
+release=${UNAME_R:-`uname -r`}
+arch=${UNAME_M:-`uname -m`}
state="unknown"
case $system in

View File

@@ -0,0 +1,170 @@
--- a/pppd/demand.c
+++ b/pppd/demand.c
@@ -36,6 +36,8 @@
#include <errno.h>
#include <fcntl.h>
#include <netdb.h>
+#include <unistd.h>
+#include <syslog.h>
#include <sys/param.h>
#include <sys/types.h>
#include <sys/wait.h>
@@ -43,6 +45,8 @@
#include <sys/resource.h>
#include <sys/stat.h>
#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
#ifdef PPP_FILTER
#include <pcap-bpf.h>
#endif
@@ -218,6 +222,14 @@ loop_chars(unsigned char *p, int n)
int c, rv;
rv = 0;
+
+/* check for synchronous connection... */
+
+ if ( (p[0] == 0xFF) && (p[1] == 0x03) ) {
+ rv = loop_frame(p,n);
+ return rv;
+ }
+
for (; n > 0; --n) {
c = *p++;
if (c == PPP_FLAG) {
@@ -294,16 +306,100 @@ loop_frame(unsigned char *frame, int len
* loopback, now that the real serial link is up.
*/
void
-demand_rexmit(int proto)
+demand_rexmit(int proto, u_int32_t newip)
{
struct packet *pkt, *prev, *nextpkt;
+ unsigned short checksum;
+ unsigned short pkt_checksum = 0;
+ unsigned iphdr;
+ struct timeval tv;
+ char cv = 0;
+ char ipstr[16];
prev = NULL;
pkt = pend_q;
pend_q = NULL;
+ tv.tv_sec = 1;
+ tv.tv_usec = 0;
+ select(0,NULL,NULL,NULL,&tv); /* Sleep for 1 Seconds */
for (; pkt != NULL; pkt = nextpkt) {
nextpkt = pkt->next;
if (PPP_PROTOCOL(pkt->data) == proto) {
+ if ( (proto == PPP_IP) && newip ) {
+ /* Get old checksum */
+
+ iphdr = (pkt->data[4] & 15) << 2;
+ checksum = *((unsigned short *) (pkt->data+14));
+ if (checksum == 0xFFFF) {
+ checksum = 0;
+ }
+
+
+ if (pkt->data[13] == 17) {
+ pkt_checksum = *((unsigned short *) (pkt->data+10+iphdr));
+ if (pkt_checksum) {
+ cv = 1;
+ if (pkt_checksum == 0xFFFF) {
+ pkt_checksum = 0;
+ }
+ }
+ else {
+ cv = 0;
+ }
+ }
+
+ if (pkt->data[13] == 6) {
+ pkt_checksum = *((unsigned short *) (pkt->data+20+iphdr));
+ cv = 1;
+ if (pkt_checksum == 0xFFFF) {
+ pkt_checksum = 0;
+ }
+ }
+
+ /* Delete old Source-IP-Address */
+ checksum -= *((unsigned short *) (pkt->data+16)) ^ 0xFFFF;
+ checksum -= *((unsigned short *) (pkt->data+18)) ^ 0xFFFF;
+
+ pkt_checksum -= *((unsigned short *) (pkt->data+16)) ^ 0xFFFF;
+ pkt_checksum -= *((unsigned short *) (pkt->data+18)) ^ 0xFFFF;
+
+ /* Change Source-IP-Address */
+ * ((u_int32_t *) (pkt->data + 16)) = newip;
+
+ /* Add new Source-IP-Address */
+ checksum += *((unsigned short *) (pkt->data+16)) ^ 0xFFFF;
+ checksum += *((unsigned short *) (pkt->data+18)) ^ 0xFFFF;
+
+ pkt_checksum += *((unsigned short *) (pkt->data+16)) ^ 0xFFFF;
+ pkt_checksum += *((unsigned short *) (pkt->data+18)) ^ 0xFFFF;
+
+ /* Write new checksum */
+ if (!checksum) {
+ checksum = 0xFFFF;
+ }
+ *((unsigned short *) (pkt->data+14)) = checksum;
+ if (pkt->data[13] == 6) {
+ *((unsigned short *) (pkt->data+20+iphdr)) = pkt_checksum;
+ }
+ if (cv && (pkt->data[13] == 17) ) {
+ *((unsigned short *) (pkt->data+10+iphdr)) = pkt_checksum;
+ }
+
+ /* Log Packet */
+ strcpy(ipstr,inet_ntoa(*( (struct in_addr *) (pkt->data+16))));
+ if (pkt->data[13] == 1) {
+ syslog(LOG_INFO,"Open ICMP %s -> %s\n",
+ ipstr,
+ inet_ntoa(*( (struct in_addr *) (pkt->data+20))));
+ } else {
+ syslog(LOG_INFO,"Open %s %s:%d -> %s:%d\n",
+ pkt->data[13] == 6 ? "TCP" : "UDP",
+ ipstr,
+ ntohs(*( (short *) (pkt->data+iphdr+4))),
+ inet_ntoa(*( (struct in_addr *) (pkt->data+20))),
+ ntohs(*( (short *) (pkt->data+iphdr+6))));
+ }
+ }
output(0, pkt->data, pkt->length);
free(pkt);
} else {
--- a/pppd/ipcp.c
+++ b/pppd/ipcp.c
@@ -1850,7 +1850,7 @@ ipcp_up(fsm *f)
proxy_arp_set[f->unit] = 1;
}
- demand_rexmit(PPP_IP);
+ demand_rexmit(PPP_IP,go->ouraddr);
sifnpmode(f->unit, PPP_IP, NPMODE_PASS);
} else {
--- a/pppd/ipv6cp.c
+++ b/pppd/ipv6cp.c
@@ -1253,7 +1253,7 @@ ipv6cp_up(fsm *f)
if (sif6defaultroute(f->unit, go->ourid, ho->hisid))
default_route_set[f->unit] = 1;
}
- demand_rexmit(PPP_IPV6);
+ demand_rexmit(PPP_IPV6,0);
sifnpmode(f->unit, PPP_IPV6, NPMODE_PASS);
} else {
--- a/pppd/pppd.h
+++ b/pppd/pppd.h
@@ -598,7 +598,7 @@ void demand_conf(void); /* config interf
void demand_block(void); /* set all NPs to queue up packets */
void demand_unblock(void); /* set all NPs to pass packets */
void demand_discard(void); /* set all NPs to discard packets */
-void demand_rexmit(int); /* retransmit saved frames for an NP */
+void demand_rexmit(int, u_int32_t); /* retransmit saved frames for an NP*/
int loop_chars(unsigned char *, int); /* process chars from loopback */
int loop_frame(unsigned char *, int); /* should we bring link up? */

View File

@@ -0,0 +1,95 @@
pppd: Allow specifying ipv6-up and ipv6-down scripts
This patch implements the "ipv6-up-script" and "ipv6-down-script" options
which allow to specify the path of the ipv6-up and ipv6-down scripts to call.
These options default to _PATH_IPV6UP and _PATH_IPV6DOWN to retain the
existing behaviour.
The patch originated from the Debian project.
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
--- a/pppd/main.c
+++ b/pppd/main.c
@@ -295,6 +295,8 @@ main(int argc, char *argv[])
strlcpy(path_ipup, _PATH_IPUP, sizeof(path_ipup));
strlcpy(path_ipdown, _PATH_IPDOWN, sizeof(path_ipdown));
+ strlcpy(path_ipv6up, _PATH_IPV6UP, sizeof(path_ipv6up));
+ strlcpy(path_ipv6down, _PATH_IPV6DOWN, sizeof(path_ipv6down));
link_stats_valid = 0;
new_phase(PHASE_INITIALIZE);
--- a/pppd/options.c
+++ b/pppd/options.c
@@ -118,6 +118,8 @@ int req_unit = -1; /* requested interfa
char path_ipup[MAXPATHLEN]; /* pathname of ip-up script */
char path_ipdown[MAXPATHLEN];/* pathname of ip-down script */
char req_ifname[MAXIFNAMELEN]; /* requested interface name */
+char path_ipv6up[MAXPATHLEN]; /* pathname of ipv6-up script */
+char path_ipv6down[MAXPATHLEN];/* pathname of ipv6-down script */
bool multilink = 0; /* Enable multilink operation */
char *bundle_name = NULL; /* bundle name for multilink */
bool dump_options; /* print out option values */
@@ -324,6 +326,13 @@ option_t general_options[] = {
"Set pathname of ip-down script",
OPT_PRIV|OPT_STATIC, NULL, MAXPATHLEN },
+ { "ipv6-up-script", o_string, path_ipv6up,
+ "Set pathname of ipv6-up script",
+ OPT_PRIV|OPT_STATIC, NULL, MAXPATHLEN },
+ { "ipv6-down-script", o_string, path_ipv6down,
+ "Set pathname of ipv6-down script",
+ OPT_PRIV|OPT_STATIC, NULL, MAXPATHLEN },
+
#ifdef HAVE_MULTILINK
{ "multilink", o_bool, &multilink,
"Enable multilink operation", OPT_PRIO | 1 },
--- a/pppd/ipv6cp.c
+++ b/pppd/ipv6cp.c
@@ -1295,7 +1295,7 @@ ipv6cp_up(fsm *f)
*/
if (ipv6cp_script_state == s_down && ipv6cp_script_pid == 0) {
ipv6cp_script_state = s_up;
- ipv6cp_script(_PATH_IPV6UP);
+ ipv6cp_script(path_ipv6up);
}
}
@@ -1346,7 +1346,7 @@ ipv6cp_down(fsm *f)
/* Execute the ipv6-down script */
if (ipv6cp_script_state == s_up && ipv6cp_script_pid == 0) {
ipv6cp_script_state = s_down;
- ipv6cp_script(_PATH_IPV6DOWN);
+ ipv6cp_script(path_ipv6down);
}
}
@@ -1384,13 +1384,13 @@ ipv6cp_script_done(void *arg)
case s_up:
if (ipv6cp_fsm[0].state != OPENED) {
ipv6cp_script_state = s_down;
- ipv6cp_script(_PATH_IPV6DOWN);
+ ipv6cp_script(path_ipv6down);
}
break;
case s_down:
if (ipv6cp_fsm[0].state == OPENED) {
ipv6cp_script_state = s_up;
- ipv6cp_script(_PATH_IPV6UP);
+ ipv6cp_script(path_ipv6up);
}
break;
}
--- a/pppd/pppd.h
+++ b/pppd/pppd.h
@@ -328,6 +328,8 @@ extern int req_unit; /* interface unit n
extern char path_ipup[MAXPATHLEN]; /* pathname of ip-up script */
extern char path_ipdown[MAXPATHLEN]; /* pathname of ip-down script */
extern char req_ifname[MAXIFNAMELEN]; /* interface name to use */
+extern char path_ipv6up[MAXPATHLEN]; /* pathname of ipv6-up script */
+extern char path_ipv6down[MAXPATHLEN]; /* pathname of ipv6-down script */
extern bool multilink; /* enable multilink operation */
extern bool noendpoint; /* don't send or accept endpt. discrim. */
extern char *bundle_name; /* bundle name for multilink */

View File

@@ -0,0 +1,11 @@
--- a/pppd/sha1.c
+++ b/pppd/sha1.c
@@ -19,7 +19,7 @@
#include <string.h>
#include <time.h>
#include <netinet/in.h> /* htonl() */
-#include <net/ppp_defs.h>
+#include "pppd.h"
#include "sha1.h"
static void

View File

@@ -0,0 +1,54 @@
From 98ec18f098e5ef68e3a8cc6954fcaf5a7fb8b7be Mon Sep 17 00:00:00 2001
From: pali <7141871+pali@users.noreply.github.com>
Date: Mon, 15 Feb 2021 07:54:01 +0100
Subject: [PATCH] pppd: Fix compilation with older glibc or kernel headers
(#248)
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
glibc versions prior to 2.24 do not define SOL_NETLINK and linux kernel
versions prior to 4.3 do not define NETLINK_CAP_ACK. So add fallback
definitions for these macros into pppd/sys-linux.c file.
Also extend description why we call SOL_NETLINK/NETLINK_CAP_ACK option.
Signed-off-by: Pali Rohár <pali@kernel.org>
---
pppd/sys-linux.c | 18 +++++++++++++++++-
1 file changed, 17 insertions(+), 1 deletion(-)
--- a/pppd/sys-linux.c
+++ b/pppd/sys-linux.c
@@ -125,6 +125,14 @@
#include <linux/netlink.h>
#include <linux/rtnetlink.h>
#include <linux/if_addr.h>
+/* glibc versions prior to 2.24 do not define SOL_NETLINK */
+#ifndef SOL_NETLINK
+#define SOL_NETLINK 270
+#endif
+/* linux kernel versions prior to 4.3 do not define/support NETLINK_CAP_ACK */
+#ifndef NETLINK_CAP_ACK
+#define NETLINK_CAP_ACK 10
+#endif
#endif
#include "pppd.h"
@@ -2843,7 +2851,15 @@ static int append_peer_ipv6_address(unsi
if (fd < 0)
return 0;
- /* do not ask for error message content */
+ /*
+ * Tell kernel to not send to us payload of acknowledgment error message.
+ * NETLINK_CAP_ACK option is supported since Linux kernel version 4.3 and
+ * older kernel versions always send full payload in acknowledgment netlink
+ * message. We ignore payload of this message as we need only error code,
+ * to check if our set remote peer address request succeeded or failed.
+ * So ignore return value from the following setsockopt() call as setting
+ * option NETLINK_CAP_ACK means for us just a kernel hint / optimization.
+ */
one = 1;
setsockopt(fd, SOL_NETLINK, NETLINK_CAP_ACK, &one, sizeof(one));

View File

@@ -0,0 +1,518 @@
From 81ad945630120cc1c27c8bb00503be42b76ff202 Mon Sep 17 00:00:00 2001
From: Jaco Kroon <jaco@uls.co.za>
Date: Thu, 13 Jan 2022 08:38:04 +0200
Subject: [PATCH] Expand byte count statistics to 64 bits (#298)
* Add Gigawords to radius packets where applicable.
IMPORTANT NOTE: The ioctl() only supports 32-bit counters. In order t
obtain 64-bit counters, these are now pulled in from sysfs (it's assumed
to be mounted on /sys which I'm assuming is standard).
It is unknown whether sysfs will be available everywhere, as such, keep
the ioctl() method in place, but attempt to detect wrap-overs.
If the sysfs mechanism fails, fail back to the ioctl().
Given maximum data rates, the intervals between calling this needs to be
such that no more than 4GB (2^32) bytes are sent or received in any
given interval. Mostly important for radius plugin where data
accounting may be in effect.
Towards this, a timer interval on 25 seconds is set to force a ioctl()
poll irrespective of the rate of stats update calls. This may be
important for especially radius that needs to provide interim-update
intervals, if the interim updates is too long and the counters could
wrap-over twice in a single interval. At 25 seconds we should detect
all wraps up to an effective data rate of 1.37Gbps, which for my
purposes is adequate.
Possible downsides, 4 files are opened, read and closed every time
statistics is requested. This results in 12 system calls every single
time statistics is required, compared to 1 for the ioctl. Efficiency is
unknown, but as a rule of thumb fewer system calls are better, this is
however not a critical path in my opinion, so should not be a problem.
If required I can run a few benchmarks using gettimeofday() to measure
actual impact.
Signed-off-by: Jaco Kroon <jaco@uls.co.za>
* Use netlink if possible to obtain 64-bit stats.
This uses two system calls per round.
This should be preferred where available. It seems the RTM_GETSTATS was
only added from 2016 some point (4.7.0 as per pali), which is in my
opinion old, but given experience with certain embedded systems does
need to be supported.
Signed-off-by: Jaco Kroon <jaco@uls.co.za>
Co-authored-by: Jaco Kroon <jaco@iewc.co.za>
---
pppd/main.c | 5 +-
pppd/plugins/radius/etc/dictionary | 2 +
pppd/plugins/radius/radius.c | 28 ++-
pppd/plugins/radius/radiusclient.h | 2 +
pppd/pppd.h | 9 +-
pppd/sys-linux.c | 281 ++++++++++++++++++++++++++++-
6 files changed, 313 insertions(+), 14 deletions(-)
--- a/pppd/main.c
+++ b/pppd/main.c
@@ -87,6 +87,7 @@
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
+#include <inttypes.h>
#include "pppd.h"
#include "magic.h"
@@ -1230,9 +1231,9 @@ update_link_stats(int u)
slprintf(numbuf, sizeof(numbuf), "%u", link_connect_time);
script_setenv("CONNECT_TIME", numbuf, 0);
- slprintf(numbuf, sizeof(numbuf), "%u", link_stats.bytes_out);
+ snprintf(numbuf, sizeof(numbuf), "%" PRIu64, link_stats.bytes_out);
script_setenv("BYTES_SENT", numbuf, 0);
- slprintf(numbuf, sizeof(numbuf), "%u", link_stats.bytes_in);
+ snprintf(numbuf, sizeof(numbuf), "%" PRIu64, link_stats.bytes_in);
script_setenv("BYTES_RCVD", numbuf, 0);
}
--- a/pppd/plugins/radius/etc/dictionary
+++ b/pppd/plugins/radius/etc/dictionary
@@ -82,6 +82,8 @@ ATTRIBUTE Acct-Session-Time 46 integer
ATTRIBUTE Acct-Input-Packets 47 integer
ATTRIBUTE Acct-Output-Packets 48 integer
ATTRIBUTE Acct-Terminate-Cause 49 integer
+ATTRIBUTE Acct-Input-Gigawords 52 integer
+ATTRIBUTE Acct-Output-Gigawords 53 integer
ATTRIBUTE Chap-Challenge 60 string
ATTRIBUTE NAS-Port-Type 61 integer
ATTRIBUTE Port-Limit 62 integer
--- a/pppd/plugins/radius/radius.c
+++ b/pppd/plugins/radius/radius.c
@@ -1020,12 +1020,22 @@ radius_acct_stop(void)
av_type = link_connect_time;
rc_avpair_add(&send, PW_ACCT_SESSION_TIME, &av_type, 0, VENDOR_NONE);
- av_type = link_stats.bytes_out;
+ av_type = link_stats.bytes_out & 0xFFFFFFFF;
rc_avpair_add(&send, PW_ACCT_OUTPUT_OCTETS, &av_type, 0, VENDOR_NONE);
- av_type = link_stats.bytes_in;
+ if (link_stats.bytes_out > 0xFFFFFFFF) {
+ av_type = link_stats.bytes_out >> 32;
+ rc_avpair_add(&send, PW_ACCT_OUTPUT_GIGAWORDS, &av_type, 0, VENDOR_NONE);
+ }
+
+ av_type = link_stats.bytes_in & 0xFFFFFFFF;
rc_avpair_add(&send, PW_ACCT_INPUT_OCTETS, &av_type, 0, VENDOR_NONE);
+ if (link_stats.bytes_in > 0xFFFFFFFF) {
+ av_type = link_stats.bytes_in >> 32;
+ rc_avpair_add(&send, PW_ACCT_INPUT_GIGAWORDS, &av_type, 0, VENDOR_NONE);
+ }
+
av_type = link_stats.pkts_out;
rc_avpair_add(&send, PW_ACCT_OUTPUT_PACKETS, &av_type, 0, VENDOR_NONE);
@@ -1172,12 +1182,22 @@ radius_acct_interim(void *ignored)
av_type = link_connect_time;
rc_avpair_add(&send, PW_ACCT_SESSION_TIME, &av_type, 0, VENDOR_NONE);
- av_type = link_stats.bytes_out;
+ av_type = link_stats.bytes_out & 0xFFFFFFFF;
rc_avpair_add(&send, PW_ACCT_OUTPUT_OCTETS, &av_type, 0, VENDOR_NONE);
- av_type = link_stats.bytes_in;
+ if (link_stats.bytes_out > 0xFFFFFFFF) {
+ av_type = link_stats.bytes_out >> 32;
+ rc_avpair_add(&send, PW_ACCT_OUTPUT_GIGAWORDS, &av_type, 0, VENDOR_NONE);
+ }
+
+ av_type = link_stats.bytes_in & 0xFFFFFFFF;
rc_avpair_add(&send, PW_ACCT_INPUT_OCTETS, &av_type, 0, VENDOR_NONE);
+ if (link_stats.bytes_in > 0xFFFFFFFF) {
+ av_type = link_stats.bytes_in >> 32;
+ rc_avpair_add(&send, PW_ACCT_INPUT_GIGAWORDS, &av_type, 0, VENDOR_NONE);
+ }
+
av_type = link_stats.pkts_out;
rc_avpair_add(&send, PW_ACCT_OUTPUT_PACKETS, &av_type, 0, VENDOR_NONE);
--- a/pppd/plugins/radius/radiusclient.h
+++ b/pppd/plugins/radius/radiusclient.h
@@ -184,6 +184,8 @@ typedef struct pw_auth_hdr
#define PW_ACCT_LINK_COUNT 51 /* integer */
/* From RFC 2869 */
+#define PW_ACCT_INPUT_GIGAWORDS 52 /* integer */
+#define PW_ACCT_OUTPUT_GIGAWORDS 53 /* integer */
#define PW_ACCT_INTERIM_INTERVAL 85 /* integer */
/* Merit Experimental Extensions */
--- a/pppd/pppd.h
+++ b/pppd/pppd.h
@@ -53,6 +53,7 @@
#include <stdlib.h> /* for encrypt */
#include <unistd.h> /* for setkey */
#include <stdarg.h>
+#include <stdint.h>
#include <limits.h> /* for NGROUPS_MAX */
#include <sys/param.h> /* for MAXPATHLEN and BSD4_4, if defined */
#include <sys/types.h> /* for u_int32_t, if defined */
@@ -173,8 +174,8 @@ struct permitted_ip {
* pppd needs.
*/
struct pppd_stats {
- unsigned int bytes_in;
- unsigned int bytes_out;
+ uint64_t bytes_in;
+ uint64_t bytes_out;
unsigned int pkts_in;
unsigned int pkts_out;
};
@@ -347,7 +348,7 @@ extern char *max_tls_version;
extern unsigned int maxoctets; /* Maximum octetes per session (in bytes) */
extern int maxoctets_dir; /* Direction :
0 - in+out (default)
- 1 - in
+ 1 - in
2 - out
3 - max(in,out) */
extern int maxoctets_timeout; /* Timeout for check of octets limit */
@@ -356,7 +357,7 @@ extern int maxoctets_timeout; /*
#define PPP_OCTETS_DIRECTION_OUT 2
#define PPP_OCTETS_DIRECTION_MAXOVERAL 3
/* same as previos, but little different on RADIUS side */
-#define PPP_OCTETS_DIRECTION_MAXSESSION 4
+#define PPP_OCTETS_DIRECTION_MAXSESSION 4
#endif
#ifdef PPP_FILTER
--- a/pppd/sys-linux.c
+++ b/pppd/sys-linux.c
@@ -79,6 +79,7 @@
#include <sys/sysmacros.h>
#include <errno.h>
+#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <syslog.h>
@@ -92,6 +93,7 @@
#include <ctype.h>
#include <termios.h>
#include <unistd.h>
+#include <limits.h>
/* This is in netdevice.h. However, this compile will fail miserably if
you attempt to include netdevice.h because it has so many references
@@ -121,9 +123,19 @@
#include <linux/ppp_defs.h>
#include <linux/if_ppp.h>
-#ifdef INET6
#include <linux/netlink.h>
#include <linux/rtnetlink.h>
+#include <linux/if_link.h>
+/* Attempt at retaining compile-support with older than 4.7 kernels, or kernels
+ * where RTM_NEWSTATS isn't defined for whatever reason.
+ */
+#ifndef RTM_NEWSTATS
+#define RTM_NEWSTATS 92
+#define RTM_GETSTATS 94
+#define IFLA_STATS_LINK_64 1
+#endif
+
+#ifdef INET6
#include <linux/if_addr.h>
/* glibc versions prior to 2.24 do not define SOL_NETLINK */
#ifndef SOL_NETLINK
@@ -1407,11 +1419,17 @@ get_idle_time(int u, struct ppp_idle *ip
/********************************************************************
*
- * get_ppp_stats - return statistics for the link.
+ * get_ppp_stats_iocl - return statistics for the link, using the ioctl() method,
+ * this only supports 32-bit counters, so need to count the wraps.
*/
-int
-get_ppp_stats(int u, struct pppd_stats *stats)
+static int
+get_ppp_stats_ioctl(int u, struct pppd_stats *stats)
{
+ static u_int32_t previbytes = 0;
+ static u_int32_t prevobytes = 0;
+ static u_int32_t iwraps = 0;
+ static u_int32_t owraps = 0;
+
struct ifpppstatsreq req;
memset (&req, 0, sizeof (req));
@@ -1426,7 +1444,262 @@ get_ppp_stats(int u, struct pppd_stats *
stats->bytes_out = req.stats.p.ppp_obytes;
stats->pkts_in = req.stats.p.ppp_ipackets;
stats->pkts_out = req.stats.p.ppp_opackets;
+
+ if (stats->bytes_in < previbytes)
+ ++iwraps;
+ if (stats->bytes_out < prevobytes)
+ ++owraps;
+
+ previbytes = stats->bytes_in;
+ prevobytes = stats->bytes_out;
+
+ stats->bytes_in += (uint64_t)iwraps << 32;
+ stats->bytes_out += (uint64_t)owraps << 32;
+
+ return 1;
+}
+
+/********************************************************************
+ * get_ppp_stats_rtnetlink - return statistics for the link, using rtnetlink
+ * This provides native 64-bit counters.
+ */
+static int
+get_ppp_stats_rtnetlink(int u, struct pppd_stats *stats)
+{
+ static int rtnl_fd = -1;
+
+ struct sockaddr_nl nladdr;
+ struct {
+ struct nlmsghdr nlh;
+ struct if_stats_msg ifsm;
+ } nlreq;
+ struct nlresp {
+ struct nlmsghdr nlh;
+ union {
+ struct {
+ struct nlmsgerr nlerr;
+ char __end_err[0];
+ };
+ struct {
+ struct rtmsg rth;
+ struct {
+ /* We only case about these first fields from rtnl_link_stats64 */
+ uint64_t rx_packets;
+ uint64_t tx_packets;
+ uint64_t rx_bytes;
+ uint64_t tx_bytes;
+ } stats;
+ char __end_stats[0];
+ };
+ };
+ } nlresp;
+ ssize_t nlresplen;
+ struct iovec iov;
+ struct msghdr msg;
+
+ memset(&nladdr, 0, sizeof(nladdr));
+ nladdr.nl_family = AF_NETLINK;
+
+ if (rtnl_fd < 0) {
+ rtnl_fd = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
+ if (rtnl_fd < 0) {
+ error("get_ppp_stats_rtnetlink: error creating NETLINK socket: %m (line %d)", __LINE__);
+ return 0;
+ }
+
+ if (bind(rtnl_fd, (struct sockaddr *)&nladdr, sizeof(nladdr)) < 0) {
+ error("get_ppp_stats_rtnetlink: bind(AF_NETLINK): %m (line %d)", __LINE__);
+ goto err;
+ }
+ }
+
+ memset(&nlreq, 0, sizeof(nlreq));
+ nlreq.nlh.nlmsg_len = sizeof(nlreq);
+ nlreq.nlh.nlmsg_type = RTM_GETSTATS;
+ nlreq.nlh.nlmsg_flags = NLM_F_REQUEST;
+
+ nlreq.ifsm.ifindex = if_nametoindex(ifname);
+ nlreq.ifsm.filter_mask = IFLA_STATS_LINK_64;
+
+ memset(&iov, 0, sizeof(iov));
+ iov.iov_base = &nlreq;
+ iov.iov_len = sizeof(nlreq);
+
+ memset(&msg, 0, sizeof(msg));
+ msg.msg_name = &nladdr;
+ msg.msg_namelen = sizeof(nladdr);
+ msg.msg_iov = &iov;
+ msg.msg_iovlen = 1;
+
+ if (sendmsg(rtnl_fd, &msg, 0) < 0) {
+ error("get_ppp_stats_rtnetlink: sendmsg(RTM_GETSTATS): %m (line %d)", __LINE__);
+ goto err;
+ }
+
+ /* We just need to repoint to IOV ... everything else stays the same */
+ iov.iov_base = &nlresp;
+ iov.iov_len = sizeof(nlresp);
+
+ nlresplen = recvmsg(rtnl_fd, &msg, 0);
+
+ if (nlresplen < 0) {
+ error("get_ppp_stats_rtnetlink: recvmsg(RTM_GETSTATS): %m (line %d)", __LINE__);
+ goto err;
+ }
+
+ if (nlresplen < sizeof(nlresp.nlh)) {
+ error("get_ppp_stats_rtnetlink: Netlink response message was incomplete (line %d)", __LINE__);
+ goto err;
+ }
+
+ if (nlresp.nlh.nlmsg_type == NLMSG_ERROR) {
+ if (nlresplen < offsetof(struct nlresp, __end_err)) {
+ if (kernel_version >= KVERSION(4,7,0))
+ error("get_ppp_stats_rtnetlink: Netlink responded with error: %s (line %d)", strerror(-nlresp.nlerr.error), __LINE__);
+ } else {
+ error("get_ppp_stats_rtnetlink: Netlink responded with an error message, but the nlmsgerr structure is incomplete (line %d).",
+ __LINE__);
+ }
+ goto err;
+ }
+
+ if (nlresp.nlh.nlmsg_type != RTM_NEWSTATS) {
+ error("get_ppp_stats_rtnetlink: Expected RTM_NEWSTATS response, found something else (mlmsg_type %d, line %d)",
+ nlresp.nlh.nlmsg_type, __LINE__);
+ goto err;
+ }
+
+ if (nlresplen < offsetof(struct nlresp, __end_stats)) {
+ error("get_ppp_stats_rtnetlink: Obtained an insufficiently sized rtnl_link_stats64 struct from the kernel (line %d).", __LINE__);
+ goto err;
+ }
+
+ stats->bytes_in = nlresp.stats.rx_bytes;
+ stats->bytes_out = nlresp.stats.tx_bytes;
+ stats->pkts_in = nlresp.stats.rx_packets;
+ stats->pkts_out = nlresp.stats.tx_packets;
+
return 1;
+err:
+ close(rtnl_fd);
+ rtnl_fd = -1;
+ return 0;
+}
+
+/********************************************************************
+ * get_ppp_stats_sysfs - return statistics for the link, using the files in sysfs,
+ * this provides native 64-bit counters.
+ */
+static int
+get_ppp_stats_sysfs(int u, struct pppd_stats *stats)
+{
+ char fname[PATH_MAX+1];
+ char buf[21], *err; /* 2^64 < 10^20 */
+ int blen, fd, rlen;
+ unsigned long long val;
+
+ struct {
+ const char* fname;
+ void* ptr;
+ unsigned size;
+ } slist[] = {
+#define statfield(fn, field) { .fname = #fn, .ptr = &stats->field, .size = sizeof(stats->field) }
+ statfield(rx_bytes, bytes_in),
+ statfield(tx_bytes, bytes_out),
+ statfield(rx_packets, pkts_in),
+ statfield(tx_packets, pkts_out),
+#undef statfield
+ };
+
+ blen = snprintf(fname, sizeof(fname), "/sys/class/net/%s/statistics/", ifname);
+ if (blen >= sizeof(fname))
+ return 0; /* ifname max 15, so this should be impossible */
+
+ for (int i = 0; i < sizeof(slist) / sizeof(*slist); ++i) {
+ if (snprintf(fname + blen, sizeof(fname) - blen, "%s", slist[i].fname) >= sizeof(fname) - blen) {
+ fname[blen] = 0;
+ error("sysfs stats: filename %s/%s overflowed PATH_MAX", fname, slist[i].fname);
+ return 0;
+ }
+
+ fd = open(fname, O_RDONLY);
+ if (fd < 0) {
+ error("%s: %m", fname);
+ return 0;
+ }
+
+ rlen = read(fd, buf, sizeof(buf) - 1);
+ close(fd);
+ if (rlen < 0) {
+ error("%s: %m", fname);
+ return 0;
+ }
+ /* trim trailing \n if present */
+ while (rlen > 0 && buf[rlen-1] == '\n')
+ rlen--;
+ buf[rlen] = 0;
+
+ errno = 0;
+ val = strtoull(buf, &err, 10);
+ if (*buf < '0' || *buf > '9' || errno != 0 || *err) {
+ error("string to number conversion error converting %s (from %s) for remaining string %s%s%s",
+ buf, fname, err, errno ? ": " : "", errno ? strerror(errno) : "");
+ return 0;
+ }
+ switch (slist[i].size) {
+#define stattype(type) case sizeof(type): *(type*)slist[i].ptr = (type)val; break
+ stattype(uint64_t);
+ stattype(uint32_t);
+ stattype(uint16_t);
+ stattype(uint8_t);
+#undef stattype
+ default:
+ error("Don't know how to store stats for %s of size %u", slist[i].fname, slist[i].size);
+ return 0;
+ }
+ }
+
+ return 1;
+}
+
+/********************************************************************
+ * Periodic timer function to be used to keep stats up to date in case of ioctl
+ * polling.
+ *
+ * Given the 25s interval this should be fine up to data rates of 1.37Gbps.
+ * If you do change the timer, remember to also bring the get_ppp_stats (which
+ * sets up the initial trigger) as well.
+ */
+static void
+ppp_stats_poller(void* u)
+{
+ struct pppd_stats dummy;
+ get_ppp_stats_ioctl((long)u, &dummy);
+ TIMEOUT(ppp_stats_poller, u, 25);
+}
+
+/********************************************************************
+ * get_ppp_stats - return statistics for the link.
+ */
+int get_ppp_stats(int u, struct pppd_stats *stats)
+{
+ static int (*func)(int, struct pppd_stats*) = NULL;
+
+ if (!func) {
+ if (get_ppp_stats_rtnetlink(u, stats)) {
+ func = get_ppp_stats_rtnetlink;
+ return 1;
+ }
+ if (get_ppp_stats_sysfs(u, stats)) {
+ func = get_ppp_stats_sysfs;
+ return 1;
+ }
+ warn("statistics falling back to ioctl which only supports 32-bit counters");
+ func = get_ppp_stats_ioctl;
+ TIMEOUT(ppp_stats_poller, (void*)(long)u, 25);
+ }
+
+ return func(u, stats);
}
/********************************************************************

View File

@@ -0,0 +1,299 @@
From 4a54e34cf5629f9fed61f0b7d69ee3ba4d874bc6 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Pali=20Roh=C3=A1r?= <pali@kernel.org>
Date: Sat, 9 Jul 2022 13:40:24 +0200
Subject: [PATCH] pppd: Add support for registering ppp interface via Linux
rtnetlink API
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
pppd currently creates ppp network interface via PPPIOCNEWUNIT ioctl API.
This API creates a new ppp network interface named "ppp<unit_id>". If user
supply option "ifname" with custom network name then pppd calls SIOCSIFNAME
ioctl to rename "ppp<unit_id>" to custom name immediately after successful
PPPIOCNEWUNIT ioctl call. If custom name is already registered then
SIOCSIFNAME ioctl fails and pppd close current channel (which destroy also
network interface).
This has side effect that in the first few miliseconds interface has
different name as what user supplied.
Tools like systemd, udev or NetworkManager are trying to query
interface attributes based on interface name immediately when new
network interface is created.
But if interface is renamed immediately after creation then these tools
fails. For example when running pppd with option "ifname ppp-wan" following
error is reported by systemd / udev into dmesg log:
[ 35.718732] PPP generic driver version 2.4.2
[ 35.793914] NET: Registered protocol family 24
[ 35.889924] systemd-udevd[1852]: link_config: autonegotiation is unset or enabled, the speed and duplex are not writable.
[ 35.901450] ppp-wan: renamed from ppp0
[ 35.930332] systemd-udevd[1852]: link_config: could not get ethtool features for ppp0
[ 35.939473] systemd-udevd[1852]: Could not set offload features of ppp0: No such device
There is an easy way to fix this issue: Use new rtnetlink API.
Via rtnetlink API it is possible to create ppp network interface with
custom ifname atomically. Just it is not possible to specify custom ppp
unit id.
So use new rtnetlink API when user requested custom ifname without custom
ppp unit id. This will avoid system issues with interface renaming as ppp
interface is directly registered with specified final name.
This has also advantage that if requested interface name already exists
then pppd fail during registering of networking interface and not during
renaming network interface which happens after successful registration.
If user supply custom ppp unit id then it is required to use old ioctl API
as currently it is the only API which allows specifying ppp unit id.
When user does not specify custom ifname stay also with old ioctl API.
There is currently a bug in kernel which cause that when empty interface is
specified in rtnetlink message for creating ppp interface then kernel
creates ppp interface but with pseudo-random name, not derived from ppp
unit id. And therefore it is not possible to retrieve what is the name of
newly created network interface. So when user does not specify interface
name via "ifname" option (which means that want from kernel to choose some
"free" interface name) it is needed to use old ioctl API which do it
correctly for now.
Signed-off-by: Pali Rohár <pali@kernel.org>
---
pppd/sys-linux.c | 194 ++++++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 192 insertions(+), 2 deletions(-)
--- a/pppd/sys-linux.c
+++ b/pppd/sys-linux.c
@@ -126,6 +126,11 @@
#include <linux/netlink.h>
#include <linux/rtnetlink.h>
#include <linux/if_link.h>
+
+#ifdef INET6
+#include <linux/if_addr.h>
+#endif
+
/* Attempt at retaining compile-support with older than 4.7 kernels, or kernels
* where RTM_NEWSTATS isn't defined for whatever reason.
*/
@@ -135,16 +140,20 @@
#define IFLA_STATS_LINK_64 1
#endif
-#ifdef INET6
-#include <linux/if_addr.h>
/* glibc versions prior to 2.24 do not define SOL_NETLINK */
#ifndef SOL_NETLINK
#define SOL_NETLINK 270
#endif
+
/* linux kernel versions prior to 4.3 do not define/support NETLINK_CAP_ACK */
#ifndef NETLINK_CAP_ACK
#define NETLINK_CAP_ACK 10
#endif
+
+/* linux kernel versions prior to 4.7 do not define/support IFLA_PPP_DEV_FD */
+#ifndef IFLA_PPP_MAX
+/* IFLA_PPP_DEV_FD is declared as enum when IFLA_PPP_MAX is defined */
+#define IFLA_PPP_DEV_FD 1
#endif
#include "pppd.h"
@@ -657,6 +666,160 @@ void generic_disestablish_ppp(int dev_fd
}
/*
+ * make_ppp_unit_rtnetlink - register a new ppp network interface for ppp_dev_fd
+ * with specified req_ifname via rtnetlink. Interface name req_ifname must not
+ * be empty. Custom ppp unit id req_unit is ignored and kernel choose some free.
+ */
+static int make_ppp_unit_rtnetlink(void)
+{
+ struct {
+ struct nlmsghdr nlh;
+ struct ifinfomsg ifm;
+ struct {
+ struct rtattr rta;
+ char ifname[IFNAMSIZ];
+ } ifn;
+ struct {
+ struct rtattr rta;
+ struct {
+ struct rtattr rta;
+ char ifkind[sizeof("ppp")];
+ } ifik;
+ struct {
+ struct rtattr rta;
+ struct {
+ struct rtattr rta;
+ union {
+ int ppp_dev_fd;
+ } ppp;
+ } ifdata[1];
+ } ifid;
+ } ifli;
+ } nlreq;
+ struct {
+ struct nlmsghdr nlh;
+ struct nlmsgerr nlerr;
+ } nlresp;
+ struct sockaddr_nl nladdr;
+ struct iovec iov;
+ struct msghdr msg;
+ ssize_t nlresplen;
+ int one;
+ int fd;
+
+ fd = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
+ if (fd < 0) {
+ error("make_ppp_unit_rtnetlink: socket(NETLINK_ROUTE): %m (line %d)", __LINE__);
+ return 0;
+ }
+
+ /* Tell kernel to not send to us payload of acknowledgment error message. */
+ one = 1;
+ setsockopt(fd, SOL_NETLINK, NETLINK_CAP_ACK, &one, sizeof(one));
+
+ memset(&nladdr, 0, sizeof(nladdr));
+ nladdr.nl_family = AF_NETLINK;
+
+ if (bind(fd, (struct sockaddr *)&nladdr, sizeof(nladdr)) < 0) {
+ error("make_ppp_unit_rtnetlink: bind(AF_NETLINK): %m (line %d)", __LINE__);
+ close(fd);
+ return 0;
+ }
+
+ memset(&nlreq, 0, sizeof(nlreq));
+ nlreq.nlh.nlmsg_len = sizeof(nlreq);
+ nlreq.nlh.nlmsg_type = RTM_NEWLINK;
+ nlreq.nlh.nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK | NLM_F_EXCL | NLM_F_CREATE;
+ nlreq.ifm.ifi_family = AF_UNSPEC;
+ nlreq.ifm.ifi_type = ARPHRD_NETROM;
+ nlreq.ifn.rta.rta_len = sizeof(nlreq.ifn);
+ nlreq.ifn.rta.rta_type = IFLA_IFNAME;
+ strlcpy(nlreq.ifn.ifname, req_ifname, sizeof(nlreq.ifn.ifname));
+ nlreq.ifli.rta.rta_len = sizeof(nlreq.ifli);
+ nlreq.ifli.rta.rta_type = IFLA_LINKINFO;
+ nlreq.ifli.ifik.rta.rta_len = sizeof(nlreq.ifli.ifik);
+ nlreq.ifli.ifik.rta.rta_type = IFLA_INFO_KIND;
+ strcpy(nlreq.ifli.ifik.ifkind, "ppp");
+ nlreq.ifli.ifid.rta.rta_len = sizeof(nlreq.ifli.ifid);
+ nlreq.ifli.ifid.rta.rta_type = IFLA_INFO_DATA;
+ nlreq.ifli.ifid.ifdata[0].rta.rta_len = sizeof(nlreq.ifli.ifid.ifdata[0]);
+ nlreq.ifli.ifid.ifdata[0].rta.rta_type = IFLA_PPP_DEV_FD;
+ nlreq.ifli.ifid.ifdata[0].ppp.ppp_dev_fd = ppp_dev_fd;
+
+ memset(&nladdr, 0, sizeof(nladdr));
+ nladdr.nl_family = AF_NETLINK;
+
+ memset(&iov, 0, sizeof(iov));
+ iov.iov_base = &nlreq;
+ iov.iov_len = sizeof(nlreq);
+
+ memset(&msg, 0, sizeof(msg));
+ msg.msg_name = &nladdr;
+ msg.msg_namelen = sizeof(nladdr);
+ msg.msg_iov = &iov;
+ msg.msg_iovlen = 1;
+
+ if (sendmsg(fd, &msg, 0) < 0) {
+ error("make_ppp_unit_rtnetlink: sendmsg(RTM_NEWLINK/NLM_F_CREATE): %m (line %d)", __LINE__);
+ close(fd);
+ return 0;
+ }
+
+ memset(&iov, 0, sizeof(iov));
+ iov.iov_base = &nlresp;
+ iov.iov_len = sizeof(nlresp);
+
+ memset(&msg, 0, sizeof(msg));
+ msg.msg_name = &nladdr;
+ msg.msg_namelen = sizeof(nladdr);
+ msg.msg_iov = &iov;
+ msg.msg_iovlen = 1;
+
+ nlresplen = recvmsg(fd, &msg, 0);
+
+ if (nlresplen < 0) {
+ error("make_ppp_unit_rtnetlink: recvmsg(NLM_F_ACK): %m (line %d)", __LINE__);
+ close(fd);
+ return 0;
+ }
+
+ close(fd);
+
+ if (nladdr.nl_family != AF_NETLINK) {
+ error("make_ppp_unit_rtnetlink: recvmsg(NLM_F_ACK): Not a netlink packet (line %d)", __LINE__);
+ return 0;
+ }
+
+ if ((size_t)nlresplen < sizeof(nlresp) || nlresp.nlh.nlmsg_len < sizeof(nlresp)) {
+ error("make_ppp_unit_rtnetlink: recvmsg(NLM_F_ACK): Acknowledgment netlink packet too short (line %d)", __LINE__);
+ return 0;
+ }
+
+ /* acknowledgment packet for NLM_F_ACK is NLMSG_ERROR */
+ if (nlresp.nlh.nlmsg_type != NLMSG_ERROR) {
+ error("make_ppp_unit_rtnetlink: recvmsg(NLM_F_ACK): Not an acknowledgment netlink packet (line %d)", __LINE__);
+ return 0;
+ }
+
+ /* error == 0 indicates success, negative value is errno code */
+ if (nlresp.nlerr.error != 0) {
+ /*
+ * Linux kernel versions prior to 4.7 do not support creating ppp
+ * interfaces via rtnetlink API and therefore error response is
+ * expected. On older kernel versions do not show this error message.
+ * When error is different than EEXIST then pppd tries to fallback to
+ * the old ioctl method.
+ */
+ errno = (nlresp.nlerr.error < 0) ? -nlresp.nlerr.error : EINVAL;
+ if (kernel_version >= KVERSION(4,7,0))
+ error("Couldn't create ppp interface %s: %m", req_ifname);
+ return 0;
+ }
+
+ return 1;
+}
+
+/*
* make_ppp_unit - make a new ppp unit for ppp_dev_fd.
* Assumes new_style_driver.
*/
@@ -676,6 +839,33 @@ static int make_ppp_unit(void)
|| fcntl(ppp_dev_fd, F_SETFL, flags | O_NONBLOCK) == -1)
warn("Couldn't set /dev/ppp to nonblock: %m");
+ /*
+ * Via rtnetlink it is possible to create ppp network interface with
+ * custom ifname atomically. But it is not possible to specify custom
+ * ppp unit id.
+ *
+ * Tools like systemd, udev or NetworkManager are trying to query
+ * interface attributes based on interface name immediately when new
+ * network interface is created. And therefore immediate interface
+ * renaming is causing issues.
+ *
+ * So use rtnetlink API only when user requested custom ifname. It will
+ * avoid system issues with interface renaming.
+ */
+ if (req_unit == -1 && req_ifname[0] != '\0' && kernel_version >= KVERSION(2,1,16)) {
+ if (make_ppp_unit_rtnetlink()) {
+ if (ioctl(ppp_dev_fd, PPPIOCGUNIT, &ifunit))
+ fatal("Couldn't retrieve PPP unit id: %m");
+ return 0;
+ }
+ /*
+ * If interface with requested name already exist return error
+ * otherwise fallback to old ioctl method.
+ */
+ if (errno == EEXIST)
+ return -1;
+ }
+
ifunit = req_unit;
x = ioctl(ppp_dev_fd, PPPIOCNEWUNIT, &ifunit);
if (x < 0 && req_unit >= 0 && errno == EEXIST) {

View File

@@ -0,0 +1,59 @@
From 44609bfc974bdafc0316d069aabf5e2903efa805 Mon Sep 17 00:00:00 2001
From: pali <7141871+pali@users.noreply.github.com>
Date: Tue, 9 Aug 2022 11:20:15 +0200
Subject: [PATCH] pppd: Workaround for generating ppp unit id on Linux (#355)
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Linux kernel has nasty bug / feature. If PPPIOCNEWUNIT is called with
negative ppp unit id (which is default option when command line argument
"unit" is not specified; and tells kernel to choose some free ppp unit id)
and the lowest unused/free ppp unit id is present in some existing network
interface name prefixed by "ppp" string then this PPPIOCNEWUNIT ioctl
fails. In this case kernel is basically unable to create a new ppp
interface via PPPIOCNEWUNIT ioctl when user does not specify some unused
and non-conflicted unit id.
Linux kernel should be fixed to choose usable ppp unit id when was
requested via PPPIOCNEWUNIT parameter -1.
Until this happens, add a workaround for pppd to help choosing some random
ppp unit id when kernel returns this error.
Simple test case (run on system when there is no ppp interface):
sudo ./pppd ifname ppp1 nodefaultroute noauth nolock local nodetach pty "./pppd nodefaultroute noauth nolock local nodetach notty"
Second pppd process without this patch prints into syslog following error:
pppd 2.4.10-dev started by pali, uid 0
Couldn't create new ppp unit: File exists
Exit.
With this patch it falls back to random ppp unit id and succeeds:
pppd 2.4.10-dev started by pali, uid 0
Using interface ppp1361
Connect: ppp1361 <--> /dev/pts/14
...
Signed-off-by: Pali Rohár <pali@kernel.org>
---
pppd/sys-linux.c | 5 +++++
1 file changed, 5 insertions(+)
--- a/pppd/sys-linux.c
+++ b/pppd/sys-linux.c
@@ -873,6 +873,11 @@ static int make_ppp_unit(void)
ifunit = -1;
x = ioctl(ppp_dev_fd, PPPIOCNEWUNIT, &ifunit);
}
+ if (x < 0 && errno == EEXIST) {
+ srand(time(NULL) * getpid());
+ ifunit = rand() % 10000;
+ x = ioctl(ppp_dev_fd, PPPIOCNEWUNIT, &ifunit);
+ }
if (x < 0)
error("Couldn't create new ppp unit: %m");

View File

@@ -0,0 +1,218 @@
From 089687fbcc6524809ae9f4b2f8145fe3c2a91147 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Pali=20Roh=C3=A1r?= <pali@kernel.org>
Date: Sat, 7 Aug 2021 19:48:01 +0200
Subject: [PATCH] pppd: Retry registering interface when on rtnetlink -EBUSY
error
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Due to workaround in kernel module ppp_generic.ko in function
ppp_nl_newlink(), kernel may return -EBUSY error to prevent possible
mutex deadlock. In this case userspace needs to retry its request.
Proper way would be to fix kernel module to order requests and mutex
locking, so prevent deadlock in kernel and so never return this error to
userspace. Until it happens we need retry code in userspace.
Signed-off-by: Pali Rohár <pali@kernel.org>
[ backport to ppp 2.4.9 ]
Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
---
pppd/sys-linux.c | 9 ++++++++-
1 file changed, 8 insertions(+), 1 deletion(-)
--- a/pppd/sys-linux.c
+++ b/pppd/sys-linux.c
@@ -707,99 +707,101 @@ static int make_ppp_unit_rtnetlink(void)
int one;
int fd;
- fd = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
- if (fd < 0) {
- error("make_ppp_unit_rtnetlink: socket(NETLINK_ROUTE): %m (line %d)", __LINE__);
- return 0;
- }
-
- /* Tell kernel to not send to us payload of acknowledgment error message. */
- one = 1;
- setsockopt(fd, SOL_NETLINK, NETLINK_CAP_ACK, &one, sizeof(one));
+ do {
+ fd = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
+ if (fd < 0) {
+ error("make_ppp_unit_rtnetlink: socket(NETLINK_ROUTE): %m (line %d)", __LINE__);
+ return 0;
+ }
+
+ /* Tell kernel to not send to us payload of acknowledgment error message. */
+ one = 1;
+ setsockopt(fd, SOL_NETLINK, NETLINK_CAP_ACK, &one, sizeof(one));
+
+ memset(&nladdr, 0, sizeof(nladdr));
+ nladdr.nl_family = AF_NETLINK;
+
+ if (bind(fd, (struct sockaddr *)&nladdr, sizeof(nladdr)) < 0) {
+ error("make_ppp_unit_rtnetlink: bind(AF_NETLINK): %m (line %d)", __LINE__);
+ close(fd);
+ return 0;
+ }
+
+ memset(&nlreq, 0, sizeof(nlreq));
+ nlreq.nlh.nlmsg_len = sizeof(nlreq);
+ nlreq.nlh.nlmsg_type = RTM_NEWLINK;
+ nlreq.nlh.nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK | NLM_F_EXCL | NLM_F_CREATE;
+ nlreq.ifm.ifi_family = AF_UNSPEC;
+ nlreq.ifm.ifi_type = ARPHRD_NETROM;
+ nlreq.ifn.rta.rta_len = sizeof(nlreq.ifn);
+ nlreq.ifn.rta.rta_type = IFLA_IFNAME;
+ strlcpy(nlreq.ifn.ifname, req_ifname, sizeof(nlreq.ifn.ifname));
+ nlreq.ifli.rta.rta_len = sizeof(nlreq.ifli);
+ nlreq.ifli.rta.rta_type = IFLA_LINKINFO;
+ nlreq.ifli.ifik.rta.rta_len = sizeof(nlreq.ifli.ifik);
+ nlreq.ifli.ifik.rta.rta_type = IFLA_INFO_KIND;
+ strcpy(nlreq.ifli.ifik.ifkind, "ppp");
+ nlreq.ifli.ifid.rta.rta_len = sizeof(nlreq.ifli.ifid);
+ nlreq.ifli.ifid.rta.rta_type = IFLA_INFO_DATA;
+ nlreq.ifli.ifid.ifdata[0].rta.rta_len = sizeof(nlreq.ifli.ifid.ifdata[0]);
+ nlreq.ifli.ifid.ifdata[0].rta.rta_type = IFLA_PPP_DEV_FD;
+ nlreq.ifli.ifid.ifdata[0].ppp.ppp_dev_fd = ppp_dev_fd;
+
+ memset(&nladdr, 0, sizeof(nladdr));
+ nladdr.nl_family = AF_NETLINK;
+
+ memset(&iov, 0, sizeof(iov));
+ iov.iov_base = &nlreq;
+ iov.iov_len = sizeof(nlreq);
+
+ memset(&msg, 0, sizeof(msg));
+ msg.msg_name = &nladdr;
+ msg.msg_namelen = sizeof(nladdr);
+ msg.msg_iov = &iov;
+ msg.msg_iovlen = 1;
+
+ if (sendmsg(fd, &msg, 0) < 0) {
+ error("make_ppp_unit_rtnetlink: sendmsg(RTM_NEWLINK/NLM_F_CREATE): %m (line %d)", __LINE__);
+ close(fd);
+ return 0;
+ }
+
+ memset(&iov, 0, sizeof(iov));
+ iov.iov_base = &nlresp;
+ iov.iov_len = sizeof(nlresp);
+
+ memset(&msg, 0, sizeof(msg));
+ msg.msg_name = &nladdr;
+ msg.msg_namelen = sizeof(nladdr);
+ msg.msg_iov = &iov;
+ msg.msg_iovlen = 1;
+
+ nlresplen = recvmsg(fd, &msg, 0);
+
+ if (nlresplen < 0) {
+ error("make_ppp_unit_rtnetlink: recvmsg(NLM_F_ACK): %m (line %d)", __LINE__);
+ close(fd);
+ return 0;
+ }
- memset(&nladdr, 0, sizeof(nladdr));
- nladdr.nl_family = AF_NETLINK;
-
- if (bind(fd, (struct sockaddr *)&nladdr, sizeof(nladdr)) < 0) {
- error("make_ppp_unit_rtnetlink: bind(AF_NETLINK): %m (line %d)", __LINE__);
close(fd);
- return 0;
- }
-
- memset(&nlreq, 0, sizeof(nlreq));
- nlreq.nlh.nlmsg_len = sizeof(nlreq);
- nlreq.nlh.nlmsg_type = RTM_NEWLINK;
- nlreq.nlh.nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK | NLM_F_EXCL | NLM_F_CREATE;
- nlreq.ifm.ifi_family = AF_UNSPEC;
- nlreq.ifm.ifi_type = ARPHRD_NETROM;
- nlreq.ifn.rta.rta_len = sizeof(nlreq.ifn);
- nlreq.ifn.rta.rta_type = IFLA_IFNAME;
- strlcpy(nlreq.ifn.ifname, req_ifname, sizeof(nlreq.ifn.ifname));
- nlreq.ifli.rta.rta_len = sizeof(nlreq.ifli);
- nlreq.ifli.rta.rta_type = IFLA_LINKINFO;
- nlreq.ifli.ifik.rta.rta_len = sizeof(nlreq.ifli.ifik);
- nlreq.ifli.ifik.rta.rta_type = IFLA_INFO_KIND;
- strcpy(nlreq.ifli.ifik.ifkind, "ppp");
- nlreq.ifli.ifid.rta.rta_len = sizeof(nlreq.ifli.ifid);
- nlreq.ifli.ifid.rta.rta_type = IFLA_INFO_DATA;
- nlreq.ifli.ifid.ifdata[0].rta.rta_len = sizeof(nlreq.ifli.ifid.ifdata[0]);
- nlreq.ifli.ifid.ifdata[0].rta.rta_type = IFLA_PPP_DEV_FD;
- nlreq.ifli.ifid.ifdata[0].ppp.ppp_dev_fd = ppp_dev_fd;
-
- memset(&nladdr, 0, sizeof(nladdr));
- nladdr.nl_family = AF_NETLINK;
-
- memset(&iov, 0, sizeof(iov));
- iov.iov_base = &nlreq;
- iov.iov_len = sizeof(nlreq);
-
- memset(&msg, 0, sizeof(msg));
- msg.msg_name = &nladdr;
- msg.msg_namelen = sizeof(nladdr);
- msg.msg_iov = &iov;
- msg.msg_iovlen = 1;
-
- if (sendmsg(fd, &msg, 0) < 0) {
- error("make_ppp_unit_rtnetlink: sendmsg(RTM_NEWLINK/NLM_F_CREATE): %m (line %d)", __LINE__);
- close(fd);
- return 0;
- }
-
- memset(&iov, 0, sizeof(iov));
- iov.iov_base = &nlresp;
- iov.iov_len = sizeof(nlresp);
-
- memset(&msg, 0, sizeof(msg));
- msg.msg_name = &nladdr;
- msg.msg_namelen = sizeof(nladdr);
- msg.msg_iov = &iov;
- msg.msg_iovlen = 1;
-
- nlresplen = recvmsg(fd, &msg, 0);
-
- if (nlresplen < 0) {
- error("make_ppp_unit_rtnetlink: recvmsg(NLM_F_ACK): %m (line %d)", __LINE__);
- close(fd);
- return 0;
- }
-
- close(fd);
- if (nladdr.nl_family != AF_NETLINK) {
- error("make_ppp_unit_rtnetlink: recvmsg(NLM_F_ACK): Not a netlink packet (line %d)", __LINE__);
- return 0;
- }
-
- if ((size_t)nlresplen < sizeof(nlresp) || nlresp.nlh.nlmsg_len < sizeof(nlresp)) {
- error("make_ppp_unit_rtnetlink: recvmsg(NLM_F_ACK): Acknowledgment netlink packet too short (line %d)", __LINE__);
- return 0;
- }
-
- /* acknowledgment packet for NLM_F_ACK is NLMSG_ERROR */
- if (nlresp.nlh.nlmsg_type != NLMSG_ERROR) {
- error("make_ppp_unit_rtnetlink: recvmsg(NLM_F_ACK): Not an acknowledgment netlink packet (line %d)", __LINE__);
- return 0;
- }
+ if (nladdr.nl_family != AF_NETLINK) {
+ error("make_ppp_unit_rtnetlink: recvmsg(NLM_F_ACK): Not a netlink packet (line %d)", __LINE__);
+ return 0;
+ }
+
+ if ((size_t)nlresplen < sizeof(nlresp) || nlresp.nlh.nlmsg_len < sizeof(nlresp)) {
+ error("make_ppp_unit_rtnetlink: recvmsg(NLM_F_ACK): Acknowledgment netlink packet too short (line %d)", __LINE__);
+ return 0;
+ }
+
+ /* acknowledgment packet for NLM_F_ACK is NLMSG_ERROR */
+ if (nlresp.nlh.nlmsg_type != NLMSG_ERROR) {
+ error("make_ppp_unit_rtnetlink: recvmsg(NLM_F_ACK): Not an acknowledgment netlink packet (line %d)", __LINE__);
+ return 0;
+ }
+ } while (nlresp.nlerr.error == -EBUSY);
/* error == 0 indicates success, negative value is errno code */
if (nlresp.nlerr.error != 0) {

View File

@@ -0,0 +1,56 @@
pppd: tune Linux config defaults for OpenWrt
This patch adjusts a number defaults to properly match the OpenWrt environment.
It is not intended for upstream.
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
--- a/pppd/Makefile.linux
+++ b/pppd/Makefile.linux
@@ -49,7 +49,7 @@ MPPE=y
# Uncomment the next line to include support for PPP packet filtering.
# This requires that the libpcap library and headers be installed
# and that the kernel driver support PPP packet filtering.
-FILTER=y
+#FILTER=y
# Uncomment the next line to enable multilink PPP (enabled by default)
# Linux distributions: Please leave multilink ENABLED in your builds
@@ -59,7 +59,7 @@ HAVE_MULTILINK=y
# Uncomment the next line to enable the TDB database (enabled by default.)
# If you enable multilink, then TDB is automatically enabled also.
# Linux distributions: Please leave TDB ENABLED in your builds.
-USE_TDB=y
+#USE_TDB=y
# Uncomment the next line to enable Type=notify services in systemd
# If enabled, and the user sets the up_sdnotify option, then
@@ -85,13 +85,13 @@ USE_LIBUTIL=y
endif
# Enable EAP-TLS authentication (requires MPPE support, libssl and libcrypto)
-USE_EAPTLS=y
+#USE_EAPTLS=y
MAXOCTETS=y
INCLUDE_DIRS= -I../include
-COMPILE_FLAGS= -DHAVE_PATHS_H -DIPX_CHANGE -DHAVE_MMAP -pipe
+COMPILE_FLAGS= -DHAVE_PATHS_H -DHAVE_MMAP -pipe
CFLAGS= $(COPTS) $(COMPILE_FLAGS) $(INCLUDE_DIRS) '-DDESTDIR="@DESTDIR@"'
@@ -143,10 +143,10 @@ CFLAGS += -DHAS_SHADOW
#LIBS += -lshadow $(LIBS)
endif
-ifeq ($(shell echo '\#include <crypt.h>' | $(CC) -E - >/dev/null 2>&1 && echo yes),yes)
+#ifeq ($(shell echo '\#include <crypt.h>' | $(CC) -E - >/dev/null 2>&1 && echo yes),yes)
CFLAGS += -DHAVE_CRYPT_H=1
LIBS += -lcrypt
-endif
+#endif
ifdef USE_LIBUTIL
CFLAGS += -DHAVE_LOGWTMP=1

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,38 @@
build: Move optimization flags into a separate variable
Isolate optimization related compiler flags from CFLAGS and move them into a
separate COPTS variable so that it is easier to override optimizations from
the environment.
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
--- a/pppd/plugins/radius/Makefile.linux
+++ b/pppd/plugins/radius/Makefile.linux
@@ -47,13 +47,13 @@ install: all
$(INSTALL) -c -m 444 pppd-radattr.8 $(MANDIR)
radius.so: radius.o libradiusclient.a
- $(CC) $(LDFLAGS) -o radius.so -shared radius.o libradiusclient.a
+ $(CC) $(LDFLAGS) -fPIC -o radius.so -shared radius.o libradiusclient.a
radattr.so: radattr.o
- $(CC) $(LDFLAGS) -o radattr.so -shared radattr.o
+ $(CC) $(LDFLAGS) -fPIC -o radattr.so -shared radattr.o
radrealms.so: radrealms.o
- $(CC) $(LDFLAGS) -o radrealms.so -shared radrealms.o
+ $(CC) $(LDFLAGS) -fPIC -o radrealms.so -shared radrealms.o
CLIENTOBJS = avpair.o buildreq.o config.o dict.o ip_util.o \
clientid.o sendserver.o lock.o util.o md5.o
--- a/pppd/plugins/pppoe/Makefile.linux
+++ b/pppd/plugins/pppoe/Makefile.linux
@@ -38,7 +38,7 @@ debug.o: debug.c
$(CC) $(CFLAGS) -I../../.. -c -o debug.o debug.c
pppoe.so: plugin.o discovery.o if.o common.o
- $(CC) $(LDFLAGS) -o pppoe.so -shared plugin.o discovery.o if.o common.o
+ $(CC) $(LDFLAGS) -fPIC -o pppoe.so -shared plugin.o discovery.o if.o common.o
install: all
$(INSTALL) -d -m 755 $(LIBDIR)

View File

@@ -0,0 +1,72 @@
--- a/pppd/plugins/radius/config.c
+++ b/pppd/plugins/radius/config.c
@@ -371,31 +371,37 @@ static int test_config(char *filename)
}
#endif
+#if 0
if (rc_conf_int("login_tries") <= 0)
{
error("%s: login_tries <= 0 is illegal", filename);
return (-1);
}
+#endif
if (rc_conf_str("seqfile") == NULL)
{
error("%s: seqfile not specified", filename);
return (-1);
}
+#if 0
if (rc_conf_int("login_timeout") <= 0)
{
error("%s: login_timeout <= 0 is illegal", filename);
return (-1);
}
+#endif
if (rc_conf_str("mapfile") == NULL)
{
error("%s: mapfile not specified", filename);
return (-1);
}
+#if 0
if (rc_conf_str("nologin") == NULL)
{
error("%s: nologin not specified", filename);
return (-1);
}
+#endif
return 0;
}
--- a/pppd/plugins/radius/options.h
+++ b/pppd/plugins/radius/options.h
@@ -31,24 +31,21 @@ typedef struct _option {
static SERVER acctserver = {0};
static SERVER authserver = {0};
-int default_tries = 4;
-int default_timeout = 60;
-
static OPTION config_options[] = {
/* internally used options */
{"config_file", OT_STR, ST_UNDEF, NULL},
/* General options */
{"auth_order", OT_AUO, ST_UNDEF, NULL},
-{"login_tries", OT_INT, ST_UNDEF, &default_tries},
-{"login_timeout", OT_INT, ST_UNDEF, &default_timeout},
-{"nologin", OT_STR, ST_UNDEF, "/etc/nologin"},
-{"issue", OT_STR, ST_UNDEF, "/etc/radiusclient/issue"},
+{"login_tries", OT_INT, ST_UNDEF, NULL},
+{"login_timeout", OT_INT, ST_UNDEF, NULL},
+{"nologin", OT_STR, ST_UNDEF, NULL},
+{"issue", OT_STR, ST_UNDEF, NULL},
/* RADIUS specific options */
{"authserver", OT_SRV, ST_UNDEF, &authserver},
{"acctserver", OT_SRV, ST_UNDEF, &acctserver},
{"servers", OT_STR, ST_UNDEF, NULL},
{"dictionary", OT_STR, ST_UNDEF, NULL},
-{"login_radius", OT_STR, ST_UNDEF, "/usr/sbin/login.radius"},
+{"login_radius", OT_STR, ST_UNDEF, NULL},
{"seqfile", OT_STR, ST_UNDEF, NULL},
{"mapfile", OT_STR, ST_UNDEF, NULL},
{"default_realm", OT_STR, ST_UNDEF, NULL},

View File

@@ -0,0 +1,29 @@
pppd: Don't use exponential timeout in discovery phase
This patch removes the exponential timeout increase between PADO or PADS
discovery attempts.
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
--- a/pppd/plugins/pppoe/discovery.c
+++ b/pppd/plugins/pppoe/discovery.c
@@ -632,7 +632,9 @@ discovery(PPPoEConnection *conn)
conn->discoveryState = STATE_SENT_PADI;
waitForPADO(conn, timeout);
+#if 0
timeout *= 2;
+#endif
} while (conn->discoveryState == STATE_SENT_PADI);
timeout = conn->discoveryTimeout;
@@ -647,7 +649,9 @@ discovery(PPPoEConnection *conn)
sendPADR(conn);
conn->discoveryState = STATE_SENT_PADR;
waitForPADS(conn, timeout);
+#if 0
timeout *= 2;
+#endif
} while (conn->discoveryState == STATE_SENT_PADR);
if (!conn->seenMaxPayload) {

View File

@@ -0,0 +1,25 @@
pppd: Cap MTU to the user configured value
This patchs caps the calculated MTU value in lcp.c to the user specified "mru"
option value. Without this patch pppd would advertise a different MTU value
compared to what is set on the local interface in some cases.
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
--- a/pppd/lcp.c
+++ b/pppd/lcp.c
@@ -1862,12 +1862,12 @@ lcp_up(fsm *f)
* the interface MTU is set to the lowest of that, the
* MTU we want to use, and our link MRU.
*/
- mtu = ho->neg_mru? ho->mru: PPP_MRU;
+ mtu = MIN(ho->neg_mru? ho->mru: PPP_MRU, ao->mru);
mru = go->neg_mru? MAX(wo->mru, go->mru): PPP_MRU;
#ifdef HAVE_MULTILINK
if (!(multilink && go->neg_mrru && ho->neg_mrru))
#endif /* HAVE_MULTILINK */
- netif_set_mtu(f->unit, MIN(MIN(mtu, mru), ao->mru));
+ netif_set_mtu(f->unit, MIN(mtu, mru));
ppp_send_config(f->unit, mtu,
(ho->neg_asyncmap? ho->asyncmap: 0xffffffff),
ho->neg_pcompression, ho->neg_accompression);

View File

@@ -0,0 +1,24 @@
pppd: Do not clobber exit codes on hangup
When a modem hangup occurs, pppd unconditionally sets the exit status code
to EXIT_HANGUP. This patch only sets EXIT_HANGUP if the exit status code is
not already set to an error value.
The motiviation of this patch is to allow applications which remote control
pppd to react properly on errors, e.g. only redial (relaunch pppd) if there
was a hangup, but not if the CHAP authentication failed.
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
--- a/pppd/main.c
+++ b/pppd/main.c
@@ -1035,7 +1035,8 @@ get_input(void)
}
notice("Modem hangup");
hungup = 1;
- status = EXIT_HANGUP;
+ if (status == EXIT_OK)
+ status = EXIT_HANGUP;
lcp_lowerdown(0); /* serial link is no longer available */
link_terminated(0);
return;

View File

@@ -0,0 +1,20 @@
build: Add required CFLAGS for libpcap
This patch adds some flags to required to properly link libpcap within the
OpenWrt environment.
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
--- a/pppd/Makefile.linux
+++ b/pppd/Makefile.linux
@@ -210,8 +210,8 @@ LIBS += -ldl
endif
ifdef FILTER
-LIBS += -lpcap
-CFLAGS += -DPPP_FILTER
+LIBS += -lpcap -L$(STAGING_DIR)/usr/lib
+CFLAGS += -DPPP_FILTER -I$(STAGING_DIR)/usr/include
endif
ifdef HAVE_INET6

View File

@@ -0,0 +1,194 @@
pppd: Implement support for precompiled pcap filters
This patch implements support for precompiled pcap filters which is useful to
support dial-on-demand on memory constrained embedded devices without having
to link the full libpcap into pppd to generate the filters during runtime.
Two new options are introduced; "precompiled-pass-filter" specifies a pre-
compiled filter file containing rules to match packets which should be passed,
"precompiled-active-filter" specifies a filter file containing rules to match
packets which are treated as active.
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
--- a/pppd/Makefile.linux
+++ b/pppd/Makefile.linux
@@ -51,6 +51,9 @@ MPPE=y
# and that the kernel driver support PPP packet filtering.
#FILTER=y
+# Support for precompiled filters
+PRECOMPILED_FILTER=y
+
# Uncomment the next line to enable multilink PPP (enabled by default)
# Linux distributions: Please leave multilink ENABLED in your builds
# of pppd!
@@ -214,6 +217,14 @@ LIBS += -lpcap -L$(STAGING_DIR)/usr/l
CFLAGS += -DPPP_FILTER -I$(STAGING_DIR)/usr/include
endif
+ifdef PRECOMPILED_FILTER
+PPPDSRCS += pcap_pcc.c
+HEADERS += pcap_pcc.h
+PPPDOBJS += pcap_pcc.o
+LIBS += $(STAGING_DIR)/usr/lib/libpcap.a
+CFLAGS += -DPPP_FILTER -DPPP_PRECOMPILED_FILTER -I$(STAGING_DIR)/usr/include
+endif
+
ifdef HAVE_INET6
PPPDSRCS += ipv6cp.c eui64.c
HEADERS += ipv6cp.h eui64.h
--- a/pppd/options.c
+++ b/pppd/options.c
@@ -56,6 +56,7 @@
#ifdef PPP_FILTER
#include <pcap.h>
+#include <pcap-bpf.h>
/*
* There have been 3 or 4 different names for this in libpcap CVS, but
* this seems to be what they have settled on...
@@ -168,6 +169,13 @@ static int setlogfile(char **);
static int loadplugin(char **);
#endif
+#ifdef PPP_PRECOMPILED_FILTER
+#include "pcap_pcc.h"
+static int setprecompiledpassfilter(char **);
+static int setprecompiledactivefilter(char **);
+#undef PPP_FILTER
+#endif
+
#ifdef PPP_FILTER
static int setpassfilter(char **);
static int setactivefilter(char **);
@@ -360,6 +368,14 @@ option_t general_options[] = {
"set filter for active pkts", OPT_PRIO },
#endif
+#ifdef PPP_PRECOMPILED_FILTER
+ { "precompiled-pass-filter", 1, setprecompiledpassfilter,
+ "set precompiled filter for packets to pass", OPT_PRIO },
+
+ { "precompiled-active-filter", 1, setprecompiledactivefilter,
+ "set precompiled filter for active pkts", OPT_PRIO },
+#endif
+
#ifdef MAXOCTETS
{ "maxoctets", o_int, &maxoctets,
"Set connection traffic limit",
@@ -1468,6 +1484,27 @@ callfile(char **argv)
return ok;
}
+#ifdef PPP_PRECOMPILED_FILTER
+/*
+ * setprecompiledpassfilter - Set the pass filter for packets using a
+ * precompiled expression
+ */
+static int
+setprecompiledpassfilter(char **argv)
+{
+ return pcap_pre_compiled (*argv, &pass_filter);
+}
+
+/*
+ * setactivefilter - Set the active filter for packets
+ */
+static int
+setprecompiledactivefilter(char **argv)
+{
+ return pcap_pre_compiled (*argv, &active_filter);
+}
+#endif
+
#ifdef PPP_FILTER
/*
* setpassfilter - Set the pass filter for packets
--- /dev/null
+++ b/pppd/pcap_pcc.c
@@ -0,0 +1,74 @@
+#include <pcap.h>
+#include <pcap-bpf.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include "pppd.h"
+
+int pcap_pre_compiled (char * fname, struct bpf_program *p)
+{
+ char buf[128];
+ int line = 0, size = 0, index=0, ret=1;
+ FILE *f = fopen (fname, "r");
+ if (!f)
+ {
+ option_error("error opening precompiled active-filter '%s': %s",
+ fname, strerror (errno));
+ return 0;
+ }
+ while (fgets (buf, 127, f))
+ {
+ line++;
+ if (*buf == '#')
+ continue;
+ if (size)
+ {
+ /*
+ struct bpf_insn {
+ u_short code;
+ u_char jt;
+ u_char jf;
+ bpf_int32 k;
+ }
+ */
+ struct bpf_insn * insn = & p->bf_insns[index];
+ unsigned code, jt, jf, k;
+ if (sscanf (buf, "%u %u %u %u", &code, &jt, &jf, &k) != 4)
+ {
+ goto err;
+ }
+ insn->code = code;
+ insn->jt = jt;
+ insn->jf = jf;
+ insn->k = k;
+ index++;
+ }
+ else
+ {
+ if (sscanf (buf, "%u", &size) != 1)
+ {
+ goto err;
+ }
+ p->bf_len = size;
+ p->bf_insns = (struct bpf_insn *)
+ malloc (size * sizeof (struct bpf_insn));
+ }
+ }
+ if (size != index)
+ {
+ option_error("error in precompiled active-filter,"
+ " expected %d expressions, got %dn",
+ size, index);
+ ret = 0;
+ }
+ fclose(f);
+ return ret;
+
+err:
+ option_error("error in precompiled active-filter"
+ " expression line %s:%d (wrong size)\n",
+ fname, line);
+ fclose (f);
+ return 0;
+}
--- /dev/null
+++ b/pppd/pcap_pcc.h
@@ -0,0 +1,7 @@
+#ifndef PCAP_PCC_H
+#define PCAP_PCC_H
+
+#include <pcap.h>
+
+int pcap_pre_compiled (char * fname, struct bpf_program *p);
+#endif /* PCAP_PCC_H */

View File

@@ -0,0 +1,147 @@
From: George Kashperko <george@znau.edu.ua>
Make mlppp support more generic interface naming other than pppX
Signed-off-by: George Kashperko <george@znau.edu.ua>
---
pppd/multilink.c | 55 +++++++++++++++++++++++++++++++++------------
pppd/sys-linux.c | 12 +++++++++
2 files changed, 53 insertions(+), 14 deletions(-)
--- a/pppd/multilink.c
+++ b/pppd/multilink.c
@@ -35,6 +35,7 @@
#include <signal.h>
#include <netinet/in.h>
#include <unistd.h>
+#include <net/if.h>
#include "pppd.h"
#include "fsm.h"
@@ -56,7 +57,8 @@ static void iterate_bundle_links(void (*
static int get_default_epdisc(struct epdisc *);
static int parse_num(char *str, const char *key, int *valp);
-static int owns_unit(TDB_DATA pid, int unit);
+static int parse_str(char *str, const char *key, char *buf, int buflen);
+static int owns_link(TDB_DATA pid, char *ifname);
#define set_ip_epdisc(ep, addr) do { \
ep->length = 4; \
@@ -197,35 +199,38 @@ mp_join_bundle(void)
key.dptr = bundle_id;
key.dsize = p - bundle_id;
pid = tdb_fetch(pppdb, key);
+
if (pid.dptr != NULL) {
+ char tmp[IFNAMSIZ];
+
/* bundle ID exists, see if the pppd record exists */
rec = tdb_fetch(pppdb, pid);
+
if (rec.dptr != NULL && rec.dsize > 0) {
/* make sure the string is null-terminated */
rec.dptr[rec.dsize-1] = 0;
- /* parse the interface number */
- parse_num(rec.dptr, "UNIT=", &unit);
+
/* check the pid value */
if (!parse_num(rec.dptr, "PPPD_PID=", &pppd_pid)
+ || !parse_str(rec.dptr, "IFNAME=", tmp, sizeof(tmp))
+ || !parse_num(rec.dptr, "IFUNIT=", &unit)
|| !process_exists(pppd_pid)
- || !owns_unit(pid, unit))
+ || !owns_link(pid, tmp))
unit = -1;
free(rec.dptr);
}
free(pid.dptr);
- }
- if (unit >= 0) {
/* attach to existing unit */
- if (bundle_attach(unit)) {
+ if (unit >= 0 && bundle_attach(unit)) {
set_ifunit(0);
script_setenv("BUNDLE", bundle_id + 7, 0);
make_bundle_links(1);
unlock_db();
- info("Link attached to %s", ifname);
+ info("Link attached to %s", tmp);
return 1;
+ /* attach failed because bundle doesn't exist */
}
- /* attach failed because bundle doesn't exist */
}
/* we have to make a new bundle */
@@ -405,20 +410,39 @@ parse_num(char *str, const char *key, in
return 0;
}
+static int
+parse_str(char *str, const char *key, char *buf, int buflen)
+{
+ char *p, *endp;
+ int i;
+
+ p = strstr(str, key);
+ if (p) {
+ p += strlen(key);
+ while (--buflen && *p != 0 && *p != ';')
+ *(buf++) = *(p++);
+ *buf = 0;
+ return 1;
+ }
+ return 0;
+}
+
/*
- * Check whether the pppd identified by `key' still owns ppp unit `unit'.
+ * Check whether the pppd identified by `key' still owns ppp link `ifname'.
*/
static int
-owns_unit(TDB_DATA key, int unit)
+owns_link(TDB_DATA key, char *ifname)
{
- char ifkey[32];
+ char ifkey[7 + IFNAMSIZ];
TDB_DATA kd, vd;
int ret = 0;
- slprintf(ifkey, sizeof(ifkey), "UNIT=%d", unit);
+ slprintf(ifkey, sizeof(ifkey), "IFNAME=%s", ifname);
+
kd.dptr = ifkey;
kd.dsize = strlen(ifkey);
vd = tdb_fetch(pppdb, kd);
+
if (vd.dptr != NULL) {
ret = vd.dsize == key.dsize
&& memcmp(vd.dptr, key.dptr, vd.dsize) == 0;
--- a/pppd/sys-linux.c
+++ b/pppd/sys-linux.c
@@ -923,6 +923,16 @@ void cfg_bundle(int mrru, int mtru, int
add_fd(ppp_dev_fd);
}
+static void
+setenv_ifunit(void)
+{
+#ifdef USE_TDB
+ char tmp[11];
+ slprintf(tmp, sizeof(tmp), "%d", ifunit);
+ script_setenv("IFUNIT", tmp, 0);
+#endif
+}
+
/*
* make_new_bundle - create a new PPP unit (i.e. a bundle)
* and connect our channel to it. This should only get called
@@ -941,6 +951,8 @@ void make_new_bundle(int mrru, int mtru,
/* set the mrru and flags */
cfg_bundle(mrru, mtru, rssn, tssn);
+
+ setenv_ifunit();
}
/*

View File

@@ -0,0 +1,22 @@
pppd: Retain foreign default routes on Linux
On Linux, when pppd attempts to delete its default route it does not fill
the rt_dev field of the struct rtentry used to match the system default route.
As a consequence, pppd happily deletes any default route even if it belongs
to another interface.
This patch makes pppd fill out the rt_dev field so that only own default
routes are ever matched.
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
--- a/pppd/sys-linux.c
+++ b/pppd/sys-linux.c
@@ -2248,6 +2248,7 @@ int cifdefaultroute (int unit, u_int32_t
SIN_ADDR(rt.rt_genmask) = 0L;
}
+ rt.rt_dev = ifname;
rt.rt_flags = RTF_UP;
if (ioctl(sock_fd, SIOCDELRT, &rt) < 0 && errno != ESRCH) {
if (still_ppp()) {

View File

@@ -0,0 +1,34 @@
pppd: Fill in default gateway on Linux
On Linux, when pppd creates the default route, it does not set the peer
address as gateway, leading to a default route without gateway address.
This behaviour breaks various downstream programs which attempt to infer
the default gateway IP address from the system default route entry.
This patch addresses the issue by filling in the peer address as gateway
when generating the default route entry.
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
--- a/pppd/sys-linux.c
+++ b/pppd/sys-linux.c
@@ -2198,6 +2198,9 @@ int sifdefaultroute (int unit, u_int32_t
memset (&rt, 0, sizeof (rt));
SET_SA_FAMILY (rt.rt_dst, AF_INET);
+ SET_SA_FAMILY(rt.rt_gateway, AF_INET);
+ SIN_ADDR(rt.rt_gateway) = gateway;
+
rt.rt_dev = ifname;
rt.rt_metric = dfl_route_metric + 1; /* +1 for binary compatibility */
@@ -2206,7 +2209,7 @@ int sifdefaultroute (int unit, u_int32_t
SIN_ADDR(rt.rt_genmask) = 0L;
}
- rt.rt_flags = RTF_UP;
+ rt.rt_flags = RTF_UP | RTF_GATEWAY;
if (ioctl(sock_fd, SIOCADDRT, &rt) < 0) {
if ( ! ok_error ( errno ))
error("default route ioctl(SIOCADDRT): %m");

View File

@@ -0,0 +1,154 @@
pppd: Remove runtime kernel checks
On embedded system distributions the required kernel features for pppd are
more or less guaranteed to be present, so there is not much point in
performing runtime checks, it just increases the binary size.
This patch removes the runtime kernel feature checks.
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
--- a/pppd/sys-linux.c
+++ b/pppd/sys-linux.c
@@ -235,7 +235,7 @@ static int driver_is_old = 0;
static int restore_term = 0; /* 1 => we've munged the terminal */
static struct termios inittermios; /* Initial TTY termios */
-int new_style_driver = 0;
+static const int new_style_driver = 1;
static char loop_name[20];
static unsigned char inbuf[512]; /* buffer for chars read from loopback */
@@ -254,8 +254,8 @@ static int looped; /* 1 if using loop
static int link_mtu; /* mtu for the link (not bundle) */
static struct utsname utsname; /* for the kernel version */
-static int kernel_version;
#define KVERSION(j,n,p) ((j)*1000000 + (n)*1000 + (p))
+static const int kernel_version = KVERSION(2,6,37);
#define MAX_IFS 100
@@ -1933,11 +1933,12 @@ int ccp_fatal_error (int unit)
*
* path_to_procfs - find the path to the proc file system mount point
*/
-static char proc_path[MAXPATHLEN];
-static int proc_path_len;
+static char proc_path[MAXPATHLEN] = "/proc";
+static int proc_path_len = 5;
static char *path_to_procfs(const char *tail)
{
+#if 0
struct mntent *mntent;
FILE *fp;
@@ -1959,6 +1960,7 @@ static char *path_to_procfs(const char *
fclose (fp);
}
}
+#endif
strlcpy(proc_path + proc_path_len, tail,
sizeof(proc_path) - proc_path_len);
@@ -2843,15 +2845,19 @@ int ppp_available(void)
int my_version, my_modification, my_patch;
int osmaj, osmin, ospatch;
+#if 0
/* get the kernel version now, since we are called before sys_init */
uname(&utsname);
osmaj = osmin = ospatch = 0;
sscanf(utsname.release, "%d.%d.%d", &osmaj, &osmin, &ospatch);
kernel_version = KVERSION(osmaj, osmin, ospatch);
+#endif
fd = open("/dev/ppp", O_RDWR);
if (fd >= 0) {
+#if 0
new_style_driver = 1;
+#endif
/* XXX should get from driver */
driver_version = 2;
@@ -2911,6 +2917,7 @@ int ppp_available(void)
if (ok && ((ifr.ifr_hwaddr.sa_family & ~0xFF) != ARPHRD_PPP))
ok = 0;
+ return ok;
/*
* This is the PPP device. Validate the version of the driver at this
@@ -3592,6 +3599,7 @@ get_pty(int *master_fdp, int *slave_fdp,
}
#endif /* TIOCGPTN */
+#if 0
if (sfd < 0) {
/* the old way - scan through the pty name space */
for (i = 0; i < 64; ++i) {
@@ -3610,6 +3618,7 @@ get_pty(int *master_fdp, int *slave_fdp,
}
}
}
+#endif
if (sfd < 0)
return 0;
--- a/pppd/plugins/pppoatm/pppoatm.c
+++ b/pppd/plugins/pppoatm/pppoatm.c
@@ -171,14 +171,6 @@ static void disconnect_pppoatm(void)
void plugin_init(void)
{
-#ifdef linux
- extern int new_style_driver; /* From sys-linux.c */
- if (!ppp_available() && !new_style_driver)
- fatal("Kernel doesn't support ppp_generic - "
- "needed for PPPoATM");
-#else
- fatal("No PPPoATM support on this OS");
-#endif
add_options(pppoa_options);
}
--- a/pppd/plugins/pppoe/plugin.c
+++ b/pppd/plugins/pppoe/plugin.c
@@ -58,9 +58,6 @@ static char const RCSID[] =
char pppd_version[] = VERSION;
-/* From sys-linux.c in pppd -- MUST FIX THIS! */
-extern int new_style_driver;
-
char *pppd_pppoe_service = NULL;
static char *acName = NULL;
static char *existingSession = NULL;
@@ -407,10 +404,6 @@ PPPoEDevnameHook(char *cmd, char **argv,
void
plugin_init(void)
{
- if (!ppp_available() && !new_style_driver) {
- fatal("Linux kernel does not support PPPoE -- are you running 2.4.x?");
- }
-
add_options(Options);
info("PPPoE plugin from pppd %s", VERSION);
--- a/pppd/plugins/pppol2tp/pppol2tp.c
+++ b/pppd/plugins/pppol2tp/pppol2tp.c
@@ -490,12 +490,7 @@ static void pppol2tp_cleanup(void)
void plugin_init(void)
{
-#if defined(__linux__)
- extern int new_style_driver; /* From sys-linux.c */
- if (!ppp_available() && !new_style_driver)
- fatal("Kernel doesn't support ppp_generic - "
- "needed for PPPoL2TP");
-#else
+#if !defined(__linux__)
fatal("No PPPoL2TP support on this OS");
#endif
add_options(pppol2tp_options);

View File

@@ -0,0 +1,39 @@
pppd: Remove the "record" option
On many embedded systems there is not enough space to record PPP session
information to the permanent storage, therfore remove this option.
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
--- a/pppd/pppd.h
+++ b/pppd/pppd.h
@@ -318,7 +318,6 @@ extern int holdoff; /* Dead time before
extern bool holdoff_specified; /* true if user gave a holdoff value */
extern bool notty; /* Stdin/out is not a tty */
extern char *pty_socket; /* Socket to connect to pty */
-extern char *record_file; /* File to record chars sent/received */
extern bool sync_serial; /* Device is synchronous serial device */
extern int maxfail; /* Max # of unsuccessful connection attempts */
extern char linkname[MAXPATHLEN]; /* logical name for link */
--- a/pppd/tty.c
+++ b/pppd/tty.c
@@ -143,7 +143,7 @@ char *disconnect_script = NULL; /* Scrip
char *welcomer = NULL; /* Script to run after phys link estab. */
char *ptycommand = NULL; /* Command to run on other side of pty */
bool notty = 0; /* Stdin/out is not a tty */
-char *record_file = NULL; /* File to record chars sent/received */
+static char *const record_file = NULL; /* File to record chars sent/received */
int max_data_rate; /* max bytes/sec through charshunt */
bool sync_serial = 0; /* Device is synchronous serial device */
char *pty_socket = NULL; /* Socket to connect to pty */
@@ -199,8 +199,10 @@ option_t tty_options[] = {
"Send and receive over socket, arg is host:port",
OPT_PRIO | OPT_DEVNAM },
+#if 0
{ "record", o_string, &record_file,
"Record characters sent/received to file", OPT_PRIO },
+#endif
{ "crtscts", o_int, &crtscts,
"Set hardware (RTS/CTS) flow control",

View File

@@ -0,0 +1,25 @@
pppd: Disable wtmp support
Many uClibc based environments lack wtmp and utmp support, therfore remove
the code updating the wtmp information.
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
--- a/pppd/sys-linux.c
+++ b/pppd/sys-linux.c
@@ -2981,6 +2981,7 @@ int ppp_available(void)
void logwtmp (const char *line, const char *name, const char *host)
{
+#if 0
struct utmp ut, *utp;
pid_t mypid = getpid();
#if __GLIBC__ < 2
@@ -3046,6 +3047,7 @@ void logwtmp (const char *line, const ch
close (wtmp);
}
#endif
+#endif
}
#endif /* HAVE_LOGWTMP */

View File

@@ -0,0 +1,151 @@
pppd: Remove historical protocol names
Remove a number of historical protocol entries from pppd's builtin list, this
reduced the binary size without loss of features.
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
--- a/pppd/main.c
+++ b/pppd/main.c
@@ -867,14 +867,17 @@ struct protocol_list {
const char *name;
} protocol_list[] = {
{ 0x21, "IP" },
+#if 0
{ 0x23, "OSI Network Layer" },
{ 0x25, "Xerox NS IDP" },
{ 0x27, "DECnet Phase IV" },
{ 0x29, "Appletalk" },
{ 0x2b, "Novell IPX" },
+#endif
{ 0x2d, "VJ compressed TCP/IP" },
{ 0x2f, "VJ uncompressed TCP/IP" },
{ 0x31, "Bridging PDU" },
+#if 0
{ 0x33, "Stream Protocol ST-II" },
{ 0x35, "Banyan Vines" },
{ 0x39, "AppleTalk EDDP" },
@@ -888,8 +891,11 @@ struct protocol_list {
{ 0x49, "Serial Data Transport Protocol (PPP-SDTP)" },
{ 0x4b, "SNA over 802.2" },
{ 0x4d, "SNA" },
+#endif
{ 0x4f, "IP6 Header Compression" },
+#if 0
{ 0x51, "KNX Bridging Data" },
+#endif
{ 0x53, "Encryption" },
{ 0x55, "Individual Link Encryption" },
{ 0x57, "IPv6" },
@@ -900,12 +906,15 @@ struct protocol_list {
{ 0x65, "RTP IPHC Compressed non-TCP" },
{ 0x67, "RTP IPHC Compressed UDP 8" },
{ 0x69, "RTP IPHC Compressed RTP 8" },
+#if 0
{ 0x6f, "Stampede Bridging" },
{ 0x73, "MP+" },
{ 0xc1, "NTCITS IPI" },
+#endif
{ 0xfb, "single-link compression" },
{ 0xfd, "Compressed Datagram" },
{ 0x0201, "802.1d Hello Packets" },
+#if 0
{ 0x0203, "IBM Source Routing BPDU" },
{ 0x0205, "DEC LANBridge100 Spanning Tree" },
{ 0x0207, "Cisco Discovery Protocol" },
@@ -917,15 +926,19 @@ struct protocol_list {
{ 0x0231, "Luxcom" },
{ 0x0233, "Sigma Network Systems" },
{ 0x0235, "Apple Client Server Protocol" },
+#endif
{ 0x0281, "MPLS Unicast" },
{ 0x0283, "MPLS Multicast" },
+#if 0
{ 0x0285, "IEEE p1284.4 standard - data packets" },
{ 0x0287, "ETSI TETRA Network Protocol Type 1" },
+#endif
{ 0x0289, "Multichannel Flow Treatment Protocol" },
{ 0x2063, "RTP IPHC Compressed TCP No Delta" },
{ 0x2065, "RTP IPHC Context State" },
{ 0x2067, "RTP IPHC Compressed UDP 16" },
{ 0x2069, "RTP IPHC Compressed RTP 16" },
+#if 0
{ 0x4001, "Cray Communications Control Protocol" },
{ 0x4003, "CDPD Mobile Network Registration Protocol" },
{ 0x4005, "Expand accelerator protocol" },
@@ -936,8 +949,10 @@ struct protocol_list {
{ 0x4023, "RefTek Protocol" },
{ 0x4025, "Fibre Channel" },
{ 0x4027, "EMIT Protocols" },
+#endif
{ 0x405b, "Vendor-Specific Protocol (VSP)" },
{ 0x8021, "Internet Protocol Control Protocol" },
+#if 0
{ 0x8023, "OSI Network Layer Control Protocol" },
{ 0x8025, "Xerox NS IDP Control Protocol" },
{ 0x8027, "DECnet Phase IV Control Protocol" },
@@ -946,7 +961,9 @@ struct protocol_list {
{ 0x8031, "Bridging NCP" },
{ 0x8033, "Stream Protocol Control Protocol" },
{ 0x8035, "Banyan Vines Control Protocol" },
+#endif
{ 0x803d, "Multi-Link Control Protocol" },
+#if 0
{ 0x803f, "NETBIOS Framing Control Protocol" },
{ 0x8041, "Cisco Systems Control Protocol" },
{ 0x8043, "Ascom Timeplex" },
@@ -955,18 +972,24 @@ struct protocol_list {
{ 0x8049, "Serial Data Control Protocol (PPP-SDCP)" },
{ 0x804b, "SNA over 802.2 Control Protocol" },
{ 0x804d, "SNA Control Protocol" },
+#endif
{ 0x804f, "IP6 Header Compression Control Protocol" },
+#if 0
{ 0x8051, "KNX Bridging Control Protocol" },
+#endif
{ 0x8053, "Encryption Control Protocol" },
{ 0x8055, "Individual Link Encryption Control Protocol" },
{ 0x8057, "IPv6 Control Protocol" },
{ 0x8059, "PPP Muxing Control Protocol" },
{ 0x805b, "Vendor-Specific Network Control Protocol (VSNCP)" },
+#if 0
{ 0x806f, "Stampede Bridging Control Protocol" },
{ 0x8073, "MP+ Control Protocol" },
{ 0x80c1, "NTCITS IPI Control Protocol" },
+#endif
{ 0x80fb, "Single Link Compression Control Protocol" },
{ 0x80fd, "Compression Control Protocol" },
+#if 0
{ 0x8207, "Cisco Discovery Protocol Control" },
{ 0x8209, "Netcs Twin Routing" },
{ 0x820b, "STP - Control Protocol" },
@@ -975,24 +998,29 @@ struct protocol_list {
{ 0x8281, "MPLSCP" },
{ 0x8285, "IEEE p1284.4 standard - Protocol Control" },
{ 0x8287, "ETSI TETRA TNP1 Control Protocol" },
+#endif
{ 0x8289, "Multichannel Flow Treatment Protocol" },
{ 0xc021, "Link Control Protocol" },
{ 0xc023, "Password Authentication Protocol" },
{ 0xc025, "Link Quality Report" },
+#if 0
{ 0xc027, "Shiva Password Authentication Protocol" },
{ 0xc029, "CallBack Control Protocol (CBCP)" },
{ 0xc02b, "BACP Bandwidth Allocation Control Protocol" },
{ 0xc02d, "BAP" },
+#endif
{ 0xc05b, "Vendor-Specific Authentication Protocol (VSAP)" },
{ 0xc081, "Container Control Protocol" },
{ 0xc223, "Challenge Handshake Authentication Protocol" },
{ 0xc225, "RSA Authentication Protocol" },
{ 0xc227, "Extensible Authentication Protocol" },
+#if 0
{ 0xc229, "Mitsubishi Security Info Exch Ptcl (SIEP)" },
{ 0xc26f, "Stampede Bridging Authorization Protocol" },
{ 0xc281, "Proprietary Authentication Protocol" },
{ 0xc283, "Proprietary Authentication Protocol" },
{ 0xc481, "Proprietary Node ID Authentication Protocol" },
+#endif
{ 0, NULL },
};

View File

@@ -0,0 +1,28 @@
pppd: Support "nomp" option even if multilink support is off
This patch moves the "nomp" option entry outside of the defines protecting
the multilink specific code. The motivation is to allow "nomp" even if pppd
does not support multilink, so that controlling programs can unconditionally
pass it to pppd regardless of the compile time features.
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
--- a/pppd/options.c
+++ b/pppd/options.c
@@ -348,13 +348,14 @@ option_t general_options[] = {
"Enable multilink operation", OPT_PRIOSUB | OPT_ALIAS | 1 },
{ "nomultilink", o_bool, &multilink,
"Disable multilink operation", OPT_PRIOSUB | 0 },
- { "nomp", o_bool, &multilink,
- "Disable multilink operation", OPT_PRIOSUB | OPT_ALIAS | 0 },
{ "bundle", o_string, &bundle_name,
"Bundle name for multilink", OPT_PRIO },
#endif /* HAVE_MULTILINK */
+ { "nomp", o_bool, &multilink,
+ "Disable multilink operation", OPT_PRIOSUB | OPT_ALIAS | 0 },
+
#ifdef PLUGIN
{ "plugin", o_special, (void *)loadplugin,
"Load a plug-in module into pppd", OPT_PRIV | OPT_A2LIST },

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,11 @@
--- a/pppd/plugins/pptp/pptp.c
+++ b/pppd/plugins/pptp/pptp.c
@@ -48,7 +48,7 @@
#include "pptp_callmgr.h"
#include <net/if.h>
-#include <net/ethernet.h>
+#include <linux/if_ether.h>
#include <linux/if_pppox.h>
#include <stdio.h>

View File

@@ -0,0 +1,11 @@
--- a/pppd/plugins/pptp/Makefile.linux
+++ b/pppd/plugins/pptp/Makefile.linux
@@ -20,7 +20,7 @@ all: pptp.so
$(CC) $(CFLAGS) -c -o $@ $<
pptp.so: dirutil.o orckit_quirks.o pptp.o pptp_callmgr.o pptp_ctrl.o pptp_quirks.o util.o vector.o
- $(CC) -o pptp.so -shared dirutil.o orckit_quirks.o pptp.o pptp_callmgr.o pptp_ctrl.o pptp_quirks.o util.o vector.o
+ $(CC) -fPIC -o pptp.so -shared dirutil.o orckit_quirks.o pptp.o pptp_callmgr.o pptp_ctrl.o pptp_quirks.o util.o vector.o
install: all
$(INSTALL) -d -m 755 $(LIBDIR)

View File

@@ -0,0 +1,89 @@
From 831dca008699d485f2c8e91749657ef2d0b06166 Mon Sep 17 00:00:00 2001
From: Martin Schiller <ms@dev.tdt.de>
Date: Thu, 6 Dec 2018 08:43:17 +0100
Subject: [PATCH] Revert "pppd: Use openssl for the DES instead of the libcrypt
/ glibc"
For musl and glibc2.27 we can keep linking to crypt; however if we
switch to glibc 2.28 we will have to link to one of the SSL libraries.
This reverts commit 3c7b86229f7bd2600d74db14b1fe5b3896be3875.
---
pppd/Makefile.linux | 7 +++----
pppd/pppcrypt.c | 18 +++++++++---------
2 files changed, 12 insertions(+), 13 deletions(-)
--- a/pppd/Makefile.linux
+++ b/pppd/Makefile.linux
@@ -36,10 +36,10 @@ endif
LIBS = -lrt
-# Uncomment the next line to include support for Microsoft's
+# Uncomment the next 2 lines to include support for Microsoft's
# MS-CHAP authentication protocol. Also, edit plugins/radius/Makefile.linux.
CHAPMS=y
-#USE_CRYPT=y
+USE_CRYPT=y
# Don't use MSLANMAN unless you really know what you're doing.
#MSLANMAN=y
# Uncomment the next line to include support for MPPE. CHAPMS (above) must
@@ -158,8 +158,7 @@ endif
ifdef NEEDDES
ifndef USE_CRYPT
-CFLAGS += -I$(shell $(CC) --print-sysroot)/usr/include/openssl
-NEEDCRYPTOLIB = y
+LIBS += -ldes $(LIBS)
else
CFLAGS += -DUSE_CRYPT=1
endif
--- a/pppd/pppcrypt.c
+++ b/pppd/pppcrypt.c
@@ -62,7 +62,7 @@ MakeKey(u_char *key, u_char *des_key)
des_key[7] = Get7Bits(key, 49);
#ifndef USE_CRYPT
- DES_set_odd_parity((DES_cblock *)des_key);
+ des_set_odd_parity((des_cblock *)des_key);
#endif
}
@@ -147,30 +147,30 @@ DesDecrypt(u_char *cipher, u_char *clear
}
#else /* USE_CRYPT */
-static DES_key_schedule key_schedule;
+static des_key_schedule key_schedule;
bool
DesSetkey(u_char *key)
{
- DES_cblock des_key;
+ des_cblock des_key;
MakeKey(key, des_key);
- DES_set_key(&des_key, &key_schedule);
+ des_set_key(&des_key, key_schedule);
return (1);
}
bool
DesEncrypt(u_char *clear, u_char *cipher)
{
- DES_ecb_encrypt((DES_cblock *)clear, (DES_cblock *)cipher,
- &key_schedule, 1);
+ des_ecb_encrypt((des_cblock *)clear, (des_cblock *)cipher,
+ key_schedule, 1);
return (1);
}
bool
DesDecrypt(u_char *cipher, u_char *clear)
{
- DES_ecb_encrypt((DES_cblock *)cipher, (DES_cblock *)clear,
- &key_schedule, 0);
+ des_ecb_encrypt((des_cblock *)cipher, (des_cblock *)clear,
+ key_schedule, 0);
return (1);
}

View File

@@ -0,0 +1,12 @@
--- a/pppd/Makefile.linux
+++ b/pppd/Makefile.linux
@@ -49,7 +49,8 @@ MPPE=y
# Uncomment the next line to include support for PPP packet filtering.
# This requires that the libpcap library and headers be installed
# and that the kernel driver support PPP packet filtering.
-#FILTER=y
+# libpcap statically linked in OpenWRT, hence disabled here.
+FILTER=
# Support for precompiled filters
PRECOMPILED_FILTER=y