| 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_port "" \ |
| 17 | string proto "tcpudp" \ |
| 18 | string family "" \ |
| 19 | string target "DNAT" \ |
| 20 | string extra "" \ |
| 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}${redirect_dest_ip:+_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 | fw_get_negation srcdports '--dport' "$srcdports" |
| 47 | |
| 48 | list_contains FW_CONNTRACK_ZONES $redirect_src || \ |
| 49 | append FW_CONNTRACK_ZONES $redirect_src |
| 50 | |
| 51 | elif [ "$redirect_target" == "SNAT" ]; then |
| 52 | [ -n "${redirect_dest#*}" -a -n "$redirect_src_dip" ] || { |
| 53 | fw_log error "SNAT redirect ${redirect_name}: needs dest and src_dip, skipping" |
| 54 | return 0 |
| 55 | } |
| 56 | |
| 57 | fwdchain="${redirect_src:+zone_${redirect_src}_forward}" |
| 58 | |
| 59 | natopt="--to-source" |
| 60 | natchain="zone_${redirect_dest}_nat" |
| 61 | nataddr="$redirect_src_dip" |
| 62 | fw_get_port_range natports "${redirect_src_dport#!}" "-" |
| 63 | |
| 64 | fw_get_negation srcdaddr '-d' "${redirect_dest_ip:+$redirect_dest_ip/$redirect_dest_ip_prefixlen}" |
| 65 | fw_get_port_range srcdports "$redirect_dest_port" ":" |
| 66 | fw_get_negation srcdports '--dport' "$srcdports" |
| 67 | |
| 68 | list_contains FW_CONNTRACK_ZONES $redirect_dest || \ |
| 69 | append FW_CONNTRACK_ZONES $redirect_dest |
| 70 | |
| 71 | else |
| 72 | fw_log error "redirect ${redirect_name}: target must be either DNAT or SNAT, skipping" |
| 73 | return 0 |
| 74 | fi |
| 75 | |
| 76 | local mode |
| 77 | fw_get_family_mode mode ${redirect_family:-x} ${redirect_src:-$redirect_dest} I |
| 78 | |
| 79 | local srcaddr |
| 80 | fw_get_negation srcaddr '-s' "${redirect_src_ip:+$redirect_src_ip/$redirect_src_ip_prefixlen}" |
| 81 | |
| 82 | local srcports |
| 83 | fw_get_port_range srcports "$redirect_src_port" ":" |
| 84 | fw_get_negation srcports '--sport' "$srcports" |
| 85 | |
| 86 | local destaddr |
| 87 | fw_get_negation destaddr '-d' "${redirect_dest_ip:+$redirect_dest_ip/$redirect_dest_ip_prefixlen}" |
| 88 | |
| 89 | local destports |
| 90 | fw_get_port_range destports "${redirect_dest_port:-$redirect_src_dport}" ":" |
| 91 | fw_get_negation destports '--dport' "$destports" |
| 92 | |
| 93 | [ "$redirect_proto" == "tcpudp" ] && redirect_proto="tcp udp" |
| 94 | local pr; for pr in $redirect_proto; do |
| 95 | fw_get_negation pr '-p' "$pr" |
| 96 | local sm; for sm in ${redirect_src_mac:-""}; do |
| 97 | fw_get_negation sm '--mac-source' "$sm" |
| 98 | fw add $mode n $natchain $redirect_target + \ |
| 99 | { $redirect_src_ip $redirect_dest_ip } { \ |
| 100 | $srcaddr $srcdaddr $pr \ |
| 101 | $srcports $srcdports \ |
| 102 | ${sm:+-m mac $sm} \ |
| 103 | $natopt $nataddr${natports:+:$natports} \ |
| 104 | $redirect_options \ |
| 105 | } |
| 106 | |
| 107 | fw add $mode f ${fwdchain:-forward} ACCEPT + \ |
| 108 | { $redirect_src_ip $redirect_dest_ip } { \ |
| 109 | $srcaddr ${destaddr:--m conntrack --ctstate DNAT} \ |
| 110 | $pr \ |
| 111 | $srcports $destports \ |
| 112 | ${sm:+-m mac $sm} \ |
| 113 | $redirect_extra \ |
| 114 | } |
| 115 | done |
| 116 | done |
| 117 | |
| 118 | fw_callback post redirect |
| 119 | } |
| 120 | |