/*----------------------------------------------------------------------------*/ int mtcp_init_rss(mctx_t mctx, in_addr_t saddr_base, int num_addr, in_addr_t daddr, in_addr_t dport) { mtcp_manager_t mtcp; addr_pool_t ap; mtcp = GetMTCPManager(mctx); if (!mtcp) { return -1; } if (saddr_base == INADDR_ANY) { int nif_out; /* for the INADDR_ANY, find the output interface for the destination and set the saddr_base as the ip address of the output interface */ nif_out = GetOutputInterface(daddr); saddr_base = CONFIG.eths[nif_out].ip_addr; } ap = CreateAddressPoolPerCore(mctx->cpu, num_cpus, saddr_base, num_addr, daddr, dport); if (!ap) { errno = ENOMEM; return -1; } mtcp->ap = ap; return 0; }
/*----------------------------------------------------------------------------*/ uint8_t * IPOutput(struct mtcp_manager *mtcp, tcp_stream *stream, uint16_t tcplen) { struct iphdr *iph; int nif; unsigned char *haddr; if (stream->sndvar->nif_out >= 0) { nif = stream->sndvar->nif_out; } else { nif = GetOutputInterface(stream->daddr); stream->sndvar->nif_out = nif; } haddr = GetDestinationHWaddr(stream->daddr); if (!haddr) { #if 0 uint8_t *da = (uint8_t *)&stream->daddr; TRACE_INFO("[WARNING] The destination IP %u.%u.%u.%u " "is not in ARP table!\n", da[0], da[1], da[2], da[3]); #endif /* if not found in the arp table, send arp request and return NULL */ /* tcp will retry sending the packet later */ RequestARP(mtcp, stream->daddr, stream->sndvar->nif_out, mtcp->cur_ts); return NULL; } iph = (struct iphdr *)EthernetOutput(mtcp, ETH_P_IP, stream->sndvar->nif_out, haddr, tcplen + IP_HEADER_LEN); if (!iph) { return NULL; } iph->ihl = IP_HEADER_LEN >> 2; iph->version = 4; iph->tos = 0; iph->tot_len = htons(IP_HEADER_LEN + tcplen); iph->id = htons(stream->sndvar->ip_id++); iph->frag_off = htons(0x4000); // no fragmentation iph->ttl = 64; iph->protocol = IPPROTO_TCP; iph->saddr = stream->saddr; iph->daddr = stream->daddr; iph->check = 0; iph->check = ip_fast_csum(iph, iph->ihl); return (uint8_t *)(iph + 1); }
/*----------------------------------------------------------------------------*/ uint8_t * IPOutputStandalone(struct mtcp_manager *mtcp, uint16_t ip_id, uint32_t saddr, uint32_t daddr, uint16_t tcplen) { struct iphdr *iph; int nif; unsigned char * haddr; nif = GetOutputInterface(daddr); if (nif < 0) return NULL; haddr = GetDestinationHWaddr(daddr); if (!haddr) { #if 0 uint8_t *da = (uint8_t *)&daddr; TRACE_INFO("[WARNING] The destination IP %u.%u.%u.%u " "is not in ARP table!\n", da[0], da[1], da[2], da[3]); #endif RequestARP(mtcp, daddr, nif, mtcp->cur_ts); return NULL; } iph = (struct iphdr *)EthernetOutput(mtcp, ETH_P_IP, nif, haddr, tcplen + IP_HEADER_LEN); if (!iph) { return NULL; } iph->ihl = IP_HEADER_LEN >> 2; iph->version = 4; iph->tos = 0; iph->tot_len = htons(IP_HEADER_LEN + tcplen); iph->id = htons(ip_id); iph->frag_off = htons(0x4000); // no fragmentation iph->ttl = 64; iph->protocol = IPPROTO_TCP; iph->saddr = saddr; iph->daddr = daddr; iph->check = 0; iph->check = ip_fast_csum(iph, iph->ihl); return (uint8_t *)(iph + 1); }