diff --git a/net/netfilter/nf_nat_sip.c b/net/netfilter/nf_nat_sip.c index f0a735e86851..8274b85aa298 100644 --- a/net/netfilter/nf_nat_sip.c +++ b/net/netfilter/nf_nat_sip.c @@ -113,13 +113,26 @@ static int map_addr(struct sk_buff *skb, unsigned int protoff, newaddr = ct->tuplehash[!dir].tuple.src.u3; newport = ct_sip_info->forced_dport ? : ct->tuplehash[!dir].tuple.src.u.udp.port; + } else if (nf_inet_addr_cmp(&ct->tuplehash[dir].tuple.src.u3, addr) && + ct->tuplehash[dir].tuple.src.u.udp.port != port) { + newaddr = ct->tuplehash[!dir].tuple.dst.u3; + newport = 0; + } else if (nf_inet_addr_cmp(&ct->tuplehash[dir].tuple.dst.u3, addr) && + ct->tuplehash[dir].tuple.dst.u.udp.port != port) { + newaddr = ct->tuplehash[!dir].tuple.src.u3; + newport = 0; } else return 1; if (nf_inet_addr_cmp(&newaddr, addr) && newport == port) return 1; - buflen = sip_sprintf_addr_port(ct, buffer, &newaddr, ntohs(newport)); + if (newport == 0) + buflen = sip_sprintf_addr(ct, buffer, &newaddr, false); + else + buflen = sip_sprintf_addr_port(ct, buffer, &newaddr, + ntohs(newport)); + return mangle_packet(skb, protoff, dataoff, dptr, datalen, matchoff, matchlen, buffer, buflen); }