aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPatrick McHardy <kaber@trash.net>2006-05-29 21:26:47 -0400
committerDavid S. Miller <davem@sunset.davemloft.net>2006-06-18 00:29:13 -0400
commite44ab66a75e20c02193440a5e27c16c91630109b (patch)
tree13aa30980b223b19720ff5d864d43e3708339fdc
parentc0d4cfd96dd0cc0dbf49435898808b5553af4822 (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.c57
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;
40module_param(gkrouted_only, int, 0600); 40module_param(gkrouted_only, int, 0600);
41MODULE_PARM_DESC(gkrouted_only, "only accept calls from gatekeeper"); 41MODULE_PARM_DESC(gkrouted_only, "only accept calls from gatekeeper");
42 42
43static char *internal_net = NULL; 43static int callforward_filter = 1;
44static u_int32_t internal_net_addr = 0; 44module_param(callforward_filter, bool, 0600);
45static u_int32_t internal_net_mask = 0; 45MODULE_PARM_DESC(callforward_filter, "only create call forwarding expectations "
46module_param(internal_net, charp, 0600); 46 "if both endpoints are on different sides "
47MODULE_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 */
51int (*set_h245_addr_hook) (struct sk_buff ** pskb, 50int (*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)
1762static int __init init(void) 1777static 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}