[NET]: Move hardware header operations out of netdevice.

Since hardware header operations are part of the protocol class
not the device instance, make them into a separate object and
save memory.

Signed-off-by: Stephen Hemminger <shemminger@linux-foundation.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
diff --git a/include/linux/etherdevice.h b/include/linux/etherdevice.h
index 6cdb973..b7558ec 100644
--- a/include/linux/etherdevice.h
+++ b/include/linux/etherdevice.h
@@ -29,15 +29,19 @@
 #include <linux/random.h>
 
 #ifdef __KERNEL__
-extern int		eth_header(struct sk_buff *skb, struct net_device *dev,
-				   unsigned short type, void *daddr,
-				   void *saddr, unsigned len);
-extern int		eth_rebuild_header(struct sk_buff *skb);
 extern __be16		eth_type_trans(struct sk_buff *skb, struct net_device *dev);
-extern void		eth_header_cache_update(struct hh_cache *hh, struct net_device *dev,
-						unsigned char * haddr);
-extern int		eth_header_cache(struct neighbour *neigh,
-					 struct hh_cache *hh);
+extern const struct header_ops eth_header_ops;
+
+extern int eth_header(struct sk_buff *skb, struct net_device *dev,
+		      unsigned short type,
+		      const void *daddr, const void *saddr, unsigned len);
+extern int eth_rebuild_header(struct sk_buff *skb);
+extern int eth_header_parse(const struct sk_buff *skb, unsigned char *haddr);
+extern int eth_header_cache(const struct neighbour *neigh, struct hh_cache *hh);
+extern void eth_header_cache_update(struct hh_cache *hh,
+				    const struct net_device *dev,
+				    const unsigned char *haddr);
+
 
 extern struct net_device *alloc_etherdev_mq(int sizeof_priv, unsigned int queue_count);
 #define alloc_etherdev(sizeof_priv) alloc_etherdev_mq(sizeof_priv, 1)
diff --git a/include/linux/if_ether.h b/include/linux/if_ether.h
index 0e791e2c..5f92977 100644
--- a/include/linux/if_ether.h
+++ b/include/linux/if_ether.h
@@ -117,6 +117,8 @@
 	return (struct ethhdr *)skb_mac_header(skb);
 }
 
+int eth_header_parse(const struct sk_buff *skb, unsigned char *haddr);
+
 #ifdef CONFIG_SYSCTL
 extern struct ctl_table ether_table[];
 #endif
diff --git a/include/linux/if_shaper.h b/include/linux/if_shaper.h
index 5157474..3b1b7ba 100644
--- a/include/linux/if_shaper.h
+++ b/include/linux/if_shaper.h
@@ -25,17 +25,6 @@
 				   an empty queue */
 	spinlock_t lock;
 	struct net_device *dev;
-	int  (*hard_start_xmit) (struct sk_buff *skb,
-		struct net_device *dev);
-	int  (*hard_header) (struct sk_buff *skb,
-		struct net_device *dev,
-		unsigned short type,
-		void *daddr,
-		void *saddr,
-		unsigned len);
-	int  (*rebuild_header)(struct sk_buff *skb);
-	int (*hard_header_cache)(struct neighbour *neigh, struct hh_cache *hh);
-	void (*header_cache_update)(struct hh_cache *hh, struct net_device *dev, unsigned char *  haddr);
 	struct net_device_stats* (*get_stats)(struct net_device *dev);
 	struct timer_list timer;
 };
diff --git a/include/linux/isdn.h b/include/linux/isdn.h
index 3c7875b..a6fb366 100644
--- a/include/linux/isdn.h
+++ b/include/linux/isdn.h
@@ -353,13 +353,6 @@
                                        /* a particular channel (including  */
                                        /* the frame_cnt                    */
 
-  int                    (*org_hhc)(
-				    struct neighbour *neigh,
-				    struct hh_cache *hh);
-                                       /* Ptr to orig. header_cache_update */
-  void                   (*org_hcu)(struct hh_cache *,
-				    struct net_device *,
-                                    unsigned char *);
   int  pppbind;                        /* ippp device for bindings         */
   int					dialtimeout;	/* How long shall we try on dialing? (jiffies) */
   int					dialwait;		/* How long shall we wait after failed attempt? (jiffies) */
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index aae9ec3..91cd3f3 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -250,6 +250,19 @@
 #define LL_RESERVED_SPACE_EXTRA(dev,extra) \
 	((((dev)->hard_header_len+extra)&~(HH_DATA_MOD - 1)) + HH_DATA_MOD)
 
