aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorStephen Hemminger <shemminger@linux-foundation.org>2007-10-09 04:40:57 -0400
committerDavid S. Miller <davem@sunset.davemloft.net>2007-10-10 19:52:52 -0400
commit3b04ddde02cf1b6f14f2697da5c20eca5715017f (patch)
tree9da1341a5a399a507b5ea6bf5a3047506b8d8f8f /net
parentb95cce3576813ac3f86bafa6b5daaaaf7574b0fe (diff)
[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>
Diffstat (limited to 'net')
-rw-r--r--net/802/fc.c11
-rw-r--r--net/802/fddi.c10
-rw-r--r--net/802/hippi.c16
-rw-r--r--net/802/tr.c15
-rw-r--r--net/8021q/vlan.c14
-rw-r--r--net/8021q/vlan.h4
-rw-r--r--net/8021q/vlan_dev.c4
-rw-r--r--net/appletalk/dev.c4
-rw-r--r--net/ax25/ax25_ip.c15
-rw-r--r--net/core/dev.c16
-rw-r--r--net/core/neighbour.c11
-rw-r--r--net/ethernet/eth.c36
-rw-r--r--net/ipv4/arp.c6
-rw-r--r--net/ipv4/ip_gre.c13
-rw-r--r--net/ipv4/ip_output.c2
-rw-r--r--net/ipv6/ndisc.c6
-rw-r--r--net/mac80211/ieee80211.c12
-rw-r--r--net/netrom/nr_dev.c14
-rw-r--r--net/packet/af_packet.c6
-rw-r--r--net/rose/rose_dev.c13
-rw-r--r--net/sched/sch_teql.c6
21 files changed, 140 insertions, 94 deletions
diff --git a/net/802/fc.c b/net/802/fc.c
index 675d9ba8e591..cb3475ea6fda 100644
--- a/net/802/fc.c
+++ b/net/802/fc.c
@@ -35,7 +35,7 @@
35 35
36static int fc_header(struct sk_buff *skb, struct net_device *dev, 36static int fc_header(struct sk_buff *skb, struct net_device *dev,
37 unsigned short type, 37 unsigned short type,
38 void *daddr, void *saddr, unsigned len) 38 const void *daddr, const void *saddr, unsigned len)
39{ 39{
40 struct fch_hdr *fch; 40 struct fch_hdr *fch;
41 int hdr_len; 41 int hdr_len;
@@ -95,11 +95,14 @@ static int fc_rebuild_header(struct sk_buff *skb)
95#endif 95#endif
96} 96}
97 97
98static const struct header_ops fc_header_ops = {
99 .create = fc_header,
100 .rebuild = fc_rebuild_header,
101};
102
98static void fc_setup(struct net_device *dev) 103static void fc_setup(struct net_device *dev)
99{ 104{
100 dev->hard_header = fc_header; 105 dev->header_ops = &fc_header_ops;
101 dev->rebuild_header = fc_rebuild_header;
102
103 dev->type = ARPHRD_IEEE802; 106 dev->type = ARPHRD_IEEE802;
104 dev->hard_header_len = FC_HLEN; 107 dev->hard_header_len = FC_HLEN;
105 dev->mtu = 2024; 108 dev->mtu = 2024;
diff --git a/net/802/fddi.c b/net/802/fddi.c
index 91dde41b5481..0549317b9356 100644
--- a/net/802/fddi.c
+++ b/net/802/fddi.c
@@ -52,7 +52,7 @@
52 52
53static int fddi_header(struct sk_buff *skb, struct net_device *dev, 53static int fddi_header(struct sk_buff *skb, struct net_device *dev,
54 unsigned short type, 54 unsigned short type,
55 void *daddr, void *saddr, unsigned len) 55 const void *daddr, const void *saddr, unsigned len)
56{ 56{
57 int hl = FDDI_K_SNAP_HLEN; 57 int hl = FDDI_K_SNAP_HLEN;
58 struct fddihdr *fddi; 58 struct fddihdr *fddi;
@@ -175,11 +175,15 @@ static int fddi_change_mtu(struct net_device *dev, int new_mtu)
175 return(0); 175 return(0);
176} 176}
177 177
178static const struct header_ops fddi_header_ops = {
179 .create = fddi_header,
180 .rebuild = fddi_rebuild_header,
181};
182
178static void fddi_setup(struct net_device *dev) 183static void fddi_setup(struct net_device *dev)
179{ 184{
180 dev->change_mtu = fddi_change_mtu; 185 dev->change_mtu = fddi_change_mtu;
181 dev->hard_header = fddi_header; 186 dev->header_ops = &fddi_header_ops;
182 dev->rebuild_header = fddi_rebuild_header;
183 187
184 dev->type = ARPHRD_FDDI; 188 dev->type = ARPHRD_FDDI;
185 dev->hard_header_len = FDDI_K_SNAP_HLEN+3; /* Assume 802.2 SNAP hdr len + 3 pad bytes */ 189 dev->hard_header_len = FDDI_K_SNAP_HLEN+3; /* Assume 802.2 SNAP hdr len + 3 pad bytes */
diff --git a/net/802/hippi.c b/net/802/hippi.c
index 87ffc12b6891..e35dc1e0915d 100644
--- a/net/802/hippi.c
+++ b/net/802/hippi.c
@@ -45,8 +45,8 @@
45 */ 45 */
46 46
47static int hippi_header(struct sk_buff *skb, struct net_device *dev, 47static int hippi_header(struct sk_buff *skb, struct net_device *dev,
48 unsigned short type, void *daddr, void *saddr, 48 unsigned short type,
49 unsigned len) 49 const void *daddr, const void *saddr, unsigned len)
50{ 50{
51 struct hippi_hdr *hip = (struct hippi_hdr *)skb_push(skb, HIPPI_HLEN); 51 struct hippi_hdr *hip = (struct hippi_hdr *)skb_push(skb, HIPPI_HLEN);
52 struct hippi_cb *hcb = (struct hippi_cb *) skb->cb; 52 struct hippi_cb *hcb = (struct hippi_cb *) skb->cb;
@@ -182,16 +182,18 @@ static int hippi_neigh_setup_dev(struct net_device *dev, struct neigh_parms *p)
182 return 0; 182 return 0;
183} 183}
184 184
185static const struct header_ops hippi_header_ops = {
186 .create = hippi_header,
187 .rebuild = hippi_rebuild_header,
188};
189
190
185static void hippi_setup(struct net_device *dev) 191static void hippi_setup(struct net_device *dev)
186{ 192{
187 dev->set_multicast_list = NULL; 193 dev->set_multicast_list = NULL;
188 dev->change_mtu = hippi_change_mtu; 194 dev->change_mtu = hippi_change_mtu;
189 dev->hard_header = hippi_header; 195 dev->header_ops = &hippi_header_ops;
190 dev->rebuild_header = hippi_rebuild_header;
191 dev->set_mac_address = hippi_mac_addr; 196 dev->set_mac_address = hippi_mac_addr;
192 dev->hard_header_parse = NULL;
193 dev->hard_header_cache = NULL;
194 dev->header_cache_update = NULL;
195 dev->neigh_setup = hippi_neigh_setup_dev; 197 dev->neigh_setup = hippi_neigh_setup_dev;
196 198
197 /* 199 /*
diff --git a/net/802/tr.c b/net/802/tr.c
index aa3c2e936abc..a2bd0f2e3af8 100644
--- a/net/802/tr.c
+++ b/net/802/tr.c
@@ -100,7 +100,7 @@ static inline unsigned long rif_hash(const unsigned char *addr)
100 100
101static int tr_header(struct sk_buff *skb, struct net_device *dev, 101static int tr_header(struct sk_buff *skb, struct net_device *dev,
102 unsigned short type, 102 unsigned short type,
103 void *daddr, void *saddr, unsigned len) 103 const void *daddr, const void *saddr, unsigned len)
104{ 104{
105 struct trh_hdr *trh; 105 struct trh_hdr *trh;
106 int hdr_len; 106 int hdr_len;
@@ -142,7 +142,7 @@ static int tr_header(struct sk_buff *skb, struct net_device *dev,
142 if(daddr) 142 if(daddr)
143 { 143 {
144 memcpy(trh->daddr,daddr,dev->addr_len); 144 memcpy(trh->daddr,daddr,dev->addr_len);
145 tr_source_route(skb,trh,dev); 145 tr_source_route(skb, trh, dev);
146 return(hdr_len); 146 return(hdr_len);
147 } 147 }
148 148
@@ -247,7 +247,8 @@ __be16 tr_type_trans(struct sk_buff *skb, struct net_device *dev)
247 * We try to do source routing... 247 * We try to do source routing...
248 */ 248 */
249 249
250void tr_source_route(struct sk_buff *skb,struct trh_hdr *trh,struct net_device *dev) 250void tr_source_route(struct sk_buff *skb,struct trh_hdr *trh,
251 struct net_device *dev)
251{ 252{
252 int slack; 253 int slack;
253 unsigned int hash; 254 unsigned int hash;
@@ -592,14 +593,18 @@ static const struct file_operations rif_seq_fops = {
592 593
593#endif 594#endif
594 595
596static const struct header_ops tr_header_ops = {
597 .create = tr_header,
598 .rebuild= tr_rebuild_header,
599};
600
595static void tr_setup(struct net_device *dev) 601static void tr_setup(struct net_device *dev)
596{ 602{
597 /* 603 /*
598 * Configure and register 604 * Configure and register
599 */ 605 */
600 606
601 dev->hard_header = tr_header; 607 dev->header_ops = &tr_header_ops;
602 dev->rebuild_header = tr_rebuild_header;
603 608
604 dev->type = ARPHRD_IEEE802_TR; 609 dev->type = ARPHRD_IEEE802_TR;
605 dev->hard_header_len = TR_HLEN; 610 dev->hard_header_len = TR_HLEN;
diff --git a/net/8021q/vlan.c b/net/8021q/vlan.c
index 4d003e391754..f2bee234d361 100644
--- a/net/8021q/vlan.c
+++ b/net/8021q/vlan.c
@@ -314,6 +314,12 @@ int unregister_vlan_device(struct net_device *dev)
314 */ 314 */
315static struct lock_class_key vlan_netdev_xmit_lock_key; 315static struct lock_class_key vlan_netdev_xmit_lock_key;
316 316
317static const struct header_ops vlan_header_ops = {
318 .create = vlan_dev_hard_header,
319 .rebuild = vlan_dev_rebuild_header,
320 .parse = eth_header_parse,
321};
322
317static int vlan_dev_init(struct net_device *dev) 323static int vlan_dev_init(struct net_device *dev)
318{ 324{
319 struct net_device *real_dev = VLAN_DEV_INFO(dev)->real_dev; 325 struct net_device *real_dev = VLAN_DEV_INFO(dev)->real_dev;
@@ -331,18 +337,14 @@ static int vlan_dev_init(struct net_device *dev)
331 memcpy(dev->broadcast, real_dev->broadcast, dev->addr_len); 337 memcpy(dev->broadcast, real_dev->broadcast, dev->addr_len);
332 338
333 if (real_dev->features & NETIF_F_HW_VLAN_TX) { 339 if (real_dev->features & NETIF_F_HW_VLAN_TX) {
334 dev->hard_header = real_dev->hard_header; 340 dev->header_ops = real_dev->header_ops;
335 dev->hard_header_len = real_dev->hard_header_len; 341 dev->hard_header_len = real_dev->hard_header_len;
336 dev->hard_start_xmit = vlan_dev_hwaccel_hard_start_xmit; 342 dev->hard_start_xmit = vlan_dev_hwaccel_hard_start_xmit;
337 dev->rebuild_header = real_dev->rebuild_header;
338 } else { 343 } else {
339 dev->hard_header = vlan_dev_hard_header; 344 dev->header_ops = &vlan_header_ops;
340 dev->hard_header_len = real_dev->hard_header_len + VLAN_HLEN; 345 dev->hard_header_len = real_dev->hard_header_len + VLAN_HLEN;
341 dev->hard_start_xmit = vlan_dev_hard_start_xmit; 346 dev->hard_start_xmit = vlan_dev_hard_start_xmit;
342 dev->rebuild_header = vlan_dev_rebuild_header;
343 } 347 }
344 dev->hard_header_parse = real_dev->hard_header_parse;
345 dev->hard_header_cache = NULL;
346 348
347 lockdep_set_class(&dev->_xmit_lock, &vlan_netdev_xmit_lock_key); 349 lockdep_set_class(&dev->_xmit_lock, &vlan_netdev_xmit_lock_key);
348 return 0; 350 return 0;
diff --git a/net/8021q/vlan.h b/net/8021q/vlan.h
index 7df5b2935579..cf4a80d06b35 100644
--- a/net/8021q/vlan.h
+++ b/net/8021q/vlan.h
@@ -53,8 +53,8 @@ int vlan_dev_rebuild_header(struct sk_buff *skb);
53int vlan_skb_recv(struct sk_buff *skb, struct net_device *dev, 53int vlan_skb_recv(struct sk_buff *skb, struct net_device *dev,
54 struct packet_type *ptype, struct net_device *orig_dev); 54 struct packet_type *ptype, struct net_device *orig_dev);
55int vlan_dev_hard_header(struct sk_buff *skb, struct net_device *dev, 55int vlan_dev_hard_header(struct sk_buff *skb, struct net_device *dev,
56 unsigned short type, void *daddr, void *saddr, 56 unsigned short type, const void *daddr,
57 unsigned len); 57 const void *saddr, unsigned len);
58int vlan_dev_hard_start_xmit(struct sk_buff *skb, struct net_device *dev); 58int vlan_dev_hard_start_xmit(struct sk_buff *skb, struct net_device *dev);
59int vlan_dev_hwaccel_hard_start_xmit(struct sk_buff *skb, struct net_device *dev); 59int vlan_dev_hwaccel_hard_start_xmit(struct sk_buff *skb, struct net_device *dev);
60int vlan_dev_change_mtu(struct net_device *dev, int new_mtu); 60int vlan_dev_change_mtu(struct net_device *dev, int new_mtu);
diff --git a/net/8021q/vlan_dev.c b/net/8021q/vlan_dev.c
index ca8090fdabbb..1a1740aa9a8b 100644
--- a/net/8021q/vlan_dev.c
+++ b/net/8021q/vlan_dev.c
@@ -343,8 +343,8 @@ static inline unsigned short vlan_dev_get_egress_qos_mask(struct net_device* dev
343 * physical devices. 343 * physical devices.
344 */ 344 */
345int vlan_dev_hard_header(struct sk_buff *skb, struct net_device *dev, 345int vlan_dev_hard_header(struct sk_buff *skb, struct net_device *dev,
346 unsigned short type, void *daddr, void *saddr, 346 unsigned short type,
347 unsigned len) 347 const void *daddr, const void *saddr, unsigned len)
348{ 348{
349 struct vlan_hdr *vhdr; 349 struct vlan_hdr *vhdr;
350 unsigned short veth_TCI = 0; 350 unsigned short veth_TCI = 0;
diff --git a/net/appletalk/dev.c b/net/appletalk/dev.c
index 9e4dffc1e423..d856a62ab50f 100644
--- a/net/appletalk/dev.c
+++ b/net/appletalk/dev.c
@@ -24,11 +24,7 @@ static void ltalk_setup(struct net_device *dev)
24 /* Fill in the fields of the device structure with localtalk-generic values. */ 24 /* Fill in the fields of the device structure with localtalk-generic values. */
25 25
26 dev->change_mtu = ltalk_change_mtu; 26 dev->change_mtu = ltalk_change_mtu;
27 dev->hard_header = NULL;
28 dev->rebuild_header = NULL;
29 dev->set_mac_address = ltalk_mac_addr; 27 dev->set_mac_address = ltalk_mac_addr;
30 dev->hard_header_cache = NULL;
31 dev->header_cache_update= NULL;
32 28
33 dev->type = ARPHRD_LOCALTLK; 29 dev->type = ARPHRD_LOCALTLK;
34 dev->hard_header_len = LTALK_HLEN; 30 dev->hard_header_len = LTALK_HLEN;
diff --git a/net/ax25/ax25_ip.c b/net/ax25/ax25_ip.c
index 930e4918037f..f047a57aa95c 100644
--- a/net/ax25/ax25_ip.c
+++ b/net/ax25/ax25_ip.c
@@ -46,7 +46,9 @@
46 46
47#ifdef CONFIG_INET 47#ifdef CONFIG_INET
48 48
49int ax25_hard_header(struct sk_buff *skb, struct net_device *dev, unsigned short type, void *daddr, void *saddr, unsigned len) 49int ax25_hard_header(struct sk_buff *skb, struct net_device *dev,
50 unsigned short type, const void *daddr,
51 const void *saddr, unsigned len)
50{ 52{
51 unsigned char *buff; 53 unsigned char *buff;
52 54
@@ -215,7 +217,9 @@ put:
215 217
216#else /* INET */ 218#else /* INET */
217 219
218int ax25_hard_header(struct sk_buff *skb, struct net_device *dev, unsigned short type, void *daddr, void *saddr, unsigned len) 220int ax25_hard_header(struct sk_buff *skb, struct net_device *dev,
221 unsigned short type, const void *daddr,
222 const void *saddr, unsigned len)
219{ 223{
220 return -AX25_HEADER_LEN; 224 return -AX25_HEADER_LEN;
221} 225}
@@ -227,5 +231,12 @@ int ax25_rebuild_header(struct sk_buff *skb)
227 231
228#endif 232#endif
229 233
234const struct header_ops ax25_header_ops = {
235 .create = ax25_hard_header,
236 .rebuild = ax25_rebuild_header,
237};
238
230EXPORT_SYMBOL(ax25_hard_header); 239EXPORT_SYMBOL(ax25_hard_header);
231EXPORT_SYMBOL(ax25_rebuild_header); 240EXPORT_SYMBOL(ax25_rebuild_header);
241EXPORT_SYMBOL(ax25_header_ops);
242
diff --git a/net/core/dev.c b/net/core/dev.c
index 3923d5133050..d99864662582 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -967,14 +967,6 @@ void dev_load(struct net *net, const char *name)
967 request_module("%s", name); 967 request_module("%s", name);
968} 968}
969 969
970static int default_rebuild_header(struct sk_buff *skb)
971{
972 printk(KERN_DEBUG "%s: default_rebuild_header called -- BUG!\n",
973 skb->dev ? skb->dev->name : "NULL!!!");
974 kfree_skb(skb);
975 return 1;
976}
977
978/** 970/**
979 * dev_open - prepare an interface for use. 971 * dev_open - prepare an interface for use.
980 * @dev: device to open 972 * @dev: device to open
@@ -3561,14 +3553,6 @@ int register_netdevice(struct net_device *dev)
3561 } 3553 }
3562 } 3554 }
3563 3555
3564 /*
3565 * nil rebuild_header routine,
3566 * that should be never called and used as just bug trap.
3567 */
3568
3569 if (!dev->rebuild_header)
3570 dev->rebuild_header = default_rebuild_header;
3571
3572 ret = netdev_register_kobject(dev); 3556 ret = netdev_register_kobject(dev);
3573 if (ret) 3557 if (ret)
3574 goto err_uninit; 3558 goto err_uninit;
diff --git a/net/core/neighbour.c b/net/core/neighbour.c
index 10bcb9f8da5c..c52df858d0be 100644
--- a/net/core/neighbour.c
+++ b/net/core/neighbour.c
@@ -897,8 +897,8 @@ out_unlock_bh:
897static void neigh_update_hhs(struct neighbour *neigh) 897static void neigh_update_hhs(struct neighbour *neigh)
898{ 898{
899 struct hh_cache *hh; 899 struct hh_cache *hh;
900 void (*update)(struct hh_cache*, struct net_device*, unsigned char *) = 900 void (*update)(struct hh_cache*, const struct net_device*, const unsigned char *)
901 neigh->dev->header_cache_update; 901 = neigh->dev->header_ops->cache_update;
902 902
903 if (update) { 903 if (update) {
904 for (hh = neigh->hh; hh; hh = hh->hh_next) { 904 for (hh = neigh->hh; hh; hh = hh->hh_next) {
@@ -1095,7 +1095,8 @@ static void neigh_hh_init(struct neighbour *n, struct dst_entry *dst,
1095 hh->hh_type = protocol; 1095 hh->hh_type = protocol;
1096 atomic_set(&hh->hh_refcnt, 0); 1096 atomic_set(&hh->hh_refcnt, 0);
1097 hh->hh_next = NULL; 1097 hh->hh_next = NULL;
1098 if (dev->hard_header_cache(n, hh)) { 1098
1099 if (dev->header_ops->cache(n, hh)) {
1099 kfree(hh); 1100 kfree(hh);
1100 hh = NULL; 1101 hh = NULL;
1101 } else { 1102 } else {
@@ -1127,7 +1128,7 @@ int neigh_compat_output(struct sk_buff *skb)
1127 1128
1128 if (dev_hard_header(skb, dev, ntohs(skb->protocol), NULL, NULL, 1129 if (dev_hard_header(skb, dev, ntohs(skb->protocol), NULL, NULL,
1129 skb->len) < 0 && 1130 skb->len) < 0 &&
1130 dev->rebuild_header(skb)) 1131 dev->header_ops->rebuild(skb))
1131 return 0; 1132 return 0;
1132 1133
1133 return dev_queue_xmit(skb); 1134 return dev_queue_xmit(skb);
@@ -1149,7 +1150,7 @@ int neigh_resolve_output(struct sk_buff *skb)
1149 if (!neigh_event_send(neigh, skb)) { 1150 if (!neigh_event_send(neigh, skb)) {
1150 int err; 1151 int err;
1151 struct net_device *dev = neigh->dev; 1152 struct net_device *dev = neigh->dev;
1152 if (dev->hard_header_cache && !dst->hh) { 1153 if (dev->header_ops->cache && !dst->hh) {
1153 write_lock_bh(&neigh->lock); 1154 write_lock_bh(&neigh->lock);
1154 if (!dst->hh) 1155 if (!dst->hh)
1155 neigh_hh_init(neigh, dst, dst->ops->protocol); 1156 neigh_hh_init(neigh, dst, dst->ops->protocol);
diff --git a/net/ethernet/eth.c b/net/ethernet/eth.c
index bdeb2f0ace32..ed8a3d49487d 100644
--- a/net/ethernet/eth.c
+++ b/net/ethernet/eth.c
@@ -75,8 +75,9 @@ __setup("ether=", netdev_boot_setup);
75 * Set the protocol type. For a packet of type ETH_P_802_3 we put the length 75 * Set the protocol type. For a packet of type ETH_P_802_3 we put the length
76 * in here instead. It is up to the 802.2 layer to carry protocol information. 76 * in here instead. It is up to the 802.2 layer to carry protocol information.
77 */ 77 */
78int eth_header(struct sk_buff *skb, struct net_device *dev, unsigned short type, 78int eth_header(struct sk_buff *skb, struct net_device *dev,
79 void *daddr, void *saddr, unsigned len) 79 unsigned short type,
80 const void *daddr, const void *saddr, unsigned len)
80{ 81{
81 struct ethhdr *eth = (struct ethhdr *)skb_push(skb, ETH_HLEN); 82 struct ethhdr *eth = (struct ethhdr *)skb_push(skb, ETH_HLEN);
82 83
@@ -109,6 +110,7 @@ int eth_header(struct sk_buff *skb, struct net_device *dev, unsigned short type,
109 110
110 return -ETH_HLEN; 111 return -ETH_HLEN;
111} 112}
113EXPORT_SYMBOL(eth_header);
112 114
113/** 115/**
114 * eth_rebuild_header- rebuild the Ethernet MAC header. 116 * eth_rebuild_header- rebuild the Ethernet MAC header.
@@ -141,6 +143,7 @@ int eth_rebuild_header(struct sk_buff *skb)
141 143
142 return 0; 144 return 0;
143} 145}
146EXPORT_SYMBOL(eth_rebuild_header);
144 147
145/** 148/**
146 * eth_type_trans - determine the packet's protocol ID. 149 * eth_type_trans - determine the packet's protocol ID.
@@ -207,12 +210,13 @@ EXPORT_SYMBOL(eth_type_trans);
207 * @skb: packet to extract header from 210 * @skb: packet to extract header from
208 * @haddr: destination buffer 211 * @haddr: destination buffer
209 */ 212 */
210static int eth_header_parse(const struct sk_buff *skb, unsigned char *haddr) 213int eth_header_parse(const struct sk_buff *skb, unsigned char *haddr)
211{ 214{
212 const struct ethhdr *eth = eth_hdr(skb); 215 const struct ethhdr *eth = eth_hdr(skb);
213 memcpy(haddr, eth->h_source, ETH_ALEN); 216 memcpy(haddr, eth->h_source, ETH_ALEN);
214 return ETH_ALEN; 217 return ETH_ALEN;
215} 218}
219EXPORT_SYMBOL(eth_header_parse);
216 220
217/** 221/**
218 * eth_header_cache - fill cache entry from neighbour 222 * eth_header_cache - fill cache entry from neighbour
@@ -220,11 +224,11 @@ static int eth_header_parse(const struct sk_buff *skb, unsigned char *haddr)
220 * @hh: destination cache entry 224 * @hh: destination cache entry
221 * Create an Ethernet header template from the neighbour. 225 * Create an Ethernet header template from the neighbour.
222 */ 226 */
223int eth_header_cache(struct neighbour *neigh, struct hh_cache *hh) 227int eth_header_cache(const struct neighbour *neigh, struct hh_cache *hh)
224{ 228{
225 __be16 type = hh->hh_type; 229 __be16 type = hh->hh_type;
226 struct ethhdr *eth; 230 struct ethhdr *eth;
227 struct net_device *dev = neigh->dev; 231 const struct net_device *dev = neigh->dev;
228 232
229 eth = (struct ethhdr *) 233 eth = (struct ethhdr *)
230 (((u8 *) hh->hh_data) + (HH_DATA_OFF(sizeof(*eth)))); 234 (((u8 *) hh->hh_data) + (HH_DATA_OFF(sizeof(*eth))));
@@ -238,6 +242,7 @@ int eth_header_cache(struct neighbour *neigh, struct hh_cache *hh)
238 hh->hh_len = ETH_HLEN; 242 hh->hh_len = ETH_HLEN;
239 return 0; 243 return 0;
240} 244}
245EXPORT_SYMBOL(eth_header_cache);
241 246
242/** 247/**
243 * eth_header_cache_update - update cache entry 248 * eth_header_cache_update - update cache entry
@@ -247,12 +252,14 @@ int eth_header_cache(struct neighbour *neigh, struct hh_cache *hh)
247 * 252 *
248 * Called by Address Resolution module to notify changes in address. 253 * Called by Address Resolution module to notify changes in address.
249 */ 254 */
250void eth_header_cache_update(struct hh_cache *hh, struct net_device *dev, 255void eth_header_cache_update(struct hh_cache *hh,
251 unsigned char *haddr) 256 const struct net_device *dev,
257 const unsigned char *haddr)
252{ 258{
253 memcpy(((u8 *) hh->hh_data) + HH_DATA_OFF(sizeof(struct ethhdr)), 259 memcpy(((u8 *) hh->hh_data) + HH_DATA_OFF(sizeof(struct ethhdr)),
254 haddr, ETH_ALEN); 260 haddr, ETH_ALEN);
255} 261}
262EXPORT_SYMBOL(eth_header_cache_update);
256 263
257/** 264/**
258 * eth_mac_addr - set new Ethernet hardware address 265 * eth_mac_addr - set new Ethernet hardware address
@@ -291,6 +298,14 @@ static int eth_change_mtu(struct net_device *dev, int new_mtu)
291 return 0; 298 return 0;
292} 299}
293 300
301const struct header_ops eth_header_ops ____cacheline_aligned = {
302 .create = eth_header,
303 .parse = eth_header_parse,
304 .rebuild = eth_rebuild_header,
305 .cache = eth_header_cache,
306 .cache_update = eth_header_cache_update,
307};
308
294/** 309/**
295 * ether_setup - setup Ethernet network device 310 * ether_setup - setup Ethernet network device
296 * @dev: network device 311 * @dev: network device
@@ -298,13 +313,10 @@ static int eth_change_mtu(struct net_device *dev, int new_mtu)
298 */ 313 */
299void ether_setup(struct net_device *dev) 314void ether_setup(struct net_device *dev)
300{ 315{
316 dev->header_ops = &eth_header_ops;
317
301 dev->change_mtu = eth_change_mtu; 318 dev->change_mtu = eth_change_mtu;
302 dev->hard_header = eth_header;
303 dev->rebuild_header = eth_rebuild_header;
304 dev->set_mac_address = eth_mac_addr; 319 dev->set_mac_address = eth_mac_addr;
305 dev->hard_header_cache = eth_header_cache;
306 dev->header_cache_update= eth_header_cache_update;
307 dev->hard_header_parse = eth_header_parse;
308 320
309 dev->type = ARPHRD_ETHER; 321 dev->type = ARPHRD_ETHER;
310 dev->hard_header_len = ETH_HLEN; 322 dev->hard_header_len = ETH_HLEN;
diff --git a/net/ipv4/arp.c b/net/ipv4/arp.c
index 5b24c65b13c6..d8248198bcd7 100644
--- a/net/ipv4/arp.c
+++ b/net/ipv4/arp.c
@@ -253,7 +253,7 @@ static int arp_constructor(struct neighbour *neigh)
253 neigh->parms = neigh_parms_clone(parms); 253 neigh->parms = neigh_parms_clone(parms);
254 rcu_read_unlock(); 254 rcu_read_unlock();
255 255
256 if (dev->hard_header == NULL) { 256 if (!dev->header_ops) {
257 neigh->nud_state = NUD_NOARP; 257 neigh->nud_state = NUD_NOARP;
258 neigh->ops = &arp_direct_ops; 258 neigh->ops = &arp_direct_ops;
259 neigh->output = neigh->ops->queue_xmit; 259 neigh->output = neigh->ops->queue_xmit;
@@ -310,10 +310,12 @@ static int arp_constructor(struct neighbour *neigh)
310 neigh->nud_state = NUD_NOARP; 310 neigh->nud_state = NUD_NOARP;
311 memcpy(neigh->ha, dev->broadcast, dev->addr_len); 311 memcpy(neigh->ha, dev->broadcast, dev->addr_len);
312 } 312 }
313 if (dev->hard_header_cache) 313
314 if (dev->header_ops->cache)
314 neigh->ops = &arp_hh_ops; 315 neigh->ops = &arp_hh_ops;
315 else 316 else
316 neigh->ops = &arp_generic_ops; 317 neigh->ops = &arp_generic_ops;
318
317 if (neigh->nud_state&NUD_VALID) 319 if (neigh->nud_state&NUD_VALID)
318 neigh->output = neigh->ops->connected_output; 320 neigh->output = neigh->ops->connected_output;
319 else 321 else
diff --git a/net/ipv4/ip_gre.c b/net/ipv4/ip_gre.c
index ffa9f1c9dcbb..f151900efaf9 100644
--- a/net/ipv4/ip_gre.c
+++ b/net/ipv4/ip_gre.c
@@ -684,7 +684,7 @@ static int ipgre_tunnel_xmit(struct sk_buff *skb, struct net_device *dev)
684 goto tx_error; 684 goto tx_error;
685 } 685 }
686 686
687 if (dev->hard_header) { 687 if (dev->header_ops) {
688 gre_hlen = 0; 688 gre_hlen = 0;
689 tiph = (struct iphdr*)skb->data; 689 tiph = (struct iphdr*)skb->data;
690 } else { 690 } else {
@@ -1063,8 +1063,9 @@ static int ipgre_tunnel_change_mtu(struct net_device *dev, int new_mtu)
1063 1063
1064 */ 1064 */
1065 1065
1066static int ipgre_header(struct sk_buff *skb, struct net_device *dev, unsigned short type, 1066static int ipgre_header(struct sk_buff *skb, struct net_device *dev,
1067 void *daddr, void *saddr, unsigned len) 1067 unsigned short type,
1068 const void *daddr, const void *saddr, unsigned len)
1068{ 1069{
1069 struct ip_tunnel *t = netdev_priv(dev); 1070 struct ip_tunnel *t = netdev_priv(dev);
1070 struct iphdr *iph = (struct iphdr *)skb_push(skb, t->hlen); 1071 struct iphdr *iph = (struct iphdr *)skb_push(skb, t->hlen);
@@ -1091,6 +1092,10 @@ static int ipgre_header(struct sk_buff *skb, struct net_device *dev, unsigned sh
1091 return -t->hlen; 1092 return -t->hlen;
1092} 1093}
1093 1094
1095static const struct header_ops ipgre_header_ops = {
1096 .create = ipgre_header,
1097};
1098
1094static int ipgre_open(struct net_device *dev) 1099static int ipgre_open(struct net_device *dev)
1095{ 1100{
1096 struct ip_tunnel *t = netdev_priv(dev); 1101 struct ip_tunnel *t = netdev_priv(dev);
@@ -1187,7 +1192,7 @@ static int ipgre_tunnel_init(struct net_device *dev)
1187 if (!iph->saddr) 1192 if (!iph->saddr)
1188 return -EINVAL; 1193 return -EINVAL;
1189 dev->flags = IFF_BROADCAST; 1194 dev->flags = IFF_BROADCAST;
1190 dev->hard_header = ipgre_header; 1195 dev->header_ops = &ipgre_header_ops;
1191 dev->open = ipgre_open; 1196 dev->open = ipgre_open;
1192 dev->stop = ipgre_close; 1197 dev->stop = ipgre_close;
1193 } 1198 }
diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c
index 77f67b7cb9bf..699f06781fd8 100644
--- a/net/ipv4/ip_output.c
+++ b/net/ipv4/ip_output.c
@@ -169,7 +169,7 @@ static inline int ip_finish_output2(struct sk_buff *skb)
169 IP_INC_STATS(IPSTATS_MIB_OUTBCASTPKTS); 169 IP_INC_STATS(IPSTATS_MIB_OUTBCASTPKTS);
170 170
171 /* Be paranoid, rather than too clever. */ 171 /* Be paranoid, rather than too clever. */
172 if (unlikely(skb_headroom(skb) < hh_len && dev->hard_header)) { 172 if (unlikely(skb_headroom(skb) < hh_len && dev->header_ops)) {
173 struct sk_buff *skb2; 173 struct sk_buff *skb2;
174 174
175 skb2 = skb_realloc_headroom(skb, LL_RESERVED_SPACE(dev)); 175 skb2 = skb_realloc_headroom(skb, LL_RESERVED_SPACE(dev));
diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c
index 7ea5a502ca08..b761dbed8cec 100644
--- a/net/ipv6/ndisc.c
+++ b/net/ipv6/ndisc.c
@@ -354,7 +354,7 @@ static int ndisc_constructor(struct neighbour *neigh)
354 rcu_read_unlock(); 354 rcu_read_unlock();
355 355
356 neigh->type = is_multicast ? RTN_MULTICAST : RTN_UNICAST; 356 neigh->type = is_multicast ? RTN_MULTICAST : RTN_UNICAST;
357 if (dev->hard_header == NULL) { 357 if (!dev->header_ops) {
358 neigh->nud_state = NUD_NOARP; 358 neigh->nud_state = NUD_NOARP;
359 neigh->ops = &ndisc_direct_ops; 359 neigh->ops = &ndisc_direct_ops;
360 neigh->output = neigh->ops->queue_xmit; 360 neigh->output = neigh->ops->queue_xmit;
@@ -371,7 +371,7 @@ static int ndisc_constructor(struct neighbour *neigh)
371 neigh->nud_state = NUD_NOARP; 371 neigh->nud_state = NUD_NOARP;
372 memcpy(neigh->ha, dev->broadcast, dev->addr_len); 372 memcpy(neigh->ha, dev->broadcast, dev->addr_len);
373 } 373 }
374 if (dev->hard_header_cache) 374 if (dev->header_ops->cache)
375 neigh->ops = &ndisc_hh_ops; 375 neigh->ops = &ndisc_hh_ops;
376 else 376 else
377 neigh->ops = &ndisc_generic_ops; 377 neigh->ops = &ndisc_generic_ops;
@@ -807,7 +807,7 @@ static void ndisc_recv_ns(struct sk_buff *skb)
807 neigh_update(neigh, lladdr, NUD_STALE, 807 neigh_update(neigh, lladdr, NUD_STALE,
808 NEIGH_UPDATE_F_WEAK_OVERRIDE| 808 NEIGH_UPDATE_F_WEAK_OVERRIDE|
809 NEIGH_UPDATE_F_OVERRIDE); 809 NEIGH_UPDATE_F_OVERRIDE);
810 if (neigh || !dev->hard_header) { 810 if (neigh || !dev->header_ops) {
811 ndisc_send_na(dev, neigh, saddr, &msg->target, 811 ndisc_send_na(dev, neigh, saddr, &msg->target,
812 is_router, 812 is_router,
813 1, (ifp != NULL && inc), inc); 813 1, (ifp != NULL && inc), inc);
diff --git a/net/mac80211/ieee80211.c b/net/mac80211/ieee80211.c
index 0cdcf0d0c6ca..57ec8880bb1a 100644
--- a/net/mac80211/ieee80211.c
+++ b/net/mac80211/ieee80211.c
@@ -228,7 +228,6 @@ void ieee80211_if_mgmt_setup(struct net_device *dev)
228 dev->open = ieee80211_mgmt_open; 228 dev->open = ieee80211_mgmt_open;
229 dev->stop = ieee80211_mgmt_stop; 229 dev->stop = ieee80211_mgmt_stop;
230 dev->type = ARPHRD_IEEE80211_PRISM; 230 dev->type = ARPHRD_IEEE80211_PRISM;
231 dev->hard_header_parse = header_parse_80211;
232 dev->uninit = ieee80211_if_reinit; 231 dev->uninit = ieee80211_if_reinit;
233 dev->destructor = ieee80211_if_free; 232 dev->destructor = ieee80211_if_free;
234} 233}
@@ -546,10 +545,19 @@ static void ieee80211_set_multicast_list(struct net_device *dev)
546 netif_tx_unlock(local->mdev); 545 netif_tx_unlock(local->mdev);
547} 546}
548 547
548static const struct header_ops ieee80211_header_ops = {
549 .create = eth_header,
550 .parse = header_parse_80211,
551 .rebuild = eth_rebuild_header,
552 .cache = eth_header_cache,
553 .cache_update = eth_header_cache_update,
554};
555
549/* Must not be called for mdev and apdev */ 556/* Must not be called for mdev and apdev */
550void ieee80211_if_setup(struct net_device *dev) 557void ieee80211_if_setup(struct net_device *dev)
551{ 558{
552 ether_setup(dev); 559 ether_setup(dev);
560 dev->header_ops = &ieee80211_header_ops;
553 dev->hard_start_xmit = ieee80211_subif_start_xmit; 561 dev->hard_start_xmit = ieee80211_subif_start_xmit;
554 dev->wireless_handlers = &ieee80211_iw_handler_def; 562 dev->wireless_handlers = &ieee80211_iw_handler_def;
555 dev->set_multicast_list = ieee80211_set_multicast_list; 563 dev->set_multicast_list = ieee80211_set_multicast_list;
@@ -1197,7 +1205,7 @@ struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len,
1197 mdev->open = ieee80211_master_open; 1205 mdev->open = ieee80211_master_open;
1198 mdev->stop = ieee80211_master_stop; 1206 mdev->stop = ieee80211_master_stop;
1199 mdev->type = ARPHRD_IEEE80211; 1207 mdev->type = ARPHRD_IEEE80211;
1200 mdev->hard_header_parse = header_parse_80211; 1208 mdev->header_ops = &ieee80211_header_ops;
1201 1209
1202 sdata->type = IEEE80211_IF_TYPE_AP; 1210 sdata->type = IEEE80211_IF_TYPE_AP;
1203 sdata->dev = mdev; 1211 sdata->dev = mdev;
diff --git a/net/netrom/nr_dev.c b/net/netrom/nr_dev.c
index c7b5d930e732..8c68da5ef0a1 100644
--- a/net/netrom/nr_dev.c
+++ b/net/netrom/nr_dev.c
@@ -95,8 +95,9 @@ static int nr_rebuild_header(struct sk_buff *skb)
95 95
96#endif 96#endif
97 97
98static int nr_header(struct sk_buff *skb, struct net_device *dev, unsigned short type, 98static int nr_header(struct sk_buff *skb, struct net_device *dev,
99 void *daddr, void *saddr, unsigned len) 99 unsigned short type,
100 const void *daddr, const void *saddr, unsigned len)
100{ 101{
101 unsigned char *buff = skb_push(skb, NR_NETWORK_LEN + NR_TRANSPORT_LEN); 102 unsigned char *buff = skb_push(skb, NR_NETWORK_LEN + NR_TRANSPORT_LEN);
102 103
@@ -193,6 +194,12 @@ static struct net_device_stats *nr_get_stats(struct net_device *dev)
193 return &nr->stats; 194 return &nr->stats;
194} 195}
195 196
197static const struct header_ops nr_header_ops = {
198 .create = nr_header,
199 .rebuild= nr_rebuild_header,
200};
201
202
196void nr_setup(struct net_device *dev) 203void nr_setup(struct net_device *dev)
197{ 204{
198 dev->mtu = NR_MAX_PACKET_SIZE; 205 dev->mtu = NR_MAX_PACKET_SIZE;
@@ -200,11 +207,10 @@ void nr_setup(struct net_device *dev)
200 dev->open = nr_open; 207 dev->open = nr_open;
201 dev->stop = nr_close; 208 dev->stop = nr_close;
202 209
203 dev->hard_header = nr_header; 210 dev->header_ops = &nr_header_ops;
204 dev->hard_header_len = NR_NETWORK_LEN + NR_TRANSPORT_LEN; 211 dev->hard_header_len = NR_NETWORK_LEN + NR_TRANSPORT_LEN;
205 dev->addr_len = AX25_ADDR_LEN; 212 dev->addr_len = AX25_ADDR_LEN;
206 dev->type = ARPHRD_NETROM; 213 dev->type = ARPHRD_NETROM;
207 dev->rebuild_header = nr_rebuild_header;
208 dev->set_mac_address = nr_set_mac_address; 214 dev->set_mac_address = nr_set_mac_address;
209 215
210 /* New-style flags. */ 216 /* New-style flags. */
diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c
index c9ee343c2a6c..e11000a8e950 100644
--- a/net/packet/af_packet.c
+++ b/net/packet/af_packet.c
@@ -389,7 +389,7 @@ static int packet_sendmsg_spkt(struct kiocb *iocb, struct socket *sock,
389 skb_reset_network_header(skb); 389 skb_reset_network_header(skb);
390 390
391 /* Try to align data part correctly */ 391 /* Try to align data part correctly */
392 if (dev->hard_header) { 392 if (dev->header_ops) {
393 skb->data -= dev->hard_header_len; 393 skb->data -= dev->hard_header_len;
394 skb->tail -= dev->hard_header_len; 394 skb->tail -= dev->hard_header_len;
395 if (len < dev->hard_header_len) 395 if (len < dev->hard_header_len)
@@ -466,7 +466,7 @@ static int packet_rcv(struct sk_buff *skb, struct net_device *dev, struct packet
466 466
467 skb->dev = dev; 467 skb->dev = dev;
468 468
469 if (dev->hard_header) { 469 if (dev->header_ops) {
470 /* The device has an explicit notion of ll header, 470 /* The device has an explicit notion of ll header,
471 exported to higher levels. 471 exported to higher levels.
472 472
@@ -581,7 +581,7 @@ static int tpacket_rcv(struct sk_buff *skb, struct net_device *dev, struct packe
581 sk = pt->af_packet_priv; 581 sk = pt->af_packet_priv;
582 po = pkt_sk(sk); 582 po = pkt_sk(sk);
583 583
584 if (dev->hard_header) { 584 if (dev->header_ops) {
585 if (sk->sk_type != SOCK_DGRAM) 585 if (sk->sk_type != SOCK_DGRAM)
586 skb_push(skb, skb->data - skb_mac_header(skb)); 586 skb_push(skb, skb->data - skb_mac_header(skb));
587 else if (skb->pkt_type == PACKET_OUTGOING) { 587 else if (skb->pkt_type == PACKET_OUTGOING) {
diff --git a/net/rose/rose_dev.c b/net/rose/rose_dev.c
index 8d88795dc663..1b6741f1d746 100644
--- a/net/rose/rose_dev.c
+++ b/net/rose/rose_dev.c
@@ -35,8 +35,9 @@
35#include <net/ax25.h> 35#include <net/ax25.h>
36#include <net/rose.h> 36#include <net/rose.h>
37 37
38static int rose_header(struct sk_buff *skb, struct net_device *dev, unsigned short type, 38static int rose_header(struct sk_buff *skb, struct net_device *dev,
39 void *daddr, void *saddr, unsigned len) 39 unsigned short type,
40 const void *daddr, const void *saddr, unsigned len)
40{ 41{
41 unsigned char *buff = skb_push(skb, ROSE_MIN_LEN + 2); 42 unsigned char *buff = skb_push(skb, ROSE_MIN_LEN + 2);
42 43
@@ -148,6 +149,11 @@ static struct net_device_stats *rose_get_stats(struct net_device *dev)
148 return netdev_priv(dev); 149 return netdev_priv(dev);
149} 150}
150 151
152static const struct header_ops rose_header_ops = {
153 .create = rose_header,
154 .rebuild= rose_rebuild_header,
155};
156
151void rose_setup(struct net_device *dev) 157void rose_setup(struct net_device *dev)
152{ 158{
153 dev->mtu = ROSE_MAX_PACKET_SIZE - 2; 159 dev->mtu = ROSE_MAX_PACKET_SIZE - 2;
@@ -155,11 +161,10 @@ void rose_setup(struct net_device *dev)
155 dev->open = rose_open; 161 dev->open = rose_open;
156 dev->stop = rose_close; 162 dev->stop = rose_close;
157 163
158 dev->hard_header = rose_header; 164 dev->header_ops = &rose_header_ops;
159 dev->hard_header_len = AX25_BPQ_HEADER_LEN + AX25_MAX_HEADER_LEN + ROSE_MIN_LEN; 165 dev->hard_header_len = AX25_BPQ_HEADER_LEN + AX25_MAX_HEADER_LEN + ROSE_MIN_LEN;
160 dev->addr_len = ROSE_ADDR_LEN; 166 dev->addr_len = ROSE_ADDR_LEN;
161 dev->type = ARPHRD_ROSE; 167 dev->type = ARPHRD_ROSE;
162 dev->rebuild_header = rose_rebuild_header;
163 dev->set_mac_address = rose_set_mac_address; 168 dev->set_mac_address = rose_set_mac_address;
164 169
165 /* New-style flags. */ 170 /* New-style flags. */
diff --git a/net/sched/sch_teql.c b/net/sched/sch_teql.c
index d13970f3c7b1..be57cf317a7f 100644
--- a/net/sched/sch_teql.c
+++ b/net/sched/sch_teql.c
@@ -249,10 +249,10 @@ __teql_resolve(struct sk_buff *skb, struct sk_buff *skb_res, struct net_device *
249 return (skb_res == NULL) ? -EAGAIN : 1; 249 return (skb_res == NULL) ? -EAGAIN : 1;
250} 250}
251 251
252static __inline__ int 252static inline int teql_resolve(struct sk_buff *skb,
253teql_resolve(struct sk_buff *skb, struct sk_buff *skb_res, struct net_device *dev) 253 struct sk_buff *skb_res, struct net_device *dev)
254{ 254{
255 if (dev->hard_header == NULL || 255 if (dev->header_ops == NULL ||
256 skb->dst == NULL || 256 skb->dst == NULL ||
257 skb->dst->neighbour == NULL) 257 skb->dst->neighbour == NULL)
258 return 0; 258 return 0;