From: Philippe Guibert Date: Mon, 29 Jan 2018 15:56:11 +0000 (+0100) Subject: ospfd: basic support for VRF NETNS backend X-Git-Tag: frr-5.0-dev~209^2~5 X-Git-Url: https://git.puffer.fish/?a=commitdiff_plain;h=3c0eb8faa2936ed43c557fe375383d6d03646291;p=mirror%2Ffrr.git 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 --- diff --git a/ospfd/ospf_network.c b/ospfd/ospf_network.c index 022a5a138a..045634d8ab 100644 --- a/ospfd/ospf_network.c +++ b/ospfd/ospf_network.c @@ -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, diff --git a/ospfd/ospf_network.h b/ospfd/ospf_network.h index 41a7abda70..cbaf132327 100644 --- a/ospfd/ospf_network.h +++ b/ospfd/ospf_network.h @@ -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 */ diff --git a/ospfd/ospfd.c b/ospfd/ospfd.c index 68c682c6c4..79af4a55fb 100644 --- a/ospfd/ospfd.c +++ b/ospfd/ospfd.c @@ -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. */