diff options
| author | Yves-Alexis Perez <corsac@debian.org> | 2016-10-20 16:18:38 +0200 |
|---|---|---|
| committer | Yves-Alexis Perez <corsac@debian.org> | 2016-10-20 16:18:38 +0200 |
| commit | 88f22dbc6ddb53ac5b40db1d317548b0408718c9 (patch) | |
| tree | 923fc438bad68d2583b27c12036a6883d73bd5f9 /src/libcharon/plugins/kernel_netlink/kernel_netlink_ipsec.c | |
| parent | 3bba989a734d13493279f8c1266176ebb1f670bd (diff) | |
| parent | 25663e04c3ab01ef8dc9f906608282319cfea2db (diff) | |
| download | vyos-strongswan-88f22dbc6ddb53ac5b40db1d317548b0408718c9.tar.gz vyos-strongswan-88f22dbc6ddb53ac5b40db1d317548b0408718c9.zip | |
Merge tag 'upstream/5.5.1'
Upstream version 5.5.1
Diffstat (limited to 'src/libcharon/plugins/kernel_netlink/kernel_netlink_ipsec.c')
| -rw-r--r-- | src/libcharon/plugins/kernel_netlink/kernel_netlink_ipsec.c | 113 |
1 files changed, 111 insertions, 2 deletions
diff --git a/src/libcharon/plugins/kernel_netlink/kernel_netlink_ipsec.c b/src/libcharon/plugins/kernel_netlink/kernel_netlink_ipsec.c index 9c2a7c315..f3846ec07 100644 --- a/src/libcharon/plugins/kernel_netlink/kernel_netlink_ipsec.c +++ b/src/libcharon/plugins/kernel_netlink/kernel_netlink_ipsec.c @@ -1245,7 +1245,7 @@ METHOD(kernel_ipsec_t, get_cpi, status_t, */ static void format_mark(char *buf, int buflen, mark_t mark) { - if (mark.value) + if (mark.value | mark.mask) { snprintf(buf, buflen, " (mark %u/0x%08x)", mark.value, mark.mask); } @@ -1256,7 +1256,7 @@ static void format_mark(char *buf, int buflen, mark_t mark) */ static bool add_mark(struct nlmsghdr *hdr, int buflen, mark_t mark) { - if (mark.value) + if (mark.value | mark.mask) { struct xfrm_mark *xmrk; @@ -2528,6 +2528,7 @@ METHOD(kernel_ipsec_t, add_policy, status_t, id->dir, markstr, cur_priority, use_count); return SUCCESS; } + policy->reqid = assigned_sa->sa->cfg.reqid; if (this->policy_update) { @@ -2720,6 +2721,7 @@ METHOD(kernel_ipsec_t, del_policy, status_t, return SUCCESS; } current->used_by->get_first(current->used_by, (void**)&mapping); + current->reqid = mapping->sa->cfg.reqid; DBG2(DBG_KNL, "updating policy %R === %R %N%s [priority %u, " "refcount %d]", id->src_ts, id->dst_ts, policy_dir_names, id->dir, @@ -3044,6 +3046,110 @@ METHOD(kernel_ipsec_t, destroy, void, free(this); } +/** + * Get the currently configured SPD hashing thresholds for an address family + */ +static bool get_spd_hash_thresh(private_kernel_netlink_ipsec_t *this, + int type, uint8_t *lbits, uint8_t *rbits) +{ + netlink_buf_t request; + struct nlmsghdr *hdr, *out; + struct xfrmu_spdhthresh *thresh; + struct rtattr *rta; + size_t len, rtasize; + bool success = FALSE; + + memset(&request, 0, sizeof(request)); + + hdr = &request.hdr; + hdr->nlmsg_flags = NLM_F_REQUEST; + hdr->nlmsg_type = XFRM_MSG_GETSPDINFO; + hdr->nlmsg_len = NLMSG_LENGTH(sizeof(uint32_t)); + + if (this->socket_xfrm->send(this->socket_xfrm, hdr, &out, &len) == SUCCESS) + { + hdr = out; + while (NLMSG_OK(hdr, len)) + { + switch (hdr->nlmsg_type) + { + case XFRM_MSG_NEWSPDINFO: + { + rta = XFRM_RTA(hdr, uint32_t); + rtasize = XFRM_PAYLOAD(hdr, uint32_t); + while (RTA_OK(rta, rtasize)) + { + if (rta->rta_type == type && + RTA_PAYLOAD(rta) == sizeof(*thresh)) + { + thresh = RTA_DATA(rta); + *lbits = thresh->lbits; + *rbits = thresh->rbits; + success = TRUE; + break; + } + rta = RTA_NEXT(rta, rtasize); + } + break; + } + case NLMSG_ERROR: + { + struct nlmsgerr *err = NLMSG_DATA(hdr); + DBG1(DBG_KNL, "getting SPD hash threshold failed: %s (%d)", + strerror(-err->error), -err->error); + break; + } + default: + hdr = NLMSG_NEXT(hdr, len); + continue; + case NLMSG_DONE: + break; + } + break; + } + free(out); + } + return success; +} + +/** + * Configure SPD hashing threshold for an address family + */ +static void setup_spd_hash_thresh(private_kernel_netlink_ipsec_t *this, + char *key, int type, uint8_t def) +{ + struct xfrmu_spdhthresh *thresh; + struct nlmsghdr *hdr; + netlink_buf_t request; + uint8_t lbits, rbits; + + if (!get_spd_hash_thresh(this, type, &lbits, &rbits)) + { + return; + } + memset(&request, 0, sizeof(request)); + + hdr = &request.hdr; + hdr->nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK; + hdr->nlmsg_type = XFRM_MSG_NEWSPDINFO; + hdr->nlmsg_len = NLMSG_LENGTH(sizeof(uint32_t)); + + thresh = netlink_reserve(hdr, sizeof(request), type, sizeof(*thresh)); + thresh->lbits = lib->settings->get_int(lib->settings, + "%s.plugins.kernel-netlink.spdh_thresh.%s.lbits", + def, lib->ns, key); + thresh->rbits = lib->settings->get_int(lib->settings, + "%s.plugins.kernel-netlink.spdh_thresh.%s.rbits", + def, lib->ns, key); + if (thresh->lbits != lbits || thresh->rbits != rbits) + { + if (this->socket_xfrm->send_ack(this->socket_xfrm, hdr) != SUCCESS) + { + DBG1(DBG_KNL, "setting SPD hash threshold failed"); + } + } +} + /* * Described in header. */ @@ -3114,6 +3220,9 @@ kernel_netlink_ipsec_t *kernel_netlink_ipsec_create() return NULL; } + setup_spd_hash_thresh(this, "ipv4", XFRMA_SPD_IPV4_HTHRESH, 32); + setup_spd_hash_thresh(this, "ipv6", XFRMA_SPD_IPV6_HTHRESH, 128); + if (register_for_events) { struct sockaddr_nl addr; |
