mirror of
https://github.com/HorlogeSkynet/Nftables
synced 2024-11-28 16:00:22 +01:00
3834422e75
> This patch breaks `constant.language.chain-type.nftables` scope > for priority keywords and now prefers `constant.language.chain-priority.nftables`
751 lines
25 KiB
YAML
751 lines
25 KiB
YAML
%YAML 1.2
|
|
---
|
|
|
|
# nftables syntax definition for Sublime Text 3+ (>= 3092).
|
|
|
|
# `file_extensions` contains `nftables.conf` to match the default packaged file in Debian.
|
|
# `first_line_match` should match (at least) this shebang `#!/usr/sbin/nft -f`.
|
|
|
|
name: Nftables
|
|
file_extensions: [nft, nftables, nftables.conf]
|
|
first_line_match: (?:^\#!\s*\/.*\bs?bin\b.*\bnft\b)
|
|
scope: source.nftables
|
|
hidden: false
|
|
|
|
|
|
variables:
|
|
integer: (?:[[:digit:]]+)
|
|
hexadecimal: (?:(?:0x)[[:xdigit:]]+)
|
|
|
|
time_string: (?:(?:\d+[wdhms])+)
|
|
identifier: (?:[[:alpha:]_][[:alnum:]_]*)
|
|
identifier_extended: (?:[[:alpha:]_][[:alnum:]_\-\.]*)
|
|
|
|
chain_types: (?:\b(filter|route|nat)\b)
|
|
chain_hooks: (?:\b(prerouting|input|forward|output|postrouting|ingress)\b)
|
|
family_types: (?:\b(arp|bridge|inet|ip6?|netdev)\b)
|
|
# nftables >= 0.9.6, chains priorities can be set using keywords.
|
|
priorities: (?:\b(raw|mangle|(?:dst|src)nat|filter|security|out)\b)
|
|
|
|
# From <https://stackoverflow.com/a/4260512>.
|
|
mac_address: |-
|
|
(?x)
|
|
(?:[0-9a-fA-F]{2}[:-]){5}(?:[0-9a-fA-F]{2})
|
|
# From <https://stackoverflow.com/a/17871737>.
|
|
ipv4_address: |-
|
|
(?x)
|
|
(?:(?:25[0-5]|(?:2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3}
|
|
(?:25[0-5]|(?:2[0-4]|1{0,1}[0-9]){0,1}[0-9])
|
|
ipv6_address: |-
|
|
(?x)
|
|
(?:[0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|
|
|
(?:[0-9a-fA-F]{1,4}:){1,7}:|
|
|
(?:[0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|
|
|
(?:[0-9a-fA-F]{1,4}:){1,5}(?::[0-9a-fA-F]{1,4}){1,2}|
|
|
(?:[0-9a-fA-F]{1,4}:){1,4}(?::[0-9a-fA-F]{1,4}){1,3}|
|
|
(?:[0-9a-fA-F]{1,4}:){1,3}(?::[0-9a-fA-F]{1,4}){1,4}|
|
|
(?:[0-9a-fA-F]{1,4}:){1,2}(?::[0-9a-fA-F]{1,4}){1,5}|
|
|
[0-9a-fA-F]{1,4}:(?:(?::[0-9a-fA-F]{1,4}){1,6})|
|
|
:(?:(?::[0-9a-fA-F]{1,4}){1,7}|:)|
|
|
fe80:(?::[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|
|
|
::(?:ffff(?::0{1,4}){0,1}:){0,1}
|
|
(?:(?:25[0-5]|(?:2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}
|
|
(?:25[0-5]|(?:2[0-4]|1{0,1}[0-9]){0,1}[0-9])|
|
|
(?:[0-9a-fA-F]{1,4}:){1,4}:
|
|
(?:(?:25[0-5]|(?:2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}
|
|
(?:25[0-5]|(?:2[0-4]|1{0,1}[0-9]){0,1}[0-9])
|
|
# From <http://blog.markhatton.co.uk/2011/03/15/regular-expressions-for-ip-addresses/>.
|
|
ipv4_subnet: |-
|
|
(?x)
|
|
(?:{{ipv4_address}})
|
|
(?:\/)
|
|
(?:3[0-2]|[1-2][0-9]|[0-9])
|
|
ipv6_subnet: |-
|
|
(?x)
|
|
(?:{{ipv6_address}})
|
|
(?:\/)
|
|
(?:12[0-8]|1[0-1][0-9]|[1-9][0-9]|[0-9])
|
|
|
|
|
|
contexts:
|
|
main:
|
|
- include: common-blocks
|
|
- include: specifications
|
|
- include: script-commands
|
|
|
|
prototype:
|
|
- include: comments
|
|
- include: variables
|
|
- include: line-continuation
|
|
|
|
comments:
|
|
- match: (#)
|
|
scope: punctuation.definition.comment.nftables
|
|
push:
|
|
- meta_scope: comment.line.nftables
|
|
- match: (?=$)
|
|
pop: true
|
|
|
|
variables:
|
|
- match: (\$)({{identifier}})
|
|
captures:
|
|
1: punctuation.definition.variable.nftables
|
|
2: variable.other.constant.nftables
|
|
- match: (@)({{identifier}})
|
|
captures:
|
|
1: punctuation.definition.variable.nftables
|
|
2: variable.other.readwrite.set.nftables
|
|
|
|
statement-separators:
|
|
# Elements matching below patterns will 'pop' the current context off the stack.
|
|
- match: (;)
|
|
scope: punctuation.terminator.semi-colon.nftables
|
|
pop: true
|
|
- match: ($\n)
|
|
pop: true
|
|
|
|
comma:
|
|
- match: (,)
|
|
scope: punctuation.separator.comma.nftables
|
|
|
|
colon:
|
|
- match: (:)
|
|
scope: punctuation.separator.colon.nftables
|
|
|
|
semi-colon:
|
|
- match: (;)
|
|
scope: punctuation.terminator.semi-colon.nftables
|
|
|
|
line-continuation:
|
|
- match: (?:(\\)(.*)$\n)
|
|
captures:
|
|
1: punctuation.separator.continuation.nftables
|
|
2: invalid.illegal.trailing-character.nftables
|
|
|
|
values:
|
|
- include: safe-values
|
|
- include: time-string
|
|
- include: unquoted-string
|
|
|
|
safe-values:
|
|
- include: quoted-string
|
|
- include: network-addresses
|
|
- include: numerics
|
|
- include: variables
|
|
- include: anonymous-set
|
|
|
|
quoted-string:
|
|
# Apparently nftables only supports double-quoted strings.
|
|
# `prototype` won't be propagated, but `line-continuation` has to be consumed.
|
|
- match: (")
|
|
scope: punctuation.definition.string.begin.nftables
|
|
with_prototype:
|
|
- match: (\\.)
|
|
scope: constant.character.escape.nftables
|
|
- include: line-continuation
|
|
push:
|
|
- meta_include_prototype: false
|
|
- meta_scope: string.quoted.double.nftables meta.string.nftables
|
|
- match: (")
|
|
scope: punctuation.definition.string.end.nftables
|
|
pop: true
|
|
|
|
time-string:
|
|
- match: \b({{time_string}})\b
|
|
scope: string.unquoted.time-string.nftables
|
|
_expect-time-string:
|
|
- match: \b({{time_string}})\b
|
|
scope: string.unquoted.time-string.nftables
|
|
pop: true
|
|
|
|
unquoted-string:
|
|
- match: \b({{identifier_extended}})\b
|
|
scope: string.unquoted.nftables
|
|
_expect-unquoted-string:
|
|
- match: \b({{identifier_extended}})\b
|
|
scope: string.unquoted.nftables
|
|
pop: true
|
|
|
|
network-addresses:
|
|
- match: ({{mac_address}})
|
|
scope: constant.numeric.mac-address.nftables
|
|
- match: ({{ipv4_subnet}})
|
|
scope: constant.numeric.ipv4-subnet.nftables
|
|
- match: ({{ipv4_address}})
|
|
scope: constant.numeric.ipv4-address.nftables
|
|
- match: ({{ipv6_subnet}})
|
|
scope: constant.numeric.ipv6-subnet.nftables
|
|
- match: ({{ipv6_address}})
|
|
scope: constant.numeric.ipv6-address.nftables
|
|
|
|
numerics:
|
|
- include: integers-range
|
|
- include: signed-integer
|
|
- include: hexadecimal
|
|
|
|
integers-range:
|
|
- match: ({{integer}})(\-)({{integer}})
|
|
captures:
|
|
1: constant.numeric.integer.nftables
|
|
2: punctuation.separator.dash.nftables
|
|
3: constant.numeric.integer.nftables
|
|
|
|
hexadecimal:
|
|
- match: \b({{hexadecimal}})\b
|
|
scope: constant.numeric.integer.hexadecimal.nftables
|
|
|
|
signed-integer:
|
|
- match: (\-)?\b{{integer}}\b
|
|
captures:
|
|
0: constant.numeric.integer.signed.nftables
|
|
1: keyword.operator.arithmetic.nftables
|
|
|
|
integer:
|
|
# This context is not included in `numerics` because `signed-integer` supersedes it.
|
|
- match: \b({{integer}})\b
|
|
scope: constant.numeric.integer.nftables
|
|
_expect-integer:
|
|
- match: \b({{integer}})\b
|
|
scope: constant.numeric.integer.nftables
|
|
pop: true
|
|
|
|
anonymous-set:
|
|
- match: ({)
|
|
scope: punctuation.section.braces.begin.anonymous-set.nftables
|
|
push:
|
|
- meta_scope: meta.object.anonymous-set.nftables
|
|
|
|
# Anonymous sets may contain values, operators and specific separators.
|
|
# Elements in the set may have a `timeout` (death-date).
|
|
- match: \b(timeout)\b
|
|
scope: storage.type.set-element-timeout.nftables
|
|
push: _expect-time-string
|
|
|
|
- include: verdict-statements
|
|
- include: values
|
|
- include: operators
|
|
- include: comma
|
|
- include: colon
|
|
|
|
- match: (})
|
|
scope: punctuation.section.braces.end.anonymous-set.nftables
|
|
pop: true
|
|
|
|
assignment:
|
|
- match: (=)
|
|
scope: keyword.operator.assignment.nftables
|
|
set:
|
|
- include: values
|
|
- include: statement-separators
|
|
|
|
common-blocks:
|
|
# Defines.
|
|
- match: \b(define|redefine)\b
|
|
scope: keyword.control.define.nftables
|
|
push:
|
|
- match: \b({{identifier}})\b
|
|
scope: variable.other.constant.nftables
|
|
set: assignment
|
|
- match: \b(undefine)\b
|
|
scope: keyword.control.undefine.nftables
|
|
push:
|
|
- match: \b({{identifier}})\b
|
|
scope: variable.other.constant.nftables
|
|
pop: true
|
|
|
|
# Include.
|
|
- match: \b(include)\b
|
|
scope: keyword.control.import.nftables
|
|
push:
|
|
- include: quoted-string
|
|
- include: statement-separators
|
|
|
|
- include: semi-colon
|
|
|
|
script-commands:
|
|
- match: |-
|
|
(?x)
|
|
\b(
|
|
add|replace|create|
|
|
insert|delete|
|
|
get|list|
|
|
reset|flush|
|
|
rename|
|
|
import|export|
|
|
monitor|describe
|
|
)\b
|
|
scope: keyword.other.command.nftables
|
|
push:
|
|
- match: \b(table)\b
|
|
scope: storage.type.table.nftables keyword.declaration.table.nftables
|
|
set:
|
|
- include: family-types
|
|
- match: \b({{identifier_extended}})\b
|
|
scope: entity.name.table.nftables
|
|
set:
|
|
- match: ({)
|
|
scope: punctuation.section.block.begin.table.nftables
|
|
set:
|
|
- meta_scope: meta.block.table.nftables
|
|
|
|
- include: table-flags
|
|
- include: statement-separators
|
|
|
|
- match: (})
|
|
scope: punctuation.section.block.end.table.nftables
|
|
pop: true
|
|
|
|
- include: statement-separators
|
|
|
|
- match: \b(chain)\b
|
|
scope: storage.type.chain.nftables keyword.declaration.chain.nftables
|
|
set:
|
|
- include: family-types
|
|
- match: \b({{identifier_extended}})\b
|
|
scope: variable.other.readwrite.table.nftables
|
|
set: chain-specs
|
|
|
|
- match: \b(flowtable)\b
|
|
scope: storage.type.flowtable.nftables keyword.declaration.flowtable.nftables
|
|
set:
|
|
- include: family-types
|
|
- match: \b({{identifier_extended}})\b
|
|
scope: variable.other.readwrite.table.nftables
|
|
set: flowtable-specs
|
|
|
|
- match: \b(rule)\b
|
|
scope: storage.type.rule.nftables keyword.declaration.rule.nftables
|
|
set: rule-command
|
|
|
|
- match: \b(set|map)\b
|
|
scope: storage.type.set.nftables keyword.declaration.set.nftables
|
|
set:
|
|
- include: family-types
|
|
- match: \b({{identifier_extended}})\b
|
|
scope: variable.other.readwrite.table.nftables
|
|
set: set-specs
|
|
|
|
- match: \b(element)\b
|
|
scope: storage.type.element.nftables keyword.declaration.element.nftables
|
|
set:
|
|
- include: family-types
|
|
- match: \b({{identifier_extended}})\b
|
|
scope: variable.other.readwrite.table.nftables
|
|
set:
|
|
- match: \b({{identifier_extended}})\b
|
|
scope: variable.other.readwrite.set.nftables
|
|
set:
|
|
- include: anonymous-set
|
|
- include: statement-separators
|
|
|
|
- match: \b(quota)\b
|
|
scope: storage.type.quota.nftables keyword.declaration.quota.nftables
|
|
set:
|
|
- include: family-types
|
|
- match: \b({{identifier_extended}})\b
|
|
scope: variable.other.readwrite.table.nftables
|
|
set: quota-specs
|
|
|
|
- match: (?:\bct\b\s+\b(helper)\b)
|
|
captures:
|
|
1: storage.type.helper.nftables keyword.declaration.helper.nftables
|
|
set: helper-specs
|
|
|
|
- match: \b(ruleset)\b
|
|
scope: keyword.other.ruleset.nftables
|
|
set:
|
|
- include: family-types
|
|
- include: statement-separators
|
|
|
|
- include: rule-command
|
|
- include: statement-separators
|
|
rule-command:
|
|
- include: family-types
|
|
- match: \b({{identifier_extended}})\b
|
|
scope: variable.other.readwrite.table.nftables
|
|
set:
|
|
- match: \b({{identifier_extended}})\b
|
|
scope: variable.other.readwrite.chain.nftables
|
|
set:
|
|
- match: \b(handle|position)\b
|
|
scope: keyword.other.handle.nftables
|
|
push: _expect-integer
|
|
|
|
- include: rule-definitions
|
|
- include: statement-separators
|
|
|
|
# Some commands do not require to specify a chain, so we must allow it to end right here.
|
|
- include: statement-separators
|
|
|
|
specifications:
|
|
- include: table-specs
|
|
|
|
- match: \b(chain)\b
|
|
scope: storage.type.chain.nftables keyword.declaration.chain.nftables
|
|
push:
|
|
- include: family-types
|
|
- match: \b({{identifier_extended}})\b
|
|
scope: variable.other.readwrite.table.nftables
|
|
set: chain-specs
|
|
|
|
- match: \b(flowtable)\b
|
|
scope: storage.type.flowtable.nftables keyword.declaration.flowtable.nftables
|
|
push:
|
|
- include: family-types
|
|
- match: \b({{identifier_extended}})\b
|
|
scope: variable.other.readwrite.table.nftables
|
|
set: flowtable-specs
|
|
|
|
- match: \b(set|map)\b
|
|
scope: storage.type.set.nftables keyword.declaration.set.nftables
|
|
push:
|
|
- include: family-types
|
|
- match: \b({{identifier_extended}})\b
|
|
scope: variable.other.readwrite.table.nftables
|
|
set: set-specs
|
|
|
|
- match: \b(quota)\b
|
|
scope: storage.type.quota.nftables keyword.declaration.quota.nftables
|
|
push:
|
|
- include: family-types
|
|
- match: \b({{identifier_extended}})\b
|
|
scope: variable.other.readwrite.table.nftables
|
|
set: quota-specs
|
|
|
|
- match: (?:\bct\b\s+\b(helper)\b)
|
|
captures:
|
|
1: storage.type.helper.nftables keyword.declaration.helper.nftables
|
|
push:
|
|
- include: family-types
|
|
- match: \b({{identifier_extended}})\b
|
|
scope: variable.other.readwrite.table.nftables
|
|
set: helper-specs
|
|
|
|
table-specs:
|
|
- match: \b(table)\b
|
|
scope: storage.type.table.nftables keyword.declaration.table.nftables
|
|
push:
|
|
- include: family-types
|
|
- match: \b({{identifier_extended}})\b
|
|
scope: entity.name.table.nftables
|
|
set:
|
|
- match: ({)
|
|
scope: punctuation.section.block.begin.table.nftables
|
|
set:
|
|
- meta_scope: meta.block.table.nftables
|
|
|
|
- include: table-flags
|
|
|
|
- include: common-blocks
|
|
|
|
- match: \b(chain)\b
|
|
scope: storage.type.chain.nftables keyword.declaration.chain.nftables
|
|
push: chain-specs
|
|
|
|
- match: \b(flowtable)\b
|
|
scope: storage.type.flowtable.nftables keyword.declaration.flowtable.nftables
|
|
push: flowtable-specs
|
|
|
|
- match: \b(set|map)\b
|
|
scope: storage.type.set.nftables keyword.declaration.set.nftables
|
|
push: set-specs
|
|
|
|
- match: \b(quota)\b
|
|
scope: storage.type.quota.nftables keyword.declaration.quota.nftables
|
|
push: quota-specs
|
|
|
|
- match: (?:\bct\b\s+\b(helper)\b)
|
|
captures:
|
|
1: storage.type.helper.nftables keyword.declaration.helper.nftables
|
|
push: helper-specs
|
|
|
|
- match: (})
|
|
scope: punctuation.section.block.end.table.nftables
|
|
pop: true
|
|
|
|
chain-specs:
|
|
- match: \b({{identifier_extended}})\b
|
|
scope: entity.name.chain.nftables
|
|
set:
|
|
- match: ({)
|
|
scope: punctuation.section.block.begin.chain.nftables
|
|
set:
|
|
- meta_scope: meta.block.chain.nftables
|
|
|
|
# Chain settings.
|
|
- include: _consume-rule-matches-type
|
|
- match: \b(type)\b
|
|
scope: storage.type.chain-type.nftables
|
|
push:
|
|
- match: ({{chain_types}})
|
|
scope: constant.language.chain-type.nftables
|
|
set:
|
|
- match: \b(hook)\b
|
|
scope: storage.type.chain-hook.nftables
|
|
set:
|
|
- match: ({{chain_hooks}})
|
|
scope: constant.language.hook.nftables
|
|
set:
|
|
- match: \b(device)\b
|
|
scope: storage.type.chain-device.nftables
|
|
push: _expect-unquoted-string
|
|
|
|
- match: \b(priority)\b
|
|
scope: storage.type.chain-priority.nftables
|
|
set:
|
|
- match: ({{priorities}})
|
|
scope: constant.language.chain-priority.nftables
|
|
- include: signed-integer
|
|
- include: plus-or-dash
|
|
- include: statement-separators
|
|
|
|
# Chain policy.
|
|
- match: \b(policy)\b
|
|
scope: storage.type.chain-policy.nftables
|
|
push:
|
|
- match: \b(accept|drop)\b
|
|
scope: constant.language.chain-policy.nftables
|
|
- include: statement-separators
|
|
|
|
# Chain rules.
|
|
- include: rule-definitions
|
|
|
|
- include: semi-colon
|
|
- match: (})
|
|
scope: punctuation.section.block.end.chain.nftables
|
|
pop: true
|
|
|
|
flowtable-specs:
|
|
- match: \b({{identifier_extended}})\b
|
|
scope: entity.name.flowtable.nftables
|
|
set:
|
|
- match: ({)
|
|
scope: punctuation.section.block.begin.flowtable.nftables
|
|
set:
|
|
- meta_scope: meta.block.flowtable.nftables
|
|
|
|
# Flowtable settings.
|
|
- match: \b(hook)\b
|
|
scope: storage.type.flowtable-hook.nftables
|
|
push:
|
|
- match: ({{chain_hooks}})
|
|
scope: constant.language.hook.nftables
|
|
set:
|
|
- match: \b(priority)\b
|
|
scope: storage.type.flowtable-priority.nftables
|
|
set:
|
|
- match: ({{priorities}})
|
|
scope: constant.language.chain-priority.nftables
|
|
- include: signed-integer
|
|
- include: plus-or-dash
|
|
|
|
- match: \b(devices)\b
|
|
scope: storage.type.flowtable-devices.nftables
|
|
set: assignment
|
|
|
|
- include: semi-colon
|
|
- match: (})
|
|
scope: punctuation.section.block.end.flowtable.nftables
|
|
pop: true
|
|
|
|
set-specs:
|
|
- match: \b({{identifier_extended}})\b
|
|
scope: entity.name.set.nftables
|
|
set:
|
|
- match: ({)
|
|
scope: punctuation.section.braces.begin.named-set.nftables
|
|
set:
|
|
- meta_scope: meta.object.named-set.nftables
|
|
|
|
- match: \b(type)\b
|
|
scope: storage.type.set-type.nftables
|
|
push:
|
|
- match: \b((?:ipv[46]|ether)_addr|inet_(?:proto|service)|counter|ifname|mark)\b
|
|
scope: constant.language.data-type.nftables
|
|
- include: dot-operator
|
|
- include: colon
|
|
- include: verdict-statements
|
|
- match: \b(verdict)\b
|
|
scope: constant.language.verdict.nftables
|
|
- include: statement-separators
|
|
- match: \b(timeout)\b
|
|
scope: storage.type.set-timeout.nftables
|
|
push:
|
|
- include: time-string
|
|
- include: statement-separators
|
|
- match: \b(flags)\b
|
|
scope: storage.type.set-flags.nftables
|
|
push:
|
|
- match: \b(constant|interval|timeout)\b
|
|
scope: constant.language.set-flag.nftables
|
|
- include: comma
|
|
- include: statement-separators
|
|
- match: \b(gc\-interval)\b
|
|
scope: storage.type.set-gcinterval.nftables
|
|
push:
|
|
- include: time-string
|
|
- include: statement-separators
|
|
- match: \b(elements)\b
|
|
scope: storage.type.set-elements.nftables
|
|
push:
|
|
- include: assignment
|
|
- include: statement-separators
|
|
- match: \b(size)\b
|
|
scope: storage.type.set-size.nftables
|
|
push:
|
|
- include: signed-integer
|
|
- include: statement-separators
|
|
- match: \b(policy)\b
|
|
scope: storage.type.set-policy.nftables
|
|
push:
|
|
- match: \b(performance|memory)\b
|
|
scope: constant.language.set-policy.nftables
|
|
- include: statement-separators
|
|
|
|
- include: semi-colon
|
|
- match: (})
|
|
scope: punctuation.section.braces.end.named-set.nftables
|
|
pop: true
|
|
|
|
quota-specs:
|
|
- match: \b({{identifier_extended}})\b
|
|
scope: entity.name.quota.nftables
|
|
set:
|
|
- include: integer
|
|
|
|
- match: \b(over|until)\b
|
|
scope: constant.language.quota-mode.nftables
|
|
push: _expect-integer
|
|
- match: \b(used)\b
|
|
scope: constant.language.quota-used.nftables
|
|
push: _expect-integer
|
|
|
|
- include: statement-separators
|
|
|
|
helper-specs:
|
|
- match: \b({{identifier_extended}})\b
|
|
scope: entity.name.helper.nftables
|
|
set:
|
|
- match: ({)
|
|
scope: punctuation.section.braces.begin.helper.nftables
|
|
set:
|
|
- meta_scope: meta.object.helper.nftables
|
|
- match: \b(type)\b
|
|
scope: storage.type.helper-type.nftables
|
|
push:
|
|
- include: quoted-string
|
|
- match: \b(protocol)\b
|
|
scope: storage.type.helper-protocol.nftables
|
|
set:
|
|
- match: \b(tcp|udp)\b
|
|
scope: constant.language.l4-proto.nftables
|
|
- include: statement-separators
|
|
|
|
- match: \b(l3proto)\b
|
|
scope: storage.type.helper-l3proto.nftables
|
|
push:
|
|
- match: ({{family_types}})
|
|
scope: constant.language.family-type.nftables
|
|
- include: statement-separators
|
|
|
|
- include: semi-colon
|
|
- match: (})
|
|
scope: punctuation.section.braces.end.helper.nftables
|
|
pop: true
|
|
|
|
family-types:
|
|
- match: ({{family_types}})
|
|
scope: constant.language.family-type.nftables
|
|
|
|
table-flags:
|
|
- match: \b(flags)\b
|
|
scope: storage.type.table-flags.nftables
|
|
push:
|
|
- match: \b(dormant)\b
|
|
scope: constant.language.table-flag.nftables
|
|
- include: comma
|
|
- include: statement-separators
|
|
|
|
verdict-statements:
|
|
- match: \b(accept|drop|queue|continue|return)\b
|
|
scope: keyword.control.rule-statement.verdict.nftables
|
|
- match: \b(jump|goto)\b
|
|
scope: keyword.control.rule-statement.verdict.nftables
|
|
push:
|
|
- match: \b({{identifier_extended}})\b
|
|
scope: variable.other.readwrite.chain.nftables
|
|
pop: true
|
|
|
|
rule-definitions:
|
|
# Allows many various tokens in rules (additionally to `prototype`).
|
|
- include: safe-values
|
|
- include: operators
|
|
- include: comma
|
|
- include: colon
|
|
|
|
# Consumes and scopes known stateful objects keywords.
|
|
- match: \b(v?map)\b
|
|
scope: storage.type.map.nftables keyword.declaration.map.nftables
|
|
- match: \b(quota)\b
|
|
scope: storage.type.quota.nftables keyword.declaration.quota.nftables
|
|
- match: (?:\bct\b\s+\b(helper)\b)
|
|
captures:
|
|
1: storage.type.helper.nftables keyword.declaration.helper.nftables
|
|
|
|
# Each rules should (might ?) have (non-)terminal statement(s).
|
|
- include: verdict-statements
|
|
- include: _consume-status-nat
|
|
- match: |-
|
|
(?x)
|
|
\b(
|
|
log|reject|counter|limit|comment|
|
|
(?:s|d)nat|masquerade|redirect|dup|fwd|
|
|
set|flow|notrack
|
|
)\b
|
|
scope: keyword.control.rule-statement.nftables
|
|
|
|
operators:
|
|
- match: \b(eq|ne|(?:l|g)[et]|numgen|jhash)\b
|
|
scope: keyword.operator.arithmetic.nftables
|
|
- match: (&|\||\<\<|\>\>|\^)
|
|
scope: keyword.operator.bitwise.nftables
|
|
- match: ([!=]=|[\<\>]=?)
|
|
scope: keyword.operator.arithmetic.nftables
|
|
- match: \b(and|x?or)\b
|
|
scope: keyword.operator.arithmetic.nftables
|
|
- include: plus-or-dash
|
|
- include: dot-operator
|
|
|
|
plus-or-dash:
|
|
- match: \B(\+|\-)\B
|
|
scope: keyword.operator.arithmetic.nftables
|
|
|
|
dot-operator:
|
|
- match: \B(\.)\B
|
|
scope: keyword.operator.concatenation.nftables
|
|
|
|
# Below contexts require further explanations.
|
|
# Sublime Text >= 3103 ships a specific optimized REGEXP engine, not supporting look-behinds.
|
|
# See <https://www.sublimetext.com/blog/articles/sublime-text-3-build-3103> for external reference.
|
|
#
|
|
# In order to make this syntax definition working against this engine, we have to get rid of look-behinds.
|
|
# As a workaround, we define here contexts that consume tokens we shouldn't be matching elsewhere.
|
|
_consume-rule-matches-type:
|
|
# Consume some rule matches using the `type` keyword".
|
|
- match: (?:\b(?:ether|dccp|icmp(?:v6|x)?|mh|rt)\b\s+\btype\b)
|
|
|
|
# Consumes `fib ${key} ${data}` (as `data` **MIGHT** be `type`).
|
|
# See <https://wiki.nftables.org/wiki-nftables/index.php/Routing_information#fib>.
|
|
- match: \bfib\b
|
|
push:
|
|
# `${key}` might be the dot operator (`.`), so we must match it as well.
|
|
- include: dot-operator
|
|
# We assume that `fib` must be followed by a (known) `${data}` expression.
|
|
# So the first encountered one will act as a cue to leave this context.
|
|
- match: \b(oif(?:name)?|type)\b
|
|
pop: true
|
|
|
|
_consume-status-nat:
|
|
# Consume `ct status` rule matches using `(s|d)nat`.
|
|
- match: (?:\bct\b\s+\bstatus\b\s+\b(?:s|d)nat\b)
|