emacs-elpa-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[elpa] externals/nftables-mode 35e908d774 03/41: just a backup copy in c


From: Stefan Monnier
Subject: [elpa] externals/nftables-mode 35e908d774 03/41: just a backup copy in case I lose the original somewhere
Date: Mon, 23 May 2022 09:27:22 -0400 (EDT)

branch: externals/nftables-mode
commit 35e908d7745f344197429a5c188b21a1b68e7e71
Author: Trent W. Buck <trentbuck@gmail.com>
Commit: Trent W. Buck <trentbuck@gmail.com>

    just a backup copy in case I lose the original somewhere
---
 nftables-mode.el | 309 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 309 insertions(+)

diff --git a/nftables-mode.el b/nftables-mode.el
new file mode 100644
index 0000000000..494ca07659
--- /dev/null
+++ b/nftables-mode.el
@@ -0,0 +1,309 @@
+(require 'rx)
+(require 'syntax)                       ; syntax-ppss, for indentation
+
+(defvar nftables-mode-map (make-sparse-keymap))
+(defvar nftables-mode-hook nil)
+(defvar nftables-mode-syntax-table
+  (let ((table (make-syntax-table)))
+    (modify-syntax-entry ?# "<\n" table)  ; make #comment work
+    (modify-syntax-entry ?\n ">#" table)  ; make #comment work
+    (modify-syntax-entry ?_ "w" table)    ; foo_bar is 1 word (not 2)
+    table))
+
+;;; NOTE: I started with the keywords in the nano highlighter, but
+;;; they were really incomplete.  So instead I looked at the
+;;; flex/bison rules in the nft source code (as at debian/0.9.1-2-2-g3255aaa):
+;;;     
https://salsa.debian.org/pkg-netfilter-team/pkg-nftables/blob/master/src/scanner.l
+;;;     
https://salsa.debian.org/pkg-netfilter-team/pkg-nftables/blob/master/src/parser_bison.y
+;;; NOTE: not supporting multi-statement lines "list ruleset; flush ruleset".
+;;; NOTE: not supporting multi-line statements "list \\\n ruleset".
+;;; NOTE: not supporting arbitrary whitespace in some places.
+;;; NOTE: identifiers are hard (e.g. bare addresses, names, quoted strings), so
+;;;       not supporting all those properly.
+;;; NOTE: family can be omitted; it defaults to "ip" (IPv4 only).
+;;;       I am not supporting that, because you USUALLY want "inet" (IPv4/IPv6 
dual-stack).
+;;; NOTE: there are two main styles, I'm supporting only those and not a mix 
of same.
+;;;
+;;;       Style #1:
+;;;
+;;;            flush ruleset
+;;;            table inet foo {
+;;;                chain bar {
+;;;                    type filter hook input priority filter
+;;;                    policy drop
+;;;                    predicate [counter] [log] <accept|drop|reject>
+;;;                }
+;;;            }
+;;;
+;;;       Style #2 (everything at the "top level"):
+;;;
+;;;            flush ruleset
+;;;            add table inet foo
+;;;            add chain inet foo bar { type filter hook input priority 
filter; policy drop }
+;;;            add rule  inet foo bar predicate [counter] [log] 
<accept|drop|reject>
+(defvar nftables-font-lock-keywords
+  `(
+    ;; include "foo"
+    ;; list ruleset
+    ;; flush ruleset
+    (,(rx bol
+          (or "include"
+              "list ruleset"
+              "flush ruleset"
+              "list tables"
+              "list counters"
+              "list quotas")
+          eow)
+     . font-lock-preprocessor-face)
+
+    ;; define foo = bar
+    ;; define foo = { bar, baz }
+    ;; redefine foo = bar
+    ;; undefine foo
+    (,(rx bol
+          (group (or "define" "redefine" "undefine"))
+          " "
+          (group (one-or-more (any alnum ?_)))
+          eow)
+     (1 font-lock-type-face)
+     (2 font-lock-variable-name-face))
+
+    ;; add table inet my_table { ... }
+    ;; table inet my_table { ... }
+    (,(rx bol
+          (group (or "table"            ; style #1
+                     "add table"))      ; style #2
+          " "
+          ;; This is parser_bison.y:family_spec
+          (group (or "ip" "ip6" "inet" "arp" "bridge" "netdev"))
+          " "
+          (group (one-or-more (any alnum ?_)))
+          eow)
+     (1 font-lock-type-face)
+     (2 font-lock-constant-face)
+     (3 font-lock-variable-name-face))
+
+    ;;     chain my_chain {
+    ;;     set my_set {
+    ;;     map my_map {
+    (,(rx bol
+          (one-or-more blank)
+          (group (or "chain" "set" "map"))
+          " "
+          (group (one-or-more (any alnum ?_))))
+     (1 font-lock-type-face)
+     (2 font-lock-variable-name-face))
+
+    ;; add chain   inet my_table my_chain { ... }
+    ;; add set     inet my_table my_set { ... }
+    ;; add map     inet my_table my_map { ... }
+    ;; add rule    inet my_table my_chain ... <accept|drop|reject>
+    ;; add element inet my_table my_set { ... }
+    ;; add element inet my_table my_map { ... }
+    (,(rx bol
+          (group "add "
+                 (or "chain" "set" "map" "rule" "element"))
+          " "
+          (group (or "ip" "ip6" "inet" "arp" "bridge" "netdev"))
+          " "
+          (group (one-or-more (any alnum ?_)))
+          " "
+          (group (one-or-more (any alnum ?_)))
+          eow)
+     (1 font-lock-type-face)
+     (2 font-lock-constant-face)
+     (3 font-lock-variable-name-face)
+     (4 font-lock-variable-name-face))
+
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+    ;; REMAINING RULES NOT ANCHORED AT BEGINNING-OF-LINE
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+    ;; << chain specification >>
+    ;; { type filter hook input priority filter; }
+    (,(rx bow
+          (group "type")
+          " "
+          (group (or "filter" "nat" "route"))
+          " "
+          (group "hook")
+          " "
+          (group (or "prerouting"
+                     "input"
+                     "forward"
+                     "output"
+                     "postrouting"
+                     "ingress"
+                     "dormant"))
+          " "
+          (group "priority")
+          " "
+          (group (or (and (opt "-") (one-or-more digit))
+                     "raw"
+                     "mangle"
+                     "dstnat"
+                     "filter"
+                     "security"
+                     "srcnat"
+                     "dstnat"
+                     "filter"
+                     "out"
+                     "srcnat"))
+          eow)
+     (1 font-lock-type-face)
+     (3 font-lock-type-face)
+     (5 font-lock-type-face)
+     (2 font-lock-constant-face)
+     (4 font-lock-constant-face)
+     (6 font-lock-constant-face))
+
+    ;; << Table 8. Set specifications >>
+    ;; type x              # set
+    ;; type x : y          # map
+    ;; flags x , y , z     # set/map
+    ;; timeout 60s         # set
+    ;; gc-interval 12s     # set
+    ;; elements = { ... }  # set/map
+    ;; size 1000           # set/map
+    ;; auto-merge          # set
+    (,(rx bow
+          (group "type")
+          " "
+          (group (or "ipv4_addr" "ipv6_addr" "ether_addr" "inet_proto" 
"inet_service" "mark"))
+          (optional
+           " : "
+           (group (or "ipv4_addr" "ipv6_addr" "ether_addr" "inet_proto" 
"inet_service" "mark" "counter" "quota")))
+          eow)
+     (1 font-lock-type-face)
+     (2 font-lock-constant-face))
+    (,(rx bow
+          (group "flags")
+          " "
+          (group
+           (or "constant" "dynamic" "interval" "timeout")
+           (zero-or-more
+            ", "
+            (or "constant" "dynamic" "interval" "timeout")))
+          eow)
+     (1 font-lock-type-face)
+     (2 font-lock-constant-face))
+    (,(rx bow
+          (group (or "timeout" "gc-interval"))
+          " "
+          (group                        ; copied from scanner.l
+           (optional (one-or-more digit) "d")
+           (optional (one-or-more digit) "h")
+           (optional (one-or-more digit) "m")
+           (optional (one-or-more digit) "s")
+           (optional (one-or-more digit) "ms"))
+          eow)
+     (1 font-lock-type-face)
+     (2 font-lock-string-face))
+    (,(rx bow
+          (group "size")
+          " "
+          (group (one-or-more digit))
+          eow)
+     (1 font-lock-type-face)
+     (2 font-lock-string-face))
+    (,(rx bow
+          "auto-merge"
+          eow)
+     . font-lock-type-face)
+    (,(rx bow
+          (group "elements")
+          " = "
+          eow)
+     (1 font-lock-type-face))
+
+
+    ;; policy accept
+    ;; policy drop
+    (,(rx (group "policy") " " (group (or "accept" "drop")))
+     (1 font-lock-type-face)
+     (2 font-lock-function-name-face))
+
+    ;; $variable
+    ;; @array
+    (,(rx (or "@" "$")
+          alpha
+          (zero-or-more (any alnum ?_)))
+     . font-lock-variable-name-face)
+
+    ;; Simplified because scanner.l is INSANE for IPv6.
+    ;; 1234  (e.g. port number)
+    ;; 1.2.3.4
+    ;; ::1
+    (,(rx bow
+          (or
+           ;; IPv4 address (optional CIDR)
+           (and digit
+                (zero-or-more (any digit "."))
+                digit
+                (optional "/" (one-or-more digit)))
+           ;; IPv6 address (optional CIDR)
+           ;; Oops, this was matching "add"!
+           ;; WOW THIS IS REALLY REALLY HARD!
+           (and (zero-or-more (or (and (repeat 1 4 hex-digit) ":")
+                                  "::"))
+                (repeat 1 4 hex-digit)
+                (optional "/" (one-or-more digit)))
+           ;; Bare digits.
+           ;; Has to be after IPv4 address, or IPv4 address loses.
+           ;; (or (one-or-more digit))
+           )
+          eow)
+     . font-lock-string-face)
+
+
+    ;; parser_bison.y:family_spec_explicit
+    ;; (,(rx bow (or "ip" "ip6" "inet" "arp" "bridge" "netdev") eow)
+    ;;  . font-lock-constant-face)
+
+    ;; parser_bison.y:verdict_expr
+    (,(rx bow (or "accept" "drop" "continue" "return") eow)
+     . font-lock-function-name-face)
+    (,(rx bow (group (or "jump" "goto"))
+          " "
+          (group (one-or-more (any alnum ?_)))) ; chain_expr
+     (1 font-lock-function-name-face)
+     (2 font-lock-variable-name-face))
+
+
+    ))
+
+
+;;; Based on equivalent for other editors:
+;;;   * /usr/share/nano/nftables.nanorc
+;;;   * https://github.com/nfnty/vim-nftables
+;;;###autoload
+(define-derived-mode nftables-mode prog-mode "nft"
+  "FIXME docstring"
+  (setq-local comment-start "#")
+  (setq-local font-lock-defaults
+              `(nftables-font-lock-keywords nil nil))
+  ;; ;; make "table my_table {" result in indents on the next line.
+  ;; (setq-local electric-indent-chars ?\})
+  (setq-local indent-line-function #'nftables-indent-line)
+  (setq-local tab-width 4))
+
+;;; Stolen from parsnip's (bradyt's) dart-mode.
+;;; https://github.com/bradyt/dart-mode/blob/199709f7/dart-mode.el#L315
+(defun nftables-indent-line ()
+  (let (old-point)
+    (save-excursion
+      (back-to-indentation)
+      (let ((depth (car (syntax-ppss))))
+        (if (= ?\) (char-syntax (char-after)))
+            (setq depth (1- depth)))
+        (indent-line-to (* depth tab-width)))
+      (setq old-point (point)))
+    (when (< (point) old-point)
+      (back-to-indentation))))
+
+(add-to-list 'auto-mode-alist '("\\.nft\\(?:ables\\)?\\'" . nftables-mode))
+(add-to-list 'auto-mode-alist '("/etc/nftables.conf" . nftables-mode))
+(add-to-list 'interpreter-mode-alist '("nft\\(?:ables\\)?" . nftables-mode))
+
+(provide 'nftables-mode)



reply via email to

[Prev in Thread] Current Thread [Next in Thread]