aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/linux/netfilter.h2
-rw-r--r--net/ipv4/netfilter.c6
-rw-r--r--net/ipv6/netfilter.c7
-rw-r--r--net/netfilter/nf_conntrack_h323_main.c19
4 files changed, 27 insertions, 7 deletions
diff --git a/include/linux/netfilter.h b/include/linux/netfilter.h
index f42e4362d50d..9bfc7d4f5868 100644
--- a/include/linux/netfilter.h
+++ b/include/linux/netfilter.h
@@ -298,10 +298,12 @@ extern void nf_invalidate_cache(int pf);
298 Returns true or false. */ 298 Returns true or false. */
299extern int skb_make_writable(struct sk_buff *skb, unsigned int writable_len); 299extern int skb_make_writable(struct sk_buff *skb, unsigned int writable_len);
300 300
301struct flowi;
301struct nf_afinfo { 302struct nf_afinfo {
302 unsigned short family; 303 unsigned short family;
303 __sum16 (*checksum)(struct sk_buff *skb, unsigned int hook, 304 __sum16 (*checksum)(struct sk_buff *skb, unsigned int hook,
304 unsigned int dataoff, u_int8_t protocol); 305 unsigned int dataoff, u_int8_t protocol);
306 int (*route)(struct dst_entry **dst, struct flowi *fl);
305 void (*saveroute)(const struct sk_buff *skb, 307 void (*saveroute)(const struct sk_buff *skb,
306 struct nf_info *info); 308 struct nf_info *info);
307 int (*reroute)(struct sk_buff *skb, 309 int (*reroute)(struct sk_buff *skb,
diff --git a/net/ipv4/netfilter.c b/net/ipv4/netfilter.c
index d9022467e089..599d448ef57e 100644
--- a/net/ipv4/netfilter.c
+++ b/net/ipv4/netfilter.c
@@ -182,9 +182,15 @@ __sum16 nf_ip_checksum(struct sk_buff *skb, unsigned int hook,
182 182
183EXPORT_SYMBOL(nf_ip_checksum); 183EXPORT_SYMBOL(nf_ip_checksum);
184 184
185static int nf_ip_route(struct dst_entry **dst, struct flowi *fl)
186{
187 return ip_route_output_key((struct rtable **)dst, fl);
188}
189
185static struct nf_afinfo nf_ip_afinfo = { 190static struct nf_afinfo nf_ip_afinfo = {
186 .family = AF_INET, 191 .family = AF_INET,
187 .checksum = nf_ip_checksum, 192 .checksum = nf_ip_checksum,
193 .route = nf_ip_route,
188 .saveroute = nf_ip_saveroute, 194 .saveroute = nf_ip_saveroute,
189 .reroute = nf_ip_reroute, 195 .reroute = nf_ip_reroute,
190 .route_key_size = sizeof(struct ip_rt_info), 196 .route_key_size = sizeof(struct ip_rt_info),
diff --git a/net/ipv6/netfilter.c b/net/ipv6/netfilter.c
index 175e19f80253..281f732e3c97 100644
--- a/net/ipv6/netfilter.c
+++ b/net/ipv6/netfilter.c
@@ -81,6 +81,12 @@ static int nf_ip6_reroute(struct sk_buff *skb, const struct nf_info *info)
81 return 0; 81 return 0;
82} 82}
83 83
84static int nf_ip6_route(struct dst_entry **dst, struct flowi *fl)
85{
86 *dst = ip6_route_output(NULL, fl);
87 return (*dst)->error;
88}
89
84__sum16 nf_ip6_checksum(struct sk_buff *skb, unsigned int hook, 90__sum16 nf_ip6_checksum(struct sk_buff *skb, unsigned int hook,
85 unsigned int dataoff, u_int8_t protocol) 91 unsigned int dataoff, u_int8_t protocol)
86{ 92{
@@ -118,6 +124,7 @@ EXPORT_SYMBOL(nf_ip6_checksum);
118static struct nf_afinfo nf_ip6_afinfo = { 124static struct nf_afinfo nf_ip6_afinfo = {
119 .family = AF_INET6, 125 .family = AF_INET6,
120 .checksum = nf_ip6_checksum, 126 .checksum = nf_ip6_checksum,
127 .route = nf_ip6_route,
121 .saveroute = nf_ip6_saveroute, 128 .saveroute = nf_ip6_saveroute,
122 .reroute = nf_ip6_reroute, 129 .reroute = nf_ip6_reroute,
123 .route_key_size = sizeof(struct ip6_rt_info), 130 .route_key_size = sizeof(struct ip6_rt_info),
diff --git a/net/netfilter/nf_conntrack_h323_main.c b/net/netfilter/nf_conntrack_h323_main.c
index f23fd9598e19..c550257b5462 100644
--- a/net/netfilter/nf_conntrack_h323_main.c
+++ b/net/netfilter/nf_conntrack_h323_main.c
@@ -708,9 +708,15 @@ static int callforward_do_filter(union nf_conntrack_address *src,
708 union nf_conntrack_address *dst, 708 union nf_conntrack_address *dst,
709 int family) 709 int family)
710{ 710{
711 struct nf_afinfo *afinfo;
711 struct flowi fl1, fl2; 712 struct flowi fl1, fl2;
712 int ret = 0; 713 int ret = 0;
713 714
715 /* rcu_read_lock()ed by nf_hook_slow() */
716 afinfo = nf_get_afinfo(family);
717 if (!afinfo)
718 return 0;
719
714 memset(&fl1, 0, sizeof(fl1)); 720 memset(&fl1, 0, sizeof(fl1));
715 memset(&fl2, 0, sizeof(fl2)); 721 memset(&fl2, 0, sizeof(fl2));
716 722
@@ -720,8 +726,8 @@ static int callforward_do_filter(union nf_conntrack_address *src,
720 726
721 fl1.fl4_dst = src->ip; 727 fl1.fl4_dst = src->ip;
722 fl2.fl4_dst = dst->ip; 728 fl2.fl4_dst = dst->ip;
723 if (ip_route_output_key(&rt1, &fl1) == 0) { 729 if (!afinfo->route((struct dst_entry **)&rt1, &fl1)) {
724 if (ip_route_output_key(&rt2, &fl2) == 0) { 730 if (!afinfo->route((struct dst_entry **)&rt2, &fl2)) {
725 if (rt1->rt_gateway == rt2->rt_gateway && 731 if (rt1->rt_gateway == rt2->rt_gateway &&
726 rt1->u.dst.dev == rt2->u.dst.dev) 732 rt1->u.dst.dev == rt2->u.dst.dev)
727 ret = 1; 733 ret = 1;
@@ -731,16 +737,15 @@ static int callforward_do_filter(union nf_conntrack_address *src,
731 } 737 }
732 break; 738 break;
733 } 739 }
734#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) 740#if defined(CONFIG_NF_CONNTRACK_IPV6) || \
741 defined(CONFIG_NF_CONNTRACK_IPV6_MODULE)
735 case AF_INET6: { 742 case AF_INET6: {
736 struct rt6_info *rt1, *rt2; 743 struct rt6_info *rt1, *rt2;
737 744
738 memcpy(&fl1.fl6_dst, src, sizeof(fl1.fl6_dst)); 745 memcpy(&fl1.fl6_dst, src, sizeof(fl1.fl6_dst));
739 memcpy(&fl2.fl6_dst, dst, sizeof(fl2.fl6_dst)); 746 memcpy(&fl2.fl6_dst, dst, sizeof(fl2.fl6_dst));
740 rt1 = (struct rt6_info *)ip6_route_output(NULL, &fl1); 747 if (!afinfo->route((struct dst_entry **)&rt1, &fl1)) {
741 if (rt1) { 748 if (!afinfo->route((struct dst_entry **)&rt2, &fl2)) {
742 rt2 = (struct rt6_info *)ip6_route_output(NULL, &fl2);
743 if (rt2) {
744 if (!memcmp(&rt1->rt6i_gateway, &rt2->rt6i_gateway, 749 if (!memcmp(&rt1->rt6i_gateway, &rt2->rt6i_gateway,
745 sizeof(rt1->rt6i_gateway)) && 750 sizeof(rt1->rt6i_gateway)) &&
746 rt1->u.dst.dev == rt2->u.dst.dev) 751 rt1->u.dst.dev == rt2->u.dst.dev)