[SK_BUFF]: Introduce skb_transport_header(skb)
[deliverable/linux.git] / net / core / dev.c
index cf71614dae93bf29d5211b86dc487c9e9a82faff..30fcc7f9d4edde76a685fc9d0f4ef5e1628a9ca0 100644 (file)
  */
 
 static DEFINE_SPINLOCK(ptype_lock);
-static struct list_head ptype_base[16];        /* 16 way hashed list */
-static struct list_head ptype_all;             /* Taps */
+static struct list_head ptype_base[16] __read_mostly;  /* 16 way hashed list */
+static struct list_head ptype_all __read_mostly;       /* Taps */
 
 #ifdef CONFIG_NET_DMA
 static struct dma_client *net_dma_client;
@@ -751,13 +751,10 @@ int dev_change_name(struct net_device *dev, char *newname)
        else
                strlcpy(dev->name, newname, IFNAMSIZ);
 
-       err = device_rename(&dev->dev, dev->name);
-       if (!err) {
-               hlist_del(&dev->name_hlist);
-               hlist_add_head(&dev->name_hlist, dev_name_hash(dev->name));
-               raw_notifier_call_chain(&netdev_chain,
-                               NETDEV_CHANGENAME, dev);
-       }
+       device_rename(&dev->dev, dev->name);
+       hlist_del(&dev->name_hlist);
+       hlist_add_head(&dev->name_hlist, dev_name_hash(dev->name));
+       raw_notifier_call_chain(&netdev_chain, NETDEV_CHANGENAME, dev);
 
        return err;
 }
@@ -1034,23 +1031,12 @@ void net_disable_timestamp(void)
        atomic_dec(&netstamp_needed);
 }
 
-void __net_timestamp(struct sk_buff *skb)
-{
-       struct timeval tv;
-
-       do_gettimeofday(&tv);
-       skb_set_timestamp(skb, &tv);
-}
-EXPORT_SYMBOL(__net_timestamp);
-
 static inline void net_timestamp(struct sk_buff *skb)
 {
        if (atomic_read(&netstamp_needed))
                __net_timestamp(skb);
-       else {
-               skb->tstamp.off_sec = 0;
-               skb->tstamp.off_usec = 0;
-       }
+       else
+               skb->tstamp.tv64 = 0;
 }
 
 /*
@@ -1080,15 +1066,15 @@ static void dev_queue_xmit_nit(struct sk_buff *skb, struct net_device *dev)
                           set by sender, so that the second statement is
                           just protection against buggy protocols.
                         */
-                       skb2->mac.raw = skb2->data;
+                       skb_reset_mac_header(skb2);
 
