diff --git a/data/templates/firewall/upnpd.conf.j2 b/data/templates/firewall/upnpd.conf.j2
index e964fc696..616e8869f 100644
--- a/data/templates/firewall/upnpd.conf.j2
+++ b/data/templates/firewall/upnpd.conf.j2
@@ -1,175 +1,227 @@
 # This is the UPNP configuration file
 
 # WAN network interface
 ext_ifname={{ wan_interface }}
 {% if wan_ip is vyos_defined %}
+
+# if the WAN network interface for IPv6 is different than for IPv4,
+# set ext_ifname6
+#ext_ifname6=eth2
+
 # If the WAN interface has several IP addresses, you
-# can specify the one to use below
+# can specify the one to use below.
+# Setting ext_ip is also useful in double NAT setup, you can declare here
+# the public IP address.
 {%     for addr in wan_ip %}
 ext_ip={{ addr }}
 {%     endfor  %}
 {% endif %}
 
+{% if stun is vyos_defined %}
+# WAN interface must have public IP address. Otherwise it is behind NAT
+# and port forwarding is impossible. In some cases WAN interface can be
+# behind unrestricted full-cone NAT 1:1 when all incoming traffic is NAT-ed and
+# routed to WAN interfaces without any filtering. In this cases miniupnpd
+# needs to know public IP address and it can be learnt by asking external
+# server via STUN protocol. Following option enable retrieving external
+# public IP address from STUN server and detection of NAT type. You need
+# to specify also external STUN server in stun_host option below.
+# This option is disabled by default.
+ext_perform_stun=yes
+# Specify STUN server, either hostname or IP address
+# Some public STUN servers:
+#  stun.stunprotocol.org
+#  stun.sipgate.net
+#  stun.xten.com
+#  stun.l.google.com (on non standard port 19302)
+ext_stun_host={{ stun.host }}
+# Specify STUN UDP port, by default it is standard port 3478.
+ext_stun_port={{ stun.port }}
+{% endif %}
+
 # LAN network interfaces IPs / networks
 {% if listen is vyos_defined %}
 # There can be multiple listening IPs for SSDP traffic, in that case
 # use multiple 'listening_ip=...' lines, one for each network interface.
 # It can be IP address or network interface name (ie. "eth0")
 # It is mandatory to use the network interface name in order to enable IPv6
 # HTTP is available on all interfaces.
 # When MULTIPLE_EXTERNAL_IP is enabled, the external IP
 # address associated with the subnet follows. For example:
 #  listening_ip=192.168.0.1/24 88.22.44.13
+# When MULTIPLE_EXTERNAL_IP is disabled, you can list associated network
+# interfaces (for bridges)
+#  listening_ip=bridge0 em0 wlan0
 {%     for addr in listen %}
 {%         if addr | is_ipv4  %}
 listening_ip={{ addr }}
 {%         elif addr | is_ipv6  %}
 ipv6_listening_ip={{ addr }}
 {%         else %}
 listening_ip={{ addr }}
 {%         endif  %}
 {%     endfor  %}
 {% endif %}
 
 # CAUTION: mixing up WAN and LAN interfaces may introduce security risks!
 # Be sure to assign the correct interfaces to LAN and WAN and consider
 # implementing UPnP permission rules at the bottom of this configuration file
 
 # Port for HTTP (descriptions and SOAP) traffic. Set to 0 for autoselect.
 #http_port=0
 # Port for HTTPS. Set to 0 for autoselect (default)
 #https_port=0
 
 # Path to the UNIX socket used to communicate with MiniSSDPd
 # If running, MiniSSDPd will manage M-SEARCH answering.
 # default is /var/run/minissdpd.sock
 #minissdpdsocket=/var/run/minissdpd.sock
 
 {% if nat_pmp is vyos_defined %}
 # Enable NAT-PMP support (default is no)
 enable_natpmp=yes
 {% endif %}
 
 # Enable UPNP support (default is yes)
 enable_upnp=yes
 
 {% if pcp_lifetime is vyos_defined %}
 # PCP
 # Configure the minimum and maximum lifetime of a port mapping in seconds
 # 120s and 86400s (24h) are suggested values from PCP-base
 {%     if pcp_lifetime.max is vyos_defined %}
 max_lifetime={{ pcp_lifetime.max }}
 {%     endif %}
 {%     if pcp_lifetime.min is vyos_defined %}
 min_lifetime={{ pcp_lifetime.min }}
 {%     endif %}
 {% endif %}
 
