* Set the protocol type. For a packet of type ETH_P_802_3 we put the length
* in here instead. It is up to the 802.2 layer to carry protocol information.
*/
-int eth_header(struct sk_buff *skb, struct net_device *dev, unsigned short type,
- void *daddr, void *saddr, unsigned len)
+int eth_header(struct sk_buff *skb, struct net_device *dev,
+ unsigned short type,
+ const void *daddr, const void *saddr, unsigned len)
{
struct ethhdr *eth = (struct ethhdr *)skb_push(skb, ETH_HLEN);
if (!saddr)
saddr = dev->dev_addr;
- memcpy(eth->h_source, saddr, dev->addr_len);
+ memcpy(eth->h_source, saddr, ETH_ALEN);
if (daddr) {
- memcpy(eth->h_dest, daddr, dev->addr_len);
+ memcpy(eth->h_dest, daddr, ETH_ALEN);
return ETH_HLEN;
}
*/
if (dev->flags & (IFF_LOOPBACK | IFF_NOARP)) {
- memset(eth->h_dest, 0, dev->addr_len);
+ memset(eth->h_dest, 0, ETH_ALEN);
return ETH_HLEN;
}
return -ETH_HLEN;
}
+EXPORT_SYMBOL(eth_header);
/**
* eth_rebuild_header- rebuild the Ethernet MAC header.
"%s: unable to resolve type %X addresses.\n",
dev->name, (int)eth->h_proto);
- memcpy(eth->h_source, dev->dev_addr, dev->addr_len);
+ memcpy(eth->h_source, dev->dev_addr, ETH_ALEN);
break;
}
return 0;
}
+EXPORT_SYMBOL(eth_rebuild_header);
/**
* eth_type_trans - determine the packet's protocol ID.
* @skb: packet to extract header from
* @haddr: destination buffer
*/
-static int eth_header_parse(struct sk_buff *skb, unsigned char *haddr)
+int eth_header_parse(const struct sk_buff *skb, unsigned char *haddr)
{
- struct ethhdr *eth = eth_hdr(skb);
+ const struct ethhdr *eth = eth_hdr(skb);
memcpy(haddr, eth->h_source, ETH_ALEN);
return ETH_ALEN;
}
+EXPORT_SYMBOL(eth_header_parse);
/**
* eth_header_cache - fill cache entry from neighbour
* @hh: destination cache entry
* Create an Ethernet header template from the neighbour.
*/
-int eth_header_cache(struct neighbour *neigh, struct hh_cache *hh)
+int eth_header_cache(const struct neighbour *neigh, struct hh_cache *hh)
{
__be16 type = hh->hh_type;
struct ethhdr *eth;
- struct net_device *dev = neigh->dev;
+ const struct net_device *dev = neigh->dev;
eth = (struct ethhdr *)
(((u8 *) hh->hh_data) + (HH_DATA_OFF(sizeof(*eth))));
return -1;
eth->h_proto = type;
- memcpy(eth->h_source, dev->dev_addr, dev->addr_len);
- memcpy(eth->h_dest, neigh->ha, dev->addr_len);
+ memcpy(eth->h_source, dev->dev_addr, ETH_ALEN);
+ memcpy(eth->h_dest, neigh->ha, ETH_ALEN);
hh->hh_len = ETH_HLEN;
return 0;
}
+EXPORT_SYMBOL(eth_header_cache);
/**
* eth_header_cache_update - update cache entry
*
* Called by Address Resolution module to notify changes in address.
*/
-void eth_header_cache_update(struct hh_cache *hh, struct net_device *dev,
- unsigned char *haddr)
+void eth_header_cache_update(struct hh_cache *hh,
+ const struct net_device *dev,
+ const unsigned char *haddr)
{
memcpy(((u8 *) hh->hh_data) + HH_DATA_OFF(sizeof(struct ethhdr)),
- haddr, dev->addr_len);
+ haddr, ETH_ALEN);
}
+EXPORT_SYMBOL(eth_header_cache_update);
/**
* eth_mac_addr - set new Ethernet hardware address
return -EBUSY;
if (!is_valid_ether_addr(addr->sa_data))
return -EADDRNOTAVAIL;
- memcpy(dev->dev_addr, addr->sa_data, dev->addr_len);
+ memcpy(dev->dev_addr, addr->sa_data, ETH_ALEN);
return 0;
}
return 0;
}
+static int eth_validate_addr(struct net_device *dev)
+{
+ if (!is_valid_ether_addr(dev->dev_addr))
+ return -EINVAL;
+
+ return 0;
+}
+
+const struct header_ops eth_header_ops ____cacheline_aligned = {
+ .create = eth_header,
+ .parse = eth_header_parse,
+ .rebuild = eth_rebuild_header,
+ .cache = eth_header_cache,
+ .cache_update = eth_header_cache_update,
+};
+
/**
* ether_setup - setup Ethernet network device
* @dev: network device
*/
void ether_setup(struct net_device *dev)
{
+ dev->header_ops = ð_header_ops;
+
dev->change_mtu = eth_change_mtu;
- dev->hard_header = eth_header;
- dev->rebuild_header = eth_rebuild_header;
dev->set_mac_address = eth_mac_addr;
- dev->hard_header_cache = eth_header_cache;
- dev->header_cache_update= eth_header_cache_update;
- dev->hard_header_parse = eth_header_parse;
+ dev->validate_addr = eth_validate_addr;
dev->type = ARPHRD_ETHER;
dev->hard_header_len = ETH_HLEN;
return alloc_netdev_mq(sizeof_priv, "eth%d", ether_setup, queue_count);
}
EXPORT_SYMBOL(alloc_etherdev_mq);
+
+char *print_mac(char *buf, const u8 *addr)
+{
+ sprintf(buf, MAC_FMT,
+ addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]);
+ return buf;
+}
+EXPORT_SYMBOL(print_mac);