From patchwork Tue Nov 19 10:44:18 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jiri Pirko X-Patchwork-Id: 292348 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 0E89B2C00F8 for ; Tue, 19 Nov 2013 21:44:28 +1100 (EST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751597Ab3KSKoY (ORCPT ); Tue, 19 Nov 2013 05:44:24 -0500 Received: from mail-ee0-f42.google.com ([74.125.83.42]:62719 "EHLO mail-ee0-f42.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1750833Ab3KSKoW (ORCPT ); Tue, 19 Nov 2013 05:44:22 -0500 Received: by mail-ee0-f42.google.com with SMTP id e52so3149218eek.15 for ; Tue, 19 Nov 2013 02:44:21 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=4r/q3FH/LtPi2dpeFdFDXh5DJtJyeZolJjouhgH8mFw=; b=fhKlO7W3c0M9nVVGXwf+qtxaVPuGX8cla40IgCNt/V2WMUjgxajDm2q53d5XEYmMKo Ljb2DGQNLJec7AmUovfxY/Uu8yIVCjTD1dwAEOwvPEA9pQn8nfvg7VtDQeQTJ1/4C0eQ yR+tka1OE9SNyN86N0XTZRHCPg5vOv/iG8VNvpEyJP7E47pEIj1b2wYon1jrKKtrHtdR g4a9L4VikY8t7a9KQk5O1r+mDUcVI2F4fKq/e4btpFc3n/akL0YGtGY3zC83igjkbXix s1A3xQSn0Hn2r8WGpjG/hijLKRmOsQ2r5MgeBg/SYizV7AiVamrdYzXz3Z5fGyRrgGPw lkJQ== X-Gm-Message-State: ALoCoQlh92T4EvDIlzhO/rmlVVkzkDZq+4PhG3tRmBlFqEuYXz17Ds5OVHLI3WAVO5JtcgOLSNTW X-Received: by 10.15.26.131 with SMTP id n3mr409412eeu.21.1384857861713; Tue, 19 Nov 2013 02:44:21 -0800 (PST) Received: from localhost (sun-0.pirko.cz. [84.16.102.25]) by mx.google.com with ESMTPSA id s3sm47401077eeo.3.2013.11.19.02.44.20 for (version=TLSv1.2 cipher=AES128-GCM-SHA256 bits=128/128); Tue, 19 Nov 2013 02:44:21 -0800 (PST) From: Jiri Pirko To: netdev@vger.kernel.org Cc: davem@davemloft.net, kuznet@ms2.inr.ac.ru, jmorris@namei.org, yoshfuji@linux-ipv6.org, kaber@trash.net, thaller@redhat.com, stephen@networkplumber.org, hannes@stressinduktion.org, vyasevich@gmail.com, dcbw@redhat.com, David.Laight@ACULAB.COM Subject: [patch iproute2 RFC v2 1/2] add support for extended ifa_flags Date: Tue, 19 Nov 2013 11:44:18 +0100 Message-Id: <1384857859-6618-1-git-send-email-jiri@resnulli.us> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1384857809-6573-1-git-send-email-jiri@resnulli.us> References: <1384857809-6573-1-git-send-email-jiri@resnulli.us> Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org Signed-off-by: Jiri Pirko --- include/linux/if_addr.h | 1 + ip/ipaddress.c | 44 ++++++++++++++++++++++++++++++-------------- 2 files changed, 31 insertions(+), 14 deletions(-) diff --git a/include/linux/if_addr.h b/include/linux/if_addr.h index 58b39f4..cced59f 100644 --- a/include/linux/if_addr.h +++ b/include/linux/if_addr.h @@ -28,6 +28,7 @@ enum { IFA_ANYCAST, IFA_CACHEINFO, IFA_MULTICAST, + IFA_FLAGS, __IFA_MAX, }; diff --git a/ip/ipaddress.c b/ip/ipaddress.c index 1c3e4da..59dbd71 100644 --- a/ip/ipaddress.c +++ b/ip/ipaddress.c @@ -541,6 +541,13 @@ static int set_lifetime(unsigned int *lifetime, char *argv) return 0; } +static unsigned int get_ifa_flags(struct ifaddrmsg *ifa, + struct rtattr *ifa_flags_attr) +{ + return ifa_flags_attr ? rta_getattr_u32(ifa_flags_attr) : + ifa->ifa_flags; +} + int print_addrinfo(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg) { @@ -567,6 +574,8 @@ int print_addrinfo(const struct sockaddr_nl *who, struct nlmsghdr *n, parse_rtattr(rta_tb, IFA_MAX, IFA_RTA(ifa), n->nlmsg_len - NLMSG_LENGTH(sizeof(*ifa))); + ifa_flags = get_ifa_flags(ifa, rta_tb[IFA_FLAGS]); + if (!rta_tb[IFA_LOCAL]) rta_tb[IFA_LOCAL] = rta_tb[IFA_ADDRESS]; if (!rta_tb[IFA_ADDRESS]) @@ -576,7 +585,7 @@ int print_addrinfo(const struct sockaddr_nl *who, struct nlmsghdr *n, return 0; if ((filter.scope^ifa->ifa_scope)&filter.scopemask) return 0; - if ((filter.flags^ifa->ifa_flags)&filter.flagmask) + if ((filter.flags ^ ifa_flags) & filter.flagmask) return 0; if (filter.label) { SPRINT_BUF(b1); @@ -670,36 +679,35 @@ int print_addrinfo(const struct sockaddr_nl *who, struct nlmsghdr *n, abuf, sizeof(abuf))); } fprintf(fp, "scope %s ", rtnl_rtscope_n2a(ifa->ifa_scope, b1, sizeof(b1))); - ifa_flags = ifa->ifa_flags; - if (ifa->ifa_flags&IFA_F_SECONDARY) { + if (ifa_flags & IFA_F_SECONDARY) { ifa_flags &= ~IFA_F_SECONDARY; if (ifa->ifa_family == AF_INET6) fprintf(fp, "temporary "); else fprintf(fp, "secondary "); } - if (ifa->ifa_flags&IFA_F_TENTATIVE) { + if (ifa_flags & IFA_F_TENTATIVE) { ifa_flags &= ~IFA_F_TENTATIVE; fprintf(fp, "tentative "); } - if (ifa->ifa_flags&IFA_F_DEPRECATED) { + if (ifa_flags & IFA_F_DEPRECATED) { ifa_flags &= ~IFA_F_DEPRECATED; deprecated = 1; fprintf(fp, "deprecated "); } - if (ifa->ifa_flags&IFA_F_HOMEADDRESS) { + if (ifa_flags & IFA_F_HOMEADDRESS) { ifa_flags &= ~IFA_F_HOMEADDRESS; fprintf(fp, "home "); } - if (ifa->ifa_flags&IFA_F_NODAD) { + if (ifa_flags & IFA_F_NODAD) { ifa_flags &= ~IFA_F_NODAD; fprintf(fp, "nodad "); } - if (!(ifa->ifa_flags&IFA_F_PERMANENT)) { + if (!(ifa_flags & IFA_F_PERMANENT)) { fprintf(fp, "dynamic "); } else ifa_flags &= ~IFA_F_PERMANENT; - if (ifa->ifa_flags&IFA_F_DADFAILED) { + if (ifa_flags & IFA_F_DADFAILED) { ifa_flags &= ~IFA_F_DADFAILED; fprintf(fp, "dadfailed "); } @@ -926,6 +934,8 @@ static void ipaddr_filter(struct nlmsg_chain *linfo, struct nlmsg_chain *ainfo) for (a = ainfo->head; a; a = a->next) { struct nlmsghdr *n = &a->h; struct ifaddrmsg *ifa = NLMSG_DATA(n); + struct rtattr *tb[IFA_MAX + 1]; + unsigned int ifa_flags; if (ifa->ifa_index != ifi->ifi_index) continue; @@ -934,11 +944,13 @@ static void ipaddr_filter(struct nlmsg_chain *linfo, struct nlmsg_chain *ainfo) continue; if ((filter.scope^ifa->ifa_scope)&filter.scopemask) continue; - if ((filter.flags^ifa->ifa_flags)&filter.flagmask) + + parse_rtattr(tb, IFA_MAX, IFA_RTA(ifa), IFA_PAYLOAD(n)); + ifa_flags = get_ifa_flags(ifa, tb[IFA_FLAGS]); + + if ((filter.flags ^ ifa_flags) & filter.flagmask) continue; if (filter.pfx.family || filter.label) { - struct rtattr *tb[IFA_MAX+1]; - parse_rtattr(tb, IFA_MAX, IFA_RTA(ifa), IFA_PAYLOAD(n)); if (!tb[IFA_LOCAL]) tb[IFA_LOCAL] = tb[IFA_ADDRESS]; @@ -1252,6 +1264,7 @@ static int ipaddr_modify(int cmd, int flags, int argc, char **argv) __u32 preferred_lft = INFINITY_LIFE_TIME; __u32 valid_lft = INFINITY_LIFE_TIME; struct ifa_cacheinfo cinfo; + unsigned int ifa_flags = 0; memset(&req, 0, sizeof(req)); @@ -1329,9 +1342,9 @@ static int ipaddr_modify(int cmd, int flags, int argc, char **argv) if (set_lifetime(&preferred_lft, *argv)) invarg("preferred_lft value", *argv); } else if (strcmp(*argv, "home") == 0) { - req.ifa.ifa_flags |= IFA_F_HOMEADDRESS; + ifa_flags |= IFA_F_HOMEADDRESS; } else if (strcmp(*argv, "nodad") == 0) { - req.ifa.ifa_flags |= IFA_F_NODAD; + ifa_flags |= IFA_F_NODAD; } else { if (strcmp(*argv, "local") == 0) { NEXT_ARG(); @@ -1349,6 +1362,9 @@ static int ipaddr_modify(int cmd, int flags, int argc, char **argv) } argc--; argv++; } + req.ifa.ifa_flags = ifa_flags & 0xff; + addattr32(&req.n, sizeof(req), IFA_FLAGS, ifa_flags); + if (d == NULL) { fprintf(stderr, "Not enough information: \"dev\" argument is required.\n"); return -1;