]>
Commit | Line | Data |
---|---|---|
ca473936 RW |
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(&rn->p, keys->key[0], sizeof(keys->key[0])); | |
162 | ||
163 | return NB_OK; | |
164 | } | |
165 | ||
166 | const void *ripngd_instance_state_routes_route_lookup_entry( | |
167 | const void *parent_list_entry, const struct yang_list_keys *keys) | |
168 | { | |
169 | const struct ripng *ripng = parent_list_entry; | |
170 | struct prefix prefix; | |
171 | struct agg_node *rn; | |
172 | ||
173 | yang_str2ipv6p(keys->key[0], &prefix); | |
174 | ||
175 | rn = agg_node_lookup(ripng->table, &prefix); | |
176 | if (!rn || !rn->info) | |
177 | return NULL; | |
178 | ||
179 | agg_unlock_node(rn); | |
180 | ||
181 | return rn; | |
182 | } | |
183 | ||
184 | /* | |
185 | * XPath: /frr-ripngd:ripngd/instance/state/routes/route/prefix | |
186 | */ | |
187 | struct yang_data * | |
188 | ripngd_instance_state_routes_route_prefix_get_elem(const char *xpath, | |
189 | const void *list_entry) | |
190 | { | |
191 | const struct agg_node *rn = list_entry; | |
192 | const struct ripng_info *rinfo = listnode_head(rn->info); | |
193 | ||
194 | return yang_data_new_ipv6p(xpath, &rinfo->rp->p); | |
195 | } | |
196 | ||
197 | /* | |
198 | * XPath: /frr-ripngd:ripngd/instance/state/routes/route/next-hop | |
199 | */ | |
200 | struct yang_data * | |
201 | ripngd_instance_state_routes_route_next_hop_get_elem(const char *xpath, | |
202 | const void *list_entry) | |
203 | { | |
204 | const struct agg_node *rn = list_entry; | |
205 | const struct ripng_info *rinfo = listnode_head(rn->info); | |
206 | ||
207 | return yang_data_new_ipv6(xpath, &rinfo->nexthop); | |
208 | } | |
209 | ||
210 | /* | |
211 | * XPath: /frr-ripngd:ripngd/instance/state/routes/route/interface | |
212 | */ | |
213 | struct yang_data * | |
214 | ripngd_instance_state_routes_route_interface_get_elem(const char *xpath, | |
215 | const void *list_entry) | |
216 | { | |
217 | const struct agg_node *rn = list_entry; | |
218 | const struct ripng_info *rinfo = listnode_head(rn->info); | |
219 | const struct ripng *ripng = ripng_info_get_instance(rinfo); | |
220 | ||
221 | return yang_data_new_string( | |
222 | xpath, ifindex2ifname(rinfo->ifindex, ripng->vrf->vrf_id)); | |
223 | } | |
224 | ||
225 | /* | |
226 | * XPath: /frr-ripngd:ripngd/instance/state/routes/route/metric | |
227 | */ | |
228 | struct yang_data * | |
229 | ripngd_instance_state_routes_route_metric_get_elem(const char *xpath, | |
230 | const void *list_entry) | |
231 | { | |
232 | const struct agg_node *rn = list_entry; | |
233 | const struct ripng_info *rinfo = listnode_head(rn->info); | |
234 | ||
235 | return yang_data_new_uint8(xpath, rinfo->metric); | |
236 | } |