diff options
author | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-05-11 12:10:19 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-05-11 12:10:19 -0400 |
commit | ee54d2d87a8158d14434c1a3274bd7f713105836 (patch) | |
tree | cd3e1f6fc0a7fc920e4153c01f35ff7bd92d79da /net/ipv4 | |
parent | bf61f8d357e5d71d74a3ca3be3cce52bf1a2c01a (diff) | |
parent | da0dd231436ba7e81789e93dd933d7a275e1709d (diff) |
Merge master.kernel.org:/pub/scm/linux/kernel/git/davem/net-2.6
* master.kernel.org:/pub/scm/linux/kernel/git/davem/net-2.6: (31 commits)
[NETFILTER]: xt_conntrack: add compat support
[NETFILTER]: iptable_raw: ignore short packets sent by SOCK_RAW sockets
[NETFILTER]: iptable_{filter,mangle}: more descriptive "happy cracking" message
[NETFILTER]: nf_nat: Clears helper private area when NATing
[NETFILTER]: ctnetlink: clear helper area and handle unchanged helper
[NETFILTER]: nf_conntrack: Removes unused destroy operation of l3proto
[NETFILTER]: nf_conntrack: Removes duplicated declarations
[NETFILTER]: nf_nat: remove unused argument of function allocating binding
[NETFILTER]: Clean up table initialization
[NET_SCHED]: Avoid requeue warning on dev_deactivate
[NET_SCHED]: Reread dev->qdisc for NETDEV_TX_OK
[NET_SCHED]: Rationalise return value of qdisc_restart
[NET]: Fix dev->qdisc race for NETDEV_TX_LOCKED case
[UDP]: Fix AF-specific references in AF-agnostic code.
[IrDA]: KingSun/DonShine USB IrDA dongle support.
[IPV6] ROUTE: Assign rt6i_idev for ip6_{prohibit,blk_hole}_entry.
[IPV6]: Do no rely on skb->dst before it is assigned.
[IPV6]: Send ICMPv6 error on scope violations.
[SCTP]: Do not include ABORT chunk header in the notification.
[SCTP]: Correctly copy addresses in sctp_copy_laddrs
...
Diffstat (limited to 'net/ipv4')
-rw-r--r-- | net/ipv4/netfilter/arptable_filter.c | 140 | ||||
-rw-r--r-- | net/ipv4/netfilter/iptable_filter.c | 73 | ||||
-rw-r--r-- | net/ipv4/netfilter/iptable_mangle.c | 99 | ||||
-rw-r--r-- | net/ipv4/netfilter/iptable_raw.c | 79 | ||||
-rw-r--r-- | net/ipv4/netfilter/nf_nat_rule.c | 86 | ||||
-rw-r--r-- | net/ipv4/netfilter/nf_nat_standalone.c | 11 | ||||
-rw-r--r-- | net/ipv4/udp.c | 85 | ||||
-rw-r--r-- | net/ipv4/udp_impl.h | 6 | ||||
-rw-r--r-- | net/ipv4/udplite.c | 7 |
9 files changed, 182 insertions, 404 deletions
diff --git a/net/ipv4/netfilter/arptable_filter.c b/net/ipv4/netfilter/arptable_filter.c index 7edea2a169..75c0230625 100644 --- a/net/ipv4/netfilter/arptable_filter.c +++ b/net/ipv4/netfilter/arptable_filter.c | |||
@@ -15,128 +15,34 @@ MODULE_DESCRIPTION("arptables filter table"); | |||
15 | #define FILTER_VALID_HOOKS ((1 << NF_ARP_IN) | (1 << NF_ARP_OUT) | \ | 15 | #define FILTER_VALID_HOOKS ((1 << NF_ARP_IN) | (1 << NF_ARP_OUT) | \ |
16 | (1 << NF_ARP_FORWARD)) | 16 | (1 << NF_ARP_FORWARD)) |
17 | 17 | ||
18 | /* Standard entry. */ | ||
19 | struct arpt_standard | ||
20 | { | ||
21 | struct arpt_entry entry; | ||
22 | struct arpt_standard_target target; | ||
23 | }; | ||
24 | |||
25 | struct arpt_error_target | ||
26 | { | ||
27 | struct arpt_entry_target target; | ||
28 | char errorname[ARPT_FUNCTION_MAXNAMELEN]; | ||
29 | }; | ||
30 | |||
31 | struct arpt_error | ||
32 | { | ||
33 | struct arpt_entry entry; | ||
34 | struct arpt_error_target target; | ||
35 | }; | ||
36 | |||
37 | static struct | 18 | static struct |
38 | { | 19 | { |
39 | struct arpt_replace repl; | 20 | struct arpt_replace repl; |
40 | struct arpt_standard entries[3]; | 21 | struct arpt_standard entries[3]; |
41 | struct arpt_error term; | 22 | struct arpt_error term; |
42 | } initial_table __initdata | 23 | } initial_table __initdata = { |
43 | = { { "filter", FILTER_VALID_HOOKS, 4, | 24 | .repl = { |
44 | sizeof(struct arpt_standard) * 3 + sizeof(struct arpt_error), | 25 | .name = "filter", |
45 | { [NF_ARP_IN] = 0, | 26 | .valid_hooks = FILTER_VALID_HOOKS, |
46 | [NF_ARP_OUT] = sizeof(struct arpt_standard), | 27 | .num_entries = 4, |
47 | [NF_ARP_FORWARD] = 2 * sizeof(struct arpt_standard), }, | 28 | .size = sizeof(struct arpt_standard) * 3 + sizeof(struct arpt_error), |
48 | { [NF_ARP_IN] = 0, | 29 | .hook_entry = { |
49 | [NF_ARP_OUT] = sizeof(struct arpt_standard), | 30 | [NF_ARP_IN] = 0, |
50 | [NF_ARP_FORWARD] = 2 * sizeof(struct arpt_standard), }, | 31 | [NF_ARP_OUT] = sizeof(struct arpt_standard), |
51 | 0, NULL, { } }, | 32 | [NF_ARP_FORWARD] = 2 * sizeof(struct arpt_standard), |
52 | { | 33 | }, |
53 | /* ARP_IN */ | 34 | .underflow = { |
54 | { | 35 | [NF_ARP_IN] = 0, |
55 | { | 36 | [NF_ARP_OUT] = sizeof(struct arpt_standard), |
56 | { | 37 | [NF_ARP_FORWARD] = 2 * sizeof(struct arpt_standard), |
57 | { 0 }, { 0 }, { 0 }, { 0 }, | 38 | }, |
58 | 0, 0, | 39 | }, |
59 | { { 0, }, { 0, } }, | 40 | .entries = { |
60 | { { 0, }, { 0, } }, | 41 | ARPT_STANDARD_INIT(NF_ACCEPT), /* ARP_IN */ |
61 | 0, 0, | 42 | ARPT_STANDARD_INIT(NF_ACCEPT), /* ARP_OUT */ |
62 | 0, 0, | 43 | ARPT_STANDARD_INIT(NF_ACCEPT), /* ARP_FORWARD */ |
63 | 0, 0, | 44 | }, |
64 | "", "", { 0 }, { 0 }, | 45 | .term = ARPT_ERROR_INIT, |
65 | 0, 0 | ||
66 | }, | ||
67 | sizeof(struct arpt_entry), | ||
68 | sizeof(struct arpt_standard), | ||
69 | 0, | ||
70 | { 0, 0 }, { } }, | ||
71 | { { { { ARPT_ALIGN(sizeof(struct arpt_standard_target)), "" } }, { } }, | ||
72 | -NF_ACCEPT - 1 } | ||
73 | }, | ||
74 | /* ARP_OUT */ | ||
75 | { | ||
76 | { | ||
77 | { | ||
78 | { 0 }, { 0 }, { 0 }, { 0 }, | ||
79 | 0, 0, | ||
80 | { { 0, }, { 0, } }, | ||
81 | { { 0, }, { 0, } }, | ||
82 | 0, 0, | ||
83 | 0, 0, | ||
84 | 0, 0, | ||
85 | "", "", { 0 }, { 0 }, | ||
86 | 0, 0 | ||
87 | }, | ||
88 | sizeof(struct arpt_entry), | ||
89 | sizeof(struct arpt_standard), | ||
90 | 0, | ||
91 | { 0, 0 }, { } }, | ||
92 | { { { { ARPT_ALIGN(sizeof(struct arpt_standard_target)), "" } }, { } }, | ||
93 | -NF_ACCEPT - 1 } | ||
94 | }, | ||
95 | /* ARP_FORWARD */ | ||
96 | { | ||
97 | { | ||
98 | { | ||
99 | { 0 }, { 0 }, { 0 }, { 0 }, | ||
100 | 0, 0, | ||
101 | { { 0, }, { 0, } }, | ||
102 | { { 0, }, { 0, } }, | ||
103 | 0, 0, | ||
104 | 0, 0, | ||
105 | 0, 0, | ||
106 | "", "", { 0 }, { 0 }, | ||
107 | 0, 0 | ||
108 | }, | ||
109 | sizeof(struct arpt_entry), | ||
110 | sizeof(struct arpt_standard), | ||
111 | 0, | ||
112 | { 0, 0 }, { } }, | ||
113 | { { { { ARPT_ALIGN(sizeof(struct arpt_standard_target)), "" } }, { } }, | ||
114 | -NF_ACCEPT - 1 } | ||
115 | } | ||
116 | }, | ||
117 | /* ERROR */ | ||
118 | { | ||
119 | { | ||
120 | { | ||
121 | { 0 }, { 0 }, { 0 }, { 0 }, | ||
122 | 0, 0, | ||
123 | { { 0, }, { 0, } }, | ||
124 | { { 0, }, { 0, } }, | ||
125 | 0, 0, | ||
126 | 0, 0, | ||
127 | 0, 0, | ||
128 | "", "", { 0 }, { 0 }, | ||
129 | 0, 0 | ||
130 | }, | ||
131 | sizeof(struct arpt_entry), | ||
132 | sizeof(struct arpt_error), | ||
133 | 0, | ||
134 | { 0, 0 }, { } }, | ||
135 | { { { { ARPT_ALIGN(sizeof(struct arpt_error_target)), ARPT_ERROR_TARGET } }, | ||
136 | { } }, | ||
137 | "ERROR" | ||
138 | } | ||
139 | } | ||
140 | }; | 46 | }; |
141 | 47 | ||
142 | static struct arpt_table packet_filter = { | 48 | static struct arpt_table packet_filter = { |
diff --git a/net/ipv4/netfilter/iptable_filter.c b/net/ipv4/netfilter/iptable_filter.c index 42728909eb..4f51c1d7d2 100644 --- a/net/ipv4/netfilter/iptable_filter.c +++ b/net/ipv4/netfilter/iptable_filter.c | |||
@@ -26,53 +26,29 @@ static struct | |||
26 | struct ipt_replace repl; | 26 | struct ipt_replace repl; |
27 | struct ipt_standard entries[3]; | 27 | struct ipt_standard entries[3]; |
28 | struct ipt_error term; | 28 | struct ipt_error term; |
29 | } initial_table __initdata | 29 | } initial_table __initdata = { |
30 | = { { "filter", FILTER_VALID_HOOKS, 4, | 30 | .repl = { |
31 | sizeof(struct ipt_standard) * 3 + sizeof(struct ipt_error), | 31 | .name = "filter", |
32 | { [NF_IP_LOCAL_IN] = 0, | 32 | .valid_hooks = FILTER_VALID_HOOKS, |
33 | [NF_IP_FORWARD] = sizeof(struct ipt_standard), | 33 | .num_entries = 4, |
34 | [NF_IP_LOCAL_OUT] = sizeof(struct ipt_standard) * 2 }, | 34 | .size = sizeof(struct ipt_standard) * 3 + sizeof(struct ipt_error), |
35 | { [NF_IP_LOCAL_IN] = 0, | 35 | .hook_entry = { |
36 | [NF_IP_FORWARD] = sizeof(struct ipt_standard), | 36 | [NF_IP_LOCAL_IN] = 0, |
37 | [NF_IP_LOCAL_OUT] = sizeof(struct ipt_standard) * 2 }, | 37 | [NF_IP_FORWARD] = sizeof(struct ipt_standard), |
38 | 0, NULL, { } }, | 38 | [NF_IP_LOCAL_OUT] = sizeof(struct ipt_standard) * 2, |
39 | { | 39 | }, |
40 | /* LOCAL_IN */ | 40 | .underflow = { |
41 | { { { { 0 }, { 0 }, { 0 }, { 0 }, "", "", { 0 }, { 0 }, 0, 0, 0 }, | 41 | [NF_IP_LOCAL_IN] = 0, |
42 | 0, | 42 | [NF_IP_FORWARD] = sizeof(struct ipt_standard), |
43 | sizeof(struct ipt_entry), | 43 | [NF_IP_LOCAL_OUT] = sizeof(struct ipt_standard) * 2, |
44 | sizeof(struct ipt_standard), | 44 | }, |
45 | 0, { 0, 0 }, { } }, | 45 | }, |
46 | { { { { IPT_ALIGN(sizeof(struct ipt_standard_target)), "" } }, { } }, | 46 | .entries = { |
47 | -NF_ACCEPT - 1 } }, | 47 | IPT_STANDARD_INIT(NF_ACCEPT), /* LOCAL_IN */ |
48 | /* FORWARD */ | 48 | IPT_STANDARD_INIT(NF_ACCEPT), /* FORWARD */ |
49 | { { { { 0 }, { 0 }, { 0 }, { 0 }, "", "", { 0 }, { 0 }, 0, 0, 0 }, | 49 | IPT_STANDARD_INIT(NF_ACCEPT), /* LOCAL_OUT */ |
50 | 0, | 50 | }, |
51 | sizeof(struct ipt_entry), | 51 | .term = IPT_ERROR_INIT, /* ERROR */ |
52 | sizeof(struct ipt_standard), | ||
53 | 0, { 0, 0 }, { } }, | ||
54 | { { { { IPT_ALIGN(sizeof(struct ipt_standard_target)), "" } }, { } }, | ||
55 | -NF_ACCEPT - 1 } }, | ||
56 | /* LOCAL_OUT */ | ||
57 | { { { { 0 }, { 0 }, { 0 }, { 0 }, "", "", { 0 }, { 0 }, 0, 0, 0 }, | ||
58 | 0, | ||
59 | sizeof(struct ipt_entry), | ||
60 | sizeof(struct ipt_standard), | ||
61 | 0, { 0, 0 }, { } }, | ||
62 | { { { { IPT_ALIGN(sizeof(struct ipt_standard_target)), "" } }, { } }, | ||
63 | -NF_ACCEPT - 1 } } | ||
64 | }, | ||
65 | /* ERROR */ | ||
66 | { { { { 0 }, { 0 }, { 0 }, { 0 }, "", "", { 0 }, { 0 }, 0, 0, 0 }, | ||
67 | 0, | ||
68 | sizeof(struct ipt_entry), | ||
69 | sizeof(struct ipt_error), | ||
70 | 0, { 0, 0 }, { } }, | ||
71 | { { { { IPT_ALIGN(sizeof(struct ipt_error_target)), IPT_ERROR_TARGET } }, | ||
72 | { } }, | ||
73 | "ERROR" | ||
74 | } | ||
75 | } | ||
76 | }; | 52 | }; |
77 | 53 | ||
78 | static struct xt_table packet_filter = { | 54 | static struct xt_table packet_filter = { |
@@ -105,7 +81,8 @@ ipt_local_out_hook(unsigned int hook, | |||
105 | if ((*pskb)->len < sizeof(struct iphdr) | 81 | if ((*pskb)->len < sizeof(struct iphdr) |
106 | || ip_hdrlen(*pskb) < sizeof(struct iphdr)) { | 82 | || ip_hdrlen(*pskb) < sizeof(struct iphdr)) { |
107 | if (net_ratelimit()) | 83 | if (net_ratelimit()) |
108 | printk("ipt_hook: happy cracking.\n"); | 84 | printk("iptable_filter: ignoring short SOCK_RAW " |
85 | "packet.\n"); | ||
109 | return NF_ACCEPT; | 86 | return NF_ACCEPT; |
110 | } | 87 | } |
111 | 88 | ||
diff --git a/net/ipv4/netfilter/iptable_mangle.c b/net/ipv4/netfilter/iptable_mangle.c index 9278802f27..902446f7cb 100644 --- a/net/ipv4/netfilter/iptable_mangle.c +++ b/net/ipv4/netfilter/iptable_mangle.c | |||
@@ -33,73 +33,35 @@ static struct | |||
33 | struct ipt_replace repl; | 33 | struct ipt_replace repl; |
34 | struct ipt_standard entries[5]; | 34 | struct ipt_standard entries[5]; |
35 | struct ipt_error term; | 35 | struct ipt_error term; |
36 | } initial_table __initdata | 36 | } initial_table __initdata = { |
37 | = { { "mangle", MANGLE_VALID_HOOKS, 6, | 37 | .repl = { |
38 | sizeof(struct ipt_standard) * 5 + sizeof(struct ipt_error), | 38 | .name = "mangle", |
39 | { [NF_IP_PRE_ROUTING] = 0, | 39 | .valid_hooks = MANGLE_VALID_HOOKS, |
40 | [NF_IP_LOCAL_IN] = sizeof(struct ipt_standard), | 40 | .num_entries = 6, |
41 | [NF_IP_FORWARD] = sizeof(struct ipt_standard) * 2, | 41 | .size = sizeof(struct ipt_standard) * 5 + sizeof(struct ipt_error), |
42 | [NF_IP_LOCAL_OUT] = sizeof(struct ipt_standard) * 3, | 42 | .hook_entry = { |
43 | [NF_IP_POST_ROUTING] = sizeof(struct ipt_standard) * 4 }, | 43 | [NF_IP_PRE_ROUTING] = 0, |
44 | { [NF_IP_PRE_ROUTING] = 0, | 44 | [NF_IP_LOCAL_IN] = sizeof(struct ipt_standard), |
45 | [NF_IP_LOCAL_IN] = sizeof(struct ipt_standard), | 45 | [NF_IP_FORWARD] = sizeof(struct ipt_standard) * 2, |
46 | [NF_IP_FORWARD] = sizeof(struct ipt_standard) * 2, | 46 | [NF_IP_LOCAL_OUT] = sizeof(struct ipt_standard) * 3, |
47 | [NF_IP_LOCAL_OUT] = sizeof(struct ipt_standard) * 3, | 47 | [NF_IP_POST_ROUTING] = sizeof(struct ipt_standard) * 4, |
48 | [NF_IP_POST_ROUTING] = sizeof(struct ipt_standard) * 4 }, | 48 | }, |
49 | 0, NULL, { } }, | 49 | .underflow = { |
50 | { | 50 | [NF_IP_PRE_ROUTING] = 0, |
51 | /* PRE_ROUTING */ | 51 | [NF_IP_LOCAL_IN] = sizeof(struct ipt_standard), |
52 | { { { { 0 }, { 0 }, { 0 }, { 0 }, "", "", { 0 }, { 0 }, 0, 0, 0 }, | 52 | [NF_IP_FORWARD] = sizeof(struct ipt_standard) * 2, |
53 | 0, | 53 | [NF_IP_LOCAL_OUT] = sizeof(struct ipt_standard) * 3, |
54 | sizeof(struct ipt_entry), | 54 | [NF_IP_POST_ROUTING] = sizeof(struct ipt_standard) * 4, |
55 | sizeof(struct ipt_standard), | 55 | }, |
56 | 0, { 0, 0 }, { } }, | 56 | }, |
57 | { { { { IPT_ALIGN(sizeof(struct ipt_standard_target)), "" } }, { } }, | 57 | .entries = { |
58 | -NF_ACCEPT - 1 } }, | 58 | IPT_STANDARD_INIT(NF_ACCEPT), /* PRE_ROUTING */ |
59 | /* LOCAL_IN */ | 59 | IPT_STANDARD_INIT(NF_ACCEPT), /* LOCAL_IN */ |
60 | { { { { 0 }, { 0 }, { 0 }, { 0 }, "", "", { 0 }, { 0 }, 0, 0, 0 }, | 60 | IPT_STANDARD_INIT(NF_ACCEPT), /* FORWARD */ |
61 | 0, | 61 | IPT_STANDARD_INIT(NF_ACCEPT), /* LOCAL_OUT */ |
62 | sizeof(struct ipt_entry), | 62 | IPT_STANDARD_INIT(NF_ACCEPT), /* POST_ROUTING */ |
63 | sizeof(struct ipt_standard), | 63 | }, |
64 | 0, { 0, 0 }, { } }, | 64 | .term = IPT_ERROR_INIT, /* ERROR */ |
65 | { { { { IPT_ALIGN(sizeof(struct ipt_standard_target)), "" } }, { } }, | ||
66 | -NF_ACCEPT - 1 } }, | ||
67 | /* FORWARD */ | ||
68 | { { { { 0 }, { 0 }, { 0 }, { 0 }, "", "", { 0 }, { 0 }, 0, 0, 0 }, | ||
69 | 0, | ||
70 | sizeof(struct ipt_entry), | ||
71 | sizeof(struct ipt_standard), | ||
72 | 0, { 0, 0 }, { } }, | ||
73 | { { { { IPT_ALIGN(sizeof(struct ipt_standard_target)), "" } }, { } }, | ||
74 | -NF_ACCEPT - 1 } }, | ||
75 | /* LOCAL_OUT */ | ||
76 | { { { { 0 }, { 0 }, { 0 }, { 0 }, "", "", { 0 }, { 0 }, 0, 0, 0 }, | ||
77 | 0, | ||
78 | sizeof(struct ipt_entry), | ||
79 | sizeof(struct ipt_standard), | ||
80 | 0, { 0, 0 }, { } }, | ||
81 | { { { { IPT_ALIGN(sizeof(struct ipt_standard_target)), "" } }, { } }, | ||
82 | -NF_ACCEPT - 1 } }, | ||
83 | /* POST_ROUTING */ | ||
84 | { { { { 0 }, { 0 }, { 0 }, { 0 }, "", "", { 0 }, { 0 }, 0, 0, 0 }, | ||
85 | 0, | ||
86 | sizeof(struct ipt_entry), | ||
87 | sizeof(struct ipt_standard), | ||
88 | 0, { 0, 0 }, { } }, | ||
89 | { { { { IPT_ALIGN(sizeof(struct ipt_standard_target)), "" } }, { } }, | ||
90 | -NF_ACCEPT - 1 } }, | ||
91 | }, | ||
92 | /* ERROR */ | ||
93 | { { { { 0 }, { 0 }, { 0 }, { 0 }, "", "", { 0 }, { 0 }, 0, 0, 0 }, | ||
94 | 0, | ||
95 | sizeof(struct ipt_entry), | ||
96 | sizeof(struct ipt_error), | ||
97 | 0, { 0, 0 }, { } }, | ||
98 | { { { { IPT_ALIGN(sizeof(struct ipt_error_target)), IPT_ERROR_TARGET } }, | ||
99 | { } }, | ||
100 | "ERROR" | ||
101 | } | ||
102 | } | ||
103 | }; | 65 | }; |
104 | 66 | ||
105 | static struct xt_table packet_mangler = { | 67 | static struct xt_table packet_mangler = { |
@@ -138,7 +100,8 @@ ipt_local_hook(unsigned int hook, | |||
138 | if ((*pskb)->len < sizeof(struct iphdr) | 100 | if ((*pskb)->len < sizeof(struct iphdr) |
139 | || ip_hdrlen(*pskb) < sizeof(struct iphdr)) { | 101 | || ip_hdrlen(*pskb) < sizeof(struct iphdr)) { |
140 | if (net_ratelimit()) | 102 | if (net_ratelimit()) |
141 | printk("ipt_hook: happy cracking.\n"); | 103 | printk("iptable_mangle: ignoring short SOCK_RAW " |
104 | "packet.\n"); | ||
142 | return NF_ACCEPT; | 105 | return NF_ACCEPT; |
143 | } | 106 | } |
144 | 107 | ||
diff --git a/net/ipv4/netfilter/iptable_raw.c b/net/ipv4/netfilter/iptable_raw.c index 18c3d4c9ff..d6e5033956 100644 --- a/net/ipv4/netfilter/iptable_raw.c +++ b/net/ipv4/netfilter/iptable_raw.c | |||
@@ -5,6 +5,7 @@ | |||
5 | */ | 5 | */ |
6 | #include <linux/module.h> | 6 | #include <linux/module.h> |
7 | #include <linux/netfilter_ipv4/ip_tables.h> | 7 | #include <linux/netfilter_ipv4/ip_tables.h> |
8 | #include <net/ip.h> | ||
8 | 9 | ||
9 | #define RAW_VALID_HOOKS ((1 << NF_IP_PRE_ROUTING) | (1 << NF_IP_LOCAL_OUT)) | 10 | #define RAW_VALID_HOOKS ((1 << NF_IP_PRE_ROUTING) | (1 << NF_IP_LOCAL_OUT)) |
10 | 11 | ||
@@ -21,62 +22,18 @@ static struct | |||
21 | .size = sizeof(struct ipt_standard) * 2 + sizeof(struct ipt_error), | 22 | .size = sizeof(struct ipt_standard) * 2 + sizeof(struct ipt_error), |
22 | .hook_entry = { | 23 | .hook_entry = { |
23 | [NF_IP_PRE_ROUTING] = 0, | 24 | [NF_IP_PRE_ROUTING] = 0, |
24 | [NF_IP_LOCAL_OUT] = sizeof(struct ipt_standard) }, | 25 | [NF_IP_LOCAL_OUT] = sizeof(struct ipt_standard) |
26 | }, | ||
25 | .underflow = { | 27 | .underflow = { |
26 | [NF_IP_PRE_ROUTING] = 0, | 28 | [NF_IP_PRE_ROUTING] = 0, |
27 | [NF_IP_LOCAL_OUT] = sizeof(struct ipt_standard) }, | 29 | [NF_IP_LOCAL_OUT] = sizeof(struct ipt_standard) |
30 | }, | ||
28 | }, | 31 | }, |
29 | .entries = { | 32 | .entries = { |
30 | /* PRE_ROUTING */ | 33 | IPT_STANDARD_INIT(NF_ACCEPT), /* PRE_ROUTING */ |
31 | { | 34 | IPT_STANDARD_INIT(NF_ACCEPT), /* LOCAL_OUT */ |
32 | .entry = { | ||
33 | .target_offset = sizeof(struct ipt_entry), | ||
34 | .next_offset = sizeof(struct ipt_standard), | ||
35 | }, | ||
36 | .target = { | ||
37 | .target = { | ||
38 | .u = { | ||
39 | .target_size = IPT_ALIGN(sizeof(struct ipt_standard_target)), | ||
40 | }, | ||
41 | }, | ||
42 | .verdict = -NF_ACCEPT - 1, | ||
43 | }, | ||
44 | }, | ||
45 | |||
46 | /* LOCAL_OUT */ | ||
47 | { | ||
48 | .entry = { | ||
49 | .target_offset = sizeof(struct ipt_entry), | ||
50 | .next_offset = sizeof(struct ipt_standard), | ||
51 | }, | ||
52 | .target = { | ||
53 | .target = { | ||
54 | .u = { | ||
55 | .target_size = IPT_ALIGN(sizeof(struct ipt_standard_target)), | ||
56 | }, | ||
57 | }, | ||
58 | .verdict = -NF_ACCEPT - 1, | ||
59 | }, | ||
60 | }, | ||
61 | }, | 35 | }, |
62 | /* ERROR */ | 36 | .term = IPT_ERROR_INIT, /* ERROR */ |
63 | .term = { | ||
64 | .entry = { | ||
65 | .target_offset = sizeof(struct ipt_entry), | ||
66 | .next_offset = sizeof(struct ipt_error), | ||
67 | }, | ||
68 | .target = { | ||
69 | .target = { | ||
70 | .u = { | ||
71 | .user = { | ||
72 | .target_size = IPT_ALIGN(sizeof(struct ipt_error_target)), | ||
73 | .name = IPT_ERROR_TARGET, | ||
74 | }, | ||
75 | }, | ||
76 | }, | ||
77 | .errorname = "ERROR", | ||
78 | }, | ||
79 | } | ||
80 | }; | 37 | }; |
81 | 38 | ||
82 | static struct xt_table packet_raw = { | 39 | static struct xt_table packet_raw = { |
@@ -98,6 +55,24 @@ ipt_hook(unsigned int hook, | |||
98 | return ipt_do_table(pskb, hook, in, out, &packet_raw); | 55 | return ipt_do_table(pskb, hook, in, out, &packet_raw); |
99 | } | 56 | } |
100 | 57 | ||
58 | static unsigned int | ||
59 | ipt_local_hook(unsigned int hook, | ||
60 | struct sk_buff **pskb, | ||
61 | const struct net_device *in, | ||
62 | const struct net_device *out, | ||
63 | int (*okfn)(struct sk_buff *)) | ||
64 | { | ||
65 | /* root is playing with raw sockets. */ | ||
66 | if ((*pskb)->len < sizeof(struct iphdr) || | ||
67 | ip_hdrlen(*pskb) < sizeof(struct iphdr)) { | ||
68 | if (net_ratelimit()) | ||
69 | printk("iptable_raw: ignoring short SOCK_RAW" | ||
70 | "packet.\n"); | ||
71 | return NF_ACCEPT; | ||
72 | } | ||
73 | return ipt_do_table(pskb, hook, in, out, &packet_raw); | ||
74 | } | ||
75 | |||
101 | /* 'raw' is the very first table. */ | 76 | /* 'raw' is the very first table. */ |
102 | static struct nf_hook_ops ipt_ops[] = { | 77 | static struct nf_hook_ops ipt_ops[] = { |
103 | { | 78 | { |
@@ -108,7 +83,7 @@ static struct nf_hook_ops ipt_ops[] = { | |||
108 | .owner = THIS_MODULE, | 83 | .owner = THIS_MODULE, |
109 | }, | 84 | }, |
110 | { | 85 | { |
111 | .hook = ipt_hook, | 86 | .hook = ipt_local_hook, |
112 | .pf = PF_INET, | 87 | .pf = PF_INET, |
113 | .hooknum = NF_IP_LOCAL_OUT, | 88 | .hooknum = NF_IP_LOCAL_OUT, |
114 | .priority = NF_IP_PRI_RAW, | 89 | .priority = NF_IP_PRI_RAW, |
diff --git a/net/ipv4/netfilter/nf_nat_rule.c b/net/ipv4/netfilter/nf_nat_rule.c index 2534f718ab..6740736c5e 100644 --- a/net/ipv4/netfilter/nf_nat_rule.c +++ b/net/ipv4/netfilter/nf_nat_rule.c | |||
@@ -46,77 +46,20 @@ static struct | |||
46 | .hook_entry = { | 46 | .hook_entry = { |
47 | [NF_IP_PRE_ROUTING] = 0, | 47 | [NF_IP_PRE_ROUTING] = 0, |
48 | [NF_IP_POST_ROUTING] = sizeof(struct ipt_standard), | 48 | [NF_IP_POST_ROUTING] = sizeof(struct ipt_standard), |
49 | [NF_IP_LOCAL_OUT] = sizeof(struct ipt_standard) * 2 }, | 49 | [NF_IP_LOCAL_OUT] = sizeof(struct ipt_standard) * 2 |
50 | }, | ||
50 | .underflow = { | 51 | .underflow = { |
51 | [NF_IP_PRE_ROUTING] = 0, | 52 | [NF_IP_PRE_ROUTING] = 0, |
52 | [NF_IP_POST_ROUTING] = sizeof(struct ipt_standard), | 53 | [NF_IP_POST_ROUTING] = sizeof(struct ipt_standard), |
53 | [NF_IP_LOCAL_OUT] = sizeof(struct ipt_standard) * 2 }, | 54 | [NF_IP_LOCAL_OUT] = sizeof(struct ipt_standard) * 2 |
55 | }, | ||
54 | }, | 56 | }, |
55 | .entries = { | 57 | .entries = { |
56 | /* PRE_ROUTING */ | 58 | IPT_STANDARD_INIT(NF_ACCEPT), /* PRE_ROUTING */ |
57 | { | 59 | IPT_STANDARD_INIT(NF_ACCEPT), /* POST_ROUTING */ |
58 | .entry = { | 60 | IPT_STANDARD_INIT(NF_ACCEPT), /* LOCAL_OUT */ |
59 | .target_offset = sizeof(struct ipt_entry), | ||
60 | .next_offset = sizeof(struct ipt_standard), | ||
61 | }, | ||
62 | .target = { | ||
63 | .target = { | ||
64 | .u = { | ||
65 | .target_size = IPT_ALIGN(sizeof(struct ipt_standard_target)), | ||
66 | }, | ||
67 | }, | ||
68 | .verdict = -NF_ACCEPT - 1, | ||
69 | }, | ||
70 | }, | ||
71 | /* POST_ROUTING */ | ||
72 | { | ||
73 | .entry = { | ||
74 | .target_offset = sizeof(struct ipt_entry), | ||
75 | .next_offset = sizeof(struct ipt_standard), | ||
76 | }, | ||
77 | .target = { | ||
78 | .target = { | ||
79 | .u = { | ||
80 | .target_size = IPT_ALIGN(sizeof(struct ipt_standard_target)), | ||
81 | }, | ||
82 | }, | ||
83 | .verdict = -NF_ACCEPT - 1, | ||
84 | }, | ||
85 | }, | ||
86 | /* LOCAL_OUT */ | ||
87 | { | ||
88 | .entry = { | ||
89 | .target_offset = sizeof(struct ipt_entry), | ||
90 | .next_offset = sizeof(struct ipt_standard), | ||
91 | }, | ||
92 | .target = { | ||
93 | .target = { | ||
94 | .u = { | ||
95 | .target_size = IPT_ALIGN(sizeof(struct ipt_standard_target)), | ||
96 | }, | ||
97 | }, | ||
98 | .verdict = -NF_ACCEPT - 1, | ||
99 | }, | ||
100 | }, | ||
101 | }, | 61 | }, |
102 | /* ERROR */ | 62 | .term = IPT_ERROR_INIT, /* ERROR */ |
103 | .term = { | ||
104 | .entry = { | ||
105 | .target_offset = sizeof(struct ipt_entry), | ||
106 | .next_offset = sizeof(struct ipt_error), | ||
107 | }, | ||
108 | .target = { | ||
109 | .target = { | ||
110 | .u = { | ||
111 | .user = { | ||
112 | .target_size = IPT_ALIGN(sizeof(struct ipt_error_target)), | ||
113 | .name = IPT_ERROR_TARGET, | ||
114 | }, | ||
115 | }, | ||
116 | }, | ||
117 | .errorname = "ERROR", | ||
118 | }, | ||
119 | } | ||
120 | }; | 63 | }; |
121 | 64 | ||
122 | static struct xt_table nat_table = { | 65 | static struct xt_table nat_table = { |
@@ -230,9 +173,7 @@ static int ipt_dnat_checkentry(const char *tablename, | |||
230 | } | 173 | } |
231 | 174 | ||
232 | inline unsigned int | 175 | inline unsigned int |
233 | alloc_null_binding(struct nf_conn *ct, | 176 | alloc_null_binding(struct nf_conn *ct, unsigned int hooknum) |
234 | struct nf_nat_info *info, | ||
235 | unsigned int hooknum) | ||
236 | { | 177 | { |
237 | /* Force range to this IP; let proto decide mapping for | 178 | /* Force range to this IP; let proto decide mapping for |
238 | per-proto parts (hence not IP_NAT_RANGE_PROTO_SPECIFIED). | 179 | per-proto parts (hence not IP_NAT_RANGE_PROTO_SPECIFIED). |
@@ -251,9 +192,7 @@ alloc_null_binding(struct nf_conn *ct, | |||
251 | } | 192 | } |
252 | 193 | ||
253 | unsigned int | 194 | unsigned int |
254 | alloc_null_binding_confirmed(struct nf_conn *ct, | 195 | alloc_null_binding_confirmed(struct nf_conn *ct, unsigned int hooknum) |
255 | struct nf_nat_info *info, | ||
256 | unsigned int hooknum) | ||
257 | { | 196 | { |
258 | __be32 ip | 197 | __be32 ip |
259 | = (HOOK2MANIP(hooknum) == IP_NAT_MANIP_SRC | 198 | = (HOOK2MANIP(hooknum) == IP_NAT_MANIP_SRC |
@@ -275,8 +214,7 @@ int nf_nat_rule_find(struct sk_buff **pskb, | |||
275 | unsigned int hooknum, | 214 | unsigned int hooknum, |
276 | const struct net_device *in, | 215 | const struct net_device *in, |
277 | const struct net_device *out, | 216 | const struct net_device *out, |
278 | struct nf_conn *ct, | 217 | struct nf_conn *ct) |
279 | struct nf_nat_info *info) | ||
280 | { | 218 | { |
281 | int ret; | 219 | int ret; |
282 | 220 | ||
@@ -285,7 +223,7 @@ int nf_nat_rule_find(struct sk_buff **pskb, | |||
285 | if (ret == NF_ACCEPT) { | 223 | if (ret == NF_ACCEPT) { |
286 | if (!nf_nat_initialized(ct, HOOK2MANIP(hooknum))) | 224 | if (!nf_nat_initialized(ct, HOOK2MANIP(hooknum))) |
287 | /* NUL mapping */ | 225 | /* NUL mapping */ |
288 | ret = alloc_null_binding(ct, info, hooknum); | 226 | ret = alloc_null_binding(ct, hooknum); |
289 | } | 227 | } |
290 | return ret; | 228 | return ret; |
291 | } | 229 | } |
diff --git a/net/ipv4/netfilter/nf_nat_standalone.c b/net/ipv4/netfilter/nf_nat_standalone.c index 64bbed2ba7..55dac36dbc 100644 --- a/net/ipv4/netfilter/nf_nat_standalone.c +++ b/net/ipv4/netfilter/nf_nat_standalone.c | |||
@@ -80,7 +80,6 @@ nf_nat_fn(unsigned int hooknum, | |||
80 | struct nf_conn *ct; | 80 | struct nf_conn *ct; |
81 | enum ip_conntrack_info ctinfo; | 81 | enum ip_conntrack_info ctinfo; |
82 | struct nf_conn_nat *nat; | 82 | struct nf_conn_nat *nat; |
83 | struct nf_nat_info *info; | ||
84 | /* maniptype == SRC for postrouting. */ | 83 | /* maniptype == SRC for postrouting. */ |
85 | enum nf_nat_manip_type maniptype = HOOK2MANIP(hooknum); | 84 | enum nf_nat_manip_type maniptype = HOOK2MANIP(hooknum); |
86 | 85 | ||
@@ -129,7 +128,6 @@ nf_nat_fn(unsigned int hooknum, | |||
129 | } | 128 | } |
130 | /* Fall thru... (Only ICMPs can be IP_CT_IS_REPLY) */ | 129 | /* Fall thru... (Only ICMPs can be IP_CT_IS_REPLY) */ |
131 | case IP_CT_NEW: | 130 | case IP_CT_NEW: |
132 | info = &nat->info; | ||
133 | 131 | ||
134 | /* Seen it before? This can happen for loopback, retrans, | 132 | /* Seen it before? This can happen for loopback, retrans, |
135 | or local packets.. */ | 133 | or local packets.. */ |
@@ -138,14 +136,13 @@ nf_nat_fn(unsigned int hooknum, | |||
138 | 136 | ||
139 | if (unlikely(nf_ct_is_confirmed(ct))) | 137 | if (unlikely(nf_ct_is_confirmed(ct))) |
140 | /* NAT module was loaded late */ | 138 | /* NAT module was loaded late */ |
141 | ret = alloc_null_binding_confirmed(ct, info, | 139 | ret = alloc_null_binding_confirmed(ct, hooknum); |
142 | hooknum); | ||
143 | else if (hooknum == NF_IP_LOCAL_IN) | 140 | else if (hooknum == NF_IP_LOCAL_IN) |
144 | /* LOCAL_IN hook doesn't have a chain! */ | 141 | /* LOCAL_IN hook doesn't have a chain! */ |
145 | ret = alloc_null_binding(ct, info, hooknum); | 142 | ret = alloc_null_binding(ct, hooknum); |
146 | else | 143 | else |
147 | ret = nf_nat_rule_find(pskb, hooknum, in, out, | 144 | ret = nf_nat_rule_find(pskb, hooknum, in, out, |
148 | ct, info); | 145 | ct); |
149 | 146 | ||
150 | if (ret != NF_ACCEPT) { | 147 | if (ret != NF_ACCEPT) { |
151 | return ret; | 148 | return ret; |
@@ -160,10 +157,8 @@ nf_nat_fn(unsigned int hooknum, | |||
160 | /* ESTABLISHED */ | 157 | /* ESTABLISHED */ |
161 | NF_CT_ASSERT(ctinfo == IP_CT_ESTABLISHED || | 158 | NF_CT_ASSERT(ctinfo == IP_CT_ESTABLISHED || |
162 | ctinfo == (IP_CT_ESTABLISHED+IP_CT_IS_REPLY)); | 159 | ctinfo == (IP_CT_ESTABLISHED+IP_CT_IS_REPLY)); |
163 | info = &nat->info; | ||
164 | } | 160 | } |
165 | 161 | ||
166 | NF_CT_ASSERT(info); | ||
167 | return nf_nat_packet(ct, ctinfo, hooknum, pskb); | 162 | return nf_nat_packet(ct, ctinfo, hooknum, pskb); |
168 | } | 163 | } |
169 | 164 | ||
diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c index 66026df1cc..4c7e95fa09 100644 --- a/net/ipv4/udp.c +++ b/net/ipv4/udp.c | |||
@@ -118,15 +118,15 @@ static int udp_port_rover; | |||
118 | * Note about this hash function : | 118 | * Note about this hash function : |
119 | * Typical use is probably daddr = 0, only dport is going to vary hash | 119 | * Typical use is probably daddr = 0, only dport is going to vary hash |
120 | */ | 120 | */ |
121 | static inline unsigned int hash_port_and_addr(__u16 port, __be32 addr) | 121 | static inline unsigned int udp_hash_port(__u16 port) |
122 | { | 122 | { |
123 | addr ^= addr >> 16; | 123 | return port; |
124 | addr ^= addr >> 8; | ||
125 | return port ^ addr; | ||
126 | } | 124 | } |
127 | 125 | ||
128 | static inline int __udp_lib_port_inuse(unsigned int hash, int port, | 126 | static inline int __udp_lib_port_inuse(unsigned int hash, int port, |
129 | __be32 daddr, struct hlist_head udptable[]) | 127 | const struct sock *this_sk, |
128 | struct hlist_head udptable[], | ||
129 | const struct udp_get_port_ops *ops) | ||
130 | { | 130 | { |
131 | struct sock *sk; | 131 | struct sock *sk; |
132 | struct hlist_node *node; | 132 | struct hlist_node *node; |
@@ -138,7 +138,10 @@ static inline int __udp_lib_port_inuse(unsigned int hash, int port, | |||
138 | inet = inet_sk(sk); | 138 | inet = inet_sk(sk); |
139 | if (inet->num != port) | 139 | if (inet->num != port) |
140 | continue; | 140 | continue; |
141 | if (inet->rcv_saddr == daddr) | 141 | if (this_sk) { |
142 | if (ops->saddr_cmp(sk, this_sk)) | ||
143 | return 1; | ||
144 | } else if (ops->saddr_any(sk)) | ||
142 | return 1; | 145 | return 1; |
143 | } | 146 | } |
144 | return 0; | 147 | return 0; |
@@ -151,12 +154,11 @@ static inline int __udp_lib_port_inuse(unsigned int hash, int port, | |||
151 | * @snum: port number to look up | 154 | * @snum: port number to look up |
152 | * @udptable: hash list table, must be of UDP_HTABLE_SIZE | 155 | * @udptable: hash list table, must be of UDP_HTABLE_SIZE |
153 | * @port_rover: pointer to record of last unallocated port | 156 | * @port_rover: pointer to record of last unallocated port |
154 | * @saddr_comp: AF-dependent comparison of bound local IP addresses | 157 | * @ops: AF-dependent address operations |
155 | */ | 158 | */ |
156 | int __udp_lib_get_port(struct sock *sk, unsigned short snum, | 159 | int __udp_lib_get_port(struct sock *sk, unsigned short snum, |
157 | struct hlist_head udptable[], int *port_rover, | 160 | struct hlist_head udptable[], int *port_rover, |
158 | int (*saddr_comp)(const struct sock *sk1, | 161 | const struct udp_get_port_ops *ops) |
159 | const struct sock *sk2 ) ) | ||
160 | { | 162 | { |
161 | struct hlist_node *node; | 163 | struct hlist_node *node; |
162 | struct hlist_head *head; | 164 | struct hlist_head *head; |
@@ -176,8 +178,7 @@ int __udp_lib_get_port(struct sock *sk, unsigned short snum, | |||
176 | for (i = 0; i < UDP_HTABLE_SIZE; i++, result++) { | 178 | for (i = 0; i < UDP_HTABLE_SIZE; i++, result++) { |
177 | int size; | 179 | int size; |
178 | 180 | ||
179 | hash = hash_port_and_addr(result, | 181 | hash = ops->hash_port_and_rcv_saddr(result, sk); |
180 | inet_sk(sk)->rcv_saddr); | ||
181 | head = &udptable[hash & (UDP_HTABLE_SIZE - 1)]; | 182 | head = &udptable[hash & (UDP_HTABLE_SIZE - 1)]; |
182 | if (hlist_empty(head)) { | 183 | if (hlist_empty(head)) { |
183 | if (result > sysctl_local_port_range[1]) | 184 | if (result > sysctl_local_port_range[1]) |
@@ -203,17 +204,16 @@ int __udp_lib_get_port(struct sock *sk, unsigned short snum, | |||
203 | result = sysctl_local_port_range[0] | 204 | result = sysctl_local_port_range[0] |
204 | + ((result - sysctl_local_port_range[0]) & | 205 | + ((result - sysctl_local_port_range[0]) & |
205 | (UDP_HTABLE_SIZE - 1)); | 206 | (UDP_HTABLE_SIZE - 1)); |
206 | hash = hash_port_and_addr(result, 0); | 207 | hash = udp_hash_port(result); |
207 | if (__udp_lib_port_inuse(hash, result, | 208 | if (__udp_lib_port_inuse(hash, result, |
208 | 0, udptable)) | 209 | NULL, udptable, ops)) |
209 | continue; | 210 | continue; |
210 | if (!inet_sk(sk)->rcv_saddr) | 211 | if (ops->saddr_any(sk)) |
211 | break; | 212 | break; |
212 | 213 | ||
213 | hash = hash_port_and_addr(result, | 214 | hash = ops->hash_port_and_rcv_saddr(result, sk); |
214 | inet_sk(sk)->rcv_saddr); | ||
215 | if (! __udp_lib_port_inuse(hash, result, | 215 | if (! __udp_lib_port_inuse(hash, result, |
216 | inet_sk(sk)->rcv_saddr, udptable)) | 216 | sk, udptable, ops)) |
217 | break; | 217 | break; |
218 | } | 218 | } |
219 | if (i >= (1 << 16) / UDP_HTABLE_SIZE) | 219 | if (i >= (1 << 16) / UDP_HTABLE_SIZE) |
@@ -221,7 +221,7 @@ int __udp_lib_get_port(struct sock *sk, unsigned short snum, | |||
221 | gotit: | 221 | gotit: |
222 | *port_rover = snum = result; | 222 | *port_rover = snum = result; |
223 | } else { | 223 | } else { |
224 | hash = hash_port_and_addr(snum, 0); | 224 | hash = udp_hash_port(snum); |
225 | head = &udptable[hash & (UDP_HTABLE_SIZE - 1)]; | 225 | head = &udptable[hash & (UDP_HTABLE_SIZE - 1)]; |
226 | 226 | ||
227 | sk_for_each(sk2, node, head) | 227 | sk_for_each(sk2, node, head) |
@@ -231,12 +231,11 @@ gotit: | |||
231 | (!sk2->sk_reuse || !sk->sk_reuse) && | 231 | (!sk2->sk_reuse || !sk->sk_reuse) && |
232 | (!sk2->sk_bound_dev_if || !sk->sk_bound_dev_if || | 232 | (!sk2->sk_bound_dev_if || !sk->sk_bound_dev_if || |
233 | sk2->sk_bound_dev_if == sk->sk_bound_dev_if) && | 233 | sk2->sk_bound_dev_if == sk->sk_bound_dev_if) && |
234 | (*saddr_comp)(sk, sk2)) | 234 | ops->saddr_cmp(sk, sk2)) |
235 | goto fail; | 235 | goto fail; |
236 | 236 | ||
237 | if (inet_sk(sk)->rcv_saddr) { | 237 | if (!ops->saddr_any(sk)) { |
238 | hash = hash_port_and_addr(snum, | 238 | hash = ops->hash_port_and_rcv_saddr(snum, sk); |
239 | inet_sk(sk)->rcv_saddr); | ||
240 | head = &udptable[hash & (UDP_HTABLE_SIZE - 1)]; | 239 | head = &udptable[hash & (UDP_HTABLE_SIZE - 1)]; |
241 | 240 | ||
242 | sk_for_each(sk2, node, head) | 241 | sk_for_each(sk2, node, head) |
@@ -248,7 +247,7 @@ gotit: | |||
248 | !sk->sk_bound_dev_if || | 247 | !sk->sk_bound_dev_if || |
249 | sk2->sk_bound_dev_if == | 248 | sk2->sk_bound_dev_if == |
250 | sk->sk_bound_dev_if) && | 249 | sk->sk_bound_dev_if) && |
251 | (*saddr_comp)(sk, sk2)) | 250 | ops->saddr_cmp(sk, sk2)) |
252 | goto fail; | 251 | goto fail; |
253 | } | 252 | } |
254 | } | 253 | } |
@@ -266,12 +265,12 @@ fail: | |||
266 | } | 265 | } |
267 | 266 | ||
268 | int udp_get_port(struct sock *sk, unsigned short snum, | 267 | int udp_get_port(struct sock *sk, unsigned short snum, |
269 | int (*scmp)(const struct sock *, const struct sock *)) | 268 | const struct udp_get_port_ops *ops) |
270 | { | 269 | { |
271 | return __udp_lib_get_port(sk, snum, udp_hash, &udp_port_rover, scmp); | 270 | return __udp_lib_get_port(sk, snum, udp_hash, &udp_port_rover, ops); |
272 | } | 271 | } |
273 | 272 | ||
274 | int ipv4_rcv_saddr_equal(const struct sock *sk1, const struct sock *sk2) | 273 | static int ipv4_rcv_saddr_equal(const struct sock *sk1, const struct sock *sk2) |
275 | { | 274 | { |
276 | struct inet_sock *inet1 = inet_sk(sk1), *inet2 = inet_sk(sk2); | 275 | struct inet_sock *inet1 = inet_sk(sk1), *inet2 = inet_sk(sk2); |
277 | 276 | ||
@@ -280,9 +279,33 @@ int ipv4_rcv_saddr_equal(const struct sock *sk1, const struct sock *sk2) | |||
280 | inet1->rcv_saddr == inet2->rcv_saddr )); | 279 | inet1->rcv_saddr == inet2->rcv_saddr )); |
281 | } | 280 | } |
282 | 281 | ||
282 | static int ipv4_rcv_saddr_any(const struct sock *sk) | ||
283 | { | ||
284 | return !inet_sk(sk)->rcv_saddr; | ||
285 | } | ||
286 | |||
287 | static inline unsigned int ipv4_hash_port_and_addr(__u16 port, __be32 addr) | ||
288 | { | ||
289 | addr ^= addr >> 16; | ||
290 | addr ^= addr >> 8; | ||
291 | return port ^ addr; | ||
292 | } | ||
293 | |||
294 | static unsigned int ipv4_hash_port_and_rcv_saddr(__u16 port, | ||
295 | const struct sock *sk) | ||
296 | { | ||
297 | return ipv4_hash_port_and_addr(port, inet_sk(sk)->rcv_saddr); | ||
298 | } | ||
299 | |||
300 | const struct udp_get_port_ops udp_ipv4_ops = { | ||
301 | .saddr_cmp = ipv4_rcv_saddr_equal, | ||
302 | .saddr_any = ipv4_rcv_saddr_any, | ||
303 | .hash_port_and_rcv_saddr = ipv4_hash_port_and_rcv_saddr, | ||
304 | }; | ||
305 | |||
283 | static inline int udp_v4_get_port(struct sock *sk, unsigned short snum) | 306 | static inline int udp_v4_get_port(struct sock *sk, unsigned short snum) |
284 | { | 307 | { |
285 | return udp_get_port(sk, snum, ipv4_rcv_saddr_equal); | 308 | return udp_get_port(sk, snum, &udp_ipv4_ops); |
286 | } | 309 | } |
287 | 310 | ||
288 | /* UDP is nearly always wildcards out the wazoo, it makes no sense to try | 311 | /* UDP is nearly always wildcards out the wazoo, it makes no sense to try |
@@ -297,8 +320,8 @@ static struct sock *__udp4_lib_lookup(__be32 saddr, __be16 sport, | |||
297 | unsigned int hash, hashwild; | 320 | unsigned int hash, hashwild; |
298 | int score, best = -1, hport = ntohs(dport); | 321 | int score, best = -1, hport = ntohs(dport); |
299 | 322 | ||
300 | hash = hash_port_and_addr(hport, daddr); | 323 | hash = ipv4_hash_port_and_addr(hport, daddr); |
301 | hashwild = hash_port_and_addr(hport, 0); | 324 | hashwild = udp_hash_port(hport); |
302 | 325 | ||
303 | read_lock(&udp_hash_lock); | 326 | read_lock(&udp_hash_lock); |
304 | 327 | ||
@@ -1198,8 +1221,8 @@ static int __udp4_lib_mcast_deliver(struct sk_buff *skb, | |||
1198 | struct sock *sk, *skw, *sknext; | 1221 | struct sock *sk, *skw, *sknext; |
1199 | int dif; | 1222 | int dif; |
1200 | int hport = ntohs(uh->dest); | 1223 | int hport = ntohs(uh->dest); |
1201 | unsigned int hash = hash_port_and_addr(hport, daddr); | 1224 | unsigned int hash = ipv4_hash_port_and_addr(hport, daddr); |
1202 | unsigned int hashwild = hash_port_and_addr(hport, 0); | 1225 | unsigned int hashwild = udp_hash_port(hport); |
1203 | 1226 | ||
1204 | dif = skb->dev->ifindex; | 1227 | dif = skb->dev->ifindex; |
1205 | 1228 | ||
diff --git a/net/ipv4/udp_impl.h b/net/ipv4/udp_impl.h index 820a477cfa..06d94195e6 100644 --- a/net/ipv4/udp_impl.h +++ b/net/ipv4/udp_impl.h | |||
@@ -5,14 +5,14 @@ | |||
5 | #include <net/protocol.h> | 5 | #include <net/protocol.h> |
6 | #include <net/inet_common.h> | 6 | #include <net/inet_common.h> |
7 | 7 | ||
8 | extern const struct udp_get_port_ops udp_ipv4_ops; | ||
9 | |||
8 | extern int __udp4_lib_rcv(struct sk_buff *, struct hlist_head [], int ); | 10 | extern int __udp4_lib_rcv(struct sk_buff *, struct hlist_head [], int ); |
9 | extern void __udp4_lib_err(struct sk_buff *, u32, struct hlist_head []); | 11 | extern void __udp4_lib_err(struct sk_buff *, u32, struct hlist_head []); |
10 | 12 | ||
11 | extern int __udp_lib_get_port(struct sock *sk, unsigned short snum, | 13 | extern int __udp_lib_get_port(struct sock *sk, unsigned short snum, |
12 | struct hlist_head udptable[], int *port_rover, | 14 | struct hlist_head udptable[], int *port_rover, |
13 | int (*)(const struct sock*,const struct sock*)); | 15 | const struct udp_get_port_ops *ops); |
14 | extern int ipv4_rcv_saddr_equal(const struct sock *, const struct sock *); | ||
15 | |||
16 | 16 | ||
17 | extern int udp_setsockopt(struct sock *sk, int level, int optname, | 17 | extern int udp_setsockopt(struct sock *sk, int level, int optname, |
18 | char __user *optval, int optlen); | 18 | char __user *optval, int optlen); |
diff --git a/net/ipv4/udplite.c b/net/ipv4/udplite.c index f34fd686a8..3653b32dce 100644 --- a/net/ipv4/udplite.c +++ b/net/ipv4/udplite.c | |||
@@ -19,14 +19,15 @@ struct hlist_head udplite_hash[UDP_HTABLE_SIZE]; | |||
19 | static int udplite_port_rover; | 19 | static int udplite_port_rover; |
20 | 20 | ||
21 | int udplite_get_port(struct sock *sk, unsigned short p, | 21 | int udplite_get_port(struct sock *sk, unsigned short p, |
22 | int (*c)(const struct sock *, const struct sock *)) | 22 | const struct udp_get_port_ops *ops) |
23 | { | 23 | { |
24 | return __udp_lib_get_port(sk, p, udplite_hash, &udplite_port_rover, c); | 24 | return __udp_lib_get_port(sk, p, udplite_hash, |
25 | &udplite_port_rover, ops); | ||
25 | } | 26 | } |
26 | 27 | ||
27 | static int udplite_v4_get_port(struct sock *sk, unsigned short snum) | 28 | static int udplite_v4_get_port(struct sock *sk, unsigned short snum) |
28 | { | 29 | { |
29 | return udplite_get_port(sk, snum, ipv4_rcv_saddr_equal); | 30 | return udplite_get_port(sk, snum, &udp_ipv4_ops); |
30 | } | 31 | } |
31 | 32 | ||
32 | static int udplite_rcv(struct sk_buff *skb) | 33 | static int udplite_rcv(struct sk_buff *skb) |