@@ -26,29 +26,28 @@ def validate(record)
2626 end
2727
2828 validate_allowed_keys ( rule , record , index )
29-
30- add_rule_error ( "protocol must be 'tcp', 'udp', 'icmp', or 'all'" , record , index ) unless valid_protocol ( rule [ :protocol ] )
29+ add_rule_error ( "protocol must be 'tcp', 'udp', 'icmp', 'icmpv6' or 'all'" , record , index ) unless valid_protocol ( rule [ :protocol ] )
3130
3231 if valid_destination_type ( rule [ :destination ] , record , index )
3332 destinations = rule [ :destination ] . split ( ',' , -1 )
3433 add_rule_error ( "maximum destinations per rule exceeded - must be under #{ MAX_DESTINATIONS_PER_RULE } " , record , index ) unless destinations . length <= MAX_DESTINATIONS_PER_RULE
3534
3635 destinations . each do |d |
37- validate_destination ( d , record , index )
36+ validate_destination ( d , rule [ :protocol ] , get_allowed_ip_version ( rule ) , record , index )
3837 end
3938 end
4039
4140 validate_description ( rule , record , index )
4241 validate_log ( rule , record , index )
42+ validate_protocol ( rule , record , index )
43+ end
44+ end
4345
44- case rule [ :protocol ]
45- when 'tcp' , 'udp'
46- validate_tcp_udp_protocol ( rule , record , index )
47- when 'icmp'
48- validate_icmp_protocol ( rule , record , index )
49- when 'all'
50- add_rule_error ( 'ports are not allowed for protocols of type all' , record , index ) if rule [ :ports ]
51- end
46+ def get_allowed_ip_version ( rule )
47+ if rule [ :protocol ] == 'icmp'
48+ 4
49+ elsif rule [ :protocol ] == 'icmpv6'
50+ 6
5251 end
5352 end
5453
@@ -57,7 +56,7 @@ def boolean?(value)
5756 end
5857
5958 def valid_protocol ( protocol )
60- protocol . is_a? ( String ) && %w[ tcp udp icmp all ] . include? ( protocol )
59+ protocol . is_a? ( String ) && %w[ tcp udp icmp icmpv6 all ] . include? ( protocol )
6160 end
6261
6362 def validate_allowed_keys ( rule , record , index )
@@ -73,6 +72,20 @@ def validate_log(rule, record, index)
7372 add_rule_error ( 'log must be a boolean' , record , index ) if rule [ :log ] && !boolean? ( rule [ :log ] )
7473 end
7574
75+ def validate_protocol ( rule , record , index )
76+ case rule [ :protocol ]
77+ when 'tcp' , 'udp'
78+ validate_tcp_udp_protocol ( rule , record , index )
79+ when 'icmp'
80+ validate_icmp_protocol ( rule , record , index )
81+ when 'icmpv6'
82+ add_rule_error ( 'icmpv6 cannot be used if enable_ipv6 is false' , record , index ) unless CloudController ::RuleValidator . ipv6_enabled?
83+ validate_icmp_protocol ( rule , record , index )
84+ when 'all'
85+ add_rule_error ( 'ports are not allowed for protocols of type all' , record , index ) if rule [ :ports ]
86+ end
87+ end
88+
7689 def validate_tcp_udp_protocol ( rule , record , index )
7790 add_rule_error ( 'ports are required for protocols of type TCP and UDP' , record , index ) unless rule [ :ports ]
7891
@@ -128,7 +141,7 @@ def valid_destination_type(destination, record, index)
128141 true
129142 end
130143
131- def validate_destination ( destination , record , index )
144+ def validate_destination ( destination , protocol , allowed_ip_version , record , index )
132145 error_message = 'destination must be a valid CIDR, IP address, or IP address range'
133146 error_message = 'destination must contain valid CIDR(s), IP address(es), or IP address range(s)' if CloudController ::RuleValidator . comma_delimited_destinations_enabled?
134147 add_rule_error ( 'empty destination specified in comma-delimited list' , record , index ) if destination . empty?
@@ -137,12 +150,14 @@ def validate_destination(destination, record, index)
137150
138151 zeros_error_message = 'destination octets cannot contain leading zeros'
139152 add_rule_error ( zeros_error_message , record , index ) unless CloudController ::RuleValidator . no_leading_zeros ( address_list )
140-
141153 if address_list . length == 1
142- add_rule_error ( error_message , record , index ) unless CloudController ::RuleValidator . parse_ip ( address_list . first )
143-
154+ parsed_ip = CloudController ::RuleValidator . parse_ip ( address_list . first )
155+ add_rule_error ( error_message , record , index ) unless parsed_ip
156+ add_rule_error ( "for protocol \" #{ protocol } \" you cannot use IPv#{ parsed_ip . version } addresses" , record , index ) \
157+ unless valid_ip_version? ( allowed_ip_version , parsed_ip )
144158 elsif address_list . length == 2
145159 ips = CloudController ::RuleValidator . parse_ip ( address_list )
160+
146161 return add_rule_error ( 'destination IP address range is invalid' , record , index ) unless ips
147162
148163 sorted_ips = if ips . first . is_a? ( NetAddr ::IPv4 )
@@ -153,12 +168,17 @@ def validate_destination(destination, record, index)
153168
154169 reversed_range_error = 'beginning of IP address range is numerically greater than the end of its range (range endpoints are inverted)'
155170 add_rule_error ( reversed_range_error , record , index ) unless ips . first == sorted_ips . first
156-
171+ add_rule_error ( "for protocol \" #{ protocol } \" you cannot use IPv#{ ips . first . version } addresses" , record , index ) \
172+ unless valid_ip_version? ( allowed_ip_version , sorted_ips . first )
157173 else
158174 add_rule_error ( error_message , record , index )
159175 end
160176 end
161177
178+ def valid_ip_version? ( allowed_ip_version , parsed_ip )
179+ parsed_ip . nil? || allowed_ip_version . nil? || parsed_ip . version == allowed_ip_version
180+ end
181+
162182 def add_rule_error ( message , record , index )
163183 record . errors . add ( "Rules[#{ index } ]:" , message )
164184 end
0 commit comments