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

Generated by: LCOV version 1.14