-                       if (skb2->nh.raw < skb2->data ||
-                           skb2->nh.raw > skb2->tail) {
+                       if (skb_network_header(skb2) < skb2->data ||
+                           skb_network_header(skb2) > skb2->tail) {
                                if (net_ratelimit())
                                        printk(KERN_CRIT "protocol %04x is "
                                               "buggy, dev %s\n",
                                               skb2->protocol, dev->name);
-                               skb2->nh.raw = skb2->data;
+                               skb_reset_network_header(skb2);
                        }
 
                        skb2->h.raw = skb2->nh.raw;
@@ -1170,7 +1156,7 @@ EXPORT_SYMBOL(netif_device_attach);
 int skb_checksum_help(struct sk_buff *skb)
 {
        __wsum csum;
-       int ret = 0, offset = skb->h.raw - skb->data;
+       int ret = 0, offset = skb_transport_offset(skb);
 
        if (skb->ip_summed == CHECKSUM_COMPLETE)
                goto out_set_summed;
@@ -1189,12 +1175,12 @@ int skb_checksum_help(struct sk_buff *skb)
        BUG_ON(offset > (int)skb->len);
        csum = skb_checksum(skb, offset, skb->len-offset, 0);
 
-       offset = skb->tail - skb->h.raw;
+       offset = skb->tail - skb_transport_header(skb);
        BUG_ON(offset <= 0);
        BUG_ON(skb->csum_offset + 2 > offset);
 
-       *(__sum16*)(skb->h.raw + skb->csum_offset) = csum_fold(csum);
-
+       *(__sum16 *)(skb_transport_header(skb) +
+                    skb->csum_offset) = csum_fold(csum);
 out_set_summed:
        skb->ip_summed = CHECKSUM_NONE;
 out:
@@ -1220,8 +1206,8 @@ struct sk_buff *skb_gso_segment(struct sk_buff *skb, int features)
 
        BUG_ON(skb_shinfo(skb)->frag_list);
 
-       skb->mac.raw = skb->data;
-       skb->mac_len = skb->nh.raw - skb->data;
+       skb_reset_mac_header(skb);
+       skb->mac_len = skb->nh.raw - skb->mac.raw;
        __skb_pull(skb, skb->mac_len);
 
        if (unlikely(skb->ip_summed != CHECKSUM_PARTIAL)) {
@@ -1238,7 +1224,8 @@ struct sk_buff *skb_gso_segment(struct sk_buff *skb, int features)
                                segs = ERR_PTR(err);
                                if (err || skb_gso_ok(skb, features))
                                        break;
-                               __skb_push(skb, skb->data - skb->nh.raw);
+                               __skb_push(skb, (skb->data -
+                                                skb_network_header(skb)));
                        }
                        segs = ptype->gso_segment(skb, features);
                        break;
@@ -1246,7 +1233,7 @@ struct sk_buff *skb_gso_segment(struct sk_buff *skb, int features)
        }
        rcu_read_unlock();
 
-       __skb_push(skb, skb->data - skb->mac.raw);
+       __skb_push(skb, skb->data - skb_mac_header(skb));
 
        return segs;
 }
@@ -1546,9 +1533,9 @@ out:
                        Receiver routines
   =======================================================================*/
 
-int netdev_max_backlog = 1000;
-int netdev_budget = 300;
-int weight_p = 64;            /* old backlog weight */
+int netdev_max_backlog __read_mostly = 1000;
+int netdev_budget __read_mostly = 300;
+int weight_p __read_mostly = 64;            /* old backlog weight */
 
 DEFINE_PER_CPU(struct netif_rx_stats, netdev_rx_stat) = { 0, };
 
@@ -1580,7 +1567,7 @@ int netif_rx(struct sk_buff *skb)
        if (netpoll_rx(skb))
                return NET_RX_DROP;
 
