Root/package/firewall/files/lib/core_interface.sh

1# Copyright (C) 2009-2010 OpenWrt.org
2
3fw__uci_state_add() {
4    local var="$1"
5    local item="$2"
6
7    local val=" $(uci_get_state firewall core $var) "
8    val="${val// $item / }"
9    val="${val# }"
10    val="${val% }"
11    uci_revert_state firewall core $var
12    uci_set_state firewall core $var "${val:+$val }$item"
13}
14
15fw__uci_state_del() {
16    local var="$1"
17    local item="$2"
18
19    local val=" $(uci_get_state firewall core $var) "
20    val="${val// $item / }"
21    val="${val# }"
22    val="${val% }"
23    uci_revert_state firewall core $var
24    uci_set_state firewall core $var "$val"
25}
26
27fw_configure_interface() {
28    local iface=$1
29    local action=$2
30    local ifname=$3
31    local aliasnet=$4
32
33    [ "$action" == "add" ] && {
34        local status=$(uci_get_state network "$iface" up 0)
35        [ "$status" == 1 ] || [ -n "$aliasnet" ] || return 0
36    }
37
38    [ -n "$ifname" ] || {
39        ifname=$(uci_get_state network "$iface" ifname)
40        ifname="${ifname%%:*}"
41        [ -z "$ifname" ] && return 0
42    }
43
44    [ "$ifname" == "lo" ] && return 0
45
46    fw_callback pre interface
47
48    fw__do_rules() {
49        local action=$1
50        local zone=$2
51        local chain=zone_${zone}
52        local ifname=$3
53        local subnet=$4
54
55        local inet onet mode
56        fw_get_family_mode mode x $zone i
57
58        case "$mode/$subnet" in
59            # Zone supports v6 only or dual, need v6
60            G6/*:*|i/*:*)
61                inet="-s $subnet -d ::/0"
62                onet="-s ::/0 -d $subnet"
63                mode=6
64            ;;
65
66            # Zone supports v4 only or dual, need v4
67            G4/*.*.*.*|i/*.*.*.*)
68                inet="-s $subnet -d 0.0.0.0/0"
69                onet="-s 0.0.0.0/0 -d $subnet"
70                mode=4
71            ;;
72
73            # Need v6 while zone is v4
74            */*:*) fw_log info "zone $zone does not support IPv6 address family, skipping"; return ;;
75
76            # Need v4 while zone is v6
77            */*.*) fw_log info "zone $zone does not support IPv4 address family, skipping"; return ;;
78
79            # Strip prefix
80            *) mode="${mode#G}" ;;
81        esac
82
83        lock /var/run/firewall-interface.lock
84
85        fw $action $mode f ${chain}_ACCEPT ACCEPT $ { -o "$ifname" $onet }
86        fw $action $mode f ${chain}_ACCEPT ACCEPT $ { -i "$ifname" $inet }
87        fw $action $mode f ${chain}_DROP DROP $ { -o "$ifname" $onet }
88        fw $action $mode f ${chain}_DROP DROP $ { -i "$ifname" $inet }
89        fw $action $mode f ${chain}_REJECT reject $ { -o "$ifname" $onet }
90        fw $action $mode f ${chain}_REJECT reject $ { -i "$ifname" $inet }
91
92        fw $action $mode f ${chain}_MSSFIX TCPMSS $ { -o "$ifname" -p tcp --tcp-flags SYN,RST SYN --clamp-mss-to-pmtu $onet }
93
94        fw $action $mode f input ${chain} $ { -i "$ifname" $inet }
95        fw $action $mode f forward ${chain}_forward $ { -i "$ifname" $inet }
96        fw $action $mode n PREROUTING ${chain}_prerouting $ { -i "$ifname" $inet }
97        fw $action $mode r PREROUTING ${chain}_notrack $ { -i "$ifname" $inet }
98        fw $action $mode n POSTROUTING ${chain}_nat $ { -o "$ifname" $onet }
99
100        lock -u /var/run/firewall-interface.lock
101    }
102
103    local old_zones old_ifname old_subnets
104    config_get old_zones core "${iface}_zone"
105    [ -n "$old_zones" ] && {
106        config_get old_ifname core "${iface}_ifname"
107        config_get old_subnets core "${iface}_subnets"
108
109        local z
110        for z in $old_zones; do
111            local n
112            for n in ${old_subnets:-""}; do
113                fw_log info "removing $iface ($old_ifname${n:+ alias $n}) from zone $z"
114                fw__do_rules del $z $old_ifname $n
115            done
116
117            [ -n "$old_subnets" ] || {
118                fw__uci_state_del "${z}_networks" "$iface"
119                env -i ACTION=remove ZONE="$z" INTERFACE="$iface" DEVICE="$ifname" /sbin/hotplug-call firewall
120            }
121        done
122
123        local old_aliases
124        config_get old_aliases core "${iface}_aliases"
125
126        local a
127        for a in $old_aliases; do
128            fw_configure_interface "$a" del "$old_ifname"
129        done
130
131        uci_revert_state firewall core "${iface}_zone"
132        uci_revert_state firewall core "${iface}_ifname"
133        uci_revert_state firewall core "${iface}_subnets"
134        uci_revert_state firewall core "${iface}_aliases"
135    }
136
137    [ "$action" == del ] && return
138
139    [ -z "$aliasnet" ] && {
140        local aliases
141        config_get aliases "$iface" aliases
142
143        local a
144        for a in $aliases; do
145            local ipaddr netmask ip6addr
146            config_get ipaddr "$a" ipaddr
147            config_get netmask "$a" netmask
148            config_get ip6addr "$a" ip6addr
149
150            [ -n "$ipaddr" ] && fw_configure_interface "$a" add "" "$ipaddr${netmask:+/$netmask}"
151            [ -n "$ip6addr" ] && fw_configure_interface "$a" add "" "$ip6addr"
152        done
153
154        fw_sysctl_interface $ifname
155        fw_callback post interface
156
157        uci_set_state firewall core "${iface}_aliases" "$aliases"
158    } || {
159        local subnets=
160        config_get subnets core "${iface}_subnets"
161        append subnets "$aliasnet"
162
163        config_set core "${iface}_subnets" "$subnets"
164        uci_set_state firewall core "${iface}_subnets" "$subnets"
165    }
166
167    local new_zones=
168    load_zone() {
169        fw_config_get_zone "$1"
170        list_contains zone_network "$iface" || return
171
172        fw_log info "adding $iface ($ifname${aliasnet:+ alias $aliasnet}) to zone $zone_name"
173        fw__do_rules add ${zone_name} "$ifname" "$aliasnet"
174        append new_zones $zone_name
175
176        [ -n "$aliasnet" ] || {
177            fw__uci_state_add "${zone_name}_networks" "${zone_network}"
178            env -i ACTION=add ZONE="$zone_name" INTERFACE="$iface" DEVICE="$ifname" /sbin/hotplug-call firewall
179        }
180    }
181    config_foreach load_zone zone
182
183    uci_set_state firewall core "${iface}_zone" "$new_zones"
184    uci_set_state firewall core "${iface}_ifname" "$ifname"
185}
186
187fw_sysctl_interface() {
188    local ifname=$1
189    {
190        sysctl -w net.ipv4.conf.${ifname}.accept_redirects=$FW_ACCEPT_REDIRECTS
191        sysctl -w net.ipv6.conf.${ifname}.accept_redirects=$FW_ACCEPT_REDIRECTS
192        sysctl -w net.ipv4.conf.${ifname}.accept_source_route=$FW_ACCEPT_SRC_ROUTE
193        sysctl -w net.ipv6.conf.${ifname}.accept_source_route=$FW_ACCEPT_SRC_ROUTE
194    } >/dev/null 2>/dev/null
195}
196
197

Archive Download this file



interactive