LCOV - code coverage report
Current view: top level - vnsw/agent/pkt/flow_mgmt - flow_mgmt_key.h (source / functions) Hit Total Coverage
Test: OpenSDN C/C++ coverage (all TARGET_SET jobs) Lines: 119 153 77.8 %
Date: 2026-11-09 02:10:49 Functions: 52 66 78.8 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             :  * Copyright (c) 2018 Juniper Networks, Inc. All rights reserved.
       3             :  * Copyright Contributors to the OpenSDN project
       4             :  */
       5             : 
       6             : #ifndef __AGENT_PKT_FLOW_MGMT_KEY_H__
       7             : #define __AGENT_PKT_FLOW_MGMT_KEY_H__
       8             : 
       9             : #include <db/db_entry.h>
      10             : #include <pkt/flow_event.h>
      11             : 
      12             : class FlowMgmtKey {
      13             : public:
      14             :     enum Type {
      15             :         INVALID,
      16             :         INTERFACE,
      17             :         ACL,
      18             :         ACE_ID,
      19             :         VN,
      20             :         VM,
      21             :         INET4,
      22             :         INET6,
      23             :         BRIDGE,
      24             :         NH,
      25             :         VRF,
      26             :         BGPASASERVICE,
      27             :         END
      28             :     };
      29             : 
      30       21368 :     FlowMgmtKey(Type type, const DBEntry *db_entry) :
      31       21368 :         type_(type), db_entry_(db_entry) {
      32       21368 :     }
      33             : 
      34       21368 :     virtual ~FlowMgmtKey() { }
      35             : 
      36             :     // Clone the key
      37             :     virtual FlowMgmtKey *Clone() = 0;
      38             : 
      39             :     // Convert from FlowMgmtKey to FlowEvent
      40         201 :     virtual void KeyToFlowRequest(FlowEvent *req) {
      41         201 :         req->set_db_entry(db_entry_);
      42         201 :     }
      43             : 
      44             :     // Is DBEntry used as key. Routes dont use DBEntry as key
      45       65006 :     virtual bool UseDBEntry() const { return true; }
      46             : 
      47             :     // Comparator
      48       13668 :     virtual bool Compare(const FlowMgmtKey *rhs) const {
      49       13668 :         return false;
      50             :     }
      51             : 
      52      153406 :     bool IsLess(const FlowMgmtKey *rhs) const {
      53      153406 :         if (type_ != rhs->type_)
      54        7261 :             return type_ < rhs->type_;
      55             : 
      56      146145 :         if (UseDBEntry()) {
      57       65006 :             if (db_entry_ != rhs->db_entry_)
      58       51338 :                 return db_entry_ < rhs->db_entry_;
      59             :         }
      60             : 
      61       94807 :         return Compare(rhs);
      62             :     }
      63             : 
      64             :     FlowEvent::Event FreeDBEntryEvent() const;
      65        2402 :     Type type() const { return type_; }
      66       19175 :     const DBEntry *db_entry() const { return db_entry_; }
      67        1360 :     void set_db_entry(const DBEntry *db_entry) { db_entry_ = db_entry; }
      68             : 
      69             : protected:
      70             :     Type type_;
      71             :     mutable const DBEntry *db_entry_;
      72             : 
      73             : private:
      74             :     DISALLOW_COPY_AND_ASSIGN(FlowMgmtKey);
      75             : };
      76             : 
      77             : struct FlowMgmtKeyCmp {
      78      152519 :     bool operator()(const FlowMgmtKey *l, const FlowMgmtKey *r) const {
      79      152519 :         return l->IsLess(r);
      80             :     }
      81             : };
      82             : 
      83             : class AclFlowMgmtKey : public FlowMgmtKey {
      84             : public:
      85          84 :     AclFlowMgmtKey(const AclDBEntry *acl, const AclEntryIDList *ace_id_list) :
      86          84 :         FlowMgmtKey(FlowMgmtKey::ACL, acl) {
      87          84 :         if (ace_id_list) {
      88          72 :             ace_id_list_ = *ace_id_list;
      89             :         }
      90          84 :     }
      91             : 
      92         156 :     virtual ~AclFlowMgmtKey() { }
      93             : 
      94          38 :     virtual FlowMgmtKey *Clone() {
      95          38 :         return new AclFlowMgmtKey(static_cast<const AclDBEntry *>(db_entry()),
      96          38 :                                   &ace_id_list_);
      97             :     }
      98             : 
      99          91 :     const AclEntryIDList *ace_id_list() const { return &ace_id_list_; }
     100             : 
     101          25 :     void set_ace_id_list(const AclEntryIDList *list) {
     102          25 :         ace_id_list_ = *list;
     103          25 :     }
     104             : 
     105             : private:
     106             :     AclEntryIDList ace_id_list_;
     107             :     DISALLOW_COPY_AND_ASSIGN(AclFlowMgmtKey);
     108             : };
     109             : 
     110             : class VnFlowMgmtKey : public FlowMgmtKey {
     111             : public:
     112         661 :     VnFlowMgmtKey(const VnEntry *vn) : FlowMgmtKey(FlowMgmtKey::VN, vn) { }
     113        1182 :     virtual ~VnFlowMgmtKey() { }
     114             : 
     115         295 :     virtual FlowMgmtKey *Clone() {
     116         295 :         return new VnFlowMgmtKey(static_cast<const VnEntry *>(db_entry()));
     117             :     }
     118             : 
     119             : private:
     120             :     DISALLOW_COPY_AND_ASSIGN(VnFlowMgmtKey);
     121             : };
     122             : 
     123             : class InterfaceFlowMgmtKey : public FlowMgmtKey {
     124             : public:
     125        1475 :     InterfaceFlowMgmtKey(const Interface *intf) :
     126        1475 :         FlowMgmtKey(FlowMgmtKey::INTERFACE, intf) {
     127        1475 :     }
     128             : 
     129        2268 :     virtual ~InterfaceFlowMgmtKey() { }
     130             : 
     131         565 :     virtual FlowMgmtKey *Clone() {
     132         565 :         return new InterfaceFlowMgmtKey(static_cast<const Interface *>(db_entry()));
     133             :     }
     134             : 
     135             : private:
     136             :     DISALLOW_COPY_AND_ASSIGN(InterfaceFlowMgmtKey);
     137             : };
     138             : 
     139             : class NhFlowMgmtKey : public FlowMgmtKey {
     140             : public:
     141        5378 :     NhFlowMgmtKey(const NextHop *nh) : FlowMgmtKey(FlowMgmtKey::NH, nh) { }
     142        7456 :     virtual ~NhFlowMgmtKey() { }
     143             : 
     144        1864 :     virtual FlowMgmtKey *Clone() {
     145        1864 :         return new NhFlowMgmtKey(static_cast<const NextHop *>(db_entry()));
     146             :     }
     147             : 
     148             : private:
     149             :     DISALLOW_COPY_AND_ASSIGN(NhFlowMgmtKey);
     150             : };
     151             : 
     152             : class RouteFlowMgmtKey : public FlowMgmtKey {
     153             : public:
     154        9512 :     static Type AddrToType(const IpAddress &addr) {
     155        9512 :         if (addr.is_v4())
     156        6518 :             return INET4;
     157             : 
     158        2994 :         if (addr.is_v6())
     159        2994 :             return INET6;
     160             : 
     161           0 :         assert(0);
     162             :         return INVALID;
     163             :     }
     164             : 
     165             :     static Type RouteToType(const AgentRoute *rt) {
     166             :         const InetUnicastRouteEntry *inet_rt =
     167             :             dynamic_cast<const InetUnicastRouteEntry *>(rt);
     168             :         if (inet_rt) {
     169             :             return AddrToType(inet_rt->prefix_address());
     170             :         }
     171             : 
     172             :         if (dynamic_cast<const BridgeRouteEntry *>(rt))
     173             :             return BRIDGE;
     174             : 
     175             :         assert(0);
     176             :     }
     177             : 
     178        7352 :     RouteFlowMgmtKey(Type type, uint32_t vrf_id) :
     179        7352 :         FlowMgmtKey(type, NULL), vrf_id_(vrf_id) {
     180        7352 :     }
     181             : 
     182        4192 :     RouteFlowMgmtKey(Type type, const AgentRoute *rt, uint32_t vrf_id) :
     183        4192 :         FlowMgmtKey(type, rt), vrf_id_(vrf_id) {
     184        4192 :     }
     185             : 
     186       11544 :     virtual ~RouteFlowMgmtKey() { }
     187             : 
     188       81139 :     virtual bool UseDBEntry() const { return false; }
     189        2321 :     uint32_t vrf_id() const { return vrf_id_; }
     190             : 
     191             : protected:
     192             :     uint32_t vrf_id_;
     193             : 
     194             : private:
     195             :     DISALLOW_COPY_AND_ASSIGN(RouteFlowMgmtKey);
     196             : };
     197             : 
     198             : class InetRouteFlowMgmtKey : public RouteFlowMgmtKey {
     199             : public:
     200        2856 :     InetRouteFlowMgmtKey(const InetUnicastRouteEntry *route) :
     201        5712 :         RouteFlowMgmtKey(AddrToType(route->prefix_address()), route, route->vrf_id()),
     202        2856 :         ip_(route->prefix_address()), plen_(route->prefix_length()) {
     203        2856 :     }
     204             : 
     205        6656 :     InetRouteFlowMgmtKey(uint32_t vrf_id, const IpAddress &ip, uint8_t plen) :
     206        6656 :         RouteFlowMgmtKey(AddrToType(ip), vrf_id), ip_(ip), plen_(plen) {
     207        6656 :     }
     208             : 
     209       13989 :     virtual ~InetRouteFlowMgmtKey() { }
     210             : 
     211       60588 :     virtual bool Compare(const FlowMgmtKey *rhs) const {
     212       60588 :         const InetRouteFlowMgmtKey *rhs_key =
     213             :             static_cast<const InetRouteFlowMgmtKey *>(rhs);
     214       60588 :         if (vrf_id_ != rhs_key->vrf_id_)
     215       23056 :             return vrf_id_ < rhs_key->vrf_id_;
     216             : 
     217       37532 :         if (ip_ != rhs_key->ip_)
     218       20336 :             return ip_ < rhs_key->ip_;
     219             : 
     220       17196 :         return plen_ < rhs_key->plen_;
     221             :     }
     222             : 
     223             :     class KeyCmp {
     224             :     public:
     225      130081 :         static std::size_t BitLength(const InetRouteFlowMgmtKey *rt) {
     226             :             return (((sizeof(rt->vrf_id_) + sizeof(rt->type_)) << 3) +
     227      130081 :                     rt->plen_);
     228             :         }
     229             : 
     230      238223 :         static char ByteValue(const InetRouteFlowMgmtKey *rt, std::size_t idx) {
     231             :             const char *ch;
     232      238223 :             std::size_t i = idx;
     233      238223 :             if (i < sizeof(rt->vrf_id_)) {
     234       59072 :                 ch = (const char *)&rt->vrf_id_;
     235       59072 :                 return ch[sizeof(rt->vrf_id_) - i - 1];
     236             :             }
     237      179151 :             i -= sizeof(rt->vrf_id_);
     238      179151 :             if (i < sizeof(rt->type_)) {
     239       44216 :                 ch = (const char *)&rt->type_;
     240       44216 :                 return ch[sizeof(rt->type_) - i - 1];
     241             :             }
     242      134935 :             i -= sizeof(rt->type_);
     243      134935 :             if (rt->type_ == INET4) {
     244       52349 :                 return rt->ip_.to_v4().to_bytes()[i];
     245       82586 :             } else if (rt->type_ == INET6) {
     246       82586 :                 return rt->ip_.to_v6().to_bytes()[i];
     247             :             } else {
     248           0 :                 assert(0);
     249             :                 return 0;
     250             :             }
     251             :         }
     252             :     };
     253             : 
     254        3301 :     FlowMgmtKey *Clone() {
     255        3301 :         if (ip_.is_v4()) {
     256        2206 :             return new InetRouteFlowMgmtKey(vrf_id_, ip_.to_v4(), plen_);
     257             :         }
     258             : 
     259        1095 :         if (ip_.is_v6()) {
     260        1095 :             return new InetRouteFlowMgmtKey(vrf_id_, ip_.to_v6(), plen_);
     261             :         }
     262             : 
     263           0 :         return NULL;
     264             :     }
     265             : 
     266           0 :     bool Match(const IpAddress &match_ip) const {
     267           0 :         if (ip_.is_v4()) {
     268           0 :             return (Address::GetIp4SubnetAddress(ip_.to_v4(), plen_) ==
     269           0 :                     Address::GetIp4SubnetAddress(match_ip.to_v4(), plen_));
     270           0 :         } else if (ip_.is_v6()) {
     271           0 :             return (Address::GetIp6SubnetAddress(ip_.to_v6(), plen_) ==
     272           0 :                     Address::GetIp6SubnetAddress(match_ip.to_v6(), plen_));
     273             :         }
     274             : 
     275           0 :         assert(0);
     276             :         return false;
     277             :     }
     278             : 
     279             :     bool NeedsReCompute(const FlowEntry *flow);
     280           0 :     IpAddress ip() const { return ip_; }
     281           0 :     uint8_t plen() const { return plen_; }
     282             : 
     283             : private:
     284             :     friend class InetRouteFlowMgmtTree;
     285             : 
     286             :     IpAddress ip_;
     287             :     uint8_t plen_;
     288             :     Patricia::Node node_;
     289             :     DISALLOW_COPY_AND_ASSIGN(InetRouteFlowMgmtKey);
     290             : };
     291             : 
     292             : class BridgeRouteFlowMgmtKey : public RouteFlowMgmtKey {
     293             : public:
     294        1336 :     BridgeRouteFlowMgmtKey(const BridgeRouteEntry *rt) :
     295        1336 :         RouteFlowMgmtKey(BRIDGE, rt, rt->vrf_id()), mac_(rt->prefix_address()) {
     296        1336 :     }
     297             : 
     298         696 :     BridgeRouteFlowMgmtKey(uint32_t vrf_id, const MacAddress &mac) :
     299         696 :         RouteFlowMgmtKey(BRIDGE, vrf_id), mac_(mac) {
     300         696 :     }
     301             : 
     302        2654 :     virtual ~BridgeRouteFlowMgmtKey() { }
     303             : 
     304       20551 :     virtual bool Compare(const FlowMgmtKey *rhs) const {
     305       20551 :         const BridgeRouteFlowMgmtKey *rhs_key =
     306             :             static_cast<const BridgeRouteFlowMgmtKey *>(rhs);
     307       20551 :         if (vrf_id_ != rhs_key->vrf_id_)
     308        8033 :             return vrf_id_ < rhs_key->vrf_id_;
     309             : 
     310       12518 :         return mac_ < rhs_key->mac_;
     311             :     }
     312             : 
     313         490 :     FlowMgmtKey *Clone() {
     314         490 :         return new BridgeRouteFlowMgmtKey(vrf_id(), mac_);
     315             :     }
     316             : 
     317             : private:
     318             :     friend class BridgeRouteFlowMgmtTree;
     319             : 
     320             :     MacAddress mac_;
     321             :     DISALLOW_COPY_AND_ASSIGN(BridgeRouteFlowMgmtKey);
     322             : };
     323             : 
     324             : class VrfFlowMgmtKey : public FlowMgmtKey {
     325             : public:
     326        2226 :     VrfFlowMgmtKey(const VrfEntry *vrf) :
     327        2226 :         FlowMgmtKey(FlowMgmtKey::VRF, vrf) {
     328        2226 :     }
     329             : 
     330        2300 :     virtual ~VrfFlowMgmtKey() { }
     331             : 
     332          74 :     virtual FlowMgmtKey *Clone() {
     333          74 :         return new VrfFlowMgmtKey(static_cast<const VrfEntry *>(db_entry()));
     334             :     }
     335             : 
     336             : private:
     337             :     DISALLOW_COPY_AND_ASSIGN(VrfFlowMgmtKey);
     338             : };
     339             : 
     340             : class BgpAsAServiceFlowMgmtKey : public FlowMgmtKey {
     341             : public:
     342           0 :     BgpAsAServiceFlowMgmtKey(const boost::uuids::uuid &uuid,
     343             :                              uint32_t source_port,
     344             :                              uint8_t cn_index,
     345             :                              HealthCheckInstanceBase *hc_instance,
     346           0 :                              HealthCheckService *hc_service) :
     347           0 :         FlowMgmtKey(FlowMgmtKey::BGPASASERVICE, NULL), uuid_(uuid),
     348           0 :         source_port_(source_port), cn_index_(cn_index),
     349           0 :         bgp_health_check_instance_(hc_instance),
     350           0 :         bgp_health_check_service_(hc_service) { }
     351             : 
     352           0 :     virtual ~BgpAsAServiceFlowMgmtKey() { }
     353             : 
     354           0 :     virtual FlowMgmtKey *Clone() {
     355           0 :         return new BgpAsAServiceFlowMgmtKey(uuid_, source_port_, cn_index_,
     356             :                                             bgp_health_check_instance_,
     357           0 :                                             bgp_health_check_service_);
     358             :     }
     359             : 
     360           0 :     virtual bool UseDBEntry() const { return false; }
     361             : 
     362           0 :     virtual bool Compare(const FlowMgmtKey *rhs) const {
     363           0 :         const BgpAsAServiceFlowMgmtKey *rhs_key =
     364             :             static_cast<const BgpAsAServiceFlowMgmtKey *>(rhs);
     365           0 :         if (uuid_ != rhs_key->uuid_)
     366           0 :             return uuid_ < rhs_key->uuid_;
     367           0 :         if (cn_index_ != rhs_key->cn_index_)
     368           0 :             return cn_index_< rhs_key->cn_index_;
     369           0 :         return source_port_ < rhs_key->source_port_;
     370             :     }
     371             : 
     372           0 :     const boost::uuids::uuid &uuid() const { return uuid_; }
     373           0 :     uint32_t source_port() const { return source_port_; }
     374           0 :     uint8_t cn_index() const { return cn_index_; }
     375             : 
     376             :     HealthCheckInstanceBase *bgp_health_check_instance() const {
     377             :         return bgp_health_check_instance_;
     378             :     }
     379             : 
     380             :     void StartHealthCheck(Agent *agent, FlowEntry *flow,
     381             :                           const boost::uuids::uuid &hc_uuid);
     382             :     void StopHealthCheck(FlowEntry *flow);
     383             : 
     384             : private:
     385             :     boost::uuids::uuid uuid_;
     386             :     uint32_t source_port_;
     387             :     uint8_t cn_index_; //Control node index
     388             :     // By adding the health check instance here, we ensure one BFD session
     389             :     // per <VMI-SRC-IP, BGP-DEST-IP, VMI>
     390             :     mutable HealthCheckInstanceBase *bgp_health_check_instance_;
     391             :     mutable HealthCheckService *bgp_health_check_service_;
     392             :     DISALLOW_COPY_AND_ASSIGN(BgpAsAServiceFlowMgmtKey);
     393             : };
     394             : 
     395             : #endif // __AGENT_PKT_FLOW_MGMT_KEY_H__

Generated by: LCOV version 1.14