Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 78161
b: refs/heads/master
c: 7bc54c9
h: refs/heads/master
i:
  78159: 8437920
v: v3
  • Loading branch information
Pavel Emelyanov authored and David S. Miller committed Jan 28, 2008
1 parent 46a32ad commit 8f1f131
Show file tree
Hide file tree
Showing 5 changed files with 57 additions and 48 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: e372c41401993b45c721c4d92730e7e0a79f7c1b
refs/heads/master: 7bc54c90307b4bc3d7fb2ffd6ad8fbda0671a45e
19 changes: 3 additions & 16 deletions trunk/include/net/raw.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,23 +22,10 @@

extern struct proto raw_prot;

extern void raw_err(struct sock *, struct sk_buff *, u32 info);
extern int raw_rcv(struct sock *, struct sk_buff *);

/* Note: v4 ICMP wants to get at this stuff, if you change the
* hashing mechanism, make sure you update icmp.c as well.
*/
#define RAWV4_HTABLE_SIZE MAX_INET_PROTOS
extern struct hlist_head raw_v4_htable[RAWV4_HTABLE_SIZE];

extern rwlock_t raw_v4_lock;
void raw_icmp_error(struct sk_buff *, int, u32);
int raw_local_deliver(struct sk_buff *, int);


extern struct sock *__raw_v4_lookup(struct sock *sk, unsigned short num,
__be32 raddr, __be32 laddr,
int dif);

extern int raw_v4_input(struct sk_buff *skb, struct iphdr *iph, int hash);
extern int raw_rcv(struct sock *, struct sk_buff *);

#ifdef CONFIG_PROC_FS
extern int raw_proc_init(void);
Expand Down
15 changes: 1 addition & 14 deletions trunk/net/ipv4/icmp.c
Original file line number Diff line number Diff line change
Expand Up @@ -603,7 +603,6 @@ static void icmp_unreach(struct sk_buff *skb)
struct icmphdr *icmph;
int hash, protocol;
struct net_protocol *ipprot;
struct sock *raw_sk;
u32 info = 0;

/*
Expand Down Expand Up @@ -697,21 +696,9 @@ static void icmp_unreach(struct sk_buff *skb)
/*
* Deliver ICMP message to raw sockets. Pretty useless feature?
*/
raw_icmp_error(skb, protocol, info);

/* Note: See raw.c and net/raw.h, RAWV4_HTABLE_SIZE==MAX_INET_PROTOS */
hash = protocol & (MAX_INET_PROTOS - 1);
read_lock(&raw_v4_lock);
if ((raw_sk = sk_head(&raw_v4_htable[hash])) != NULL) {
while ((raw_sk = __raw_v4_lookup(raw_sk, protocol, iph->daddr,
iph->saddr,
skb->dev->ifindex)) != NULL) {
raw_err(raw_sk, skb, info);
raw_sk = sk_next(raw_sk);
iph = (struct iphdr *)skb->data;
}
}
read_unlock(&raw_v4_lock);

rcu_read_lock();
ipprot = rcu_dereference(inet_protos[hash]);
if (ipprot && ipprot->err_handler)
Expand Down
16 changes: 4 additions & 12 deletions trunk/net/ipv4/ip_input.c
Original file line number Diff line number Diff line change
Expand Up @@ -204,22 +204,14 @@ static int ip_local_deliver_finish(struct sk_buff *skb)

