diff options
author | Patrick McHardy <kaber@trash.net> | 2005-08-09 22:45:02 -0400 |
---|---|---|
committer | David S. Miller <davem@sunset.davemloft.net> | 2005-08-29 18:37:22 -0400 |
commit | d13964f4490157b8a290903362bfbc54f750a6bc (patch) | |
tree | 377297846b513224a30185fb279afd6640e361f5 /net/ipv4 | |
parent | 0bd1b59b15e4057101c89d4db15a3683c0d897f7 (diff) |
[IPV4/6]: Check if packet was actually delivered to a raw socket to decide whether to send an ICMP unreachable
Signed-off-by: Patrick McHardy <kaber@trash.net>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv4')
-rw-r--r-- | net/ipv4/ip_input.c | 4 | ||||
-rw-r--r-- | net/ipv4/raw.c | 5 |
2 files changed, 6 insertions, 3 deletions
diff --git a/net/ipv4/ip_input.c b/net/ipv4/ip_input.c index d603247bdfe9..81e18023dc19 100644 --- a/net/ipv4/ip_input.c +++ b/net/ipv4/ip_input.c | |||
@@ -225,8 +225,8 @@ static inline int ip_local_deliver_finish(struct sk_buff *skb) | |||
225 | /* If there maybe a raw socket we must check - if not we | 225 | /* If there maybe a raw socket we must check - if not we |
226 | * don't care less | 226 | * don't care less |
227 | */ | 227 | */ |
228 | if (raw_sk) | 228 | if (raw_sk && !raw_v4_input(skb, skb->nh.iph, hash)) |
229 | raw_v4_input(skb, skb->nh.iph, hash); | 229 | raw_sk = NULL; |
230 | 230 | ||
231 | if ((ipprot = rcu_dereference(inet_protos[hash])) != NULL) { | 231 | if ((ipprot = rcu_dereference(inet_protos[hash])) != NULL) { |
232 | int ret; | 232 | int ret; |
diff --git a/net/ipv4/raw.c b/net/ipv4/raw.c index d1835b1bc8c4..e222c5c26b32 100644 --- a/net/ipv4/raw.c +++ b/net/ipv4/raw.c | |||
@@ -150,10 +150,11 @@ static __inline__ int icmp_filter(struct sock *sk, struct sk_buff *skb) | |||
150 | * RFC 1122: SHOULD pass TOS value up to the transport layer. | 150 | * RFC 1122: SHOULD pass TOS value up to the transport layer. |
151 | * -> It does. And not only TOS, but all IP header. | 151 | * -> It does. And not only TOS, but all IP header. |
152 | */ | 152 | */ |
153 | void raw_v4_input(struct sk_buff *skb, struct iphdr *iph, int hash) | 153 | int raw_v4_input(struct sk_buff *skb, struct iphdr *iph, int hash) |
154 | { | 154 | { |
155 | struct sock *sk; | 155 | struct sock *sk; |
156 | struct hlist_head *head; | 156 | struct hlist_head *head; |
157 | int delivered = 0; | ||
157 | 158 | ||
158 | read_lock(&raw_v4_lock); | 159 | read_lock(&raw_v4_lock); |
159 | head = &raw_v4_htable[hash]; | 160 | head = &raw_v4_htable[hash]; |
@@ -164,6 +165,7 @@ void raw_v4_input(struct sk_buff *skb, struct iphdr *iph, int hash) | |||
164 | skb->dev->ifindex); | 165 | skb->dev->ifindex); |
165 | 166 | ||
166 | while (sk) { | 167 | while (sk) { |
168 | delivered = 1; | ||
167 | if (iph->protocol != IPPROTO_ICMP || !icmp_filter(sk, skb)) { | 169 | if (iph->protocol != IPPROTO_ICMP || !icmp_filter(sk, skb)) { |
168 | struct sk_buff *clone = skb_clone(skb, GFP_ATOMIC); | 170 | struct sk_buff *clone = skb_clone(skb, GFP_ATOMIC); |
169 | 171 | ||
@@ -177,6 +179,7 @@ void raw_v4_input(struct sk_buff *skb, struct iphdr *iph, int hash) | |||
177 | } | 179 | } |
178 | out: | 180 | out: |
179 | read_unlock(&raw_v4_lock); | 181 | read_unlock(&raw_v4_lock); |
182 | return delivered; | ||
180 | } | 183 | } |
181 | 184 | ||
182 | void raw_err (struct sock *sk, struct sk_buff *skb, u32 info) | 185 | void raw_err (struct sock *sk, struct sk_buff *skb, u32 info) |