]> git.ipfire.org Git - thirdparty/lxc.git/commitdiff
Add gateway as direct route for interface
authorGuilhem Lettron <guilhem.lettron@gmail.com>
Tue, 29 Oct 2013 02:31:49 +0000 (03:31 +0100)
committerStéphane Graber <stgraber@ubuntu.com>
Tue, 26 Nov 2013 15:22:47 +0000 (10:22 -0500)
Signed-off-by: Guilhem Lettron <guilhem.lettron@gmail.com>
Acked-by: Stéphane Graber <stgraber@ubuntu.com>
src/lxc/conf.c
src/lxc/network.c
src/lxc/network.h

index 534e6e6fb7e8db5aee6d51d6d7ba45c117b75723..7e85ae17c39ccd620e4740f9f2c8a56d7666405d 100644 (file)
@@ -2504,6 +2504,12 @@ static int setup_netdev(struct lxc_netdev *netdev)
                        return -1;
                }
 
+               err = lxc_ipv4_dest_add(netdev->ifindex, netdev->ipv4_gateway);
+               if (err) {
+                       ERROR("failed to add ipv4 dest for '%s': %s",
+                                     ifname, strerror(-err));
+               }
+
                err = lxc_ipv4_gateway_add(netdev->ifindex, netdev->ipv4_gateway);
                if (err) {
                        ERROR("failed to setup ipv4 gateway for '%s': %s",
@@ -2529,6 +2535,12 @@ static int setup_netdev(struct lxc_netdev *netdev)
                        return -1;
                }
 
+               err = lxc_ipv6_dest_add(netdev->ifindex, netdev->ipv6_gateway);
+               if (err) {
+                       ERROR("failed to add ipv6 dest for '%s': %s",
+                             ifname, strerror(-err));
+               }
+
                err = lxc_ipv6_gateway_add(netdev->ifindex, netdev->ipv6_gateway);
                if (err) {
                        ERROR("failed to setup ipv6 gateway for '%s': %s",
index 94ff1f0cafc262dc0f6fcd386eb68353a8e1d41a..941f0ec21bfa56d651f2358ef829177971faaed8 100644 (file)
@@ -998,6 +998,66 @@ int lxc_ipv6_gateway_add(int ifindex, struct in6_addr *gw)
        return ip_gateway_add(AF_INET6, ifindex, gw);
 }
 
+static int ip_route_dest_add(int family, int ifindex, void *dest)
+{
+       struct nl_handler nlh;
+       struct nlmsg *nlmsg = NULL, *answer = NULL;
+       struct rt_req *rt_req;
+       int addrlen;
+       int err;
+       
+       addrlen = family == AF_INET ? sizeof(struct in_addr) :
+               sizeof(struct in6_addr);
+       
+       err = netlink_open(&nlh, NETLINK_ROUTE);
+       if (err)
+               return err;
+       
+       err = -ENOMEM;
+       nlmsg = nlmsg_alloc(NLMSG_GOOD_SIZE);
+       if (!nlmsg)
+               goto out;
+       
+       answer = nlmsg_alloc(NLMSG_GOOD_SIZE);
+       if (!answer)
+               goto out;
+       
+       rt_req = (struct rt_req *)nlmsg;
+       rt_req->nlmsg.nlmsghdr.nlmsg_len =
+               NLMSG_LENGTH(sizeof(struct rtmsg));
+       rt_req->nlmsg.nlmsghdr.nlmsg_flags =
+               NLM_F_ACK|NLM_F_REQUEST|NLM_F_CREATE|NLM_F_EXCL;
+       rt_req->nlmsg.nlmsghdr.nlmsg_type = RTM_NEWROUTE;
+       rt_req->rt.rtm_family = family;
+       rt_req->rt.rtm_table = RT_TABLE_MAIN;
+       rt_req->rt.rtm_scope = RT_SCOPE_LINK;
+       rt_req->rt.rtm_protocol = RTPROT_BOOT;
+       rt_req->rt.rtm_type = RTN_UNICAST;
+       rt_req->rt.rtm_dst_len = addrlen*8;
+       
+       err = -EINVAL;
+       if (nla_put_buffer(nlmsg, RTA_DST, dest, addrlen))
+               goto out;
+       if (nla_put_u32(nlmsg, RTA_OIF, ifindex))
+               goto out;
+       err = netlink_transaction(&nlh, nlmsg, answer);
+out:
+       netlink_close(&nlh);
+       nlmsg_free(answer);
+       nlmsg_free(nlmsg);
+       return err;
+}
+
+int lxc_ipv4_dest_add(int ifindex, struct in_addr *dest)
+{
+       return ip_route_dest_add(AF_INET, ifindex, dest);
+}
+
+int lxc_ipv6_dest_add(int ifindex, struct in6_addr *dest)
+{
+       return ip_route_dest_add(AF_INET6, ifindex, dest);
+}
+
 /*
  * There is a lxc_bridge_attach, but no need of a bridge detach
  * as automatically done by kernel when a netdev is deleted.
index 58db9a19af6946503b07fa3b185bfcf8a5b12dc2..e3bb7f46752df9153b1c4424c7519f371dd826b5 100644 (file)
@@ -92,6 +92,12 @@ extern int lxc_ipv4_addr_add(int ifindex, struct in_addr *addr,
 extern int lxc_ipv4_addr_get(int ifindex, struct in_addr **res);
 extern int lxc_ipv6_addr_get(int ifindex, struct in6_addr **res);
 
+/*
+ * Set a destination route to an interface
+ */
+extern int lxc_ipv4_dest_add(int ifindex, struct in_addr *dest);
+extern int lxc_ipv6_dest_add(int ifindex, struct in6_addr *dest);
+
 /*
  * Set default route.
  */