diff options
author | Julian Anastasov <ja@ssi.bg> | 2010-10-17 09:32:29 -0400 |
---|---|---|
committer | Simon Horman <horms@verge.net.au> | 2010-10-21 04:51:28 -0400 |
commit | 1ca5bb5450aa2401fa272efeb741ebb260d0fbb0 (patch) | |
tree | 93b8fa7478bb1f04e2bd443932d29590ce0e623c /net | |
parent | 4256f1aaa662697c1faa0984b7a698c2c8c57735 (diff) |
ipvs: create ip_vs_defrag_user
Create new function ip_vs_defrag_user to return correct
IP_DEFRAG_xxx user depending on the hooknum. It will be needed
when we add handlers in LOCAL_OUT.
Signed-off-by: Julian Anastasov <ja@ssi.bg>
Signed-off-by: Simon Horman <horms@verge.net.au>
Diffstat (limited to 'net')
-rw-r--r-- | net/netfilter/ipvs/ip_vs_core.c | 55 |
1 files changed, 34 insertions, 21 deletions
diff --git a/net/netfilter/ipvs/ip_vs_core.c b/net/netfilter/ipvs/ip_vs_core.c index 27ecb258ea70..f7f52831c4a6 100644 --- a/net/netfilter/ipvs/ip_vs_core.c +++ b/net/netfilter/ipvs/ip_vs_core.c | |||
@@ -543,6 +543,15 @@ __sum16 ip_vs_checksum_complete(struct sk_buff *skb, int offset) | |||
543 | return csum_fold(skb_checksum(skb, offset, skb->len - offset, 0)); | 543 | return csum_fold(skb_checksum(skb, offset, skb->len - offset, 0)); |
544 | } | 544 | } |
545 | 545 | ||
546 | static inline enum ip_defrag_users ip_vs_defrag_user(unsigned int hooknum) | ||
547 | { | ||
548 | if (NF_INET_LOCAL_IN == hooknum) | ||
549 | return IP_DEFRAG_VS_IN; | ||
550 | if (NF_INET_FORWARD == hooknum) | ||
551 | return IP_DEFRAG_VS_FWD; | ||
552 | return IP_DEFRAG_VS_OUT; | ||
553 | } | ||
554 | |||
546 | static inline int ip_vs_gather_frags(struct sk_buff *skb, u_int32_t user) | 555 | static inline int ip_vs_gather_frags(struct sk_buff *skb, u_int32_t user) |
547 | { | 556 | { |
548 | int err = ip_defrag(skb, user); | 557 | int err = ip_defrag(skb, user); |
@@ -714,7 +723,8 @@ out: | |||
714 | * Find any that might be relevant, check against existing connections. | 723 | * Find any that might be relevant, check against existing connections. |
715 | * Currently handles error types - unreachable, quench, ttl exceeded. | 724 | * Currently handles error types - unreachable, quench, ttl exceeded. |
716 | */ | 725 | */ |
717 | static int ip_vs_out_icmp(struct sk_buff *skb, int *related) | 726 | static int ip_vs_out_icmp(struct sk_buff *skb, int *related, |
727 | unsigned int hooknum) | ||
718 | { | 728 | { |
719 | struct iphdr *iph; | 729 | struct iphdr *iph; |
720 | struct icmphdr _icmph, *ic; | 730 | struct icmphdr _icmph, *ic; |
@@ -729,7 +739,7 @@ static int ip_vs_out_icmp(struct sk_buff *skb, int *related) | |||
729 | 739 | ||
730 | /* reassemble IP fragments */ | 740 | /* reassemble IP fragments */ |
731 | if (ip_hdr(skb)->frag_off & htons(IP_MF | IP_OFFSET)) { | 741 | if (ip_hdr(skb)->frag_off & htons(IP_MF | IP_OFFSET)) { |
732 | if (ip_vs_gather_frags(skb, IP_DEFRAG_VS_OUT)) | 742 | if (ip_vs_gather_frags(skb, ip_vs_defrag_user(hooknum))) |
733 | return NF_STOLEN; | 743 | return NF_STOLEN; |
734 | } | 744 | } |
735 | 745 | ||
@@ -788,7 +798,8 @@ static int ip_vs_out_icmp(struct sk_buff *skb, int *related) | |||
788 | } | 798 | } |
789 | 799 | ||
790 | #ifdef CONFIG_IP_VS_IPV6 | 800 | #ifdef CONFIG_IP_VS_IPV6 |
791 | static int ip_vs_out_icmp_v6(struct sk_buff *skb, int *related) | 801 | static int ip_vs_out_icmp_v6(struct sk_buff *skb, int *related, |
802 | unsigned int hooknum) | ||
792 | { | 803 | { |
793 | struct ipv6hdr *iph; | 804 | struct ipv6hdr *iph; |
794 | struct icmp6hdr _icmph, *ic; | 805 | struct icmp6hdr _icmph, *ic; |
@@ -804,7 +815,7 @@ static int ip_vs_out_icmp_v6(struct sk_buff *skb, int *related) | |||
804 | 815 | ||
805 | /* reassemble IP fragments */ | 816 | /* reassemble IP fragments */ |
806 | if (ipv6_hdr(skb)->nexthdr == IPPROTO_FRAGMENT) { | 817 | if (ipv6_hdr(skb)->nexthdr == IPPROTO_FRAGMENT) { |
807 | if (ip_vs_gather_frags_v6(skb, IP_DEFRAG_VS_OUT)) | 818 | if (ip_vs_gather_frags_v6(skb, ip_vs_defrag_user(hooknum))) |
808 | return NF_STOLEN; | 819 | return NF_STOLEN; |
809 | } | 820 | } |
810 | 821 | ||
@@ -986,7 +997,9 @@ ip_vs_out(unsigned int hooknum, struct sk_buff *skb, | |||
986 | #ifdef CONFIG_IP_VS_IPV6 | 997 | #ifdef CONFIG_IP_VS_IPV6 |
987 | if (af == AF_INET6) { | 998 | if (af == AF_INET6) { |
988 | if (unlikely(iph.protocol == IPPROTO_ICMPV6)) { | 999 | if (unlikely(iph.protocol == IPPROTO_ICMPV6)) { |
989 | int related, verdict = ip_vs_out_icmp_v6(skb, &related); | 1000 | int related; |
1001 | int verdict = ip_vs_out_icmp_v6(skb, &related, | ||
1002 | hooknum); | ||
990 | 1003 | ||
991 | if (related) { | 1004 | if (related) { |
992 | if (sysctl_ip_vs_snat_reroute && | 1005 | if (sysctl_ip_vs_snat_reroute && |
@@ -1000,7 +1013,8 @@ ip_vs_out(unsigned int hooknum, struct sk_buff *skb, | |||
1000 | } else | 1013 | } else |
1001 | #endif | 1014 | #endif |
1002 | if (unlikely(iph.protocol == IPPROTO_ICMP)) { | 1015 | if (unlikely(iph.protocol == IPPROTO_ICMP)) { |
1003 | int related, verdict = ip_vs_out_icmp(skb, &related); | 1016 | int related; |
1017 | int verdict = ip_vs_out_icmp(skb, &related, hooknum); | ||
1004 | 1018 | ||
1005 | if (related) { | 1019 | if (related) { |
1006 | if (sysctl_ip_vs_snat_reroute && | 1020 | if (sysctl_ip_vs_snat_reroute && |
@@ -1019,19 +1033,19 @@ ip_vs_out(unsigned int hooknum, struct sk_buff *skb, | |||
1019 | /* reassemble IP fragments */ | 1033 | /* reassemble IP fragments */ |
1020 | #ifdef CONFIG_IP_VS_IPV6 | 1034 | #ifdef CONFIG_IP_VS_IPV6 |
1021 | if (af == AF_INET6) { | 1035 | if (af == AF_INET6) { |
1022 | if (unlikely(iph.protocol == IPPROTO_ICMPV6)) { | 1036 | if (ipv6_hdr(skb)->nexthdr == IPPROTO_FRAGMENT) { |
1023 | int related, verdict = ip_vs_out_icmp_v6(skb, &related); | 1037 | if (ip_vs_gather_frags_v6(skb, |
1024 | 1038 | ip_vs_defrag_user(hooknum))) | |
1025 | if (related) | 1039 | return NF_STOLEN; |
1026 | return verdict; | ||
1027 | |||
1028 | ip_vs_fill_iphdr(af, skb_network_header(skb), &iph); | ||
1029 | } | 1040 | } |
1041 | |||
1042 | ip_vs_fill_iphdr(af, skb_network_header(skb), &iph); | ||
1030 | } else | 1043 | } else |
1031 | #endif | 1044 | #endif |
1032 | if (unlikely(ip_hdr(skb)->frag_off & htons(IP_MF|IP_OFFSET) && | 1045 | if (unlikely(ip_hdr(skb)->frag_off & htons(IP_MF|IP_OFFSET) && |
1033 | !pp->dont_defrag)) { | 1046 | !pp->dont_defrag)) { |
1034 | if (ip_vs_gather_frags(skb, IP_DEFRAG_VS_OUT)) | 1047 | if (ip_vs_gather_frags(skb, |
1048 | ip_vs_defrag_user(hooknum))) | ||
1035 | return NF_STOLEN; | 1049 | return NF_STOLEN; |
1036 | 1050 | ||
1037 | ip_vs_fill_iphdr(af, skb_network_header(skb), &iph); | 1051 | ip_vs_fill_iphdr(af, skb_network_header(skb), &iph); |
@@ -1114,8 +1128,7 @@ ip_vs_in_icmp(struct sk_buff *skb, int *related, unsigned int hooknum) | |||
1114 | 1128 | ||
1115 | /* reassemble IP fragments */ | 1129 | /* reassemble IP fragments */ |
1116 | if (ip_hdr(skb)->frag_off & htons(IP_MF | IP_OFFSET)) { | 1130 | if (ip_hdr(skb)->frag_off & htons(IP_MF | IP_OFFSET)) { |
1117 | if (ip_vs_gather_frags(skb, hooknum == NF_INET_LOCAL_IN ? | 1131 | if (ip_vs_gather_frags(skb, ip_vs_defrag_user(hooknum))) |
1118 | IP_DEFRAG_VS_IN : IP_DEFRAG_VS_FWD)) | ||
1119 | return NF_STOLEN; | 1132 | return NF_STOLEN; |
1120 | } | 1133 | } |
1121 | 1134 | ||
@@ -1226,9 +1239,7 @@ ip_vs_in_icmp_v6(struct sk_buff *skb, int *related, unsigned int hooknum) | |||
1226 | 1239 | ||
1227 | /* reassemble IP fragments */ | 1240 | /* reassemble IP fragments */ |
1228 | if (ipv6_hdr(skb)->nexthdr == IPPROTO_FRAGMENT) { | 1241 | if (ipv6_hdr(skb)->nexthdr == IPPROTO_FRAGMENT) { |
1229 | if (ip_vs_gather_frags_v6(skb, hooknum == NF_INET_LOCAL_IN ? | 1242 | if (ip_vs_gather_frags_v6(skb, ip_vs_defrag_user(hooknum))) |
1230 | IP_DEFRAG_VS_IN : | ||
1231 | IP_DEFRAG_VS_FWD)) | ||
1232 | return NF_STOLEN; | 1243 | return NF_STOLEN; |
1233 | } | 1244 | } |
1234 | 1245 | ||
@@ -1349,7 +1360,8 @@ ip_vs_in(unsigned int hooknum, struct sk_buff *skb, | |||
1349 | #ifdef CONFIG_IP_VS_IPV6 | 1360 | #ifdef CONFIG_IP_VS_IPV6 |
1350 | if (af == AF_INET6) { | 1361 | if (af == AF_INET6) { |
1351 | if (unlikely(iph.protocol == IPPROTO_ICMPV6)) { | 1362 | if (unlikely(iph.protocol == IPPROTO_ICMPV6)) { |
1352 | int related, verdict = ip_vs_in_icmp_v6(skb, &related, hooknum); | 1363 | int related; |
1364 | int verdict = ip_vs_in_icmp_v6(skb, &related, hooknum); | ||
1353 | 1365 | ||
1354 | if (related) | 1366 | if (related) |
1355 | return verdict; | 1367 | return verdict; |
@@ -1358,7 +1370,8 @@ ip_vs_in(unsigned int hooknum, struct sk_buff *skb, | |||
1358 | } else | 1370 | } else |
1359 | #endif | 1371 | #endif |
1360 | if (unlikely(iph.protocol == IPPROTO_ICMP)) { | 1372 | if (unlikely(iph.protocol == IPPROTO_ICMP)) { |
1361 | int related, verdict = ip_vs_in_icmp(skb, &related, hooknum); | 1373 | int related; |
1374 | int verdict = ip_vs_in_icmp(skb, &related, hooknum); | ||
1362 | 1375 | ||
1363 | if (related) | 1376 | if (related) |
1364 | return verdict; | 1377 | return verdict; |