diff options
author | Patrick McHardy <kaber@trash.net> | 2006-05-29 21:26:47 -0400 |
---|---|---|
committer | David S. Miller <davem@sunset.davemloft.net> | 2006-06-18 00:29:13 -0400 |
commit | e44ab66a75e20c02193440a5e27c16c91630109b (patch) | |
tree | 13aa30980b223b19720ff5d864d43e3708339fdc | |
parent | c0d4cfd96dd0cc0dbf49435898808b5553af4822 (diff) |
[NETFILTER]: H.323 helper: replace internal_net_addr parameter by routing-based heuristic
Call Forwarding doesn't need to create an expectation if both peers can
reach each other without our help. The internal_net_addr parameter
lets the user explicitly specify a single network where this is true,
but is not very flexible and even fails in the common case that calls
will both be forwarded to outside parties and inside parties. Use an
optional heuristic based on routing instead, the assumption is that
if bpth the outgoing device and the gateway are equal, both peers can
reach each other directly.
Signed-off-by: Patrick McHardy <kaber@trash.net>
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | net/ipv4/netfilter/ip_conntrack_helper_h323.c | 57 |
1 files changed, 27 insertions, 30 deletions
diff --git a/net/ipv4/netfilter/ip_conntrack_helper_h323.c b/net/ipv4/netfilter/ip_conntrack_helper_h323.c index 3052468a6ab1..0665674218c6 100644 --- a/net/ipv4/netfilter/ip_conntrack_helper_h323.c +++ b/net/ipv4/netfilter/ip_conntrack_helper_h323.c | |||
@@ -40,12 +40,11 @@ static int gkrouted_only = 1; | |||
40 | module_param(gkrouted_only, int, 0600); | 40 | module_param(gkrouted_only, int, 0600); |
41 | MODULE_PARM_DESC(gkrouted_only, "only accept calls from gatekeeper"); | 41 | MODULE_PARM_DESC(gkrouted_only, "only accept calls from gatekeeper"); |
42 | 42 | ||
43 | static char *internal_net = NULL; | 43 | static int callforward_filter = 1; |
44 | static u_int32_t internal_net_addr = 0; | 44 | module_param(callforward_filter, bool, 0600); |
45 | static u_int32_t internal_net_mask = 0; | 45 | MODULE_PARM_DESC(callforward_filter, "only create call forwarding expectations " |
46 | module_param(internal_net, charp, 0600); | 46 | "if both endpoints are on different sides " |
47 | MODULE_PARM_DESC(internal_net, "specify your internal network using format " | 47 | "(determined by routing information)"); |
48 | "address/mask. this is used by call forwarding support"); | ||
49 | 48 | ||
50 | /* Hooks for NAT */ | 49 | /* Hooks for NAT */ |
51 | int (*set_h245_addr_hook) (struct sk_buff ** pskb, | 50 | int (*set_h245_addr_hook) (struct sk_buff ** pskb, |
@@ -721,12 +720,28 @@ static int expect_callforwarding(struct sk_buff **pskb, | |||
721 | 720 | ||
722 | /* If the calling party is on the same side of the forward-to party, | 721 | /* If the calling party is on the same side of the forward-to party, |
723 | * we don't need to track the second call */ | 722 | * we don't need to track the second call */ |
724 | if (internal_net && | 723 | if (callforward_filter) { |
725 | ((ip & internal_net_mask) == internal_net_addr) == | 724 | struct rtable *rt1, *rt2; |
726 | ((ct->tuplehash[!dir].tuple.src.ip & internal_net_mask) == | 725 | struct flowi fl1 = { |
727 | internal_net_addr)) { | 726 | .fl4_dst = ip, |
728 | DEBUGP("ip_ct_q931: Call Forwarding not tracked\n"); | 727 | }; |
729 | return 0; | 728 | struct flowi fl2 = { |
729 | .fl4_dst = ct->tuplehash[!dir].tuple.src.ip, | ||
730 | }; | ||
731 | |||
732 | if (ip_route_output_key(&rt1, &fl1) == 0) { | ||
733 | if (ip_route_output_key(&rt2, &fl2) == 0) { | ||
734 | if (rt1->rt_gateway == rt2->rt_gateway && | ||
735 | rt1->u.dst.dev == rt2->u.dst.dev) | ||
736 | ret = 1; | ||
737 | dst_release(&rt2->u.dst); | ||
738 | } | ||
739 | dst_release(&rt1->u.dst); | ||
740 | } | ||
741 | if (ret) { | ||
742 | DEBUGP("ip_ct_q931: Call Forwarding not tracked\n"); | ||
743 | return 0; | ||
744 | } | ||
730 | } | 745 | } |
731 | 746 | ||
732 | /* Create expect for the second call leg */ | 747 | /* Create expect for the second call leg */ |
@@ -1762,7 +1777,6 @@ static void fini(void) | |||
1762 | static int __init init(void) | 1777 | static int __init init(void) |
1763 | { | 1778 | { |
1764 | int ret; | 1779 | int ret; |
1765 | char *p; | ||
1766 | 1780 | ||
1767 | h323_buffer = kmalloc(65536, GFP_KERNEL); | 1781 | h323_buffer = kmalloc(65536, GFP_KERNEL); |
1768 | if (!h323_buffer) | 1782 | if (!h323_buffer) |
@@ -1772,23 +1786,6 @@ static int __init init(void) | |||
1772 | fini(); | 1786 | fini(); |
1773 | return ret; | 1787 | return ret; |
1774 | } | 1788 | } |
1775 | |||
1776 | if (internal_net) { | ||
1777 | if ((p = strchr(internal_net, '/'))) | ||
1778 | *p++ = 0; | ||
1779 | if (isdigit(internal_net[0])) { | ||
1780 | internal_net_addr = in_aton(internal_net); | ||
1781 | if (p && isdigit(p[0])) | ||
1782 | internal_net_mask = in_aton(p); | ||
1783 | else | ||
1784 | internal_net_mask = 0xffffffff; | ||
1785 | internal_net_addr &= internal_net_mask; | ||
1786 | } | ||
1787 | DEBUGP("ip_ct_h323: internal_net = %u.%u.%u.%u/%u.%u.%u.%u\n", | ||
1788 | NIPQUAD(internal_net_addr), | ||
1789 | NIPQUAD(internal_net_mask)); | ||
1790 | } | ||
1791 | |||
1792 | DEBUGP("ip_ct_h323: init success\n"); | 1789 | DEBUGP("ip_ct_h323: init success\n"); |
1793 | return 0; | 1790 | return 0; |
1794 | } | 1791 | } |