linux/net/sched
Ido Schimmel 99f8efac7f net: Do not turn on carrier when protodown is on
The protodown functionality allows user space to turn off the carrier of
a net device:

 # ip link add name dummy1 up type dummy
 # ip link add name macvlan1 up link dummy1 type macvlan mode bridge
 # ip link set dev macvlan1 protodown on
 $ ip -br link show dev macvlan1
 macvlan1@dummy1  DOWN           0a:5c:a3:05:c7:86 <NO-CARRIER,BROADCAST,MULTICAST,UP>

Different applications can set different protodown reasons, which
prevents an application from turning on the carrier of a net device as
long as others want it down:

 # ip link set dev macvlan1 protodown_reason 1 on
 # ip link set dev macvlan1 protodown_reason 2 on
 # ip link set dev macvlan1 protodown off
 Error: Cannot clear protodown, active reasons.
 # ip link set dev macvlan1 protodown_reason 2 off
 # ip link set dev macvlan1 protodown off
 Error: Cannot clear protodown, active reasons.
 # ip link set dev macvlan1 protodown_reason 1 off
 # ip link set dev macvlan1 protodown off
 $ ip -br link show dev macvlan1
 macvlan1@dummy1  UP             0a:5c:a3:05:c7:86 <BROADCAST,MULTICAST,UP,LOWER_UP>

Unfortunately, this mechanism is not very useful when the carrier of a
net device can be toggled by toggling the carrier of its lower device:

 # ip link set dev macvlan1 protodown on
 $ ip -br link show dev macvlan1
 macvlan1@dummy1  DOWN           0a:5c:a3:05:c7:86 <NO-CARRIER,BROADCAST,MULTICAST,UP>
 # ip link set dev dummy1 carrier off
 # ip link set dev dummy1 carrier on
 $ ip -br link show dev macvlan1
 macvlan1@dummy1  UP             0a:5c:a3:05:c7:86 <BROADCAST,MULTICAST,UP,LOWER_UP>

Obviously, this is not the intended behavior and it is unlikely to be
relied on by anyone. In fact, it is a problem for applications like FRR
that use protodown with macvlan on top of a bridge as part of Virtual
Router Redundancy Protocol (VRRP).

Solve this by preventing a net device configured with protodown on from
gaining carrier by making netif_carrier_on() a NOP when protodown is
turned on.

Output with the patch:

 # ip link add name dummy1 up type dummy
 # ip link add name macvlan1 up link dummy1 type macvlan mode bridge
 # ip link set dev macvlan1 protodown on
 $ ip -br link show dev macvlan1
 macvlan1@dummy1  DOWN           0a:5c:a3:05:c7:86 <NO-CARRIER,BROADCAST,MULTICAST,UP>
 # ip link set dev dummy1 carrier off
 # ip link set dev dummy1 carrier on
 $ ip -br link show dev macvlan1
 macvlan1@dummy1  DOWN           0a:5c:a3:05:c7:86 <NO-CARRIER,BROADCAST,MULTICAST,UP>
 # ip link set dev macvlan1 protodown off
 $ ip -br link show dev macvlan1
 macvlan1@dummy1  UP             0a:5c:a3:05:c7:86 <BROADCAST,MULTICAST,UP,LOWER_UP>

