ifmap plugin subscribes to assing_vip bus signal
authorAndreas Steffen <andreas.steffen@strongswan.org>
Thu, 4 Apr 2013 11:40:57 +0000 (13:40 +0200)
committerAndreas Steffen <andreas.steffen@strongswan.org>
Sat, 6 Apr 2013 09:09:41 +0000 (11:09 +0200)
src/libcharon/bus/bus.c
src/libcharon/bus/bus.h
src/libcharon/bus/listeners/listener.h
src/libcharon/plugins/tnc_ifmap/tnc_ifmap_listener.c
src/libcharon/plugins/tnc_ifmap/tnc_ifmap_soap.c
src/libcharon/plugins/tnc_ifmap/tnc_ifmap_soap.h
src/libcharon/sa/ike_sa.c

index b5cdaaa..f87371c 100644 (file)
@@ -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(),
index 18d57bc..9619816 100644 (file)
@@ -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);
index 7822893..2747010 100644 (file)
@@ -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_ @}*/
index 4b2538e..1603c93 100644 (file)
@@ -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,
index 8d5da58..fb97a6d 100644 (file)
@@ -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,
index 4a0434a..d193f7e 100644 (file)
@@ -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
index 8c4dabd..050279a 100644 (file)
@@ -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);