diff --git a/data/templates/accel-ppp/pptp.config.tmpl b/data/templates/accel-ppp/pptp.config.tmpl
index 3cfc4a906..dcb1ddf08 100644
--- a/data/templates/accel-ppp/pptp.config.tmpl
+++ b/data/templates/accel-ppp/pptp.config.tmpl
@@ -1,98 +1,112 @@
 ### generated by accel_pptp.py ###
 [modules]
 log_syslog
 pptp
 shaper
 {% if auth_mode == 'local' %}
 chap-secrets
 {% elif auth_mode == 'radius' %}
 radius
 {% endif %}
 ippool
 {% for proto in auth_proto %}
 {{proto}}
 {% endfor %}
 
 [core]
 thread-count={{ thread_cnt }}
 
 [log]
 syslog=accel-pptp,daemon
 copy=1
 level=5
 
 {% if dnsv4 %}
 [dns]
 {% for dns in dnsv4 %}
 dns{{ loop.index }}={{ dns }}
 {% endfor %}
 {% endif %}
 
 {% if wins %}
 [wins]
 {% for server in wins %}
 wins{{ loop.index }}={{ server }}
 {% endfor %}
 {% endif %}
 
 
 [pptp]
 ifname=pptp%d
 {% if outside_addr %}
 bind={{ outside_addr }}
 {% endif %}
 verbose=1
 ppp-max-mtu={{mtu}}
 mppe={{ ppp_mppe }}
 echo-interval=10
 echo-failure=3
 
 
 [client-ip-range]
 0.0.0.0/0
 
 [ip-pool]
 tunnel={{ client_ip_pool }}
 gw-ip-address={{ gw_ip }}
 
 [ppp]
 verbose=5
 check-ip=1
 single-session=replace
 
 {% if auth_mode == 'local' %}
 [chap-secrets]
 chap-secrets={{ chap_secrets_file }}
 {% elif auth_mode == 'radius' %}
 [radius]
 verbose=1
 {% for r in radius_server %}
 server={{ r.server }},{{ r.key }},auth-port={{ r.port }},acct-port={{ r.acct_port }},req-limit=0,fail-time={{ r.fail_time }}
 {% endfor %}
 
 {% if radius_acct_inter_jitter %}
 acct-interim-jitter={{ radius_acct_inter_jitter }}
 {% endif %}
 
 acct-timeout={{ radius_acct_tmo }}
 timeout={{ radius_timeout }}
 max-try={{ radius_max_try }}
 
 {% if radius_nas_id %}
 nas-identifier={{ radius_nas_id }}
 {% endif %}
 {% if radius_nas_ip %}
 nas-ip-address={{ radius_nas_ip }}
 {% endif %}
 {% if radius_source_address %}
 bind={{ radius_source_address }}
 {% endif %}
 {% endif %}
 {# Both chap-secrets and radius block required the gw-ip-address #}
 {% if gw_ip is defined and gw_ip is not none %}
 gw-ip-address={{ gw_ip }}
 {% endif %}
 
+{% if radius_shaper_enable %}
+[shaper]
+verbose=1
+{%     if radius_shaper_attr %}
+attr={{ radius_shaper_attr }}
+{%     endif %}
+{%     if radius_shaper_multiplier %}
+rate-multiplier={{ radius_shaper_multiplier }}
+{%     endif %}
+{%     if radius_shaper_vendor %}
+vendor={{ radius_shaper_vendor }}
+{%     endif %}
+{% endif %}
+
 [cli]
 tcp=127.0.0.1:2003
 
diff --git a/interface-definitions/vpn_pptp.xml.in b/interface-definitions/vpn_pptp.xml.in
index 9b84a00c1..8c2f4cc94 100644
--- a/interface-definitions/vpn_pptp.xml.in
+++ b/interface-definitions/vpn_pptp.xml.in
@@ -1,120 +1,125 @@
 <?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>
         </properties>
         <children>
           <node name="remote-access">
             <properties>
               <help>Remote access PPTP VPN</help>
             </properties>
             <children>
               #include <include/accel-ppp/mtu-128-16384.xml.i>
               <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/name-server-ipv4.xml.i>
               #include <include/accel-ppp/wins-server.xml.i>
               <node name="client-ip-pool">
                 <properties>
                   <help>Pool of client IP addresses (must be within a /24)</help>
                 </properties>
                 <children>
                   #include <include/accel-ppp/client-ip-pool-start-stop.xml.i>
                 </children>
               </node>
               #include <include/accel-ppp/gateway-address.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>
                       <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>
                     </properties>
                   </leafNode>
                   <leafNode name="mppe">
                     <properties>
                       <help>Specifies mppe negotioation preference. (default require mppe 128-bit stateless</help>
                       <valueHelp>
                         <format>deny</format>
                         <description>deny mppe</description>
                       </valueHelp>
                       <valueHelp>
                         <format>prefer</format>
                         <description>ask client for mppe, if it rejects do not fail</description>
                       </valueHelp>
                       <valueHelp>
                         <format>require</format>
                         <description>ask client for mppe, if it rejects drop connection</description>
                       </valueHelp>
                       <constraint>
                         <regex>^(deny|prefer|require)$</regex>
                       </constraint>
                       <completionHelp>
                         <list>deny prefer require</list>
                       </completionHelp>
                     </properties>
                   </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>
                           </leafNode>
                         </children>
                       </tagNode>
                     </children>
                   </node>
+                  <node name="radius">
+                    <children>
+                      #include <include/accel-ppp/radius-additions-rate-limit.xml.i>
+                    </children>
+                  </node>
                   #include <include/radius-server-ipv4.xml.i>
                   #include <include/accel-ppp/radius-additions.xml.i>
                 </children>
               </node>
             </children>
           </node>
         </children>
       </node>
     </children>
   </node>
 </interfaceDefinition>
diff --git a/src/conf_mode/vpn_pptp.py b/src/conf_mode/vpn_pptp.py
index 30abe4782..9af82a309 100755
--- a/src/conf_mode/vpn_pptp.py
+++ b/src/conf_mode/vpn_pptp.py
@@ -1,296 +1,301 @@
 #!/usr/bin/env python3
 #
-# Copyright (C) 2018-2020 VyOS maintainers and contributors
+# Copyright (C) 2018-2023 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
 import re
 
 from copy import deepcopy
 from stat import S_IRUSR, S_IWUSR, S_IRGRP
 from sys import exit
 
 from vyos.config import Config
 from vyos.template import render
 from vyos.util import call, get_half_cpus
 from vyos import ConfigError
 
 from vyos import airbag
 airbag.enable()
 
 pptp_conf = '/run/accel-pppd/pptp.conf'
 pptp_chap_secrets = '/run/accel-pppd/pptp.chap-secrets'
 
 default_pptp = {
     'auth_mode' : 'local',
     'local_users' : [],
     'radius_server' : [],
     'radius_acct_inter_jitter': '',
     'radius_acct_tmo' : '30',
     'radius_max_try' : '3',
     'radius_timeout' : '30',
     'radius_nas_id' : '',
     'radius_nas_ip' : '',
     'radius_source_address' : '',
     'radius_shaper_attr' : '',
+    'radius_shaper_enable': False,
+    'radius_shaper_multiplier': '',
     'radius_shaper_vendor': '',
     'radius_dynamic_author' : '',
     'chap_secrets_file': pptp_chap_secrets, # used in Jinja2 template
     'outside_addr': '',
     'dnsv4': [],
     'wins': [],
     'client_ip_pool': '',
     'mtu': '1436',
     'auth_proto' : ['auth_mschap_v2'],
     'ppp_mppe' : 'prefer',
     'thread_cnt': get_half_cpus()
 }
 
 def get_config(config=None):
     if config:
         conf = config
     else:
         conf = Config()
     base_path = ['vpn', 'pptp', 'remote-access']
     if not conf.exists(base_path):
         return None
 
     pptp = deepcopy(default_pptp)
     conf.set_level(base_path)
 
     if conf.exists(['name-server']):
         pptp['dnsv4'] = conf.return_values(['name-server'])
 
     if conf.exists(['wins-server']):
         pptp['wins'] = conf.return_values(['wins-server'])
 
     if conf.exists(['outside-address']):
         pptp['outside_addr'] = conf.return_value(['outside-address'])
 
     if conf.exists(['authentication', 'mode']):
         pptp['auth_mode'] = conf.return_value(['authentication', 'mode'])
 
     #
     # local auth
     if conf.exists(['authentication', 'local-users']):
         for username in conf.list_nodes(['authentication', 'local-users', 'username']):
             user = {
                 'name': username,
                 'password' : '',
                 'state' : 'enabled',
                 'ip' : '*',
             }
 
             conf.set_level(base_path + ['authentication', 'local-users', 'username', username])
 
             if conf.exists(['password']):
                 user['password'] = conf.return_value(['password'])
 
             if conf.exists(['disable']):
                 user['state'] = 'disable'
 
             if conf.exists(['static-ip']):
                 user['ip'] = conf.return_value(['static-ip'])
 
             if not conf.exists(['disable']):
                 pptp['local_users'].append(user)
 
     #
     # RADIUS auth and settings
     conf.set_level(base_path + ['authentication', 'radius'])
     if conf.exists(['server']):
         for server in conf.list_nodes(['server']):
             radius = {
                 'server' : server,
                 'key' : '',
                 'fail_time' : 0,
                 'port' : '1812',
                 'acct_port' : '1813'
             }
 
             conf.set_level(base_path + ['authentication', 'radius', 'server', server])
 
             if conf.exists(['disable-accounting']):
                 radius['acct_port'] = '0'
 
             if conf.exists(['fail-time']):
                 radius['fail_time'] = conf.return_value(['fail-time'])
 
             if conf.exists(['port']):
                 radius['port'] = conf.return_value(['port'])
 
             if conf.exists(['acct-port']):
                 radius['acct_port'] = conf.return_value(['acct-port'])
 
             if conf.exists(['key']):
                 radius['key'] = conf.return_value(['key'])
 
             if not conf.exists(['disable']):
                 pptp['radius_server'].append(radius)
 
         #
         # advanced radius-setting
         conf.set_level(base_path + ['authentication', 'radius'])
 
         if conf.exists(['acct-interim-jitter']):
             pptp['radius_acct_inter_jitter'] = conf.return_value(['acct-interim-jitter'])
 
         if conf.exists(['acct-timeout']):
             pptp['radius_acct_tmo'] = conf.return_value(['acct-timeout'])
 
         if conf.exists(['max-try']):
             pptp['radius_max_try'] = conf.return_value(['max-try'])
 
         if conf.exists(['timeout']):
             pptp['radius_timeout'] = conf.return_value(['timeout'])
 
         if conf.exists(['nas-identifier']):
             pptp['radius_nas_id'] = conf.return_value(['nas-identifier'])
 
         if conf.exists(['nas-ip-address']):
             pptp['radius_nas_ip'] = conf.return_value(['nas-ip-address'])
 
         if conf.exists(['source-address']):
             pptp['radius_source_address'] = conf.return_value(['source-address'])
 
         # Dynamic Authorization Extensions (DOA)/Change Of Authentication (COA)
         if conf.exists(['dae-server']):
             dae = {
                 'port' : '',
                 'server' : '',
                 'key' : ''
             }
 
             if conf.exists(['dynamic-author', 'ip-address']):
                 dae['server'] = conf.return_value(['dynamic-author', 'ip-address'])
 
             if conf.exists(['dynamic-author', 'port']):
                 dae['port'] = conf.return_value(['dynamic-author', 'port'])
 
             if conf.exists(['dynamic-author', 'key']):
                 dae['key'] = conf.return_value(['dynamic-author', 'key'])
 
             pptp['radius_dynamic_author'] = dae
 
+        # Rate limit
+        if conf.exists(['rate-limit', 'attribute']):
+            pptp['radius_shaper_attr'] = conf.return_value(['rate-limit', 'attribute'])
+
         if conf.exists(['rate-limit', 'enable']):
-            pptp['radius_shaper_attr'] = 'Filter-Id'
-            c_attr = ['rate-limit', 'enable', 'attribute']
-            if conf.exists(c_attr):
-                pptp['radius_shaper_attr'] = conf.return_value(c_attr)
-
-            c_vendor = ['rate-limit', 'enable', 'vendor']
-            if conf.exists(c_vendor):
-                pptp['radius_shaper_vendor'] = conf.return_value(c_vendor)
+            pptp['radius_shaper_enable'] = True
+
+        if conf.exists(['rate-limit', 'multiplier']):
+            pptp['radius_shaper_multiplier'] = conf.return_value(['rate-limit', 'multiplier'])
+
+        if conf.exists(['rate-limit', 'vendor']):
+            pptp['radius_shaper_vendor'] = conf.return_value(['rate-limit', 'vendor'])
 
     conf.set_level(base_path)
     if conf.exists(['client-ip-pool']):
         if conf.exists(['client-ip-pool', 'start']) and conf.exists(['client-ip-pool', 'stop']):
             start = conf.return_value(['client-ip-pool', 'start'])
             stop  = conf.return_value(['client-ip-pool', 'stop'])
             pptp['client_ip_pool'] = start + '-' + re.search('[0-9]+$', stop).group(0)
 
     if conf.exists(['mtu']):
         pptp['mtu'] = conf.return_value(['mtu'])
 
     # gateway address
     if conf.exists(['gateway-address']):
         pptp['gw_ip'] = conf.return_value(['gateway-address'])
     else:
         # calculate gw-ip-address
         if conf.exists(['client-ip-pool', 'start']):
             # use start ip as gw-ip-address
             pptp['gateway_address'] = conf.return_value(['client-ip-pool', 'start'])
 
     if conf.exists(['authentication', 'require']):
         # clear default list content, now populate with actual CLI values
         pptp['auth_proto'] = []
         auth_mods = {
             'pap': 'auth_pap',
             'chap': 'auth_chap_md5',
             'mschap': 'auth_mschap_v1',
             'mschap-v2': 'auth_mschap_v2'
         }
 
         for proto in conf.return_values(['authentication', 'require']):
             pptp['auth_proto'].append(auth_mods[proto])
 
     if conf.exists(['authentication', 'mppe']):
         pptp['ppp_mppe'] = conf.return_value(['authentication', 'mppe'])
 
     return pptp
 
 
 def verify(pptp):
     if not pptp:
         return None
 
     if pptp['auth_mode'] == 'local':
         if not pptp['local_users']:
             raise ConfigError('PPTP local auth mode requires local users to be configured!')
 
         for user in pptp['local_users']:
             username = user['name']
             if not user['password']:
                 raise ConfigError(f'Password required for local user "{username}"')
 
     elif pptp['auth_mode'] == 'radius':
         if len(pptp['radius_server']) == 0:
             raise ConfigError('RADIUS authentication requires at least one server')
 
         for radius in pptp['radius_server']:
             if not radius['key']:
                 server = radius['server']
                 raise ConfigError(f'Missing RADIUS secret key for server "{ server }"')
 
     if len(pptp['dnsv4']) > 2:
         raise ConfigError('Not more then two IPv4 DNS name-servers can be configured')
 
     if len(pptp['wins']) > 2:
         raise ConfigError('Not more then two IPv4 WINS name-servers can be configured')
 
 
 def generate(pptp):
     if not pptp:
         return None
 
     render(pptp_conf, 'accel-ppp/pptp.config.tmpl', pptp)
 
     if pptp['local_users']:
         render(pptp_chap_secrets, 'accel-ppp/chap-secrets.tmpl', pptp)
         os.chmod(pptp_chap_secrets, S_IRUSR | S_IWUSR | S_IRGRP)
     else:
         if os.path.exists(pptp_chap_secrets):
              os.unlink(pptp_chap_secrets)
 
 
 def apply(pptp):
     if not pptp:
         call('systemctl stop accel-ppp@pptp.service')
         for file in [pptp_conf, pptp_chap_secrets]:
             if os.path.exists(file):
                 os.unlink(file)
 
         return None
 
     call('systemctl restart accel-ppp@pptp.service')
 
 if __name__ == '__main__':
     try:
         c = get_config()
         verify(c)
         generate(c)
         apply(c)
     except ConfigError as e:
         print(e)
         exit(1)