mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-08-06 00:41:20 +00:00
ospfd: basic support for VRF NETNS backend
The change consists in taking into account of the VRF identifier upon which the ospf socket is created. Moreover, if the VRF is a netns backend, then it is not necessary to perform the bind operations to vrf device. Also, when a VRF instance is enabled, it informs ospf VRF, and automatically OSPF VRF benefits from it. Reversely, when VRF instance is disabled, then OSPF VRF will be disabled too. Signed-off-by: Philippe Guibert <philippe.guibert@6wind.com>
This commit is contained in:
parent
97896a91c2
commit
3c0eb8faa2
@ -169,42 +169,27 @@ int ospf_if_ipmulticast(struct ospf *top, struct prefix *p, ifindex_t ifindex)
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ospf_bind_vrfdevice(struct ospf *ospf, int ospf_sock)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
#ifdef SO_BINDTODEVICE
|
||||
|
||||
if (ospf && ospf->vrf_id != VRF_DEFAULT &&
|
||||
ospf->vrf_id != VRF_UNKNOWN) {
|
||||
ret = setsockopt(ospf_sock, SOL_SOCKET, SO_BINDTODEVICE,
|
||||
ospf->name,
|
||||
strlen(ospf->name));
|
||||
if (ret < 0) {
|
||||
int save_errno = errno;
|
||||
|
||||
zlog_warn("%s: Could not setsockopt SO_BINDTODEVICE %s",
|
||||
__PRETTY_FUNCTION__,
|
||||
safe_strerror(save_errno));
|
||||
}
|
||||
|
||||
}
|
||||
#endif
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ospf_sock_init(struct ospf *ospf)
|
||||
{
|
||||
int ospf_sock;
|
||||
int ret, hincl = 1;
|
||||
int bufsize = (8 * 1024 * 1024);
|
||||
|
||||
/* silently ignore. already done */
|
||||
if (ospf->fd > 0)
|
||||
return -1;
|
||||
|
||||
if (ospf->vrf_id == VRF_UNKNOWN) {
|
||||
/* silently return since VRF is not ready */
|
||||
return -1;
|
||||
}
|
||||
if (ospfd_privs.change(ZPRIVS_RAISE)) {
|
||||
zlog_err("ospf_sock_init: could not raise privs, %s",
|
||||
safe_strerror(errno));
|
||||
}
|
||||
|
||||
ospf_sock = socket(AF_INET, SOCK_RAW, IPPROTO_OSPFIGP);
|
||||
ospf_sock = vrf_socket(AF_INET, SOCK_RAW, IPPROTO_OSPFIGP,
|
||||
ospf->vrf_id, ospf->name);
|
||||
if (ospf_sock < 0) {
|
||||
int save_errno = errno;
|
||||
|
||||
@ -216,12 +201,6 @@ int ospf_sock_init(struct ospf *ospf)
|
||||
exit(1);
|
||||
}
|
||||
|
||||
ret = ospf_bind_vrfdevice(ospf, ospf_sock);
|
||||
if (ret < 0) {
|
||||
close(ospf_sock);
|
||||
goto out;
|
||||
}
|
||||
|
||||
#ifdef IP_HDRINCL
|
||||
/* we will include IP header with packet */
|
||||
ret = setsockopt(ospf_sock, IPPROTO_IP, IP_HDRINCL, &hincl,
|
||||
|
@ -30,6 +30,5 @@ extern int ospf_if_add_alldrouters(struct ospf *, struct prefix *, ifindex_t);
|
||||
extern int ospf_if_drop_alldrouters(struct ospf *, struct prefix *, ifindex_t);
|
||||
extern int ospf_if_ipmulticast(struct ospf *, struct prefix *, ifindex_t);
|
||||
extern int ospf_sock_init(struct ospf *ospf);
|
||||
extern int ospf_bind_vrfdevice(struct ospf *, int);
|
||||
|
||||
#endif /* _ZEBRA_OSPF_NETWORK_H */
|
||||
|
@ -308,12 +308,6 @@ static struct ospf *ospf_new(u_short instance, const char *name)
|
||||
new->lsa_refresh_interval, &new->t_lsa_refresher);
|
||||
new->lsa_refresher_started = monotime(NULL);
|
||||
|
||||
if ((ospf_sock_init(new)) < 0) {
|
||||
zlog_err(
|
||||
"ospf_new: fatal error: ospf_sock_init was unable to open "
|
||||
"a socket");
|
||||
exit(1);
|
||||
}
|
||||
if ((new->ibuf = stream_new(OSPF_MAX_PACKET_SIZE + 1)) == NULL) {
|
||||
zlog_err(
|
||||
"ospf_new: fatal error: stream_new(%u) failed allocating ibuf",
|
||||
@ -321,7 +315,6 @@ static struct ospf *ospf_new(u_short instance, const char *name)
|
||||
exit(1);
|
||||
}
|
||||
new->t_read = NULL;
|
||||
thread_add_read(master, ospf_read, new, new->fd, &new->t_read);
|
||||
new->oi_write_q = list_new();
|
||||
new->write_oi_count = OSPF_WRITE_INTERFACE_COUNT_DEFAULT;
|
||||
|
||||
@ -332,6 +325,16 @@ static struct ospf *ospf_new(u_short instance, const char *name)
|
||||
|
||||
QOBJ_REG(new, ospf);
|
||||
|
||||
new->fd = -1;
|
||||
if ((ospf_sock_init(new)) < 0) {
|
||||
if (new->vrf_id != VRF_UNKNOWN)
|
||||
zlog_warn(
|
||||
"%s: ospf_sock_init is unable to open a socket",
|
||||
__func__);
|
||||
return new;
|
||||
}
|
||||
thread_add_read(master, ospf_read, new, new->fd, &new->t_read);
|
||||
|
||||
return new;
|
||||
}
|
||||
|
||||
@ -2050,6 +2053,7 @@ static int ospf_vrf_enable(struct vrf *vrf)
|
||||
{
|
||||
struct ospf *ospf = NULL;
|
||||
vrf_id_t old_vrf_id;
|
||||
int ret = 0;
|
||||
|
||||
if (IS_DEBUG_OSPF_EVENT)
|
||||
zlog_debug("%s: VRF %s id %u enabled",
|
||||
@ -2070,13 +2074,15 @@ static int ospf_vrf_enable(struct vrf *vrf)
|
||||
zlog_err("ospf_sock_init: could not raise privs, %s",
|
||||
safe_strerror(errno));
|
||||
}
|
||||
if (ospf_bind_vrfdevice(ospf, ospf->fd) < 0)
|
||||
return 0;
|
||||
ret = ospf_sock_init(ospf);
|
||||
if (ospfd_privs.change(ZPRIVS_LOWER)) {
|
||||
zlog_err("ospf_sock_init: could not lower privs, %s",
|
||||
safe_strerror(errno));
|
||||
}
|
||||
|
||||
if (ret < 0 || ospf->fd <= 0)
|
||||
return 0;
|
||||
thread_add_read(master, ospf_read, ospf,
|
||||
ospf->fd, &ospf->t_read);
|
||||
ospf->oi_running = 1;
|
||||
ospf_zebra_vrf_register(ospf);
|
||||
ospf_router_id_update(ospf);
|
||||
@ -2111,6 +2117,9 @@ static int ospf_vrf_disable(struct vrf *vrf)
|
||||
if (IS_DEBUG_OSPF_EVENT)
|
||||
zlog_debug("%s: ospf old_vrf_id %d unlinked",
|
||||
__PRETTY_FUNCTION__, old_vrf_id);
|
||||
thread_cancel(ospf->t_read);
|
||||
close(ospf->fd);
|
||||
ospf->fd = -1;
|
||||
}
|
||||
|
||||
/* Note: This is a callback, the VRF will be deleted by the caller. */
|
||||
|
Loading…
Reference in New Issue
Block a user