Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
Help
Support
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
U
udpdk
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
ywj
udpdk
Commits
9fac978e
Commit
9fac978e
authored
Nov 05, 2020
by
Leonardo Lai
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
bugfix: failed to receive packets on INADDR_ANY
parent
d61b436e
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
39 additions
and
23 deletions
+39
-23
udpdk/udpdk_bind_table.c
udpdk/udpdk_bind_table.c
+10
-7
udpdk/udpdk_poller.c
udpdk/udpdk_poller.c
+28
-13
udpdk/udpdk_syscall.c
udpdk/udpdk_syscall.c
+1
-3
No files found.
udpdk/udpdk_bind_table.c
View file @
9fac978e
...
...
@@ -7,10 +7,13 @@
// the IPs bound to that port (typically one, but can be many)
//
#include <arpa/inet.h> // inet_ntop
#include <netinet/in.h> // INADDR_ANY
#include "udpdk_bind_table.h"
#include "udpdk_shmalloc.h"
#define RTE_LOGTYPE_BTABLE RTE_LOGTYPE_USER1
const
void
*
bind_info_alloc
=
NULL
;
list_t
**
sock_bind_table
;
...
...
@@ -34,13 +37,14 @@ int btable_get_free_port(void)
return
i
;
}
}
RTE_LOG
(
WARNING
,
BTABLE
,
"Failed to find a free port
\n
"
);
return
-
1
;
}
/* Verify if binding the pair (ip, port) is possible, provided the
* options and the previous bindings.
*/
static
inline
int
btable_can_bind
(
struct
in_addr
ip
,
int
port
,
int
opts
)
static
inline
bool
btable_can_bind
(
struct
in_addr
ip
,
int
port
,
int
opts
)
{
bool
reuse_addr
=
opts
&
SO_REUSEADDR
;
bool
reuse_port
=
opts
&
SO_REUSEPORT
;
...
...
@@ -52,7 +56,7 @@ static inline int btable_can_bind(struct in_addr ip, int port, int opts)
bool
oth_reuseport
;
if
(
sock_bind_table
[
port
]
==
NULL
)
{
return
0
;
return
true
;
}
ip_new
=
ip
.
s_addr
;
...
...
@@ -81,11 +85,7 @@ static inline int btable_can_bind(struct in_addr ip, int port, int opts)
}
list_iterator_destroy
(
it
);
if
(
can_bind
)
{
return
0
;
}
else
{
return
-
1
;
}
return
can_bind
;
}
int
btable_add_binding
(
int
s
,
struct
in_addr
ip
,
int
port
,
int
opts
)
...
...
@@ -95,6 +95,9 @@ int btable_add_binding(int s, struct in_addr ip, int port, int opts)
// Check if binding this pair is allowed
if
(
!
btable_can_bind
(
ip
,
port
,
opts
))
{
char
buf
[
INET_ADDRSTRLEN
];
inet_ntop
(
AF_INET
,
&
ip
,
buf
,
sizeof
(
buf
));
RTE_LOG
(
WARNING
,
BTABLE
,
"Cannot bind socket %d to %s:%d
\n
"
,
s
,
buf
,
ntohs
(
port
));
return
-
1
;
}
...
...
udpdk/udpdk_poller.c
View file @
9fac978e
...
...
@@ -312,6 +312,8 @@ static inline void reassemble(struct rte_mbuf *m, uint16_t portid, uint32_t queu
uint16_t
udp_dst_port
;
unsigned
long
ip_dst_addr
;
int
sock_id
;
bool
delivered_once
=
false
;
bool
delivered_last
=
false
;
rxq
=
&
qconf
->
rx_queue
;
...
...
@@ -360,26 +362,39 @@ static inline void reassemble(struct rte_mbuf *m, uint16_t portid, uint32_t queu
// Find the sock_ids corresponding to the UDP dst port (L4 switching) and enqueue the packet to its queue
list_t
*
binds
=
btable_get_bindings
(
udp_dst_port
);
if
(
binds
==
NULL
)
{
RTE_LOG
(
WARNING
,
POLLBODY
,
"Dropping packet for port %d: no socket bound
\n
"
,
udp_dst_port
);
RTE_LOG
(
WARNING
,
POLLBODY
,
"Dropping packet for port %d: no socket bound
\n
"
,
ntohs
(
udp_dst_port
)
);
return
;
}
list_iterator_t
*
it
=
list_iterator_new
(
binds
,
LIST_HEAD
);
list_node_t
*
node
;
while
((
node
=
list_iterator_next
(
it
)))
{
// TODO hand non trivial cases (see below)
/*
if dest unicast and not REUSEPORT (LIKELY), enqueue and break
if dest unicast and SO_REUSEPORT, should load balance
if dest broadcast and SO_REUSEADDR o SO_REUSEPORT, enqueue and continue
*/
if
(
ip_dst_addr
==
((
struct
bind_info
*
)(
node
->
val
))
->
ip_addr
.
s_addr
)
{
break
;
unsigned
long
ip_oth
=
((
struct
bind_info
*
)(
node
->
val
))
->
ip_addr
.
s_addr
;
bool
oth_reuseaddr
=
((
struct
bind_info
*
)(
node
->
val
))
->
reuse_addr
;
bool
oth_reuseport
=
((
struct
bind_info
*
)(
node
->
val
))
->
reuse_port
;
// TODO the semantic should be more complex actually:
// if dest unicast and SO_REUSEPORT, should load balance
// if dest broadcast and SO_REUSEADDR or SO_REUSEPORT, should deliver to all
// If matching
if
(
likely
((
ip_dst_addr
==
ip_oth
)
||
(
ip_oth
==
INADDR_ANY
)))
{
// Deliver to this socket
enqueue_rx_packet
(((
struct
bind_info
*
)(
node
->
val
))
->
sockfd
,
m
);
delivered_once
=
true
;
// If other socket may exist on the same port, keep scanning
if
(
oth_reuseaddr
||
oth_reuseport
)
{
m
=
rte_pktmbuf_clone
(
m
,
rxq
->
pool
);
delivered_last
=
false
;
continue
;
}
else
{
delivered_last
=
true
;
break
;
}
}
}
if
(
node
!=
NULL
)
{
enqueue_rx_packet
(((
struct
bind_info
*
)(
node
->
val
))
->
sockfd
,
m
);
}
else
{
RTE_LOG
(
WARNING
,
POLLBODY
,
"Dropping packet for port %d: no socket matching
\n
"
,
udp_dst_port
);
if
(
!
delivered_last
)
{
rte_pktmbuf_free
(
m
);
}
if
(
!
delivered_once
)
{
RTE_LOG
(
WARNING
,
POLLBODY
,
"Dropped packet to port %d: no socket matching
\n
"
,
ntohs
(
udp_dst_port
));
}
list_iterator_destroy
(
it
);
}
...
...
udpdk/udpdk_syscall.c
View file @
9fac978e
...
...
@@ -218,7 +218,6 @@ static int bind_validate_args(int sockfd, const struct sockaddr *addr, socklen_t
int
udpdk_bind
(
int
sockfd
,
const
struct
sockaddr
*
addr
,
socklen_t
addrlen
)
{
int
ret
;
unsigned
short
port
;
const
struct
sockaddr_in
*
addr_in
=
(
struct
sockaddr_in
*
)
addr
;
...
...
@@ -229,8 +228,7 @@ int udpdk_bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen)
// Try to bind the socket
port
=
addr_in
->
sin_port
;
ret
=
btable_add_binding
(
sockfd
,
addr_in
->
sin_addr
,
port
,
exch_zone_desc
->
slots
[
sockfd
].
so_options
);
if
(
ret
!=
-
1
)
{
if
(
btable_add_binding
(
sockfd
,
addr_in
->
sin_addr
,
port
,
exch_zone_desc
->
slots
[
sockfd
].
so_options
)
<
0
)
{
errno
=
EADDRINUSE
;
RTE_LOG
(
ERR
,
SYSCALL
,
"Failed to bind because port %d is already in use
\n
"
,
ntohs
(
port
));
return
-
1
;
...
...
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