diff --git a/dockers/docker-fpm-frr/frr/zebra/zebra.interfaces.conf.j2 b/dockers/docker-fpm-frr/frr/zebra/zebra.interfaces.conf.j2 index 88ad9b46dac2..1605761cb638 100644 --- a/dockers/docker-fpm-frr/frr/zebra/zebra.interfaces.conf.j2 +++ b/dockers/docker-fpm-frr/frr/zebra/zebra.interfaces.conf.j2 @@ -9,6 +9,31 @@ exit {% endfor %} {% endif %} {% endblock vrf %} +{% block setsrc %} +{% if BGP_GLOBALS is defined and BGP_GLOBALS|length > 0 %} +{% for vrf, bgp_sess in BGP_GLOBALS.items() %} +{% if 'route_map' in bgp_sess %} +! +vrf {{ vrf }} + ip protocol bgp route-map {{ bgp_sess['route_map'] }} +{% endif %} +{% if 'route_map_ipv6' in bgp_sess %} +! +vrf {{ vrf }} + ipv6 protocol bgp route-map {{ bgp_sess['route_map_ipv6'] }} +{% endif %} +{% endfor %} +{% endif %} +{% if ROUTE_MAP is defined and ROUTE_MAP|length > 0 %} +{% for rm_key, rm_val in ROUTE_MAP.items() %} +{% if 'route_operation' in rm_val and 'set_src' in rm_val %} +! +route-map {{rm_key[0]}} {{rm_val['route_operation']}} {{rm_key[1]}} + set src {{rm_val['set_src']}} +{% endif %} +{% endfor %} +{% endif %} +{% endblock setsrc %} ! {% block interfaces %} ! Enable nht through default route diff --git a/src/sonic-frr-mgmt-framework/frrcfgd/frrcfgd.py b/src/sonic-frr-mgmt-framework/frrcfgd/frrcfgd.py index c2a9f0c142ad..2adbc341339a 100755 --- a/src/sonic-frr-mgmt-framework/frrcfgd/frrcfgd.py +++ b/src/sonic-frr-mgmt-framework/frrcfgd/frrcfgd.py @@ -1754,7 +1754,9 @@ class BGPConfigDaemon: ('confed_id', '{no:no-prefix}bgp confederation identifier {}'), ('confed_peers', '{no:no-prefix}bgp confederation peers {}', hdl_confed_peers), (['keepalive', 'holdtime'], '{no:no-prefix}timers bgp {} {}'), - (['max_med_admin', '+max_med_admin_val'], '{no:no-prefix}bgp max-med administrative {}', ['true', 'false']) + (['max_med_admin', '+max_med_admin_val'], '{no:no-prefix}bgp max-med administrative {}', ['true', 'false']), + ('route_map', '[zebra]{no:no-prefix}ip protocol bgp route-map {}'), + ('route_map_ipv6', '[zebra]{no:no-prefix}ipv6 protocol bgp route-map {}'), ] global_af_key_map = [(['ebgp_route_distance', @@ -1877,6 +1879,7 @@ class BGPConfigDaemon: ('call_route_map', '{no:no-prefix}call {:enable-only}'), ('set_origin', '[bgpd]{no:no-prefix}set origin {:tolower}'), ('set_local_pref', '[bgpd]{no:no-prefix}set local-preference {}'), + ('set_src', '[zebra]{no:no-prefix}set src {}'), ('set_next_hop', '{no:no-prefix}set ip next-hop {}'), ('set_ipv6_next_hop_global', '[bgpd]{no:no-prefix}set ipv6 next-hop global {}'), ('set_ipv6_next_hop_prefer_global', '[bgpd]{no:no-prefix}set ipv6 next-hop prefer-global', ['true', 'false']), @@ -2642,6 +2645,13 @@ def __update_bgp(self, data_list): if local_asn is None: syslog.syslog(syslog.LOG_ERR, 'local ASN for VRF %s was not configured' % vrf) continue + for route_map_key in ['route_map', 'route_map_ipv6']: + if route_map_key in data: + # Route maps are configured in a different context, so they need a different cmd_prefix + cmd_prefix = ['configure terminal', 'vrf {}'.format(vrf)] + if not key_map.run_command(self, table, {route_map_key: data[route_map_key]}, cmd_prefix): + syslog.syslog(syslog.LOG_ERR, 'failed running BGP global config command') + del data[route_map_key] cmd_prefix = ['configure terminal', 'router bgp {} vrf {}'.format(local_asn, vrf)] if not key_map.run_command(self, table, data, cmd_prefix): syslog.syslog(syslog.LOG_ERR, 'failed running BGP global config command') diff --git a/src/sonic-frr/frr b/src/sonic-frr/frr index de0e358b877a..3539968c38ed 160000 --- a/src/sonic-frr/frr +++ b/src/sonic-frr/frr @@ -1 +1 @@ -Subproject commit de0e358b877ac9b595e7fb387a302c960a4c02d1 +Subproject commit 3539968c38ed8d46b9705014b5492b1a610888d5 diff --git a/src/sonic-yang-models/tests/yang_model_tests/tests/bgp.json b/src/sonic-yang-models/tests/yang_model_tests/tests/bgp.json index 543a985670f3..64b60fb52b36 100644 --- a/src/sonic-yang-models/tests/yang_model_tests/tests/bgp.json +++ b/src/sonic-yang-models/tests/yang_model_tests/tests/bgp.json @@ -2,6 +2,9 @@ "BGP_GLOBAL_VALID": { "desc": "Configure BGP global table." }, + "BGP_GLOBAL_ROUTE_MAP_VALID": { + "desc": "Configure BGP global table with route map." + }, "BGP_NEIGHBOR_ALL_VALID": { "desc": "Configure BGP neighbor table." }, diff --git a/src/sonic-yang-models/tests/yang_model_tests/tests_config/bgp.json b/src/sonic-yang-models/tests/yang_model_tests/tests_config/bgp.json index 6ecc90c38699..dea1ab387b0b 100644 --- a/src/sonic-yang-models/tests/yang_model_tests/tests_config/bgp.json +++ b/src/sonic-yang-models/tests/yang_model_tests/tests_config/bgp.json @@ -82,6 +82,36 @@ } }, + "BGP_GLOBAL_ROUTE_MAP_VALID": { + "sonic-vrf:sonic-vrf":{ + "sonic-vrf:VRF": { + "VRF_LIST": [ + { + "name":"Vrf1" + } + ] + } + }, + "sonic-bgp-global:sonic-bgp-global": { + "sonic-bgp-global:BGP_GLOBALS": { + "BGP_GLOBALS_LIST": [ + { + "vrf_name":"default", + "local_asn": 65001, + "route_map": "RM_SET_SRC", + "route_map_ipv6": "RM_SET_SRC6" + }, + { + "vrf_name":"Vrf1", + "local_asn": 65001, + "route_map": "RM_SET_SRC", + "route_map_ipv6": "RM_SET_SRC6" + } + ] + } + } + }, + "BGP_NEIGHBOR_ALL_VALID": { "sonic-port:sonic-port": { "sonic-port:PORT": { diff --git a/src/sonic-yang-models/tests/yang_model_tests/tests_config/route_filter.json b/src/sonic-yang-models/tests/yang_model_tests/tests_config/route_filter.json index 55ba644ae6be..d99a59cafa56 100644 --- a/src/sonic-yang-models/tests/yang_model_tests/tests_config/route_filter.json +++ b/src/sonic-yang-models/tests/yang_model_tests/tests_config/route_filter.json @@ -180,6 +180,7 @@ "set_metric_action": "METRIC_SET_VALUE", "set_metric": 50, "set_next_hop": "10.10.10.10", + "set_src": "10.10.10.10", "set_ipv6_next_hop_global": "1000::1", "set_ipv6_next_hop_prefer_global": true, "set_repeat_asn": 5, diff --git a/src/sonic-yang-models/yang-models/sonic-bgp-global.yang b/src/sonic-yang-models/yang-models/sonic-bgp-global.yang index db6c02356aa6..12a0b2ef3955 100644 --- a/src/sonic-yang-models/yang-models/sonic-bgp-global.yang +++ b/src/sonic-yang-models/yang-models/sonic-bgp-global.yang @@ -317,6 +317,16 @@ module sonic-bgp-global { type uint16; description "Hold time"; } + + leaf route_map { + type string; + description "IPv4 route map to apply to BGP-learned routes in Zebra"; + } + + leaf route_map_ipv6 { + type string; + description "IPv6 route map to apply to BGP-learned routes in Zebra"; + } } } diff --git a/src/sonic-yang-models/yang-models/sonic-route-map.yang b/src/sonic-yang-models/yang-models/sonic-route-map.yang index 3a5d1f256fd3..bcbe11790214 100644 --- a/src/sonic-yang-models/yang-models/sonic-route-map.yang +++ b/src/sonic-yang-models/yang-models/sonic-route-map.yang @@ -294,6 +294,11 @@ module sonic-route-map { description "Set metric value"; } + leaf set_src{ + type string; + description "Set route source address"; + } + leaf set_next_hop{ type string; description "Set IP nexthop";