aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv4/raw.c
diff options
context:
space:
mode:
authorPavel Emelyanov <xemul@openvz.org>2007-11-20 01:35:07 -0500
committerDavid S. Miller <davem@davemloft.net>2008-01-28 17:54:28 -0500
commit7bc54c90307b4bc3d7fb2ffd6ad8fbda0671a45e (patch)
tree74e2030d9603c41ce5dc3699862804a69300b7dc /net/ipv4/raw.c
parente372c41401993b45c721c4d92730e7e0a79f7c1b (diff)
[IPv4] RAW: Compact the API for the kernel
The raw sockets functions are explicitly used from inside the kernel in two places: 1. in ip_local_deliver_finish to intercept skb-s 2. in icmp_error For this purposes many functions and even data structures, that are naturally internal for raw protocol, are exported. Compact the API to two functions and hide all the other (including hash table and rwlock) inside the net/ipv4/raw.c Signed-off-by: Pavel Emelyanov <xemul@openvz.org> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv4/raw.c')
-rw-r--r--net/ipv4/raw.c53
1 files changed, 48 insertions, 5 deletions
diff --git a/net/ipv4/raw.c b/net/ipv4/raw.c
index b80987d2fc55..8a506618b912 100644
--- a/net/ipv4/raw.c
+++ b/net/ipv4/raw.c
@@ -80,8 +80,10 @@
80#include <linux/netfilter.h> 80#include <linux/netfilter.h>
81#include <linux/netfilter_ipv4.h> 81#include <linux/netfilter_ipv4.h>
82 82
83struct hlist_head raw_v4_htable[RAWV4_HTABLE_SIZE]; 83#define RAWV4_HTABLE_SIZE MAX_INET_PROTOS
84DEFINE_RWLOCK(raw_v4_lock); 84
85static struct hlist_head raw_v4_htable[RAWV4_HTABLE_SIZE];
86static DEFINE_RWLOCK(raw_v4_lock);
85 87
86static void raw_v4_hash(struct sock *sk) 88static void raw_v4_hash(struct sock *sk)
87{ 89{
@@ -102,7 +104,7 @@ static void raw_v4_unhash(struct sock *sk)
102 write_unlock_bh(&raw_v4_lock); 104 write_unlock_bh(&raw_v4_lock);
103} 105}
104 106
105struct sock *__raw_v4_lookup(struct sock *sk, unsigned short num, 107static struct sock *__raw_v4_lookup(struct sock *sk, unsigned short num,
106 __be32 raddr, __be32 laddr, 108 __be32 raddr, __be32 laddr,
107 int dif) 109 int dif)
108{ 110{
@@ -150,7 +152,7 @@ static __inline__ int icmp_filter(struct sock *sk, struct sk_buff *skb)
150 * RFC 1122: SHOULD pass TOS value up to the transport layer. 152 * RFC 1122: SHOULD pass TOS value up to the transport layer.
151 * -> It does. And not only TOS, but all IP header. 153 * -> It does. And not only TOS, but all IP header.
152 */ 154 */
153int raw_v4_input(struct sk_buff *skb, struct iphdr *iph, int hash) 155static int raw_v4_input(struct sk_buff *skb, struct iphdr *iph, int hash)
154{ 156{
155 struct sock *sk; 157 struct sock *sk;
156 struct hlist_head *head; 158 struct hlist_head *head;
@@ -182,7 +184,25 @@ out:
182 return delivered; 184 return delivered;
183} 185}
184 186
185void raw_err (struct sock *sk, struct sk_buff *skb, u32 info) 187int raw_local_deliver(struct sk_buff *skb, int protocol)
188{
189 int hash;
190 struct sock *raw_sk;
191
192 hash = protocol & (RAWV4_HTABLE_SIZE - 1);
193 raw_sk = sk_head(&raw_v4_htable[hash]);
194
195 /* If there maybe a raw socket we must check - if not we
196 * don't care less
197 */
198 if (raw_sk && !raw_v4_input(skb, ip_hdr(skb), hash))
199 raw_sk = NULL;
200
201 return raw_sk != NULL;
202
203}
204
205static void raw_err(struct sock *sk, struct sk_buff *skb, u32 info)
186{ 206{
187 struct inet_sock *inet = inet_sk(sk); 207 struct inet_sock *inet = inet_sk(sk);
188 const int type = icmp_hdr(skb)->type; 208 const int type = icmp_hdr(skb)->type;
@@ -236,6 +256,29 @@ void raw_err (struct sock *sk, struct sk_buff *skb, u32 info)
236 } 256 }
237} 257}
238 258
259void raw_icmp_error(struct sk_buff *skb, int protocol, u32 info)
260{
261 int hash;
262 struct sock *raw_sk;
263 struct iphdr *iph;
264
265 hash = protocol & (RAWV4_HTABLE_SIZE - 1);
266
267 read_lock(&raw_v4_lock);
268 raw_sk = sk_head(&raw_v4_htable[hash]);
269 if (raw_sk != NULL) {
270 iph = (struct iphdr *)skb->data;
271 while ((raw_sk = __raw_v4_lookup(raw_sk, protocol, iph->daddr,
272 iph->saddr,
273 skb->dev->ifindex)) != NULL) {
274 raw_err(raw_sk, skb, info);
275 raw_sk = sk_next(raw_sk);
276 iph = (struct iphdr *)skb->data;
277 }
278 }
279 read_unlock(&raw_v4_lock);
280}
281
239static int raw_rcv_skb(struct sock * sk, struct sk_buff * skb) 282static int raw_rcv_skb(struct sock * sk, struct sk_buff * skb)
240{ 283{
241 /* Charge it to the socket. */ 284 /* Charge it to the socket. */