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

Generated by: LCOV version 1.14