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
21 * along with GNU Zebra; see the file COPYING. If not, write to the Free
22 * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
27 * Developer tests for the zebra code that interfaces with the
28 * forwarding plane manager.
30 * The functions here are built into developer builds of zebra (when
31 * DEV_BUILD is defined), and can be called via the 'invoke' cli
36 * # invoke zebra function zfpm_dt_benchmark_protobuf_encode 100000
44 #include "zebra/rib.h"
45 #include "zebra/zserv.h"
46 #include "zebra/zebra_vrf.h"
48 #include "zebra_fpm_private.h"
50 #include "qpb/qpb_allocator.h"
51 #include "qpb/linear_allocator.h"
54 #include "fpm/fpm.pb-c.h"
59 extern int zfpm_dt_benchmark_netlink_encode (int argc
, const char **argv
);
60 extern int zfpm_dt_benchmark_protobuf_encode (int argc
, const char **argv
);
61 extern int zfpm_dt_benchmark_protobuf_decode (int argc
, const char **argv
);
66 * Selects a suitable rib destination for fpm interface tests.
69 zfpm_dt_find_route (rib_dest_t
**dest_p
, struct rib
**rib_p
)
71 struct route_node
*rnode
;
72 route_table_iter_t iter
;
73 struct route_table
*table
;
78 table
= zebra_vrf_table (AFI_IP
, SAFI_UNICAST
, VRF_DEFAULT
);
82 route_table_iter_init(&iter
, table
);
83 while ((rnode
= route_table_iter_next(&iter
)))
85 dest
= rib_dest_from_rnode (rnode
);
90 rib
= zfpm_route_for_update(dest
);
94 if (rib
->nexthop_active_num
<= 0)
106 route_table_iter_cleanup(&iter
);
112 * zfpm_dt_benchmark_netlink_encode
115 zfpm_dt_benchmark_netlink_encode (int argc
, const char **argv
)
124 times
= atoi(argv
[0]);
127 if (!zfpm_dt_find_route(&dest
, &rib
)) {
131 for (i
= 0; i
< times
; i
++) {
132 len
= zfpm_netlink_encode_route(RTM_NEWROUTE
, dest
, rib
, buf
, sizeof(buf
));
140 #endif /* HAVE_NETLINK */
145 * zfpm_dt_benchmark_protobuf_encode
148 zfpm_dt_benchmark_protobuf_encode (int argc
, const char **argv
)
157 times
= atoi(argv
[0]);
160 if (!zfpm_dt_find_route(&dest
, &rib
)) {
164 for (i
= 0; i
< times
; i
++) {
165 len
= zfpm_protobuf_encode_route(dest
, rib
, buf
, sizeof(buf
));
174 * zfpm_dt_log_fpm_message
177 zfpm_dt_log_fpm_message (Fpm__Message
*msg
)
179 Fpm__AddRoute
*add_route
;
180 Fpm__Nexthop
*nexthop
;
181 struct prefix prefix
;
182 u_char family
, nh_family
;
186 char buf
[INET6_ADDRSTRLEN
];
187 union g_addr nh_addr
;
189 if (msg
->type
!= FPM__MESSAGE__TYPE__ADD_ROUTE
)
192 zfpm_debug ("Add route message");
193 add_route
= msg
->add_route
;
195 if (!qpb_address_family_get (add_route
->address_family
, &family
))
198 if (!qpb_l3_prefix_get (add_route
->key
->prefix
, family
, &prefix
))
201 zfpm_debug ("Vrf id: %d, Prefix: %s/%d, Metric: %d", add_route
->vrf_id
,
202 inet_ntop (family
, &prefix
.u
.prefix
, buf
, sizeof (buf
)),
203 prefix
.prefixlen
, add_route
->metric
);
208 for (i
= 0; i
< add_route
->n_nexthops
; i
++)
210 nexthop
= add_route
->nexthops
[i
];
211 if (!qpb_if_identifier_get (nexthop
->if_id
, &if_index
, &if_name
))
214 if (nexthop
->address
)
215 qpb_l3_address_get (nexthop
->address
, &nh_family
, &nh_addr
);
217 zfpm_debug ("Nexthop - if_index: %d (%s), gateway: %s, ", if_index
,
218 if_name
? if_name
: "name not specified",
219 nexthop
->address
? inet_ntoa (nh_addr
.ipv4
) : "None");
224 * zfpm_dt_benchmark_protobuf_decode
227 zfpm_dt_benchmark_protobuf_decode (int argc
, const char **argv
)
232 uint8_t msg_buf
[4096];
233 QPB_DECLARE_STACK_ALLOCATOR (allocator
, 8192);
234 Fpm__Message
*fpm_msg
;
236 QPB_INIT_STACK_ALLOCATOR (allocator
);
240 times
= atoi(argv
[0]);
242 if (!zfpm_dt_find_route (&dest
, &rib
))
246 * Encode the route into the message buffer once only.
248 len
= zfpm_protobuf_encode_route (dest
, rib
, msg_buf
, sizeof (msg_buf
));
252 // Decode once, and display the decoded message
253 fpm_msg
= fpm__message__unpack(&allocator
, len
, msg_buf
);
257 zfpm_dt_log_fpm_message(fpm_msg
);
258 QPB_RESET_STACK_ALLOCATOR (allocator
);
262 * Decode encoded message the specified number of times.
264 for (i
= 0; i
< times
; i
++)
266 fpm_msg
= fpm__message__unpack (&allocator
, len
, msg_buf
);
271 // fpm__message__free_unpacked(msg, NULL);
272 QPB_RESET_STACK_ALLOCATOR (allocator
);
277 #endif /* HAVE_PROTOBUF */