diff --git a/lib/puppet/provider/firewall/firewall.rb b/lib/puppet/provider/firewall/firewall.rb
index dc41b3eb7..f4fa2b31c 100644
--- a/lib/puppet/provider/firewall/firewall.rb
+++ b/lib/puppet/provider/firewall/firewall.rb
@@ -74,6 +74,7 @@ class Puppet::Provider::Firewall::Firewall
     ipsec_dir: '--dir',
     ipsec_policy: '--pol',
     state: '--state',
+    ctmask: '--ctmask',
     ctstate: '--ctstate',
     ctproto: '--ctproto',
     ctorigsrc: '--ctorigsrc',
@@ -122,6 +123,7 @@ class Puppet::Provider::Firewall::Firewall
     nflog_range: '--nflog-range',
     nflog_size: '--nflog-size',
     nflog_threshold: '--nflog-threshold',
+    nfmask: '--nfmask',
     gateway: '--gateway',
     clamp_mss_to_pmtu: '--clamp-mss-to-pmtu',
     set_mss: '--set-mss',
@@ -141,6 +143,7 @@ class Puppet::Provider::Firewall::Firewall
     log_tcp_options: '--log-tcp-options',
     log_ip_options: '--log-ip-options',
     reject: '--reject-with',
+    restore_mark: '--restore-mark',
     set_mark: '--set-xmark',
     match_mark: '-m mark --mark',
     mss: '-m tcpmss --mss',
@@ -186,7 +189,7 @@ class Puppet::Provider::Firewall::Firewall
     :checksum_fill, :clamp_mss_to_pmtu, :isfragment, :ishasmorefrags, :islastfrag, :isfirstfrag,
     :log_uid, :log_tcp_sequence, :log_tcp_options, :log_ip_options, :random_fully, :random,
     :rdest, :reap, :rsource, :rttl, :socket, :physdev_is_bridged, :physdev_is_in, :physdev_is_out,
-    :time_contiguous, :kernel_timezone, :clusterip_new, :queue_bypass, :ipvs, :notrack
+    :time_contiguous, :kernel_timezone, :clusterip_new, :queue_bypass, :ipvs, :notrack, :restore_mark
   ]
 
   # Properties that use "-m <ipt module name>" (with the potential to have multiple
@@ -245,7 +248,7 @@ class Puppet::Provider::Firewall::Firewall
     :clusterip_clustermac, :clusterip_total_nodes, :clusterip_local_node, :clusterip_hash_init, :queue_num, :queue_bypass,
     :nflog_group, :nflog_prefix, :nflog_range, :nflog_size, :nflog_threshold, :clamp_mss_to_pmtu, :gateway,
     :set_mss, :set_dscp, :set_dscp_class, :todest, :tosource, :toports, :to, :checksum_fill, :random_fully, :random, :log_prefix,
-    :log_level, :log_uid, :log_tcp_sequence, :log_tcp_options, :log_ip_options, :reject, :set_mark, :match_mark, :mss,
+    :log_level, :log_uid, :log_tcp_sequence, :log_tcp_options, :log_ip_options, :reject, :set_mark, :match_mark, :restore_mark, :nfmask, :ctmask, :mss,
     :connlimit_upto, :connlimit_above, :connlimit_mask, :connmark,
     :time_start, :time_stop, :month_days, :week_days, :date_start, :date_stop, :time_contiguous, :kernel_timezone,
     :u32, :src_cc, :dst_cc, :hashlimit_upto, :hashlimit_above, :hashlimit_name, :hashlimit_burst,
diff --git a/lib/puppet/provider/firewallchain/firewallchain.rb b/lib/puppet/provider/firewallchain/firewallchain.rb
index 4670ae2d4..a889794fc 100644
--- a/lib/puppet/provider/firewallchain/firewallchain.rb
+++ b/lib/puppet/provider/firewallchain/firewallchain.rb
@@ -47,6 +47,40 @@ class Puppet::Provider::Firewallchain::Firewallchain
   def get(_context)
     # Create empty return array
     chains = []
+    # Built-in chains are not always visible in iptables-save, but they are still there.
+    # Add them to the chains if they aren't found by iptables-save.
+    built_in_chains = []
+    [
+      # filter table
+      "FORWARD:filter",
+      "INPUT:filter",
+      "OUTPUT:filter",
+      # mangle table
+      "FORWARD:mangle",
+      "INPUT:mangle",
+      "OUTPUT:mangle",
+      "POSTROUTING:mangle",
+      "PREROUTING:mangle",
+      # nat table
+      "INPUT:nat",
+      "OUTPUT:nat",
+      "POSTROUTING:nat",
+      "PREROUTING:nat",
+      # raw table
+      "OUTPUT:raw",
+      "PREROUTING:raw"
+    ].each do | chain_table |
+      ['IPv4', 'IPv6'].each do |protocol|
+          name = "#{chain_table}:#{protocol}"
+          chain_hash = {
+            name: name,
+            purge: false,
+            ignore_foreign: false,
+            ensure: 'present'
+          }
+          built_in_chains << chain_hash
+      end
+    end
     # Scan String to retrieve all Chains and Policies
     ['IPv4', 'IPv6'].each do |protocol|
       # Retrieve String containing all IPv4 information
@@ -67,7 +101,13 @@ def get(_context)
         end
       end
     end
-    # Return array
+    # Add built_in_chains to chains only if they haven't already been found
+    built_in_chains.each do |built_in_chain|
+      unless chains.any? { |chain| chain[:name] == built_in_chain[:name] }
+        chains << built_in_chain
+      end
+    end
+
     chains
   end
 
diff --git a/lib/puppet/type/firewall.rb b/lib/puppet/type/firewall.rb
index 066db2f05..fa3cbba64 100644
--- a/lib/puppet/type/firewall.rb
+++ b/lib/puppet/type/firewall.rb
@@ -593,6 +593,18 @@
         In order to maintain compatibility it is also possible to negate all values given in the array to achieve the same behaviour.
       DESC
     },
+    ctmask: {
+      type: 'Optional[String]',
+      desc: <<-DESC
+      ctmask
+      DESC
+    },
+    nfmask: {
+      type: 'Optional[String]',
+      desc: <<-DESC
+      nfmask
+      DESC
+    },
     ctstate: {
       type: 'Optional[Variant[Pattern[/^(?:!\s)?(?:INVALID|ESTABLISHED|NEW|RELATED|UNTRACKED|SNAT|DNAT)$/], Array[Pattern[/^(?:!\s)?(?:INVALID|ESTABLISHED|NEW|RELATED|UNTRACKED|SNAT|DNAT)$/]]]]',
       desc: <<-DESC
@@ -1270,6 +1282,12 @@
       IPv6 allows: icmp6-no-route, no-route, icmp6-adm-prohibited, adm-prohibited, icmp6-addr-unreachable, addr-unreach, or icmp6-port-unreachable.
       DESC
     },
+    restore_mark: {
+      type: 'Optional[Boolean]',
+      desc: <<-DESC
+      Whether or not to restore mark.
+      DESC
+    },
     set_mark: {
       type: 'Optional[Pattern[/^[a-fA-F0-9x]+(?:\/[a-fA-F0-9x]+)?$/]]',
       desc: <<-DESC