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"
46 #include "zebra_fpm_private.h"
48 #include "qpb/qpb_allocator.h"
49 #include "qpb/linear_allocator.h"
52 #include "fpm/fpm.pb-c.h"
57 extern int zfpm_dt_benchmark_netlink_encode (int argc
, const char **argv
);
58 extern int zfpm_dt_benchmark_protobuf_encode (int argc
, const char **argv
);
59 extern int zfpm_dt_benchmark_protobuf_decode (int argc
, const char **argv
);
64 * Selects a suitable rib destination for fpm interface tests.
67 zfpm_dt_find_route (rib_dest_t
**dest_p
, struct rib
**rib_p
)
69 struct route_node
*rnode
;
70 route_table_iter_t iter
;
71 struct route_table
*table
;
76 table
= zebra_vrf_table (AFI_IP
, SAFI_UNICAST
, VRF_DEFAULT
);
80 route_table_iter_init(&iter
, table
);
81 while ((rnode
= route_table_iter_next(&iter
)))
83 dest
= rib_dest_from_rnode (rnode
);
88 rib
= zfpm_route_for_update(dest
);
92 if (rib
->nexthop_active_num
<= 0)
104 route_table_iter_cleanup(&iter
);
110 * zfpm_dt_benchmark_netlink_encode
113 zfpm_dt_benchmark_netlink_encode (int argc
, const char **argv
)
122 times
= atoi(argv
[0]);
125 if (!zfpm_dt_find_route(&dest
, &rib
)) {
129 for (i
= 0; i
< times
; i
++) {
130 len
= zfpm_netlink_encode_route(RTM_NEWROUTE
, dest
, rib
, buf
, sizeof(buf
));
138 #endif /* HAVE_NETLINK */
143 * zfpm_dt_benchmark_protobuf_encode
146 zfpm_dt_benchmark_protobuf_encode (int argc
, const char **argv
)
155 times
= atoi(argv
[0]);
158 if (!zfpm_dt_find_route(&dest
, &rib
)) {
162 for (i
= 0; i
< times
; i
++) {
163 len
= zfpm_protobuf_encode_route(dest
, rib
, buf
, sizeof(buf
));
172 * zfpm_dt_log_fpm_message
175 zfpm_dt_log_fpm_message (Fpm__Message
*msg
)
177 Fpm__AddRoute
*add_route
;
178 Fpm__Nexthop
*nexthop
;
179 struct prefix prefix
;
180 u_char family
, nh_family
;
184 char buf
[INET6_ADDRSTRLEN
];
185 union g_addr nh_addr
;
187 if (msg
->type
!= FPM__MESSAGE__TYPE__ADD_ROUTE
)
190 zfpm_debug ("Add route message");
191 add_route
= msg
->add_route
;
193 if (!qpb_address_family_get (add_route
->address_family
, &family
))
196 if (!qpb_l3_prefix_get (add_route
->key
->prefix
, family
, &prefix
))
199 zfpm_debug ("Vrf id: %d, Prefix: %s/%d, Metric: %d", add_route
->vrf_id
,
200 inet_ntop (family
, &prefix
.u
.prefix
, buf
, sizeof (buf
)),
201 prefix
.prefixlen
, add_route
->metric
);
206 for (i
= 0; i
< add_route
->n_nexthops
; i
++)
208 nexthop
= add_route
->nexthops
[i
];
209 if (!qpb_if_identifier_get (nexthop
->if_id
, &if_index
, &if_name
))
212 if (nexthop
->address
)
213 qpb_l3_address_get (nexthop
->address
, &nh_family
, &nh_addr
);
215 zfpm_debug ("Nexthop - if_index: %d (%s), gateway: %s, ", if_index
,
216 if_name
? if_name
: "name not specified",
217 nexthop
->address
? inet_ntoa (nh_addr
.ipv4
) : "None");
222 * zfpm_dt_benchmark_protobuf_decode
225 zfpm_dt_benchmark_protobuf_decode (int argc
, const char **argv
)
230 uint8_t msg_buf
[4096];
231 QPB_DECLARE_STACK_ALLOCATOR (allocator
, 8192);
232 Fpm__Message
*fpm_msg
;
234 QPB_INIT_STACK_ALLOCATOR (allocator
);
238 times
= atoi(argv
[0]);
240 if (!zfpm_dt_find_route (&dest
, &rib
))
244 * Encode the route into the message buffer once only.
246 len
= zfpm_protobuf_encode_route (dest
, rib
, msg_buf
, sizeof (msg_buf
));
250 // Decode once, and display the decoded message
251 fpm_msg
= fpm__message__unpack(&allocator
, len
, msg_buf
);
255 zfpm_dt_log_fpm_message(fpm_msg
);
256 QPB_RESET_STACK_ALLOCATOR (allocator
);
260 * Decode encoded message the specified number of times.
262 for (i
= 0; i
< times
; i
++)
264 fpm_msg
= fpm__message__unpack (&allocator
, len
, msg_buf
);
269 // fpm__message__free_unpacked(msg, NULL);
270 QPB_RESET_STACK_ALLOCATOR (allocator
);
275 #endif /* HAVE_PROTOBUF */