cisco_node_utils 1.9.0 → 1.10.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (49) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +34 -0
  3. data/README.md +14 -0
  4. data/ext/mkrf_conf.rb +1 -1
  5. data/lib/cisco_node_utils/ace.rb +142 -7
  6. data/lib/cisco_node_utils/banner.rb +63 -0
  7. data/lib/cisco_node_utils/bridge_domain.rb +1 -1
  8. data/lib/cisco_node_utils/cisco_cmn_utils.rb +1 -1
  9. data/lib/cisco_node_utils/client/utils.rb +20 -10
  10. data/lib/cisco_node_utils/cmd_ref/acl.yaml +1 -1
  11. data/lib/cisco_node_utils/cmd_ref/banner.yaml +7 -0
  12. data/lib/cisco_node_utils/cmd_ref/fabricpath.yaml +2 -2
  13. data/lib/cisco_node_utils/cmd_ref/hostname.yaml +8 -0
  14. data/lib/cisco_node_utils/cmd_ref/interface.yaml +20 -12
  15. data/lib/cisco_node_utils/cmd_ref/interface_hsrp_group.yaml +3 -3
  16. data/lib/cisco_node_utils/cmd_ref/ip_multicast.yaml +6 -2
  17. data/lib/cisco_node_utils/cmd_ref/snmp_server.yaml +4 -1
  18. data/lib/cisco_node_utils/cmd_ref/syslog_facility.yaml +10 -0
  19. data/lib/cisco_node_utils/cmd_ref/syslog_server.yaml +3 -3
  20. data/lib/cisco_node_utils/cmd_ref/syslog_settings.yaml +16 -0
  21. data/lib/cisco_node_utils/cmd_ref/tacacs_server_host.yaml +2 -2
  22. data/lib/cisco_node_utils/environment.rb +8 -1
  23. data/lib/cisco_node_utils/hostname.rb +62 -0
  24. data/lib/cisco_node_utils/interface.rb +59 -2
  25. data/lib/cisco_node_utils/interface_DEPRECATED.rb +5 -0
  26. data/lib/cisco_node_utils/interface_hsrp_group.rb +17 -6
  27. data/lib/cisco_node_utils/ip_multicast.rb +13 -9
  28. data/lib/cisco_node_utils/node.rb +4 -1
  29. data/lib/cisco_node_utils/syslog_facility.rb +64 -0
  30. data/lib/cisco_node_utils/syslog_server.rb +18 -13
  31. data/lib/cisco_node_utils/syslog_settings.rb +43 -1
  32. data/lib/cisco_node_utils/version.rb +1 -1
  33. data/lib/cisco_node_utils/vlan.rb +1 -1
  34. data/lib/cisco_node_utils/vxlan_vtep_vni.rb +21 -8
  35. data/spec/environment_spec.rb +107 -0
  36. data/tests/ciscotest.rb +8 -1
  37. data/tests/test_ace.rb +60 -3
  38. data/tests/test_banner.rb +85 -0
  39. data/tests/test_bgp_af.rb +1 -1
  40. data/tests/test_hostname.rb +64 -0
  41. data/tests/test_interface.rb +22 -1
  42. data/tests/test_interface_hsrp_group.rb +12 -24
  43. data/tests/test_ip_multicast.rb +32 -21
  44. data/tests/test_nxapi.rb +8 -4
  45. data/tests/test_syslog_facility.rb +80 -0
  46. data/tests/test_syslog_server.rb +3 -2
  47. data/tests/test_syslog_settings.rb +16 -1
  48. data/tests/yum_package.yaml +5 -0
  49. metadata +12 -3
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: f41913654bc402d2a30d3c2345e0ac1fbd587ffe
4
- data.tar.gz: a20bebaeb60c419708f83b078c8f5e61464788ec
3
+ metadata.gz: db160cf1dedda53f077ad5e3c246a7106be834ea
4
+ data.tar.gz: 31eac56721204dbbf673355acaa1dd5591af3ed3
5
5
  SHA512:
