From: Guilhem Lettron Date: Tue, 29 Oct 2013 02:31:49 +0000 (+0100) Subject: Add gateway as direct route for interface X-Git-Tag: lxc-1.0.0.beta1~90 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=77dcf03a791f26942e997714291a8ab97693877f;p=thirdparty%2Flxc.git Add gateway as direct route for interface Signed-off-by: Guilhem Lettron Acked-by: Stéphane Graber --- diff --git a/src/lxc/conf.c b/src/lxc/conf.c index 534e6e6fb..7e85ae17c 100644 --- a/src/lxc/conf.c +++ b/src/lxc/conf.c @@ -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", diff --git a/src/lxc/network.c b/src/lxc/network.c index 94ff1f0ca..941f0ec21 100644 --- a/src/lxc/network.c +++ b/src/lxc/network.c @@ -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. diff --git a/src/lxc/network.h b/src/lxc/network.h index 58db9a19a..e3bb7f467 100644 --- a/src/lxc/network.h +++ b/src/lxc/network.h @@ -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. */