*/
#include "common.h"
+#include <linux/ethtool.h>
#include <linux/rtnetlink.h>
static void __netif_up(netif_t *netif)
return 0;
}
+static struct ethtool_ops network_ethtool_ops =
+{
+ .get_tx_csum = ethtool_op_get_tx_csum,
+ .set_tx_csum = ethtool_op_set_tx_csum,
+};
+
netif_t *alloc_netif(domid_t domid, unsigned int handle, u8 be_mac[ETH_ALEN])
{
int err = 0, i;
dev->get_stats = netif_be_get_stats;
dev->open = net_open;
dev->stop = net_close;
- dev->features = NETIF_F_NO_CSUM;
+ dev->features = NETIF_F_IP_CSUM;
+
+ SET_ETHTOOL_OPS(dev, &network_ethtool_ops);
/* Disable queuing. */
dev->tx_queue_len = 0;
/* Defer checksum calculation. */
skb->proto_csum_blank = 1;
/* Must be a local packet: assert its integrity. */
- skb->proto_csum_valid = 1;
+ skb->proto_data_valid = 1;
}
- skb->ip_summed = skb->proto_csum_valid ?
+ skb->ip_summed = skb->proto_data_valid ?
CHECKSUM_UNNECESSARY : CHECKSUM_NONE;
skb->pkt_type = PACKET_HOST; /* overridden by eth_type_trans() */
return &np->stats;
}
+static struct ethtool_ops network_ethtool_ops =
+{
+ .get_tx_csum = ethtool_op_get_tx_csum,
+ .set_tx_csum = ethtool_op_set_tx_csum,
+};
+
static void loopback_construct(struct net_device *dev, struct net_device *lo)
{
struct net_private *np = netdev_priv(dev);
dev->tx_queue_len = 0;
- dev->features = NETIF_F_HIGHDMA | NETIF_F_LLTX;
+ dev->features = (NETIF_F_HIGHDMA |
+ NETIF_F_LLTX |
+ NETIF_F_IP_CSUM);
+
+ SET_ETHTOOL_OPS(dev, &network_ethtool_ops);
/*
* We do not set a jumbo MTU on the interface. Otherwise the network
/*dev->mtu = 16*1024;*/
}
-static struct ethtool_ops network_ethtool_ops =
-{
- .get_tx_csum = ethtool_op_get_tx_csum,
- .set_tx_csum = ethtool_op_set_tx_csum,
-};
-
static int __init make_loopback(int i)
{
struct net_device *dev1, *dev2;
loopback_construct(dev1, dev2);
loopback_construct(dev2, dev1);
- dev1->features |= NETIF_F_NO_CSUM;
- dev2->features |= NETIF_F_IP_CSUM;
-
- SET_ETHTOOL_OPS(dev2, &network_ethtool_ops);
-
/*
* Initialise a dummy MAC address for the 'dummy backend' interface. We
* choose the numerically largest non-broadcast address to prevent the
skb->len + hlen);
BUG_ON(ret);
nskb->dev = skb->dev;
- nskb->proto_csum_valid = skb->proto_csum_valid;
+ nskb->proto_data_valid = skb->proto_data_valid;
dev_kfree_skb(skb);
skb = nskb;
}
{
netif_t *netif = NULL;
s8 status;
- u16 size, id, irq;
+ u16 size, id, irq, flags;
multicall_entry_t *mcl;
mmu_update_t *mmu;
gnttab_transfer_t *gop;
}
irq = netif->irq;
id = RING_GET_REQUEST(&netif->rx, netif->rx.rsp_prod_pvt)->id;
+ flags = 0;
+ if (skb->ip_summed == CHECKSUM_HW)
+ flags |= NETRXF_csum_blank;
+ if (skb->proto_data_valid)
+ flags |= NETRXF_data_validated;
if (make_rx_response(netif, id, status,
(unsigned long)skb->data & ~PAGE_MASK,
- size, skb->proto_csum_valid ?
- NETRXF_data_validated : 0) &&
+ size, flags) &&
(rx_notify[irq] == 0)) {
rx_notify[irq] = 1;
notify_list[notify_nr++] = irq;
skb->dev = netif->dev;
skb->protocol = eth_type_trans(skb, skb->dev);
- /*
- * No checking needed on localhost, but remember the field is
- * blank.
- */
- skb->ip_summed = CHECKSUM_UNNECESSARY;
- skb->proto_csum_valid = 1;
+ if (txreq.flags & NETTXF_data_validated) {
+ skb->ip_summed = CHECKSUM_UNNECESSARY;
+ skb->proto_data_valid = 1;
+ } else {
+ skb->ip_summed = CHECKSUM_NONE;
+ skb->proto_data_valid = 0;
+ }
skb->proto_csum_blank = !!(txreq.flags & NETTXF_csum_blank);
netif->stats.rx_bytes += txreq.size;
tx->gref = np->grant_tx_ref[id] = ref;
tx->offset = (unsigned long)skb->data & ~PAGE_MASK;
tx->size = skb->len;
- tx->flags = (skb->ip_summed == CHECKSUM_HW) ? NETTXF_csum_blank : 0;
+
+ tx->flags = 0;
+ if (skb->ip_summed == CHECKSUM_HW)
+ tx->flags |= NETTXF_csum_blank;
+ if (skb->proto_data_valid)
+ tx->flags |= NETTXF_data_validated;
np->tx.req_prod_pvt = i + 1;
RING_PUSH_REQUESTS_AND_CHECK_NOTIFY(&np->tx, notify);
skb->len = rx->status;
skb->tail = skb->data + skb->len;
- if (rx->flags & NETRXF_data_validated)
+ if (rx->flags & NETRXF_data_validated) {
skb->ip_summed = CHECKSUM_UNNECESSARY;
+ skb->proto_data_valid = 1;
+ } else {
+ skb->ip_summed = CHECKSUM_NONE;
+ skb->proto_data_valid = 0;
+ }
+ skb->proto_csum_blank = !!(rx->flags & NETRXF_csum_blank);
np->stats.rx_packets++;
np->stats.rx_bytes += rx->status;
* @local_df: allow local fragmentation
* @cloned: Head may be cloned (check refcnt to be sure)
* @nohdr: Payload reference only, must not modify header
- * @proto_csum_valid: Protocol csum validated since arriving at localhost
+ * @proto_data_valid: Protocol data validated since arriving at localhost
* @proto_csum_blank: Protocol csum must be added before leaving localhost
* @pkt_type: Packet class
* @fclone: skbuff clone status
ipvs_property:1;
#else
ipvs_property:1,
- proto_csum_valid:1,
+ proto_data_valid:1,
proto_csum_blank:1;
#endif
__be16 protocol;
#ifdef CONFIG_XEN
switch (skb->ip_summed) {
case CHECKSUM_UNNECESSARY:
- skb->proto_csum_valid = 1;
+ skb->proto_data_valid = 1;
break;
case CHECKSUM_HW:
/* XXX Implement me. */
default:
- skb->proto_csum_valid = 0;
+ skb->proto_data_valid = 0;
break;
}
#endif
n->cloned = 1;
n->nohdr = 0;
#ifdef CONFIG_XEN
- C(proto_csum_valid);
+ C(proto_data_valid);
C(proto_csum_blank);
#endif
C(pkt_type);