6
- metadata.gz: daed7260c5c3b320216186f6c10ed0468bf78a6c5038b8bd6a0d5521e61dc606088ba505feda784318e6cf9800b7dfb8414824db66e8950193df8a877f76db22
7
- data.tar.gz: fbab02d4e41a802249bc5b30b1b87392392f5f4cba319c554e825d8bed79ae3bf26a5186d640219b7d0e2da5472b50a2c18f850f31e232e15ee3c15db04f39bb
6
+ metadata.gz: d6330230a4a619e0e497d5c79d5757bfe3141e53605550033fdcfcb9f4e8cfafd93e8aa2a457fd4989ff40c636001f6a070475736abf30c1cd72eb0a09126db5
7
+ data.tar.gz: ac35c7431032dddce3c7fbc92c20028a6843fb25314e218925e1fa37610e6735e0a593e4aaa04ca2812182e20aa96a3d43205e436d5d2c655f850c828fddf78b
@@ -1,6 +1,39 @@
1
1
  Changelog
2
2
  =========
3
3
 
4
+ ## [v1.10.0]
5
+
6
+ ### New Cisco Resources
7
+
8
+ ### Added
9
+ * Added syslog_facility with attribute:
10
+ * `level`
11
+ * Extend syslog_server with attribute:
12
+ * `facility`
13
+ * Extend interface with attributes:
14
+ * `ipv6_redirects`
15
+ * Extend ace with attributes:
16
+ * `proto_option`
17
+ * `vlan`
18
+ * `set_erspan_dscp`
19
+ * `set_erspan_gre_proto`
20
+ * Extend network_dns with attributes:
21
+ * `hostname`
22
+ * Added ability to specify environment at run time
23
+
24
+ Example:
25
+ ```ruby
26
+ env = { host: '192.168.1.1', port: nil, username: 'admin', password: 'admin123', cookie: nil }
27
+ Cisco::Environment.add_env('default', env)
28
+ ```
29
+
30
+ ### Changed
31
+
32
+ ### Removed
33
+
34
+ ### Issues Addressed
35
+ * Removed default values for authentication in `interface_hsrp_group`
36
+
4
37
  ## [v1.9.0]
5
38
 
6
39
  ### New Cisco Resources
@@ -554,6 +587,7 @@ Changelog
554
587
  [git-flow]: https://github.com/petervanderdoes/gitflow-avh
555
588
  [SimpleCov]: https://github.com/colszowka/simplecov
556
589
 
590
+ [v1.10.0]: https://github.com/cisco/cisco-network-node-utils/compare/v1.9.0...v1.10.0
557
591
  [v1.9.0]: https://github.com/cisco/cisco-network-node-utils/compare/v1.8.0...v1.9.0
558
592
  [v1.8.0]: https://github.com/cisco/cisco-network-node-utils/compare/v1.7.0...v1.8.0
559
593
  [v1.7.0]: https://github.com/cisco/cisco-network-node-utils/compare/v1.6.0...v1.7.0
data/README.md CHANGED
@@ -85,6 +85,14 @@ An example configuration file (illustrating each of the above scenarios) is prov
85
85
 
86
86
  *For security purposes, it is highly recommended that access to this file be restricted to only the owning user (`chmod 0600`).*
87
87
 
88
+ Configuration may also be specified at runtime and can be used in the absence of configuration files or to override them.
89
+
90
+ Example:
91
+ ```ruby
92
+ env = { host: '192.168.1.1', port: nil, username: 'admin', password: 'admin123', cookie: nil }
93
+ Cisco::Environment.add_env('default', env)
94
+ ```
95
+
88
96
  ## <a name="documentation">Documentation</a>
89
97
 
90
98
  ### Client
@@ -151,12 +159,18 @@ client2 = Cisco::Client.create('n9k')
151
159
  # Warning: Make sure to exclude devices using the 'no_proxy' environment variable
152
160
  # to ensure successful remote connections.
153
161
 
162
+ # Add runtime configuration for remote device and connect
163
+ env = { host: '192.168.1.1', port: nil, username: 'admin', password: 'admin123', cookie: nil }
164
+ Cisco::Environment.add_env('remote', env)
165
+ client3 = Cisco::Client.create('remote')
166
+
154
167
  # Use connections to get and set device state.
155
168
  client1.set(values: 'feature vtp')
156
169
  client1.set(values: 'vtp domain mycompany.com')
157
170
  puts client1.get(command: 'show vtp status | inc Domain')
158
171
 
159
172
  puts client2.get(command: 'show version')
