core_interface.sh 5.6 KB

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