mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-08-14 06:12:32 +00:00
Key changes:
- The aspath and community structures now have a json_object where we store the json representation. This is updated at the same time the "str" for aspath/community are updated. We do this so that we do not have to compute the json rep - Added a small wrappper to libjson0, the wrapper lives in quagga's lib/json.[ch]. - Added more structure to the json output. Sample output: show ip bgp summary json ------------------------ BGP router identifier 10.0.0.1, local AS number 10 BGP table version 2400 RIB entries 4799, using 562 KiB of memory Peers 17, using 284 KiB of memory Peer groups 4, using 224 bytes of memory Neighbor V AS MsgRcvd MsgSent TblVer InQ OutQ Up/Down State/PfxRcd 1.1.1.1 4 10 0 0 0 0 0 never Active 10.0.0.2 4 10 104 7 0 0 0 00:02:29 600 10.0.0.3 4 10 104 7 0 0 0 00:02:29 600 10.0.0.4 4 10 204 7 0 0 0 00:02:29 1200 20.1.1.6 4 20 406 210 0 0 0 00:02:44 600 20.1.1.7 4 20 406 210 0 0 0 00:02:44 600 40.1.1.2 4 40 406 210 0 0 0 00:02:44 600 40.1.1.6 4 40 406 210 0 0 0 00:02:44 600 40.1.1.10 4 40 406 210 0 0 0 00:02:44 600 Total number of neighbors 9 { "as": 10, "dynamic-peers": 0, "peer-count": 17, "peer-group-count": 4, "peer-group-memory": 224, "peer-memory": 291312, "peers": { "1.1.1.1": { "inq": 0, "msgrcvd": 0, "msgsent": 0, "outq": 0, "prefix-advertised-count": 0, "prefix-received-count": 0, "remote-as": 10, "state": "Active", "table-version": 0, "uptime": "never", "version": 4 }, "10.0.0.2": { "hostname": "r2", "inq": 0, "msgrcvd": 104, "msgsent": 7, "outq": 0, "prefix-advertised-count": 1200, "prefix-received-count": 600, "remote-as": 10, "state": "Established", "table-version": 0, "uptime": "00:02:21", "version": 4 }, "10.0.0.3": { "hostname": "r3", "inq": 0, "msgrcvd": 104, "msgsent": 7, "outq": 0, "prefix-advertised-count": 1200, "prefix-received-count": 600, "remote-as": 10, "state": "Established", "table-version": 0, "uptime": "00:02:21", "version": 4 }, "10.0.0.4": { "hostname": "r4", "inq": 0, "msgrcvd": 204, "msgsent": 7, "outq": 0, "prefix-advertised-count": 1200, "prefix-received-count": 1200, "remote-as": 10, "state": "Established", "table-version": 0, "uptime": "00:02:21", "version": 4 }, "20.1.1.6": { "hostname": "r6", "inq": 0, "msgrcvd": 406, "msgsent": 210, "outq": 0, "prefix-advertised-count": 2400, "prefix-received-count": 600, "remote-as": 20, "state": "Established", "table-version": 0, "uptime": "00:02:36", "version": 4 }, "20.1.1.7": { "hostname": "r7", "inq": 0, "msgrcvd": 406, "msgsent": 210, "outq": 0, "prefix-advertised-count": 2400, "prefix-received-count": 600, "remote-as": 20, "state": "Established", "table-version": 0, "uptime": "00:02:36", "version": 4 }, "40.1.1.10": { "hostname": "r10", "inq": 0, "msgrcvd": 406, "msgsent": 210, "outq": 0, "prefix-advertised-count": 2400, "prefix-received-count": 600, "remote-as": 40, "state": "Established", "table-version": 0, "uptime": "00:02:36", "version": 4 }, "40.1.1.2": { "hostname": "r8", "inq": 0, "msgrcvd": 406, "msgsent": 210, "outq": 0, "prefix-advertised-count": 2400, "prefix-received-count": 600, "remote-as": 40, "state": "Established", "table-version": 0, "uptime": "00:02:36", "version": 4 }, "40.1.1.6": { "hostname": "r9", "inq": 0, "msgrcvd": 406, "msgsent": 210, "outq": 0, "prefix-advertised-count": 2400, "prefix-received-count": 600, "remote-as": 40, "state": "Established", "table-version": 0, "uptime": "00:02:36", "version": 4 } }, "rib-count": 4799, "rib-memory": 575880, "router-id": "10.0.0.1", "table-version": 2400, "total-peers": 9 } show ip bgp json ---------------- *> 40.1.1.2 0 0 100 200 300 400 500 40 i * 40.3.88.0/24 40.1.1.6 0 0 100 200 300 400 500 40 i * 40.1.1.10 0 0 100 200 300 400 500 40 i *> 40.1.1.2 0 0 100 200 300 400 500 40 i * 40.3.89.0/24 40.1.1.6 0 0 100 200 300 400 500 40 i * 40.1.1.10 0 0 100 200 300 400 500 40 i *> 40.1.1.2 0 0 100 200 300 400 500 40 i "40.3.88.0/24": [ { "aspath": "100 200 300 400 500 40", "med": 0, "nexthops": [ { "afi": "ipv4", "ip": "40.1.1.6", "used": true } ], "origin": "IGP", "path-from": "external", "valid": true, "weight": 0 }, { "aspath": "100 200 300 400 500 40", "med": 0, "nexthops": [ { "afi": "ipv4", "ip": "40.1.1.10", "used": true } ], "origin": "IGP", "path-from": "external", "valid": true, "weight": 0 }, { "aspath": "100 200 300 400 500 40", "bestpath": true, "med": 0, "nexthops": [ { "afi": "ipv4", "ip": "40.1.1.2", "used": true } ], "origin": "IGP", "path-from": "external", "valid": true, "weight": 0 } ], "40.3.89.0/24": [ { "aspath": "100 200 300 400 500 40", "med": 0, "nexthops": [ { "afi": "ipv4", "ip": "40.1.1.6", "used": true } ], "origin": "IGP", "path-from": "external", "valid": true, "weight": 0 }, { "aspath": "100 200 300 400 500 40", "med": 0, "nexthops": [ { "afi": "ipv4", "ip": "40.1.1.10", "used": true } ], "origin": "IGP", "path-from": "external", "valid": true, "weight": 0 }, { "aspath": "100 200 300 400 500 40", "bestpath": true, "med": 0, "nexthops": [ { "afi": "ipv4", "ip": "40.1.1.2", "used": true } ], "origin": "IGP", "path-from": "external", "valid": true, "weight": 0 } ], show ip bgp x.x.x.x json ------------------------ BGP routing table entry for 40.3.86.0/24 Paths: (3 available, best #3, table Default-IP-Routing-Table) Advertised to non peer-group peers: 10.0.0.2 10.0.0.3 10.0.0.4 20.1.1.6 20.1.1.7 40.1.1.2 40.1.1.6 40.1.1.10 100 200 300 400 500 40 40.1.1.6 from 40.1.1.6 (40.0.0.9) Origin IGP, metric 0, localpref 100, valid, external Community: 1:1 2:2 3:3 4:4 10:10 20:20 Extended Community: RT💯100 RT:200:200 RT:300:300 RT:400:400 SoO:44:44 SoO:55:55 SoO:66:66 Last update: Fri May 8 21:23:41 2015 100 200 300 400 500 40 40.1.1.10 from 40.1.1.10 (40.0.0.10) Origin IGP, metric 0, localpref 100, valid, external Community: 1:1 2:2 3:3 4:4 10:10 20:20 Extended Community: RT💯100 RT:200:200 RT:300:300 RT:400:400 SoO:44:44 SoO:55:55 SoO:66:66 Last update: Fri May 8 21:23:41 2015 100 200 300 400 500 40 40.1.1.2 from 40.1.1.2 (40.0.0.8) Origin IGP, metric 0, localpref 100, valid, external, best Community: 1:1 2:2 3:3 4:4 10:10 20:20 Extended Community: RT💯100 RT:200:200 RT:300:300 RT:400:400 SoO:44:44 SoO:55:55 SoO:66:66 Last update: Fri May 8 21:23:41 2015 { "advertised-to": { "10.0.0.2": { "hostname": "r2" }, "10.0.0.3": { "hostname": "r3" }, "10.0.0.4": { "hostname": "r4" }, "20.1.1.6": { "hostname": "r6" }, "20.1.1.7": { "hostname": "r7" }, "40.1.1.10": { "hostname": "r10" }, "40.1.1.2": { "hostname": "r8" }, "40.1.1.6": { "hostname": "r9" } }, "paths": [ { "aspath": { "length": 6, "segments": [ { "list": [ 100, 200, 300, 400, 500, 40 ], "type": "as-sequence" } ], "string": "100 200 300 400 500 40" }, "community": { "list": [ "1:1", "2:2", "3:3", "4:4", "10:10", "20:20" ], "string": "1:1 2:2 3:3 4:4 10:10 20:20" }, "extended-community": { "string": "RT💯100 RT:200:200 RT:300:300 RT:400:400 SoO:44:44 SoO:55:55 SoO:66:66" }, "last-update": { "epoch": 1431120222, "string": "Fri May 8 21:23:42 2015\n" }, "localpref": 100, "med": 0, "nexthops": [ { "accessible": true, "afi": "ipv4", "ip": "40.1.1.6", "metric": 0, "used": true } ], "origin": "IGP", "peer": { "hostname": "r9", "peer-id": "40.1.1.6", "router-id": "40.0.0.9", "type": "external" }, "valid": true }, { "aspath": { "length": 6, "segments": [ { "list": [ 100, 200, 300, 400, 500, 40 ], "type": "as-sequence" } ], "string": "100 200 300 400 500 40" }, "community": { "list": [ "1:1", "2:2", "3:3", "4:4", "10:10", "20:20" ], "string": "1:1 2:2 3:3 4:4 10:10 20:20" }, "extended-community": { "string": "RT💯100 RT:200:200 RT:300:300 RT:400:400 SoO:44:44 SoO:55:55 SoO:66:66" }, "last-update": { "epoch": 1431120222, "string": "Fri May 8 21:23:42 2015\n" }, "localpref": 100, "med": 0, "nexthops": [ { "accessible": true, "afi": "ipv4", "ip": "40.1.1.10", "metric": 0, "used": true } ], "origin": "IGP", "peer": { "hostname": "r10", "peer-id": "40.1.1.10", "router-id": "40.0.0.10", "type": "external" }, "valid": true }, { "aspath": { "length": 6, "segments": [ { "list": [ 100, 200, 300, 400, 500, 40 ], "type": "as-sequence" } ], "string": "100 200 300 400 500 40" }, "bestpath": { "overall": true }, "community": { "list": [ "1:1", "2:2", "3:3", "4:4", "10:10", "20:20" ], "string": "1:1 2:2 3:3 4:4 10:10 20:20" }, "extended-community": { "string": "RT💯100 RT:200:200 RT:300:300 RT:400:400 SoO:44:44 SoO:55:55 SoO:66:66" }, "last-update": { "epoch": 1431120222, "string": "Fri May 8 21:23:42 2015\n" }, "localpref": 100, "med": 0, "nexthops": [ { "accessible": true, "afi": "ipv4", "ip": "40.1.1.2", "metric": 0, "used": true } ], "origin": "IGP", "peer": { "hostname": "r8", "peer-id": "40.1.1.2", "router-id": "40.0.0.8", "type": "external" }, "valid": true } ], "prefix": "40.3.86.0", "prefixlen": 24 }
This commit is contained in:
parent
31a4638f7d
commit
f1aa5d8ac8
@ -99,6 +99,14 @@ assegment_data_new (int num)
|
||||
return (XMALLOC (MTYPE_AS_SEG_DATA, ASSEGMENT_DATA_SIZE (num, 1)));
|
||||
}
|
||||
|
||||
const char *aspath_segment_type_str[] = {
|
||||
"as-invalid",
|
||||
"as-set",
|
||||
"as-sequence",
|
||||
"as-confed-sequence",
|
||||
"as-confed-set"
|
||||
};
|
||||
|
||||
/* Get a new segment. Note that 0 is an allowed length,
|
||||
* and will result in a segment with no allocated data segment.
|
||||
* the caller should immediately assign data to the segment, as the segment
|
||||
@ -326,6 +334,13 @@ aspath_free (struct aspath *aspath)
|
||||
assegment_free_all (aspath->segments);
|
||||
if (aspath->str)
|
||||
XFREE (MTYPE_AS_STR, aspath->str);
|
||||
|
||||
if (aspath->json)
|
||||
{
|
||||
json_object_free(aspath->json);
|
||||
aspath->json = NULL;
|
||||
}
|
||||
|
||||
XFREE (MTYPE_AS_PATH, aspath);
|
||||
}
|
||||
|
||||
@ -500,10 +515,19 @@ aspath_make_str_count (struct aspath *as)
|
||||
int str_size;
|
||||
int len = 0;
|
||||
char *str_buf;
|
||||
json_object *jaspath_segments = NULL;
|
||||
json_object *jseg = NULL;
|
||||
json_object *jseg_list = NULL;
|
||||
|
||||
as->json = json_object_new_object();
|
||||
jaspath_segments = json_object_new_array();
|
||||
|
||||
/* Empty aspath. */
|
||||
if (!as->segments)
|
||||
{
|
||||
json_object_string_add(as->json, "string", "Local");
|
||||
json_object_object_add(as->json, "segments", jaspath_segments);
|
||||
json_object_int_add(as->json, "length", 0);
|
||||
as->str = XMALLOC (MTYPE_AS_STR, 1);
|
||||
as->str[0] = '\0';
|
||||
as->str_len = 0;
|
||||
@ -546,6 +570,8 @@ aspath_make_str_count (struct aspath *as)
|
||||
XFREE (MTYPE_AS_STR, str_buf);
|
||||
as->str = NULL;
|
||||
as->str_len = 0;
|
||||
json_object_free(as->json);
|
||||
as->json = NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
@ -571,15 +597,24 @@ aspath_make_str_count (struct aspath *as)
|
||||
len += snprintf (str_buf + len, str_size - len,
|
||||
"%c",
|
||||
aspath_delimiter_char (seg->type, AS_SEG_START));
|
||||
|
||||
jseg_list = json_object_new_array();
|
||||
|
||||
/* write out the ASNs, with their seperators, bar the last one*/
|
||||
for (i = 0; i < seg->length; i++)
|
||||
{
|
||||
json_object_array_add(jseg_list, json_object_new_int(seg->as[i]));
|
||||
|
||||
len += snprintf (str_buf + len, str_size - len, "%u", seg->as[i]);
|
||||
|
||||
if (i < (seg->length - 1))
|
||||
len += snprintf (str_buf + len, str_size - len, "%c", seperator);
|
||||
}
|
||||
|
||||
jseg = json_object_new_object();
|
||||
json_object_string_add(jseg, "type", aspath_segment_type_str[seg->type]);
|
||||
json_object_object_add(jseg, "list", jseg_list);
|
||||
json_object_array_add(jaspath_segments, jseg);
|
||||
|
||||
if (seg->type != AS_SEQUENCE)
|
||||
len += snprintf (str_buf + len, str_size - len, "%c",
|
||||
@ -596,6 +631,9 @@ aspath_make_str_count (struct aspath *as)
|
||||
as->str = str_buf;
|
||||
as->str_len = len;
|
||||
|
||||
json_object_string_add(as->json, "string", str_buf);
|
||||
json_object_object_add(as->json, "segments", jaspath_segments);
|
||||
json_object_int_add(as->json, "length", aspath_count_hops (as));
|
||||
return;
|
||||
}
|
||||
|
||||
@ -604,6 +642,13 @@ aspath_str_update (struct aspath *as)
|
||||
{
|
||||
if (as->str)
|
||||
XFREE (MTYPE_AS_STR, as->str);
|
||||
|
||||
if (as->json)
|
||||
{
|
||||
json_object_free(as->json);
|
||||
as->json = NULL;
|
||||
}
|
||||
|
||||
aspath_make_str_count (as);
|
||||
}
|
||||
|
||||
@ -637,6 +682,7 @@ aspath_dup (struct aspath *aspath)
|
||||
struct aspath *new;
|
||||
|
||||
new = XCALLOC (MTYPE_AS_PATH, sizeof (struct aspath));
|
||||
new->json = NULL;
|
||||
|
||||
if (aspath->segments)
|
||||
new->segments = assegment_dup_all (aspath->segments);
|
||||
@ -675,6 +721,7 @@ aspath_hash_alloc (void *arg)
|
||||
new->segments = aspath->segments;
|
||||
new->str = aspath->str;
|
||||
new->str_len = aspath->str_len;
|
||||
new->json = aspath->json;
|
||||
|
||||
return new;
|
||||
}
|
||||
@ -1239,6 +1286,7 @@ aspath_remove_private_asns (struct aspath *aspath)
|
||||
|
||||
new = XCALLOC (MTYPE_AS_PATH, sizeof (struct aspath));
|
||||
|
||||
new->json = NULL;
|
||||
new_seg = NULL;
|
||||
last_new_seg = NULL;
|
||||
seg = aspath->segments;
|
||||
@ -1628,7 +1676,11 @@ aspath_reconcile_as4 ( struct aspath *aspath, struct aspath *as4path)
|
||||
}
|
||||
|
||||
if (!hops)
|
||||
return aspath_dup (as4path);
|
||||
{
|
||||
newpath = aspath_dup (as4path);
|
||||
aspath_str_update(newpath);
|
||||
return newpath;
|
||||
}
|
||||
|
||||
if ( BGP_DEBUG(as4, AS4))
|
||||
zlog_debug("[AS4] got AS_PATH %s and AS4_PATH %s synthesizing now",
|
||||
|
@ -21,6 +21,8 @@ Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
#ifndef _QUAGGA_BGP_ASPATH_H
|
||||
#define _QUAGGA_BGP_ASPATH_H
|
||||
|
||||
#include "lib/json.h"
|
||||
|
||||
/* AS path segment type. */
|
||||
#define AS_SET 1
|
||||
#define AS_SEQUENCE 2
|
||||
@ -63,6 +65,9 @@ struct aspath
|
||||
/* segment data */
|
||||
struct assegment *segments;
|
||||
|
||||
/* AS path as a json object */
|
||||
json_object *json;
|
||||
|
||||
/* String expression of AS path. This string is used by vty output
|
||||
and AS path regular expression match. */
|
||||
char *str;
|
||||
|
@ -44,6 +44,13 @@ community_free (struct community *com)
|
||||
XFREE (MTYPE_COMMUNITY_VAL, com->val);
|
||||
if (com->str)
|
||||
XFREE (MTYPE_COMMUNITY_STR, com->str);
|
||||
|
||||
if (com->json)
|
||||
{
|
||||
json_object_free(com->json);
|
||||
com->json = NULL;
|
||||
}
|
||||
|
||||
XFREE (MTYPE_COMMUNITY, com);
|
||||
}
|
||||
|
||||
@ -170,6 +177,7 @@ community_uniq_sort (struct community *com)
|
||||
return NULL;
|
||||
|
||||
new = community_new ();;
|
||||
new->json = NULL;
|
||||
|
||||
for (i = 0; i < com->size; i++)
|
||||
{
|
||||
@ -194,8 +202,8 @@ community_uniq_sort (struct community *com)
|
||||
0xFFFFFF03 "local-AS"
|
||||
|
||||
For other values, "AS:VAL" format is used. */
|
||||
static char *
|
||||
community_com2str (struct community *com)
|
||||
static void
|
||||
set_community_string (struct community *com)
|
||||
{
|
||||
int i;
|
||||
char *str;
|
||||
@ -205,16 +213,25 @@ community_com2str (struct community *com)
|
||||
u_int32_t comval;
|
||||
u_int16_t as;
|
||||
u_int16_t val;
|
||||
json_object *json_community_list = NULL;
|
||||
json_object *json_string = NULL;
|
||||
|
||||
if (!com)
|
||||
return NULL;
|
||||
|
||||
com->json = json_object_new_object();
|
||||
json_community_list = json_object_new_array();
|
||||
|
||||
/* When communities attribute is empty. */
|
||||
if (com->size == 0)
|
||||
{
|
||||
str = XMALLOC (MTYPE_COMMUNITY_STR, 1);
|
||||
str[0] = '\0';
|
||||
return str;
|
||||
|
||||
json_object_string_add(com->json, "string", "");
|
||||
json_object_object_add(com->json, "list", json_community_list);
|
||||
com->str = str;
|
||||
return;
|
||||
}
|
||||
|
||||
/* Memory allocation is time consuming work. So we calculate
|
||||
@ -266,30 +283,42 @@ community_com2str (struct community *com)
|
||||
case COMMUNITY_INTERNET:
|
||||
strcpy (pnt, "internet");
|
||||
pnt += strlen ("internet");
|
||||
json_string = json_object_new_string("internet");
|
||||
json_object_array_add(json_community_list, json_string);
|
||||
break;
|
||||
case COMMUNITY_NO_EXPORT:
|
||||
strcpy (pnt, "no-export");
|
||||
pnt += strlen ("no-export");
|
||||
json_string = json_object_new_string("no-export");
|
||||
json_object_array_add(json_community_list, json_string);
|
||||
break;
|
||||
case COMMUNITY_NO_ADVERTISE:
|
||||
strcpy (pnt, "no-advertise");
|
||||
pnt += strlen ("no-advertise");
|
||||
json_string = json_object_new_string("no-advertise");
|
||||
json_object_array_add(json_community_list, json_string);
|
||||
break;
|
||||
case COMMUNITY_LOCAL_AS:
|
||||
strcpy (pnt, "local-AS");
|
||||
pnt += strlen ("local-AS");
|
||||
json_string = json_object_new_string("local-AS");
|
||||
json_object_array_add(json_community_list, json_string);
|
||||
break;
|
||||
default:
|
||||
as = (comval >> 16) & 0xFFFF;
|
||||
val = comval & 0xFFFF;
|
||||
sprintf (pnt, "%u:%d", as, val);
|
||||
json_string = json_object_new_string(pnt);
|
||||
json_object_array_add(json_community_list, json_string);
|
||||
pnt += strlen (pnt);
|
||||
break;
|
||||
}
|
||||
}
|
||||
*pnt = '\0';
|
||||
|
||||
return str;
|
||||
json_object_string_add(com->json, "string", str);
|
||||
json_object_object_add(com->json, "list", json_community_list);
|
||||
com->str = str;
|
||||
}
|
||||
|
||||
/* Intern communities attribute. */
|
||||
@ -314,7 +343,7 @@ community_intern (struct community *com)
|
||||
|
||||
/* Make string. */
|
||||
if (! find->str)
|
||||
find->str = community_com2str (find);
|
||||
set_community_string (find);
|
||||
|
||||
return find;
|
||||
}
|
||||
@ -383,9 +412,9 @@ community_str (struct community *com)
|
||||
{
|
||||
if (!com)
|
||||
return NULL;
|
||||
|
||||
|
||||
if (! com->str)
|
||||
com->str = community_com2str (com);
|
||||
set_community_string (com);
|
||||
return com->str;
|
||||
}
|
||||
|
||||
@ -599,7 +628,10 @@ community_str2com (const char *str)
|
||||
case community_token_no_advertise:
|
||||
case community_token_local_as:
|
||||
if (com == NULL)
|
||||
com = community_new();
|
||||
{
|
||||
com = community_new();
|
||||
com->json = NULL;
|
||||
}
|
||||
community_add_val (com, val);
|
||||
break;
|
||||
case community_token_unknown:
|
||||
|
@ -21,6 +21,8 @@ Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
#ifndef _QUAGGA_BGP_COMMUNITY_H
|
||||
#define _QUAGGA_BGP_COMMUNITY_H
|
||||
|
||||
#include "lib/json.h"
|
||||
|
||||
/* Communities attribute. */
|
||||
struct community
|
||||
{
|
||||
@ -33,6 +35,9 @@ struct community
|
||||
/* Communities value. */
|
||||
u_int32_t *val;
|
||||
|
||||
/* Communities as a json object */
|
||||
json_object *json;
|
||||
|
||||
/* String of community attribute. This sring is used by vty output
|
||||
and expanded community-list for regular expression match. */
|
||||
char *str;
|
||||
|
@ -20,7 +20,6 @@ Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
|
||||
#include <zebra.h>
|
||||
#include <math.h>
|
||||
#include <json/json.h>
|
||||
|
||||
#include "prefix.h"
|
||||
#include "memory.h"
|
||||
@ -587,8 +586,6 @@ bgp_damp_info_vty (struct vty *vty, struct bgp_info *binfo,
|
||||
time_t t_now, t_diff;
|
||||
char timebuf[BGP_UPTIME_LEN];
|
||||
int penalty;
|
||||
json_object *json_int;
|
||||
json_object *json_string;
|
||||
|
||||
if (!binfo->extra)
|
||||
return;
|
||||
@ -608,20 +605,16 @@ bgp_damp_info_vty (struct vty *vty, struct bgp_info *binfo,
|
||||
|
||||
if (json_path)
|
||||
{
|
||||
json_int = json_object_new_int(penalty);
|
||||
json_object_object_add(json_path, "dampening-penalty", json_int);
|
||||
|
||||
json_int = json_object_new_int(bdi->flap);
|
||||
json_object_object_add(json_path, "dampening-flap-count", json_int);
|
||||
|
||||
json_string = json_object_new_string(peer_uptime (bdi->start_time, timebuf, BGP_UPTIME_LEN));
|
||||
json_object_object_add(json_path, "dampening-flap-period", json_string);
|
||||
json_object_int_add(json_path, "dampening-penalty", penalty);
|
||||
json_object_int_add(json_path, "dampening-flap-count", bdi->flap);
|
||||
json_object_string_add(json_path, "dampening-flap-period",
|
||||
peer_uptime (bdi->start_time, timebuf, BGP_UPTIME_LEN));
|
||||
|
||||
if (CHECK_FLAG (binfo->flags, BGP_INFO_DAMPED)
|
||||
&& ! CHECK_FLAG (binfo->flags, BGP_INFO_HISTORY))
|
||||
{
|
||||
json_string = json_object_new_string(bgp_get_reuse_time (penalty, timebuf, BGP_UPTIME_LEN));
|
||||
json_object_object_add(json_path, "dampening-reuse-in", json_string);
|
||||
json_object_string_add(json_path, "dampening-reuse-in",
|
||||
bgp_get_reuse_time (penalty, timebuf, BGP_UPTIME_LEN));
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -21,7 +21,7 @@ Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
#ifndef _QUAGGA_BGP_DAMP_H
|
||||
#define _QUAGGA_BGP_DAMP_H
|
||||
|
||||
#include <json/json.h>
|
||||
#include "lib/json.h"
|
||||
|
||||
/* Structure maintained on a per-route basis. */
|
||||
struct bgp_damp_info
|
||||
|
@ -21,8 +21,6 @@ Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
#ifndef _QUAGGA_BGP_OPEN_H
|
||||
#define _QUAGGA_BGP_OPEN_H
|
||||
|
||||
#include <json/json.h>
|
||||
|
||||
/* Standard header for capability TLV */
|
||||
struct capability_header
|
||||
{
|
||||
|
642
bgpd/bgp_route.c
642
bgpd/bgp_route.c
File diff suppressed because it is too large
Load Diff
@ -21,7 +21,7 @@ Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
#ifndef _QUAGGA_BGP_ROUTE_H
|
||||
#define _QUAGGA_BGP_ROUTE_H
|
||||
|
||||
#include <json/json.h>
|
||||
#include "lib/json.h"
|
||||
#include "queue.h"
|
||||
#include "bgp_table.h"
|
||||
|
||||
|
172
bgpd/bgp_vty.c
172
bgpd/bgp_vty.c
@ -8453,11 +8453,8 @@ bgp_show_summary (struct vty *vty, struct bgp *bgp, int afi, int safi,
|
||||
char timebuf[BGP_UPTIME_LEN], dn_flag[2];
|
||||
int len;
|
||||
json_object *json = NULL;
|
||||
json_object *json_int = NULL;
|
||||
json_object *json_string = NULL;
|
||||
json_object *json_peer = NULL;
|
||||
json_object *json_peers = NULL;
|
||||
json_object *json_boolean_true = NULL;
|
||||
|
||||
/* Header string for each address family. */
|
||||
static char header[] = "Neighbor V AS MsgRcvd MsgSent TblVer InQ OutQ Up/Down State/PfxRcd";
|
||||
@ -8465,8 +8462,7 @@ bgp_show_summary (struct vty *vty, struct bgp *bgp, int afi, int safi,
|
||||
if (use_json)
|
||||
{
|
||||
json = json_object_new_object();
|
||||
json_peers = json_object_new_array();
|
||||
json_boolean_true = json_object_new_boolean(1);
|
||||
json_peers = json_object_new_object();
|
||||
}
|
||||
|
||||
for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
|
||||
@ -8484,11 +8480,8 @@ bgp_show_summary (struct vty *vty, struct bgp *bgp, int afi, int safi,
|
||||
/* Usage summary and header */
|
||||
if (use_json)
|
||||
{
|
||||
json_string = json_object_new_string(inet_ntoa (bgp->router_id));
|
||||
json_object_object_add(json, "router-id", json_string);
|
||||
|
||||
json_int = json_object_new_int(bgp->as);
|
||||
json_object_object_add(json, "as", json_int);
|
||||
json_object_string_add(json, "router-id", inet_ntoa (bgp->router_id));
|
||||
json_object_int_add(json, "as", bgp->as);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -8501,36 +8494,28 @@ bgp_show_summary (struct vty *vty, struct bgp *bgp, int afi, int safi,
|
||||
{
|
||||
if (use_json)
|
||||
{
|
||||
json_int = json_object_new_int(bgp->v_update_delay);
|
||||
json_object_object_add(json, "update-delay-limit", json_int);
|
||||
json_object_int_add(json, "update-delay-limit", bgp->v_update_delay);
|
||||
|
||||
if (bgp->v_update_delay != bgp->v_establish_wait)
|
||||
{
|
||||
json_int = json_object_new_int(bgp->v_establish_wait);
|
||||
json_object_object_add(json, "update-delay-establish-wait", json_int);
|
||||
}
|
||||
json_object_int_add(json, "update-delay-establish-wait", bgp->v_establish_wait);
|
||||
|
||||
if (bgp_update_delay_active(bgp))
|
||||
{
|
||||
json_string = json_object_new_string(bgp->update_delay_begin_time);
|
||||
json_object_object_add(json, "update-delay-first-neighbor", json_string);
|
||||
json_object_object_add(json, "update-delay-in-progress", json_boolean_true);
|
||||
json_object_string_add(json, "update-delay-first-neighbor", bgp->update_delay_begin_time);
|
||||
json_object_boolean_true_add(json, "update-delay-in-progress");
|
||||
}
|
||||
else
|
||||
{
|
||||
if (bgp->update_delay_over)
|
||||
{
|
||||
json_string = json_object_new_string(bgp->update_delay_begin_time);
|
||||
json_object_object_add(json, "update-delay-first-neighbor", json_string);
|
||||
|
||||
json_string = json_object_new_string(bgp->update_delay_end_time);
|
||||
json_object_object_add(json, "update-delay-bestpath-resumed", json_string);
|
||||
|
||||
json_string = json_object_new_string(bgp->update_delay_zebra_resume_time);
|
||||
json_object_object_add(json, "update-delay-zebra-update-resume", json_string);
|
||||
|
||||
json_string = json_object_new_string(bgp->update_delay_peers_resume_time);
|
||||
json_object_object_add(json, "update-delay-peer-update-resume", json_string);
|
||||
json_object_string_add(json, "update-delay-first-neighbor",
|
||||
bgp->update_delay_begin_time);
|
||||
json_object_string_add(json, "update-delay-bestpath-resumed",
|
||||
bgp->update_delay_end_time);
|
||||
json_object_string_add(json, "update-delay-zebra-update-resume",
|
||||
bgp->update_delay_zebra_resume_time);
|
||||
json_object_string_add(json, "update-delay-peer-update-resume",
|
||||
bgp->update_delay_peers_resume_time);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -8568,43 +8553,34 @@ bgp_show_summary (struct vty *vty, struct bgp *bgp, int afi, int safi,
|
||||
if (use_json)
|
||||
{
|
||||
if (bgp_maxmed_onstartup_configured(bgp) && bgp->maxmed_active)
|
||||
json_object_object_add(json, "max-med-on-startup", json_boolean_true);
|
||||
json_object_boolean_true_add(json, "max-med-on-startup");
|
||||
if (bgp->v_maxmed_admin)
|
||||
json_object_object_add(json, "max-med-administrative", json_boolean_true);
|
||||
json_object_boolean_true_add(json, "max-med-administrative");
|
||||
|
||||
json_int = json_object_new_int(bgp_table_version(bgp->rib[afi][safi]));
|
||||
json_object_object_add(json, "table-version", json_int);
|
||||
json_object_int_add(json, "table-version", bgp_table_version(bgp->rib[afi][safi]));
|
||||
|
||||
ents = bgp_table_count (bgp->rib[afi][safi]);
|
||||
json_int = json_object_new_int(ents);
|
||||
json_object_object_add(json, "rib-count", json_int);
|
||||
json_int = json_object_new_int(ents * sizeof (struct bgp_node));
|
||||
json_object_object_add(json, "rib-memory", json_int);
|
||||
json_object_int_add(json, "rib-count", ents);
|
||||
json_object_int_add(json, "rib-memory", ents * sizeof (struct bgp_node));
|
||||
|
||||
ents = listcount (bgp->peer);
|
||||
json_int = json_object_new_int(ents);
|
||||
json_object_object_add(json, "peer-count", json_int);
|
||||
json_int = json_object_new_int(ents * sizeof (struct peer));
|
||||
json_object_object_add(json, "peer-memory", json_int);
|
||||
json_object_int_add(json, "peer-count", ents);
|
||||
json_object_int_add(json, "peer-memory", ents * sizeof (struct peer));
|
||||
|
||||
if ((ents = listcount (bgp->rsclient)))
|
||||
{
|
||||
json_int = json_object_new_int(ents);
|
||||
json_object_object_add(json, "rsclient-count", json_int);
|
||||
json_int = json_object_new_int(ents * sizeof (struct peer));
|
||||
json_object_object_add(json, "rsclient-memory", json_int);
|
||||
json_object_int_add(json, "rsclient-count", ents);
|
||||
json_object_int_add(json, "rsclient-memory", ents * sizeof (struct peer));
|
||||
}
|
||||
|
||||
if ((ents = listcount (bgp->group)))
|
||||
{
|
||||
json_int = json_object_new_int(ents);
|
||||
json_object_object_add(json, "peer-group-count", json_int);
|
||||
json_int = json_object_new_int(ents * sizeof (struct peer_group));
|
||||
json_object_object_add(json, "peer-group-memory", json_int);
|
||||
json_object_int_add(json, "peer-group-count", ents);
|
||||
json_object_int_add(json, "peer-group-memory", ents * sizeof (struct peer_group));
|
||||
}
|
||||
|
||||
if (CHECK_FLAG (bgp->af_flags[afi][safi], BGP_CONFIG_DAMPENING))
|
||||
json_object_object_add(json, "dampening-enabled", json_boolean_true);
|
||||
json_object_boolean_true_add(json, "dampening-enabled");
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -8657,69 +8633,48 @@ bgp_show_summary (struct vty *vty, struct bgp *bgp, int afi, int safi,
|
||||
json_peer = json_object_new_object();
|
||||
|
||||
if (peer_dynamic_neighbor(peer))
|
||||
json_object_object_add(json_peer, "dynamic-peer", json_boolean_true);
|
||||
|
||||
json_string = json_object_new_string(peer->host);
|
||||
json_object_object_add(json_peer, "peer-id", json_string);
|
||||
json_object_boolean_true_add(json_peer, "dynamic-peer");
|
||||
|
||||
if (peer->hostname)
|
||||
{
|
||||
json_string = json_object_new_string(peer->hostname);
|
||||
json_object_object_add(json_peer, "hostname", json_string);
|
||||
}
|
||||
json_object_string_add(json_peer, "hostname", peer->hostname);
|
||||
|
||||
if (peer->domainname)
|
||||
{
|
||||
json_string = json_object_new_string(peer->domainname);
|
||||
json_object_object_add(json_peer, "domainname", json_string);
|
||||
}
|
||||
json_object_string_add(json_peer, "domainname", peer->domainname);
|
||||
|
||||
json_int = json_object_new_int(peer->as);
|
||||
json_object_object_add(json_peer, "remote-as", json_int);
|
||||
json_object_int_add(json_peer, "remote-as", peer->as);
|
||||
json_object_int_add(json_peer, "version", 4);
|
||||
json_object_int_add(json_peer, "msgrcvd",
|
||||
peer->open_in + peer->update_in + peer->keepalive_in
|
||||
+ peer->notify_in + peer->refresh_in
|
||||
+ peer->dynamic_cap_in);
|
||||
json_object_int_add(json_peer, "msgsent",
|
||||
peer->open_out + peer->update_out + peer->keepalive_out
|
||||
+ peer->notify_out + peer->refresh_out
|
||||
+ peer->dynamic_cap_out);
|
||||
|
||||
json_int = json_object_new_int(4);
|
||||
json_object_object_add(json_peer, "version", json_int);
|
||||
|
||||
json_int = json_object_new_int(peer->open_in + peer->update_in + peer->keepalive_in
|
||||
+ peer->notify_in + peer->refresh_in
|
||||
+ peer->dynamic_cap_in);
|
||||
json_object_object_add(json_peer, "msgrcvd", json_int);
|
||||
|
||||
json_int = json_object_new_int(peer->open_out + peer->update_out + peer->keepalive_out
|
||||
+ peer->notify_out + peer->refresh_out
|
||||
+ peer->dynamic_cap_out);
|
||||
json_object_object_add(json_peer, "msgsent", json_int);
|
||||
|
||||
json_int = json_object_new_int(peer->version[afi][safi]);
|
||||
json_object_object_add(json_peer, "table-version", json_int);
|
||||
|
||||
json_int = json_object_new_int(peer->obuf->count);
|
||||
json_object_object_add(json_peer, "outq", json_int);
|
||||
|
||||
json_int = json_object_new_int(0);
|
||||
json_object_object_add(json_peer, "inq", json_int);
|
||||
|
||||
json_string = json_object_new_string(peer_uptime (peer->uptime, timebuf, BGP_UPTIME_LEN));
|
||||
json_object_object_add(json_peer, "uptime", json_string);
|
||||
|
||||
json_int = json_object_new_int(peer->pcount[afi][safi]);
|
||||
json_object_object_add(json_peer, "prefix-received-count", json_int);
|
||||
|
||||
json_int = json_object_new_int(bgp_adj_out_count(peer, afi, safi));
|
||||
json_object_object_add(json_peer, "prefix-advertised-count", json_int);
|
||||
json_object_int_add(json_peer, "table-version", peer->version[afi][safi]);
|
||||
json_object_int_add(json_peer, "outq", peer->obuf->count);
|
||||
json_object_int_add(json_peer, "inq", 0);
|
||||
json_object_string_add(json_peer, "uptime",
|
||||
peer_uptime (peer->uptime, timebuf, BGP_UPTIME_LEN));
|
||||
json_object_int_add(json_peer, "prefix-received-count", peer->pcount[afi][safi]);
|
||||
json_object_int_add(json_peer, "prefix-advertised-count", bgp_adj_out_count(peer, afi, safi));
|
||||
|
||||
if (CHECK_FLAG (peer->flags, PEER_FLAG_SHUTDOWN))
|
||||
json_string = json_object_new_string("Idle (Admin)");
|
||||
|
||||
json_object_string_add(json_peer, "state", "Idle (Admin)");
|
||||
else if (CHECK_FLAG (peer->sflags, PEER_STATUS_PREFIX_OVERFLOW))
|
||||
json_string = json_object_new_string("Idle (PfxCt)");
|
||||
|
||||
json_object_string_add(json_peer, "state", "Idle (PfxCt)");
|
||||
else
|
||||
json_string = json_object_new_string(LOOKUP(bgp_status_msg, peer->status));
|
||||
json_object_string_add(json_peer, "state", LOOKUP(bgp_status_msg, peer->status));
|
||||
|
||||
json_object_object_add(json_peer, "state", json_string);
|
||||
if (peer->conf_if)
|
||||
json_object_string_add(json_peer, "id-type", "interface");
|
||||
else if (peer->su.sa.sa_family == AF_INET)
|
||||
json_object_string_add(json_peer, "id-type", "ipv4");
|
||||
else if (peer->su.sa.sa_family == AF_INET6)
|
||||
json_object_string_add(json_peer, "id-type", "ipv6");
|
||||
|
||||
json_object_array_add(json_peers, json_peer);
|
||||
json_object_object_add(json_peers, peer->host, json_peer);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -8756,7 +8711,7 @@ bgp_show_summary (struct vty *vty, struct bgp *bgp, int afi, int safi,
|
||||
0,
|
||||
peer->obuf->count);
|
||||
|
||||
vty_out (vty, "%8s",
|
||||
vty_out (vty, "%-8s",
|
||||
peer_uptime (peer->uptime, timebuf, BGP_UPTIME_LEN));
|
||||
|
||||
if (peer->status == Established)
|
||||
@ -8779,16 +8734,11 @@ bgp_show_summary (struct vty *vty, struct bgp *bgp, int afi, int safi,
|
||||
{
|
||||
json_object_object_add(json, "peers", json_peers);
|
||||
|
||||
json_int = json_object_new_int(count);
|
||||
json_object_object_add(json, "total-peers", json_int);
|
||||
|
||||
json_int = json_object_new_int(dn_count);
|
||||
json_object_object_add(json, "dynamic-peers", json_int);
|
||||
json_object_int_add(json, "total-peers", count);
|
||||
json_object_int_add(json, "dynamic-peers", dn_count);
|
||||
|
||||
vty_out (vty, "%s%s", json_object_to_json_string(json), VTY_NEWLINE);
|
||||
|
||||
// Recursively free all json structures
|
||||
json_object_put(json);
|
||||
json_object_free(json);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -5818,7 +5818,7 @@ peer_uptime (time_t uptime2, char *buf, size_t len)
|
||||
/* If there is no connection has been done before print `never'. */
|
||||
if (uptime2 == 0)
|
||||
{
|
||||
snprintf (buf, len, "never ");
|
||||
snprintf (buf, len, "never");
|
||||
return buf;
|
||||
}
|
||||
|
||||
|
@ -12,7 +12,7 @@ libzebra_la_SOURCES = \
|
||||
sockunion.c prefix.c thread.c if.c memory.c buffer.c table.c hash.c \
|
||||
filter.c routemap.c distribute.c stream.c str.c log.c plist.c \
|
||||
zclient.c sockopt.c smux.c agentx.c snmp.c md5.c if_rmap.c keychain.c privs.c \
|
||||
sigevent.c pqueue.c jhash.c memtypes.c workqueue.c nexthop.c
|
||||
sigevent.c pqueue.c jhash.c memtypes.c workqueue.c nexthop.c json.c
|
||||
|
||||
BUILT_SOURCES = memtypes.h route_types.h gitversion.h
|
||||
|
||||
@ -27,7 +27,7 @@ pkginclude_HEADERS = \
|
||||
str.h stream.h table.h thread.h vector.h version.h vty.h zebra.h \
|
||||
plist.h zclient.h sockopt.h smux.h md5.h if_rmap.h keychain.h \
|
||||
privs.h sigevent.h pqueue.h jhash.h zassert.h memtypes.h \
|
||||
workqueue.h route_types.h libospf.h nexthop.h
|
||||
workqueue.h route_types.h libospf.h nexthop.h json.h
|
||||
|
||||
EXTRA_DIST = \
|
||||
regex.c regex-gnu.h \
|
||||
|
59
lib/json.c
Normal file
59
lib/json.c
Normal file
@ -0,0 +1,59 @@
|
||||
/* json-c wrapper
|
||||
* Copyright (C) 2015 Cumulus Networks, Inc.
|
||||
*
|
||||
* This file is part of GNU Zebra.
|
||||
*
|
||||
* GNU Zebra 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, or (at your option) any
|
||||
* later version.
|
||||
*
|
||||
* GNU Zebra is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with GNU Zebra; see the file COPYING. If not, write to the Free
|
||||
* Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
* 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include "lib/json.h"
|
||||
|
||||
void
|
||||
json_object_string_add(struct json_object* obj, const char *key,
|
||||
const char *s)
|
||||
{
|
||||
json_object_object_add(obj, key, json_object_new_string(s));
|
||||
}
|
||||
|
||||
void
|
||||
json_object_int_add(struct json_object* obj, const char *key, int32_t i)
|
||||
{
|
||||
json_object_object_add(obj, key, json_object_new_int(i));
|
||||
}
|
||||
|
||||
void
|
||||
json_object_boolean_false_add(struct json_object* obj, const char *key)
|
||||
{
|
||||
json_object_object_add(obj, key, json_object_new_boolean(0));
|
||||
}
|
||||
|
||||
void
|
||||
json_object_boolean_true_add(struct json_object* obj, const char *key)
|
||||
{
|
||||
json_object_object_add(obj, key, json_object_new_boolean(1));
|
||||
}
|
||||
|
||||
struct json_object*
|
||||
json_object_lock(struct json_object *obj)
|
||||
{
|
||||
return json_object_get(obj);
|
||||
}
|
||||
|
||||
void
|
||||
json_object_free(struct json_object *obj)
|
||||
{
|
||||
json_object_put(obj);
|
||||
}
|
38
lib/json.h
Normal file
38
lib/json.h
Normal file
@ -0,0 +1,38 @@
|
||||
/* json-c wrapper
|
||||
* Copyright (C) 2015 Cumulus Networks, Inc.
|
||||
*
|
||||
* This file is part of GNU Zebra.
|
||||
*
|
||||
* GNU Zebra 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, or (at your option) any
|
||||
* later version.
|
||||
*
|
||||
* GNU Zebra is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with GNU Zebra; see the file COPYING. If not, write to the Free
|
||||
* Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
* 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef _QUAGGA_JSON_H
|
||||
#define _QUAGGA_JSON_H
|
||||
|
||||
#include <json/json.h>
|
||||
|
||||
extern void json_object_string_add(struct json_object* obj, const char *key,
|
||||
const char *s);
|
||||
extern void json_object_int_add(struct json_object* obj, const char *key,
|
||||
int32_t i);
|
||||
extern void json_object_boolean_false_add(struct json_object* obj,
|
||||
const char *key);
|
||||
extern void json_object_boolean_true_add(struct json_object* obj,
|
||||
const char *key);
|
||||
extern struct json_object* json_object_lock(struct json_object *obj);
|
||||
extern void json_object_free(struct json_object *obj);
|
||||
|
||||
#endif /* _QUAGGA_JSON_H */
|
Loading…
Reference in New Issue
Block a user