]> git.puffer.fish Git - mirror/frr.git/commitdiff
ospfd: basic support for VRF NETNS backend
authorPhilippe Guibert <philippe.guibert@6wind.com>
Mon, 29 Jan 2018 15:56:11 +0000 (16:56 +0100)
committerPhilippe Guibert <philippe.guibert@6wind.com>
Tue, 27 Feb 2018 10:11:24 +0000 (11:11 +0100)
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>
ospfd/ospf_network.c
ospfd/ospf_network.h
ospfd/ospfd.c

index 022a5a138af117483c9665d1c7948ebd493f16a3..045634d8ab631d11034600a39536c73dd3aa54dd 100644 (file)
@@ -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,
index 41a7abda7013ed1af4b6e1d25d7d859c0576b440..cbaf1323277cb18cfcf9036f0e31e5309efe14db 100644 (file)
@@ -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 */
index 68c682c6c4824128580773f94c88baa944c6c058..79af4a55fb9e1b558f7c656141a35f35c884a1c4 100644 (file)
@@ -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. */