Skip to content

bfdd: update and add protocol handler - #30364

Draft
Wolf480pl wants to merge 3 commits into
openwrt:masterfrom
Wolf480pl:wolf-bfdd
Draft

bfdd: update and add protocol handler#30364
Wolf480pl wants to merge 3 commits into
openwrt:masterfrom
Wolf480pl:wolf-bfdd

Conversation

@Wolf480pl

Copy link
Copy Markdown

📦 Package Details

Maintainer: @lucize

Description:
Add netifd protocol handler for bfdd, after updating to a version of bfdd that has the changes necessary to make that possible.
That version is from my pull request to the upstream repo: rzalamena/bfdd#6
so I suppose merging that PR is blocking for this one.

The idea behind this protocol handler is that if you have an interface of a protocol that, on its own, can't detect if it's up or down (eg. wireguard), you can add a second interface of bfd protocol on the same device, and it will only go up once bfdd detects that the other end is reachable. Then you can configure routes on this bfd interface, and netifd will only enable those once the interface goes up.


🧪 Run Testing Details

  • OpenWrt Version: 24.10
  • OpenWrt Target/Subtarget: ramips/mt7621
  • OpenWrt Device: Netgear R6220

(Once I get a separate router for testing, I'll try testing on 25.12 and master as well)


✅ Formalities

  • I have reviewed the CONTRIBUTING.md file for detailed contributing guidelines.

If your PR contains a patch:

It doesn't

This includes an upstream fix for gcc-10+ compatibility,
so we can drop our gcc-10 patch.

It also includes a fix for a crash when dynamically adding BFD sessions
with a label that was in use before.

Signed-off-by: Wolf Pl <[email protected]>
Update to upstream version containing improvements to bfdctl,
including bugfixes and new CLI flags that make it possible
to dynamically add peer definitions to bfdd, without going through
the static config.

These features will be needed for a bfd protocol handler for netifd.

Signed-off-by: Wolf Pl <[email protected]>
Add a netifd protocol handler for bfdd.

It's intended to be used as a second protocol on a device that already has
a protocol that can't detect its up-ness on its own (eg. wireguard).

When bfdd detects the link to be up or down, it the protocol handler
will propagate that status to  the bfd interface in netifd,
which will cause its routes (and possibly other settings)
to be applied or retracted in response.

The interface's device is used both as a device to which the settings
are applied, and a device to which the bfd session is bound.
This might not be optimal for multihop BFD, but I wanted to keep things
simple for now. Maybe adding a way to separately specify each of these
devices will need to be added in the future.

Signed-off-by: Wolf Pl <[email protected]>
@openwrt

openwrt Bot commented Aug 23, 2026

Copy link
Copy Markdown

Formality Check: Suggestions Available

We checked this pull request against the contribution guidelines. Here is what needs your attention:

⚠️ STYLISTIC WARNINGS & SUGGESTIONS

Package Release Audit:

  • ⚠️ Package net/bfdd version updated from 'c54534beb524afc3972039f57b56ec65332b43f7' to '921bfa05b0e0020eb910cffc2a6edf37543b84cf', but PKG_RELEASE was not reset to 1 (currently: '2')

Something broken? Consider reporting an issue.
Running version 3eeda58 deployed on 2026-08-18 11:06:29 CEST

@Wolf480pl

Copy link
Copy Markdown
Author

Package net/bfdd version updated [...] but PKG_RELEASE was not reset to 1 (currently: '2')

It was reset to one in the commit that updated the version.
Then the final commit that adds the netifd protocol handler bumps PKG_RELEASE, since it changes the contents of the built package.

I can put both of those changes in one commit and avoid bumping PKG_RELEASE - please let me know if that's preferred.

@lucize

lucize commented Aug 23, 2026

Copy link
Copy Markdown
Contributor

can't test this as I mainly use the frr-bfd now

@Wolf480pl

Wolf480pl commented Aug 23, 2026

Copy link
Copy Markdown
Author

can't test this as I mainly use the frr-bfd now

would it make sense to add myself as another maintainer once I start using this package as part of my long-term setup?

@lucize

lucize commented Aug 23, 2026

Copy link
Copy Markdown
Contributor

yes, please do it!

@openwrt-ai openwrt-ai left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed 3 commits. Nothing here is a hard blocker beyond what the PR already acknowledges (it is a draft pending the upstream bfdd PR); the missing peer_address validation and the teardown ordering are the two I would want resolved before merge.

Commit checks

  • 6410a8d "bfdd: add netifd protocol handler" — the diff matches the message, but the body has a stray word and a double space: "When bfdd detects the link to be up or down, it the protocol handler will propagate that status to the bfd interface". Worth fixing while the branch is still being rebased.

On the PKG_RELEASE warning from the formality bot: your reasoning in the thread is right — 87d02ad resets it to 1 with the version bump and 6410a8d increments it for the added files. That is the documented behaviour for this repo, so no change needed on that account.


Generated by Claude Code

Comment thread net/bfdd/Makefile
PKG_RELEASE:=2

PKG_SOURCE_VERSION:=c54534beb524afc3972039f57b56ec65332b43f7
# TODO: update to a commit from master once https://github.com/rzalamena/bfdd/bfdd/pulls/6 is merged

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The URL in this TODO is malformed and 404s — it has the repo name twice and pulls instead of pull. The PR description links the correct one (https://github.com/rzalamena/bfdd/pull/6).

Suggested change
# TODO: update to a commit from master once https://github.com/rzalamena/bfdd/bfdd/pulls/6 is merged
# TODO: update to a commit from master once https://github.com/rzalamena/bfdd/pull/6 is merged

Generated by Claude Code

Comment thread net/bfdd/files/bfd.sh
Comment on lines +37 to +38
json_get_vars detect_multiplier receive_interval transmit_interval echo_mode echo_interval

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

peer_address is never validated, but bfdd.template.json documents peer-address as mandatory. If the user forgets option peer_address, line 67 runs bfdctl -a -i <dev> -p "" ..., bfdctl exits non-zero, and netifd will keep re-running setup in a restart loop instead of telling the user what is wrong. Other handlers in the feed guard this with proto_notify_error + proto_block_restart, e.g. tayga-proto.sh:20.

Suggested change
json_get_vars detect_multiplier receive_interval transmit_interval echo_mode echo_interval
json_get_vars detect_multiplier receive_interval transmit_interval echo_mode echo_interval
if [ -z "$peer_address" ]; then
proto_notify_error "$config" "MISSING_PEER_ADDRESS"
proto_block_restart "$config"
return 1
fi

The template also marks local-address as mandatory for multihop, so a matching check under [ "$multihop" = "1" ] would be worth adding too.


Generated by Claude Code

Comment thread net/bfdd/files/bfd.sh
Comment on lines +39 to +41
if ! pidof bfdd; then
service bfdd start
fi

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Two problems here:

  1. pidof bfdd prints the matched PIDs on stdout, and proto handlers run under netifd, so every single ifup of a bfd interface writes a stray PID line into the log. Redirect it.
  2. service bfdd start hands off to procd and returns immediately — it does not wait for bfdd to create its control socket. The bfdctl invocation at line 66 runs right after, so on the very first setup (cold boot, or bfdd not yet started) it can fail to connect and the whole setup fails. Either poll for the control socket before continuing, or make the interface depend on bfdd being started at boot and only proto_notify_error/proto_block_restart when it is not running.
Suggested change
if ! pidof bfdd; then
service bfdd start
fi
if ! pidof bfdd >/dev/null; then
service bfdd start
fi

Separately, worth deciding deliberately: this silently starts a service the user may have stopped or disabled on purpose.


Generated by Claude Code

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it can fail to connect and the whole setup fails

Yes, and netifd will keep restarting the protocol handler until it succeeds.
I don't see what polling for startup accomplishes that the current implementation doesn't.

Separately, worth deciding deliberately: this silently starts a service the user may have stopped or disabled on purpose.

Just like the protocol handler for xl2tpd

Comment thread net/bfdd/files/bfd.sh
[ -z "$transmit_interval" ] || json_add_string "transmit-interval" "$transmit_interval"
[ -z "$echo_interval" ] || json_add_string "echo-interval" "$echo_interval"

json_add_boolean "echo-mode" "$echo_mode"

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This one option escapes the guard pattern the comment on lines 53-56 sets up. When the user does not set option echo_mode, json_get_vars leaves $echo_mode empty and jshn serialises an empty boolean as false, so the key is present and the daemon default is overridden rather than used — exactly the case the comment says you want to avoid. It happens to be harmless today because echo-mode defaults to false anyway, but it will silently diverge if that default ever changes.

Suggested change
json_add_boolean "echo-mode" "$echo_mode"
[ -z "$echo_mode" ] || json_add_boolean "echo-mode" "$echo_mode"

Generated by Claude Code

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

echo_mode is not an interval, that comment doesn't apply to it
bfdd's struct bpc_config has no bpc_has_echomode that could be used to signify bpf_echomode's absence

Comment thread net/bfdd/files/bfd.sh
Comment on lines +75 to +79
# first kill the bfdctl -M that listens for events,
# since it holds refcount on the bfd session, preventing it from being deleted
proto_kill_command "$config"
# then remove the session
bfdctl -d -L "$config"

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The comment claims an ordering that proto_kill_command does not actually give you. proto_kill_command is a ubus call network.interface kill_command — it asks netifd to deliver a signal and returns as soon as ubus acknowledges it; it does not wait for bfdctl -M to reap. So bfdctl -d -L "$config" on line 79 can easily run while the monitor still holds the refcount, which is precisely the failure the comment says it is avoiding, and the session is then left behind in bfdd — a subsequent ifup would hit a stale label.

Did you observe this working reliably, or is it timing-dependent on your setup? If it is not guaranteed, the teardown probably needs to wait for the monitor to exit (poll on the pid) or retry the delete.

Also worth noting: if bfdd is not running at teardown time, bfdctl -d fails and its error goes to the log with no handling.


Generated by Claude Code

Comment thread net/bfdd/files/bfd-event
up=1
fi

echo "bfd-event: config=$config up=$up ifname=$ifname"

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: this reads like debug scaffolding — it fires on every BFD state change and lands in the log as an unattributed bare line. If the logging is wanted, route it through logger so it is tagged and can be filtered; otherwise drop it.

Suggested change
echo "bfd-event: config=$config up=$up ifname=$ifname"
logger -t bfd-event "config=$config up=$up ifname=$ifname"

Generated by Claude Code

Comment thread net/bfdd/files/bfd-event

up=0
if [ "$state" = "up" ]; then
up=1

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: this file indents with 2 spaces while the sibling file added in the same commit (bfd.sh) and the package's existing files/bfdd.init both use 4. Worth making the two new files agree.

Suggested change
up=1
up=1

(For what it's worth, every other netifd proto handler in the feed — net/tayga/files/tayga-proto.sh, net/openvpn/files/lib/netifd/proto/openvpn.sh, net/bonding/files/lib/netifd/proto/bonding.sh — indents with tabs, so tabs would be the more conventional choice for bfd.sh too. Not a blocker either way, just pick one.)


Generated by Claude Code

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants