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
bb82346e
You need to sign in or sign up before continuing.
Commit
bb82346e
authored
Jun 10, 2022
by
Antoine Kaufmann
Browse files
sims/net/switch: parallel connection establishment
(uses SimBricksBaseIfEstablish)
parent
83d363ae
Changes
1
Show whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
115 additions
and
81 deletions
+115
-81
sims/net/switch/net_switch.cc
sims/net/switch/net_switch.cc
+115
-81
No files found.
sims/net/switch/net_switch.cc
View file @
bb82346e
...
@@ -95,70 +95,81 @@ struct hash<MAC> {
...
@@ -95,70 +95,81 @@ struct hash<MAC> {
}
// namespace std
}
// namespace std
/**
Abstract base switch port
*/
/**
Normal network switch port (conneting to a NIC)
*/
class
Port
{
class
Net
Port
{
public:
public:
enum
RxPollState
{
enum
RxPollState
{
kRxPollSuccess
=
0
,
kRxPollSuccess
=
0
,
kRxPollFail
=
1
,
kRxPollFail
=
1
,
kRxPollSync
=
2
,
kRxPollSync
=
2
,
};
};
struct
SimbricksNetIf
netif_
;
virtual
~
Port
()
=
default
;
virtual
bool
Connect
(
const
char
*
path
,
int
sync
)
=
0
;
virtual
bool
IsSync
()
=
0
;
virtual
void
Sync
(
uint64_t
cur_ts
)
=
0
;
virtual
uint64_t
NextTimestamp
()
=
0
;
virtual
enum
RxPollState
RxPacket
(
const
void
*&
data
,
size_t
&
len
,
uint64_t
cur_ts
)
=
0
;
virtual
void
RxDone
()
=
0
;
virtual
bool
TxPacket
(
const
void
*
data
,
size_t
len
,
uint64_t
cur_ts
)
=
0
;
};
/** Normal network switch port (conneting to a NIC) */
class
NetPort
:
public
Port
{
protected:
protected:
struct
SimbricksNetIf
netifObj_
;
struct
SimbricksNetIf
*
netif_
;
volatile
union
SimbricksProtoNetMsg
*
rx_
;
volatile
union
SimbricksProtoNetMsg
*
rx_
;
int
sync_
;
int
sync_
;
const
char
*
path_
;
bool
Init
()
{
struct
SimbricksBaseIfParams
params
=
netParams
;
params
.
sync_mode
=
(
sync_
?
kSimbricksBaseIfSyncOptional
:
kSimbricksBaseIfSyncDisabled
);
params
.
sock_path
=
path_
;
params
.
blocking_conn
=
false
;
if
(
SimbricksBaseIfInit
(
&
netif_
.
base
,
&
params
))
{
perror
(
"Init: SimbricksBaseIfInit failed"
);
return
false
;
}
return
true
;
}
public:
public:
NetPort
(
)
:
netif_
(
&
netifObj_
),
rx_
(
nullptr
),
sync_
(
0
)
{
NetPort
(
const
char
*
path
,
int
sync
)
:
rx_
(
nullptr
),
sync_
(
sync
),
path_
(
path
)
{
memset
(
&
netif
Obj
_
,
0
,
sizeof
(
netif
Obj
_
));
memset
(
&
netif_
,
0
,
sizeof
(
netif_
));
}
}
NetPort
(
const
NetPort
&
other
)
:
netifObj_
(
other
.
netifObj_
),
NetPort
(
const
NetPort
&
other
)
:
netif_
(
other
.
netif_
),
netif_
(
&
netifObj_
),
rx_
(
other
.
rx_
),
sync_
(
other
.
sync_
)
{}
rx_
(
other
.
rx_
),
sync_
(
other
.
sync_
),
path_
(
other
.
path_
)
{}
virtual
bool
Prepare
()
{
if
(
!
Init
())
return
false
;
virtual
bool
Connect
(
const
char
*
path
,
int
sync
)
override
{
if
(
SimbricksBaseIfConnect
(
&
netif_
.
base
))
{
sync_
=
sync
;
perror
(
"Prepare: SimbricksBaseIfConnect failed"
)
;
return
SimbricksNetIfInit
(
netif_
,
&
netParams
,
path
,
&
sync_
)
==
0
;
return
false
;
}
}
virtual
bool
IsSync
()
override
{
return
true
;
}
virtual
void
Prepared
()
{
sync_
=
SimbricksBaseIfSyncEnabled
(
&
netif_
.
base
);
}
bool
IsSync
()
{
return
sync_
;
return
sync_
;
}
}
virtual
void
Sync
(
uint64_t
cur_ts
)
override
{
void
Sync
(
uint64_t
cur_ts
)
{
while
(
SimbricksNetIfOutSync
(
netif_
,
cur_ts
));
while
(
SimbricksNetIfOutSync
(
&
netif_
,
cur_ts
));
}
}
virtual
uint64_t
NextTimestamp
()
override
{
uint64_t
NextTimestamp
()
{
return
SimbricksNetIfInTimestamp
(
netif_
);
return
SimbricksNetIfInTimestamp
(
&
netif_
);
}
}
virtual
enum
RxPollState
RxPacket
(
enum
RxPollState
RxPacket
(
const
void
*&
data
,
size_t
&
len
,
uint64_t
cur_ts
)
override
{
const
void
*&
data
,
size_t
&
len
,
uint64_t
cur_ts
)
{
assert
(
rx_
==
nullptr
);
assert
(
rx_
==
nullptr
);
rx_
=
SimbricksNetIfInPoll
(
netif_
,
cur_ts
);
rx_
=
SimbricksNetIfInPoll
(
&
netif_
,
cur_ts
);
if
(
!
rx_
)
if
(
!
rx_
)
return
kRxPollFail
;
return
kRxPollFail
;
uint8_t
type
=
SimbricksNetIfInType
(
netif_
,
rx_
);
uint8_t
type
=
SimbricksNetIfInType
(
&
netif_
,
rx_
);
if
(
type
==
SIMBRICKS_PROTO_NET_MSG_PACKET
)
{
if
(
type
==
SIMBRICKS_PROTO_NET_MSG_PACKET
)
{
data
=
(
const
void
*
)
rx_
->
packet
.
data
;
data
=
(
const
void
*
)
rx_
->
packet
.
data
;
len
=
rx_
->
packet
.
len
;
len
=
rx_
->
packet
.
len
;
...
@@ -171,22 +182,22 @@ class NetPort : public Port {
...
@@ -171,22 +182,22 @@ class NetPort : public Port {
}
}
}
}
virtual
void
RxDone
()
override
{
void
RxDone
()
{
assert
(
rx_
!=
nullptr
);
assert
(
rx_
!=
nullptr
);
SimbricksNetIfInDone
(
netif_
,
rx_
);
SimbricksNetIfInDone
(
&
netif_
,
rx_
);
rx_
=
nullptr
;
rx_
=
nullptr
;
}
}
virtual
bool
TxPacket
(
bool
TxPacket
(
const
void
*
data
,
size_t
len
,
uint64_t
cur_ts
)
override
{
const
void
*
data
,
size_t
len
,
uint64_t
cur_ts
)
{
volatile
union
SimbricksProtoNetMsg
*
msg_to
=
volatile
union
SimbricksProtoNetMsg
*
msg_to
=
SimbricksNetIfOutAlloc
(
netif_
,
cur_ts
);
SimbricksNetIfOutAlloc
(
&
netif_
,
cur_ts
);
if
(
!
msg_to
&&
!
sync_
)
{
if
(
!
msg_to
&&
!
sync_
)
{
return
false
;
return
false
;
}
else
if
(
!
msg_to
&&
sync_
)
{
}
else
if
(
!
msg_to
&&
sync_
)
{
while
(
!
msg_to
)
while
(
!
msg_to
)
msg_to
=
SimbricksNetIfOutAlloc
(
netif_
,
cur_ts
);
msg_to
=
SimbricksNetIfOutAlloc
(
&
netif_
,
cur_ts
);
}
}
volatile
struct
SimbricksProtoNetMsgPacket
*
rx
;
volatile
struct
SimbricksProtoNetMsgPacket
*
rx
;
rx
=
&
msg_to
->
packet
;
rx
=
&
msg_to
->
packet
;
...
@@ -194,53 +205,82 @@ class NetPort : public Port {
...
@@ -194,53 +205,82 @@ class NetPort : public Port {
rx
->
port
=
0
;
rx
->
port
=
0
;
memcpy
((
void
*
)
rx
->
data
,
data
,
len
);
memcpy
((
void
*
)
rx
->
data
,
data
,
len
);
SimbricksNetIfOutSend
(
netif_
,
msg_to
,
SIMBRICKS_PROTO_NET_MSG_PACKET
);
SimbricksNetIfOutSend
(
&
netif_
,
msg_to
,
SIMBRICKS_PROTO_NET_MSG_PACKET
);
return
true
;
return
true
;
}
}
};
};
/**
Hosting network
switch port (connected to another network) */
/**
Listening
switch port (connected to
by
another network) */
class
Net
Host
Port
:
public
NetPort
{
class
Net
Listen
Port
:
public
NetPort
{
protected:
protected:
struct
Simbricks
NicIf
nicif
_
;
struct
Simbricks
BaseIfSHMPool
pool
_
;
public:
public:
NetHostPort
()
{
NetListenPort
(
const
char
*
path
,
int
sync
)
:
NetPort
(
path
,
sync
)
{
netif_
=
&
nicif_
.
net
;
memset
(
&
pool_
,
0
,
sizeof
(
pool_
));
memset
(
&
nicif_
,
0
,
sizeof
(
nicif_
));
}
}
Net
Host
Port
(
const
Net
Host
Port
&
other
)
:
NetPort
(
other
),
nicif_
(
other
.
nicif_
)
{
Net
Listen
Port
(
const
Net
Listen
Port
&
other
)
:
NetPort
(
other
),
netif_
=
&
nicif_
.
net
;
pool_
(
other
.
pool_
)
{
}
}
virtual
bool
Connect
(
const
char
*
path
,
int
sync
)
override
{
virtual
bool
Prepare
()
override
{
sync_
=
sync
;
if
(
!
Init
())
std
::
string
shm_path
=
path
;
return
false
;
std
::
string
shm_path
=
path_
;
shm_path
+=
"-shm"
;
shm_path
+=
"-shm"
;
struct
SimbricksBaseIfParams
params
=
netParams
;
params
.
sock_path
=
path
;
if
(
SimbricksBaseIfSHMPoolCreate
(
&
pool_
,
shm_path
.
c_str
(),
if
(
!
sync
)
SimbricksBaseIfSHMSize
(
&
netif_
.
base
.
params
))
!=
0
)
{
params
.
sync_mode
=
kSimbricksBaseIfSyncDisabled
;
perror
(
"Prepare: SimbricksBaseIfSHMPoolCreate failed"
);
int
ret
=
SimbricksNicIfInit
(
&
nicif_
,
shm_path
.
c_str
(),
&
params
,
nullptr
,
return
false
;
nullptr
);
sync_
=
SimbricksBaseIfSyncEnabled
(
&
netif_
->
base
);
return
ret
==
0
;
}
}
virtual
bool
IsSync
()
override
{
if
(
SimbricksBaseIfListen
(
&
netif_
.
base
,
&
pool_
)
!=
0
)
{
return
sync_
;
perror
(
"Prepare: SimbricksBaseIfListen failed"
);
return
false
;
}
return
true
;
}
}
};
};
static
bool
ConnectAll
(
std
::
vector
<
NetPort
*>
ports
)
{
size_t
n
=
ports
.
size
();
struct
SimBricksBaseIfEstablishData
ests
[
n
];
struct
SimbricksProtoNetIntro
intro
;
printf
(
"start connecting...
\n
"
);
for
(
size_t
i
=
0
;
i
<
n
;
i
++
)
{
NetPort
*
p
=
ports
[
i
];
ests
[
i
].
base_if
=
&
p
->
netif_
.
base
;
ests
[
i
].
tx_intro
=
&
intro
;
ests
[
i
].
tx_intro_len
=
sizeof
(
intro
);
ests
[
i
].
rx_intro
=
&
intro
;
ests
[
i
].
rx_intro_len
=
sizeof
(
intro
);
if
(
!
p
->
Prepare
())
return
false
;
}
if
(
SimBricksBaseIfEstablish
(
ests
,
n
))
{
fprintf
(
stderr
,
"ConnectAll: SimBricksBaseIfEstablish failed
\n
"
);
return
false
;
}
printf
(
"done connecting
\n
"
);
return
true
;
}
/* Global variables */
/* Global variables */
static
uint64_t
cur_ts
=
0
;
static
uint64_t
cur_ts
=
0
;
static
int
exiting
=
0
;
static
int
exiting
=
0
;
static
const
uint8_t
bcast
[
6
]
=
{
0xFF
};
static
const
uint8_t
bcast
[
6
]
=
{
0xFF
};
static
const
MAC
bcast_addr
(
bcast
);
static
const
MAC
bcast_addr
(
bcast
);
static
std
::
vector
<
Port
*>
ports
;
static
std
::
vector
<
Net
Port
*>
ports
;
static
std
::
unordered_map
<
MAC
,
int
>
mac_table
;
static
std
::
unordered_map
<
MAC
,
int
>
mac_table
;
static
void
sigint_handler
(
int
dummy
)
{
static
void
sigint_handler
(
int
dummy
)
{
...
@@ -260,7 +300,7 @@ static void sigusr2_handler(int dummy) {
...
@@ -260,7 +300,7 @@ static void sigusr2_handler(int dummy) {
static
void
forward_pkt
(
const
void
*
pkt_data
,
size_t
pkt_len
,
size_t
port_id
,
static
void
forward_pkt
(
const
void
*
pkt_data
,
size_t
pkt_len
,
size_t
port_id
,
size_t
iport_id
)
{
size_t
iport_id
)
{
struct
pcap_pkthdr
ph
;
struct
pcap_pkthdr
ph
;
Port
&
dest_port
=
*
ports
[
port_id
];
Net
Port
&
dest_port
=
*
ports
[
port_id
];
// log to pcap file if initialized
// log to pcap file if initialized
if
(
dumpfile
)
{
if
(
dumpfile
)
{
...
@@ -303,7 +343,7 @@ static void forward_pkt(const void *pkt_data, size_t pkt_len, size_t port_id,
...
@@ -303,7 +343,7 @@ static void forward_pkt(const void *pkt_data, size_t pkt_len, size_t port_id,
fprintf
(
stderr
,
"forward_pkt: dropping packet on port %zu
\n
"
,
port_id
);
fprintf
(
stderr
,
"forward_pkt: dropping packet on port %zu
\n
"
,
port_id
);
}
}
static
void
switch_pkt
(
Port
&
port
,
size_t
iport
)
{
static
void
switch_pkt
(
Net
Port
&
port
,
size_t
iport
)
{
const
void
*
pkt_data
;
const
void
*
pkt_data
;
size_t
pkt_len
;
size_t
pkt_len
;
...
@@ -314,8 +354,8 @@ static void switch_pkt(Port &port, size_t iport) {
...
@@ -314,8 +354,8 @@ static void switch_pkt(Port &port, size_t iport) {
}
}
#endif
#endif
enum
Port
::
RxPollState
poll
=
port
.
RxPacket
(
pkt_data
,
pkt_len
,
cur_ts
);
enum
Net
Port
::
RxPollState
poll
=
port
.
RxPacket
(
pkt_data
,
pkt_len
,
cur_ts
);
if
(
poll
==
Port
::
kRxPollFail
)
{
if
(
poll
==
Net
Port
::
kRxPollFail
)
{
return
;
return
;
}
}
...
@@ -326,7 +366,7 @@ static void switch_pkt(Port &port, size_t iport) {
...
@@ -326,7 +366,7 @@ static void switch_pkt(Port &port, size_t iport) {
}
}
#endif
#endif
if
(
poll
==
Port
::
kRxPollSuccess
)
{
if
(
poll
==
Net
Port
::
kRxPollSuccess
)
{
// Get MAC addresses
// Get MAC addresses
MAC
dst
((
const
uint8_t
*
)
pkt_data
),
src
((
const
uint8_t
*
)
pkt_data
+
6
);
MAC
dst
((
const
uint8_t
*
)
pkt_data
),
src
((
const
uint8_t
*
)
pkt_data
+
6
);
// MAC learning
// MAC learning
...
@@ -348,7 +388,7 @@ static void switch_pkt(Port &port, size_t iport) {
...
@@ -348,7 +388,7 @@ static void switch_pkt(Port &port, size_t iport) {
}
}
}
}
}
}
}
else
if
(
poll
==
Port
::
kRxPollSync
)
{
}
else
if
(
poll
==
Net
Port
::
kRxPollSync
)
{
#ifdef NETSWITCH_STAT
#ifdef NETSWITCH_STAT
d2n_poll_sync
+=
1
;
d2n_poll_sync
+=
1
;
if
(
stat_flag
){
if
(
stat_flag
){
...
@@ -374,23 +414,15 @@ int main(int argc, char *argv[]) {
...
@@ -374,23 +414,15 @@ int main(int argc, char *argv[]) {
while
((
c
=
getopt
(
argc
,
argv
,
"s:h:uS:E:p:"
))
!=
-
1
&&
!
bad_option
)
{
while
((
c
=
getopt
(
argc
,
argv
,
"s:h:uS:E:p:"
))
!=
-
1
&&
!
bad_option
)
{
switch
(
c
)
{
switch
(
c
)
{
case
's'
:
{
case
's'
:
{
NetPort
*
port
=
new
NetPort
;
NetPort
*
port
=
new
NetPort
(
optarg
,
sync_eth
)
;
fprintf
(
stderr
,
"Switch connecting to: %s
\n
"
,
optarg
);
fprintf
(
stderr
,
"Switch connecting to: %s
\n
"
,
optarg
);
if
(
!
port
->
Connect
(
optarg
,
sync_eth
))
{
fprintf
(
stderr
,
"connecting to %s failed
\n
"
,
optarg
);
return
EXIT_FAILURE
;
}
ports
.
push_back
(
port
);
ports
.
push_back
(
port
);
break
;
break
;
}
}
case
'h'
:
{
case
'h'
:
{
Net
Host
Port
*
port
=
new
Net
HostPort
;
Net
Listen
Port
*
port
=
new
Net
ListenPort
(
optarg
,
sync_eth
)
;
fprintf
(
stderr
,
"Switch listening on: %s
\n
"
,
optarg
);
fprintf
(
stderr
,
"Switch listening on: %s
\n
"
,
optarg
);
if
(
!
port
->
Connect
(
optarg
,
sync_eth
))
{
fprintf
(
stderr
,
"listening on %s failed
\n
"
,
optarg
);
return
EXIT_FAILURE
;
}
ports
.
push_back
(
port
);
ports
.
push_back
(
port
);
break
;
break
;
}
}
...
@@ -440,6 +472,8 @@ int main(int argc, char *argv[]) {
...
@@ -440,6 +472,8 @@ int main(int argc, char *argv[]) {
signal
(
SIGUSR2
,
sigusr2_handler
);
signal
(
SIGUSR2
,
sigusr2_handler
);
#endif
#endif
if
(
!
ConnectAll
(
ports
))
return
EXIT_FAILURE
;
printf
(
"start polling
\n
"
);
printf
(
"start polling
\n
"
);
while
(
!
exiting
)
{
while
(
!
exiting
)
{
...
...
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