]> git.proxmox.com Git - mirror_iproute2.git/commitdiff
Merge branch 'iproute2-master' into next
authorDavid Ahern <dsahern@gmail.com>
Wed, 17 Apr 2019 20:59:44 +0000 (13:59 -0700)
committerDavid Ahern <dsahern@gmail.com>
Wed, 17 Apr 2019 20:59:44 +0000 (13:59 -0700)
Signed-off-by: David Ahern <dsahern@gmail.com>
12 files changed:
.mailmap [new file with mode: 0644]
include/uapi/linux/if_tun.h
include/uapi/linux/tcp.h
include/uapi/linux/tipc_netlink.h
man/man8/rdma-link.8
man/man8/tipc-link.8
rdma/dev.c
rdma/link.c
rdma/rdma.h
rdma/res.h
rdma/utils.c
tipc/link.c

diff --git a/.mailmap b/.mailmap
new file mode 100644 (file)
index 0000000..c012d3d
--- /dev/null
+++ b/.mailmap
@@ -0,0 +1,8 @@
+#
+# This list is used by git-shortlog to fix a few botched name translations
+# in the git archive, either because the author's full name was messed up
+# and/or not always written the same way, making contributions from the
+# same person appearing not to be so or badly displayed.
+#
+Steve Wise <larrystevenwise@gmail.com> <swise@opengridcomputing.com>
+Steve Wise <larrystevenwise@gmail.com> <swise@chelsio.com>
index 2f01165514a779c7199f82aa3f5b4092bcc113b5..8489ae03744b1cdd013e82af292a3d469ef4299e 100644 (file)
@@ -60,6 +60,7 @@
 #define TUNSETSTEERINGEBPF _IOR('T', 224, int)
 #define TUNSETFILTEREBPF _IOR('T', 225, int)
 #define TUNSETCARRIER _IOW('T', 226, int)
+#define TUNGETDEVNETNS _IO('T', 227)
 
 /* TUNSETIFF ifr flags */
 #define IFF_TUN                0x0001
