fw4: fix emitting device jump rules for family restricted zones
[project/firewall4.git] / root / usr / share / firewall4 / main.uc
1 {%
2
3 let fw4 = require("fw4");
4
5 function read_state() {
6 let state = fw4.read_state();
7
8 if (!state) {
9 warn("Unable to read firewall state - do you need to start the firewall?\n");
10 exit(1);
11 }
12
13 return state;
14 }
15
16 function reload_sets() {
17 let state = read_state(),
18 sets = fw4.check_set_types();
19
20 for (let set in state.ipsets) {
21 if (!set.loadfile || !length(set.entries))
22 continue;
23
24 if (!exists(sets, set.name)) {
25 warn(sprintf("Named set '%s' does not exist - do you need to restart the firewall?\n",
26 set.name));
27 continue;
28 }
29 else if (fw4.concat(sets[set.name]) != fw4.concat(set.types)) {
30 warn(sprintf("Named set '%s' has a different type - want '%s' but is '%s' - do you need to restart the firewall?\n",
31 set.name, fw4.concat(set.types), fw4.concat(sets[set.name])));
32 continue;
33 }
34
35 let first = true;
36 let printer = (entry) => {
37 if (first) {
38 print("add element inet fw4 ", set.name, " {\n");
39 first = false;
40 }
41
42 print("\t", join(" . ", entry), ",\n");
43 };
44
45 print("flush set inet fw4 ", set.name, "\n");
46
47 map(set.entries, printer);
48 fw4.parse_setfile(set, printer);
49
50 if (!first)
51 print("}\n\n");
52 }
53 }
54
55 function render_ruleset(use_statefile) {
56 fw4.load(use_statefile);
57
58 include("templates/ruleset.uc", { fw4, type, exists, length, include });
59 }
60
61 function lookup_network(net) {
62 let state = read_state();
63
64 for (let zone in state.zones) {
65 for (let network in (zone.network || [])) {
66 if (network.device == net) {
67 print(zone.name, "\n");
68 exit(0);
69 }
70 }
71 }
72
73 exit(1);
74 }
75
76 function lookup_device(dev) {
77 let state = read_state();
78
79 for (let zone in state.zones) {
80 for (let rule in (zone.match_rules || [])) {
81 if (dev in rule.devices_pos) {
82 print(zone.name, "\n");
83 exit(0);
84 }
85 }
86 }
87
88 exit(1);
89 }
90
91 function lookup_zone(name, dev) {
92 let state = read_state();
93
94 for (let zone in state.zones) {
95 if (zone.name == name) {
96 let devices = [];
97 map(zone.match_rules, (r) => push(devices, ...(r.devices_pos || [])));
98
99 if (dev) {
100 if (dev in devices) {
101 print(dev, "\n");
102 exit(0);
103 }
104
105 exit(1);
106 }
107
108 if (length(devices))
109 print(join("\n", devices), "\n");
110
111 exit(0);
112 }
113 }
114
115 exit(1);
116 }
117
118
119 switch (getenv("ACTION")) {
120 case "start":
121 return render_ruleset(true);
122
123 case "print":
124 return render_ruleset(false);
125
126 case "reload-sets":
127 return reload_sets();
128
129 case "network":
130 return lookup_network(getenv("OBJECT"));
131
132 case "device":
133 return lookup_device(getenv("OBJECT"));
134
135 case "zone":
136 return lookup_zone(getenv("OBJECT"), getenv("DEVICE"));
137 }