From patchwork Sun Jun 23 16:24:03 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mike Rapoport X-Patchwork-Id: 253581 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 5DBE22C04C8 for ; Mon, 24 Jun 2013 02:24:20 +1000 (EST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752034Ab3FWQYR (ORCPT ); Sun, 23 Jun 2013 12:24:17 -0400 Received: from na3sys010aog109.obsmtp.com ([74.125.245.86]:41094 "HELO na3sys010aog109.obsmtp.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with SMTP id S1751764Ab3FWQYP (ORCPT ); Sun, 23 Jun 2013 12:24:15 -0400 Received: from mail-ee0-f51.google.com ([74.125.83.51]) (using TLSv1) by na3sys010aob109.postini.com ([74.125.244.12]) with SMTP ID DSNKUcchLspzomoYhSrN9baxl3Bq9rJiPCjQ@postini.com; Sun, 23 Jun 2013 09:24:15 PDT Received: by mail-ee0-f51.google.com with SMTP id e52so5526994eek.24 for ; Sun, 23 Jun 2013 09:24:13 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20120113; h=from:to:cc:subject:date:message-id:x-mailer:in-reply-to:references :in-reply-to:references:x-gm-message-state; bh=trBEvCv5bkRfWNoH2Fpb4JOhvpdVoIRN7DBZkVLB1qQ=; b=dRd9kLzx87ViHQL/HF65+QODlQ5k23wFUsYiSmZQl1++ZJqgOXHvsxvo767eBwfso0 WwezqbBoUrdTYvxIJFw6BD/LyJyloDP320sO1626q3idDERnvgrLIo0L+JEoyXQbOkTl E+6TQ+byIaIypGlqD1nnZqJRRimWuv51sHpIebwp/KBevf7l1mW9vzcuAJcetzSNrKAf tEIkXZhQcKLVWIxQ4zSx9N0XZzZWVXWZgty37VUE3PeOw1yQhsaNXJt4FDh30mHWVhFH F0I05l5UXCYHH36McfRxO6BViLqKxRxgQ1+WhRELrsjhGPhSMBPbiFRnjK9INS9R/IsT LLiw== X-Received: by 10.14.48.77 with SMTP id u53mr20140010eeb.154.1372004653466; Sun, 23 Jun 2013 09:24:13 -0700 (PDT) X-Received: by 10.14.48.77 with SMTP id u53mr20140002eeb.154.1372004653386; Sun, 23 Jun 2013 09:24:13 -0700 (PDT) Received: from mike.rapoport@ravellosystems.com (46-116-14-239.bb.netvision.net.il. [46.116.14.239]) by mx.google.com with ESMTPSA id ci50sm22137897eeb.12.2013.06.23.09.24.10 for (version=TLSv1.2 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Sun, 23 Jun 2013 09:24:12 -0700 (PDT) Received: by mike.rapoport@ravellosystems.com (sSMTP sendmail emulation); Sun, 23 Jun 2013 19:24:08 +0300 From: Mike Rapoport To: netdev@vger.kernel.org Cc: Stephen Hemminger , David Stevens , Thomas Graf , Mike Rapoport Subject: [PATCH iproute2 2/2] vxlan: allow specifying multiple default destinations Date: Sun, 23 Jun 2013 19:24:03 +0300 Message-Id: <1372004643-24718-2-git-send-email-mike.rapoport@ravellosystems.com> X-Mailer: git-send-email 1.8.1.5 In-Reply-To: <1372004643-24718-1-git-send-email-mike.rapoport@ravellosystems.com> References: <1372004643-24718-1-git-send-email-mike.rapoport@ravellosystems.com> In-Reply-To: <1372004543-24675-1-git-send-email-mike.rapoport@ravellosystems.com> References: <1372004543-24675-1-git-send-email-mike.rapoport@ravellosystems.com> X-Gm-Message-State: ALoCoQl4nZjEqTMus7OPAtJ/yYtowofjKTcDyo+JTDuVj51KdZ8Xs+AdUi9hY0Quh0MSVL/mugoC3ONnl63FwGo1OR6xOlDRCyHWrDQOAsIAW51paKMinxURt1CfSMAjktmrM/0W5/we4S9yEP9dOIHmpYRYvwI+bjZSa+WwDUOufHL5sAH9Ayo= Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org Signed-off-by: Mike Rapoport --- ip/iplink_vxlan.c | 167 +++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 166 insertions(+), 1 deletion(-) diff --git a/ip/iplink_vxlan.c b/ip/iplink_vxlan.c index 92ddfb4..ba9a5d8 100644 --- a/ip/iplink_vxlan.c +++ b/ip/iplink_vxlan.c @@ -35,6 +35,130 @@ static void explain(void) fprintf(stderr, " TTL := { 1..255 | inherit }\n"); } +static void explain_change(void) +{ + fprintf(stderr, "Usage: ... vxlan id VNI\n"); + fprintf(stderr, " [ dstadd DST ]\n"); + fprintf(stderr, " [ dstdel ADDR ]\n"); + fprintf(stderr, "\n"); + fprintf(stderr, "Where: VNI := 0-16777215\n"); ++ fprintf(stderr, " DST := [ ADDR [port PORT] [vni VNI] [via DEV]]\n"); +} + +static int vxlan_parse_dstadd(int *argcp, char ***argvp, struct nlmsghdr *n) +{ + int argc = *argcp; + char **argv = *argvp; + __u32 vni, ifindex; + __u16 port; + struct rtattr *nest; + int addr_set = 0; + + nest = addattr_nest(n, 1024, IFLA_VXLAN_REMOTE_NEW); + + while (argc > 0) { + if (!matches(*argv, "vni")) { + NEXT_ARG(); + if (get_u32(&vni, *argv, 0) || + vni >= 1u << 24) + invarg("invalid id", *argv); + addattr32(n, 1024, IFLA_VXLAN_REMOTE_VNI, vni); + } else if (!matches(*argv, "port")) { + NEXT_ARG(); + if (get_u16(&port, *argv, 0)) + invarg("port", *argv); + addattr32(n, 1024, IFLA_VXLAN_REMOTE_PORT, htons(port)); + } else if (!matches(*argv, "via")) { + NEXT_ARG(); + ifindex = if_nametoindex(*argv); + addattr32(n, 1024, IFLA_VXLAN_REMOTE_IFINDEX, ifindex); + } else { + inet_prefix addr; + get_prefix(&addr, *argv, AF_UNSPEC); + addattr_l(n, 1024, IFLA_VXLAN_REMOTE_ADDR, + &addr.data, addr.bytelen); + addr_set = 1; + } + argc--, argv++; + } + + if (!addr_set) + incomplete_command(); + + addattr_nest_end(n, nest); + + *argcp = argc; + *argvp = argv; + return 0; +} + +static int vxlan_parse_dstdel(int *argcp, char ***argvp, struct nlmsghdr *n) +{ + int argc = *argcp; + char **argv = *argvp; + struct rtattr *nest; + + nest = addattr_nest(n, 1024, IFLA_VXLAN_REMOTE_DEL); + + while (argc > 0) { + inet_prefix addr; + get_prefix(&addr, *argv, AF_UNSPEC); + addattr_l(n, 1024, IFLA_VXLAN_REMOTE_ADDR, + &addr.data, addr.bytelen); + argc--, argv++; + } + + if (argc == *argcp) + incomplete_command(); + + addattr_nest_end(n, nest); + + *argcp = argc; + *argvp = argv; + return 0; +} + +static int vxlan_parse_opt_change(struct link_util *lu, int argc, char **argv, + struct nlmsghdr *n) +{ + __u32 vni = 0; + int vni_set = 0; + struct rtattr *remotes; + + while (argc > 0) { + if (!matches(*argv, "id") || + !matches(*argv, "vni")) { + NEXT_ARG(); + if (get_u32(&vni, *argv, 0) || + vni >= 1u << 24) + invarg("invalid id", *argv); + vni_set = 1; + } else if (!matches(*argv, "dstadd")) { + NEXT_ARG(); + remotes = addattr_nest(n, 1024, IFLA_VXLAN_REMOTES); + vxlan_parse_dstadd(&argc, &argv, n); + addattr_nest_end(n, remotes); + } else if (!matches(*argv, "dstdel")) { + NEXT_ARG(); + remotes = addattr_nest(n, 1024, IFLA_VXLAN_REMOTES); + vxlan_parse_dstdel(&argc, &argv, n); + addattr_nest_end(n, remotes); + } else { + fprintf(stderr, "vxlan: unknown command \"%s\"?\n", *argv); + explain_change(); + return -1; + } + argc--, argv++; + } + + if (!vni_set) { + fprintf(stderr, "vxlan: missing virtual network identifier\n"); + return -1; + } + + return 0; +} + static int vxlan_parse_opt_create(struct link_util *lu, int argc, char **argv, struct nlmsghdr *n) { @@ -190,7 +314,45 @@ static int vxlan_parse_opt_create(struct link_util *lu, int argc, char **argv, static int vxlan_parse_opt(struct link_util *lu, int argc, char **argv, struct nlmsghdr *n) { - return vxlan_parse_opt_create(lu, argc, argv, n); + if (n->nlmsg_flags & NLM_F_CREATE) + return vxlan_parse_opt_create(lu, argc, argv, n); + + return vxlan_parse_opt_change(lu, argc, argv, n); +} + +static void vxlan_print_remote(FILE *f, struct rtattr *attr) +{ + struct rtattr *tb[IFLA_VXLAN_REMOTE_MAX]; + char s1[1024]; + + parse_rtattr_nested(tb, IFLA_VXLAN_REMOTE_MAX, attr); + + if (tb[IFLA_VXLAN_REMOTE_ADDR]) { + struct rtattr *i = tb[IFLA_VXLAN_REMOTE_ADDR]; + if (RTA_PAYLOAD(i) >= sizeof(struct in6_addr)) { + struct in6_addr addr; + memcpy(&addr, RTA_DATA(i), sizeof(struct in6_addr)); + fprintf(f, " %s\n", + format_host(AF_INET6, sizeof(struct in6_addr), + &addr, s1, sizeof(s1))); + } else if (RTA_PAYLOAD(i) >= sizeof(__be32)) { + __be32 addr = rta_getattr_u32(i); + fprintf(f, " %s\n", + format_host(AF_INET, 4, &addr, s1, sizeof(s1))); + } + } +} + +static void vxlan_print_remotes(FILE *f, struct rtattr *attr) +{ + struct rtattr *i; + int rem, n = 0; + + fprintf(f, "\n default destinations :\n"); + + rem = RTA_PAYLOAD(attr); + for (i = RTA_DATA(attr); RTA_OK(i, rem); i = RTA_NEXT(i, rem), n++) + vxlan_print_remote(f, i); } static void vxlan_print_opt(struct link_util *lu, FILE *f, struct rtattr *tb[]) @@ -283,6 +445,9 @@ static void vxlan_print_opt(struct link_util *lu, FILE *f, struct rtattr *tb[]) if (tb[IFLA_VXLAN_LIMIT] && (maxaddr = rta_getattr_u32(tb[IFLA_VXLAN_LIMIT]) != 0)) fprintf(f, "maxaddr %u ", maxaddr); + + if (tb[IFLA_VXLAN_REMOTES]) + vxlan_print_remotes(f, tb[IFLA_VXLAN_REMOTES]); } struct link_util vxlan_link_util = {