From patchwork Sun Mar 12 23:01:36 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Hannes Frederic Sowa X-Patchwork-Id: 737906 X-Patchwork-Delegate: shemminger@vyatta.com Return-Path: X-Original-To: patchwork-incoming@ozlabs.org Delivered-To: patchwork-incoming@ozlabs.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 3vhGj80f38z9s78 for ; Mon, 13 Mar 2017 10:02:04 +1100 (AEDT) Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=stressinduktion.org header.i=@stressinduktion.org header.b="QJK//NP0"; dkim=pass (1024-bit key; unprotected) header.d=messagingengine.com header.i=@messagingengine.com header.b="BTrDgck0"; dkim-atps=neutral Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S935583AbdCLXCC (ORCPT ); Sun, 12 Mar 2017 19:02:02 -0400 Received: from out1-smtp.messagingengine.com ([66.111.4.25]:54682 "EHLO out1-smtp.messagingengine.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S935545AbdCLXBv (ORCPT ); Sun, 12 Mar 2017 19:01:51 -0400 Received: from compute7.internal (compute7.nyi.internal [10.202.2.47]) by mailout.nyi.internal (Postfix) with ESMTP id E334C2067F for ; Sun, 12 Mar 2017 19:01:44 -0400 (EDT) Received: from frontend2 ([10.202.2.161]) by compute7.internal (MEProxy); Sun, 12 Mar 2017 19:01:44 -0400 DKIM-Signature: v=1; a=rsa-sha1; c=relaxed/relaxed; d= stressinduktion.org; h=date:from:in-reply-to:message-id :references:subject:to:x-me-sender:x-me-sender:x-sasl-enc :x-sasl-enc; s=mesmtp; bh=NjLtTivP/OlNzDUU5QYX35Y8bCQ=; b=QJK//N P0V4XmjDircP2x8m6G66z7KgVkmzQXkVANFFuvsj7rBrgGfxL/gL5RR8BftHPPPO vqaePfrpjg0IRzsMQDibhpiik46/vhQMppXuEHwPaUdm40knbPfx3NxdLXOQxEYI KJGEN8S+pk9igeBkvh/rorUoNe9BJ0/FywRig= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed/relaxed; d= messagingengine.com; h=date:from:in-reply-to:message-id :references:subject:to:x-me-sender:x-me-sender:x-sasl-enc :x-sasl-enc; s=smtpout; bh=NjLtTivP/OlNzDUU5QYX35Y8bCQ=; b=BTrDg ck0bPFTa0yU5DzPP8hkPMQZhYSx9i7cfUDrL40urj4jZZWoMWt5h6gwBcBi7f3WF MFC2eqCmiT65AWp6N1m9ixE2a8e+I4gN5i6s1uJ1jaN5DcDre/yOeSYjAqHlrUrQ 3S6vE8P5nDq0I8KtnQKBHDW0Q5x77T5XX3Q2wA= X-ME-Sender: X-Sasl-enc: 2M5uayn/zev1KUk3fgto4uF2R5wtV5VtGdInl84PLNW8 1489359704 Received: from m.localhost.localhost (unknown [213.55.211.72]) by mail.messagingengine.com (Postfix) with ESMTPA id EDC64240CF for ; Sun, 12 Mar 2017 19:01:43 -0400 (EDT) From: Hannes Frederic Sowa To: netdev@vger.kernel.org Subject: [PATCH RFC iproute v1 2/4] afnetns: support for ipv4/v6 address management Date: Mon, 13 Mar 2017 00:01:36 +0100 Message-Id: <20170312230138.5096-3-hannes@stressinduktion.org> X-Mailer: git-send-email 2.9.3 In-Reply-To: <20170312230138.5096-1-hannes@stressinduktion.org> References: <20170312230138.5096-1-hannes@stressinduktion.org> Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org Support ip address add xxx.yyy.zzz.lll/kk dev eth0 afnetns Signed-off-by: Hannes Frederic Sowa --- include/libnetlink.h | 7 +++++++ include/linux/if_addr.h | 2 ++ include/namespace.h | 2 ++ ip/ipaddress.c | 32 ++++++++++++++++++++++++++++++++ ip/ipafnetns.c | 26 +++++++------------------- lib/namespace.c | 21 +++++++++++++++++++++ 6 files changed, 71 insertions(+), 19 deletions(-) diff --git a/include/libnetlink.h b/include/libnetlink.h index bd0267dfcc02ad..81ba0d3a032360 100644 --- a/include/libnetlink.h +++ b/include/libnetlink.h @@ -152,10 +152,17 @@ static inline __u32 rta_getattr_u32(const struct rtattr *rta) { return *(__u32 *)RTA_DATA(rta); } + +static inline __s32 rta_getattr_s32(const struct rtattr *rta) +{ + return *(__s32 *)RTA_DATA(rta); +} + static inline __be32 rta_getattr_be32(const struct rtattr *rta) { return ntohl(rta_getattr_u32(rta)); } + static inline __u64 rta_getattr_u64(const struct rtattr *rta) { __u64 tmp; diff --git a/include/linux/if_addr.h b/include/linux/if_addr.h index 26f0ecff9f13dd..dea1abe593ab29 100644 --- a/include/linux/if_addr.h +++ b/include/linux/if_addr.h @@ -32,6 +32,8 @@ enum { IFA_CACHEINFO, IFA_MULTICAST, IFA_FLAGS, + IFA_AFNETNS_FD, + IFA_AFNETNS_INODE, __IFA_MAX, }; diff --git a/include/namespace.h b/include/namespace.h index acecc8c1f0d2b8..e0745ab0b50972 100644 --- a/include/namespace.h +++ b/include/namespace.h @@ -52,6 +52,8 @@ int netns_switch(char *netns); int netns_get_fd(const char *netns); int netns_foreach(int (*func)(char *nsname, void *arg), void *arg); +int afnetns_open(const char *name); + struct netns_func { int (*func)(char *nsname, void *arg); void *arg; diff --git a/ip/ipaddress.c b/ip/ipaddress.c index b8d9c7d917fe8d..2994b6a3e0a154 100644 --- a/ip/ipaddress.c +++ b/ip/ipaddress.c @@ -37,6 +37,7 @@ #include "ip_common.h" #include "xdp.h" #include "color.h" +#include "namespace.h" enum { IPADD_LIST, @@ -999,6 +1000,18 @@ static int set_lifetime(unsigned int *lifetime, char *argv) return 0; } +static int afnetns_get_fd(const char *name) +{ + int ns = -1; + + if (name[0] == '/') + ns = open(name, O_RDONLY | O_CLOEXEC); + else + ns = afnetns_open(name); + + return ns; +} + static unsigned int get_ifa_flags(struct ifaddrmsg *ifa, struct rtattr *ifa_flags_attr) { @@ -1205,6 +1218,10 @@ int print_addrinfo(const struct sockaddr_nl *who, struct nlmsghdr *n, fprintf(fp, "%usec", ci->ifa_prefered); } } + if (rta_tb[IFA_AFNETNS_INODE]) { + fprintf(fp, " afnet:[%u]", + rta_getattr_u32(rta_tb[IFA_AFNETNS_INODE])); + } fprintf(fp, "\n"); brief_exit: fflush(fp); @@ -1883,6 +1900,7 @@ static int ipaddr_modify(int cmd, int flags, int argc, char **argv) int brd_len = 0; int any_len = 0; int scoped = 0; + int afnetns_fd = -1; __u32 preferred_lft = INFINITY_LIFE_TIME; __u32 valid_lft = INFINITY_LIFE_TIME; unsigned int ifa_flags = 0; @@ -1958,6 +1976,14 @@ static int ipaddr_modify(int cmd, int flags, int argc, char **argv) preferred_lftp = *argv; if (set_lifetime(&preferred_lft, *argv)) invarg("preferred_lft value", *argv); + } else if (strcmp(*argv, "afnetns") == 0) { + if (afnetns_fd != -1) + duparg("afnetns", *argv); + + NEXT_ARG(); + afnetns_fd = afnetns_get_fd(*argv); + if (afnetns_fd < 0) + invarg("afnetns", *argv); } else if (strcmp(*argv, "home") == 0) { ifa_flags |= IFA_F_HOMEADDRESS; } else if (strcmp(*argv, "nodad") == 0) { @@ -2064,9 +2090,15 @@ static int ipaddr_modify(int cmd, int flags, int argc, char **argv) return -1; } + if (afnetns_fd != -1) + addattr32(&req.n, sizeof(req), IFA_AFNETNS_FD, afnetns_fd); + if (rtnl_talk(&rth, &req.n, NULL, 0) < 0) return -2; + if (afnetns_fd > 0) + close(afnetns_fd); + return 0; } diff --git a/ip/ipafnetns.c b/ip/ipafnetns.c index 5b7a7e59bc947a..5a197ad3866d18 100644 --- a/ip/ipafnetns.c +++ b/ip/ipafnetns.c @@ -148,37 +148,25 @@ out_delete: static int afnetns_switch(const char *name) { int err, ns; - char *path; - err = asprintf(&path, "%s/%s", AFNETNS_RUN_DIR, name); - if (err < 0) { - perror("asprintf"); - return err; - }; - - ns = open(path, O_RDONLY | O_CLOEXEC); - if (ns < 0) { - fprintf(stderr, "Cannot open afnet namespace \"%s\": %s\n", - name, strerror(errno)); - err = ns; - goto out; - } + ns = afnetns_open(name); + if (ns < 0) + return ns; err = setns(ns, CLONE_NEWAFNET); if (err) { fprintf(stderr, "setting the afnet namespace \"%s\" failed: %s\n", name, strerror(errno)); - goto out; + return err; } + err = close(ns); if (err) { perror("close"); - goto out; + return err; } -out: - free(path); - return err; + return 0; } static int afnetns_exec(int argc, char **argv) diff --git a/lib/namespace.c b/lib/namespace.c index 30b513889e6e24..f20e5b6ef5a3ef 100644 --- a/lib/namespace.c +++ b/lib/namespace.c @@ -124,3 +124,24 @@ int netns_foreach(int (*func)(char *nsname, void *arg), void *arg) closedir(dir); return 0; } + +int afnetns_open(const char *name) +{ + int ns; + char *path; + + ns = asprintf(&path, "%s/%s", AFNETNS_RUN_DIR, name); + if (ns < 0) { + perror("asprintf"); + return ns; + }; + + ns = open(path, O_RDONLY | O_CLOEXEC); + if (ns < 0) { + fprintf(stderr, "Cannot open afnet namespace \"%s\": %s\n", + name, strerror(errno)); + } + + free(path); + return ns; +}