4 * @copyright Copyright (C) 2016 Sproute Networks, Inc.
6 * @author Avneesh Sachdev <avneesh@sproute.com>
8 * This file is part of GNU Zebra.
10 * GNU Zebra is free software; you can redistribute it and/or modify it
11 * under the terms of the GNU General Public License as published by the
12 * Free Software Foundation; either version 2, or (at your option) any
15 * GNU Zebra is distributed in the hope that it will be useful, but
16 * WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 * General Public License for more details.
20 * You should have received a copy of the GNU General Public License along
21 * with this program; see the file COPYING; if not, write to the Free Software
22 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
26 * Developer tests for the zebra code that interfaces with the
27 * forwarding plane manager.
29 * The functions here are built into developer builds of zebra (when
30 * DEV_BUILD is defined), and can be called via the 'invoke' cli
35 * # invoke zebra function zfpm_dt_benchmark_protobuf_encode 100000
43 #include "zebra/rib.h"
44 #include "zebra/zserv.h"
45 #include "zebra/zebra_vrf.h"
47 #include "zebra_fpm_private.h"
49 #include "qpb/qpb_allocator.h"
50 #include "qpb/linear_allocator.h"
54 #include "fpm/fpm.pb-c.h"
60 extern int zfpm_dt_benchmark_netlink_encode (int argc
, const char **argv
);
61 extern int zfpm_dt_benchmark_protobuf_encode (int argc
, const char **argv
);
62 extern int zfpm_dt_benchmark_protobuf_decode (int argc
, const char **argv
);
67 * Selects a suitable rib destination for fpm interface tests.
70 zfpm_dt_find_route (rib_dest_t
**dest_p
, struct route_entry
**re_p
)
72 struct route_node
*rnode
;
73 route_table_iter_t iter
;
74 struct route_table
*table
;
76 struct route_entry
*re
;
79 table
= zebra_vrf_table (AFI_IP
, SAFI_UNICAST
, VRF_DEFAULT
);
83 route_table_iter_init(&iter
, table
);
84 while ((rnode
= route_table_iter_next(&iter
)))
86 dest
= rib_dest_from_rnode (rnode
);
91 re
= zfpm_route_for_update(dest
);
95 if (re
->nexthop_active_num
<= 0)
107 route_table_iter_cleanup(&iter
);
113 * zfpm_dt_benchmark_netlink_encode
116 zfpm_dt_benchmark_netlink_encode (int argc
, const char **argv
)
120 struct route_entry
*re
;
125 times
= atoi(argv
[0]);
128 if (!zfpm_dt_find_route(&dest
, &re
)) {
132 for (i
= 0; i
< times
; i
++) {
133 len
= zfpm_netlink_encode_route(RTM_NEWROUTE
, dest
, re
, buf
, sizeof(buf
));
141 #endif /* HAVE_NETLINK */
146 * zfpm_dt_benchmark_protobuf_encode
149 zfpm_dt_benchmark_protobuf_encode (int argc
, const char **argv
)
153 struct route_entry
*re
;
158 times
= atoi(argv
[0]);
161 if (!zfpm_dt_find_route(&dest
, &re
)) {
165 for (i
= 0; i
< times
; i
++) {
166 len
= zfpm_protobuf_encode_route(dest
, re
, buf
, sizeof(buf
));
175 * zfpm_dt_log_fpm_message
178 zfpm_dt_log_fpm_message (Fpm__Message
*msg
)
180 Fpm__AddRoute
*add_route
;
181 Fpm__Nexthop
*nexthop
;
182 struct prefix prefix
;
183 u_char family
, nh_family
;
187 char buf
[INET6_ADDRSTRLEN
];
188 union g_addr nh_addr
;
190 if (msg
->type
!= FPM__MESSAGE__TYPE__ADD_ROUTE
)
193 zfpm_debug ("Add route message");
194 add_route
= msg
->add_route
;
196 if (!qpb_address_family_get (add_route
->address_family
, &family
))
199 if (!qpb_l3_prefix_get (add_route
->key
->prefix
, family
, &prefix
))
202 zfpm_debug ("Vrf id: %d, Prefix: %s/%d, Metric: %d", add_route
->vrf_id
,
203 inet_ntop (family
, &prefix
.u
.prefix
, buf
, sizeof (buf
)),
204 prefix
.prefixlen
, add_route
->metric
);
209 for (i
= 0; i
< add_route
->n_nexthops
; i
++)
211 nexthop
= add_route
->nexthops
[i
];
212 if (!qpb_if_identifier_get (nexthop
->if_id
, &if_index
, &if_name
))
215 if (nexthop
->address
)
216 qpb_l3_address_get (nexthop
->address
, &nh_family
, &nh_addr
);
218 zfpm_debug ("Nexthop - if_index: %d (%s), gateway: %s, ", if_index
,
219 if_name
? if_name
: "name not specified",
220 nexthop
->address
? inet_ntoa (nh_addr
.ipv4
) : "None");
225 * zfpm_dt_benchmark_protobuf_decode
228 zfpm_dt_benchmark_protobuf_decode (int argc
, const char **argv
)
232 struct route_entry
*re
;
233 uint8_t msg_buf
[4096];
234 QPB_DECLARE_STACK_ALLOCATOR (allocator
, 8192);
235 Fpm__Message
*fpm_msg
;
237 QPB_INIT_STACK_ALLOCATOR (allocator
);
241 times
= atoi(argv
[0]);
243 if (!zfpm_dt_find_route (&dest
, &re
))
247 * Encode the route into the message buffer once only.
249 len
= zfpm_protobuf_encode_route (dest
, re
, msg_buf
, sizeof (msg_buf
));
253 // Decode once, and display the decoded message
254 fpm_msg
= fpm__message__unpack(&allocator
, len
, msg_buf
);
258 zfpm_dt_log_fpm_message(fpm_msg
);
259 QPB_RESET_STACK_ALLOCATOR (allocator
);
263 * Decode encoded message the specified number of times.
265 for (i
= 0; i
< times
; i
++)
267 fpm_msg
= fpm__message__unpack (&allocator
, len
, msg_buf
);
272 // fpm__message__free_unpacked(msg, NULL);
273 QPB_RESET_STACK_ALLOCATOR (allocator
);
278 #endif /* HAVE_PROTOBUF */