diff options
| author | anlan_cs <vic.lan@pica8.com> | 2022-05-03 09:26:15 -0400 | 
|---|---|---|
| committer | anlan_cs <vic.lan@pica8.com> | 2022-05-06 01:28:21 -0400 | 
| commit | 7ffd0b80aaa69919f903f70aa8fed54ee1688ceb (patch) | |
| tree | 5a7c3e1fb800f0eb0f0af72226440c7aa50a617b /bfdd | |
| parent | 50f1f2e724f8614ada1a1a02dd28f1ff3af06e08 (diff) | |
bfdd: fix override between sessions
After two single-hop sessions (*no local address are configured*) on two
interfaces are UP, remove one address of one interface, both of them
(actually, quite independent sessions) come to be DOWN, not just one.
Consider two boxes: A with `a1` and `a2` adddress on two interfaces,
and B with `b1` and `b2`.
Two sessions are set up and ok: `s1` with <a1,b1> and `s2` with <a2,b2>.
After `a1` of A is removed, there is an unhappy coincidence:
1) On A: `s1` changes local address, and sends <a2,b1> packets with help
of route.
2) On B: wrongly regarded <a2,b1> packets with non-zero remote descriminator
as part of `s2`, and are dropped for mismatched remote remote descriminator.
3) On A: `s1` sends <a2,b1> packets with zero remote descriminator to
initialize this session.
4) On B: wrongly regarded <a2,b1> packets with zero remote descriminator as
part of `s2`. Then `s2` will vibrate.
So the good sessions are overridden.
In this case, the <a2,b1> packets with zero remote descriminator won't take
effect until the current good sessions become bad.
Since single-hop sessions are allowed to be set without bound inteface in
current code, this commit adds one check in `bfd_recv_cb()` to avoid wrong
override.
Signed-off-by: anlan_cs <vic.lan@pica8.com>
Diffstat (limited to 'bfdd')
| -rw-r--r-- | bfdd/bfd_packet.c | 8 | 
1 files changed, 8 insertions, 0 deletions
diff --git a/bfdd/bfd_packet.c b/bfdd/bfd_packet.c index eff81d4b63..c717a333a6 100644 --- a/bfdd/bfd_packet.c +++ b/bfdd/bfd_packet.c @@ -639,6 +639,14 @@ void bfd_recv_cb(struct thread *t)  		return;  	} +	/* Ensure that existing good sessions are not overridden. */ +	if (!cp->discrs.remote_discr && bfd->ses_state != PTM_BFD_DOWN && +	    bfd->ses_state != PTM_BFD_ADM_DOWN) { +		cp_debug(is_mhop, &peer, &local, ifindex, vrfid, +			 "'remote discriminator' is zero, not overridden"); +		return; +	} +  	/*  	 * Multi hop: validate packet TTL.  	 */  | 
