Line data Source code
1 : /*
2 : * vr_util.c -- common functions used by utilities in a library form
3 : *
4 : * Copyright (c) 2015, Juniper Networks, Inc.
5 : * All rights reserved
6 : */
7 : #include <ctype.h>
8 : #include <stdio.h>
9 : #include <stdlib.h>
10 : #include <unistd.h>
11 : #include <errno.h>
12 : #include <stdbool.h>
13 : #include <stdint.h>
14 : #include <ctype.h>
15 : #include <inttypes.h>
16 : #include <fcntl.h>
17 : #include <time.h>
18 :
19 : #include <sys/types.h>
20 : #include <sys/stat.h>
21 : #include <sys/socket.h>
22 : #include <sys/mman.h>
23 : #if defined(__linux__)
24 : #include <linux/netlink.h>
25 : #include <linux/rtnetlink.h>
26 : #include <linux/if_ether.h>
27 : #include <linux/dcbnl.h>
28 : #endif
29 :
30 : #include <net/if.h>
31 : #include <netinet/in.h>
32 :
33 : #include "vr_types.h"
34 : #include "nl_util.h"
35 : #include "vr_message.h"
36 : #include "vr_genetlink.h"
37 : #include "vr_interface.h"
38 : #include "vr_packet.h"
39 : #include "vr_nexthop.h"
40 : #include "vr_route.h"
41 : #include "vr_bridge.h"
42 : #include "vr_mem.h"
43 : #include "ini_parser.h"
44 :
45 : /* Suppress NetLink error messages */
46 : bool vr_ignore_nl_errors = false;
47 : int genetlink_group_id = 0;
48 : static bool vr_header_include = 0;
49 :
50 : char *
51 0 : vr_extract_token(char *string, char token_separator)
52 : {
53 : int ret;
54 : unsigned int length;
55 :
56 : char *sep;
57 :
58 : /* skip over leading white spaces */
59 0 : while ((*string == ' ') && string++);
60 :
61 : /* if there is nothing left after the spaces, return */
62 0 : if (!(length = strlen(string))) {
63 0 : return NULL;
64 : }
65 :
66 : /* If first character is a separator its a malforned request */
67 0 : if (*string == token_separator) {
68 0 : printf("Malformed request: separator used incorrectly \n");
69 0 : return NULL;
70 : }
71 :
72 : /* start searching for the token */
73 0 : sep = strchr(string, token_separator);
74 0 : if (sep) {
75 0 : length = sep - string;
76 : /* terminate the token with NULL */
77 0 : string[sep - string] = '\0';
78 0 : length = strlen(string);
79 : }
80 :
81 : /* remove trailing spaces */
82 0 : length -= 1;
83 0 : while ((*(string + length) == ' ') && --length);
84 0 : *(string + length + 1) = '\0';
85 :
86 : /*
87 : * reset the separator to space, since a space at the beginning
88 : * will be snipped
89 : */
90 0 : if (sep && (((sep - string)) != strlen(string)))
91 0 : string[sep - string] = ' ';
92 :
93 0 : return string;
94 : }
95 :
96 : bool
97 0 : vr_valid_ipv6_address(const char *addr)
98 : {
99 0 : unsigned int i = 0, j = 0, sep_count = 0;
100 :
101 : /* a '*' is treated as a valid address */
102 0 : if (!strncmp(addr, "*", 1) && (strlen(addr) == 1))
103 0 : return true;
104 :
105 0 : while (*(addr + i)) {
106 0 : if (isalnum(*(addr + i))) {
107 0 : j++;
108 0 : } else if (*(addr + i) == ':') {
109 0 : j = 0;
110 0 : sep_count++;
111 : } else {
112 0 : printf("match: \"%s\" is not a valid ipv6 address format\n", addr);
113 0 : return false;
114 : }
115 :
116 0 : if ((j > 4) || (sep_count > 7)) {
117 0 : printf("match: \"%s\" is not a valid ipv6 address format\n", addr);
118 0 : return false;
119 : }
120 :
121 0 : i++;
122 : }
123 :
124 0 : return true;
125 : }
126 :
127 : bool
128 0 : vr_valid_ipv4_address(const char *addr)
129 : {
130 0 : unsigned int i = 0, j = 0, sep_count = 0;
131 :
132 : /* a '*' is treated as a valid address */
133 0 : if (!strncmp(addr, "*", 1) && (strlen(addr) == 1))
134 0 : return true;
135 :
136 : /* every character should be either a digit or a '.' */
137 0 : while (*(addr + i)) {
138 0 : if (isdigit(*(addr + i))) {
139 0 : j++;
140 0 : } else if (i && (*(addr + i) == '.')) {
141 0 : j = 0;
142 0 : ++sep_count;
143 : } else {
144 0 : printf("match: \"%s\" is not a valid ipv4 address format\n", addr);
145 0 : return false;
146 : }
147 :
148 0 : if ((j > 3) || (sep_count > 3)) {
149 0 : printf("match: \"%s\" is not a valid ipv4 address format\n", addr);
150 0 : return false;
151 : }
152 :
153 0 : i++;
154 : }
155 :
156 0 : if (sep_count != 3) {
157 0 : printf("match: \"%s\" is not a valid ipv4 address format\n", addr);
158 0 : return false;
159 : }
160 :
161 0 : return true;
162 : }
163 :
164 : bool
165 10 : vr_valid_mac_address(const char *mac)
166 : {
167 10 : uint8_t null_mac[VR_ETHER_ALEN] = { 0 };
168 :
169 10 : if (!mac || !memcmp(mac, null_mac, VR_ETHER_ALEN))
170 10 : return false;
171 :
172 0 : return true;
173 : }
174 :
175 : char *
176 5 : vr_proto_string(unsigned short proto)
177 : {
178 5 : switch (proto) {
179 2 : case VR_IP_PROTO_TCP:
180 2 : return "TCP";
181 : break;
182 :
183 0 : case VR_IP_PROTO_UDP:
184 0 : return "UDP";
185 : break;
186 :
187 3 : case VR_IP_PROTO_ICMP:
188 3 : return "ICMP";
189 : break;
190 :
191 0 : case VR_IP_PROTO_SCTP:
192 0 : return "SCTP";
193 : break;
194 :
195 0 : case VR_IP_PROTO_ICMP6:
196 0 : return "ICMPv6";
197 : break;
198 :
199 :
200 0 : default:
201 0 : return "UNKNOWN";
202 : }
203 :
204 : return "UNKNOWN";
205 : }
206 :
207 : /* send and receive */
208 : int
209 2862 : vr_recvmsg_generic(struct nl_client *cl, bool dump, bool msg_wait)
210 : {
211 2862 : int ret = 0;
212 2862 : bool pending = true;
213 : struct nl_response *resp;
214 : struct nlmsghdr *nlh;
215 :
216 2863 : while (pending) {
217 2863 : if (msg_wait) {
218 0 : ret = nl_recvmsg_waitall(cl);
219 : } else {
220 2863 : ret = nl_recvmsg(cl);
221 : }
222 2863 : if (ret > 0) {
223 2863 : if (dump) {
224 2 : pending = true;
225 : } else {
226 2861 : pending = false;
227 : }
228 :
229 2863 : resp = nl_parse_reply(cl);
230 2863 : if (resp->nl_op == SANDESH_REQUEST) {
231 2863 : sandesh_decode(resp->nl_data, resp->nl_len,
232 : vr_find_sandesh_info, &ret);
233 0 : } else if (resp->nl_type == NL_MSG_TYPE_DONE) {
234 0 : pending = false;
235 : }
236 : } else {
237 0 : return ret;
238 : }
239 :
240 2863 : nlh = (struct nlmsghdr *)cl->cl_buf;
241 2863 : if (!nlh || !nlh->nlmsg_flags)
242 : break;
243 : }
244 :
245 2862 : return ret;
246 : }
247 :
248 : int
249 2862 : vr_recvmsg(struct nl_client *cl, bool dump)
250 : {
251 2862 : return vr_recvmsg_generic(cl, dump, false);
252 : }
253 :
254 : int
255 0 : vr_recvmsg_waitall(struct nl_client *cl, bool dump)
256 : {
257 0 : return vr_recvmsg_generic(cl, dump, true);
258 : }
259 :
260 : int
261 2862 : vr_sendmsg(struct nl_client *cl, void *request,
262 : char *request_string)
263 : {
264 : int ret, error, attr_len;
265 :
266 : /* nlmsg header */
267 2862 : ret = nl_build_nlh(cl, cl->cl_genl_family_id, NLM_F_REQUEST);
268 2862 : if (ret)
269 0 : return ret;
270 :
271 : /* Generic nlmsg header */
272 2862 : ret = nl_build_genlh(cl, SANDESH_REQUEST, 0);
273 2862 : if (ret)
274 0 : return ret;
275 :
276 2862 : attr_len = nl_get_attr_hdr_size();
277 5724 : ret = sandesh_encode(request, request_string, vr_find_sandesh_info,
278 2862 : (nl_get_buf_ptr(cl) + attr_len),
279 2862 : (nl_get_buf_len(cl) - attr_len), &error);
280 2862 : if (ret <= 0)
281 0 : return ret;
282 :
283 : /* Add sandesh attribute */
284 2862 : nl_build_attr(cl, ret, NL_ATTR_VR_MESSAGE_PROTOCOL);
285 2862 : nl_update_nlh(cl);
286 :
287 2862 : return nl_sendmsg(cl);
288 : }
289 :
290 : struct nl_client *
291 2951 : vr_get_nl_client(int proto)
292 : {
293 : int ret;
294 2951 : int sock_proto = proto;
295 : struct nl_client *cl;
296 :
297 2951 : cl = nl_register_client();
298 2951 : if (!cl)
299 0 : return NULL;
300 :
301 2951 : parse_ini_file();
302 :
303 2951 : if (proto == VR_NETLINK_PROTO_DEFAULT)
304 2951 : sock_proto = get_protocol();
305 :
306 2951 : ret = nl_socket(cl, get_domain(), get_type(), sock_proto);
307 2951 : if (ret <= 0)
308 0 : goto fail;
309 :
310 2951 : ret = nl_connect(cl, get_ip(), get_port(), genetlink_group_id);
311 2951 : if (ret < 0)
312 0 : goto fail;
313 :
314 5902 : if ((proto == VR_NETLINK_PROTO_DEFAULT) &&
315 2951 : (get_platform() != VTEST_PLATFORM) &&
316 0 : (vrouter_obtain_family_id(cl) <= 0))
317 0 : goto fail;
318 :
319 2951 : return cl;
320 :
321 0 : fail:
322 0 : if (cl)
323 0 : nl_free_client(cl);
324 :
325 0 : return NULL;
326 : }
327 :
328 : int
329 0 : vr_send_get_bridge_table_data(struct nl_client *cl)
330 : {
331 : int ret;
332 : vr_bridge_table_data req;
333 :
334 0 : memset(&req, 0, sizeof(req));
335 0 : req.btable_op = SANDESH_OP_GET;
336 0 : req.btable_rid = 0;
337 :
338 0 : return vr_sendmsg(cl, &req, "vr_bridge_table_data");
339 : }
340 :
341 : int
342 0 : vr_send_set_dcb_state(struct nl_client *cl, uint8_t *ifname, uint8_t state)
343 : {
344 : int ret;
345 :
346 0 : ret = nl_build_set_dcb_state_msg(cl, ifname, state);
347 0 : if (ret < 0)
348 0 : return ret;
349 :
350 0 : ret = nl_dcb_sendmsg(cl, DCB_CMD_SSTATE, NULL);
351 0 : if (ret <= 0)
352 0 : return ret;
353 :
354 0 : if (ret != state) {
355 0 : printf("vRouter: Set DCB State failed (Req/Resp: %u/%d)\n",
356 : state, ret);
357 0 : return -1;
358 : }
359 :
360 0 : return 0;
361 : }
362 :
363 : int
364 0 : vr_send_get_dcb_state(struct nl_client *cl, uint8_t *ifname)
365 : {
366 : int ret;
367 :
368 0 : ret = nl_build_get_dcb_state_msg(cl, ifname);
369 0 : if (ret < 0)
370 0 : return ret;
371 :
372 0 : return nl_dcb_sendmsg(cl, DCB_CMD_GSTATE, NULL);
373 : }
374 :
375 : int
376 0 : vr_send_set_dcbx(struct nl_client *cl, uint8_t *ifname, uint8_t dcbx)
377 : {
378 : int ret;
379 :
380 0 : ret = nl_build_set_dcbx(cl, ifname, dcbx);
381 0 : if (ret < 0)
382 0 : return ret;
383 :
384 0 : ret = nl_dcb_sendmsg(cl, DCB_CMD_SDCBX, NULL);
385 0 : if (ret < 0)
386 0 : return ret;
387 :
388 0 : if (ret) {
389 0 : printf("vRouter: Set DCBX failed (Req/Resp: %u/%d)\n",
390 : dcbx, ret);
391 0 : return -1;
392 : }
393 :
394 0 : return 0;
395 : }
396 :
397 : int
398 0 : vr_send_get_dcbx(struct nl_client *cl, uint8_t *ifname)
399 : {
400 : int ret;
401 :
402 0 : ret = nl_build_get_dcbx(cl, ifname);
403 0 : if (ret < 0)
404 0 : return ret;
405 :
406 0 : return nl_dcb_sendmsg(cl, DCB_CMD_GDCBX, NULL);
407 : }
408 :
409 : int
410 0 : vr_send_get_priority_config(struct nl_client *cl, uint8_t *ifname,
411 : struct priority *p)
412 : {
413 : int ret;
414 :
415 0 : ret = nl_build_get_priority_config_msg(cl, ifname);
416 0 : if (ret < 0)
417 0 : return ret;
418 :
419 0 : ret = nl_dcb_sendmsg(cl, DCB_CMD_PGTX_GCFG, p);
420 0 : if (ret < 0)
421 0 : return ret;
422 :
423 0 : return 0;
424 : }
425 :
426 : int
427 0 : vr_send_set_priority_config(struct nl_client *cl, uint8_t *ifname,
428 : struct priority *p)
429 : {
430 : int ret;
431 :
432 0 : ret = nl_build_set_priority_config_msg(cl, ifname, p);
433 0 : if (ret < 0)
434 0 : return ret;
435 :
436 0 : ret = nl_dcb_sendmsg(cl, DCB_CMD_PGTX_SCFG, NULL);
437 0 : if (ret < 0)
438 0 : return ret;
439 :
440 0 : return 0;
441 : }
442 :
443 : int
444 0 : vr_send_set_dcb_all(struct nl_client *cl, uint8_t *ifname)
445 : {
446 : int ret;
447 :
448 0 : ret = nl_build_set_dcb_all(cl, ifname);
449 0 : if (ret < 0)
450 0 : return ret;
451 :
452 0 : return nl_dcb_sendmsg(cl, DCB_CMD_SET_ALL, NULL);
453 : }
454 :
455 : int
456 0 : vr_send_get_ieee_ets(struct nl_client *cl, uint8_t *ifname,
457 : struct priority *p)
458 : {
459 : int ret;
460 :
461 0 : ret = nl_build_get_ieee_ets(cl, ifname, p);
462 0 : if (ret < 0)
463 0 : return ret;
464 :
465 0 : return nl_dcb_sendmsg(cl, DCB_CMD_IEEE_GET, p);
466 : }
467 :
468 : int
469 0 : vr_send_set_ieee_ets(struct nl_client *cl, uint8_t *ifname,
470 : struct priority *p)
471 : {
472 : int ret;
473 :
474 0 : ret = nl_build_set_ieee_ets(cl, ifname, p);
475 0 : if (ret < 0)
476 0 : return ret;
477 :
478 0 : return nl_dcb_sendmsg(cl, DCB_CMD_IEEE_SET, NULL);
479 : }
480 :
481 : void
482 1 : vr_print_drop_stats(vr_drop_stats_req *stats, int core)
483 : {
484 1 : int platform = get_platform();
485 :
486 1 : if (core != (unsigned)-1)
487 0 : printf("Statistics for core %u\n\n", core);
488 :
489 1 : if (stats->vds_pcpu_stats_failure_status)
490 0 : printf("Failed to maintain PerCPU stats for this interface\n\n");
491 :
492 1 : PRINT_DROP_STAT("Invalid IF", stats->vds_invalid_if);
493 1 : PRINT_DROP_STAT("Invalid ARP", stats->vds_invalid_arp);
494 1 : PRINT_DROP_STAT("Trap No IF", stats->vds_trap_no_if);
495 1 : PRINT_DROP_STAT("IF TX Discard", stats->vds_interface_tx_discard);
496 1 : PRINT_DROP_STAT("IF Drop", stats->vds_interface_drop);
497 1 : PRINT_DROP_STAT("IF RX Discard", stats->vds_interface_rx_discard);
498 1 : PRINT_DROP_STAT("Flow Unusable", stats->vds_flow_unusable);
499 1 : PRINT_DROP_STAT("Flow No Memory",stats->vds_flow_no_memory);
500 1 : PRINT_DROP_STAT("Flow Table Full", stats->vds_flow_table_full);
501 1 : PRINT_DROP_STAT("Flow NAT no rflow", stats->vds_flow_nat_no_rflow);
502 1 : PRINT_DROP_STAT("Flow Action Drop", stats->vds_flow_action_drop);
503 1 : PRINT_DROP_STAT("Flow Action Invalid", stats->vds_flow_action_invalid);
504 1 : PRINT_DROP_STAT("Flow Invalid Protocol", stats->vds_flow_invalid_protocol);
505 1 : PRINT_DROP_STAT("Flow Queue Limit Exceeded", stats->vds_flow_queue_limit_exceeded);
506 1 : PRINT_DROP_STAT("New Flow Drops", stats->vds_drop_new_flow);
507 1 : PRINT_DROP_STAT("Flow Unusable (Eviction)", stats->vds_flow_evict);
508 1 : PRINT_DROP_STAT("Original Packet Trapped", stats->vds_trap_original);
509 1 : PRINT_DROP_STAT("Discards", stats->vds_discard);
510 1 : PRINT_DROP_STAT("TTL Exceeded", stats->vds_ttl_exceeded);
511 1 : PRINT_DROP_STAT("Mcast Clone Fail", stats->vds_mcast_clone_fail);
512 1 : PRINT_DROP_STAT("Invalid NH", stats->vds_invalid_nh);
513 1 : PRINT_DROP_STAT("Invalid Label", stats->vds_invalid_label);
514 1 : PRINT_DROP_STAT("Invalid Protocol", stats->vds_invalid_protocol);
515 1 : PRINT_DROP_STAT("Etree Leaf to Leaf", stats->vds_leaf_to_leaf);
516 1 : PRINT_DROP_STAT("Bmac/ISID Mismatch", stats->vds_bmac_isid_mismatch);
517 1 : PRINT_DROP_STAT("Rewrite Fail", stats->vds_rewrite_fail);
518 1 : PRINT_DROP_STAT("Invalid Mcast Source", stats->vds_invalid_mcast_source);
519 1 : PRINT_DROP_STAT("Packet Loop", stats->vds_pkt_loop);
520 1 : PRINT_DROP_STAT("Push Fails", stats->vds_push);
521 1 : PRINT_DROP_STAT("Pull Fails", stats->vds_pull);
522 1 : PRINT_DROP_STAT("Duplicate", stats->vds_duplicated);
523 1 : PRINT_DROP_STAT("Head Alloc Fails", stats->vds_head_alloc_fail);
524 1 : PRINT_DROP_STAT("PCOW fails", stats->vds_pcow_fail);
525 1 : PRINT_DROP_STAT("Invalid Packets", stats->vds_invalid_packet);
526 1 : PRINT_DROP_STAT("Misc", stats->vds_misc);
527 1 : PRINT_DROP_STAT("Nowhere to go", stats->vds_nowhere_to_go);
528 1 : PRINT_DROP_STAT("Checksum errors", stats->vds_cksum_err);
529 1 : PRINT_DROP_STAT("No Fmd", stats->vds_no_fmd);
530 1 : PRINT_DROP_STAT("Invalid VNID", stats->vds_invalid_vnid);
531 1 : PRINT_DROP_STAT("Fragment errors", stats->vds_frag_err);
532 1 : PRINT_DROP_STAT("Invalid Source", stats->vds_invalid_source);
533 1 : PRINT_DROP_STAT("Jumbo Mcast Pkt with DF Bit", stats->vds_mcast_df_bit);
534 1 : PRINT_DROP_STAT("No L2 Route", stats->vds_l2_no_route);
535 1 : PRINT_DROP_STAT("Memory Failures", stats->vds_no_memory);
536 1 : PRINT_DROP_STAT("Fragment Queueing Failures", stats->vds_fragment_queue_fail);
537 1 : PRINT_DROP_STAT("No Encrypt Path Failures", stats->vds_no_crypt_path);
538 1 : PRINT_DROP_STAT("Invalid HBS received packet", stats->vds_invalid_hbs_pkt);
539 1 : PRINT_DROP_STAT("No Fragment Entries", stats->vds_no_frag_entry);
540 1 : PRINT_DROP_STAT("ICMP errors", stats->vds_icmp_error);
541 1 : PRINT_DROP_STAT("Clone Failures", stats->vds_clone_fail);
542 1 : PRINT_DROP_STAT("Invalid underlay ECMP", stats->vds_invalid_underlay_ecmp);
543 :
544 1 : if (platform == DPDK_PLATFORM)
545 : {
546 0 : PRINT_DROP_STAT("VLAN fwd intf failed TX", stats->vds_vlan_fwd_tx);
547 0 : PRINT_DROP_STAT("VLAN fwd intf failed enq", stats->vds_vlan_fwd_enq);
548 : }
549 1 : return;
550 : }
551 :
552 : void
553 0 : vr_print_drop_dbg_stats(vr_drop_stats_req *stats, int core)
554 : {
555 0 : printf("Cloned Original %" PRIu64 "\n",
556 : stats->vds_cloned_original);
557 0 : return;
558 : }
559 :
560 : const char *
561 0 : vr_pkt_vp_type_rsn(unsigned char vp_type)
562 : {
563 0 : switch(vp_type) {
564 0 : case VP_TYPE_ARP: return "ARP";
565 0 : case VP_TYPE_IP : return "IP";
566 0 : case VP_TYPE_IP6: return "IP6";
567 0 : case VP_TYPE_IPOIP: return "IPOIP";
568 0 : case VP_TYPE_IP6OIP: return "IP6OIP";
569 0 : case VP_TYPE_AGENT: return "AGENT";
570 0 : case VP_TYPE_PBB: return "PBB";
571 0 : default: return "UNKNOWN";
572 : }
573 : }
574 :
575 : const char *
576 0 : vr_pkt_droplog_rsn(unsigned short drop_reason)
577 : {
578 0 : switch(drop_reason) {
579 0 : case VP_DROP_DISCARD:
580 0 : return "Discards";
581 0 : case VP_DROP_PULL:
582 0 : return "Pull Fails";
583 0 : case VP_DROP_INVALID_IF:
584 0 : return "Invalid IF";
585 0 : case VP_DROP_INVALID_ARP:
586 0 : return "Invalid ARP";
587 0 : case VP_DROP_TRAP_NO_IF:
588 0 : return "Trap No IF";
589 0 : case VP_DROP_NOWHERE_TO_GO:
590 0 : return "Nowhere to go";
591 0 : case VP_DROP_FLOW_QUEUE_LIMIT_EXCEEDED:
592 0 : return "Flow Queue Limit Exceeded";
593 0 : case VP_DROP_FLOW_NO_MEMORY:
594 0 : return "Flow No Memory";
595 0 : case VP_DROP_FLOW_INVALID_PROTOCOL:
596 0 : return "Flow Invalid Protocol";
597 0 : case VP_DROP_FLOW_NAT_NO_RFLOW:
598 0 : return "Flow NAT no rflow";
599 0 : case VP_DROP_FLOW_ACTION_DROP:
600 0 : return "Flow Action Drop";
601 0 : case VP_DROP_FLOW_ACTION_INVALID:
602 0 : return "Flow Action Invalid";
603 0 : case VP_DROP_FLOW_UNUSABLE:
604 0 : return "Flow Unusable";
605 0 : case VP_DROP_FLOW_TABLE_FULL:
606 0 : return "Flow Table Full";
607 0 : case VP_DROP_INTERFACE_TX_DISCARD:
608 0 : return "IF TX Discard";
609 0 : case VP_DROP_INTERFACE_DROP:
610 0 : return "IF Drop";
611 0 : case VP_DROP_DUPLICATED:
612 0 : return "Duplicate";
613 0 : case VP_DROP_PUSH:
614 0 : return "Push Fails";
615 0 : case VP_DROP_TTL_EXCEEDED:
616 0 : return "TTL Exceeded";
617 0 : case VP_DROP_INVALID_NH:
618 0 : return "Invalid NH";
619 0 : case VP_DROP_INVALID_LABEL:
620 0 : return "Invalid Label";
621 0 : case VP_DROP_INVALID_PROTOCOL:
622 0 : return "Invalid Protocol";
623 0 : case VP_DROP_INTERFACE_RX_DISCARD:
624 0 : return "IF RX Discard";
625 0 : case VP_DROP_INVALID_MCAST_SOURCE:
626 0 : return "Invalid Mcast Source";
627 0 : case VP_DROP_HEAD_ALLOC_FAIL:
628 0 : return "Head Alloc Fails";
629 0 : case VP_DROP_PCOW_FAIL:
630 0 : return "PCOW fails";
631 0 : case VP_DROP_MCAST_DF_BIT:
632 0 : return "Jumbo Mcast Pkt with DF Bit";
633 0 : case VP_DROP_MCAST_CLONE_FAIL:
634 0 : return "Mcast Clone Fail";
635 0 : case VP_DROP_NO_MEMORY:
636 0 : return "Memory Failures";
637 0 : case VP_DROP_REWRITE_FAIL:
638 0 : return "Rewrite Fail";
639 0 : case VP_DROP_MISC:
640 0 : return "Misc";
641 0 : case VP_DROP_INVALID_PACKET:
642 0 : return "Invalid Packets";
643 0 : case VP_DROP_CKSUM_ERR:
644 0 : return "Checksum errors";
645 0 : case VP_DROP_NO_FMD:
646 0 : return "No Fmd";
647 0 : case VP_DROP_CLONED_ORIGINAL:
648 0 : return "Cloned Original";
649 0 : case VP_DROP_INVALID_VNID:
650 0 : return "Invalid VNID";
651 0 : case VP_DROP_FRAGMENTS:
652 0 : return "Fragment errors";
653 0 : case VP_DROP_INVALID_SOURCE:
654 0 : return "Invalid Source";
655 0 : case VP_DROP_L2_NO_ROUTE:
656 0 : return "No L2 Route";
657 0 : case VP_DROP_FRAGMENT_QUEUE_FAIL:
658 0 : return "Fragment Queueing Failures";
659 0 : case VP_DROP_VLAN_FWD_TX:
660 0 : return "VLAN fwd intf failed TX";
661 0 : case VP_DROP_VLAN_FWD_ENQ:
662 0 : return "VLAN fwd intf failed enq";
663 0 : case VP_DROP_NEW_FLOWS:
664 0 : return "New Flow Drops";
665 0 : case VP_DROP_FLOW_EVICT:
666 0 : return "Flow Unusable (Eviction)";
667 0 : case VP_DROP_TRAP_ORIGINAL:
668 0 : return "Original Packet Trapped";
669 0 : case VP_DROP_LEAF_TO_LEAF:
670 0 : return "Etree Leaf to Leaf";
671 0 : case VP_DROP_BMAC_ISID_MISMATCH:
672 0 : return "Bmac/ISID Mismatch";
673 0 : case VP_DROP_PKT_LOOP:
674 0 : return "Packet Loop";
675 0 : case VP_DROP_NO_CRYPT_PATH:
676 0 : return "No Encrypt Path Failures";
677 0 : case VP_DROP_INVALID_HBS_PKT:
678 0 : return "Invalid HBS received packet";
679 0 : case VP_DROP_NO_FRAG_ENTRY:
680 0 : return "No Fragment Entries";
681 0 : case VP_DROP_ICMP_ERROR:
682 0 : return "ICMP errors";
683 0 : case VP_DROP_CLONE_FAIL:
684 0 : return "Clone Failures";
685 0 : case VP_DROP_INVALID_UNDERLAY_ECMP:
686 0 : return "Invalid underlay ECMP";
687 0 : default:
688 0 : return "Unknow";
689 : }
690 :
691 : }
692 0 : void vr_print_pkt_drop_log_data(vr_pkt_drop_log_req *pkt_log, int i,
693 : uint8_t show_pkt_drop_type)
694 : {
695 0 : int j = 0;
696 0 : vr_pkt_drop_log_t *pkt_log_utils =
697 : (vr_pkt_drop_log_t*)pkt_log->vdl_pkt_droplog_arr;
698 : struct tm *ptr_time;
699 0 : char ipv6_addr[INET6_ADDRSTRLEN] = "";
700 :
701 : /* String mapping for packet drop log */
702 0 : char vr_pkt_droplog_str[][50] = {
703 : FILE_MAP(string)
704 : };
705 :
706 0 : if (!pkt_log_utils[i].vp_type)
707 0 : return;
708 :
709 0 : if ((show_pkt_drop_type != VP_DROP_MAX) &&
710 0 : (show_pkt_drop_type != pkt_log_utils[i].drop_reason))
711 0 : return;
712 :
713 0 : if((pkt_log->vdl_log_idx+i < VR_PKT_DROP_LOG_MAX) &&
714 0 : (!vr_header_include))
715 : {
716 0 : vr_print_pkt_drop_log_header(pkt_log);
717 0 : vr_header_include = 1;
718 : }
719 :
720 0 : ptr_time = localtime(&(pkt_log_utils[i].timestamp));
721 :
722 0 : printf("sl no: %d ", pkt_log->vdl_log_idx+i);
723 0 : printf("Epoch Time: %ld ", pkt_log_utils[i].timestamp);
724 0 : printf("Local Time: %s ", asctime(ptr_time));
725 0 : printf("Packet Type: %s ", vr_pkt_vp_type_rsn(pkt_log_utils[i].vp_type));
726 0 : if(pkt_log_utils[i].drop_reason)
727 0 : printf("Drop reason: %s ", vr_pkt_droplog_rsn(pkt_log_utils[i].drop_reason));
728 0 : PRINT_PKT_LOG("Vif idx:", pkt_log_utils[i].vif_idx);
729 0 : PRINT_PKT_LOG("Nexthop id:", pkt_log_utils[i].nh_id);
730 0 : if(pkt_log_utils[i].vp_type == VP_TYPE_IP)
731 : {
732 0 : printf("Src IP: %s ", inet_ntoa(pkt_log_utils[i].src.ipv4));
733 0 : printf("Dst IP: %s ", inet_ntoa(pkt_log_utils[i].dst.ipv4));
734 : }
735 0 : else if (pkt_log_utils[i].vp_type == VP_TYPE_IP6)
736 : {
737 0 : inet_ntop(AF_INET6, &pkt_log_utils[i].src.ipv6, ipv6_addr, INET6_ADDRSTRLEN);
738 0 : printf("Src IPv6: %s ", ipv6_addr);
739 0 : inet_ntop(AF_INET6, &pkt_log_utils[i].dst.ipv6, ipv6_addr, INET6_ADDRSTRLEN);
740 0 : printf("Dst IPv6: %s ", ipv6_addr);
741 : }
742 :
743 0 : PRINT_PKT_LOG("Source port:", pkt_log_utils[i].sport);
744 0 : PRINT_PKT_LOG("Dest port:", pkt_log_utils[i].dport);
745 0 : if(pkt_log_utils[i].drop_loc.file)
746 0 : printf("file: %s ", vr_pkt_droplog_str[pkt_log_utils[i].drop_loc.file]);
747 0 : printf("line no: %d ", pkt_log_utils[i].drop_loc.line);
748 :
749 0 : if(pkt_log_utils[i].pkt_len)
750 : {
751 0 : printf("Packet Length: %d ", pkt_log_utils[i].pkt_len);
752 0 : printf("Packet Data: ");
753 :
754 0 : if(pkt_log_utils[i].pkt_len > 100)
755 0 : for(j = 0; j < 100; j++)
756 0 : printf("%02X ", pkt_log_utils[i].pkt_header[j]);
757 : else
758 0 : for(j=0;j<pkt_log_utils[i].pkt_len;j++)
759 0 : printf("%02X ", pkt_log_utils[i].pkt_header[j]);
760 : }
761 0 : printf("\n\n");
762 : }
763 0 : void vr_print_pkt_drop_log_header(vr_pkt_drop_log_req *pkt_log)
764 : {
765 0 : printf("**********PKT DROP LOG**********\n");
766 0 : printf("Total No. of CPU's %d\n", pkt_log->vdl_max_num_cores);
767 : /* When requested for core 0, it will try to log for all cores
768 : * so here manually printing as core 1 */
769 0 : if(pkt_log->vdl_core == 0)
770 0 : printf("Pkt Drop Log for Core 1\n\n");
771 : else
772 0 : printf("Pkt Drop Log for Core %d\n\n", pkt_log->vdl_core);
773 0 : }
774 : void
775 0 : vr_print_pkt_drop_log(vr_pkt_drop_log_req *pkt_log, uint8_t show_pkt_drop_type)
776 : {
777 0 : int i = 0, log_buffer_iter = 0;
778 : static bool vr_header_include = 0;
779 :
780 : /* When configured pkt buffer size is than MAX_ALLOWED_BUFFER_SIZE */
781 0 : if(pkt_log->vdl_pkt_droplog_max_bufsz - pkt_log->vdl_log_idx <
782 : VR_PKT_DROPLOG_MAX_ALLOW_BUFSZ)
783 : {
784 0 : log_buffer_iter = pkt_log->vdl_pkt_droplog_max_bufsz - pkt_log->vdl_log_idx;
785 : }
786 : else
787 0 : log_buffer_iter = VR_PKT_DROPLOG_MAX_ALLOW_BUFSZ;
788 :
789 0 : for(i = 0; i < log_buffer_iter; i++)
790 0 : vr_print_pkt_drop_log_data(pkt_log, i, show_pkt_drop_type);
791 :
792 : /* On Every VR_PKT_DROP_LOG_MAX count time need to check this
793 : * flag to print PKT DROP header
794 : */
795 0 : if((pkt_log->vdl_log_idx + log_buffer_iter == VR_PKT_DROP_LOG_MAX) &&
796 : (vr_header_include))
797 : {
798 0 : vr_header_include = 0;
799 : }
800 0 : return;
801 : }
802 :
803 : int
804 17 : vr_response_common_process(vr_response *resp, bool *dump_pending)
805 : {
806 17 : int ret = 0;
807 :
808 17 : if (dump_pending)
809 17 : *dump_pending = false;
810 :
811 17 : if (resp->resp_code < 0) {
812 4 : if (!vr_ignore_nl_errors) {
813 4 : printf("vRouter(Response): %s (%d)\n", strerror(-resp->resp_code),
814 4 : -resp->resp_code);
815 : }
816 4 : ret = resp->resp_code;
817 : } else {
818 13 : if ((resp->resp_code & VR_MESSAGE_DUMP_INCOMPLETE) &&
819 : dump_pending)
820 0 : *dump_pending = true;
821 : }
822 :
823 17 : return ret;
824 : }
825 :
826 : /* dropstats start */
827 : uint64_t
828 5 : vr_sum_drop_stats(vr_drop_stats_req *req)
829 : {
830 5 : uint64_t sum = 0;
831 :
832 5 : sum += req->vds_discard;
833 5 : sum += req->vds_pull;
834 5 : sum += req->vds_invalid_if;
835 5 : sum += req->vds_invalid_arp;
836 5 : sum += req->vds_trap_no_if;
837 5 : sum += req->vds_nowhere_to_go;
838 5 : sum += req->vds_flow_queue_limit_exceeded;
839 5 : sum += req->vds_flow_no_memory;
840 5 : sum += req->vds_flow_invalid_protocol;
841 5 : sum += req->vds_flow_nat_no_rflow;
842 5 : sum += req->vds_flow_action_drop;
843 5 : sum += req->vds_flow_action_invalid;
844 5 : sum += req->vds_flow_unusable;
845 5 : sum += req->vds_flow_table_full;
846 5 : sum += req->vds_interface_tx_discard;
847 5 : sum += req->vds_interface_drop;
848 5 : sum += req->vds_duplicated;
849 5 : sum += req->vds_push;
850 5 : sum += req->vds_ttl_exceeded;
851 5 : sum += req->vds_invalid_nh;
852 5 : sum += req->vds_invalid_label;
853 5 : sum += req->vds_invalid_protocol;
854 5 : sum += req->vds_interface_rx_discard;
855 5 : sum += req->vds_invalid_mcast_source;
856 5 : sum += req->vds_head_alloc_fail;
857 5 : sum += req->vds_pcow_fail;
858 5 : sum += req->vds_mcast_df_bit;
859 5 : sum += req->vds_mcast_clone_fail;
860 5 : sum += req->vds_no_memory;
861 5 : sum += req->vds_rewrite_fail;
862 5 : sum += req->vds_misc;
863 5 : sum += req->vds_invalid_packet;
864 5 : sum += req->vds_cksum_err;
865 5 : sum += req->vds_no_fmd;
866 5 : sum += req->vds_cloned_original;
867 5 : sum += req->vds_invalid_vnid;
868 5 : sum += req->vds_frag_err;
869 5 : sum += req->vds_invalid_source;
870 5 : sum += req->vds_l2_no_route;
871 5 : sum += req->vds_fragment_queue_fail;
872 5 : sum += req->vds_vlan_fwd_tx;
873 5 : sum += req->vds_vlan_fwd_enq;
874 5 : sum += req->vds_drop_new_flow;
875 5 : sum += req->vds_trap_original;
876 5 : sum += req->vds_pkt_loop;
877 5 : sum += req->vds_no_crypt_path;
878 5 : sum += req->vds_invalid_underlay_ecmp;
879 :
880 5 : return sum;
881 : }
882 :
883 : void
884 5 : vr_drop_stats_req_destroy(vr_drop_stats_req *req)
885 : {
886 5 : if (!req)
887 0 : return;
888 :
889 5 : free(req);
890 5 : return;
891 : }
892 :
893 : vr_drop_stats_req *
894 5 : vr_drop_stats_req_get_copy(vr_drop_stats_req *src)
895 : {
896 : vr_drop_stats_req *dst;
897 :
898 5 : if (!src)
899 0 : return NULL;
900 :
901 5 : dst = malloc(sizeof(*dst));
902 5 : if (!dst)
903 0 : return NULL;
904 :
905 5 : *dst = *src;
906 5 : return dst;
907 : }
908 :
909 : int
910 6 : vr_send_drop_stats_get(struct nl_client *cl, unsigned int router_id,
911 : short core)
912 : {
913 : vr_drop_stats_req req;
914 :
915 6 : memset(&req, 0, sizeof(req));
916 6 : req.h_op = SANDESH_OP_GET;
917 6 : req.vds_rid = router_id;
918 6 : req.vds_core = core;
919 :
920 6 : return vr_sendmsg(cl, &req, "vr_drop_stats_req");
921 : }
922 :
923 :
924 : int
925 1 : vr_send_info_dump(struct nl_client *cl, unsigned int router_id,
926 : int marker, int buff_table_id, vr_info_msg_en msginfo, int buffsz,
927 : uint8_t *vr_info_inbuf)
928 : {
929 : vr_info_req req;
930 :
931 1 : memset(&req, 0, sizeof(req));
932 1 : req.h_op = SANDESH_OP_DUMP;
933 1 : req.vdu_rid = router_id;
934 1 : req.vdu_marker = marker;
935 1 : req.vdu_buff_table_id = buff_table_id;
936 1 : req.vdu_msginfo = msginfo;
937 1 : req.vdu_outbufsz = buffsz;
938 1 : if(vr_info_inbuf != NULL) {
939 1 : req.vdu_inbuf_size = strlen(vr_info_inbuf);
940 1 : req.vdu_inbuf = vr_info_inbuf;
941 : }
942 1 : return vr_sendmsg(cl, &req, "vr_info_req");
943 : }
944 :
945 : int
946 0 : vr_pkt_drop_log_reset(struct nl_client *cl)
947 : {
948 : vr_pkt_drop_log_req req;
949 :
950 0 : memset(&req, 0, sizeof(req));
951 0 : req.h_op = SANDESH_OP_RESET;
952 :
953 0 : return vr_sendmsg(cl, &req, "vr_pkt_drop_log_req");
954 : }
955 :
956 : int
957 0 : vr_drop_stats_reset(struct nl_client *cl)
958 : {
959 : vr_drop_stats_req req;
960 :
961 0 : memset(&req, 0, sizeof(req));
962 0 : req.h_op = SANDESH_OP_RESET;
963 :
964 0 : return vr_sendmsg(cl, &req, "vr_drop_stats_req");
965 : }
966 :
967 : int
968 0 : vr_drop_type_set(struct nl_client *cl, uint8_t pkt_drop_log_type)
969 : {
970 : vr_pkt_drop_log_req req;
971 :
972 0 : memset(&req, 0, sizeof(req));
973 0 : req.h_op = SANDESH_OP_ADD;
974 0 : req.vdl_pkt_droplog_type = pkt_drop_log_type;
975 :
976 : /* this flag is to indentify bettwn min log config and drop type set
977 : if 1 used for drop type config
978 : if 0 used for min log config
979 : */
980 0 : req.vdl_pkt_droplog_config = true;
981 :
982 0 : return vr_sendmsg(cl, &req, "vr_pkt_drop_log_req");
983 : }
984 :
985 : int
986 0 : vr_min_log_enable(struct nl_client *cl, bool min_log)
987 : {
988 : vr_pkt_drop_log_req req;
989 :
990 0 : memset(&req, 0, sizeof(req));
991 0 : req.h_op = SANDESH_OP_ADD;
992 0 : req.vdl_pkt_droplog_min_sysctl_en = min_log;
993 :
994 : /* this flag is to indentify between min log config and drop type set
995 : if 1 used for drop type config
996 : if 0 used for min log config
997 : */
998 0 : req.vdl_pkt_droplog_config = false;
999 0 : return vr_sendmsg(cl, &req, "vr_pkt_drop_log_req");
1000 : }
1001 :
1002 0 : int vr_pkt_drop_log_request(struct nl_client *cl, unsigned int router_id,
1003 : unsigned int core, int log_idx )
1004 : {
1005 0 : int ret = 0;
1006 : vr_pkt_drop_log_req req;
1007 :
1008 0 : memset(&req, 0, sizeof(req));
1009 :
1010 0 : req.vdl_pkt_droplog_arr = (char *)malloc(1);
1011 :
1012 0 : req.h_op = SANDESH_OP_GET;
1013 0 : req.vdl_rid = router_id;
1014 0 : req.vdl_core = core;
1015 0 : req.vdl_log_idx = log_idx;
1016 :
1017 0 : ret = vr_sendmsg(cl, &req, "vr_pkt_drop_log_req");
1018 :
1019 0 : free(req.vdl_pkt_droplog_arr);
1020 :
1021 0 : return ret;
1022 : }
1023 : /* dropstats end */
1024 :
1025 : /* Interface start */
1026 : void
1027 25 : vr_interface_req_destroy(vr_interface_req *req)
1028 : {
1029 25 : if (!req)
1030 18 : return;
1031 :
1032 7 : if (req->vifr_name) {
1033 7 : free(req->vifr_name);
1034 7 : req->vifr_name = NULL;
1035 : }
1036 :
1037 7 : if (req->vifr_queue_ierrors_to_lcore_size &&
1038 7 : req->vifr_queue_ierrors_to_lcore) {
1039 7 : free(req->vifr_queue_ierrors_to_lcore);
1040 7 : req->vifr_queue_ierrors_to_lcore = NULL;
1041 7 : req->vifr_queue_ierrors_to_lcore_size = 0;
1042 : }
1043 :
1044 :
1045 7 : if (req->vifr_mac && req->vifr_mac_size) {
1046 7 : free(req->vifr_mac);
1047 7 : req->vifr_mac = NULL;
1048 7 : req->vifr_mac_size = 0;
1049 : }
1050 :
1051 7 : if (req->vifr_src_mac && req->vifr_src_mac_size) {
1052 0 : free(req->vifr_src_mac);
1053 0 : req->vifr_src_mac = NULL;
1054 0 : req->vifr_src_mac_size = 0;
1055 : }
1056 :
1057 7 : if (req->vifr_fat_flow_protocol_port_size &&
1058 0 : req->vifr_fat_flow_protocol_port) {
1059 0 : free(req->vifr_fat_flow_protocol_port);
1060 0 : req->vifr_fat_flow_protocol_port = NULL;
1061 0 : req->vifr_fat_flow_protocol_port_size = 0;
1062 : }
1063 :
1064 7 : if (req->vifr_fat_flow_src_prefix_h &&
1065 0 : req->vifr_fat_flow_src_prefix_h_size) {
1066 0 : free(req->vifr_fat_flow_src_prefix_h);
1067 0 : req->vifr_fat_flow_src_prefix_h = NULL;
1068 0 : req->vifr_fat_flow_src_prefix_h_size = 0;
1069 : }
1070 7 : if (req->vifr_fat_flow_src_prefix_l &&
1071 0 : req->vifr_fat_flow_src_prefix_l_size) {
1072 0 : free(req->vifr_fat_flow_src_prefix_l);
1073 0 : req->vifr_fat_flow_src_prefix_l = NULL;
1074 0 : req->vifr_fat_flow_src_prefix_l_size = 0;
1075 : }
1076 7 : if (req->vifr_fat_flow_src_prefix_mask &&
1077 0 : req->vifr_fat_flow_src_prefix_mask_size) {
1078 0 : free(req->vifr_fat_flow_src_prefix_mask);
1079 0 : req->vifr_fat_flow_src_prefix_mask = NULL;
1080 0 : req->vifr_fat_flow_src_prefix_mask_size = 0;
1081 : }
1082 7 : if (req->vifr_fat_flow_src_aggregate_plen &&
1083 0 : req->vifr_fat_flow_src_aggregate_plen_size) {
1084 0 : free(req->vifr_fat_flow_src_aggregate_plen);
1085 0 : req->vifr_fat_flow_src_aggregate_plen = NULL;
1086 0 : req->vifr_fat_flow_src_aggregate_plen_size = 0;
1087 : }
1088 7 : if (req->vifr_fat_flow_dst_prefix_h &&
1089 0 : req->vifr_fat_flow_dst_prefix_h_size) {
1090 0 : free(req->vifr_fat_flow_dst_prefix_h);
1091 0 : req->vifr_fat_flow_dst_prefix_h = NULL;
1092 0 : req->vifr_fat_flow_dst_prefix_h_size = 0;
1093 : }
1094 7 : if (req->vifr_fat_flow_dst_prefix_l &&
1095 0 : req->vifr_fat_flow_dst_prefix_l_size) {
1096 0 : free(req->vifr_fat_flow_dst_prefix_l);
1097 0 : req->vifr_fat_flow_dst_prefix_l = NULL;
1098 0 : req->vifr_fat_flow_dst_prefix_l_size = 0;
1099 : }
1100 7 : if (req->vifr_fat_flow_dst_prefix_mask &&
1101 0 : req->vifr_fat_flow_dst_prefix_mask_size) {
1102 0 : free(req->vifr_fat_flow_dst_prefix_mask);
1103 0 : req->vifr_fat_flow_dst_prefix_mask = NULL;
1104 0 : req->vifr_fat_flow_dst_prefix_mask_size = 0;
1105 : }
1106 7 : if (req->vifr_fat_flow_dst_aggregate_plen &&
1107 0 : req->vifr_fat_flow_dst_aggregate_plen_size) {
1108 0 : free(req->vifr_fat_flow_dst_aggregate_plen);
1109 0 : req->vifr_fat_flow_dst_aggregate_plen = NULL;
1110 0 : req->vifr_fat_flow_dst_aggregate_plen_size = 0;
1111 : }
1112 :
1113 7 : if (req->vifr_fat_flow_exclude_ip_list_size &&
1114 0 : req->vifr_fat_flow_exclude_ip_list) {
1115 0 : free(req->vifr_fat_flow_exclude_ip_list);
1116 0 : req->vifr_fat_flow_exclude_ip_list = NULL;
1117 0 : req->vifr_fat_flow_exclude_ip_list_size = 0;
1118 : }
1119 7 : if (req->vifr_fat_flow_exclude_ip6_u_list_size &&
1120 0 : req->vifr_fat_flow_exclude_ip6_u_list) {
1121 0 : free(req->vifr_fat_flow_exclude_ip6_u_list);
1122 0 : req->vifr_fat_flow_exclude_ip6_u_list = NULL;
1123 0 : req->vifr_fat_flow_exclude_ip6_u_list_size = 0;
1124 : }
1125 7 : if (req->vifr_fat_flow_exclude_ip6_l_list_size &&
1126 0 : req->vifr_fat_flow_exclude_ip6_l_list) {
1127 0 : free(req->vifr_fat_flow_exclude_ip6_l_list);
1128 0 : req->vifr_fat_flow_exclude_ip6_l_list = NULL;
1129 0 : req->vifr_fat_flow_exclude_ip6_l_list_size = 0;
1130 : }
1131 :
1132 7 : free(req);
1133 7 : return;
1134 : }
1135 :
1136 :
1137 : vr_interface_req *
1138 7 : vr_interface_req_get_copy(vr_interface_req *src)
1139 : {
1140 : vr_interface_req *dst;
1141 :
1142 7 : dst = malloc(sizeof(*dst));
1143 7 : if (!dst)
1144 0 : return NULL;
1145 :
1146 7 : *dst = *src;
1147 7 : dst->vifr_name = NULL;
1148 7 : dst->vifr_queue_ierrors_to_lcore_size = 0;
1149 7 : dst->vifr_queue_ierrors_to_lcore = NULL;
1150 7 : dst->vifr_mac_size = 0;
1151 7 : dst->vifr_mac = NULL;
1152 7 : dst->vifr_src_mac_size = 0;
1153 7 : dst->vifr_src_mac = NULL;
1154 7 : dst->vifr_fat_flow_protocol_port_size = 0;
1155 7 : dst->vifr_fat_flow_protocol_port = NULL;
1156 7 : dst->vifr_fat_flow_src_prefix_h = NULL;
1157 7 : dst->vifr_fat_flow_src_prefix_h_size = 0;
1158 7 : dst->vifr_fat_flow_src_prefix_l = NULL;
1159 7 : dst->vifr_fat_flow_src_prefix_l_size = 0;
1160 7 : dst->vifr_fat_flow_src_prefix_mask = NULL;
1161 7 : dst->vifr_fat_flow_src_prefix_mask_size = 0;
1162 7 : dst->vifr_fat_flow_src_aggregate_plen = NULL;
1163 7 : dst->vifr_fat_flow_src_aggregate_plen_size = 0;
1164 7 : dst->vifr_fat_flow_dst_prefix_h = NULL;
1165 7 : dst->vifr_fat_flow_dst_prefix_h_size = 0;
1166 7 : dst->vifr_fat_flow_dst_prefix_l = NULL;
1167 7 : dst->vifr_fat_flow_dst_prefix_l_size = 0;
1168 7 : dst->vifr_fat_flow_dst_prefix_mask = NULL;
1169 7 : dst->vifr_fat_flow_dst_prefix_mask_size = 0;
1170 7 : dst->vifr_fat_flow_dst_aggregate_plen = NULL;
1171 7 : dst->vifr_fat_flow_dst_aggregate_plen_size = 0;
1172 7 : dst->vifr_fat_flow_exclude_ip_list_size = 0;
1173 7 : dst->vifr_fat_flow_exclude_ip_list = NULL;
1174 7 : dst->vifr_fat_flow_exclude_ip6_u_list_size = 0;
1175 7 : dst->vifr_fat_flow_exclude_ip6_u_list = NULL;
1176 7 : dst->vifr_fat_flow_exclude_ip6_l_list_size = 0;
1177 7 : dst->vifr_fat_flow_exclude_ip6_l_list = NULL;
1178 :
1179 7 : if (src->vifr_name) {
1180 7 : dst->vifr_name = malloc(strlen(src->vifr_name) + 1);
1181 7 : if (!dst->vifr_name)
1182 0 : goto free_vif;
1183 7 : memcpy(dst->vifr_name, src->vifr_name, strlen(src->vifr_name) + 1);
1184 : }
1185 :
1186 7 : if (src->vifr_queue_ierrors_to_lcore_size &&
1187 7 : src->vifr_queue_ierrors_to_lcore) {
1188 7 : dst->vifr_queue_ierrors_to_lcore =
1189 7 : malloc(src->vifr_queue_ierrors_to_lcore_size * sizeof(uint64_t));
1190 7 : if (!dst->vifr_queue_ierrors_to_lcore)
1191 0 : goto free_vif;
1192 :
1193 7 : memcpy(dst->vifr_queue_ierrors_to_lcore,
1194 7 : src->vifr_queue_ierrors_to_lcore,
1195 7 : src->vifr_queue_ierrors_to_lcore_size);
1196 7 : dst->vifr_queue_ierrors_to_lcore_size =
1197 7 : src->vifr_queue_ierrors_to_lcore_size;
1198 : }
1199 :
1200 7 : if (src->vifr_mac && src->vifr_mac_size) {
1201 7 : dst->vifr_mac = malloc(src->vifr_mac_size);
1202 7 : if (!dst->vifr_mac)
1203 0 : goto free_vif;
1204 :
1205 7 : memcpy(dst->vifr_mac, src->vifr_mac, src->vifr_mac_size);
1206 7 : dst->vifr_mac_size = src->vifr_mac_size;
1207 : }
1208 :
1209 7 : if (src->vifr_src_mac && src->vifr_src_mac_size) {
1210 0 : dst->vifr_src_mac = malloc(src->vifr_src_mac_size);
1211 0 : if (!dst->vifr_src_mac)
1212 0 : goto free_vif;
1213 :
1214 0 : memcpy(dst->vifr_src_mac, src->vifr_src_mac, src->vifr_src_mac_size);
1215 0 : dst->vifr_src_mac_size = src->vifr_src_mac_size;
1216 : }
1217 :
1218 :
1219 7 : if (src->vifr_fat_flow_protocol_port_size &&
1220 0 : src->vifr_fat_flow_protocol_port) {
1221 0 : dst->vifr_fat_flow_protocol_port =
1222 0 : malloc(src->vifr_fat_flow_protocol_port_size * sizeof(uint32_t));
1223 0 : if (!dst->vifr_fat_flow_protocol_port)
1224 0 : goto free_vif;
1225 :
1226 0 : memcpy(dst->vifr_fat_flow_protocol_port,
1227 0 : src->vifr_fat_flow_protocol_port,
1228 0 : src->vifr_fat_flow_protocol_port_size);
1229 0 : dst->vifr_fat_flow_protocol_port_size =
1230 0 : src->vifr_fat_flow_protocol_port_size;
1231 : }
1232 :
1233 7 : if (src->vifr_fat_flow_src_prefix_h_size &&
1234 0 : src->vifr_fat_flow_src_prefix_h) {
1235 0 : dst->vifr_fat_flow_src_prefix_h =
1236 0 : malloc(src->vifr_fat_flow_src_prefix_h_size * sizeof(uint64_t));
1237 0 : if (!dst->vifr_fat_flow_src_prefix_h)
1238 0 : goto free_vif;
1239 0 : memcpy(dst->vifr_fat_flow_src_prefix_h, src->vifr_fat_flow_src_prefix_h,
1240 0 : src->vifr_fat_flow_src_prefix_h_size);
1241 0 : dst->vifr_fat_flow_src_prefix_h_size = src->vifr_fat_flow_src_prefix_h_size;
1242 : }
1243 :
1244 7 : if (src->vifr_fat_flow_src_prefix_l_size &&
1245 0 : src->vifr_fat_flow_src_prefix_l) {
1246 0 : dst->vifr_fat_flow_src_prefix_l =
1247 0 : malloc(src->vifr_fat_flow_src_prefix_l_size * sizeof(uint64_t));
1248 0 : if (!dst->vifr_fat_flow_src_prefix_l)
1249 0 : goto free_vif;
1250 0 : memcpy(dst->vifr_fat_flow_src_prefix_l, src->vifr_fat_flow_src_prefix_l,
1251 0 : src->vifr_fat_flow_src_prefix_l_size);
1252 0 : dst->vifr_fat_flow_src_prefix_l_size = src->vifr_fat_flow_src_prefix_l_size;
1253 : }
1254 7 : if (src->vifr_fat_flow_src_prefix_mask_size &&
1255 0 : src->vifr_fat_flow_src_prefix_mask) {
1256 0 : dst->vifr_fat_flow_src_prefix_mask =
1257 0 : malloc(src->vifr_fat_flow_src_prefix_mask_size * sizeof(uint8_t));
1258 0 : if (!dst->vifr_fat_flow_src_prefix_mask)
1259 0 : goto free_vif;
1260 0 : memcpy(dst->vifr_fat_flow_src_prefix_mask, src->vifr_fat_flow_src_prefix_mask,
1261 0 : src->vifr_fat_flow_src_prefix_mask_size);
1262 0 : dst->vifr_fat_flow_src_prefix_mask_size = src->vifr_fat_flow_src_prefix_mask_size;
1263 : }
1264 7 : if (src->vifr_fat_flow_src_aggregate_plen_size &&
1265 0 : src->vifr_fat_flow_src_aggregate_plen) {
1266 0 : dst->vifr_fat_flow_src_aggregate_plen =
1267 0 : malloc(src->vifr_fat_flow_src_aggregate_plen_size * sizeof(uint8_t));
1268 0 : if (!dst->vifr_fat_flow_src_aggregate_plen)
1269 0 : goto free_vif;
1270 0 : memcpy(dst->vifr_fat_flow_src_aggregate_plen, src->vifr_fat_flow_src_aggregate_plen,
1271 0 : src->vifr_fat_flow_src_aggregate_plen_size);
1272 0 : dst->vifr_fat_flow_src_aggregate_plen_size = src->vifr_fat_flow_src_aggregate_plen_size;
1273 : }
1274 7 : if (src->vifr_fat_flow_dst_prefix_h_size &&
1275 0 : src->vifr_fat_flow_dst_prefix_h) {
1276 0 : dst->vifr_fat_flow_dst_prefix_h =
1277 0 : malloc(src->vifr_fat_flow_dst_prefix_h_size * sizeof(uint64_t));
1278 0 : if (!dst->vifr_fat_flow_dst_prefix_h)
1279 0 : goto free_vif;
1280 0 : memcpy(dst->vifr_fat_flow_dst_prefix_h, src->vifr_fat_flow_dst_prefix_h,
1281 0 : src->vifr_fat_flow_dst_prefix_h_size);
1282 0 : dst->vifr_fat_flow_dst_prefix_h_size = src->vifr_fat_flow_dst_prefix_h_size;
1283 : }
1284 7 : if (src->vifr_fat_flow_dst_prefix_l_size &&
1285 0 : src->vifr_fat_flow_dst_prefix_l) {
1286 0 : dst->vifr_fat_flow_dst_prefix_l =
1287 0 : malloc(src->vifr_fat_flow_dst_prefix_l_size * sizeof(uint64_t));
1288 0 : if (!dst->vifr_fat_flow_dst_prefix_l)
1289 0 : goto free_vif;
1290 0 : memcpy(dst->vifr_fat_flow_dst_prefix_l, src->vifr_fat_flow_dst_prefix_l,
1291 0 : src->vifr_fat_flow_dst_prefix_l_size);
1292 0 : dst->vifr_fat_flow_dst_prefix_l_size = src->vifr_fat_flow_dst_prefix_l_size;
1293 : }
1294 7 : if (src->vifr_fat_flow_dst_prefix_mask_size &&
1295 0 : src->vifr_fat_flow_dst_prefix_mask) {
1296 0 : dst->vifr_fat_flow_dst_prefix_mask =
1297 0 : malloc(src->vifr_fat_flow_dst_prefix_mask_size * sizeof(uint8_t));
1298 0 : if (!dst->vifr_fat_flow_dst_prefix_mask)
1299 0 : goto free_vif;
1300 0 : memcpy(dst->vifr_fat_flow_dst_prefix_mask, src->vifr_fat_flow_dst_prefix_mask,
1301 0 : src->vifr_fat_flow_dst_prefix_mask_size);
1302 0 : dst->vifr_fat_flow_dst_prefix_mask_size = src->vifr_fat_flow_dst_prefix_mask_size;
1303 : }
1304 7 : if (src->vifr_fat_flow_dst_aggregate_plen_size &&
1305 0 : src->vifr_fat_flow_dst_aggregate_plen) {
1306 0 : dst->vifr_fat_flow_dst_aggregate_plen =
1307 0 : malloc(src->vifr_fat_flow_dst_aggregate_plen_size * sizeof(uint8_t));
1308 0 : if (!dst->vifr_fat_flow_dst_aggregate_plen)
1309 0 : goto free_vif;
1310 0 : memcpy(dst->vifr_fat_flow_dst_aggregate_plen, src->vifr_fat_flow_dst_aggregate_plen,
1311 0 : src->vifr_fat_flow_dst_aggregate_plen_size);
1312 0 : dst->vifr_fat_flow_dst_aggregate_plen_size = src->vifr_fat_flow_dst_aggregate_plen_size;
1313 : }
1314 :
1315 7 : if (src->vifr_fat_flow_exclude_ip_list_size &&
1316 0 : src->vifr_fat_flow_exclude_ip_list) {
1317 0 : dst->vifr_fat_flow_exclude_ip_list = malloc(src->vifr_fat_flow_exclude_ip_list_size * sizeof(uint64_t));
1318 0 : if (!dst->vifr_fat_flow_exclude_ip_list) {
1319 0 : goto free_vif;
1320 : }
1321 0 : memcpy(dst->vifr_fat_flow_exclude_ip_list, src->vifr_fat_flow_exclude_ip_list,
1322 0 : src->vifr_fat_flow_exclude_ip_list_size * sizeof(uint64_t));
1323 0 : dst->vifr_fat_flow_exclude_ip_list_size = src->vifr_fat_flow_exclude_ip_list_size;
1324 : }
1325 :
1326 7 : if (src->vifr_fat_flow_exclude_ip6_u_list_size &&
1327 0 : src->vifr_fat_flow_exclude_ip6_u_list) {
1328 0 : dst->vifr_fat_flow_exclude_ip6_u_list = malloc(src->vifr_fat_flow_exclude_ip6_u_list_size * sizeof(uint64_t));
1329 0 : if (!dst->vifr_fat_flow_exclude_ip6_u_list) {
1330 0 : goto free_vif;
1331 : }
1332 0 : memcpy(dst->vifr_fat_flow_exclude_ip6_u_list, src->vifr_fat_flow_exclude_ip6_u_list,
1333 0 : src->vifr_fat_flow_exclude_ip6_u_list_size * sizeof(uint64_t));
1334 0 : dst->vifr_fat_flow_exclude_ip6_u_list_size = src->vifr_fat_flow_exclude_ip6_u_list_size;
1335 : }
1336 7 : if (src->vifr_fat_flow_exclude_ip6_l_list_size &&
1337 0 : src->vifr_fat_flow_exclude_ip6_l_list) {
1338 0 : dst->vifr_fat_flow_exclude_ip6_l_list = malloc(src->vifr_fat_flow_exclude_ip6_l_list_size * sizeof(uint64_t));
1339 0 : if (!dst->vifr_fat_flow_exclude_ip6_l_list) {
1340 0 : goto free_vif;
1341 : }
1342 0 : memcpy(dst->vifr_fat_flow_exclude_ip6_l_list, src->vifr_fat_flow_exclude_ip6_l_list,
1343 0 : src->vifr_fat_flow_exclude_ip6_l_list_size * sizeof(uint64_t));
1344 0 : dst->vifr_fat_flow_exclude_ip6_l_list_size = src->vifr_fat_flow_exclude_ip6_l_list_size;
1345 : }
1346 :
1347 7 : return dst;
1348 :
1349 0 : free_vif:
1350 0 : vr_interface_req_destroy(dst);
1351 0 : dst = NULL;
1352 0 : return NULL;
1353 : }
1354 :
1355 : int
1356 0 : vr_send_interface_dump(struct nl_client *cl, unsigned int router_id,
1357 : int marker, int core)
1358 : {
1359 : vr_interface_req req;
1360 :
1361 0 : memset(&req, 0, sizeof(req));
1362 0 : req.h_op = SANDESH_OP_DUMP;
1363 0 : req.vifr_rid = router_id;
1364 0 : req.vifr_marker = marker;
1365 0 : req.vifr_core = core;
1366 0 : return vr_sendmsg(cl, &req, "vr_interface_req");
1367 : }
1368 :
1369 : int
1370 10 : vr_send_interface_get(struct nl_client *cl, unsigned int router_id,
1371 : int vif_index, int os_index, int core, int get_drops)
1372 : {
1373 : vr_interface_req req;
1374 :
1375 10 : memset(&req, 0, sizeof(req));
1376 :
1377 10 : req.h_op = SANDESH_OP_GET;
1378 10 : req.vifr_rid = router_id;
1379 10 : req.vifr_os_idx = os_index;
1380 10 : req.vifr_idx = vif_index;
1381 10 : req.vifr_core = core;
1382 10 : if (get_drops)
1383 0 : req.vifr_flags |= VIF_FLAG_GET_DROP_STATS;
1384 :
1385 10 : return vr_sendmsg(cl, &req, "vr_interface_req");
1386 : }
1387 :
1388 : int
1389 8 : vr_send_interface_delete(struct nl_client *cl, unsigned int router_id,
1390 : char *vif_name, int vif_index)
1391 : {
1392 : vr_interface_req req;
1393 :
1394 8 : memset(&req, 0, sizeof(req));
1395 :
1396 8 : req.h_op = SANDESH_OP_DEL;
1397 8 : req.vifr_rid = router_id;
1398 8 : req.vifr_name = vif_name;
1399 8 : req.vifr_idx = vif_index;
1400 :
1401 8 : return vr_sendmsg(cl, &req, "vr_interface_req");
1402 : }
1403 :
1404 : int
1405 0 : vr_send_interface_add(struct nl_client *cl, int router_id, char *vif_name,
1406 : int os_index, int vif_index, int *vif_xconnect_index, int vif_type,
1407 : unsigned int vrf, unsigned int flags, int8_t *vif_mac, int8_t vif_transport,
1408 : const char *guid)
1409 : {
1410 0 : int platform, i = 0;
1411 : vr_interface_req req;
1412 :
1413 0 : platform = get_platform();
1414 0 : memset(&req, 0, sizeof(req));
1415 :
1416 0 : req.h_op = SANDESH_OP_ADD;
1417 0 : if (vif_name)
1418 0 : req.vifr_name = vif_name;
1419 0 : if (vif_mac) {
1420 0 : req.vifr_mac_size = 6;
1421 0 : req.vifr_mac = vif_mac;
1422 : }
1423 0 : req.vifr_vrf = vrf;
1424 0 : req.vifr_mcast_vrf = (uint16_t)(-1);
1425 :
1426 0 : if (os_index > 0)
1427 0 : req.vifr_os_idx = os_index;
1428 :
1429 0 : req.vifr_idx = vif_index;
1430 0 : req.vifr_rid = router_id;
1431 0 : req.vifr_type = vif_type;
1432 0 : req.vifr_flags = flags;
1433 0 : req.vifr_transport = vif_transport;
1434 :
1435 0 : if (vif_type == VIF_TYPE_HOST) {
1436 0 : for(i = 0; i < VR_MAX_PHY_INF; i++) {
1437 0 : if(vif_xconnect_index[i] < 0) {
1438 0 : break;
1439 : }
1440 : }
1441 0 : req.vifr_cross_connect_idx_size = i;
1442 0 : req.vifr_cross_connect_idx = vif_xconnect_index;
1443 : }
1444 :
1445 0 : return vr_sendmsg(cl, &req, "vr_interface_req");
1446 : }
1447 :
1448 : int
1449 1 : vr_send_vif_clear_stats(struct nl_client *cl, unsigned int router_id,
1450 : int vif_idx, int core)
1451 : {
1452 : vr_interface_req req;
1453 :
1454 1 : memset(&req, 0, sizeof(req));
1455 1 : req.h_op = SANDESH_OP_RESET;
1456 1 : req.vifr_rid = router_id;
1457 1 : req.vifr_idx = vif_idx;
1458 1 : req.vifr_core = core + 1;
1459 :
1460 1 : return vr_sendmsg(cl, &req, "vr_interface_req");
1461 : }
1462 :
1463 : /* interface end */
1464 :
1465 :
1466 : int
1467 0 : vr_send_mem_stats_get(struct nl_client *cl, unsigned int router_id)
1468 : {
1469 : vr_mem_stats_req req;
1470 :
1471 0 : memset(&req, 0, sizeof(req));
1472 0 : req.h_op = SANDESH_OP_GET;
1473 0 : req.vms_rid = router_id;
1474 :
1475 0 : return vr_sendmsg(cl, &req, "vr_mem_stats_req");
1476 : }
1477 :
1478 : /* mirror start */
1479 : void
1480 0 : vr_mirror_req_destroy(vr_mirror_req *req)
1481 : {
1482 0 : if (!req)
1483 0 : return;
1484 :
1485 0 : free(req);
1486 :
1487 0 : return;
1488 : }
1489 :
1490 : vr_mirror_req *
1491 0 : vr_mirror_req_get_copy(vr_mirror_req *req)
1492 : {
1493 : vr_mirror_req *dst;
1494 :
1495 0 : if (!req)
1496 0 : return NULL;
1497 :
1498 0 : dst = malloc(sizeof(*req));
1499 0 : if (!dst)
1500 0 : return NULL;
1501 :
1502 0 : *dst = *req;
1503 :
1504 0 : return dst;
1505 : }
1506 :
1507 : int
1508 0 : vr_send_mirror_dump(struct nl_client *cl, unsigned int router_id,
1509 : int marker)
1510 : {
1511 : vr_mirror_req req;
1512 :
1513 0 : req.h_op = SANDESH_OP_DUMP;
1514 0 : req.mirr_rid = router_id;
1515 0 : req.mirr_marker = marker;
1516 :
1517 0 : return vr_sendmsg(cl, &req, "vr_mirror_req");
1518 : }
1519 :
1520 : int
1521 0 : vr_send_mirror_get(struct nl_client *cl, unsigned int router_id,
1522 : unsigned int mirror_index)
1523 : {
1524 : vr_mirror_req req;
1525 :
1526 0 : req.h_op = SANDESH_OP_GET;
1527 0 : req.mirr_rid = router_id;
1528 0 : req.mirr_index = mirror_index;
1529 :
1530 0 : return vr_sendmsg(cl, &req, "vr_mirror_req");
1531 : }
1532 :
1533 : int
1534 0 : vr_send_mirror_delete(struct nl_client *cl, unsigned int router_id,
1535 : unsigned int mirror_index)
1536 : {
1537 : vr_mirror_req req;
1538 :
1539 0 : req.h_op = SANDESH_OP_DEL;
1540 0 : req.mirr_rid = router_id;
1541 0 : req.mirr_index = mirror_index;
1542 :
1543 0 : return vr_sendmsg(cl, &req, "vr_mirror_req");
1544 : }
1545 :
1546 : int
1547 0 : vr_send_mirror_add(struct nl_client *cl, unsigned int router_id,
1548 : unsigned int mirror_index, int mirror_nh_index,
1549 : unsigned int mirror_flags, int vni_id)
1550 : {
1551 : vr_mirror_req req;
1552 :
1553 0 : memset(&req, 0, sizeof(req));
1554 :
1555 0 : req.h_op = SANDESH_OP_ADD;
1556 0 : req.mirr_rid = router_id;
1557 0 : req.mirr_index = mirror_index;
1558 0 : req.mirr_nhid = mirror_nh_index;
1559 0 : req.mirr_flags = mirror_flags;
1560 0 : req.mirr_vni = vni_id;
1561 :
1562 0 : return vr_sendmsg(cl, &req, "vr_mirror_req");
1563 : }
1564 : /* mirror end */
1565 :
1566 : int
1567 0 : vr_send_vrf_dump(struct nl_client *cl, unsigned int router_id,
1568 : int marker)
1569 : {
1570 : vr_vrf_req req;
1571 :
1572 0 : req.h_op = SANDESH_OP_DUMP;
1573 0 : req.vrf_rid = router_id;
1574 0 : req.vrf_marker = marker;
1575 :
1576 0 : return vr_sendmsg(cl, &req, "vr_vrf_req");
1577 : }
1578 :
1579 : int
1580 0 : vr_send_vrf_get(struct nl_client *cl, unsigned int router_id,
1581 : unsigned int vrf_index)
1582 : {
1583 : vr_vrf_req req;
1584 :
1585 0 : req.h_op = SANDESH_OP_GET;
1586 0 : req.vrf_rid = router_id;
1587 0 : req.vrf_idx = vrf_index;
1588 :
1589 0 : return vr_sendmsg(cl, &req, "vr_vrf_req");
1590 : }
1591 :
1592 : int
1593 0 : vr_send_vrf_delete(struct nl_client *cl, unsigned int router_id,
1594 : unsigned int vrf_index)
1595 : {
1596 : vr_vrf_req req;
1597 :
1598 0 : req.h_op = SANDESH_OP_DEL;
1599 0 : req.vrf_rid = router_id;
1600 0 : req.vrf_idx = vrf_index;
1601 :
1602 0 : return vr_sendmsg(cl, &req, "vr_vrf_req");
1603 : }
1604 :
1605 : int
1606 0 : vr_send_vrf_add(struct nl_client *cl, unsigned int router_id,
1607 : unsigned int vrf_index, int hbfl_idx, int hbfr_idx,
1608 : unsigned int vrf_flags)
1609 : {
1610 : vr_vrf_req req;
1611 :
1612 0 : memset(&req, 0, sizeof(req));
1613 :
1614 0 : req.h_op = SANDESH_OP_ADD;
1615 0 : req.vrf_rid = router_id;
1616 0 : req.vrf_idx = vrf_index;
1617 0 : req.vrf_flags = vrf_flags;
1618 0 : req.vrf_hbfl_vif_idx = hbfl_idx;
1619 0 : req.vrf_hbfr_vif_idx = hbfr_idx;
1620 :
1621 0 : return vr_sendmsg(cl, &req, "vr_vrf_req");
1622 : }
1623 :
1624 : int
1625 0 : vr_send_mpls_delete(struct nl_client *cl, unsigned int router_id,
1626 : unsigned int label)
1627 : {
1628 : vr_mpls_req req;
1629 :
1630 0 : memset(&req, 0, sizeof(req));
1631 0 : req.h_op = SANDESH_OP_DEL;
1632 0 : req.mr_rid = router_id;
1633 0 : req.mr_label = label;
1634 :
1635 0 : return vr_sendmsg(cl, &req, "vr_mpls_req");
1636 : }
1637 :
1638 : int
1639 0 : vr_send_mpls_dump(struct nl_client *cl, unsigned int router_id, int marker)
1640 : {
1641 : vr_mpls_req req;
1642 :
1643 0 : memset(&req, 0, sizeof(req));
1644 0 : req.h_op = SANDESH_OP_DUMP;
1645 0 : req.mr_rid = router_id;
1646 0 : req.mr_marker = marker;
1647 :
1648 0 : return vr_sendmsg(cl, &req, "vr_mpls_req");
1649 : }
1650 :
1651 : int
1652 0 : vr_send_mpls_get(struct nl_client *cl, unsigned int router_id, unsigned int label)
1653 : {
1654 : vr_mpls_req req;
1655 :
1656 0 : memset(&req, 0, sizeof(req));
1657 0 : req.h_op = SANDESH_OP_GET;
1658 0 : req.mr_rid = router_id;
1659 0 : req.mr_label = label;
1660 :
1661 0 : return vr_sendmsg(cl, &req, "vr_mpls_req");
1662 : }
1663 :
1664 : int
1665 0 : vr_send_mpls_add(struct nl_client *cl, unsigned int router_id,
1666 : unsigned int label, unsigned int nh_index)
1667 : {
1668 : vr_mpls_req req;
1669 :
1670 0 : memset(&req, 0, sizeof(req));
1671 0 : req.h_op = SANDESH_OP_ADD;
1672 0 : req.mr_rid = router_id;
1673 0 : req.mr_label = label;
1674 0 : req.mr_nhid = nh_index;
1675 :
1676 0 : return vr_sendmsg(cl, &req, "vr_mpls_req");
1677 : }
1678 :
1679 : char *
1680 7 : vr_nexthop_type_string(vr_nexthop_req *nh)
1681 : {
1682 7 : switch (nh->nhr_type) {
1683 0 : case NH_DEAD:
1684 0 : return "DEAD";
1685 : break;
1686 :
1687 0 : case NH_RCV:
1688 0 : return "RECEIVE";
1689 : break;
1690 :
1691 7 : case NH_ENCAP:
1692 7 : return "ENCAP";
1693 : break;
1694 :
1695 0 : case NH_TUNNEL:
1696 0 : return "TUNNEL";
1697 : break;
1698 :
1699 0 : case NH_RESOLVE:
1700 0 : return "RESOLVE";
1701 : break;
1702 :
1703 0 : case NH_DISCARD:
1704 0 : return "DISCARD";
1705 : break;
1706 :
1707 0 : case NH_COMPOSITE:
1708 0 : return "COMPOSITE";
1709 : break;
1710 :
1711 0 : case NH_VRF_TRANSLATE:
1712 0 : return "VRF_TRANSLATE";
1713 : break;
1714 :
1715 0 : case NH_L2_RCV:
1716 0 : return "L2_RECEIVE";
1717 : break;
1718 :
1719 0 : default:
1720 0 : return "NONE";
1721 : }
1722 :
1723 : return "NONE";
1724 : }
1725 :
1726 :
1727 : bool
1728 10 : vr_nexthop_req_has_vif(vr_nexthop_req *req)
1729 : {
1730 10 : switch (req->nhr_type) {
1731 2 : case NH_ENCAP:
1732 : case NH_TUNNEL:
1733 : case NH_RCV:
1734 : case NH_L2_RCV:
1735 2 : return true;
1736 : break;
1737 :
1738 8 : case NH_COMPOSITE:
1739 : default:
1740 8 : return false;
1741 : break;
1742 : }
1743 :
1744 : return false;
1745 : }
1746 :
1747 : void
1748 115 : vr_nexthop_req_destroy(vr_nexthop_req *req)
1749 : {
1750 115 : if (!req)
1751 100 : return;
1752 :
1753 15 : if (req->nhr_encap_size && req->nhr_encap) {
1754 7 : free(req->nhr_encap);
1755 7 : req->nhr_encap = NULL;
1756 7 : req->nhr_encap_size = 0;
1757 7 : req->nhr_encap_len = 0;
1758 : }
1759 :
1760 15 : if (req->nhr_nh_list_size && req->nhr_nh_list) {
1761 0 : free(req->nhr_nh_list);
1762 0 : req->nhr_nh_list = NULL;
1763 0 : req->nhr_nh_list_size = 0;
1764 : }
1765 :
1766 15 : if (req->nhr_label_list_size && req->nhr_label_list) {
1767 0 : free(req->nhr_label_list);
1768 0 : req->nhr_label_list = NULL;
1769 0 : req->nhr_label_list_size = 0;
1770 : }
1771 :
1772 15 : if (req->nhr_tun_sip6_size && req->nhr_tun_sip6) {
1773 0 : free(req->nhr_tun_sip6);
1774 0 : req->nhr_tun_sip6 = NULL;
1775 0 : req->nhr_tun_sip6_size = 0;
1776 : }
1777 :
1778 15 : if (req->nhr_tun_dip6_size && req->nhr_tun_dip6) {
1779 0 : free(req->nhr_tun_dip6);
1780 0 : req->nhr_tun_dip6 = NULL;
1781 0 : req->nhr_tun_dip6_size = 0;
1782 : }
1783 :
1784 15 : if (req->nhr_encap_oif_id_size && req->nhr_encap_oif_id) {
1785 15 : free(req->nhr_encap_oif_id);
1786 15 : req->nhr_encap_oif_id = NULL;
1787 15 : req->nhr_encap_oif_id_size = 0;
1788 : }
1789 :
1790 15 : if (req->nhr_encap_valid_size && req->nhr_encap_valid) {
1791 0 : free(req->nhr_encap_valid);
1792 0 : req->nhr_encap_valid = NULL;
1793 0 : req->nhr_encap_valid_size = 0;
1794 : }
1795 :
1796 15 : free(req);
1797 :
1798 15 : return;
1799 : }
1800 :
1801 : vr_nexthop_req *
1802 15 : vr_nexthop_req_get_copy(vr_nexthop_req *src)
1803 : {
1804 : vr_nexthop_req *dst;
1805 :
1806 15 : dst = calloc(sizeof(vr_nexthop_req), 1);
1807 15 : if (!dst)
1808 0 : return NULL;
1809 :
1810 : /* first copy the in-built members */
1811 15 : *dst = *src;
1812 :
1813 15 : dst->nhr_encap = NULL;
1814 15 : dst->nhr_encap_size = 0;
1815 15 : dst->nhr_nh_list = NULL;
1816 15 : dst->nhr_nh_list_size = 0;
1817 15 : dst->nhr_label_list = NULL;
1818 15 : dst->nhr_label_list_size = 0;
1819 15 : dst->nhr_tun_sip6 = NULL;
1820 15 : dst->nhr_tun_sip6_size = 0;
1821 15 : dst->nhr_tun_dip6 = NULL;
1822 15 : dst->nhr_tun_dip6_size = 0;
1823 15 : dst->nhr_encap_oif_id = NULL;
1824 15 : dst->nhr_encap_oif_id_size = 0;
1825 15 : dst->nhr_encap_valid = NULL;
1826 15 : dst->nhr_encap_valid_size = 0;
1827 :
1828 : /* ...and then the list elements */
1829 15 : if (src->nhr_encap_size && src->nhr_encap) {
1830 7 : dst->nhr_encap = malloc(src->nhr_encap_size);
1831 7 : if (!dst->nhr_encap)
1832 0 : goto free_nh;
1833 7 : memcpy(dst->nhr_encap, src->nhr_encap, src->nhr_encap_size);
1834 7 : dst->nhr_encap_size = src->nhr_encap_size;
1835 : }
1836 :
1837 : /* component nexthop list */
1838 15 : if (src->nhr_nh_list_size && src->nhr_nh_list) {
1839 0 : dst->nhr_nh_list = malloc(src->nhr_nh_list_size * sizeof(uint32_t));
1840 0 : if (!src->nhr_nh_list)
1841 0 : goto free_nh;
1842 0 : memcpy(dst->nhr_nh_list, src->nhr_nh_list,
1843 0 : src->nhr_nh_list_size * sizeof(uint32_t));
1844 0 : dst->nhr_nh_list_size = src->nhr_nh_list_size;
1845 : }
1846 :
1847 : /* label list */
1848 15 : if (src->nhr_label_list_size && src->nhr_label_list) {
1849 0 : dst->nhr_label_list = malloc(src->nhr_label_list_size * sizeof(uint32_t));
1850 0 : if (!src->nhr_label_list)
1851 0 : goto free_nh;
1852 0 : memcpy(dst->nhr_label_list, src->nhr_label_list,
1853 0 : src->nhr_label_list_size * sizeof(uint32_t));
1854 0 : dst->nhr_label_list_size = src->nhr_label_list_size;
1855 : }
1856 :
1857 : /* ipv6 tunnel source */
1858 15 : if (src->nhr_tun_sip6_size && src->nhr_tun_sip6) {
1859 0 : dst->nhr_tun_sip6 = malloc(src->nhr_tun_sip6_size);
1860 0 : if (!src->nhr_tun_sip6)
1861 0 : goto free_nh;
1862 0 : memcpy(dst->nhr_tun_sip6, src->nhr_tun_sip6, src->nhr_tun_sip6_size);
1863 0 : dst->nhr_tun_sip6_size = src->nhr_tun_sip6_size;
1864 : }
1865 :
1866 : /* ipv6 tunnel destination */
1867 15 : if (src->nhr_tun_dip6_size && src->nhr_tun_dip6) {
1868 0 : dst->nhr_tun_dip6 = malloc(src->nhr_tun_dip6_size);
1869 0 : if (!src->nhr_tun_dip6)
1870 0 : goto free_nh;
1871 0 : memcpy(dst->nhr_tun_dip6, src->nhr_tun_dip6, src->nhr_tun_dip6_size);
1872 0 : dst->nhr_tun_dip6_size = src->nhr_tun_dip6_size;
1873 : }
1874 :
1875 : /* encap oif id list */
1876 15 : if (src->nhr_encap_oif_id_size && src->nhr_encap_oif_id) {
1877 15 : dst->nhr_encap_oif_id = malloc(src->nhr_encap_oif_id_size * sizeof(int32_t));
1878 15 : if (!src->nhr_encap_oif_id)
1879 0 : goto free_nh;
1880 15 : memcpy(dst->nhr_encap_oif_id, src->nhr_encap_oif_id,
1881 15 : src->nhr_encap_oif_id_size * sizeof(int32_t));
1882 15 : dst->nhr_encap_oif_id_size = src->nhr_encap_oif_id_size;
1883 : }
1884 :
1885 : /* encap valid list */
1886 15 : if (src->nhr_encap_valid_size && src->nhr_encap_valid &&
1887 0 : (src->nhr_flags & NH_FLAG_TUNNEL_UNDERLAY_ECMP)) {
1888 0 : dst->nhr_encap_valid = malloc(src->nhr_encap_valid_size * sizeof(int32_t));
1889 0 : if (!src->nhr_encap_valid)
1890 0 : goto free_nh;
1891 0 : memcpy(dst->nhr_encap_valid, src->nhr_encap_valid,
1892 0 : src->nhr_encap_valid_size * sizeof(int32_t));
1893 0 : dst->nhr_encap_valid_size = src->nhr_encap_valid_size;
1894 : }
1895 :
1896 15 : return dst;
1897 :
1898 0 : free_nh:
1899 0 : vr_nexthop_req_destroy(dst);
1900 0 : return NULL;
1901 : }
1902 :
1903 : int
1904 0 : vr_send_nexthop_delete(struct nl_client *cl, unsigned int router_id,
1905 : unsigned int nh_index)
1906 : {
1907 : vr_nexthop_req req;
1908 :
1909 0 : memset(&req, 0, sizeof(req));
1910 0 : req.h_op = SANDESH_OP_DEL;
1911 0 : req.nhr_rid = router_id;
1912 0 : req.nhr_id = nh_index;
1913 :
1914 0 : return vr_sendmsg(cl, &req, "vr_nexthop_req");
1915 : }
1916 :
1917 : int
1918 0 : vr_send_nexthop_dump(struct nl_client *cl, unsigned int router_id,
1919 : int marker)
1920 : {
1921 : vr_nexthop_req req;
1922 :
1923 0 : memset(&req, 0, sizeof(req));
1924 0 : req.h_op = SANDESH_OP_DUMP;
1925 0 : req.nhr_rid = router_id;
1926 0 : req.nhr_marker = marker;
1927 :
1928 0 : return vr_sendmsg(cl, &req, "vr_nexthop_req");
1929 : }
1930 :
1931 : int
1932 19 : vr_send_nexthop_get(struct nl_client *cl, unsigned int router_id,
1933 : unsigned int nh_index)
1934 : {
1935 : vr_nexthop_req req;
1936 :
1937 19 : memset(&req, 0, sizeof(req));
1938 19 : req.h_op = SANDESH_OP_GET;
1939 19 : req.nhr_rid = router_id;
1940 19 : req.nhr_id = nh_index;
1941 :
1942 19 : return vr_sendmsg(cl, &req, "vr_nexthop_req");
1943 : }
1944 :
1945 : int
1946 0 : vr_send_pbb_tunnel_add(struct nl_client *cl, unsigned int router_id, int
1947 : nh_index, unsigned int flags, int vrf_index, int8_t *bmac,
1948 : unsigned int direct_nh_id, unsigned int direct_label)
1949 : {
1950 0 : int ret = 0;
1951 : unsigned int i;
1952 : vr_nexthop_req req;
1953 :
1954 0 : memset(&req, 0, sizeof(req));
1955 0 : req.h_op = SANDESH_OP_ADD;
1956 0 : req.nhr_rid = router_id;
1957 0 : req.nhr_vrf = vrf_index;
1958 0 : req.nhr_id = nh_index;
1959 0 : req.nhr_flags = flags;
1960 0 : req.nhr_type = NH_TUNNEL;
1961 :
1962 0 : req.nhr_encap_oif_id_size = 1;
1963 0 : req.nhr_encap_oif_id = calloc(req.nhr_encap_oif_id_size, sizeof(unsigned int));
1964 0 : if (!req.nhr_encap_oif_id) {
1965 0 : ret = -ENOMEM;
1966 0 : goto fail;
1967 : }
1968 0 : req.nhr_encap_oif_id[0] = 0;
1969 :
1970 0 : req.nhr_nh_list_size = 1;
1971 0 : req.nhr_nh_list = calloc(1, sizeof(uint32_t));
1972 0 : if (!req.nhr_nh_list) {
1973 0 : ret = -ENOMEM;
1974 0 : goto fail;
1975 : }
1976 :
1977 0 : req.nhr_label_list = calloc(1, sizeof(uint32_t));
1978 0 : if (!req.nhr_label_list) {
1979 0 : ret = -ENOMEM;
1980 0 : goto fail;
1981 : }
1982 :
1983 0 : req.nhr_pbb_mac_size = VR_ETHER_ALEN;
1984 0 : req.nhr_pbb_mac = calloc(VR_ETHER_ALEN, sizeof(uint8_t));
1985 0 : if (!req.nhr_pbb_mac) {
1986 0 : ret = -ENOMEM;
1987 0 : goto fail;
1988 : }
1989 0 : VR_MAC_COPY(req.nhr_pbb_mac, bmac);
1990 :
1991 0 : req.nhr_label_list_size = 1;
1992 0 : req.nhr_nh_list[0] = direct_nh_id;
1993 0 : req.nhr_label_list[0] = direct_label;
1994 0 : req.nhr_family = AF_BRIDGE;
1995 :
1996 0 : ret = vr_sendmsg(cl, &req, "vr_nexthop_req");
1997 0 : fail:
1998 0 : if (req.nhr_nh_list) {
1999 0 : free(req.nhr_nh_list);
2000 0 : req.nhr_nh_list = NULL;
2001 : }
2002 :
2003 0 : if (req.nhr_label_list) {
2004 0 : free(req.nhr_label_list);
2005 0 : req.nhr_label_list = NULL;
2006 : }
2007 :
2008 0 : return ret;
2009 : }
2010 :
2011 : int
2012 0 : vr_send_nexthop_composite_add(struct nl_client *cl, unsigned int router_id,
2013 : int nh_index, unsigned int flags, int vrf_index,
2014 : unsigned int num_components, unsigned int *component_nh_indices,
2015 : unsigned int *component_labels, unsigned int family)
2016 : {
2017 0 : int ret = 0;
2018 : unsigned int i;
2019 : vr_nexthop_req req;
2020 :
2021 0 : memset(&req, 0, sizeof(req));
2022 0 : req.h_op = SANDESH_OP_ADD;
2023 0 : req.nhr_rid = router_id;
2024 0 : req.nhr_vrf = vrf_index;
2025 0 : req.nhr_id = nh_index;
2026 0 : req.nhr_flags = flags;
2027 0 : req.nhr_type = NH_COMPOSITE;
2028 :
2029 0 : req.nhr_nh_list_size = num_components;
2030 0 : req.nhr_nh_list = calloc(num_components, sizeof(uint32_t));
2031 0 : if (!req.nhr_nh_list) {
2032 0 : ret = -ENOMEM;
2033 0 : goto fail;
2034 : }
2035 :
2036 0 : req.nhr_label_list = calloc(num_components, sizeof(uint32_t));
2037 0 : if (!req.nhr_label_list) {
2038 0 : ret = -ENOMEM;
2039 0 : goto fail;
2040 : }
2041 :
2042 0 : req.nhr_label_list_size = num_components;
2043 0 : for (i = 0; i < num_components; i++) {
2044 0 : req.nhr_nh_list[i] = component_nh_indices[i];
2045 0 : req.nhr_label_list[i] = component_labels[i];
2046 : }
2047 :
2048 :
2049 0 : req.nhr_family = family;
2050 :
2051 0 : ret = vr_sendmsg(cl, &req, "vr_nexthop_req");
2052 0 : fail:
2053 0 : if (req.nhr_nh_list) {
2054 0 : free(req.nhr_nh_list);
2055 0 : req.nhr_nh_list = NULL;
2056 : }
2057 :
2058 0 : if (req.nhr_label_list) {
2059 0 : free(req.nhr_label_list);
2060 0 : req.nhr_label_list = NULL;
2061 : }
2062 :
2063 0 : return ret;
2064 : }
2065 :
2066 :
2067 : int
2068 0 : vr_send_nexthop_encap_tunnel_add(struct nl_client *cl, unsigned int router_id,
2069 : unsigned int type, int nh_index, unsigned int flags, int vrf_index,
2070 : int *vif_index, int8_t smac[][6], int8_t dmac[][6], struct in_addr sip,
2071 : struct in_addr dip, int sport, int dport, int8_t *l3_vxlan_mac, int family,
2072 : int count)
2073 : {
2074 : vr_nexthop_req req;
2075 : int i;
2076 :
2077 0 : memset(&req, 0, sizeof(req));
2078 :
2079 0 : req.h_op = SANDESH_OP_ADD;
2080 0 : req.nhr_rid = router_id;
2081 0 : req.nhr_vrf = vrf_index;
2082 0 : req.nhr_id = nh_index;
2083 0 : req.nhr_flags = flags;
2084 0 : req.nhr_type = type;
2085 0 : if (req.nhr_flags & NH_FLAG_TUNNEL_UNDERLAY_ECMP) {
2086 0 : req.nhr_encap_oif_id_size = VR_MAX_PHY_INF;
2087 0 : req.nhr_encap_valid_size = VR_MAX_PHY_INF;
2088 0 : req.nhr_encap_valid = malloc(req.nhr_encap_valid_size * sizeof(unsigned int));
2089 : } else {
2090 0 : req.nhr_encap_oif_id_size = 1;
2091 0 : req.nhr_encap_valid_size = 0;
2092 0 : req.nhr_encap_valid = NULL;
2093 : }
2094 0 : req.nhr_encap_oif_id = malloc(req.nhr_encap_oif_id_size * sizeof(unsigned int));
2095 0 : if (flags & NH_FLAG_TUNNEL_UNDERLAY_ECMP) {
2096 0 : for (i = 0; i < VR_MAX_PHY_INF; i++) {
2097 0 : if (vif_index[i] < 0)
2098 0 : req.nhr_encap_valid[i] = 0;
2099 : else
2100 0 : req.nhr_encap_valid[i] = 1;
2101 0 : req.nhr_encap_oif_id[i] = vif_index[i];
2102 : }
2103 : }
2104 : else
2105 0 : req.nhr_encap_oif_id[0] = vif_index[0];
2106 0 : if (count)
2107 0 : req.nhr_encap_len = 14;
2108 0 : req.nhr_encap_size = 14 * count;
2109 0 : req.nhr_encap = malloc(req.nhr_encap_size);
2110 0 : if (!req.nhr_encap)
2111 0 : return -ENOMEM;
2112 0 : for (i = 0; i < count; i++) {
2113 0 : memcpy(req.nhr_encap + i*14, dmac, 6);
2114 0 : memcpy(req.nhr_encap + i*14 + 6, smac, 6);
2115 0 : *(uint16_t *)(&req.nhr_encap[12 + i*14]) = htons(0x0800);
2116 : }
2117 :
2118 : #if defined(__linux__)
2119 0 : req.nhr_encap_family = ETH_P_ARP;
2120 : #endif
2121 :
2122 0 : if (type == NH_TUNNEL) {
2123 0 : req.nhr_tun_sip = sip.s_addr;
2124 0 : req.nhr_tun_dip = dip.s_addr;
2125 0 : if ((sport >= 0) && (dport >= 0)) {
2126 0 : req.nhr_tun_sport = htons(sport);
2127 0 : req.nhr_tun_dport = htons(dport);
2128 : }
2129 0 : if (flags & NH_FLAG_L3_VXLAN) {
2130 0 : req.nhr_rw_dst_mac_size = 6;
2131 0 : req.nhr_rw_dst_mac = malloc(req.nhr_rw_dst_mac_size);
2132 0 : memcpy(req.nhr_rw_dst_mac, l3_vxlan_mac, 6);
2133 : }
2134 : }
2135 :
2136 0 : if (type == NH_ENCAP)
2137 0 : req.nhr_family = family;
2138 :
2139 0 : return vr_sendmsg(cl, &req, "vr_nexthop_req");
2140 : }
2141 :
2142 : int
2143 0 : vr_send_nexthop_add(struct nl_client *cl, unsigned int router_id,
2144 : unsigned int type, int nh_index, unsigned int flags, int vrf_index,
2145 : int *vif_index, int family)
2146 : {
2147 : vr_nexthop_req req;
2148 :
2149 0 : memset(&req, 0, sizeof(req));
2150 :
2151 0 : req.h_op = SANDESH_OP_ADD;
2152 0 : req.nhr_rid = router_id;
2153 0 : req.nhr_vrf = vrf_index;
2154 0 : req.nhr_id = nh_index;
2155 0 : req.nhr_flags = flags;
2156 0 : req.nhr_type = type;
2157 0 : req.nhr_family = family;
2158 0 : req.nhr_encap_oif_id_size = 1;
2159 0 : req.nhr_encap_valid_size = 0;
2160 0 : req.nhr_encap_valid = NULL;
2161 0 : req.nhr_encap_oif_id = malloc(req.nhr_encap_oif_id_size * sizeof(unsigned int));
2162 0 : req.nhr_encap_len = 14;
2163 0 : req.nhr_encap_oif_id[0] = vif_index[0];
2164 :
2165 0 : return vr_sendmsg(cl, &req, "vr_nexthop_req");
2166 : }
2167 :
2168 : void
2169 20 : vr_route_req_destroy(vr_route_req *req)
2170 : {
2171 20 : if (!req)
2172 10 : return;
2173 :
2174 10 : if (req->rtr_prefix_size && req->rtr_prefix) {
2175 0 : free(req->rtr_prefix);
2176 0 : req->rtr_prefix = NULL;
2177 0 : req->rtr_prefix_size = 0;
2178 : }
2179 :
2180 10 : if (req->rtr_mac_size && req->rtr_mac) {
2181 0 : free(req->rtr_mac);
2182 0 : req->rtr_mac = NULL;
2183 0 : req->rtr_mac_size = 0;
2184 : }
2185 :
2186 10 : free(req);
2187 10 : return;
2188 : }
2189 :
2190 : void
2191 10 : address_mask(uint8_t *addr, uint8_t plen, unsigned int family)
2192 : {
2193 : int i;
2194 : uint8_t address_bits;
2195 : uint8_t mask[VR_IP6_ADDRESS_LEN];
2196 :
2197 10 : if (family == AF_INET) {
2198 10 : address_bits = VR_IP_ADDRESS_LEN * 8;
2199 : } else {
2200 0 : address_bits = VR_IP6_ADDRESS_LEN * 8;
2201 : }
2202 :
2203 10 : memset(mask, 0xFF, sizeof(mask));
2204 74 : for (i = address_bits - 1; i >= plen; i--) {
2205 64 : mask[i / 8] ^= (1 << (7 - (i % 8)));
2206 : }
2207 :
2208 50 : for (i = 0; i < (address_bits / 8); i++) {
2209 40 : addr[i] &= mask[i];
2210 : }
2211 :
2212 10 : return;
2213 : }
2214 :
2215 : vr_route_req *
2216 10 : vr_route_req_get_copy(vr_route_req *src)
2217 : {
2218 : vr_route_req *dst;
2219 :
2220 10 : dst = malloc(sizeof(*dst));
2221 10 : if (!dst)
2222 0 : return NULL;
2223 :
2224 10 : *dst = *src;
2225 :
2226 10 : dst->rtr_prefix_size = 0;
2227 10 : dst->rtr_prefix = NULL;
2228 :
2229 10 : dst->rtr_marker_size = 0;
2230 10 : dst->rtr_marker = NULL;
2231 :
2232 10 : dst->rtr_mac_size = 0;
2233 10 : dst->rtr_mac = NULL;
2234 :
2235 10 : if (src->rtr_prefix_size && src->rtr_prefix) {
2236 10 : dst->rtr_prefix = malloc(src->rtr_prefix_size);
2237 10 : if (!dst->rtr_prefix)
2238 0 : goto free_rtr_req;
2239 10 : memcpy(dst->rtr_prefix, src->rtr_prefix, src->rtr_prefix_size);
2240 : }
2241 :
2242 10 : if (src->rtr_mac_size && src->rtr_mac) {
2243 6 : dst->rtr_mac = malloc(src->rtr_mac_size);
2244 6 : if (!dst->rtr_mac)
2245 0 : goto free_rtr_req;
2246 6 : memcpy(dst->rtr_mac, src->rtr_mac, src->rtr_mac_size);
2247 : }
2248 :
2249 10 : return dst;
2250 :
2251 0 : free_rtr_req:
2252 0 : vr_route_req_destroy(dst);
2253 0 : return NULL;
2254 : }
2255 :
2256 : int
2257 0 : vr_send_route_dump(struct nl_client *cl, unsigned int router_id, unsigned int vrf,
2258 : unsigned int family, uint8_t *marker)
2259 : {
2260 : vr_route_req req;
2261 :
2262 0 : memset(&req, 0, sizeof(req));
2263 0 : req.h_op = SANDESH_OP_DUMP;
2264 0 : req.rtr_rid = router_id;
2265 0 : req.rtr_vrf_id = vrf;
2266 0 : req.rtr_family = family;
2267 :
2268 0 : if (family == AF_BRIDGE) {
2269 0 : req.rtr_mac = marker;
2270 0 : req.rtr_mac_size = VR_ETHER_ALEN;
2271 : } else {
2272 0 : req.rtr_prefix = marker;
2273 0 : req.rtr_prefix_size = RT_IP_ADDR_SIZE(family);
2274 0 : req.rtr_marker = marker;
2275 0 : req.rtr_marker_size = RT_IP_ADDR_SIZE(family);
2276 : }
2277 :
2278 0 : return vr_sendmsg(cl, &req, "vr_route_req");
2279 : }
2280 :
2281 : static int
2282 10 : vr_send_route_common(struct nl_client *cl, unsigned int op,
2283 : unsigned int router_id, unsigned int vrf, unsigned int family,
2284 : uint8_t *prefix, unsigned int prefix_len, unsigned int nh_index,
2285 : int label, uint8_t *mac, uint32_t replace_len, unsigned int flags)
2286 : {
2287 : vr_route_req req;
2288 :
2289 10 : memset(&req, 0, sizeof(req));
2290 10 : req.h_op = op;
2291 10 : req.rtr_rid = router_id;
2292 10 : req.rtr_vrf_id = vrf;
2293 10 : req.rtr_family = family;
2294 :
2295 10 : if ((family == AF_INET) || (family == AF_INET6)) {
2296 10 : req.rtr_prefix = prefix;
2297 10 : req.rtr_prefix_size = RT_IP_ADDR_SIZE(family);
2298 10 : req.rtr_prefix_len = prefix_len;
2299 0 : } else if (family == AF_BRIDGE) {
2300 0 : req.rtr_index = VR_BE_INVALID_INDEX;
2301 : }
2302 :
2303 10 : if (mac) {
2304 10 : req.rtr_mac = mac;
2305 10 : req.rtr_mac_size = VR_ETHER_ALEN;
2306 : }
2307 :
2308 10 : req.rtr_replace_plen = replace_len;
2309 10 : req.rtr_label_flags = flags;
2310 10 : req.rtr_label = label;
2311 10 : if (label != -1)
2312 10 : req.rtr_label_flags |= VR_RT_LABEL_VALID_FLAG;
2313 :
2314 10 : req.rtr_nh_id = nh_index;
2315 :
2316 10 : return vr_sendmsg(cl, &req, "vr_route_req");
2317 : }
2318 :
2319 : int
2320 10 : vr_send_route_get(struct nl_client *cl,
2321 : unsigned int router_id, unsigned int vrf, unsigned int family,
2322 : uint8_t *prefix, unsigned int prefix_len, uint8_t *mac)
2323 : {
2324 10 : return vr_send_route_common(cl, SANDESH_OP_GET, router_id, vrf,
2325 : family, prefix, prefix_len, 0, 0, mac, 0, 0);
2326 : }
2327 :
2328 : int
2329 0 : vr_send_route_delete(struct nl_client *cl,
2330 : unsigned int router_id, unsigned int vrf, unsigned int family,
2331 : uint8_t *prefix, unsigned int prefix_len, unsigned int nh_index,
2332 : int label, uint8_t *mac, uint32_t replace_len, unsigned int flags)
2333 : {
2334 0 : return vr_send_route_common(cl, SANDESH_OP_DEL, router_id, vrf,
2335 : family, prefix, prefix_len, nh_index, label,
2336 : mac, replace_len, flags);
2337 : }
2338 :
2339 : int
2340 0 : vr_send_route_add(struct nl_client *cl,
2341 : unsigned int router_id, unsigned int vrf, unsigned int family,
2342 : uint8_t *prefix, unsigned int prefix_len, unsigned int nh_index,
2343 : int label, uint8_t *mac, uint32_t replace_len, unsigned int flags)
2344 : {
2345 0 : return vr_send_route_common(cl, SANDESH_OP_ADD, router_id, vrf,
2346 : family, prefix, prefix_len, nh_index, label,
2347 : mac, replace_len,flags);
2348 : }
2349 :
2350 : /* vrf assign start */
2351 : int
2352 0 : vr_send_vrf_assign_dump(struct nl_client *cl, unsigned int router_id,
2353 : unsigned int vif_index, int marker)
2354 : {
2355 : vr_vrf_assign_req req;
2356 :
2357 0 : memset(&req, 0, sizeof(req));
2358 0 : req.h_op = SANDESH_OP_DUMP;
2359 0 : req.var_rid = router_id;
2360 0 : req.var_vif_index = vif_index;
2361 0 : req.var_marker = marker;
2362 :
2363 0 : return vr_sendmsg(cl, &req, "vr_vrf_assign_req");
2364 : }
2365 :
2366 : int
2367 0 : vr_send_vrf_assign_set(struct nl_client *cl, unsigned int router_id,
2368 : unsigned int vif_index, unsigned int vlan_id, unsigned int vrf_id)
2369 : {
2370 :
2371 : vr_vrf_assign_req req;
2372 :
2373 0 : memset(&req, 0, sizeof(req));
2374 0 : req.h_op = SANDESH_OP_ADD;
2375 0 : req.var_rid = router_id;
2376 0 : req.var_vif_index = vif_index;
2377 0 : req.var_vif_vrf = vrf_id;
2378 0 : req.var_vlan_id = vlan_id;
2379 :
2380 0 : return vr_sendmsg(cl, &req, "vr_vrf_assign_req");
2381 : }
2382 : /* vrf assign end */
2383 :
2384 : int
2385 0 : vr_send_vrf_stats_dump(struct nl_client *cl, unsigned int router_id, int marker)
2386 : {
2387 : vr_vrf_stats_req req;
2388 :
2389 0 : memset(&req, 0, sizeof(req));
2390 0 : req.h_op = SANDESH_OP_DUMP;
2391 0 : req.vsr_rid = router_id;
2392 0 : req.vsr_marker = marker;
2393 0 : req.vsr_family = AF_INET;
2394 :
2395 0 : return vr_sendmsg(cl, &req, "vr_vrf_stats_req");
2396 : }
2397 :
2398 : int
2399 0 : vr_send_vrf_stats_get(struct nl_client *cl, unsigned int router_id,
2400 : unsigned int vrf)
2401 : {
2402 : vr_vrf_stats_req req;
2403 :
2404 0 : memset(&req, 0, sizeof(req));
2405 0 : req.h_op = SANDESH_OP_GET;
2406 0 : req.vsr_rid = router_id;
2407 0 : req.vsr_vrf = vrf;
2408 0 : req.vsr_family = AF_INET;
2409 :
2410 0 : return vr_sendmsg(cl, &req, "vr_vrf_stats_req");
2411 : }
2412 :
2413 : int
2414 0 : vr_send_vrouter_get(struct nl_client *cl, unsigned int router_id)
2415 : {
2416 : vrouter_ops req;
2417 :
2418 0 : memset(&req, 0, sizeof(req));
2419 0 : req.h_op = SANDESH_OP_GET;
2420 :
2421 0 : return vr_sendmsg(cl, &req, "vrouter_ops");
2422 : }
2423 :
2424 : int
2425 0 : vr_send_vrouter_set_logging(struct nl_client *cl, unsigned int router_id,
2426 : unsigned int log_level, unsigned int *e_log_types, unsigned int e_size,
2427 : unsigned int *d_log_types, unsigned int d_size)
2428 : {
2429 : vrouter_ops req;
2430 :
2431 0 : memset(&req, 0, sizeof(req));
2432 0 : req.h_op = SANDESH_OP_ADD;
2433 :
2434 0 : if (log_level > 0)
2435 0 : req.vo_log_level = log_level;
2436 :
2437 0 : if (e_log_types && e_size) {
2438 0 : req.vo_log_type_enable_size = e_size;
2439 0 : req.vo_log_type_enable = e_log_types;
2440 : }
2441 :
2442 0 : if (d_log_types && d_size) {
2443 0 : req.vo_log_type_disable_size = d_size;
2444 0 : req.vo_log_type_disable = d_log_types;
2445 : }
2446 :
2447 : /*
2448 : * We create request to change logging options only. As we do not change
2449 : * vRouter's runtime parameters here, they need to be set to a meaningless
2450 : * value. They cannot be left zeroed, because 0 means 'feature turned off'.
2451 : */
2452 0 : req.vo_perfr = -1;
2453 0 : req.vo_perfs = -1;
2454 0 : req.vo_from_vm_mss_adj = -1;
2455 0 : req.vo_to_vm_mss_adj = -1;
2456 0 : req.vo_perfr1 = -1;
2457 0 : req.vo_perfr2 = -1;
2458 0 : req.vo_perfr3 = -1;
2459 0 : req.vo_perfp = -1;
2460 0 : req.vo_perfq1 = -1;
2461 0 : req.vo_perfq2 = -1;
2462 0 : req.vo_perfq3 = -1;
2463 0 : req.vo_udp_coff = -1;
2464 0 : req.vo_flow_hold_limit = -1;
2465 0 : req.vo_mudp = -1;
2466 0 : req.vo_packet_dump = -1;
2467 :
2468 0 : return vr_sendmsg(cl, &req, "vrouter_ops");
2469 : }
2470 :
2471 : int
2472 0 : vr_send_vrouter_set_runtime_opts(struct nl_client *cl, unsigned int router_id,
2473 : int perfr, int perfs, int from_vm_mss_adj, int to_vm_mss_adj,
2474 : int perfr1, int perfr2, int perfr3, int perfp, int perfq1,
2475 : int perfq2, int perfq3, int udp_coff, int flow_hold_limit,
2476 : int mudp, int btokens, int binterval, int bstep,
2477 : unsigned int priority_tagging, int packet_dump)
2478 : {
2479 : vrouter_ops req;
2480 :
2481 0 : memset(&req, 0, sizeof(req));
2482 0 : req.h_op = SANDESH_OP_ADD;
2483 :
2484 : /*
2485 : * vRouter runtime options. Adjustable by sysctl as well.
2486 : *
2487 : * No real validation is required, as sysctl does not perform any.
2488 : * Variables are only tested to be -1 ('do not change'),
2489 : * 0 ('feature turned off'), or non-zero ('feature turned on').
2490 : */
2491 0 : req.vo_perfr = perfr;
2492 0 : req.vo_perfs = perfs;
2493 0 : req.vo_from_vm_mss_adj = from_vm_mss_adj;
2494 0 : req.vo_to_vm_mss_adj = to_vm_mss_adj;
2495 0 : req.vo_perfr1 = perfr1;
2496 0 : req.vo_perfr2 = perfr2;
2497 0 : req.vo_perfr3 = perfr3;
2498 0 : req.vo_perfp = perfp;
2499 0 : req.vo_perfq1 = perfq1;
2500 0 : req.vo_perfq2 = perfq2;
2501 0 : req.vo_perfq3 = perfq3;
2502 0 : req.vo_udp_coff = udp_coff;
2503 0 : req.vo_flow_hold_limit = flow_hold_limit;
2504 0 : req.vo_mudp = mudp;
2505 0 : req.vo_burst_tokens = btokens;
2506 0 : req.vo_burst_interval = binterval;
2507 0 : req.vo_burst_step = bstep;
2508 0 : req.vo_priority_tagging = priority_tagging;
2509 0 : req.vo_packet_dump = packet_dump;
2510 :
2511 : /*
2512 : * We create request to change runtime (sysctl) options only. Log level
2513 : * fields can be left zeroed, because only non-zero values are meaningful
2514 : * in this case.
2515 : */
2516 :
2517 0 : return vr_sendmsg(cl, &req, "vrouter_ops");
2518 : }
2519 :
2520 : int
2521 0 : vr_send_vxlan_delete(struct nl_client *cl, unsigned int router_id,
2522 : unsigned int vnid)
2523 : {
2524 : vr_vxlan_req req;
2525 :
2526 0 : memset(&req, 0, sizeof(req));
2527 0 : req.h_op = SANDESH_OP_DEL;
2528 0 : req.vxlanr_vnid = vnid;
2529 :
2530 0 : return vr_sendmsg(cl, &req, "vr_vxlan_req");
2531 : }
2532 :
2533 : int
2534 0 : vr_send_vxlan_dump(struct nl_client *cl, unsigned int router_id,
2535 : int marker)
2536 : {
2537 : vr_vxlan_req req;
2538 :
2539 0 : memset(&req, 0, sizeof(req));
2540 0 : req.h_op = SANDESH_OP_DUMP;
2541 0 : req.vxlanr_vnid = marker;
2542 :
2543 0 : return vr_sendmsg(cl, &req, "vr_vxlan_req");
2544 : }
2545 :
2546 : int
2547 0 : vr_send_vxlan_get(struct nl_client *cl, unsigned int router_id,
2548 : unsigned int vnid)
2549 : {
2550 : vr_vxlan_req req;
2551 :
2552 0 : memset(&req, 0, sizeof(req));
2553 0 : req.h_op = SANDESH_OP_GET;
2554 0 : req.vxlanr_vnid = vnid;
2555 :
2556 0 : return vr_sendmsg(cl, &req, "vr_vxlan_req");
2557 : }
2558 :
2559 : int
2560 0 : vr_send_vxlan_add(struct nl_client *cl, unsigned int router_id,
2561 : unsigned int vnid, unsigned int nh_index)
2562 : {
2563 : vr_vxlan_req req;
2564 :
2565 0 : memset(&req, 0, sizeof(req));
2566 0 : req.h_op = SANDESH_OP_ADD;
2567 0 : req.vxlanr_vnid = vnid;
2568 0 : req.vxlanr_nhid = nh_index;
2569 :
2570 0 : return vr_sendmsg(cl, &req, "vr_vxlan_req");
2571 : }
2572 :
2573 : int
2574 0 : vr_send_fc_map_get(struct nl_client *cl, unsigned int router_id,
2575 : uint8_t fc_map_id)
2576 : {
2577 : vr_fc_map_req req;
2578 0 : int16_t id = fc_map_id;
2579 :
2580 0 : memset(&req, 0, sizeof(req));
2581 0 : req.h_op = SANDESH_OP_GET;
2582 0 : req.fmr_rid = router_id;
2583 0 : req.fmr_id = &id;
2584 0 : req.fmr_id_size = 1;
2585 :
2586 0 : return vr_sendmsg(cl, &req, "vr_fc_map_req");
2587 : }
2588 :
2589 : int
2590 0 : vr_send_fc_map_dump(struct nl_client *cl, unsigned int router_id,
2591 : int marker)
2592 : {
2593 : vr_fc_map_req req;
2594 :
2595 0 : memset(&req, 0, sizeof(req));
2596 0 : req.h_op = SANDESH_OP_DUMP;
2597 0 : req.fmr_rid = router_id;
2598 0 : req.fmr_marker = marker;
2599 :
2600 0 : return vr_sendmsg(cl, &req, "vr_fc_map_req");
2601 : }
2602 :
2603 : int
2604 0 : vr_send_fc_map_delete(struct nl_client *cl, unsigned int router_id,
2605 : uint8_t fc_id)
2606 : {
2607 : vr_fc_map_req req;
2608 0 : int16_t id = fc_id;
2609 :
2610 0 : memset(&req, 0, sizeof(req));
2611 0 : req.h_op = SANDESH_OP_DEL;
2612 0 : req.fmr_rid = router_id;
2613 0 : req.fmr_id = &id;
2614 0 : req.fmr_id_size = 1;
2615 :
2616 0 : return vr_sendmsg(cl, &req, "vr_fc_map_req");
2617 : }
2618 :
2619 : int
2620 0 : vr_send_fc_map_add(struct nl_client *cl, unsigned int router_id,
2621 : int16_t *fc_id, uint8_t fc_id_size,
2622 : uint8_t *dscp, uint8_t *mpls_qos, uint8_t *dotonep, uint8_t *queue)
2623 : {
2624 : vr_fc_map_req req;
2625 :
2626 0 : memset(&req, 0, sizeof(req));
2627 0 : req.fmr_rid = router_id;
2628 :
2629 0 : req.fmr_id = fc_id;
2630 0 : req.fmr_id_size = fc_id_size;
2631 0 : req.fmr_dscp = dscp;
2632 0 : req.fmr_dscp_size = fc_id_size;
2633 0 : req.fmr_mpls_qos = mpls_qos;
2634 0 : req.fmr_mpls_qos_size = fc_id_size;
2635 0 : req.fmr_dotonep = dotonep;
2636 0 : req.fmr_dotonep_size = fc_id_size;
2637 0 : req.fmr_queue_id = queue;
2638 0 : req.fmr_queue_id_size = fc_id_size;
2639 :
2640 0 : return vr_sendmsg(cl, &req, "vr_fc_map_req");
2641 : }
2642 :
2643 : int
2644 0 : vr_send_qos_map_get(struct nl_client *cl, unsigned int router_id,
2645 : unsigned int qos_map_id)
2646 : {
2647 : vr_qos_map_req req;
2648 :
2649 0 : memset(&req, 0, sizeof(req));
2650 0 : req.h_op = SANDESH_OP_GET;
2651 0 : req.qmr_rid = router_id;
2652 0 : req.qmr_id = qos_map_id;
2653 :
2654 0 : return vr_sendmsg(cl, &req, "vr_qos_map_req");
2655 : }
2656 :
2657 :
2658 : int
2659 0 : vr_send_qos_map_dump(struct nl_client *cl, unsigned int router_id,
2660 : int marker)
2661 : {
2662 : vr_qos_map_req req;
2663 :
2664 0 : memset(&req, 0, sizeof(req));
2665 0 : req.h_op = SANDESH_OP_DUMP;
2666 0 : req.qmr_rid = router_id;
2667 0 : req.qmr_marker = marker;
2668 :
2669 0 : return vr_sendmsg(cl, &req, "vr_qos_map_req");
2670 : }
2671 :
2672 : int
2673 0 : vr_send_qos_map_delete(struct nl_client *cl, unsigned int router_id,
2674 : unsigned int qos_map_id)
2675 : {
2676 : vr_qos_map_req req;
2677 :
2678 0 : memset(&req, 0, sizeof(req));
2679 0 : req.h_op = SANDESH_OP_DEL;
2680 0 : req.qmr_rid = router_id;
2681 0 : req.qmr_id = qos_map_id;
2682 :
2683 0 : return vr_sendmsg(cl, &req, "vr_qos_map_req");
2684 : }
2685 :
2686 : int
2687 0 : vr_send_qos_map_add(struct nl_client *cl, unsigned int router_id,
2688 : unsigned int qos_id,
2689 : uint8_t *dscp, uint8_t num_dscp, uint8_t *dscp_fc_id,
2690 : uint8_t *mpls_qos, uint8_t num_mpls_qos, uint8_t *mpls_qos_fc_id,
2691 : uint8_t *dotonep, uint8_t num_dotonep, uint8_t *dotonep_fc_id)
2692 : {
2693 : vr_qos_map_req req;
2694 :
2695 0 : memset(&req, 0, sizeof(req));
2696 0 : req.h_op = SANDESH_OP_ADD;
2697 0 : req.qmr_rid = router_id;
2698 0 : req.qmr_id = qos_id;
2699 :
2700 0 : if (num_dscp) {
2701 0 : req.qmr_dscp = dscp;
2702 0 : req.qmr_dscp_size = num_dscp;
2703 0 : req.qmr_dscp_fc_id = dscp_fc_id;
2704 0 : req.qmr_dscp_fc_id_size = num_dscp;
2705 : }
2706 :
2707 0 : if (num_mpls_qos) {
2708 0 : req.qmr_mpls_qos = mpls_qos;
2709 0 : req.qmr_mpls_qos_size = num_mpls_qos;
2710 0 : req.qmr_mpls_qos_fc_id = mpls_qos_fc_id;
2711 0 : req.qmr_mpls_qos_fc_id_size = num_mpls_qos;
2712 : }
2713 :
2714 0 : if (num_dotonep) {
2715 0 : req.qmr_dotonep = dotonep;
2716 0 : req.qmr_dotonep_size = num_dotonep;
2717 0 : req.qmr_dotonep_fc_id = dotonep_fc_id;
2718 0 : req.qmr_dotonep_fc_id_size = num_dotonep;
2719 : }
2720 :
2721 0 : return vr_sendmsg(cl, &req, "vr_qos_map_req");
2722 : }
2723 :
2724 : int
2725 0 : vr_send_ddp_req(struct nl_client *cl, vr_info_msg_en msginfo, uint8_t *vr_info_inbuf)
2726 : {
2727 : vr_info_req req;
2728 :
2729 0 : memset(&req, 0, sizeof(req));
2730 :
2731 0 : req.h_op = SANDESH_OP_DUMP;
2732 0 : req.vdu_msginfo = msginfo;
2733 :
2734 0 : if (vr_info_inbuf != NULL) {
2735 0 : req.vdu_inbuf_size = strlen(vr_info_inbuf);
2736 0 : req.vdu_inbuf = vr_info_inbuf;
2737 : }
2738 0 : return vr_sendmsg(cl, &req, "vr_info_req");
2739 : }
|