@protocol = "IPv6"
@resource_map = {
- :burst => "--limit-burst",
- :checksum_fill => "--checksum-fill",
- :clamp_mss_to_pmtu => "--clamp-mss-to-pmtu",
- :connlimit_above => "-m connlimit --connlimit-above",
- :connlimit_mask => "--connlimit-mask",
- :connmark => "-m connmark --mark",
- :ctstate => "-m conntrack --ctstate",
- :destination => "-d",
- :dport => ["-m multiport --dports", "--dport"],
- :dst_range => '--dst-range',
- :dst_type => "--dst-type",
- :gateway => "--gateway",
- :gid => "--gid-owner",
- :hop_limit => "-m hl --hl-eq",
- :icmp => "-m icmp6 --icmpv6-type",
- :iniface => "-i",
- :ipsec_dir => "-m policy --dir",
- :ipsec_policy => "--pol",
- :ipset => "-m set --match-set",
- :isfirstfrag => "-m frag --fragid 0 --fragfirst",
- :ishasmorefrags => "-m frag --fragid 0 --fragmore",
- :islastfrag => "-m frag --fragid 0 --fraglast",
- :jump => "-j",
- :length => "-m length --length",
- :limit => "-m limit --limit",
- :log_level => "--log-level",
- :log_prefix => "--log-prefix",
- :log_uid => "--log-uid",
- :mask => "--mask",
- :match_mark => "-m mark --mark",
- :name => "-m comment --comment",
- :mac_source => ["-m mac --mac-source", "--mac-source"],
- :mss => "-m tcpmss --mss",
- :outiface => "-o",
- :pkttype => "-m pkttype --pkt-type",
- :port => '-m multiport --ports',
- :proto => "-p",
- :queue_num => "--queue-num",
- :queue_bypass => "--queue-bypass",
- :rdest => "--rdest",
- :reap => "--reap",
- :recent => "-m recent",
- :reject => "--reject-with",
- :rhitcount => "--hitcount",
- :rname => "--name",
- :rseconds => "--seconds",
- :rsource => "--rsource",
- :rttl => "--rttl",
- :set_dscp => '--set-dscp',
- :set_dscp_class => '--set-dscp-class',
- :set_mark => mark_flag,
- :set_mss => '--set-mss',
- :socket => "-m socket",
- :source => "-s",
- :sport => ["-m multiport --sports", "--sport"],
- :src_range => '--src-range',
- :src_type => "--src-type",
- :stat_every => '--every',
- :stat_mode => "-m statistic --mode",
- :stat_packet => '--packet',
- :stat_probability => '--probability',
- :state => "-m state --state",
- :string => "-m string --string",
- :string_algo => "--algo",
- :string_from => "--from",
- :string_to => "--to",
- :table => "-t",
- :tcp_flags => "-m tcp --tcp-flags",
- :todest => "--to-destination",
- :toports => "--to-ports",
- :tosource => "--to-source",
- :uid => "--uid-owner",
- :physdev_in => "--physdev-in",
- :physdev_out => "--physdev-out",
- :physdev_is_bridged => "--physdev-is-bridged",
- :physdev_is_in => "--physdev-is-in",
- :physdev_is_out => "--physdev-is-out",
- :date_start => "--datestart",
- :date_stop => "--datestop",
- :time_start => "--timestart",
- :time_stop => "--timestop",
- :month_days => "--monthdays",
- :week_days => "--weekdays",
- :time_contiguous => "--contiguous",
- :kernel_timezone => "--kerneltz",
- :src_cc => "--source-country",
- :dst_cc => "--destination-country",
+ :burst => "--limit-burst",
+ :checksum_fill => "--checksum-fill",
+ :clamp_mss_to_pmtu => "--clamp-mss-to-pmtu",
+ :connlimit_above => "-m connlimit --connlimit-above",
+ :connlimit_mask => "--connlimit-mask",
+ :connmark => "-m connmark --mark",
+ :ctstate => "-m conntrack --ctstate",
+ :destination => "-d",
+ :dport => ["-m multiport --dports", "--dport"],
+ :dst_range => '--dst-range',
+ :dst_type => "--dst-type",
+ :gateway => "--gateway",
+ :gid => "--gid-owner",
+ :hop_limit => "-m hl --hl-eq",
+ :icmp => "-m icmp6 --icmpv6-type",
+ :iniface => "-i",
+ :ipsec_dir => "-m policy --dir",
+ :ipsec_policy => "--pol",
+ :ipset => "-m set --match-set",
+ :isfirstfrag => "-m frag --fragid 0 --fragfirst",
+ :ishasmorefrags => "-m frag --fragid 0 --fragmore",
+ :islastfrag => "-m frag --fragid 0 --fraglast",
+ :jump => "-j",
+ :length => "-m length --length",
+ :limit => "-m limit --limit",
+ :log_level => "--log-level",
+ :log_prefix => "--log-prefix",
+ :log_uid => "--log-uid",
+ :mask => "--mask",
+ :match_mark => "-m mark --mark",
+ :name => "-m comment --comment",
+ :mac_source => ["-m mac --mac-source", "--mac-source"],
+ :mss => "-m tcpmss --mss",
+ :outiface => "-o",
+ :pkttype => "-m pkttype --pkt-type",
+ :port => '-m multiport --ports',
+ :proto => "-p",
+ :queue_num => "--queue-num",
+ :queue_bypass => "--queue-bypass",
+ :rdest => "--rdest",
+ :reap => "--reap",
+ :recent => "-m recent",
+ :reject => "--reject-with",
+ :rhitcount => "--hitcount",
+ :rname => "--name",
+ :rseconds => "--seconds",
+ :rsource => "--rsource",
+ :rttl => "--rttl",
+ :set_dscp => '--set-dscp',
+ :set_dscp_class => '--set-dscp-class',
+ :set_mark => mark_flag,
+ :set_mss => '--set-mss',
+ :socket => "-m socket",
+ :source => "-s",
+ :sport => ["-m multiport --sports", "--sport"],
+ :src_range => '--src-range',
+ :src_type => "--src-type",
+ :stat_every => '--every',
+ :stat_mode => "-m statistic --mode",
+ :stat_packet => '--packet',
+ :stat_probability => '--probability',
+ :state => "-m state --state",
+ :string => "-m string --string",
+ :string_algo => "--algo",
+ :string_from => "--from",
+ :string_to => "--to",
+ :table => "-t",
+ :tcp_flags => "-m tcp --tcp-flags",
+ :todest => "--to-destination",
+ :toports => "--to-ports",
+ :tosource => "--to-source",
+ :uid => "--uid-owner",
+ :physdev_in => "--physdev-in",
+ :physdev_out => "--physdev-out",
+ :physdev_is_bridged => "--physdev-is-bridged",
+ :physdev_is_in => "--physdev-is-in",
+ :physdev_is_out => "--physdev-is-out",
+ :date_start => "--datestart",
+ :date_stop => "--datestop",
+ :time_start => "--timestart",
+ :time_stop => "--timestop",
+ :month_days => "--monthdays",
+ :week_days => "--weekdays",
+ :time_contiguous => "--contiguous",
+ :kernel_timezone => "--kerneltz",
+ :src_cc => "--source-country",
+ :dst_cc => "--destination-country",
+ :hashlimit_name => "--hashlimit-name",
+ :hashlimit_upto => "--hashlimit-upto",
+ :hashlimit_above => "--hashlimit-above",
+ :hashlimit_burst => "--hashlimit-burst",
+ :hashlimit_mode => "--hashlimit-mode",
+ :hashlimit_srcmask => "--hashlimit-srcmask",
+ :hashlimit_dstmask => "--hashlimit-dstmask",
+ :hashlimit_htable_size => "--hashlimit-htable-size",
+ :hashlimit_htable_max => "--hashlimit-htable-max",
+ :hashlimit_htable_expire => "--hashlimit-htable-expire",
+ :hashlimit_htable_gcinterval => "--hashlimit-htable-gcinterval",
+
}
# These are known booleans that do not take a value, but we want to munge
:iprange => [:src_range, :dst_range],
:owner => [:uid, :gid],
:time => [:time_start, :time_stop, :month_days, :week_days, :date_start, :date_stop, :time_contiguous, :kernel_timezone],
- :geoip => [:src_cc, :dst_cc]
+ :geoip => [:src_cc, :dst_cc],
+ :hashlimit => [:hashlimit_upto, :hashlimit_above, :hashlimit_name, :hashlimit_burst, :hashlimit_mode, :hashlimit_srcmask, :hashlimit_dstmask,
+ :hashlimit_htable_size, :hashlimit_htable_max, :hashlimit_htable_expire, :hashlimit_htable_gcinterval],
+
}
# Create property methods dynamically
:string_from, :string_to, :jump, :clamp_mss_to_pmtu, :gateway, :todest,
:tosource, :toports, :checksum_fill, :log_level, :log_prefix, :log_uid, :reject, :set_mss, :set_dscp, :set_dscp_class, :mss, :queue_num, :queue_bypass,
:set_mark, :match_mark, :connlimit_above, :connlimit_mask, :connmark, :time_start, :time_stop, :month_days, :week_days, :date_start, :date_stop, :time_contiguous, :kernel_timezone,
- :src_cc, :dst_cc, :name]
+ :src_cc, :dst_cc, :hashlimit_upto, :hashlimit_above, :hashlimit_name, :hashlimit_burst,
+ :hashlimit_mode, :hashlimit_srcmask, :hashlimit_dstmask, :hashlimit_htable_size,
+ :hashlimit_htable_max, :hashlimit_htable_expire, :hashlimit_htable_gcinterval, :name]
end
@protocol = "IPv4"
@resource_map = {
- :burst => "--limit-burst",
- :checksum_fill => "--checksum-fill",
- :clamp_mss_to_pmtu => "--clamp-mss-to-pmtu",
- :connlimit_above => "-m connlimit --connlimit-above",
- :connlimit_mask => "--connlimit-mask",
- :connmark => "-m connmark --mark",
- :ctstate => "-m conntrack --ctstate",
- :destination => "-d",
- :dport => ["-m multiport --dports", "--dport"],
- :dst_range => "--dst-range",
- :dst_type => "--dst-type",
- :gateway => "--gateway",
- :gid => "--gid-owner",
- :icmp => "-m icmp --icmp-type",
- :iniface => "-i",
- :ipsec_dir => "-m policy --dir",
- :ipsec_policy => "--pol",
- :ipset => "-m set --match-set",
- :isfragment => "-f",
- :jump => "-j",
- :goto => "-g",
- :length => "-m length --length",
- :limit => "-m limit --limit",
- :log_level => "--log-level",
- :log_prefix => "--log-prefix",
- :log_uid => "--log-uid",
- :mac_source => ["-m mac --mac-source", "--mac-source"],
- :mask => '--mask',
- :match_mark => "-m mark --mark",
- :mss => '-m tcpmss --mss',
- :name => "-m comment --comment",
- :nflog_group => "--nflog-group",
- :nflog_prefix => "--nflog-prefix",
- :nflog_range => "--nflog-range",
- :nflog_threshold => "--nflog-threshold",
- :outiface => "-o",
- :pkttype => "-m pkttype --pkt-type",
- :port => '-m multiport --ports',
- :proto => "-p",
- :queue_num => "--queue-num",
- :queue_bypass => "--queue-bypass",
- :random => "--random",
- :rdest => "--rdest",
- :reap => "--reap",
- :recent => "-m recent",
- :reject => "--reject-with",
- :rhitcount => "--hitcount",
- :rname => "--name",
- :rseconds => "--seconds",
- :rsource => "--rsource",
- :rttl => "--rttl",
- :set_dscp => '--set-dscp',
- :set_dscp_class => '--set-dscp-class',
- :set_mark => mark_flag,
- :set_mss => '--set-mss',
- :socket => "-m socket",
- :source => "-s",
- :sport => ["-m multiport --sports", "--sport"],
- :src_range => "--src-range",
- :src_type => "--src-type",
- :stat_every => '--every',
- :stat_mode => "-m statistic --mode",
- :stat_packet => '--packet',
- :stat_probability => '--probability',
- :state => "-m state --state",
- :string => "-m string --string",
- :string_algo => "--algo",
- :string_from => "--from",
- :string_to => "--to",
- :table => "-t",
- :tcp_flags => "-m tcp --tcp-flags",
- :todest => "--to-destination",
- :toports => "--to-ports",
- :tosource => "--to-source",
- :to => "--to",
- :uid => "--uid-owner",
- :physdev_in => "--physdev-in",
- :physdev_out => "--physdev-out",
- :physdev_is_bridged => "--physdev-is-bridged",
- :physdev_is_in => "--physdev-is-in",
- :physdev_is_out => "--physdev-is-out",
- :date_start => "--datestart",
- :date_stop => "--datestop",
- :time_start => "--timestart",
- :time_stop => "--timestop",
- :month_days => "--monthdays",
- :week_days => "--weekdays",
- :time_contiguous => "--contiguous",
- :kernel_timezone => "--kerneltz",
- :clusterip_new => "--new",
- :clusterip_hashmode => "--hashmode",
- :clusterip_clustermac => "--clustermac",
- :clusterip_total_nodes => "--total-nodes",
- :clusterip_local_node => "--local-node",
- :clusterip_hash_init => "--hash-init",
- :src_cc => "--source-country",
- :dst_cc => "--destination-country",
+ :burst => "--limit-burst",
+ :checksum_fill => "--checksum-fill",
+ :clamp_mss_to_pmtu => "--clamp-mss-to-pmtu",
+ :connlimit_above => "-m connlimit --connlimit-above",
+ :connlimit_mask => "--connlimit-mask",
+ :connmark => "-m connmark --mark",
+ :ctstate => "-m conntrack --ctstate",
+ :destination => "-d",
+ :dport => ["-m multiport --dports", "--dport"],
+ :dst_range => "--dst-range",
+ :dst_type => "--dst-type",
+ :gateway => "--gateway",
+ :gid => "--gid-owner",
+ :icmp => "-m icmp --icmp-type",
+ :iniface => "-i",
+ :ipsec_dir => "-m policy --dir",
+ :ipsec_policy => "--pol",
+ :ipset => "-m set --match-set",
+ :isfragment => "-f",
+ :jump => "-j",
+ :goto => "-g",
+ :length => "-m length --length",
+ :limit => "-m limit --limit",
+ :log_level => "--log-level",
+ :log_prefix => "--log-prefix",
+ :log_uid => "--log-uid",
+ :mac_source => ["-m mac --mac-source", "--mac-source"],
+ :mask => '--mask',
+ :match_mark => "-m mark --mark",
+ :mss => '-m tcpmss --mss',
+ :name => "-m comment --comment",
+ :nflog_group => "--nflog-group",
+ :nflog_prefix => "--nflog-prefix",
+ :nflog_range => "--nflog-range",
+ :nflog_threshold => "--nflog-threshold",
+ :outiface => "-o",
+ :pkttype => "-m pkttype --pkt-type",
+ :port => '-m multiport --ports',
+ :proto => "-p",
+ :queue_num => "--queue-num",
+ :queue_bypass => "--queue-bypass",
+ :random => "--random",
+ :rdest => "--rdest",
+ :reap => "--reap",
+ :recent => "-m recent",
+ :reject => "--reject-with",
+ :rhitcount => "--hitcount",
+ :rname => "--name",
+ :rseconds => "--seconds",
+ :rsource => "--rsource",
+ :rttl => "--rttl",
+ :set_dscp => '--set-dscp',
+ :set_dscp_class => '--set-dscp-class',
+ :set_mark => mark_flag,
+ :set_mss => '--set-mss',
+ :socket => "-m socket",
+ :source => "-s",
+ :sport => ["-m multiport --sports", "--sport"],
+ :src_range => "--src-range",
+ :src_type => "--src-type",
+ :stat_every => '--every',
+ :stat_mode => "-m statistic --mode",
+ :stat_packet => '--packet',
+ :stat_probability => '--probability',
+ :state => "-m state --state",
+ :string => "-m string --string",
+ :string_algo => "--algo",
+ :string_from => "--from",
+ :string_to => "--to",
+ :table => "-t",
+ :tcp_flags => "-m tcp --tcp-flags",
+ :todest => "--to-destination",
+ :toports => "--to-ports",
+ :tosource => "--to-source",
+ :to => "--to",
+ :uid => "--uid-owner",
+ :physdev_in => "--physdev-in",
+ :physdev_out => "--physdev-out",
+ :physdev_is_bridged => "--physdev-is-bridged",
+ :physdev_is_in => "--physdev-is-in",
+ :physdev_is_out => "--physdev-is-out",
+ :date_start => "--datestart",
+ :date_stop => "--datestop",
+ :time_start => "--timestart",
+ :time_stop => "--timestop",
+ :month_days => "--monthdays",
+ :week_days => "--weekdays",
+ :time_contiguous => "--contiguous",
+ :kernel_timezone => "--kerneltz",
+ :clusterip_new => "--new",
+ :clusterip_hashmode => "--hashmode",
+ :clusterip_clustermac => "--clustermac",
+ :clusterip_total_nodes => "--total-nodes",
+ :clusterip_local_node => "--local-node",
+ :clusterip_hash_init => "--hash-init",
+ :src_cc => "--source-country",
+ :dst_cc => "--destination-country",
+ :hashlimit_name => "--hashlimit-name",
+ :hashlimit_upto => "--hashlimit-upto",
+ :hashlimit_above => "--hashlimit-above",
+ :hashlimit_burst => "--hashlimit-burst",
+ :hashlimit_mode => "--hashlimit-mode",
+ :hashlimit_srcmask => "--hashlimit-srcmask",
+ :hashlimit_dstmask => "--hashlimit-dstmask",
+ :hashlimit_htable_size => "--hashlimit-htable-size",
+ :hashlimit_htable_max => "--hashlimit-htable-max",
+ :hashlimit_htable_expire => "--hashlimit-htable-expire",
+ :hashlimit_htable_gcinterval => "--hashlimit-htable-gcinterval",
}
# These are known booleans that do not take a value, but we want to munge
:iprange => [:src_range, :dst_range],
:owner => [:uid, :gid],
:time => [:time_start, :time_stop, :month_days, :week_days, :date_start, :date_stop, :time_contiguous, :kernel_timezone],
- :geoip => [:src_cc, :dst_cc]
+ :geoip => [:src_cc, :dst_cc],
+ :hashlimit => [:hashlimit_upto, :hashlimit_above, :hashlimit_name, :hashlimit_burst, :hashlimit_mode, :hashlimit_srcmask, :hashlimit_dstmask,
+ :hashlimit_htable_size, :hashlimit_htable_max, :hashlimit_htable_expire, :hashlimit_htable_gcinterval],
}
def self.munge_resource_map_from_existing_values(resource_map_original, compare)
:set_mss, :set_dscp, :set_dscp_class, :todest, :tosource, :toports, :to, :checksum_fill, :random, :log_prefix,
:log_level, :log_uid, :reject, :set_mark, :match_mark, :mss, :connlimit_above, :connlimit_mask, :connmark, :time_start, :time_stop,
:month_days, :week_days, :date_start, :date_stop, :time_contiguous, :kernel_timezone,
- :src_cc, :dst_cc, :name]
+ :src_cc, :dst_cc, :hashlimit_upto, :hashlimit_above, :hashlimit_name, :hashlimit_burst,
+ :hashlimit_mode, :hashlimit_srcmask, :hashlimit_dstmask, :hashlimit_htable_size,
+ :hashlimit_htable_max, :hashlimit_htable_expire, :hashlimit_htable_gcinterval, :name]
def insert
debug 'Inserting rule %s' % resource[:name]
feature :string_matching, "String matching features"
feature :queue_num, "Which NFQUEUE to send packets to"
feature :queue_bypass, "If nothing is listening on queue_num, allow packets to bypass the queue"
+ feature :hashlimit, "Hashlimit features"
# provider specific features
feature :iptables, "The provider provides iptables features."
newvalues(/^[A-Z]{2}(,[A-Z]{2})*$/)
end
+ newproperty(:hashlimit_name) do
+ desc <<-EOS
+ The name for the /proc/net/ipt_hashlimit/foo entry.
+ This parameter is required.
+ EOS
+ end
+
+ newproperty(:hashlimit_upto) do
+ desc <<-EOS
+ Match if the rate is below or equal to amount/quantum. It is specified either as a number, with an optional time quantum suffix (the default is 3/hour), or as amountb/second (number of bytes per second).
+ This parameter or hashlimit_above is required.
+ Allowed forms are '40','40/second','40/minute','40/hour','40/day'.
+ EOS
+ end
+
+ newproperty(:hashlimit_above) do
+ desc <<-EOS
+ Match if the rate is above amount/quantum.
+ This parameter or hashlimit_upto is required.
+ Allowed forms are '40','40/second','40/minute','40/hour','40/day'.
+ EOS
+ end
+
+ newproperty(:hashlimit_burst) do
+ desc <<-EOS
+ Maximum initial number of packets to match: this number gets recharged by one every time the limit specified above is not reached, up to this number; the default is 5. When byte-based rate matching is requested, this option specifies the amount of bytes that can exceed the given rate. This option should be used with caution -- if the entry expires, the burst value is reset too.
+ EOS
+ newvalue(/^\d+$/)
+ end
+
+ newproperty(:hashlimit_mode) do
+ desc <<-EOS
+ A comma-separated list of objects to take into consideration. If no --hashlimit-mode option is given, hashlimit acts like limit, but at the expensive of doing the hash housekeeping.
+ Allowed values are: srcip, srcport, dstip, dstport
+ EOS
+ end
+
+ newproperty(:hashlimit_srcmask) do
+ desc <<-EOS
+ When --hashlimit-mode srcip is used, all source addresses encountered will be grouped according to the given prefix length and the so-created subnet will be subject to hashlimit. prefix must be between (inclusive) 0 and 32. Note that --hashlimit-srcmask 0 is basically doing the same thing as not specifying srcip for --hashlimit-mode, but is technically more expensive.
+ EOS
+ end
+
+ newproperty(:hashlimit_dstmask) do
+ desc <<-EOS
+ Like --hashlimit-srcmask, but for destination addresses.
+ EOS
+ end
+
+ newproperty(:hashlimit_htable_size) do
+ desc <<-EOS
+ The number of buckets of the hash table
+ EOS
+ end
+
+ newproperty(:hashlimit_htable_max) do
+ desc <<-EOS
+ Maximum entries in the hash.
+ EOS
+ end
+
+ newproperty(:hashlimit_htable_expire) do
+ desc <<-EOS
+ After how many milliseconds do hash entries expire.
+ EOS
+ end
+
+ newproperty(:hashlimit_htable_gcinterval) do
+ desc <<-EOS
+ How many milliseconds between garbage collection intervals.
+ EOS
+ end
+
autorequire(:firewallchain) do
reqs = []
protocol = nil
end
end
+ if value(:hashlimit_name)
+ unless value(:hashlimit_upto) || value(:hashlimit_above)
+ self.fail "Either hashlimit_upto or hashlimit_above are required"
+ end
+ end
end
end
--- /dev/null
+
+require 'spec_helper_acceptance'
+
+describe 'hashlimit property' do
+ before :all do
+ iptables_flush_all_tables
+ ip6tables_flush_all_tables
+ end
+
+ describe 'hashlimit_tests' do
+ context 'hashlimit_above' do
+ it 'applies' do
+ pp = <<-EOS
+ class { '::firewall': }
+ firewall { '800 - hashlimit_above test':
+ chain => 'INPUT',
+ proto => 'tcp',
+ hashlimit_name => 'above',
+ hashlimit_above => '512kb/s',
+ hashlimit_htable_gcinterval => '10',
+ hashlimit_mode => 'srcip,dstip',
+ action => accept,
+ }
+ EOS
+
+ apply_manifest(pp, :catch_failures => true)
+ apply_manifest(pp, :catch_changes => do_catch_changes)
+ end
+
+ it 'should contain the rule' do
+ shell('iptables-save') do |r|
+ expect(r.stdout).to match(/-A INPUT -p tcp -m hashlimit --hashlimit-above 512kb\/s --hashlimit-mode srcip,dstip --hashlimit-name above --hashlimit-htable-gcinterval 10 -m comment --comment "800 - hashlimit_above test" -j ACCEPT/)
+ end
+ end
+ end
+
+ context 'hashlimit_above_ip6' do
+ it 'applies' do
+ pp = <<-EOS
+ class { '::firewall': }
+ firewall { '801 - hashlimit_above test ipv6':
+ chain => 'INPUT',
+ provider => 'ip6tables',
+ proto => 'tcp',
+ hashlimit_name => 'above-ip6',
+ hashlimit_above => '512kb/s',
+ hashlimit_htable_gcinterval => '10',
+ hashlimit_mode => 'srcip,dstip',
+ action => accept,
+ }
+ EOS
+
+ apply_manifest(pp, :catch_failures => true)
+ apply_manifest(pp, :catch_changes => do_catch_changes)
+ end
+
+ it 'should contain the rule' do
+ shell('ip6tables-save') do |r|
+ expect(r.stdout).to match(/-A INPUT -p tcp -m hashlimit --hashlimit-above 512kb\/s --hashlimit-mode srcip,dstip --hashlimit-name above-ip6 --hashlimit-htable-gcinterval 10 -m comment --comment "801 - hashlimit_above test ipv6" -j ACCEPT/)
+ end
+ end
+ end
+
+ context 'hashlimit_upto' do
+ it 'applies' do
+ pp = <<-EOS
+ class { '::firewall': }
+ firewall { '802 - hashlimit_upto test':
+ chain => 'INPUT',
+ hashlimit_name => 'upto',
+ hashlimit_upto => '16/sec',
+ hashlimit_burst => '640',
+ hashlimit_htable_size => '1310000',
+ hashlimit_htable_max => '320000',
+ hashlimit_htable_expire => '36000000',
+ action => accept,
+ }
+ EOS
+
+ apply_manifest(pp, :catch_failures => true)
+ apply_manifest(pp, :catch_changes => do_catch_changes)
+ end
+
+ it 'should contain the rule' do
+ shell('iptables-save') do |r|
+ expect(r.stdout).to match(/-A INPUT -p tcp -m hashlimit --hashlimit-upto 16\/sec --hashlimit-burst 640 --hashlimit-name upto --hashlimit-htable-size 1310000 --hashlimit-htable-max 320000 --hashlimit-htable-expire 36000000 -m comment --comment "802 - hashlimit_upto test" -j ACCEPT/)
+ end
+ end
+ end
+
+ context 'hashlimit_upto_ip6' do
+ it 'applies' do
+ pp = <<-EOS
+ class { '::firewall': }
+ firewall { '803 - hashlimit_upto test ip6':
+ chain => 'INPUT',
+ provider => 'ip6tables',
+ hashlimit_name => 'upto-ip6',
+ hashlimit_upto => '16/sec',
+ hashlimit_burst => '640',
+ hashlimit_htable_size => '1310000',
+ hashlimit_htable_max => '320000',
+ hashlimit_htable_expire => '36000000',
+ action => accept,
+ }
+ EOS
+
+ apply_manifest(pp, :catch_failures => true)
+ apply_manifest(pp, :catch_changes => do_catch_changes)
+ end
+
+ it 'should contain the rule' do
+ shell('ip6tables-save') do |r|
+ expect(r.stdout).to match(/-A INPUT -p tcp -m hashlimit --hashlimit-upto 16\/sec --hashlimit-burst 640 --hashlimit-name upto-ip6 --hashlimit-htable-size 1310000 --hashlimit-htable-max 320000 --hashlimit-htable-expire 36000000 -m comment --comment "803 - hashlimit_upto test ip6" -j ACCEPT/)
+ end
+ end
+ end
+
+ end
+
+end