2 * Copyright (C) 2018 NetDEF, Inc.
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License as published by the Free
7 * Software Foundation; either version 2 of the License, or (at your option)
10 * This program is distributed in the hope that it will be useful, but WITHOUT
11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
15 * You should have received a copy of the GNU General Public License along
16 * with this program; see the file COPYING; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
29 #include "northbound.h"
32 #include "ripd/ripd.h"
33 #include "ripd/rip_nb.h"
34 #include "ripd/rip_debug.h"
35 #include "ripd/rip_interface.h"
38 * XPath: /frr-ripd:ripd/instance
40 const void *ripd_instance_get_next(struct nb_cb_get_next_args
*args
)
42 struct rip
*rip
= (struct rip
*)args
->list_entry
;
44 if (args
->list_entry
== NULL
)
45 rip
= RB_MIN(rip_instance_head
, &rip_instances
);
47 rip
= RB_NEXT(rip_instance_head
, rip
);
52 int ripd_instance_get_keys(struct nb_cb_get_keys_args
*args
)
54 const struct rip
*rip
= args
->list_entry
;
57 strlcpy(args
->keys
->key
[0], rip
->vrf_name
, sizeof(args
->keys
->key
[0]));
62 const void *ripd_instance_lookup_entry(struct nb_cb_lookup_entry_args
*args
)
64 const char *vrf_name
= args
->keys
->key
[0];
66 return rip_lookup_by_vrf_name(vrf_name
);
70 * XPath: /frr-ripd:ripd/instance/state/neighbors/neighbor
72 const void *ripd_instance_state_neighbors_neighbor_get_next(
73 struct nb_cb_get_next_args
*args
)
75 const struct rip
*rip
= args
->parent_list_entry
;
76 struct listnode
*node
;
78 if (args
->list_entry
== NULL
)
79 node
= listhead(rip
->peer_list
);
81 node
= listnextnode((struct listnode
*)args
->list_entry
);
86 int ripd_instance_state_neighbors_neighbor_get_keys(
87 struct nb_cb_get_keys_args
*args
)
89 const struct listnode
*node
= args
->list_entry
;
90 const struct rip_peer
*peer
= listgetdata(node
);
93 (void)inet_ntop(AF_INET
, &peer
->addr
, args
->keys
->key
[0],
94 sizeof(args
->keys
->key
[0]));
99 const void *ripd_instance_state_neighbors_neighbor_lookup_entry(
100 struct nb_cb_lookup_entry_args
*args
)
102 const struct rip
*rip
= args
->parent_list_entry
;
103 struct in_addr address
;
104 struct rip_peer
*peer
;
105 struct listnode
*node
;
107 yang_str2ipv4(args
->keys
->key
[0], &address
);
109 for (ALL_LIST_ELEMENTS_RO(rip
->peer_list
, node
, peer
)) {
110 if (IPV4_ADDR_SAME(&peer
->addr
, &address
))
118 * XPath: /frr-ripd:ripd/instance/state/neighbors/neighbor/address
120 struct yang_data
*ripd_instance_state_neighbors_neighbor_address_get_elem(
121 struct nb_cb_get_elem_args
*args
)
123 const struct listnode
*node
= args
->list_entry
;
124 const struct rip_peer
*peer
= listgetdata(node
);
126 return yang_data_new_ipv4(args
->xpath
, &peer
->addr
);
130 * XPath: /frr-ripd:ripd/instance/state/neighbors/neighbor/last-update
132 struct yang_data
*ripd_instance_state_neighbors_neighbor_last_update_get_elem(
133 struct nb_cb_get_elem_args
*args
)
135 /* TODO: yang:date-and-time is tricky */
140 * XPath: /frr-ripd:ripd/instance/state/neighbors/neighbor/bad-packets-rcvd
143 ripd_instance_state_neighbors_neighbor_bad_packets_rcvd_get_elem(
144 struct nb_cb_get_elem_args
*args
)
146 const struct listnode
*node
= args
->list_entry
;
147 const struct rip_peer
*peer
= listgetdata(node
);
149 return yang_data_new_uint32(args
->xpath
, peer
->recv_badpackets
);
153 * XPath: /frr-ripd:ripd/instance/state/neighbors/neighbor/bad-routes-rcvd
156 ripd_instance_state_neighbors_neighbor_bad_routes_rcvd_get_elem(
157 struct nb_cb_get_elem_args
*args
)
159 const struct listnode
*node
= args
->list_entry
;
160 const struct rip_peer
*peer
= listgetdata(node
);
162 return yang_data_new_uint32(args
->xpath
, peer
->recv_badroutes
);
166 * XPath: /frr-ripd:ripd/instance/state/routes/route
169 ripd_instance_state_routes_route_get_next(struct nb_cb_get_next_args
*args
)
171 const struct rip
*rip
= args
->parent_list_entry
;
172 struct route_node
*rn
;
174 if (args
->list_entry
== NULL
)
175 rn
= route_top(rip
->table
);
177 rn
= route_next((struct route_node
*)args
->list_entry
);
178 /* Optimization: skip empty route nodes. */
179 while (rn
&& rn
->info
== NULL
)
185 int ripd_instance_state_routes_route_get_keys(struct nb_cb_get_keys_args
*args
)
187 const struct route_node
*rn
= args
->list_entry
;
190 (void)prefix2str(&rn
->p
, args
->keys
->key
[0],
191 sizeof(args
->keys
->key
[0]));
196 const void *ripd_instance_state_routes_route_lookup_entry(
197 struct nb_cb_lookup_entry_args
*args
)
199 const struct rip
*rip
= args
->parent_list_entry
;
200 struct prefix prefix
;
201 struct route_node
*rn
;
203 yang_str2ipv4p(args
->keys
->key
[0], &prefix
);
205 rn
= route_node_lookup(rip
->table
, &prefix
);
206 if (!rn
|| !rn
->info
)
209 route_unlock_node(rn
);
215 * XPath: /frr-ripd:ripd/instance/state/routes/route/prefix
217 struct yang_data
*ripd_instance_state_routes_route_prefix_get_elem(
218 struct nb_cb_get_elem_args
*args
)
220 const struct route_node
*rn
= args
->list_entry
;
221 const struct rip_info
*rinfo
= listnode_head(rn
->info
);
223 return yang_data_new_ipv4p(args
->xpath
, &rinfo
->rp
->p
);
227 * XPath: /frr-ripd:ripd/instance/state/routes/route/next-hop
229 struct yang_data
*ripd_instance_state_routes_route_next_hop_get_elem(
230 struct nb_cb_get_elem_args
*args
)
232 const struct route_node
*rn
= args
->list_entry
;
233 const struct rip_info
*rinfo
= listnode_head(rn
->info
);
235 switch (rinfo
->nh
.type
) {
236 case NEXTHOP_TYPE_IPV4
:
237 case NEXTHOP_TYPE_IPV4_IFINDEX
:
238 return yang_data_new_ipv4(args
->xpath
, &rinfo
->nh
.gate
.ipv4
);
245 * XPath: /frr-ripd:ripd/instance/state/routes/route/interface
247 struct yang_data
*ripd_instance_state_routes_route_interface_get_elem(
248 struct nb_cb_get_elem_args
*args
)
250 const struct route_node
*rn
= args
->list_entry
;
251 const struct rip_info
*rinfo
= listnode_head(rn
->info
);
252 const struct rip
*rip
= rip_info_get_instance(rinfo
);
254 switch (rinfo
->nh
.type
) {
255 case NEXTHOP_TYPE_IFINDEX
:
256 case NEXTHOP_TYPE_IPV4_IFINDEX
:
257 return yang_data_new_string(
259 ifindex2ifname(rinfo
->nh
.ifindex
, rip
->vrf
->vrf_id
));
266 * XPath: /frr-ripd:ripd/instance/state/routes/route/metric
268 struct yang_data
*ripd_instance_state_routes_route_metric_get_elem(
269 struct nb_cb_get_elem_args
*args
)
271 const struct route_node
*rn
= args
->list_entry
;
272 const struct rip_info
*rinfo
= listnode_head(rn
->info
);
274 return yang_data_new_uint8(args
->xpath
, rinfo
->metric
);