+struct header_ops {
+	int	(*create) (struct sk_buff *skb, struct net_device *dev,
+			   unsigned short type, const void *daddr,
+			   const void *saddr, unsigned len);
+	int	(*parse)(const struct sk_buff *skb, unsigned char *haddr);
+	int	(*rebuild)(struct sk_buff *skb);
+#define HAVE_HEADER_CACHE
+	int	(*cache)(const struct neighbour *neigh, struct hh_cache *hh);
+	void	(*cache_update)(struct hh_cache *hh,
+				const struct net_device *dev,
+				const unsigned char *haddr);
+};
+
 /* These flag bits are private to the generic network queueing
  * layer, they may not be explicitly referenced by any other
  * code.
@@ -492,6 +505,9 @@
 #endif
 	const struct ethtool_ops *ethtool_ops;
 
+	/* Hardware header description */
+	const struct header_ops *header_ops;
+
 	/*
 	 * This marks the end of the "visible" part of the structure. All
 	 * fields hereafter are internal to the system, and may change at
@@ -615,13 +631,6 @@
 	int			(*open)(struct net_device *dev);
 	int			(*stop)(struct net_device *dev);
 #define HAVE_NETDEV_POLL
-	int			(*hard_header) (struct sk_buff *skb,
-						struct net_device *dev,
-						unsigned short type,
-						void *daddr,
-						void *saddr,
-						unsigned len);
-	int			(*rebuild_header)(struct sk_buff *skb);
 #define HAVE_CHANGE_RX_FLAGS
 	void			(*change_rx_flags)(struct net_device *dev,
 						   int flags);
@@ -638,12 +647,6 @@
 #define HAVE_SET_CONFIG
 	int			(*set_config)(struct net_device *dev,
 					      struct ifmap *map);
-#define HAVE_HEADER_CACHE
-	int			(*hard_header_cache)(struct neighbour *neigh,
-						     struct hh_cache *hh);
-	void			(*header_cache_update)(struct hh_cache *hh,
-						       struct net_device *dev,
-						       unsigned char *  haddr);
 #define HAVE_CHANGE_MTU
 	int			(*change_mtu)(struct net_device *dev, int new_mtu);
 
@@ -657,8 +660,6 @@
 	void			(*vlan_rx_kill_vid)(struct net_device *dev,
 						    unsigned short vid);
 
-	int			(*hard_header_parse)(const struct sk_buff *skb,
-						     unsigned char *haddr);
 	int			(*neigh_setup)(struct net_device *dev, struct neigh_parms *);
 #ifdef CONFIG_NETPOLL
 	struct netpoll_info	*npinfo;
@@ -802,11 +803,13 @@
 
 static inline int dev_hard_header(struct sk_buff *skb, struct net_device *dev,
 				  unsigned short type,
-				  void *daddr, void *saddr, unsigned len)
+				  const void *daddr, const void *saddr,
+				  unsigned len)
 {
-	if (!dev->hard_header)
+	if (!dev->header_ops)
 		return 0;
-	return dev->hard_header(skb, dev, type, daddr, saddr, len);
+
+	return dev->header_ops->create(skb, dev, type, daddr, saddr, len);
 }
 
 static inline int dev_parse_header(const struct sk_buff *skb,
@@ -814,9 +817,9 @@
 {
 	const struct net_device *dev = skb->dev;
 
-	if (!dev->hard_header_parse)
+	if (!dev->header_ops->parse)
 		return 0;
-	return dev->hard_header_parse(skb, haddr);
+	return dev->header_ops->parse(skb, haddr);
 }
 
 typedef int gifconf_func_t(struct net_device * dev, char __user * bufptr, int len);
diff --git a/include/net/ax25.h b/include/net/ax25.h
index 99a4e36..4e3cd93 100644
--- a/include/net/ax25.h
+++ b/include/net/ax25.h
@@ -363,8 +363,11 @@
 extern int  ax25_kiss_rcv(struct sk_buff *, struct net_device *, struct packet_type *, struct net_device *);
 
 /* ax25_ip.c */
-extern int  ax25_hard_header(struct sk_buff *, struct net_device *, unsigned short, void *, void *, unsigned int);
+extern int ax25_hard_header(struct sk_buff *, struct net_device *,
+			    unsigned short, const void *,
+			    const void *, unsigned int);
 extern int  ax25_rebuild_header(struct sk_buff *);
+extern const struct header_ops ax25_header_ops;
 
 /* ax25_out.c */
 extern ax25_cb *ax25_send_frame(struct sk_buff *, int, ax25_address *, ax25_address *, ax25_digi *, struct net_device *);
diff --git a/include/net/pkt_sched.h b/include/net/pkt_sched.h
index 9e22526..ab61809 100644
--- a/include/net/pkt_sched.h
+++ b/include/net/pkt_sched.h
@@ -97,10 +97,9 @@
 /* Calculate maximal size of packet seen by hard_start_xmit
    routine of this device.
  */
-static inline unsigned psched_mtu(struct net_device *dev)
+static inline unsigned psched_mtu(const struct net_device *dev)
 {
-	unsigned mtu = dev->mtu;
-	return dev->hard_header ? mtu + dev->hard_header_len : mtu;
+	return dev->mtu + dev->hard_header_len;
 }
 
 #endif