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

