Skip to content
Permalink
Browse files

net: shell: Add ppp network interface support

Print point-to-point network information properly.

Signed-off-by: Jukka Rissanen <jukka.rissanen@linux.intel.com>
  • Loading branch information...
jukkar committed Jul 9, 2019
1 parent 4df61cd commit 4a5543db25237c0b9108d0feee11e582d265b411
Showing with 261 additions and 7 deletions.
  1. +19 −0 include/net/ppp.h
  2. +199 −0 subsys/net/ip/net_shell.c
  3. +43 −7 subsys/net/l2/ppp/ppp_l2.c
@@ -575,6 +575,25 @@ static inline int net_ppp_ping(int idx, s32_t timeout)
}
#endif

/**
* @brief Get PPP context information. This is only used by net-shell to
* print information about PPP.
*
* @param idx PPP network interface index
*
* @return PPP context or NULL if idx is invalid.
*/
#if defined(CONFIG_NET_L2_PPP) && defined(CONFIG_NET_SHELL)
struct ppp_context *net_ppp_context_get(int idx);
#else
static inline struct ppp_context *net_ppp_context_get(int idx)
{
ARG_UNUSED(idx);

return NULL;
}
#endif

#ifdef __cplusplus
}
#endif
@@ -21,6 +21,7 @@ LOG_MODULE_REGISTER(net_shell, LOG_LEVEL_DBG);

#include <net/net_if.h>
#include <net/dns_resolve.h>
#include <net/ppp.h>
#include <net/net_stats.h>
#include <sys/printk.h>

@@ -56,6 +57,11 @@ LOG_MODULE_REGISTER(net_shell, LOG_LEVEL_DBG);
#include "ethernet/gptp/gptp_private.h"
#endif

#if defined(CONFIG_NET_L2_PPP)
#include <net/ppp.h>
#include "ppp/ppp_internal.h"
#endif

#include "net_shell.h"
#include "net_stats.h"

@@ -141,6 +147,16 @@ static const char *iface2str(struct net_if *iface, const char **extra)
}
#endif

#ifdef CONFIG_NET_L2_PPP
if (net_if_l2(iface) == &NET_L2_GET_NAME(PPP)) {
if (extra) {
*extra = "===";
}

return "PPP";
}
#endif

#ifdef CONFIG_NET_L2_DUMMY
if (net_if_l2(iface) == &NET_L2_GET_NAME(DUMMY)) {
if (extra) {
@@ -677,6 +693,18 @@ static void print_eth_stats(struct net_if *iface, struct net_stats_eth *data,
}
#endif /* CONFIG_NET_STATISTICS_ETHERNET && CONFIG_NET_STATISTICS_USER_API */

#if defined(CONFIG_NET_STATISTICS_PPP) && \
defined(CONFIG_NET_STATISTICS_USER_API)
static void print_ppp_stats(struct net_if *iface, struct net_stats_ppp *data,
const struct shell *shell)
{
PR("Frames recv %u\n", data->pkts.rx);
PR("Frames sent %u\n", data->pkts.tx);
PR("Frames dropped %u\n", data->drop);
PR("Bad FCS %u\n", data->chkerr);
}
#endif /* CONFIG_NET_STATISTICS_PPP && CONFIG_NET_STATISTICS_USER_API */

static void print_tc_tx_stats(const struct shell *shell, struct net_if *iface)
{
#if NET_TC_TX_COUNT > 1
@@ -866,6 +894,20 @@ static void net_shell_print_statistics(struct net_if *iface, void *user_data)
}
}
#endif /* CONFIG_NET_STATISTICS_ETHERNET && CONFIG_NET_STATISTICS_USER_API */

#if defined(CONFIG_NET_STATISTICS_PPP) && \
defined(CONFIG_NET_STATISTICS_USER_API)
if (iface && net_if_l2(iface) == &NET_L2_GET_NAME(PPP)) {
struct net_stats_ppp ppp_data;
int ret;

ret = net_mgmt(NET_REQUEST_STATS_GET_PPP, iface,
&ppp_data, sizeof(ppp_data));
if (!ret) {
print_ppp_stats(iface, &ppp_data, shell);
}
}
#endif /* CONFIG_NET_STATISTICS_PPP && CONFIG_NET_STATISTICS_USER_API */
}
#endif /* CONFIG_NET_STATISTICS */

@@ -3039,6 +3081,97 @@ static int cmd_net_ping(const struct shell *shell, size_t argc, char *argv[])
#endif
}

