fw4: prefer /dev/stdin if available
[project/firewall4.git] / root / sbin / fw4
1 #!/bin/sh
2
3 set -o pipefail
4
5 MAIN=/usr/share/firewall4/main.uc
6 LOCK=/var/run/fw4.lock
7 STATE=/var/run/fw4.state
8 VERBOSE=
9
10 [ -e /dev/stdin ] && STDIN=/dev/stdin || STDIN=/proc/self/fd/0
11
12 [ -t 2 ] && export TTY=1
13
14 die() {
15 [ -n "$QUIET" ] || echo "$@" >&2
16 exit 1
17 }
18
19 start() {
20 {
21 flock -x 1000
22
23 case "$1" in
24 start)
25 [ -f $STATE ] && die "The fw4 firewall appears to be already loaded."
26 ;;
27 reload)
28 [ ! -f $STATE ] && die "The fw4 firewall does not appear to be loaded."
29
30 # Delete state to force reloading ubus state
31 rm -f $STATE
32 ;;
33 esac
34
35 ACTION=start \
36 utpl -S $MAIN | nft $VERBOSE -f $STDIN
37 } 1000>$LOCK
38 }
39
40 print() {
41 ACTION=print \
42 utpl -S $MAIN
43 }
44
45 stop() {
46 {
47 flock -x 1000
48
49 if nft list tables inet | grep -sq "table inet fw4"; then
50 nft delete table inet fw4
51 rm -f $STATE
52 else
53 return 1
54 fi
55 } 1000>$LOCK
56 }
57
58 flush() {
59 {
60 flock -x 1000
61
62 local dummy family table
63 nft list tables | while read dummy family table; do
64 nft delete table "$family" "$table"
65 done
66
67 rm -f $STATE
68 } 1000>$LOCK
69 }
70
71 reload_sets() {
72 ACTION=reload-sets \
73 flock -x $LOCK utpl -S $MAIN | nft $VERBOSE -f $STDIN
74 }
75
76 lookup() {
77 ACTION=$1 OBJECT=$2 DEVICE=$3 \
78 flock -x $LOCK utpl -S $MAIN
79 }
80
81 while [ -n "$1" ]; do
82 case "$1" in
83 -q)
84 export QUIET=1
85 shift
86 ;;
87 -v)
88 export VERBOSE=-e
89 shift
90 ;;
91 *)
92 break
93 ;;
94 esac
95 done
96
97 case "$1" in
98 start|reload)
99 start "$1"
100 ;;
101 stop)
102 stop || die "The fw4 firewall does not appear to be loaded, try fw4 flush to delete all rules."
103 ;;
104 flush)
105 flush
106 ;;
107 restart)
108 stop || rm -f $STATE
109 start
110 ;;
111 print)
112 print
113 ;;
114 reload-sets)
115 reload_sets
116 ;;
117 network|device|zone)
118 lookup "$@"
119 ;;
120 *)
121 cat <<EOT
122 Usage:
123
124 $0 [-v] [-q] start|stop|flush|restart|reload
125
126 Start, stop, flush, restart or reload the firewall respectively.
127
128
129 $0 [-v] [-q] reload-sets
130
131 Reload the contents of all declared sets but do not touch the
132 ruleset.
133
134
135 $0 [-q] print
136
137 Print the rendered ruleset.
138
139
140 $0 [-q] network {net}
141
142 Print the name of the firewall zone covering the given network.
143
144 Exits with code 1 if the network is not found or if no zone is
145 covering it.
146
147
148 $0 [-q] device {dev}
149
150 Print the name of the firewall zone covering the given device.
151
152 Exits with code 1 if the device is not found or if no zone is
153 covering it.
154
155
156 $0 [-q] zone {zone} [dev]
157
158 Print all covered devices of the given zone, optionally restricted
159 to only the given device name.
160
161 Exits with code 1 if zone is not found or if a device is specified
162 and not covered by the given zone.
163
164 EOT
165 ;;
166 esac