diff options
Diffstat (limited to 'zebra/zebra_rnh.c')
| -rw-r--r-- | zebra/zebra_rnh.c | 185 | 
1 files changed, 146 insertions, 39 deletions
diff --git a/zebra/zebra_rnh.c b/zebra/zebra_rnh.c index 7934a9d206..599c679864 100644 --- a/zebra/zebra_rnh.c +++ b/zebra/zebra_rnh.c @@ -62,7 +62,8 @@ static void free_state(vrf_id_t vrf_id, struct route_entry *re,  static void copy_state(struct rnh *rnh, const struct route_entry *re,  		       struct route_node *rn);  static bool compare_state(struct route_entry *r1, struct route_entry *r2); -static void print_rnh(struct route_node *rn, struct vty *vty); +static void print_rnh(struct route_node *rn, struct vty *vty, +		      json_object *json);  static int zebra_client_cleanup_rnh(struct zserv *client);  void zebra_rnh_init(void) @@ -803,7 +804,8 @@ void zebra_evaluate_rnh(struct zebra_vrf *zvrf, afi_t afi, int force,  }  void zebra_print_rnh_table(vrf_id_t vrfid, afi_t afi, safi_t safi, -			   struct vty *vty, const struct prefix *p) +			   struct vty *vty, const struct prefix *p, +			   json_object *json)  {  	struct route_table *table;  	struct route_node *rn; @@ -820,7 +822,7 @@ void zebra_print_rnh_table(vrf_id_t vrfid, afi_t afi, safi_t safi,  			continue;  		if (rn->info) -			print_rnh(rn, vty); +			print_rnh(rn, vty, json);  	}  } @@ -1268,73 +1270,178 @@ failure:  	return -1;  } -static void print_nh(struct nexthop *nexthop, struct vty *vty) +static void print_nh(struct nexthop *nexthop, struct vty *vty, +		     json_object *json)  { -	char buf[BUFSIZ];  	struct zebra_ns *zns = zebra_ns_lookup(nexthop->vrf_id);  	switch (nexthop->type) {  	case NEXTHOP_TYPE_IPV4:  	case NEXTHOP_TYPE_IPV4_IFINDEX: -		vty_out(vty, " via %pI4", &nexthop->gate.ipv4); -		if (nexthop->ifindex) -			vty_out(vty, ", %s", -				ifindex2ifname_per_ns(zns, nexthop->ifindex)); +		if (json) { +			json_object_string_addf(json, "ip", "%pI4", +						&nexthop->gate.ipv4); +			if (nexthop->ifindex) +				json_object_string_add( +					json, "interface", +					ifindex2ifname_per_ns( +						zns, nexthop->ifindex)); +		} else { +			vty_out(vty, " via %pI4", &nexthop->gate.ipv4); +			if (nexthop->ifindex) +				vty_out(vty, ", %s", +					ifindex2ifname_per_ns( +						zns, nexthop->ifindex)); +		}  		break;  	case NEXTHOP_TYPE_IPV6:  	case NEXTHOP_TYPE_IPV6_IFINDEX: -		vty_out(vty, " %s", -			inet_ntop(AF_INET6, &nexthop->gate.ipv6, buf, BUFSIZ)); -		if (nexthop->ifindex) -			vty_out(vty, ", via %s", -				ifindex2ifname_per_ns(zns, nexthop->ifindex)); +		if (json) { +			json_object_string_addf(json, "ip", "%pI6", +						&nexthop->gate.ipv6); +			if (nexthop->ifindex) +				json_object_string_add( +					json, "interface", +					ifindex2ifname_per_ns( +						zns, nexthop->ifindex)); +		} else { +			vty_out(vty, " %pI6", &nexthop->gate.ipv6); +			if (nexthop->ifindex) +				vty_out(vty, ", via %s", +					ifindex2ifname_per_ns( +						zns, nexthop->ifindex)); +		}  		break;  	case NEXTHOP_TYPE_IFINDEX: -		vty_out(vty, " is directly connected, %s", -			ifindex2ifname_per_ns(zns, nexthop->ifindex)); +		if (json) { +			json_object_string_add( +				json, "interface", +				ifindex2ifname_per_ns(zns, nexthop->ifindex)); +			json_object_boolean_true_add(json, "directlyConnected"); +		} else { +			vty_out(vty, " is directly connected, %s", +				ifindex2ifname_per_ns(zns, nexthop->ifindex)); +		}  		break;  	case NEXTHOP_TYPE_BLACKHOLE: -		vty_out(vty, " is directly connected, Null0"); +		if (json) { +			json_object_string_add(json, "interface", "Null0"); +			json_object_boolean_true_add(json, "directlyConnected"); +		} else { +			vty_out(vty, " is directly connected, Null0"); +		}  		break;  	default:  		break;  	} -	vty_out(vty, "\n"); + +	if (!json) +		vty_out(vty, "\n");  } -static void print_rnh(struct route_node *rn, struct vty *vty) +static void print_rnh(struct route_node *rn, struct vty *vty, json_object *json)  {  	struct rnh *rnh;  	struct nexthop *nexthop;  	struct listnode *node;  	struct zserv *client;  	char buf[BUFSIZ]; +	json_object *json_nht = NULL; +	json_object *json_client_array = NULL; +	json_object *json_client = NULL; +	json_object *json_nexthop_array = NULL; +	json_object *json_nexthop = NULL;  	rnh = rn->info; -	vty_out(vty, "%s%s\n", -		inet_ntop(rn->p.family, &rn->p.u.prefix, buf, BUFSIZ), -		CHECK_FLAG(rnh->flags, ZEBRA_NHT_CONNECTED) ? "(Connected)" -							    : ""); -	if (rnh->state) { -		vty_out(vty, " resolved via %s\n", -			zebra_route_string(rnh->state->type)); -		for (nexthop = rnh->state->nhe->nhg.nexthop; nexthop; -		     nexthop = nexthop->next) -			print_nh(nexthop, vty); -	} else -		vty_out(vty, " unresolved%s\n", + +	if (json) { +		json_nht = json_object_new_object(); +		json_nexthop_array = json_object_new_array(); +		json_client_array = json_object_new_array(); + +		json_object_object_add( +			json, +			inet_ntop(rn->p.family, &rn->p.u.prefix, buf, BUFSIZ), +			json_nht); +		json_object_boolean_add( +			json_nht, "nhtConnected", +			CHECK_FLAG(rnh->flags, ZEBRA_NHT_CONNECTED)); +		json_object_object_add(json_nht, "clientList", +				       json_client_array); +		json_object_object_add(json_nht, "gates", json_nexthop_array); +	} else { +		vty_out(vty, "%s%s\n", +			inet_ntop(rn->p.family, &rn->p.u.prefix, buf, BUFSIZ),  			CHECK_FLAG(rnh->flags, ZEBRA_NHT_CONNECTED)  				? "(Connected)"  				: ""); +	} + +	if (rnh->state) { +		if (json) +			json_object_string_add( +				json_nht, "resolvedProtocol", +				zebra_route_string(rnh->state->type)); +		else +			vty_out(vty, " resolved via %s\n", +				zebra_route_string(rnh->state->type)); + +		for (nexthop = rnh->state->nhe->nhg.nexthop; nexthop; +		     nexthop = nexthop->next) { +			if (json) { +				json_nexthop = json_object_new_object(); +				json_object_array_add(json_nexthop_array, +						      json_nexthop); +			} +			print_nh(nexthop, vty, json_nexthop); +		} +	} else { +		if (json) +			json_object_boolean_add( +				json_nht, "unresolved", +				CHECK_FLAG(rnh->flags, ZEBRA_NHT_CONNECTED)); +		else +			vty_out(vty, " unresolved%s\n", +				CHECK_FLAG(rnh->flags, ZEBRA_NHT_CONNECTED) +					? "(Connected)" +					: ""); +	} + +	if (!json) +		vty_out(vty, " Client list:"); + +	for (ALL_LIST_ELEMENTS_RO(rnh->client_list, node, client)) { +		if (json) { +			json_client = json_object_new_object(); +			json_object_array_add(json_client_array, json_client); + +			json_object_string_add( +				json_client, "protocol", +				zebra_route_string(client->proto)); +			json_object_int_add(json_client, "socket", +					    client->sock); +			json_object_string_add(json_client, "protocolFiltered", +					       (rnh->filtered[client->proto] +							? "(filtered)" +							: "none")); +		} else { +			vty_out(vty, " %s(fd %d)%s", +				zebra_route_string(client->proto), client->sock, +				rnh->filtered[client->proto] ? "(filtered)" +							     : ""); +		} +	} + +	if (!list_isempty(rnh->zebra_pseudowire_list)) { +		if (json) +			json_object_boolean_true_add(json_nht, +						     "zebraPseudowires"); +		else +			vty_out(vty, " zebra[pseudowires]"); +	} -	vty_out(vty, " Client list:"); -	for (ALL_LIST_ELEMENTS_RO(rnh->client_list, node, client)) -		vty_out(vty, " %s(fd %d)%s", zebra_route_string(client->proto), -			client->sock, -			rnh->filtered[client->proto] ? "(filtered)" : ""); -	if (!list_isempty(rnh->zebra_pseudowire_list)) -		vty_out(vty, " zebra[pseudowires]"); -	vty_out(vty, "\n"); +	if (!json) +		vty_out(vty, "\n");  }  static int zebra_cleanup_rnh_client(vrf_id_t vrf_id, afi_t afi, safi_t safi,  | 
