@@ -231,9 +231,72 @@ def _get_attrs(client_manager, parsed_args):
231231 if 'flavor_id' in parsed_args and parsed_args .flavor_id is not None :
232232 attrs ['flavor_id' ] = parsed_args .flavor_id
233233
234+ for attr in ('enable_default_route_bfd' , 'enable_default_route_ecmp' ):
235+ value = getattr (parsed_args , attr , None )
236+ if value is not None :
237+ attrs [attr ] = value
238+
234239 return attrs
235240
236241
242+ def _parser_add_bfd_ecmp_arguments (parser ):
243+ """Helper to add BFD and ECMP args for CreateRouter and SetRouter."""
244+ parser .add_argument (
245+ '--enable-default-route-bfd' ,
246+ dest = 'enable_default_route_bfd' ,
247+ default = None ,
248+ action = 'store_true' ,
249+ help = _ (
250+ "Enable BFD sessions for default routes inferred from "
251+ "the external gateway port subnets for this router."
252+ ),
253+ )
254+ parser .add_argument (
255+ '--disable-default-route-bfd' ,
256+ dest = 'enable_default_route_bfd' ,
257+ default = None ,
258+ action = 'store_false' ,
259+ help = _ (
260+ "Disable BFD sessions for default routes inferred from "
261+ "the external gateway port subnets for this router."
262+ ),
263+ )
264+ parser .add_argument (
265+ '--enable-default-route-ecmp' ,
266+ dest = 'enable_default_route_ecmp' ,
267+ default = None ,
268+ action = 'store_true' ,
269+ help = _ (
270+ "Add ECMP default routes if multiple are available via "
271+ "different gateway ports."
272+ ),
273+ )
274+ parser .add_argument (
275+ '--disable-default-route-ecmp' ,
276+ dest = 'enable_default_route_ecmp' ,
277+ default = None ,
278+ action = 'store_false' ,
279+ help = _ ("Add default route only for first gateway port." ),
280+ )
281+
282+
283+ def _command_check_bfd_ecmp_supported (attrs , client ):
284+ """Helper to check for server side support when bfd/ecmp attrs provided.
285+
286+ :raises: exceptions.CommandError
287+ """
288+ if (
289+ 'enable_default_route_bfd' in attrs
290+ or 'enable_default_route_ecmp' in attrs
291+ ) and not is_multiple_gateways_supported (client ):
292+ msg = _ (
293+ 'The external-gateway-multihoming extension is not enabled at '
294+ 'the Neutron side, cannot use --enable-default-route-bfd or '
295+ '--enable-default-route-ecmp arguments.'
296+ )
297+ raise exceptions .CommandError (msg )
298+
299+
237300class AddPortToRouter (command .Command ):
238301 _description = _ ("Add a port to a router" )
239302
@@ -502,6 +565,7 @@ def get_parser(self, prog_name):
502565 metavar = '<flavor-id>' ,
503566 help = _ ("Associate the router to a flavor by ID" ),
504567 )
568+ _parser_add_bfd_ecmp_arguments (parser )
505569
506570 return parser
507571
@@ -527,6 +591,8 @@ def take_action(self, parsed_args):
527591 if parsed_args .enable_ndp_proxy is not None :
528592 attrs ['enable_ndp_proxy' ] = parsed_args .enable_ndp_proxy
529593
594+ _command_check_bfd_ecmp_supported (attrs , client )
595+
530596 external_gateways = attrs .pop ('external_gateways' , None )
531597 obj = client .create_router (** attrs )
532598 # tags cannot be set when created, so tags need to be set later.
@@ -943,6 +1009,7 @@ def get_parser(self, prog_name):
9431009 help = _ ("Remove QoS policy from router gateway IPs" ),
9441010 )
9451011 _tag .add_tag_option_to_parser_for_set (parser , _ ('router' ))
1012+ _parser_add_bfd_ecmp_arguments (parser )
9461013 return parser
9471014
9481015 def take_action (self , parsed_args ):
@@ -1015,6 +1082,8 @@ def take_action(self, parsed_args):
10151082 if parsed_args .enable_ndp_proxy is not None :
10161083 attrs ['enable_ndp_proxy' ] = parsed_args .enable_ndp_proxy
10171084
1085+ _command_check_bfd_ecmp_supported (attrs , client )
1086+
10181087 if attrs :
10191088 external_gateways = attrs .pop ('external_gateways' , None )
10201089 client .update_router (obj , ** attrs )
0 commit comments