diff --git a/SOURCES/0015-ethtool-copy.h-sync-with-net-next.patch b/SOURCES/0015-ethtool-copy.h-sync-with-net-next.patch new file mode 100644 index 0000000..b8f0db5 --- /dev/null +++ b/SOURCES/0015-ethtool-copy.h-sync-with-net-next.patch @@ -0,0 +1,115 @@ +From ac4c40ab13bbd42145331766f74c3928bc9e6d51 Mon Sep 17 00:00:00 2001 +From: Edward Cree +Date: Fri, 9 Mar 2018 15:03:46 +0000 +Subject: [PATCH 15/18] ethtool-copy.h: sync with net-next + +This covers kernel changes up to commit 84a1d9c48200, + net: ethtool: extend RXNFC API to support RSS spreading of filter matches + +Signed-off-by: Edward Cree +Signed-off-by: John W. Linville +(cherry picked from commit 23b2e3b14405221b564c5dd6d7bf48c48e3db2c8) +--- + ethtool-copy.h | 32 ++++++++++++++++++++++++++------ + 1 file changed, 26 insertions(+), 6 deletions(-) + +diff --git a/ethtool-copy.h b/ethtool-copy.h +index f4e7bb2..8cc61e9 100644 +--- a/ethtool-copy.h ++++ b/ethtool-copy.h +@@ -912,12 +912,15 @@ static __inline__ __u64 ethtool_get_flow_spec_ring_vf(__u64 ring_cookie) + * @flow_type: Type of flow to be affected, e.g. %TCP_V4_FLOW + * @data: Command-dependent value + * @fs: Flow classification rule ++ * @rss_context: RSS context to be affected + * @rule_cnt: Number of rules to be affected + * @rule_locs: Array of used rule locations + * + * For %ETHTOOL_GRXFH and %ETHTOOL_SRXFH, @data is a bitmask indicating + * the fields included in the flow hash, e.g. %RXH_IP_SRC. The following +- * structure fields must not be used. ++ * structure fields must not be used, except that if @flow_type includes ++ * the %FLOW_RSS flag, then @rss_context determines which RSS context to ++ * act on. + * + * For %ETHTOOL_GRXRINGS, @data is set to the number of RX rings/queues + * on return. +@@ -929,7 +932,9 @@ static __inline__ __u64 ethtool_get_flow_spec_ring_vf(__u64 ring_cookie) + * set in @data then special location values should not be used. + * + * For %ETHTOOL_GRXCLSRULE, @fs.@location specifies the location of an +- * existing rule on entry and @fs contains the rule on return. ++ * existing rule on entry and @fs contains the rule on return; if ++ * @fs.@flow_type includes the %FLOW_RSS flag, then @rss_context is ++ * filled with the RSS context ID associated with the rule. + * + * For %ETHTOOL_GRXCLSRLALL, @rule_cnt specifies the array size of the + * user buffer for @rule_locs on entry. On return, @data is the size +@@ -940,7 +945,11 @@ static __inline__ __u64 ethtool_get_flow_spec_ring_vf(__u64 ring_cookie) + * For %ETHTOOL_SRXCLSRLINS, @fs specifies the rule to add or update. + * @fs.@location either specifies the location to use or is a special + * location value with %RX_CLS_LOC_SPECIAL flag set. On return, +- * @fs.@location is the actual rule location. ++ * @fs.@location is the actual rule location. If @fs.@flow_type ++ * includes the %FLOW_RSS flag, @rss_context is the RSS context ID to ++ * use for flow spreading traffic which matches this rule. The value ++ * from the rxfh indirection table will be added to @fs.@ring_cookie ++ * to choose which ring to deliver to. + * + * For %ETHTOOL_SRXCLSRLDEL, @fs.@location specifies the location of an + * existing rule on entry. +@@ -961,7 +970,10 @@ struct ethtool_rxnfc { + __u32 flow_type; + __u64 data; + struct ethtool_rx_flow_spec fs; +- __u32 rule_cnt; ++ union { ++ __u32 rule_cnt; ++ __u32 rss_context; ++ }; + __u32 rule_locs[0]; + }; + +@@ -988,7 +1000,11 @@ struct ethtool_rxfh_indir { + /** + * struct ethtool_rxfh - command to get/set RX flow hash indir or/and hash key. + * @cmd: Specific command number - %ETHTOOL_GRSSH or %ETHTOOL_SRSSH +- * @rss_context: RSS context identifier. ++ * @rss_context: RSS context identifier. Context 0 is the default for normal ++ * traffic; other contexts can be referenced as the destination for RX flow ++ * classification rules. %ETH_RXFH_CONTEXT_ALLOC is used with command ++ * %ETHTOOL_SRSSH to allocate a new RSS context; on return this field will ++ * contain the ID of the newly allocated context. + * @indir_size: On entry, the array size of the user buffer for the + * indirection table, which may be zero, or (for %ETHTOOL_SRSSH), + * %ETH_RXFH_INDIR_NO_CHANGE. On return from %ETHTOOL_GRSSH, +@@ -1007,7 +1023,8 @@ struct ethtool_rxfh_indir { + * size should be returned. For %ETHTOOL_SRSSH, an @indir_size of + * %ETH_RXFH_INDIR_NO_CHANGE means that indir table setting is not requested + * and a @indir_size of zero means the indir table should be reset to default +- * values. An hfunc of zero means that hash function setting is not requested. ++ * values (if @rss_context == 0) or that the RSS context should be deleted. ++ * An hfunc of zero means that hash function setting is not requested. + */ + struct ethtool_rxfh { + __u32 cmd; +@@ -1019,6 +1036,7 @@ struct ethtool_rxfh { + __u32 rsvd32; + __u32 rss_config[0]; + }; ++#define ETH_RXFH_CONTEXT_ALLOC 0xffffffff + #define ETH_RXFH_INDIR_NO_CHANGE 0xffffffff + + /** +@@ -1633,6 +1651,8 @@ static __inline__ int ethtool_validate_duplex(__u8 duplex) + /* Flag to enable additional fields in struct ethtool_rx_flow_spec */ + #define FLOW_EXT 0x80000000 + #define FLOW_MAC_EXT 0x40000000 ++/* Flag to enable RSS spreading of traffic matching rule (nfc only) */ ++#define FLOW_RSS 0x20000000 + + /* L3-L4 network traffic flow hash options */ + #define RXH_L2DA (1 << 1) +-- +1.8.3.1 + diff --git a/SOURCES/0016-ethtool-add-support-for-extra-RSS-contexts-and-RSS-s.patch b/SOURCES/0016-ethtool-add-support-for-extra-RSS-contexts-and-RSS-s.patch new file mode 100644 index 0000000..1f1ee2a --- /dev/null +++ b/SOURCES/0016-ethtool-add-support-for-extra-RSS-contexts-and-RSS-s.patch @@ -0,0 +1,475 @@ +From 10b4bae4d7f2fa4768fbe90cbfa18ed6059e5a5b Mon Sep 17 00:00:00 2001 +From: Edward Cree +Date: Fri, 9 Mar 2018 15:04:12 +0000 +Subject: [PATCH 16/18] ethtool: add support for extra RSS contexts and RSS + steering filters + +RSS contexts can be created on a device with -X ... context new, modified + with -X ... context N, and deleted with -X ... context N delete. +N-tuple filters can be directed at those contexts with -N ... context N. + +Signed-off-by: Edward Cree +Signed-off-by: John W. Linville +(cherry picked from commit f5d55b967e0c5757e423805a70d1a298e307e91e) +--- + ethtool.c | 141 ++++++++++++++++++++++++++++++++++++++++++++++++++++--------- + internal.h | 4 +- + rxclass.c | 58 +++++++++++++++++++++---- + 3 files changed, 173 insertions(+), 30 deletions(-) + +diff --git a/ethtool.c b/ethtool.c +index 2e9ee2c..a276fdb 100644 +--- a/ethtool.c ++++ b/ethtool.c +@@ -1513,7 +1513,7 @@ static void dump_features(const struct feature_defs *defs, + + static int dump_rxfhash(int fhash, u64 val) + { +- switch (fhash) { ++ switch (fhash & ~FLOW_RSS) { + case TCP_V4_FLOW: + fprintf(stdout, "TCP over IPV4 flows"); + break; +@@ -3527,11 +3527,20 @@ static int do_srxclass(struct cmd_context *ctx) + if (ctx->argc < 2) + exit_bad_args(); + +- if (ctx->argc == 3 && !strcmp(ctx->argp[0], "rx-flow-hash")) { ++ if (!strcmp(ctx->argp[0], "rx-flow-hash")) { + int rx_fhash_set; + u32 rx_fhash_val; + struct ethtool_rxnfc nfccmd; ++ bool flow_rss = false; + ++ if (ctx->argc == 5) { ++ if (strcmp(ctx->argp[3], "context")) ++ exit_bad_args(); ++ flow_rss = true; ++ nfccmd.rss_context = get_u32(ctx->argp[4], 0); ++ } else if (ctx->argc != 3) { ++ exit_bad_args(); ++ } + rx_fhash_set = rxflow_str_to_type(ctx->argp[1]); + if (!rx_fhash_set) + exit_bad_args(); +@@ -3541,16 +3550,19 @@ static int do_srxclass(struct cmd_context *ctx) + nfccmd.cmd = ETHTOOL_SRXFH; + nfccmd.flow_type = rx_fhash_set; + nfccmd.data = rx_fhash_val; ++ if (flow_rss) ++ nfccmd.flow_type |= FLOW_RSS; + + err = send_ioctl(ctx, &nfccmd); + if (err < 0) + perror("Cannot change RX network flow hashing options"); + } else if (!strcmp(ctx->argp[0], "flow-type")) { + struct ethtool_rx_flow_spec rx_rule_fs; ++ __u32 rss_context = 0; + + ctx->argc--; + ctx->argp++; +- if (rxclass_parse_ruleopts(ctx, &rx_rule_fs) < 0) ++ if (rxclass_parse_ruleopts(ctx, &rx_rule_fs, &rss_context) < 0) + exit_bad_args(); + + /* attempt to add rule via N-tuple specifier */ +@@ -3559,7 +3571,7 @@ static int do_srxclass(struct cmd_context *ctx) + return 0; + + /* attempt to add rule via network flow classifier */ +- err = rxclass_rule_ins(ctx, &rx_rule_fs); ++ err = rxclass_rule_ins(ctx, &rx_rule_fs, rss_context); + if (err < 0) { + fprintf(stderr, "Cannot insert" + " classification rule\n"); +@@ -3588,8 +3600,18 @@ static int do_grxclass(struct cmd_context *ctx) + struct ethtool_rxnfc nfccmd; + int err; + +- if (ctx->argc == 2 && !strcmp(ctx->argp[0], "rx-flow-hash")) { ++ if (ctx->argc > 0 && !strcmp(ctx->argp[0], "rx-flow-hash")) { + int rx_fhash_get; ++ bool flow_rss = false; ++ ++ if (ctx->argc == 4) { ++ if (strcmp(ctx->argp[2], "context")) ++ exit_bad_args(); ++ flow_rss = true; ++ nfccmd.rss_context = get_u32(ctx->argp[3], 0); ++ } else if (ctx->argc != 2) { ++ exit_bad_args(); ++ } + + rx_fhash_get = rxflow_str_to_type(ctx->argp[1]); + if (!rx_fhash_get) +@@ -3597,11 +3619,17 @@ static int do_grxclass(struct cmd_context *ctx) + + nfccmd.cmd = ETHTOOL_GRXFH; + nfccmd.flow_type = rx_fhash_get; ++ if (flow_rss) ++ nfccmd.flow_type |= FLOW_RSS; + err = send_ioctl(ctx, &nfccmd); +- if (err < 0) ++ if (err < 0) { + perror("Cannot get RX network flow hashing options"); +- else ++ } else { ++ if (flow_rss) ++ fprintf(stdout, "For RSS context %u:\n", ++ nfccmd.rss_context); + dump_rxfhash(rx_fhash_get, nfccmd.data); ++ } + } else if (ctx->argc == 2 && !strcmp(ctx->argp[0], "rule")) { + int rx_class_rule_get = + get_uint_range(ctx->argp[1], 0, INT_MAX); +@@ -3693,10 +3721,23 @@ static int do_grxfh(struct cmd_context *ctx) + struct ethtool_rxfh rss_head = {0}; + struct ethtool_rxnfc ring_count; + struct ethtool_rxfh *rss; ++ u32 rss_context = 0; + u32 i, indir_bytes; ++ int arg_num = 0; + char *hkey; + int err; + ++ while (arg_num < ctx->argc) { ++ if (!strcmp(ctx->argp[arg_num], "context")) { ++ ++arg_num; ++ rss_context = get_int_range(ctx->argp[arg_num], 0, 1, ++ ETH_RXFH_CONTEXT_ALLOC - 1); ++ ++arg_num; ++ } else { ++ exit_bad_args(); ++ } ++ } ++ + ring_count.cmd = ETHTOOL_GRXRINGS; + err = send_ioctl(ctx, &ring_count); + if (err < 0) { +@@ -3705,6 +3746,7 @@ static int do_grxfh(struct cmd_context *ctx) + } + + rss_head.cmd = ETHTOOL_GRSSH; ++ rss_head.rss_context = rss_context; + err = send_ioctl(ctx, &rss_head); + if (err < 0 && errno == EOPNOTSUPP) { + return do_grxfhindir(ctx, &ring_count); +@@ -3722,6 +3764,7 @@ static int do_grxfh(struct cmd_context *ctx) + } + + rss->cmd = ETHTOOL_GRSSH; ++ rss->rss_context = rss_context; + rss->indir_size = rss_head.indir_size; + rss->key_size = rss_head.key_size; + err = send_ioctl(ctx, rss); +@@ -3882,6 +3925,8 @@ static int do_srxfh(struct cmd_context *ctx) + u32 req_hfunc = 0; + u32 entry_size = sizeof(rss_head.rss_config[0]); + u32 num_weights = 0; ++ u32 rss_context = 0; ++ int delete = 0; + + if (ctx->argc < 1) + exit_bad_args(); +@@ -3917,6 +3962,18 @@ static int do_srxfh(struct cmd_context *ctx) + if (!req_hfunc_name) + exit_bad_args(); + ++arg_num; ++ } else if (!strcmp(ctx->argp[arg_num], "context")) { ++ ++arg_num; ++ if(!strcmp(ctx->argp[arg_num], "new")) ++ rss_context = ETH_RXFH_CONTEXT_ALLOC; ++ else ++ rss_context = get_int_range( ++ ctx->argp[arg_num], 0, 1, ++ ETH_RXFH_CONTEXT_ALLOC - 1); ++ ++arg_num; ++ } else if (!strcmp(ctx->argp[arg_num], "delete")) { ++ ++arg_num; ++ delete = 1; + } else { + exit_bad_args(); + } +@@ -3940,6 +3997,41 @@ static int do_srxfh(struct cmd_context *ctx) + return 1; + } + ++ if (rxfhindir_default && rss_context) { ++ fprintf(stderr, ++ "Default and context options are mutually exclusive\n"); ++ return 1; ++ } ++ ++ if (delete && !rss_context) { ++ fprintf(stderr, "Delete option requires context option\n"); ++ return 1; ++ } ++ ++ if (delete && rxfhindir_weight) { ++ fprintf(stderr, ++ "Delete and weight options are mutually exclusive\n"); ++ return 1; ++ } ++ ++ if (delete && rxfhindir_equal) { ++ fprintf(stderr, ++ "Delete and equal options are mutually exclusive\n"); ++ return 1; ++ } ++ ++ if (delete && rxfhindir_default) { ++ fprintf(stderr, ++ "Delete and default options are mutually exclusive\n"); ++ return 1; ++ } ++ ++ if (delete && rxfhindir_key) { ++ fprintf(stderr, ++ "Delete and hkey options are mutually exclusive\n"); ++ return 1; ++ } ++ + ring_count.cmd = ETHTOOL_GRXRINGS; + err = send_ioctl(ctx, &ring_count); + if (err < 0) { +@@ -3950,7 +4042,7 @@ static int do_srxfh(struct cmd_context *ctx) + rss_head.cmd = ETHTOOL_GRSSH; + err = send_ioctl(ctx, &rss_head); + if (err < 0 && errno == EOPNOTSUPP && !rxfhindir_key && +- !req_hfunc_name) { ++ !req_hfunc_name && !rss_context) { + return do_srxfhindir(ctx, rxfhindir_default, rxfhindir_equal, + rxfhindir_weight, num_weights); + } else if (err < 0) { +@@ -3998,14 +4090,19 @@ static int do_srxfh(struct cmd_context *ctx) + goto free; + } + rss->cmd = ETHTOOL_SRSSH; +- rss->indir_size = rss_head.indir_size; +- rss->key_size = rss_head.key_size; ++ rss->rss_context = rss_context; + rss->hfunc = req_hfunc; +- +- if (fill_indir_table(&rss->indir_size, rss->rss_config, rxfhindir_default, +- rxfhindir_equal, rxfhindir_weight, num_weights)) { +- err = 1; +- goto free; ++ if (delete) { ++ rss->indir_size = rss->key_size = 0; ++ } else { ++ rss->indir_size = rss_head.indir_size; ++ rss->key_size = rss_head.key_size; ++ if (fill_indir_table(&rss->indir_size, rss->rss_config, ++ rxfhindir_default, rxfhindir_equal, ++ rxfhindir_weight, num_weights)) { ++ err = 1; ++ goto free; ++ } + } + + if (hkey) +@@ -4018,6 +4115,8 @@ static int do_srxfh(struct cmd_context *ctx) + if (err < 0) { + perror("Cannot set RX flow hash configuration"); + err = 1; ++ } else if (rss_context == ETH_RXFH_CONTEXT_ALLOC) { ++ printf("New RSS context is %d\n", rss->rss_context); + } + + free: +@@ -4803,12 +4902,12 @@ static const struct option { + { "-n|-u|--show-nfc|--show-ntuple", 1, do_grxclass, + "Show Rx network flow classification options or rules", + " [ rx-flow-hash tcp4|udp4|ah4|esp4|sctp4|" +- "tcp6|udp6|ah6|esp6|sctp6 |\n" ++ "tcp6|udp6|ah6|esp6|sctp6 [context %d] |\n" + " rule %d ]\n" }, + { "-N|-U|--config-nfc|--config-ntuple", 1, do_srxclass, + "Configure Rx network flow classification options or rules", + " rx-flow-hash tcp4|udp4|ah4|esp4|sctp4|" +- "tcp6|udp6|ah6|esp6|sctp6 m|v|t|s|d|f|n|r... |\n" ++ "tcp6|udp6|ah6|esp6|sctp6 m|v|t|s|d|f|n|r... [context %d] |\n" + " flow-type ether|ip4|tcp4|udp4|sctp4|ah4|esp4|" + "ip6|tcp6|udp6|ah6|esp6|sctp6\n" + " [ src %x:%x:%x:%x:%x:%x [m %x:%x:%x:%x:%x:%x] ]\n" +@@ -4827,17 +4926,21 @@ static const struct option { + " [ user-def %x [m %x] ]\n" + " [ dst-mac %x:%x:%x:%x:%x:%x [m %x:%x:%x:%x:%x:%x] ]\n" + " [ action %d ]\n" ++ " [ context %d ]\n" + " [ loc %d]] |\n" + " delete %d\n" }, + { "-T|--show-time-stamping", 1, do_tsinfo, + "Show time stamping capabilities" }, + { "-x|--show-rxfh-indir|--show-rxfh", 1, do_grxfh, +- "Show Rx flow hash indirection table and/or RSS hash key" }, ++ "Show Rx flow hash indirection table and/or RSS hash key", ++ " [ context %d ]\n" }, + { "-X|--set-rxfh-indir|--rxfh", 1, do_srxfh, + "Set Rx flow hash indirection table and/or RSS hash key", ++ " [ context %d|new ]\n" + " [ equal N | weight W0 W1 ... | default ]\n" + " [ hkey %x:%x:%x:%x:%x:.... ]\n" +- " [ hfunc FUNC ]\n" }, ++ " [ hfunc FUNC ]\n" ++ " [ delete ]\n" }, + { "-f|--flash", 1, do_flash, + "Flash firmware image from the specified file to a region on the device", + " FILENAME [ REGION-NUMBER-TO-FLASH ]\n" }, +diff --git a/internal.h b/internal.h +index 4e658ea..913f4eb 100644 +--- a/internal.h ++++ b/internal.h +@@ -332,11 +332,11 @@ int vmxnet3_dump_regs(struct ethtool_drvinfo *info, struct ethtool_regs *regs); + + /* Rx flow classification */ + int rxclass_parse_ruleopts(struct cmd_context *ctx, +- struct ethtool_rx_flow_spec *fsp); ++ struct ethtool_rx_flow_spec *fsp, __u32 *rss_context); + int rxclass_rule_getall(struct cmd_context *ctx); + int rxclass_rule_get(struct cmd_context *ctx, __u32 loc); + int rxclass_rule_ins(struct cmd_context *ctx, +- struct ethtool_rx_flow_spec *fsp); ++ struct ethtool_rx_flow_spec *fsp, __u32 rss_context); + int rxclass_rule_del(struct cmd_context *ctx, __u32 loc); + + /* Module EEPROM parsing code */ +diff --git a/rxclass.c b/rxclass.c +index c7bfeba..39c9eca 100644 +--- a/rxclass.c ++++ b/rxclass.c +@@ -94,14 +94,15 @@ static void rxclass_print_nfc_spec_ext(struct ethtool_rx_flow_spec *fsp) + } + } + +-static void rxclass_print_nfc_rule(struct ethtool_rx_flow_spec *fsp) ++static void rxclass_print_nfc_rule(struct ethtool_rx_flow_spec *fsp, ++ __u32 rss_context) + { + unsigned char *smac, *smacm, *dmac, *dmacm; + __u32 flow_type; + + fprintf(stdout, "Filter: %d\n", fsp->location); + +- flow_type = fsp->flow_type & ~(FLOW_EXT | FLOW_MAC_EXT); ++ flow_type = fsp->flow_type & ~(FLOW_EXT | FLOW_MAC_EXT | FLOW_RSS); + + invert_flow_mask(fsp); + +@@ -247,6 +248,9 @@ static void rxclass_print_nfc_rule(struct ethtool_rx_flow_spec *fsp) + + rxclass_print_nfc_spec_ext(fsp); + ++ if (fsp->flow_type & FLOW_RSS) ++ fprintf(stdout, "\tRSS Context ID: %u\n", rss_context); ++ + if (fsp->ring_cookie != RX_CLS_FLOW_DISC) + fprintf(stdout, "\tAction: Direct to queue %llu\n", + fsp->ring_cookie); +@@ -256,10 +260,11 @@ static void rxclass_print_nfc_rule(struct ethtool_rx_flow_spec *fsp) + fprintf(stdout, "\n"); + } + +-static void rxclass_print_rule(struct ethtool_rx_flow_spec *fsp) ++static void rxclass_print_rule(struct ethtool_rx_flow_spec *fsp, ++ __u32 rss_context) + { + /* print the rule in this location */ +- switch (fsp->flow_type & ~(FLOW_EXT | FLOW_MAC_EXT)) { ++ switch (fsp->flow_type & ~(FLOW_EXT | FLOW_MAC_EXT | FLOW_RSS)) { + case TCP_V4_FLOW: + case UDP_V4_FLOW: + case SCTP_V4_FLOW: +@@ -272,11 +277,11 @@ static void rxclass_print_rule(struct ethtool_rx_flow_spec *fsp) + case ESP_V6_FLOW: + case IPV6_USER_FLOW: + case ETHER_FLOW: +- rxclass_print_nfc_rule(fsp); ++ rxclass_print_nfc_rule(fsp, rss_context); + break; + case IPV4_USER_FLOW: + if (fsp->h_u.usr_ip4_spec.ip_ver == ETH_RX_NFC_IP4) +- rxclass_print_nfc_rule(fsp); ++ rxclass_print_nfc_rule(fsp, rss_context); + else /* IPv6 uses IPV6_USER_FLOW */ + fprintf(stderr, "IPV4_USER_FLOW with wrong ip_ver\n"); + break; +@@ -320,7 +325,7 @@ int rxclass_rule_get(struct cmd_context *ctx, __u32 loc) + } + + /* display rule */ +- rxclass_print_rule(&nfccmd.fs); ++ rxclass_print_rule(&nfccmd.fs, (__u32)nfccmd.rss_context); + return err; + } + +@@ -550,7 +555,7 @@ out: + } + + int rxclass_rule_ins(struct cmd_context *ctx, +- struct ethtool_rx_flow_spec *fsp) ++ struct ethtool_rx_flow_spec *fsp, __u32 rss_context) + { + struct ethtool_rxnfc nfccmd; + __u32 loc = fsp->location; +@@ -568,6 +573,7 @@ int rxclass_rule_ins(struct cmd_context *ctx, + + /* notify netdev of new rule */ + nfccmd.cmd = ETHTOOL_SRXCLSRLINS; ++ nfccmd.rss_context = rss_context; + nfccmd.fs = *fsp; + err = send_ioctl(ctx, &nfccmd); + if (err < 0) +@@ -1184,7 +1190,7 @@ static int rxclass_get_mask(char *str, unsigned char *p, + } + + int rxclass_parse_ruleopts(struct cmd_context *ctx, +- struct ethtool_rx_flow_spec *fsp) ++ struct ethtool_rx_flow_spec *fsp, __u32 *rss_context) + { + const struct rule_opts *options; + unsigned char *p = (unsigned char *)fsp; +@@ -1273,6 +1279,40 @@ int rxclass_parse_ruleopts(struct cmd_context *ctx, + for (i = 1; i < argc;) { + const struct rule_opts *opt; + int idx; ++ ++ /* special handling for 'context %d' as it doesn't go in ++ * the struct ethtool_rx_flow_spec ++ */ ++ if (!strcmp(argp[i], "context")) { ++ unsigned long long val; ++ ++ i++; ++ if (i >= argc) { ++ fprintf(stderr, "'context' missing value\n"); ++ return -1; ++ } ++ ++ if (rxclass_get_ulong(argp[i], &val, 32)) { ++ fprintf(stderr, "Invalid context value[%s]\n", ++ argp[i]); ++ return -1; ++ } ++ ++ /* Can't use the ALLOC special value as the context ID ++ * of a filter to insert ++ */ ++ if ((__u32)val == ETH_RXFH_CONTEXT_ALLOC) { ++ fprintf(stderr, "Bad context value %x\n", ++ (__u32)val); ++ return -1; ++ } ++ ++ *rss_context = (__u32)val; ++ fsp->flow_type |= FLOW_RSS; ++ i++; ++ continue; ++ } ++ + for (opt = options, idx = 0; idx < n_opts; idx++, opt++) { + char mask_name[16]; + +-- +1.8.3.1 + diff --git a/SOURCES/0017-ethtool.8-Document-RSS-context-control-and-RSS-filte.patch b/SOURCES/0017-ethtool.8-Document-RSS-context-control-and-RSS-filte.patch new file mode 100644 index 0000000..1153a9c --- /dev/null +++ b/SOURCES/0017-ethtool.8-Document-RSS-context-control-and-RSS-filte.patch @@ -0,0 +1,75 @@ +From 2fb429c04c2da29701c250351bb8877f9d0e5ac2 Mon Sep 17 00:00:00 2001 +From: Edward Cree +Date: Fri, 9 Mar 2018 15:04:21 +0000 +Subject: [PATCH 17/18] ethtool.8: Document RSS context control and RSS filters + +Signed-off-by: Edward Cree +Signed-off-by: John W. Linville +(cherry picked from commit 172d6f10021dcce940d0354b266a9f4bbfde0b94) +--- + ethtool.8.in | 28 ++++++++++++++++++++++++++++ + 1 file changed, 28 insertions(+) + +diff --git a/ethtool.8.in b/ethtool.8.in +index 6816020..dd2e3f5 100644 +--- a/ethtool.8.in ++++ b/ethtool.8.in +@@ -274,6 +274,7 @@ ethtool \- query or control network driver and hardware settings + .BM user\-def + .RB [ dst-mac \ \*(MA\ [ m \ \*(MA]] + .BN action ++.BN context + .BN loc + .RB | + .br +@@ -303,6 +304,10 @@ ethtool \- query or control network driver and hardware settings + .RB ...\ | \ default \ ] + .RB [ hfunc + .IR FUNC ] ++.RB [ context ++.I CTX ++.RB |\ new ] ++.RB [ delete ] + .HP + .B ethtool \-f|\-\-flash + .I devname file +@@ -832,6 +837,13 @@ lB l. + 0 or higher Rx queue to route the flow + .TE + .TP ++.BI context \ N ++Specifies the RSS context to spread packets over multiple queues; either ++.B 0 ++for the default RSS context, or a value returned by ++.BI ethtool\ -X\ ... \ context ++.BR new . ++.TP + .BI loc \ N + Specify the location/ID to insert the rule. This will overwrite + any rule present in that location and will not go through any +@@ -883,6 +895,22 @@ must be non-zero and must not exceed the size of the indirection table. + .TP + .BI default + Sets the receive flow hash indirection table to its default value. ++.TP ++\fBcontext \fICTX\fR | \fBnew\fR ++Specifies an RSS context to act on; either ++.B new ++to allocate a new RSS context, or ++.IR CTX , ++a value returned by a previous ++.IB ... \ context ++.BR new . ++.TP ++.B delete ++Delete the specified RSS context. May only be used in conjunction with ++.B context ++and a non-zero ++.I CTX ++value. + .RE + .TP + .B \-f \-\-flash +-- +1.8.3.1 + diff --git a/SOURCES/0018-ethtool-don-t-fall-back-to-grxfhindir-when-context-w.patch b/SOURCES/0018-ethtool-don-t-fall-back-to-grxfhindir-when-context-w.patch new file mode 100644 index 0000000..9f1cab4 --- /dev/null +++ b/SOURCES/0018-ethtool-don-t-fall-back-to-grxfhindir-when-context-w.patch @@ -0,0 +1,34 @@ +From 6ff8142033aed6f9eafe7c4f8a67a55c5a98ab2f Mon Sep 17 00:00:00 2001 +From: Edward Cree +Date: Mon, 19 Mar 2018 16:52:06 +0000 +Subject: [PATCH 18/18] ethtool: don't fall back to grxfhindir when context was + specified + +In do_grfxh(), if rss_context is non-zero, we must not fall back to + do_grxfhindir() if ETHTOOL_GRSSH fails, for that reads the default RSS + context and not the one specified. + +Fixes: f5d55b967e0c ("ethtool: add support for extra RSS contexts and RSS steering filters") +Signed-off-by: Edward Cree +Signed-off-by: John W. Linville +(cherry picked from commit 7984d34ea893a529330b6addb959cbf6e3ec026f) +--- + ethtool.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/ethtool.c b/ethtool.c +index a276fdb..2ecc13f 100644 +--- a/ethtool.c ++++ b/ethtool.c +@@ -3748,7 +3748,7 @@ static int do_grxfh(struct cmd_context *ctx) + rss_head.cmd = ETHTOOL_GRSSH; + rss_head.rss_context = rss_context; + err = send_ioctl(ctx, &rss_head); +- if (err < 0 && errno == EOPNOTSUPP) { ++ if (err < 0 && errno == EOPNOTSUPP && !rss_context) { + return do_grxfhindir(ctx, &ring_count); + } else if (err < 0) { + perror("Cannot get RX flow hash indir size and/or key size"); +-- +1.8.3.1 + diff --git a/SPECS/ethtool.spec b/SPECS/ethtool.spec index 03936c1..92b6745 100644 --- a/SPECS/ethtool.spec +++ b/SPECS/ethtool.spec @@ -1,13 +1,12 @@ Name: ethtool Epoch: 2 Version: 4.8 -Release: 7%{?dist} +Release: 9%{?dist} Summary: Settings tool for Ethernet NICs License: GPLv2 Group: Applications/System -#Old URL: http://sourceforge.net/projects/gkernel/ -URL: http://ftp.kernel.org/pub/software/network/%{name}/ +URL: https://www.kernel.org/pub/software/network/%{name}/ # When using tarball from released upstream version: # - http://ftp.kernel.org/pub/software/network/%{name}/%{name}-%{version}.tar.bz2 @@ -35,6 +34,10 @@ Patch10: 0011-ethtool.8-Document-56000-advertise-link-modes.patch Patch11: 0012-ethtool-Remove-UDP-Fragmentation-Offload-error-print.patch Patch12: 0013-ethtool-copy.h-sync-with-net-next.patch Patch13: 0014-ethtool-Support-for-FEC-encoding-control.patch +Patch14: 0015-ethtool-copy.h-sync-with-net-next.patch +Patch15: 0016-ethtool-add-support-for-extra-RSS-contexts-and-RSS-s.patch +Patch16: 0017-ethtool.8-Document-RSS-context-control-and-RSS-filte.patch +Patch17: 0018-ethtool-don-t-fall-back-to-grxfhindir-when-context-w.patch %description This utility allows querying and changing settings such as speed, @@ -57,6 +60,10 @@ network devices, especially of Ethernet devices. %patch11 -p1 %patch12 -p1 %patch13 -p1 +%patch14 -p1 +%patch15 -p1 +%patch16 -p1 +%patch17 -p1 # Only needed when using upstream git # aclocal @@ -79,6 +86,12 @@ make DESTDIR=%{buildroot} INSTALL='install -p' install %{_mandir}/man8/%{name}.8* %changelog +* Mon Jul 2 2018 Ivan Vecera - 2:4.8-9 +- Added support for extra RSS contexts and steering filters + +* Mon Jun 11 2018 Ivan Vecera - 2:4.8-8 +- Fixed RPM URL field in spec file + * Wed Jan 10 2018 Ivan Vecera - 2:4.8-7 - Fixed synopsis in ethtool man page