static int cmd_net_ppp_ping(const struct shell *shell, size_t argc,
char *argv[])
{
#if defined(CONFIG_NET_PPP)
if (argv[1]) {
int ret, idx = get_iface_idx(shell, argv[1]);

if (idx < 0) {
return -ENOEXEC;
}

ret = net_ppp_ping(idx, K_SECONDS(1));
if (ret < 0) {
if (ret == -EAGAIN) {
PR_INFO("PPP Echo-Req timeout.\n");
} else if (ret == -ENODEV || ret == -ENOENT) {
PR_INFO("Not a PPP interface (%d)\n", idx);
} else {
PR_INFO("PPP Echo-Req failed (%d)\n", ret);
}
}
} else {
PR_INFO("PPP network interface must be given.\n");
return -ENOEXEC;
}
#else
PR_INFO("PPP not enabled. Set CONFIG_NET_L2_PPP to enable it.\n");
#endif
return 0;
}

static int cmd_net_ppp_status(const struct shell *shell, size_t argc,
char *argv[])
{
#if defined(CONFIG_NET_PPP)
int idx = 0;
struct ppp_context *ctx;

if (argv[1]) {
idx = get_iface_idx(shell, argv[1]);
if (idx < 0) {
return -ENOEXEC;
}
}

ctx = net_ppp_context_get(idx);
if (!ctx) {
PR_INFO("PPP context not found.\n");
return -ENOEXEC;
}

PR("PPP phase : %s (%d)\n", ppp_phase_str(ctx->phase),
ctx->phase);
PR("LCP state : %s (%d)\n",
ppp_state_str(ctx->lcp.fsm.state), ctx->lcp.fsm.state);
PR("LCP retransmits : %u\n", ctx->lcp.fsm.retransmits);
PR("LCP NACK loops : %u\n", ctx->lcp.fsm.nack_loops);
PR("LCP NACKs recv : %u\n", ctx->lcp.fsm.recv_nack_loops);
PR("LCP current id : %d\n", ctx->lcp.fsm.id);
PR("LCP ACK received : %s\n", ctx->lcp.fsm.ack_received ?
"yes" : "no");

#if defined(CONFIG_NET_IPV4)
PR("IPCP state : %s (%d)\n",
ppp_state_str(ctx->ipcp.fsm.state), ctx->ipcp.fsm.state);
PR("IPCP retransmits : %u\n", ctx->ipcp.fsm.retransmits);
PR("IPCP NACK loops : %u\n", ctx->ipcp.fsm.nack_loops);
PR("IPCP NACKs recv : %u\n", ctx->ipcp.fsm.recv_nack_loops);
PR("IPCP current id : %d\n", ctx->ipcp.fsm.id);
PR("IPCP ACK received : %s\n", ctx->ipcp.fsm.ack_received ?
"yes" : "no");
#endif /* CONFIG_NET_IPV4 */

#if defined(CONFIG_NET_IPV6)
PR("IPv6CP state : %s (%d)\n",
ppp_state_str(ctx->ipv6cp.fsm.state), ctx->ipv6cp.fsm.state);
PR("IPv6CP retransmits : %u\n", ctx->ipv6cp.fsm.retransmits);
PR("IPv6CP NACK loops : %u\n", ctx->ipv6cp.fsm.nack_loops);
PR("IPv6CP NACKs recv : %u\n", ctx->ipv6cp.fsm.recv_nack_loops);
PR("IPv6CP current id : %d\n", ctx->ipv6cp.fsm.id);
PR("IPv6CP ACK received : %s\n", ctx->ipv6cp.fsm.ack_received ?
"yes" : "no");
#endif /* CONFIG_NET_IPV6 */

#else
PR_INFO("PPP not enabled. Set CONFIG_NET_L2_PPP and CONFIG_NET_PPP "
"to enable PPP.\n");
#endif
return 0;
}

static int cmd_net_route(const struct shell *shell, size_t argc, char *argv[])
{
#if defined(CONFIG_NET_ROUTE) || defined(CONFIG_NET_ROUTE_MCAST)
@@ -3832,8 +3965,63 @@ static void iface_index_get(size_t idx, struct shell_static_entry *entry)
}

#define IFACE_DYN_CMD &iface_index

#if defined(CONFIG_NET_PPP)
static char *set_iface_ppp_index_buffer(size_t idx)
{
struct net_if *iface = net_if_get_by_index(idx);

if (!iface) {
return NULL;
}

if (net_if_l2(iface) != &NET_L2_GET_NAME(PPP)) {
return NULL;
}

snprintk(iface_index_buffer[idx], MAX_IFACE_STR_LEN, "%zu", idx);

return iface_index_buffer[idx];
}

