]> git.proxmox.com Git - mirror_frr.git/blob - ripngd/ripng_nb_state.c
Merge pull request #6071 from ton31337/feature/rfc6286
[mirror_frr.git] / ripngd / ripng_nb_state.c
1 /*
2 * Copyright (C) 2018 NetDEF, Inc.
3 * Renato Westphal
4 *
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)
8 * any later version.
9 *
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
13 * more details.
14 *
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
18 */
19
20 #include <zebra.h>
21
22 #include "if.h"
23 #include "vrf.h"
24 #include "log.h"
25 #include "prefix.h"
26 #include "table.h"
27 #include "command.h"
28 #include "routemap.h"
29 #include "agg_table.h"
30 #include "northbound.h"
31 #include "libfrr.h"
32
33 #include "ripngd/ripngd.h"
34 #include "ripngd/ripng_nb.h"
35 #include "ripngd/ripng_debug.h"
36 #include "ripngd/ripng_route.h"
37
38 /*
39 * XPath: /frr-ripngd:ripngd/instance/state/neighbors/neighbor
40 */
41 const void *
42 ripngd_instance_state_neighbors_neighbor_get_next(const void *parent_list_entry,
43 const void *list_entry)
44 {
45 const struct ripng *ripng = parent_list_entry;
46 struct listnode *node;
47
48 if (list_entry == NULL)
49 node = listhead(ripng->peer_list);
50 else
51 node = listnextnode((struct listnode *)list_entry);
52
53 return node;
54 }
55
56 int ripngd_instance_state_neighbors_neighbor_get_keys(
57 const void *list_entry, struct yang_list_keys *keys)
58 {
59 const struct listnode *node = list_entry;
60 const struct ripng_peer *peer = listgetdata(node);
61
62 keys->num = 1;
63 (void)inet_ntop(AF_INET6, &peer->addr, keys->key[0],
64 sizeof(keys->key[0]));
65
66 return NB_OK;
67 }
68
69 const void *ripngd_instance_state_neighbors_neighbor_lookup_entry(
70 const void *parent_list_entry, const struct yang_list_keys *keys)
71 {
72 const struct ripng *ripng = parent_list_entry;
73 struct in6_addr address;
74 struct ripng_peer *peer;
75 struct listnode *node;
76
77 yang_str2ipv6(keys->key[0], &address);
78
79 for (ALL_LIST_ELEMENTS_RO(ripng->peer_list, node, peer)) {
80 if (IPV6_ADDR_SAME(&peer->addr, &address))
81 return node;
82 }
83
84 return NULL;
85 }
86
87 /*
88 * XPath: /frr-ripngd:ripngd/instance/state/neighbors/neighbor/address
89 */
90 struct yang_data *ripngd_instance_state_neighbors_neighbor_address_get_elem(
91 const char *xpath, const void *list_entry)
92 {
93 const struct listnode *node = list_entry;
94 const struct ripng_peer *peer = listgetdata(node);
95
96 return yang_data_new_ipv6(xpath, &peer->addr);
97 }
98
99 /*
100 * XPath: /frr-ripngd:ripngd/instance/state/neighbors/neighbor/last-update
101 */
102 struct yang_data *ripngd_instance_state_neighbors_neighbor_last_update_get_elem(
103 const char *xpath, const void *list_entry)
104 {
105 /* TODO: yang:date-and-time is tricky */
106 return NULL;
107 }
108
109 /*
110 * XPath: /frr-ripngd:ripngd/instance/state/neighbors/neighbor/bad-packets-rcvd
111 */
112 struct yang_data *
113 ripngd_instance_state_neighbors_neighbor_bad_packets_rcvd_get_elem(
114 const char *xpath, const void *list_entry)
115 {
116 const struct listnode *node = list_entry;
117 const struct ripng_peer *peer = listgetdata(node);
118
119 return yang_data_new_uint32(xpath, peer->recv_badpackets);
120 }
121
122 /*
123 * XPath: /frr-ripngd:ripngd/instance/state/neighbors/neighbor/bad-routes-rcvd
124 */
125 struct yang_data *
126 ripngd_instance_state_neighbors_neighbor_bad_routes_rcvd_get_elem(
127 const char *xpath, const void *list_entry)
128 {
129 const struct listnode *node = list_entry;
130 const struct ripng_peer *peer = listgetdata(node);
131
132 return yang_data_new_uint32(xpath, peer->recv_badroutes);
133 }
134
135 /*
136 * XPath: /frr-ripngd:ripngd/instance/state/routes/route
137 */
138 const void *
139 ripngd_instance_state_routes_route_get_next(const void *parent_list_entry,
140 const void *list_entry)
141 {
142 const struct ripng *ripng = parent_list_entry;
143 struct agg_node *rn;
144
145 if (list_entry == NULL)
146 rn = agg_route_top(ripng->table);
147 else
148 rn = agg_route_next((struct agg_node *)list_entry);
149 while (rn && rn->info == NULL)
150 rn = agg_route_next(rn);
151
152 return rn;
153 }
154
155 int ripngd_instance_state_routes_route_get_keys(const void *list_entry,
156 struct yang_list_keys *keys)
157 {
158 const struct agg_node *rn = list_entry;
159
160 keys->num = 1;
161 (void)prefix2str(agg_node_get_prefix(rn), keys->key[0],
162 sizeof(keys->key[0]));
163
164 return NB_OK;
165 }
166
167 const void *ripngd_instance_state_routes_route_lookup_entry(
168 const void *parent_list_entry, const struct yang_list_keys *keys)
169 {
170 const struct ripng *ripng = parent_list_entry;
171 struct prefix prefix;
172 struct agg_node *rn;
173
174 yang_str2ipv6p(keys->key[0], &prefix);
175
176 rn = agg_node_lookup(ripng->table, &prefix);
177 if (!rn || !rn->info)
178 return NULL;
179
180 agg_unlock_node(rn);
181
182 return rn;
183 }
184
185 /*
186 * XPath: /frr-ripngd:ripngd/instance/state/routes/route/prefix
187 */
188 struct yang_data *
189 ripngd_instance_state_routes_route_prefix_get_elem(const char *xpath,
190 const void *list_entry)
191 {
192 const struct agg_node *rn = list_entry;
193 const struct ripng_info *rinfo = listnode_head(rn->info);
194
195 return yang_data_new_ipv6p(xpath, agg_node_get_prefix(rinfo->rp));
196 }
197
198 /*
199 * XPath: /frr-ripngd:ripngd/instance/state/routes/route/next-hop
200 */
201 struct yang_data *
202 ripngd_instance_state_routes_route_next_hop_get_elem(const char *xpath,
203 const void *list_entry)
204 {
205 const struct agg_node *rn = list_entry;
206 const struct ripng_info *rinfo = listnode_head(rn->info);
207
208 return yang_data_new_ipv6(xpath, &rinfo->nexthop);
209 }
210
211 /*
212 * XPath: /frr-ripngd:ripngd/instance/state/routes/route/interface
213 */
214 struct yang_data *
215 ripngd_instance_state_routes_route_interface_get_elem(const char *xpath,
216 const void *list_entry)
217 {
218 const struct agg_node *rn = list_entry;
219 const struct ripng_info *rinfo = listnode_head(rn->info);
220 const struct ripng *ripng = ripng_info_get_instance(rinfo);
221
222 return yang_data_new_string(
223 xpath, ifindex2ifname(rinfo->ifindex, ripng->vrf->vrf_id));
224 }
225
226 /*
227 * XPath: /frr-ripngd:ripngd/instance/state/routes/route/metric
228 */
229 struct yang_data *
230 ripngd_instance_state_routes_route_metric_get_elem(const char *xpath,
231 const void *list_entry)
232 {
233 const struct agg_node *rn = list_entry;
234 const struct ripng_info *rinfo = listnode_head(rn->info);
235
236 return yang_data_new_uint8(xpath, rinfo->metric);
237 }