diff options
author | Andreas Steffen <andreas.steffen@strongswan.org> | 2008-10-31 01:43:23 +0000 |
---|---|---|
committer | Andreas Steffen <andreas.steffen@strongswan.org> | 2008-10-31 01:43:23 +0000 |
commit | e526d22818bb8e4b9ae659eaa89098c324625cf0 (patch) | |
tree | 5dd46d33fb33697f5e821aee256e44bcad4b6e05 /src/charon/plugins/kernel_netlink/kernel_netlink_ipsec.c | |
parent | 19aff61b1946cc72d7a250ce3b99affac2616b86 (diff) | |
download | strongswan-e526d22818bb8e4b9ae659eaa89098c324625cf0.tar.bz2 strongswan-e526d22818bb8e4b9ae659eaa89098c324625cf0.tar.xz |
parse xfrm and pf_key acquire messages and subscribe to migrate messages
Diffstat (limited to 'src/charon/plugins/kernel_netlink/kernel_netlink_ipsec.c')
-rw-r--r-- | src/charon/plugins/kernel_netlink/kernel_netlink_ipsec.c | 85 |
1 files changed, 75 insertions, 10 deletions
diff --git a/src/charon/plugins/kernel_netlink/kernel_netlink_ipsec.c b/src/charon/plugins/kernel_netlink/kernel_netlink_ipsec.c index 1b526e6f0..d5ff47954 100644 --- a/src/charon/plugins/kernel_netlink/kernel_netlink_ipsec.c +++ b/src/charon/plugins/kernel_netlink/kernel_netlink_ipsec.c @@ -381,6 +381,53 @@ static struct xfrm_selector ts2selector(traffic_selector_t *src, return sel; } +/** + * convert a xfrm_selector to a src|dst traffic_selector + */ +static traffic_selector_t* selector2ts(struct xfrm_selector *sel, bool src) +{ + ts_type_t type; + chunk_t addr; + u_int16_t port, port_mask, from_port, to_port; + + if (src) + { + addr.ptr = (u_char*)&sel->saddr; + port = sel->sport; + port_mask = sel->sport_mask; + } + else + { + addr.ptr = (u_char*)&sel->daddr; + port = sel->dport; + port_mask = sel->dport_mask; + } + /* The Linux 2.6 kernel does not set the selector's family field, + * so as a kludge we additionally test the prefix length. + */ + if (sel->family == AF_INET || sel->prefixlen_d == 32) + { + type = TS_IPV4_ADDR_RANGE; + addr.len = 4; + } + else + { + type = TS_IPV6_ADDR_RANGE; + addr.len = 16; + } + if (port_mask == 0) + { + from_port = 0; + to_port = 65535; + } + else + { + from_port = to_port = ntohs(port); + } + + return traffic_selector_create_from_bytes(sel->proto, type, + addr, from_port, addr, to_port); +} /** * process a XFRM_MSG_ACQUIRE from kernel @@ -389,15 +436,22 @@ static void process_acquire(private_kernel_netlink_ipsec_t *this, struct nlmsghd { u_int32_t reqid = 0; int proto = 0; + traffic_selector_t *src_ts, *dst_ts; + struct xfrm_user_acquire *acquire; + struct rtattr *rtattr; + size_t rtsize; job_t *job; - struct rtattr *rtattr = XFRM_RTA(hdr, struct xfrm_user_acquire); - size_t rtsize = XFRM_PAYLOAD(hdr, struct xfrm_user_tmpl); + rtattr = XFRM_RTA(hdr, struct xfrm_user_acquire); + rtsize = XFRM_PAYLOAD(hdr, struct xfrm_user_tmpl); + if (RTA_OK(rtattr, rtsize)) { if (rtattr->rta_type == XFRMA_TMPL) { - struct xfrm_user_tmpl* tmpl = (struct xfrm_user_tmpl*)RTA_DATA(rtattr); + struct xfrm_user_tmpl* tmpl; + + tmpl = (struct xfrm_user_tmpl*)RTA_DATA(rtattr); reqid = tmpl->reqid; proto = tmpl->id.proto; } @@ -412,14 +466,14 @@ static void process_acquire(private_kernel_netlink_ipsec_t *this, struct nlmsghd /* acquire for AH/ESP only, not for IPCOMP */ return; } - if (reqid == 0) - { - DBG1(DBG_KNL, "received a XFRM_MSG_ACQUIRE, but no reqid found"); - return; - } DBG2(DBG_KNL, "received a XFRM_MSG_ACQUIRE"); - DBG1(DBG_KNL, "creating acquire job for CHILD_SA with reqid {%d}", reqid); - job = (job_t*)acquire_job_create(reqid); + + acquire = (struct xfrm_user_acquire*)NLMSG_DATA(hdr); + src_ts = selector2ts(&acquire->sel, TRUE); + dst_ts = selector2ts(&acquire->sel, FALSE); + DBG1(DBG_KNL, "creating acquire job %R === %R for CHILD_SA with reqid {%d}", + src_ts, dst_ts, reqid); + job = (job_t*)acquire_job_create(reqid, src_ts, dst_ts); charon->processor->queue_job(charon->processor, job); } @@ -462,6 +516,14 @@ static void process_expire(private_kernel_netlink_ipsec_t *this, struct nlmsghdr } /** + * process a XFRM_MSG_MIGRATE from kernel + */ +static void process_migrate(private_kernel_netlink_ipsec_t *this, struct nlmsghdr *hdr) +{ + DBG2(DBG_KNL, "received a XFRM_MSG_MIGRATE"); +} + +/** * process a XFRM_MSG_MAPPING from kernel */ static void process_mapping(private_kernel_netlink_ipsec_t *this, @@ -540,6 +602,9 @@ static job_requeue_t receive_events(private_kernel_netlink_ipsec_t *this) case XFRM_MSG_EXPIRE: process_expire(this, hdr); break; + case XFRM_MSG_MIGRATE: + process_migrate(this, hdr); + break; case XFRM_MSG_MAPPING: process_mapping(this, hdr); break; |