Skip to content

Commit 1555d20

Browse files
Arkadi Sharshevskydavem330
authored andcommitted
devlink: Support for pipeline debug (dpipe)
The pipeline debug is used to export the pipeline abstractions for the main objects - tables, headers and entries. The only support for set is for changing the counter parameter on specific table. The basic structures: Header - can represent a real protocol header information or internal metadata. Generic protocol headers like IPv4 can be shared between drivers. Each driver can add local headers. Field - part of a header. Can represent protocol field or specific ASIC metadata field. Hardware special metadata fields can be mapped to different resources, for example switch ASIC ports can have internal number which from the systems point of view is mapped to netdeivce ifindex. Match - represent specific match rule. Can describe match on specific field or header. The header index should be specified as well in order to support several header instances of the same type (tunneling). Action - represents specific action rule. Actions can describe operations on specific field values for example like set, increment, etc. And header operation like add and delete. Value - represents value which can be associated with specific match or action. Table - represents a hardware block which can be described with match/ action behavior. The match/action can be done on the packets data or on the internal metadata that it gathered along the packets traversal throw the pipeline which is vendor specific and should be exported in order to provide understanding of ASICs behavior. Entry - represents single record in a specific table. The entry is identified by specific combination of values for match/action. Prior to accessing the tables/entries the drivers provide the header/ field data base which is used by driver to user-space. The data base is split between the shared headers and unique headers. Signed-off-by: Arkadi Sharshevsky <[email protected]> Signed-off-by: Jiri Pirko <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent cc628c9 commit 1555d20

File tree

3 files changed

+1161
-1
lines changed

3 files changed

+1161
-1
lines changed

include/net/devlink.h

