LCOV - code coverage report
Current view: top level - root/contrail/vrouter/utils - vr_util.c (source / functions) Hit Total Coverage
Test: OpenSDN C/C++ coverage (all TARGET_SET jobs) Lines: 449 1547 29.0 %
Date: 2026-11-09 02:10:49 Functions: 28 99 28.3 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.14