LCOV - code coverage report
Current view: top level - vnsw/agent/kstate - flow_kstate.cc (source / functions) Hit Total Coverage
Test: OpenSDN C/C++ coverage (all TARGET_SET jobs) Lines: 0 251 0.0 %
Date: 2026-11-09 02:10:49 Functions: 0 10 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             :  * Copyright (c) 2013 Juniper Networks, Inc. All rights reserved.
       3             :  * Copyright Contributors to the OpenSDN project
       4             :  */
       5             : 
       6             : #include <base/task.h>
       7             : #include <base/address_util.h>
       8             : 
       9             : #include <cmn/agent_cmn.h>
      10             : #include <kstate/kstate.h>
      11             : #include <kstate/flow_kstate.h>
      12             : 
      13             : #include <vr_flow.h>
      14             : #include <vr_mirror.h>
      15             : 
      16             : #include <pkt/flow_table.h>
      17             : 
      18             : #include <vrouter/ksync/flowtable_ksync.h>
      19             : #include <vrouter/ksync/ksync_init.h>
      20             : 
      21             : using namespace std;
      22             : 
      23           0 : FlowKState::FlowKState(Agent *agent, const string &resp_ctx, int idx) :
      24             :     Task((TaskScheduler::GetInstance()->GetTaskId("Agent::FlowResponder")),
      25           0 :             0), response_context_(resp_ctx), flow_idx_(idx), evicted_(0),
      26           0 :     flow_iteration_key_(0), agent_(agent) {
      27           0 : }
      28             : 
      29           0 : FlowKState::FlowKState(Agent *agent, const string &resp_ctx,
      30           0 :                        const string &iter_idx) :
      31             :     Task((TaskScheduler::GetInstance()->GetTaskId("Agent::FlowResponder")),
      32           0 :             0), response_context_(resp_ctx), flow_idx_(-1), evicted_(0),
      33           0 :     flow_iteration_key_(0), agent_(agent) {
      34           0 :     stringToInteger(iter_idx, flow_iteration_key_);
      35           0 : }
      36             : 
      37           0 : void FlowKState::SendResponse(KFlowResp *resp) const {
      38           0 :     resp->set_context(response_context_);
      39           0 :     resp->Response();
      40           0 : }
      41             : 
      42           0 : const string FlowKState::FlagToStr(unsigned int flag) const {
      43           0 :     switch(flag) {
      44           0 :         case VR_FLOW_FLAG_ACTIVE:
      45           0 :             return " ACTIVE ";
      46           0 :         case VR_FLOW_FLAG_MIRROR:
      47           0 :             return " MIRROR ";
      48           0 :         case VR_FLOW_FLAG_VRFT:
      49           0 :             return " VRFT ";
      50           0 :         case VR_FLOW_FLAG_SNAT:
      51           0 :             return " SNAT ";
      52           0 :         case VR_FLOW_FLAG_SPAT:
      53           0 :             return " SPAT ";
      54           0 :         case VR_FLOW_FLAG_DNAT:
      55           0 :             return " DNAT ";
      56           0 :         case VR_FLOW_FLAG_DPAT:
      57           0 :             return " DPAT ";
      58           0 :         case VR_FLOW_FLAG_LINK_LOCAL:
      59           0 :             return " LINK_LOCAL ";
      60           0 :         case VR_FLOW_FLAG_EVICTED:
      61           0 :             return " EVICTED ";
      62           0 :         case VR_FLOW_FLAG_EVICT_CANDIDATE:
      63           0 :             return " EVICT_CANDIDATE ";
      64           0 :         case VR_FLOW_FLAG_NEW_FLOW:
      65           0 :             return " NEW_FLOW ";
      66           0 :         case VR_FLOW_FLAG_MODIFIED:
      67           0 :             return " MODIFIED ";
      68           0 :         case VR_RFLOW_VALID:
      69           0 :             return " RFLOW_VALID ";
      70           0 :         default:
      71           0 :             return " INVALID ";
      72             :     }
      73             : }
      74             : 
      75           0 : const string FlowKState::TcpFlagToStr(unsigned int flag) const {
      76           0 :     switch(flag) {
      77           0 :         case VR_FLOW_TCP_SYN:
      78           0 :             return " SYN ";
      79           0 :         case VR_FLOW_TCP_SYN_R:
      80           0 :             return " SYN_R ";
      81           0 :         case VR_FLOW_TCP_ESTABLISHED:
      82           0 :             return " ESTB ";
      83           0 :         case VR_FLOW_TCP_ESTABLISHED_R:
      84           0 :             return " ESTB_R ";
      85           0 :         case VR_FLOW_TCP_FIN:
      86           0 :             return " FIN ";
      87           0 :         case VR_FLOW_TCP_FIN_R:
      88           0 :             return " FIN_R ";
      89           0 :         case VR_FLOW_TCP_RST:
      90           0 :             return " RST ";
      91           0 :         case VR_FLOW_TCP_HALF_CLOSE:
      92           0 :             return " HALF_CLOSE ";
      93           0 :         case VR_FLOW_TCP_DEAD:
      94           0 :             return " DEAD ";
      95           0 :         default:
      96           0 :             return " INVALID ";
      97             :     }
      98             : }
      99             : 
     100           0 : void FlowKState::UpdateFlagStr(string &str, bool &set, bool tcp, unsigned sflag,
     101             :                                unsigned cflag) const {
     102           0 :     string flag_str;
     103           0 :     if (sflag & cflag) {
     104           0 :         if (tcp) {
     105           0 :             flag_str.assign(TcpFlagToStr(cflag));
     106             :         } else {
     107           0 :             flag_str.assign(FlagToStr(cflag));
     108             :         }
     109           0 :         if (set) {
     110           0 :             str.append("|" + flag_str);
     111             :         } else {
     112           0 :             str.assign(flag_str);
     113           0 :             set = true;
     114             :         }
     115             :     }
     116           0 : }
     117             : 
     118           0 : const std::string FlowKState::DropCodeToStr(uint8_t drop_code) const {
     119           0 :     switch (drop_code) {
     120           0 :     case VR_FLOW_DR_UNKNOWN:
     121           0 :         return "Unknown";
     122           0 :     case VR_FLOW_DR_UNAVIALABLE_INTF:
     123           0 :         return "IntfErr";
     124           0 :     case VR_FLOW_DR_IPv4_FWD_DIS:
     125           0 :         return "Ipv4Dis";
     126           0 :     case VR_FLOW_DR_UNAVAILABLE_VRF:
     127           0 :         return "VrfErr";
     128           0 :     case VR_FLOW_DR_NO_SRC_ROUTE:
     129           0 :         return "NoSrcRt";
     130           0 :     case VR_FLOW_DR_NO_DST_ROUTE:
     131           0 :         return "NoDstRt";
     132           0 :     case VR_FLOW_DR_AUDIT_ENTRY:
     133           0 :         return "Audit";
     134           0 :     case VR_FLOW_DR_VRF_CHANGE:
     135           0 :         return "VrfChange";
     136           0 :     case VR_FLOW_DR_NO_REVERSE_FLOW:
     137           0 :         return "NoRevFlow";
     138           0 :     case VR_FLOW_DR_REVERSE_FLOW_CHANGE:
     139           0 :         return "RevFlowChng";
     140           0 :     case VR_FLOW_DR_NAT_CHANGE:
     141           0 :         return "NatChng";
     142           0 :     case VR_FLOW_DR_FLOW_LIMIT:
     143           0 :         return "FlowLim";
     144           0 :     case VR_FLOW_DR_LINKLOCAL_SRC_NAT:
     145           0 :         return "LinkSrcNatErr";
     146           0 :     case VR_FLOW_DR_POLICY:
     147           0 :         return "Policy";
     148           0 :     case VR_FLOW_DR_OUT_POLICY:
     149           0 :         return "OutPolicy";
     150           0 :     case VR_FLOW_DR_SG:
     151           0 :         return "SG";
     152           0 :     case VR_FLOW_DR_OUT_SG:
     153           0 :         return "OutSG";
     154           0 :     case VR_FLOW_DR_REVERSE_SG:
     155           0 :         return "RevSG";
     156           0 :     case VR_FLOW_DR_REVERSE_OUT_SG:
     157           0 :         return "RevOutSG";
     158           0 :     case VR_FLOW_DR_FW_POLICY:
     159           0 :         return "FwPolicy";
     160           0 :     case VR_FLOW_DR_OUT_FW_POLICY:
     161           0 :         return "OutFwPolicy";
     162           0 :     case VR_FLOW_DR_REVERSE_FW_POLICY:
     163           0 :         return "RevFwPolicy";
     164           0 :     case VR_FLOW_DR_REVERSE_OUT_FW_POLICY:
     165           0 :         return "RevOutFwPolicy";
     166           0 :     case VR_FLOW_DR_SAME_FLOW_RFLOW_KEY:
     167           0 :         return "SameFlowRflowKey";
     168           0 :     default:
     169           0 :         return "Unknown";
     170             :     }
     171             : }
     172             : 
     173           0 : void FlowKState::SetFlowHandle(KFlowResp *resp, const uint32_t idx) const {
     174           0 :     if (evicted_) {
     175           0 :         resp->set_flow_handle(integerToString(idx) + " evicted_set");
     176             :     } else {
     177           0 :         resp->set_flow_handle(integerToString(idx));
     178             :     }
     179           0 : }
     180             : 
     181           0 : void FlowKState::SetFlowData(vector<KFlowInfo> &list,
     182             :                              const vr_flow_entry *k_flow,
     183             :                              const int index) const {
     184           0 :     KFlowInfo data;
     185           0 :     bool action_drop = false;
     186           0 :     KSyncFlowMemory *flow_mem = agent_->ksync()->ksync_flow_memory();
     187           0 :     IpAddress sip, dip;
     188           0 :     flow_mem->VrFlowToIp(k_flow, &sip, &dip);
     189           0 :     string action_str;
     190           0 :     string flag_str, tcp_flags;
     191           0 :     data.set_index((unsigned int)index);
     192           0 :     data.set_sport((unsigned)ntohs(k_flow->fe_key.flow4_sport));
     193           0 :     data.set_dport((unsigned)ntohs(k_flow->fe_key.flow4_dport));
     194           0 :     data.set_sip(sip.to_string());
     195           0 :     data.set_dip(dip.to_string());
     196           0 :     data.set_vrf_id(k_flow->fe_vrf);
     197           0 :     data.set_proto(k_flow->fe_key.flow4_proto);
     198           0 :     data.set_nhid(k_flow->fe_key.flow_nh_id);
     199           0 :     switch (k_flow->fe_action) {
     200           0 :         case VR_FLOW_ACTION_FORWARD:
     201           0 :             action_str.assign("FORWARD");
     202           0 :             break;
     203           0 :         case VR_FLOW_ACTION_DROP:
     204           0 :             action_str.assign("DROP");
     205           0 :             action_drop = true;
     206           0 :             break;
     207           0 :         case VR_FLOW_ACTION_NAT:
     208           0 :             action_str.assign("NAT");
     209           0 :             break;
     210           0 :         case VR_FLOW_ACTION_HOLD:
     211           0 :             action_str.assign("HOLD");
     212           0 :             break;
     213           0 :         default:
     214           0 :             action_str.assign("INVALID");
     215             :     }
     216           0 :     data.set_action(action_str);
     217           0 :     bool assigned = false;
     218           0 :     UpdateFlagStr(flag_str, assigned, false, k_flow->fe_flags,
     219             :                   VR_FLOW_FLAG_ACTIVE);
     220           0 :     UpdateFlagStr(flag_str, assigned, false, k_flow->fe_flags,
     221             :                   VR_FLOW_FLAG_MIRROR);
     222           0 :     UpdateFlagStr(flag_str, assigned, false, k_flow->fe_flags,
     223             :                   VR_FLOW_FLAG_VRFT);
     224           0 :     UpdateFlagStr(flag_str, assigned, false, k_flow->fe_flags,
     225             :                   VR_FLOW_FLAG_SNAT);
     226           0 :     UpdateFlagStr(flag_str, assigned, false, k_flow->fe_flags,
     227             :                   VR_FLOW_FLAG_SPAT);
     228           0 :     UpdateFlagStr(flag_str, assigned, false, k_flow->fe_flags,
     229             :                   VR_FLOW_FLAG_DNAT);
     230           0 :     UpdateFlagStr(flag_str, assigned, false, k_flow->fe_flags,
     231             :                   VR_FLOW_FLAG_SPAT);
     232           0 :     UpdateFlagStr(flag_str, assigned, false, k_flow->fe_flags,
     233             :                   VR_FLOW_FLAG_LINK_LOCAL);
     234           0 :     UpdateFlagStr(flag_str, assigned, false, k_flow->fe_flags,
     235             :                   VR_FLOW_FLAG_EVICTED);
     236           0 :     UpdateFlagStr(flag_str, assigned, false, k_flow->fe_flags,
     237             :                   VR_FLOW_FLAG_EVICT_CANDIDATE);
     238           0 :     UpdateFlagStr(flag_str, assigned, false, k_flow->fe_flags,
     239             :                   VR_FLOW_FLAG_NEW_FLOW);
     240           0 :     UpdateFlagStr(flag_str, assigned, false, k_flow->fe_flags,
     241             :                   VR_FLOW_FLAG_MODIFIED);
     242           0 :     UpdateFlagStr(flag_str, assigned, false, k_flow->fe_flags, VR_RFLOW_VALID);
     243           0 :     data.set_flags(flag_str);
     244             : 
     245           0 :     if (k_flow->fe_key.flow4_proto == IPPROTO_TCP) {
     246           0 :         assigned = false;
     247           0 :         UpdateFlagStr(tcp_flags, assigned, true, k_flow->fe_tcp_flags,
     248             :                       VR_FLOW_TCP_SYN);
     249           0 :         UpdateFlagStr(tcp_flags, assigned, true, k_flow->fe_tcp_flags,
     250             :                       VR_FLOW_TCP_SYN_R);
     251           0 :         UpdateFlagStr(tcp_flags, assigned, true, k_flow->fe_tcp_flags,
     252             :                       VR_FLOW_TCP_ESTABLISHED);
     253           0 :         UpdateFlagStr(tcp_flags, assigned, true, k_flow->fe_tcp_flags,
     254             :                       VR_FLOW_TCP_ESTABLISHED_R);
     255           0 :         UpdateFlagStr(tcp_flags, assigned, true, k_flow->fe_tcp_flags,
     256             :                       VR_FLOW_TCP_FIN);
     257           0 :         UpdateFlagStr(tcp_flags, assigned, true, k_flow->fe_tcp_flags,
     258             :                       VR_FLOW_TCP_FIN_R);
     259           0 :         UpdateFlagStr(tcp_flags, assigned, true, k_flow->fe_tcp_flags,
     260             :                       VR_FLOW_TCP_RST);
     261           0 :         UpdateFlagStr(tcp_flags, assigned, true, k_flow->fe_tcp_flags,
     262             :                       VR_FLOW_TCP_HALF_CLOSE);
     263           0 :         UpdateFlagStr(tcp_flags, assigned, true, k_flow->fe_tcp_flags,
     264             :                       VR_FLOW_TCP_DEAD);
     265           0 :         data.set_tcp_flags(tcp_flags);
     266             :     }
     267           0 :     if (action_drop) {
     268           0 :         data.set_drop_reason(DropCodeToStr(k_flow->fe_drop_reason));
     269             :     }
     270           0 :     data.set_underlay_udp_sport(k_flow->fe_udp_src_port);
     271           0 :     data.set_rflow(k_flow->fe_rflow);
     272           0 :     data.set_d_vrf_id(k_flow->fe_dvrf);
     273           0 :     data.set_bytes(k_flow->fe_stats.flow_bytes);
     274           0 :     data.set_pkts(k_flow->fe_stats.flow_packets);
     275           0 :     if (k_flow->fe_mirror_id != VR_MAX_MIRROR_INDICES) {
     276           0 :         data.set_mirror_id(k_flow->fe_mirror_id);
     277             :     }
     278           0 :     if (k_flow->fe_sec_mirror_id != VR_MAX_MIRROR_INDICES) {
     279           0 :         data.set_sec_mirror_id(k_flow->fe_sec_mirror_id);
     280             :     }
     281           0 :     if (k_flow->fe_ecmp_nh_index != -1) {
     282           0 :         data.set_ecmp_index(k_flow->fe_ecmp_nh_index);
     283             :     }
     284           0 :     data.set_ttl(k_flow->fe_ttl);
     285           0 :     data.set_qos_id(k_flow->fe_qos_id);
     286           0 :     data.set_gen_id(k_flow->fe_gen_id);
     287           0 :     data.set_tcp_seq(k_flow->fe_tcp_seq);
     288           0 :     data.set_oflow_bytes(k_flow->fe_stats.flow_bytes_oflow);
     289           0 :     data.set_oflow_packets(k_flow->fe_stats.flow_packets_oflow);
     290           0 :     data.set_underlay_gw_index(k_flow->fe_underlay_ecmp_index);
     291           0 :     list.push_back(data);
     292           0 : }
     293             : 
     294           0 : bool FlowKState::Run() {
     295           0 :     int count = 0;
     296             :     const vr_flow_entry *k_flow;
     297             :     KFlowResp *resp;
     298             : 
     299           0 :     KSyncFlowMemory *ksync_obj = agent_->ksync()->ksync_flow_memory();
     300             : 
     301           0 :     if (flow_idx_ != -1) {
     302           0 :         k_flow = ksync_obj->GetKernelFlowEntry(flow_idx_, false);
     303           0 :         if (k_flow) {
     304           0 :             resp = new KFlowResp();
     305             :             vector<KFlowInfo> &list = const_cast<std::vector<KFlowInfo>&>
     306           0 :                                           (resp->get_flow_list());
     307           0 :             SetFlowData(list, k_flow, flow_idx_);
     308           0 :             SendResponse(resp);
     309             :         } else {
     310           0 :             ErrResp *resp = new ErrResp();
     311           0 :             resp->set_context(response_context_);
     312           0 :             resp->Response();
     313             :         }
     314           0 :         return true;
     315             :     }
     316           0 :     uint32_t idx = flow_iteration_key_;
     317           0 :     uint32_t max_flows = ksync_obj->table_entries_count();
     318             : 
     319           0 :     resp = new KFlowResp();
     320             :     vector<KFlowInfo> &list = const_cast<std::vector<KFlowInfo>&>
     321           0 :                                   (resp->get_flow_list());
     322           0 :     while(idx < max_flows) {
     323           0 :         k_flow = ksync_obj->GetKernelFlowEntry(idx, false);
     324           0 :         idx++;
     325           0 :         if (k_flow) {
     326           0 :             if((k_flow->fe_flags & VR_FLOW_FLAG_EVICTED) && (!evicted_)) {
     327           0 :                 continue;
     328             :             }
     329           0 :             count++;
     330           0 :             SetFlowData(list, k_flow, (idx-1));
     331             :         }
     332           0 :         if (count == KState::kMaxEntriesPerResponse) {
     333           0 :             if (idx != max_flows) {
     334           0 :                 SetFlowHandle(resp, idx);
     335             :             } else {
     336           0 :                 SetFlowHandle(resp, 0);
     337             :             }
     338           0 :             SendResponse(resp);
     339           0 :             return true;
     340             :         }
     341             :     }
     342           0 :     SetFlowHandle(resp, 0);
     343           0 :     SendResponse(resp);
     344             : 
     345           0 :     return true;
     346             : }

Generated by: LCOV version 1.14