index 799b5c5fd49e32dafd40774a3e9328cd96e209d8..2d5627978aa2a0e1eb2643c60f3567f14503164d 100644 (file)
@@ -160,15 +160,42 @@ enum {
 #define TCPI_OPT_ECN_SEEN      16 /* we received at least one packet with ECT */
 #define TCPI_OPT_SYN_DATA      32 /* SYN-ACK acked data in SYN sent or rcvd */
 
+/*
+ * Sender's congestion state indicating normal or abnormal situations
+ * in the last round of packets sent. The state is driven by the ACK
+ * information and timer events.
+ */
 enum tcp_ca_state {
+       /*
+        * Nothing bad has been observed recently.
+        * No apparent reordering, packet loss, or ECN marks.
+        */
        TCP_CA_Open = 0,
 #define TCPF_CA_Open   (1<<TCP_CA_Open)
+       /*
+        * The sender enters disordered state when it has received DUPACKs or
+        * SACKs in the last round of packets sent. This could be due to packet
+        * loss or reordering but needs further information to confirm packets
+        * have been lost.
+        */
        TCP_CA_Disorder = 1,
 #define TCPF_CA_Disorder (1<<TCP_CA_Disorder)
+       /*
+        * The sender enters Congestion Window Reduction (CWR) state when it
+        * has received ACKs with ECN-ECE marks, or has experienced congestion
+        * or packet discard on the sender host (e.g. qdisc).
+        */
        TCP_CA_CWR = 2,
 #define TCPF_CA_CWR    (1<<TCP_CA_CWR)
+       /*
+        * The sender is in fast recovery and retransmitting lost packets,
+        * typically triggered by ACK events.
+        */
        TCP_CA_Recovery = 3,
 #define TCPF_CA_Recovery (1<<TCP_CA_Recovery)
+       /*
+        * The sender is in loss recovery triggered by retransmission timeout.
+        */
        TCP_CA_Loss = 4
 #define TCPF_CA_Loss   (1<<TCP_CA_Loss)
 };
index 0ebe02ef1a86b1eeceeac99c8354bd38516a26e2..efb958fd167d02c372ece2278bce41da9a58f847 100644 (file)
@@ -281,6 +281,8 @@ enum {
        TIPC_NLA_PROP_TOL,              /* u32 */
        TIPC_NLA_PROP_WIN,              /* u32 */
        TIPC_NLA_PROP_MTU,              /* u32 */
+       TIPC_NLA_PROP_BROADCAST,        /* u32 */
+       TIPC_NLA_PROP_BROADCAST_RATIO,  /* u32 */
 
        __TIPC_NLA_PROP_MAX,
        TIPC_NLA_PROP_MAX = __TIPC_NLA_PROP_MAX - 1
index bddf34746e8b2261022bbf9a602560987ec841d0..b3b40de75852b12d72375bc4ed5aef1601d0c3f1 100644 (file)
@@ -22,6 +22,18 @@ rdma-link \- rdma link configuration
 .B rdma link show
 .RI "[ " DEV/PORT_INDEX " ]"
 
+.ti -8
+.B rdma link add
+.BR NAME
+.BR type
+.BR TYPE
+.BR netdev
+.BR NETDEV
+
+.ti -8
+.B rdma link delete
+.RI NAME
+
 .ti -8
 .B rdma link help
 
@@ -33,6 +45,31 @@ rdma-link \- rdma link configuration
 - specifies the RDMA link to show.
 If this argument is omitted all links are listed.
 
+.SS rdma link add NAME type TYPE netdev NETDEV - add an rdma link for the specified type to the network device
+.sp
+.BR NAME
+- specifies the new name of the rdma link to add
+
+.BR TYPE
+- specifies which rdma type to use.  Link types:
+.sp
+.in +8
+.B rxe
+- Soft RoCE driver
+.sp
+.B siw
+- Soft iWARP driver
+.in -8
+
+.BR NETDEV
+- specifies the network device to which the link is bound
+
+.SS rdma link delete NAME - delete an rdma link
+.PP
+.BR NAME
+- specifies the name of the rdma link to delete
+.PP
+
 .SH "EXAMPLES"
 .PP
 rdma link show
@@ -45,6 +82,16 @@ rdma link show mlx5_2/1
 Shows the state of specified rdma link.
 .RE
 .PP
+rdma link add rxe_eth0 type rxe netdev eth0
+.RS 4
+Adds a RXE link named rxe_eth0 to network device eth0
+.RE
+.PP
+rdma link del rxe_eth0
+.RS 4
+Removes RXE link rxe_eth0
+.RE
+.PP
 
 .SH SEE ALSO
 .BR rdma (8),
index 01afa1c3ad9f48256e23da6fffe40ed20e23b21f..47dae25d3626eaa2c2c0620e4bbcb85c00185f89 100644 (file)
@@ -1,4 +1,4 @@
-.TH TIPC-LINK 8 "02 Jun 2015" "iproute2" "Linux"
+.TH TIPC-LINK 8 "22 Mar 2019" "iproute2" "Linux"
 
 .\" For consistency, please keep padding right aligned.
 .\" For example '.B "foo " bar' and not '.B foo " bar"'
@@ -14,18 +14,36 @@ tipc-link \- show links or modify link properties
 
 .ti -8
 .B tipc link set
-.RB "{ " "priority "
+.br
+.RB "[ " "{ " "priority "
 .IR PRIORITY
 .RB "| " tolerance
 .IR TOLERANCE
 .RB "| " window
 .IR "WINDOW " }
-.BI "link " LINK
+.BI "link " LINK " ]"
+.RB "|"
+.br
+.RB "[ "
+.RB "{ " broadcast " [ "
+.IR BROADCAST
+.RB " | "
+.IR REPLICAST
+.RB " | "
+.IR AUTOSELECT
+.RB "[ " ratio
+.IR SIZE
+.RB "] " ] " } " "]"
 
 .ti -8
 .B tipc link get
-.RB "{ " "priority" " | " tolerance " | " window " } " link
-.I LINK
+.br
+.RB "[ " "{ " "priority" " | " tolerance " | " window " } " link
+.IR LINK " ] "
+.RB "|"
+.br
+.RB "[ " { " broadcast " } " ]"
+.br
 
 .ti -8
 .B tipc link statistics
@@ -306,6 +324,31 @@ They are usually transient and occur during the cluster startup phase
 or network reconfiguration.
 Possible status are: U or D. The status U implies up and D down.
 
