948f57c7bf
Signed-off-by: Kevin Fenzi <kevin@scrye.com>
1497 lines
45 KiB
Diff
1497 lines
45 KiB
Diff
From 0324098afaee6e9e72050b2c8a6fb47803c36494 Mon Sep 17 00:00:00 2001
|
|
From: =?UTF-8?q?Eivind=20N=C3=A6ss?= <eivnaes@yahoo.com>
|
|
Date: Sat, 4 Mar 2023 23:26:00 +0100
|
|
Subject: [PATCH 1/3] build: detect pppd version via pkg-config for
|
|
PPPD_PLUGIN_DIR
|
|
|
|
Ppp 2.5 adds a pkg-config file, so we can detect the version.
|
|
Use it.
|
|
|
|
[thaller@redhat.com: split out patch]
|
|
---
|
|
configure.ac | 8 ++++++--
|
|
meson.build | 9 ++++++++-
|
|
2 files changed, 14 insertions(+), 3 deletions(-)
|
|
|
|
diff --git a/configure.ac b/configure.ac
|
|
index 4a550cb5ae..1057b4e933 100644
|
|
--- a/configure.ac
|
|
+++ b/configure.ac
|
|
@@ -767,13 +767,17 @@ else
|
|
fi
|
|
AM_CONDITIONAL(WITH_PPP, test "${enable_ppp}" = "yes")
|
|
|
|
+PPPD_VERSION=2.4.9
|
|
+PKG_CHECK_EXISTS([pppd], [
|
|
+ PPPD_VERSION=`$PKG_CONFIG --modversion pppd`
|
|
+])
|
|
+
|
|
AC_ARG_WITH([pppd-plugin-dir],
|
|
AS_HELP_STRING([--with-pppd-plugin-dir=DIR], [path to the pppd plugins directory]))
|
|
-
|
|
if test -n "$with_pppd_plugin_dir" ; then
|
|
PPPD_PLUGIN_DIR="$with_pppd_plugin_dir"
|
|
else
|
|
- PPPD_PLUGIN_DIR="${libdir}/pppd/2.4.5"
|
|
+ PPPD_PLUGIN_DIR="${libdir}/pppd/$PPPD_VERSION"
|
|
fi
|
|
AC_SUBST(PPPD_PLUGIN_DIR)
|
|
|
|
diff --git a/meson.build b/meson.build
|
|
index b41597cab9..bed0702a1c 100644
|
|
--- a/meson.build
|
|
+++ b/meson.build
|
|
@@ -563,6 +563,13 @@ enable_ppp = get_option('ppp')
|
|
if enable_ppp
|
|
assert(cc.has_header('pppd/pppd.h'), 'couldn\'t find pppd.h. pppd development headers are required')
|
|
|
|
+ pppd_dep = dependency('pppd', required: false)
|
|
+ if (pppd_dep.found())
|
|
+ pppd_version = pppd_dep.version()
|
|
+ else
|
|
+ pppd_version = '2.4.9'
|
|
+ endif
|
|
+
|
|
pppd_path = get_option('pppd')
|
|
if pppd_path == ''
|
|
pppd = find_program('pppd', '/sbin/pppd', '/usr/sbin/pppd', required: false)
|
|
@@ -574,7 +581,7 @@ if enable_ppp
|
|
|
|
pppd_plugin_dir = get_option('pppd_plugin_dir')
|
|
if pppd_plugin_dir == ''
|
|
- pppd_plugin_dir = join_paths(nm_libdir, 'pppd', '2.4.5')
|
|
+ pppd_plugin_dir = join_paths(nm_libdir, 'pppd', pppd_version)
|
|
endif
|
|
endif
|
|
config_h.set10('WITH_PPP', enable_ppp)
|
|
--
|
|
GitLab
|
|
|
|
|
|
From 8469c09a5006f9189c9b496ffa4c7e6755d56084 Mon Sep 17 00:00:00 2001
|
|
From: =?UTF-8?q?Eivind=20N=C3=A6ss?= <eivnaes@yahoo.com>
|
|
Date: Sat, 4 Mar 2023 22:26:00 +0000
|
|
Subject: [PATCH 2/3] ppp, adding support for compiling against pppd-2.5.0
|
|
|
|
This change does the following
|
|
* Adding in nm-pppd-compat.h to mask details regarding different
|
|
versions of pppd.
|
|
* Fix the nm-pppd-plugin.c regarding differences in API between
|
|
2.4.9 (current) and latet pppd 2.5.0 in master branch
|
|
* Additional fixes to the configure.ac to appropriately set defines used
|
|
for compilation
|
|
---
|
|
Makefile.am | 1 +
|
|
config.h.meson | 3 +
|
|
configure.ac | 5 ++
|
|
meson.build | 4 ++
|
|
src/core/ppp/nm-pppd-compat.h | 122 ++++++++++++++++++++++++++++++++++
|
|
src/core/ppp/nm-pppd-plugin.c | 45 ++++++-------
|
|
6 files changed, 157 insertions(+), 23 deletions(-)
|
|
create mode 100644 src/core/ppp/nm-pppd-compat.h
|
|
|
|
diff --git a/Makefile.am b/Makefile.am
|
|
index cd30c7201e..4ff3ce2b26 100644
|
|
--- a/Makefile.am
|
|
+++ b/Makefile.am
|
|
@@ -3302,6 +3302,7 @@ src_core_ppp_nm_pppd_plugin_la_CPPFLAGS = \
|
|
src_core_ppp_nm_pppd_plugin_la_SOURCES = \
|
|
src/core/ppp/nm-pppd-plugin.c \
|
|
src/core/ppp/nm-pppd-plugin.h \
|
|
+ src/core/ppp/nm-pppd-compat.h \
|
|
src/core/ppp/nm-ppp-status.h
|
|
|
|
src_core_ppp_nm_pppd_plugin_la_LDFLAGS = \
|
|
diff --git a/config.h.meson b/config.h.meson
|
|
index 7337165082..a9fd32475a 100644
|
|
--- a/config.h.meson
|
|
+++ b/config.h.meson
|
|
@@ -236,6 +236,9 @@
|
|
/* Define if you have PPP support */
|
|
#mesondefine WITH_PPP
|
|
|
|
+/* Define if you have a more recent version of pppd */
|
|
+#mesondefine WITH_PPP_VERSION_2_5_OR_NEWER
|
|
+
|
|
/* Define to path of pppd binary */
|
|
#mesondefine PPPD_PATH
|
|
|
|
diff --git a/configure.ac b/configure.ac
|
|
index 1057b4e933..aa68cdc609 100644
|
|
--- a/configure.ac
|
|
+++ b/configure.ac
|
|
@@ -790,6 +790,11 @@ fi
|
|
AC_DEFINE_UNQUOTED(PPPD_PATH, "$PPPD_PATH", [Define to path of pppd binary])
|
|
AC_SUBST(PPPD_PATH)
|
|
|
|
+AC_CHECK_HEADERS(pppd/chap.h)
|
|
+if test "x$ac_cv_header_pppd_chap_h" = xyes; then
|
|
+ AC_DEFINE(WITH_PPP_VERSION_2_5_OR_NEWER, 1, "Defined if one has a recent version of pppd headers installed")
|
|
+fi
|
|
+
|
|
# ModemManager1 with libmm-glib
|
|
AC_ARG_WITH(modem-manager-1,
|
|
AS_HELP_STRING([--with-modem-manager-1],
|
|
diff --git a/meson.build b/meson.build
|
|
index bed0702a1c..b967ccae5a 100644
|
|
--- a/meson.build
|
|
+++ b/meson.build
|
|
@@ -583,6 +583,10 @@ if enable_ppp
|
|
if pppd_plugin_dir == ''
|
|
pppd_plugin_dir = join_paths(nm_libdir, 'pppd', pppd_version)
|
|
endif
|
|
+
|
|
+ if (pppd_dep.found())
|
|
+ config_h.set10('WITH_PPP_VERSION_2_5_OR_NEWER', 1)
|
|
+ endif
|
|
endif
|
|
config_h.set10('WITH_PPP', enable_ppp)
|
|
|
|
diff --git a/src/core/ppp/nm-pppd-compat.h b/src/core/ppp/nm-pppd-compat.h
|
|
new file mode 100644
|
|
index 0000000000..08bdedfab9
|
|
--- /dev/null
|
|
+++ b/src/core/ppp/nm-pppd-compat.h
|
|
@@ -0,0 +1,122 @@
|
|
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
|
+/*
|
|
+ * Copyright (C) Eivind Næss, eivnaes@yahoo.com
|
|
+ */
|
|
+
|
|
+#ifndef __NM_PPPD_COMPAT_H__
|
|
+#define __NM_PPPD_COMPAT_H__
|
|
+
|
|
+/* Define INET6 to compile with IPv6 support against older pppd headers,
|
|
+ pppd >= 2.5.0 use PPP_WITH_IPV6CP and is defined in pppdconf.h */
|
|
+#define INET6 1
|
|
+
|
|
+/* PPP < 2.5.0 defines and exports VERSION which overlaps with current package VERSION define.
|
|
+ this silly macro magic is to work around that. */
|
|
+#undef VERSION
|
|
+#include <pppd/pppd.h>
|
|
+
|
|
+#ifndef PPPD_VERSION
|
|
+#define PPPD_VERSION VERSION
|
|
+#endif
|
|
+
|
|
+#include <pppd/fsm.h>
|
|
+#include <pppd/eui64.h>
|
|
+#include <pppd/ipcp.h>
|
|
+#include <pppd/ipv6cp.h>
|
|
+#include <pppd/upap.h>
|
|
+
|
|
+#ifdef WITH_PPP_VERSION_2_5_OR_NEWER
|
|
+#include <pppd/chap.h>
|
|
+#else
|
|
+#include <pppd/chap-new.h>
|
|
+#include <pppd/chap_ms.h>
|
|
+#endif
|
|
+
|
|
+#ifndef PPP_PROTO_CHAP
|
|
+#define PPP_PROTO_CHAP 0xc223
|
|
+#endif
|
|
+
|
|
+#ifndef PPP_PROTO_EAP
|
|
+#define PPP_PROTO_EAP 0xc227
|
|
+#endif
|
|
+
|
|
+#ifndef WITH_PPP_VERSION_2_5_OR_NEWER
|
|
+
|
|
+static inline bool
|
|
+debug_on(void)
|
|
+{
|
|
+ return debug;
|
|
+}
|
|
+
|
|
+static inline const char *
|
|
+ppp_ipparam(void)
|
|
+{
|
|
+ return ipparam;
|
|
+}
|
|
+
|
|
+static inline int
|
|
+ppp_ifunit(void)
|
|
+{
|
|
+ return ifunit;
|
|
+}
|
|
+
|
|
+static inline const char *
|
|
+ppp_ifname(void)
|
|
+{
|
|
+ return ifname;
|
|
+}
|
|
+
|
|
+static inline int
|
|
+ppp_get_mtu(int idx)
|
|
+{
|
|
+ return netif_get_mtu(idx);
|
|
+}
|
|
+
|
|
+static inline void
|
|
+ppp_set_ifname(const char *new_name)
|
|
+{
|
|
+ g_strlcpy(ifname, new_name, IF_NAMESIZE);
|
|
+}
|
|
+
|
|
+typedef enum ppp_notify {
|
|
+ NF_PID_CHANGE,
|
|
+ NF_PHASE_CHANGE,
|
|
+ NF_EXIT,
|
|
+ NF_SIGNALED,
|
|
+ NF_IP_UP,
|
|
+ NF_IP_DOWN,
|
|
+ NF_IPV6_UP,
|
|
+ NF_IPV6_DOWN,
|
|
+ NF_AUTH_UP,
|
|
+ NF_LINK_DOWN,
|
|
+ NF_FORK,
|
|
+ NF_MAX_NOTIFY
|
|
+} ppp_notify_t;
|
|
+
|
|
+typedef void(ppp_notify_fn)(void *ctx, int arg);
|
|
+
|
|
+static inline void
|
|
+ppp_add_notify(ppp_notify_t type, ppp_notify_fn *func, void *ctx)
|
|
+{
|
|
+ static struct notifier **list[NF_MAX_NOTIFY] = {
|
|
+ [NF_PID_CHANGE] = &pidchange,
|
|
+ [NF_PHASE_CHANGE] = &phasechange,
|
|
+ [NF_EXIT] = &exitnotify,
|
|
+ [NF_SIGNALED] = &sigreceived,
|
|
+ [NF_IP_UP] = &ip_up_notifier,
|
|
+ [NF_IP_DOWN] = &ip_down_notifier,
|
|
+ [NF_IPV6_UP] = &ipv6_up_notifier,
|
|
+ [NF_IPV6_DOWN] = &ipv6_down_notifier,
|
|
+ [NF_AUTH_UP] = &auth_up_notifier,
|
|
+ [NF_LINK_DOWN] = &link_down_notifier,
|
|
+ [NF_FORK] = &fork_notifier,
|
|
+ };
|
|
+
|
|
+ struct notifier **notify = list[type];
|
|
+ if (notify) {
|
|
+ add_notifier(notify, func, ctx);
|
|
+ }
|
|
+}
|
|
+
|
|
+#endif /* #ifndef WITH_PPP_VERSION_2_5_OR_NEWER */
|
|
+#endif /* #ifdef __NM_PPPD_COMPAT_H__ */
|
|
diff --git a/src/core/ppp/nm-pppd-plugin.c b/src/core/ppp/nm-pppd-plugin.c
|
|
index e2e34d2aaf..59a2dcc94b 100644
|
|
--- a/src/core/ppp/nm-pppd-plugin.c
|
|
+++ b/src/core/ppp/nm-pppd-plugin.c
|
|
@@ -7,29 +7,23 @@
|
|
#include <config.h>
|
|
#define ___CONFIG_H__
|
|
|
|
-#include <pppd/pppd.h>
|
|
-#include <pppd/fsm.h>
|
|
-#include <pppd/ipcp.h>
|
|
#include <sys/socket.h>
|
|
#include <netinet/in.h>
|
|
#include <net/if.h>
|
|
#include <arpa/inet.h>
|
|
#include <dlfcn.h>
|
|
+#include <glib.h>
|
|
|
|
-#define INET6
|
|
-#include <pppd/eui64.h>
|
|
-#include <pppd/ipv6cp.h>
|
|
+#include "nm-pppd-plugin.h"
|
|
+#include "nm-pppd-compat.h"
|
|
+#include "nm-ppp-status.h"
|
|
|
|
#include "libnm-glib-aux/nm-default-glib.h"
|
|
-
|
|
#include "nm-dbus-interface.h"
|
|
|
|
-#include "nm-pppd-plugin.h"
|
|
-#include "nm-ppp-status.h"
|
|
-
|
|
int plugin_init(void);
|
|
|
|
-char pppd_version[] = VERSION;
|
|
+char pppd_version[] = PPPD_VERSION;
|
|
|
|
static struct {
|
|
GDBusConnection *dbus_connection;
|
|
@@ -125,7 +119,7 @@ nm_phasechange(int arg)
|
|
char new_name[IF_NAMESIZE];
|
|
int ifindex;
|
|
|
|
- ifindex = if_nametoindex(ifname);
|
|
+ ifindex = if_nametoindex(ppp_ifname());
|
|
|
|
/* Make a sync call to ensure that when the call
|
|
* terminates the interface already has its final
|
|
@@ -143,9 +137,11 @@ nm_phasechange(int arg)
|
|
NULL);
|
|
|
|
/* Update the name in pppd if NM changed it */
|
|
- if (if_indextoname(ifindex, new_name) && !nm_streq0(ifname, new_name)) {
|
|
- g_message("nm-ppp-plugin: interface name changed from '%s' to '%s'", ifname, new_name);
|
|
- g_strlcpy(ifname, new_name, IF_NAMESIZE);
|
|
+ if (if_indextoname(ifindex, new_name) && !nm_streq0(ppp_ifname(), new_name)) {
|
|
+ g_message("nm-ppp-plugin: interface name changed from '%s' to '%s'",
|
|
+ ppp_ifname(),
|
|
+ new_name);
|
|
+ ppp_set_ifname(new_name);
|
|
}
|
|
}
|
|
}
|
|
@@ -166,7 +162,7 @@ nm_ip_up(void *data, int arg)
|
|
ipcp_options opts = ipcp_gotoptions[0];
|
|
ipcp_options peer_opts = ipcp_hisoptions[0];
|
|
GVariantBuilder builder;
|
|
- guint32 pppd_made_up_address = htonl(0x0a404040 + ifunit);
|
|
+ guint32 pppd_made_up_address = htonl(0x0a404040 + ppp_ifunit());
|
|
|
|
g_return_if_fail(G_IS_DBUS_CONNECTION(gl.dbus_connection));
|
|
|
|
@@ -186,7 +182,7 @@ nm_ip_up(void *data, int arg)
|
|
g_variant_builder_add(&builder,
|
|
"{sv}",
|
|
NM_PPP_IP4_CONFIG_INTERFACE,
|
|
- g_variant_new_string(ifname));
|
|
+ g_variant_new_string(ppp_ifname()));
|
|
|
|
g_variant_builder_add(&builder,
|
|
"{sv}",
|
|
@@ -292,7 +288,7 @@ nm_ip6_up(void *data, int arg)
|
|
g_variant_builder_add(&builder,
|
|
"{sv}",
|
|
NM_PPP_IP6_CONFIG_INTERFACE,
|
|
- g_variant_new_string(ifname));
|
|
+ g_variant_new_string(ppp_ifname()));
|
|
g_variant_builder_add(&builder, "{sv}", NM_PPP_IP6_CONFIG_OUR_IID, eui64_to_variant(go->ourid));
|
|
g_variant_builder_add(&builder,
|
|
"{sv}",
|
|
@@ -393,6 +389,7 @@ nm_exit_notify(void *data, int arg)
|
|
static void
|
|
add_ip6_notifier(void)
|
|
{
|
|
+#if WITH_PPP_VERSION < PPP_VERSION(2, 5, 0)
|
|
static struct notifier **notifier = NULL;
|
|
static gsize load_once = 0;
|
|
|
|
@@ -409,6 +406,9 @@ add_ip6_notifier(void)
|
|
add_notifier(notifier, nm_ip6_up, NULL);
|
|
else
|
|
g_message("nm-ppp-plugin: no IPV6CP notifier support; IPv6 not available");
|
|
+#else
|
|
+ ppp_add_notify(NF_IPV6_UP, nm_ip6_up, NULL);
|
|
+#endif
|
|
}
|
|
|
|
int
|
|
@@ -427,17 +427,16 @@ plugin_init(void)
|
|
return -1;
|
|
}
|
|
|
|
- gl.ipparam = g_strdup(ipparam);
|
|
+ gl.ipparam = g_strdup(ppp_ipparam());
|
|
|
|
chap_passwd_hook = get_credentials;
|
|
chap_check_hook = get_chap_check;
|
|
pap_passwd_hook = get_credentials;
|
|
pap_check_hook = get_pap_check;
|
|
|
|
- add_notifier(&phasechange, nm_phasechange_hook, NULL);
|
|
- add_notifier(&ip_up_notifier, nm_ip_up, NULL);
|
|
- add_notifier(&exitnotify, nm_exit_notify, NULL);
|
|
+ ppp_add_notify(NF_PHASE_CHANGE, nm_phasechange_hook, NULL);
|
|
+ ppp_add_notify(NF_IP_UP, nm_ip_up, NULL);
|
|
+ ppp_add_notify(NF_EXIT, nm_exit_notify, NULL);
|
|
add_ip6_notifier();
|
|
-
|
|
return 0;
|
|
}
|
|
--
|
|
GitLab
|
|
|
|
|
|
From afe80171b24d20151ecde0ff952a9800c15908d8 Mon Sep 17 00:00:00 2001
|
|
From: Thomas Haller <thaller@redhat.com>
|
|
Date: Sun, 16 Apr 2023 15:31:54 +0200
|
|
Subject: [PATCH 3/3] ppp: move ppp code to "nm-pppd-compat.c"
|
|
|
|
Using the ppp code is rather ugly.
|
|
|
|
Historically, the pppd headers don't follow a good naming convention,
|
|
and define things that cause conflicts with our headers:
|
|
|
|
/usr/include/pppd/patchlevel.h:#define VERSION "2.4.9"
|
|
/usr/include/pppd/pppd.h:typedef unsigned char bool;
|
|
|
|
Hence we had to include the pppd headers in certain order, and be
|
|
careful.
|
|
|
|
ppp 2.5 changes API and cleans that up. But since we need to support
|
|
also old versions, it does not immediately simplify anything.
|
|
|
|
Only include "pppd" headers in "nm-pppd-compat.c" and expose a wrapper
|
|
API from "nm-pppd-compat.h". The purpose is that "nm-pppd-compat.h"
|
|
exposes clean names, while all the handling of ppp is in the source
|
|
file.
|
|
---
|
|
Makefile.am | 7 +-
|
|
config.h.meson | 3 -
|
|
configure.ac | 24 ++-
|
|
meson.build | 7 +-
|
|
src/core/ppp/meson.build | 6 +-
|
|
src/core/ppp/nm-ppp-manager.c | 2 +-
|
|
src/core/ppp/nm-ppp-mgr.c | 2 +-
|
|
src/core/ppp/nm-ppp-status.h | 29 ++--
|
|
src/core/ppp/nm-pppd-compat.c | 304 ++++++++++++++++++++++++++++++++++
|
|
src/core/ppp/nm-pppd-compat.h | 170 +++++++------------
|
|
src/core/ppp/nm-pppd-plugin.c | 187 ++++++++-------------
|
|
11 files changed, 472 insertions(+), 269 deletions(-)
|
|
create mode 100644 src/core/ppp/nm-pppd-compat.c
|
|
|
|
diff --git a/Makefile.am b/Makefile.am
|
|
index 4ff3ce2b26..72918243da 100644
|
|
--- a/Makefile.am
|
|
+++ b/Makefile.am
|
|
@@ -3297,12 +3297,15 @@ src_core_ppp_nm_pppd_plugin_la_CPPFLAGS = \
|
|
-I$(builddir)/src \
|
|
-I$(builddir)/src/libnm-core-public \
|
|
-I$(srcdir)/src/libnm-core-public \
|
|
- $(GLIB_CFLAGS)
|
|
+ $(GLIB_CFLAGS) \
|
|
+ $(PPPD_CFLAGS) \
|
|
+ $(NULL)
|
|
|
|
src_core_ppp_nm_pppd_plugin_la_SOURCES = \
|
|
+ src/core/ppp/nm-pppd-compat.c \
|
|
+ src/core/ppp/nm-pppd-compat.h \
|
|
src/core/ppp/nm-pppd-plugin.c \
|
|
src/core/ppp/nm-pppd-plugin.h \
|
|
- src/core/ppp/nm-pppd-compat.h \
|
|
src/core/ppp/nm-ppp-status.h
|
|
|
|
src_core_ppp_nm_pppd_plugin_la_LDFLAGS = \
|
|
diff --git a/config.h.meson b/config.h.meson
|
|
index a9fd32475a..7337165082 100644
|
|
--- a/config.h.meson
|
|
+++ b/config.h.meson
|
|
@@ -236,9 +236,6 @@
|
|
/* Define if you have PPP support */
|
|
#mesondefine WITH_PPP
|
|
|
|
-/* Define if you have a more recent version of pppd */
|
|
-#mesondefine WITH_PPP_VERSION_2_5_OR_NEWER
|
|
-
|
|
/* Define to path of pppd binary */
|
|
#mesondefine PPPD_PATH
|
|
|
|
diff --git a/configure.ac b/configure.ac
|
|
index aa68cdc609..3809cda9df 100644
|
|
--- a/configure.ac
|
|
+++ b/configure.ac
|
|
@@ -754,24 +754,27 @@ fi
|
|
AC_SUBST(DBUS_SYS_DIR)
|
|
|
|
# pppd
|
|
+PPPD_VERSION=2.4.9
|
|
+PKG_CHECK_EXISTS([pppd], [
|
|
+ PPPD_VERSION=`$PKG_CONFIG --modversion pppd`
|
|
+ PPPD_CFLAGS=`$PKG_CONFIG --cflags pppd`
|
|
+])
|
|
+
|
|
AC_ARG_ENABLE(ppp,
|
|
AS_HELP_STRING([--enable-ppp], [enable PPP/PPPoE support]),
|
|
[enable_ppp=${enableval}], [enable_ppp=yes])
|
|
if test "${enable_ppp}" = "yes"; then
|
|
- AC_CHECK_HEADERS(pppd/pppd.h,,
|
|
- AC_MSG_ERROR("couldn't find pppd.h. pppd development headers are required."))
|
|
-
|
|
+ if test -z "$PPPD_CFLAGS" ; then
|
|
+ AC_CHECK_HEADERS(pppd/pppd.h,,
|
|
+ AC_MSG_ERROR("couldn't find pppd.h. pppd development headers are required."),)
|
|
+ fi
|
|
+ AC_SUBST(PPPD_CFLAGS, ["$PPPD_CFLAGS"])
|
|
AC_DEFINE(WITH_PPP, 1, [Define if you have PPP support])
|
|
else
|
|
AC_DEFINE(WITH_PPP, 0, [Define if you have PPP support])
|
|
fi
|
|
AM_CONDITIONAL(WITH_PPP, test "${enable_ppp}" = "yes")
|
|
|
|
-PPPD_VERSION=2.4.9
|
|
-PKG_CHECK_EXISTS([pppd], [
|
|
- PPPD_VERSION=`$PKG_CONFIG --modversion pppd`
|
|
-])
|
|
-
|
|
AC_ARG_WITH([pppd-plugin-dir],
|
|
AS_HELP_STRING([--with-pppd-plugin-dir=DIR], [path to the pppd plugins directory]))
|
|
if test -n "$with_pppd_plugin_dir" ; then
|
|
@@ -790,11 +793,6 @@ fi
|
|
AC_DEFINE_UNQUOTED(PPPD_PATH, "$PPPD_PATH", [Define to path of pppd binary])
|
|
AC_SUBST(PPPD_PATH)
|
|
|
|
-AC_CHECK_HEADERS(pppd/chap.h)
|
|
-if test "x$ac_cv_header_pppd_chap_h" = xyes; then
|
|
- AC_DEFINE(WITH_PPP_VERSION_2_5_OR_NEWER, 1, "Defined if one has a recent version of pppd headers installed")
|
|
-fi
|
|
-
|
|
# ModemManager1 with libmm-glib
|
|
AC_ARG_WITH(modem-manager-1,
|
|
AS_HELP_STRING([--with-modem-manager-1],
|
|
diff --git a/meson.build b/meson.build
|
|
index b967ccae5a..9747065e7a 100644
|
|
--- a/meson.build
|
|
+++ b/meson.build
|
|
@@ -561,12 +561,11 @@ config_h.set10('WITH_FIREWALLD_ZONE', enable_firewalld_zone)
|
|
# pppd
|
|
enable_ppp = get_option('ppp')
|
|
if enable_ppp
|
|
- assert(cc.has_header('pppd/pppd.h'), 'couldn\'t find pppd.h. pppd development headers are required')
|
|
-
|
|
pppd_dep = dependency('pppd', required: false)
|
|
if (pppd_dep.found())
|
|
pppd_version = pppd_dep.version()
|
|
else
|
|
+ assert(cc.has_header('pppd/pppd.h'), 'couldn\'t find pppd.h. pppd development headers are required')
|
|
pppd_version = '2.4.9'
|
|
endif
|
|
|
|
@@ -583,10 +582,6 @@ if enable_ppp
|
|
if pppd_plugin_dir == ''
|
|
pppd_plugin_dir = join_paths(nm_libdir, 'pppd', pppd_version)
|
|
endif
|
|
-
|
|
- if (pppd_dep.found())
|
|
- config_h.set10('WITH_PPP_VERSION_2_5_OR_NEWER', 1)
|
|
- endif
|
|
endif
|
|
config_h.set10('WITH_PPP', enable_ppp)
|
|
|
|
diff --git a/src/core/ppp/meson.build b/src/core/ppp/meson.build
|
|
index 9ee46113f5..2365ffa8fb 100644
|
|
--- a/src/core/ppp/meson.build
|
|
+++ b/src/core/ppp/meson.build
|
|
@@ -3,7 +3,10 @@
|
|
nm_pppd_plugin = shared_module(
|
|
'nm-pppd-plugin',
|
|
name_prefix: '',
|
|
- sources: 'nm-pppd-plugin.c',
|
|
+ sources: [
|
|
+ 'nm-pppd-compat.c',
|
|
+ 'nm-pppd-plugin.c',
|
|
+ ],
|
|
include_directories: [
|
|
src_inc,
|
|
top_inc,
|
|
@@ -11,6 +14,7 @@ nm_pppd_plugin = shared_module(
|
|
dependencies: [
|
|
libnm_core_public_dep,
|
|
glib_dep,
|
|
+ pppd_dep,
|
|
],
|
|
link_with: [
|
|
libnm_core_impl,
|
|
diff --git a/src/core/ppp/nm-ppp-manager.c b/src/core/ppp/nm-ppp-manager.c
|
|
index 14cd57317e..bb043a7e41 100644
|
|
--- a/src/core/ppp/nm-ppp-manager.c
|
|
+++ b/src/core/ppp/nm-ppp-manager.c
|
|
@@ -428,7 +428,7 @@ impl_ppp_manager_set_state(NMDBusObject *obj,
|
|
|
|
if (ppp_state >= NM_PPP_STATUS_INTERN_DEAD) {
|
|
/* we don't expect an intern state to be reported by the plugin. */
|
|
- ppp_state = NM_PPP_STATUS_UNKNOWN;
|
|
+ ppp_state = NM_PPP_STATUS_INTERN_UNKNOWN;
|
|
}
|
|
|
|
g_signal_emit(self, signals[STATE_CHANGED], 0, (guint) ppp_state);
|
|
diff --git a/src/core/ppp/nm-ppp-mgr.c b/src/core/ppp/nm-ppp-mgr.c
|
|
index bebffaf37c..91d9a021b2 100644
|
|
--- a/src/core/ppp/nm-ppp-mgr.c
|
|
+++ b/src/core/ppp/nm-ppp-mgr.c
|
|
@@ -257,7 +257,7 @@ _ppp_signal_state_changed(NMPPPManager *ppp_manager, guint ppp_state_u, gpointer
|
|
const char *reason_msg;
|
|
|
|
if ((guint) ppp_state != ppp_state_u)
|
|
- ppp_state = NM_PPP_STATUS_UNKNOWN;
|
|
+ ppp_state = NM_PPP_STATUS_INTERN_UNKNOWN;
|
|
|
|
switch (ppp_state) {
|
|
case NM_PPP_STATUS_DISCONNECT:
|
|
diff --git a/src/core/ppp/nm-ppp-status.h b/src/core/ppp/nm-ppp-status.h
|
|
index df0ac10ba2..57b48fe922 100644
|
|
--- a/src/core/ppp/nm-ppp-status.h
|
|
+++ b/src/core/ppp/nm-ppp-status.h
|
|
@@ -8,23 +8,24 @@
|
|
#define __NM_PPP_STATUS_H__
|
|
|
|
typedef enum {
|
|
- NM_PPP_STATUS_UNKNOWN,
|
|
|
|
- NM_PPP_STATUS_DEAD,
|
|
- NM_PPP_STATUS_INITIALIZE,
|
|
- NM_PPP_STATUS_SERIALCONN,
|
|
- NM_PPP_STATUS_DORMANT,
|
|
- NM_PPP_STATUS_ESTABLISH,
|
|
- NM_PPP_STATUS_AUTHENTICATE,
|
|
- NM_PPP_STATUS_CALLBACK,
|
|
- NM_PPP_STATUS_NETWORK,
|
|
- NM_PPP_STATUS_RUNNING,
|
|
- NM_PPP_STATUS_TERMINATE,
|
|
- NM_PPP_STATUS_DISCONNECT,
|
|
- NM_PPP_STATUS_HOLDOFF,
|
|
- NM_PPP_STATUS_MASTER,
|
|
+ /* The numeric values correspond to the PHASE_{DEAD,} defines from <pppd/pppd.h>. */
|
|
+ NM_PPP_STATUS_DEAD = 0,
|
|
+ NM_PPP_STATUS_INITIALIZE = 1,
|
|
+ NM_PPP_STATUS_SERIALCONN = 2,
|
|
+ NM_PPP_STATUS_DORMANT = 3,
|
|
+ NM_PPP_STATUS_ESTABLISH = 4,
|
|
+ NM_PPP_STATUS_AUTHENTICATE = 5,
|
|
+ NM_PPP_STATUS_CALLBACK = 6,
|
|
+ NM_PPP_STATUS_NETWORK = 7,
|
|
+ NM_PPP_STATUS_RUNNING = 8,
|
|
+ NM_PPP_STATUS_TERMINATE = 9,
|
|
+ NM_PPP_STATUS_DISCONNECT = 10,
|
|
+ NM_PPP_STATUS_HOLDOFF = 11,
|
|
+ NM_PPP_STATUS_MASTER = 12,
|
|
|
|
/* these states are internal and not announced by the pppd plugin. */
|
|
+ NM_PPP_STATUS_INTERN_UNKNOWN = 20,
|
|
NM_PPP_STATUS_INTERN_DEAD,
|
|
} NMPPPStatus;
|
|
|
|
diff --git a/src/core/ppp/nm-pppd-compat.c b/src/core/ppp/nm-pppd-compat.c
|
|
new file mode 100644
|
|
index 0000000000..fd67eb3493
|
|
--- /dev/null
|
|
+++ b/src/core/ppp/nm-pppd-compat.c
|
|
@@ -0,0 +1,304 @@
|
|
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
|
+/*
|
|
+ * Copyright (C) 2023 Eivind Næss, eivnaes@yahoo.com
|
|
+ */
|
|
+
|
|
+/*****************************************************************************/
|
|
+
|
|
+/* PPP headers define some symbols as we do. We need to be careful to handle
|
|
+ * the conflict, and include stuff in a certain order. */
|
|
+
|
|
+#include <config.h>
|
|
+#define ___CONFIG_H__
|
|
+
|
|
+/*****************************************************************************/
|
|
+
|
|
+#if defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6))
|
|
+_Pragma("GCC diagnostic push") _Pragma("GCC diagnostic ignored \"-Wstrict-prototypes\"")
|
|
+#define _NM_PRAGMA_WARNING_REENABLE _Pragma("GCC diagnostic pop")
|
|
+#elif defined(__clang__)
|
|
+_Pragma("clang diagnostic push") _Pragma("clang diagnostic ignored \"-Wunknown-warning-option\"")
|
|
+ _Pragma("clang diagnostic ignored \"-Wstrict-prototypes\"")
|
|
+#define _NM_PRAGMA_WARNING_REENABLE _Pragma("clang diagnostic pop")
|
|
+#else
|
|
+#define _NM_PRAGMA_WARNING_REENABLE
|
|
+#endif
|
|
+
|
|
+/*****************************************************************************/
|
|
+
|
|
+#define INET6 1
|
|
+
|
|
+#include <pppd/pppd.h>
|
|
+
|
|
+#ifdef DATE
|
|
+/* Before ppp 2.5, pppd/patchlevel.h defined "DATE". Use that for detection. */
|
|
+#define PPP_VERSION_2_5_OR_NEWER 0
|
|
+#else
|
|
+#define PPP_VERSION_2_5_OR_NEWER 1
|
|
+#endif
|
|
+
|
|
+#include <pppd/eui64.h>
|
|
+#include <pppd/fsm.h>
|
|
+#include <pppd/ipcp.h>
|
|
+#include <pppd/ipv6cp.h>
|
|
+#include <pppd/upap.h>
|
|
+
|
|
+#if PPP_VERSION_2_5_OR_NEWER
|
|
+#include <pppd/chap.h>
|
|
+#else
|
|
+#include <pppd/chap-new.h>
|
|
+#include <pppd/chap_ms.h>
|
|
+#endif
|
|
+
|
|
+ char pppd_version[] = (
|
|
+#if PPP_VERSION_2_5_OR_NEWER
|
|
+ PPPD_VERSION
|
|
+#else
|
|
+ VERSION
|
|
+#endif
|
|
+ );
|
|
+
|
|
+#undef VERSION
|
|
+
|
|
+_NM_PRAGMA_WARNING_REENABLE;
|
|
+
|
|
+/*****************************************************************************/
|
|
+
|
|
+#include "libnm-glib-aux/nm-default-glib.h"
|
|
+
|
|
+#include "nm-pppd-compat.h"
|
|
+
|
|
+#include <net/if.h>
|
|
+#include <dlfcn.h>
|
|
+
|
|
+#include "nm-ppp-status.h"
|
|
+
|
|
+/*****************************************************************************/
|
|
+
|
|
+G_STATIC_ASSERT((gint64) NM_PPP_STATUS_DEAD == PHASE_DEAD);
|
|
+G_STATIC_ASSERT((gint64) NM_PPP_STATUS_INITIALIZE == PHASE_INITIALIZE);
|
|
+G_STATIC_ASSERT((gint64) NM_PPP_STATUS_SERIALCONN == PHASE_SERIALCONN);
|
|
+G_STATIC_ASSERT((gint64) NM_PPP_STATUS_DORMANT == PHASE_DORMANT);
|
|
+G_STATIC_ASSERT((gint64) NM_PPP_STATUS_ESTABLISH == PHASE_ESTABLISH);
|
|
+G_STATIC_ASSERT((gint64) NM_PPP_STATUS_AUTHENTICATE == PHASE_AUTHENTICATE);
|
|
+G_STATIC_ASSERT((gint64) NM_PPP_STATUS_CALLBACK == PHASE_CALLBACK);
|
|
+G_STATIC_ASSERT((gint64) NM_PPP_STATUS_NETWORK == PHASE_NETWORK);
|
|
+G_STATIC_ASSERT((gint64) NM_PPP_STATUS_RUNNING == PHASE_RUNNING);
|
|
+G_STATIC_ASSERT((gint64) NM_PPP_STATUS_TERMINATE == PHASE_TERMINATE);
|
|
+G_STATIC_ASSERT((gint64) NM_PPP_STATUS_DISCONNECT == PHASE_DISCONNECT);
|
|
+G_STATIC_ASSERT((gint64) NM_PPP_STATUS_HOLDOFF == PHASE_HOLDOFF);
|
|
+G_STATIC_ASSERT((gint64) NM_PPP_STATUS_MASTER == PHASE_MASTER);
|
|
+
|
|
+G_STATIC_ASSERT(NM_PPPD_COMPAT_MAXNAMELEN == MAXNAMELEN);
|
|
+G_STATIC_ASSERT(NM_PPPD_COMPAT_MAXSECRETLEN == MAXSECRETLEN);
|
|
+
|
|
+/*****************************************************************************/
|
|
+
|
|
+int
|
|
+nm_pppd_compat_get_ifunit(void)
|
|
+{
|
|
+ int i;
|
|
+
|
|
+#if PPP_VERSION_2_5_OR_NEWER
|
|
+ i = ppp_ifunit();
|
|
+#else
|
|
+ i = ifunit;
|
|
+#endif
|
|
+
|
|
+ return i;
|
|
+}
|
|
+
|
|
+const char *
|
|
+nm_pppd_compat_get_ifname(void)
|
|
+{
|
|
+ const char *s;
|
|
+
|
|
+#if PPP_VERSION_2_5_OR_NEWER
|
|
+ s = ppp_ifname();
|
|
+#else
|
|
+ s = ifname;
|
|
+#endif
|
|
+
|
|
+ nm_assert(s);
|
|
+ nm_assert(strlen(s) < IFNAMSIZ);
|
|
+ return s;
|
|
+}
|
|
+
|
|
+void
|
|
+nm_pppd_compat_set_ifname(const char *arg_ifname)
|
|
+{
|
|
+ nm_assert(arg_ifname);
|
|
+ nm_assert(strlen(arg_ifname) < IFNAMSIZ);
|
|
+
|
|
+#if PPP_VERSION_2_5_OR_NEWER
|
|
+ ppp_set_ifname(arg_ifname);
|
|
+#else
|
|
+ g_strlcpy(ifname, arg_ifname, IFNAMSIZ);
|
|
+#endif
|
|
+}
|
|
+
|
|
+const char *
|
|
+nm_pppd_compat_get_ipparam(void)
|
|
+{
|
|
+ const char *s;
|
|
+
|
|
+#if PPP_VERSION_2_5_OR_NEWER
|
|
+ s = ppp_ipparam();
|
|
+#else
|
|
+ s = ipparam;
|
|
+#endif
|
|
+
|
|
+ return s;
|
|
+}
|
|
+
|
|
+void
|
|
+nm_pppd_compat_get_ipcp_options(NMPppdCompatIPCPOptions *out_got, NMPppdCompatIPCPOptions *out_his)
|
|
+{
|
|
+ const ipcp_options *const got = &ipcp_gotoptions[0];
|
|
+ const ipcp_options *const his = &ipcp_hisoptions[0];
|
|
+
|
|
+ nm_assert(out_got);
|
|
+ nm_assert(out_his);
|
|
+
|
|
+ *out_got = (NMPppdCompatIPCPOptions){
|
|
+ .ouraddr = got->ouraddr,
|
|
+ .hisaddr = got->hisaddr,
|
|
+ .dnsaddr = {got->dnsaddr[0], got->dnsaddr[1]},
|
|
+ .winsaddr = {got->winsaddr[0], got->winsaddr[1]},
|
|
+ };
|
|
+
|
|
+ *out_his = (NMPppdCompatIPCPOptions){
|
|
+ .ouraddr = his->ouraddr,
|
|
+ .hisaddr = his->hisaddr,
|
|
+ .dnsaddr = {his->dnsaddr[0], his->dnsaddr[1]},
|
|
+ .winsaddr = {his->winsaddr[0], his->winsaddr[1]},
|
|
+ };
|
|
+}
|
|
+
|
|
+void
|
|
+nm_pppd_compat_get_ipv6cp_options(NMPppdCompatIPV6CPOptions *out_got,
|
|
+ NMPppdCompatIPV6CPOptions *out_his)
|
|
+{
|
|
+ const ipv6cp_options *const his = &ipv6cp_hisoptions[0];
|
|
+ const ipv6cp_options *const got = &ipv6cp_gotoptions[0];
|
|
+
|
|
+ G_STATIC_ASSERT(sizeof(guint64) == sizeof(eui64_t));
|
|
+
|
|
+ nm_assert(out_got);
|
|
+ nm_assert(out_his);
|
|
+
|
|
+ *out_got = (NMPppdCompatIPV6CPOptions){};
|
|
+ memcpy(&out_got->ourid, &got->ourid, sizeof(guint64));
|
|
+ memcpy(&out_got->hisid, &got->hisid, sizeof(guint64));
|
|
+
|
|
+ *out_his = (NMPppdCompatIPV6CPOptions){};
|
|
+ memcpy(&out_his->ourid, &his->ourid, sizeof(guint64));
|
|
+ memcpy(&out_his->hisid, &his->hisid, sizeof(guint64));
|
|
+}
|
|
+
|
|
+void
|
|
+nm_pppd_compat_set_chap_passwd_hook(int (*hook)(char *user, char *password))
|
|
+{
|
|
+ chap_passwd_hook = hook;
|
|
+}
|
|
+
|
|
+void
|
|
+nm_pppd_compat_set_chap_check_hook(int (*hook)(void))
|
|
+{
|
|
+ chap_check_hook = hook;
|
|
+}
|
|
+
|
|
+void
|
|
+nm_pppd_compat_set_pap_passwd_hook(int (*hook)(char *user, char *passwd))
|
|
+{
|
|
+ pap_passwd_hook = hook;
|
|
+}
|
|
+
|
|
+void
|
|
+nm_pppd_compat_set_pap_check_hook(int (*hook)(void))
|
|
+{
|
|
+ pap_check_hook = hook;
|
|
+}
|
|
+
|
|
+gboolean
|
|
+nm_pppd_compat_add_notify(NMPppdCompatNotifyT type, void (*func)(void *ctx, int arg), void *ctx)
|
|
+{
|
|
+ nm_assert(NM_IN_SET(type,
|
|
+ NM_PPPD_COMPAT_NF_PID_CHANGE,
|
|
+ NM_PPPD_COMPAT_NF_PHASE_CHANGE,
|
|
+ NM_PPPD_COMPAT_NF_EXIT,
|
|
+ NM_PPPD_COMPAT_NF_SIGNALED,
|
|
+ NM_PPPD_COMPAT_NF_IP_UP,
|
|
+ NM_PPPD_COMPAT_NF_IP_DOWN,
|
|
+ NM_PPPD_COMPAT_NF_IPV6_UP,
|
|
+ NM_PPPD_COMPAT_NF_IPV6_DOWN,
|
|
+ NM_PPPD_COMPAT_NF_AUTH_UP,
|
|
+ NM_PPPD_COMPAT_NF_LINK_DOWN,
|
|
+ NM_PPPD_COMPAT_NF_FORK));
|
|
+ nm_assert(func);
|
|
+
|
|
+#if PPP_VERSION_2_5_OR_NEWER
|
|
+ {
|
|
+ G_STATIC_ASSERT((gint64) NM_PPPD_COMPAT_NF_PID_CHANGE == NF_PID_CHANGE);
|
|
+ G_STATIC_ASSERT((gint64) NM_PPPD_COMPAT_NF_PHASE_CHANGE == NF_PHASE_CHANGE);
|
|
+ G_STATIC_ASSERT((gint64) NM_PPPD_COMPAT_NF_EXIT == NF_EXIT);
|
|
+ G_STATIC_ASSERT((gint64) NM_PPPD_COMPAT_NF_SIGNALED == NF_SIGNALED);
|
|
+ G_STATIC_ASSERT((gint64) NM_PPPD_COMPAT_NF_IP_UP == NF_IP_UP);
|
|
+ G_STATIC_ASSERT((gint64) NM_PPPD_COMPAT_NF_IP_DOWN == NF_IP_DOWN);
|
|
+ G_STATIC_ASSERT((gint64) NM_PPPD_COMPAT_NF_IPV6_UP == NF_IPV6_UP);
|
|
+ G_STATIC_ASSERT((gint64) NM_PPPD_COMPAT_NF_IPV6_DOWN == NF_IPV6_DOWN);
|
|
+ G_STATIC_ASSERT((gint64) NM_PPPD_COMPAT_NF_AUTH_UP == NF_AUTH_UP);
|
|
+ G_STATIC_ASSERT((gint64) NM_PPPD_COMPAT_NF_LINK_DOWN == NF_LINK_DOWN);
|
|
+ G_STATIC_ASSERT((gint64) NM_PPPD_COMPAT_NF_FORK == NF_FORK);
|
|
+
|
|
+ ppp_add_notify((gint64) type, func, ctx);
|
|
+ return TRUE;
|
|
+ }
|
|
+#else
|
|
+ {
|
|
+ static struct notifier **list[] = {
|
|
+ [NM_PPPD_COMPAT_NF_PID_CHANGE] = &pidchange,
|
|
+ [NM_PPPD_COMPAT_NF_PHASE_CHANGE] = &phasechange,
|
|
+ [NM_PPPD_COMPAT_NF_EXIT] = &exitnotify,
|
|
+ [NM_PPPD_COMPAT_NF_SIGNALED] = &sigreceived,
|
|
+ [NM_PPPD_COMPAT_NF_IP_UP] = &ip_up_notifier,
|
|
+ [NM_PPPD_COMPAT_NF_IP_DOWN] = &ip_down_notifier,
|
|
+ [NM_PPPD_COMPAT_NF_IPV6_UP] = NULL /* ipv6_up_notifier */,
|
|
+ [NM_PPPD_COMPAT_NF_IPV6_DOWN] = NULL /* ipv6_down_notifier */,
|
|
+ [NM_PPPD_COMPAT_NF_AUTH_UP] = &auth_up_notifier,
|
|
+ [NM_PPPD_COMPAT_NF_LINK_DOWN] = &link_down_notifier,
|
|
+ [NM_PPPD_COMPAT_NF_FORK] = &fork_notifier,
|
|
+ };
|
|
+ struct notifier **notifier;
|
|
+
|
|
+ nm_assert(_NM_INT_NOT_NEGATIVE(type) && type < G_N_ELEMENTS(list));
|
|
+
|
|
+ if (NM_IN_SET(type, NM_PPPD_COMPAT_NF_IPV6_UP, NM_PPPD_COMPAT_NF_IPV6_DOWN)) {
|
|
+ static gsize load_once = 0;
|
|
+
|
|
+ /* pppd might be build without IPv6 support. Load the symbols dynamically. */
|
|
+ if (g_once_init_enter(&load_once)) {
|
|
+ void *handle;
|
|
+
|
|
+ handle = dlopen(NULL, RTLD_NOW | RTLD_GLOBAL);
|
|
+ if (handle) {
|
|
+ list[NM_PPPD_COMPAT_NF_IPV6_UP] = dlsym(handle, "ipv6_up_notifier");
|
|
+ list[NM_PPPD_COMPAT_NF_IPV6_DOWN] = dlsym(handle, "ipv6_down_notifier");
|
|
+ dlclose(handle);
|
|
+ }
|
|
+ g_once_init_leave(&load_once, 1);
|
|
+ }
|
|
+
|
|
+ notifier = list[type];
|
|
+ } else {
|
|
+ notifier = list[type];
|
|
+ nm_assert(notifier);
|
|
+ }
|
|
+
|
|
+ if (notifier)
|
|
+ add_notifier(notifier, func, ctx);
|
|
+
|
|
+ return !!notifier;
|
|
+ }
|
|
+#endif
|
|
+}
|
|
diff --git a/src/core/ppp/nm-pppd-compat.h b/src/core/ppp/nm-pppd-compat.h
|
|
index 08bdedfab9..11376e360e 100644
|
|
--- a/src/core/ppp/nm-pppd-compat.h
|
|
+++ b/src/core/ppp/nm-pppd-compat.h
|
|
@@ -1,122 +1,64 @@
|
|
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
|
/*
|
|
- * Copyright (C) Eivind Næss, eivnaes@yahoo.com
|
|
+ * Copyright (C) 2023 Eivind Næss, eivnaes@yahoo.com
|
|
*/
|
|
|
|
#ifndef __NM_PPPD_COMPAT_H__
|
|
#define __NM_PPPD_COMPAT_H__
|
|
|
|
-/* Define INET6 to compile with IPv6 support against older pppd headers,
|
|
- pppd >= 2.5.0 use PPP_WITH_IPV6CP and is defined in pppdconf.h */
|
|
-#define INET6 1
|
|
-
|
|
-/* PPP < 2.5.0 defines and exports VERSION which overlaps with current package VERSION define.
|
|
- this silly macro magic is to work around that. */
|
|
-#undef VERSION
|
|
-#include <pppd/pppd.h>
|
|
-
|
|
-#ifndef PPPD_VERSION
|
|
-#define PPPD_VERSION VERSION
|
|
-#endif
|
|
-
|
|
-#include <pppd/fsm.h>
|
|
-#include <pppd/eui64.h>
|
|
-#include <pppd/ipcp.h>
|
|
-#include <pppd/ipv6cp.h>
|
|
-#include <pppd/upap.h>
|
|
-
|
|
-#ifdef WITH_PPP_VERSION_2_5_OR_NEWER
|
|
-#include <pppd/chap.h>
|
|
-#else
|
|
-#include <pppd/chap-new.h>
|
|
-#include <pppd/chap_ms.h>
|
|
-#endif
|
|
-
|
|
-#ifndef PPP_PROTO_CHAP
|
|
-#define PPP_PROTO_CHAP 0xc223
|
|
-#endif
|
|
-
|
|
-#ifndef PPP_PROTO_EAP
|
|
-#define PPP_PROTO_EAP 0xc227
|
|
-#endif
|
|
-
|
|
-#ifndef WITH_PPP_VERSION_2_5_OR_NEWER
|
|
-
|
|
-static inline bool
|
|
-debug_on(void)
|
|
-{
|
|
- return debug;
|
|
-}
|
|
-
|
|
-static inline const char *
|
|
-ppp_ipparam(void)
|
|
-{
|
|
- return ipparam;
|
|
-}
|
|
-
|
|
-static inline int
|
|
-ppp_ifunit(void)
|
|
-{
|
|
- return ifunit;
|
|
-}
|
|
-
|
|
-static inline const char *
|
|
-ppp_ifname(void)
|
|
-{
|
|
- return ifname;
|
|
-}
|
|
-
|
|
-static inline int
|
|
-ppp_get_mtu(int idx)
|
|
-{
|
|
- return netif_get_mtu(idx);
|
|
-}
|
|
-
|
|
-static inline void
|
|
-ppp_set_ifname(const char *new_name)
|
|
-{
|
|
- g_strlcpy(ifname, new_name, IF_NAMESIZE);
|
|
-}
|
|
-
|
|
-typedef enum ppp_notify {
|
|
- NF_PID_CHANGE,
|
|
- NF_PHASE_CHANGE,
|
|
- NF_EXIT,
|
|
- NF_SIGNALED,
|
|
- NF_IP_UP,
|
|
- NF_IP_DOWN,
|
|
- NF_IPV6_UP,
|
|
- NF_IPV6_DOWN,
|
|
- NF_AUTH_UP,
|
|
- NF_LINK_DOWN,
|
|
- NF_FORK,
|
|
- NF_MAX_NOTIFY
|
|
-} ppp_notify_t;
|
|
-
|
|
-typedef void(ppp_notify_fn)(void *ctx, int arg);
|
|
-
|
|
-static inline void
|
|
-ppp_add_notify(ppp_notify_t type, ppp_notify_fn *func, void *ctx)
|
|
-{
|
|
- static struct notifier **list[NF_MAX_NOTIFY] = {
|
|
- [NF_PID_CHANGE] = &pidchange,
|
|
- [NF_PHASE_CHANGE] = &phasechange,
|
|
- [NF_EXIT] = &exitnotify,
|
|
- [NF_SIGNALED] = &sigreceived,
|
|
- [NF_IP_UP] = &ip_up_notifier,
|
|
- [NF_IP_DOWN] = &ip_down_notifier,
|
|
- [NF_IPV6_UP] = &ipv6_up_notifier,
|
|
- [NF_IPV6_DOWN] = &ipv6_down_notifier,
|
|
- [NF_AUTH_UP] = &auth_up_notifier,
|
|
- [NF_LINK_DOWN] = &link_down_notifier,
|
|
- [NF_FORK] = &fork_notifier,
|
|
- };
|
|
-
|
|
- struct notifier **notify = list[type];
|
|
- if (notify) {
|
|
- add_notifier(notify, func, ctx);
|
|
- }
|
|
-}
|
|
-
|
|
-#endif /* #ifndef WITH_PPP_VERSION_2_5_OR_NEWER */
|
|
+#define NM_PPPD_COMPAT_MAXNAMELEN 256
|
|
+#define NM_PPPD_COMPAT_MAXSECRETLEN 256
|
|
+
|
|
+int nm_pppd_compat_get_ifunit(void);
|
|
+
|
|
+const char *nm_pppd_compat_get_ifname(void);
|
|
+void nm_pppd_compat_set_ifname(const char *ifname);
|
|
+
|
|
+const char *nm_pppd_compat_get_ipparam(void);
|
|
+
|
|
+typedef struct {
|
|
+ /* has information from "ipcp_options" */
|
|
+ in_addr_t ouraddr;
|
|
+ in_addr_t hisaddr;
|
|
+ in_addr_t dnsaddr[2];
|
|
+ in_addr_t winsaddr[2];
|
|
+} NMPppdCompatIPCPOptions;
|
|
+
|
|
+void nm_pppd_compat_get_ipcp_options(NMPppdCompatIPCPOptions *out_got,
|
|
+ NMPppdCompatIPCPOptions *out_his);
|
|
+
|
|
+typedef struct {
|
|
+ /* has information from "ipv6cp_options" */
|
|
+ guint64 ourid;
|
|
+ guint64 hisid;
|
|
+} NMPppdCompatIPV6CPOptions;
|
|
+
|
|
+void nm_pppd_compat_get_ipv6cp_options(NMPppdCompatIPV6CPOptions *out_got,
|
|
+ NMPppdCompatIPV6CPOptions *out_his);
|
|
+
|
|
+void nm_pppd_compat_set_chap_passwd_hook(int (*hook)(char *user, char *password));
|
|
+
|
|
+void nm_pppd_compat_set_chap_check_hook(int (*hook)(void));
|
|
+
|
|
+void nm_pppd_compat_set_pap_passwd_hook(int (*hook)(char *user, char *passwd));
|
|
+
|
|
+void nm_pppd_compat_set_pap_check_hook(int (*hook)(void));
|
|
+
|
|
+typedef enum {
|
|
+ NM_PPPD_COMPAT_NF_PID_CHANGE,
|
|
+ NM_PPPD_COMPAT_NF_PHASE_CHANGE,
|
|
+ NM_PPPD_COMPAT_NF_EXIT,
|
|
+ NM_PPPD_COMPAT_NF_SIGNALED,
|
|
+ NM_PPPD_COMPAT_NF_IP_UP,
|
|
+ NM_PPPD_COMPAT_NF_IP_DOWN,
|
|
+ NM_PPPD_COMPAT_NF_IPV6_UP,
|
|
+ NM_PPPD_COMPAT_NF_IPV6_DOWN,
|
|
+ NM_PPPD_COMPAT_NF_AUTH_UP,
|
|
+ NM_PPPD_COMPAT_NF_LINK_DOWN,
|
|
+ NM_PPPD_COMPAT_NF_FORK,
|
|
+} NMPppdCompatNotifyT;
|
|
+
|
|
+gboolean
|
|
+nm_pppd_compat_add_notify(NMPppdCompatNotifyT type, void (*func)(void *ctx, int arg), void *ctx);
|
|
+
|
|
#endif /* #ifdef __NM_PPPD_COMPAT_H__ */
|
|
diff --git a/src/core/ppp/nm-pppd-plugin.c b/src/core/ppp/nm-pppd-plugin.c
|
|
index 59a2dcc94b..93425f382c 100644
|
|
--- a/src/core/ppp/nm-pppd-plugin.c
|
|
+++ b/src/core/ppp/nm-pppd-plugin.c
|
|
@@ -4,8 +4,9 @@
|
|
* Copyright (C) 2008 Red Hat, Inc.
|
|
*/
|
|
|
|
-#include <config.h>
|
|
-#define ___CONFIG_H__
|
|
+#include "libnm-glib-aux/nm-default-glib.h"
|
|
+
|
|
+#include "nm-pppd-plugin.h"
|
|
|
|
#include <sys/socket.h>
|
|
#include <netinet/in.h>
|
|
@@ -14,17 +15,12 @@
|
|
#include <dlfcn.h>
|
|
#include <glib.h>
|
|
|
|
-#include "nm-pppd-plugin.h"
|
|
#include "nm-pppd-compat.h"
|
|
#include "nm-ppp-status.h"
|
|
-
|
|
-#include "libnm-glib-aux/nm-default-glib.h"
|
|
#include "nm-dbus-interface.h"
|
|
|
|
int plugin_init(void);
|
|
|
|
-char pppd_version[] = PPPD_VERSION;
|
|
-
|
|
static struct {
|
|
GDBusConnection *dbus_connection;
|
|
char *ipparam;
|
|
@@ -33,73 +29,63 @@ static struct {
|
|
static void
|
|
nm_phasechange(int arg)
|
|
{
|
|
- NMPPPStatus ppp_status = NM_PPP_STATUS_UNKNOWN;
|
|
+ NMPPPStatus ppp_status;
|
|
char *ppp_phase;
|
|
|
|
g_return_if_fail(G_IS_DBUS_CONNECTION(gl.dbus_connection));
|
|
|
|
+ ppp_status = arg;
|
|
+
|
|
switch (arg) {
|
|
- case PHASE_DEAD:
|
|
- ppp_status = NM_PPP_STATUS_DEAD;
|
|
- ppp_phase = "dead";
|
|
+ case NM_PPP_STATUS_DEAD:
|
|
+ ppp_phase = "dead";
|
|
break;
|
|
- case PHASE_INITIALIZE:
|
|
- ppp_status = NM_PPP_STATUS_INITIALIZE;
|
|
- ppp_phase = "initialize";
|
|
+ case NM_PPP_STATUS_INITIALIZE:
|
|
+ ppp_phase = "initialize";
|
|
break;
|
|
- case PHASE_SERIALCONN:
|
|
- ppp_status = NM_PPP_STATUS_SERIALCONN;
|
|
- ppp_phase = "serial connection";
|
|
+ case NM_PPP_STATUS_SERIALCONN:
|
|
+ ppp_phase = "serial connection";
|
|
break;
|
|
- case PHASE_DORMANT:
|
|
- ppp_status = NM_PPP_STATUS_DORMANT;
|
|
- ppp_phase = "dormant";
|
|
+ case NM_PPP_STATUS_DORMANT:
|
|
+ ppp_phase = "dormant";
|
|
break;
|
|
- case PHASE_ESTABLISH:
|
|
- ppp_status = NM_PPP_STATUS_ESTABLISH;
|
|
- ppp_phase = "establish";
|
|
+ case NM_PPP_STATUS_ESTABLISH:
|
|
+ ppp_phase = "establish";
|
|
break;
|
|
- case PHASE_AUTHENTICATE:
|
|
- ppp_status = NM_PPP_STATUS_AUTHENTICATE;
|
|
- ppp_phase = "authenticate";
|
|
+ case NM_PPP_STATUS_AUTHENTICATE:
|
|
+ ppp_phase = "authenticate";
|
|
break;
|
|
- case PHASE_CALLBACK:
|
|
- ppp_status = NM_PPP_STATUS_CALLBACK;
|
|
- ppp_phase = "callback";
|
|
+ case NM_PPP_STATUS_CALLBACK:
|
|
+ ppp_phase = "callback";
|
|
break;
|
|
- case PHASE_NETWORK:
|
|
- ppp_status = NM_PPP_STATUS_NETWORK;
|
|
- ppp_phase = "network";
|
|
+ case NM_PPP_STATUS_NETWORK:
|
|
+ ppp_phase = "network";
|
|
break;
|
|
- case PHASE_RUNNING:
|
|
- ppp_status = NM_PPP_STATUS_RUNNING;
|
|
- ppp_phase = "running";
|
|
+ case NM_PPP_STATUS_RUNNING:
|
|
+ ppp_phase = "running";
|
|
break;
|
|
- case PHASE_TERMINATE:
|
|
- ppp_status = NM_PPP_STATUS_TERMINATE;
|
|
- ppp_phase = "terminate";
|
|
+ case NM_PPP_STATUS_TERMINATE:
|
|
+ ppp_phase = "terminate";
|
|
break;
|
|
- case PHASE_DISCONNECT:
|
|
- ppp_status = NM_PPP_STATUS_DISCONNECT;
|
|
- ppp_phase = "disconnect";
|
|
+ case NM_PPP_STATUS_DISCONNECT:
|
|
+ ppp_phase = "disconnect";
|
|
break;
|
|
- case PHASE_HOLDOFF:
|
|
- ppp_status = NM_PPP_STATUS_HOLDOFF;
|
|
- ppp_phase = "holdoff";
|
|
+ case NM_PPP_STATUS_HOLDOFF:
|
|
+ ppp_phase = "holdoff";
|
|
break;
|
|
- case PHASE_MASTER:
|
|
- ppp_status = NM_PPP_STATUS_MASTER;
|
|
- ppp_phase = "master";
|
|
+ case NM_PPP_STATUS_MASTER:
|
|
+ ppp_phase = "master";
|
|
break;
|
|
|
|
default:
|
|
- ppp_phase = "unknown";
|
|
+ ppp_status = NM_PPP_STATUS_INTERN_UNKNOWN;
|
|
+ ppp_phase = "unknown";
|
|
break;
|
|
}
|
|
|
|
g_message("nm-ppp-plugin: status %d / phase '%s'", ppp_status, ppp_phase);
|
|
|
|
- if (ppp_status != NM_PPP_STATUS_UNKNOWN) {
|
|
+ if (ppp_status != NM_PPP_STATUS_INTERN_UNKNOWN) {
|
|
g_dbus_connection_call(gl.dbus_connection,
|
|
NM_DBUS_SERVICE,
|
|
gl.ipparam,
|
|
@@ -119,7 +105,7 @@ nm_phasechange(int arg)
|
|
char new_name[IF_NAMESIZE];
|
|
int ifindex;
|
|
|
|
- ifindex = if_nametoindex(ppp_ifname());
|
|
+ ifindex = if_nametoindex(nm_pppd_compat_get_ifname());
|
|
|
|
/* Make a sync call to ensure that when the call
|
|
* terminates the interface already has its final
|
|
@@ -137,11 +123,12 @@ nm_phasechange(int arg)
|
|
NULL);
|
|
|
|
/* Update the name in pppd if NM changed it */
|
|
- if (if_indextoname(ifindex, new_name) && !nm_streq0(ppp_ifname(), new_name)) {
|
|
+ if (if_indextoname(ifindex, new_name)
|
|
+ && !nm_streq0(nm_pppd_compat_get_ifname(), new_name)) {
|
|
g_message("nm-ppp-plugin: interface name changed from '%s' to '%s'",
|
|
- ppp_ifname(),
|
|
+ nm_pppd_compat_get_ifname(),
|
|
new_name);
|
|
- ppp_set_ifname(new_name);
|
|
+ nm_pppd_compat_set_ifname(new_name);
|
|
}
|
|
}
|
|
}
|
|
@@ -150,7 +137,7 @@ static void
|
|
nm_phasechange_hook(void *data, int arg)
|
|
{
|
|
/* We send the nofication in exitnotify instead */
|
|
- if (arg == PHASE_DEAD)
|
|
+ if (arg == NM_PPP_STATUS_DEAD)
|
|
return;
|
|
|
|
nm_phasechange(arg);
|
|
@@ -159,18 +146,21 @@ nm_phasechange_hook(void *data, int arg)
|
|
static void
|
|
nm_ip_up(void *data, int arg)
|
|
{
|
|
- ipcp_options opts = ipcp_gotoptions[0];
|
|
- ipcp_options peer_opts = ipcp_hisoptions[0];
|
|
- GVariantBuilder builder;
|
|
- guint32 pppd_made_up_address = htonl(0x0a404040 + ppp_ifunit());
|
|
+ NMPppdCompatIPCPOptions opts;
|
|
+ NMPppdCompatIPCPOptions peer_opts;
|
|
+ GVariantBuilder builder;
|
|
+ const in_addr_t pppd_made_up_address =
|
|
+ htonl(0x0a404040u + ((guint) nm_pppd_compat_get_ifunit()));
|
|
|
|
g_return_if_fail(G_IS_DBUS_CONNECTION(gl.dbus_connection));
|
|
|
|
g_message("nm-ppp-plugin: ip-up event");
|
|
|
|
+ nm_pppd_compat_get_ipcp_options(&opts, &peer_opts);
|
|
+
|
|
if (!opts.ouraddr) {
|
|
g_warning("nm-ppp-plugin: didn't receive an internal IP from pppd!");
|
|
- nm_phasechange(PHASE_DEAD);
|
|
+ nm_phasechange(NM_PPP_STATUS_DEAD);
|
|
return;
|
|
}
|
|
|
|
@@ -182,7 +172,7 @@ nm_ip_up(void *data, int arg)
|
|
g_variant_builder_add(&builder,
|
|
"{sv}",
|
|
NM_PPP_IP4_CONFIG_INTERFACE,
|
|
- g_variant_new_string(ppp_ifname()));
|
|
+ g_variant_new_string(nm_pppd_compat_get_ifname()));
|
|
|
|
g_variant_builder_add(&builder,
|
|
"{sv}",
|
|
@@ -259,28 +249,19 @@ nm_ip_up(void *data, int arg)
|
|
NULL);
|
|
}
|
|
|
|
-static GVariant *
|
|
-eui64_to_variant(eui64_t eui)
|
|
-{
|
|
- guint64 iid;
|
|
-
|
|
- G_STATIC_ASSERT(sizeof(iid) == sizeof(eui));
|
|
-
|
|
- memcpy(&iid, &eui, sizeof(eui));
|
|
- return g_variant_new_uint64(iid);
|
|
-}
|
|
-
|
|
static void
|
|
nm_ip6_up(void *data, int arg)
|
|
{
|
|
- ipv6cp_options *ho = &ipv6cp_hisoptions[0];
|
|
- ipv6cp_options *go = &ipv6cp_gotoptions[0];
|
|
- GVariantBuilder builder;
|
|
+ NMPppdCompatIPV6CPOptions his;
|
|
+ NMPppdCompatIPV6CPOptions got;
|
|
+ GVariantBuilder builder;
|
|
|
|
g_return_if_fail(G_IS_DBUS_CONNECTION(gl.dbus_connection));
|
|
|
|
g_message("nm-ppp-plugin: ip6-up event");
|
|
|
|
+ nm_pppd_compat_get_ipv6cp_options(&got, &his);
|
|
+
|
|
g_variant_builder_init(&builder, G_VARIANT_TYPE_VARDICT);
|
|
/* Keep sending the interface name to be backwards compatible
|
|
* with older versions of NM during a package upgrade, where
|
|
@@ -288,12 +269,15 @@ nm_ip6_up(void *data, int arg)
|
|
g_variant_builder_add(&builder,
|
|
"{sv}",
|
|
NM_PPP_IP6_CONFIG_INTERFACE,
|
|
- g_variant_new_string(ppp_ifname()));
|
|
- g_variant_builder_add(&builder, "{sv}", NM_PPP_IP6_CONFIG_OUR_IID, eui64_to_variant(go->ourid));
|
|
+ g_variant_new_string(nm_pppd_compat_get_ifname()));
|
|
+ g_variant_builder_add(&builder,
|
|
+ "{sv}",
|
|
+ NM_PPP_IP6_CONFIG_OUR_IID,
|
|
+ g_variant_new_uint64(got.ourid));
|
|
g_variant_builder_add(&builder,
|
|
"{sv}",
|
|
NM_PPP_IP6_CONFIG_PEER_IID,
|
|
- eui64_to_variant(ho->hisid));
|
|
+ g_variant_new_uint64(his.hisid));
|
|
|
|
/* DNS is done via DHCPv6 or router advertisements */
|
|
|
|
@@ -364,8 +348,8 @@ get_credentials(char *username, char *password)
|
|
|
|
g_variant_get(ret, "(&s&s)", &my_username, &my_password);
|
|
|
|
- g_strlcpy(username, my_username, MAXNAMELEN);
|
|
- g_strlcpy(password, my_password, MAXSECRETLEN);
|
|
+ g_strlcpy(username, my_username, NM_PPPD_COMPAT_MAXNAMELEN);
|
|
+ g_strlcpy(password, my_password, NM_PPPD_COMPAT_MAXSECRETLEN);
|
|
|
|
return 1;
|
|
}
|
|
@@ -378,7 +362,7 @@ nm_exit_notify(void *data, int arg)
|
|
/* We wait until this point to notify dead phase to make sure that
|
|
* the serial port has recovered already its original settings.
|
|
*/
|
|
- nm_phasechange(PHASE_DEAD);
|
|
+ nm_phasechange(NM_PPP_STATUS_DEAD);
|
|
|
|
g_message("nm-ppp-plugin: cleaning up");
|
|
|
|
@@ -386,31 +370,6 @@ nm_exit_notify(void *data, int arg)
|
|
nm_clear_g_free(&gl.ipparam);
|
|
}
|
|
|
|
-static void
|
|
-add_ip6_notifier(void)
|
|
-{
|
|
-#if WITH_PPP_VERSION < PPP_VERSION(2, 5, 0)
|
|
- static struct notifier **notifier = NULL;
|
|
- static gsize load_once = 0;
|
|
-
|
|
- if (g_once_init_enter(&load_once)) {
|
|
- void *handle = dlopen(NULL, RTLD_NOW | RTLD_GLOBAL);
|
|
-
|
|
- if (handle) {
|
|
- notifier = dlsym(handle, "ipv6_up_notifier");
|
|
- dlclose(handle);
|
|
- }
|
|
- g_once_init_leave(&load_once, 1);
|
|
- }
|
|
- if (notifier)
|
|
- add_notifier(notifier, nm_ip6_up, NULL);
|
|
- else
|
|
- g_message("nm-ppp-plugin: no IPV6CP notifier support; IPv6 not available");
|
|
-#else
|
|
- ppp_add_notify(NF_IPV6_UP, nm_ip6_up, NULL);
|
|
-#endif
|
|
-}
|
|
-
|
|
int
|
|
plugin_init(void)
|
|
{
|
|
@@ -427,16 +386,16 @@ plugin_init(void)
|
|
return -1;
|
|
}
|
|
|
|
- gl.ipparam = g_strdup(ppp_ipparam());
|
|
+ gl.ipparam = g_strdup(nm_pppd_compat_get_ipparam());
|
|
|
|
- chap_passwd_hook = get_credentials;
|
|
- chap_check_hook = get_chap_check;
|
|
- pap_passwd_hook = get_credentials;
|
|
- pap_check_hook = get_pap_check;
|
|
+ nm_pppd_compat_set_chap_passwd_hook(get_credentials);
|
|
+ nm_pppd_compat_set_chap_check_hook(get_chap_check);
|
|
+ nm_pppd_compat_set_pap_passwd_hook(get_credentials);
|
|
+ nm_pppd_compat_set_pap_check_hook(get_pap_check);
|
|
|
|
- ppp_add_notify(NF_PHASE_CHANGE, nm_phasechange_hook, NULL);
|
|
- ppp_add_notify(NF_IP_UP, nm_ip_up, NULL);
|
|
- ppp_add_notify(NF_EXIT, nm_exit_notify, NULL);
|
|
- add_ip6_notifier();
|
|
+ nm_pppd_compat_add_notify(NM_PPPD_COMPAT_NF_PHASE_CHANGE, nm_phasechange_hook, NULL);
|
|
+ nm_pppd_compat_add_notify(NM_PPPD_COMPAT_NF_IP_UP, nm_ip_up, NULL);
|
|
+ nm_pppd_compat_add_notify(NM_PPPD_COMPAT_NF_EXIT, nm_exit_notify, NULL);
|
|
+ nm_pppd_compat_add_notify(NM_PPPD_COMPAT_NF_IPV6_UP, nm_ip6_up, NULL);
|
|
return 0;
|
|
}
|
|
--
|
|
GitLab
|
|
|