+# table names for netfilter nft. Default is "filter" for both
+#upnp_table_name=
+#upnp_nat_table_name=
+# chain names for netfilter and netfilter nft
+# netfilter : default are MINIUPNPD, MINIUPNPD, MINIUPNPD-POSTROUTING
+# netfilter nft : default are miniupnpd, prerouting_miniupnpd, postrouting_miniupnpd
+#upnp_forward_chain=forwardUPnP
+#upnp_nat_chain=UPnP
+#upnp_nat_postrouting_chain=UPnP-Postrouting
+
+# Lease file location
+lease_file=/config/upnp.leases
 
 # To enable the next few runtime options, see compile time
 # ENABLE_MANUFACTURER_INFO_CONFIGURATION (config.h)
 
 {% if friendly_name is vyos_defined %}
 # Name of this service, default is "`uname -s` router"
 friendly_name={{ friendly_name }}
 {% endif  %}
 
 # Manufacturer name, default is "`uname -s`"
 manufacturer_name=VyOS
 
 # Manufacturer URL, default is URL of OS vendor
 manufacturer_url=https://vyos.io/
 
 # Model name, default is "`uname -s` router"
 model_name=VyOS Router Model
 
 # Model description, default is "`uname -s` router"
 model_description=Vyos open source enterprise router/firewall operating system
 
 # Model URL, default is URL of OS vendor
 model_url=https://vyos.io/
 
+# Bitrates reported by daemon in bits per second
+# by default miniupnpd tries to get WAN interface speed
+#bitrate_up=1000000
+#bitrate_down=10000000
+
 {% if secure_mode is vyos_defined %}
 # Secure Mode, UPnP clients can only add mappings to their own IP
 secure_mode=yes
 {% else %}
 # Secure Mode, UPnP clients can only add mappings to their own IP
 secure_mode=no
 {% endif %}
 
 {% if presentation_url is vyos_defined %}
 # Default presentation URL is HTTP address on port 80
 # If set to an empty string, no presentationURL element will appear
 # in the XML description of the device, which prevents MS Windows
 # from displaying an icon in the "Network Connections" panel.
 #presentation_url= {{ presentation_url }}
 {% endif %}
 
 # Report system uptime instead of daemon uptime
 system_uptime=yes
 
+# Notify interval in seconds. default is 30 seconds.
+#notify_interval=240
+notify_interval=60
+
 # Unused rules cleaning.
 # never remove any rule before this threshold for the number
 # of redirections is exceeded. default to 20
 clean_ruleset_threshold=10
 # Clean process work interval in seconds. default to 0 (disabled).
 # a 600 seconds (10 minutes) interval makes sense
 clean_ruleset_interval=600
 
+############################################################################
+## The next 5 config parameters (packet_log, anchor, queue, tag, quickrules)
+## are specific to BSD's pf(4) packet filter and hence cannot be enabled in
+## VyOS.
+# Log packets in pf (default is no)
+#packet_log=no
+
 # Anchor name in pf (default is miniupnpd)
-# Something wrong with this option "anchor", comment it out
-#   vyos@r14# miniupnpd -vv -f /run/upnp/miniupnp.conf
-#   invalid option in file /run/upnp/miniupnp.conf line 74 : anchor=VyOS
-#anchor=VyOS
+#anchor=miniupnpd
 
-uuid={{ uuid }}
+# ALTQ queue in pf
+# Filter rules must be used for this to be used.
+# compile with PF_ENABLE_FILTER_RULES (see config.h file)
+#queue=queue_name1
 
-# Lease file location
-lease_file=/config/upnp.leases
+# Tag name in pf
+#tag=tag_name1
+
+# Make filter rules in pf quick or not. default is yes
+# active when compiled with PF_ENABLE_FILTER_RULES (see config.h file)
+#quickrules=no
+##
+## End of pf(4)-specific configuration not to be set in VyOS.
+############################################################################
+
+# UUID, generate your own UUID with "make genuuid"
+uuid={{ uuid }}
 
 # Daemon's serial and model number when reporting to clients
 # (in XML description)
 #serial=12345678
 #model_number=1
 
+# If compiled with IGD_V2 defined, force reporting IGDv1 in rootDesc (default
+# is no)
+#force_igd_desc_v1=no
+
 {% if rule is vyos_defined %}
