From patchwork Mon Feb 16 22:23:35 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Madhu Challa X-Patchwork-Id: 440407 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 8B5A41401DA for ; Tue, 17 Feb 2015 09:39:15 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751731AbbBPWjK (ORCPT ); Mon, 16 Feb 2015 17:39:10 -0500 Received: from mail-pd0-f173.google.com ([209.85.192.173]:39292 "EHLO mail-pd0-f173.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751722AbbBPWjJ (ORCPT ); Mon, 16 Feb 2015 17:39:09 -0500 Received: by pdjy10 with SMTP id y10so39200094pdj.6 for ; Mon, 16 Feb 2015 14:39:08 -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; bh=7knzBXgFUjGA7S2hCeITklO1dsPRlS9UBJb/Dtn+WuY=; b=A9aSOtr4en4767P1TCqQd9uoXmLHytwxAs8zxYeGbEpFzztgAprRW3Flj2PxZllmRi /7CyBk7Gm+3EoNCo0x3Pnr1z0AhoNPqPVR+yYalSY9og768tNV6JYOXKF3WFQjIeK4ai 9oGtuB2o24nHifY6ArV36lH5ndEt99wpE1jN7+SrDU8m9YY0rtn3UPHH+i5mpylQMjB9 mJYr48wQnVjorFg0iRC7a7ojT2ylRKZ7jStu49DEoqgSe64A16oOImAraeFdPq4wKk92 mo2XzTeMCnGg47sriA7zikOzzM0Ji1qCkYe8NO6cdBv2ZaOoIsjpKIHDGUnczrB3eONE ffeA== X-Gm-Message-State: ALoCoQlcIyr/VQtmc/vtHwgD/H8A0XTkEuCoi+/Z0DUpjdRP/ppy+fdVPEGWxz41vSr9cYkINcJJ X-Received: by 10.68.242.163 with SMTP id wr3mr44351603pbc.159.1424126348617; Mon, 16 Feb 2015 14:39:08 -0800 (PST) Received: from localhost.localdomain ([173.36.240.158]) by mx.google.com with ESMTPSA id iv1sm15591667pbc.87.2015.02.16.14.39.08 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Mon, 16 Feb 2015 14:39:08 -0800 (PST) From: Madhu Challa To: netdev@vger.kernel.org Cc: Madhu Challa Subject: [PATCH] iproute2: Extend ip address command to enable multicast group join/leave on IP level. Date: Mon, 16 Feb 2015 14:23:35 -0800 Message-Id: <1424125415-4616-1-git-send-email-challa@noironetworks.com> X-Mailer: git-send-email 1.9.1 Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org Joining multicast group on ethernet level via "ip maddr" command would not work if we have an Ethernet switch that does igmp snooping since the switch would not replicate multicast packets on ports that did not have IGMP reports for the multicast addresses. Linux vxlan interfaces created via "ip link add vxlan" have the group option that enables then to do the required join. By extending ip address command with option "autojoin" we can get similar functionality for openvswitch vxlan interfaces as well as other tunneling mechanisms that need to receive multicast traffic. The kernel code is structured similar to how the vxlan driver does a group join / leave. example: ip address add 224.1.1.10/24 dev eth5 autojoin ip address del 224.1.1.10/24 dev eth5 Signed-off-by: Madhu Challa --- include/linux/if_addr.h | 1 + ip/ipaddress.c | 26 +++++++++++++++++++++++++- 2 files changed, 26 insertions(+), 1 deletion(-) diff --git a/include/linux/if_addr.h b/include/linux/if_addr.h index cc375e4..2033adc 100644 --- a/include/linux/if_addr.h +++ b/include/linux/if_addr.h @@ -50,6 +50,7 @@ enum { #define IFA_F_PERMANENT 0x80 #define IFA_F_MANAGETEMPADDR 0x100 #define IFA_F_NOPREFIXROUTE 0x200 +#define IFA_F_MCAUTOJOIN 0x400 struct ifa_cacheinfo { __u32 ifa_prefered; diff --git a/ip/ipaddress.c b/ip/ipaddress.c index 3730424..4f7a81d 100644 --- a/ip/ipaddress.c +++ b/ip/ipaddress.c @@ -84,7 +84,7 @@ static void usage(void) fprintf(stderr, " [-]tentative | [-]deprecated | [-]dadfailed | temporary |\n"); fprintf(stderr, " CONFFLAG-LIST ]\n"); fprintf(stderr, "CONFFLAG-LIST := [ CONFFLAG-LIST ] CONFFLAG\n"); - fprintf(stderr, "CONFFLAG := [ home | nodad | mngtmpaddr | noprefixroute ]\n"); + fprintf(stderr, "CONFFLAG := [ home | nodad | mngtmpaddr | noprefixroute | autojoin ]\n"); fprintf(stderr, "LIFETIME := [ valid_lft LFT ] [ preferred_lft LFT ]\n"); fprintf(stderr, "LFT := forever | SECONDS\n"); @@ -901,6 +901,10 @@ int print_addrinfo(const struct sockaddr_nl *who, struct nlmsghdr *n, ifa_flags &= ~IFA_F_NOPREFIXROUTE; fprintf(fp, "noprefixroute "); } + if (ifa_flags & IFA_F_MCAUTOJOIN) { + ifa_flags &= ~IFA_F_MCAUTOJOIN; + fprintf(fp, "autojoin"); + } if (!(ifa_flags & IFA_F_PERMANENT)) { fprintf(fp, "dynamic "); } else @@ -1340,6 +1344,9 @@ static int ipaddr_list_flush_or_save(int argc, char **argv, int action) } else if (strcmp(*argv, "noprefixroute") == 0) { filter.flags |= IFA_F_NOPREFIXROUTE; filter.flagmask |= IFA_F_NOPREFIXROUTE; + } else if (strcmp(*argv, "autojoin") == 0) { + filter.flags |= IFA_F_MCAUTOJOIN; + filter.flagmask |= IFA_F_MCAUTOJOIN; } else if (strcmp(*argv, "dadfailed") == 0) { filter.flags |= IFA_F_DADFAILED; filter.flagmask |= IFA_F_DADFAILED; @@ -1544,6 +1551,16 @@ static int default_scope(inet_prefix *lcl) return 0; } +static bool ipaddr_is_multicast(inet_prefix *a) +{ + if (a->family == AF_INET) + return IN_MULTICAST(ntohl(a->data[0])); + else if (a->family == AF_INET6) + return IN6_IS_ADDR_MULTICAST(a->data); + else + return false; +} + static int ipaddr_modify(int cmd, int flags, int argc, char **argv) { struct { @@ -1651,6 +1668,8 @@ static int ipaddr_modify(int cmd, int flags, int argc, char **argv) ifa_flags |= IFA_F_MANAGETEMPADDR; } else if (strcmp(*argv, "noprefixroute") == 0) { ifa_flags |= IFA_F_NOPREFIXROUTE; + } else if (strcmp(*argv, "autojoin") == 0) { + ifa_flags |= IFA_F_MCAUTOJOIN; } else { if (strcmp(*argv, "local") == 0) { NEXT_ARG(); @@ -1741,6 +1760,11 @@ static int ipaddr_modify(int cmd, int flags, int argc, char **argv) sizeof(cinfo)); } + if ((ifa_flags & IFA_F_MCAUTOJOIN) && !ipaddr_is_multicast(&lcl)) { + fprintf(stderr, "autojoin needs multicast address\n"); + return -1; + } + if (rtnl_talk(&rth, &req.n, 0, 0, NULL) < 0) return -2;