Re: [patch iproute2/net-next repost] devlink: Add support for pipeline debug (dpipe)

2017-04-15 Thread David Miller
From: Jiri Pirko 
Date: Sat, 15 Apr 2017 10:59:03 +0200

> Sat, Apr 15, 2017 at 01:01:38AM CEST, step...@networkplumber.org wrote:
>>On Thu, 13 Apr 2017 11:30:27 +0200
>>Jiri Pirko  wrote:
>>
>>> We actually took this code from teamdctl (at least it was an influence).
>>> Devlink style is so much different in every aspect from the rest of the
>>> iproute2 suite. And I did it on purpose, because it is much nicer and
>>> easier to read. I would like to continue on this and don't do things in
>>> the was the existing tools do. I don't see any problem with that.
>>
>>No. That is road to ruin. Every package is free to use what ever style
>>it wants. But don't crossover please.
> 
> So we are stuck with some ugly way just because some other util does it?
> Well, in devlink I wrote lot of things differently, nicer. For example
> cmdline parsing. Why is it a "road to ruin"?

I agree with Jiri, if he wants to stylize devlink a certain way that
makes sense for devlink information, that is perfectly fine and does
not impact the way the rest of iproute2's output appears to the user
at all.


Re: [patch iproute2/net-next repost] devlink: Add support for pipeline debug (dpipe)

2017-04-15 Thread Jiri Pirko
Sat, Apr 15, 2017 at 01:01:38AM CEST, step...@networkplumber.org wrote:
>On Thu, 13 Apr 2017 11:30:27 +0200
>Jiri Pirko  wrote:
>
>> We actually took this code from teamdctl (at least it was an influence).
>> Devlink style is so much different in every aspect from the rest of the
>> iproute2 suite. And I did it on purpose, because it is much nicer and
>> easier to read. I would like to continue on this and don't do things in
>> the was the existing tools do. I don't see any problem with that.
>
>No. That is road to ruin. Every package is free to use what ever style
>it wants. But don't crossover please.

So we are stuck with some ugly way just because some other util does it?
Well, in devlink I wrote lot of things differently, nicer. For example
cmdline parsing. Why is it a "road to ruin"?


Re: [patch iproute2/net-next repost] devlink: Add support for pipeline debug (dpipe)

2017-04-14 Thread Stephen Hemminger
On Thu, 13 Apr 2017 11:30:27 +0200
Jiri Pirko  wrote:

> We actually took this code from teamdctl (at least it was an influence).
> Devlink style is so much different in every aspect from the rest of the
> iproute2 suite. And I did it on purpose, because it is much nicer and
> easier to read. I would like to continue on this and don't do things in
> the was the existing tools do. I don't see any problem with that.

No. That is road to ruin. Every package is free to use what ever style
it wants. But don't crossover please.


Re: [patch iproute2/net-next repost] devlink: Add support for pipeline debug (dpipe)

