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