LCOV - code coverage report
Current view: top level - bgp - bgp_proto.h (source / functions) Hit Total Coverage
Test: OpenSDN C/C++ coverage (all TARGET_SET jobs) Lines: 102 174 58.6 %
Date: 2026-11-09 02:10:49 Functions: 24 25 96.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             : #ifndef SRC_BGP_BGP_PROTO_H_
       7             : #define SRC_BGP_BGP_PROTO_H_
       8             : 
       9             : #include <sstream>
      10             : #include <string>
      11             : #include <vector>
      12             : 
      13             : #include "base/parse_object.h"
      14             : #include "bgp/bgp_attr.h"
      15             : #include "bgp/community.h"
      16             : 
      17             : struct BgpMpNlri;
      18             : class BgpPeer;
      19             : 
      20             : class BgpProto {
      21             : public:
      22             :     enum MessageType {
      23             :         OPEN = 1,
      24             :         UPDATE = 2,
      25             :         NOTIFICATION = 3,
      26             :         KEEPALIVE = 4
      27             :     };
      28             : 
      29             :     enum BgpPeerType {
      30             :         IBGP,
      31             :         EBGP,
      32             :         XMPP,
      33             :     };
      34             : 
      35           4 :     static std::string BgpPeerTypeString(BgpPeerType peer_type) {
      36           4 :         switch (peer_type) {
      37           4 :         case IBGP:
      38           4 :             return "IBGP";
      39             :             break;
      40           0 :         case EBGP:
      41           0 :             return "EBGP";
      42             :             break;
      43           0 :         case XMPP:
      44           0 :             return "XMPP";
      45             :             break;
      46             :         }
      47           0 :         assert(false);
      48             :         return "OTHER";
      49             :     }
      50             : 
      51             :     struct BgpMessage : public ParseObject {
      52      405171 :         explicit BgpMessage(MessageType type) : type(type) {
      53      405169 :         }
      54             :         MessageType type;
      55           0 :         virtual const std::string ToString() const { return ""; }
      56             :     };
      57             : 
      58             :     struct OpenMessage : public BgpMessage {
      59             :         enum OpenOptParamTypes {
      60             :             OPEN_OPT_CAPABILITIES = 2,
      61             :         };
      62             : 
      63             :         OpenMessage();
      64             :         ~OpenMessage();
      65             :         int Validate(BgpPeer *peer) const;
      66             :         uint32_t as_num;
      67             :         int32_t holdtime;
      68             :         uint32_t identifier;
      69             : 
      70             :         struct Capability : public ParseObject {
      71             :             enum CapabilityCode {
      72             :                 Reserved = 0,
      73             :                 MpExtension = 1,
      74             :                 RouteRefresh = 2,
      75             :                 OutboundRouteFiltering = 3,
      76             :                 MultipleRoutesToADestination = 4,
      77             :                 ExtendedNextHop = 5,
      78             :                 GracefulRestart = 64,
      79             :                 AS4Support = 65,
      80             :                 Dynamic = 67,
      81             :                 MultisessionBgp = 68,
      82             :                 AddPath = 69,
      83             :                 EnhancedRouteRefresh = 70,
      84             :                 LongLivedGracefulRestart = 71,
      85             :                 RouteRefreshCisco = 128
      86             :             };
      87       33173 :             static std::string CapabilityToString(int capability) {
      88       33173 :                 switch (capability) {
      89           0 :                 case Reserved:
      90           0 :                     return "Reserved";
      91       21304 :                 case MpExtension:
      92       21304 :                     return "MpExtension";
      93         122 :                 case RouteRefresh:
      94         122 :                     return "RouteRefresh";
      95           0 :                 case OutboundRouteFiltering:
      96           0 :                     return "OutboundRouteFiltering";
      97           0 :                 case MultipleRoutesToADestination:
      98           0 :                     return "MultipleRoutesToADestination";
      99           0 :                 case ExtendedNextHop:
     100           0 :                     return "ExtendedNextHop";
     101        6585 :                 case GracefulRestart:
     102        6585 :                     return "GracefulRestart";
     103         122 :                 case AS4Support:
     104         122 :                     return "AS4Support";
     105           0 :                 case Dynamic:
     106           0 :                     return "Dynamic";
     107           0 :                 case MultisessionBgp:
     108           0 :                     return "MultisessionBgp";
     109           0 :                 case AddPath:
     110           0 :                     return "AddPath";
     111           0 :                 case EnhancedRouteRefresh:
     112           0 :                     return "EnhancedRouteRefresh";
     113        4918 :                 case LongLivedGracefulRestart:
     114        4918 :                     return "LongLivedGracefulRestart";
     115         122 :                 case RouteRefreshCisco:
     116         122 :                     return "RouteRefreshCisco";
     117             :                 }
     118             : 
     119           0 :                 std::ostringstream oss;
     120           0 :                 oss << "Unknown(" << capability << ")";
     121           0 :                 return oss.str();
     122             :             }
     123       23641 :             Capability() : code(Reserved) { }
     124      434221 :             explicit Capability(int code, const uint8_t *src, int size) :
     125      434221 :                 code(code), capability(src, src + size) {}
     126             : 
     127             :             struct GR {
     128             :                 enum Flags {
     129             :                     ForwardingStatePreservedFlag = 0x80,
     130             :                     RestartedFlag = 0x8000,
     131             :                     NotificationFlag = 0x4000,
     132             :                     RestartTimeMask = 0x0FFF,
     133             :                 };
     134      213689 :                 explicit GR() { Initialize(); }
     135     1429786 :                 void Initialize() {
     136     1429786 :                     flags = 0;
     137     1429786 :                     time = 0;
     138     1429786 :                     families.clear();
     139     1429786 :                 }
     140             :                 struct Family {
     141      610613 :                     Family(uint16_t afi, uint8_t safi, uint8_t flags) :
     142      610613 :                         afi(afi), safi(safi), flags(flags) { }
     143             :                     uint16_t afi;
     144             :                     uint8_t  safi;
     145             :                     uint8_t  flags;
     146             : 
     147       19505 :                     bool forwarding_state_preserved() const {
     148       19505 :                         return (flags & ForwardingStatePreservedFlag) != 0;
     149             :                     }
     150             :                 };
     151             :                 static Capability *Encode(uint16_t gr_time, bool restarted,
     152             :                         bool notification,
     153             :                         const std::vector<uint8_t> &gr_afi_flags,
     154             :                         const std::vector<Address::Family> &gr_families);
     155             :                 static bool Decode(GR *gr_params,
     156             :                         const std::vector<Capability *> &capabilities);
     157             :                 static void GetFamilies(const GR &gr_params,
     158             :                                         std::vector<std::string> *families);
     159           8 :                 bool restarted() const { return (flags & RestartedFlag) != 0; }
     160        2527 :                 bool notification() const {
     161        2527 :                     return (flags & NotificationFlag) != 0;
     162             :                 }
     163      405131 :                 void set_flags(uint16_t gr_cap_bytes) {
     164      405131 :                     flags = gr_cap_bytes & ~RestartTimeMask;
     165      405131 :                 }
     166      405131 :                 void set_time(uint16_t gr_cap_bytes) {
     167      405131 :                     time = gr_cap_bytes & RestartTimeMask;
     168      405131 :                 }
     169             :                 uint16_t flags;
     170             :                 uint16_t time;
     171             :                 std::vector<Family> families;
     172             :             };
     173             : 
     174             :             struct LLGR {
     175             :                 enum {
     176             :                     ForwardingStatePreservedFlag = 0x80,
     177             :                     RestartTimeMask = 0x00FFFFFF,
     178             :                 };
     179      213688 :                 explicit LLGR() { Initialize(); }
     180     1424152 :                 void Initialize() {
     181     1424152 :                     time = 0;
     182     1424152 :                     families.clear();
     183     1424152 :                 }
     184             :                 struct Family {
     185      610595 :                     Family(uint16_t afi, uint8_t safi, uint8_t flags,
     186      610595 :                            uint32_t time) :
     187      610595 :                             afi(afi), safi(safi), flags(flags), time(time) {
     188      610595 :                     }
     189             :                     uint16_t afi;
     190             :                     uint8_t  safi;
     191             :                     uint8_t  flags;
     192             :                     uint32_t time; // 24 bits only
     193             : 
     194       19293 :                     bool forwarding_state_preserved() const {
     195       19293 :                         return (flags & ForwardingStatePreservedFlag) != 0;
     196             :                     }
     197             :                 };
     198             : 
     199             :                 static Capability *Encode(uint32_t llgr_time,
     200             :                         uint8_t llgr_afi_flags,
     201             :                         const std::vector<Address::Family> &llgr_families);
     202             :                 static bool Decode(LLGR *llgr_params,
     203             :                         const std::vector<Capability *> &capabilities);
     204             :                 static void GetFamilies(const LLGR &llgr_params,
     205             :                                         std::vector<std::string> *families);
     206             :                 uint32_t time;
     207             :                 std::vector<Family> families;
     208             :             };
     209             : 
     210             :             int code;
     211             :             std::vector<uint8_t> capability;
     212             :         };
     213             : 
     214             :         struct OptParam : public ParseObject {
     215       31877 :             ~OptParam() {
     216       15938 :                 STLDeleteValues(&capabilities);
     217       31878 :             }
     218             :             std::vector<Capability *> capabilities;
     219             :         };
     220             :         std::vector<OptParam *> opt_params;
     221             :         static BgpProto::OpenMessage *Decode(const uint8_t *data, size_t size);
     222             :         static int EncodeData(OpenMessage *msg, uint8_t *data, size_t size);
     223             :         virtual const std::string ToString() const;
     224             : 
     225             :     private:
     226             :         int ValidateCapabilities(BgpPeer *peer) const;
     227             :         int EncodeCapabilities(OpenMessage *msg, uint8_t *data, size_t size);
     228             :     };
     229             : 
     230             :     struct Notification : public BgpMessage {
     231             :         enum Code {
     232             :             MsgHdrErr = 1,
     233             :             OpenMsgErr = 2,
     234             :             UpdateMsgErr = 3,
     235             :             HoldTimerExp = 4,
     236             :             FSMErr = 5,
     237             :             Cease = 6
     238             :         };
     239             :         static std::string CodeToString(Code code) {
     240             :             switch (code) {
     241             :             case MsgHdrErr:
     242             :                 return "Message Header Error";
     243             :             case OpenMsgErr:
     244             :                 return "OPEN Message Error";
     245             :             case UpdateMsgErr:
     246             :                 return "UPDATE Message Error";
     247             :             case HoldTimerExp:
     248             :                 return "Hold Timer Expired";
     249             :             case FSMErr:
     250             :                 return "Finite State Machine Error";
     251             :             case Cease:
     252             :                 return "Cease";
     253             :             }
     254             : 
     255             :             std::ostringstream oss;
     256             :             oss << "Unknown(" << code << ")";
     257             :             return oss.str();
     258             :         }
     259             :         enum MsgHdrSubCode {
     260             :             ConnNotSync = 1,
     261             :             BadMsgLength = 2,
     262             :             BadMsgType = 3,
     263             :         };
     264          10 :         static std::string MsgHdrSubcodeToString(MsgHdrSubCode sub_code) {
     265          10 :             switch (sub_code) {
     266           0 :             case ConnNotSync:
     267           0 :                 return "Connection Not Synchronized";
     268           0 :             case BadMsgLength:
     269           0 :                 return "Bad Message Length";
     270           0 :             case BadMsgType:
     271           0 :                 return "Bad Message Type";
     272             :             }
     273             : 
     274          20 :             std::ostringstream oss;
     275          10 :             oss << "Unknown(" << sub_code << ")";
     276          10 :             return oss.str();
     277             :         }
     278             :         enum OpenMsgSubCode {
     279             :             UnsupportedVersion = 1,
     280             :             BadPeerAS = 2,
     281             :             BadBgpId = 3,
     282             :             UnsupportedOptionalParam = 4,
     283             :             AuthenticationFailure = 5,
     284             :             UnacceptableHoldTime = 6,
     285             :             UnsupportedCapability = 7
     286             :         };
     287         267 :         static std::string OpenMsgSubcodeToString(OpenMsgSubCode sub_code) {
     288         267 :             switch (sub_code) {
     289           0 :             case UnsupportedVersion:
     290           0 :                 return "Unsupported Version Number";
     291         222 :             case BadPeerAS:
     292         222 :                 return "Bad Peer AS";
     293           8 :             case BadBgpId:
     294           8 :                 return "Bad BGP Identifier";
     295           0 :             case UnsupportedOptionalParam:
     296           0 :                 return "Unsupported Optional Parameter";
     297           0 :             case AuthenticationFailure:
     298           0 :                 return "Authentication Failure";
     299           0 :             case UnacceptableHoldTime:
     300           0 :                 return "Unacceptable Hold Time";
     301          27 :             case UnsupportedCapability:
     302          27 :                 return "Unsupported Capability";
     303             :             }
     304             : 
     305          20 :             std::ostringstream oss;
     306          10 :             oss << "Unknown(" << sub_code << ")";
     307          10 :             return oss.str();
     308             :         }
     309             :         enum UpdateMsgSubCode {
     310             :             MalformedAttributeList = 1,
     311             :             UnrecognizedWellKnownAttrib = 2,
     312             :             MissingWellKnownAttrib = 3,
     313             :             AttribFlagsError = 4,
     314             :             AttribLengthError = 5,
     315             :             InvalidOrigin = 6,
     316             :             InvalidNH = 8,
     317             :             OptionalAttribError = 9,
     318             :             InvalidNetworkField = 10,
     319             :             MalformedASPath = 11
     320             :         };
     321          10 :         static std::string UpdateMsgSubCodeToString(UpdateMsgSubCode sub_code) {
     322          10 :             switch (sub_code) {
     323           0 :             case MalformedAttributeList:
     324           0 :                 return "Malformed Attribute List";
     325           0 :             case UnrecognizedWellKnownAttrib:
     326           0 :                 return "Unrecognized Well-known Attribute";
     327           0 :             case MissingWellKnownAttrib:
     328           0 :                 return "Missing Well-known Attribute";
     329           0 :             case AttribFlagsError:
     330           0 :                 return "Attribute Flags Error";
     331           0 :             case AttribLengthError:
     332           0 :                 return "Attribute Length Error";
     333           0 :             case InvalidOrigin:
     334           0 :                 return "Invalid ORIGIN Attribute";
     335           0 :             case InvalidNH:
     336           0 :                 return "Invalid NEXT_HOP Attribute";
     337           0 :             case OptionalAttribError:
     338           0 :                 return "Optional Attribute Error";
     339           0 :             case InvalidNetworkField:
     340           0 :                 return "Invalid Network Field";
     341           0 :             case MalformedASPath:
     342           0 :                 return "Malformed AS_PATH";
     343             :             }
     344             : 
     345          20 :             std::ostringstream oss;
     346          10 :             oss << "Unknown(" << sub_code << ")";
     347          10 :             return oss.str();
     348             :         }
     349             :         enum FsmSubcode {
     350             :             UnspecifiedError = 0,
     351             :             OpenSentError = 1,
     352             :             OpenConfirmError = 2,
     353             :             EstablishedError = 3
     354             :         };
     355          22 :         static std::string FsmSubcodeToString(FsmSubcode sub_code) {
     356          22 :             switch (sub_code) {
     357          22 :             case UnspecifiedError:
     358          22 :                 return "Unspecified Error";
     359           0 :             case OpenSentError:
     360           0 :                 return "Receive Unexpected Message in OpenSent State";
     361           0 :             case OpenConfirmError:
     362           0 :                 return "Receive Unexpected Message in OpenConfirm State";
     363           0 :             case EstablishedError:
     364           0 :                 return "Receive Unexpected Message in Established State";
     365             :             }
     366             : 
     367           0 :             std::ostringstream oss;
     368           0 :             oss << "Unknown(" << sub_code << ")";
     369           0 :             return oss.str();
     370             :         }
     371             :         enum CeaseSubCode {
     372             :             Unknown = 0,
     373             :             MaxPrefixes = 1,
     374             :             AdminShutdown = 2,
     375             :             PeerDeconfigured = 3,
     376             :             AdminReset = 4,
     377             :             ConnectionRejected = 5,
     378             :             OtherConfigChange = 6,
     379             :             ConnectionCollision = 7,
     380             :             OutOfResources = 8,
     381             :             HardReset = 9,
     382             :         };
     383             : 
     384       14212 :         static std::string CeaseSubcodeToString(CeaseSubCode sub_code) {
     385       14212 :             switch (sub_code) {
     386         576 :             case Unknown:
     387         576 :                 return "Unspecified Error";
     388         584 :             case MaxPrefixes:
     389         584 :                 return "Received Maximum prefixes from peer";
     390        4533 :             case AdminShutdown:
     391        4533 :                 return "Administrator has disabled the peer";
     392        4647 :             case PeerDeconfigured:
     393        4647 :                 return "Administrator has unconfigured the peer";
     394          24 :             case AdminReset:
     395          24 :                 return "Administrator reset the peer";
     396         268 :             case ConnectionRejected:
     397         268 :                 return "Connection is rejected by the peer";
     398        1101 :             case OtherConfigChange:
     399        1101 :                 return "Peer configuration has changed";
     400        2462 :             case ConnectionCollision:
     401        2462 :                 return "Connection collision";
     402           0 :             case OutOfResources:
     403           0 :                 return "Unable handle peer due to resource limit";
     404          16 :             case HardReset:
     405          16 :                 return "Received HardReset to skip GR Helper mode";
     406             :             }
     407             : 
     408           1 :             std::ostringstream oss;
     409           0 :             oss << "Unknown(" << sub_code << ")";
     410           0 :             return oss.str();
     411             :         }
     412             : 
     413             :         Notification();
     414             :         int error;
     415             :         int subcode;
     416             :         std::string data;
     417             :         static BgpProto::Notification *Decode(const uint8_t *data, size_t size);
     418             :         static int EncodeData(Notification *msg, uint8_t *data, size_t size);
     419             :         virtual const std::string ToString() const;
     420             :         static const std::string toString(Code code, int subcode);
     421             :     };
     422             : 
     423             :     struct Keepalive : public BgpMessage {
     424             :         Keepalive();
     425             :         static BgpProto::Keepalive *Decode(const uint8_t *data, size_t size);
     426             :     };
     427             : 
     428             :     struct Update : public BgpMessage {
     429             :         Update();
     430             :         ~Update();
     431             :         int Validate(const BgpPeer *, std::string *data);
     432             :         int CompareTo(const Update &rhs) const;
     433             :         static BgpProto::Update *Decode(const uint8_t *data, size_t size);
     434             : 
     435             :         std::vector <BgpProtoPrefix *> withdrawn_routes;
     436             :         std::vector <BgpAttribute *> path_attributes;
     437             :         std::vector <BgpProtoPrefix *> nlri;
     438             :         static int EncodeData(Update *msg, uint8_t *data, size_t size);
     439             :     };
     440             : 
     441             :     static const int kMinMessageSize = 19;
     442             :     static const int kMaxMessageSize = 4096;
     443             : 
     444             :     static BgpMessage *Decode(const uint8_t *data, size_t size,
     445             :                               ParseErrorContext *ec = NULL, bool as4 = false);
     446             : 
     447             :     static int Encode(const BgpMessage *msg, uint8_t *data, size_t size,
     448             :                       EncodeOffsets *offsets = NULL, bool as4 = false);
     449             :     static int Encode(const BgpMpNlri *msg, uint8_t *data, size_t size,
     450             :                       EncodeOffsets *offsets = NULL);
     451             : };
     452             : 
     453             : #endif  // SRC_BGP_BGP_PROTO_H_

Generated by: LCOV version 1.14