Skip to content

Commit 400ae12

Browse files
committed
pfcp: Support pfcp-peer-list
Initial support to fast restart mecanism. While restarting UPF function, pfcp association are done. In basic mode of operations, pfcp association are initiated by SMF, but it can delay bootstrap delay to the time intiial association is setup. This extension make it faster by initiating pfcp association to remote SMF if specified. Signed-off-by: Alexandre Cassen <acassen@gmail.com>
1 parent 7cbc3f8 commit 400ae12

File tree

9 files changed

+231
-4
lines changed

9 files changed

+231
-4
lines changed

lib/command.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ enum node_type {
5757
CDR_NODE, /* CDR commands. */
5858
GTP_PROXY_NODE, /* GTP Proxy commands. */
5959
GTP_ROUTER_NODE, /* GTP Router commands. */
60+
PFCP_PEER_LIST_NODE, /* PFCP Peer List commands. */
6061
PFCP_PROXY_NODE, /* PFCP Proxy commands. */
6162
PFCP_ROUTER_NODE, /* PFCP Router commands. */
6263

src/gtp_data.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ alloc_daemon_data(void)
5858
INIT_LIST_HEAD(&new->gtp_cdr);
5959
INIT_LIST_HEAD(&new->gtp_proxy_ctx);
6060
INIT_LIST_HEAD(&new->gtp_router_ctx);
61+
INIT_LIST_HEAD(&new->pfcp_peers);
6162
INIT_LIST_HEAD(&new->pfcp_router_ctx);
6263
gtp_bpf_progs_init();
6364
pppoe_init();

src/include/gtp_data.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ struct data {
5353
struct list_head gtp_cdr;
5454
struct list_head gtp_proxy_ctx;
5555
struct list_head gtp_router_ctx;
56+
struct list_head pfcp_peers;;
5657
struct list_head pfcp_router_ctx;;
5758

5859
unsigned long flags;

src/pfcp/include/pfcp_assoc.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
#include "gtp_stddef.h"
2626
#include "pfcp_ie.h"
2727
#include "list_head.h"
28+
#include "addr.h"
2829
#include "vty.h"
2930

3031
/* Hash table */

src/pfcp/include/pfcp_router.h

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
#include "gtp_bpf_prog.h"
2828

2929
#define PFCP_ROUTER_DELAYED 2
30+
#define PFCP_PEER_MAX 16
3031

3132
enum pfcp_flags {
3233
PFCP_ROUTER_FL_LISTEN,
@@ -71,7 +72,21 @@ struct pfcp_router {
7172
struct list_head next;
7273
};
7374

75+
struct pfcp_peer_list {
76+
char name[GTP_NAME_MAX_LEN];
77+
char description[GTP_STR_MAX_LEN];
78+
union addr addr[PFCP_PEER_MAX];
79+
int nr_addr;
80+
81+
struct list_head next;
82+
};
83+
84+
7485
/* Prototypes */
86+
struct pfcp_peer_list *pfcp_peer_list_get(const char *name);
87+
struct pfcp_peer_list *pfcp_peer_list_alloc(const char *name);
88+
void pfcp_peer_list_ctx_destroy(struct pfcp_peer_list *ctx);
89+
void pfcp_peer_list_destroy(void);
7590
int pfcp_gtpu_ingress_init(struct inet_server *srv);
7691
int pfcp_gtpu_ingress_process(struct inet_server *srv,
7792
struct sockaddr_storage *addr_from);

src/pfcp/pfcp.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ pfcp_init(void)
3838
int
3939
pfcp_destroy(void)
4040
{
41+
pfcp_peer_list_destroy();
4142
pfcp_assoc_destroy();
4243
pfcp_router_destroy();
4344
pfcp_sessions_destroy();

src/pfcp/pfcp_bpf.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -496,7 +496,7 @@ static struct gtp_bpf_prog_tpl pfcp_bpf_tpl = {
496496
};
497497

498498
static void __attribute__((constructor))
499-
gtp_bpf_fwd_init(void)
499+
pfcp_bpf_init(void)
500500
{
501501
gtp_bpf_prog_tpl_register(&pfcp_bpf_tpl);
502502
}

src/pfcp/pfcp_router.c

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,58 @@ extern struct data *daemon_data;
3838
extern struct thread_master *master;
3939

4040

41+
/*
42+
* PFCP Peer utilities
43+
*/
44+
struct pfcp_peer_list *
45+
pfcp_peer_list_get(const char *name)
46+
{
47+
struct pfcp_peer_list *p;
48+
size_t len = strlen(name);
49+
50+
list_for_each_entry(p, &daemon_data->pfcp_peers, next) {
51+
if (!strncmp(p->name, name, len))
52+
return p;
53+
}
54+
55+
return NULL;
56+
}
57+
58+
struct pfcp_peer_list *
59+
pfcp_peer_list_alloc(const char *name)
60+
{
61+
struct pfcp_peer_list *new;
62+
63+
PMALLOC(new);
64+
if (!new) {
65+
errno = ENOMEM;
66+
return NULL;
67+
}
68+
INIT_LIST_HEAD(&new->next);
69+
bsd_strlcpy(new->name, name, GTP_NAME_MAX_LEN - 1);
70+
71+
list_add_tail(&new->next, &daemon_data->pfcp_peers);
72+
73+
return new;
74+
}
75+
76+
void
77+
pfcp_peer_list_ctx_destroy(struct pfcp_peer_list *p)
78+
{
79+
list_del(&p->next);
80+
FREE(p);
81+
}
82+
83+
void
84+
pfcp_peer_list_destroy(void)
85+
{
86+
struct pfcp_peer_list *p, *_p;
87+
88+
list_for_each_entry_safe(p, _p, &daemon_data->pfcp_peers, next)
89+
pfcp_peer_list_ctx_destroy(p);
90+
}
91+
92+
4193
/*
4294
* Helpers
4395
*/

src/pfcp/pfcp_router_vty.c

Lines changed: 158 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626
#include "gtp_data.h"
2727
#include "gtp.h"
2828
#include "gtp_bpf_utils.h"
29-
#include "include/pfcp_router.h"
29+
#include "pfcp_router.h"
3030
#include "inet_server.h"
3131
#include "pfcp_assoc.h"
3232
#include "pfcp.h"
@@ -60,7 +60,7 @@ DEFUN(pfcp_router,
6060
new = pfcp_router_get(argv[0]);
6161
new = (new) ? : pfcp_router_alloc(argv[0]);
6262
if (!new) {
63-
vty_out(vty, "%% Error allocating pfcp-router:%s !!!%s"
63+
vty_out(vty, "%% Error allocating pfcp-router:'%s' !!!%s"
6464
, argv[0], VTY_NEWLINE);
6565
return CMD_WARNING;
6666
}
@@ -86,7 +86,7 @@ DEFUN(no_pfcp_router,
8686
/* Already existing ? */
8787
c = pfcp_router_get(argv[0]);
8888
if (!c) {
89-
vty_out(vty, "%% unknown gtp-router %s%s", argv[0], VTY_NEWLINE);
89+
vty_out(vty, "%% unknown pfcp-router:'%s'%s", argv[0], VTY_NEWLINE);
9090
return CMD_WARNING;
9191
}
9292

@@ -455,6 +455,109 @@ DEFUN(show_pfcp_assoc,
455455
}
456456

457457

458+
/*
459+
* PFCP Peers command
460+
*/
461+
DEFUN(pfcp_peer_list,
462+
pfcp_peer_list_cmd,
463+
"pfcp-peer-list STRING",
464+
"Configure PFCP Peer List\n"
465+
"PFCP Peer list Name")
466+
{
467+
struct pfcp_peer_list *new;
468+
469+
if (argc < 1) {
470+
vty_out(vty, "%% missing arguments%s", VTY_NEWLINE);
471+
return CMD_WARNING;
472+
}
473+
474+
/* Already existing ? */
475+
new = pfcp_peer_list_get(argv[0]);
476+
new = (new) ? : pfcp_peer_list_alloc(argv[0]);
477+
if (!new) {
478+
vty_out(vty, "%% Error allocating pfcp-peer:'%s' !!!%s"
479+
, argv[0], VTY_NEWLINE);
480+
return CMD_WARNING;
481+
}
482+
483+
vty->node = PFCP_ROUTER_NODE;
484+
vty->index = new;
485+
return CMD_SUCCESS;
486+
}
487+
488+
DEFUN(no_pfcp_peer_list,
489+
no_pfcp_peer_list_cmd,
490+
"no pfcp-peer-list STRING",
491+
"Destroy PFCP Peer List\n"
492+
"PFCP Peer list Name")
493+
{
494+
struct pfcp_peer_list *p;
495+
496+
if (argc < 1) {
497+
vty_out(vty, "%% missing arguments%s", VTY_NEWLINE);
498+
return CMD_WARNING;
499+
}
500+
501+
/* Already existing ? */
502+
p = pfcp_peer_list_get(argv[0]);
503+
if (!p) {
504+
vty_out(vty, "%% unknown pfcp-peer:'%s'%s", argv[0], VTY_NEWLINE);
505+
return CMD_WARNING;
506+
}
507+
508+
pfcp_peer_list_ctx_destroy(p);
509+
510+
return CMD_SUCCESS;
511+
}
512+
513+
DEFUN(pfcp_peer_list_desciption,
514+
pfcp_peer_list_description_cmd,
515+
"description STRING",
516+
"Set PFCP Peer list description\n"
517+
"description\n")
518+
{
519+
struct pfcp_peer_list *p = vty->index;
520+
521+
snprintf(p->description, sizeof(p->description), "%s", argv[0]);
522+
523+
return CMD_SUCCESS;
524+
}
525+
526+
DEFUN(pfcp_peer,
527+
pfcp_peer_cmd,
528+
"peer STRING",
529+
"Create a PFCP Peer\n"
530+
"PFCP Peer")
531+
{
532+
struct pfcp_peer_list *p = vty->index;
533+
int err;
534+
535+
if (argc < 1) {
536+
vty_out(vty, "%% missing arguments%s", VTY_NEWLINE);
537+
return CMD_WARNING;
538+
}
539+
540+
err = addr_parse(argv[0], &p->addr[p->nr_addr]);
541+
if (err) {
542+
vty_out(vty, "%% invalid peer:'%s'%s", argv[0], VTY_NEWLINE);
543+
return CMD_WARNING;
544+
}
545+
546+
switch (p->addr[p->nr_addr].family) {
547+
case AF_INET:
548+
if (!p->addr[p->nr_addr].sin.sin_port)
549+
p->addr[p->nr_addr].sin.sin_port = htons(PFCP_PORT);
550+
case AF_INET6:
551+
if (!p->addr[p->nr_addr].sin6.sin6_port)
552+
p->addr[p->nr_addr].sin6.sin6_port = htons(PFCP_PORT);
553+
}
554+
555+
p->nr_addr++;
556+
557+
return CMD_SUCCESS;
558+
}
559+
560+
458561
/* Show */
459562
DEFUN(show_pfcp_bpf,
460563
show_pfcp_bpf_cmd,
@@ -543,6 +646,30 @@ config_pfcp_router_write(struct vty *vty)
543646
return CMD_SUCCESS;
544647
}
545648

649+
static int
650+
config_pfcp_peer_list_write(struct vty *vty)
651+
{
652+
struct list_head *l = &daemon_data->pfcp_peers;
653+
struct pfcp_peer_list *p;
654+
char addr_str[64];
655+
int i;
656+
657+
list_for_each_entry(p, l, next) {
658+
vty_out(vty, "pfcp-peer-list %s%s", p->name, VTY_NEWLINE);
659+
if (p->description[0])
660+
vty_out(vty, " description %s%s"
661+
, p->description, VTY_NEWLINE);
662+
for (i = 0; i < p->nr_addr; i++) {
663+
vty_out(vty, " peer %s%s"
664+
, addr_stringify(&p->addr[i], addr_str, sizeof(addr_str))
665+
, VTY_NEWLINE);
666+
}
667+
668+
}
669+
670+
return 0;
671+
}
672+
546673

547674
/*
548675
* VTY init
@@ -576,6 +703,21 @@ cmd_ext_pfcp_router_install(void)
576703
return 0;
577704
}
578705

706+
static int
707+
cmd_ext_pfcp_peer_install(void)
708+
{
709+
/* Install PFCP Router commands. */
710+
install_element(CONFIG_NODE, &pfcp_peer_list_cmd);
711+
install_element(CONFIG_NODE, &no_pfcp_peer_list_cmd);
712+
713+
install_default(PFCP_PEER_LIST_NODE);
714+
install_element(PFCP_PEER_LIST_NODE, &pfcp_peer_list_description_cmd);
715+
install_element(PFCP_PEER_LIST_NODE, &pfcp_peer_cmd);
716+
717+
return 0;
718+
}
719+
720+
579721
struct cmd_node pfcp_router_node = {
580722
.node = PFCP_ROUTER_NODE,
581723
.parent_node = CONFIG_NODE,
@@ -588,8 +730,21 @@ static struct cmd_ext cmd_ext_pfcp_router = {
588730
.install = cmd_ext_pfcp_router_install,
589731
};
590732

733+
struct cmd_node pfcp_peer_list_node = {
734+
.node = PFCP_PEER_LIST_NODE,
735+
.parent_node = CONFIG_NODE,
736+
.prompt ="%s(pfcp-peer-list)# ",
737+
.config_write = config_pfcp_peer_list_write,
738+
};
739+
740+
static struct cmd_ext cmd_ext_pfcp_peer_list = {
741+
.node = &pfcp_peer_list_node,
742+
.install = cmd_ext_pfcp_peer_install,
743+
};
744+
591745
static void __attribute__((constructor))
592746
pfcp_router_vty_init(void)
593747
{
594748
cmd_ext_register(&cmd_ext_pfcp_router);
749+
cmd_ext_register(&cmd_ext_pfcp_peer_list);
595750
}

0 commit comments

Comments
 (0)