#!/usr/bin/lua

local uci = require('simple-uci').cursor()


local defaults = uci:get_first('firewall', 'defaults')
uci:set('firewall', defaults, 'input', 'REJECT')


local function reject_input_on_wan(zone)
	if zone.name == 'wan' then
		uci:set('firewall', zone['.name'], 'input', 'REJECT')
		uci:set('firewall', zone['.name'], 'conntrack', true)
	end

	return true
end

uci:foreach('firewall', 'zone', reject_input_on_wan)

for _, zone in ipairs({'mesh', 'local_client', 'wired_mesh'}) do
	-- Other packages assign interfaces to these zones
	uci:section('firewall', 'zone', zone, {
		name = zone,
		network = {},
		input = 'REJECT',
		output = 'ACCEPT',
		forward = 'REJECT',
	})

	uci:section('firewall', 'rule', zone .. '_ICMPv6_in', {
		src = zone,
		proto = 'icmp',
		icmp_type = {
			'echo-request',
			'echo-reply',
			'destination-unreachable',
			'packet-too-big',
			'time-exceeded',
			'bad-header',
			'unknown-header-type',
			'router-solicitation',
			'neighbour-solicitation',
			'router-advertisement',
			'neighbour-advertisement',
			'130/0', -- Multicast Listener Query
			'131/0', -- Multicast Listener Report
			'132/0', -- Multicast Listener Done
			'143/0', -- MLDv2
		},
		limit = '1000/sec',
		family = 'ipv6',
		target = 'ACCEPT',
	})

	-- Can be removed soon: was never in a release
	uci:delete('firewall', zone .. '_ICMPv6_out')
end

uci:section('firewall', 'rule', 'local_client_ICMPv4_in', {
	src = 'local_client',
	proto = 'icmp',
	icmp_type = {
		'echo-request',
	},
	family = 'ipv4',
	target = 'ACCEPT',
})


-- allow inbound SSH from anywhere
for _, zone in ipairs({ 'wan', 'local_client', 'mesh' }) do
	uci:section('firewall', 'rule', zone .. '_ssh', {
		name =  zone .. '_ssh',
		src = zone,
		dest_port = '22',
		proto = 'tcp',
		target = 'ACCEPT',
	})
end


-- We can't put mesh_wan into this zone, as mesh_wan is the same
-- interface as wan, which has its own zone
uci:set('firewall', 'wired_mesh', 'network', {'mesh_lan'})

-- VXLAN for wired meshing
for _, zone in ipairs({'wired_mesh', 'wan'}) do
	uci:section('firewall', 'rule', zone .. '_vxlan', {
		name =  zone .. '_vxlan',
		src = zone,
		family = 'ipv6',
		src_ip = 'fe80::/64',
		proto = 'udp',
		dest_port = '4789',
		target = 'ACCEPT',
	})
	uci:reorder('firewall', zone .. '_vxlan', 0)
end


uci:save('firewall')
