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 \ 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_bridge.o iplink_bridge_slave.o ipfou.o iplink_ipvlan.o \
iplink_geneve.o iplink_vrf.o iproute_lwtunnel.o ipmacsec.o ipila.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 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 { struct link_filter {
int ifindex; int ifindex;
int family; int family;
@ -101,8 +108,6 @@ static inline int rtm_get_table(struct rtmsg *r, struct rtattr **tb)
extern struct rtnl_handle rth; extern struct rtnl_handle rth;
#include <stdbool.h>
struct link_util { struct link_util {
struct link_util *next; struct link_util *next;
const char *id; 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); void print_num(FILE *fp, unsigned int width, uint64_t count);
#include "json_writer.h" #endif /* _IP_COMMON_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

View File

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

View File

@ -3,7 +3,7 @@ include ../config.mk
CFLAGS += -fPIC CFLAGS += -fPIC
UTILOBJ = utils.o rt_names.o ll_types.o ll_proto.o ll_addr.o \ 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 names.o color.o bpf.o exec.o fs.o
NLOBJ=libgenl.o ll_map.o libnetlink.o NLOBJ=libgenl.o ll_map.o libnetlink.o

View File

@ -40,6 +40,7 @@
#include <arpa/inet.h> #include <arpa/inet.h>
#include "utils.h" #include "utils.h"
#include "json_print.h"
#include "bpf_util.h" #include "bpf_util.h"
#include "bpf_elf.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; int fd, ret, dump_ok = 0;
SPRINT_BUF(tmp); 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); fd = bpf_prog_fd_by_id(id);
if (fd < 0) if (fd < 0)
return dump_ok; goto out;
ret = bpf_prog_info_by_fd(fd, &info, &len); ret = bpf_prog_info_by_fd(fd, &info, &len);
if (!ret && len) { if (!ret && len) {
fprintf(f, "tag %s ", int jited = !!info.jited_prog_len;
hexstring_n2a(info.tag, sizeof(info.tag),
tmp, sizeof(tmp))); print_string(PRINT_ANY, "tag", "tag %s ",
if (info.jited_prog_len) 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 "); fprintf(f, "jited ");
dump_ok = 1; dump_ok = 1;
} }
close(fd); close(fd);
out:
close_json_object();
return dump_ok; 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 * This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License * 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. * 2 of the License, or (at your option) any later version.
* *
* Authors: Julien Fortin, <julien@cumulusnetworks.com> * Authors: Julien Fortin, <julien@cumulusnetworks.com>
*
*/ */
#include <stdarg.h> #include <stdarg.h>
#include <stdio.h> #include <stdio.h>
#include "utils.h" #include "utils.h"
#include "ip_common.h" #include "json_print.h"
#include "json_writer.h"
static json_writer_t *_jw; static json_writer_t *_jw;
static FILE *_fp; static FILE *_fp;

View File

@ -322,7 +322,7 @@ normal routing tables.
.P .P
.B Route tables: .B Route tables:
Linux-2.x can pack routes into several routing tables identified 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 .B @SYSCONFDIR@/rt_tables
By default all normal routes are inserted into the By default all normal routes are inserted into the
.B main .B main