diff --git a/config/main.py b/config/main.py index 3daf93c73d..888b0fe3cc 100755 --- a/config/main.py +++ b/config/main.py @@ -4009,6 +4009,8 @@ def add_route(ctx, command_str): # If defined intf name, check if it belongs to interface if 'ifname' in route: if (not route['ifname'] in config_db.get_keys('VLAN_INTERFACE') and + not route['ifname'] in config_db.get_keys('VLAN') and + not route['ifname'] in config_db.get_keys('VLAN_INTERFACE') and not route['ifname'] in config_db.get_keys('INTERFACE') and not route['ifname'] in config_db.get_keys('PORTCHANNEL_INTERFACE') and not route['ifname'] == 'null'): @@ -4054,6 +4056,9 @@ def add_route(ctx, command_str): # Check if exist entry with key keys = config_db.get_keys('STATIC_ROUTE') if key in keys: + if 'null' in route['ifname']: + ctx.fail("this route is already configured on nexthop, remove it before configuring to black hole") + # If exist update current entry current_entry = config_db.get_entry('STATIC_ROUTE', key) diff --git a/tests/static_routes_test.py b/tests/static_routes_test.py index c354cb97c4..fe8507b0ba 100644 --- a/tests/static_routes_test.py +++ b/tests/static_routes_test.py @@ -25,6 +25,9 @@ ERROR_INVALID_IP = ''' Error: ip address is not valid. ''' +ERROR_BLACKHOLE = ''' +Error: this route is already configured on nexthop, remove it before configuring to black hole +''' class TestStaticRoutes(object): @@ -358,6 +361,70 @@ def test_del_entire_ECMP_static_route(self): print(result.exit_code, result.output) assert not '14.2.3.4/32' in db.cfgdb.get_table('STATIC_ROUTE') + def test_static_route_blackhole_with_nexthop(self): + db = Db() + runner = CliRunner() + obj = {'config_db':db.cfgdb} + + # config route add prefix 15.2.3.4/32 nexthop 30.0.0.5 + result = runner.invoke(config.config.commands["route"].commands["add"], \ + ["prefix", "15.2.3.4/32", "nexthop", "30.0.0.5"], obj=obj) + print(result.exit_code, result.output) + assert ('15.2.3.4/32') in db.cfgdb.get_table('STATIC_ROUTE') + assert db.cfgdb.get_entry('STATIC_ROUTE', '15.2.3.4/32') == {'nexthop': '30.0.0.5', 'blackhole': 'false', 'distance': '0', 'ifname': '', 'nexthop-vrf': ''} + + # config route add prefix 15.2.3.4/32 dev null + result = runner.invoke(config.config.commands["route"].commands["add"], \ + ["prefix", "15.2.3.4/32", "nexthop", "dev", "null"], obj=obj) + print(result.exit_code, result.output) + assert ERROR_BLACKHOLE in result.output + + def test_static_route_dev_ethernet(self): + db = Db() + runner = CliRunner() + obj = {'config_db':db.cfgdb} + + # config route add prefix 16.2.3.4/32 nexthop dev Ethernet0 + result = runner.invoke(config.config.commands["route"].commands["add"], \ + ["prefix", "16.2.3.4/32", "nexthop", "dev", "Ethernet0"], obj=obj) + print(result.exit_code, result.output) + assert ('16.2.3.4/32') in db.cfgdb.get_table('STATIC_ROUTE') + assert db.cfgdb.get_entry('STATIC_ROUTE', '16.2.3.4/32') == {'nexthop': '', 'blackhole': 'false', 'distance': '0', 'ifname': 'Ethernet0', 'nexthop-vrf': ''} + + # config route del prefix 16.2.3.4/32 nexthop dev Ethernet0 + result = runner.invoke(config.config.commands["route"].commands["del"], \ + ["prefix", "16.2.3.4/32", "nexthop", "dev", "Ethernet0"], obj=obj) + print(result.exit_code, result.output) + assert not '16.2.3.4/32' in db.cfgdb.get_table('STATIC_ROUTE') + + def test_static_route_dev_vlan(self): + db = Db() + runner = CliRunner() + obj = {'config_db':db.cfgdb} + + # config vlan add 40 + result = runner.invoke(config.config.commands["vlan"].commands["add"], ["4016"], obj=db) + print(result.exit_code, result.output) + assert ('Vlan4016') in db.cfgdb.get_table('VLAN') + + # config route add prefix 16.2.3.4/32 nexthop dev Vlan4016 + result = runner.invoke(config.config.commands["route"].commands["add"], \ + ["prefix", "16.2.3.4/32", "nexthop", "dev", "Vlan4016"], obj=obj) + print(result.exit_code, result.output) + assert ('16.2.3.4/32') in db.cfgdb.get_table('STATIC_ROUTE') + assert db.cfgdb.get_entry('STATIC_ROUTE', '16.2.3.4/32') == {'nexthop': '', 'blackhole': 'false', 'distance': '0', 'ifname': 'Vlan4016', 'nexthop-vrf': ''} + + # config route del prefix 16.2.3.4/32 nexthop dev Vlan4016 + result = runner.invoke(config.config.commands["route"].commands["del"], \ + ["prefix", "16.2.3.4/32", "nexthop", "dev", "Vlan4016"], obj=obj) + print(result.exit_code, result.output) + assert not '16.2.3.4/32' in db.cfgdb.get_table('STATIC_ROUTE') + + # config vlan del 4016 + result = runner.invoke(config.config.commands["vlan"].commands["del"], ["4016"], obj=db) + print(result.exit_code, result.output) + assert not ('Vlan4016') in db.cfgdb.get_table('VLAN') + @classmethod def teardown_class(cls): os.environ['UTILITIES_UNIT_TESTING'] = "0"