rcu_read_lock();
{
/* Note: See raw.c and net/raw.h, RAWV4_HTABLE_SIZE==MAX_INET_PROTOS */
int protocol = ip_hdr(skb)->protocol;
int hash;
struct sock *raw_sk;
int hash, raw;
struct net_protocol *ipprot;

resubmit:
hash = protocol & (MAX_INET_PROTOS - 1);
raw_sk = sk_head(&raw_v4_htable[hash]);

/* If there maybe a raw socket we must check - if not we
* don't care less
*/
if (raw_sk && !raw_v4_input(skb, ip_hdr(skb), hash))
raw_sk = NULL;
raw = raw_local_deliver(skb, protocol);

hash = protocol & (MAX_INET_PROTOS - 1);
if ((ipprot = rcu_dereference(inet_protos[hash])) != NULL) {
int ret;

Expand All @@ -237,7 +229,7 @@ static int ip_local_deliver_finish(struct sk_buff *skb)
}
IP_INC_STATS_BH(IPSTATS_MIB_INDELIVERS);
} else {
if (!raw_sk) {
if (!raw) {
if (xfrm4_policy_check(NULL, XFRM_POLICY_IN, skb)) {
IP_INC_STATS_BH(IPSTATS_MIB_INUNKNOWNPROTOS);
icmp_send(skb, ICMP_DEST_UNREACH,
Expand Down
53 changes: 48 additions & 5 deletions trunk/net/ipv4/raw.c
Original file line number Diff line number Diff line change
Expand Up @@ -80,8 +80,10 @@
#include <linux/netfilter.h>
#include <linux/netfilter_ipv4.h>

struct hlist_head raw_v4_htable[RAWV4_HTABLE_SIZE];
DEFINE_RWLOCK(raw_v4_lock);
#define RAWV4_HTABLE_SIZE MAX_INET_PROTOS

static struct hlist_head raw_v4_htable[RAWV4_HTABLE_SIZE];
static DEFINE_RWLOCK(raw_v4_lock);

static void raw_v4_hash(struct sock *sk)
{
Expand All @@ -102,7 +104,7 @@ static void raw_v4_unhash(struct sock *sk)
write_unlock_bh(&raw_v4_lock);
}

struct sock *__raw_v4_lookup(struct sock *sk, unsigned short num,
static struct sock *__raw_v4_lookup(struct sock *sk, unsigned short num,
__be32 raddr, __be32 laddr,
int dif)
{
Expand Down Expand Up @@ -150,7 +152,7 @@ static __inline__ int icmp_filter(struct sock *sk, struct sk_buff *skb)
* RFC 1122: SHOULD pass TOS value up to the transport layer.
* -> It does. And not only TOS, but all IP header.
*/
int raw_v4_input(struct sk_buff *skb, struct iphdr *iph, int hash)
static int raw_v4_input(struct sk_buff *skb, struct iphdr *iph, int hash)
{
struct sock *sk;
struct hlist_head *head;
Expand Down Expand Up @@ -182,7 +184,25 @@ int raw_v4_input(struct sk_buff *skb, struct iphdr *iph, int hash)
return delivered;
}

void raw_err (struct sock *sk, struct sk_buff *skb, u32 info)
int raw_local_deliver(struct sk_buff *skb, int protocol)
{
int hash;
struct sock *raw_sk;

hash = protocol & (RAWV4_HTABLE_SIZE - 1);
raw_sk = sk_head(&raw_v4_htable[hash]);

/* If there maybe a raw socket we must check - if not we
* don't care less
*/
if (raw_sk && !raw_v4_input(skb, ip_hdr(skb), hash))
raw_sk = NULL;

return raw_sk != NULL;

}

static void raw_err(struct sock *sk, struct sk_buff *skb, u32 info)
{
struct inet_sock *inet = inet_sk(sk);
const int type = icmp_hdr(skb)->type;
Expand Down Expand Up @@ -236,6 +256,29 @@ void raw_err (struct sock *sk, struct sk_buff *skb, u32 info)
}
}

void raw_icmp_error(struct sk_buff *skb, int protocol, u32 info)
{
int hash;
struct sock *raw_sk;
struct iphdr *iph;

hash = protocol & (RAWV4_HTABLE_SIZE - 1);

read_lock(&raw_v4_lock);
raw_sk = sk_head(&raw_v4_htable[hash]);
if (raw_sk != NULL) {
iph = (struct iphdr *)skb->data;
while ((raw_sk = __raw_v4_lookup(raw_sk, protocol, iph->daddr,
iph->saddr,
skb->dev->ifindex)) != NULL) {
raw_err(raw_sk, skb, info);
raw_sk = sk_next(raw_sk);
iph = (struct iphdr *)skb->data;
}
}
read_unlock(&raw_v4_lock);
}

static int raw_rcv_skb(struct sock * sk, struct sk_buff * skb)
{
/* Charge it to the socket. */
Expand Down

0 comments on commit 8f1f131

Please sign in to comment.