-
Notifications
You must be signed in to change notification settings - Fork 1.4k
bfd: fix RFC 5880 compliance violations in packet reception #20324
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?
Conversation
riw777
left a comment
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.
looks good
bfdd/bfd_packet.c
Outdated
| if (a->sa_sin.sin_family == AF_INET) { | ||
| return (a->sa_sin.sin_addr.s_addr == b->sa_sin.sin_addr.s_addr); | ||
| } else if (a->sa_sin.sin_family == AF_INET6) { | ||
| return (memcmp(&a->sa_sin6.sin6_addr, &b->sa_sin6.sin6_addr, |
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.
Let's use IPV6_ADDR_CMP().
|
This pull request has conflicts, please resolve those before we can evaluate the pull request. |
7f384d6 to
541eb49
Compare
|
This pull request has conflicts, please resolve those before we can evaluate the pull request. |
541eb49 to
0a8b7b3
Compare
|
|
Fixes in this commit:
1. RFC violation on session reset.
2. RFC violation on checking of cp->len.
3. RFC violation on the timing of updating remote discriminator.
For 1, the previous logic in `bfd_recv_cb` incorrectly discarded all
packets with `Your Discriminator` set to 0 if the local session state was
`UP` or `INIT`. This violated RFC 5880 Section 6.8.6, which requires
accepting such packets (specifically when State is DOWN) to handle remote
peer restarts. This discrepancy may cause "zombie sessions" where the local
side remained UP ignoring the peer's reset signal.
The original check was introduced with the intention to prevent session aliasing,
which caused session state flapping. However, the check was too broad.
This patch replaces the state-based check with a more strict address-based check:
- Removed the conditions of `bfd->ses_state !=` which would block legitimate resets.
- Added `match_ip_address` to verify that if a zero-discriminator packet arrives for
an UP session. its destination address matches the session's bound local address.
- Added the check required by the RFC 5880 that if a zero remote discriminator packet
arrives with a state that is not DOWN or ADMIN_DOWN, the packet should be dropped.
This allows legitimate peer resets (correct destination) to proceed while dropping
aliased packets that causes vibration.
For 2, this is a relatively minor one and potentially nitpicking. But RFC 5880 requires
that the parser should check `cp->len < 26` if A bit is set, so I include it.
For 3, the patch delays the update of remote discriminator to after `bfd_check_auth` returns
success. This is required by the RFC. Updating remote discriminator before auth check
would incorrectly update local state even when authentication fails, which can be harmful.
This patch also modifies `bfd.h` to add a new pair of marco that get and set A bit. It also
changes the implementation of `BFD_SETCBIT` to align with other marco's way of implementation.
Signed-off-by: ace_momo <[email protected]>
Greptile OverviewGreptile SummaryChangesFixed three RFC 5880 compliance violations in BFD packet reception:
Key ImprovementsThe address-based check for zero-discriminator packets correctly handles the zombie session problem where peers restart but the local side remains UP. The new logic validates the destination address matches the session's bound local address before accepting the reset, preventing session flapping from aliased packets while allowing legitimate resets to proceed. Confidence Score: 4/5
Important Files Changed
Sequence DiagramsequenceDiagram
participant Remote as Remote BFD Peer
participant Net as Network
participant Recv as bfd_recv_cb()
participant Sess as BFD Session
participant Auth as bfd_check_auth()
Remote->>Net: BFD Control Packet
Net->>Recv: Packet arrives
Note over Recv: Basic validation<br/>(version, length, TTL)
alt A bit set
Recv->>Recv: Check len >= BFD_PKT_LEN + 2
else A bit clear
Recv->>Recv: Check len >= BFD_PKT_LEN
end
Recv->>Sess: Find session by discriminator
alt Your Discriminator = 0
alt Session state = UP
Recv->>Recv: Verify local address matches
alt Address mismatch
Recv-->>Net: Drop packet (prevent aliasing)
end
end
Recv->>Recv: Check packet state field
alt Packet state != DOWN or ADMIN_DOWN
Recv-->>Net: Drop packet per RFC 5880
end
end
Note over Recv: Log discriminator changes
Recv->>Auth: Perform authentication check
Auth-->>Recv: Return result
alt Authentication failed
Recv-->>Net: Drop packet
else Authentication succeeded
Note over Recv: Update remote discriminator<br/>after auth verification
Recv->>Sess: Update remote discriminator
Recv->>Sess: Update timers and state
end
|
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.
2 files reviewed, 2 comments
|
|
||
| bfd->discrs.remote_discr = ntohl(cp->discrs.my_discr); | ||
|
|
||
|
|
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.
Trailing whitespace on this line
| /* Check authentication. */ |
Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!
Prompt To Fix With AI
This is a comment left during a code review.
Path: bfdd/bfd_packet.c
Line: 1080:1080
Comment:
Trailing whitespace on this line
```suggestion
/* Check authentication. */
```
<sub>Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!</sub>
How can I resolve this? If you propose a fix, please make it concise.| char *vrf_name; | ||
| }; | ||
| #endif /* _BFD_H_ */ | ||
| #endif /* _BFD_H_ */ No newline at end of file |
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.
Missing newline at end of file
| #endif /* _BFD_H_ */ | |
| #endif /* _BFD_H_ */ | |
Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!
Prompt To Fix With AI
This is a comment left during a code review.
Path: bfdd/bfd.h
Line: 900:900
Comment:
Missing newline at end of file
```suggestion
#endif /* _BFD_H_ */
```
<sub>Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!</sub>
How can I resolve this? If you propose a fix, please make it concise.
Fixes in this commit:
For 1, the previous logic in
bfd_recv_cbincorrectly discarded all packets withYour Discriminatorset to 0 if the local session state wasUPorINIT. This violated RFC 5880 Section 6.8.6, which requires accepting such packets (specifically when State is DOWN) to handle remote peer restarts. This discrepancy may cause "zombie sessions" where the local side remained UP ignoring the peer's reset signal.The original check was introduced with the intention to prevent session aliasing, which caused session state flapping. However, the check was too broad.
This patch replaces the state-based check with a more strict address-based check:
bfd->ses_state !=which would block legitimate resets.match_ip_addressto verify that if a zero-discriminator packet arrives for an UP session. its destination address matches the session's bound local address.This allows legitimate peer resets (correct destination) to proceed while dropping aliased packets that causes vibration.
For 2, this is a relatively minor one and potentially nitpicking. But RFC 5880 requires that the parser should check
cp->len < 26if A bit is set, so I include it.For 3, the patch delays the update of remote discriminator to after
bfd_check_authreturns success. This is required by the RFC. Updating remote discriminator before auth check would incorrectly update local state even when authentication fails, which can be harmful.This patch also modifies
bfd.hto add a new pair of marco that get and set A bit. It also changes the implementation ofBFD_SETCBITto align with other marco's way of implementation.