Merge branch 'master' into net-next

This commit is contained in:
Stephen Hemminger 2017-05-30 17:40:57 -07:00
commit 2ecb169280
7 changed files with 180 additions and 21 deletions

View File

@ -176,6 +176,7 @@ static void ifname_map_free(struct ifname_map *ifname_map)
#define DL_OPT_ESWITCH_INLINE_MODE BIT(12)
#define DL_OPT_DPIPE_TABLE_NAME BIT(13)
#define DL_OPT_DPIPE_TABLE_COUNTERS BIT(14)
#define DL_OPT_ESWITCH_ENCAP_MODE BIT(15)
struct dl_opts {
uint32_t present; /* flags of present items */
@ -195,6 +196,7 @@ struct dl_opts {
enum devlink_eswitch_inline_mode eswitch_inline_mode;
const char *dpipe_table_name;
bool dpipe_counters_enable;
bool eswitch_encap_mode;
};
struct dl {
@ -299,6 +301,7 @@ static const enum mnl_attr_data_type devlink_policy[DEVLINK_ATTR_MAX + 1] = {
[DEVLINK_ATTR_SB_OCC_MAX] = MNL_TYPE_U32,
[DEVLINK_ATTR_ESWITCH_MODE] = MNL_TYPE_U16,
[DEVLINK_ATTR_ESWITCH_INLINE_MODE] = MNL_TYPE_U8,
[DEVLINK_ATTR_ESWITCH_ENCAP_MODE] = MNL_TYPE_U8,
[DEVLINK_ATTR_DPIPE_TABLES] = MNL_TYPE_NESTED,
[DEVLINK_ATTR_DPIPE_TABLE] = MNL_TYPE_NESTED,
[DEVLINK_ATTR_DPIPE_TABLE_NAME] = MNL_TYPE_STRING,
@ -754,6 +757,19 @@ static int dpipe_counters_enable_get(const char *typestr,
return 0;
}
static int eswitch_encap_mode_get(const char *typestr, bool *p_mode)
{
if (strcmp(typestr, "enable") == 0) {
*p_mode = true;
} else if (strcmp(typestr, "disable") == 0) {
*p_mode = false;
} else {
pr_err("Unknown eswitch encap mode \"%s\"\n", typestr);
return -EINVAL;
}
return 0;
}
static int dl_argv_parse(struct dl *dl, uint32_t o_required,
uint32_t o_optional)
{
@ -908,7 +924,19 @@ static int dl_argv_parse(struct dl *dl, uint32_t o_required,
if (err)
return err;
o_found |= DL_OPT_DPIPE_TABLE_COUNTERS;
} else if (dl_argv_match(dl, "encap") &&
(o_all & DL_OPT_ESWITCH_ENCAP_MODE)) {
const char *typestr;
dl_arg_inc(dl);
err = dl_argv_str(dl, &typestr);
if (err)
return err;
err = eswitch_encap_mode_get(typestr,
&opts->eswitch_encap_mode);
if (err)
return err;
o_found |= DL_OPT_ESWITCH_ENCAP_MODE;
} else {
pr_err("Unknown option \"%s\"\n", dl_argv(dl));
return -EINVAL;
@ -986,6 +1014,13 @@ static int dl_argv_parse(struct dl *dl, uint32_t o_required,
pr_err("Dpipe table counter state expected\n");
return -EINVAL;
}
if ((o_required & DL_OPT_ESWITCH_ENCAP_MODE) &&
!(o_found & DL_OPT_ESWITCH_ENCAP_MODE)) {
pr_err("E-Switch encapsulation option expected.\n");
return -EINVAL;
}
return 0;
}
@ -1041,6 +1076,9 @@ static void dl_opts_put(struct nlmsghdr *nlh, struct dl *dl)
if (opts->present & DL_OPT_DPIPE_TABLE_COUNTERS)
mnl_attr_put_u8(nlh, DEVLINK_ATTR_DPIPE_TABLE_COUNTERS_ENABLED,
opts->dpipe_counters_enable);
if (opts->present & DL_OPT_ESWITCH_ENCAP_MODE)
mnl_attr_put_u8(nlh, DEVLINK_ATTR_ESWITCH_ENCAP_MODE,
opts->eswitch_encap_mode);
}
static int dl_argv_parse_put(struct nlmsghdr *nlh, struct dl *dl,
@ -1097,6 +1135,7 @@ static void cmd_dev_help(void)
pr_err("Usage: devlink dev show [ DEV ]\n");
pr_err(" devlink dev eswitch set DEV [ mode { legacy | switchdev } ]\n");
pr_err(" [ inline-mode { none | link | network | transport } ]\n");
pr_err(" [ encap { disable | enable } ]\n");
pr_err(" devlink dev eswitch show DEV\n");
}
@ -1421,6 +1460,12 @@ static void pr_out_eswitch(struct dl *dl, struct nlattr **tb)
eswitch_inline_mode_name(mnl_attr_get_u8(
tb[DEVLINK_ATTR_ESWITCH_INLINE_MODE])));
if (tb[DEVLINK_ATTR_ESWITCH_ENCAP_MODE]) {
bool encap_mode = !!mnl_attr_get_u8(tb[DEVLINK_ATTR_ESWITCH_ENCAP_MODE]);
pr_out_str(dl, "encap", encap_mode ? "enable" : "disable");
}
pr_out_handle_end(dl);
}
@ -1465,7 +1510,8 @@ static int cmd_dev_eswitch_set(struct dl *dl)
err = dl_argv_parse_put(nlh, dl, DL_OPT_HANDLE,
DL_OPT_ESWITCH_MODE |
DL_OPT_ESWITCH_INLINE_MODE);
DL_OPT_ESWITCH_INLINE_MODE |
DL_OPT_ESWITCH_ENCAP_MODE);
if (err)
return err;

