Merge branch 'master' into net-next

This commit is contained in:
Stephen Hemminger 2017-09-22 10:10:01 -07:00
commit b7a38c397d
8 changed files with 139 additions and 98 deletions

71
include/json_print.h Normal file
View File

@ -0,0 +1,71 @@
/*
* json_print.h "print regular or json output, based on json_writer".
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version
* 2 of the License, or (at your option) any later version.
*
* Authors: Julien Fortin, <julien@cumulusnetworks.com>
*/
#ifndef _JSON_PRINT_H_
#define _JSON_PRINT_H_
#include "json_writer.h"
#include "color.h"
json_writer_t *get_json_writer(void);
/*
* use:
* - PRINT_ANY for context based output
* - PRINT_FP for non json specific output
* - PRINT_JSON for json specific output
*/
enum output_type {
PRINT_FP = 1,
PRINT_JSON = 2,
PRINT_ANY = 4,
};
void new_json_obj(int json, FILE *fp);
void delete_json_obj(void);
bool is_json_context(void);
void set_current_fp(FILE *fp);
void fflush_fp(void);
void open_json_object(const char *str);
void close_json_object(void);
void open_json_array(enum output_type type, const char *delim);
void close_json_array(enum output_type type, const char *delim);
#define _PRINT_FUNC(type_name, type) \
void print_color_##type_name(enum output_type t, \
enum color_attr color, \
const char *key, \
const char *fmt, \
type value); \
\
static inline void print_##type_name(enum output_type t, \
const char *key, \
const char *fmt, \
type value) \
{ \
print_color_##type_name(t, -1, key, fmt, value); \
}
_PRINT_FUNC(int, int);
_PRINT_FUNC(bool, bool);
_PRINT_FUNC(null, const char*);
_PRINT_FUNC(string, const char*);
_PRINT_FUNC(uint, uint64_t);
_PRINT_FUNC(hu, unsigned short);
_PRINT_FUNC(hex, unsigned int);
_PRINT_FUNC(0xhex, unsigned int);
_PRINT_FUNC(lluint, unsigned long long int);
#undef _PRINT_FUNC
#endif /* _JSON_PRINT_H_ */

View File

@ -9,7 +9,7 @@ IPOBJ=ip.o ipaddress.o ipaddrlabel.o iproute.o iprule.o ipnetns.o \
link_iptnl.o link_gre6.o iplink_bond.o iplink_bond_slave.o iplink_hsr.o \
iplink_bridge.o iplink_bridge_slave.o ipfou.o iplink_ipvlan.o \
iplink_geneve.o iplink_vrf.o iproute_lwtunnel.o ipmacsec.o ipila.o \
ipvrf.o iplink_xstats.o ipseg6.o ip_print.o
ipvrf.o iplink_xstats.o ipseg6.o
RTMONOBJ=rtmon.o

View File

@ -1,3 +1,10 @@
#ifndef _IP_COMMON_H_
#define _IP_COMMON_H_
#include <stdbool.h>
#include "json_print.h"
struct link_filter {
int ifindex;
int family;
@ -101,8 +108,6 @@ static inline int rtm_get_table(struct rtmsg *r, struct rtattr **tb)
extern struct rtnl_handle rth;
#include <stdbool.h>
struct link_util {
struct link_util *next;
const char *id;
@ -141,58 +146,4 @@ int name_is_vrf(const char *name);
void print_num(FILE *fp, unsigned int width, uint64_t count);
#include "json_writer.h"
json_writer_t *get_json_writer(void);
/*
* use:
* - PRINT_ANY for context based output
* - PRINT_FP for non json specific output
* - PRINT_JSON for json specific output
*/
enum output_type {
PRINT_FP = 1,
PRINT_JSON = 2,
PRINT_ANY = 4,
};
void new_json_obj(int json, FILE *fp);
void delete_json_obj(void);
bool is_json_context(void);
void set_current_fp(FILE *fp);
void fflush_fp(void);
void open_json_object(const char *str);
void close_json_object(void);
void open_json_array(enum output_type type, const char *delim);
void close_json_array(enum output_type type, const char *delim);
#include "color.h"
#define _PRINT_FUNC(type_name, type) \
void print_color_##type_name(enum output_type t, \
enum color_attr color, \
const char *key, \
const char *fmt, \
type value); \
\
static inline void print_##type_name(enum output_type t, \
const char *key, \
const char *fmt, \
type value) \
{ \
print_color_##type_name(t, -1, key, fmt, value); \
}
_PRINT_FUNC(int, int);
_PRINT_FUNC(bool, bool);
_PRINT_FUNC(null, const char*);
_PRINT_FUNC(string, const char*);
_PRINT_FUNC(uint, uint64_t);
_PRINT_FUNC(hu, unsigned short);
_PRINT_FUNC(hex, unsigned int);
_PRINT_FUNC(0xhex, unsigned int);
_PRINT_FUNC(lluint, unsigned long long int);
#undef _PRINT_FUNC
#endif /* _IP_COMMON_H_ */

View File

