Skip to content

Commit

Permalink
Add gateway as direct route for interface
Browse files Browse the repository at this point in the history
Signed-off-by: Guilhem Lettron <guilhem.lettron@gmail.com>
Acked-by: Stéphane Graber <stgraber@ubuntu.com>
  • Loading branch information
guilhem authored and stgraber committed Nov 26, 2013
1 parent 7ee37fa commit 77dcf03
Show file tree
Hide file tree
Showing 3 changed files with 78 additions and 0 deletions.
12 changes: 12 additions & 0 deletions src/lxc/conf.c
Expand Up @@ -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",
Expand All @@ -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",
Expand Down
60 changes: 60 additions & 0 deletions src/lxc/network.c
Expand Up @@ -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.
Expand Down
6 changes: 6 additions & 0 deletions src/lxc/network.h
Expand Up @@ -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.
*/
Expand Down

0 comments on commit 77dcf03

Please sign in to comment.