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;
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,
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 */
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",
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;
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;
}
{
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",
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);
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. */