From cba134ae70f097bf6df484acba3868f7d2d1cc39 Mon Sep 17 00:00:00 2001 From: Roman Mashak Date: Fri, 19 May 2017 13:05:43 -0400 Subject: [PATCH 1/6] tc: fix Makefile to build skbmod Signed-off-by: Roman Mashak --- tc/Makefile | 1 + 1 file changed, 1 insertion(+) diff --git a/tc/Makefile b/tc/Makefile index 9a6bb1dd..678b3029 100644 --- a/tc/Makefile +++ b/tc/Makefile @@ -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 From 98447086f875a21ceccae9be00a36908fe8321d6 Mon Sep 17 00:00:00 2001 From: Baruch Siach Date: Mon, 22 May 2017 16:27:53 +0300 Subject: [PATCH 2/6] ip: include libc headers first Including libc headers first helps as a workaround to redefinition of struct ethhdr with a suitably patched musl libc that suppresses the kernel if_ether.h. Signed-off-by: Baruch Siach --- ip/iplink_bridge.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ip/iplink_bridge.c b/ip/iplink_bridge.c index 818b43c8..cccdec1c 100644 --- a/ip/iplink_bridge.c +++ b/ip/iplink_bridge.c @@ -13,9 +13,9 @@ #include #include #include +#include #include #include -#include #include #include "rt_names.h" From 05a14fc1218885ba6236b409fbf6b89976b8636e Mon Sep 17 00:00:00 2001 From: David Ahern Date: Tue, 16 May 2017 14:22:46 -0700 Subject: [PATCH 3/6] netlink: Change rtnl_dump_done to always show error The original code which became rtnl_dump_done only shows netlink errors if the protocol is NETLINK_SOCK_DIAG, but netlink dumps always appends the length which contains any error encountered during the dump. Update rtnl_dump_done to always show the error if there is one. As an *example* without this patch, dumping a route object that exceeds the internal buffer size terminates with no message to the user -- the dump just ends because the NLMSG_DONE attribute was received. With this patch the user at least gets a message that the dump was aborted. $ ip ro ls default via 10.0.2.2 dev eth0 10.0.2.0/24 dev eth0 proto kernel scope link src 10.0.2.15 10.10.0.0/16 dev veth1 proto kernel scope link src 10.10.0.1 172.16.1.0/24 dev br0.11 proto kernel scope link src 172.16.1.1 Error: Buffer too small for object Dump terminated The point of this patch is to notify the user of a failure versus silently exiting on a partial dump. Because the NLMSG_DONE attribute was received, the entire dump needs to be restarted to use a larger buffer for EMSGSIZE errors. That could be done automatically but it has other user impacts (e.g., duplicate output if the dump is restarted) and should be the subject of a different patch. Signed-off-by: David Ahern --- lib/libnetlink.c | 34 ++++++++++++++++++++-------------- 1 file changed, 20 insertions(+), 14 deletions(-) diff --git a/lib/libnetlink.c b/lib/libnetlink.c index 5b75b2db..d4b831f6 100644 --- a/lib/libnetlink.c +++ b/lib/libnetlink.c @@ -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; } From d315b706e9d4a550096140aa298d46b2aa7733e9 Mon Sep 17 00:00:00 2001 From: Roi Dayan Date: Sun, 21 May 2017 08:37:27 +0300 Subject: [PATCH 4/6] devlink: Add option to set and show eswitch encapsulation support This is an e-switch global knob to enable HW support for applying encapsulation/decapsulation to VF traffic as part of SRIOV e-switch offloading. The actual encap/decap is carried out (along with the matching and other actions) per offloaded e-switch rules, e.g as done when offloading the TC tunnel key action. Possible values are enable/disable. Signed-off-by: Roi Dayan Reviewed-by: Jiri Pirko --- devlink/devlink.c | 48 +++++++++++++++++++++++++++++++++++++++++- man/man8/devlink-dev.8 | 13 ++++++++++++ 2 files changed, 60 insertions(+), 1 deletion(-) diff --git a/devlink/devlink.c b/devlink/devlink.c index e22ee0a0..f9bc16c3 100644 --- a/devlink/devlink.c +++ b/devlink/devlink.c @@ -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; diff --git a/man/man8/devlink-dev.8 b/man/man8/devlink-dev.8 index 6bfe66f8..b074d57a 100644 --- a/man/man8/devlink-dev.8 +++ b/man/man8/devlink-dev.8 @@ -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 From f6fc1055e41a8a924313c336b39b9ffe0c86938b Mon Sep 17 00:00:00 2001 From: Phil Sutter Date: Tue, 23 May 2017 15:40:57 +0200 Subject: [PATCH 5/6] tc: m_xt: Prevent a segfault in libipt This happens with NAT targets, such as SNAT, DNAT and MASQUERADE. These are still not usable with this patch, but at least tc doesn't crash anymore when one tries to use them. Signed-off-by: Phil Sutter --- tc/m_xt.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/tc/m_xt.c b/tc/m_xt.c index e59df8e1..ad52d239 100644 --- a/tc/m_xt.c +++ b/tc/m_xt.c @@ -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, From 759fa6086eea16e1397a29439361fb13e31ace17 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Remigiusz=20Ko=C5=82=C5=82=C4=85taj?= Date: Fri, 19 May 2017 14:54:49 +0200 Subject: [PATCH 6/6] ip: add handling for new CAN netlink interface MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This patch adds handling for new CAN netlink interface introduced in 4.11 kernel: - IFLA_CAN_TERMINATION, - IFLA_CAN_TERMINATION_CONST, - IFLA_CAN_BITRATE_CONST, - IFLA_CAN_DATA_BITRATE_CONST Output example: $ip -d link show can0 6: can0: mtu 16 qdisc noop state DOWN mode DEFAULT group default qlen 10 link/can promiscuity 0 can state STOPPED (berr-counter tx 0 rx 0) restart-ms 0 bitrate 80000 [ 20000, 33333, 50000, 80000, 83333, 100000, 125000, 150000, 175000, 200000, 225000, 250000, 275000, 300000, 500000, 625000, 800000, 1000000 ] termination 0 [ 0, 120 ] clock 0numtxqueues 1 numrxqueues 1 gso_max_size 65536 gso_max_segs 65535 Signed-off-by: Remigiusz Kołłątaj --- ip/iplink_can.c | 98 +++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 94 insertions(+), 4 deletions(-) diff --git a/ip/iplink_can.c b/ip/iplink_can.c index 20d4d37d..5df56b2b 100644 --- a/ip/iplink_can.c +++ b/ip/iplink_can.c @@ -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]);