static char *set_iface_ppp_index_help(size_t idx)
{
struct net_if *iface = net_if_get_by_index(idx);

if (!iface) {
return NULL;
}

if (net_if_l2(iface) != &NET_L2_GET_NAME(PPP)) {
return NULL;
}

snprintk(iface_help_buffer[idx], MAX_IFACE_HELP_STR_LEN,
"%s (%p)", iface2str(iface, NULL), iface);

return iface_help_buffer[idx];
}

static void iface_ppp_index_get(size_t idx, struct shell_static_entry *entry);

SHELL_DYNAMIC_CMD_CREATE(iface_ppp_index, iface_ppp_index_get);

static void iface_ppp_index_get(size_t idx, struct shell_static_entry *entry)
{
entry->handler = NULL;
entry->help = set_iface_ppp_index_help(idx);
entry->subcmd = &iface_ppp_index;
entry->syntax = set_iface_ppp_index_buffer(idx);
}

#define IFACE_PPP_DYN_CMD &iface_ppp_index
#else
#define IFACE_PPP_DYN_CMD NULL
#endif /* CONFIG_NET_PPP */

#else
#define IFACE_DYN_CMD NULL
#define IFACE_PPP_DYN_CMD NULL
#endif /* CONFIG_NET_SHELL_DYN_CMD_COMPLETION */

SHELL_STATIC_SUBCMD_SET_CREATE(net_cmd_iface,
@@ -3851,6 +4039,16 @@ SHELL_STATIC_SUBCMD_SET_CREATE(net_cmd_iface,
SHELL_SUBCMD_SET_END
);

SHELL_STATIC_SUBCMD_SET_CREATE(net_cmd_ppp,
SHELL_CMD(ping, IFACE_PPP_DYN_CMD,
"'net ppp ping <index>' sends Echo-request to PPP interface.",
cmd_net_ppp_ping),
SHELL_CMD(status, NULL,
"'net ppp status' prints information about PPP.",
cmd_net_ppp_status),
SHELL_SUBCMD_SET_END
);

#if defined(CONFIG_NET_IPV6) && defined(CONFIG_NET_SHELL_DYN_CMD_COMPLETION)
static
char nbr_address_buffer[CONFIG_NET_IPV6_MAX_NEIGHBORS][NET_IPV6_ADDR_LEN];
@@ -3995,6 +4193,7 @@ SHELL_STATIC_SUBCMD_SET_CREATE(net_commands,
SHELL_CMD(nbr, &net_cmd_nbr, "Print neighbor information.",
cmd_net_nbr),
SHELL_CMD(ping, &net_cmd_ping, "Ping a network host.", cmd_net_ping),
SHELL_CMD(ppp, &net_cmd_ppp, "PPP information.", cmd_net_ppp_status),
SHELL_CMD(route, NULL, "Show network route.", cmd_net_route),
SHELL_CMD(stacks, NULL, "Show network stacks information.",
cmd_net_stacks),
@@ -300,21 +300,34 @@ void net_ppp_carrier_off(struct net_if *iface)
}

#if defined(CONFIG_NET_SHELL)
int net_ppp_ping(int idx, s32_t timeout)
static int get_ppp_context(int idx, struct ppp_context **ctx,
struct net_if **iface)
{
struct net_if *iface = net_if_get_by_index(idx);
struct ppp_context *ctx;
int ret;
*iface = net_if_get_by_index(idx);

if (!iface) {
if (!*iface) {
return -ENOENT;
}

if (net_if_l2(iface) != &NET_L2_GET_NAME(PPP)) {
if (net_if_l2(*iface) != &NET_L2_GET_NAME(PPP)) {
return -ENODEV;
}

ctx = net_if_l2_data(iface);
*ctx = net_if_l2_data(*iface);

return 0;
}

int net_ppp_ping(int idx, s32_t timeout)
{
struct ppp_context *ctx;
struct net_if *iface;
int ret;

ret = get_ppp_context(idx, &ctx, &iface);
if (ret < 0) {
return ret;
}

ctx->shell.echo_req_data = sys_rand32_get();

@@ -327,6 +340,29 @@ int net_ppp_ping(int idx, s32_t timeout)

return k_sem_take(&ctx->shell.wait_echo_reply, timeout);
}

struct ppp_context *net_ppp_context_get(int idx)
{
struct ppp_context *ctx;
struct net_if *iface;
int ret;

if (idx == 0) {
iface = net_if_get_first_by_type(&NET_L2_GET_NAME(PPP));
if (!iface) {
return NULL;
}

return net_if_l2_data(iface);
}

ret = get_ppp_context(idx, &ctx, &iface);
if (ret < 0) {
return NULL;
}

return ctx;
}
#endif

const struct ppp_protocol_handler *ppp_lcp_get(void)

0 comments on commit 4a5543d

Please sign in to comment.
You can’t perform that action at this time.