From ba2880d569989b55b9eb25e1cd4c630bf438f2b0 Mon Sep 17 00:00:00 2001 From: Andreas Steffen Date: Thu, 4 Apr 2013 13:40:57 +0200 Subject: [PATCH] ifmap plugin subscribes to assing_vip bus signal --- src/libcharon/bus/bus.c | 29 +++++++++++++++ src/libcharon/bus/bus.h | 9 +++++ src/libcharon/bus/listeners/listener.h | 15 ++++++++ .../plugins/tnc_ifmap/tnc_ifmap_listener.c | 22 ++++++++++- src/libcharon/plugins/tnc_ifmap/tnc_ifmap_soap.c | 43 ++++++++++++++++++++++ src/libcharon/plugins/tnc_ifmap/tnc_ifmap_soap.h | 13 ++++++- src/libcharon/sa/ike_sa.c | 6 +++ 7 files changed, 135 insertions(+), 2 deletions(-) diff --git a/src/libcharon/bus/bus.c b/src/libcharon/bus/bus.c index b5cdaaa..f87371c 100644 --- a/src/libcharon/bus/bus.c +++ b/src/libcharon/bus/bus.c @@ -759,6 +759,34 @@ METHOD(bus_t, narrow, void, this->mutex->unlock(this->mutex); } +METHOD(bus_t, assign_vip, void, + private_bus_t *this, ike_sa_t *ike_sa, host_t *vip, bool assign) +{ + enumerator_t *enumerator; + entry_t *entry; + bool keep; + + this->mutex->lock(this->mutex); + enumerator = this->listeners->create_enumerator(this->listeners); + while (enumerator->enumerate(enumerator, &entry)) + { + if (entry->calling || !entry->listener->assign_vip) + { + continue; + } + entry->calling++; + keep = entry->listener->assign_vip(entry->listener, ike_sa, + vip, assign); + entry->calling--; + if (!keep) + { + unregister_listener(this, entry, enumerator); + } + } + enumerator->destroy(enumerator); + this->mutex->unlock(this->mutex); +} + METHOD(bus_t, destroy, void, private_bus_t *this) { @@ -807,6 +835,7 @@ bus_t *bus_create() .child_rekey = _child_rekey, .authorize = _authorize, .narrow = _narrow, + .assign_vip = _assign_vip, .destroy = _destroy, }, .listeners = linked_list_create(), diff --git a/src/libcharon/bus/bus.h b/src/libcharon/bus/bus.h index 18d57bc..9619816 100644 --- a/src/libcharon/bus/bus.h +++ b/src/libcharon/bus/bus.h @@ -386,6 +386,15 @@ struct bus_t { void (*child_rekey)(bus_t *this, child_sa_t *old, child_sa_t *new); /** + * Virtual IP assignment hook. + * + * @param ike_sa IKE_SA the VIP is assigned to + * @param vip Virtual IPv4 or IV6 address + * @param assign TRUE if assigned to IKE_SA, FALSE if released + */ + void (*assign_vip)(bus_t *this, ike_sa_t *ike_sa, host_t *vip, bool assign); + + /** * Destroy the event bus. */ void (*destroy) (bus_t *this); diff --git a/src/libcharon/bus/listeners/listener.h b/src/libcharon/bus/listeners/listener.h index 7822893..2747010 100644 --- a/src/libcharon/bus/listeners/listener.h +++ b/src/libcharon/bus/listeners/listener.h @@ -190,6 +190,21 @@ struct listener_t { */ bool (*narrow)(listener_t *this, ike_sa_t *ike_sa, child_sa_t *child_sa, narrow_hook_t type, linked_list_t *local, linked_list_t *remote); + + /** + * Virtual IP address assignment hook + * + * This hook gets invoked when a a Virtual IP address is assigned to an + * IKE_SA (assign = TRUE) and again when it is released (assign = FALSE) + * + * @param ike_sa IKE_SA the VIP is assigned to + * @param vip Virtual IPv4 or IV6 address + * @param assign TRUE if assigned to IKE_SA, FALSE if released + * @return TRUE to stay registered, FALSE to unregister + */ + bool (*assign_vip)(listener_t *this, ike_sa_t *ike_sa, host_t *vip, + bool assign); + }; #endif /** LISTENER_H_ @}*/ diff --git a/src/libcharon/plugins/tnc_ifmap/tnc_ifmap_listener.c b/src/libcharon/plugins/tnc_ifmap/tnc_ifmap_listener.c index 4b2538e..1603c93 100644 --- a/src/libcharon/plugins/tnc_ifmap/tnc_ifmap_listener.c +++ b/src/libcharon/plugins/tnc_ifmap/tnc_ifmap_listener.c @@ -71,8 +71,9 @@ static bool publish_device_ip_addresses(private_tnc_ifmap_listener_t *this) */ static bool reload_metadata(private_tnc_ifmap_listener_t *this) { - enumerator_t *enumerator; + enumerator_t *enumerator, *evips; ike_sa_t *ike_sa; + host_t *vip; bool success = TRUE; enumerator = charon->controller->create_ike_sa_enumerator( @@ -88,6 +89,16 @@ static bool reload_metadata(private_tnc_ifmap_listener_t *this) success = FALSE; break; } + evips = ike_sa->create_virtual_ip_enumerator(ike_sa, FALSE); + while (evips->enumerate(evips, &vip)) + { + if (!this->ifmap->publish_virtual_ip(this->ifmap, ike_sa, vip, TRUE)) + { + success = FALSE; + break; + } + } + evips->destroy(evips); } enumerator->destroy(enumerator); @@ -104,6 +115,14 @@ METHOD(listener_t, ike_updown, bool, return TRUE; } +METHOD(listener_t, assign_vip, bool, + private_tnc_ifmap_listener_t *this, ike_sa_t *ike_sa, host_t *vip, + bool assign) +{ + this->ifmap->publish_virtual_ip(this->ifmap, ike_sa, vip, assign); + return TRUE; +} + METHOD(listener_t, alert, bool, private_tnc_ifmap_listener_t *this, ike_sa_t *ike_sa, alert_t alert, va_list args) @@ -144,6 +163,7 @@ tnc_ifmap_listener_t *tnc_ifmap_listener_create(bool reload) .public = { .listener = { .ike_updown = _ike_updown, + .assign_vip = _assign_vip, .alert = _alert, }, .destroy = _destroy, diff --git a/src/libcharon/plugins/tnc_ifmap/tnc_ifmap_soap.c b/src/libcharon/plugins/tnc_ifmap/tnc_ifmap_soap.c index 8d5da58..fb97a6d 100644 --- a/src/libcharon/plugins/tnc_ifmap/tnc_ifmap_soap.c +++ b/src/libcharon/plugins/tnc_ifmap/tnc_ifmap_soap.c @@ -579,6 +579,48 @@ METHOD(tnc_ifmap_soap_t, publish_device_ip, bool, return success; } +METHOD(tnc_ifmap_soap_t, publish_virtual_ip, bool, + private_tnc_ifmap_soap_t *this, ike_sa_t *ike_sa, host_t *vip, bool assign) +{ + tnc_ifmap_soap_msg_t *soap_msg; + xmlNodePtr request, node; + u_int32_t ike_sa_id; + bool success; + + /* extract relevant data from IKE_SA*/ + ike_sa_id = ike_sa->get_unique_id(ike_sa); + + /* build publish request */ + request = create_publish_request(this); + + /** + * update or delete access-request-ip metadata for a virtual IP address + */ + if (assign) + { + node = xmlNewNode(NULL, "update"); + } + else + { + node = create_delete_filter(this, "access-request-ip"); + } + xmlAddChild(request, node); + + /* add access-request, virtual ip-address and [if assign] metadata */ + xmlAddChild(node, create_access_request(this, ike_sa_id)); + xmlAddChild(node, create_ip_address(this, vip)); + if (assign) + { + xmlAddChild(node, create_metadata(this, "access-request-ip")); + } + + soap_msg = tnc_ifmap_soap_msg_create(this->uri, this->user_pass, this->tls); + success = soap_msg->post(soap_msg, request, "publishReceived", NULL); + soap_msg->destroy(soap_msg); + + return success; +} + METHOD(tnc_ifmap_soap_t, publish_enforcement_report, bool, private_tnc_ifmap_soap_t *this, host_t *host, char *action, char *reason) { @@ -851,6 +893,7 @@ tnc_ifmap_soap_t *tnc_ifmap_soap_create() .purgePublisher = _purgePublisher, .publish_ike_sa = _publish_ike_sa, .publish_device_ip = _publish_device_ip, + .publish_virtual_ip = _publish_virtual_ip, .publish_enforcement_report = _publish_enforcement_report, .endSession = _endSession, .get_session_id = _get_session_id, diff --git a/src/libcharon/plugins/tnc_ifmap/tnc_ifmap_soap.h b/src/libcharon/plugins/tnc_ifmap/tnc_ifmap_soap.h index 4a0434a..d193f7e 100644 --- a/src/libcharon/plugins/tnc_ifmap/tnc_ifmap_soap.h +++ b/src/libcharon/plugins/tnc_ifmap/tnc_ifmap_soap.h @@ -56,7 +56,7 @@ struct tnc_ifmap_soap_t { /** * Publish metadata about established/deleted IKE_SAs * - * @param ike_sa IKE_SA for which metadate is published + * @param ike_sa IKE_SA for which metadata is published * @param up TRUE if IKE_SEA is up, FALSE if down * @return TRUE if command was successful */ @@ -71,6 +71,17 @@ struct tnc_ifmap_soap_t { bool (*publish_device_ip)(tnc_ifmap_soap_t *this, host_t *host); /** + * Publish Virtual IP access-request-ip metadata + * + * @param ike_sa IKE_SA for which metadata is published + * @param vip Virtual IP address of peer + * @param assign TRUE if assigned, FALSE if removed + * @return TRUE if command was successful + */ + bool (*publish_virtual_ip)(tnc_ifmap_soap_t *this, ike_sa_t *ike_sa, + host_t *vip, bool assign); + + /** * Publish enforcement-report metadata * * @param host Host to be enforced diff --git a/src/libcharon/sa/ike_sa.c b/src/libcharon/sa/ike_sa.c index 8c4dabd..050279a 100644 --- a/src/libcharon/sa/ike_sa.c +++ b/src/libcharon/sa/ike_sa.c @@ -766,6 +766,7 @@ METHOD(ike_sa_t, add_virtual_ip, void, else { this->other_vips->insert_last(this->other_vips, ip->clone(ip)); + charon->bus->assign_vip(charon->bus, &this->public, ip, TRUE); } } @@ -783,6 +784,10 @@ METHOD(ike_sa_t, clear_virtual_ips, void, hydra->kernel_interface->del_ip(hydra->kernel_interface, vip, -1, TRUE); } + else + { + charon->bus->assign_vip(charon->bus, &this->public, vip, FALSE); + } vip->destroy(vip); } } @@ -2119,6 +2124,7 @@ METHOD(ike_sa_t, destroy, void, hydra->attributes->release_address(hydra->attributes, pools, vip, id); pools->destroy(pools); } + charon->bus->assign_vip(charon->bus, &this->public, vip, FALSE); vip->destroy(vip); } this->other_vips->destroy(this->other_vips); -- 2.7.4