summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPin-Yen Lin <treapking@google.com>2018-08-13 14:23:24 +0800
committerEarl Ou <shunhsingou@google.com>2018-09-07 09:30:30 +0000
commit606b1b46f5ff382b0d9f35d515f137071785aeab (patch)
treedaf0e643cfdc09a283413a4ac4c68d33c86c3eb8
parent743a1b5cdd8e607f2e1bb5ad182047c512eae3f8 (diff)
downloadgem5-606b1b46f5ff382b0d9f35d515f137071785aeab.tar.xz
net: Fix a bug when handling IPv6 packets
When gem5 runs with the networking support, it will run into an assertion fail and aborted. This is because it tries to calculate checksum for IPv6 packet and this makes the IpPtr pointer ``ip'' become NULL. For that there is functions and classes for IPv6 in base/inet.cc, I added IPv6 support for i8254xGBe.cc. Because IPv6 header does not have identification number, I ignored some of the debug messages using ip->id(). Change-Id: Ida5e36aefd2c5c26053f8152a0aac24191e7757c Reviewed-on: https://gem5-review.googlesource.com/12339 Reviewed-by: Earl Ou <shunhsingou@google.com> Reviewed-by: Jason Lowe-Power <jason@lowepower.com> Maintainer: Gabe Black <gabeblack@google.com>
-rw-r--r--src/dev/net/i8254xGBe.cc63
1 files changed, 36 insertions, 27 deletions
diff --git a/src/dev/net/i8254xGBe.cc b/src/dev/net/i8254xGBe.cc
index 3359b0d61..88528c4b7 100644
--- a/src/dev/net/i8254xGBe.cc
+++ b/src/dev/net/i8254xGBe.cc
@@ -1373,13 +1373,19 @@ IGbE::RxDescCache::pktComplete()
status |= RXDS_EOP;
IpPtr ip(pktPtr);
+ Ip6Ptr ip6(pktPtr);
- if (ip) {
- DPRINTF(EthernetDesc, "Proccesing Ip packet with Id=%d\n", ip->id());
- ptype |= RXDP_IPV4;
- ip_id = ip->id();
+ if (ip || ip6) {
+ if (ip) {
+ DPRINTF(EthernetDesc, "Proccesing Ip packet with Id=%d\n",
+ ip->id());
+ ptype |= RXDP_IPV4;
+ ip_id = ip->id();
+ }
+ if (ip6)
+ ptype |= RXDP_IPV6;
- if (igbe->regs.rxcsum.ipofld()) {
+ if (ip && igbe->regs.rxcsum.ipofld()) {
DPRINTF(EthernetDesc, "Checking IP checksum\n");
status |= RXDS_IPCS;
csum = htole(cksum(ip));
@@ -1390,7 +1396,7 @@ IGbE::RxDescCache::pktComplete()
DPRINTF(EthernetDesc, "Checksum is bad!!\n");
}
}
- TcpPtr tcp(ip);
+ TcpPtr tcp = ip ? TcpPtr(ip) : TcpPtr(ip6);
if (tcp && igbe->regs.rxcsum.tuofld()) {
DPRINTF(EthernetDesc, "Checking TCP checksum\n");
status |= RXDS_TCPCS;
@@ -1404,7 +1410,7 @@ IGbE::RxDescCache::pktComplete()
}
}
- UdpPtr udp(ip);
+ UdpPtr udp = ip ? UdpPtr(ip) : UdpPtr(ip6);
if (udp && igbe->regs.rxcsum.tuofld()) {
DPRINTF(EthernetDesc, "Checking UDP checksum\n");
status |= RXDS_UDPCS;
@@ -1838,26 +1844,28 @@ IGbE::TxDescCache::pktComplete()
if (useTso) {
IpPtr ip(pktPtr);
+ Ip6Ptr ip6(pktPtr);
if (ip) {
DPRINTF(EthernetDesc, "TSO: Modifying IP header. Id + %d\n",
tsoPkts);
ip->id(ip->id() + tsoPkts++);
ip->len(pktPtr->length - EthPtr(pktPtr)->size());
-
- TcpPtr tcp(ip);
- if (tcp) {
- DPRINTF(EthernetDesc,
- "TSO: Modifying TCP header. old seq %d + %d\n",
- tcp->seq(), tsoPrevSeq);
- tcp->seq(tcp->seq() + tsoPrevSeq);
- if (tsoUsedLen != tsoTotalLen)
- tcp->flags(tcp->flags() & ~9); // clear fin & psh
- }
- UdpPtr udp(ip);
- if (udp) {
- DPRINTF(EthernetDesc, "TSO: Modifying UDP header.\n");
- udp->len(pktPtr->length - EthPtr(pktPtr)->size());
- }
+ }
+ if (ip6)
+ ip6->plen(pktPtr->length - EthPtr(pktPtr)->size());
+ TcpPtr tcp = ip ? TcpPtr(ip) : TcpPtr(ip6);
+ if (tcp) {
+ DPRINTF(EthernetDesc,
+ "TSO: Modifying TCP header. old seq %d + %d\n",
+ tcp->seq(), tsoPrevSeq);
+ tcp->seq(tcp->seq() + tsoPrevSeq);
+ if (tsoUsedLen != tsoTotalLen)
+ tcp->flags(tcp->flags() & ~9); // clear fin & psh
+ }
+ UdpPtr udp = ip ? UdpPtr(ip) : UdpPtr(ip6);
+ if (udp) {
+ DPRINTF(EthernetDesc, "TSO: Modifying UDP header.\n");
+ udp->len(pktPtr->length - EthPtr(pktPtr)->size());
}
tsoPrevSeq = tsoUsedLen;
}
@@ -1872,19 +1880,20 @@ IGbE::TxDescCache::pktComplete()
}
// Checksums are only ofloaded for new descriptor types
- if (TxdOp::isData(desc) && ( TxdOp::ixsm(desc) || TxdOp::txsm(desc)) ) {
+ if (TxdOp::isData(desc) && (TxdOp::ixsm(desc) || TxdOp::txsm(desc))) {
DPRINTF(EthernetDesc, "Calculating checksums for packet\n");
IpPtr ip(pktPtr);
- assert(ip);
- if (TxdOp::ixsm(desc)) {
+ Ip6Ptr ip6(pktPtr);
+ assert(ip || ip6);
+ if (ip && TxdOp::ixsm(desc)) {
ip->sum(0);
ip->sum(cksum(ip));
igbe->txIpChecksums++;
DPRINTF(EthernetDesc, "Calculated IP checksum\n");
}
if (TxdOp::txsm(desc)) {
- TcpPtr tcp(ip);
- UdpPtr udp(ip);
+ TcpPtr tcp = ip ? TcpPtr(ip) : TcpPtr(ip6);
+ UdpPtr udp = ip ? UdpPtr(ip) : UdpPtr(ip6);
if (tcp) {
tcp->sum(0);
tcp->sum(cksum(tcp));