-
Notifications
You must be signed in to change notification settings - Fork 1.5k
Bgp capability common #22254
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Bgp capability common #22254
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -89,8 +89,54 @@ const size_t cap_modsizes[] = { | |
| [CAPABILITY_CODE_ROLE] = 1, | ||
| [CAPABILITY_CODE_SOFT_VERSION] = 1, | ||
| [CAPABILITY_CODE_PATHS_LIMIT] = 5, | ||
| [CAPABILITY_CODE_LINK_LOCAL] = 1, | ||
| }; | ||
|
|
||
| bool bgp_capability_length_check(struct peer_connection *connection, uint8_t code, uint16_t length) | ||
| { | ||
| struct peer *peer = connection->peer; | ||
|
|
||
| switch (code) { | ||
| case CAPABILITY_CODE_MP: | ||
| case CAPABILITY_CODE_REFRESH: | ||
| case CAPABILITY_CODE_ORF: | ||
| case CAPABILITY_CODE_RESTART: | ||
| case CAPABILITY_CODE_AS4: | ||
| case CAPABILITY_CODE_ADDPATH: | ||
| case CAPABILITY_CODE_DYNAMIC: | ||
| case CAPABILITY_CODE_ENHE: | ||
| case CAPABILITY_CODE_FQDN: | ||
| case CAPABILITY_CODE_ENHANCED_RR: | ||
| case CAPABILITY_CODE_EXT_MESSAGE: | ||
| case CAPABILITY_CODE_ROLE: | ||
| case CAPABILITY_CODE_SOFT_VERSION: | ||
| case CAPABILITY_CODE_PATHS_LIMIT: | ||
| case CAPABILITY_CODE_LLGR: | ||
| case CAPABILITY_CODE_LINK_LOCAL: | ||
| if (length < cap_minsizes[code]) { | ||
| zlog_info("%pBP: %s Capability length error: got %u, expected at least %u", | ||
| peer, lookup_msg(capcode_str, code, NULL), length, | ||
| (unsigned int)cap_minsizes[code]); | ||
| bgp_notify_send(connection, BGP_NOTIFY_OPEN_ERR, | ||
| BGP_NOTIFY_OPEN_MALFORMED_ATTR); | ||
| return false; | ||
| } | ||
| if (length && length % cap_modsizes[code] != 0) { | ||
| zlog_info("%pBP: %s Capability length error: got %u, expected a multiple of %u", | ||
| peer, lookup_msg(capcode_str, code, NULL), length, | ||
| (unsigned int)cap_modsizes[code]); | ||
| bgp_notify_send(connection, BGP_NOTIFY_OPEN_ERR, | ||
| BGP_NOTIFY_OPEN_MALFORMED_ATTR); | ||
| return false; | ||
| } | ||
| break; | ||
| default: | ||
| break; | ||
| } | ||
|
Comment on lines
+99
to
+135
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Prompt To Fix With AIThis is a comment left during a code review.
Path: bgpd/bgp_open.c
Line: 99-134
Comment:
**`CAPABILITY_CODE_LLGR` missing from shared length-check**
`CAPABILITY_CODE_LLGR` has entries in both `cap_minsizes` and `cap_modsizes` (lines 64 and 88 respectively), but it is absent from the switch in `bgp_capability_length_check`. This was pre-existing in both original switch blocks, but now that those blocks are consolidated into a single authoritative function, it becomes more visible: LLGR capability lengths are never validated. Any peer sending a malformed LLGR capability can bypass the sanity check entirely.
How can I resolve this? If you propose a fix, please make it concise. |
||
|
|
||
| return true; | ||
| } | ||
|
|
||
| /* BGP-4 Multiprotocol Extensions lead us to the complex world. We can | ||
| negotiate remote peer supports extensions or not. But if | ||
| remote-peer doesn't supports negotiation process itself. We would | ||
|
|
@@ -1116,53 +1162,8 @@ static int bgp_capability_parse(struct peer_connection *connection, size_t lengt | |
| caphdr.code, caphdr.length); | ||
|
|
||
| /* Length sanity check, type-specific, for known capabilities */ | ||
| switch (caphdr.code) { | ||
| case CAPABILITY_CODE_MP: | ||
| case CAPABILITY_CODE_REFRESH: | ||
| case CAPABILITY_CODE_ORF: | ||
| case CAPABILITY_CODE_RESTART: | ||
| case CAPABILITY_CODE_AS4: | ||
| case CAPABILITY_CODE_ADDPATH: | ||
| case CAPABILITY_CODE_DYNAMIC: | ||
| case CAPABILITY_CODE_ENHE: | ||
| case CAPABILITY_CODE_FQDN: | ||
| case CAPABILITY_CODE_ENHANCED_RR: | ||
| case CAPABILITY_CODE_EXT_MESSAGE: | ||
| case CAPABILITY_CODE_ROLE: | ||
| case CAPABILITY_CODE_SOFT_VERSION: | ||
| case CAPABILITY_CODE_PATHS_LIMIT: | ||
| case CAPABILITY_CODE_LLGR: | ||
| /* Check length. */ | ||
| if (caphdr.length < cap_minsizes[caphdr.code]) { | ||
| zlog_info( | ||
| "%s %s Capability length error: got %u, expected at least %u", | ||
| peer->host, | ||
| lookup_msg(capcode_str, caphdr.code, | ||
| NULL), | ||
| caphdr.length, | ||
| (unsigned)cap_minsizes[caphdr.code]); | ||
| bgp_notify_send(connection, BGP_NOTIFY_OPEN_ERR, | ||
| BGP_NOTIFY_OPEN_MALFORMED_ATTR); | ||
| return -1; | ||
| } | ||
| if (caphdr.length | ||
| && caphdr.length % cap_modsizes[caphdr.code] != 0) { | ||
| zlog_info( | ||
| "%s %s Capability length error: got %u, expected a multiple of %u", | ||
| peer->host, | ||
| lookup_msg(capcode_str, caphdr.code, | ||
| NULL), | ||
| caphdr.length, | ||
| (unsigned)cap_modsizes[caphdr.code]); | ||
| bgp_notify_send(connection, BGP_NOTIFY_OPEN_ERR, | ||
| BGP_NOTIFY_OPEN_MALFORMED_ATTR); | ||
| return -1; | ||
| } | ||
| break; | ||
| /* we deliberately ignore unknown codes, see below */ | ||
| default: | ||
| break; | ||
| } | ||
| if (!bgp_capability_length_check(connection, caphdr.code, caphdr.length)) | ||
| return -1; | ||
|
|
||
| switch (caphdr.code) { | ||
| case CAPABILITY_CODE_MP: { | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
link-local capability is length of 0, why do we need it here?