The following pull request was submitted through Github.
It can be accessed and reviewed at: https://github.com/lxc/lxc/pull/3277

This e-mail was sent by the LXC bot, direct replies will not reach the author
unless they happen to be subscribed to this list.

=== Description (from pull-request) ===
Removes need for ip command when managing IP neighbour proxies.

Signed-off-by: Thomas Parrott <thomas.parr...@canonical.com>
From 5fe147e9740c5e86bdb58c5cd01ad0e558a8838b Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parr...@canonical.com>
Date: Sun, 8 Mar 2020 17:48:01 +0000
Subject: [PATCH] network: Uses netlink for IP neighbour proxy management

Removes need for ip command when managing IP neighbour proxies.

Signed-off-by: Thomas Parrott <thomas.parr...@canonical.com>
---
 src/lxc/network.c | 112 +++++++++++++++++++++++++---------------------
 1 file changed, 62 insertions(+), 50 deletions(-)

diff --git a/src/lxc/network.c b/src/lxc/network.c
index 7b9ea1f25a..3bfcae721b 100644
--- a/src/lxc/network.c
+++ b/src/lxc/network.c
@@ -200,56 +200,49 @@ struct ip_proxy_args {
        const char *dev;
 };
 
-static int lxc_add_ip_neigh_proxy_exec_wrapper(void *data)
+static int lxc_ip_neigh_proxy(__u16 nlmsg_type, int family, int ifindex, void 
*dest)
 {
-       struct ip_proxy_args *args = data;
-
-       execlp("ip", "ip", "neigh", "add", "proxy", args->ip, "dev", args->dev, 
(char *)NULL);
-       return -1;
-}
+       int addrlen, err;
+       struct nl_handler nlh;
+       struct ndmsg *rt;
+       struct nlmsg *answer = NULL, *nlmsg = NULL;
 
-static int lxc_del_ip_neigh_proxy_exec_wrapper(void *data)
-{
-       struct ip_proxy_args *args = data;
+       addrlen = family == AF_INET ? sizeof(struct in_addr) : sizeof(struct 
in6_addr);
 
-       execlp("ip", "ip", "neigh", "flush", "proxy", args->ip, "dev", 
args->dev, (char *)NULL);
-       return -1;
-}
+       err = netlink_open(&nlh, NETLINK_ROUTE);
+       if (err)
+               return err;
 
-static int lxc_add_ip_neigh_proxy(const char *ip, const char *dev)
-{
-       int ret;
-       char cmd_output[PATH_MAX] = {0};
-       struct ip_proxy_args args = {
-               .ip = ip,
-               .dev = dev,
-       };
+       err = -ENOMEM;
+       nlmsg = nlmsg_alloc(NLMSG_GOOD_SIZE);
+       if (!nlmsg)
+               goto out;
 
-       ret = run_command(cmd_output, sizeof(cmd_output), 
lxc_add_ip_neigh_proxy_exec_wrapper, &args);
-       if (ret < 0) {
-               ERROR("Failed to add ip proxy \"%s\" to dev \"%s\": %s", ip, 
dev, cmd_output);
-               return -1;
-       }
+       answer = nlmsg_alloc_reserve(NLMSG_GOOD_SIZE);
+       if (!answer)
+               goto out;
 
-       return 0;
-}
+       nlmsg->nlmsghdr->nlmsg_flags = NLM_F_ACK | NLM_F_REQUEST | NLM_F_CREATE 
| NLM_F_EXCL;
+       nlmsg->nlmsghdr->nlmsg_type = nlmsg_type;
 
-static int lxc_del_ip_neigh_proxy(const char *ip, const char *dev)
-{
-       int ret;
-       char cmd_output[PATH_MAX] = {0};
-       struct ip_proxy_args args = {
-               .ip = ip,
-               .dev = dev,
-       };
+       rt = nlmsg_reserve(nlmsg, sizeof(struct ndmsg));
+       if (!rt)
+               goto out;
+       rt->ndm_ifindex = ifindex;
+       rt->ndm_flags = NTF_PROXY;
+       rt->ndm_type = NDA_DST;
+       rt->ndm_family = family;
 
-       ret = run_command(cmd_output, sizeof(cmd_output), 
lxc_del_ip_neigh_proxy_exec_wrapper, &args);
-       if (ret < 0) {
-               ERROR("Failed to delete ip proxy \"%s\" to dev \"%s\": %s", ip, 
dev, cmd_output);
-               return -1;
-       }
+       err = -EINVAL;
+       if (nla_put_buffer(nlmsg, NDA_DST, dest, addrlen))
+               goto out;
 
-       return 0;
+       err = netlink_transaction(&nlh, nlmsg, answer);
+out:
+       netlink_close(&nlh);
+       nlmsg_free(answer);
+       nlmsg_free(nlmsg);
+       return err;
 }
 
 static int lxc_is_ip_forwarding_enabled(const char *ifname, int family)
@@ -395,7 +388,7 @@ static int instantiate_veth(struct lxc_handler *handler, 
struct lxc_netdev *netd
                                goto out_delete;
                        }
 
