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:
Donald Sharp 2015-06-12 07:59:11 -07:00
parent 31a4638f7d
commit f1aa5d8ac8
14 changed files with 578 additions and 476 deletions

View File

@ -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",

View File

@ -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;

View File

@ -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:

View File

@ -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;

View File

@ -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

View File

@ -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

View File

@ -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
{

File diff suppressed because it is too large Load Diff

View File

@ -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"

View File

@ -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
{

View File

@ -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;
}

View File

@ -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
View 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
View 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 */