@ -14,9 +14,9 @@
#include <linux/bpf.h>
#include "json_print.h"
#include "xdp.h"
#include "bpf_util.h"
#include "ip_common.h"
extern int force;
@ -82,6 +82,22 @@ int xdp_parse(int *argc, char ***argv, struct iplink_req *req, bool generic,
return 0;
}
static void xdp_dump_json(struct rtattr *tb[IFLA_XDP_MAX + 1])
{
__u32 prog_id = 0;
__u8 mode;
mode = rta_getattr_u8(tb[IFLA_XDP_ATTACHED]);
if (tb[IFLA_XDP_PROG_ID])
prog_id = rta_getattr_u32(tb[IFLA_XDP_PROG_ID]);
open_json_object("xdp");
print_uint(PRINT_JSON, "mode", NULL, mode);
if (prog_id)
bpf_dump_prog_info(NULL, prog_id);
close_json_object();
}
void xdp_dump(FILE *fp, struct rtattr *xdp, bool link, bool details)
{
struct rtattr *tb[IFLA_XDP_MAX + 1];
@ -94,34 +110,32 @@ void xdp_dump(FILE *fp, struct rtattr *xdp, bool link, bool details)
return;
mode = rta_getattr_u8(tb[IFLA_XDP_ATTACHED]);
if (is_json_context()) {
print_uint(PRINT_JSON, "attached", NULL, mode);
} else {
if (mode == XDP_ATTACHED_NONE)
return;
else if (details && link)
fprintf(fp, "%s prog/xdp", _SL_);
else if (mode == XDP_ATTACHED_DRV)
fprintf(fp, "xdp");
else if (mode == XDP_ATTACHED_SKB)
fprintf(fp, "xdpgeneric");
else if (mode == XDP_ATTACHED_HW)
fprintf(fp, "xdpoffload");
else
fprintf(fp, "xdp[%u]", mode);
if (mode == XDP_ATTACHED_NONE)
return;
else if (is_json_context())
return details ? (void)0 : xdp_dump_json(tb);
else if (details && link)
fprintf(fp, "%s prog/xdp", _SL_);
else if (mode == XDP_ATTACHED_DRV)
fprintf(fp, "xdp");
else if (mode == XDP_ATTACHED_SKB)
fprintf(fp, "xdpgeneric");
else if (mode == XDP_ATTACHED_HW)
fprintf(fp, "xdpoffload");
else
fprintf(fp, "xdp[%u]", mode);
if (tb[IFLA_XDP_PROG_ID])
prog_id = rta_getattr_u32(tb[IFLA_XDP_PROG_ID]);
if (!details) {
if (prog_id && !link)
fprintf(fp, "/id:%u", prog_id);
fprintf(fp, " ");
return;
}
if (tb[IFLA_XDP_PROG_ID])
prog_id = rta_getattr_u32(tb[IFLA_XDP_PROG_ID]);
if (!details) {
if (prog_id && !link)
fprintf(fp, "/id:%u", prog_id);
fprintf(fp, " ");
return;
}
if (prog_id) {
fprintf(fp, " ");
bpf_dump_prog_info(fp, prog_id);
}
if (prog_id) {
fprintf(fp, " ");
bpf_dump_prog_info(fp, prog_id);
}
}

View File

@ -3,7 +3,7 @@ include ../config.mk
CFLAGS += -fPIC
UTILOBJ = utils.o rt_names.o ll_types.o ll_proto.o ll_addr.o \
inet_proto.o namespace.o json_writer.o \
inet_proto.o namespace.o json_writer.o json_print.o \
names.o color.o bpf.o exec.o fs.o
NLOBJ=libgenl.o ll_map.o libnetlink.o

View File

@ -40,6 +40,7 @@
#include <arpa/inet.h>
#include "utils.h"
#include "json_print.h"
#include "bpf_util.h"
#include "bpf_elf.h"
@ -186,23 +187,29 @@ int bpf_dump_prog_info(FILE *f, uint32_t id)
int fd, ret, dump_ok = 0;
SPRINT_BUF(tmp);
fprintf(f, "id %u ", id);
open_json_object("prog");
print_uint(PRINT_ANY, "id", "id %u ", id);
fd = bpf_prog_fd_by_id(id);
if (fd < 0)
return dump_ok;
goto out;
ret = bpf_prog_info_by_fd(fd, &info, &len);
if (!ret && len) {
fprintf(f, "tag %s ",
hexstring_n2a(info.tag, sizeof(info.tag),
tmp, sizeof(tmp)));
if (info.jited_prog_len)
int jited = !!info.jited_prog_len;
print_string(PRINT_ANY, "tag", "tag %s ",
hexstring_n2a(info.tag, sizeof(info.tag),
tmp, sizeof(tmp)));
print_uint(PRINT_JSON, "jited", NULL, jited);
if (jited && !is_json_context())
fprintf(f, "jited ");
dump_ok = 1;
}
close(fd);
out:
close_json_object();
return dump_ok;
}

View File

@ -1,5 +1,5 @@
/*
* ip_print.c "ip print regular or json output".
* json_print.c "print regular or json output, based on json_writer".
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@ -7,15 +7,13 @@
* 2 of the License, or (at your option) any later version.
*
* Authors: Julien Fortin, <julien@cumulusnetworks.com>
*
*/
#include <stdarg.h>
#include <stdio.h>
#include "utils.h"
#include "ip_common.h"
#include "json_writer.h"
#include "json_print.h"
static json_writer_t *_jw;
static FILE *_fp;

View File

@ -322,7 +322,7 @@ normal routing tables.
.P
.B Route tables:
Linux-2.x can pack routes into several routing tables identified
by a number in the range from 1 to 2^31 or by name from the file
by a number in the range from 1 to 2^32-1 or by name from the file
.B @SYSCONFDIR@/rt_tables
By default all normal routes are inserted into the
.B main