View File

@ -13,9 +13,9 @@
#include <stdlib.h>
#include <string.h>
#include <netinet/in.h>
#include <netinet/ether.h>
#include <linux/if_link.h>
#include <linux/if_bridge.h>
#include <netinet/ether.h>
#include <net/if.h>
#include "rt_names.h"

View File

@ -41,6 +41,8 @@ static void print_usage(FILE *f)
"\t[ restart-ms TIME-MS ]\n"
"\t[ restart ]\n"
"\n"
"\t[ termination { 0..65535 } ]\n"
"\n"
"\tWhere: BITRATE := { 1..1000000 }\n"
"\t SAMPLE-POINT := { 0.000..0.999 }\n"
"\t TQ := { NUMBER }\n"
@ -220,6 +222,14 @@ static int can_parse_opt(struct link_util *lu, int argc, char **argv,
if (get_u32(&val, *argv, 0))
invarg("invalid \"restart-ms\" value\n", *argv);
addattr32(n, 1024, IFLA_CAN_RESTART_MS, val);
} else if (matches(*argv, "termination") == 0) {
__u16 val;
NEXT_ARG();
if (get_u16(&val, *argv, 0))
invarg("invalid \"termination\" value\n",
*argv);
addattr16(n, 1024, IFLA_CAN_TERMINATION, val);
} else if (matches(*argv, "help") == 0) {
usage();
return -1;
@ -282,7 +292,8 @@ static void can_print_opt(struct link_util *lu, FILE *f, struct rtattr *tb[])
fprintf(f, "restart-ms %d ", *restart_ms);
}
if (tb[IFLA_CAN_BITTIMING]) {
/* bittiming is irrelevant if fixed bitrate is defined */
if (tb[IFLA_CAN_BITTIMING] && !tb[IFLA_CAN_BITRATE_CONST]) {
struct can_bittiming *bt = RTA_DATA(tb[IFLA_CAN_BITTIMING]);
fprintf(f, "\n bitrate %d sample-point %.3f ",
@ -292,7 +303,8 @@ static void can_print_opt(struct link_util *lu, FILE *f, struct rtattr *tb[])
bt->sjw);
}
if (tb[IFLA_CAN_BITTIMING_CONST]) {
/* bittiming const is irrelevant if fixed bitrate is defined */
if (tb[IFLA_CAN_BITTIMING_CONST] && !tb[IFLA_CAN_BITRATE_CONST]) {
struct can_bittiming_const *btc =
RTA_DATA(tb[IFLA_CAN_BITTIMING_CONST]);
@ -303,7 +315,37 @@ static void can_print_opt(struct link_util *lu, FILE *f, struct rtattr *tb[])
btc->brp_min, btc->brp_max, btc->brp_inc);
}
if (tb[IFLA_CAN_DATA_BITTIMING]) {
if (tb[IFLA_CAN_BITRATE_CONST]) {
__u32 *bitrate_const = RTA_DATA(tb[IFLA_CAN_BITRATE_CONST]);
int bitrate_cnt = RTA_PAYLOAD(tb[IFLA_CAN_BITRATE_CONST]) /
sizeof(*bitrate_const);
int i;
__u32 bitrate = 0;
if (tb[IFLA_CAN_BITTIMING]) {
struct can_bittiming *bt =
RTA_DATA(tb[IFLA_CAN_BITTIMING]);
bitrate = bt->bitrate;
}
fprintf(f, "\n bitrate %u", bitrate);
fprintf(f, "\n [");
for (i = 0; i < bitrate_cnt - 1; ++i) {
/* This will keep lines below 80 signs */
if (!(i % 6) && i)
fprintf(f, "\n ");
fprintf(f, "%8u, ", bitrate_const[i]);
}
if (!(i % 6) && i)
fprintf(f, "\n ");
fprintf(f, "%8u ]", bitrate_const[i]);
}
/* data bittiming is irrelevant if fixed bitrate is defined */
if (tb[IFLA_CAN_DATA_BITTIMING] && !tb[IFLA_CAN_DATA_BITRATE_CONST]) {
struct can_bittiming *dbt =
RTA_DATA(tb[IFLA_CAN_DATA_BITTIMING]);
@ -315,7 +357,9 @@ static void can_print_opt(struct link_util *lu, FILE *f, struct rtattr *tb[])
dbt->phase_seg2, dbt->sjw);
}
if (tb[IFLA_CAN_DATA_BITTIMING_CONST]) {
/* data bittiming const is irrelevant if fixed bitrate is defined */
if (tb[IFLA_CAN_DATA_BITTIMING_CONST] &&
!tb[IFLA_CAN_DATA_BITRATE_CONST]) {
struct can_bittiming_const *dbtc =
RTA_DATA(tb[IFLA_CAN_DATA_BITTIMING_CONST]);
@ -326,6 +370,52 @@ static void can_print_opt(struct link_util *lu, FILE *f, struct rtattr *tb[])
dbtc->brp_min, dbtc->brp_max, dbtc->brp_inc);
}
if (tb[IFLA_CAN_DATA_BITRATE_CONST]) {
__u32 *dbitrate_const =
RTA_DATA(tb[IFLA_CAN_DATA_BITRATE_CONST]);
int dbitrate_cnt =
RTA_PAYLOAD(tb[IFLA_CAN_DATA_BITRATE_CONST]) /
sizeof(*dbitrate_const);
int i;
__u32 dbitrate = 0;
if (tb[IFLA_CAN_DATA_BITTIMING]) {
struct can_bittiming *dbt =
RTA_DATA(tb[IFLA_CAN_DATA_BITTIMING]);
dbitrate = dbt->bitrate;
}
fprintf(f, "\n dbitrate %u", dbitrate);
fprintf(f, "\n [");
for (i = 0; i < dbitrate_cnt - 1; ++i) {
/* This will keep lines below 80 signs */
if (!(i % 6) && i)
fprintf(f, "\n ");
fprintf(f, "%8u, ", dbitrate_const[i]);
}
if (!(i % 6) && i)
fprintf(f, "\n ");
fprintf(f, "%8u ]", dbitrate_const[i]);
}
if (tb[IFLA_CAN_TERMINATION_CONST] && tb[IFLA_CAN_TERMINATION]) {
__u16 *trm = RTA_DATA(tb[IFLA_CAN_TERMINATION]);
__u16 *trm_const = RTA_DATA(tb[IFLA_CAN_TERMINATION_CONST]);
int trm_cnt = RTA_PAYLOAD(tb[IFLA_CAN_TERMINATION_CONST]) /
sizeof(*trm_const);
int i;
fprintf(f, "\n termination %hu [ ", *trm);
for (i = 0; i < trm_cnt - 1; ++i)
fprintf(f, "%hu, ", trm_const[i]);
fprintf(f, "%hu ]", trm_const[i]);
}
if (tb[IFLA_CAN_CLOCK]) {
struct can_clock *clock = RTA_DATA(tb[IFLA_CAN_CLOCK]);

View File

@ -266,21 +266,27 @@ static int rtnl_dump_done(const struct rtnl_handle *rth,
{
int len = *(int *)NLMSG_DATA(h);
if (rth->proto == NETLINK_SOCK_DIAG) {
if (h->nlmsg_len < NLMSG_LENGTH(sizeof(int))) {
fprintf(stderr, "DONE truncated\n");
return -1;
}
if (len < 0) {
errno = -len;
if (errno == ENOENT || errno == EOPNOTSUPP)
return -1;
perror("RTNETLINK answers");
return len;
}
if (h->nlmsg_len < NLMSG_LENGTH(sizeof(int))) {
fprintf(stderr, "DONE truncated\n");
return -1;
}
if (len < 0) {
errno = -len;
switch (errno) {
case ENOENT:
case EOPNOTSUPP:
return -1;
case EMSGSIZE:
fprintf(stderr,
"Error: Buffer too small for object.\n");
break;
default:
perror("RTNETLINK answers");
}
return len;
}
return 0;
}

View File

@ -34,6 +34,9 @@ devlink-dev \- devlink device configuration
.RI "[ "
.BR inline-mode " { " none " | " link " | " network " | " transport " } "
.RI "]"
.RI "[ "
.BR encap " { " disable " | " enable " } "
.RI "]"
.ti -8
.BR "devlink dev eswitch show"
@ -81,6 +84,16 @@ Some HWs need the VF driver to put part of the packet headers on the TX descript
.I transport
- L4 mode
.TP
.BR encap " { " disable " | " enable " } "
Set eswitch encapsulation support
.I disable
- Disable encapsulation support
.I enable
- Enable encapsulation support
.SH "EXAMPLES"
.PP
devlink dev show

View File

@ -45,6 +45,7 @@ TCMODULES += m_nat.o
TCMODULES += m_pedit.o
TCMODULES += m_ife.o
TCMODULES += m_skbedit.o
TCMODULES += m_skbmod.o
TCMODULES += m_csum.o
TCMODULES += m_simple.o
TCMODULES += m_vlan.o

View File

@ -146,6 +146,9 @@ static int parse_ipt(struct action_util *a, int *argc_p,
char ***argv_p, int tca_id, struct nlmsghdr *n)
{
struct xtables_target *m = NULL;
#if XTABLES_VERSION_CODE >= 6
struct ipt_entry fw = {};
#endif
struct rtattr *tail;
int c;
@ -206,7 +209,7 @@ static int parse_ipt(struct action_util *a, int *argc_p,
default:
#if XTABLES_VERSION_CODE >= 6
if (m != NULL && m->x6_parse != NULL) {
xtables_option_tpcall(c, argv, 0, m, NULL);
xtables_option_tpcall(c, argv, 0, m, &fw);
#else
if (m != NULL && m->parse != NULL) {
m->parse(c - m->option_offset, argv, 0,