#include <linux/wireless.h>
#include <linux/kernel.h>
#include <linux/kmod.h>
+#include <net/net_namespace.h>
#include <net/ip.h>
#include <net/protocol.h>
#include <linux/skbuff.h>
struct sock *sk;
struct sockaddr_pkt *spkt;
+ if (dev->nd_net != &init_net)
+ goto out;
+
/*
* When we registered the protocol we saved the socket in the data
* field for just this event.
*/
saddr->spkt_device[13] = 0;
- dev = dev_get_by_name(saddr->spkt_device);
+ dev = dev_get_by_name(&init_net, saddr->spkt_device);
err = -ENODEV;
if (dev == NULL)
goto out_unlock;
int skb_len = skb->len;
unsigned int snaplen, res;
+ if (dev->nd_net != &init_net)
+ goto drop;
+
if (skb->pkt_type == PACKET_LOOPBACK)
goto drop;
struct sk_buff *copy_skb = NULL;
struct timeval tv;
+ if (dev->nd_net != &init_net)
+ goto drop;
+
if (skb->pkt_type == PACKET_LOOPBACK)
goto drop;
h->tp_snaplen = snaplen;
h->tp_mac = macoff;
h->tp_net = netoff;
- if (skb->tstamp.tv64 == 0) {
- __net_timestamp(skb);
- sock_enable_timestamp(sk);
- }
- tv = ktime_to_timeval(skb->tstamp);
+ if (skb->tstamp.tv64)
+ tv = ktime_to_timeval(skb->tstamp);
+ else
+ do_gettimeofday(&tv);
h->tp_sec = tv.tv_sec;
h->tp_usec = tv.tv_usec;
}
- dev = dev_get_by_index(ifindex);
+ dev = dev_get_by_index(&init_net, ifindex);
err = -ENXIO;
if (dev == NULL)
goto out_unlock;
return -EINVAL;
strlcpy(name,uaddr->sa_data,sizeof(name));
- dev = dev_get_by_name(name);
+ dev = dev_get_by_name(&init_net, name);
if (dev) {
err = packet_do_bind(sk, dev, pkt_sk(sk)->num);
dev_put(dev);
if (sll->sll_ifindex) {
err = -ENODEV;
- dev = dev_get_by_index(sll->sll_ifindex);
+ dev = dev_get_by_index(&init_net, sll->sll_ifindex);
if (dev == NULL)
goto out;
}
* Create a packet of type SOCK_PACKET.
*/
-static int packet_create(struct socket *sock, int protocol)
+static int packet_create(struct net *net, struct socket *sock, int protocol)
{
struct sock *sk;
struct packet_sock *po;
__be16 proto = (__force __be16)protocol; /* weird, but documented */
int err;
+ if (net != &init_net)
+ return -EAFNOSUPPORT;
+
if (!capable(CAP_NET_RAW))
return -EPERM;
if (sock->type != SOCK_DGRAM && sock->type != SOCK_RAW &&
sock->state = SS_UNCONNECTED;
err = -ENOBUFS;
- sk = sk_alloc(PF_PACKET, GFP_KERNEL, &packet_proto, 1);
+ sk = sk_alloc(net, PF_PACKET, GFP_KERNEL, &packet_proto, 1);
if (sk == NULL)
goto out;
return -EOPNOTSUPP;
uaddr->sa_family = AF_PACKET;
- dev = dev_get_by_index(pkt_sk(sk)->ifindex);
+ dev = dev_get_by_index(&init_net, pkt_sk(sk)->ifindex);
if (dev) {
strlcpy(uaddr->sa_data, dev->name, 15);
dev_put(dev);
sll->sll_family = AF_PACKET;
sll->sll_ifindex = po->ifindex;
sll->sll_protocol = po->num;
- dev = dev_get_by_index(po->ifindex);
+ dev = dev_get_by_index(&init_net, po->ifindex);
if (dev) {
sll->sll_hatype = dev->type;
sll->sll_halen = dev->addr_len;
rtnl_lock();
err = -ENODEV;
- dev = __dev_get_by_index(mreq->mr_ifindex);
+ dev = __dev_get_by_index(&init_net, mreq->mr_ifindex);
if (!dev)
goto done;
if (--ml->count == 0) {
struct net_device *dev;
*mlp = ml->next;
- dev = dev_get_by_index(ml->ifindex);
+ dev = dev_get_by_index(&init_net, ml->ifindex);
if (dev) {
packet_dev_mc(dev, ml, -1);
dev_put(dev);
struct net_device *dev;
po->mclist = ml->next;
- if ((dev = dev_get_by_index(ml->ifindex)) != NULL) {
+ if ((dev = dev_get_by_index(&init_net, ml->ifindex)) != NULL) {
packet_dev_mc(dev, ml, -1);
dev_put(dev);
}
struct hlist_node *node;
struct net_device *dev = data;
+ if (dev->nd_net != &init_net)
+ return NOTIFY_DONE;
+
read_lock(&packet_sklist_lock);
sk_for_each(sk, node, &packet_sklist) {
struct packet_sock *po = pkt_sk(sk);
static void __exit packet_exit(void)
{
- proc_net_remove("packet");
+ proc_net_remove(&init_net, "packet");
unregister_netdevice_notifier(&packet_netdev_notifier);
sock_unregister(PF_PACKET);
proto_unregister(&packet_proto);
sock_register(&packet_family_ops);
register_netdevice_notifier(&packet_netdev_notifier);
- proc_net_fops_create("packet", 0, &packet_seq_fops);
+ proc_net_fops_create(&init_net, "packet", 0, &packet_seq_fops);
out:
return rc;
}