diff --git a/include/dp_session.h b/include/dp_session.h index 8201da2e..b3975dc0 100644 --- a/include/dp_session.h +++ b/include/dp_session.h @@ -1,4 +1,5 @@ /* + * Copyright (c) 2021, SafePoint . All rights reserved. * Copyright (c) 2020, AT&T Intellectual Property. All rights reserved. * * SPDX-License-Identifier: LGPL-2.1-only @@ -65,6 +66,56 @@ enum dp_session_state { SESSION_STATE_CLOSED, } __attribute__ ((__packed__)); +/** + * Session attribute. + */ +enum dp_session_attr { + SESSION_ATTR_BYTES_IN = 1, + SESSION_ATTR_PKTS_IN = (1 << 1), + SESSION_ATTR_PROTOCOL = (1 << 2), + SESSION_ATTR_TCP_FLAGS = (1 << 3), + SESSION_ATTR_L4_SRC_PORT = (1 << 4), + SESSION_ATTR_IPV4_SRC_ADDR = (1 << 5), + SESSION_ATTR_L4_DST_PORT = (1 << 6), + SESSION_ATTR_IPV4_DST_ADDR = (1 << 7), + SESSION_ATTR_CREATE_TIME = (1 << 8), + SESSION_ATTR_BYTES_OUT = (1 << 9), + SESSION_ATTR_PKTS_OUT = (1 << 10), + SESSION_ATTR_IF_NAME = (1 << 11), + SESSION_ATTR_DPI = (1 << 12), +}; + +#define SESSION_ATTR_ALL 0xffffffff +#define SESSION_ATTR_SENTRY (SESSION_ATTR_L4_SRC_PORT \ + | SESSION_ATTR_IPV4_SRC_ADDR \ + | SESSION_ATTR_L4_DST_PORT \ + | SESSION_ATTR_IPV4_DST_ADDR \ + | SESSION_ATTR_IF_NAME) + +struct dp_session_info { + enum dp_session_attr query; + uint64_t se_id; + uint16_t se_flags; + uint8_t se_protocol; + uint8_t se_protocol_state; + uint64_t se_pkts_in; + uint64_t se_bytes_in; + uint64_t se_create_time; /* time session was created */ + uint64_t se_pkts_out; + uint64_t se_bytes_out; + + /* address */ + int se_af; + uint16_t se_src_port; + uint32_t se_src_addr; + uint16_t se_dst_port; + uint32_t se_dst_addr; + const char *se_ifname; + const char *se_app_name; + const char *se_app_proto; + const char *se_app_type; +}; + #define SESSION_STATE_FIRST SESSION_STATE_NONE #define SESSION_STATE_LAST SESSION_STATE_CLOSED #define SESSION_STATE_SIZE (SESSION_STATE_LAST + 1) @@ -233,6 +284,12 @@ void *dp_session_get_private(int id, const struct session *session); int dp_session_table_walk(dp_session_walk_t *fn, void *data, unsigned int types); +/** + * Query a session's info. + */ +int dp_session_query(struct session *s, enum dp_session_attr query, + struct dp_session_info *info); + /** * Get a session's unique id. * diff --git a/src/npf/dpi/dpi.c b/src/npf/dpi/dpi.c index cd97de9b..38eef174 100644 --- a/src/npf/dpi/dpi.c +++ b/src/npf/dpi/dpi.c @@ -1,4 +1,5 @@ /* + * Copyright (c) 2021, SafePoint . All rights reserved. * Copyright (c) 2017-2020, AT&T Intellectual Property. All rights reserved. * * Copyright (c) 2016-2017 by Brocade Communications Systems, Inc. @@ -523,6 +524,22 @@ dpi_app_type_name_to_id(uint8_t engine_id, const char *type_name) return engine ? engine->type_to_id(type_name) : DPI_APP_ERROR; } +const char* +dpi_app_id_to_name(uint8_t engine_id, uint32_t app) +{ + struct dpi_engine_procs *engine = NULL_ENGINE; + ENGINE_PROC_FIND(engine, engine_id, appid_to_name); + return engine ? engine->appid_to_name(app) : NULL; +} + +const char* +dpi_app_type_to_name(uint8_t engine_id, uint32_t type) +{ + struct dpi_engine_procs *engine = NULL_ENGINE; + ENGINE_PROC_FIND(engine, engine_id, apptype_to_name); + return engine ? engine->apptype_to_name(type) : NULL; +} + void dpi_info_json(struct dpi_flow *dpi_flow, json_writer_t *json) { diff --git a/src/npf/dpi/dpi_internal.h b/src/npf/dpi/dpi_internal.h index db87f379..4fef5f48 100644 --- a/src/npf/dpi/dpi_internal.h +++ b/src/npf/dpi/dpi_internal.h @@ -1,4 +1,5 @@ /* + * Copyright (c) 2021, SafePoint . All rights reserved. * Copyright (c) 2017-2018,2020, AT&T Intellectual Property. * All rights reserved. * @@ -404,8 +405,21 @@ struct dpi_engine_procs { */ size_t (*info_log)(struct dpi_engine_flow *flow, char *buf, size_t buf_len); + + /** + * Get name of app id. + */ + const char* (*appid_to_name)(uint32_t app); + + /** + * Get type of type id. + */ + const char* (*apptype_to_name)(uint32_t type); }; +const char *dpi_app_id_to_name(uint8_t engine_id, uint32_t app); +const char *dpi_app_type_to_name(uint8_t engine_id, uint32_t type); + bool no_app_id(uint32_t app_id); bool no_app_type(uint32_t app_type); diff --git a/src/npf/dpi/dpi_user.c b/src/npf/dpi/dpi_user.c index 8fde1f0f..99faf66d 100644 --- a/src/npf/dpi/dpi_user.c +++ b/src/npf/dpi/dpi_user.c @@ -1,4 +1,5 @@ /* + * Copyright (c) 2021 SafePoint . All rights reserved. * Copyright (c) 2020 AT&T Intellectual Property. All rights reserved. * * SPDX-License-Identifier: LGPL-2.1-only @@ -317,4 +318,6 @@ struct dpi_engine_procs user_engine_procs = { .type_to_id = dpi_user_type_to_id, .info_json = dpi_user_flow_json, .info_log = dpi_user_flow_log, + .appid_to_name = dpi_user_id_to_name, + .apptype_to_name = dpi_user_type_to_name, }; diff --git a/src/npf/dpi/ndpi.c b/src/npf/dpi/ndpi.c index 07132108..93498828 100644 --- a/src/npf/dpi/ndpi.c +++ b/src/npf/dpi/ndpi.c @@ -1,4 +1,5 @@ /* + * Copyright (c) 2021 SafePoint . All rights reserved. * Copyright (c) 2021 AT&T Intellectual Property. All rights reserved. * * SPDX-License-Identifier: LGPL-2.1-only @@ -537,4 +538,6 @@ struct dpi_engine_procs ndpi_engine_procs = { .type_to_id = dpi_ndpi_app_type_name_to_id, .info_json = dpi_ndpi_info_json, .info_log = dpi_ndpi_info_log, + .appid_to_name = dpi_ndpi_app_id_to_name, + .apptype_to_name = dpi_ndpi_app_type_to_name, }; diff --git a/src/npf/npf_dataplane_session.c b/src/npf/npf_dataplane_session.c index 7379e7b5..883c52cb 100644 --- a/src/npf/npf_dataplane_session.c +++ b/src/npf/npf_dataplane_session.c @@ -1,4 +1,5 @@ /* + * Copyright (c) 2021, SafePoint . All rights reserved. * Copyright (c) 2017-2020, AT&T Intellectual Property. All rights reserved. * Copyright (c) 2016 by Brocade Communications Systems, Inc. * All rights reserved. @@ -113,6 +114,12 @@ static int dps_feature_nat_info(void *data, uint32_t *taddr, uint16_t *tport) return npf_session_feature_nat_info(se, taddr, tport); } +static void dps_feature_query(struct dp_session_info *info, struct session *s, + struct session_feature *sf) +{ + return npf_session_feature_query(info, s, sf); +} + /* Callbacks for the npf_session_t */ static const struct session_feature_ops ops = { .expired = dps_feature_expire, @@ -120,6 +127,7 @@ static const struct session_feature_ops ops = { .json = dps_feature_json, .log = dps_feature_log, .nat_info = dps_feature_nat_info, + .query = dps_feature_query, }; /* diff --git a/src/npf/npf_session.c b/src/npf/npf_session.c index aa9400e5..5c59faf0 100644 --- a/src/npf/npf_session.c +++ b/src/npf/npf_session.c @@ -1,4 +1,5 @@ /* + * Copyright (c) 2021, SafePoint . All rights reserved. * Copyright (c) 2017-2021, AT&T Intellectual Property. All rights reserved. * Copyright (c) 2016 by Brocade Communications Systems, Inc. * All rights reserved. @@ -2099,3 +2100,28 @@ int npf_session_npf_pack_activate(struct npf_session *se, struct ifnet *ifp) se->s_flags |= SE_ACTIVE; return 0; } + +static int get_dpi_info(uint8_t engine, uint32_t app, uint32_t proto, + uint32_t type, void *data) +{ + if (no_app_id(app) && no_app_id(proto) && no_app_type(type)) + return 0; + + struct dp_session_info *p = data; + p->se_app_name = dpi_app_id_to_name(engine, app); + p->se_app_proto = dpi_app_id_to_name(engine, proto); + p->se_app_type = dpi_app_type_to_name(engine, type); + return 1; +} + +void npf_session_feature_query(struct dp_session_info *info, + struct session *s __unused, + struct session_feature *sf) +{ + npf_session_t *se = sf->sf_data; + enum dp_session_attr query = info->query; + + /* DPI query */ + if (query & SESSION_ATTR_DPI && se->s_dpi) + dpi_flow_for_each_engine(se->s_dpi, get_dpi_info, info); +} diff --git a/src/npf/npf_session.h b/src/npf/npf_session.h index cec0a81e..253e5f63 100644 --- a/src/npf/npf_session.h +++ b/src/npf/npf_session.h @@ -1,4 +1,5 @@ /* + * Copyright (c) 2021, SafePoint . All rights reserved. * Copyright (c) 2017-2019, AT&T Intellectual Property. All rights reserved. * Copyright (c) 2016 by Brocade Communications Systems, Inc. * All rights reserved. @@ -135,6 +136,8 @@ npf_nat_t *npf_session_retnat(npf_session_t *se, const int di, bool *forw); void npf_session_feature_json(json_writer_t *json, npf_session_t *se); void npf_session_feature_log(enum session_log_event event, struct session *s, struct session_feature *sf); +void npf_session_feature_query(struct dp_session_info *info, struct session *s, + struct session_feature *sf); int npf_session_feature_nat_info(npf_session_t *se, uint32_t *taddr, uint16_t *tport); diff --git a/src/session/session.c b/src/session/session.c index ab4f3507..5a6fffc0 100644 --- a/src/session/session.c +++ b/src/session/session.c @@ -1,4 +1,5 @@ /* + * Copyright (c) 2021, SafePoint . All rights reserved. * Copyright (c) 2017-2021, AT&T Intellectual Property. All rights reserved. * Copyright (c) 2017 by Brocade Communications Systems, Inc. * All rights reserved. @@ -1943,7 +1944,7 @@ int session_npf_pack_restore(struct npf_pack_dp_session *pds, s->se_flags = SESSION_INSERTED; rc = session_npf_pack_stats_restore(s, stats); - if (rc) + if (rc) goto error; *session = s; @@ -2033,3 +2034,79 @@ uint64_t dp_session_unique_id(const struct session *session) return 0; return session->se_id; } + +/* walk function for query features */ +static int se_feature_query(struct session *s, struct session_feature *sf, + void *data) +{ + struct dp_session_info *info = data; + + if (sf->sf_ops && sf->sf_ops->query) + sf->sf_ops->query(info, s, sf); + + return 0; +} + +int dp_session_query(struct session *s, enum dp_session_attr query, + struct dp_session_info *info) +{ + if (!s) + return -1; + + info->se_id = s->se_id; + + if (query & SESSION_ATTR_PROTOCOL) { + info->se_protocol = s->se_protocol; + info->se_protocol_state = s->se_protocol_state; + } + if (query & SESSION_ATTR_BYTES_IN) + info->se_bytes_in = rte_atomic64_read(&s->se_bytes_in); + if (query & SESSION_ATTR_PKTS_IN) + info->se_pkts_in = rte_atomic64_read(&s->se_pkts_in); + if (query & SESSION_ATTR_CREATE_TIME) + info->se_create_time = s->se_create_time; + if (query & SESSION_ATTR_BYTES_OUT) + info->se_bytes_out = rte_atomic64_read(&s->se_bytes_out); + if (query & SESSION_ATTR_PKTS_OUT) + info->se_pkts_out = rte_atomic64_read(&s->se_pkts_out); + + if (query & SESSION_ATTR_SENTRY) { + const void *saddr; + const void *daddr; + uint32_t if_index; + uint16_t sid; + uint16_t did; + + struct sentry *sen = rcu_dereference(s->se_sen); + if (sen) { + session_sentry_extract(sen, &if_index, &info->se_af, + &saddr, &sid, &daddr, &did); + + if (query & SESSION_ATTR_L4_SRC_PORT) + info->se_src_port = sid; + if (query & SESSION_ATTR_IPV4_SRC_ADDR) + info->se_src_addr = *(uint32_t *)saddr; + if (query & SESSION_ATTR_L4_DST_PORT) + info->se_dst_port = did; + if (query & SESSION_ATTR_IPV4_DST_ADDR) + info->se_dst_addr = *(uint32_t *)daddr; + if (query & SESSION_ATTR_IF_NAME) + info->se_ifname = + ifnet_indextoname_safe(if_index); + } + } + + if (query & SESSION_ATTR_DPI) { + info->query = query; + + /* set default value in case no info found */ + info->se_app_name = NULL; + info->se_app_proto = NULL; + info->se_app_type = NULL; + + session_feature_walk_session(s, SESSION_FEATURE_ALL, + se_feature_query, info); + } + + return 0; +} diff --git a/src/session/session.h b/src/session/session.h index aea9b70a..73b50b04 100644 --- a/src/session/session.h +++ b/src/session/session.h @@ -1,4 +1,5 @@ /* + * Copyright (c) 2021, SafePoint . All rights reserved. * Copyright (c) 2017-2021, AT&T Intellectual Property. All rights reserved. * Copyright (c) 2017 by Brocade Communications Systems, Inc. * All rights reserved. @@ -106,6 +107,9 @@ struct session_feature_ops { void (*log)(enum session_log_event event, struct session *s, struct session_feature *sf); int (*nat_info)(void *data, uint32_t *taddr, uint16_t *tport); + + void (*query)(struct dp_session_info *info, struct session *s, + struct session_feature *sf); }; #define SESS_FEAT_REQ_EXPIRY 0x01 /* feature marked for expiry */