-                       err = lxc_add_ip_neigh_proxy(bufinet4, veth1);
+                       err = lxc_ip_neigh_proxy(RTM_NEWNEIGH, AF_INET, 
netdev->priv.veth_attr.ifindex, netdev->ipv4_gateway);
                        if (err) {
                                log_error_errno(-1, err, "Failed to add gateway 
ipv4 proxy on \"%s\"", veth1);
                                goto out_delete;
@@ -431,7 +424,7 @@ static int instantiate_veth(struct lxc_handler *handler, 
struct lxc_netdev *netd
                                goto out_delete;
                        }
 
-                       err = lxc_add_ip_neigh_proxy(bufinet6, veth1);
+                       err = lxc_ip_neigh_proxy(RTM_NEWNEIGH, AF_INET6, 
netdev->priv.veth_attr.ifindex, netdev->ipv6_gateway);
                        if (err) {
                                log_error_errno(-1, err, "Failed to add gateway 
ipv6 proxy on \"%s\"", veth1);
                                goto out_delete;
@@ -3129,7 +3122,14 @@ static int lxc_setup_l2proxy(struct lxc_netdev *netdev) {
        struct lxc_inet6dev *inet6dev;
        char bufinet4[INET_ADDRSTRLEN], bufinet6[INET6_ADDRSTRLEN];
        int err = 0;
-       unsigned int lo_ifindex = 0;
+       unsigned int lo_ifindex = 0, link_ifindex = 0;
+
+       link_ifindex = if_nametoindex(netdev->link);
+       if (link_ifindex == 0) {
+               ERROR("Failed to retrieve ifindex for \"%s\" l2proxy setup", 
netdev->link);
+               return ret_set_errno(-1, EINVAL);
+       }
+
 
        /* If IPv4 addresses are specified, then check that sysctl is 
configured correctly. */
        if (!lxc_list_empty(&netdev->ipv4)) {
@@ -3176,7 +3176,7 @@ static int lxc_setup_l2proxy(struct lxc_netdev *netdev) {
                if (!inet_ntop(AF_INET, &inet4dev->addr, bufinet4, 
sizeof(bufinet4)))
                        return ret_set_errno(-1, -errno);
 
-               if (lxc_add_ip_neigh_proxy(bufinet4, netdev->link) < 0)
+               if (lxc_ip_neigh_proxy(RTM_NEWNEIGH, AF_INET, link_ifindex, 
&inet4dev->addr) < 0)
                        return ret_set_errno(-1, EINVAL);
 
                /* IPVLAN requires a route to local-loopback to trigger 
l2proxy. */
@@ -3194,7 +3194,7 @@ static int lxc_setup_l2proxy(struct lxc_netdev *netdev) {
                if (!inet_ntop(AF_INET6, &inet6dev->addr, bufinet6, 
sizeof(bufinet6)))
                        return ret_set_errno(-1, -errno);
 
-               if (lxc_add_ip_neigh_proxy(bufinet6, netdev->link) < 0)
+               if (lxc_ip_neigh_proxy(RTM_NEWNEIGH, AF_INET6, link_ifindex, 
&inet6dev->addr) < 0)
                        return ret_set_errno(-1, EINVAL);
 
                /* IPVLAN requires a route to local-loopback to trigger 
l2proxy. */
@@ -3212,7 +3212,7 @@ static int lxc_setup_l2proxy(struct lxc_netdev *netdev) {
 
 static int lxc_delete_ipv4_l2proxy(struct in_addr *ip, char *link, unsigned 
int lo_ifindex) {
        char bufinet4[INET_ADDRSTRLEN];
-       unsigned int errCount = 0;
+       unsigned int errCount = 0, link_ifindex = 0;
 
        if (!inet_ntop(AF_INET, ip, bufinet4, sizeof(bufinet4))) {
                SYSERROR("Failed to convert IP for l2proxy ipv4 removal on dev 
\"%s\"", link);
@@ -3229,7 +3229,13 @@ static int lxc_delete_ipv4_l2proxy(struct in_addr *ip, 
char *link, unsigned int
 
        /* If link is supplied remove the IP neigh proxy entry for this IP on 
the device. */
        if (link[0] != '\0') {
-               if (lxc_del_ip_neigh_proxy(bufinet4, link) < 0)
+               link_ifindex = if_nametoindex(link);
+               if (link_ifindex == 0) {
+                       ERROR("Failed to retrieve ifindex for \"%s\" l2proxy 
cleanup", link);
+                       return ret_set_errno(-1, EINVAL);
+               }
+
+               if (lxc_ip_neigh_proxy(RTM_DELNEIGH, AF_INET, link_ifindex, ip) 
< 0)
                        errCount++;
        }
 
@@ -3241,7 +3247,7 @@ static int lxc_delete_ipv4_l2proxy(struct in_addr *ip, 
char *link, unsigned int
 
 static int lxc_delete_ipv6_l2proxy(struct in6_addr *ip, char *link, unsigned 
int lo_ifindex) {
        char bufinet6[INET6_ADDRSTRLEN];
-       unsigned int errCount = 0;
+       unsigned int errCount = 0, link_ifindex = 0;
 
        if (!inet_ntop(AF_INET6, ip, bufinet6, sizeof(bufinet6))) {
                SYSERROR("Failed to convert IP for l2proxy ipv6 removal on dev 
\"%s\"", link);
@@ -3258,7 +3264,13 @@ static int lxc_delete_ipv6_l2proxy(struct in6_addr *ip, 
char *link, unsigned int
 
        /* If link is supplied remove the IP neigh proxy entry for this IP on 
the device. */
        if (link[0] != '\0') {
-               if (lxc_del_ip_neigh_proxy(bufinet6, link) < 0)
+               link_ifindex = if_nametoindex(link);
+               if (link_ifindex == 0) {
+                       ERROR("Failed to retrieve ifindex for \"%s\" l2proxy 
cleanup", link);
+                       return ret_set_errno(-1, EINVAL);
+               }
+
+               if (lxc_ip_neigh_proxy(RTM_DELNEIGH, AF_INET6, link_ifindex, 
ip) < 0)
                        errCount++;
        }
 
_______________________________________________
lxc-devel mailing list
lxc-devel@lists.linuxcontainers.org
http://lists.linuxcontainers.org/listinfo/lxc-devel

Reply via email to