@@ -3844,13 +3844,50 @@ static void pr_out_reload_data(struct dl *dl, struct nlattr **tb)
pr_out_object_end(dl);
}
+static void pr_out_dev_nested(struct dl *dl, const struct nlmsghdr *nlh)
+{
+ struct nlattr *attr, *attr2;
+ int count = 0;
+
+ mnl_attr_for_each(attr, nlh, sizeof(struct genlmsghdr)) {
+ if (mnl_attr_get_type(attr) == DEVLINK_ATTR_NESTED_DEVLINK) {
+ count++;
+ attr2 = attr;
+ }
+ }
+ if (!count) {
+ return;
+ } else if (count == 1) {
+ pr_out_nested_handle(attr2);
+ return;
+ }
+
+ pr_out_array_start(dl, "nested_devlinks");
+ mnl_attr_for_each(attr, nlh, sizeof(struct genlmsghdr)) {
+ if (mnl_attr_get_type(attr) == DEVLINK_ATTR_NESTED_DEVLINK) {
+ check_indent_newline(dl);
+ if (dl->json_output)
+ open_json_object(NULL);
+ check_indent_newline(dl);
+ pr_out_nested_handle(attr);
+ if (dl->json_output)
+ close_json_object();
+ else
+ __pr_out_newline();
+ }
+ }
+ pr_out_array_end(dl);
+}
-static void pr_out_dev(struct dl *dl, struct nlattr **tb)
+static void pr_out_dev(struct dl *dl, const struct nlmsghdr *nlh,
+ struct nlattr **tb)
{
if ((tb[DEVLINK_ATTR_RELOAD_FAILED] && mnl_attr_get_u8(tb[DEVLINK_ATTR_RELOAD_FAILED])) ||
- (tb[DEVLINK_ATTR_DEV_STATS] && dl->stats)) {
+ (tb[DEVLINK_ATTR_DEV_STATS] && dl->stats) ||
+ tb[DEVLINK_ATTR_NESTED_DEVLINK]) {
__pr_out_handle_start(dl, tb, true, false);
pr_out_reload_data(dl, tb);
+ pr_out_dev_nested(dl, nlh);
pr_out_handle_end(dl);
} else {
pr_out_handle(dl, tb);
@@ -3867,7 +3904,7 @@ static int cmd_dev_show_cb(const struct nlmsghdr *nlh, void *data)
if (!tb[DEVLINK_ATTR_BUS_NAME] || !tb[DEVLINK_ATTR_DEV_NAME])
return MNL_CB_ERROR;
- pr_out_dev(dl, tb);
+ pr_out_dev(dl, nlh, tb);
return MNL_CB_OK;
}
@@ -6783,7 +6820,7 @@ static int cmd_mon_show_cb(const struct nlmsghdr *nlh, void *data)
return MNL_CB_ERROR;
pr_out_mon_header(genl->cmd);
dl->stats = true;
- pr_out_dev(dl, tb);
+ pr_out_dev(dl, nlh, tb);
pr_out_mon_footer();
break;
case DEVLINK_CMD_PORT_GET: /* fall through */