diff --git a/data/templates/accel-ppp/pptp.config.j2 b/data/templates/accel-ppp/pptp.config.j2
index 7fe4b17bf..290e6235d 100644
--- a/data/templates/accel-ppp/pptp.config.j2
+++ b/data/templates/accel-ppp/pptp.config.j2
@@ -1,83 +1,75 @@
 ### generated by accel_pptp.py ###
 [modules]
 log_syslog
 pptp
 shaper
 {# Common authentication backend definitions #}
 {% include 'accel-ppp/config_modules_auth_mode.j2' %}
 ippool
 {# Common IPv6 definitions #}
 {% include 'accel-ppp/config_modules_ipv6.j2' %}
 {# Common authentication protocols (pap, chap ...) #}
-{% if authentication.require is vyos_defined %}
-{%     if authentication.require == 'chap' %}
-auth_chap_md5
-{%     elif authentication.require == 'mschap' %}
-auth_mschap_v1
-{%     else %}
-auth_{{ authentication.require.replace('-', '_') }}
-{%     endif %}
-{% endif %}
+{% include 'accel-ppp/config_modules_auth_protocols.j2' %}
 
 [core]
 thread-count={{ thread_count }}
 
 [common]
 {% if max_concurrent_sessions is vyos_defined %}
 max-starting={{ max_concurrent_sessions }}
 {% endif %}
 
 [log]
 syslog=accel-pptp,daemon
 copy=1
 level=5
 
 {# Common DNS name-server definition #}
 {% include 'accel-ppp/config_name_server.j2' %}
 
 {% if wins_server is vyos_defined %}
 [wins]
 {%     for server in wins_server %}
 wins{{ loop.index }}={{ server }}
 {%     endfor %}
 {% endif %}
 
 [pptp]
 ifname=pptp%d
 {% if outside_address is vyos_defined %}
 bind={{ outside_address }}
 {% endif %}
 verbose=1
 ppp-max-mtu={{ mtu }}
 mppe={{ authentication.mppe }}
 echo-interval=10
 echo-failure=3
 {% if default_pool is vyos_defined %}
 ip-pool={{ default_pool }}
 {% endif %}
 {% if default_ipv6_pool is vyos_defined %}
 ipv6-pool={{ default_ipv6_pool }}
 ipv6-pool-delegate={{ default_ipv6_pool }}
 {% endif %}
 
 [client-ip-range]
 0.0.0.0/0
 
 {# Common IP pool definitions #}
 {% include 'accel-ppp/config_ip_pool.j2' %}
 
 {# Common IPv6 pool definitions #}
 {% include 'accel-ppp/config_ipv6_pool.j2' %}
 
 {# Common ppp-options definitions #}
 {% include 'accel-ppp/ppp-options.j2' %}
 
 {# Common chap-secrets and RADIUS server/option definitions #}
 {% include 'accel-ppp/config_chap_secrets_radius.j2' %}
 
 {# Common RADIUS shaper configuration #}
 {% include 'accel-ppp/config_shaper_radius.j2' %}
 
 [cli]
 tcp=127.0.0.1:2003
 
diff --git a/interface-definitions/include/version/pptp-version.xml.i b/interface-definitions/include/version/pptp-version.xml.i
index 3e1482ecc..a877d77ff 100644
--- a/interface-definitions/include/version/pptp-version.xml.i
+++ b/interface-definitions/include/version/pptp-version.xml.i
@@ -1,3 +1,3 @@
 <!-- include start from include/version/pptp-version.xml.i -->
-<syntaxVersion component='pptp' version='4'></syntaxVersion>
+<syntaxVersion component='pptp' version='5'></syntaxVersion>
 <!-- include end -->
diff --git a/interface-definitions/service_ipoe-server.xml.in b/interface-definitions/service_ipoe-server.xml.in
index eeec2aeef..23d6e54d1 100644
--- a/interface-definitions/service_ipoe-server.xml.in
+++ b/interface-definitions/service_ipoe-server.xml.in
@@ -1,191 +1,191 @@
 <?xml version="1.0"?>
 <interfaceDefinition>
   <node name="service">
     <children>
       <node name="ipoe-server" owner="${vyos_conf_scripts_dir}/service_ipoe-server.py">
         <properties>
           <help>Internet Protocol over Ethernet (IPoE) Server</help>
           <priority>900</priority>
         </properties>
         <children>
+          <node name="authentication">
+            <properties>
+              <help>Client authentication methods</help>
+            </properties>
+            <children>
+              #include <include/accel-ppp/auth-mode.xml.i>
+              <tagNode name="interface">
+                <properties>
+                  <help>Network interface for client MAC addresses</help>
+                  <completionHelp>
+                    <script>${vyos_completion_dir}/list_interfaces</script>
+                  </completionHelp>
+                </properties>
+                <children>
+                  <tagNode name="mac">
+                    <properties>
+                      <help>Media Access Control (MAC) address</help>
+                      <valueHelp>
+                        <format>macaddr</format>
+                        <description>Hardware (MAC) address</description>
+                      </valueHelp>
+                      <constraint>
+                        <validator name="mac-address"/>
+                      </constraint>
+                    </properties>
+                    <children>
+                      <node name="rate-limit">
+                        <properties>
+                          <help>Upload/Download speed limits</help>
+                        </properties>
+                        <children>
+                          <leafNode name="upload">
+                            <properties>
+                              <help>Upload bandwidth limit in kbits/sec</help>
+                              <constraint>
+                                <validator name="numeric" argument="--range  1-4294967295"/>
+                              </constraint>
+                            </properties>
+                          </leafNode>
+                          <leafNode name="download">
+                            <properties>
+                              <help>Download bandwidth limit in kbits/sec</help>
+                              <constraint>
+                                <validator name="numeric" argument="--range  1-4294967295"/>
+                              </constraint>
+                            </properties>
+                          </leafNode>
+                        </children>
+                      </node>
+                      <leafNode name="vlan">
+                        <properties>
+                          <help>VLAN monitor for automatic creation of VLAN interfaces</help>
+                          <valueHelp>
+                            <format>u32:1-4094</format>
+                            <description>Client VLAN id</description>
+                          </valueHelp>
+                          <constraint>
+                            <validator name="numeric" argument="--range 1-4094"/>
+                          </constraint>
+                          <constraintErrorMessage>VLAN IDs need to be in range 1-4094</constraintErrorMessage>
+                        </properties>
+                      </leafNode>
+                    </children>
+                  </tagNode>
+                </children>
+              </tagNode>
+              #include <include/radius-auth-server-ipv4.xml.i>
+              #include <include/accel-ppp/radius-additions.xml.i>
+              <node name="radius">
+                <children>
+                  #include <include/accel-ppp/radius-additions-rate-limit.xml.i>
+                </children>
+              </node>
+            </children>
+          </node>
           <tagNode name="interface">
             <properties>
               <help>Interface to listen dhcp or unclassified packets</help>
               <completionHelp>
                 <script>${vyos_completion_dir}/list_interfaces</script>
               </completionHelp>
             </properties>
             <children>
               <leafNode name="mode">
                 <properties>
                   <help>Client connectivity mode</help>
                   <completionHelp>
                     <list>l2 l3</list>
                   </completionHelp>
                   <valueHelp>
                     <format>l2</format>
                     <description>Client located on same interface as server</description>
                   </valueHelp>
                   <valueHelp>
                     <format>l3</format>
                     <description>Client located behind a router</description>
                   </valueHelp>
                   <constraint>
                     <regex>(l2|l3)</regex>
                   </constraint>
                 </properties>
                 <defaultValue>l2</defaultValue>
               </leafNode>
               <leafNode name="network">
                 <properties>
                   <help>Enables clients to share the same network or each client has its own vlan</help>
                   <completionHelp>
                     <list>shared vlan</list>
                   </completionHelp>
                   <constraint>
                     <regex>(shared|vlan)</regex>
                   </constraint>
                   <valueHelp>
                     <format>shared</format>
                     <description>Multiple clients share the same network</description>
                   </valueHelp>
                   <valueHelp>
                     <format>vlan</format>
                     <description>One VLAN per client</description>
                   </valueHelp>
                 </properties>
                 <defaultValue>shared</defaultValue>
               </leafNode>
               <leafNode name="client-subnet">
                 <properties>
                   <help>Client address pool</help>
                   <valueHelp>
                     <format>ipv4net</format>
                     <description>IPv4 address and prefix length</description>
                   </valueHelp>
                   <constraint>
                     <validator name="ipv4-prefix"/>
                   </constraint>
                 </properties>
               </leafNode>
               <node name="external-dhcp">
                 <properties>
                   <help>DHCP requests will be forwarded</help>
                 </properties>
                 <children>
                   <leafNode name="dhcp-relay">
                     <properties>
                       <help>DHCP Server the request will be redirected to.</help>
                       <valueHelp>
                         <format>ipv4</format>
                         <description>IPv4 address of the DHCP Server</description>
                       </valueHelp>
                       <constraint>
                         <validator name="ipv4-address"/>
                       </constraint>
                     </properties>
                   </leafNode>
                   <leafNode name="giaddr">
                     <properties>
                       <help>Relay Agent IPv4 Address</help>
                       <valueHelp>
                         <format>ipv4</format>
                         <description>Gateway IP address</description>
                       </valueHelp>
                       <constraint>
                         <validator name="ipv4-address"/>
                       </constraint>
                     </properties>
                   </leafNode>
                 </children>
               </node>
               #include <include/accel-ppp/vlan.xml.i>
             </children>
           </tagNode>
           #include <include/accel-ppp/max-concurrent-sessions.xml.i>
           #include <include/name-server-ipv4-ipv6.xml.i>
           #include <include/accel-ppp/client-ip-pool.xml.i>
           #include <include/accel-ppp/gateway-address-multi.xml.i>
           #include <include/accel-ppp/client-ipv6-pool.xml.i>
-          <node name="authentication">
-            <properties>
-              <help>Client authentication methods</help>
-            </properties>
-            <children>
-              #include <include/accel-ppp/auth-mode.xml.i>
-              <tagNode name="interface">
-                <properties>
-                  <help>Network interface for client MAC addresses</help>
-                  <completionHelp>
-                    <script>${vyos_completion_dir}/list_interfaces</script>
-                  </completionHelp>
-                </properties>
-                <children>
-                  <tagNode name="mac">
-                    <properties>
-                      <help>Media Access Control (MAC) address</help>
-                      <valueHelp>
-                        <format>macaddr</format>
-                        <description>Hardware (MAC) address</description>
-                      </valueHelp>
-                      <constraint>
-                        <validator name="mac-address"/>
-                      </constraint>
-                    </properties>
-                    <children>
-                      <node name="rate-limit">
-                        <properties>
-                          <help>Upload/Download speed limits</help>
-                        </properties>
-                        <children>
-                          <leafNode name="upload">
-                            <properties>
-                              <help>Upload bandwidth limit in kbits/sec</help>
-                              <constraint>
-                                <validator name="numeric" argument="--range 1-65535"/>
-                              </constraint>
-                            </properties>
-                          </leafNode>
-                          <leafNode name="download">
-                            <properties>
-                              <help>Download bandwidth limit in kbits/sec</help>
-                              <constraint>
-                                <validator name="numeric" argument="--range 1-65535"/>
-                              </constraint>
-                            </properties>
-                          </leafNode>
-                        </children>
-                      </node>
-                      <leafNode name="vlan">
-                        <properties>
-                          <help>VLAN monitor for automatic creation of VLAN interfaces</help>
-                          <valueHelp>
-                            <format>u32:1-4094</format>
-                            <description>Client VLAN id</description>
-                          </valueHelp>
-                          <constraint>
-                            <validator name="numeric" argument="--range 1-4094"/>
-                          </constraint>
-                          <constraintErrorMessage>VLAN IDs need to be in range 1-4094</constraintErrorMessage>
-                        </properties>
-                      </leafNode>
-                    </children>
-                  </tagNode>
-                </children>
-              </tagNode>
-              <node name="radius">
-                <children>
-                  #include <include/accel-ppp/radius-additions-rate-limit.xml.i>
-                </children>
-              </node>
-              #include <include/radius-auth-server-ipv4.xml.i>
-              #include <include/accel-ppp/radius-additions.xml.i>
-            </children>
-          </node>
           #include <include/accel-ppp/default-pool.xml.i>
           #include <include/accel-ppp/default-ipv6-pool.xml.i>
         </children>
       </node>
     </children>
   </node>
 </interfaceDefinition>
diff --git a/interface-definitions/vpn_l2tp.xml.in b/interface-definitions/vpn_l2tp.xml.in
index 942690bca..6148e3269 100644
--- a/interface-definitions/vpn_l2tp.xml.in
+++ b/interface-definitions/vpn_l2tp.xml.in
@@ -1,146 +1,146 @@
 <?xml version="1.0"?>
 <interfaceDefinition>
   <node name="vpn">
     <children>
       <node name="l2tp" owner="${vyos_conf_scripts_dir}/vpn_l2tp.py">
         <properties>
           <help>L2TP Virtual Private Network (VPN)</help>
           <priority>902</priority>
         </properties>
         <children>
           <node name="remote-access">
             <properties>
               <help>Remote access L2TP VPN</help>
             </properties>
             <children>
+              <node name="authentication">
+                <properties>
+                  <help>Authentication for remote access L2TP VPN</help>
+                </properties>
+                <children>
+                  #include <include/accel-ppp/auth-local-users.xml.i>
+                  #include <include/accel-ppp/auth-mode.xml.i>
+                  #include <include/accel-ppp/auth-protocols.xml.i>
+                  #include <include/radius-auth-server-ipv4.xml.i>
+                  #include <include/accel-ppp/radius-additions.xml.i>
+                  <node name="radius">
+                    <children>
+                      #include <include/accel-ppp/radius-additions-rate-limit.xml.i>
+                    </children>
+                  </node>
+                </children>
+              </node>
               #include <include/accel-ppp/max-concurrent-sessions.xml.i>
               #include <include/accel-ppp/mtu-128-16384.xml.i>
               <leafNode name="mtu">
                 <defaultValue>1436</defaultValue>
               </leafNode>
               <leafNode name="outside-address">
                 <properties>
                   <help>External IP address to which VPN clients will connect</help>
                   <constraint>
                     <validator name="ipv4-address"/>
                   </constraint>
                 </properties>
               </leafNode>
               #include <include/accel-ppp/gateway-address.xml.i>
               #include <include/name-server-ipv4-ipv6.xml.i>
               <node name="lns">
                 <properties>
                   <help>L2TP Network Server (LNS)</help>
                 </properties>
                 <children>
                   <leafNode name="shared-secret">
                     <properties>
                       <help>Tunnel password used to authenticate the client (LAC)</help>
                     </properties>
                   </leafNode>
                   <leafNode name="host-name">
                     <properties>
                       <help>Sent to the client (LAC) in the Host-Name attribute</help>
                       <constraint>
                         #include <include/constraint/host-name.xml.i>
                       </constraint>
                       <constraintErrorMessage>Host-name must be alphanumeric and can contain hyphens</constraintErrorMessage>
                     </properties>
                   </leafNode>
                 </children>
               </node>
               <node name="ipsec-settings">
                 <properties>
                   <help>Internet Protocol Security (IPsec) for remote access L2TP VPN</help>
                 </properties>
                 <children>
                   <node name="authentication">
                     <properties>
                       <help>IPsec authentication settings</help>
                     </properties>
                     <children>
                       <leafNode name="mode">
                         <properties>
                           <help>Authentication mode for IPsec</help>
                           <valueHelp>
                             <format>pre-shared-secret</format>
                             <description>Use pre-shared secret for IPsec authentication</description>
                           </valueHelp>
                           <valueHelp>
                             <format>x509</format>
                             <description>Use X.509 certificate for IPsec authentication</description>
                           </valueHelp>
                           <constraint>
                             <regex>(pre-shared-secret|x509)</regex>
                           </constraint>
                           <completionHelp>
                             <list>pre-shared-secret x509</list>
                           </completionHelp>
                         </properties>
                       </leafNode>
                       #include <include/ipsec/authentication-pre-shared-secret.xml.i>
                       #include <include/ipsec/authentication-x509.xml.i>
                     </children>
                   </node>
                   <leafNode name="ike-lifetime">
                     <properties>
                       <help>IKE lifetime</help>
                       <valueHelp>
                         <format>u32:30-86400</format>
                         <description>IKE lifetime in seconds</description>
                       </valueHelp>
                       <constraint>
                         <validator name="numeric" argument="--range 30-86400"/>
                       </constraint>
                     </properties>
                     <defaultValue>3600</defaultValue>
                   </leafNode>
                    <leafNode name="lifetime">
                     <properties>
                       <help>ESP lifetime</help>
                       <valueHelp>
                         <format>u32:30-86400</format>
                         <description>IKE lifetime in seconds</description>
                       </valueHelp>
                       <constraint>
                         <validator name="numeric" argument="--range 30-86400"/>
                       </constraint>
                     </properties>
                     <defaultValue>3600</defaultValue>
                   </leafNode>
                   #include <include/ipsec/esp-group.xml.i>
                   #include <include/ipsec/ike-group.xml.i>
                 </children>
               </node>
               #include <include/accel-ppp/wins-server.xml.i>
               #include <include/accel-ppp/client-ip-pool.xml.i>
               #include <include/accel-ppp/client-ipv6-pool.xml.i>
               #include <include/generic-description.xml.i>
               #include <include/dhcp-interface.xml.i>
-              <node name="authentication">
-                <properties>
-                  <help>Authentication for remote access L2TP VPN</help>
-                </properties>
-                <children>
-                  #include <include/accel-ppp/auth-protocols.xml.i>
-                  #include <include/accel-ppp/auth-mode.xml.i>
-                  #include <include/accel-ppp/auth-local-users.xml.i>
-                  #include <include/radius-auth-server-ipv4.xml.i>
-                  #include <include/accel-ppp/radius-additions.xml.i>
-                  <node name="radius">
-                    <children>
-                      #include <include/accel-ppp/radius-additions-rate-limit.xml.i>
-                    </children>
-                  </node>
-                </children>
-              </node>
               #include <include/accel-ppp/ppp-options.xml.i>
               #include <include/accel-ppp/default-pool.xml.i>
               #include <include/accel-ppp/default-ipv6-pool.xml.i>
             </children>
           </node>
         </children>
       </node>
     </children>
   </node>
 </interfaceDefinition>
diff --git a/interface-definitions/vpn_pptp.xml.in b/interface-definitions/vpn_pptp.xml.in
index d23086c02..2e2a3bec4 100644
--- a/interface-definitions/vpn_pptp.xml.in
+++ b/interface-definitions/vpn_pptp.xml.in
@@ -1,122 +1,60 @@
 <?xml version="1.0"?>
 <interfaceDefinition>
   <node name="vpn">
     <children>
       <node name="pptp" owner="${vyos_conf_scripts_dir}/vpn_pptp.py">
         <properties>
           <help>Point to Point Tunneling Protocol (PPTP) Virtual Private Network (VPN)</help>
           <priority>901</priority>
         </properties>
         <children>
           <node name="remote-access">
             <properties>
               <help>Remote access PPTP VPN</help>
             </properties>
             <children>
+              <node name="authentication">
+                <properties>
+                  <help>Authentication for remote access PPTP VPN</help>
+                </properties>
+                <children>
+                  #include <include/accel-ppp/auth-local-users.xml.i>
+                  #include <include/accel-ppp/auth-mode.xml.i>
+                  #include <include/accel-ppp/auth-protocols.xml.i>
+                  #include <include/radius-auth-server-ipv4.xml.i>
+                  #include <include/accel-ppp/radius-additions.xml.i>
+                  <node name="radius">
+                    <children>
+                      #include <include/accel-ppp/radius-additions-rate-limit.xml.i>
+                    </children>
+                  </node>
+                </children>
+              </node>
               #include <include/accel-ppp/max-concurrent-sessions.xml.i>
               #include <include/accel-ppp/mtu-128-16384.xml.i>
               <leafNode name="mtu">
                 <defaultValue>1436</defaultValue>
               </leafNode>
               <leafNode name="outside-address">
                 <properties>
                   <help>External IP address to which VPN clients will connect</help>
                   <constraint>
                     <validator name="ipv4-address"/>
                   </constraint>
                 </properties>
               </leafNode>
               #include <include/accel-ppp/gateway-address.xml.i>
               #include <include/name-server-ipv4-ipv6.xml.i>
               #include <include/accel-ppp/wins-server.xml.i>
               #include <include/accel-ppp/client-ip-pool.xml.i>
-              <node name="authentication">
-                <properties>
-                  <help>Authentication for remote access PPTP VPN</help>
-                </properties>
-                <children>
-                  <leafNode name="require">
-                    <properties>
-                      <help>Authentication protocol for remote access peer PPTP VPN</help>
-                      <completionHelp>
-                        <list>pap chap mschap mschap-v2</list>
-                      </completionHelp>
-                      <valueHelp>
-                        <format>pap</format>
-                        <description>Require the peer to authenticate itself using PAP [Password Authentication Protocol].</description>
-                      </valueHelp>
-                      <valueHelp>
-                        <format>chap</format>
-                        <description>Require the peer to authenticate itself using CHAP [Challenge Handshake Authentication Protocol].</description>
-                      </valueHelp>
-                      <valueHelp>
-                        <format>mschap</format>
-                        <description>Require the peer to authenticate itself using CHAP [Challenge Handshake Authentication Protocol].</description>
-                      </valueHelp>
-                      <valueHelp>
-                        <format>mschap-v2</format>
-                        <description>Require the peer to authenticate itself using MS-CHAPv2 [Microsoft Challenge Handshake Authentication Protocol, Version 2].</description>
-                      </valueHelp>
-                      <constraint>
-                        <regex>(pap|chap|mschap|mschap-v2)</regex>
-                      </constraint>
-                    </properties>
-                    <defaultValue>mschap-v2</defaultValue>
-                  </leafNode>
-                  #include <include/accel-ppp/auth-mode.xml.i>
-                  <node name="local-users">
-                    <properties>
-                      <help>Local user authentication for remote access PPTP VPN</help>
-                    </properties>
-                    <children>
-                      <tagNode name="username">
-                        <properties>
-                          <help>User name for authentication</help>
-                        </properties>
-                        <children>
-                          #include <include/generic-disable-node.xml.i>
-                          <leafNode name="password">
-                            <properties>
-                              <help>Password for authentication</help>
-                            </properties>
-                          </leafNode>
-                          <leafNode name="static-ip">
-                            <properties>
-                              <help>Static client IP address</help>
-                            </properties>
-                            <defaultValue>*</defaultValue>
-                          </leafNode>
-                        </children>
-                      </tagNode>
-                    </children>
-                  </node>
-                  <node name="radius">
-                    <children>
-                      #include <include/accel-ppp/radius-additions-rate-limit.xml.i>
-                    </children>
-                  </node>
-                  #include <include/radius-auth-server-ipv4.xml.i>
-                  #include <include/accel-ppp/radius-additions.xml.i>
-                  <node name="radius">
-                    <children>
-                      <leafNode name="timeout">
-                        <defaultValue>30</defaultValue>
-                      </leafNode>
-                      <leafNode name="acct-timeout">
-                        <defaultValue>30</defaultValue>
-                      </leafNode>
-                    </children>
-                  </node>
-                </children>
-              </node>
               #include <include/accel-ppp/default-pool.xml.i>
               #include <include/accel-ppp/client-ipv6-pool.xml.i>
               #include <include/accel-ppp/default-ipv6-pool.xml.i>
               #include <include/accel-ppp/ppp-options.xml.i>
             </children>
           </node>
         </children>
       </node>
     </children>
   </node>
 </interfaceDefinition>
diff --git a/python/vyos/accel_ppp_util.py b/python/vyos/accel_ppp_util.py
index d60402e48..bd0c46a19 100644
--- a/python/vyos/accel_ppp_util.py
+++ b/python/vyos/accel_ppp_util.py
@@ -1,202 +1,206 @@
 # Copyright 2023-2024 VyOS maintainers and contributors <maintainers@vyos.io>
 #
 # This library is free software; you can redistribute it and/or
 # modify it under the terms of the GNU Lesser General Public
 # License as published by the Free Software Foundation; either
 # version 2.1 of the License, or (at your option) any later version.
 #
 # This library is distributed in the hope that it will be useful,
 # but WITHOUT ANY WARRANTY; without even the implied warranty of
 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 # Lesser General Public License for more details.
 #
 # You should have received a copy of the GNU Lesser General Public
 # License along with this library.  If not, see <http://www.gnu.org/licenses/>.
 
 # The sole purpose of this module is to hold common functions used in
 # all kinds of implementations to verify the CLI configuration.
 # It is started by migrating the interfaces to the new get_config_dict()
 # approach which will lead to a lot of code that can be reused.
 
 # NOTE: imports should be as local as possible to the function which
 # makes use of it!
 
 from vyos import ConfigError
 from vyos.base import Warning
 from vyos.utils.dict import dict_search
 
 def get_pools_in_order(data: dict) -> list:
     """Return a list of dictionaries representing pool data in the order
     in which they should be allocated. Pool must be defined before we can
     use it with 'next-pool' option.
 
     Args:
         data: A dictionary of pool data, where the keys are pool names and the
         values are dictionaries containing the 'subnet' key and the optional
         'next_pool' key.
 
     Returns:
         list: A list of dictionaries
 
     Raises:
         ValueError: If a 'next_pool' key references a pool name that
                     has not been defined.
         ValueError: If a circular reference is found in the 'next_pool' keys.
 
     Example:
         config_data = {
         ... 'first-pool': {
         ... 'next_pool': 'second-pool',
         ... 'subnet': '192.0.2.0/25'
         ... },
         ... 'second-pool': {
         ... 'next_pool': 'third-pool',
         ... 'subnet': '203.0.113.0/25'
         ... },
         ... 'third-pool': {
         ... 'subnet': '198.51.100.0/24'
         ... },
         ... 'foo': {
         ... 'subnet': '100.64.0.0/24',
         ... 'next_pool': 'second-pool'
         ... }
         ... }
 
         % get_pools_in_order(config_data)
         [{'third-pool': {'subnet': '198.51.100.0/24'}},
         {'second-pool': {'next_pool': 'third-pool', 'subnet': '203.0.113.0/25'}},
         {'first-pool': {'next_pool': 'second-pool', 'subnet': '192.0.2.0/25'}},
         {'foo': {'next_pool': 'second-pool', 'subnet': '100.64.0.0/24'}}]
     """
     pools = []
     unresolved_pools = {}
 
     for pool, pool_config in data.items():
         if "next_pool" not in pool_config or not pool_config["next_pool"]:
             pools.insert(0, {pool: pool_config})
         else:
             unresolved_pools[pool] = pool_config
 
     while unresolved_pools:
         resolved_pools = []
 
         for pool, pool_config in unresolved_pools.items():
             next_pool_name = pool_config["next_pool"]
 
             if any(p for p in pools if next_pool_name in p):
                 index = next(
                     (i for i, p in enumerate(pools) if next_pool_name in p), None
                 )
                 pools.insert(index + 1, {pool: pool_config})
                 resolved_pools.append(pool)
             elif next_pool_name in unresolved_pools:
                 # next pool not yet resolved
                 pass
             else:
                 raise ConfigError(
                     f"Pool '{next_pool_name}' not defined in configuration data"
                 )
 
         if not resolved_pools:
             raise ConfigError("Circular reference in configuration data")
 
         for pool in resolved_pools:
             unresolved_pools.pop(pool)
 
     return pools
 
 
 def verify_accel_ppp_base_service(config, local_users=True):
     """
     Common helper function which must be used by all Accel-PPP services based
     on get_config_dict()
     """
     # vertify auth settings
     if local_users and dict_search("authentication.mode", config) == "local":
         if (
             dict_search("authentication.local_users", config) is None
             or dict_search("authentication.local_users", config) == {}
         ):
             raise ConfigError(
                 "Authentication mode local requires local users to be configured!"
             )
 
         for user in dict_search("authentication.local_users.username", config):
             user_config = config["authentication"]["local_users"]["username"][user]
 
             if "password" not in user_config:
                 raise ConfigError(f'Password required for local user "{user}"')
 
             if "rate_limit" in user_config:
                 # if up/download is set, check that both have a value
                 if not {"upload", "download"} <= set(user_config["rate_limit"]):
                     raise ConfigError(
                         f'User "{user}" has rate-limit configured for only one '
                         "direction but both upload and download must be given!"
                     )
 
     elif dict_search("authentication.mode", config) == "radius":
         if not dict_search("authentication.radius.server", config):
             raise ConfigError("RADIUS authentication requires at least one server")
 
         for server in dict_search("authentication.radius.server", config):
             radius_config = config["authentication"]["radius"]["server"][server]
             if "key" not in radius_config:
                 raise ConfigError(f'Missing RADIUS secret key for server "{server}"')
 
+    if dict_search('authentication.radius.dynamic_author.server', config):
+        if not dict_search('authentication.radius.dynamic_author.key', config):
+            raise ConfigError('DAE/CoA server key required!')
+
     if "name_server_ipv4" in config:
         if len(config["name_server_ipv4"]) > 2:
             raise ConfigError(
                 "Not more then two IPv4 DNS name-servers " "can be configured"
             )
 
     if "name_server_ipv6" in config:
         if len(config["name_server_ipv6"]) > 3:
             raise ConfigError(
                 "Not more then three IPv6 DNS name-servers " "can be configured"
             )
 
 
 
 def verify_accel_ppp_ip_pool(vpn_config):
     """
     Common helper function which must be used by Accel-PPP
     services (pptp, l2tp, sstp, pppoe) to verify client-ip-pool
     and client-ipv6-pool
     """
     if dict_search("client_ip_pool", vpn_config):
         for pool_name, pool_config in vpn_config["client_ip_pool"].items():
             next_pool = dict_search(f"next_pool", pool_config)
             if next_pool:
                 if next_pool not in vpn_config["client_ip_pool"]:
                     raise ConfigError(
                         f'Next pool "{next_pool}" does not exist')
                 if not dict_search(f"range", pool_config):
                     raise ConfigError(
                         f'Pool "{pool_name}" does not contain range but next-pool exists'
                     )
     if not dict_search("gateway_address", vpn_config):
         Warning("IPv4 Server requires gateway-address to be configured!")
 
     default_pool = dict_search("default_pool", vpn_config)
     if default_pool:
         if default_pool not in dict_search("client_ip_pool", vpn_config):
             raise ConfigError(f'Default pool "{default_pool}" does not exists')
 
     if 'client_ipv6_pool' in vpn_config:
         for ipv6_pool, ipv6_pool_config in vpn_config['client_ipv6_pool'].items():
             if 'delegate' in ipv6_pool_config and 'prefix' not in ipv6_pool_config:
                 raise ConfigError(
                     f'IPv6 delegate-prefix requires IPv6 prefix to be configured in "{ipv6_pool}"!')
 
     if dict_search('authentication.mode', vpn_config) in ['local', 'noauth']:
         if not dict_search('client_ip_pool', vpn_config) and not dict_search(
                 'client_ipv6_pool', vpn_config):
             raise ConfigError(
                 "Local auth mode requires local client-ip-pool or client-ipv6-pool to be configured!")
         if dict_search('client_ip_pool', vpn_config) and not dict_search(
                 'default_pool', vpn_config):
             Warning("'default-pool' is not defined")
         if dict_search('client_ipv6_pool', vpn_config) and not dict_search(
                 'default_ipv6_pool', vpn_config):
             Warning("'default-ipv6-pool' is not defined")
diff --git a/smoketest/scripts/cli/test_vpn_l2tp.py b/smoketest/scripts/cli/test_vpn_l2tp.py
index e253f0e49..c3b5b500d 100755
--- a/smoketest/scripts/cli/test_vpn_l2tp.py
+++ b/smoketest/scripts/cli/test_vpn_l2tp.py
@@ -1,100 +1,100 @@
 #!/usr/bin/env python3
 #
 # Copyright (C) 2023-2024 VyOS maintainers and contributors
 #
 # This program is free software; you can redistribute it and/or modify
 # it under the terms of the GNU General Public License version 2 or later as
 # published by the Free Software Foundation.
 #
 # This program is distributed in the hope that it will be useful,
 # but WITHOUT ANY WARRANTY; without even the implied warranty of
 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 # GNU General Public License for more details.
 #
 # You should have received a copy of the GNU General Public License
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 import re
 import unittest
 
 from base_accel_ppp_test import BasicAccelPPPTest
 from configparser import ConfigParser
 from vyos.utils.process import cmd
 
 
 class TestVPNL2TPServer(BasicAccelPPPTest.TestCase):
     @classmethod
     def setUpClass(cls):
         cls._base_path = ['vpn', 'l2tp', 'remote-access']
         cls._config_file = '/run/accel-pppd/l2tp.conf'
         cls._chap_secrets = '/run/accel-pppd/l2tp.chap-secrets'
         cls._protocol_section = 'l2tp'
         # call base-classes classmethod
         super(TestVPNL2TPServer, cls).setUpClass()
 
     @classmethod
     def tearDownClass(cls):
         super(TestVPNL2TPServer, cls).tearDownClass()
 
     def basic_protocol_specific_config(self):
         pass
 
     def test_l2tp_server_authentication_protocols(self):
-        # Test configuration of local authentication for PPPoE server
+        # Test configuration of local authentication protocols
         self.basic_config()
 
         # explicitly test mschap-v2 - no special reason
         self.set( ['authentication', 'protocols', 'mschap-v2'])
 
         # commit changes
         self.cli_commit()
 
         # Validate configuration values
         conf = ConfigParser(allow_no_value=True)
         conf.read(self._config_file)
 
         self.assertEqual(conf['modules']['auth_mschap_v2'], None)
 
     def test_vpn_l2tp_dependence_ipsec_swanctl(self):
         # Test config vpn for tasks T3843 and T5926
 
         base_path = ['vpn', 'l2tp', 'remote-access']
         # make precondition
         self.cli_set(['interfaces', 'dummy', 'dum0', 'address', '203.0.113.1/32'])
         self.cli_set(['vpn', 'ipsec', 'interface', 'dum0'])
 
         self.cli_commit()
         # check ipsec apply to swanctl
         self.assertEqual('', cmd('echo vyos | sudo -S swanctl -L '))
 
         self.cli_set(base_path + ['authentication', 'local-users', 'username', 'foo', 'password', 'bar'])
         self.cli_set(base_path + ['authentication', 'mode', 'local'])
         self.cli_set(base_path + ['authentication', 'protocols', 'chap'])
         self.cli_set(base_path + ['client-ip-pool', 'first', 'range', '10.200.100.100-10.200.100.110'])
         self.cli_set(base_path + ['description', 'VPN - REMOTE'])
         self.cli_set(base_path + ['name-server', '1.1.1.1'])
         self.cli_set(base_path + ['ipsec-settings', 'authentication', 'mode', 'pre-shared-secret'])
         self.cli_set(base_path + ['ipsec-settings', 'authentication', 'pre-shared-secret', 'SeCret'])
         self.cli_set(base_path + ['ipsec-settings', 'ike-lifetime', '8600'])
         self.cli_set(base_path + ['ipsec-settings', 'lifetime', '3600'])
         self.cli_set(base_path + ['outside-address', '203.0.113.1'])
         self.cli_set(base_path + ['gateway-address', '203.0.113.1'])
 
         self.cli_commit()
 
         # check l2tp apply to swanctl
         self.assertTrue('l2tp_remote_access:' in cmd('echo vyos | sudo -S swanctl -L '))
 
         self.cli_delete(['vpn', 'l2tp'])
         self.cli_commit()
 
         # check l2tp apply to swanctl after delete config
         self.assertEqual('', cmd('echo vyos | sudo -S swanctl -L '))
 
         # need to correct tearDown test
         self.basic_config()
         self.cli_set(base_path + ['authentication', 'protocols', 'chap'])
         self.cli_commit()
 
 
 if __name__ == '__main__':
     unittest.main(verbosity=2)
diff --git a/smoketest/scripts/cli/test_vpn_pptp.py b/smoketest/scripts/cli/test_vpn_pptp.py
index 40dcb7f80..ac46d210d 100755
--- a/smoketest/scripts/cli/test_vpn_pptp.py
+++ b/smoketest/scripts/cli/test_vpn_pptp.py
@@ -1,204 +1,44 @@
 #!/usr/bin/env python3
 #
 # Copyright (C) 2023-2024 VyOS maintainers and contributors
 #
 # This program is free software; you can redistribute it and/or modify
 # it under the terms of the GNU General Public License version 2 or later as
 # published by the Free Software Foundation.
 #
 # This program is distributed in the hope that it will be useful,
 # but WITHOUT ANY WARRANTY; without even the implied warranty of
 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 # GNU General Public License for more details.
 #
 # You should have received a copy of the GNU General Public License
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
 import re
 import unittest
 
 from configparser import ConfigParser
 from vyos.utils.process import cmd
 from base_accel_ppp_test import BasicAccelPPPTest
 from vyos.template import is_ipv4
 
 
 class TestVPNPPTPServer(BasicAccelPPPTest.TestCase):
     @classmethod
     def setUpClass(cls):
         cls._base_path = ['vpn', 'pptp', 'remote-access']
         cls._config_file = '/run/accel-pppd/pptp.conf'
         cls._chap_secrets = '/run/accel-pppd/pptp.chap-secrets'
         cls._protocol_section = 'pptp'
         # call base-classes classmethod
         super(TestVPNPPTPServer, cls).setUpClass()
 
     @classmethod
     def tearDownClass(cls):
         super(TestVPNPPTPServer, cls).tearDownClass()
 
     def basic_protocol_specific_config(self):
         pass
 
-    def test_accel_local_authentication(self):
-        # Test configuration of local authentication
-        self.basic_config()
-
-        # upload / download limit
-        user = "test"
-        password = "test2"
-        static_ip = "100.100.100.101"
-        upload = "5000"
-        download = "10000"
-
-        self.set(
-            [
-                "authentication",
-                "local-users",
-                "username",
-                user,
-                "password",
-                password,
-            ]
-        )
-        self.set(
-            [
-                "authentication",
-                "local-users",
-                "username",
-                user,
-                "static-ip",
-                static_ip,
-            ]
-        )
-
-        # commit changes
-        self.cli_commit()
-
-        # Validate configuration values
-        conf = ConfigParser(allow_no_value=True, delimiters="=", strict=False)
-        conf.read(self._config_file)
-
-        # check proper path to chap-secrets file
-        self.assertEqual(conf["chap-secrets"]["chap-secrets"], self._chap_secrets)
-
-        # basic verification
-        self.verify(conf)
-
-        # check local users
-        tmp = cmd(f"sudo cat {self._chap_secrets}")
-        regex = f"{user}\s+\*\s+{password}\s+{static_ip}\s"
-        tmp = re.findall(regex, tmp)
-        self.assertTrue(tmp)
-
-        # Check local-users default value(s)
-        self.delete(["authentication", "local-users", "username", user, "static-ip"])
-        # commit changes
-        self.cli_commit()
-
-        # check local users
-        tmp = cmd(f"sudo cat {self._chap_secrets}")
-        regex = f"{user}\s+\*\s+{password}\s+\*\s"
-        tmp = re.findall(regex, tmp)
-        self.assertTrue(tmp)
-
-    def test_accel_radius_authentication(self):
-        # Test configuration of RADIUS authentication for PPPoE server
-        self.basic_config()
-
-        radius_server = "192.0.2.22"
-        radius_key = "secretVyOS"
-        radius_port = "2000"
-        radius_port_acc = "3000"
-
-        self.set(["authentication", "mode", "radius"])
-        self.set(
-            ["authentication", "radius", "server", radius_server, "key", radius_key]
-        )
-        self.set(
-            [
-                "authentication",
-                "radius",
-                "server",
-                radius_server,
-                "port",
-                radius_port,
-            ]
-        )
-        self.set(
-            [
-                "authentication",
-                "radius",
-                "server",
-                radius_server,
-                "acct-port",
-                radius_port_acc,
-            ]
-        )
-
-        nas_id = "VyOS-PPPoE"
-        nas_ip = "7.7.7.7"
-        self.set(["authentication", "radius", "nas-identifier", nas_id])
-        self.set(["authentication", "radius", "nas-ip-address", nas_ip])
-
-        source_address = "1.2.3.4"
-        self.set(["authentication", "radius", "source-address", source_address])
-
-        # commit changes
-        self.cli_commit()
-
-        # Validate configuration values
-        conf = ConfigParser(allow_no_value=True, delimiters="=", strict=False)
-        conf.read(self._config_file)
-
-        # basic verification
-        self.verify(conf)
-
-        # check auth
-        self.assertTrue(conf["radius"].getboolean("verbose"))
-        self.assertEqual(conf["radius"]["acct-timeout"], "30")
-        self.assertEqual(conf["radius"]["timeout"], "30")
-        self.assertEqual(conf["radius"]["max-try"], "3")
-
-        self.assertEqual(conf["radius"]["nas-identifier"], nas_id)
-        self.assertEqual(conf["radius"]["nas-ip-address"], nas_ip)
-        self.assertEqual(conf["radius"]["bind"], source_address)
-
-        server = conf["radius"]["server"].split(",")
-        self.assertEqual(radius_server, server[0])
-        self.assertEqual(radius_key, server[1])
-        self.assertEqual(f"auth-port={radius_port}", server[2])
-        self.assertEqual(f"acct-port={radius_port_acc}", server[3])
-        self.assertEqual(f"req-limit=0", server[4])
-        self.assertEqual(f"fail-time=0", server[5])
-
-        #
-        # Disable Radius Accounting
-        #
-        self.delete(["authentication", "radius", "server", radius_server, "acct-port"])
-        self.set(
-            [
-                "authentication",
-                "radius",
-                "server",
-                radius_server,
-                "disable-accounting",
-            ]
-        )
-
-        # commit changes
-        self.cli_commit()
-
-        conf.read(self._config_file)
-
-        server = conf["radius"]["server"].split(",")
-        self.assertEqual(radius_server, server[0])
-        self.assertEqual(radius_key, server[1])
-        self.assertEqual(f"auth-port={radius_port}", server[2])
-        self.assertEqual(f"acct-port=0", server[3])
-        self.assertEqual(f"req-limit=0", server[4])
-        self.assertEqual(f"fail-time=0", server[5])
-
-
 if __name__ == '__main__':
     unittest.main(verbosity=2)
diff --git a/src/conf_mode/service_ipoe-server.py b/src/conf_mode/service_ipoe-server.py
index 6df6f3dc7..5f72b983c 100755
--- a/src/conf_mode/service_ipoe-server.py
+++ b/src/conf_mode/service_ipoe-server.py
@@ -1,118 +1,110 @@
 #!/usr/bin/env python3
 #
 # Copyright (C) 2018-2024 VyOS maintainers and contributors
 #
 # This program is free software; you can redistribute it and/or modify
 # it under the terms of the GNU General Public License version 2 or later as
 # published by the Free Software Foundation.
 #
 # This program is distributed in the hope that it will be useful,
 # but WITHOUT ANY WARRANTY; without even the implied warranty of
 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 # GNU General Public License for more details.
 #
 # You should have received a copy of the GNU General Public License
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
 import os
 
 from sys import exit
 
 from vyos.config import Config
 from vyos.configdict import get_accel_dict
 from vyos.configverify import verify_interface_exists
 from vyos.template import render
 from vyos.utils.process import call
 from vyos.utils.dict import dict_search
 from vyos.accel_ppp_util import get_pools_in_order
 from vyos.accel_ppp_util import verify_accel_ppp_ip_pool
+from vyos.accel_ppp_util import verify_accel_ppp_base_service
 from vyos import ConfigError
 from vyos import airbag
 airbag.enable()
 
 
 ipoe_conf = '/run/accel-pppd/ipoe.conf'
 ipoe_chap_secrets = '/run/accel-pppd/ipoe.chap-secrets'
 
 
 def get_config(config=None):
     if config:
         conf = config
     else:
         conf = Config()
     base = ['service', 'ipoe-server']
     if not conf.exists(base):
         return None
 
     # retrieve common dictionary keys
     ipoe = get_accel_dict(conf, base, ipoe_chap_secrets)
 
     if dict_search('client_ip_pool', ipoe):
         # Multiple named pools require ordered values T5099
         ipoe['ordered_named_pools'] = get_pools_in_order(dict_search('client_ip_pool', ipoe))
 
     ipoe['server_type'] = 'ipoe'
     return ipoe
 
 
 def verify(ipoe):
     if not ipoe:
         return None
 
     if 'interface' not in ipoe:
         raise ConfigError('No IPoE interface configured')
 
     for interface, iface_config in ipoe['interface'].items():
         verify_interface_exists(interface)
         if 'client_subnet' in iface_config and 'vlan' in iface_config:
             raise ConfigError('Option "client-subnet" incompatible with "vlan"!'
                               'Use "ipoe client-ip-pool" instead.')
 
+    verify_accel_ppp_base_service(ipoe, local_users=False)
     verify_accel_ppp_ip_pool(ipoe)
 
-    if dict_search('authentication.mode', ipoe) == 'radius':
-        if not dict_search('authentication.radius.server', ipoe):
-            raise ConfigError('RADIUS authentication requires at least one server')
-
-        for server in dict_search('authentication.radius.server', ipoe):
-            radius_config = ipoe['authentication']['radius']['server'][server]
-            if 'key' not in radius_config:
-                raise ConfigError(f'Missing RADIUS secret key for server "{server}"')
-
-
     return None
 
 
 def generate(ipoe):
     if not ipoe:
         return None
 
     render(ipoe_conf, 'accel-ppp/ipoe.config.j2', ipoe)
 
     if dict_search('authentication.mode', ipoe) == 'local':
         render(ipoe_chap_secrets, 'accel-ppp/chap-secrets.ipoe.j2',
                ipoe, permission=0o640)
     return None
 
 
 def apply(ipoe):
     systemd_service = 'accel-ppp@ipoe.service'
     if ipoe == None:
         call(f'systemctl stop {systemd_service}')
         for file in [ipoe_conf, ipoe_chap_secrets]:
             if os.path.exists(file):
                 os.unlink(file)
 
         return None
 
     call(f'systemctl reload-or-restart {systemd_service}')
 
 if __name__ == '__main__':
     try:
         c = get_config()
         verify(c)
         generate(c)
         apply(c)
     except ConfigError as e:
         print(e)
         exit(1)
diff --git a/src/conf_mode/service_pppoe-server.py b/src/conf_mode/service_pppoe-server.py
index 31299a15c..c2dfbdb44 100755
--- a/src/conf_mode/service_pppoe-server.py
+++ b/src/conf_mode/service_pppoe-server.py
@@ -1,126 +1,120 @@
 #!/usr/bin/env python3
 #
 # Copyright (C) 2018-2024 VyOS maintainers and contributors
 #
 # This program is free software; you can redistribute it and/or modify
 # it under the terms of the GNU General Public License version 2 or later as
 # published by the Free Software Foundation.
 #
 # This program is distributed in the hope that it will be useful,
 # but WITHOUT ANY WARRANTY; without even the implied warranty of
 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 # GNU General Public License for more details.
 #
 # You should have received a copy of the GNU General Public License
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
 import os
 
 from sys import exit
 
 from vyos.config import Config
 from vyos.configdict import get_accel_dict
 from vyos.configdict import is_node_changed
 from vyos.configverify import verify_interface_exists
 from vyos.template import render
 from vyos.utils.process import call
 from vyos.utils.dict import dict_search
 from vyos.accel_ppp_util import verify_accel_ppp_base_service
 from vyos.accel_ppp_util import verify_accel_ppp_ip_pool
 from vyos.accel_ppp_util import get_pools_in_order
 from vyos import ConfigError
 from vyos import airbag
 
 airbag.enable()
 
 pppoe_conf = r'/run/accel-pppd/pppoe.conf'
 pppoe_chap_secrets = r'/run/accel-pppd/pppoe.chap-secrets'
 
 def get_config(config=None):
     if config:
         conf = config
     else:
         conf = Config()
     base = ['service', 'pppoe-server']
     if not conf.exists(base):
         return None
 
     # retrieve common dictionary keys
     pppoe = get_accel_dict(conf, base, pppoe_chap_secrets)
 
     if dict_search('client_ip_pool', pppoe):
         # Multiple named pools require ordered values T5099
         pppoe['ordered_named_pools'] = get_pools_in_order(dict_search('client_ip_pool', pppoe))
 
     # reload-or-restart does not implemented in accel-ppp
     # use this workaround until it will be implemented
     # https://phabricator.accel-ppp.org/T3
     conditions = [is_node_changed(conf, base + ['client-ip-pool']),
                   is_node_changed(conf, base + ['client-ipv6-pool']),
                   is_node_changed(conf, base + ['interface'])]
     if any(conditions):
         pppoe.update({'restart_required': {}})
     pppoe['server_type'] = 'pppoe'
     return pppoe
 
 def verify(pppoe):
     if not pppoe:
         return None
 
     verify_accel_ppp_base_service(pppoe)
+    verify_accel_ppp_ip_pool(pppoe)
 
     if 'wins_server' in pppoe and len(pppoe['wins_server']) > 2:
         raise ConfigError('Not more then two WINS name-servers can be configured')
 
     if 'interface' not in pppoe:
         raise ConfigError('At least one listen interface must be defined!')
 
     # Check is interface exists in the system
     for interface in pppoe['interface']:
         verify_interface_exists(interface)
 
-    verify_accel_ppp_ip_pool(pppoe)
-
-    if dict_search('authentication.radius.dynamic_author.server', pppoe):
-        if not dict_search('authentication.radius.dynamic_author.key', pppoe):
-            raise ConfigError('DA/CoE server key required!')
-
-
     return None
 
 
 def generate(pppoe):
     if not pppoe:
         return None
 
     render(pppoe_conf, 'accel-ppp/pppoe.config.j2', pppoe)
 
     if dict_search('authentication.mode', pppoe) == 'local':
         render(pppoe_chap_secrets, 'accel-ppp/chap-secrets.config_dict.j2',
                pppoe, permission=0o640)
     return None
 
 
 def apply(pppoe):
     systemd_service = 'accel-ppp@pppoe.service'
     if not pppoe:
         call(f'systemctl stop {systemd_service}')
         for file in [pppoe_conf, pppoe_chap_secrets]:
             if os.path.exists(file):
                 os.unlink(file)
         return None
 
     if 'restart_required' in pppoe:
         call(f'systemctl restart {systemd_service}')
     else:
         call(f'systemctl reload-or-restart {systemd_service}')
 
 if __name__ == '__main__':
     try:
         c = get_config()
         verify(c)
         generate(c)
         apply(c)
     except ConfigError as e:
         print(e)
         exit(1)
diff --git a/src/conf_mode/vpn_l2tp.py b/src/conf_mode/vpn_l2tp.py
index 4ca717814..266381754 100755
--- a/src/conf_mode/vpn_l2tp.py
+++ b/src/conf_mode/vpn_l2tp.py
@@ -1,116 +1,109 @@
 #!/usr/bin/env python3
 #
 # Copyright (C) 2019-2024 VyOS maintainers and contributors
 #
 # This program is free software; you can redistribute it and/or modify
 # it under the terms of the GNU General Public License version 2 or later as
 # published by the Free Software Foundation.
 #
 # This program is distributed in the hope that it will be useful,
 # but WITHOUT ANY WARRANTY; without even the implied warranty of
 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 # GNU General Public License for more details.
 #
 # You should have received a copy of the GNU General Public License
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
 import os
 
 from sys import exit
 
 from vyos.config import Config
 from vyos.configdep import call_dependents, set_dependents
 from vyos.configdict import get_accel_dict
 from vyos.template import render
 from vyos.utils.process import call
 from vyos.utils.dict import dict_search
 from vyos.accel_ppp_util import verify_accel_ppp_base_service
 from vyos.accel_ppp_util import verify_accel_ppp_ip_pool
 from vyos.accel_ppp_util import get_pools_in_order
-from vyos.base import Warning
 from vyos import ConfigError
 
 from vyos import airbag
 airbag.enable()
 
 
 l2tp_conf = '/run/accel-pppd/l2tp.conf'
 l2tp_chap_secrets = '/run/accel-pppd/l2tp.chap-secrets'
 
 def get_config(config=None):
     if config:
         conf = config
     else:
         conf = Config()
     base = ['vpn', 'l2tp', 'remote-access']
 
     set_dependents('ipsec', conf)
 
     if not conf.exists(base):
         return None
 
     # retrieve common dictionary keys
     l2tp = get_accel_dict(conf, base, l2tp_chap_secrets)
     if dict_search('client_ip_pool', l2tp):
         # Multiple named pools require ordered values T5099
         l2tp['ordered_named_pools'] = get_pools_in_order(
             dict_search('client_ip_pool', l2tp))
     l2tp['server_type'] = 'l2tp'
     return l2tp
 
 
 def verify(l2tp):
     if not l2tp:
         return None
 
     verify_accel_ppp_base_service(l2tp)
-
-    if dict_search('authentication.radius.dynamic_author.server', l2tp):
-        if not dict_search('authentication.radius.dynamic_author.key', l2tp):
-            raise ConfigError('DA/CoE server key required!')
-
     verify_accel_ppp_ip_pool(l2tp)
 
-
     if 'wins_server' in l2tp and len(l2tp['wins_server']) > 2:
         raise ConfigError(
             'Not more then two WINS name-servers can be configured')
 
     return None
 
 
 def generate(l2tp):
     if not l2tp:
         return None
 
     render(l2tp_conf, 'accel-ppp/l2tp.config.j2', l2tp)
 
     if dict_search('authentication.mode', l2tp) == 'local':
         render(l2tp_chap_secrets, 'accel-ppp/chap-secrets.config_dict.j2',
                l2tp, permission=0o640)
 
     return None
 
 
 def apply(l2tp):
     if not l2tp:
         call('systemctl stop accel-ppp@l2tp.service')
         for file in [l2tp_chap_secrets, l2tp_conf]:
             if os.path.exists(file):
                 os.unlink(file)
     else:
         call('systemctl restart accel-ppp@l2tp.service')
 
     call_dependents()
 
 
 if __name__ == '__main__':
     try:
         c = get_config()
         verify(c)
         generate(c)
         apply(c)
 
     except ConfigError as e:
         print(e)
         exit(1)
diff --git a/src/migration-scripts/pptp/4-to-5 b/src/migration-scripts/pptp/4-to-5
new file mode 100755
index 000000000..d4b3f9a14
--- /dev/null
+++ b/src/migration-scripts/pptp/4-to-5
@@ -0,0 +1,66 @@
+#!/usr/bin/env python3
+#
+# Copyright (C) 2024 VyOS maintainers and contributors
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 or later as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+# - Move 'require' from 'protocols' in  'authentication' node
+# - Migrate to new default values in radius timeout and acct-timeout
+
+import os
+
+from sys import argv
+from sys import exit
+from vyos.configtree import ConfigTree
+
+
+if len(argv) < 2:
+    print("Must specify file name!")
+    exit(1)
+
+file_name = argv[1]
+
+with open(file_name, 'r') as f:
+    config_file = f.read()
+
+config = ConfigTree(config_file)
+base = ['vpn', 'pptp', 'remote-access']
+
+if not config.exists(base):
+    exit(0)
+
+#migrate require to protocols
+require_path = base + ['authentication', 'require']
+if config.exists(require_path):
+    protocols = list(config.return_values(require_path))
+    for protocol in protocols:
+        config.set(base + ['authentication', 'protocols'], value=protocol,
+                   replace=False)
+    config.delete(require_path)
+else:
+    config.set(base + ['authentication', 'protocols'], value='mschap-v2')
+
+radius_path = base + ['authentication', 'radius']
+if config.exists(radius_path):
+    if not config.exists(radius_path + ['timeout']):
+        config.set(radius_path + ['timeout'], value=3)
+    if not config.exists(radius_path + ['acct-timeout']):
+        config.set(radius_path + ['acct-timeout'], value=3)
+
+
+try:
+    with open(file_name, 'w') as f:
+        f.write(config.to_string())
+except OSError as e:
+    print("Failed to save the modified config: {}".format(e))
+    exit(1)