]>
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 | */ | |
60ee8be1 RW |
41 | const void *ripngd_instance_state_neighbors_neighbor_get_next( |
42 | struct nb_cb_get_next_args *args) | |
ca473936 | 43 | { |
60ee8be1 | 44 | const struct ripng *ripng = args->parent_list_entry; |
ca473936 RW |
45 | struct listnode *node; |
46 | ||
60ee8be1 | 47 | if (args->list_entry == NULL) |
ca473936 RW |
48 | node = listhead(ripng->peer_list); |
49 | else | |
60ee8be1 | 50 | node = listnextnode((struct listnode *)args->list_entry); |
ca473936 RW |
51 | |
52 | return node; | |
53 | } | |
54 | ||
55 | int ripngd_instance_state_neighbors_neighbor_get_keys( | |
60ee8be1 | 56 | struct nb_cb_get_keys_args *args) |
ca473936 | 57 | { |
60ee8be1 | 58 | const struct listnode *node = args->list_entry; |
ca473936 RW |
59 | const struct ripng_peer *peer = listgetdata(node); |
60 | ||
60ee8be1 RW |
61 | args->keys->num = 1; |
62 | (void)inet_ntop(AF_INET6, &peer->addr, args->keys->key[0], | |
63 | sizeof(args->keys->key[0])); | |
ca473936 RW |
64 | |
65 | return NB_OK; | |
66 | } | |
67 | ||
68 | const void *ripngd_instance_state_neighbors_neighbor_lookup_entry( | |
60ee8be1 | 69 | struct nb_cb_lookup_entry_args *args) |
ca473936 | 70 | { |
60ee8be1 | 71 | const struct ripng *ripng = args->parent_list_entry; |
ca473936 RW |
72 | struct in6_addr address; |
73 | struct ripng_peer *peer; | |
74 | struct listnode *node; | |
75 | ||
60ee8be1 | 76 | yang_str2ipv6(args->keys->key[0], &address); |
ca473936 RW |
77 | |
78 | for (ALL_LIST_ELEMENTS_RO(ripng->peer_list, node, peer)) { | |
79 | if (IPV6_ADDR_SAME(&peer->addr, &address)) | |
80 | return node; | |
81 | } | |
82 | ||
83 | return NULL; | |
84 | } | |
85 | ||
86 | /* | |
87 | * XPath: /frr-ripngd:ripngd/instance/state/neighbors/neighbor/address | |
88 | */ | |
89 | struct yang_data *ripngd_instance_state_neighbors_neighbor_address_get_elem( | |
60ee8be1 | 90 | struct nb_cb_get_elem_args *args) |
ca473936 | 91 | { |
60ee8be1 | 92 | const struct listnode *node = args->list_entry; |
ca473936 RW |
93 | const struct ripng_peer *peer = listgetdata(node); |
94 | ||
60ee8be1 | 95 | return yang_data_new_ipv6(args->xpath, &peer->addr); |
ca473936 RW |
96 | } |
97 | ||
98 | /* | |
99 | * XPath: /frr-ripngd:ripngd/instance/state/neighbors/neighbor/last-update | |
100 | */ | |
101 | struct yang_data *ripngd_instance_state_neighbors_neighbor_last_update_get_elem( | |
60ee8be1 | 102 | struct nb_cb_get_elem_args *args) |
ca473936 RW |
103 | { |
104 | /* TODO: yang:date-and-time is tricky */ | |
105 | return NULL; | |
106 | } | |
107 | ||
108 | /* | |
109 | * XPath: /frr-ripngd:ripngd/instance/state/neighbors/neighbor/bad-packets-rcvd | |
110 | */ | |
111 | struct yang_data * | |
112 | ripngd_instance_state_neighbors_neighbor_bad_packets_rcvd_get_elem( | |
60ee8be1 | 113 | struct nb_cb_get_elem_args *args) |
ca473936 | 114 | { |
60ee8be1 | 115 | const struct listnode *node = args->list_entry; |
ca473936 RW |
116 | const struct ripng_peer *peer = listgetdata(node); |
117 | ||
60ee8be1 | 118 | return yang_data_new_uint32(args->xpath, peer->recv_badpackets); |
ca473936 RW |
119 | } |
120 | ||
121 | /* | |
122 | * XPath: /frr-ripngd:ripngd/instance/state/neighbors/neighbor/bad-routes-rcvd | |
123 | */ | |
124 | struct yang_data * | |
125 | ripngd_instance_state_neighbors_neighbor_bad_routes_rcvd_get_elem( | |
60ee8be1 | 126 | struct nb_cb_get_elem_args *args) |
ca473936 | 127 | { |
60ee8be1 | 128 | const struct listnode *node = args->list_entry; |
ca473936 RW |
129 | const struct ripng_peer *peer = listgetdata(node); |
130 | ||
60ee8be1 | 131 | return yang_data_new_uint32(args->xpath, peer->recv_badroutes); |
ca473936 RW |
132 | } |
133 | ||
134 | /* | |
135 | * XPath: /frr-ripngd:ripngd/instance/state/routes/route | |
136 | */ | |
137 | const void * | |
60ee8be1 | 138 | ripngd_instance_state_routes_route_get_next(struct nb_cb_get_next_args *args) |
ca473936 | 139 | { |
60ee8be1 | 140 | const struct ripng *ripng = args->parent_list_entry; |
ca473936 RW |
141 | struct agg_node *rn; |
142 | ||
60ee8be1 | 143 | if (args->list_entry == NULL) |
ca473936 RW |
144 | rn = agg_route_top(ripng->table); |
145 | else | |
60ee8be1 | 146 | rn = agg_route_next((struct agg_node *)args->list_entry); |
78769ea2 | 147 | /* Optimization: skip empty route nodes. */ |
ca473936 RW |
148 | while (rn && rn->info == NULL) |
149 | rn = agg_route_next(rn); | |
150 | ||
151 | return rn; | |
152 | } | |
153 | ||
60ee8be1 RW |
154 | int ripngd_instance_state_routes_route_get_keys( |
155 | struct nb_cb_get_keys_args *args) | |
ca473936 | 156 | { |
60ee8be1 | 157 | const struct agg_node *rn = args->list_entry; |
ca473936 | 158 | |
60ee8be1 RW |
159 | args->keys->num = 1; |
160 | (void)prefix2str(agg_node_get_prefix(rn), args->keys->key[0], | |
161 | sizeof(args->keys->key[0])); | |
ca473936 RW |
162 | |
163 | return NB_OK; | |
164 | } | |
165 | ||
166 | const void *ripngd_instance_state_routes_route_lookup_entry( | |
60ee8be1 | 167 | struct nb_cb_lookup_entry_args *args) |
ca473936 | 168 | { |
60ee8be1 | 169 | const struct ripng *ripng = args->parent_list_entry; |
ca473936 RW |
170 | struct prefix prefix; |
171 | struct agg_node *rn; | |
172 | ||
60ee8be1 | 173 | yang_str2ipv6p(args->keys->key[0], &prefix); |
ca473936 RW |
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 | */ | |
60ee8be1 RW |
187 | struct yang_data *ripngd_instance_state_routes_route_prefix_get_elem( |
188 | struct nb_cb_get_elem_args *args) | |
ca473936 | 189 | { |
60ee8be1 | 190 | const struct agg_node *rn = args->list_entry; |
ca473936 RW |
191 | const struct ripng_info *rinfo = listnode_head(rn->info); |
192 | ||
60ee8be1 | 193 | return yang_data_new_ipv6p(args->xpath, agg_node_get_prefix(rinfo->rp)); |
ca473936 RW |
194 | } |
195 | ||
196 | /* | |
197 | * XPath: /frr-ripngd:ripngd/instance/state/routes/route/next-hop | |
198 | */ | |
60ee8be1 RW |
199 | struct yang_data *ripngd_instance_state_routes_route_next_hop_get_elem( |
200 | struct nb_cb_get_elem_args *args) | |
ca473936 | 201 | { |
60ee8be1 | 202 | const struct agg_node *rn = args->list_entry; |
ca473936 RW |
203 | const struct ripng_info *rinfo = listnode_head(rn->info); |
204 | ||
60ee8be1 | 205 | return yang_data_new_ipv6(args->xpath, &rinfo->nexthop); |
ca473936 RW |
206 | } |
207 | ||
208 | /* | |
209 | * XPath: /frr-ripngd:ripngd/instance/state/routes/route/interface | |
210 | */ | |
60ee8be1 RW |
211 | struct yang_data *ripngd_instance_state_routes_route_interface_get_elem( |
212 | struct nb_cb_get_elem_args *args) | |
ca473936 | 213 | { |
60ee8be1 | 214 | const struct agg_node *rn = args->list_entry; |
ca473936 RW |
215 | const struct ripng_info *rinfo = listnode_head(rn->info); |
216 | const struct ripng *ripng = ripng_info_get_instance(rinfo); | |
217 | ||
218 | return yang_data_new_string( | |
60ee8be1 RW |
219 | args->xpath, |
220 | ifindex2ifname(rinfo->ifindex, ripng->vrf->vrf_id)); | |
ca473936 RW |
221 | } |
222 | ||
223 | /* | |
224 | * XPath: /frr-ripngd:ripngd/instance/state/routes/route/metric | |
225 | */ | |
60ee8be1 RW |
226 | struct yang_data *ripngd_instance_state_routes_route_metric_get_elem( |
227 | struct nb_cb_get_elem_args *args) | |
ca473936 | 228 | { |
60ee8be1 | 229 | const struct agg_node *rn = args->list_entry; |
ca473936 RW |
230 | const struct ripng_info *rinfo = listnode_head(rn->info); |
231 | ||
60ee8be1 | 232 | return yang_data_new_uint8(args->xpath, rinfo->metric); |
ca473936 | 233 | } |