+.SS Broadcast properties
+.TP
+.B  BROADCAST
+.br
+Forces all multicast traffic to be transmitted via broadcast only,
+irrespective of cluster size and number of destinations.
+
+.TP
+.B REPLICAST
+.br
+Forces all multicast traffic to be transmitted via replicast only,
+irrespective of cluster size and number of destinations.
+
+.TP
+.B AUTOSELECT
+.br
+Auto switching to broadcast or replicast depending on cluster size and
+destination node number.
+
+.TP
+.B ratio SIZE
+.br
+Set the AUTOSELECT criteria, percentage of destination nodes vs cluster
+size.
+
 .SH EXAMPLES
 .PP
 tipc link monitor list
index 954e00153e3db8d5a451fd1019ff2145281638f0..3396252022002c41e0082bb417747d55d34f5afa 100644 (file)
@@ -268,7 +268,7 @@ static int dev_set_name(struct rd *rd)
        mnl_attr_put_u32(rd->nlh, RDMA_NLDEV_ATTR_DEV_INDEX, rd->dev_idx);
        mnl_attr_put_strz(rd->nlh, RDMA_NLDEV_ATTR_DEV_NAME, rd_argv(rd));
 
-       return rd_send_msg(rd);
+       return rd_sendrecv_msg(rd, seq);
 }
 
 static int dev_one_set(struct rd *rd)
index 89e81b84b2ccae8c0401c4ae2e972e57f7022c73..10b2e513e98af29ecbe375103795e95d32431c5a 100644 (file)
@@ -9,6 +9,9 @@
 static int link_help(struct rd *rd)
 {
        pr_out("Usage: %s link show [DEV/PORT_INDEX]\n", rd->filename);
+       pr_out("Usage: %s link add NAME type TYPE netdev NETDEV\n",
+              rd->filename);
+       pr_out("Usage: %s link delete NAME\n", rd->filename);
        return 0;
 }
 
@@ -336,10 +339,85 @@ static int link_show(struct rd *rd)
        return rd_exec_link(rd, link_one_show, true);
 }
 