-# UPnP permission rules
-# (allow|deny) (external port range) IP/mask (internal port range)
+# UPnP permission rules (also enforced for NAT-PMP and PCP)
+# (allow|deny) (external port range) IP/mask (internal port range) (optional regex filter)
 # A port range is <min port>-<max port> or <port> if there is only
 # one port in the range.
 # IP/mask format must be nnn.nnn.nnn.nnn/nn
 # It is advised to only allow redirection of port >= 1024
 # and end the rule set with "deny 0-65535 0.0.0.0/0 0-65535"
 # The following default ruleset allows specific LAN side IP addresses
 # to request only ephemeral ports. It is recommended that users
 # modify the IP ranges to match their own internal networks, and
 # also consider implementing network-specific restrictions
 # CAUTION: failure to enforce any rules may permit insecure requests to be made!
 {%     for rule, config in rule.items() %}
 {%         if config.disable is not vyos_defined %}
 {{ config.action }} {{ config.external_port_range }} {{ config.ip }}{{ '/32' if '/' not in config.ip else '' }} {{ config.internal_port_range }}
 {%         endif %}
 {%     endfor %}
 {% endif %}
-
-{% if stun is vyos_defined %}
-# WAN interface must have public IP address. Otherwise it is behind NAT
-# and port forwarding is impossible. In some cases WAN interface can be
-# behind unrestricted NAT 1:1 when all incoming traffic is NAT-ed and
-# routed to WAN interfaces without any filtering. In this cases miniupnpd
-# needs to know public IP address and it can be learnt by asking external
-# server via STUN protocol. Following option enable retrieving external
-# public IP address from STUN server and detection of NAT type. You need
-# to specify also external STUN server in stun_host option below.
-# This option is disabled by default.
-ext_perform_stun=yes
-# Specify STUN server, either hostname or IP address
-# Some public STUN servers:
-#  stun.stunprotocol.org
-#  stun.sipgate.net
-#  stun.xten.com
-#  stun.l.google.com (on non standard port 19302)
-ext_stun_host={{ stun.host }}
-# Specify STUN UDP port, by default it is standard port 3478.
-ext_stun_port={{ stun.port }}
-{% endif %}
diff --git a/interface-definitions/service_upnp.xml.in b/interface-definitions/service_upnp.xml.in
index 20e01bfbd..064386ee5 100644
--- a/interface-definitions/service_upnp.xml.in
+++ b/interface-definitions/service_upnp.xml.in
@@ -1,228 +1,229 @@
 <?xml version="1.0"?>
 <interfaceDefinition>
   <node name="service">
     <children>
       <node name="upnp" owner="${vyos_conf_scripts_dir}/service_upnp.py">
         <properties>
           <help>Universal Plug and Play (UPnP) service</help>
           <priority>900</priority>
         </properties>
         <children>
           <leafNode name="friendly-name">
             <properties>
               <help>Name of this service</help>
               <valueHelp>
                 <format>txt</format>
                 <description>Friendly name</description>
               </valueHelp>
             </properties>
           </leafNode>
           <leafNode name="wan-interface">
             <properties>
               <help>WAN network interface</help>
               <completionHelp>
                 <script>${vyos_completion_dir}/list_interfaces</script>
               </completionHelp>
               <constraint>
                 #include <include/constraint/interface-name.xml.i>
               </constraint>
             </properties>
           </leafNode>
           <leafNode name="wan-ip">
             <properties>
               <help>WAN network IP</help>
               <valueHelp>
                 <format>ipv4</format>
                 <description>IPv4 address</description>
               </valueHelp>
               <valueHelp>
                 <format>ipv6</format>
                 <description>IPv6 address</description>
               </valueHelp>
               <constraint>
                 <validator name="ipv4-address" />
                 <validator name="ipv6-address" />
               </constraint>
               <multi/>
             </properties>
           </leafNode>
           <leafNode name="nat-pmp">
             <properties>
               <help>Enable NAT-PMP support</help>
               <valueless />
             </properties>
           </leafNode>
           <leafNode name="secure-mode">
             <properties>
               <help>Enable Secure Mode</help>
               <valueless />
             </properties>
           </leafNode>
           <leafNode name="presentation-url">
             <properties>
               <help>Presentation Url</help>
               <valueHelp>
                 <format>txt</format>
                 <description>Presentation Url</description>
               </valueHelp>
             </properties>
           </leafNode>
           <node name="pcp-lifetime">
             <properties>
               <help>PCP-base lifetime Option</help>
             </properties>
             <children>
               <leafNode name="max">
                 <properties>
                   <help>Max lifetime time</help>
                   <constraint>
                     <validator name="numeric" />
                   </constraint>
                 </properties>
               </leafNode>
               <leafNode name="min">
                 <properties>
                   <help>Min lifetime time</help>
                   <constraint>
                     <validator name="numeric" />
                   </constraint>
                 </properties>
               </leafNode>
             </children>
           </node>
           <leafNode name="listen">
             <properties>
               <help>Local IP addresses for service to listen on</help>
               <completionHelp>
                 <script>${vyos_completion_dir}/list_local_ips.sh --both</script>
                 <script>${vyos_completion_dir}/list_interfaces</script>
               </completionHelp>
               <valueHelp>
                 <format>&lt;interface&gt;</format>
                 <description>Monitor interface address</description>
               </valueHelp>
               <valueHelp>
                 <format>ipv4</format>
                 <description>IPv4 address to listen for incoming connections</description>
               </valueHelp>
               <valueHelp>
                 <format>ipv4net</format>
                 <description>IPv4 prefix to listen for incoming connections</description>
               </valueHelp>
               <valueHelp>
                 <format>ipv6</format>
                 <description>IPv6 address to listen for incoming connections</description>
               </valueHelp>
               <valueHelp>
                 <format>ipv6net</format>
                 <description>IPv6 prefix to listen for incoming connections</description>
               </valueHelp>
               <multi/>
               <constraint>
                 #include <include/constraint/interface-name.xml.i>
                 <validator name="ip-address"/>
                 <validator name="ipv4-prefix"/>
                 <validator name="ipv6-prefix"/>
               </constraint>
             </properties>
           </leafNode>
           <node name="stun">
             <properties>
               <help>Enable STUN probe support (can be used with NAT 1:1 support for WAN interfaces)</help>
             </properties>
             <children>
               <leafNode name="host">
                 <properties>
                   <help>The STUN server address</help>
                   <valueHelp>
                     <format>txt</format>
                     <description>The STUN server host address</description>
                   </valueHelp>
                   <constraint>
                     <validator name="fqdn"/>
                   </constraint>
                 </properties>
               </leafNode>
               #include <include/port-number.xml.i>
             </children>
           </node>
           <tagNode name="rule">
             <properties>
               <help>UPnP Rule</help>
               <valueHelp>
                 <format>u32:0-65535</format>
                 <description>Rule number</description>
               </valueHelp>
               <constraint>
                 <validator name="numeric" argument="--range 0-65535"/>
               </constraint>
             </properties>
             <children>
               #include <include/generic-disable-node.xml.i>
               <leafNode name="external-port-range">
                 <properties>
                   <help>Port range (REQUIRE)</help>
                   <valueHelp>
                     <format>&lt;port&gt;</format>
                     <description>single port</description>
                   </valueHelp>
                   <valueHelp>
                     <format>&lt;portN&gt;-&lt;portM&gt;</format>
                     <description>Port range (use '-' as delimiter)</description>
                   </valueHelp>
                   <constraint>
                     <validator name="port-range"/>
                   </constraint>
                 </properties>
               </leafNode>
               <leafNode name="internal-port-range">
                 <properties>
                   <help>Port range (REQUIRE)</help>
                   <valueHelp>
                     <format>&lt;port&gt;</format>
                     <description>single port</description>
                   </valueHelp>
                   <valueHelp>
                     <format>&lt;portN&gt;-&lt;portM&gt;</format>
                     <description>Port range (use '-' as delimiter)</description>
                   </valueHelp>
                   <constraint>
                     <validator name="port-range"/>
                   </constraint>
                 </properties>
               </leafNode>
               <leafNode name="ip">
                 <properties>
                   <help>The IP to which this rule applies (REQUIRE)</help>
                   <valueHelp>
                     <format>ipv4</format>
                     <description>The IPv4 address to which this rule applies</description>
                   </valueHelp>
                   <valueHelp>
                     <format>ipv4net</format>
                     <description>The IPv4 to which this rule applies</description>
                   </valueHelp>
                   <constraint>
                     <validator name="ipv4-address"/>
                     <validator name="ipv4-host"/>
+                    <validator name="ipv4-prefix"/>
                   </constraint>
                 </properties>
               </leafNode>
               <leafNode name="action">
                 <properties>
                   <help>Actions against the rule (REQUIRE)</help>
                   <completionHelp>
                     <list>allow deny</list>
                   </completionHelp>
                   <constraint>
                     <regex>(allow|deny)</regex>
                   </constraint>
                 </properties>
               </leafNode>
             </children>
           </tagNode>
         </children>
       </node>
     </children>
   </node>
 </interfaceDefinition>