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
fa41ef71
Commit
fa41ef71
authored
Nov 02, 2020
by
Leonardo Lai
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
reworked bindings table
parent
841b83bc
Changes
11
Hide whitespace changes
Inline
Side-by-side
Showing
11 changed files
with
360 additions
and
104 deletions
+360
-104
LICENSE
LICENSE
+2
-0
udpdk/Makefile
udpdk/Makefile
+19
-6
udpdk/shmalloc/udpdk_shmalloc.c
udpdk/shmalloc/udpdk_shmalloc.c
+155
-0
udpdk/shmalloc/udpdk_shmalloc.h
udpdk/shmalloc/udpdk_shmalloc.h
+21
-0
udpdk/udpdk_bind_table.c
udpdk/udpdk_bind_table.c
+129
-0
udpdk/udpdk_bind_table.h
udpdk/udpdk_bind_table.h
+16
-8
udpdk/udpdk_constants.h
udpdk/udpdk_constants.h
+1
-0
udpdk/udpdk_globals.c
udpdk/udpdk_globals.c
+1
-3
udpdk/udpdk_init.c
udpdk/udpdk_init.c
+7
-2
udpdk/udpdk_lookup_table.c
udpdk/udpdk_lookup_table.c
+0
-85
udpdk/udpdk_types.h
udpdk/udpdk_types.h
+9
-0
No files found.
LICENSE
View file @
fa41ef71
...
...
@@ -35,3 +35,5 @@ This software uses code from:
License: BSD 3-Clause
- inih: https://github.com/benhoyt/inih
License: BSD 3-Clause
- list: https://github.com/clibs/list
License: MIT
udpdk/Makefile
View file @
fa41ef71
...
...
@@ -33,12 +33,14 @@ CFLAGS+= --param large-function-growth=1000
DPDK_CFLAGS
=
-DRTE_MACHINE_CPUFLAG_SSE
-DRTE_MACHINE_CPUFLAG_SSE2
-DRTE_MACHINE_CPUFLAG_SSE3
DPDK_CFLAGS
+=
-DRTE_MACHINE_CPUFLAG_SSSE3
-DRTE_MACHINE_CPUFLAG_SSE4_1
-DRTE_MACHINE_CPUFLAG_SSE4_2
DPDK_CFLAGS
+=
-DRTE_COMPILE_TIME_CPUFLAGS
=
RTE_CPUFLAG_SSE,RTE_CPUFLAG_SSE2,RTE_CPUFLAG_SSE3,RTE_CPUFLAG_SSSE3,RTE_CPUFLAG_SSE4_1,RTE_CPUFLAG_SSE4_2
DPDK_CFLAGS
+=
-I
${UDPDK_DPDK}
/include
DPDK_CFLAGS
+=
-I
${INIH}
UDPDK_C
=
${CC}
-c
$(DPDK_CFLAGS)
${CFLAGS}
${WERROR}
$<
UDPDK_CFLAGS
+=
-I
${UDPDK_DPDK}
/include
UDPDK_CFLAGS
+=
-I
${INIH}
UDPDK_CFLAGS
+=
-Ilist
-Ishmalloc
UDPDK_SRCS
+=
\
UDPDK_C
=
${CC}
-c
$(DPDK_CFLAGS)
$(UDPDK_CFLAGS)
${CFLAGS}
${WERROR}
$<
UDPDK_CORE_SRCS
+=
\
udpdk_args.c
\
udpdk_globals.c
\
udpdk_init.c
\
...
...
@@ -46,8 +48,19 @@ UDPDK_SRCS+= \
udpdk_poller.c
\
udpdk_syscall.c
\
UDPDK_LIST_SRCS
+=
\
list/list.c
\
list/list_node.c
\
list/list_iterator.c
\
list/list_globals.c
\
list/list_init.c
UDPDK_SHM_SRCS
+=
shmalloc/udpdk_shmalloc.c
\
SRCS
=
${UDPDK_SRCS}
SRCS
+=
${UDPDK_CORE_SRCS}
SRCS
+=
${UDPDK_LIST_SRCS}
SRCS
+=
${UDPDK_SHM_SRCS}
OBJS
+=
$(
patsubst
%.c,%.o,
${SRCS}
)
...
...
@@ -67,7 +80,7 @@ libudpdk.a: ${OBJS}
rm
-f
$*
.ro
${OBJS}
:
%.o: %.c
${UDPDK_C}
${UDPDK_C}
-o
$@
.PHONY
:
clean
clean
:
...
...
udpdk/shmalloc/udpdk_shmalloc.c
0 → 100644
View file @
fa41ef71
//
// Created by leoll2 on 11/01/20.
// Copyright (c) 2020 Leonardo Lai. All rights reserved.
//
#include <string.h>
#include "udpdk_shmalloc.h"
#define SetBit(A,k) (A[(k / 32)] |= (1 << (k % 32)))
#define ClearBit(A,k) (A[(k / 32)] &= ~(1 << (k % 32)))
#define TestBit(A,k) (A[(k / 32)] & (1 << (k % 32)))
struct
allocator
{
unsigned
size
;
unsigned
elem_size
;
// size (byte) of each element
unsigned
n_free
;
unsigned
next_free
;
// index of next free
unsigned
pool_offset
;
// offset (bytes) from the begin of memzone
};
const
struct
rte_memzone
*
udpdk_init_allocator
(
const
char
*
name
,
unsigned
size
,
unsigned
elem_size
)
{
unsigned
mem_needed
;
unsigned
p_off
;
const
struct
rte_memzone
*
mz
;
struct
allocator
*
all
;
const
int
*
free_bitfield
;
//Round-up elem_size to cache line multiple (64 byte)
elem_size
=
(
elem_size
+
64
-
1
)
/
64
;
// Determine how much memory is needed (pool size + bitfield of free elems + variables)
mem_needed
=
sizeof
(
struct
allocator
)
+
(
size
/
8
+
1
);
mem_needed
=
(
mem_needed
+
elem_size
-
1
)
/
elem_size
;
// align
p_off
=
mem_needed
;
mem_needed
+=
(
size
*
elem_size
);
// Allocate the memory for the allocator and its pool
mz
=
rte_memzone_reserve
(
name
,
mem_needed
,
rte_socket_id
(),
0
);
if
(
mz
==
NULL
)
{
return
NULL
;
}
// Initialize the allocator internal variables
all
=
(
struct
allocator
*
)(
void
*
)
mz
->
addr
;
all
->
size
=
size
;
all
->
elem_size
=
elem_size
;
all
->
n_free
=
size
;
all
->
next_free
=
0
;
all
->
pool_offset
=
p_off
;
// Mark all the elements as free
free_bitfield
=
(
int
*
)(
all
+
1
);
memset
((
void
*
)
free_bitfield
,
0
,
(
size
/
8
+
1
));
return
mz
;
}
void
*
udpdk_shmalloc
(
const
struct
rte_memzone
*
mz
)
{
struct
allocator
*
all
;
int
*
free_bitfield
;
unsigned
size
;
unsigned
p_off
;
unsigned
i
,
j
;
void
*
ret
;
all
=
(
struct
allocator
*
)(
void
*
)
mz
->
addr
;
free_bitfield
=
(
int
*
)(
all
+
1
);
if
(
all
->
n_free
==
0
)
{
RTE_LOG
(
WARNING
,
SHM
,
"shmalloc failed: out of memory
\n
"
);
return
NULL
;
}
size
=
all
->
size
;
p_off
=
all
->
pool_offset
;
// Compute and store the pointer to return
ret
=
((
void
*
)
mz
->
addr
+
p_off
+
(
all
->
next_free
*
all
->
elem_size
));
--
all
->
n_free
;
// Update the free bitfield
SetBit
(
free_bitfield
,
all
->
next_free
);
// Find the next free slot
if
(
all
->
n_free
!=
0
)
{
j
=
all
->
next_free
+
1
;
for
(
int
i
=
0
;
i
<
size
;
i
++
)
{
if
(
j
>=
size
)
{
j
=
0
;
}
if
(
!
TestBit
(
free_bitfield
,
j
))
{
all
->
next_free
=
j
;
break
;
}
++
j
;
}
}
return
ret
;
}
// NOTE: the memzone is only needed to check memory boundaries
void
udpdk_shfree
(
const
struct
rte_memzone
*
mz
,
void
*
addr
)
{
struct
allocator
*
all
;
int
*
free_bitfield
;
unsigned
p_off
;
unsigned
i
;
void
*
pool_start
;
void
*
pool_end
;
all
=
(
struct
allocator
*
)(
void
*
)
mz
->
addr
;
free_bitfield
=
(
int
*
)(
all
+
1
);
p_off
=
all
->
pool_offset
;
// Validate the address
pool_start
=
(
void
*
)
mz
->
addr
+
p_off
;
pool_end
=
((
void
*
)
mz
->
addr
+
p_off
+
(
all
->
size
*
all
->
elem_size
));
if
((
addr
<
pool_start
)
||
(
addr
>=
pool_end
))
{
RTE_LOG
(
WARNING
,
SHM
,
"Double free
\n
"
);
return
;
}
// Check if the memory was really allocated
i
=
(
addr
-
pool_start
)
/
all
->
elem_size
;
if
(
!
TestBit
(
free_bitfield
,
i
))
{
RTE_LOG
(
WARNING
,
SHM
,
"Double free
\n
"
);
return
;
}
// Free
ClearBit
(
free_bitfield
,
i
);
++
all
->
n_free
;
// If prevoiusly full, recompute next_free
if
(
all
->
n_free
==
1
)
{
all
->
next_free
=
i
;
}
}
void
udpdk_destroy_allocator
(
const
struct
rte_memzone
*
mz
)
{
const
struct
allocator
*
all
;
all
=
(
struct
allocator
*
)(
void
*
)
mz
->
addr
;
if
(
all
->
n_free
!=
all
->
size
)
{
RTE_LOG
(
WARNING
,
SHM
,
"Destroying shm allocator before all the elements were freed!
\n
"
);
}
rte_memzone_free
(
mz
);
}
udpdk/shmalloc/udpdk_shmalloc.h
0 → 100644
View file @
fa41ef71
//
// Created by leoll2 on 11/01/20.
// Copyright (c) 2020 Leonardo Lai. All rights reserved.
//
#ifndef UDPDK_SHMALLOC_H
#define UDPDK_SHMALLOC_H
#include <rte_compat.h>
#include <rte_memory.h>
#include <rte_common.h>
const
struct
rte_memzone
*
udpdk_init_allocator
(
const
char
*
name
,
unsigned
size
,
unsigned
elem_size
);
void
*
udpdk_shmalloc
(
const
struct
rte_memzone
*
mz
);
void
udpdk_shfree
(
const
struct
rte_memzone
*
mz
,
void
*
addr
);
void
udpdk_destroy_allocator
(
const
struct
rte_memzone
*
mz
);
#endif // UDPDK_SHMALLOC_H
udpdk/udpdk_bind_table.c
0 → 100644
View file @
fa41ef71
//
// Created by leoll2 on 9/27/20.
// Copyright (c) 2020 Leonardo Lai. All rights reserved.
//
// Data structure to hold (ip, port) pairs of bound sockets
// It is an array of size MAX_PORTS of lists; each list contains all
// the IPs bound to that port (typically one, but can be many)
//
#include "udpdk_bind_table.h"
void
*
bind_info_alloc
=
NULL
;
list_t
*
sock_bind_table
[
UDP_MAX_PORT
];
/* Initialize the bindings table */
inline
void
btable_init
(
void
)
{
// Create the allocator for bind_info elements
bind_info_alloc
=
udpdk_init_allocator
(
"list_t_alloc"
,
NUM_SOCKETS_MAX
,
sizeof
(
struct
bind_info
));
// All ports are initially free
for
(
unsigned
i
=
0
;
i
<
UDP_MAX_PORT
;
i
++
)
{
sock_bind_table
[
i
]
=
NULL
;
}
}
/* Get the index of a free port (-1 if none available) */
inline
int
btable_get_free_port
(
void
)
{
for
(
unsigned
i
=
0
;
i
<
UDP_MAX_PORT
;
i
++
)
{
if
(
sock_bind_table
[
i
]
==
NULL
)
{
return
i
;
}
}
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
)
{
bool
reuse_addr
=
opts
&
SO_REUSEADDR
;
bool
reuse_port
=
opts
&
SO_REUSEPORT
;
bool
can_bind
=
true
;
list_iterator_t
*
it
;
list_node_t
*
node
;
unsigned
long
ip_oth
,
ip_new
;
int
opts_oth
;
if
(
sock_bind_table
[
port
]
==
NULL
)
{
return
0
;
}
ip_new
=
ip
.
s_addr
;
it
=
list_iterator_new
(
sock_bind_table
[
port
],
LIST_HEAD
);
while
((
node
=
list_iterator_next
(
it
)))
{
ip_oth
=
node
->
val
.
ip_addr
.
s_addr
;
opts_oth
=
node
->
val
.
opts
;
// If different, and none is INADDR_ANY, continue
if
((
ip_oth
!=
ip_new
)
&&
(
ip_oth
!=
INADDR_ANY
)
&&
(
ip_new
!=
INADDRY_ANY
))
{
continue
;
}
// If different, one is INADDR_ANY, and the new has SO_REUSEADDR or SO_REUSEPORT, continue
if
((
ip_oth
!=
ip_new
)
&&
((
ip_oth
==
INADDR_ANY
)
||
(
ip_new
!=
INADDRY_ANY
))
&&
((
opts
&
SO_REUSEADDR
)
||
(
opts
&
SO_REUSEPORT
)))
{
continue
;
}
// If same, not INADDR_ANY and both have SO_REUSEPORT, continue
if
((
ip_oth
==
ip_new
)
&&
(
ip_new
!=
INADDR_ANY
)
&&
(
opts
&
SO_REUSEPORT
)
&&
(
ops_oth
&
SO_REUSEPORT
))
{
continue
;
}
can_bind
=
false
;
break
;
}
list_iterator_destroy
(
it
);
if
(
can_bind
)
{
return
0
;
}
else
{
return
-
1
;
}
}
inline
int
btable_add_binding
(
int
s
,
struct
in_addr
ip
,
int
port
,
int
opts
)
{
struct
bind_info
*
b
;
list_node_t
*
ln
;
// Check if binding this pair is allowed
if
(
!
btable_can_bind
(
ip
,
port
,
opts
))
{
return
-
1
;
}
// Allocate the list if missing
if
(
sock_bind_table
[
port
]
==
NULL
)
{
sock_bind_table
[
port
]
=
list_new
();
}
// Allocate and setup a new bind_info element
b
=
(
struct
bind_info
)
udpdk_shmalloc
(
bind_info_alloc
);
b
->
sockfd
=
s
;
b
->
ip_addr
=
ip
;
b
->
reuse_addr
=
opts
&
SO_REUSEADDR
;
b
->
reuse_port
=
opts
&
SO_REUSEPORT
;
b
->
closed
=
false
;
// Insert the bind_info in the list
ln
=
list_node_new
(
b
);
if
(
ip
.
s_addr
==
INADDR_ANY
)
{
list_lpush
(
sock_bind_table
[
port
],
ln
);
}
else
{
list_rpush
(
sock_bind_table
[
port
],
ln
);
}
}
/* Remove a binding from the port */
void
btable_del_binding
(
int
s
,
int
port
)
{
// TODO rimuovi dalla lista
// TODO free bind_info memory
// TODO se la lista è vuota, dealloca la lista -> porta torna libera
}
/* Get all the bind_info descriptors of the sockets bound to the given port */
list_t
*
btable_get_bindings
(
int
port
)
{
return
sock_bind_table
[
port
];
}
udpdk/udpdk_
lookup
_table.h
→
udpdk/udpdk_
bind
_table.h
View file @
fa41ef71
...
...
@@ -3,16 +3,13 @@
// Copyright (c) 2020 Leonardo Lai. All rights reserved.
//
#ifndef UDPDK_
LOOKUP
_TABLE_H
#define UDPDK_
LOOKUP
_TABLE_H
#ifndef UDPDK_
BIND
_TABLE_H
#define UDPDK_
BIND
_TABLE_H
#include "udpdk_constants.h"
#include "udpdk_types.h"
typedef
struct
htable_item
{
int
key
;
int
val
;
}
htable_item
;
/*
void htable_init(htable_item *table);
int htable_insert(htable_item *table, int key, int val);
...
...
@@ -20,5 +17,16 @@ int htable_insert(htable_item *table, int key, int val);
int htable_lookup(htable_item *table, int key);
int htable_delete(htable_item *table, int key);
*/
void
btable_init
(
void
);
int
btable_get_free_port
(
void
);
int
btable_add_binding
(
int
s
,
struct
in_addr
ip
,
int
port
,
int
opts
);
void
btable_del_binding
(
int
s
,
int
port
);
list_t
*
btable_get_bindings
(
int
port
);
#endif //UDPDK_
LOOKUP
_TABLE_H
#endif //UDPDK_
BIND
_TABLE_H
udpdk/udpdk_constants.h
View file @
fa41ef71
...
...
@@ -10,6 +10,7 @@
#define MIN(a,b) ((a) < (b) ? a : b)
#define NUM_SOCKETS_MAX 1024
#define UDP_MAX_PORT 65536
/* DPDK ports */
#define PORT_RX 0
...
...
udpdk/udpdk_globals.c
View file @
fa41ef71
...
...
@@ -27,8 +27,6 @@ struct rte_mempool *tx_pktmbuf_direct_pool = NULL;
struct
rte_mempool
*
tx_pktmbuf_indirect_pool
=
NULL
;
htable_item
*
udp_port_table
=
NULL
;
struct
exch_zone_info
*
exch_zone_desc
=
NULL
;
struct
exch_slot
*
exch_slots
=
NULL
;
\ No newline at end of file
struct
exch_slot
*
exch_slots
=
NULL
;
udpdk/udpdk_init.c
View file @
fa41ef71
...
...
@@ -20,6 +20,7 @@
#include <rte_memory.h>
#include <rte_memzone.h>
#include "list.h"
#include "udpdk_api.h"
#include "udpdk_args.h"
#include "udpdk_constants.h"
...
...
@@ -34,7 +35,6 @@
extern
int
interrupted
;
extern
struct
exch_zone_info
*
exch_zone_desc
;
extern
struct
exch_slot
*
exch_slots
;
extern
htable_item
*
udp_port_table
;
extern
struct
rte_mempool
*
rx_pktmbuf_pool
;
extern
struct
rte_mempool
*
tx_pktmbuf_pool
;
extern
struct
rte_mempool
*
tx_pktmbuf_direct_pool
;
...
...
@@ -303,6 +303,9 @@ int udpdk_init(int argc, char *argv[])
return
-
1
;
}
// Initialize the list allocators
udpdk_list_init
();
// Initialize pools of mbuf
retval
=
init_mbuf_pools
();
if
(
retval
<
0
)
{
...
...
@@ -385,4 +388,6 @@ void udpdk_cleanup(void)
rte_eth_dev_stop
(
port_id
);
rte_eth_dev_close
(
port_id
);
}
}
\ No newline at end of file
udpdk_list_deinit
();
}
udpdk/udpdk_lookup_table.c
deleted
100644 → 0
View file @
841b83bc
//
// Created by leoll2 on 9/27/20.
// Copyright (c) 2020 Leonardo Lai. All rights reserved.
//
// Simple hashmap with fixed size, useful to implement L4 port switching.
// Keys and values must be non-negative integers (-1 is reserved for 'empty')
//
#include "udpdk_lookup_table.h"
#define h(x) (9649 * x % NUM_SOCKETS_MAX)
void
htable_init
(
htable_item
*
table
)
{
for
(
int
i
=
0
;
i
<
NUM_SOCKETS_MAX
;
i
++
)
{
table
[
i
].
key
=
-
1
;
}
}
static
inline
int
htable_get_idx
(
htable_item
*
table
,
int
key
)
{
int
i
=
h
(
key
);
int
free_idx
=
-
1
;
int
scanned
=
0
;
// find a free slot (linear probing starting from hashed index)
while
((
table
[
i
].
key
!=
key
)
&&
(
++
scanned
<
NUM_SOCKETS_MAX
))
{
if
(
free_idx
==
-
1
&&
table
[
i
].
key
==
-
1
)
{
// store the first free index
free_idx
=
i
;
}
i
++
;
if
(
i
==
NUM_SOCKETS_MAX
)
{
i
=
0
;
}
}
// table is full
if
(
scanned
==
NUM_SOCKETS_MAX
)
{
return
free_idx
;
}
return
i
;
}
inline
int
htable_insert
(
htable_item
*
table
,
int
key
,
int
val
)
{
int
i
=
htable_get_idx
(
table
,
key
);
if
(
i
==
-
1
)
{
// full
return
-
1
;
}
table
[
i
].
key
=
key
;
table
[
i
].
val
=
val
;
return
0
;
}
inline
int
htable_delete
(
htable_item
*
table
,
int
key
)
{
int
i
=
htable_get_idx
(
table
,
key
);
if
(
i
==
-
1
)
{
// not found (table full)
return
-
1
;
}
else
if
(
table
[
i
].
key
==
-
1
)
{
// not found (table not full)
return
-
1
;
}
else
{
// remove
table
[
i
].
key
=
-
1
;
return
0
;
}
}
inline
int
htable_lookup
(
htable_item
*
table
,
int
key
)
{
int
i
=
htable_get_idx
(
table
,
key
);
if
(
i
==
-
1
)
{
// not found (table full)
return
-
1
;
}
else
if
(
table
[
i
].
key
==
-
1
)
{
// not found (table not full)
return
-
1
;
}
else
{
return
table
[
i
].
val
;
}
}
udpdk/udpdk_types.h
View file @
fa41ef71
...
...
@@ -22,9 +22,18 @@
#include <unistd.h>
#include "udpdk_constants.h"
#include "list.h"
enum
exch_ring_func
{
EXCH_RING_RX
,
EXCH_RING_TX
};
struct
bind_info
{
int
sockfd
;
// socket fd of the (addr, port) pair
struct
in_addr
ip_addr
;
// IPv4 address associated to the socket
bool
reuse_addr
;
// SO_REUSEADDR
bool
reuse_port
;
// SO_REUSEPORT
bool
closed
;
// mark this binding as closed
};
struct
exch_slot_info
{
int
used
;
// used by an open socket
int
bound
;
// used by a socket that did 'bind'
...
...
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