Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
ycai
simbricks
Commits
1eb0180c
Commit
1eb0180c
authored
Oct 28, 2020
by
Jialin Li
Browse files
add net switch
parent
02c660d6
Changes
6
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
231 additions
and
1 deletion
+231
-1
Makefile
Makefile
+6
-1
experiments/common-functions.sh
experiments/common-functions.sh
+21
-0
experiments/experiments/qemu-corundum-bm-echo-switch.sh
experiments/experiments/qemu-corundum-bm-echo-switch.sh
+18
-0
net_switch/Makefile
net_switch/Makefile
+11
-0
net_switch/net_switch
net_switch/net_switch
+0
-0
net_switch/net_switch.cc
net_switch/net_switch.cc
+175
-0
No files found.
Makefile
View file @
1eb0180c
...
@@ -5,7 +5,8 @@ all: \
...
@@ -5,7 +5,8 @@ all: \
corundum_bm/corundum_bm
\
corundum_bm/corundum_bm
\
i40e_bm/i40e_bm
\
i40e_bm/i40e_bm
\
net_tap/net_tap
\
net_tap/net_tap
\
net_wire/net_wire
net_wire/net_wire
\
net_switch/net_switch
clean
:
clean
:
$(MAKE)
-C
corundum/ clean
$(MAKE)
-C
corundum/ clean
...
@@ -14,6 +15,7 @@ clean:
...
@@ -14,6 +15,7 @@ clean:
$(MAKE)
-C
dummy_nic/ clean
$(MAKE)
-C
dummy_nic/ clean
$(MAKE)
-C
net_tap/ clean
$(MAKE)
-C
net_tap/ clean
$(MAKE)
-C
net_wire/ clean
$(MAKE)
-C
net_wire/ clean
$(MAKE)
-C
net_switch/ clean
$(MAKE)
-C
nicsim_common/ clean
$(MAKE)
-C
nicsim_common/ clean
$(MAKE)
-C
netsim_common/ clean
$(MAKE)
-C
netsim_common/ clean
$(MAKE)
-C
libnicbm/ clean
$(MAKE)
-C
libnicbm/ clean
...
@@ -49,6 +51,9 @@ net_tap/net_tap: netsim_common/libnetsim_common.a
...
@@ -49,6 +51,9 @@ net_tap/net_tap: netsim_common/libnetsim_common.a
net_wire/net_wire
:
netsim_common/libnetsim_common.a
net_wire/net_wire
:
netsim_common/libnetsim_common.a
$(MAKE)
-C
net_wire/
$(MAKE)
-C
net_wire/
net_switch/net_switch
:
netsim_common/libnetsim_common.a
$(MAKE)
-C
net_switch/
nicsim_common/libnicsim_common.a
:
nicsim_common/libnicsim_common.a
:
$(MAKE)
-C
nicsim_common/
$(MAKE)
-C
nicsim_common/
...
...
experiments/common-functions.sh
View file @
1eb0180c
...
@@ -182,6 +182,27 @@ run_wire() {
...
@@ -182,6 +182,27 @@ run_wire() {
return
$pid
return
$pid
}
}
# Args:
# - Instance name
# - sim instance 1
# - sim instance 2
# - [sim instance 3, ...]
run_switch
()
{
echo
Starting switch
$1
args
=
for
iface
in
${
@
:2
}
do
args
=
"
$args
-s
$WORKDIR
/eth.
$iface
"
done
$EHSIM_BASE
/net_switch/net_switch
\
$args
&>
$OUTDIR
/switch.
$1
.log &
pid
=
$!
ALL_PIDS
=
"
$ALL_PIDS
$pid
"
return
$pid
}
# Args:
# Args:
# - Instance name
# - Instance name
# - Port names
# - Port names
...
...
experiments/experiments/qemu-corundum-bm-echo-switch.sh
0 → 100644
View file @
1eb0180c
#!/bin/bash
source
common-functions.sh
init_out qemu-corundum-bm-echo-switch
$1
run_corundum_bm a
run_corundum_bm b
run_corundum_bm c
run_corundum_bm d
sleep
2
run_switch sw a b c d
run_qemu a a build/qemu-echo-server-0.tar
run_qemu b b build/qemu-echo-server-1.tar
run_qemu c c build/qemu-echo-server-2.tar
run_qemu d d build/qemu-echo-client.tar
client_pid
=
$!
wait
$client_pid
cleanup
net_switch/Makefile
0 → 100644
View file @
1eb0180c
CPPFLAGS
:=
-I
../proto
-I
../netsim_common/include
CFLAGS
:=
-Wall
-Wextra
-O3
LD
:=
g++
all
:
net_switch
net_switch
:
net_switch.o ../netsim_common/libnetsim_common.a
$(LD)
-o
$@
$^
clean
:
rm
-f
*
.o net_switch
net_switch/net_switch
0 → 100755
View file @
1eb0180c
File added
net_switch/net_switch.cc
0 → 100644
View file @
1eb0180c
#include <cstdio>
#include <cstdlib>
#include <csignal>
#include <climits>
#include <cstring>
#include <unistd.h>
#include <vector>
#include <unordered_map>
extern
"C"
{
#include <netsim.h>
};
#define SYNC_PERIOD (500 * 1000ULL) // 500ns
#define ETH_LATENCY (500 * 1000ULL) // 500ns
/* MAC address type */
struct
MAC
{
const
volatile
uint8_t
*
data
;
MAC
(
const
volatile
uint8_t
*
data
)
:
data
(
data
)
{}
bool
operator
==
(
const
MAC
&
other
)
const
{
for
(
int
i
=
0
;
i
<
6
;
i
++
)
{
if
(
data
[
i
]
!=
other
.
data
[
i
])
{
return
false
;
}
}
return
true
;
}
};
namespace
std
{
template
<
>
struct
hash
<
MAC
>
{
size_t
operator
()(
const
MAC
&
m
)
const
{
size_t
res
=
0
;
for
(
int
i
=
0
;
i
<
6
;
i
++
)
{
res
=
(
res
<<
4
)
|
(
res
^
m
.
data
[
i
]);
}
return
res
;
}
};
}
// namespace std
/* Global variables */
static
uint64_t
cur_ts
=
0
;
static
int
exiting
=
0
;
static
const
volatile
uint8_t
bcast
[
6
]
=
{
0xFF
};
static
const
MAC
bcast_addr
(
bcast
);
static
std
::
vector
<
struct
netsim_interface
>
nsifs
;
static
std
::
unordered_map
<
MAC
,
int
>
mac_table
;
static
void
sigint_handler
(
int
dummy
)
{
exiting
=
1
;
}
static
void
forward_pkt
(
volatile
struct
cosim_eth_proto_d2n_send
*
tx
,
int
port
)
{
volatile
union
cosim_eth_proto_n2d
*
msg_to
;
msg_to
=
netsim_n2d_alloc
(
&
nsifs
[
port
],
cur_ts
,
ETH_LATENCY
);
if
(
msg_to
!=
NULL
)
{
volatile
struct
cosim_eth_proto_n2d_recv
*
rx
;
rx
=
&
msg_to
->
recv
;
rx
->
len
=
tx
->
len
;
rx
->
port
=
0
;
memcpy
((
void
*
)
rx
->
data
,
(
void
*
)
tx
->
data
,
tx
->
len
);
// WMB();
rx
->
own_type
=
COSIM_ETH_PROTO_N2D_MSG_RECV
|
COSIM_ETH_PROTO_N2D_OWN_DEV
;
}
else
{
fprintf
(
stderr
,
"forward_pkt: dropping packet
\n
"
);
}
}
static
void
switch_pkt
(
struct
netsim_interface
*
nsif
,
int
iport
)
{
volatile
union
cosim_eth_proto_d2n
*
msg_from
=
netsim_d2n_poll
(
nsif
,
cur_ts
);
if
(
msg_from
==
NULL
)
{
return
;
}
uint8_t
type
=
msg_from
->
dummy
.
own_type
&
COSIM_ETH_PROTO_D2N_MSG_MASK
;
if
(
type
==
COSIM_ETH_PROTO_D2N_MSG_SEND
)
{
volatile
struct
cosim_eth_proto_d2n_send
*
tx
;
tx
=
&
msg_from
->
send
;
// Get MAC addresses
MAC
dst
(
tx
->
data
),
src
(
tx
->
data
+
6
);
// MAC learning
if
(
!
(
src
==
bcast_addr
))
{
mac_table
[
src
]
=
iport
;
}
// L2 forwarding
if
(
mac_table
.
count
(
dst
)
>
0
)
{
int
eport
=
mac_table
.
at
(
dst
);
forward_pkt
(
tx
,
eport
);
}
else
{
// Broadcast
for
(
int
eport
=
0
;
eport
<
nsifs
.
size
();
eport
++
)
{
if
(
eport
!=
iport
)
{
// Do not forward to ingress port
forward_pkt
(
tx
,
eport
);
}
}
}
}
else
if
(
type
==
COSIM_ETH_PROTO_D2N_MSG_SYNC
)
{
}
else
{
fprintf
(
stderr
,
"switch_pkt: unsupported type=%u
\n
"
,
type
);
abort
();
}
netsim_d2n_done
(
nsif
,
msg_from
);
}
int
main
(
int
argc
,
char
*
argv
[])
{
int
c
;
// Parse command line argument
while
((
c
=
getopt
(
argc
,
argv
,
"s:"
))
!=
-
1
)
{
switch
(
c
)
{
case
's'
:
{
struct
netsim_interface
nsif
;
int
sync
=
1
;
if
(
netsim_init
(
&
nsif
,
optarg
,
&
sync
)
!=
0
)
{
return
EXIT_FAILURE
;
}
nsifs
.
push_back
(
nsif
);
}
default:
fprintf
(
stderr
,
"unknown option %c
\n
"
,
c
);
}
}
if
(
nsifs
.
empty
())
{
fprintf
(
stderr
,
"Usage: net_switch -s SOCKET-A [-s SOCKET-B ...]
\n
"
);
return
EXIT_FAILURE
;
}
signal
(
SIGINT
,
sigint_handler
);
signal
(
SIGTERM
,
sigint_handler
);
printf
(
"start polling
\n
"
);
while
(
!
exiting
)
{
// Sync all interfaces
for
(
auto
&
nsif
:
nsifs
)
{
if
(
netsim_n2d_sync
(
&
nsif
,
cur_ts
,
ETH_LATENCY
,
SYNC_PERIOD
)
!=
0
)
{
fprintf
(
stderr
,
"netsim_n2d_sync failed
\n
"
);
abort
();
}
}
// Switch packets
uint64_t
min_ts
;
do
{
min_ts
=
ULLONG_MAX
;
for
(
int
port
=
0
;
port
<
nsifs
.
size
();
port
++
)
{
auto
&
nsif
=
nsifs
.
at
(
port
);
switch_pkt
(
&
nsif
,
port
);
if
(
nsif
.
sync
)
{
uint64_t
ts
=
netsim_d2n_timestamp
(
&
nsif
);
min_ts
=
ts
<
min_ts
?
ts
:
min_ts
;
}
}
}
while
(
!
exiting
&&
(
min_ts
<=
cur_ts
));
// Update cur_ts
if
(
min_ts
<
ULLONG_MAX
)
{
cur_ts
=
min_ts
;
}
}
return
0
;
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment