summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJukka Rissanen <jukka.rissanen@linux.intel.com>2011-06-22 13:37:41 +0300
committerSamuel Ortiz <sameo@linux.intel.com>2011-06-27 16:15:08 +0200
commit9542c566a1a38ca1760dbdef7e41441cbb7fe918 (patch)
treee36c97f8264a9d66a7c8cc412150e59b9b67290b
parentbde93d67e7659cde42bb71e20f47cb4a0c8052fc (diff)
downloadconnman-9542c566a1a38ca1760dbdef7e41441cbb7fe918.tar.gz
connman-9542c566a1a38ca1760dbdef7e41441cbb7fe918.tar.bz2
connman-9542c566a1a38ca1760dbdef7e41441cbb7fe918.zip
inet: Added support functions for setting and clearing IPv6 gateway address.
-rw-r--r--include/inet.h2
-rw-r--r--src/inet.c92
2 files changed, 94 insertions, 0 deletions
diff --git a/include/inet.h b/include/inet.h
index 19f4455d..1aa23ea9 100644
--- a/include/inet.h
+++ b/include/inet.h
@@ -69,6 +69,8 @@ int connman_inet_del_ipv6_network_route(int index, const char *host,
int connman_inet_del_ipv6_host_route(int index, const char *host);
int connman_inet_set_ipv6_gateway_address(int index, const char *gateway);
int connman_inet_clear_ipv6_gateway_address(int index, const char *gateway);
+int connman_inet_set_ipv6_gateway_interface(int index);
+int connman_inet_clear_ipv6_gateway_interface(int index);
int connman_inet_add_to_bridge(int index, const char *bridge);
int connman_inet_remove_from_bridge(int index, const char *bridge);
diff --git a/src/inet.c b/src/inet.c
index 05ead31c..d8986508 100644
--- a/src/inet.c
+++ b/src/inet.c
@@ -1014,6 +1014,52 @@ int connman_inet_set_gateway_interface(int index)
return err;
}
+int connman_inet_set_ipv6_gateway_interface(int index)
+{
+ struct ifreq ifr;
+ struct rtentry rt;
+ struct sockaddr_in6 addr;
+ const struct in6_addr any = IN6ADDR_ANY_INIT;
+ int sk, err;
+
+ DBG("");
+
+ sk = socket(PF_INET6, SOCK_DGRAM, 0);
+ if (sk < 0)
+ return -1;
+
+ memset(&ifr, 0, sizeof(ifr));
+ ifr.ifr_ifindex = index;
+
+ if (ioctl(sk, SIOCGIFNAME, &ifr) < 0) {
+ close(sk);
+ return -1;
+ }
+
+ DBG("ifname %s", ifr.ifr_name);
+
+ memset(&rt, 0, sizeof(rt));
+ rt.rt_flags = RTF_UP;
+
+ memset(&addr, 0, sizeof(addr));
+ addr.sin6_family = AF_INET6;
+ addr.sin6_addr = any;
+
+ memcpy(&rt.rt_genmask, &addr, sizeof(rt.rt_genmask));
+ memcpy(&rt.rt_dst, &addr, sizeof(rt.rt_dst));
+ memcpy(&rt.rt_gateway, &addr, sizeof(rt.rt_gateway));
+
+ rt.rt_dev = ifr.ifr_name;
+
+ err = ioctl(sk, SIOCADDRT, &rt);
+ if (err < 0)
+ connman_error("Setting default interface route failed (%s)",
+ strerror(errno));
+ close(sk);
+
+ return err;
+}
+
int connman_inet_clear_gateway_address(int index, const char *gateway)
{
struct ifreq ifr;
@@ -1110,6 +1156,52 @@ int connman_inet_clear_gateway_interface(int index)
return err;
}
+int connman_inet_clear_ipv6_gateway_interface(int index)
+{
+ struct ifreq ifr;
+ struct rtentry rt;
+ struct sockaddr_in6 addr;
+ const struct in6_addr any = IN6ADDR_ANY_INIT;
+ int sk, err;
+
+ DBG("");
+
+ sk = socket(PF_INET6, SOCK_DGRAM, 0);
+ if (sk < 0)
+ return -1;
+
+ memset(&ifr, 0, sizeof(ifr));
+ ifr.ifr_ifindex = index;
+
+ if (ioctl(sk, SIOCGIFNAME, &ifr) < 0) {
+ close(sk);
+ return -1;
+ }
+
+ DBG("ifname %s", ifr.ifr_name);
+
+ memset(&rt, 0, sizeof(rt));
+ rt.rt_flags = RTF_UP;
+
+ memset(&addr, 0, sizeof(addr));
+ addr.sin6_family = AF_INET6;
+ addr.sin6_addr = any;
+
+ memcpy(&rt.rt_genmask, &addr, sizeof(rt.rt_genmask));
+ memcpy(&rt.rt_dst, &addr, sizeof(rt.rt_dst));
+ memcpy(&rt.rt_gateway, &addr, sizeof(rt.rt_gateway));
+
+ rt.rt_dev = ifr.ifr_name;
+
+ err = ioctl(sk, SIOCDELRT, &rt);
+ if (err < 0)
+ connman_error("Removing default interface route failed (%s)",
+ strerror(errno));
+ close(sk);
+
+ return err;
+}
+
connman_bool_t connman_inet_compare_subnet(int index, const char *host)
{
struct ifreq ifr;