173
+ puts client3.get(command: 'show version')
160
174
  ```
161
175
 
162
176
  #### High-level Node API
@@ -37,7 +37,7 @@ begin
37
37
  os == 'ios_xr' || deps << Gem::Dependency.new('net_http_unix',
38
38
  '~> 0.2', '>= 0.2.1')
39
39
  # NX-OS doesn't need gRPC
40
- os == 'nexus' || deps << Gem::Dependency.new('grpc', '~> 0.12')
40
+ os == 'nexus' || deps << Gem::Dependency.new('grpc', '~> 1.14.1')
41
41
 
42
42
  deps.each do |dep|
43
43
  installed = dep.matching_specs
@@ -1,4 +1,4 @@
1
- # Copyright (c) 2015-2016 Cisco and/or its affiliates.
1
+ # Copyright (c) 2015-2018 Cisco and/or its affiliates.
2
2
  #
3
3
  # Licensed under the Apache License, Version 2.0 (the "License");
4
4
  # you may not use this file except in compliance with the License.
@@ -12,6 +12,7 @@
12
12
  # See the License for the specific language governing permissions and
13
13
  # limitations under the License.
14
14
 
15
+ require 'ipaddr'
15
16
  require_relative 'node_util'
16
17
 
17
18
  module Cisco
@@ -73,6 +74,9 @@ module Cisco
73
74
  remark = Regexp.new('(?<seqno>\d+) remark (?<remark>.*)').match(str)
74
75
  return remark unless remark.nil?
75
76
 
77
+ # specialized icmp protocol handling
78
+ return icmp_ace_get(str) if str.include?('icmp')
79
+
76
80
  # rubocop:disable Metrics/LineLength
77
81
  regexp = Regexp.new('(?<seqno>\d+) (?<action>\S+)'\
78
82
  ' *(?<proto>\d+|\S+)'\
@@ -95,6 +99,60 @@ module Cisco
95
99
  regexp.match(str)
96
100
  end
97
101
 
102
+ # icmp ace getter
103
+ def icmp_ace_get(str)
104
+ # rubocop:disable Metrics/LineLength
105
+ # fragments is nvgen at a different location than all other
106
+ # proto_option so get rid of it so as not to mess up other fields
107
+ str.sub!('fragments ', '')
108
+ regexp = Regexp.new('(?<seqno>\d+) (?<action>\S+)'\
109
+ ' *(?<proto>\d+|\S+)'\
110
+ ' *(?<src_addr>any|host \S+|[:\.0-9a-fA-F]+ [:\.0-9a-fA-F]+|[:\.0-9a-fA-F]+\/\d+|addrgroup \S+)'\
111
+ ' *(?<dst_addr>any|host \S+|[:\.0-9a-fA-F]+ [:\.0-9a-fA-F]+|[:\.0-9a-fA-F]+\/\d+|addrgroup \S+)'\
112
+ ' *(?<proto_option>\S+)?'\
113
+ ' *(?<precedence>precedence \S+)?'\
114
+ ' *(?<dscp>dscp \S+)?'\
115
+ ' *(?<time_range>time-range \S+)?'\
116
+ ' *(?<packet_length>packet-length (range \d+ \d+|(lt|eq|gt|neq) \d+))?'\
117
+ ' *(?<ttl>ttl \d+)?'\
118
+ ' *(?<vlan>vlan \d+)?'\
119
+ ' *(?<set_erspan_gre_proto>set-erspan-gre-proto \d+)?'\
120
+ ' *(?<set_erspan_dscp>set-erspan-dscp \d+)?'\
121
+ ' *(?<redirect>redirect \S+)?')
122
+ regexp_no_proto_option = Regexp.new('(?<seqno>\d+) (?<action>\S+)'\
123
+ ' *(?<proto>\d+|\S+)'\
124
+ ' *(?<src_addr>any|host \S+|[:\.0-9a-fA-F]+ [:\.0-9a-fA-F]+|[:\.0-9a-fA-F]+\/\d+|addrgroup \S+)'\
125
+ ' *(?<dst_addr>any|host \S+|[:\.0-9a-fA-F]+ [:\.0-9a-fA-F]+|[:\.0-9a-fA-F]+\/\d+|addrgroup \S+)'\
126
+ ' *(?<precedence>precedence \S+)?'\
127
+ ' *(?<dscp>dscp \S+)?'\
128
+ ' *(?<time_range>time-range \S+)?'\
129
+ ' *(?<packet_length>packet-length (range \d+ \d+|(lt|eq|gt|neq) \d+))?'\
130
+ ' *(?<ttl>ttl \d+)?'\
131
+ ' *(?<vlan>vlan \d+)?'\
132
+ ' *(?<set_erspan_gre_proto>set-erspan-gre-proto \d+)?'\
133
+ ' *(?<set_erspan_dscp>set-erspan-dscp \d+)?'\
134
+ ' *(?<redirect>redirect \S+)?')
135
+ temp = regexp.match(str)
136
+ po = temp[:proto_option]
137
+ if po.nil?
138
+ return temp
139
+ # redirect can be proto_option or an actual redirect to interface
140
+ elsif po.strip.match(/redirect$/)
141
+ if str.match(/Ethernet|port-channel/)
142
+ # if proto_option is given as redirect and also redirect to intf
143
+ # we need to do extra processing
144
+ return temp if check_redirect_repeat(str)
145
+ return regexp_no_proto_option.match(str)
146
+ end
147
+ # the reserved keywords check
148
+ elsif po.strip.match(/precedence$|dscp$|time-range$|packet-length$|ttl$|vlan$|set-erspan-gre-proto$|set-erspan-dscp$|log$/)
149
+ return regexp_no_proto_option.match(str)
150
+ else
151
+ return temp
152
+ end
153
+ # rubocop:enable Metrics/LineLength
154
+ end
155
+
98
156
  # common ace setter. Put the values you need in a hash and pass it in.
99
157
  # attrs = {:action=>'permit', :proto=>'tcp', :src =>'host 1.1.1.1'}
100
158
  def ace_set(attrs)
@@ -130,6 +188,10 @@ module Cisco
130
188
  :tcp_option_length,
131
189
  :redirect,
132
190
  :log,
191
+ :proto_option,
192
+ :set_erspan_dscp,
193
+ :set_erspan_gre_proto,
194
+ :vlan,
133
195
  ].each do |p|
134
196
  attrs[p] = '' if attrs[p].nil?
135
197
  send(p.to_s + '=', attrs[p])
@@ -139,6 +201,21 @@ module Cisco
139
201
  config_set('acl', cmd, @set_args)
140
202
  end
141
203
 
204
+ def valid_ipv6?(addr)
205
+ begin
206
+ ret = IPAddr.new(addr.split[0]).ipv6?
207
+ rescue
208
+ ret = false
209
+ end
210
+ ret
211
+ end
212
+
213
+ def check_redirect_repeat(str)
214
+ return false unless str.include?('redirect')
215
+ nstr = str.sub('redirect', '').strip
216
+ nstr.include?('redirect') ? true : false
217
+ end
218
+
142
219
  # PROPERTIES
143
220
  # ----------
144
221
  def seqno
@@ -182,7 +259,7 @@ module Cisco
182
259
  return nil if match.nil? || !match.names.include?('src_addr')
183
260
  addr = match[:src_addr]
184
261
  # Normalize addr. Some platforms zero_pad ipv6 addrs.
185
- addr.gsub!(/^0*/, '').gsub!(/:0*/, ':')
262
+ addr.gsub!(/^0*/, '').gsub!(/:0*/, ':') if valid_ipv6?(addr)
186
263
  addr
187
264
  end
188
265
 
@@ -205,7 +282,7 @@ module Cisco
205
282
  return nil if match.nil? || !match.names.include?('dst_addr')
206
283
  addr = match[:dst_addr]
207
284
  # Normalize addr. Some platforms zero_pad ipv6 addrs.
208
- addr.gsub!(/^0*/, '').gsub!(/:0*/, ':')
285
+ addr.gsub!(/^0*/, '').gsub!(/:0*/, ':') if valid_ipv6?(addr)
209
286
  addr
210
287
  end
211
288
 
@@ -261,6 +338,49 @@ module Cisco
261
338
  @set_args[:dscp] = Utils.attach_prefix(dscp, :dscp)
262
339
  end
263
340
 
341
+ def vlan
342
+ Utils.extract_value(ace_get, 'vlan')
343
+ end
344
+
345
+ def vlan=(vlan)
346
+ @set_args[:vlan] = Utils.attach_prefix(vlan, :vlan)
347
+ end
348
+
349
+ def set_erspan_dscp
350
+ ret = Utils.extract_value(ace_get, 'set_erspan_dscp', 'set-erspan-dscp')
351
+ return ret if ret
352
+ # position of set_erspan_dscp is different in older release so check again
353
+ str = config_get('acl', 'ace', @get_args)
354
+ sstr = str.split
355
+ return sstr[sstr.index('set-erspan-dscp') + 1] if
356
+ sstr.include?('set-erspan-dscp')
357
+ end
358
+
359
+ def set_erspan_dscp=(set_erspan_dscp)
360
+ @set_args[:set_erspan_dscp] = Utils.attach_prefix(set_erspan_dscp,
361
+ :set_erspan_dscp,
362
+ 'set-erspan-dscp')
363
+ end
364
+
365
+ def set_erspan_gre_proto
366
+ ret = Utils.extract_value(ace_get, 'set_erspan_gre_proto',
367
+ 'set-erspan-gre-proto')
368
+ return ret if ret
369
+ # position of set_erspan_gre_proto is different in older release
370
+ # so check again
371
+ str = config_get('acl', 'ace', @get_args)
372
+ sstr = str.split
373
+ return sstr[sstr.index('set-erspan-gre-proto') + 1] if
374
+ sstr.include?('set-erspan-gre-proto')
375
+ end
376
+
377
+ def set_erspan_gre_proto=(set_erspan_gre_proto)
378
+ @set_args[:set_erspan_gre_proto] =
379
+ Utils.attach_prefix(set_erspan_gre_proto,
380
+ :set_erspan_gre_proto,
381
+ 'set-erspan-gre-proto')
382
+ end
383
+
264
384
  def time_range
265
385
  Utils.extract_value(ace_get, 'time_range', 'time-range')
266
386
  end
@@ -317,12 +437,27 @@ module Cisco
317
437
  @set_args[:redirect] = Utils.attach_prefix(redirect, :redirect)
318
438
  end
319
439
 
320
- def log
440
+ def proto_option
321
441
  match = ace_get
442
+ return nil if match.nil? || proto != 'icmp' || !remark.nil?
443
+ # fragments is nvgen at a different location than all other
444
+ # proto_option
445
+ if config_get('acl', 'ace', @get_args).include?('fragments')
446
+ return 'fragments'
447
+ end
448
+ # log is special case
449
+ return nil if !match.names.include?('proto_option') ||
450
+ match[:proto_option] == 'log'
451
+ match[:proto_option]
452
+ end
453
+
454
+ def proto_option=(proto_option)
455
+ @set_args[:proto_option] = proto_option
456
+ end
457
+
458
+ def log
322
459
  return nil unless remark.nil?
323
- return false if match.nil?
324
- return false unless match.names.include?('log')
325
- match[:log] == 'log' ? true : false
460
+ config_get('acl', 'ace', @get_args).include?('log') ? true : false
326
461
  end
327
462
 
328
463
  def log=(log)
@@ -0,0 +1,63 @@
1
+ # Banner provider class
2
+ #
3
+ # Rick Sherman et al., August 2018
4
+ #
5
+ # Copyright (c) 2014-2018 Cisco and/or its affiliates.
6
+ #
7
+ # Licensed under the Apache License, Version 2.0 (the "License");
8
+ # you may not use this file except in compliance with the License.
9
+ # You may obtain a copy of the License at
10
+ #
11
+ # http://www.apache.org/licenses/LICENSE-2.0
12
+ #
13
+ # Unless required by applicable law or agreed to in writing, software
14
+ # distributed under the License is distributed on an "AS IS" BASIS,
15
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16
+ # See the License for the specific language governing permissions and
17
+ # limitations under the License.
18
+
19
+ require_relative 'node_util'
20
+
21
+ module Cisco
22
+ # Banner - node utility class for Banner configuration management
23
+ class Banner < NodeUtil
24
+ attr_reader :name
25
+
26
+ def initialize(name)
27
+ fail TypeError unless name.is_a?(String)
28
+ fail ArgumentError,
29
+ "This provider only accepts an id of 'default'" \
30
+ unless name.eql?('default')
31
+ @name = name
32
+ end
33
+
34
+ def self.banners
35
+ hash = {}
36
+ hash['default'] = Banner.new('default')
37
+ hash
38
+ end
39
+
40
+ def ==(other)
41
+ name == other.name
42
+ end
43
+
44
+ def motd
45
+ config_get('banner', 'motd')
46
+ end
47
+
48
+ def motd=(val)
49
+ if val.nil? && (motd != default_motd)
50
+ config_set('banner', 'motd', state: 'no', motd: '')
51
+ elsif !val.nil?
52
+ config_set('banner',
53
+ 'motd',
54
+ state: '',
55
+ motd: "^#{val.gsub(/\n/, '\\n')}^")
56
+ end
57
+ end
58
+
59
+ def default_motd
60
+ config_get_default('banner', 'motd')
61
+ end
62
+ end # class
63
+ end # module
@@ -144,7 +144,7 @@ module Cisco
144
144
  # This type property can be defined only for one bd
145
145
  def fabric_control
146
146
  match = config_get('bridge_domain', 'fabric_control', bd: @bd_ids)
147
- match == @bd_ids ? true : false
147
+ match.to_s == @bd_ids ? true : false
148
148
  end
149
149
 
150
150
  def fabric_control=(val)
@@ -362,7 +362,7 @@ module Cisco
362
362
  end # merge_range
363
363
 
364
364
  def self.add_quotes(value)
365
- return value if image_version?(/7.3.0/)
365
+ return value if image_version?(/7.3/)
366
366
  value = "\"#{value}\"" unless
367
367
  value.start_with?('"') && value.end_with?('"')
368
368
  value
@@ -111,16 +111,26 @@ class Cisco::Client
111
111
  return input.map { |item| to_regexp(item) }
112
112
  else
113
113
  # The string might be explicitly formatted as a regexp
114
- if input[0] == '/' && input[-1] == '/'
115
- # '/foo/' => %r{foo}
116
- return Regexp.new(input[1..-2])
117
- elsif input[0] == '/' && input[-2..-1] == '/i'
118
- # '/foo/i' => %r{foo}i
119
- return Regexp.new(input[1..-3], Regexp::IGNORECASE)
120
- else
121
- # 'foo' => %r{^foo$}i
122
- return Regexp.new("^#{input}$", Regexp::IGNORECASE)
114
+ # Dynamically handle modifiers
115
+ input.match(%r{(?<regex>^\/.*\/)(?<options>[imx]*)?}) do |m|
116
+ options = []
117
+ m['options'].each_char do |c|
118
+ case c
119
+ when 'i'
120
+ options << Regexp::IGNORECASE
121
+ when 'm'
122
+ options << Regexp::MULTILINE
123
+ when 'x'
124
+ options << Regexp::EXTENDED
125
+ end
126
+ end
127
+ return Regexp.new(m['regex'][1..-2], options.reduce(:|))
123
128
  end
129
+ # otherwise this value is a regular string
130
+ # convert to case insensitive regex
131
+ # 'foo' => %r{^foo$}i
132
+ return Regexp.new("^#{input}$", Regexp::IGNORECASE)
133
+
124
134
  end
125
135
  end
126
136
 
@@ -151,7 +161,7 @@ class Cisco::Client
151
161
  end
152
162
  return final
153
163
  end
154
- fail "No key \"#{filter}\" in #{data}" if data[filter].nil?
164
+ fail "No key \"#{filter}\" in #{data}" unless data.key?(filter)
155
165
  data = data[filter]
156
166
  end
157
167
  end
@@ -12,7 +12,7 @@ _template:
12
12
 
13
13
  ace:
14
14
  get_value: '/^<seqno> .+$/'
15
- set_value: '<state> <seqno> <action> <proto> <src_addr> <src_port> <dst_addr> <dst_port> <tcp_flags> <established> <precedence> <dscp> <http_method> <time_range> <packet_length> <ttl> <tcp_option_length> <redirect> <log>'
15
+ set_value: '<state> <seqno> <action> <proto> <src_addr> <src_port> <dst_addr> <dst_port> <proto_option> <tcp_flags> <established> <precedence> <dscp> <http_method> <time_range> <packet_length> <ttl> <tcp_option_length> <vlan> <redirect> <set_erspan_dscp> <set_erspan_gre_proto> <log>'
16
16
 
17
17
  ace_destroy:
18
18
  set_value: 'no <seqno>'