in net.c [487:563]
static int fwnet_finish_incoming_packet(struct net_device *net,
struct sk_buff *skb, u16 source_node_id,
bool is_broadcast, u16 ether_type)
{
int status;
switch (ether_type) {
case ETH_P_ARP:
case ETH_P_IP:
#if IS_ENABLED(CONFIG_IPV6)
case ETH_P_IPV6:
#endif
break;
default:
goto err;
}
/* Write metadata, and then pass to the receive level */
skb->dev = net;
skb->ip_summed = CHECKSUM_NONE;
/*
* Parse the encapsulation header. This actually does the job of
* converting to an ethernet-like pseudo frame header.
*/
if (dev_hard_header(skb, net, ether_type,
is_broadcast ? net->broadcast : net->dev_addr,
NULL, skb->len) >= 0) {
struct fwnet_header *eth;
u16 *rawp;
__be16 protocol;
skb_reset_mac_header(skb);
skb_pull(skb, sizeof(*eth));
eth = (struct fwnet_header *)skb_mac_header(skb);
if (fwnet_hwaddr_is_multicast(eth->h_dest)) {
if (memcmp(eth->h_dest, net->broadcast,
net->addr_len) == 0)
skb->pkt_type = PACKET_BROADCAST;
#if 0
else
skb->pkt_type = PACKET_MULTICAST;
#endif
} else {
if (memcmp(eth->h_dest, net->dev_addr, net->addr_len))
skb->pkt_type = PACKET_OTHERHOST;
}
if (ntohs(eth->h_proto) >= ETH_P_802_3_MIN) {
protocol = eth->h_proto;
} else {
rawp = (u16 *)skb->data;
if (*rawp == 0xffff)
protocol = htons(ETH_P_802_3);
else
protocol = htons(ETH_P_802_2);
}
skb->protocol = protocol;
}
status = netif_rx(skb);
if (status == NET_RX_DROP) {
net->stats.rx_errors++;
net->stats.rx_dropped++;
} else {
net->stats.rx_packets++;
net->stats.rx_bytes += skb->len;
}
return 0;
err:
net->stats.rx_errors++;
net->stats.rx_dropped++;
dev_kfree_skb_any(skb);
return -ENOENT;
}