raw.c (74be62c7cefbf320e0605f3da6639ef80448ff00) | raw.c (67359930e185c491b47cb958d5f1d6c1af4598a2) |
---|---|
1/* 2 * INET An implementation of the TCP/IP protocol suite for the LINUX 3 * operating system. INET is implemented using the BSD Socket 4 * interface as the means of communication with the user level. 5 * 6 * RAW - implementation of IP "raw" sockets. 7 * 8 * Authors: Ross Biro --- 108 unchanged lines hidden (view full) --- 117 write_lock_bh(&h->lock); 118 if (sk_del_node_init(sk)) 119 sock_prot_inuse_add(sock_net(sk), sk->sk_prot, -1); 120 write_unlock_bh(&h->lock); 121} 122EXPORT_SYMBOL_GPL(raw_unhash_sk); 123 124struct sock *__raw_v4_lookup(struct net *net, struct sock *sk, | 1/* 2 * INET An implementation of the TCP/IP protocol suite for the LINUX 3 * operating system. INET is implemented using the BSD Socket 4 * interface as the means of communication with the user level. 5 * 6 * RAW - implementation of IP "raw" sockets. 7 * 8 * Authors: Ross Biro --- 108 unchanged lines hidden (view full) --- 117 write_lock_bh(&h->lock); 118 if (sk_del_node_init(sk)) 119 sock_prot_inuse_add(sock_net(sk), sk->sk_prot, -1); 120 write_unlock_bh(&h->lock); 121} 122EXPORT_SYMBOL_GPL(raw_unhash_sk); 123 124struct sock *__raw_v4_lookup(struct net *net, struct sock *sk, |
125 unsigned short num, __be32 raddr, __be32 laddr, int dif) | 125 unsigned short num, __be32 raddr, __be32 laddr, 126 int dif, int sdif) |
126{ 127 sk_for_each_from(sk) { 128 struct inet_sock *inet = inet_sk(sk); 129 130 if (net_eq(sock_net(sk), net) && inet->inet_num == num && 131 !(inet->inet_daddr && inet->inet_daddr != raddr) && 132 !(inet->inet_rcv_saddr && inet->inet_rcv_saddr != laddr) && | 127{ 128 sk_for_each_from(sk) { 129 struct inet_sock *inet = inet_sk(sk); 130 131 if (net_eq(sock_net(sk), net) && inet->inet_num == num && 132 !(inet->inet_daddr && inet->inet_daddr != raddr) && 133 !(inet->inet_rcv_saddr && inet->inet_rcv_saddr != laddr) && |
133 !(sk->sk_bound_dev_if && sk->sk_bound_dev_if != dif)) | 134 !(sk->sk_bound_dev_if && sk->sk_bound_dev_if != dif && 135 sk->sk_bound_dev_if != sdif)) |
134 goto found; /* gotcha */ 135 } 136 sk = NULL; 137found: 138 return sk; 139} 140EXPORT_SYMBOL_GPL(__raw_v4_lookup); 141 --- 24 unchanged lines hidden (view full) --- 166/* IP input processing comes here for RAW socket delivery. 167 * Caller owns SKB, so we must make clones. 168 * 169 * RFC 1122: SHOULD pass TOS value up to the transport layer. 170 * -> It does. And not only TOS, but all IP header. 171 */ 172static int raw_v4_input(struct sk_buff *skb, const struct iphdr *iph, int hash) 173{ | 136 goto found; /* gotcha */ 137 } 138 sk = NULL; 139found: 140 return sk; 141} 142EXPORT_SYMBOL_GPL(__raw_v4_lookup); 143 --- 24 unchanged lines hidden (view full) --- 168/* IP input processing comes here for RAW socket delivery. 169 * Caller owns SKB, so we must make clones. 170 * 171 * RFC 1122: SHOULD pass TOS value up to the transport layer. 172 * -> It does. And not only TOS, but all IP header. 173 */ 174static int raw_v4_input(struct sk_buff *skb, const struct iphdr *iph, int hash) 175{ |
176 int sdif = inet_sdif(skb); |
|
174 struct sock *sk; 175 struct hlist_head *head; 176 int delivered = 0; 177 struct net *net; 178 179 read_lock(&raw_v4_hashinfo.lock); 180 head = &raw_v4_hashinfo.ht[hash]; 181 if (hlist_empty(head)) 182 goto out; 183 184 net = dev_net(skb->dev); 185 sk = __raw_v4_lookup(net, __sk_head(head), iph->protocol, 186 iph->saddr, iph->daddr, | 177 struct sock *sk; 178 struct hlist_head *head; 179 int delivered = 0; 180 struct net *net; 181 182 read_lock(&raw_v4_hashinfo.lock); 183 head = &raw_v4_hashinfo.ht[hash]; 184 if (hlist_empty(head)) 185 goto out; 186 187 net = dev_net(skb->dev); 188 sk = __raw_v4_lookup(net, __sk_head(head), iph->protocol, 189 iph->saddr, iph->daddr, |
187 skb->dev->ifindex); | 190 skb->dev->ifindex, sdif); |
188 189 while (sk) { 190 delivered = 1; 191 if ((iph->protocol != IPPROTO_ICMP || !icmp_filter(sk, skb)) && 192 ip_mc_sf_allow(sk, iph->daddr, iph->saddr, 193 skb->dev->ifindex)) { 194 struct sk_buff *clone = skb_clone(skb, GFP_ATOMIC); 195 196 /* Not releasing hash table! */ 197 if (clone) 198 raw_rcv(sk, clone); 199 } 200 sk = __raw_v4_lookup(net, sk_next(sk), iph->protocol, 201 iph->saddr, iph->daddr, | 191 192 while (sk) { 193 delivered = 1; 194 if ((iph->protocol != IPPROTO_ICMP || !icmp_filter(sk, skb)) && 195 ip_mc_sf_allow(sk, iph->daddr, iph->saddr, 196 skb->dev->ifindex)) { 197 struct sk_buff *clone = skb_clone(skb, GFP_ATOMIC); 198 199 /* Not releasing hash table! */ 200 if (clone) 201 raw_rcv(sk, clone); 202 } 203 sk = __raw_v4_lookup(net, sk_next(sk), iph->protocol, 204 iph->saddr, iph->daddr, |
202 skb->dev->ifindex); | 205 skb->dev->ifindex, sdif); |
203 } 204out: 205 read_unlock(&raw_v4_hashinfo.lock); 206 return delivered; 207} 208 209int raw_local_deliver(struct sk_buff *skb, int protocol) 210{ --- 81 unchanged lines hidden (view full) --- 292 const struct iphdr *iph; 293 struct net *net; 294 295 hash = protocol & (RAW_HTABLE_SIZE - 1); 296 297 read_lock(&raw_v4_hashinfo.lock); 298 raw_sk = sk_head(&raw_v4_hashinfo.ht[hash]); 299 if (raw_sk) { | 206 } 207out: 208 read_unlock(&raw_v4_hashinfo.lock); 209 return delivered; 210} 211 212int raw_local_deliver(struct sk_buff *skb, int protocol) 213{ --- 81 unchanged lines hidden (view full) --- 295 const struct iphdr *iph; 296 struct net *net; 297 298 hash = protocol & (RAW_HTABLE_SIZE - 1); 299 300 read_lock(&raw_v4_hashinfo.lock); 301 raw_sk = sk_head(&raw_v4_hashinfo.ht[hash]); 302 if (raw_sk) { |
303 int dif = skb->dev->ifindex; 304 int sdif = inet_sdif(skb); 305 |
|
300 iph = (const struct iphdr *)skb->data; 301 net = dev_net(skb->dev); 302 303 while ((raw_sk = __raw_v4_lookup(net, raw_sk, protocol, 304 iph->daddr, iph->saddr, | 306 iph = (const struct iphdr *)skb->data; 307 net = dev_net(skb->dev); 308 309 while ((raw_sk = __raw_v4_lookup(net, raw_sk, protocol, 310 iph->daddr, iph->saddr, |
305 skb->dev->ifindex)) != NULL) { | 311 dif, sdif)) != NULL) { |
306 raw_err(raw_sk, skb, info); 307 raw_sk = sk_next(raw_sk); 308 iph = (const struct iphdr *)skb->data; 309 } 310 } 311 read_unlock(&raw_v4_hashinfo.lock); 312} 313 --- 830 unchanged lines hidden --- | 312 raw_err(raw_sk, skb, info); 313 raw_sk = sk_next(raw_sk); 314 iph = (const struct iphdr *)skb->data; 315 } 316 } 317 read_unlock(&raw_v4_hashinfo.lock); 318} 319 --- 830 unchanged lines hidden --- |