Add an optional kernel-interface parameter to install IPs with a custom prefix
authorMartin Willi <martin@revosec.ch>
Fri, 9 Nov 2012 14:46:58 +0000 (15:46 +0100)
committerMartin Willi <martin@revosec.ch>
Thu, 29 Nov 2012 09:22:51 +0000 (10:22 +0100)
src/frontends/android/jni/libandroidbridge/kernel/android_net.c
src/libcharon/sa/child_sa.c
src/libcharon/sa/ike_sa.c
src/libhydra/kernel/kernel_interface.c
src/libhydra/kernel/kernel_interface.h
src/libhydra/kernel/kernel_net.h
src/libhydra/plugins/kernel_netlink/kernel_netlink_net.c
src/libhydra/plugins/kernel_pfroute/kernel_pfroute_net.c

index 032fe20..8dc32e6 100644 (file)
@@ -92,7 +92,8 @@ METHOD(kernel_net_t, get_source_addr, host_t*,
 }
 
 METHOD(kernel_net_t, add_ip, status_t,
-       private_kernel_android_net_t *this, host_t *virtual_ip, host_t *iface_ip)
+       private_kernel_android_net_t *this, host_t *virtual_ip, int prefix,
+       host_t *iface_ip)
 {
        /* we get the IP from the IKE_SA once the CHILD_SA is established */
        return SUCCESS;
index 1245734..e1f244e 100644 (file)
@@ -824,8 +824,8 @@ METHOD(child_sa_t, add_policies, status_t,
  */
 static void reinstall_vip(host_t *vip, host_t *me)
 {
-       hydra->kernel_interface->del_ip(hydra->kernel_interface, vip);
-       hydra->kernel_interface->add_ip(hydra->kernel_interface, vip, me);
+       hydra->kernel_interface->del_ip(hydra->kernel_interface, vip, -1);
+       hydra->kernel_interface->add_ip(hydra->kernel_interface, vip, -1, me);
 }
 
 METHOD(child_sa_t, update, status_t,
index 0005188..63c34c3 100644 (file)
@@ -742,8 +742,8 @@ METHOD(ike_sa_t, add_virtual_ip, void,
        if (local)
        {
                DBG1(DBG_IKE, "installing new virtual IP %H", ip);
-               if (hydra->kernel_interface->add_ip(hydra->kernel_interface, ip,
-                                                                                       this->my_host) == SUCCESS)
+               if (hydra->kernel_interface->add_ip(hydra->kernel_interface,
+                                                                                       ip, -1, this->my_host) == SUCCESS)
                {
                        this->my_vips->insert_last(this->my_vips, ip->clone(ip));
                }
@@ -769,7 +769,7 @@ METHOD(ike_sa_t, clear_virtual_ips, void,
        {
                if (local)
                {
-                       hydra->kernel_interface->del_ip(hydra->kernel_interface, vip);
+                       hydra->kernel_interface->del_ip(hydra->kernel_interface, vip, -1);
                }
                vip->destroy(vip);
        }
@@ -2076,7 +2076,7 @@ METHOD(ike_sa_t, destroy, void,
 
        while (this->my_vips->remove_last(this->my_vips, (void**)&vip) == SUCCESS)
        {
-               hydra->kernel_interface->del_ip(hydra->kernel_interface, vip);
+               hydra->kernel_interface->del_ip(hydra->kernel_interface, vip, -1);
                vip->destroy(vip);
        }
        this->my_vips->destroy(this->my_vips);
index 5425861..2fbe848 100644 (file)
@@ -312,23 +312,24 @@ METHOD(kernel_interface_t, create_address_enumerator, enumerator_t*,
 }
 
 METHOD(kernel_interface_t, add_ip, status_t,
-       private_kernel_interface_t *this, host_t *virtual_ip, host_t *iface_ip)
+       private_kernel_interface_t *this, host_t *virtual_ip, int prefix,
+       host_t *iface_ip)
 {
        if (!this->net)
        {
                return NOT_SUPPORTED;
        }
-       return this->net->add_ip(this->net, virtual_ip, iface_ip);
+       return this->net->add_ip(this->net, virtual_ip, prefix, iface_ip);
 }
 
 METHOD(kernel_interface_t, del_ip, status_t,
-       private_kernel_interface_t *this, host_t *virtual_ip)
+       private_kernel_interface_t *this, host_t *virtual_ip, int prefix)
 {
        if (!this->net)
        {
                return NOT_SUPPORTED;
        }
-       return this->net->del_ip(this->net, virtual_ip);
+       return this->net->del_ip(this->net, virtual_ip, prefix);
 }
 
 METHOD(kernel_interface_t, add_route, status_t,
index 7058466..e3ebce8 100644 (file)
@@ -336,10 +336,11 @@ struct kernel_interface_t {
         * The virtual IP is attached to the interface where the iface_ip is found.
         *
         * @param virtual_ip    virtual ip address to assign
+        * @param prefix                prefix length to install IP with, -1 for auto
         * @param iface_ip              IP of an interface to attach virtual IP
         * @return                              SUCCESS if operation completed
         */
-       status_t (*add_ip) (kernel_interface_t *this, host_t *virtual_ip,
+       status_t (*add_ip) (kernel_interface_t *this, host_t *virtual_ip, int prefix,
                                                host_t *iface_ip);
 
        /**
@@ -348,9 +349,10 @@ struct kernel_interface_t {
         * The kernel interface uses refcounting, see add_ip().
         *
         * @param virtual_ip    virtual ip address to assign
+        * @param prefix                prefix length of the IP to uninstall, -1 for auto
         * @return                              SUCCESS if operation completed
         */
-       status_t (*del_ip) (kernel_interface_t *this, host_t *virtual_ip);
+       status_t (*del_ip) (kernel_interface_t *this, host_t *virtual_ip, int prefix);
 
        /**
         * Add a route.
index 0f2e31c..50881ab 100644 (file)
@@ -115,10 +115,11 @@ struct kernel_net_t {
         * The virtual IP is attached to the interface where the iface_ip is found.
         *
         * @param virtual_ip    virtual ip address to assign
+        * @param prefix                prefix length to install with IP address, -1 for auto
         * @param iface_ip              IP of an interface to attach virtual IP
         * @return                              SUCCESS if operation completed
         */
-       status_t (*add_ip) (kernel_net_t *this, host_t *virtual_ip,
+       status_t (*add_ip) (kernel_net_t *this, host_t *virtual_ip, int prefix,
                                                host_t *iface_ip);
 
        /**
@@ -127,9 +128,10 @@ struct kernel_net_t {
         * The kernel interface uses refcounting, see add_ip().
         *
         * @param virtual_ip    virtual ip address to assign
+        * @param prefix                prefix length of the IP to uninstall, -1 for auto
         * @return                              SUCCESS if operation completed
         */
-       status_t (*del_ip) (kernel_net_t *this, host_t *virtual_ip);
+       status_t (*del_ip) (kernel_net_t *this, host_t *virtual_ip, int prefix);
 
        /**
         * Add a route.
index 7653d47..7db51fc 100644 (file)
@@ -1634,7 +1634,7 @@ METHOD(kernel_net_t, get_nexthop, host_t*,
  * By setting the appropriate nlmsg_type, the ip will be set or unset.
  */
 static status_t manage_ipaddr(private_kernel_netlink_net_t *this, int nlmsg_type,
-                                                         int flags, int if_index, host_t *ip)
+                                                         int flags, int if_index, host_t *ip, int prefix)
 {
        netlink_buf_t request;
        struct nlmsghdr *hdr;
@@ -1653,7 +1653,7 @@ static status_t manage_ipaddr(private_kernel_netlink_net_t *this, int nlmsg_type
        msg = (struct ifaddrmsg*)NLMSG_DATA(hdr);
        msg->ifa_family = ip->get_family(ip);
        msg->ifa_flags = 0;
-       msg->ifa_prefixlen = 8 * chunk.len;
+       msg->ifa_prefixlen = prefix < 0 ? chunk.len * 8 : prefix;
        msg->ifa_scope = RT_SCOPE_UNIVERSE;
        msg->ifa_index = if_index;
 
@@ -1663,7 +1663,8 @@ static status_t manage_ipaddr(private_kernel_netlink_net_t *this, int nlmsg_type
 }
 
 METHOD(kernel_net_t, add_ip, status_t,
-       private_kernel_netlink_net_t *this, host_t *virtual_ip, host_t *iface_ip)
+       private_kernel_netlink_net_t *this, host_t *virtual_ip, int prefix,
+       host_t *iface_ip)
 {
        addr_map_entry_t *entry, lookup = {
                .ip = virtual_ip,
@@ -1738,7 +1739,7 @@ METHOD(kernel_net_t, add_ip, status_t,
                iface->addrs->insert_last(iface->addrs, addr);
                addr_map_entry_add(this->vips, addr, iface);
                if (manage_ipaddr(this, RTM_NEWADDR, NLM_F_CREATE | NLM_F_EXCL,
-                                                 iface->ifindex, virtual_ip) == SUCCESS)
+                                                 iface->ifindex, virtual_ip, prefix) == SUCCESS)
                {
                        while (!is_vip_installed_or_gone(this, virtual_ip, &entry))
                        {       /* wait until address appears */
@@ -1763,7 +1764,7 @@ METHOD(kernel_net_t, add_ip, status_t,
 }
 
 METHOD(kernel_net_t, del_ip, status_t,
-       private_kernel_netlink_net_t *this, host_t *virtual_ip)
+       private_kernel_netlink_net_t *this, host_t *virtual_ip, int prefix)
 {
        addr_map_entry_t *entry, lookup = {
                .ip = virtual_ip,
@@ -1802,7 +1803,7 @@ METHOD(kernel_net_t, del_ip, status_t,
                 * until the entry is gone, also so we can wait below */
                entry->addr->installed = FALSE;
                status = manage_ipaddr(this, RTM_DELADDR, 0, entry->iface->ifindex,
-                                                          virtual_ip);
+                                                          virtual_ip, prefix);
                if (status == SUCCESS)
                {       /* wait until the address is really gone */
                        while (is_known_vip(this, virtual_ip))
index d45c5bb..c53ec01 100644 (file)
@@ -640,13 +640,14 @@ METHOD(kernel_net_t, get_nexthop, host_t*,
 }
 
 METHOD(kernel_net_t, add_ip, status_t,
-       private_kernel_pfroute_net_t *this, host_t *virtual_ip, host_t *iface_ip)
+       private_kernel_pfroute_net_t *this, host_t *virtual_ip, int prefix,
+       host_t *iface_ip)
 {
        return FAILED;
 }
 
 METHOD(kernel_net_t, del_ip, status_t,
-       private_kernel_pfroute_net_t *this, host_t *virtual_ip)
+       private_kernel_pfroute_net_t *this, host_t *virtual_ip, int prefix)
 {
        return FAILED;
 }