Skip to content

Commit 277e81c

Browse files
authored
Merge pull request FRRouting#20302 from Pdoijode/pdoijode/bgp-err-codes
Add error codes and improve operator messaging
2 parents 87e0f6b + 77da4c2 commit 277e81c

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

48 files changed

+599
-252
lines changed

bgpd/bgp_attr.c

Lines changed: 18 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -470,9 +470,8 @@ static bool bgp_attr_aigp_get_tlv_metric(uint8_t *pnt, int length,
470470
* and SHOULD be discarded as specified in this section.
471471
*/
472472
if (*aigp == BGP_AIGP_TLV_METRIC_MAX) {
473-
zlog_err("Bad AIGP TLV (%s) length: %llu",
474-
BGP_AIGP_TLV_METRIC_DESC,
475-
BGP_AIGP_TLV_METRIC_MAX);
473+
flog_err(EC_BGP_ATTR_AIGP, "Bad AIGP TLV (%s) length: %llu",
474+
BGP_AIGP_TLV_METRIC_DESC, BGP_AIGP_TLV_METRIC_MAX);
476475
return false;
477476
}
478477

@@ -558,7 +557,7 @@ static bool bgp_attr_aigp_valid(uint8_t *pnt, int length)
558557
uint8_t *end = data + length;
559558

560559
if (length < 3) {
561-
zlog_err("Bad AIGP attribute length (MUST be minimum 3): %u",
560+
flog_err(EC_BGP_ATTR_AIGP, "Bad AIGP attribute length (MUST be minimum 3): %u",
562561
length);
563562
return false;
564563
}
@@ -575,22 +574,22 @@ static bool bgp_attr_aigp_valid(uint8_t *pnt, int length)
575574
(void)data;
576575

577576
if (length < tlv_length) {
578-
zlog_err(
579-
"Bad AIGP attribute length: %u, but TLV length: %u",
580-
length, tlv_length);
577+
flog_err(EC_BGP_ATTR_AIGP,
578+
"Bad AIGP attribute length: %u, but TLV length: %u", length,
579+
tlv_length);
581580
return false;
582581
}
583582

584583
if (tlv_length < 3) {
585-
zlog_err("Bad AIGP TLV length (MUST be minimum 3): %u",
584+
flog_err(EC_BGP_ATTR_AIGP, "Bad AIGP TLV length (MUST be minimum 3): %u",
586585
tlv_length);
587586
return false;
588587
}
589588

590589
/* AIGP TLV, Length: 11 */
591590
if (tlv_type == BGP_AIGP_TLV_METRIC &&
592591
tlv_length != BGP_AIGP_TLV_METRIC_LEN) {
593-
zlog_err("Bad AIGP TLV (%s) length: %u",
592+
flog_err(EC_BGP_ATTR_AIGP, "Bad AIGP TLV (%s) length: %u",
594593
BGP_AIGP_TLV_METRIC_DESC, tlv_length);
595594
return false;
596595
}
@@ -3089,8 +3088,8 @@ static int bgp_attr_encap(struct bgp_attr_parser_args *args)
30893088

30903089
if (!CHECK_FLAG(flag, BGP_ATTR_FLAG_TRANS)
30913090
|| !CHECK_FLAG(flag, BGP_ATTR_FLAG_OPTIONAL)) {
3092-
zlog_err("Tunnel Encap attribute flag isn't optional and transitive %d",
3093-
flag);
3091+
flog_err(EC_BGP_ATTR_FLAG,
3092+
"Tunnel Encap attribute flag isn't optional and transitive %d", flag);
30943093
return bgp_attr_malformed(args, BGP_NOTIFY_UPDATE_OPT_ATTR_ERR,
30953094
args->total);
30963095
}
@@ -3100,8 +3099,8 @@ static int bgp_attr_encap(struct bgp_attr_parser_args *args)
31003099
uint16_t tlv_length;
31013100

31023101
if (length < 4) {
3103-
zlog_err(
3104-
"Tunnel Encap attribute not long enough to contain outer T,L");
3102+
flog_err(EC_BGP_ATTR_LEN,
3103+
"Tunnel Encap attribute not long enough to contain outer T,L");
31053104
return bgp_attr_malformed(args,
31063105
BGP_NOTIFY_UPDATE_OPT_ATTR_ERR,
31073106
args->total);
@@ -3139,15 +3138,17 @@ static int bgp_attr_encap(struct bgp_attr_parser_args *args)
31393138
}
31403139

31413140
if (sublength > length) {
3142-
zlog_err("Tunnel Encap attribute sub-tlv length %d exceeds remaining length %d",
3141+
flog_err(EC_BGP_ATTR_LEN,
3142+
"Tunnel Encap attribute sub-tlv length %d exceeds remaining length %d",
31433143
sublength, length);
31443144
return bgp_attr_malformed(args,
31453145
BGP_NOTIFY_UPDATE_OPT_ATTR_ERR,
31463146
args->total);
31473147
}
31483148

31493149
if (STREAM_READABLE(BGP_INPUT(connection)) < sublength) {
3150-
zlog_err("Tunnel Encap attribute sub-tlv length %d exceeds remaining stream length %zu",
3150+
flog_err(EC_BGP_ATTR_LEN,
3151+
"Tunnel Encap attribute sub-tlv length %d exceeds remaining stream length %zu",
31513152
sublength, STREAM_READABLE(BGP_INPUT(connection)));
31523153
return bgp_attr_malformed(args,
31533154
BGP_NOTIFY_UPDATE_OPT_ATTR_ERR,
@@ -3199,8 +3200,8 @@ static int bgp_attr_encap(struct bgp_attr_parser_args *args)
31993200

32003201
if (length) {
32013202
/* spurious leftover data */
3202-
zlog_err("Tunnel Encap attribute length is bad: %d leftover octets",
3203-
length);
3203+
flog_err(EC_BGP_ATTR_LEN,
3204+
"Tunnel Encap attribute length is bad: %d leftover octets", length);
32043205
return bgp_attr_malformed(args, BGP_NOTIFY_UPDATE_OPT_ATTR_ERR,
32053206
args->total);
32063207
}

bgpd/bgp_errors.c

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -491,6 +491,84 @@ static struct log_ref ferr_bgp_err[] = {
491491
.description = "BGP could not find the label for the specified path_info",
492492
.suggestion = "Most likely a bug. This should never happen. Please try to build a reproducer and report.",
493493
},
494+
{
495+
.code = EC_BGP_ROUTE_REFRESH_INVALID,
496+
.title = "BGP route refresh message format error",
497+
.description = "BGP received an invalid or malformed route refresh message from peer (enhanced route refresh length error, invalid subtype, or EoRR without BoRR)",
498+
.suggestion = "Check BGP capability compatibility with peer. Verify enhanced route refresh configuration and ensure proper BoRR/EoRR sequence.",
499+
},
500+
{
501+
.code = EC_BGP_PER_SRC_NHG,
502+
.title = "BGP per-source nexthop group resolution failed",
503+
.description = "BGP unable to resolve IPv6 nexthop for per-source nexthop group",
504+
.suggestion = "Ensure the nexthop group and advertised paths include IPv6 information. Verify per-source nexthop group configuration.",
505+
},
506+
{
507+
.code = EC_BGP_ROUTE_ATTRIBUTE_MALFORMED,
508+
.title = "BGP route attribute is malformed or invalid",
509+
.description = "BGP received or processed a route with malformed attributes (prefix, RD, ESI, MAC, gateway IP, L2VPN prefix data, address family mismatches, route-map/label-index mismatches) or referenced route not found",
510+
.suggestion = "Check route definitions and EVPN/L2VPN configuration. Verify peer configuration for attribute consistency, address family matching, and static route configuration alignment. Ensure all referenced routes exist and route data format is correct.",
511+
},
512+
{
513+
.code = EC_BGP_CONFIG_CONSTRAINT_VIOLATION,
514+
.title = "BGP configuration constraint violated",
515+
.description = "BGP configuration attempted to change an immutable parameter (e.g., label-index)",
516+
.suggestion = "Review configuration changes to ensure immutable parameters are not modified after initial setup.",
517+
},
518+
{
519+
.code = EC_BGP_ROUTE_MAP_SCRIPT,
520+
.title = "BGP route-map script execution failed",
521+
.description = "BGP route-map script or function failed to load or execute properly",
522+
.suggestion = "Debug the route-map script and ensure it returns successful status. Verify script accessibility and correct any errors in the script file.",
523+
},
524+
{
525+
.code = EC_BGP_VRF_NOT_FOUND,
526+
.title = "BGP VRF not found",
527+
.description = "BGP requested VRF does not exist or cannot be found",
528+
.suggestion = "Create the required VRF or correct the configured VRF name.",
529+
},
530+
{
531+
.code = EC_BGP_ZEBRA_MSG_DECODE,
532+
.title = "BGP failed to decode message from Zebra",
533+
.description = "BGP received a malformed or incompatible message from Zebra daemon",
534+
.suggestion = "Ensure BGP and Zebra daemons are version-synchronized and IPC communication is healthy. Check for version mismatches between daemons.",
535+
},
536+
{
537+
.code = EC_BGP_SRV6_LOCATOR_MISMATCH,
538+
.title = "BGP SRv6 locator name mismatch",
539+
.description = "BGP SRv6 locator advertised by BGP doesn't match the locator name in the SRv6 chunk from Zebra",
540+
.suggestion = "Fix the inconsistent SRv6 locator configuration between BGP and Zebra.",
541+
},
542+
{
543+
.code = EC_BGP_INVALID_BGP_INSTANCE_ID,
544+
.title = "BGP instance ID out of range",
545+
.description = "BGP instance ID specified is outside the valid range",
546+
.suggestion = "Set a valid instance ID in the configuration within the allowed range.",
547+
},
548+
{
549+
.code = EC_BGP_SRV6_SID_MODE_CONFLICT,
550+
.title = "BGP SRv6 SID mode configuration conflict",
551+
.description = "BGP SRv6 configuration has both index-mode and auto-mode enabled simultaneously",
552+
.suggestion = "Choose one SRv6 SID mode (typically auto), remove the other from the config, and reapply the import/export settings.",
553+
},
554+
{
555+
.code = EC_BGP_CONFIG_TIMEOUT,
556+
.title = "BGP configuration timeout",
557+
.description = "BGP configuration end timer expired during config application",
558+
.suggestion = "Review provisioning speed or increase the configuration timeout value.",
559+
},
560+
{
561+
.code = EC_BGP_LABEL_POOL_INSERT_FAIL,
562+
.title = "BGP label pool insertion failed",
563+
.description = "BGP failed to insert a label into the label pool tracking structure",
564+
.suggestion = "Restart BGP service. If issues persist, gather log files and open an issue.",
565+
},
566+
{
567+
.code = EC_BGP_TTL_SECURITY_FAIL,
568+
.title = "BGP TTL security configuration failed",
569+
.description = "BGP failed to configure TTL security parameters (min/max TTL) on peer connection",
570+
.suggestion = "Ensure both peers support TTL security feature and verify kernel supports TTL security socket options. Check peer TTL security configuration for compatibility.",
571+
},
494572
{
495573
.code = END_FERR,
496574
}

bgpd/bgp_errors.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,19 @@ enum bgp_log_refs {
9393
EC_BGP_SENDQ_STUCK_WARN,
9494
EC_BGP_SENDQ_STUCK_PROPER,
9595
EC_BGP_PATH_WITHOUT_LABEL,
96+
EC_BGP_ROUTE_REFRESH_INVALID,
97+
EC_BGP_PER_SRC_NHG,
98+
EC_BGP_ROUTE_ATTRIBUTE_MALFORMED,
99+
EC_BGP_CONFIG_CONSTRAINT_VIOLATION,
100+
EC_BGP_ROUTE_MAP_SCRIPT,
101+
EC_BGP_VRF_NOT_FOUND,
102+
EC_BGP_ZEBRA_MSG_DECODE,
103+
EC_BGP_SRV6_LOCATOR_MISMATCH,
104+
EC_BGP_INVALID_BGP_INSTANCE_ID,
105+
EC_BGP_SRV6_SID_MODE_CONFLICT,
106+
EC_BGP_CONFIG_TIMEOUT,
107+
EC_BGP_LABEL_POOL_INSERT_FAIL,
108+
EC_BGP_TTL_SECURITY_FAIL,
96109
};
97110

98111
extern void bgp_error_init(void);

bgpd/bgp_fsm.c

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1927,8 +1927,8 @@ static void bgp_connect_check(struct event *event)
19271927

19281928
/* If getsockopt is fail, this is fatal error. */
19291929
if (ret < 0) {
1930-
zlog_err("can't get sockopt for nonblocking connect: %d(%s)",
1931-
errno, safe_strerror(errno));
1930+
flog_err(EC_LIB_SOCKET, "can't get sockopt for nonblocking connect: %d(%s)", errno,
1931+
safe_strerror(errno));
19321932
BGP_EVENT_ADD(connection, TCP_fatal_error);
19331933
return;
19341934
}
@@ -2936,7 +2936,7 @@ bgp_peer_inherit_global_gr_mode(struct peer *peer,
29362936
break;
29372937
case GLOBAL_INVALID:
29382938
default:
2939-
zlog_err("Unexpected Global GR mode %d", global_gr_mode);
2939+
flog_err(EC_LIB_DEVELOPMENT, "Unexpected Global GR mode %d", global_gr_mode);
29402940
}
29412941
}
29422942

@@ -3240,8 +3240,8 @@ void bgp_peer_move_to_gr_mode(struct peer *peer, enum peer_mode new_state)
32403240
break;
32413241
case PEER_INVALID:
32423242
default:
3243-
zlog_err(
3244-
"[BGP_GR] Default switch mode ::: SOMETHING IS WRONG !!!");
3243+
flog_err(EC_LIB_DEVELOPMENT,
3244+
"[BGP_GR] Default switch mode ::: SOMETHING IS WRONG !!!");
32453245
break;
32463246
}
32473247
bgp_peer_gr_flags_update(peer);

bgpd/bgp_labelpool.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -296,8 +296,9 @@ static mpls_label_t get_label_from_pool(void *labelid)
296296
lbl = chunk->first + index;
297297
if (skiplist_insert(lp->inuse, (void *)lbl, labelid)) {
298298
/* something is very wrong */
299-
zlog_err("%s: unable to insert inuse label %u (id %p)",
300-
__func__, (uint32_t)lbl, labelid);
299+
flog_err(EC_BGP_LABEL_POOL_INSERT_FAIL,
300+
"%s: unable to insert inuse label %u (id %p)", __func__,
301+
(uint32_t)lbl, labelid);
301302
return MPLS_LABEL_NONE;
302303
}
303304

bgpd/bgp_main.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -484,8 +484,9 @@ int main(int argc, char **argv)
484484
case 'I':
485485
instance = atoi(optarg);
486486
if (instance > (unsigned short)-1)
487-
zlog_err("Instance %i out of range (0..%u)",
488-
instance, (unsigned short)-1);
487+
flog_err(EC_BGP_INVALID_BGP_INSTANCE_ID,
488+
"Instance %i out of range (0..%u)", instance,
489+
(unsigned short)-1);
489490
break;
490491
case 's':
491492
buffer_size = atoi(optarg);

bgpd/bgp_mplsvpn.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -827,7 +827,8 @@ void ensure_vrf_tovpn_sid_per_af(struct bgp *bgp_vpn, struct bgp *bgp_vrf,
827827
if ((tovpn_sid_index != 0 && tovpn_sid_auto) ||
828828
(tovpn_sid_index != 0 && is_tovpn_sid_explicit) ||
829829
(tovpn_sid_auto && is_tovpn_sid_explicit)) {
830-
zlog_err("%s: more than one mode selected among index-mode, auto-mode and explicit-mode. ignored.",
830+
flog_err(EC_BGP_SRV6_SID_MODE_CONFLICT,
831+
"%s: more than one mode selected among index-mode, auto-mode and explicit-mode. ignored.",
831832
__func__);
832833
return;
833834
}
@@ -915,7 +916,8 @@ void ensure_vrf_tovpn_sid_per_vrf(struct bgp *bgp_vpn, struct bgp *bgp_vrf)
915916
if ((tovpn_sid_index != 0 && tovpn_sid_auto) ||
916917
(tovpn_sid_index != 0 && is_tovpn_sid_explicit) ||
917918
(tovpn_sid_auto && is_tovpn_sid_explicit)) {
918-
zlog_err("%s: more than one mode selected among index-mode, auto-mode and explicit-mode. ignored.",
919+
flog_err(EC_BGP_SRV6_SID_MODE_CONFLICT,
920+
"%s: more than one mode selected among index-mode, auto-mode and explicit-mode. ignored.",
919921
__func__);
920922
return;
921923
}

bgpd/bgp_network.c

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -217,11 +217,10 @@ static void bgp_update_setsockopt_tcp_keepalive(struct bgp *bgp, int fd)
217217
bgp->tcp_keepalive_intvl,
218218
bgp->tcp_keepalive_probes);
219219
if (ret < 0)
220-
zlog_err(
221-
"Can't set TCP keepalive on socket %d, idle %u intvl %u probes %u",
222-
fd, bgp->tcp_keepalive_idle,
223-
bgp->tcp_keepalive_intvl,
224-
bgp->tcp_keepalive_probes);
220+
flog_err(EC_LIB_SOCKET,
221+
"Can't set TCP keepalive on socket %d, idle %u intvl %u probes %u",
222+
fd, bgp->tcp_keepalive_idle, bgp->tcp_keepalive_intvl,
223+
bgp->tcp_keepalive_probes);
225224
}
226225
}
227226

@@ -522,7 +521,8 @@ static void bgp_accept(struct event *event)
522521

523522
if (bgp_set_socket_ttl(incoming) < 0) {
524523
peer_set_last_reset(dynamic_peer, PEER_DOWN_SOCKET_ERROR);
525-
zlog_err("%s: Unable to set min/max TTL on peer %s (dynamic), error received: %s(%d)",
524+
flog_err(EC_BGP_TTL_SECURITY_FAIL,
525+
"%s: Unable to set min/max TTL on peer %s (dynamic), error received: %s(%d)",
526526
__func__, dynamic_peer->host, safe_strerror(errno), errno);
527527
frrtrace(3, frr_bgp, bgp_err_str, dynamic_peer->host,
528528
dynamic_peer->flags, 1);

0 commit comments

Comments
 (0)