Lines changed: 259 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@ struct devlink {
2525
struct list_head list;
2626
struct list_head port_list;
2727
struct list_head sb_list;
28+
struct list_head dpipe_table_list;
29+
struct devlink_dpipe_headers *dpipe_headers;
2830
const struct devlink_ops *ops;
2931
struct device *dev;
3032
possible_net_t _net;
@@ -49,6 +51,178 @@ struct devlink_sb_pool_info {
4951
enum devlink_sb_threshold_type threshold_type;
5052
};
5153

54+
/**
55+
* struct devlink_dpipe_field - dpipe field object
56+
* @name: field name
57+
* @id: index inside the headers field array
58+
* @bitwidth: bitwidth
59+
* @mapping_type: mapping type
60+
*/
61+
struct devlink_dpipe_field {
62+
const char *name;
63+
unsigned int id;
64+
unsigned int bitwidth;
65+
enum devlink_dpipe_field_mapping_type mapping_type;
66+
};
67+
68+
/**
69+
* struct devlink_dpipe_header - dpipe header object
70+
* @name: header name
71+
* @id: index, global/local detrmined by global bit
72+
* @fields: fields
73+
* @fields_count: number of fields
74+
* @global: indicates if header is shared like most protocol header
75+
* or driver specific
76+
*/
77+
struct devlink_dpipe_header {
78+
const char *name;
79+
unsigned int id;
80+
struct devlink_dpipe_field *fields;
81+
unsigned int fields_count;
82+
bool global;
83+
};
84+
85+
/**
86+
* struct devlink_dpipe_match - represents match operation
87+
* @type: type of match
88+
* @header_index: header index (packets can have several headers of same
89+
* type like in case of tunnels)
90+
* @header: header
91+
* @fieled_id: field index
92+
*/
93+
struct devlink_dpipe_match {
94+
enum devlink_dpipe_match_type type;
95+
unsigned int header_index;
96+
struct devlink_dpipe_header *header;
97+
unsigned int field_id;
98+
};
99+
100+
/**
101+
* struct devlink_dpipe_action - represents action operation
102+
* @type: type of action
103+
* @header_index: header index (packets can have several headers of same
104+
* type like in case of tunnels)
105+
* @header: header
106+
* @fieled_id: field index
107+
*/
108+
struct devlink_dpipe_action {
109+
enum devlink_dpipe_action_type type;
110+
unsigned int header_index;
111+
struct devlink_dpipe_header *header;
112+
unsigned int field_id;
113+
};
114+
115+
/**
116+
* struct devlink_dpipe_value - represents value of match/action
117+
* @action: action
118+
* @match: match
119+
* @mapping_value: in case the field has some mapping this value
120+
* specified the mapping value
121+
* @mapping_valid: specify if mapping value is valid
122+
* @value_size: value size
123+
* @value: value
124+
* @mask: bit mask
125+
*/
126+
struct devlink_dpipe_value {
127+
union {
128+
struct devlink_dpipe_action *action;
129+
struct devlink_dpipe_match *match;
130+
};
131+
unsigned int mapping_value;
132+
bool mapping_valid;
133+
unsigned int value_size;
134+
void *value;
135+
void *mask;
136+
};
137+
138+
/**
139+
* struct devlink_dpipe_entry - table entry object
140+
* @index: index of the entry in the table
141+
* @match_values: match values
142+
* @matche_values_count: count of matches tuples
143+
* @action_values: actions values
144+
* @action_values_count: count of actions values
145+
* @counter: value of counter
146+
* @counter_valid: Specify if value is valid from hardware
147+
*/
148+
struct devlink_dpipe_entry {
149+
u64 index;
150+
struct devlink_dpipe_value *match_values;
151+
unsigned int match_values_count;
152+
struct devlink_dpipe_value *action_values;
153+
unsigned int action_values_count;
154+
u64 counter;
155+
bool counter_valid;
156+
};
157+
158+
/**
159+
* struct devlink_dpipe_dump_ctx - context provided to driver in order
160+
* to dump
161+
* @info: info
162+
* @cmd: devlink command
163+
* @skb: skb
164+
* @nest: top attribute
165+
* @hdr: hdr
166+
*/
167+
struct devlink_dpipe_dump_ctx {
168+
struct genl_info *info;
169+
enum devlink_command cmd;
170+
struct sk_buff *skb;
171+
struct nlattr *nest;
172+
void *hdr;
173+
};
174+
175+
struct devlink_dpipe_table_ops;
176+
177+
/**
178+
* struct devlink_dpipe_table - table object
179+
* @priv: private
180+
* @name: table name
181+
* @size: maximum number of entries
182+
* @counters_enabled: indicates if counters are active
183+
* @counter_control_extern: indicates if counter control is in dpipe or
184+
* external tool
185+
* @table_ops: table operations
186+
* @rcu: rcu
187+
*/
188+
struct devlink_dpipe_table {
189+
void *priv;
190+
struct list_head list;
191+
const char *name;
192+
u64 size;
193+
bool counters_enabled;
194+
bool counter_control_extern;
195+
struct devlink_dpipe_table_ops *table_ops;
196+
struct rcu_head rcu;
197+
};
198+
199+
/**
200+
* struct devlink_dpipe_table_ops - dpipe_table ops
201+
* @actions_dump - dumps all tables actions
202+
* @matches_dump - dumps all tables matches
203+
* @entries_dump - dumps all active entries in the table
204+
* @counters_set_update - when changing the counter status hardware sync
205+
* maybe needed to allocate/free counter related
206+
* resources
207+
*/
208+
struct devlink_dpipe_table_ops {
209+
int (*actions_dump)(void *priv, struct sk_buff *skb);
210+
int (*matches_dump)(void *priv, struct sk_buff *skb);
211+
int (*entries_dump)(void *priv, bool counters_enabled,
212+
struct devlink_dpipe_dump_ctx *dump_ctx);
213+
int (*counters_set_update)(void *priv, bool enable);
214+
};
215+
216+
/**
217+
* struct devlink_dpipe_headers - dpipe headers
218+
* @headers - header array can be shared (global bit) or driver specific
219+
* @headers_count - count of headers
220+
*/
221+
struct devlink_dpipe_headers {
222+
struct devlink_dpipe_header **headers;
223+
unsigned int headers_count;
224+
};
225+
52226
struct devlink_ops {
53227
int (*port_type_set)(struct devlink_port *devlink_port,
54228
enum devlink_port_type port_type);
@@ -132,6 +306,26 @@ int devlink_sb_register(struct devlink *devlink, unsigned int sb_index,
132306
u16 egress_pools_count, u16 ingress_tc_count,
133307
u16 egress_tc_count);
134308
void devlink_sb_unregister(struct devlink *devlink, unsigned int sb_index);
309+
int devlink_dpipe_table_register(struct devlink *devlink,
310+
const char *table_name,
311+
struct devlink_dpipe_table_ops *table_ops,
312+
void *priv, u64 size,
313+
bool counter_control_extern);
314+
void devlink_dpipe_table_unregister(struct devlink *devlink,
315+
const char *table_name);
316+
int devlink_dpipe_headers_register(struct devlink *devlink,
317+
struct devlink_dpipe_headers *dpipe_headers);
318+
void devlink_dpipe_headers_unregister(struct devlink *devlink);
319+
bool devlink_dpipe_table_counter_enabled(struct devlink *devlink,
320+
const char *table_name);
321+
int devlink_dpipe_entry_ctx_prepare(struct devlink_dpipe_dump_ctx *dump_ctx);
322+
int devlink_dpipe_entry_ctx_append(struct devlink_dpipe_dump_ctx *dump_ctx,
323+
struct devlink_dpipe_entry *entry);
324+
int devlink_dpipe_entry_ctx_close(struct devlink_dpipe_dump_ctx *dump_ctx);
325+
int devlink_dpipe_action_put(struct sk_buff *skb,
326+
struct devlink_dpipe_action *action);
327+
int devlink_dpipe_match_put(struct sk_buff *skb,
328+
struct devlink_dpipe_match *match);
135329

136330
#else
137331

@@ -200,6 +394,71 @@ static inline void devlink_sb_unregister(struct devlink *devlink,
200394
{
201395
}
202396

397+
static inline int
398+
devlink_dpipe_table_register(struct devlink *devlink,
399+
const char *table_name,
400+
struct devlink_dpipe_table_ops *table_ops,
401+
void *priv, u64 size,
402+
bool counter_control_extern)
403+
{
404+
return 0;
405+
}
406+
407+
static inline void devlink_dpipe_table_unregister(struct devlink *devlink,
408+
const char *table_name)
409+
{
410+
}
411+
412+
static inline int devlink_dpipe_headers_register(struct devlink *devlink,
413+
struct devlink_dpipe_headers *
414+
dpipe_headers)
415+
{
416+
return 0;
417+
}
418+
419+
static inline void devlink_dpipe_headers_unregister(struct devlink *devlink)
420+
{
421+
}
422+
423+
static inline bool devlink_dpipe_table_counter_enabled(struct devlink *devlink,
424+
const char *table_name)
425+
{
426+
return false;
427+
}
428+
429+
static inline int
430+
devlink_dpipe_entry_ctx_prepare(struct devlink_dpipe_dump_ctx *dump_ctx)
431+
{
432+
return 0;
433+
}
434+
435+
static inline int
436+
devlink_dpipe_entry_ctx_append(struct devlink_dpipe_dump_ctx *dump_ctx,
437+
struct devlink_dpipe_entry *entry)
438+
{
439+
return 0;
440+
}
441+
442+
static inline int
443+
devlink_dpipe_entry_ctx_close(struct devlink_dpipe_dump_ctx *dump_ctx)
444+
{
445+
return 0;
446+
}
447+
448+
static inline int
449+
devlink_dpipe_action_put(struct sk_buff *skb,
450+
struct devlink_dpipe_action *action)
451+
{
452+
return 0;
453+
}
454+
455+
static inline int
456+
devlink_dpipe_match_put(struct sk_buff *skb,
457+
struct devlink_dpipe_match *match)
458+
{
459+
return 0;
460+
}
461+
203462
#endif
204463

205464
#endif /* _NET_DEVLINK_H_ */

include/uapi/linux/devlink.h

Lines changed: 66 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,8 +65,12 @@ enum devlink_command {
6565
#define DEVLINK_CMD_ESWITCH_MODE_SET /* obsolete, never use this! */ \
6666
DEVLINK_CMD_ESWITCH_SET
6767

68-
/* add new commands above here */
68+
DEVLINK_CMD_DPIPE_TABLE_GET,
69+
DEVLINK_CMD_DPIPE_ENTRIES_GET,
70+
DEVLINK_CMD_DPIPE_HEADERS_GET,
71+
DEVLINK_CMD_DPIPE_TABLE_COUNTERS_SET,
6972

73+
/* add new commands above here */
7074
__DEVLINK_CMD_MAX,
7175
DEVLINK_CMD_MAX = __DEVLINK_CMD_MAX - 1
7276
};
@@ -148,10 +152,71 @@ enum devlink_attr {
148152
DEVLINK_ATTR_ESWITCH_MODE, /* u16 */
149153
DEVLINK_ATTR_ESWITCH_INLINE_MODE, /* u8 */
150154

155+
DEVLINK_ATTR_DPIPE_TABLES, /* nested */
156+
DEVLINK_ATTR_DPIPE_TABLE, /* nested */
157+
DEVLINK_ATTR_DPIPE_TABLE_NAME, /* string */
158+
DEVLINK_ATTR_DPIPE_TABLE_SIZE, /* u64 */
159+
DEVLINK_ATTR_DPIPE_TABLE_MATCHES, /* nested */
160+
DEVLINK_ATTR_DPIPE_TABLE_ACTIONS, /* nested */
161+
DEVLINK_ATTR_DPIPE_TABLE_COUNTERS_ENABLED, /* u8 */
162+
163+
DEVLINK_ATTR_DPIPE_ENTRIES, /* nested */
164+
DEVLINK_ATTR_DPIPE_ENTRY, /* nested */
165+
DEVLINK_ATTR_DPIPE_ENTRY_INDEX, /* u64 */
166+
DEVLINK_ATTR_DPIPE_ENTRY_MATCH_VALUES, /* nested */
167+
DEVLINK_ATTR_DPIPE_ENTRY_ACTION_VALUES, /* nested */
168+
DEVLINK_ATTR_DPIPE_ENTRY_COUNTER, /* u64 */
169+
170+
DEVLINK_ATTR_DPIPE_MATCH, /* nested */
171+
DEVLINK_ATTR_DPIPE_MATCH_VALUE, /* nested */
172+
DEVLINK_ATTR_DPIPE_MATCH_TYPE, /* u32 */
173+
174+
DEVLINK_ATTR_DPIPE_ACTION, /* nested */
175+
DEVLINK_ATTR_DPIPE_ACTION_VALUE, /* nested */
176+
DEVLINK_ATTR_DPIPE_ACTION_TYPE, /* u32 */
177+
178+
DEVLINK_ATTR_DPIPE_VALUE,
179+
DEVLINK_ATTR_DPIPE_VALUE_MASK,
180+
DEVLINK_ATTR_DPIPE_VALUE_MAPPING, /* u32 */
181+
182+
DEVLINK_ATTR_DPIPE_HEADERS, /* nested */
183+
DEVLINK_ATTR_DPIPE_HEADER, /* nested */
184+
DEVLINK_ATTR_DPIPE_HEADER_NAME, /* string */
185+
DEVLINK_ATTR_DPIPE_HEADER_ID, /* u32 */
186+
DEVLINK_ATTR_DPIPE_HEADER_FIELDS, /* nested */
187+
DEVLINK_ATTR_DPIPE_HEADER_GLOBAL, /* u8 */
188+
DEVLINK_ATTR_DPIPE_HEADER_INDEX, /* u32 */
189+
190+
DEVLINK_ATTR_DPIPE_FIELD, /* nested */
191+
DEVLINK_ATTR_DPIPE_FIELD_NAME, /* string */
192+
DEVLINK_ATTR_DPIPE_FIELD_ID, /* u32 */
193+
DEVLINK_ATTR_DPIPE_FIELD_BITWIDTH, /* u32 */
194+
DEVLINK_ATTR_DPIPE_FIELD_MAPPING_TYPE, /* u32 */
195+
196+
DEVLINK_ATTR_PAD,
197+
151198
/* add new attributes above here, update the policy in devlink.c */
152199

153200
__DEVLINK_ATTR_MAX,
154201
DEVLINK_ATTR_MAX = __DEVLINK_ATTR_MAX - 1
155202
};
156203

204+
/* Mapping between internal resource described by the field and system
205+
* structure
206+
*/
207+
enum devlink_dpipe_field_mapping_type {
208+
DEVLINK_DPIPE_FIELD_MAPPING_TYPE_NONE,
209+
DEVLINK_DPIPE_FIELD_MAPPING_TYPE_IFINDEX,
210+
};
211+
212+
/* Match type - specify the type of the match */
213+
enum devlink_dpipe_match_type {
214+
DEVLINK_DPIPE_MATCH_TYPE_FIELD_EXACT,
215+
};
216+
217+
/* Action type - specify the action type */
218+
enum devlink_dpipe_action_type {
219+
DEVLINK_DPIPE_ACTION_TYPE_FIELD_MODIFY,
220+
};
221+
157222
#endif /* _UAPI_LINUX_DEVLINK_H_ */

0 commit comments

Comments
 (0)