From: Patrick McHardy <kaber@trash.net>
To: Patrick McHardy <kaber@trash.net>
Cc: Andrew McDonald <andrew@mcdonald.org.uk>,
netdev@vger.kernel.org, yoshfuji@linux-ipv6.org,
davem@davemloft.net, linux-kernel@vger.kernel.org
Subject: Re: [PATCH 2.6.13rc3] IPv6: Check interface bindings on IPv6 raw socket reception
Date: Sun, 24 Jul 2005 07:39:12 +0200 [thread overview]
Message-ID: <42E32980.2090604@trash.net> (raw)
In-Reply-To: <42E2DFAE.8070101@trash.net>
[-- Attachment #1: Type: text/plain, Size: 684 bytes --]
Patrick McHardy wrote:
> Andrew McDonald wrote:
>
>> Take account of whether a socket is bound to a particular device when
>> selecting an IPv6 raw socket to receive a packet. Also perform this
>> check when receiving IPv6 packets with router alert options.
>
> I guess this one makes sense on top.
>
> [IPV4/6]: Check if packet was actually delivered to a raw socket to decide whether to send an ICMP unreachable
The Last patch didn't handle ICMP socket filters correctly, here is a
better one.
If a raw socket is bound to a single device the packet might not be
delivered even though there is a socket in the protocol hash. Send
back an ICMP protocol unreachable in this case.
[-- Attachment #2: x.diff --]
[-- Type: text/x-patch, Size: 4427 bytes --]
[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>
---
commit eb82d02518ac3a400663163995097749d91c7c4c
tree 1719713411b5e656ab5926ee633c39c0edfb1108
parent 36245c9aaddbed7e50d9600c8d1889ebee48a90f
author Patrick McHardy <kaber@trash.net> Sun, 24 Jul 2005 06:54:32 +0200
committer Patrick McHardy <kaber@trash.net> Sun, 24 Jul 2005 06:54:32 +0200
include/net/raw.h | 2 +-
include/net/rawv6.h | 2 +-
net/ipv4/ip_input.c | 4 ++--
net/ipv4/raw.c | 5 ++++-
net/ipv6/ip6_input.c | 4 ++--
net/ipv6/raw.c | 5 ++++-
6 files changed, 14 insertions(+), 8 deletions(-)
diff --git a/include/net/raw.h b/include/net/raw.h
--- a/include/net/raw.h
+++ b/include/net/raw.h
@@ -37,6 +37,6 @@ extern struct sock *__raw_v4_lookup(stru
unsigned long raddr, unsigned long laddr,
int dif);
-extern void raw_v4_input(struct sk_buff *skb, struct iphdr *iph, int hash);
+extern int raw_v4_input(struct sk_buff *skb, struct iphdr *iph, int hash);
#endif /* _RAW_H */
diff --git a/include/net/rawv6.h b/include/net/rawv6.h
--- a/include/net/rawv6.h
+++ b/include/net/rawv6.h
@@ -7,7 +7,7 @@
extern struct hlist_head raw_v6_htable[RAWV6_HTABLE_SIZE];
extern rwlock_t raw_v6_lock;
-extern void ipv6_raw_deliver(struct sk_buff *skb, int nexthdr);
+extern int ipv6_raw_deliver(struct sk_buff *skb, int nexthdr);
extern struct sock *__raw_v6_lookup(struct sock *sk, unsigned short num,
struct in6_addr *loc_addr, struct in6_addr *rmt_addr,
diff --git a/net/ipv4/ip_input.c b/net/ipv4/ip_input.c
--- a/net/ipv4/ip_input.c
+++ b/net/ipv4/ip_input.c
@@ -225,8 +225,8 @@ static inline int ip_local_deliver_finis
/* If there maybe a raw socket we must check - if not we
* don't care less
*/
- if (raw_sk)
- raw_v4_input(skb, skb->nh.iph, hash);
+ if (raw_sk && !raw_v4_input(skb, skb->nh.iph, hash))
+ raw_sk = NULL;
if ((ipprot = rcu_dereference(inet_protos[hash])) != NULL) {
int ret;
diff --git a/net/ipv4/raw.c b/net/ipv4/raw.c
--- a/net/ipv4/raw.c
+++ b/net/ipv4/raw.c
@@ -150,10 +150,11 @@ static __inline__ int icmp_filter(struct
* RFC 1122: SHOULD pass TOS value up to the transport layer.
* -> It does. And not only TOS, but all IP header.
*/
-void raw_v4_input(struct sk_buff *skb, struct iphdr *iph, int hash)
+int raw_v4_input(struct sk_buff *skb, struct iphdr *iph, int hash)
{
struct sock *sk;
struct hlist_head *head;
+ int delivered = 0;
read_lock(&raw_v4_lock);
head = &raw_v4_htable[hash];
@@ -164,6 +165,7 @@ void raw_v4_input(struct sk_buff *skb, s
skb->dev->ifindex);
while (sk) {
+ delivered = 1;
if (iph->protocol != IPPROTO_ICMP || !icmp_filter(sk, skb)) {
struct sk_buff *clone = skb_clone(skb, GFP_ATOMIC);
@@ -177,6 +179,7 @@ void raw_v4_input(struct sk_buff *skb, s
}
out:
read_unlock(&raw_v4_lock);
+ return delivered;
}
void raw_err (struct sock *sk, struct sk_buff *skb, u32 info)
diff --git a/net/ipv6/ip6_input.c b/net/ipv6/ip6_input.c
--- a/net/ipv6/ip6_input.c
+++ b/net/ipv6/ip6_input.c
@@ -166,8 +166,8 @@ resubmit:
nexthdr = skb->nh.raw[nhoff];
raw_sk = sk_head(&raw_v6_htable[nexthdr & (MAX_INET_PROTOS - 1)]);
- if (raw_sk)
- ipv6_raw_deliver(skb, nexthdr);
+ if (raw_sk && !ipv6_raw_deliver(skb, nexthdr))
+ raw_sk = NULL;
hash = nexthdr & (MAX_INET_PROTOS - 1);
if ((ipprot = rcu_dereference(inet6_protos[hash])) != NULL) {
diff --git a/net/ipv6/raw.c b/net/ipv6/raw.c
--- a/net/ipv6/raw.c
+++ b/net/ipv6/raw.c
@@ -141,11 +141,12 @@ static __inline__ int icmpv6_filter(stru
*
* Caller owns SKB so we must make clones.
*/
-void ipv6_raw_deliver(struct sk_buff *skb, int nexthdr)
+int ipv6_raw_deliver(struct sk_buff *skb, int nexthdr)
{
struct in6_addr *saddr;
struct in6_addr *daddr;
struct sock *sk;
+ int delivered = 0;
__u8 hash;
saddr = &skb->nh.ipv6h->saddr;
@@ -167,6 +168,7 @@ void ipv6_raw_deliver(struct sk_buff *sk
sk = __raw_v6_lookup(sk, nexthdr, daddr, saddr, skb->dev->ifindex);
while (sk) {
+ delivered = 1;
if (nexthdr != IPPROTO_ICMPV6 || !icmpv6_filter(sk, skb)) {
struct sk_buff *clone = skb_clone(skb, GFP_ATOMIC);
@@ -179,6 +181,7 @@ void ipv6_raw_deliver(struct sk_buff *sk
}
out:
read_unlock(&raw_v6_lock);
+ return delivered;
}
/* This cleans up af_inet6 a bit. -DaveM */
next prev parent reply other threads:[~2005-07-24 5:39 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2005-07-23 18:04 [PATCH 2.6.13rc3] IPv6: Check interface bindings on IPv6 raw socket reception Andrew McDonald
2005-07-24 0:24 ` Patrick McHardy
2005-07-24 5:39 ` Patrick McHardy [this message]
2005-07-27 21:38 ` David S. Miller
2005-07-27 21:38 ` David S. Miller
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=42E32980.2090604@trash.net \
--to=kaber@trash.net \
--cc=andrew@mcdonald.org.uk \
--cc=davem@davemloft.net \
--cc=linux-kernel@vger.kernel.org \
--cc=netdev@vger.kernel.org \
--cc=yoshfuji@linux-ipv6.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.