diff options
author | Mike Belopuhov <mikeb@cvs.openbsd.org> | 2017-03-27 10:43:54 +0000 |
---|---|---|
committer | Mike Belopuhov <mikeb@cvs.openbsd.org> | 2017-03-27 10:43:54 +0000 |
commit | 0d62c88379c433684936e1bc216ad78bbe48da45 (patch) | |
tree | f44c7287a07cb8a9db064b34583d0bb74462a7ef /sbin/iked | |
parent | ccda4cad342df8f6cfc0f1188fa8c95e8fdad017 (diff) |
Factor out flows into separate configuration messages
We reach an imsg payload limit with just a few traffic selectors
so in order to load more we need to split them up and send separately.
Suggested and OK reyk
Diffstat (limited to 'sbin/iked')
-rw-r--r-- | sbin/iked/config.c | 100 | ||||
-rw-r--r-- | sbin/iked/iked.h | 5 | ||||
-rw-r--r-- | sbin/iked/ikev2.c | 4 | ||||
-rw-r--r-- | sbin/iked/parse.y | 3 | ||||
-rw-r--r-- | sbin/iked/types.h | 3 |
5 files changed, 85 insertions, 30 deletions
diff --git a/sbin/iked/config.c b/sbin/iked/config.c index a0f591cf12f..d24da1445c9 100644 --- a/sbin/iked/config.c +++ b/sbin/iked/config.c @@ -1,4 +1,4 @@ -/* $OpenBSD: config.c,v 1.46 2017/03/27 10:29:02 reyk Exp $ */ +/* $OpenBSD: config.c,v 1.47 2017/03/27 10:43:53 mikeb Exp $ */ /* * Copyright (c) 2010-2013 Reyk Floeter <reyk@openbsd.org> @@ -625,23 +625,17 @@ config_setpolicy(struct iked *env, struct iked_policy *pol, enum privsep_procid id) { struct iked_proposal *prop; - struct iked_flow *flow; struct iked_transform *xform; - size_t size, iovcnt, j, c = 0; + size_t iovcnt, j, c = 0; struct iovec iov[IOV_MAX]; iovcnt = 1; - size = sizeof(*pol); TAILQ_FOREACH(prop, &pol->pol_proposals, prop_entry) { - size += (prop->prop_nxforms * sizeof(*xform)) + - (sizeof(*prop)); iovcnt += prop->prop_nxforms + 1; } - iovcnt += pol->pol_nflows; - if (iovcnt > IOV_MAX) { - log_warn("%s: too many proposals/flows", __func__); + log_warn("%s: too many proposals", __func__); return (-1); } @@ -660,18 +654,42 @@ config_setpolicy(struct iked *env, struct iked_policy *pol, } } - RB_FOREACH(flow, iked_flows, &pol->pol_flows) { - iov[c].iov_base = flow; - iov[c++].iov_len = sizeof(*flow); - } - print_policy(pol); if (env->sc_opts & IKED_OPT_NOACTION) return (0); - if (proc_composev(&env->sc_ps, id, IMSG_CFG_POLICY, iov, iovcnt) == -1) + if (proc_composev(&env->sc_ps, id, IMSG_CFG_POLICY, iov, + iovcnt) == -1) { + log_debug("%s: proc_composev failed", __func__); return (-1); + } + + return (0); +} + +int +config_setflow(struct iked *env, struct iked_policy *pol, + enum privsep_procid id) +{ + struct iked_flow *flow; + struct iovec iov[2]; + + if (env->sc_opts & IKED_OPT_NOACTION) + return (0); + + RB_FOREACH(flow, iked_flows, &pol->pol_flows) { + iov[0].iov_base = &pol->pol_id; + iov[0].iov_len = sizeof(pol->pol_id); + iov[1].iov_base = flow; + iov[1].iov_len = sizeof(*flow); + + if (proc_composev(&env->sc_ps, id, IMSG_CFG_FLOW, + iov, 2) == -1) { + log_debug("%s: proc_composev failed", __func__); + return (-1); + } + } return (0); } @@ -682,7 +700,6 @@ config_getpolicy(struct iked *env, struct imsg *imsg) struct iked_policy *pol; struct iked_proposal pp, *prop; struct iked_transform xf, *xform; - struct iked_flow *flow; off_t offset = 0; unsigned int i, j; uint8_t *buf = (uint8_t *)imsg->data; @@ -719,16 +736,8 @@ config_getpolicy(struct iked *env, struct imsg *imsg) } } - for (i = 0; i < pol->pol_nflows; i++) { - if ((flow = calloc(1, sizeof(*flow))) == NULL) - fatal("config_getpolicy: new flow"); - - memcpy(flow, buf + offset, sizeof(*flow)); - offset += sizeof(*flow); - - if (RB_INSERT(iked_flows, &pol->pol_flows, flow)) - free(flow); - } + /* Flows are sent separately */ + pol->pol_nflows = 0; TAILQ_INSERT_TAIL(&env->sc_policies, pol, pol_entry); @@ -743,6 +752,45 @@ config_getpolicy(struct iked *env, struct imsg *imsg) } int +config_getflow(struct iked *env, struct imsg *imsg) +{ + struct iked_policy *pol; + struct iked_flow *flow; + off_t offset = 0; + unsigned int id; + uint8_t *buf = (uint8_t *)imsg->data; + + if (IMSG_DATA_SIZE(imsg) < sizeof(id)) + fatalx("bad length imsg received"); + + memcpy(&id, buf, sizeof(id)); + offset += sizeof(id); + + TAILQ_FOREACH(pol, &env->sc_policies, pol_entry) { + if (pol->pol_id == id) + break; + } + if (pol == NULL) { + log_warnx("%s: unknown policy %u", __func__, id); + return (-1); + } + + if ((flow = calloc(1, sizeof(*flow))) == NULL) + fatal("config_getpolicy: new flow"); + + memcpy(flow, buf + offset, sizeof(*flow)); + + if (RB_INSERT(iked_flows, &pol->pol_flows, flow)) { + log_warnx("%s: received duplicate flow", __func__); + free(flow); + return (-1); + } + pol->pol_nflows++; + + return (0); +} + +int config_setcompile(struct iked *env, enum privsep_procid id) { if (env->sc_opts & IKED_OPT_NOACTION) diff --git a/sbin/iked/iked.h b/sbin/iked/iked.h index 997ec1a56e4..ed4d0f257be 100644 --- a/sbin/iked/iked.h +++ b/sbin/iked/iked.h @@ -1,4 +1,4 @@ -/* $OpenBSD: iked.h,v 1.111 2017/03/27 10:21:19 reyk Exp $ */ +/* $OpenBSD: iked.h,v 1.112 2017/03/27 10:43:53 mikeb Exp $ */ /* * Copyright (c) 2010-2013 Reyk Floeter <reyk@openbsd.org> @@ -666,6 +666,9 @@ int config_getreset(struct iked *, struct imsg *); int config_setpolicy(struct iked *, struct iked_policy *, enum privsep_procid); int config_getpolicy(struct iked *, struct imsg *); +int config_setflow(struct iked *, struct iked_policy *, + enum privsep_procid); +int config_getflow(struct iked *, struct imsg *); int config_setsocket(struct iked *, struct sockaddr_storage *, in_port_t, enum privsep_procid); int config_getsocket(struct iked *env, struct imsg *, diff --git a/sbin/iked/ikev2.c b/sbin/iked/ikev2.c index 740f0bfeaed..d8c15be8cc2 100644 --- a/sbin/iked/ikev2.c +++ b/sbin/iked/ikev2.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ikev2.c,v 1.147 2017/03/27 10:29:02 reyk Exp $ */ +/* $OpenBSD: ikev2.c,v 1.148 2017/03/27 10:43:53 mikeb Exp $ */ /* * Copyright (c) 2010-2013 Reyk Floeter <reyk@openbsd.org> @@ -195,6 +195,8 @@ ikev2_dispatch_parent(int fd, struct privsep_proc *p, struct imsg *imsg) return (config_getpfkey(env, imsg)); case IMSG_CFG_POLICY: return (config_getpolicy(env, imsg)); + case IMSG_CFG_FLOW: + return (config_getflow(env, imsg)); case IMSG_CFG_USER: return (config_getuser(env, imsg)); case IMSG_COMPILE: diff --git a/sbin/iked/parse.y b/sbin/iked/parse.y index 58b0b825abc..01c887ddd1f 100644 --- a/sbin/iked/parse.y +++ b/sbin/iked/parse.y @@ -1,4 +1,4 @@ -/* $OpenBSD: parse.y,v 1.62 2017/03/27 10:06:41 reyk Exp $ */ +/* $OpenBSD: parse.y,v 1.63 2017/03/27 10:43:53 mikeb Exp $ */ /* * Copyright (c) 2010-2013 Reyk Floeter <reyk@openbsd.org> @@ -2859,6 +2859,7 @@ create_ike(char *name, int af, uint8_t ipproto, struct ipsec_hosts *hosts, } config_setpolicy(env, &pol, PROC_IKEV2); + config_setflow(env, &pol, PROC_IKEV2); rules++; return (0); diff --git a/sbin/iked/types.h b/sbin/iked/types.h index 8e29d39f0ee..df358ee4e7d 100644 --- a/sbin/iked/types.h +++ b/sbin/iked/types.h @@ -1,4 +1,4 @@ -/* $OpenBSD: types.h,v 1.27 2017/03/27 10:21:19 reyk Exp $ */ +/* $OpenBSD: types.h,v 1.28 2017/03/27 10:43:53 mikeb Exp $ */ /* * Copyright (c) 2010-2013 Reyk Floeter <reyk@openbsd.org> @@ -104,6 +104,7 @@ enum imsg_type { IMSG_PFKEY_SOCKET, IMSG_IKE_MESSAGE, IMSG_CFG_POLICY, + IMSG_CFG_FLOW, IMSG_CFG_USER, IMSG_CERTREQ, IMSG_CERT, |