12874c5fdSThomas Gleixner // SPDX-License-Identifier: GPL-2.0-or-later
21da177e4SLinus Torvalds /*
31da177e4SLinus Torvalds * INET An implementation of the TCP/IP protocol suite for the LINUX
41da177e4SLinus Torvalds * operating system. INET is implemented using the BSD Socket
51da177e4SLinus Torvalds * interface as the means of communication with the user level.
61da177e4SLinus Torvalds *
71da177e4SLinus Torvalds * Ethernet-type device handling.
81da177e4SLinus Torvalds *
91da177e4SLinus Torvalds * Version: @(#)eth.c 1.0.7 05/25/93
101da177e4SLinus Torvalds *
1102c30a84SJesper Juhl * Authors: Ross Biro
121da177e4SLinus Torvalds * Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
131da177e4SLinus Torvalds * Mark Evans, <evansmp@uhura.aston.ac.uk>
141da177e4SLinus Torvalds * Florian La Roche, <rzsfl@rz.uni-sb.de>
151da177e4SLinus Torvalds * Alan Cox, <gw4pts@gw4pts.ampr.org>
161da177e4SLinus Torvalds *
171da177e4SLinus Torvalds * Fixes:
181da177e4SLinus Torvalds * Mr Linux : Arp problems
191da177e4SLinus Torvalds * Alan Cox : Generic queue tidyup (very tiny here)
201da177e4SLinus Torvalds * Alan Cox : eth_header ntohs should be htons
211da177e4SLinus Torvalds * Alan Cox : eth_rebuild_header missing an htons and
221da177e4SLinus Torvalds * minor other things.
231da177e4SLinus Torvalds * Tegge : Arp bug fixes.
241da177e4SLinus Torvalds * Florian : Removed many unnecessary functions, code cleanup
251da177e4SLinus Torvalds * and changes for new arp and skbuff.
261da177e4SLinus Torvalds * Alan Cox : Redid header building to reflect new format.
271da177e4SLinus Torvalds * Alan Cox : ARP only when compiled with CONFIG_INET
281da177e4SLinus Torvalds * Greg Page : 802.2 and SNAP stuff.
291da177e4SLinus Torvalds * Alan Cox : MAC layer pointers/new format.
301da177e4SLinus Torvalds * Paul Gortmaker : eth_copy_and_sum shouldn't csum padding.
311da177e4SLinus Torvalds * Alan Cox : Protect against forwarding explosions with
321da177e4SLinus Torvalds * older network drivers and IFF_ALLMULTI.
331da177e4SLinus Torvalds * Christer Weinigel : Better rebuild header message.
341da177e4SLinus Torvalds * Andrew Morton : 26Feb01: kill ether_setup() - use netdev_boot_setup().
351da177e4SLinus Torvalds */
361da177e4SLinus Torvalds #include <linux/module.h>
371da177e4SLinus Torvalds #include <linux/types.h>
381da177e4SLinus Torvalds #include <linux/kernel.h>
391da177e4SLinus Torvalds #include <linux/string.h>
401da177e4SLinus Torvalds #include <linux/mm.h>
411da177e4SLinus Torvalds #include <linux/socket.h>
421da177e4SLinus Torvalds #include <linux/in.h>
431da177e4SLinus Torvalds #include <linux/inet.h>
441da177e4SLinus Torvalds #include <linux/ip.h>
451da177e4SLinus Torvalds #include <linux/netdevice.h>
460e839df9SBartosz Golaszewski #include <linux/nvmem-consumer.h>
471da177e4SLinus Torvalds #include <linux/etherdevice.h>
481da177e4SLinus Torvalds #include <linux/skbuff.h>
491da177e4SLinus Torvalds #include <linux/errno.h>
501da177e4SLinus Torvalds #include <linux/init.h>
5146f25dffSKris Katterjohn #include <linux/if_ether.h>
52c7f5d105SDavid S. Miller #include <linux/of_net.h>
53c7f5d105SDavid S. Miller #include <linux/pci.h>
54433baf07SJakub Kicinski #include <linux/property.h>
551da177e4SLinus Torvalds #include <net/dst.h>
561da177e4SLinus Torvalds #include <net/arp.h>
571da177e4SLinus Torvalds #include <net/sock.h>
581da177e4SLinus Torvalds #include <net/ipv6.h>
591da177e4SLinus Torvalds #include <net/ip.h>
60cf85d08fSLennert Buytenhek #include <net/dsa.h>
6110b89ee4SJiri Pirko #include <net/flow_dissector.h>
625588796eSAlexander Lobakin #include <net/gro.h>
63118a7b0eSAvinash Kumar #include <linux/uaccess.h>
64d0a81f67SJesper Dangaard Brouer #include <net/pkt_sched.h>
651da177e4SLinus Torvalds
66d3e01f71SStephen Hemminger /**
67d3e01f71SStephen Hemminger * eth_header - create the Ethernet header
68d3e01f71SStephen Hemminger * @skb: buffer to alter
69d3e01f71SStephen Hemminger * @dev: source device
70d3e01f71SStephen Hemminger * @type: Ethernet type field
71d3e01f71SStephen Hemminger * @daddr: destination address (NULL leave destination address)
72d3e01f71SStephen Hemminger * @saddr: source address (NULL use device source address)
73d3e01f71SStephen Hemminger * @len: packet length (<= skb->len)
741da177e4SLinus Torvalds *
75d3e01f71SStephen Hemminger *
76bf9ae538SOctavian Purdila * Set the protocol type. For a packet of type ETH_P_802_3/2 we put the length
77bf9ae538SOctavian Purdila * in here instead.
781da177e4SLinus Torvalds */
eth_header(struct sk_buff * skb,struct net_device * dev,unsigned short type,const void * daddr,const void * saddr,unsigned int len)793b04dddeSStephen Hemminger int eth_header(struct sk_buff *skb, struct net_device *dev,
803b04dddeSStephen Hemminger unsigned short type,
8195c96174SEric Dumazet const void *daddr, const void *saddr, unsigned int len)
821da177e4SLinus Torvalds {
83d58ff351SJohannes Berg struct ethhdr *eth = skb_push(skb, ETH_HLEN);
841da177e4SLinus Torvalds
85bf9ae538SOctavian Purdila if (type != ETH_P_802_3 && type != ETH_P_802_2)
861da177e4SLinus Torvalds eth->h_proto = htons(type);
871da177e4SLinus Torvalds else
881da177e4SLinus Torvalds eth->h_proto = htons(len);
891da177e4SLinus Torvalds
901da177e4SLinus Torvalds /*
911da177e4SLinus Torvalds * Set the source hardware address.
921da177e4SLinus Torvalds */
931da177e4SLinus Torvalds
94ff593c59SDenis Vlasenko if (!saddr)
95ff593c59SDenis Vlasenko saddr = dev->dev_addr;
9623f1f4efSStephen Hemminger memcpy(eth->h_source, saddr, ETH_ALEN);
971da177e4SLinus Torvalds
982e4ca75bSStephen Hemminger if (daddr) {
9923f1f4efSStephen Hemminger memcpy(eth->h_dest, daddr, ETH_ALEN);
100f8d0e3f1SJamal Hadi Salim return ETH_HLEN;
101f8d0e3f1SJamal Hadi Salim }
102f8d0e3f1SJamal Hadi Salim
1031da177e4SLinus Torvalds /*
1041da177e4SLinus Torvalds * Anyway, the loopback-device should never use this function...
1051da177e4SLinus Torvalds */
1061da177e4SLinus Torvalds
1072e4ca75bSStephen Hemminger if (dev->flags & (IFF_LOOPBACK | IFF_NOARP)) {
108afc130ddSJoe Perches eth_zero_addr(eth->h_dest);
1091da177e4SLinus Torvalds return ETH_HLEN;
1101da177e4SLinus Torvalds }
1111da177e4SLinus Torvalds
1121da177e4SLinus Torvalds return -ETH_HLEN;
1131da177e4SLinus Torvalds }
1143b04dddeSStephen Hemminger EXPORT_SYMBOL(eth_header);
1151da177e4SLinus Torvalds
116d3e01f71SStephen Hemminger /**
117ecea4991SMasanari Iida * eth_get_headlen - determine the length of header for an ethernet frame
118c43f1255SStanislav Fomichev * @dev: pointer to network device
11956193d1bSAlexander Duyck * @data: pointer to start of frame
12056193d1bSAlexander Duyck * @len: total length of frame
12156193d1bSAlexander Duyck *
12256193d1bSAlexander Duyck * Make a best effort attempt to pull the length for all of the headers for
12356193d1bSAlexander Duyck * a given frame in a linear buffer.
12456193d1bSAlexander Duyck */
eth_get_headlen(const struct net_device * dev,const void * data,u32 len)12559753ce8SAlexander Lobakin u32 eth_get_headlen(const struct net_device *dev, const void *data, u32 len)
12656193d1bSAlexander Duyck {
127d975ddd6SAlexander Duyck const unsigned int flags = FLOW_DISSECTOR_F_PARSE_1ST_FRAG;
12856193d1bSAlexander Duyck const struct ethhdr *eth = (const struct ethhdr *)data;
12972a338bcSPaolo Abeni struct flow_keys_basic keys;
13056193d1bSAlexander Duyck
13156193d1bSAlexander Duyck /* this should never happen, but better safe than sorry */
1328a4683a5SJesper Dangaard Brouer if (unlikely(len < sizeof(*eth)))
13356193d1bSAlexander Duyck return len;
13456193d1bSAlexander Duyck
13556193d1bSAlexander Duyck /* parse any remaining L2/L3 headers, check for L4 */
136c43f1255SStanislav Fomichev if (!skb_flow_dissect_flow_keys_basic(dev_net(dev), NULL, &keys, data,
1373cbf4ffbSStanislav Fomichev eth->h_proto, sizeof(*eth),
1383cbf4ffbSStanislav Fomichev len, flags))
139c3f83241STom Herbert return max_t(u32, keys.control.thoff, sizeof(*eth));
14056193d1bSAlexander Duyck
14156193d1bSAlexander Duyck /* parse for any L4 headers */
14256193d1bSAlexander Duyck return min_t(u32, __skb_get_poff(NULL, data, &keys, len), len);
14356193d1bSAlexander Duyck }
14456193d1bSAlexander Duyck EXPORT_SYMBOL(eth_get_headlen);
14556193d1bSAlexander Duyck
14656193d1bSAlexander Duyck /**
147d3e01f71SStephen Hemminger * eth_type_trans - determine the packet's protocol ID.
148d3e01f71SStephen Hemminger * @skb: received socket data
149d3e01f71SStephen Hemminger * @dev: receiving network device
150d3e01f71SStephen Hemminger *
151d3e01f71SStephen Hemminger * The rule here is that we
1521da177e4SLinus Torvalds * assume 802.3 if the type field is short enough to be a length.
1531da177e4SLinus Torvalds * This is normal practice and works for any 'now in use' protocol.
1541da177e4SLinus Torvalds */
eth_type_trans(struct sk_buff * skb,struct net_device * dev)155ab611487SAlexey Dobriyan __be16 eth_type_trans(struct sk_buff *skb, struct net_device *dev)
1561da177e4SLinus Torvalds {
1570864c158SEric Dumazet unsigned short _service_access_point;
1580864c158SEric Dumazet const unsigned short *sap;
1590864c158SEric Dumazet const struct ethhdr *eth;
1601da177e4SLinus Torvalds
1614c13eb66SArnaldo Carvalho de Melo skb->dev = dev;
162459a98edSArnaldo Carvalho de Melo skb_reset_mac_header(skb);
163610986e7SAlexander Duyck
164610986e7SAlexander Duyck eth = (struct ethhdr *)skb->data;
16547d29646SDavid S. Miller skb_pull_inline(skb, ETH_HLEN);
1661da177e4SLinus Torvalds
167ca958a1bSRahul Rameshbabu eth_skb_pkt_type(skb, dev);
1681da177e4SLinus Torvalds
169cf85d08fSLennert Buytenhek /*
170cf85d08fSLennert Buytenhek * Some variants of DSA tagging don't have an ethertype field
171cf85d08fSLennert Buytenhek * at all, so we check here whether one of those tagging
172cf85d08fSLennert Buytenhek * variants has been configured on the receiving interface,
173cf85d08fSLennert Buytenhek * and if so, set skb->protocol without looking at the packet.
174cf85d08fSLennert Buytenhek */
175edac6f63SVladimir Oltean if (unlikely(netdev_uses_dsa(dev)))
1763e8a72d1SFlorian Fainelli return htons(ETH_P_XDSA);
177cf85d08fSLennert Buytenhek
1782c7a88c2SAlexander Duyck if (likely(eth_proto_is_802_3(eth->h_proto)))
1791da177e4SLinus Torvalds return eth->h_proto;
1801da177e4SLinus Torvalds
1811da177e4SLinus Torvalds /*
1821da177e4SLinus Torvalds * This is a magic hack to spot IPX packets. Older Novell breaks
1831da177e4SLinus Torvalds * the protocol design and runs IPX over 802.3 without an 802.2 LLC
1841da177e4SLinus Torvalds * layer. We look for FFFF which isn't a used 802.2 SSAP/DSAP. This
1851da177e4SLinus Torvalds * won't work for fault tolerant netware but does for the rest.
1861da177e4SLinus Torvalds */
1870864c158SEric Dumazet sap = skb_header_pointer(skb, 0, sizeof(*sap), &_service_access_point);
1880864c158SEric Dumazet if (sap && *sap == 0xFFFF)
1891da177e4SLinus Torvalds return htons(ETH_P_802_3);
1901da177e4SLinus Torvalds
1911da177e4SLinus Torvalds /*
1921da177e4SLinus Torvalds * Real 802.2 LLC
1931da177e4SLinus Torvalds */
1941da177e4SLinus Torvalds return htons(ETH_P_802_2);
1951da177e4SLinus Torvalds }
1962e4ca75bSStephen Hemminger EXPORT_SYMBOL(eth_type_trans);
1971da177e4SLinus Torvalds
198d3e01f71SStephen Hemminger /**
199d3e01f71SStephen Hemminger * eth_header_parse - extract hardware address from packet
200d3e01f71SStephen Hemminger * @skb: packet to extract header from
201d3e01f71SStephen Hemminger * @haddr: destination buffer
202d3e01f71SStephen Hemminger */
eth_header_parse(const struct sk_buff * skb,unsigned char * haddr)2033b04dddeSStephen Hemminger int eth_header_parse(const struct sk_buff *skb, unsigned char *haddr)
2041da177e4SLinus Torvalds {
205b95cce35SStephen Hemminger const struct ethhdr *eth = eth_hdr(skb);
2061da177e4SLinus Torvalds memcpy(haddr, eth->h_source, ETH_ALEN);
2071da177e4SLinus Torvalds return ETH_ALEN;
2081da177e4SLinus Torvalds }
2093b04dddeSStephen Hemminger EXPORT_SYMBOL(eth_header_parse);
2101da177e4SLinus Torvalds
211d3e01f71SStephen Hemminger /**
212d3e01f71SStephen Hemminger * eth_header_cache - fill cache entry from neighbour
213d3e01f71SStephen Hemminger * @neigh: source neighbour
214d3e01f71SStephen Hemminger * @hh: destination cache entry
21548daec03SRandy Dunlap * @type: Ethernet type field
2162c53040fSBen Hutchings *
217d3e01f71SStephen Hemminger * Create an Ethernet header template from the neighbour.
218d3e01f71SStephen Hemminger */
eth_header_cache(const struct neighbour * neigh,struct hh_cache * hh,__be16 type)219e69dd336SDavid S. Miller int eth_header_cache(const struct neighbour *neigh, struct hh_cache *hh, __be16 type)
2201da177e4SLinus Torvalds {
2211da177e4SLinus Torvalds struct ethhdr *eth;
2223b04dddeSStephen Hemminger const struct net_device *dev = neigh->dev;
2231da177e4SLinus Torvalds
2241da177e4SLinus Torvalds eth = (struct ethhdr *)
2251da177e4SLinus Torvalds (((u8 *) hh->hh_data) + (HH_DATA_OFF(sizeof(*eth))));
2261da177e4SLinus Torvalds
227f576e24fSYOSHIFUJI Hideaki if (type == htons(ETH_P_802_3))
2281da177e4SLinus Torvalds return -1;
2291da177e4SLinus Torvalds
2301da177e4SLinus Torvalds eth->h_proto = type;
23123f1f4efSStephen Hemminger memcpy(eth->h_source, dev->dev_addr, ETH_ALEN);
23223f1f4efSStephen Hemminger memcpy(eth->h_dest, neigh->ha, ETH_ALEN);
233c305c6aeSEric Dumazet
234c305c6aeSEric Dumazet /* Pairs with READ_ONCE() in neigh_resolve_output(),
235c305c6aeSEric Dumazet * neigh_hh_output() and neigh_update_hhs().
236c305c6aeSEric Dumazet */
237c305c6aeSEric Dumazet smp_store_release(&hh->hh_len, ETH_HLEN);
238c305c6aeSEric Dumazet
2391da177e4SLinus Torvalds return 0;
2401da177e4SLinus Torvalds }
2413b04dddeSStephen Hemminger EXPORT_SYMBOL(eth_header_cache);
2421da177e4SLinus Torvalds
243d3e01f71SStephen Hemminger /**
244d3e01f71SStephen Hemminger * eth_header_cache_update - update cache entry
245d3e01f71SStephen Hemminger * @hh: destination cache entry
246d3e01f71SStephen Hemminger * @dev: network device
247d3e01f71SStephen Hemminger * @haddr: new hardware address
248d3e01f71SStephen Hemminger *
2491da177e4SLinus Torvalds * Called by Address Resolution module to notify changes in address.
2501da177e4SLinus Torvalds */
eth_header_cache_update(struct hh_cache * hh,const struct net_device * dev,const unsigned char * haddr)2513b04dddeSStephen Hemminger void eth_header_cache_update(struct hh_cache *hh,
2523b04dddeSStephen Hemminger const struct net_device *dev,
2533b04dddeSStephen Hemminger const unsigned char *haddr)
2541da177e4SLinus Torvalds {
2551da177e4SLinus Torvalds memcpy(((u8 *) hh->hh_data) + HH_DATA_OFF(sizeof(struct ethhdr)),
25623f1f4efSStephen Hemminger haddr, ETH_ALEN);
2571da177e4SLinus Torvalds }
2583b04dddeSStephen Hemminger EXPORT_SYMBOL(eth_header_cache_update);
2591da177e4SLinus Torvalds
260d3e01f71SStephen Hemminger /**
261c1639be9SMauro Carvalho Chehab * eth_header_parse_protocol - extract protocol from L2 header
262ace53b2eSMaxim Mikityanskiy * @skb: packet to extract protocol from
263ace53b2eSMaxim Mikityanskiy */
eth_header_parse_protocol(const struct sk_buff * skb)264ace53b2eSMaxim Mikityanskiy __be16 eth_header_parse_protocol(const struct sk_buff *skb)
265ace53b2eSMaxim Mikityanskiy {
266ace53b2eSMaxim Mikityanskiy const struct ethhdr *eth = eth_hdr(skb);
267ace53b2eSMaxim Mikityanskiy
268ace53b2eSMaxim Mikityanskiy return eth->h_proto;
269ace53b2eSMaxim Mikityanskiy }
270ace53b2eSMaxim Mikityanskiy EXPORT_SYMBOL(eth_header_parse_protocol);
271ace53b2eSMaxim Mikityanskiy
272ace53b2eSMaxim Mikityanskiy /**
273fa0879e3SStefan Hajnoczi * eth_prepare_mac_addr_change - prepare for mac change
274fa0879e3SStefan Hajnoczi * @dev: network device
275fa0879e3SStefan Hajnoczi * @p: socket address
276fa0879e3SStefan Hajnoczi */
eth_prepare_mac_addr_change(struct net_device * dev,void * p)277fa0879e3SStefan Hajnoczi int eth_prepare_mac_addr_change(struct net_device *dev, void *p)
278fa0879e3SStefan Hajnoczi {
279fa0879e3SStefan Hajnoczi struct sockaddr *addr = p;
280fa0879e3SStefan Hajnoczi
281fa0879e3SStefan Hajnoczi if (!(dev->priv_flags & IFF_LIVE_ADDR_CHANGE) && netif_running(dev))
282fa0879e3SStefan Hajnoczi return -EBUSY;
283fa0879e3SStefan Hajnoczi if (!is_valid_ether_addr(addr->sa_data))
284fa0879e3SStefan Hajnoczi return -EADDRNOTAVAIL;
285fa0879e3SStefan Hajnoczi return 0;
286fa0879e3SStefan Hajnoczi }
287fa0879e3SStefan Hajnoczi EXPORT_SYMBOL(eth_prepare_mac_addr_change);
288fa0879e3SStefan Hajnoczi
289fa0879e3SStefan Hajnoczi /**
290fa0879e3SStefan Hajnoczi * eth_commit_mac_addr_change - commit mac change
291fa0879e3SStefan Hajnoczi * @dev: network device
292fa0879e3SStefan Hajnoczi * @p: socket address
293fa0879e3SStefan Hajnoczi */
eth_commit_mac_addr_change(struct net_device * dev,void * p)294fa0879e3SStefan Hajnoczi void eth_commit_mac_addr_change(struct net_device *dev, void *p)
295fa0879e3SStefan Hajnoczi {
296fa0879e3SStefan Hajnoczi struct sockaddr *addr = p;
297fa0879e3SStefan Hajnoczi
298a96d317fSJakub Kicinski eth_hw_addr_set(dev, addr->sa_data);
299fa0879e3SStefan Hajnoczi }
300fa0879e3SStefan Hajnoczi EXPORT_SYMBOL(eth_commit_mac_addr_change);
301fa0879e3SStefan Hajnoczi
302fa0879e3SStefan Hajnoczi /**
303d3e01f71SStephen Hemminger * eth_mac_addr - set new Ethernet hardware address
304d3e01f71SStephen Hemminger * @dev: network device
305d3e01f71SStephen Hemminger * @p: socket address
3062c53040fSBen Hutchings *
307d3e01f71SStephen Hemminger * Change hardware address of device.
308d3e01f71SStephen Hemminger *
309d3e01f71SStephen Hemminger * This doesn't change hardware matching, so needs to be overridden
310d3e01f71SStephen Hemminger * for most real devices.
311d3e01f71SStephen Hemminger */
eth_mac_addr(struct net_device * dev,void * p)312ccad637bSStephen Hemminger int eth_mac_addr(struct net_device *dev, void *p)
3131da177e4SLinus Torvalds {
314fa0879e3SStefan Hajnoczi int ret;
31571bffe55SPatrick McHardy
316fa0879e3SStefan Hajnoczi ret = eth_prepare_mac_addr_change(dev, p);
317fa0879e3SStefan Hajnoczi if (ret < 0)
318fa0879e3SStefan Hajnoczi return ret;
319fa0879e3SStefan Hajnoczi eth_commit_mac_addr_change(dev, p);
3201da177e4SLinus Torvalds return 0;
3211da177e4SLinus Torvalds }
322ccad637bSStephen Hemminger EXPORT_SYMBOL(eth_mac_addr);
3231da177e4SLinus Torvalds
eth_validate_addr(struct net_device * dev)324ccad637bSStephen Hemminger int eth_validate_addr(struct net_device *dev)
325bada339bSJeff Garzik {
326bada339bSJeff Garzik if (!is_valid_ether_addr(dev->dev_addr))
3272ed9926eSPatrick McHardy return -EADDRNOTAVAIL;
328bada339bSJeff Garzik
329bada339bSJeff Garzik return 0;
330bada339bSJeff Garzik }
331ccad637bSStephen Hemminger EXPORT_SYMBOL(eth_validate_addr);
332bada339bSJeff Garzik
3333b04dddeSStephen Hemminger const struct header_ops eth_header_ops ____cacheline_aligned = {
3343b04dddeSStephen Hemminger .create = eth_header,
3353b04dddeSStephen Hemminger .parse = eth_header_parse,
3363b04dddeSStephen Hemminger .cache = eth_header_cache,
3373b04dddeSStephen Hemminger .cache_update = eth_header_cache_update,
338ace53b2eSMaxim Mikityanskiy .parse_protocol = eth_header_parse_protocol,
3393b04dddeSStephen Hemminger };
3403b04dddeSStephen Hemminger
341d3e01f71SStephen Hemminger /**
342d3e01f71SStephen Hemminger * ether_setup - setup Ethernet network device
343d3e01f71SStephen Hemminger * @dev: network device
3442c53040fSBen Hutchings *
345d3e01f71SStephen Hemminger * Fill in the fields of the device structure with Ethernet-generic values.
3461da177e4SLinus Torvalds */
ether_setup(struct net_device * dev)3471da177e4SLinus Torvalds void ether_setup(struct net_device *dev)
3481da177e4SLinus Torvalds {
3493b04dddeSStephen Hemminger dev->header_ops = ð_header_ops;
3501da177e4SLinus Torvalds dev->type = ARPHRD_ETHER;
3511da177e4SLinus Torvalds dev->hard_header_len = ETH_HLEN;
352217e6fa2SWillem de Bruijn dev->min_header_len = ETH_HLEN;
35346f25dffSKris Katterjohn dev->mtu = ETH_DATA_LEN;
354a52ad514SJarod Wilson dev->min_mtu = ETH_MIN_MTU;
355a52ad514SJarod Wilson dev->max_mtu = ETH_DATA_LEN;
3561da177e4SLinus Torvalds dev->addr_len = ETH_ALEN;
357d0a81f67SJesper Dangaard Brouer dev->tx_queue_len = DEFAULT_TX_QUEUE_LEN;
3581da177e4SLinus Torvalds dev->flags = IFF_BROADCAST|IFF_MULTICAST;
35931dda0aeSnhorman dev->priv_flags |= IFF_TX_SKB_SHARING;
3601da177e4SLinus Torvalds
361afc130ddSJoe Perches eth_broadcast_addr(dev->broadcast);
3621da177e4SLinus Torvalds
3631da177e4SLinus Torvalds }
3641da177e4SLinus Torvalds EXPORT_SYMBOL(ether_setup);
3651da177e4SLinus Torvalds
3661da177e4SLinus Torvalds /**
36736909ea4STom Herbert * alloc_etherdev_mqs - Allocates and sets up an Ethernet device
3681da177e4SLinus Torvalds * @sizeof_priv: Size of additional driver-private structure to be allocated
369d3e01f71SStephen Hemminger * for this Ethernet device
37036909ea4STom Herbert * @txqs: The number of TX queues this device has.
3713806b4f3SRandy Dunlap * @rxqs: The number of RX queues this device has.
3721da177e4SLinus Torvalds *
373d3e01f71SStephen Hemminger * Fill in the fields of the device structure with Ethernet-generic
3741da177e4SLinus Torvalds * values. Basically does everything except registering the device.
3751da177e4SLinus Torvalds *
3761da177e4SLinus Torvalds * Constructs a new net device, complete with a private data area of
377d3e01f71SStephen Hemminger * size (sizeof_priv). A 32-byte (not bit) alignment is enforced for
3781da177e4SLinus Torvalds * this private data area.
3791da177e4SLinus Torvalds */
3801da177e4SLinus Torvalds
alloc_etherdev_mqs(int sizeof_priv,unsigned int txqs,unsigned int rxqs)38136909ea4STom Herbert struct net_device *alloc_etherdev_mqs(int sizeof_priv, unsigned int txqs,
38236909ea4STom Herbert unsigned int rxqs)
3831da177e4SLinus Torvalds {
384e9f656b7SIan Wienand return alloc_netdev_mqs(sizeof_priv, "eth%d", NET_NAME_ENUM,
385c835a677STom Gundersen ether_setup, txqs, rxqs);
3861da177e4SLinus Torvalds }
38736909ea4STom Herbert EXPORT_SYMBOL(alloc_etherdev_mqs);
3880795af57SJoe Perches
sysfs_format_mac(char * buf,const unsigned char * addr,int len)3897ffc49a6SMichael Chan ssize_t sysfs_format_mac(char *buf, const unsigned char *addr, int len)
3907ffc49a6SMichael Chan {
39116dc16d9Sye xingchen return sysfs_emit(buf, "%*phC\n", len, addr);
3927ffc49a6SMichael Chan }
3937ffc49a6SMichael Chan EXPORT_SYMBOL(sysfs_format_mac);
3949b174d88SJesse Gross
eth_gro_receive(struct list_head * head,struct sk_buff * skb)395d4546c25SDavid Miller struct sk_buff *eth_gro_receive(struct list_head *head, struct sk_buff *skb)
3969b174d88SJesse Gross {
3979b174d88SJesse Gross const struct packet_offload *ptype;
398d4546c25SDavid Miller unsigned int hlen, off_eth;
399d4546c25SDavid Miller struct sk_buff *pp = NULL;
400d4546c25SDavid Miller struct ethhdr *eh, *eh2;
401d4546c25SDavid Miller struct sk_buff *p;
4029b174d88SJesse Gross __be16 type;
4039b174d88SJesse Gross int flush = 1;
4049b174d88SJesse Gross
4059b174d88SJesse Gross off_eth = skb_gro_offset(skb);
4069b174d88SJesse Gross hlen = off_eth + sizeof(*eh);
40735ffb665SRichard Gobert eh = skb_gro_header(skb, hlen, off_eth);
4089b174d88SJesse Gross if (unlikely(!eh))
4099b174d88SJesse Gross goto out;
4109b174d88SJesse Gross
4119b174d88SJesse Gross flush = 0;
4129b174d88SJesse Gross
413d4546c25SDavid Miller list_for_each_entry(p, head, list) {
4149b174d88SJesse Gross if (!NAPI_GRO_CB(p)->same_flow)
4159b174d88SJesse Gross continue;
4169b174d88SJesse Gross
4179b174d88SJesse Gross eh2 = (struct ethhdr *)(p->data + off_eth);
4189b174d88SJesse Gross if (compare_ether_header(eh, eh2)) {
4199b174d88SJesse Gross NAPI_GRO_CB(p)->same_flow = 0;
4209b174d88SJesse Gross continue;
4219b174d88SJesse Gross }
4229b174d88SJesse Gross }
4239b174d88SJesse Gross
4249b174d88SJesse Gross type = eh->h_proto;
4259b174d88SJesse Gross
4269b174d88SJesse Gross ptype = gro_find_receive_by_type(type);
4279b174d88SJesse Gross if (ptype == NULL) {
4289b174d88SJesse Gross flush = 1;
429fc1ca334SEric Dumazet goto out;
4309b174d88SJesse Gross }
4319b174d88SJesse Gross
4329b174d88SJesse Gross skb_gro_pull(skb, sizeof(*eh));
4339b174d88SJesse Gross skb_gro_postpull_rcsum(skb, eh, sizeof(*eh));
4345588796eSAlexander Lobakin
4355588796eSAlexander Lobakin pp = indirect_call_gro_receive_inet(ptype->callbacks.gro_receive,
4365588796eSAlexander Lobakin ipv6_gro_receive, inet_gro_receive,
4375588796eSAlexander Lobakin head, skb);
4389b174d88SJesse Gross
4399b174d88SJesse Gross out:
4405f114163SSteffen Klassert skb_gro_flush_final(skb, pp, flush);
4419b174d88SJesse Gross
4429b174d88SJesse Gross return pp;
4439b174d88SJesse Gross }
4449b174d88SJesse Gross EXPORT_SYMBOL(eth_gro_receive);
4459b174d88SJesse Gross
eth_gro_complete(struct sk_buff * skb,int nhoff)4469b174d88SJesse Gross int eth_gro_complete(struct sk_buff *skb, int nhoff)
4479b174d88SJesse Gross {
4489b174d88SJesse Gross struct ethhdr *eh = (struct ethhdr *)(skb->data + nhoff);
4499b174d88SJesse Gross __be16 type = eh->h_proto;
4509b174d88SJesse Gross struct packet_offload *ptype;
4519b174d88SJesse Gross int err = -ENOSYS;
4529b174d88SJesse Gross
4539b174d88SJesse Gross if (skb->encapsulation)
4549b174d88SJesse Gross skb_set_inner_mac_header(skb, nhoff);
4559b174d88SJesse Gross
4569b174d88SJesse Gross ptype = gro_find_complete_by_type(type);
4579b174d88SJesse Gross if (ptype != NULL)
4585588796eSAlexander Lobakin err = INDIRECT_CALL_INET(ptype->callbacks.gro_complete,
4595588796eSAlexander Lobakin ipv6_gro_complete, inet_gro_complete,
4605588796eSAlexander Lobakin skb, nhoff + sizeof(*eh));
4619b174d88SJesse Gross
4629b174d88SJesse Gross return err;
4639b174d88SJesse Gross }
4649b174d88SJesse Gross EXPORT_SYMBOL(eth_gro_complete);
4659b174d88SJesse Gross
4669b174d88SJesse Gross static struct packet_offload eth_packet_offload __read_mostly = {
4679b174d88SJesse Gross .type = cpu_to_be16(ETH_P_TEB),
468bdef7de4SDavid S. Miller .priority = 10,
4699b174d88SJesse Gross .callbacks = {
4709b174d88SJesse Gross .gro_receive = eth_gro_receive,
4719b174d88SJesse Gross .gro_complete = eth_gro_complete,
4729b174d88SJesse Gross },
4739b174d88SJesse Gross };
4749b174d88SJesse Gross
eth_offload_init(void)4759b174d88SJesse Gross static int __init eth_offload_init(void)
4769b174d88SJesse Gross {
4779b174d88SJesse Gross dev_add_offload(ð_packet_offload);
4789b174d88SJesse Gross
4799b174d88SJesse Gross return 0;
4809b174d88SJesse Gross }
4819b174d88SJesse Gross
4829b174d88SJesse Gross fs_initcall(eth_offload_init);
483c7f5d105SDavid S. Miller
arch_get_platform_mac_address(void)484c7f5d105SDavid S. Miller unsigned char * __weak arch_get_platform_mac_address(void)
485c7f5d105SDavid S. Miller {
486c7f5d105SDavid S. Miller return NULL;
487c7f5d105SDavid S. Miller }
488c7f5d105SDavid S. Miller
eth_platform_get_mac_address(struct device * dev,u8 * mac_addr)489c7f5d105SDavid S. Miller int eth_platform_get_mac_address(struct device *dev, u8 *mac_addr)
490c7f5d105SDavid S. Miller {
49183216e39SMichael Walle unsigned char *addr;
49283216e39SMichael Walle int ret;
493c7f5d105SDavid S. Miller
49483216e39SMichael Walle ret = of_get_mac_address(dev->of_node, mac_addr);
49583216e39SMichael Walle if (!ret)
49683216e39SMichael Walle return 0;
49783216e39SMichael Walle
498c7f5d105SDavid S. Miller addr = arch_get_platform_mac_address();
499c7f5d105SDavid S. Miller if (!addr)
500c7f5d105SDavid S. Miller return -ENODEV;
501c7f5d105SDavid S. Miller
502c7f5d105SDavid S. Miller ether_addr_copy(mac_addr, addr);
503db4bad07SHeiner Kallweit
504c7f5d105SDavid S. Miller return 0;
505c7f5d105SDavid S. Miller }
506c7f5d105SDavid S. Miller EXPORT_SYMBOL(eth_platform_get_mac_address);
5070e839df9SBartosz Golaszewski
5080e839df9SBartosz Golaszewski /**
509ba882580SJakub Kicinski * platform_get_ethdev_address - Set netdev's MAC address from a given device
510ba882580SJakub Kicinski * @dev: Pointer to the device
511ba882580SJakub Kicinski * @netdev: Pointer to netdev to write the address to
512ba882580SJakub Kicinski *
513ba882580SJakub Kicinski * Wrapper around eth_platform_get_mac_address() which writes the address
514ba882580SJakub Kicinski * directly to netdev->dev_addr.
515ba882580SJakub Kicinski */
platform_get_ethdev_address(struct device * dev,struct net_device * netdev)516ba882580SJakub Kicinski int platform_get_ethdev_address(struct device *dev, struct net_device *netdev)
517ba882580SJakub Kicinski {
518ba882580SJakub Kicinski u8 addr[ETH_ALEN] __aligned(2);
519ba882580SJakub Kicinski int ret;
520ba882580SJakub Kicinski
521ba882580SJakub Kicinski ret = eth_platform_get_mac_address(dev, addr);
522ba882580SJakub Kicinski if (!ret)
523ba882580SJakub Kicinski eth_hw_addr_set(netdev, addr);
524ba882580SJakub Kicinski return ret;
525ba882580SJakub Kicinski }
526ba882580SJakub Kicinski EXPORT_SYMBOL(platform_get_ethdev_address);
527ba882580SJakub Kicinski
528ba882580SJakub Kicinski /**
529c1639be9SMauro Carvalho Chehab * nvmem_get_mac_address - Obtain the MAC address from an nvmem cell named
530c1639be9SMauro Carvalho Chehab * 'mac-address' associated with given device.
5310e839df9SBartosz Golaszewski *
5320e839df9SBartosz Golaszewski * @dev: Device with which the mac-address cell is associated.
5330e839df9SBartosz Golaszewski * @addrbuf: Buffer to which the MAC address will be copied on success.
5340e839df9SBartosz Golaszewski *
5350e839df9SBartosz Golaszewski * Returns 0 on success or a negative error number on failure.
5360e839df9SBartosz Golaszewski */
nvmem_get_mac_address(struct device * dev,void * addrbuf)5370e839df9SBartosz Golaszewski int nvmem_get_mac_address(struct device *dev, void *addrbuf)
5380e839df9SBartosz Golaszewski {
5390e839df9SBartosz Golaszewski struct nvmem_cell *cell;
5400e839df9SBartosz Golaszewski const void *mac;
5410e839df9SBartosz Golaszewski size_t len;
5420e839df9SBartosz Golaszewski
5430e839df9SBartosz Golaszewski cell = nvmem_cell_get(dev, "mac-address");
5440e839df9SBartosz Golaszewski if (IS_ERR(cell))
5450e839df9SBartosz Golaszewski return PTR_ERR(cell);
5460e839df9SBartosz Golaszewski
5470e839df9SBartosz Golaszewski mac = nvmem_cell_read(cell, &len);
5480e839df9SBartosz Golaszewski nvmem_cell_put(cell);
5490e839df9SBartosz Golaszewski
5500e839df9SBartosz Golaszewski if (IS_ERR(mac))
5510e839df9SBartosz Golaszewski return PTR_ERR(mac);
5520e839df9SBartosz Golaszewski
5530e839df9SBartosz Golaszewski if (len != ETH_ALEN || !is_valid_ether_addr(mac)) {
5540e839df9SBartosz Golaszewski kfree(mac);
5550e839df9SBartosz Golaszewski return -EINVAL;
5560e839df9SBartosz Golaszewski }
5570e839df9SBartosz Golaszewski
5580e839df9SBartosz Golaszewski ether_addr_copy(addrbuf, mac);
5590e839df9SBartosz Golaszewski kfree(mac);
5600e839df9SBartosz Golaszewski
5610e839df9SBartosz Golaszewski return 0;
5620e839df9SBartosz Golaszewski }
563433baf07SJakub Kicinski
fwnode_get_mac_addr(struct fwnode_handle * fwnode,const char * name,char * addr)5648017c4d8SJakub Kicinski static int fwnode_get_mac_addr(struct fwnode_handle *fwnode,
5650a14501eSJakub Kicinski const char *name, char *addr)
566433baf07SJakub Kicinski {
5678017c4d8SJakub Kicinski int ret;
568433baf07SJakub Kicinski
5690a14501eSJakub Kicinski ret = fwnode_property_read_u8_array(fwnode, name, addr, ETH_ALEN);
5708017c4d8SJakub Kicinski if (ret)
5718017c4d8SJakub Kicinski return ret;
5728017c4d8SJakub Kicinski
5738017c4d8SJakub Kicinski if (!is_valid_ether_addr(addr))
5748017c4d8SJakub Kicinski return -EINVAL;
5758017c4d8SJakub Kicinski return 0;
576433baf07SJakub Kicinski }
577433baf07SJakub Kicinski
578433baf07SJakub Kicinski /**
579433baf07SJakub Kicinski * fwnode_get_mac_address - Get the MAC from the firmware node
580433baf07SJakub Kicinski * @fwnode: Pointer to the firmware node
581433baf07SJakub Kicinski * @addr: Address of buffer to store the MAC in
582433baf07SJakub Kicinski *
583433baf07SJakub Kicinski * Search the firmware node for the best MAC address to use. 'mac-address' is
584433baf07SJakub Kicinski * checked first, because that is supposed to contain to "most recent" MAC
585433baf07SJakub Kicinski * address. If that isn't set, then 'local-mac-address' is checked next,
586433baf07SJakub Kicinski * because that is the default address. If that isn't set, then the obsolete
587433baf07SJakub Kicinski * 'address' is checked, just in case we're using an old device tree.
588433baf07SJakub Kicinski *
589433baf07SJakub Kicinski * Note that the 'address' property is supposed to contain a virtual address of
590433baf07SJakub Kicinski * the register set, but some DTS files have redefined that property to be the
591433baf07SJakub Kicinski * MAC address.
592433baf07SJakub Kicinski *
593433baf07SJakub Kicinski * All-zero MAC addresses are rejected, because those could be properties that
594433baf07SJakub Kicinski * exist in the firmware tables, but were not updated by the firmware. For
595433baf07SJakub Kicinski * example, the DTS could define 'mac-address' and 'local-mac-address', with
596433baf07SJakub Kicinski * zero MAC addresses. Some older U-Boots only initialized 'local-mac-address'.
597433baf07SJakub Kicinski * In this case, the real MAC is in 'local-mac-address', and 'mac-address'
598433baf07SJakub Kicinski * exists but is all zeros.
599433baf07SJakub Kicinski */
fwnode_get_mac_address(struct fwnode_handle * fwnode,char * addr)6000a14501eSJakub Kicinski int fwnode_get_mac_address(struct fwnode_handle *fwnode, char *addr)
601433baf07SJakub Kicinski {
6020a14501eSJakub Kicinski if (!fwnode_get_mac_addr(fwnode, "mac-address", addr) ||
6030a14501eSJakub Kicinski !fwnode_get_mac_addr(fwnode, "local-mac-address", addr) ||
6040a14501eSJakub Kicinski !fwnode_get_mac_addr(fwnode, "address", addr))
6058017c4d8SJakub Kicinski return 0;
606433baf07SJakub Kicinski
6078017c4d8SJakub Kicinski return -ENOENT;
608433baf07SJakub Kicinski }
609433baf07SJakub Kicinski EXPORT_SYMBOL(fwnode_get_mac_address);
610433baf07SJakub Kicinski
611433baf07SJakub Kicinski /**
612433baf07SJakub Kicinski * device_get_mac_address - Get the MAC for a given device
613433baf07SJakub Kicinski * @dev: Pointer to the device
614433baf07SJakub Kicinski * @addr: Address of buffer to store the MAC in
615433baf07SJakub Kicinski */
device_get_mac_address(struct device * dev,char * addr)6160a14501eSJakub Kicinski int device_get_mac_address(struct device *dev, char *addr)
617433baf07SJakub Kicinski {
6180a14501eSJakub Kicinski return fwnode_get_mac_address(dev_fwnode(dev), addr);
619433baf07SJakub Kicinski }
620433baf07SJakub Kicinski EXPORT_SYMBOL(device_get_mac_address);
621d9eb4490SJakub Kicinski
622d9eb4490SJakub Kicinski /**
623d9eb4490SJakub Kicinski * device_get_ethdev_address - Set netdev's MAC address from a given device
624d9eb4490SJakub Kicinski * @dev: Pointer to the device
625d9eb4490SJakub Kicinski * @netdev: Pointer to netdev to write the address to
626d9eb4490SJakub Kicinski *
627d9eb4490SJakub Kicinski * Wrapper around device_get_mac_address() which writes the address
628d9eb4490SJakub Kicinski * directly to netdev->dev_addr.
629d9eb4490SJakub Kicinski */
device_get_ethdev_address(struct device * dev,struct net_device * netdev)630d9eb4490SJakub Kicinski int device_get_ethdev_address(struct device *dev, struct net_device *netdev)
631d9eb4490SJakub Kicinski {
632d9eb4490SJakub Kicinski u8 addr[ETH_ALEN];
633d9eb4490SJakub Kicinski int ret;
634d9eb4490SJakub Kicinski
635d9eb4490SJakub Kicinski ret = device_get_mac_address(dev, addr);
636d9eb4490SJakub Kicinski if (!ret)
637d9eb4490SJakub Kicinski eth_hw_addr_set(netdev, addr);
638d9eb4490SJakub Kicinski return ret;
639d9eb4490SJakub Kicinski }
640d9eb4490SJakub Kicinski EXPORT_SYMBOL(device_get_ethdev_address);
641