#include <asm/uaccess.h>
#include <asm/ioctls.h>
#include <asm/page.h>
+#include <asm/cacheflush.h>
#include <asm/io.h>
#include <linux/proc_fs.h>
#include <linux/seq_file.h>
spinlock_t bind_lock;
char running; /* prot_hook is attached*/
int ifindex; /* bound device */
- unsigned short num;
+ __be16 num;
#ifdef CONFIG_PACKET_MULTICAST
struct packet_mclist *mclist;
#endif
struct sockaddr_pkt *saddr=(struct sockaddr_pkt *)msg->msg_name;
struct sk_buff *skb;
struct net_device *dev;
- unsigned short proto=0;
+ __be16 proto=0;
int err;
/*
if (dev == NULL)
goto out_unlock;
+ err = -ENETDOWN;
+ if (!(dev->flags & IFF_UP))
+ goto out_unlock;
+
/*
* You may not queue a frame bigger than the mtu. This is the lowest level
* raw protocol and you must do your own fragmentation at this level.
if (err)
goto out_free;
- err = -ENETDOWN;
- if (!(dev->flags & IFF_UP))
- goto out_free;
-
/*
* Now send it
*/
}
#endif
-static inline int run_filter(struct sk_buff *skb, struct sock *sk,
- unsigned *snaplen)
+static inline unsigned int run_filter(struct sk_buff *skb, struct sock *sk,
+ unsigned int res)
{
struct sk_filter *filter;
- int err = 0;
rcu_read_lock_bh();
filter = rcu_dereference(sk->sk_filter);
- if (filter != NULL) {
- err = sk_run_filter(skb, filter->insns, filter->len);
- if (!err)
- err = -EPERM;
- else if (*snaplen > err)
- *snaplen = err;
- }
+ if (filter != NULL)
+ res = sk_run_filter(skb, filter->insns, filter->len);
rcu_read_unlock_bh();
- return err;
+ return res;
}
/*
struct packet_sock *po;
u8 * skb_head = skb->data;
int skb_len = skb->len;
- unsigned snaplen;
+ unsigned int snaplen, res;
if (skb->pkt_type == PACKET_LOOPBACK)
goto drop;
snaplen = skb->len;
- if (run_filter(skb, sk, &snaplen) < 0)
+ res = run_filter(skb, sk, snaplen);
+ if (!res)
goto drop_n_restore;
+ if (snaplen > res)
+ snaplen = res;
if (atomic_read(&sk->sk_rmem_alloc) + skb->truesize >=
(unsigned)sk->sk_rcvbuf)
struct tpacket_hdr *h;
u8 * skb_head = skb->data;
int skb_len = skb->len;
- unsigned snaplen;
+ unsigned int snaplen, res;
unsigned long status = TP_STATUS_LOSING|TP_STATUS_USER;
unsigned short macoff, netoff;
struct sk_buff *copy_skb = NULL;
snaplen = skb->len;
- if (run_filter(skb, sk, &snaplen) < 0)
+ res = run_filter(skb, sk, snaplen);
+ if (!res)
goto drop_n_restore;
+ if (snaplen > res)
+ snaplen = res;
if (sk->sk_type == SOCK_DGRAM) {
macoff = netoff = TPACKET_ALIGN(TPACKET_HDRLEN) + 16;
sll->sll_ifindex = dev->ifindex;
h->tp_status = status;
- mb();
+ smp_mb();
{
struct page *p_start, *p_end;
struct sockaddr_ll *saddr=(struct sockaddr_ll *)msg->msg_name;
struct sk_buff *skb;
struct net_device *dev;
- unsigned short proto;
+ __be16 proto;
unsigned char *addr;
int ifindex, err, reserve = 0;
if (sock->type == SOCK_RAW)
reserve = dev->hard_header_len;
+ err = -ENETDOWN;
+ if (!(dev->flags & IFF_UP))
+ goto out_unlock;
+
err = -EMSGSIZE;
if (len > dev->mtu+reserve)
goto out_unlock;
skb->dev = dev;
skb->priority = sk->sk_priority;
- err = -ENETDOWN;
- if (!(dev->flags & IFF_UP))
- goto out_free;
-
/*
* Now send it
*/
* Attach a packet hook.
*/
-static int packet_do_bind(struct sock *sk, struct net_device *dev, int protocol)
+static int packet_do_bind(struct sock *sk, struct net_device *dev, __be16 protocol)
{
struct packet_sock *po = pkt_sk(sk);
/*
{
struct sock *sk;
struct packet_sock *po;
+ __be16 proto = (__force __be16)protocol; /* weird, but documented */
int err;
if (!capable(CAP_NET_RAW))
po = pkt_sk(sk);
sk->sk_family = PF_PACKET;
- po->num = protocol;
+ po->num = proto;
sk->sk_destruct = packet_sock_destruct;
atomic_inc(&packet_socks_nr);
#endif
po->prot_hook.af_packet_priv = sk;
- if (protocol) {
- po->prot_hook.type = protocol;
+ if (proto) {
+ po->prot_hook.type = proto;
dev_add_pack(&po->prot_hook);
sock_hold(sk);
po->running = 1;
{
char **pg_vec = NULL;
struct packet_sock *po = pkt_sk(sk);
- int was_running, num, order = 0;
+ int was_running, order = 0;
+ __be16 num;
int err = 0;
if (req->tp_block_nr) {