]> git.proxmox.com Git - mirror_iproute2.git/commitdiff
bridge: mdb: add support for source address
authorNikolay Aleksandrov <nikolay@nvidia.com>
Thu, 8 Oct 2020 13:50:19 +0000 (16:50 +0300)
committerDavid Ahern <dsahern@gmail.com>
Mon, 12 Oct 2020 02:07:25 +0000 (20:07 -0600)
This patch adds the user-space control and dump of mdb entry source
address. When setting the new MDBA_SET_ENTRY_ATTRS nested attribute is
used and inside is added MDBE_ATTR_SOURCE based on the address family.
When dumping we look for MDBA_MDB_EATTR_SOURCE and if present we add the
"src x.x.x.x" output. The source address will be always shown as it's
needed to match the entry to modify it from user-space.

Example:
 $ bridge mdb add dev bridge port ens13 grp 239.0.0.1 src 1.2.3.4 permanent vid 100
 $ bridge mdb show
 dev bridge port ens13 grp 239.0.0.1 src 1.2.3.4 permanent vid 100

Signed-off-by: Nikolay Aleksandrov <nikolay@nvidia.com>
Signed-off-by: David Ahern <dsahern@gmail.com>
bridge/mdb.c
man/man8/bridge.8

index 928ae56d29a79186b7136463b9bdab01e8c1c6e1..01c8a6e389a8c788dbfde7b8f800779a5d07cb5e 100644 (file)
@@ -31,7 +31,7 @@ static unsigned int filter_index, filter_vlan;
 static void usage(void)
 {
        fprintf(stderr,
-               "Usage: bridge mdb { add | del } dev DEV port PORT grp GROUP [permanent | temp] [vid VID]\n"
+               "Usage: bridge mdb { add | del } dev DEV port PORT grp GROUP [src SOURCE] [permanent | temp] [vid VID]\n"
                "       bridge mdb {show} [ dev DEV ] [ vid VID ]\n");
        exit(-1);
 }
@@ -118,16 +118,16 @@ static void br_print_router_ports(FILE *f, struct rtattr *attr,
 static void print_mdb_entry(FILE *f, int ifindex, const struct br_mdb_entry *e,
                            struct nlmsghdr *n, struct rtattr **tb)
 {
+       const void *grp, *src;
        SPRINT_BUF(abuf);
        const char *dev;
-       const void *src;
        int af;
 
        if (filter_vlan && e->vid != filter_vlan)
                return;
 
        af = e->addr.proto == htons(ETH_P_IP) ? AF_INET : AF_INET6;
-       src = af == AF_INET ? (const void *)&e->addr.u.ip4 :
+       grp = af == AF_INET ? (const void *)&e->addr.u.ip4 :
                              (const void *)&e->addr.u.ip6;
        dev = ll_index_to_name(ifindex);
 
@@ -140,8 +140,13 @@ static void print_mdb_entry(FILE *f, int ifindex, const struct br_mdb_entry *e,
 
        print_color_string(PRINT_ANY, ifa_family_color(af),
                            "grp", " grp %s",
-                           inet_ntop(af, src, abuf, sizeof(abuf)));
-
+                           inet_ntop(af, grp, abuf, sizeof(abuf)));
+       if (tb && tb[MDBA_MDB_EATTR_SOURCE]) {
+               src = (const void *)RTA_DATA(tb[MDBA_MDB_EATTR_SOURCE]);
+               print_color_string(PRINT_ANY, ifa_family_color(af),
+                                  "src", " src %s",
+                                  inet_ntop(af, src, abuf, sizeof(abuf)));
+       }
        print_string(PRINT_ANY, "state", " %s",
                           (e->state & MDB_PERMANENT) ? "permanent" : "temp");
 
@@ -378,8 +383,8 @@ static int mdb_modify(int cmd, int flags, int argc, char **argv)
                .n.nlmsg_type = cmd,
                .bpm.family = PF_BRIDGE,
        };
+       char *d = NULL, *p = NULL, *grp = NULL, *src = NULL;
        struct br_mdb_entry entry = {};
-       char *d = NULL, *p = NULL, *grp = NULL;
        short vid = 0;
 
        while (argc > 0) {
@@ -400,6 +405,9 @@ static int mdb_modify(int cmd, int flags, int argc, char **argv)
                } else if (strcmp(*argv, "vid") == 0) {
                        NEXT_ARG();
                        vid = atoi(*argv);
+               } else if (strcmp(*argv, "src") == 0) {
+                       NEXT_ARG();
+                       src = *argv;
                } else {
                        if (matches(*argv, "help") == 0)
                                usage();
@@ -431,6 +439,24 @@ static int mdb_modify(int cmd, int flags, int argc, char **argv)
 
        entry.vid = vid;
        addattr_l(&req.n, sizeof(req), MDBA_SET_ENTRY, &entry, sizeof(entry));
+       if (src) {
+               struct rtattr *nest = addattr_nest(&req.n, sizeof(req),
+                                                  MDBA_SET_ENTRY_ATTRS);
+               struct in6_addr src_ip6;
+               __be32 src_ip4;
+
+               nest->rta_type |= NLA_F_NESTED;
+               if (!inet_pton(AF_INET, src, &src_ip4)) {
+                       if (!inet_pton(AF_INET6, src, &src_ip6)) {
+                               fprintf(stderr, "Invalid source address \"%s\"\n", src);
+                               return -1;
+                       }
+                       addattr_l(&req.n, sizeof(req), MDBE_ATTR_SOURCE, &src_ip6, sizeof(src_ip6));
+               } else {
+                       addattr32(&req.n, sizeof(req), MDBE_ATTR_SOURCE, src_ip4);
+               }
+               addattr_nest_end(&req.n, nest);
+       }
 
        if (rtnl_talk(&rth, &req.n, NULL) < 0)
                return -1;
index b06005763bc2618d80374dc333dea23f2a9583e1..84b9b70c7dea46292d260a018fa7e728d9fd70dc 100644 (file)
@@ -116,6 +116,8 @@ bridge \- show / manipulate bridge addresses and devices
 .I PORT
 .B grp
 .IR GROUP " [ "
+.B src
+.IR SOURCE " ] [ "
 .BR permanent " | " temp " ] [ "
 .B vid
 .IR VID " ] "
@@ -694,6 +696,12 @@ the port.
 - the mdb entry is temporary (default)
 .sp
 
+.TP
+.BI src " SOURCE"
+optional source IP address of a sender for this multicast group. If IGMPv3 for IPv4, or
+MLDv2 for IPv6 respectively, are enabled it will be included in the lookup when
+forwarding multicast traffic.
+
 .TP
 .BI vid " VID"
 the VLAN ID which is known to have members of this multicast group.