bridge: Add backup nexthop ID support
Subsystems (3)
Ido Schimmel
maintainerPATCH 1/1 bridge: Add backup nexthop ID support
Extend the bridge and ip utilities to set and show the backup nexthop ID bridge port attribute. A value of 0 (default) disables the feature, in which case the attribute is not printed since it is not emitted by the kernel.
Example:
# bridge -d link show dev swp1 | grep -o "backup_nhid [0-9]*" # bridge -d -j -p link show dev swp1 | jq '.[]["backup_nhid"]' null
# bridge link set dev swp1 backup_nhid 10 # bridge -d link show dev swp1 | grep -o "backup_nhid [0-9]*" backup_nhid 10 # bridge -d -j -p link show dev swp1 | jq '.[]["backup_nhid"]' 10
# bridge link set dev swp1 backup_nhid 0 # bridge -d link show dev swp1 | grep -o "backup_nhid [0-9]*" # bridge -d -j -p link show dev swp1 | jq '.[]["backup_nhid"]' null
# ip -d link show dev swp1 | grep -o "backup_nhid [0-9]*" # ip -d -j -p lin show dev swp1 | jq '.[]["linkinfo"]["info_slave_data"]["backup_nhid"]' null
# ip link set dev swp1 type bridge_slave backup_nhid 10 # ip -d link show dev swp1 | grep -o "backup_nhid [0-9]*" backup_nhid 10 # ip -d -j -p lin show dev swp1 | jq '.[]["linkinfo"]["info_slave_data"]["backup_nhid"]' 10
# ip link set dev swp1 type bridge_slave backup_nhid 0 # ip -d link show dev swp1 | grep -o "backup_nhid [0-9]*" # ip -d -j -p lin show dev swp1 | jq '.[]["linkinfo"]["info_slave_data"]["backup_nhid"]' null
--- bridge/link.c | 14 ++++++++++++++ ip/iplink_bridge_slave.c | 13 +++++++++++++ man/man8/bridge.8 | 9 +++++++++ man/man8/ip-link.8.in | 11 ++++++++++- 4 files changed, 46 insertions(+), 1 deletion(-)
bridge/link.c +14 -0
@@ -186,6 +186,10 @@ static void print_protinfo(FILE *fp, struct rtattr *attr) ll_index_to_name(ifidx)); } +if (prtb[IFLA_BRPORT_BACKUP_NHID ]) +print_uint (PRINT_ANY ,"backup_nhid" ,"backup_nhid %u " , +rta_getattr_u32 (prtb[IFLA_BRPORT_BACKUP_NHID ])); +if (prtb[IFLA_BRPORT_ISOLATED ])print_on_off (PRINT_ANY ,"isolated" ,"isolated %s " ,rta_getattr_u8 (prtb[IFLA_BRPORT_ISOLATED ]));
@@ -311,6 +315,7 @@ static void usage(void)" [ mab {on | off} ]\n" " [ hwmode {vepa | veb} ]\n" " [ backup_port DEVICE ] [ nobackup_port ]\n" +" [ backup_nhid NHID ]\n" " [ self ] [ master ]\n" " bridge link show [dev DEV]\n");exit (-1 );
@@ -330,6 +335,7 @@ static int brlink_modify(int argc, char **argv) };char *d =NULL ;int backup_port_idx =-1 ; +__s32 backup_nhid =-1 ;__s8 neigh_suppress =-1 ;__s8 neigh_vlan_suppress =-1 ;__s8 learning =-1 ;
@@ -493,6 +499,10 @@ static int brlink_modify(int argc, char **argv) } }else if (strcmp (*argv,"nobackup_port" ) ==0 ) { backup_port_idx =0 ; + }else if (strcmp (*argv,"backup_nhid" ) ==0 ) { +NEXT_ARG (); +if (get_s32 (&backup_nhid, *argv,0 )) +invarg ("invalid backup_nhid" , *argv); }else {usage (); }
@@ -579,6 +589,10 @@ static int brlink_modify(int argc, char **argv)addattr32 (&req.n,sizeof (req),IFLA_BRPORT_BACKUP_PORT , backup_port_idx); +if (backup_nhid !=-1 ) +addattr32 (&req.n,sizeof (req),IFLA_BRPORT_BACKUP_NHID , + backup_nhid); +addattr_nest_end (&req.n, nest);/* IFLA_AF_SPEC nested attribute. Contains IFLA_BRIDGE_FLAGS that
ip/iplink_bridge_slave.c +13 -0
@@ -43,6 +43,7 @@ static void print_explain(FILE *f)" [ locked {on | off} ]\n" " [ mab {on | off} ]\n" " [ backup_port DEVICE ] [ nobackup_port ]\n" +" [ backup_nhid NHID ]\n" ); }
@@ -301,6 +302,10 @@ static void bridge_slave_print_opt(struct link_util *lu, FILE *f,print_string (PRINT_ANY ,"backup_port" ,"backup_port %s " ,ll_index_to_name (backup_p)); } + +if (tb[IFLA_BRPORT_BACKUP_NHID ]) +print_uint (PRINT_ANY ,"backup_nhid" ,"backup_nhid %u " , +rta_getattr_u32 (tb[IFLA_BRPORT_BACKUP_NHID ])); } static void bridge_slave_parse_on_off(char *arg_name, char *arg_val,
@@ -436,6 +441,14 @@ static int bridge_slave_parse_opt(struct link_util *lu, int argc, char **argv,addattr32 (n,1024 ,IFLA_BRPORT_BACKUP_PORT , ifindex); }else if (matches (*argv,"nobackup_port" ) ==0 ) {addattr32 (n,1024 ,IFLA_BRPORT_BACKUP_PORT ,0 ); + }else if (strcmp (*argv,"backup_nhid" ) ==0 ) { +__u32 backup_nhid; + +NEXT_ARG (); +if (get_u32 (&backup_nhid, *argv,0 )) +invarg ("backup_nhid is invalid" , *argv); +addattr32 (n,1024 ,IFLA_BRPORT_BACKUP_NHID , + backup_nhid); }else if (matches (*argv,"help" ) ==0 ) {explain ();return -1 ;
man/man8/bridge.8 +9 -0
@@ -61,6 +61,8 @@ bridge \- show / manipulate bridge addresses and devices .B backup_port .IR DEVICE " ] [" .BR nobackup_port " ] [ " +.B backup_nhid +.IR NHID " ] [" .BR self " ] [ " master " ]" .ti -8
@@ -647,6 +649,13 @@ configured backup port .B nobackup_port Removes the currently configured backup port +.TP +.BI backup_nhid " NHID" +The FDB nexthop object ID (see \fBip-nexthop\fR(8)) to attach to packets being +redirected to a backup port that has VLAN tunnel mapping enabled (via the +\fBvlan_tunnel\fR option). Setting a value of 0 (default) has the effect of not +attaching any ID. + .TP .B self link setting is configured on specified physical device
man/man8/ip-link.8.in +10 -1
@@ -2539,7 +2539,10 @@ the following additional arguments are supported: ] [ .BR backup_port " DEVICE" ] [ -.BR nobackup_port " ]" +.BR nobackup_port +] [ +.BR backup_nhid " NHID" +] .in +8 .sp
@@ -2678,6 +2681,12 @@ configured backup port .BR nobackup_port - removes the currently configured backup port +.BI backup_nhid " NHID" +- the FDB nexthop object ID (see \fBip-nexthop\fR(8)) to attach to packets +being redirected to a backup port that has VLAN tunnel mapping enabled (via the +\fBvlan_tunnel\fR option). Setting a value of 0 (default) has the effect of not +attaching any ID. + .in -8 .TP
Signature · 1 line
2.40.1
bridge/link.c static void print_protinfo(FILE *fp, struct rtattr *attr) · line 192
Quoted 12 lines · Ido Schimmel
bridge/link.c +4
-0@@ -186,6 +186,10 @@ static void print_protinfo(FILE *fp, struct rtattr *attr) ll_index_to_name(ifidx)); } +if (prtb[IFLA_BRPORT_BACKUP_NHID ]) +print_uint (PRINT_ANY ,"backup_nhid" ,"backup_nhid %u " , +rta_getattr_u32 (prtb[IFLA_BRPORT_BACKUP_NHID ])); +
This doesn't build on current main. I think we usually send the relevant header sync patch, but maybe there's an assumption the maintainer pushes it _before_ this patch? I'm not sure, just calling it out.
bridge/link.c static void usage(void) · line 318
Quoted 8 lines
bridge/link.c +1
-0if (prtb[IFLA_BRPORT_ISOLATED ])print_on_off (PRINT_ANY ,"isolated" ,"isolated %s " ,rta_getattr_u8 (prtb[IFLA_BRPORT_ISOLATED ]));@@ -311,6 +315,7 @@ static void usage(void)" [ mab {on | off} ]\n" " [ hwmode {vepa | veb} ]\n" " [ backup_port DEVICE ] [ nobackup_port ]\n" +" [ backup_nhid NHID ]\n"
I thought about whether there should be "nobackup_nhid", but no. The corresponding nobackup_port is necessary because it would be awkward to specify "backup_port ''" or something. No such issue with NHID.
Quoted 12 lines
bridge/link.c +1
-0" [ self ] [ master ]\n" " bridge link show [dev DEV]\n");exit (-1 );@@ -330,6 +335,7 @@ static int brlink_modify(int argc, char **argv) };char *d =NULL ;int backup_port_idx =-1 ; +__s32 backup_nhid =-1 ;__s8 neigh_suppress =-1 ;__s8 neigh_vlan_suppress =-1 ;__s8 learning =-1 ;
bridge/link.c static int brlink_modify(int argc, char **argv) · line 505
Quoted 7 lines
bridge/link.c +4
-0@@ -493,6 +499,10 @@ static int brlink_modify(int argc, char **argv) } }else if (strcmp (*argv,"nobackup_port" ) ==0 ) { backup_port_idx =0 ; + }else if (strcmp (*argv,"backup_nhid" ) ==0 ) { +NEXT_ARG (); +if (get_s32 (&backup_nhid, *argv,0 )) +invarg ("invalid backup_nhid" , *argv);
Not sure about that s32. NHID's are unsigned in general. I can add a NHID of 0xffffffff just fine:
# ip nexthop add id 0xffffffff via 192.0.2.3 dev Xd
(Though ip nexthop show then loops endlessly probably because -1 is used as a sentinel in the dump code. Oops!)
IMHO the tool should allow configuring this. You allow full u32 range for the "ip" tool, no need for "bridge" to be arbitrarily limited.
Quoted 11 lines · Petr Machata
Quoted 8 lines · Ido Schimmel
bridge/link.c +0
-0@@ -186,6 +186,10 @@ static void print_protinfo(FILE *fp, struct rtattr *attr) ll_index_to_name(ifidx)); }
Quoted 8 lines
bridge/link.c static void print_protinfo(FILE *fp, struct rtattr *attr) · line 192
Quoted 4 lines
bridge/link.c +4
-0+if (prtb[IFLA_BRPORT_BACKUP_NHID ]) +print_uint (PRINT_ANY ,"backup_nhid" ,"backup_nhid %u " , +rta_getattr_u32 (prtb[IFLA_BRPORT_BACKUP_NHID ])); +This doesn't build on current main. I think we usually send the relevant header sync patch, but maybe there's an assumption the maintainer pushes it _before_ this patch? I'm not sure, just calling it out.
Not needed. David syncs the headers himself.
Quoted 37 lines
bridge/link.c static void usage(void) · line 318
Quoted 9 lines
bridge/link.c +1
-0if (prtb[IFLA_BRPORT_ISOLATED ])print_on_off (PRINT_ANY ,"isolated" ,"isolated %s " ,rta_getattr_u8 (prtb[IFLA_BRPORT_ISOLATED ]));@@ -311,6 +315,7 @@ static void usage(void)" [ mab {on | off} ]\n" " [ hwmode {vepa | veb} ]\n" " [ backup_port DEVICE ] [ nobackup_port ]\n" +" [ backup_nhid NHID ]\n" I thought about whether there should be "
nobackup_nhid", but no. The correspondingnobackup_portis necessary because it would be awkward to specify "backup_port''" or something. No such issue with NHID.Quoted 12 lines
bridge/link.c +1
-0" [ self ] [ master ]\n" " bridge link show [dev DEV]\n");exit (-1 );@@ -330,6 +335,7 @@ static int brlink_modify(int argc, char **argv) };char *d =NULL ;int backup_port_idx =-1 ; +__s32 backup_nhid =-1 ;__s8 neigh_suppress =-1 ;__s8 neigh_vlan_suppress =-1 ;__s8 learning =-1 ;bridge/link.c static int brlink_modify(int argc, char **argv) · line 505
Quoted 7 lines
bridge/link.c +4
-0@@ -493,6 +499,10 @@ static int brlink_modify(int argc, char **argv) } }else if (strcmp (*argv,"nobackup_port" ) ==0 ) { backup_port_idx =0 ; + }else if (strcmp (*argv,"backup_nhid" ) ==0 ) { +NEXT_ARG (); +if (get_s32 (&backup_nhid, *argv,0 )) +invarg ("invalid backup_nhid" , *argv);Not sure about that s32. NHID's are unsigned in general. I can add a NHID of
0xffffffffjust fine:
Quoted 7 lines
# ip nexthop add id 0xffffffff via 192.0.2.3 dev Xd(Though ip nexthop show then loops endlessly probably because -1 is used as a sentinel in the dump code. Oops!)
IMHO the tool should allow configuring this. You allow full u32 range for the "ip" tool, no need for "bridge" to be arbitrarily limited.
What about the diff below?
bridge/link.c +5 -3
@@ -334,8 +334,9 @@ static int brlink_modify(int argc, char **argv) .ifm.ifi_family = PF_BRIDGE, };char *d =NULL ; +bool backup_nhid_set = false; +__u32 backup_nhid;int backup_port_idx =-1 ; -__s32 backup_nhid =-1 ;__s8 neigh_suppress =-1 ;__s8 neigh_vlan_suppress =-1 ;__s8 learning =-1 ;
@@ -501,8 +502,9 @@ static int brlink_modify(int argc, char **argv) backup_port_idx =0 ; }else if (strcmp (*argv,"backup_nhid" ) ==0 ) {NEXT_ARG (); -if (get_s32 (&backup_nhid, *argv,0 )) +if (get_u32 (&backup_nhid, *argv,0 ))invarg ("invalid backup_nhid" , *argv); + backup_nhid_set = true; }else {usage (); }
@@ -589,7 +591,7 @@ static int brlink_modify(int argc, char **argv)addattr32 (&req.n,sizeof (req),IFLA_BRPORT_BACKUP_PORT , backup_port_idx); -if (backup_nhid !=-1 ) +if (backup_nhid_set)addattr32 (&req.n,sizeof (req),IFLA_BRPORT_BACKUP_NHID , backup_nhid);
Petr Machata
Reviewed-byQuoted 53 lines · Ido Schimmel
Quoted 15 lines · Petr Machata
Review static int brlink_modify(int argc, char **argv) · line 505
Quoted 8 lines · Ido Schimmel
(quoted diff) +4
-0@@ -493,6 +499,10 @@ static int brlink_modify(int argc, char **argv) } } else if (strcmp(*argv, "nobackup_port") == 0) { backup_port_idx = 0; + } else if (strcmp(*argv, "backup_nhid") == 0) { + NEXT_ARG(); + if (get_s32(&backup_nhid, *argv, 0)) + invarg("invalid backup_nhid", *argv);Not sure about that s32. NHID's are unsigned in general. I can add a NHID of
0xffffffffjust fine:Quoted 7 lines
# ip nexthop add id 0xffffffff via 192.0.2.3 dev Xd(Though ip nexthop show then loops endlessly probably because -1 is used as a sentinel in the dump code. Oops!)
IMHO the tool should allow configuring this. You allow full u32 range for the "ip" tool, no need for "bridge" to be arbitrarily limited.
What about the diff below?
bridge/link.c +4
-2@@ -334,8 +334,9 @@ static int brlink_modify(int argc, char **argv) .ifm.ifi_family = PF_BRIDGE, };char *d =NULL ; +bool backup_nhid_set = false; +__u32 backup_nhid;int backup_port_idx =-1 ; -__s32 backup_nhid =-1 ;__s8 neigh_suppress =-1 ;__s8 neigh_vlan_suppress =-1 ;__s8 learning =-1 ;@@ -501,8 +502,9 @@ static int brlink_modify(int argc, char **argv) backup_port_idx =0 ; }else if (strcmp (*argv,"backup_nhid" ) ==0 ) {NEXT_ARG (); -if (get_s32 (&backup_nhid, *argv,0 )) +if (get_u32 (&backup_nhid, *argv,0 ))invarg ("invalid backup_nhid" , *argv); + backup_nhid_set = true; }else {usage (); }
bridge/link.c static int brlink_modify(int argc, char **argv) · line 596
Quoted 7 lines
bridge/link.c +1
-1@@ -589,7 +591,7 @@ static int brlink_modify(int argc, char **argv)addattr32 (&req.n,sizeof (req),IFLA_BRPORT_BACKUP_PORT , backup_port_idx); -if (backup_nhid !=-1 ) +if (backup_nhid_set)addattr32 (&req.n,sizeof (req),IFLA_BRPORT_BACKUP_NHID , backup_nhid);
Yep, that's what I had in mind.
With that:
Quoted 21 lines · Ido Schimmel
Quoted 11 lines · Petr Machata
Quoted 8 lines · Ido Schimmel
bridge/link.c +0
-0@@ -186,6 +186,10 @@ static void print_protinfo(FILE *fp, struct rtattr *attr) ll_index_to_name(ifidx)); }Quoted 8 lines
bridge/link.c static void print_protinfo(FILE *fp, struct rtattr *attr) · line 192
Quoted 4 lines
bridge/link.c +4
-0+if (prtb[IFLA_BRPORT_BACKUP_NHID ]) +print_uint (PRINT_ANY ,"backup_nhid" ,"backup_nhid %u " , +rta_getattr_u32 (prtb[IFLA_BRPORT_BACKUP_NHID ])); +This doesn't build on current main. I think we usually send the relevant header sync patch, but maybe there's an assumption the maintainer pushes it _before_ this patch? I'm not sure, just calling it out.
Quoted 1 line
Not needed. David syncs the headers himself.
just pushed the update.
Quoted 38 lines
Quoted 38 lines
bridge/link.c static void usage(void) · line 318
Quoted 10 lines
bridge/link.c +1
-0if (prtb[IFLA_BRPORT_ISOLATED ])print_on_off (PRINT_ANY ,"isolated" ,"isolated %s " ,rta_getattr_u8 (prtb[IFLA_BRPORT_ISOLATED ]));@@ -311,6 +315,7 @@ static void usage(void)" [ mab {on | off} ]\n" " [ hwmode {vepa | veb} ]\n" " [ backup_port DEVICE ] [ nobackup_port ]\n" +" [ backup_nhid NHID ]\n" I thought about whether there should be "
nobackup_nhid", but no. The correspondingnobackup_portis necessary because it would be awkward to specify "backup_port''" or something. No such issue with NHID.Quoted 12 lines
bridge/link.c +1
-0" [ self ] [ master ]\n" " bridge link show [dev DEV]\n");exit (-1 );@@ -330,6 +335,7 @@ static int brlink_modify(int argc, char **argv) };char *d =NULL ;int backup_port_idx =-1 ; +__s32 backup_nhid =-1 ;__s8 neigh_suppress =-1 ;__s8 neigh_vlan_suppress =-1 ;__s8 learning =-1 ;bridge/link.c static int brlink_modify(int argc, char **argv) · line 505
Quoted 7 lines
bridge/link.c +4
-0@@ -493,6 +499,10 @@ static int brlink_modify(int argc, char **argv) } }else if (strcmp (*argv,"nobackup_port" ) ==0 ) { backup_port_idx =0 ; + }else if (strcmp (*argv,"backup_nhid" ) ==0 ) { +NEXT_ARG (); +if (get_s32 (&backup_nhid, *argv,0 )) +invarg ("invalid backup_nhid" , *argv);Not sure about that s32. NHID's are unsigned in general. I can add a NHID of
0xffffffffjust fine:
Quoted 4 lines
Quoted 4 lines
# ip nexthop add id 0xffffffff via 192.0.2.3 dev Xd(Though ip nexthop show then loops endlessly probably because -1 is used as a sentinel in the dump code. Oops!)
ugh, please send a fix.
Quoted 1 line · David Ahern
ugh, please send a fix.
Will send a fix tomorrow. Seems to be fixed by [1], but we might need something similar for the bucket dump.
[1]
net/ipv4/nexthop.c +2 -2
@@ -3170,7 +3170,7 @@ static int nh_valid_dump_req(const struct nlmsghdr *nlh, }struct rtm_dump_nh_ctx { -u32 idx; +u64 idx; }; static struct rtm_dump_nh_ctx *
@@ -3192,7 +3192,7 @@ static int rtm_dump_walk_nexthops(struct sk_buff *skb, void *data) {struct rb_node *node; -int s_idx; +u64 s_idx;int err; s_idx = ctx->idx;