+static int link_add_netdev(struct rd *rd)
+{
+       char *link_netdev;
+       uint32_t seq;
+
+       if (rd_no_arg(rd)) {
+               pr_err("Please provide a net device name.\n");
+               return -EINVAL;
+       }
+
+       link_netdev = rd_argv(rd);
+       rd_prepare_msg(rd, RDMA_NLDEV_CMD_NEWLINK, &seq,
+                      (NLM_F_REQUEST | NLM_F_ACK));
+       mnl_attr_put_strz(rd->nlh, RDMA_NLDEV_ATTR_DEV_NAME, rd->link_name);
+       mnl_attr_put_strz(rd->nlh, RDMA_NLDEV_ATTR_LINK_TYPE, rd->link_type);
+       mnl_attr_put_strz(rd->nlh, RDMA_NLDEV_ATTR_NDEV_NAME, link_netdev);
+       return rd_sendrecv_msg(rd, seq);
+}
+
+static int link_add_type(struct rd *rd)
+{
+       const struct rd_cmd cmds[] = {
+               { NULL,         link_help},
+               { "netdev",     link_add_netdev},
+               { 0 }
+       };
+
+       if (rd_no_arg(rd)) {
+               pr_err("Please provide a link type name.\n");
+               return -EINVAL;
+       }
+       rd->link_type = rd_argv(rd);
+       rd_arg_inc(rd);
+       return rd_exec_cmd(rd, cmds, "parameter");
+}
+
+static int link_add(struct rd *rd)
+{
+       const struct rd_cmd cmds[] = {
+               { NULL,         link_help},
+               { "type",       link_add_type},
+               { 0 }
+       };
+
+       if (rd_no_arg(rd)) {
+               pr_err("Please provide a link name to add.\n");
+               return -EINVAL;
+       }
+       rd->link_name = rd_argv(rd);
+       rd_arg_inc(rd);
+
+       return rd_exec_cmd(rd, cmds, "parameter");
+}
+
+static int _link_del(struct rd *rd)
+{
+       uint32_t seq;
+
+       if (!rd_no_arg(rd)) {
+               pr_err("Unknown parameter %s\n", rd_argv(rd));
+               return -EINVAL;
+       }
+       rd_prepare_msg(rd, RDMA_NLDEV_CMD_DELLINK, &seq,
+                      (NLM_F_REQUEST | NLM_F_ACK));
+       mnl_attr_put_u32(rd->nlh, RDMA_NLDEV_ATTR_DEV_INDEX, rd->dev_idx);
+       return rd_sendrecv_msg(rd, seq);
+}
+
+static int link_del(struct rd *rd)
+{
+       return rd_exec_require_dev(rd, _link_del);
+}
+
 int cmd_link(struct rd *rd)
 {
        const struct rd_cmd cmds[] = {
                { NULL,         link_show },
+               { "add",        link_add },
+               { "delete",     link_del },
                { "show",       link_show },
                { "list",       link_show },
                { "help",       link_help },
index 1022e9a29291d49896ebf9d103e9c0345792e23b..9ed9e045044583442141a8e7242c1028b83323ae 100644 (file)
@@ -68,7 +68,10 @@ struct rd {
        json_writer_t *jw;
        bool json_output;
        bool pretty_output;
+       bool suppress_errors;
        struct list_head filter_list;
+       char *link_name;
+       char *link_type;
 };
 
 struct rd_cmd {
@@ -119,6 +122,7 @@ bool rd_is_string_filtered_attr(struct rd *rd, const char *key, const char *val,
  */
 int rd_send_msg(struct rd *rd);
 int rd_recv_msg(struct rd *rd, mnl_cb_t callback, void *data, uint32_t seq);
+int rd_sendrecv_msg(struct rd *rd, unsigned int seq);
 void rd_prepare_msg(struct rd *rd, uint32_t cmd, uint32_t *seq, uint16_t flags);
 int rd_dev_init_cb(const struct nlmsghdr *nlh, void *data);
 int rd_attr_cb(const struct nlattr *attr, void *data);
index b4a7e552bfb799eb9697fb2d631742a4640a758b..525171fcec511cd3da1b83aad33806a8e6273cdd 100644 (file)
@@ -31,6 +31,7 @@ int res_qp_idx_parse_cb(const struct nlmsghdr *nlh, void *data);
                if (id) {                                                              \
                        ret = rd_doit_index(rd, &idx);                                 \
                        if (ret) {                                                     \
+                               rd->suppress_errors = true;                            \
                                ret = _res_send_idx_msg(rd, command,                   \
                                                        name##_idx_parse_cb,           \
                                                        idx, id);                      \
index 1f6bf330bdbb553947c94752ea88ac49f30cb0ee..11ed8a73b2d3e4ea62a20927464bd1af8e45f920 100644 (file)
@@ -693,10 +693,28 @@ int rd_recv_msg(struct rd *rd, mnl_cb_t callback, void *data, unsigned int seq)
                ret = mnl_cb_run(buf, ret, seq, portid, callback, data);
        } while (ret > 0);
 
+       if (ret < 0 && !rd->suppress_errors)
+               perror("error");
+
        mnl_socket_close(rd->nl);
        return ret;
 }
 
+static int null_cb(const struct nlmsghdr *nlh, void *data)
+{
+       return MNL_CB_OK;
+}
+
+int rd_sendrecv_msg(struct rd *rd, unsigned int seq)
+{
+       int ret;
+
+       ret = rd_send_msg(rd);
+       if (!ret)
+               ret = rd_recv_msg(rd, null_cb, rd, seq);
+       return ret;
+}
+
 static struct dev_map *_dev_map_lookup(struct rd *rd, const char *dev_name)
 {
        struct dev_map *dev_map;
index 43e26da3fa6b5a6dacf30106eedfe7d63bb27476..e123c18635756917943dc6f48a97d592db7b4785 100644 (file)
@@ -28,6 +28,9 @@
 #define PRIORITY_STR "priority"
 #define TOLERANCE_STR "tolerance"
 #define WINDOW_STR "window"
+#define BROADCAST_STR "broadcast"
+
+static const char tipc_bclink_name[] = "broadcast-link";
 
 static int link_list_cb(const struct nlmsghdr *nlh, void *data)
 {
@@ -172,10 +175,92 @@ static void cmd_link_get_help(struct cmdl *cmdl)
                "PROPERTIES\n"
                " tolerance             - Get link tolerance\n"
                " priority              - Get link priority\n"
-               " window                - Get link window\n",
+               " window                - Get link window\n"
+               " broadcast             - Get link broadcast\n",
+               cmdl->argv[0]);
+}
+
+static int cmd_link_get_bcast_cb(const struct nlmsghdr *nlh, void *data)
+{
+       int *prop = data;
+       int prop_ratio = TIPC_NLA_PROP_BROADCAST_RATIO;
+       struct genlmsghdr *genl = mnl_nlmsg_get_payload(nlh);
+       struct nlattr *info[TIPC_NLA_MAX + 1] = {};
+       struct nlattr *attrs[TIPC_NLA_LINK_MAX + 1] = {};
+       struct nlattr *props[TIPC_NLA_PROP_MAX + 1] = {};
+       int bc_mode;
+
+       mnl_attr_parse(nlh, sizeof(*genl), parse_attrs, info);
+       if (!info[TIPC_NLA_LINK])
+               return MNL_CB_ERROR;
+
+       mnl_attr_parse_nested(info[TIPC_NLA_LINK], parse_attrs, attrs);
+       if (!attrs[TIPC_NLA_LINK_PROP])
+               return MNL_CB_ERROR;
+
+       mnl_attr_parse_nested(attrs[TIPC_NLA_LINK_PROP], parse_attrs, props);
+       if (!props[*prop])
+               return MNL_CB_ERROR;
+
+       bc_mode = mnl_attr_get_u32(props[*prop]);
+
+       new_json_obj(json);
+       open_json_object(NULL);
+       switch (bc_mode) {
+       case 0x1:
+               print_string(PRINT_ANY, "method", "%s\n", "BROADCAST");
+               break;
+       case 0x2:
+               print_string(PRINT_ANY, "method", "%s\n", "REPLICAST");
+               break;
+       case 0x4:
+               print_string(PRINT_ANY, "method", "%s", "AUTOSELECT");
+               close_json_object();
+               open_json_object(NULL);
+               print_uint(PRINT_ANY, "ratio", " ratio:%u%\n",
+                          mnl_attr_get_u32(props[prop_ratio]));
+               break;
+       default:
+               print_string(PRINT_ANY, NULL, "UNKNOWN\n", NULL);
+               break;
+       }
+       close_json_object();
+       delete_json_obj();
+       return MNL_CB_OK;
+}
+
+static void cmd_link_get_bcast_help(struct cmdl *cmdl)
+{
+       fprintf(stderr, "Usage: %s link get PPROPERTY\n\n"
+               "PROPERTIES\n"
+               " broadcast             - Get link broadcast\n",
                cmdl->argv[0]);
 }
 
+static int cmd_link_get_bcast(struct nlmsghdr *nlh, const struct cmd *cmd,
+                            struct cmdl *cmdl, void *data)
+{
+       int prop = TIPC_NLA_PROP_BROADCAST;
+       char buf[MNL_SOCKET_BUFFER_SIZE];
+       struct nlattr *attrs;
+
+       if (help_flag) {
+               (cmd->help)(cmdl);
+               return -EINVAL;
+       }
+
+       nlh = msg_init(buf, TIPC_NL_LINK_GET);
+       if (!nlh) {
+               fprintf(stderr, "error, message initialisation failed\n");
+               return -1;
+       }
+       attrs = mnl_attr_nest_start(nlh, TIPC_NLA_LINK);
+       /* Direct to broadcast-link setting */
+       mnl_attr_put_strz(nlh, TIPC_NLA_LINK_NAME, tipc_bclink_name);
+       mnl_attr_nest_end(nlh, attrs);
+       return msg_doit(nlh, cmd_link_get_bcast_cb, &prop);
+}
+
 static int cmd_link_get(struct nlmsghdr *nlh, const struct cmd *cmd,
                        struct cmdl *cmdl, void *data)
 {
@@ -183,6 +268,7 @@ static int cmd_link_get(struct nlmsghdr *nlh, const struct cmd *cmd,
                { PRIORITY_STR, cmd_link_get_prop,      cmd_link_get_help },
                { TOLERANCE_STR,        cmd_link_get_prop,      cmd_link_get_help },
                { WINDOW_STR,   cmd_link_get_prop,      cmd_link_get_help },
+               { BROADCAST_STR, cmd_link_get_bcast, cmd_link_get_bcast_help },
                { NULL }
        };
 
@@ -521,7 +607,8 @@ static void cmd_link_set_help(struct cmdl *cmdl)
                "PROPERTIES\n"
                " tolerance TOLERANCE   - Set link tolerance\n"
                " priority PRIORITY     - Set link priority\n"
-               " window WINDOW         - Set link window\n",
+               " window WINDOW         - Set link window\n"
+               " broadcast BROADCAST   - Set link broadcast\n",
                cmdl->argv[0]);
 }
 
@@ -585,6 +672,95 @@ static int cmd_link_set_prop(struct nlmsghdr *nlh, const struct cmd *cmd,
        return msg_doit(nlh, link_get_cb, &prop);
 }
 
+static void cmd_link_set_bcast_help(struct cmdl *cmdl)
+{
+       fprintf(stderr, "Usage: %s link set broadcast PROPERTY\n\n"
+               "PROPERTIES\n"
+               " BROADCAST         - Forces all multicast traffic to be\n"
+               "                     transmitted via broadcast only,\n"
+               "                     irrespective of cluster size and number\n"
+               "                     of destinations\n\n"
+               " REPLICAST         - Forces all multicast traffic to be\n"
+               "                     transmitted via replicast only,\n"
+               "                     irrespective of cluster size and number\n"
+               "                     of destinations\n\n"
+               " AUTOSELECT        - Auto switching to broadcast or replicast\n"
+               "                     depending on cluster size and destination\n"
+               "                     node number\n\n"
+               " ratio SIZE        - Set the AUTOSELECT criteria, percentage of\n"
+               "                     destination nodes vs cluster size\n\n",
+               cmdl->argv[0]);
+}
+
+static int cmd_link_set_bcast(struct nlmsghdr *nlh, const struct cmd *cmd,
+                            struct cmdl *cmdl, void *data)
+{
+       char buf[MNL_SOCKET_BUFFER_SIZE];
+       struct nlattr *props;
+       struct nlattr *attrs;
+       struct opt *opt;
+       struct opt opts[] = {
+               { "BROADCAST",  OPT_KEY, NULL },
+               { "REPLICAST",  OPT_KEY, NULL },
+               { "AUTOSELECT", OPT_KEY, NULL },
+               { "ratio",      OPT_KEYVAL,     NULL },
+               { NULL }
+       };
+       int method = 0;
+
+       if (help_flag) {
+               (cmd->help)(cmdl);
+               return -EINVAL;
+       }
+
+       if (parse_opts(opts, cmdl) < 0)
+               return -EINVAL;
+
+       for (opt = opts; opt->key; opt++)
+               if (opt->val)
+                       break;
+
+       if (!opt || !opt->key) {
+               (cmd->help)(cmdl);
+               return -EINVAL;
+       }
+
+       nlh = msg_init(buf, TIPC_NL_LINK_SET);
+       if (!nlh) {
+               fprintf(stderr, "error, message initialisation failed\n");
+               return -1;
+       }
+
+       attrs = mnl_attr_nest_start(nlh, TIPC_NLA_LINK);
+       /* Direct to broadcast-link setting */
+       mnl_attr_put_strz(nlh, TIPC_NLA_LINK_NAME, tipc_bclink_name);
+       props = mnl_attr_nest_start(nlh, TIPC_NLA_LINK_PROP);
+
+       if (get_opt(opts, "BROADCAST"))
+               method = 0x1;
+       else if (get_opt(opts, "REPLICAST"))
+               method = 0x2;
+       else if (get_opt(opts, "AUTOSELECT"))
+               method = 0x4;
+
+       opt = get_opt(opts, "ratio");
+       if (!method && !opt) {
+               (cmd->help)(cmdl);
+               return -EINVAL;
+       }
+
+       if (method)
+               mnl_attr_put_u32(nlh, TIPC_NLA_PROP_BROADCAST, method);
+
+       if (opt)
+               mnl_attr_put_u32(nlh, TIPC_NLA_PROP_BROADCAST_RATIO,
+                                atoi(opt->val));
+
+       mnl_attr_nest_end(nlh, props);
+       mnl_attr_nest_end(nlh, attrs);
+       return msg_doit(nlh, NULL, NULL);
+}
+
 static int cmd_link_set(struct nlmsghdr *nlh, const struct cmd *cmd,
                        struct cmdl *cmdl, void *data)
 {
@@ -592,6 +768,7 @@ static int cmd_link_set(struct nlmsghdr *nlh, const struct cmd *cmd,
                { PRIORITY_STR, cmd_link_set_prop,      cmd_link_set_help },
                { TOLERANCE_STR,        cmd_link_set_prop,      cmd_link_set_help },
                { WINDOW_STR,   cmd_link_set_prop,      cmd_link_set_help },
+               { BROADCAST_STR, cmd_link_set_bcast, cmd_link_set_bcast_help },
                { NULL }
        };