LCOV - code coverage report
Current view: top level - root/contrail/vrouter/dp-core - vrouter.c (source / functions) Hit Total Coverage
Test: OpenSDN C/C++ coverage (all TARGET_SET jobs) Lines: 38 292 13.0 %
Date: 2026-08-03 02:19:58 Functions: 6 16 37.5 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             :  * se ts=4;se expandtab
       3             :  *
       4             :  * vrouter.c -- virtual router
       5             :  *
       6             :  * Copyright (c) 2013 Juniper Networks, Inc. All rights reserved.
       7             :  */
       8             : #include <vr_os.h>
       9             : #if defined(__linux__)
      10             : #include <linux/version.h>
      11             : #endif
      12             : #include "vr_types.h"
      13             : #include "vr_sandesh.h"
      14             : #include "vr_message.h"
      15             : #include "vr_cpuid.h"
      16             : #include <vr_packet.h>
      17             : #include <vr_interface.h>
      18             : #include <vr_nexthop.h>
      19             : #include <vr_route.h>
      20             : #include <vr_mpls.h>
      21             : #include <vr_flow.h>
      22             : #include <vr_bridge.h>
      23             : #include <vr_packet.h>
      24             : #include <vr_mirror.h>
      25             : #include <vr_vrf_table.h>
      26             : #include <vr_vxlan.h>
      27             : #include <vr_qos.h>
      28             : #include <vr_offloads_dp.h>
      29             : 
      30             : static struct vrouter router;
      31             : struct host_os *vrouter_host;
      32             : struct vr_offload_ops *offload_ops;
      33             : void (*vr_init_cpuid)(struct vr_cpu_type_t *vr_cpu_type) = NULL;
      34             : struct vr_cpu_type_t vr_cpu_type = {0};
      35             : static bool vr_ipv6_underlay_enabled = false;
      36             : bool vr_force_ipv6_underlay_enabled = false;
      37             : 
      38             : extern struct host_os *vrouter_get_host(void);
      39             : extern int vr_stats_init(struct vrouter *);
      40             : extern void vr_stats_exit(struct vrouter *, bool);
      41             : #if defined (__linux__) && defined(__KERNEL__)
      42             : extern int vr_shmem_init(void);
      43             : #endif
      44             : 
      45             : extern unsigned int vr_flow_entries;
      46             : extern unsigned int vr_oflow_entries;
      47             : extern unsigned int vr_bridge_entries;
      48             : extern unsigned int vr_bridge_oentries;
      49             : extern unsigned int vif_bridge_entries;
      50             : extern unsigned int vif_bridge_oentries;
      51             : extern unsigned int vr_pkt_droplog_bufsz;
      52             : extern unsigned int vr_pkt_droplog_buf_en;
      53             : extern unsigned int vr_pkt_droplog_sysctl_en;
      54             : extern const char *ContrailBuildInfo;
      55             : extern unsigned int vr_uncond_close_flow_on_tcp_rst;
      56             : extern void *vr_flow_table;
      57             : extern void *vr_oflow_table;
      58             : extern void *vr_bridge_table;
      59             : extern void *vr_obridge_table;
      60             : void vrouter_exit(bool);
      61             : 
      62             : volatile bool vr_not_ready = true;
      63             : 
      64             : /* Below hugepage req recv and resp variables are added for debug purpose */
      65             : int vr_hpage_req_recv = 0;
      66             : int vr_hpage_req_resp = 0;
      67             : int vr_hpage_mem_fail = 0;
      68             : int vr_genetlink_group_id = 0;
      69             : 
      70             : unsigned int vr_memory_alloc_checks = 0;
      71             : unsigned int vr_priority_tagging = 0;
      72             : 
      73             : struct vr_module {
      74             :     char *mod_name;
      75             :     int error;
      76             :     const char *error_func;
      77             :     int error_line;
      78             :     int error_data;
      79             :     int (*init)(struct vrouter *);
      80             :     void (*exit)(struct vrouter *, bool);
      81             :     void (*shut)(struct vrouter *);
      82             :     int (*mem)(struct vrouter *);
      83             : };
      84             : 
      85             : struct vr_module *module_under_init;
      86             : 
      87             : static struct vr_module modules[] = {
      88             :     {
      89             :         .mod_name       =       "Stats",
      90             :         .init           =       vr_stats_init,
      91             :         .exit           =       vr_stats_exit,
      92             :     },
      93             :     {
      94             :         .mod_name       =       "Nexthop",
      95             :         .init           =       vr_nexthop_init,
      96             :         .exit           =       vr_nexthop_exit,
      97             :     },
      98             :     {
      99             :         .mod_name       =       "Fib",
     100             :         .init           =       vr_fib_init,
     101             :         .mem            =       vr_fib_mem,
     102             :         .exit           =       vr_fib_exit,
     103             :     },
     104             :     {
     105             :         .mod_name       =       "Mpls",
     106             :         .init           =       vr_mpls_init,
     107             :         .exit           =       vr_mpls_exit,
     108             :     },
     109             :     {
     110             :         .mod_name       =       "Flow",
     111             :         .init           =       vr_flow_init,
     112             :         .mem            =       vr_flow_mem,
     113             :         .exit           =       vr_flow_exit,
     114             :     },
     115             :     {
     116             :         .mod_name       =       "Mirror",
     117             :         .init           =       vr_mirror_init,
     118             :         .exit           =       vr_mirror_exit,
     119             :     },
     120             :     {
     121             :         .mod_name       =       "Vxlan",
     122             :         .init           =       vr_vxlan_init,
     123             :         .exit           =       vr_vxlan_exit,
     124             :     },
     125             :     {
     126             :         .mod_name       =       "QOS",
     127             :         .init           =       vr_qos_init,
     128             :         .exit           =       vr_qos_exit,
     129             :     },
     130             :     {
     131             :         .mod_name       =       "Offloads",
     132             :         .init           =       vr_offloads_init,
     133             :         .exit           =       vr_offloads_exit,
     134             :     },
     135             :     {
     136             :         .mod_name       =       "Vrf",
     137             :         .init           =       vr_vrf_table_init,
     138             :         .exit           =       vr_vrf_table_exit,
     139             :     },
     140             :     {
     141             :         .mod_name       =       "Interface",
     142             :         .init           =       vr_interface_init,
     143             :         .exit           =       vr_interface_exit,
     144             :         .shut           =       vr_interface_shut,
     145             :     },
     146             : };
     147             : 
     148             : 
     149             : #define VR_NUM_MODULES  (sizeof(modules) / sizeof(modules[0]))
     150             : /*
     151             :  * TODO For BSD we turn off all performance tweaks for now, it will
     152             :  * be implemented later.
     153             :  */
     154             : /*
     155             :  * Enable changes for better performance
     156             :  */
     157             : #if defined(__linux__)
     158             : int vr_perfr = 1;    /* GRO */
     159             : int vr_perfs = 1;    /* segmentation in software */
     160             : #endif
     161             : 
     162             : /*
     163             :  * Enable MPLS over UDP globally
     164             :  */
     165             : int vr_mudp = 0;
     166             : 
     167             : /*
     168             :  * TCP MSS adjust settings
     169             :  */
     170             : #if defined(__linux__)
     171             : int vr_from_vm_mss_adj = 1; /* adjust TCP MSS on packets from VM */
     172             : int vr_to_vm_mss_adj = 1;   /* adjust TCP MSS on packet sent to VM */
     173             : #endif
     174             : /*
     175             :  * Following sysctls are to enable RPS. Based on empirical results,
     176             :  * performing RPS immediately after packets arrive on a physical interface
     177             :  * gives the best bidirectional throughput (as opposed to performing
     178             :  * RPS after pulling inner headers on the CPU core which received the
     179             :  * interrupt from the physical interface). This is probably because
     180             :  * more work can happen in parallel on multiple cores in the former case.
     181             :  * So, vr_perfr1 is set to 0 and vr_perfr3 is set to 1. vr_perfr2 is always
     182             :  * set as the vhost thread is usually scheduled on the CPU which received
     183             :  * the packet after GRO. Setting vr_perfr2 allows us to influence the
     184             :  * scheduling of the vhost thread to some extent (otherwise the scheduler
     185             :  * can sometimes make sub-optimal choices such as scheduling it on the CPU
     186             :  * which receives interrupts from the physical interface). vrouter ensures
     187             :  * that the receive processing happens on multiple cores which are in the
     188             :  * same NUMA node as the physical interface i.e. the CPU core which receives
     189             :  * packets from the physical interface is different from the CPU core which
     190             :  * does vrouter RX processing. A third CPU core does GRO processing (assuming
     191             :  * that enough cores are available). Also, hyper-thread siblings of the
     192             :  * above 3 cores are not used by vrouter for RX processing.
     193             :  */
     194             : #if defined(__linux__)
     195             : 
     196             : int vr_perfr1 = 0;   /* RPS after pulling inner headers */
     197             : int vr_perfr2 = 1;   /* RPS after GRO on pkt1 interface */
     198             : int vr_perfr3 = 1;   /* RPS from physical interface rx handler */
     199             : int vr_perfp = 1;    /* pull inner headers, faster version */
     200             : 
     201             : int vr_use_linux_br = 0; /* nop if netdev_rx_handler_register() is used */
     202             : 
     203             : #endif
     204             : /*
     205             :  * Following sysctls can be set if vrouter shouldn't pick a CPU for RPS
     206             :  * core based on a hash of the received packet. Turned off by default.
     207             :  */
     208             : int vr_perfq1 = 0;   /* CPU to send packets to if vr_perfr1 is 1 */
     209             : int vr_perfq2 = 0;   /* CPU to send packets to if vr_perfr2 is 1 */
     210             : int vr_perfq3 = 0;   /* CPU to send packets to if vr_perfr3 is 1 */
     211             : 
     212             : /* Should NIC perform checksum offload for outer UDP header? */
     213             : int vr_udp_coff = 0;
     214             : 
     215             : int
     216           0 : vr_module_error(int error, const char *func,
     217             :         int line, int mod_specific)
     218             : {
     219           0 :     struct vr_module *module = module_under_init;
     220             : 
     221             :     /*
     222             :      * set the error only if it was not set earlier. sometimes, the module
     223             :      * init can call functions which fail and set the error. In those cases,
     224             :      * for the sake of consistency, the module init should also be able to
     225             :      * call this function without overwriting the set error data
     226             :      */
     227           0 :     if (module && !module->error) {
     228           0 :         module->error = error;
     229           0 :         module->error_func = func;
     230           0 :         module->error_line = line;
     231           0 :         module->error_data = mod_specific;
     232             :     }
     233             : 
     234           0 :     return error;
     235             : }
     236             : 
     237             : static void
     238           0 : vr_module_debug_dump(void)
     239             : {
     240           0 :     struct vr_module *module = module_under_init;
     241             : 
     242           0 :     if (!module)
     243           0 :         return;
     244             : 
     245           0 :     vr_printf("vrouter (%s): Init failed at %s:%d with return %d (data %d)\n",
     246             :             module->mod_name, module->error_func, module->error_line,
     247             :             module->error, module->error_data);
     248             : 
     249             :     /* reset error data */
     250           0 :     module->error = 0;
     251           0 :     module->error_func = NULL;
     252           0 :     module->error_line = -1;
     253           0 :     module->error_data = 0;
     254             : 
     255           0 :     return;
     256             : }
     257             : 
     258             : struct vrouter *
     259   863209548 : vrouter_get(unsigned int vr_id)
     260             : {
     261   863209548 :     return &router;
     262             : }
     263             : 
     264             : unsigned int
     265         332 : vrouter_generation_num_get(struct vrouter *router)
     266             : {
     267         332 :     return ++router->vr_generation_num;
     268             : }
     269             : 
     270             : static void
     271           0 : vrouter_ops_destroy(vrouter_ops *req)
     272             : {
     273           0 :     if (!req)
     274           0 :         return;
     275             : 
     276           0 :     if (req->vo_build_info) {
     277           0 :         vr_free(req->vo_build_info, VR_BUILD_INFO_OBJECT);
     278           0 :         req->vo_build_info = NULL;
     279             :     }
     280             : 
     281           0 :     if (req->vo_log_type_enable) {
     282           0 :         vr_free(req->vo_log_type_enable, VR_LOG_TYPES_OBJECT);
     283           0 :         req->vo_log_type_enable = NULL;
     284             :     }
     285             : 
     286           0 :     vr_free(req, VR_VROUTER_REQ_OBJECT);
     287             : 
     288           0 :     return;
     289             : }
     290             : 
     291             : static vrouter_ops *
     292           0 : vrouter_ops_get(void)
     293             : {
     294             :     vrouter_ops *req;
     295             : 
     296           0 :     req = vr_zalloc(sizeof(*req), VR_VROUTER_REQ_OBJECT);
     297           0 :     if (!req)
     298           0 :         return NULL;
     299             : 
     300           0 :     req->vo_build_info = vr_zalloc(strlen(ContrailBuildInfo) + 1,
     301             :             VR_BUILD_INFO_OBJECT);
     302           0 :     if (!req->vo_build_info) {
     303           0 :         vr_free(req, VR_VROUTER_REQ_OBJECT);
     304           0 :         return NULL;
     305             :     }
     306             : 
     307           0 :     return req;
     308             : }
     309             : 
     310             : static void
     311           0 : vrouter_ops_get_process(void *s_req)
     312             : {
     313           0 :     int ret = 0;
     314             :     struct vrouter *router;
     315           0 :     vrouter_ops *req = (vrouter_ops *)s_req;
     316           0 :     vrouter_ops *resp = NULL;
     317             : 
     318           0 :     if (req->h_op != SANDESH_OP_GET) {
     319           0 :         ret = -EOPNOTSUPP;
     320           0 :         goto generate_response;
     321             :     }
     322             : 
     323           0 :     router = vrouter_get(req->vo_rid);
     324           0 :     if (!router) {
     325           0 :         ret = -EINVAL;
     326           0 :         goto generate_response;
     327             :     }
     328             : 
     329           0 :     resp = vrouter_ops_get();
     330           0 :     if (!resp) {
     331           0 :         ret = -ENOMEM;
     332           0 :         goto generate_response;
     333             :     }
     334             : 
     335             :     /* Startup command line parameters */
     336           0 :     resp->vo_interfaces = router->vr_max_interfaces;
     337           0 :     resp->vo_vrfs = router->vr_max_vrfs;
     338           0 :     resp->vo_mpls_labels = router->vr_max_labels;
     339           0 :     resp->vo_nexthops = router->vr_max_nexthops;
     340           0 :     resp->vo_bridge_entries = vr_bridge_entries;
     341           0 :     resp->vo_oflow_bridge_entries = vr_bridge_oentries;
     342           0 :     resp->vo_flow_entries = vr_flow_entries;
     343           0 :     resp->vo_oflow_entries = vr_oflow_entries;
     344           0 :     resp->vo_mirror_entries = router->vr_max_mirror_indices;
     345           0 :     resp->vo_vif_bridge_entries = vif_bridge_entries;
     346           0 :     resp->vo_vif_oflow_bridge_entries = vif_bridge_oentries;
     347           0 :     resp->vo_pkt_droplog_bufsz = vr_pkt_droplog_bufsz;
     348           0 :     resp->vo_pkt_droplog_buf_en = vr_pkt_droplog_buf_en;
     349             : 
     350             :     /* Runtime parameters adjustable via sysctl or the vrouter utility */
     351           0 :     resp->vo_perfr = vr_perfr;
     352           0 :     resp->vo_perfs = vr_perfs;
     353           0 :     resp->vo_from_vm_mss_adj = vr_from_vm_mss_adj;
     354           0 :     resp->vo_to_vm_mss_adj = vr_to_vm_mss_adj;
     355           0 :     resp->vo_perfr1 = vr_perfr1;
     356           0 :     resp->vo_perfr2 = vr_perfr2;
     357           0 :     resp->vo_perfr3 = vr_perfr3;
     358           0 :     resp->vo_perfp = vr_perfp;
     359           0 :     resp->vo_perfq1 = vr_perfq1;
     360           0 :     resp->vo_perfq2 = vr_perfq2;
     361           0 :     resp->vo_perfq3 = vr_perfq3;
     362           0 :     resp->vo_udp_coff = vr_udp_coff;
     363           0 :     resp->vo_flow_hold_limit = vr_flow_hold_limit;
     364           0 :     resp->vo_mudp = vr_mudp;
     365           0 :     resp->vo_packet_dump = 0;
     366           0 :     resp->vo_pkt_droplog_en = vr_pkt_droplog_sysctl_en;
     367           0 :     resp->vo_pkt_droplog_min_en = vr_pkt_droplog_min_sysctl_en;
     368           0 :     resp->vo_uncond_close_flow_on_tcp_rst = vr_uncond_close_flow_on_tcp_rst;
     369           0 :     resp->vo_genetlink_group_id = vr_genetlink_group_id;
     370             : 
     371           0 :     if(vr_get_dump_packets != NULL) {
     372           0 :         resp->vo_packet_dump = vr_get_dump_packets();
     373             :     }
     374             : 
     375             :     /* Build info */
     376           0 :     memcpy(resp->vo_build_info, ContrailBuildInfo,
     377           0 :            strlen(ContrailBuildInfo)+1);
     378             : 
     379             :     /* Logging entries */
     380           0 :     resp->vo_log_level = vr_get_log_level();
     381           0 :     resp->vo_log_type_enable =
     382           0 :         vr_get_enabled_log_types(&resp->vo_log_type_enable_size);
     383             : 
     384             : 
     385             :     /* Used entries */
     386           0 :     resp->vo_flow_used_entries =
     387           0 :         vr_flow_table_used_total_entries(router);
     388           0 :     resp->vo_flow_used_oentries =
     389           0 :        vr_flow_table_used_oflow_entries(router);
     390             : 
     391           0 :     resp->vo_bridge_used_entries =
     392           0 :         vr_bridge_table_used_total_entries(router);
     393           0 :     resp->vo_bridge_used_oentries =
     394           0 :         vr_bridge_table_used_oflow_entries(router);
     395             : 
     396           0 :     vr_flow_get_burst_params(router, &resp->vo_burst_tokens,
     397           0 :             &resp->vo_burst_interval, &resp->vo_burst_step);
     398             : 
     399           0 :     resp->vo_memory_alloc_checks = vr_memory_alloc_checks;
     400           0 :     resp->vo_priority_tagging = vr_priority_tagging;
     401             : 
     402           0 :     req = resp;
     403           0 : generate_response:
     404           0 :     if (ret)
     405           0 :         req = NULL;
     406             : 
     407           0 :     vr_message_response(VR_VROUTER_OPS_OBJECT_ID, req, ret, false);
     408           0 :     if (resp)
     409           0 :         vrouter_ops_destroy(resp);
     410             : 
     411           0 :     return;
     412             : }
     413             : 
     414             : /**
     415             :  * A handler for control messages.
     416             :  *
     417             :  * Currently logging control and runtime parameters are supported.
     418             :  * Setting runtime parameters is also possible via sysctl.
     419             :  *
     420             :  * @param s_req Received request to be processed.
     421             :  */
     422             : static void
     423           0 : vrouter_ops_add_process(void *s_req)
     424             : {
     425             :     int i;
     426             : 
     427           0 :     vrouter_ops *req = (vrouter_ops *)s_req;
     428             : 
     429             :     /* Log levels */
     430           0 :     if (req->vo_log_level)
     431           0 :         vr_set_log_level(req->vo_log_level);
     432             : 
     433           0 :     if (req->vo_log_type_enable_size)
     434           0 :         for (i = 0; i < req->vo_log_type_enable_size; ++i)
     435           0 :             vr_set_log_type(req->vo_log_type_enable[i], 1);
     436             : 
     437           0 :     if (req->vo_log_type_disable_size)
     438           0 :         for (i = 0; i < req->vo_log_type_disable_size; ++i)
     439           0 :             vr_set_log_type(req->vo_log_type_disable[i], 0);
     440             : 
     441             :     /* Runtime parameters */
     442           0 :     if (req->vo_packet_dump != -1 && vr_set_dump_packets != NULL)
     443           0 :         vr_set_dump_packets(req->vo_packet_dump);
     444           0 :     if (req->vo_perfr != -1)
     445           0 :         vr_perfr = req->vo_perfr;
     446           0 :     if (req->vo_perfs != -1)
     447           0 :         vr_perfs = req->vo_perfs;
     448           0 :     if (req->vo_from_vm_mss_adj != -1)
     449           0 :         vr_from_vm_mss_adj = req->vo_from_vm_mss_adj;
     450           0 :     if (req->vo_to_vm_mss_adj != -1)
     451           0 :         vr_to_vm_mss_adj = req->vo_to_vm_mss_adj;
     452           0 :     if (req->vo_perfr1 != -1)
     453           0 :         vr_perfr1 = req->vo_perfr1;
     454           0 :     if (req->vo_perfr2 != -1)
     455           0 :         vr_perfr2 = req->vo_perfr2;
     456           0 :     if (req->vo_perfr3 != -1)
     457           0 :         vr_perfr3 = req->vo_perfr3;
     458           0 :     if (req->vo_perfp != -1)
     459           0 :         vr_perfp = req->vo_perfp;
     460           0 :     if (req->vo_perfq1 != -1)
     461           0 :         vr_perfq1 = req->vo_perfq1;
     462           0 :     if (req->vo_perfq2 != -1)
     463           0 :         vr_perfq2 = req->vo_perfq2;
     464           0 :     if (req->vo_perfq3 != -1)
     465           0 :         vr_perfq3 = req->vo_perfq3;
     466           0 :     if (req->vo_udp_coff != -1)
     467           0 :         vr_udp_coff = req->vo_udp_coff;
     468           0 :     if (req->vo_flow_hold_limit != -1)
     469           0 :         vr_flow_hold_limit = (unsigned int)req->vo_flow_hold_limit;
     470           0 :     if (req->vo_mudp != -1)
     471           0 :         vr_mudp = req->vo_mudp;
     472           0 :     vr_flow_set_burst_params(vrouter_get(req->vo_rid), req->vo_burst_tokens,
     473             :             req->vo_burst_interval, req->vo_burst_step);
     474             : 
     475           0 :     vr_priority_tagging = req->vo_priority_tagging;
     476             : 
     477             :     /* Neither of currently called functions signals an error. Just send OK
     478             :      * response here for now. */
     479           0 :     vr_send_response(0);
     480           0 : }
     481             : 
     482             : void
     483          53 : vrouter_exit(bool soft_reset)
     484             : {
     485             :     int i;
     486             : 
     487         636 :     for (i = 0; i < (int)VR_NUM_MODULES; i++)
     488         583 :         if (modules[i].shut)
     489          53 :             modules[i].shut(&router);
     490             : 
     491             :     /* Mark that vrouter is no more ready as shut is already done */
     492          53 :     vr_not_ready = true;
     493             : 
     494             :     /* Flush the previous ashynchronous events, before init */
     495          53 :     if (vr_soft_reset)
     496          53 :         vr_soft_reset(&router);
     497             : 
     498         636 :     for (i = VR_NUM_MODULES - 1; i >= 0; --i) {
     499         583 :         modules[i].exit(&router, soft_reset);
     500             :     }
     501             : 
     502             :     /*
     503             :      * This is necessary on operating systems that don't
     504             :      * unload the binary on exit.
     505             :      * When soft reset is happening we must not reinitialize
     506             :      * vrouter struct.
     507             :      */
     508          53 :     if (!soft_reset) {
     509          53 :         memset(&router, 0, sizeof(router));
     510             :     }
     511             : 
     512          53 :     return;
     513             : }
     514             : 
     515             : int
     516          53 : vrouter_init(void)
     517             : {
     518             :     unsigned int i;
     519             :     int ret;
     520             : 
     521             :     /* init CPU id struct*/
     522          53 :     if (vr_init_cpuid != NULL)
     523          53 :         vr_init_cpuid(&vr_cpu_type);
     524             : 
     525          53 :     vrouter_host = vrouter_get_host();
     526          53 :     if (!vrouter_host && (ret = -ENOMEM))
     527           0 :         goto init_fail;
     528             : 
     529         636 :     for (i = 0; i < VR_NUM_MODULES; i++) {
     530         583 :         module_under_init = &modules[i];
     531         583 :         ret = modules[i].init(&router);
     532         583 :         if (ret) {
     533           0 :             vr_printf("vrouter module %u init error (%d)\n", i, ret);
     534           0 :             goto init_fail;
     535             :         }
     536             :         // actually, this is not executed in the linux kernel mode
     537             :         // in most cases
     538         583 :         if (vr_hpage_mem_fail || !vr_huge_page_config) {
     539         583 :             if (modules[i].mem) {
     540         106 :                 ret = modules[i].mem(&router);
     541         106 :                 if (ret) {
     542           0 :                     vr_printf("vrouter module %u mem error (%d)\n", i, ret);
     543           0 :                     goto init_fail;
     544             :                 }
     545             :             }
     546             :         }
     547             :     }
     548          53 :     vr_hpage_mem_fail = 0;
     549          53 :     module_under_init = NULL;
     550          53 :     vr_not_ready = false;
     551          53 :     return 0;
     552             : 
     553           0 : init_fail:
     554           0 :     vrouter_exit(false);
     555           0 :     vr_module_debug_dump();
     556           0 :     module_under_init = NULL;
     557             : 
     558           0 :     return ret;
     559             : }
     560             : 
     561             : static int
     562           0 : vrouter_soft_reset(void)
     563             : {
     564           0 :     int ret = 0;
     565           0 :     vrouter_exit(true);
     566           0 :     ret = vrouter_init();
     567           0 :     if (!ret)
     568           0 :         ret = vr_offload_soft_reset();
     569           0 :     return ret;
     570             : }
     571             : 
     572             : void
     573           0 : vrouter_ops_process(void *s_req)
     574             : {
     575             :     int ret;
     576             : 
     577           0 :     vrouter_ops *ops = (vrouter_ops *)s_req;
     578             : 
     579           0 :     switch (ops->h_op) {
     580           0 :     case SANDESH_OP_RESET:
     581           0 :         vr_printf("vrouter soft reset start\n");
     582           0 :         ret = vrouter_soft_reset();
     583           0 :         vr_printf("vrouter soft reset done (%d)\n", ret);
     584           0 :         break;
     585             : 
     586           0 :     case SANDESH_OP_GET:
     587           0 :         vrouter_ops_get_process(s_req);
     588           0 :         return;
     589             : 
     590           0 :     case SANDESH_OP_ADD:
     591           0 :         vrouter_ops_add_process(s_req);
     592           0 :         return;
     593             : 
     594           0 :     default:
     595           0 :         ret = -EOPNOTSUPP;
     596             :     }
     597             : 
     598           0 :     vr_send_response(ret);
     599             : 
     600           0 :     return;
     601             : }
     602             : 
     603           0 : static int vr_shmem_open(const struct vrouter *router) {
     604             : #if defined (__linux__) && defined(__KERNEL__)
     605             :     if (router->vr_flow_table != NULL &&
     606             :         router->vr_bridge_table != NULL) {
     607             :         printk ("tables are in memory\n");
     608             :         return vr_shmem_init();
     609             :     }
     610             :     return -1;
     611             : #endif
     612           0 :     return 0;
     613             : }
     614             : 
     615             : void
     616           0 : vr_hugepage_config_process(void *s_req)
     617             : {
     618           0 :     int i, ret = -EEXIST, mret = 0;
     619             :     vr_hugepage_config hcfg_resp;
     620           0 :     vr_hugepage_config *req= (vr_hugepage_config *)s_req;
     621           0 :     struct vrouter *router = vrouter_get(0);
     622             : 
     623             :     /* Debug purpose: Increment below variable when we get hugepage req from agent */
     624           0 :     vr_hpage_req_recv++;
     625             : 
     626             :     /* Only addition of huge pages is supported */
     627           0 :     if (req->vhp_op != SANDESH_OP_ADD) {
     628           0 :         vr_send_response(-EOPNOTSUPP);
     629           0 :         return;
     630             :     }
     631             : 
     632             :     /* Invoke huge page configuration only if a segment exists */
     633           0 :     if (vr_huge_page_config) {
     634           0 :         ret = vr_huge_page_config(req->vhp_mem, req->vhp_mem_size,
     635           0 :                                   req->vhp_psize, req->vhp_psize_size,
     636           0 :                                   req->vhp_mem_sz, req->vhp_mem_sz_size,
     637             :                                   req->vhp_file_paths, req->vhp_file_path_sz);
     638             :     }
     639             : 
     640           0 :     if (ret != -EEXIST) {
     641           0 :         for (i = 0; i < (int)VR_NUM_MODULES; i++) {
     642           0 :             if (modules[i].mem)  {
     643           0 :                 mret = modules[i].mem(router);
     644           0 :                 if (mret)
     645           0 :                     break;
     646             :             }
     647             :         }
     648             :     }
     649             : 
     650           0 :     memset(&hcfg_resp, 0, sizeof(hcfg_resp));
     651           0 :     hcfg_resp.vhp_op = req->vhp_op;
     652             : 
     653             :     /*
     654             :      * If we fail to allocate memory both in huge pages and as well
     655             :      * regular respond with VR_HPAGE_CFG_RESP_MEM_FAILURE. Return status
     656             :      * in vrouter_response would be an error value. If memory allocation
     657             :      * succeds in either the huge pages or regular, return status is
     658             :      * going to be "0" and response code gives the details of the
     659             :      * allocation
     660             :      */
     661             : 
     662           0 :     switch (ret)  {
     663           0 :     case 0:
     664           0 :         if (!mret)
     665           0 :             hcfg_resp.vhp_resp = VR_HPAGE_CFG_RESP_HPAGE_SUCCESS;
     666           0 :         break;
     667             : 
     668           0 :     case -EINVAL:
     669           0 :         if (!mret) {
     670           0 :             hcfg_resp.vhp_resp = VR_HPAGE_CFG_RESP_INVALID_ARG_MEM_INITED;
     671           0 :             ret = 0;
     672             :         }
     673           0 :         break;
     674             : 
     675           0 :     case -EEXIST:
     676           0 :         hcfg_resp.vhp_resp = VR_HPAGE_CFG_RESP_MEM_ALREADY_INITED;
     677           0 :         break;
     678             : 
     679           0 :     case -ENOMEM:
     680           0 :         if (!mret) {
     681           0 :             hcfg_resp.vhp_resp = VR_HPAGE_CFG_RESP_HPAGE_FAILURE_MEM_INITED;
     682           0 :             ret = 0;
     683             :         }
     684           0 :         break;
     685             : 
     686           0 :     case -E2BIG:
     687           0 :         if (!mret) {
     688           0 :             hcfg_resp.vhp_resp = VR_HPAGE_CFG_RESP_HPAGE_PARTIAL_SUCCESS;
     689           0 :             ret = 0;
     690             :         }
     691           0 :         break;
     692             : 
     693           0 :     default:
     694           0 :         ret = -EINVAL;
     695           0 :         break;
     696             :     }
     697             : 
     698           0 :     if (mret) {
     699           0 :         hcfg_resp.vhp_resp = VR_HPAGE_CFG_RESP_MEM_FAILURE;
     700           0 :         ret = mret;
     701             :         /* cleaning up partially allocated memory. */
     702           0 :         for (i = 0; i < (int)VR_NUM_MODULES; i++) {
     703           0 :             if (modules[i].mem)  {
     704           0 :                 modules[i].exit(router, false);
     705             :             }
     706             :         }
     707           0 :         vr_hpage_mem_fail = mret;
     708             :     }
     709             : 
     710           0 :     if (ret == 0) {
     711           0 :         ret = vr_shmem_open(router);
     712           0 :         if (ret != 0) {
     713           0 :             hcfg_resp.vhp_resp = VR_HPAGE_CFG_RESP_SHMEM_FAILURE;
     714             :         }
     715             :     }
     716             : 
     717             :     /* Debug purpose: Increment below variable before sending response */
     718           0 :     vr_hpage_req_resp++;
     719           0 :     vr_printf("Huge page req_recv_cntr:%d resp_cntr:%d resp: %d ret: %d\n", vr_hpage_req_recv,
     720             :             vr_hpage_req_resp, hcfg_resp.vhp_resp, ret);
     721             : 
     722           0 :     vr_message_response(VR_HPAGE_CFG_OBJECT_ID, &hcfg_resp, ret,
     723             :                 false);
     724             : 
     725           0 :     return;
     726             : }
     727             : 
     728             : bool
     729          13 : vr_is_ipv6_underlay_enabled(void)
     730             : {
     731          13 :     return vr_ipv6_underlay_enabled ||
     732             :         vr_force_ipv6_underlay_enabled;
     733             : }
     734             : 
     735             : void
     736           9 : vr_set_ipv6_underlay_enabled(void)
     737             : {
     738           9 :     vr_ipv6_underlay_enabled = true;
     739           9 : }

Generated by: LCOV version 1.14