-       if (!skb->tstamp.off_sec)
+       if (!skb->tstamp.tv64)
                net_timestamp(skb);
 
        /*
@@ -1687,9 +1674,9 @@ static void net_tx_action(struct softirq_action *h)
        }
 }
 
-static __inline__ int deliver_skb(struct sk_buff *skb,
-                                 struct packet_type *pt_prev,
-                                 struct net_device *orig_dev)
+static inline int deliver_skb(struct sk_buff *skb,
+                             struct packet_type *pt_prev,
+                             struct net_device *orig_dev)
 {
        atomic_inc(&skb->users);
        return pt_prev->func(skb, skb->dev, pt_prev, orig_dev);
@@ -1741,8 +1728,8 @@ static int ing_filter(struct sk_buff *skb)
        if (dev->qdisc_ingress) {
                __u32 ttl = (__u32) G_TC_RTTL(skb->tc_verd);
                if (MAX_RED_LOOP < ttl++) {
-                       printk(KERN_WARNING "Redir loop detected Dropping packet (%s->%s)\n",
-                               skb->input_dev->name, skb->dev->name);
+                       printk(KERN_WARNING "Redir loop detected Dropping packet (%d->%d)\n",
+                               skb->iif, skb->dev->ifindex);
                        return TC_ACT_SHOT;
                }
 
@@ -1750,10 +1737,10 @@ static int ing_filter(struct sk_buff *skb)
 
                skb->tc_verd = SET_TC_AT(skb->tc_verd,AT_INGRESS);
 
-               spin_lock(&dev->ingress_lock);
+               spin_lock(&dev->queue_lock);
                if ((q = dev->qdisc_ingress) != NULL)
                        result = q->enqueue(skb, q);
-               spin_unlock(&dev->ingress_lock);
+               spin_unlock(&dev->queue_lock);
 
        }
 
@@ -1772,11 +1759,11 @@ int netif_receive_skb(struct sk_buff *skb)
        if (skb->dev->poll && netpoll_rx(skb))
                return NET_RX_DROP;
 
-       if (!skb->tstamp.off_sec)
+       if (!skb->tstamp.tv64)
                net_timestamp(skb);
 
-       if (!skb->input_dev)
-               skb->input_dev = skb->dev;
+       if (!skb->iif)
+               skb->iif = skb->dev->ifindex;
 
        orig_dev = skb_bond(skb);
 
@@ -1785,7 +1772,8 @@ int netif_receive_skb(struct sk_buff *skb)
 
        __get_cpu_var(netdev_rx_stat).total++;
 
-       skb->h.raw = skb->nh.raw = skb->data;
+       skb_reset_network_header(skb);
+       skb_reset_transport_header(skb);
        skb->mac_len = skb->nh.raw - skb->mac.raw;
 
        pt_prev = NULL;
@@ -2079,7 +2067,7 @@ static int dev_ifconf(char __user *arg)
  *     This is invoked by the /proc filesystem handler to display a device
  *     in detail.
  */
-static __inline__ struct net_device *dev_get_idx(loff_t pos)
+static struct net_device *dev_get_idx(loff_t pos)
 {
        struct net_device *dev;
        loff_t i;
@@ -2188,7 +2176,7 @@ static int softnet_seq_show(struct seq_file *seq, void *v)
        return 0;
 }
 