2017-04-13 Thread Jiri Pirko
Thu, Apr 13, 2017 at 01:45:25AM CEST, step...@networkplumber.org wrote:
>On Tue, 28 Mar 2017 17:26:54 +0200
>Jiri Pirko  wrote:
>
>>  
>>  #define pr_err(args...) fprintf(stderr, ##args)
>> -#define pr_out(args...) fprintf(stdout, ##args)
>> +#define pr_out(args...) \
>> +do {\
>> +if (g_indent_newline) { \
>> +fprintf(stdout, "%s", g_indent_str);\
>> +g_indent_newline = false;   \
>> +}   \
>> +fprintf(stdout, ##args);\
>> +} while (0)
>> +
>>  #define pr_out_sp(num, args...) \
>>  do {\
>>  int ret = fprintf(stdout, ##args);  \
>> @@ -42,6 +50,35 @@
>>  fprintf(stdout, "%*s", num - ret, "");  \
>>  } while (0)
>>  
>> +static int g_indent_level;
>> +static bool g_indent_newline;
>> +#define INDENT_STR_STEP 2
>> +#define INDENT_STR_MAXLEN 32
>> +static char g_indent_str[INDENT_STR_MAXLEN + 1] = "";
>> +
>> +static void __pr_out_indent_inc(void)
>> +{
>> +if (g_indent_level + INDENT_STR_STEP > INDENT_STR_MAXLEN)
>> +return;
>> +g_indent_level += INDENT_STR_STEP;
>> +memset(g_indent_str, ' ', sizeof(g_indent_str));
>> +g_indent_str[g_indent_level] = '\0';
>> +}
>> +
>> +static void __pr_out_indent_dec(void)
>> +{
>> +if (g_indent_level - INDENT_STR_STEP < 0)
>> +return;
>> +g_indent_level -= INDENT_STR_STEP;
>> +g_indent_str[g_indent_level] = '\0';
>> +}
>> +
>> +static void __pr_out_newline(void)
>> +{
>> +pr_out("\n");
>> +g_indent_newline = true;
>> +}
>> +
>
>Thanks for adding the support. Like many reviews, I am fine with the
>functionality but it is the details of the implementation that are of
>concern.
>
>Why this new set of output formatting routines, this doesn't resemble other 
>code
>in ip utilities. Looks more like you copied and pasted it from somewhere else.
>The indentation in existing ip command output isn't pretty or fancy but it 
>works.
>
>Please try and make this code look like all the other code. Yes, I know it
>may not be to your taste (it isn't mine either), but consistency is more 
>important
>than individual style.

We actually took this code from teamdctl (at least it was an influence).
Devlink style is so much different in every aspect from the rest of the
iproute2 suite. And I did it on purpose, because it is much nicer and
easier to read. I would like to continue on this and don't do things in
the was the existing tools do. I don't see any problem with that.


>
>> @ -314,6 +356,102 @@ static int attr_cb(const struct nlattr *attr, void 
>> *data)
>>  if (type == DEVLINK_ATTR_ESWITCH_INLINE_MODE &&
>>  mnl_attr_validate(attr, MNL_TYPE_U8) < 0)
>>  return MNL_CB_ERROR;
>> +if (type == DEVLINK_ATTR_DPIPE_TABLES &&
>> +mnl_attr_validate(attr, MNL_TYPE_NESTED) < 0)
>> +return MNL_CB_ERROR;
>> +if (type == DEVLINK_ATTR_DPIPE_TABLE &&
>> +mnl_attr_validate(attr, MNL_TYPE_NESTED) < 0)
>> +return MNL_CB_ERROR;
>> +if (type == DEVLINK_ATTR_DPIPE_TABLE_NAME &&
>> +mnl_attr_validate(attr, MNL_TYPE_STRING) < 0)
>> +return MNL_CB_ERROR;
>> +if (type == DEVLINK_ATTR_DPIPE_TABLE_SIZE &&
>> +mnl_attr_validate(attr, MNL_TYPE_U64) < 0)
>> +return MNL_CB_ERROR;
>> +if (type == DEVLINK_ATTR_DPIPE_TABLE_MATCHES &&
>> +mnl_attr_validate(attr, MNL_TYPE_NESTED) < 0)
>> +return MNL_CB_ERROR;
>> +if (type == DEVLINK_ATTR_DPIPE_TABLE_ACTIONS &&
>> +mnl_attr_validate(attr, MNL_TYPE_NESTED) < 0)
>> +return MNL_CB_ERROR;
>> +if (type == DEVLINK_ATTR_DPIPE_TABLE_COUNTERS_ENABLED &&
>> +mnl_attr_validate(attr, MNL_TYPE_U8) < 0)
>> +return MNL_CB_ERROR;
>> +if (type == DEVLINK_ATTR_DPIPE_ENTRIES &&
>> +mnl_attr_validate(attr, MNL_TYPE_NESTED) < 0)
>> +return MNL_CB_ERROR;
>> +if (type == DEVLINK_ATTR_DPIPE_ENTRY &&
>> +mnl_attr_validate(attr, MNL_TYPE_NESTED) < 0)
>> +return MNL_CB_ERROR;
>> +if (type == DEVLINK_ATTR_DPIPE_ENTRY_INDEX &&
>> +mnl_attr_validate(attr, MNL_TYPE_U64) < 0)
>> +return MNL_CB_ERROR;
>> +if (type == DEVLINK_ATTR_DPIPE_ENTRY_MATCH_VALUES &&
>> +mnl_attr_validate(attr, MNL_TYPE_NESTED) < 0)
>> +return MNL_CB_ERROR;
>> +if (type == DEVLINK_ATTR_DPIPE_ENTRY_ACTION_VALUES &&
>> +mnl_attr_validate(attr, MNL_TYPE_NESTED) < 0)
>> +return MNL_CB_ERROR;
>> +if (type == DEVLINK_ATTR_DPIPE_ENTRY_COUNTER &&
>> +mnl_attr_validate(attr, MNL_TYPE_U64) < 0)
>> +return MNL_CB_ERROR;
>> + 

Re: [patch iproute2/net-next repost] devlink: Add support for pipeline debug (dpipe)

2017-04-12 Thread Stephen Hemminger
On Tue, 28 Mar 2017 17:26:54 +0200
Jiri Pirko  wrote:

>  
>  #define pr_err(args...) fprintf(stderr, ##args)
> -#define pr_out(args...) fprintf(stdout, ##args)
> +#define pr_out(args...)  \
> + do {\
> + if (g_indent_newline) { \
> + fprintf(stdout, "%s", g_indent_str);\
> + g_indent_newline = false;   \
> + }   \
> + fprintf(stdout, ##args);\
> + } while (0)
> +
>  #define pr_out_sp(num, args...)  \
>   do {\
>   int ret = fprintf(stdout, ##args);  \
> @@ -42,6 +50,35 @@
>   fprintf(stdout, "%*s", num - ret, "");  \
>   } while (0)
>  
> +static int g_indent_level;
> +static bool g_indent_newline;
> +#define INDENT_STR_STEP 2
> +#define INDENT_STR_MAXLEN 32
> +static char g_indent_str[INDENT_STR_MAXLEN + 1] = "";
> +
> +static void __pr_out_indent_inc(void)
> +{
> + if (g_indent_level + INDENT_STR_STEP > INDENT_STR_MAXLEN)
> + return;
> + g_indent_level += INDENT_STR_STEP;
> + memset(g_indent_str, ' ', sizeof(g_indent_str));
> + g_indent_str[g_indent_level] = '\0';
> +}
> +
> +static void __pr_out_indent_dec(void)
> +{
> + if (g_indent_level - INDENT_STR_STEP < 0)
> + return;
> + g_indent_level -= INDENT_STR_STEP;
> + g_indent_str[g_indent_level] = '\0';
> +}
> +
> +static void __pr_out_newline(void)
> +{
> + pr_out("\n");
> + g_indent_newline = true;
> +}
> +

Thanks for adding the support. Like many reviews, I am fine with the
functionality but it is the details of the implementation that are of
concern.

Why this new set of output formatting routines, this doesn't resemble other code
in ip utilities. Looks more like you copied and pasted it from somewhere else.
The indentation in existing ip command output isn't pretty or fancy but it 
works.

Please try and make this code look like all the other code. Yes, I know it
may not be to your taste (it isn't mine either), but consistency is more 
important
than individual style.

> @ -314,6 +356,102 @@ static int attr_cb(const struct nlattr *attr, void *data)
>   if (type == DEVLINK_ATTR_ESWITCH_INLINE_MODE &&
>   mnl_attr_validate(attr, MNL_TYPE_U8) < 0)
>   return MNL_CB_ERROR;
> + if (type == DEVLINK_ATTR_DPIPE_TABLES &&
> + mnl_attr_validate(attr, MNL_TYPE_NESTED) < 0)
> + return MNL_CB_ERROR;
> + if (type == DEVLINK_ATTR_DPIPE_TABLE &&
> + mnl_attr_validate(attr, MNL_TYPE_NESTED) < 0)
> + return MNL_CB_ERROR;
> + if (type == DEVLINK_ATTR_DPIPE_TABLE_NAME &&
> + mnl_attr_validate(attr, MNL_TYPE_STRING) < 0)
> + return MNL_CB_ERROR;
> + if (type == DEVLINK_ATTR_DPIPE_TABLE_SIZE &&
> + mnl_attr_validate(attr, MNL_TYPE_U64) < 0)
> + return MNL_CB_ERROR;
> + if (type == DEVLINK_ATTR_DPIPE_TABLE_MATCHES &&
> + mnl_attr_validate(attr, MNL_TYPE_NESTED) < 0)
> + return MNL_CB_ERROR;
> + if (type == DEVLINK_ATTR_DPIPE_TABLE_ACTIONS &&
> + mnl_attr_validate(attr, MNL_TYPE_NESTED) < 0)
> + return MNL_CB_ERROR;
> + if (type == DEVLINK_ATTR_DPIPE_TABLE_COUNTERS_ENABLED &&
> + mnl_attr_validate(attr, MNL_TYPE_U8) < 0)
> + return MNL_CB_ERROR;
> + if (type == DEVLINK_ATTR_DPIPE_ENTRIES &&
> + mnl_attr_validate(attr, MNL_TYPE_NESTED) < 0)
> + return MNL_CB_ERROR;
> + if (type == DEVLINK_ATTR_DPIPE_ENTRY &&
> + mnl_attr_validate(attr, MNL_TYPE_NESTED) < 0)
> + return MNL_CB_ERROR;
> + if (type == DEVLINK_ATTR_DPIPE_ENTRY_INDEX &&
> + mnl_attr_validate(attr, MNL_TYPE_U64) < 0)
> + return MNL_CB_ERROR;
> + if (type == DEVLINK_ATTR_DPIPE_ENTRY_MATCH_VALUES &&
> + mnl_attr_validate(attr, MNL_TYPE_NESTED) < 0)
> + return MNL_CB_ERROR;
> + if (type == DEVLINK_ATTR_DPIPE_ENTRY_ACTION_VALUES &&
> + mnl_attr_validate(attr, MNL_TYPE_NESTED) < 0)
> + return MNL_CB_ERROR;
> + if (type == DEVLINK_ATTR_DPIPE_ENTRY_COUNTER &&
> + mnl_attr_validate(attr, MNL_TYPE_U64) < 0)
> + return MNL_CB_ERROR;
> + if (type == DEVLINK_ATTR_DPIPE_MATCH &&
> + mnl_attr_validate(attr, MNL_TYPE_NESTED) < 0)
> + return MNL_CB_ERROR;
> + if (type == DEVLINK_ATTR_DPIPE_MATCH_VALUE &&
> + mnl_attr_validate(attr, MNL_TYPE_NESTED) < 0)
> + return MNL_CB_ERROR;
> + if (type == DEVLINK_ATTR_DPIPE_MATCH_TYPE &&
> + mnl_attr_validate(attr, MNL_TYPE_U32) < 0)
> + return MNL_CB_ERROR;
> + if (type == DEVLINK_ATTR_DPIPE_ACTION &&
> + 

[patch iproute2/net-next repost] devlink: Add support for pipeline debug (dpipe)

2017-03-28 Thread Jiri Pirko
From: Arkadi Sharshevsky 

Add support for pipeline debug (dpipe). The headers are used both the
gain visibillity into the headers supported by the hardware, and to
build the headers/field database which is used by other commands.

Examples:

First we can see the headers supported by the hardware:

$devlink dpipe header show pci/:03:00.0

pci/:03:00.0:
  name mlxsw_meta
  field:
name erif_port bitwidth 32 mapping_type ifindex
name l3_forward bitwidth 1
name l2_drop bitwidth 1

Note that mapping_type is presented only if relevant. Also the header/
field id's are reported by the kernel they are not shown by default.
They can be observed by using the -v option. Also the headers scope
(global/local) is specified.

$devlink -v dpipe header show pci/:03:00.0

pci/:03:00.0:
  name mlxsw_meta id 0 global false
  field:
name erif_port id 0 bitwidth 32 mapping_type ifindex
name l3_forward id 1 bitwidth 1
name l2_drop id 2 bitwidth 1

Second we can examine the tables supported by the hardware. In order
to dump all the tables no table name should be provided:
$devlink dpipe table show pci/:03:00.0

In order to examine specific table its name have to be specified:
$devlink dpipe table show pci/:03:00.0 name erif

pci/:03:00.0:
  name mlxsw_erif size 800 counters_enabled true
  match:
type field_exact header mlxsw_meta field erif_port mapping ifindex
  action:
type field_modify header mlxsw_meta field l3_forward
type field_modify header mlxsw_meta field l2_drop

To enable/disable counters on the table:
$devlink dpipe table set pci/:03:00.0 name erif counters enable
$devlink dpipe table set pci/:03:00.0 name erif counters disable

In order to see the current entries in the hardware for specific table:
$devlink dpipe table dump pci/:03:00.0 name erif

pci/:03:00.0:
  index 0 counter 0
  match_value:
type field_exact header mlxsw_meta field erif_port mapping ifindex 
mapping_value 383 value 0
  action_value:
type field_modify header mlxsw_meta field l3_forward value 1

  index 1 counter 0
  match_value:
type field_exact header mlxsw_meta field erif_port mapping ifindex 
mapping_value 381 value 1
  action_value:
type field_modify header mlxsw_meta field l3_forward value 1

In the above example the table contains two entries which does match
on erif port and forwards the packet or drop it (currently only the
forward count is implemented). The counter values are provided for
example. In case the counting is not enabled on the table the counters
will not be available.

Signed-off-by: Arkadi Sharshevsky 
Signed-off-by: Jiri Pirko 
---
 devlink/devlink.c   | 1413 +++
 include/linux/devlink.h |   67 ++-
 2 files changed, 1382 insertions(+), 98 deletions(-)

diff --git a/devlink/devlink.c b/devlink/devlink.c
index e90226e..3d525ea 100644
--- a/devlink/devlink.c
+++ b/devlink/devlink.c
@@ -34,7 +34,15 @@
 #define ESWITCH_INLINE_MODE_TRANSPORT "transport"
 
 #define pr_err(args...) fprintf(stderr, ##args)
-#define pr_out(args...) fprintf(stdout, ##args)
+#define pr_out(args...)\
+   do {\
+   if (g_indent_newline) { \
+   fprintf(stdout, "%s", g_indent_str);\
+   g_indent_newline = false;   \
+   }   \
+   fprintf(stdout, ##args);\
+   } while (0)
+
 #define pr_out_sp(num, args...)\
do {\
int ret = fprintf(stdout, ##args);  \
@@ -42,6 +50,35 @@
fprintf(stdout, "%*s", num - ret, "");  \
} while (0)
 
+static int g_indent_level;
+static bool g_indent_newline;
+#define INDENT_STR_STEP 2
+#define INDENT_STR_MAXLEN 32
+static char g_indent_str[INDENT_STR_MAXLEN + 1] = "";
+
+static void __pr_out_indent_inc(void)
+{
+   if (g_indent_level + INDENT_STR_STEP > INDENT_STR_MAXLEN)
+   return;
+   g_indent_level += INDENT_STR_STEP;
+   memset(g_indent_str, ' ', sizeof(g_indent_str));
+   g_indent_str[g_indent_level] = '\0';
+}
+
+static void __pr_out_indent_dec(void)
+{
+   if (g_indent_level - INDENT_STR_STEP < 0)
+   return;
+   g_indent_level -= INDENT_STR_STEP;
+   g_indent_str[g_indent_level] = '\0';
+}
+
+static void __pr_out_newline(void)
+{
+   pr_out("\n");
+   g_indent_newline = true;
+}
+
 static int _mnlg_socket_recv_run(struct mnlg_socket *nlg,
 mnl_cb_t data_cb, void *data)
 {
@@ -137,6 +174,8 @@ static void ifname_map_free(struct ifname_map *ifname_map)
 #define DL_OPT_SB_TC   BIT(10)
 #define DL_OPT_ESWITCH_MODEBIT(11)
 #define DL_OPT_ESWITC