Signed-off-by: Ido Schimmel <idosch@nvidia.com>
Link: https://patch.msgid.link/20260507105906.891817-3-idosch@nvidia.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
History 2026-05-08 16:50:26 -07:00
..
act_api.c net/sched: add qstats_cpu_drop_inc() helper 2026-05-04 18:59:07 -07:00
act_bpf.c net/sched: add qstats_cpu_drop_inc() helper 2026-05-04 18:59:07 -07:00
act_connmark.c Convert 'alloc_obj' family to use the new default GFP_KERNEL argument 2026-02-21 17:09:51 -08:00
act_csum.c net: sched: act_csum: validate nested VLAN headers 2026-04-03 14:34:56 -07:00
act_ct.c net/sched: act_ct: Only release RCU read lock after ct_ft 2026-04-12 09:26:15 -07:00
act_ctinfo.c Convert 'alloc_obj' family to use the new default GFP_KERNEL argument 2026-02-21 17:09:51 -08:00
act_gact.c net/sched: Add module aliases for cls_,sch_,act_ modules 2024-02-02 10:57:55 -08:00
act_gate.c net/sched: act_gate: snapshot parameters with RCU on replace 2026-02-27 16:10:36 -08:00
act_ife.c net/sched: add qstats_cpu_drop_inc() helper 2026-05-04 18:59:07 -07:00
act_meta_mark.c treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 152 2019-05-30 11:26:32 -07:00
act_meta_skbprio.c treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 152 2019-05-30 11:26:32 -07:00
act_meta_skbtcindex.c treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 152 2019-05-30 11:26:32 -07:00
act_mirred.c net/sched: act_mirred: fix wrong device for mac_header_xmit check in tcf_blockcast_redir 2026-04-16 11:16:32 +02:00
act_mpls.c net/sched: add qstats_cpu_drop_inc() helper 2026-05-04 18:59:07 -07:00
act_nat.c Convert 'alloc_obj' family to use the new default GFP_KERNEL argument 2026-02-21 17:09:51 -08:00
act_pedit.c Convert 'alloc_obj' family to use the new default GFP_KERNEL argument 2026-02-21 17:09:51 -08:00
act_police.c net/sched: add qstats_cpu_drop_inc() helper 2026-05-04 18:59:07 -07:00
act_sample.c net: sched: act_sample: add action cookie to sample 2024-07-05 17:45:47 -07:00
act_simple.c net/sched: Remove redundant memset(0) call in reset_policy() 2025-08-12 17:13:29 -07:00
act_skbedit.c net/sched: add qstats_cpu_drop_inc() helper 2026-05-04 18:59:07 -07:00
act_skbmod.c net/sched: rename qstats_overlimit_inc() to qstats_cpu_overlimit_inc() 2026-04-29 16:42:44 -07:00
act_tunnel_key.c net_sched: add back BH safety to tcf_lock 2025-09-02 15:51:45 -07:00
act_vlan.c Convert 'alloc_obj' family to use the new default GFP_KERNEL argument 2026-02-21 17:09:51 -08:00
bpf_qdisc.c bpf: net_sched: Use the correct destructor kfunc type 2026-01-12 18:53:57 -08:00
cls_api.c net: sched: cls_api: fix tc_chain_fill_node to initialize tcm_info to zero to prevent an info-leak 2026-03-30 17:56:40 -07:00
cls_basic.c Convert 'alloc_obj' family to use the new default GFP_KERNEL argument 2026-02-21 17:09:51 -08:00
cls_bpf.c Convert 'alloc_obj' family to use the new default GFP_KERNEL argument 2026-02-21 17:09:51 -08:00
cls_cgroup.c Convert 'alloc_obj' family to use the new default GFP_KERNEL argument 2026-02-21 17:09:51 -08:00
cls_flow.c net/sched: cls_flow: fix NULL pointer dereference on shared blocks 2026-04-02 15:08:42 +02:00
cls_flower.c net/sched: cls_flower: revert unintended changes 2026-04-30 13:47:01 +02:00
cls_fw.c net/sched: cls_fw: fix NULL dereference of "old" filters before change() 2026-04-12 08:49:13 -07:00
cls_matchall.c Convert 'alloc_obj' family to use the new default GFP_KERNEL argument 2026-02-21 17:09:51 -08:00
cls_route.c Convert 'alloc_obj' family to use the new default GFP_KERNEL argument 2026-02-21 17:09:51 -08:00
cls_u32.c net: sched: cls_u32: Avoid memcpy() false-positive warning in u32_init_knode() 2026-03-10 19:39:35 -07:00
em_canid.c net/sched: em_canid: fix uninit-value in em_canid_match 2025-11-26 16:28:10 +01:00
em_cmp.c net: sched: fix TCF_LAYER_TRANSPORT handling in tcf_get_base_ptr() 2025-11-24 18:53:14 -08:00
em_ipset.c sched: consistently handle layer3 header accesses in the presence of VLANs 2020-07-03 14:34:53 -07:00
em_ipt.c sched: consistently handle layer3 header accesses in the presence of VLANs 2020-07-03 14:34:53 -07:00
em_meta.c Convert 'alloc_obj' family to use the new default GFP_KERNEL argument 2026-02-21 17:09:51 -08:00
em_nbyte.c net: sched: fix TCF_LAYER_TRANSPORT handling in tcf_get_base_ptr() 2025-11-24 18:53:14 -08:00
em_text.c Convert 'alloc_obj' family to use the new default GFP_KERNEL argument 2026-02-21 17:09:51 -08:00
em_u32.c net: fill in MODULE_DESCRIPTION()s for net/sched 2024-02-09 14:12:02 -08:00
ematch.c net_sched: reject TCF_EM_SIMPLE case for complex ematch module 2022-12-19 09:43:18 +00:00
Kconfig sched: Add enqueue/dequeue of dualpi2 qdisc 2025-07-23 17:52:07 -07:00
Makefile sched: Add enqueue/dequeue of dualpi2 qdisc 2025-07-23 17:52:07 -07:00
sch_api.c net/sched: speedup tc_dump_qdisc() when tcm_handle is provided 2026-05-04 19:32:19 -07:00
sch_blackhole.c Revert "net: sched: Pass root lock to Qdisc_ops.enqueue" 2020-07-16 16:48:34 -07:00
sch_cake.c Merge git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net 2026-05-07 11:19:07 -07:00
sch_cbs.c net/sched: cbs: Fix integer overflow in cbs_set_port_rate() 2024-10-15 18:25:47 -07:00
sch_choke.c net/sched: sch_choke: annotate data-races in choke_dump_stats() 2026-04-27 17:41:08 -07:00
sch_codel.c codel: annotate data-races in codel_dump_stats() 2026-04-08 19:18:52 -07:00
sch_drr.c Convert 'alloc_obj' family to use the new default GFP_KERNEL argument 2026-02-21 17:09:51 -08:00
sch_dualpi2.c net/sched: sch_dualpi2: drain both C-queue and L-queue in dualpi2_change() 2026-04-21 15:00:39 +02:00
sch_etf.c net_sched: sch_tfs: implement lockless etf_dump() 2024-04-19 11:34:07 +01:00
sch_ets.c net/sched: ets: fix divide by zero in the offload path 2026-02-26 18:28:47 -08:00
sch_fifo.c pfifo_tail_enqueue: Drop new packet when sch->limit == 0 2025-02-05 18:13:58 -08:00
sch_fq.c Merge git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net 2026-03-05 12:11:05 -08:00
sch_fq_codel.c Merge git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net 2026-05-07 11:19:07 -07:00
sch_fq_pie.c net/sched: sch_fq_pie: annotate data-races in fq_pie_dump_stats() 2026-04-27 17:41:52 -07:00
sch_frag.c net: convert remaining ipv6_stub users to direct function calls 2026-03-29 11:21:23 -07:00
sch_generic.c net: Do not turn on carrier when protodown is on 2026-05-08 16:50:26 -07:00
sch_gred.c net/sched: add qstats_cpu_drop_inc() helper 2026-05-04 18:59:07 -07:00
sch_hfsc.c net/sched: sch_hfsc: fix divide-by-zero in rtsc_min() 2026-03-27 20:41:11 -07:00
sch_hhf.c net_sched: sch_hhf: annotate data-races in hhf_dump_stats() 2026-04-22 21:12:40 -07:00
sch_htb.c net/sched: do not reset queues in graft operations 2026-03-09 18:55:55 -07:00
sch_ingress.c clsact: Fix use-after-free in init/destroy rollback asymmetry 2026-03-17 12:09:16 +01:00
sch_mq.c net/sched: do not reset queues in graft operations 2026-03-09 18:55:55 -07:00
sch_mqprio.c net/sched: do not reset queues in graft operations 2026-03-09 18:55:55 -07:00
sch_mqprio_lib.c net: sched: Fill in missing MODULE_DESCRIPTION for qdiscs 2023-11-01 21:49:09 -07:00
sch_mqprio_lib.h net/sched: mqprio: allow per-TC user input of FP adminStatus 2023-04-13 22:22:10 -07:00
sch_multiq.c Convert 'alloc_obj' family to use the new default GFP_KERNEL argument 2026-02-21 17:09:51 -08:00
sch_netem.c net/sched: netem: check for negative latency and jitter 2026-04-27 17:30:28 -07:00
sch_pie.c net/sched: sch_pie: annotate more data-races in pie_dump_stats() 2026-05-01 17:54:57 -07:00
sch_plug.c net/sched: Add module aliases for cls_,sch_,act_ modules 2024-02-02 10:57:55 -08:00
sch_prio.c net_sched: prio: fix a race in prio_tune() 2025-06-12 08:05:49 -07:00
sch_qfq.c Convert 'alloc_obj' family to use the new default GFP_KERNEL argument 2026-02-21 17:09:51 -08:00
sch_red.c net/sched: sch_red: Replace direct dequeue call with peek and qdisc_dequeue_peeked 2026-05-02 10:20:55 -07:00
sch_sfb.c net/sched: sch_sfb: Replace direct dequeue call with peek and qdisc_dequeue_peeked 2026-05-02 10:20:56 -07:00
sch_sfq.c net/sched: sch_sfq: annotate data-races from sfq_dump_class_stats() 2026-05-06 17:46:05 -07:00
sch_skbprio.c net_sched: skbprio: Remove overly strict queue assertions 2025-04-02 16:03:32 -07:00
sch_taprio.c net/sched: taprio: prepare taprio_dump() for RTNL removal 2026-05-04 18:33:06 -07:00
sch_tbf.c net_sched: use qdisc_skb_cb(skb)->pkt_segs in bstats_update() 2025-11-25 16:10:32 +01:00
sch_teql.c net/sched: teql: Fix double-free in teql_master_xmit 2026-03-16 19:40:32 -07:00