-static struct seq_operations dev_seq_ops = {
+static const struct seq_operations dev_seq_ops = {
        .start = dev_seq_start,
        .next  = dev_seq_next,
        .stop  = dev_seq_stop,
@@ -2208,7 +2196,7 @@ static const struct file_operations dev_seq_fops = {
        .release = seq_release,
 };
 
-static struct seq_operations softnet_seq_ops = {
+static const struct seq_operations softnet_seq_ops = {
        .start = softnet_seq_start,
        .next  = softnet_seq_next,
        .stop  = softnet_seq_stop,
@@ -2228,6 +2216,135 @@ static const struct file_operations softnet_seq_fops = {
        .release = seq_release,
 };
 
+static void *ptype_get_idx(loff_t pos)
+{
+       struct packet_type *pt = NULL;
+       loff_t i = 0;
+       int t;
+
+       list_for_each_entry_rcu(pt, &ptype_all, list) {
+               if (i == pos)
+                       return pt;
+               ++i;
+       }
+
+       for (t = 0; t < 16; t++) {
+               list_for_each_entry_rcu(pt, &ptype_base[t], list) {
+                       if (i == pos)
+                               return pt;
+                       ++i;
+               }
+       }
+       return NULL;
+}
+
+static void *ptype_seq_start(struct seq_file *seq, loff_t *pos)
+{
+       rcu_read_lock();
+       return *pos ? ptype_get_idx(*pos - 1) : SEQ_START_TOKEN;
+}
+
+static void *ptype_seq_next(struct seq_file *seq, void *v, loff_t *pos)
+{
+       struct packet_type *pt;
+       struct list_head *nxt;
+       int hash;
+
+       ++*pos;
+       if (v == SEQ_START_TOKEN)
+               return ptype_get_idx(0);
+
+       pt = v;
+       nxt = pt->list.next;
+       if (pt->type == htons(ETH_P_ALL)) {
+               if (nxt != &ptype_all)
+                       goto found;
+               hash = 0;
+               nxt = ptype_base[0].next;
+       } else
+               hash = ntohs(pt->type) & 15;
+
+       while (nxt == &ptype_base[hash]) {
+               if (++hash >= 16)
+                       return NULL;
+               nxt = ptype_base[hash].next;
+       }
+found:
+       return list_entry(nxt, struct packet_type, list);
+}
+
+static void ptype_seq_stop(struct seq_file *seq, void *v)
+{
+       rcu_read_unlock();
+}
+
+static void ptype_seq_decode(struct seq_file *seq, void *sym)
+{
+#ifdef CONFIG_KALLSYMS
+       unsigned long offset = 0, symsize;
+       const char *symname;
+       char *modname;
+       char namebuf[128];
+
+       symname = kallsyms_lookup((unsigned long)sym, &symsize, &offset,
+                                 &modname, namebuf);
+
+       if (symname) {
+               char *delim = ":";
+
+               if (!modname)
+                       modname = delim = "";
+               seq_printf(seq, "%s%s%s%s+0x%lx", delim, modname, delim,
+                          symname, offset);
+               return;
+       }
+#endif
+
+       seq_printf(seq, "[%p]", sym);
+}
+
+static int ptype_seq_show(struct seq_file *seq, void *v)
+{
+       struct packet_type *pt = v;
+
+       if (v == SEQ_START_TOKEN)
+               seq_puts(seq, "Type Device      Function\n");
+       else {
+               if (pt->type == htons(ETH_P_ALL))
+                       seq_puts(seq, "ALL ");
+               else
+                       seq_printf(seq, "%04x", ntohs(pt->type));
+
+               seq_printf(seq, " %-8s ",
+                          pt->dev ? pt->dev->name : "");
+               ptype_seq_decode(seq,  pt->func);
+               seq_putc(seq, '\n');
+       }
+
+       return 0;
+}
+
+static const struct seq_operations ptype_seq_ops = {
+       .start = ptype_seq_start,
+       .next  = ptype_seq_next,
+       .stop  = ptype_seq_stop,
+       .show  = ptype_seq_show,
+};
+
+static int ptype_seq_open(struct inode *inode, struct file *file)
+{
+       return seq_open(file, &ptype_seq_ops);
+}
+
+static const struct file_operations ptype_seq_fops = {
+       .owner   = THIS_MODULE,
+       .open    = ptype_seq_open,
+       .read    = seq_read,
+       .llseek  = seq_lseek,
+       .release = seq_release,
+};
+
+
 #ifdef CONFIG_WIRELESS_EXT
 extern int wireless_proc_init(void);
 #else
@@ -2242,6 +2359,9 @@ static int __init dev_proc_init(void)
                goto out;
        if (!proc_net_fops_create("softnet_stat", S_IRUGO, &softnet_seq_fops))
                goto out_dev;
+       if (!proc_net_fops_create("ptype", S_IRUGO, &ptype_seq_fops))
+               goto out_dev2;
+
        if (wireless_proc_init())
                goto out_softnet;
        rc = 0;
@@ -2249,6 +2369,8 @@ out:
        return rc;
 out_softnet:
        proc_net_remove("softnet_stat");
+out_dev2:
+       proc_net_remove("ptype");
 out_dev:
        proc_net_remove("dev");
        goto out;
@@ -2850,7 +2972,7 @@ static int dev_boot_phase = 1;
 static DEFINE_SPINLOCK(net_todo_list_lock);
 static struct list_head net_todo_list = LIST_HEAD_INIT(net_todo_list);
 
-static inline void net_set_todo(struct net_device *dev)
+static void net_set_todo(struct net_device *dev)
 {
        spin_lock(&net_todo_list_lock);
        list_add_tail(&dev->todo_list, &net_todo_list);
This page took 0.031162 seconds and 5 git commands to generate.