diff --git a/src/gtp_router_hdl.c b/src/gtp_router_hdl.c index 5216120..ff5e59a 100644 --- a/src/gtp_router_hdl.c +++ b/src/gtp_router_hdl.c @@ -1077,7 +1077,7 @@ gtpc_change_notification_request_hdl(gtp_server_worker_t *w, struct sockaddr_sto */ static const struct { int (*hdl) (gtp_server_worker_t *, struct sockaddr_storage *); -} gtpc_msg_hdl[0xff] = { +} gtpc_msg_hdl[0xff + 1] = { [GTP_ECHO_REQUEST_TYPE] = { gtpc_echo_request_hdl }, [GTP_CREATE_SESSION_REQUEST_TYPE] = { gtpc_create_session_request_hdl }, [GTP_DELETE_SESSION_REQUEST_TYPE] = { gtpc_delete_session_request_hdl }, @@ -1142,7 +1142,7 @@ gtpu_end_marker_hdl(gtp_server_worker_t *w, struct sockaddr_storage *addr) static const struct { int (*hdl) (gtp_server_worker_t *, struct sockaddr_storage *); -} gtpu_msg_hdl[0xff] = { +} gtpu_msg_hdl[0xff + 1] = { [GTPU_ECHO_REQ_TYPE] = { gtpu_echo_request_hdl }, [GTPU_ERR_IND_TYPE] = { gtpu_error_indication_hdl }, [GTPU_END_MARKER_TYPE] = { gtpu_end_marker_hdl }, diff --git a/src/gtp_router_vty.c b/src/gtp_router_vty.c index 0df643c..7b8630e 100644 --- a/src/gtp_router_vty.c +++ b/src/gtp_router_vty.c @@ -189,9 +189,9 @@ DEFUN(gtpu_router_tunnel_endpoint, static int gtp_config_write(vty_t *vty) { - list_head_t *l = &daemon_data->gtp_router_ctx; - gtp_server_t *srv; - gtp_router_t *ctx; + list_head_t *l = &daemon_data->gtp_router_ctx; + gtp_server_t *srv; + gtp_router_t *ctx; list_for_each_entry(ctx, l, next) { vty_out(vty, "gtp-router %s%s", ctx->name, VTY_NEWLINE); diff --git a/src/gtp_session.c b/src/gtp_session.c index 521b943..a074d7b 100644 --- a/src/gtp_session.c +++ b/src/gtp_session.c @@ -472,7 +472,7 @@ __gtp_session_teid_up_vty(vty_t *vty, list_head_t *l) " bearer-id:0x%.2x remote_ipaddr:%u.%u.%u.%u%s" , ntohl(t->id), t->bearer_id, NIPQUAD(t->ipv4) , VTY_NEWLINE); - gtp_xdp_rt_teid_vty(vty, ntohl(t->id)); + gtp_xdp_rt_teid_vty(vty, t); } } return 0; diff --git a/src/gtp_switch_hdl.c b/src/gtp_switch_hdl.c index 1ba41e7..41b3980 100644 --- a/src/gtp_switch_hdl.c +++ b/src/gtp_switch_hdl.c @@ -259,7 +259,7 @@ gtpu_end_marker_hdl(gtp_server_worker_t *w, struct sockaddr_storage *addr) static const struct { gtp_teid_t * (*hdl) (gtp_server_worker_t *, struct sockaddr_storage *); -} gtpu_msg_hdl[0xff] = { +} gtpu_msg_hdl[0xff + 1] = { [GTPU_ECHO_REQ_TYPE] = { gtpu_echo_request_hdl }, [GTPU_ERR_IND_TYPE] = { gtpu_error_indication_hdl }, [GTPU_END_MARKER_TYPE] = { gtpu_end_marker_hdl }, diff --git a/src/gtp_switch_hdl_v1.c b/src/gtp_switch_hdl_v1.c index db9cf9d..90e7e69 100644 --- a/src/gtp_switch_hdl_v1.c +++ b/src/gtp_switch_hdl_v1.c @@ -689,7 +689,7 @@ gtp1_delete_pdp_response_hdl(gtp_server_worker_t *w, struct sockaddr_storage *ad static const struct { uint8_t family; /* GTP_INIT : Initial | GTP_TRIG : Triggered*/ gtp_teid_t * (*hdl) (gtp_server_worker_t *, struct sockaddr_storage *); -} gtpc_msg_hdl[0xff] = { +} gtpc_msg_hdl[0xff + 1] = { [GTP_ECHO_REQUEST_TYPE] = { GTP_INIT, gtp1_echo_request_hdl }, [GTP_CREATE_PDP_CONTEXT_REQUEST] = { GTP_INIT, gtp1_create_pdp_request_hdl }, [GTP_CREATE_PDP_CONTEXT_RESPONSE] = { GTP_TRIG, gtp1_create_pdp_response_hdl }, diff --git a/src/gtp_switch_hdl_v2.c b/src/gtp_switch_hdl_v2.c index 5c62a32..f8b068f 100644 --- a/src/gtp_switch_hdl_v2.c +++ b/src/gtp_switch_hdl_v2.c @@ -1053,7 +1053,7 @@ static const struct { uint8_t family; /* GTP_INIT : Initial | GTP_TRIG : Triggered*/ int direction; /* GTP_INGRESS : sGW -> pGW | GTP_EGRESS : pGW -> sGW */ gtp_teid_t * (*hdl) (gtp_server_worker_t *, struct sockaddr_storage *, int); -} gtpc_msg_hdl[0xff] = { +} gtpc_msg_hdl[0xff + 1] = { [GTP_ECHO_REQUEST_TYPE] = { GTP_INIT, GTP_INGRESS, gtpc_echo_request_hdl }, [GTP_CREATE_SESSION_REQUEST_TYPE] = { GTP_INIT, GTP_INGRESS, gtpc_create_session_request_hdl }, [GTP_CREATE_SESSION_RESPONSE_TYPE] = { GTP_TRIG, GTP_EGRESS, gtpc_create_session_response_hdl }, diff --git a/src/gtp_xdp_ppp.c b/src/gtp_xdp_ppp.c index 0ac741e..ef82885 100644 --- a/src/gtp_xdp_ppp.c +++ b/src/gtp_xdp_ppp.c @@ -136,7 +136,7 @@ gtp_xdp_ppp_key_set(gtp_teid_t *t, struct ppp_key *ppp_k, spppoe_t *spppoe) } static int -gtp_xdp_ppp_map_action(int action, gtp_teid_t *t, struct bpf_map *map) +gtp_xdp_ppp_map_action(struct bpf_map *map, int action, gtp_teid_t *t) { gtp_session_t *s = t->session; spppoe_t *spppoe = s->s_pppoe; @@ -205,6 +205,84 @@ gtp_xdp_ppp_map_action(int action, gtp_teid_t *t, struct bpf_map *map) return err; } +static int +gtp_xdp_teid_vty(struct bpf_map *map, vty_t *vty, gtp_teid_t *t) +{ + unsigned int nr_cpus = bpf_num_possible_cpus(); + gtp_session_t *s = t->session; + spppoe_t *spppoe = s->s_pppoe; + struct ip_rt_key rt_k = { 0 }; + struct ppp_key ppp_k = { 0 }, next_ppp_k = { 0 }; + struct gtp_rt_rule *r; + char errmsg[GTP_XDP_STRERR_BUFSIZE]; + int err = 0, i; + uint64_t packets, bytes; + size_t sz; + + /* Allocate temp rule */ + r = gtp_xdp_ppp_rule_alloc(&sz); + if (!r) { + vty_out(vty, "%% Cant allocate temp rt_rule%s", VTY_NEWLINE); + return -1; + } + + if (t) { + if (__test_bit(GTP_TEID_FL_EGRESS, &t->flags)) { + gtp_xdp_rt_key_set(t, &rt_k); + err = bpf_map__lookup_elem(map, &rt_k, sizeof(struct ip_rt_key), r, sz, 0); + } else { + gtp_xdp_ppp_key_set(t, &ppp_k, spppoe); + err = bpf_map__lookup_elem(map, &ppp_k, sizeof(struct ppp_key), r, sz, 0); + } + + if (err) { + libbpf_strerror(err, errmsg, GTP_XDP_STRERR_BUFSIZE); + vty_out(vty, " %% No data-plane ?! (%s)%s", errmsg, VTY_NEWLINE); + goto end; + } + + packets = bytes = 0; + for (i = 0; i < nr_cpus; i++) { + packets += r[i].packets; + bytes += r[i].bytes; + } + + vty_out(vty, " %.7s pkts:%ld bytes:%ld%s" + , __test_bit(GTP_TEID_FL_EGRESS, &t->flags) ? "egress" : "ingress" + , packets, bytes, VTY_NEWLINE); + goto end; + } + + /* ingress hashtab */ + while (bpf_map__get_next_key(map, &ppp_k, &next_ppp_k, sizeof(struct ppp_key)) == 0) { + ppp_k = next_ppp_k; + err = bpf_map__lookup_elem(map, &ppp_k, sizeof(struct ppp_key), r, sz, 0); + if (err) { + libbpf_strerror(err, errmsg, GTP_XDP_STRERR_BUFSIZE); + vty_out(vty, "%% error fetching value for session:0x%.4x (%s)%s" + , ppp_k.session_id, errmsg, VTY_NEWLINE); + continue; + } + + packets = bytes = 0; + for (i = 0; i < nr_cpus; i++) { + packets += r[i].packets; + bytes += r[i].bytes; + } + + vty_out(vty, "| 0x%.8x | %.2x:%.2x:%.2x:%.2x:%.2x:%.2x| %9s | %12ld | %19ld |%s" + , ntohl(r[0].teid) + , r[0].h_dst[0], r[0].h_dst[1], r[0].h_dst[2] + , r[0].h_dst[3], r[0].h_dst[4], r[0].h_dst[5] + , "ingress" + , packets, bytes + , VTY_NEWLINE); + } + end: + free(r); + return 0; +} + int gtp_xdp_ppp_action(int action, gtp_teid_t *t, struct bpf_map *map_ingress, struct bpf_map *map_egress) @@ -212,10 +290,36 @@ gtp_xdp_ppp_action(int action, gtp_teid_t *t, struct bpf_map *map_ppp_ingress = xdp_ppp_maps[XDP_RT_MAP_PPP_INGRESS].map; if (__test_bit(GTP_TEID_FL_EGRESS, &t->flags)) - return gtp_xdp_ppp_map_action(action, t, map_egress); + return gtp_xdp_ppp_map_action(map_egress, action, t); + + if (__test_bit(GTP_FL_PPP_INGRESS_LOADED_BIT, &daemon_data->flags)) + return gtp_xdp_ppp_map_action(map_ppp_ingress, action, t); + + return gtp_xdp_ppp_map_action(map_ingress, action, t); +} + +int +gtp_xdp_ppp_teid_vty(vty_t *vty, gtp_teid_t *t, + struct bpf_map *map_ingress, struct bpf_map *map_egress) +{ + struct bpf_map *map_ppp_ingress = xdp_ppp_maps[XDP_RT_MAP_PPP_INGRESS].map; + + if (__test_bit(GTP_TEID_FL_EGRESS, &t->flags)) + return gtp_xdp_teid_vty(map_egress, vty, t); + + if (__test_bit(GTP_FL_PPP_INGRESS_LOADED_BIT, &daemon_data->flags)) + return gtp_xdp_teid_vty(map_ppp_ingress, vty, t); + + return gtp_xdp_teid_vty(map_ingress, vty, t); +} + +int +gtp_xdp_ppp_vty(vty_t *vty, struct bpf_map *map_ingress) +{ + struct bpf_map *map_ppp_ingress = xdp_ppp_maps[XDP_RT_MAP_PPP_INGRESS].map; if (__test_bit(GTP_FL_PPP_INGRESS_LOADED_BIT, &daemon_data->flags)) - return gtp_xdp_ppp_map_action(action, t, map_ppp_ingress); + return gtp_xdp_teid_vty(map_ppp_ingress, vty, NULL); - return gtp_xdp_ppp_map_action(action, t, map_ingress); + return gtp_xdp_teid_vty(map_ingress, vty, NULL); } \ No newline at end of file diff --git a/src/gtp_xdp_rt.c b/src/gtp_xdp_rt.c index 8cfbbdb..a0d0856 100644 --- a/src/gtp_xdp_rt.c +++ b/src/gtp_xdp_rt.c @@ -175,7 +175,7 @@ gtp_xdp_rt_key_set(gtp_teid_t *t, struct ip_rt_key *rt_key) } static int -gtp_xdp_rt_action(int action, gtp_teid_t *t, struct bpf_map *map) +gtp_xdp_rt_action(struct bpf_map *map, int action, gtp_teid_t *t) { struct gtp_rt_rule *new = NULL; char errmsg[GTP_XDP_STRERR_BUFSIZE]; @@ -231,14 +231,14 @@ gtp_xdp_rt_action(int action, gtp_teid_t *t, struct bpf_map *map) } static int -gtp_xdp_teid_vty(struct bpf_map *map, vty_t *vty, __be32 id) +gtp_xdp_teid_vty(struct bpf_map *map, vty_t *vty, gtp_teid_t *t) { unsigned int nr_cpus = bpf_num_possible_cpus(); struct ip_rt_key key = { 0 }, next_key = { 0 }; struct gtp_rt_rule *r; char errmsg[GTP_XDP_STRERR_BUFSIZE]; char addr_ip[16]; - int err = 0, i; + int err = 0, i; uint64_t packets, bytes; size_t sz; @@ -249,6 +249,28 @@ gtp_xdp_teid_vty(struct bpf_map *map, vty_t *vty, __be32 id) return -1; } + if (t) { + gtp_xdp_rt_key_set(t, &key); + err = bpf_map__lookup_elem(map, &key, sizeof(struct ip_rt_key), r, sz, 0); + if (err) { + libbpf_strerror(err, errmsg, GTP_XDP_STRERR_BUFSIZE); + vty_out(vty, " %% No data-plane ?! (%s)%s", errmsg, VTY_NEWLINE); + goto end; + } + + packets = bytes = 0; + for (i = 0; i < nr_cpus; i++) { + packets += r[i].packets; + bytes += r[i].bytes; + } + + vty_out(vty, " %.7s pkts:%ld bytes:%ld%s" + , __test_bit(GTP_TEID_FL_EGRESS, &t->flags) ? "egress" : "ingress" + , packets, bytes, VTY_NEWLINE); + + goto end; + } + /* Walk hashtab */ while (bpf_map__get_next_key(map, &key, &next_key, sizeof(struct ip_rt_key)) == 0) { key = next_key; @@ -274,6 +296,7 @@ gtp_xdp_teid_vty(struct bpf_map *map, vty_t *vty, __be32 id) , VTY_NEWLINE); } + end: free(r); return 0; } @@ -298,16 +321,30 @@ gtp_xdp_rt_teid_action(int action, gtp_teid_t *t) xdp_rt_maps[XDP_RT_MAP_PPP_INGRESS].map, xdp_rt_maps[XDP_RT_MAP_PPP_EGRESS].map); - return gtp_xdp_rt_action(action, t, xdp_rt_maps[direction].map); + return gtp_xdp_rt_action(xdp_rt_maps[direction].map, action, t); } int -gtp_xdp_rt_teid_vty(vty_t *vty, __be32 id) +gtp_xdp_rt_teid_vty(vty_t *vty, gtp_teid_t *t) { - if (!__test_bit(GTP_FL_GTP_ROUTE_LOADED_BIT, &daemon_data->flags)) + gtp_session_t *s; + gtp_apn_t *apn; + int direction; + + if (!__test_bit(GTP_FL_GTP_ROUTE_LOADED_BIT, &daemon_data->flags) || !t) return -1; - return 0; + direction = __test_bit(GTP_TEID_FL_EGRESS, &t->flags); + s = t->session; + apn = s->apn; + + /* PPPoE vrf ? */ + if (apn->vrf && __test_bit(IP_VRF_FL_PPPOE_BIT, &apn->vrf->flags)) + return gtp_xdp_ppp_teid_vty(vty, t, + xdp_rt_maps[XDP_RT_MAP_PPP_INGRESS].map, + xdp_rt_maps[XDP_RT_MAP_PPP_EGRESS].map); + + return gtp_xdp_teid_vty(xdp_rt_maps[direction].map, vty, t); } int @@ -320,8 +357,10 @@ gtp_xdp_rt_vty(vty_t *vty) "| TEID | Endpoint Address | Direction | Packets | Bytes |%s" "+------------+------------------+-----------+--------------+---------------------+%s" , VTY_NEWLINE, VTY_NEWLINE, VTY_NEWLINE); - gtp_xdp_teid_vty(xdp_rt_maps[XDP_RT_MAP_TEID_INGRESS].map, vty, 0); - gtp_xdp_teid_vty(xdp_rt_maps[XDP_RT_MAP_TEID_EGRESS].map, vty, 0); + gtp_xdp_teid_vty(xdp_rt_maps[XDP_RT_MAP_TEID_INGRESS].map, vty, NULL); + gtp_xdp_teid_vty(xdp_rt_maps[XDP_RT_MAP_TEID_EGRESS].map, vty, NULL); + gtp_xdp_teid_vty(xdp_rt_maps[XDP_RT_MAP_PPP_EGRESS].map, vty, NULL); + gtp_xdp_ppp_vty(vty, xdp_rt_maps[XDP_RT_MAP_PPP_INGRESS].map); vty_out(vty, "+------------+------------------+-----------+--------------+---------------------+%s" , VTY_NEWLINE); return 0; diff --git a/src/include/gtp_xdp_ppp.h b/src/include/gtp_xdp_ppp.h index 4d92e5b..40577db 100644 --- a/src/include/gtp_xdp_ppp.h +++ b/src/include/gtp_xdp_ppp.h @@ -29,6 +29,8 @@ struct ppp_key { /* Prototypes */ extern int gtp_xdp_ppp_action(int, gtp_teid_t *, struct bpf_map *, struct bpf_map *); +extern int gtp_xdp_ppp_teid_vty(vty_t *, gtp_teid_t *, struct bpf_map *, struct bpf_map *); +extern int gtp_xdp_ppp_vty(vty_t *, struct bpf_map *); extern int gtp_xdp_ppp_load(gtp_bpf_opts_t *); extern void gtp_xdp_ppp_unload(gtp_bpf_opts_t *); diff --git a/src/include/gtp_xdp_rt.h b/src/include/gtp_xdp_rt.h index 0ae6e8e..010384b 100644 --- a/src/include/gtp_xdp_rt.h +++ b/src/include/gtp_xdp_rt.h @@ -63,7 +63,7 @@ extern int gtp_xdp_rt_load(gtp_bpf_opts_t *); extern void gtp_xdp_rt_unload(gtp_bpf_opts_t *); extern int gtp_xdp_rt_key_set(gtp_teid_t *, struct ip_rt_key *); extern int gtp_xdp_rt_teid_action(int, gtp_teid_t *); -extern int gtp_xdp_rt_teid_vty(vty_t *, __be32); +extern int gtp_xdp_rt_teid_vty(vty_t *, gtp_teid_t *); extern int gtp_xdp_rt_vty(vty_t *); extern int gtp_xdp_rt_iptnl_action(int, gtp_iptnl_t *); extern int gtp_xdp_rt_iptnl_vty(vty_t *);