Commit c78c3ecc authored by Hejing Li's avatar Hejing Li
Browse files

net_switch: change debug print format for mac address

parent 3eb4098d
...@@ -36,17 +36,29 @@ ...@@ -36,17 +36,29 @@
#include <iostream> #include <iostream>
#include <vector> #include <vector>
#include <arpa/inet.h>
#include<netinet/udp.h>
#include <linux/ip.h>
#include <linux/if_ether.h>
#include <simbricks/base/cxxatomicfix.h> #include <simbricks/base/cxxatomicfix.h>
extern "C" { extern "C" {
#include <simbricks/mem/if.h> #include <simbricks/mem/if.h>
#include <simbricks/nicif/nicif.h> #include <simbricks/nicif/nicif.h>
#include <simbricks/base/proto.h> #include <simbricks/mem/memop.h>
}; };
#define MEMNIC_DEBUG 1
static int exiting = 0; static int exiting = 0;
static uint64_t cur_ts = 0; static uint64_t cur_ts = 0;
uint16_t src_port = 1;
uint16_t dest_port = 1;
uint32_t ip_addr = 0x0F0E0D0C;
uint64_t mac_addr = 0;
static void sigint_handler(int dummy) { static void sigint_handler(int dummy) {
exiting = 1; exiting = 1;
...@@ -56,44 +68,81 @@ static void sigusr1_handler(int dummy) { ...@@ -56,44 +68,81 @@ static void sigusr1_handler(int dummy) {
fprintf(stderr, "main_time = %lu\n", cur_ts); fprintf(stderr, "main_time = %lu\n", cur_ts);
} }
bool MemifInit(struct SimbricksMemIf *memif, const char *shm_path, bool MemNicIfInit(struct SimbricksMemIf *memif, struct SimbricksNetIf *netif,
struct SimbricksBaseIfParams *memParams) { const char *shm_path,
struct SimbricksBaseIfParams *memParams,
struct SimbricksBaseIfParams *netParams) {
struct SimbricksBaseIf *membase = &memif->base; struct SimbricksBaseIf *membase = &memif->base;
struct SimbricksBaseIf *netbase = &netif->base;
// first allocate pool
size_t shm_size = 0;
if (memParams){
shm_size += memParams->in_num_entries * memParams->in_entries_size;
shm_size += memParams->out_num_entries * memParams->out_entries_size;
}
if (netParams){
shm_size += netParams->in_num_entries * netParams->in_entries_size;
shm_size += netParams->out_num_entries * netParams->out_entries_size;
}
std::string shm_path_ = shm_path;
struct SimbricksBaseIfSHMPool pool_; struct SimbricksBaseIfSHMPool pool_;
memset(&pool_, 0, sizeof(pool_)); memset(&pool_, 0, sizeof(pool_));
struct SimBricksBaseIfEstablishData ests[1]; if (SimbricksBaseIfSHMPoolCreate(&pool_, shm_path_.c_str(), shm_size) !=
struct SimbricksProtoMemHostIntro intro; 0) {
perror("MemNicIfInit: SimbricksBaseIfSHMPoolCreate failed");
return false;
}
struct SimBricksBaseIfEstablishData ests[2];
struct SimbricksProtoMemHostIntro mem_intro;
struct SimbricksProtoNetIntro net_intro;
unsigned n_bifs = 0; unsigned n_bifs = 0;
memset(&intro, 0, sizeof(intro)); memset(&net_intro, 0, sizeof(net_intro));
ests[n_bifs].base_if = membase;
ests[n_bifs].tx_intro = &intro; // MemIf Init
ests[n_bifs].tx_intro_len = sizeof(intro);
ests[n_bifs].rx_intro = &intro;
ests[n_bifs].rx_intro_len = sizeof(intro);
n_bifs++;
if (SimbricksBaseIfInit(membase, memParams)) { if (SimbricksBaseIfInit(membase, memParams)) {
perror("Init: SimbricksBaseIfInit failed"); perror("MemIfInit: SimbricksBaseIfInit failed");
} }
std::string shm_path_ = shm_path; if (SimbricksBaseIfListen(membase, &pool_) != 0) {
perror("MemifInit: SimbricksBaseIfListen failed");
if (SimbricksBaseIfSHMPoolCreate(
&pool_, shm_path_.c_str(),
SimbricksBaseIfSHMSize(&membase->params)) != 0) {
perror("MemifInit: SimbricksBaseIfSHMPoolCreate failed");
return false; return false;
} }
if (SimbricksBaseIfListen(membase, &pool_) != 0) { memset(&mem_intro, 0, sizeof(mem_intro));
perror("MemifInit: SimbricksBaseIfListen failed"); ests[n_bifs].base_if = membase;
ests[n_bifs].tx_intro = &mem_intro;
ests[n_bifs].tx_intro_len = sizeof(mem_intro);
ests[n_bifs].rx_intro = &mem_intro;
ests[n_bifs].rx_intro_len = sizeof(mem_intro);
n_bifs++;
// NetIf Init
if (SimbricksBaseIfInit(netbase, netParams)) {
perror("NetIfInit: SimbricksBaseIfInit failed");
}
if (SimbricksBaseIfListen(netbase, &pool_) != 0) {
perror("NetIfInit: SimbricksBaseIfListen failed");
return false; return false;
} }
if (SimBricksBaseIfEstablish(ests, 1)) { memset(&net_intro, 0, sizeof(net_intro));
ests[n_bifs].base_if = netbase;
ests[n_bifs].tx_intro = &net_intro;
ests[n_bifs].tx_intro_len = sizeof(net_intro);
ests[n_bifs].rx_intro = &net_intro;
ests[n_bifs].rx_intro_len = sizeof(net_intro);
n_bifs++;
if (SimBricksBaseIfEstablish(ests, 2)) {
fprintf(stderr, "SimBricksBaseIfEstablish failed\n"); fprintf(stderr, "SimBricksBaseIfEstablish failed\n");
return false; return false;
} }
...@@ -102,36 +151,120 @@ bool MemifInit(struct SimbricksMemIf *memif, const char *shm_path, ...@@ -102,36 +151,120 @@ bool MemifInit(struct SimbricksMemIf *memif, const char *shm_path,
return true; return true;
} }
void EthSend(SimbricksNetIf *netif, volatile union SimbricksProtoMemH2M *data, size_t len) { static inline int SimbricksMemNicIfSync(struct SimbricksMemIf *memif,
struct SimbricksNetIf *netif,
uint64_t cur_ts) {
return ((SimbricksMemIfM2HOutSync(memif, cur_ts) == 0 &&
SimbricksNetIfOutSync(netif, cur_ts) == 0)
? 0
: -1);
}
static inline uint64_t SimbricksMemNicIfNextTimestamp(
struct SimbricksMemIf *memif, struct SimbricksNetIf *netif) {
uint64_t net_in = SimbricksNetIfInTimestamp(netif);
uint64_t mem_in = SimbricksMemIfH2MInTimestamp(memif);
return (net_in < mem_in ? net_in : mem_in);
}
void ForwardToETH(SimbricksNetIf *netif, volatile union SimbricksProtoMemH2M *data, uint8_t type) {
volatile union SimbricksProtoNetMsg *msg = SimbricksNetIfOutAlloc(netif, cur_ts); volatile union SimbricksProtoNetMsg *msg = SimbricksNetIfOutAlloc(netif, cur_ts);
if (msg == NULL) if (msg == NULL)
return; return;
volatile struct SimbricksProtoNetMsgPacket *packet = &msg->packet; volatile struct SimbricksProtoNetMsgPacket *packet = &msg->packet;
packet->port = 0;
packet->len = len; // Add Ethernet header
memcpy((void *)packet->data, (void *)data, len); struct ethhdr *eth_hdr = (struct ethhdr *)packet->data;
uint64_t dest_mac = 0xFFFFFFFF;
memcpy(eth_hdr->h_source, &mac_addr, sizeof(uint64_t));
memcpy(eth_hdr->h_dest, &dest_mac, sizeof(uint64_t)); // Keep destination to broadcast for now
eth_hdr->h_proto = htons(ETH_P_IP);
// Add IP header
struct iphdr *ip_hdr = (struct iphdr *)(eth_hdr + 1);
ip_hdr->daddr = 0xFFFFFFFF;
ip_hdr->saddr = ip_addr;
ip_hdr->tot_len = sizeof(struct iphdr) + sizeof(struct udphdr) + sizeof(struct MemOp);
if (type == SIMBRICKS_PROTO_MEM_H2M_MSG_WRITE){
ip_hdr->tot_len += data->write.len;
}
// Add UDP header
struct udphdr *udp_hdr = (struct udphdr *)(ip_hdr + 1);
udp_hdr->uh_sport = src_port;
udp_hdr->uh_dport = dest_port;
udp_hdr->uh_ulen = sizeof(struct udphdr) + sizeof(struct MemOp);
if (type == SIMBRICKS_PROTO_MEM_H2M_MSG_WRITE){
udp_hdr->uh_ulen += data->write.len;
}
udp_hdr->uh_sum = 0; // To update later
// Fill the MemOps struct in the payload
struct MemOp *memop = (struct MemOp *)(udp_hdr + 1);
void *payload;
switch (type) {
case SIMBRICKS_PROTO_MEM_H2M_MSG_READ:
memop->OpType = type;
memop->req_id = data->read.req_id;
memop->as_id = data->read.as_id;
memop->addr = data->read.addr;
memop->len = data->read.len;
break;
case SIMBRICKS_PROTO_MEM_H2M_MSG_WRITE:
memop->OpType = type;
memop->req_id = data->write.req_id;
memop->as_id = data->write.as_id;
memop->addr = data->write.addr;
memop->len = data->write.len;
payload = (void *)(memop + 1);
memcpy((void *)payload, (void *)data->write.data, data->write.len);
break;
default:
fprintf(stderr, "ForwardToETH: unsupported type=%u\n", type);
}
SimbricksNetIfOutSend(netif, msg, SIMBRICKS_PROTO_NET_MSG_PACKET); SimbricksNetIfOutSend(netif, msg, SIMBRICKS_PROTO_NET_MSG_PACKET);
} }
void EthRx(SimbricksMemIf *memif, volatile struct SimbricksProtoNetMsgPacket *packet) {
uint8_t type; void ForwardToMEM(SimbricksMemIf *memif, volatile struct SimbricksProtoNetMsgPacket *packet) {
volatile union SimbricksProtoMemM2H *msg = SimbricksMemIfM2HOutAlloc(memif, cur_ts); volatile union SimbricksProtoMemM2H *msg = SimbricksMemIfM2HOutAlloc(memif, cur_ts);
if (msg == NULL) if (msg == NULL)
return; return;
volatile struct SimbricksProtoMemM2HReadcomp *rc;
volatile struct SimbricksProtoMemM2HWritecomp *wc;
type = SimbricksMemIfM2HInType(memif, msg);
uint8_t type;
struct ethhdr *eth_hdr = (struct ethhdr *)packet->data;
struct iphdr *ip_hdr = (struct iphdr *)(eth_hdr + 1);
struct udphdr *udp_hdr = (struct udphdr *)(ip_hdr + 1);
struct MemOp *memop = (struct MemOp *)(udp_hdr + 1);
void *data = (void *)(memop + 1);
type = memop->OpType;
switch (type){ switch (type){
case SIMBRICKS_PROTO_MEM_M2H_MSG_READCOMP: case SIMBRICKS_PROTO_MEM_M2H_MSG_READCOMP:
volatile struct SimbricksProtoMemM2HReadcomp *rc;
rc = &msg->readcomp; rc = &msg->readcomp;
memcpy((void*)msg, (void*)packet->data, packet->len); rc->req_id = memop->req_id;
memcpy((void*)rc->data, (void*)data, memop->len);
SimbricksMemIfM2HOutSend(memif, msg, SIMBRICKS_PROTO_MEM_M2H_MSG_READCOMP); SimbricksMemIfM2HOutSend(memif, msg, SIMBRICKS_PROTO_MEM_M2H_MSG_READCOMP);
break; break;
case SIMBRICKS_PROTO_MEM_M2H_MSG_WRITECOMP: case SIMBRICKS_PROTO_MEM_M2H_MSG_WRITECOMP:
volatile struct SimbricksProtoMemM2HWritecomp *wc;
wc = &msg->writecomp; wc = &msg->writecomp;
memcpy((void*)msg, (void *)packet->data, packet->len); wc->req_id = memop->req_id;
SimbricksMemIfM2HOutSend(memif, msg, SIMBRICKS_PROTO_MEM_M2H_MSG_WRITECOMP); SimbricksMemIfM2HOutSend(memif, msg, SIMBRICKS_PROTO_MEM_M2H_MSG_WRITECOMP);
break; break;
...@@ -144,7 +277,7 @@ void EthRx(SimbricksMemIf *memif, volatile struct SimbricksProtoNetMsgPacket *pa ...@@ -144,7 +277,7 @@ void EthRx(SimbricksMemIf *memif, volatile struct SimbricksProtoNetMsgPacket *pa
} }
void PollM2H(struct SimbricksMemIf *memif, SimbricksNetIf *netif, uint64_t cur_ts) { void PollN2M(SimbricksNetIf *netif, struct SimbricksMemIf *memif, uint64_t cur_ts) {
volatile union SimbricksProtoNetMsg *msg = SimbricksNetIfInPoll(netif, cur_ts); volatile union SimbricksProtoNetMsg *msg = SimbricksNetIfInPoll(netif, cur_ts);
if (msg == NULL){ if (msg == NULL){
return; return;
...@@ -154,14 +287,14 @@ void PollM2H(struct SimbricksMemIf *memif, SimbricksNetIf *netif, uint64_t cur_t ...@@ -154,14 +287,14 @@ void PollM2H(struct SimbricksMemIf *memif, SimbricksNetIf *netif, uint64_t cur_t
type = SimbricksNetIfInType(netif, msg); type = SimbricksNetIfInType(netif, msg);
switch (type) { switch (type) {
case SIMBRICKS_PROTO_NET_MSG_PACKET: case SIMBRICKS_PROTO_NET_MSG_PACKET:
EthRx(memif, &msg->packet); ForwardToMEM(memif, &msg->packet);
break; break;
case SIMBRICKS_PROTO_MSG_TYPE_SYNC: case SIMBRICKS_PROTO_MSG_TYPE_SYNC:
break; break;
default: default:
fprintf(stderr, "poll_m2h: unsupported type=%u\n", type); fprintf(stderr, "poll_n2m: unsupported type=%u\n", type);
} }
SimbricksNetIfInDone(netif, msg); SimbricksNetIfInDone(netif, msg);
...@@ -170,7 +303,7 @@ void PollM2H(struct SimbricksMemIf *memif, SimbricksNetIf *netif, uint64_t cur_t ...@@ -170,7 +303,7 @@ void PollM2H(struct SimbricksMemIf *memif, SimbricksNetIf *netif, uint64_t cur_t
void PollH2M(struct SimbricksMemIf *memif, SimbricksNetIf *netif, uint64_t cur_ts) { void PollH2M(struct SimbricksMemIf *memif, SimbricksNetIf *netif, uint64_t cur_ts) {
volatile union SimbricksProtoMemH2M *msg = SimbricksMemIfH2MInPoll(memif, cur_ts); volatile union SimbricksProtoMemH2M *msg = SimbricksMemIfH2MInPoll(memif, cur_ts);
if (msg == NULL){ if (msg == NULL) {
return; return;
} }
uint8_t type; uint8_t type;
...@@ -179,11 +312,11 @@ void PollH2M(struct SimbricksMemIf *memif, SimbricksNetIf *netif, uint64_t cur_t ...@@ -179,11 +312,11 @@ void PollH2M(struct SimbricksMemIf *memif, SimbricksNetIf *netif, uint64_t cur_t
switch (type) { switch (type) {
case SIMBRICKS_PROTO_MEM_H2M_MSG_READ: case SIMBRICKS_PROTO_MEM_H2M_MSG_READ:
EthSend(netif, msg, sizeof(SimbricksProtoMemH2M)); ForwardToETH(netif, msg, type);
break; break;
case SIMBRICKS_PROTO_MEM_H2M_MSG_WRITE: case SIMBRICKS_PROTO_MEM_H2M_MSG_WRITE:
EthSend(netif, msg, sizeof(SimbricksProtoMemH2M)); ForwardToETH(netif, msg, type);
break; break;
case SIMBRICKS_PROTO_MSG_TYPE_SYNC: case SIMBRICKS_PROTO_MSG_TYPE_SYNC:
break; break;
...@@ -200,54 +333,56 @@ int main(int argc, char *argv[]) { ...@@ -200,54 +333,56 @@ int main(int argc, char *argv[]) {
signal(SIGUSR1, sigusr1_handler); signal(SIGUSR1, sigusr1_handler);
int sync_mem = 1, sync_net = 1; int sync_mem = 1, sync_net = 1;
uint64_t ts_a = 0;
uint64_t ts_b = 0; uint64_t ts_mem = 0;
uint64_t ts_net = 0;
const char *shmPath; const char *shmPath;
struct SimbricksBaseIfParams memParams; struct SimbricksBaseIfParams memParams;
struct SimbricksBaseIfParams netParams; struct SimbricksBaseIfParams netParams;
struct SimbricksMemIf memif; struct SimbricksMemIf memif;
struct SimbricksNicIf netif; struct SimbricksNetIf netif;
SimbricksMemIfDefaultParams(&memParams); SimbricksMemIfDefaultParams(&memParams);
SimbricksNetIfDefaultParams(&netParams); SimbricksNetIfDefaultParams(&netParams);
printf("sizeof(struct SimbricksProtoMemH2MWrite): %lu\n",
sizeof(struct SimbricksProtoMemH2MWrite));
if (argc < 4 || argc > 10) { if (argc < 4 || argc > 10) {
fprintf(stderr, fprintf(stderr,
"Usage: memnic MEM-SOCKET NET-SOCKET" "Usage: memnic MEM-SOCKET NET-SOCKET"
"SHM [SYNC-MODE] [START-TICK] [SYNC-PERIOD] [MEM-LATENCY]" "SHM [MAC-ADDR] [SYNC-MODE] [START-TICK] [SYNC-PERIOD] [MEM-LATENCY]"
"[ETH-LATENCY]\n"); "[ETH-LATENCY]\n");
return -1; return -1;
} }
if (argc >= 6)
cur_ts = strtoull(argv[5], NULL, 0);
if (argc >= 7) if (argc >= 7)
memParams.sync_interval = netParams.sync_interval = cur_ts = strtoull(argv[6], NULL, 0);
strtoull(argv[6], NULL, 0) * 1000ULL;
if (argc >= 8) if (argc >= 8)
memParams.link_latency = strtoull(argv[7], NULL, 0) * 1000ULL; memParams.sync_interval = netParams.sync_interval =
strtoull(argv[7], NULL, 0) * 1000ULL;
if (argc >= 9) if (argc >= 9)
netParams.link_latency = strtoull(argv[8], NULL, 0) * 1000ULL; memParams.link_latency = strtoull(argv[8], NULL, 0) * 1000ULL;
if (argc >= 10)
netParams.link_latency = strtoull(argv[9], NULL, 0) * 1000ULL;
memParams.sock_path = argv[1]; memParams.sock_path = argv[1];
netParams.sock_path = argv[2]; netParams.sock_path = argv[2];
shmPath = argv[3]; shmPath = argv[3];
mac_addr = strtoull(argv[4], NULL, 16);
memParams.sync_mode = kSimbricksBaseIfSyncOptional; memParams.sync_mode = kSimbricksBaseIfSyncOptional;
netParams.sync_mode = kSimbricksBaseIfSyncOptional; netParams.sync_mode = kSimbricksBaseIfSyncOptional;
memParams.blocking_conn = false; memParams.blocking_conn = false;
memif.base.sync = sync_mem; memif.base.sync = sync_mem;
netif.net.base.sync = sync_net; netif.base.sync = sync_net;
if(SimbricksNicIfInit(&netif, shmPath, &netParams, NULL, NULL)){
fprintf(stderr, "nicif init error happens");
return -1;
}
if (!MemifInit(&memif, shmPath, &memParams)){ if (!MemNicIfInit(&memif, &netif, shmPath, &memParams, &netParams)){
fprintf(stderr, "memif init error happens"); fprintf(stderr, "MemNicIf init error happens");
return -1; return -1;
} }
...@@ -255,28 +390,30 @@ int main(int argc, char *argv[]) { ...@@ -255,28 +390,30 @@ int main(int argc, char *argv[]) {
fprintf(stderr, "start polling\n"); fprintf(stderr, "start polling\n");
while (!exiting){ while (!exiting){
while (SimbricksMemIfM2HOutSync(&memif, cur_ts)) { while (SimbricksMemNicIfSync(&memif, &netif, cur_ts)) {
fprintf(stderr, "warn: SimbricksMemnetifSync failed (memif=%lu)\n", cur_ts); fprintf(stderr, "warn: SimbricksMemNicIfSync failed (memif=%lu)\n", cur_ts);
} }
while (SimbricksNetIfOutSync(&netif.net, cur_ts)) {
fprintf(stderr, "warn: SimbricksNicifSync failed (netif=%lu)\n", cur_ts);
}
do { do {
PollH2M(&memif, &netif.net, cur_ts); PollH2M(&memif, &netif, cur_ts);
PollM2H(&memif, &netif.net, cur_ts); PollN2M(&netif, &memif, cur_ts);
ts_a = SimbricksMemIfH2MInTimestamp(&memif);
ts_b = SimbricksNetIfInTimestamp(&netif.net); ts_mem = SimbricksMemIfH2MInTimestamp(&memif);
ts_net = SimbricksNetIfInTimestamp(&netif);
} while (!exiting && } while (!exiting &&
((sync_mem && ts_a <= cur_ts) || (sync_net && ts_b <= cur_ts))); ((sync_mem && ts_mem <= cur_ts) || (sync_net && ts_net <= cur_ts)));
if (sync_mem && sync_net) if (sync_mem && sync_net)
cur_ts = ts_a <= ts_b ? ts_a : ts_b; cur_ts = ts_mem <= ts_net ? ts_mem : ts_net;
else if (sync_mem) else if (sync_mem)
cur_ts = ts_a; cur_ts = ts_mem;
else if (sync_net) else if (sync_net)
cur_ts = ts_b; cur_ts = ts_net;
} }
// Todo: cleanup
return 0; return 0;
} }
...@@ -321,10 +321,19 @@ static void forward_pkt(const void *pkt_data, size_t pkt_len, size_t port_id, ...@@ -321,10 +321,19 @@ static void forward_pkt(const void *pkt_data, size_t pkt_len, size_t port_id,
hdr = (struct ethhdr *)pkt_data; hdr = (struct ethhdr *)pkt_data;
eth_proto = ntohs(hdr->h_proto); eth_proto = ntohs(hdr->h_proto);
iph = (struct iphdr *)(hdr + 1); iph = (struct iphdr *)(hdr + 1);
uint64_t dmac = (*(uint64_t *)hdr->h_dest) & 0xFFFFFFFFFFULL; int i;
uint64_t smac = (*(uint64_t *)hdr->h_source) & 0xFFFFFFFFFFULL;
fprintf(stderr, "%20lu: [P %zu -> %zu] %lx -> %lx ", cur_ts, iport_id, fprintf(stderr, "%20lu: [P %zu -> %zu] ", cur_ts, iport_id,
port_id, smac, dmac); port_id);
fprintf(stderr, "src_mac: ");
for (i = 0; i < ETH_ALEN; i++){
fprintf(stderr, "%X:", hdr->h_source[i]);
}
fprintf(stderr, " -> ");
for (i = 0; i < ETH_ALEN; i++){
fprintf(stderr, "%X:", hdr->h_dest[i]);
}
if (eth_proto == ETH_P_IP) { if (eth_proto == ETH_P_IP) {
fprintf(stderr, "[ IP] "); fprintf(stderr, "[ IP] ");
fprintf(stderr, "%8X -> %8X len: %lu\n", iph->saddr, iph->daddr, fprintf(stderr, "%8X -> %8X len: %lu\n", iph->saddr, iph->daddr,
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment