Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

8.0 backports #8827

Merged
merged 44 commits into from
Jun 16, 2021
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
44 commits
Select commit Hold shift + click to select a range
92e19ec
ospf6d: unlink router from vrf on deletion
idryzhov May 27, 2021
4ef2323
pceplib: fix mixup of global/local variables
idryzhov May 28, 2021
09cbc07
isisd, ospf6d, pimd: set vrf_id when creating bfd sessions
idryzhov May 31, 2021
00574f0
isisd: fix using vrf interface as a loopback
idryzhov May 28, 2021
b144fae
ospf6d: fix using vrf interface as a loopback
idryzhov May 28, 2021
0e99a6c
bgpd: pass correct vrf_id to vrf_socket when creating bgp view socket
idryzhov May 31, 2021
cd89989
lib: fix binding to a vrf
idryzhov May 6, 2021
21cd75a
tests: remove tcp_l3mdev_accept setting
idryzhov May 7, 2021
fb6c9eb
doc: update VRF support description
idryzhov May 12, 2021
bfe3510
pathd: fix render candidate-path bandwidth
edipascale May 18, 2021
093a8f6
doc: Replace single tick with double tick under developer/topotests.rst
ton31337 Jun 2, 2021
753c7da
ospfd: if destroy the whole ospf, then remove ospf's interface config…
anlancs Jun 2, 2021
3f30364
doc: remove varnames from command descriptions
idryzhov Jun 2, 2021
9e3fd54
bfdd: fix bfd key structure
idryzhov Jun 1, 2021
1077c27
doc: fix link-params commands
idryzhov Jun 2, 2021
1627291
doc: add separate section for nexthop tracking
idryzhov Jun 2, 2021
b273ee4
lib, vtysh: reduce code duplication
idryzhov Jun 2, 2021
8010eb4
lib: fix output of "list" and "find" commands
idryzhov Jun 2, 2021
1d91cb7
bgpd: fix enabling bfd debug
idryzhov May 28, 2021
aeae109
lib: fix bfd multihop
idryzhov May 27, 2021
15a1754
lib: fix default ttl for single-hop bfd sessions
idryzhov Jun 1, 2021
ccb83eb
bfdd: don't store interface pointer for multihop sessions
idryzhov May 28, 2021
55d9ae7
bfdd: forbid setting interface for multihop sessions
idryzhov May 28, 2021
8ab721b
zebra: fix config after exit from vrf
idryzhov Jun 2, 2021
39a0be2
lib: fix address sanitizer crash on `find`
rzalamena Jun 7, 2021
86147fc
ospfd: fix passive interface configuration
idryzhov Jun 4, 2021
3b9c5af
doc: replace "passive-interface IFNAME" with "ip ospf passive"
idryzhov Jun 5, 2021
e68ecdc
ospfd: fix GR helper initialization and termination
rwestphal May 31, 2021
bb590fa
ospfd: fix small issue when exiting from the GR helper mode
rwestphal May 31, 2021
fc2ef24
ospfd: fix crash when logging a Grace-LSA
rwestphal May 31, 2021
16e7fe2
ospfd: fix dangling pointer when exiting from the helper mode
rwestphal May 31, 2021
d11e0c8
ospfd: fix null pointer dereference when flushing an opaque LSA
rwestphal May 31, 2021
8ff13a6
ospfd: fix cleanup of MaxAge LSAs on exit
rwestphal May 31, 2021
8f2eb95
ospfd: fix logging of what triggered the SPF run
rwestphal May 31, 2021
dd65dbe
zebra, ospfd: fix typos in the graceful restart code
rwestphal May 31, 2021
cd63b18
ospfd: fix wrong NSSA debug guards
rwestphal May 31, 2021
8e25bd9
lib, ospfd, ospf6d: fix logging of pointer addresses
rwestphal May 31, 2021
6a74bca
ospfd: fix crash when displaying neighbor data in JSON
rwestphal May 31, 2021
de4b84a
zebra: Give extra space and stop processing if we run out of space
donaldsharp Jun 8, 2021
8e85b98
ospfd: fix memory leaks in summarization
idryzhov Jun 8, 2021
0f7e131
tests: fix ospf6_topo1_vrf
idryzhov Jun 7, 2021
11712da
ospf6d: fix interface area configuration
idryzhov May 25, 2021
83ba066
doc: replace "interface IFNAME area" with "ipv6 ospf6 area"
idryzhov May 25, 2021
2cfc327
tests: replace "interface IFNAME area" with "ipv6 ospf6 area"
idryzhov Jun 7, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
lib: fix binding to a vrf
There are two possible use-cases for the `vrf_bind` function:
- bind socket to an interface in a vrf
- bind socket to a vrf device

For the former case, there's one problem - success is returned when the
interface is not found. In that case, the socket is left unbound without
throwing an error.

For the latter case, there are multiple possible problems:
- If the name is not set, then the socket is left unbound (zebra, vrrp).
- If the name is "default" and there's an interface with that name in the
  default VRF, then the socket is bound to that interface.
- In most daemons, if the router is configured before the VRF is actually
  created, we're trying to open and bind the socket right after the
  daemon receives a VRF registration from zebra. We may not receive the
  VRF-interface registration from zebra yet at that point. Therefore,
  `if_lookup_by_name` fails, and the socket is left unbound.

This commit fixes all the issues and updates the function description.

Suggested-by: Pat Ruddy <pat@voltanet.io>
Signed-off-by: Igor Ryzhov <iryzhov@nfware.com>
  • Loading branch information
idryzhov committed Jun 8, 2021
commit cd899898eee0126547d2931d9de7db025151c653
51 changes: 38 additions & 13 deletions lib/vrf.c
Original file line number Diff line number Diff line change
Expand Up @@ -993,25 +993,50 @@ const char *vrf_get_default_name(void)
return vrf_default_name;
}

int vrf_bind(vrf_id_t vrf_id, int fd, const char *name)
int vrf_bind(vrf_id_t vrf_id, int fd, const char *ifname)
{
int ret = 0;
struct interface *ifp;
struct vrf *vrf;

if (fd < 0)
return -1;

if (vrf_id == VRF_UNKNOWN)
return -1;

/* can't bind to a VRF that doesn't exist */
vrf = vrf_lookup_by_id(vrf_id);
if (!vrf_is_enabled(vrf))
return -1;

if (ifname && strcmp(ifname, vrf->name)) {
/* binding to a regular interface */

/* can't bind to an interface that doesn't exist */
ifp = if_lookup_by_name(ifname, vrf_id);
if (!ifp)
return -1;
} else {
/* binding to a VRF device */

/* nothing to do for netns */
if (vrf_is_backend_netns())
return 0;

/* nothing to do for default vrf */
if (vrf_id == VRF_DEFAULT)
return 0;

ifname = vrf->name;
}

if (fd < 0 || name == NULL)
return fd;
/* the device should exist
* otherwise we should return
* case ifname = vrf in netns mode => return
*/
ifp = if_lookup_by_name(name, vrf_id);
if (!ifp)
return fd;
#ifdef SO_BINDTODEVICE
ret = setsockopt(fd, SOL_SOCKET, SO_BINDTODEVICE, name, strlen(name)+1);
ret = setsockopt(fd, SOL_SOCKET, SO_BINDTODEVICE, ifname,
strlen(ifname) + 1);
if (ret < 0)
zlog_debug("bind to interface %s failed, errno=%d", name,
errno);
zlog_err("bind to interface %s failed, errno=%d", ifname,
errno);
#endif /* SO_BINDTODEVICE */
return ret;
}
Expand Down
11 changes: 5 additions & 6 deletions lib/vrf.h
Original file line number Diff line number Diff line change
Expand Up @@ -251,15 +251,14 @@ extern int vrf_sockunion_socket(const union sockunion *su, vrf_id_t vrf_id,
const char *name);

/*
* Binds a socket to a VRF device.
* Binds a socket to an interface (ifname) in a VRF (vrf_id).
*
* If name is null, the socket is not bound, irrespective of any other
* arguments.
* If ifname is NULL or is equal to the VRF name then bind to a VRF device.
* Otherwise, bind to the specified interface in the specified VRF.
*
* name should be the name of the VRF device. vrf_id should be the
* corresponding vrf_id (the ifindex of the device).
* Returns 0 on success and -1 on failure.
*/
extern int vrf_bind(vrf_id_t vrf_id, int fd, const char *name);
extern int vrf_bind(vrf_id_t vrf_id, int fd, const char *ifname);

/* VRF ioctl operations */
extern int vrf_getaddrinfo(const char *node, const char *service,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@
from lib import topotest
from lib.topogen import Topogen, TopoRouter, get_topogen
from lib.topolog import logger
from lib.common_config import adjust_router_l3mdev
from lib.common_config import required_linux_kernel_version

# Required to instantiate the topology builder class.
from mininet.topo import Topo
Expand All @@ -66,6 +66,12 @@ def build(self, *_args, **_opts):

def setup_module(mod):
"Sets up the pytest environment"

# Required linux kernel version for this suite to run.
result = required_linux_kernel_version("5.0")
if result is not True:
pytest.skip("Kernel requirements are not met")

tgen = Topogen(BGPIPV6RTADVVRFTopo, mod.__name__)
tgen.start_topology()

Expand All @@ -84,9 +90,6 @@ def setup_module(mod):
for cmd in cmds:
output = tgen.net[rname].cmd(cmd.format(rname))

# adjust handling of vrf traffic
adjust_router_l3mdev(tgen, rname)

for rname, router in router_list.items():
router.load_config(
TopoRouter.RD_ZEBRA, os.path.join(CWD, "{}/zebra.conf".format(rname))
Expand Down
13 changes: 6 additions & 7 deletions tests/topotests/ospf6_topo1_vrf/test_ospf6_topo1_vrf.py
Original file line number Diff line number Diff line change
Expand Up @@ -92,10 +92,7 @@
from lib.topogen import Topogen, TopoRouter, get_topogen
from lib.topolog import logger
from lib.topotest import iproute2_is_vrf_capable
from lib.common_config import (
required_linux_kernel_version,
adjust_router_l3mdev,
)
from lib.common_config import required_linux_kernel_version

#####################################################
##
Expand Down Expand Up @@ -159,6 +156,11 @@ def build(self, **_opts):
def setup_module(mod):
"Sets up the pytest environment"

# Required linux kernel version for this suite to run.
result = required_linux_kernel_version("5.0")
if result is not True:
pytest.skip("Kernel requirements are not met")

tgen = Topogen(NetworkTopo, mod.__name__)
tgen.start_topology()

Expand Down Expand Up @@ -197,9 +199,6 @@ def setup_module(mod):
for cmd in cmds2:
output = tgen.net[rname].cmd(cmd.format(rname))

# adjust handling of vrf traffic
adjust_router_l3mdev(tgen, rname)

for rname, router in tgen.routers().items():
router.load_config(
TopoRouter.RD_ZEBRA, os.path.join(CWD, "{}/zebra.conf".format(rname))
Expand Down