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

Generated by: LCOV version 1.14