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);