From ecb7368655c188d2371ed23de28c4ce93ecb447c Mon Sep 17 00:00:00 2001 From: sudhanshukumar22 Date: Sun, 1 Nov 2020 03:50:35 -0800 Subject: [PATCH] bgpd: BGP session not established for ipv6 link local address with vrf config Description: BGP session not established for ipv6 link local address with vrf config Problem Description/Summary : BGP session not established for ipv6 link local address with vrf configyy 1.Configure ipv6 link-local address fe80::1234/64 on dut1 and fe80::4567/64 on dut2 2.Configure BGP neighbors for ipv6 link-local on both dut1 and dut2 3.Verify BGP session is UP over link-local ipv6 address 4.Observed that bgp session not established for ipv6 link local address Expected Behavior : BGP session should be established for ipv6 link local address with vrf config Signed-off-by: sudhanshukumar22 --- bgpd/bgp_network.c | 4 + bgpd/bgp_zebra.c | 3 + .../bgp_vrf_ipv6_link_local/__init__.py | 0 .../bgp_vrf_ipv6_link_local/r1/bgpd.conf | 8 ++ .../bgp_vrf_ipv6_link_local/r1/zebra.conf | 8 ++ .../bgp_vrf_ipv6_link_local/r2/bgpd.conf | 9 ++ .../bgp_vrf_ipv6_link_local/r2/zebra.conf | 8 ++ .../test_bgp_vrf_ipv6_ll_func.py | 121 ++++++++++++++++++ 8 files changed, 161 insertions(+) create mode 100755 tests/topotests/bgp_vrf_ipv6_link_local/__init__.py create mode 100755 tests/topotests/bgp_vrf_ipv6_link_local/r1/bgpd.conf create mode 100755 tests/topotests/bgp_vrf_ipv6_link_local/r1/zebra.conf create mode 100755 tests/topotests/bgp_vrf_ipv6_link_local/r2/bgpd.conf create mode 100755 tests/topotests/bgp_vrf_ipv6_link_local/r2/zebra.conf create mode 100755 tests/topotests/bgp_vrf_ipv6_link_local/test_bgp_vrf_ipv6_ll_func.py diff --git a/bgpd/bgp_network.c b/bgpd/bgp_network.c index 03ff27c7ca55..5691a98996f2 100644 --- a/bgpd/bgp_network.c +++ b/bgpd/bgp_network.c @@ -660,6 +660,10 @@ static int bgp_update_address(struct interface *ifp, const union sockunion *dst, return 1; prefix2sockunion(sel, addr); + + if (IN6_IS_ADDR_LINKLOCAL(&addr->sin6.sin6_addr)) + addr->sin6.sin6_scope_id = ifp->ifindex; + return 0; } diff --git a/bgpd/bgp_zebra.c b/bgpd/bgp_zebra.c index c554332255df..13664c68531d 100644 --- a/bgpd/bgp_zebra.c +++ b/bgpd/bgp_zebra.c @@ -759,6 +759,9 @@ bool bgp_zebra_nexthop_set(union sockunion *local, union sockunion *remote, ? peer->conf_if : peer->ifname, peer->bgp->vrf_id); + else if (peer->update_if) + ifp = if_lookup_by_name(peer->update_if, + peer->bgp->vrf_id); } else if (peer->update_if) ifp = if_lookup_by_name(peer->update_if, peer->bgp->vrf_id); diff --git a/tests/topotests/bgp_vrf_ipv6_link_local/__init__.py b/tests/topotests/bgp_vrf_ipv6_link_local/__init__.py new file mode 100755 index 000000000000..e69de29bb2d1 diff --git a/tests/topotests/bgp_vrf_ipv6_link_local/r1/bgpd.conf b/tests/topotests/bgp_vrf_ipv6_link_local/r1/bgpd.conf new file mode 100755 index 000000000000..9896b56826b9 --- /dev/null +++ b/tests/topotests/bgp_vrf_ipv6_link_local/r1/bgpd.conf @@ -0,0 +1,8 @@ +! +router bgp 65001 vrf blue + neighbor 192.168.255.2 remote-as 65002 + neighbor 192.168.255.2 timers 3 10 + neighbor fe80:1::2 remote-as 65002 + neighbor fe80:1::2 timers 3 10 + neighbor fe80:1::2 interface r1-eth1 +! diff --git a/tests/topotests/bgp_vrf_ipv6_link_local/r1/zebra.conf b/tests/topotests/bgp_vrf_ipv6_link_local/r1/zebra.conf new file mode 100755 index 000000000000..ca3941017f07 --- /dev/null +++ b/tests/topotests/bgp_vrf_ipv6_link_local/r1/zebra.conf @@ -0,0 +1,8 @@ +! +interface r1-eth1 vrf blue + ip address 192.168.255.1/24 + ipv6 address fe80:1::1/64 +! +ip forwarding +ipv6 forwarding +! diff --git a/tests/topotests/bgp_vrf_ipv6_link_local/r2/bgpd.conf b/tests/topotests/bgp_vrf_ipv6_link_local/r2/bgpd.conf new file mode 100755 index 000000000000..694af0911441 --- /dev/null +++ b/tests/topotests/bgp_vrf_ipv6_link_local/r2/bgpd.conf @@ -0,0 +1,9 @@ +! +router bgp 65002 vrf blue + neighbor 192.168.255.1 remote-as 65001 + neighbor 192.168.255.1 timers 3 10 + neighbor fe80:1::1 remote-as 65001 + neighbor fe80:1::1 timers 3 10 + neighbor fe80:1::1 interface r2-eth1 + +! diff --git a/tests/topotests/bgp_vrf_ipv6_link_local/r2/zebra.conf b/tests/topotests/bgp_vrf_ipv6_link_local/r2/zebra.conf new file mode 100755 index 000000000000..d6ed716d49ed --- /dev/null +++ b/tests/topotests/bgp_vrf_ipv6_link_local/r2/zebra.conf @@ -0,0 +1,8 @@ +! +interface r2-eth1 vrf blue + ip address 192.168.255.2/24 + ipv6 address fe80:1::2/64 +! +ip forwarding +ipv6 forwarding +! diff --git a/tests/topotests/bgp_vrf_ipv6_link_local/test_bgp_vrf_ipv6_ll_func.py b/tests/topotests/bgp_vrf_ipv6_link_local/test_bgp_vrf_ipv6_ll_func.py new file mode 100755 index 000000000000..3c8fa97fe359 --- /dev/null +++ b/tests/topotests/bgp_vrf_ipv6_link_local/test_bgp_vrf_ipv6_ll_func.py @@ -0,0 +1,121 @@ +#!/usr/bin/env python +# +# Copyright 2021 Broadcom. The term Broadcom refers to Broadcom Inc. and/or +# its subsidiaries. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +""" +Test link-local address as a BGP peer over VRF. +""" + +import os +import sys +import json +import pytest +import functools + +CWD = os.path.dirname(os.path.realpath(__file__)) +sys.path.append(os.path.join(CWD, "../")) + +# pylint: disable=C0413 +from lib import topotest +from lib.topogen import Topogen, TopoRouter, get_topogen +from lib.topolog import logger +from mininet.topo import Topo + + +class TemplateTopo(Topo): + def build(self, *_args, **_opts): + tgen = get_topogen(self) + + for routern in range(1, 3): + tgen.add_router("r{}".format(routern)) + switch = tgen.add_switch("s1") + switch.add_link(tgen.gears["r1"]) + switch.add_link(tgen.gears["r2"]) + + # r1-r2 2 + switch = tgen.add_switch("s2") + switch.add_link(tgen.gears["r1"]) + switch.add_link(tgen.gears["r2"]) + + +def setup_module(mod): + tgen = Topogen(TemplateTopo, mod.__name__) + tgen.start_topology() + + r1 = tgen.gears["r1"] + r2 = tgen.gears["r2"] + + # blue vrf + r1.run("ip link add blue type vrf table 1001") + r1.run("ip link set up dev blue") + r2.run("ip link add blue type vrf table 1001") + r2.run("ip link set up dev blue") + + r1.run("ip link add lo1 type dummy") + r1.run("ip link set lo1 master blue") + r1.run("ip link set up dev lo1") + r2.run("ip link add lo1 type dummy") + r2.run("ip link set up dev lo1") + r2.run("ip link set lo1 master blue") + + r1.run("ip link set r1-eth1 master blue") + r2.run("ip link set r2-eth1 master blue") + + r1.run("ip link set up dev r1-eth1") + r2.run("ip link set up dev r2-eth1") + router_list = tgen.routers() + + for i, (rname, router) in enumerate(router_list.items(), 1): + router.load_config( + TopoRouter.RD_ZEBRA, os.path.join(CWD, "{}/zebra.conf".format(rname)) + ) + router.load_config( + TopoRouter.RD_BGP, os.path.join(CWD, "{}/bgpd.conf".format(rname)) + ) + tgen.start_router() + + +def teardown_module(mod): + tgen = get_topogen() + tgen.stop_topology() + + +def test_bgp_vrf_link_local(): + tgen = get_topogen() + + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + + def _bgp_peer_group_configured(): + output = json.loads( + tgen.gears["r1"].vtysh_cmd("show ip bgp vrf blue neighbor json") + ) + expected = { + "fe80:1::2": {"bgpState": "Established"}, + } + return topotest.json_cmp(output, expected) + + test_func = functools.partial(_bgp_peer_group_configured) + success, result = topotest.run_and_expect(test_func, None, count=60, wait=0.5) + + assert result is None, 'Failed bgp convergence in "{}"'.format(tgen.gears["r1"]) + + +if __name__ == "__main__": + args = ["-s"] + sys.argv[1:] + sys.exit(pytest.main(args)) +