core_interface.sh 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203
  1. # Copyright (C) 2009-2011 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 "$val"
  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. fw $action $mode f ${chain}_MSSFIX TCPMSS $ { -o "$ifname" -p tcp --tcp-flags SYN,RST SYN --clamp-mss-to-pmtu $onet }
  79. fw $action $mode f input ${chain} $ { -i "$ifname" $inet }
  80. fw $action $mode f forward ${chain}_forward $ { -i "$ifname" $inet }
  81. fw $action $mode n PREROUTING ${chain}_prerouting $ { -i "$ifname" $inet }
  82. fw $action $mode r PREROUTING ${chain}_notrack $ { -i "$ifname" $inet }
  83. fw $action $mode n POSTROUTING ${chain}_nat $ { -o "$ifname" $onet }
  84. lock -u /var/run/firewall-interface.lock
  85. }
  86. local old_zones old_ifname old_subnets
  87. config_get old_zones core "${iface}_zone"
  88. [ -n "$old_zones" ] && {
  89. config_get old_ifname core "${iface}_ifname"
  90. config_get old_subnets core "${iface}_subnets"
  91. local z
  92. for z in $old_zones; do
  93. local n
  94. for n in ${old_subnets:-""}; do
  95. fw_log info "removing $iface ($old_ifname${n:+ alias $n}) from zone $z"
  96. fw__do_rules del $z $old_ifname $n
  97. done
  98. [ -n "$old_subnets" ] || {
  99. fw__uci_state_del "${z}_networks" "$iface"
  100. env -i ACTION=remove ZONE="$z" INTERFACE="$iface" DEVICE="$ifname" /sbin/hotplug-call firewall
  101. }
  102. done
  103. local old_aliases
  104. config_get old_aliases core "${iface}_aliases"
  105. local a
  106. for a in $old_aliases; do
  107. fw_configure_interface "$a" del "$old_ifname"
  108. done
  109. uci_revert_state firewall core "${iface}_zone"
  110. uci_revert_state firewall core "${iface}_ifname"
  111. uci_revert_state firewall core "${iface}_subnets"
  112. uci_revert_state firewall core "${iface}_aliases"
  113. }
  114. [ "$action" == del ] && return
  115. [ -z "$aliasnet" ] && {
  116. local aliases
  117. config_get aliases "$iface" aliases
  118. local a
  119. for a in $aliases; do
  120. local ipaddr netmask ip6addr
  121. config_get ipaddr "$a" ipaddr
  122. config_get netmask "$a" netmask
  123. config_get ip6addr "$a" ip6addr
  124. [ -n "$ipaddr" ] && fw_configure_interface "$a" add "" "$ipaddr${netmask:+/$netmask}"
  125. [ -n "$ip6addr" ] && fw_configure_interface "$a" add "" "$ip6addr"
  126. done
  127. fw_sysctl_interface $ifname
  128. fw_callback post interface
  129. uci_toggle_state firewall core "${iface}_aliases" "$aliases"
  130. } || {
  131. local subnets=
  132. config_get subnets core "${iface}_subnets"
  133. append subnets "$aliasnet"
  134. config_set core "${iface}_subnets" "$subnets"
  135. uci_toggle_state firewall core "${iface}_subnets" "$subnets"
  136. }
  137. local new_zones=
  138. load_zone() {
  139. fw_config_get_zone "$1"
  140. list_contains zone_network "$iface" || return
  141. fw_log info "adding $iface ($ifname${aliasnet:+ alias $aliasnet}) to zone $zone_name"
  142. fw__do_rules add ${zone_name} "$ifname" "$aliasnet"
  143. append new_zones $zone_name
  144. [ -n "$aliasnet" ] || {
  145. fw__uci_state_add "${zone_name}_networks" "${zone_network}"
  146. env -i ACTION=add ZONE="$zone_name" INTERFACE="$iface" DEVICE="$ifname" /sbin/hotplug-call firewall
  147. }
  148. }
  149. config_foreach load_zone zone
  150. uci_toggle_state firewall core "${iface}_zone" "$new_zones"
  151. uci_toggle_state firewall core "${iface}_ifname" "$ifname"
  152. }
  153. fw_sysctl_interface() {
  154. local ifname=$1
  155. {
  156. sysctl -w net.ipv4.conf.${ifname}.accept_redirects=$FW_ACCEPT_REDIRECTS
  157. sysctl -w net.ipv6.conf.${ifname}.accept_redirects=$FW_ACCEPT_REDIRECTS
  158. sysctl -w net.ipv4.conf.${ifname}.accept_source_route=$FW_ACCEPT_SRC_ROUTE
  159. sysctl -w net.ipv6.conf.${ifname}.accept_source_route=$FW_ACCEPT_SRC_ROUTE
  160. } >/dev/null 2>/dev/null
  161. }