This is pledge for ospfd's SE and RDE process. The parent can't be pledged
right now because of the same issue that bgpd has (carp demote).

Had to shuffle some code around (as a benefit rdomain check is no longer a
fatal error). Please test, running this on a test router and it seems to
be OK.

-- 
:wq Claudio

Index: interface.c
===================================================================
RCS file: /cvs/src/usr.sbin/ospfd/interface.c,v
retrieving revision 1.80
diff -u -p -r1.80 interface.c
--- interface.c 22 Nov 2015 13:09:10 -0000      1.80
+++ interface.c 3 Dec 2015 11:53:20 -0000
@@ -198,6 +198,7 @@ if_new(struct kif *kif, struct kif_addr 
        /* get mtu, index and flags */
        iface->mtu = kif->mtu;
        iface->ifindex = kif->ifindex;
+       iface->rdomain = kif->rdomain;
        iface->flags = kif->flags;
        iface->linkstate = kif->link_state;
        iface->if_type = kif->if_type;
@@ -241,9 +242,6 @@ if_del(struct iface *iface)
 void
 if_init(struct ospfd_conf *xconf, struct iface *iface)
 {
-       struct ifreq    ifr;
-       u_int           rdomain;
-
        /* init the dummy local neighbor */
        iface->self = nbr_new(ospfe_router_id(), iface, 1);
 
@@ -253,18 +251,6 @@ if_init(struct ospfd_conf *xconf, struct
        evtimer_set(&iface->wait_timer, if_wait_timer, iface);
 
        iface->fd = xconf->ospf_socket;
-
-       strlcpy(ifr.ifr_name, iface->name, sizeof(ifr.ifr_name));
-       if (ioctl(iface->fd, SIOCGIFRDOMAIN, (caddr_t)&ifr) == -1)
-               rdomain = 0;
-       else {
-               rdomain = ifr.ifr_rdomainid;
-               if (setsockopt(iface->fd, SOL_SOCKET, SO_RTABLE,
-                   &rdomain, sizeof(rdomain)) == -1)
-                       fatal("failed to set rdomain");
-       }
-       if (rdomain != xconf->rdomain)
-               fatalx("interface rdomain mismatch");
 
        ospfe_demote_iface(iface, 0);
 }
Index: kroute.c
===================================================================
RCS file: /cvs/src/usr.sbin/ospfd/kroute.c,v
retrieving revision 1.105
diff -u -p -r1.105 kroute.c
--- kroute.c    26 Oct 2015 11:46:25 -0000      1.105
+++ kroute.c    3 Dec 2015 11:53:20 -0000
@@ -85,7 +85,6 @@ void                   kroute_clear(void);
 struct kif_node                *kif_find(u_short);
 struct kif_node                *kif_insert(u_short);
 int                     kif_remove(struct kif_node *);
-void                    kif_clear(void);
 struct kif             *kif_update(u_short, int, struct if_data *,
                            struct sockaddr_dl *);
 int                     kif_validate(u_short);
@@ -110,22 +109,17 @@ int               rtmsg_process(char *, size_t);
 void           kr_fib_reload_timer(int, short, void *);
 void           kr_fib_reload_arm_timer(int);
 
-RB_HEAD(kroute_tree, kroute_node)      krt;
+RB_HEAD(kroute_tree, kroute_node)      krt = RB_INITIALIZER(&krt);
 RB_PROTOTYPE(kroute_tree, kroute_node, entry, kroute_compare)
 RB_GENERATE(kroute_tree, kroute_node, entry, kroute_compare)
 
-RB_HEAD(kif_tree, kif_node)            kit;
+RB_HEAD(kif_tree, kif_node)            kit = RB_INITIALIZER(&kit);
 RB_PROTOTYPE(kif_tree, kif_node, entry, kif_compare)
 RB_GENERATE(kif_tree, kif_node, entry, kif_compare)
 
 int
 kif_init(void)
 {
-       RB_INIT(&kit);
-       /* init also krt tree so that we can call kr_shutdown() */
-       RB_INIT(&krt);
-       kr_state.fib_sync = 0;  /* decoupled */
-
        if (fetchifs(0) == -1)
                return (-1);
 
@@ -886,6 +880,7 @@ kif_update(u_short ifindex, int flags, s
        kif->k.if_type = ifd->ifi_type;
        kif->k.baudrate = ifd->ifi_baudrate;
        kif->k.mtu = ifd->ifi_mtu;
+       kif->k.rdomain = ifd->ifi_rdomain;
 
        if (sdl && sdl->sdl_family == AF_LINK) {
                if (sdl->sdl_nlen >= sizeof(kif->k.ifname))
Index: ospfd.c
===================================================================
RCS file: /cvs/src/usr.sbin/ospfd/ospfd.c,v
retrieving revision 1.87
diff -u -p -r1.87 ospfd.c
--- ospfd.c     3 Dec 2015 11:41:06 -0000       1.87
+++ ospfd.c     3 Dec 2015 11:53:20 -0000
@@ -192,13 +192,12 @@ main(int argc, char *argv[])
                opts |= OSPFD_OPT_STUB_ROUTER;
        }
 
-
        /* fetch interfaces early */
        kif_init();
 
        /* parse config file */
        if ((ospfd_conf = parse_config(conffile, opts)) == NULL) {
-               kr_shutdown();
+               kif_clear();
                exit(1);
        }
        ospfd_conf->csock = sockname;
@@ -208,7 +207,7 @@ main(int argc, char *argv[])
                        print_config(ospfd_conf);
                else
                        fprintf(stderr, "configuration OK\n");
-               kr_shutdown();
+               kif_clear();
                exit(0);
        }
 
Index: ospfd.h
===================================================================
RCS file: /cvs/src/usr.sbin/ospfd/ospfd.h,v
retrieving revision 1.93
diff -u -p -r1.93 ospfd.h
--- ospfd.h     22 Nov 2015 13:09:10 -0000      1.93
+++ ospfd.h     3 Dec 2015 11:53:20 -0000
@@ -336,6 +336,7 @@ struct iface {
        u_int32_t                crypt_seq_num;
        time_t                   uptime;
        unsigned int             ifindex;
+       u_int                    rdomain;
        int                      fd;
        int                      state;
        int                      mtu;
@@ -416,7 +417,8 @@ struct kif {
        u_int64_t                baudrate;
        int                      flags;
        int                      mtu;
-       u_short                  ifindex;
+       unsigned int             ifindex;
+       u_int                    rdomain;
        u_int8_t                 if_type;
        u_int8_t                 link_state;
        u_int8_t                 nh_reachable;  /* for nexthop verification */
@@ -554,6 +556,7 @@ u_int16_t    iso_cksum(void *, u_int16_t, 
 
 /* kroute.c */
 int             kif_init(void);
+void            kif_clear(void);
 int             kr_init(int, u_int);
 int             kr_change(struct kroute *, int);
 int             kr_delete(struct kroute *);
Index: ospfe.c
===================================================================
RCS file: /cvs/src/usr.sbin/ospfd/ospfe.c,v
retrieving revision 1.93
diff -u -p -r1.93 ospfe.c
--- ospfe.c     3 Dec 2015 11:41:06 -0000       1.93
+++ ospfe.c     3 Dec 2015 11:53:21 -0000
@@ -87,6 +87,9 @@ ospfe(struct ospfd_conf *xconf, int pipe
                return (pid);
        }
 
+       /* cleanup a bit */
+       kif_clear();
+
        /* create ospfd control socket outside chroot */
        if (control_init(xconf->csock) == -1)
                fatalx("control socket setup failed");
@@ -126,6 +129,9 @@ ospfe(struct ospfd_conf *xconf, int pipe
            setresuid(pw->pw_uid, pw->pw_uid, pw->pw_uid))
                fatal("can't drop privileges");
 
+       if (pledge("stdio inet mcast", NULL) == -1)
+               fatal("pledge");
+
        event_init();
        nbr_init(NBR_HASHSIZE);
        lsa_cache_init(LSA_HASHSIZE);
@@ -224,7 +230,6 @@ ospfe_shutdown(void)
        }
 
        nbr_del(nbr_find_peerid(NBR_IDSELF));
-       kr_shutdown();
        close(oeconf->ospf_socket);
 
        /* clean up */
Index: parse.y
===================================================================
RCS file: /cvs/src/usr.sbin/ospfd/parse.y,v
retrieving revision 1.79
diff -u -p -r1.79 parse.y
--- parse.y     20 Nov 2014 05:51:20 -0000      1.79
+++ parse.y     3 Dec 2015 11:53:21 -0000
@@ -107,6 +107,7 @@ struct config_defaults      *defs;
 
 struct area    *conf_get_area(struct in_addr);
 struct iface   *conf_get_if(struct kif *, struct kif_addr *);
+int             conf_check_rdomain(unsigned int);
 
 typedef struct {
        union {
@@ -1133,6 +1134,9 @@ parse_config(char *filename, int opts)
        /* free global config defaults */
        md_list_clr(&globaldefs.md_list);
 
+       /* check that all interfaces belong to the configured rdomain */
+       errors += conf_check_rdomain(conf->rdomain);
+
        if (errors) {
                clear_config(conf);
                return (NULL);
@@ -1253,6 +1257,25 @@ conf_get_if(struct kif *kif, struct kif_
        i->auth_keyid = 1;
 
        return (i);
+}
+
+int
+conf_check_rdomain(unsigned int rdomain)
+{
+       struct area     *a;
+       struct iface    *i;
+       int              errs = 0;
+
+       LIST_FOREACH(a, &conf->area_list, entry)
+               LIST_FOREACH(i, &a->iface_list, entry)
+                       if (i->rdomain != rdomain) {
+                               logit(LOG_CRIT,
+                                   "interface %s not in rdomain %u",
+                                   i->name, rdomain);
+                               errs++;
+                       }
+
+       return (errs);
 }
 
 void
Index: rde.c
===================================================================
RCS file: /cvs/src/usr.sbin/ospfd/rde.c,v
retrieving revision 1.99
diff -u -p -r1.99 rde.c
--- rde.c       3 Dec 2015 11:41:06 -0000       1.99
+++ rde.c       3 Dec 2015 11:53:21 -0000
@@ -111,6 +111,9 @@ rde(struct ospfd_conf *xconf, int pipe_p
                return (pid);
        }
 
+       /* cleanup a bit */
+       kif_clear();
+
        rdeconf = xconf;
 
        if ((pw = getpwnam(OSPFD_USER)) == NULL)
@@ -129,6 +132,9 @@ rde(struct ospfd_conf *xconf, int pipe_p
            setresuid(pw->pw_uid, pw->pw_uid, pw->pw_uid))
                fatal("can't drop privileges");
 
+       if (pledge("stdio", NULL) == -1)
+               fatal("pledge");
+
        event_init();
        rde_nbr_init(NBR_HASHSIZE);
        lsa_init(&asext_tree);
@@ -211,7 +217,6 @@ rde_shutdown(void)
        }
        rde_asext_free();
        rde_nbr_free();
-       kr_shutdown();
 
        msgbuf_clear(&iev_ospfe->ibuf.w);
        free(iev_ospfe);

Reply via email to