| 1 | # Copyright (C) 2009-2010 OpenWrt.org |
| 2 | |
| 3 | fw_config_get_redirect() { |
| 4 | [ "${redirect_NAME}" != "$1" ] || return |
| 5 | fw_config_get_section "$1" redirect { \ |
| 6 | string _name "$1" \ |
| 7 | string name "" \ |
| 8 | string src "" \ |
| 9 | ipaddr src_ip "" \ |
| 10 | ipaddr src_dip "" \ |
| 11 | string src_mac "" \ |
| 12 | string src_port "" \ |
| 13 | string src_dport "" \ |
| 14 | string dest "" \ |
| 15 | ipaddr dest_ip "" \ |
| 16 | string dest_mac "" \ |
| 17 | string dest_port "" \ |
| 18 | string proto "tcpudp" \ |
| 19 | string family "" \ |
| 20 | string target "DNAT" \ |
| 21 | } || return |
| 22 | [ -n "$redirect_name" ] || redirect_name=$redirect__name |
| 23 | } |
| 24 | |
| 25 | fw_load_redirect() { |
| 26 | fw_config_get_redirect "$1" |
| 27 | |
| 28 | fw_callback pre redirect |
| 29 | |
| 30 | local fwdchain natchain natopt nataddr natports srcdaddr srcdports |
| 31 | if [ "$redirect_target" == "DNAT" ]; then |
| 32 | [ -n "$redirect_src" -a -n "$redirect_dest_ip$redirect_dest_port" ] || { |
| 33 | fw_log error "DNAT redirect ${redirect_name}: needs src and dest_ip or dest_port, skipping" |
| 34 | return 0 |
| 35 | } |
| 36 | |
| 37 | fwdchain="zone_${redirect_src}_forward" |
| 38 | |
| 39 | natopt="--to-destination" |
| 40 | natchain="zone_${redirect_src}_prerouting" |
| 41 | nataddr="$redirect_dest_ip" |
| 42 | fw_get_port_range natports "$redirect_dest_port" "-" |
| 43 | |
| 44 | fw_get_negation srcdaddr '-d' "${redirect_src_dip:+$redirect_src_dip/$redirect_src_dip_prefixlen}" |
| 45 | fw_get_port_range srcdports "$redirect_src_dport" ":" |
| 46 | |
| 47 | list_contains FW_CONNTRACK_ZONES $redirect_src || \ |
| 48 | append FW_CONNTRACK_ZONES $redirect_src |
| 49 | |
| 50 | elif [ "$redirect_target" == "SNAT" ]; then |
| 51 | [ -n "$redirect_dest" -a -n "$redirect_src_dip" ] || { |
| 52 | fw_log error "SNAT redirect ${redirect_name}: needs dest and src_dip, skipping" |
| 53 | return 0 |
| 54 | } |
| 55 | |
| 56 | fwdchain="${redirect_src:+zone_${redirect_src}_forward}" |
| 57 | |
| 58 | natopt="--to-source" |
| 59 | natchain="zone_${redirect_dest}_nat" |
| 60 | nataddr="$redirect_src_dip" |
| 61 | fw_get_port_range natports "$redirect_src_dport" "-" |
| 62 | |
| 63 | fw_get_negation srcdaddr '-d' "${redirect_dest_ip:+$redirect_dest_ip/$redirect_dest_ip_prefixlen}" |
| 64 | fw_get_port_range srcdports "$redirect_dest_port" ":" |
| 65 | |
| 66 | list_contains FW_CONNTRACK_ZONES $redirect_dest || \ |
| 67 | append FW_CONNTRACK_ZONES $redirect_dest |
| 68 | |
| 69 | else |
| 70 | fw_log error "redirect ${redirect_name}: target must be either DNAT or SNAT, skipping" |
| 71 | return 0 |
| 72 | fi |
| 73 | |
| 74 | local mode |
| 75 | fw_get_family_mode mode ${redirect_family:-x} ${redirect_src:-$redirect_dest} I |
| 76 | |
| 77 | local srcaddr |
| 78 | fw_get_negation srcaddr '-s' "${redirect_src_ip:+$redirect_src_ip/$redirect_src_ip_prefixlen}" |
| 79 | |
| 80 | local srcports |
| 81 | fw_get_port_range srcports "$redirect_src_port" ":" |
| 82 | |
| 83 | local destaddr |
| 84 | fw_get_negation destaddr '-d' "${redirect_dest_ip:+$redirect_dest_ip/$redirect_dest_ip_prefixlen}" |
| 85 | |
| 86 | local destports |
| 87 | fw_get_port_range destports "${redirect_dest_port:-$redirect_src_dport}" ":" |
| 88 | |
| 89 | [ "$redirect_proto" == "tcpudp" ] && redirect_proto="tcp udp" |
| 90 | for redirect_proto in $redirect_proto; do |
| 91 | local pos |
| 92 | eval 'pos=$((++FW__REDIR_COUNT_'${mode#G}'_'$natchain'))' |
| 93 | |
| 94 | fw add $mode n $natchain $redirect_target $pos { $redirect_src_ip $redirect_dest_ip } { \ |
| 95 | $srcaddr $srcdaddr \ |
| 96 | ${redirect_proto:+-p $redirect_proto} \ |
| 97 | ${srcports:+--sport $srcports} \ |
| 98 | ${srcdports:+--dport $srcdports} \ |
| 99 | ${redirect_src_mac:+-m mac --mac-source $redirect_src_mac} \ |
| 100 | $natopt $nataddr${natports:+:$natports} \ |
| 101 | } |
| 102 | |
| 103 | [ -n "$destaddr" ] && \ |
| 104 | fw add $mode f ${fwdchain:-forward} ACCEPT ^ { $redirect_src_ip $redirect_dest_ip } { \ |
| 105 | $srcaddr $destaddr \ |
| 106 | ${redirect_proto:+-p $redirect_proto} \ |
| 107 | ${srcports:+--sport $srcports} \ |
| 108 | ${destports:+--dport $destports} \ |
| 109 | ${redirect_src_mac:+-m mac --mac-source $redirect_src_mac} \ |
| 110 | } |
| 111 | done |
| 112 | |
| 113 | fw_callback post redirect |
| 114 | } |
| 115 | |