* Re: [PATCH iproute2 master 1/2] json: move json printer to common library
From: Julien Fortin @ 2017-09-21 17:47 UTC (permalink / raw)
To: Daniel Borkmann; +Cc: Stephen Hemminger, ast, netdev
In-Reply-To: <635a857b7b32cd0df79805f8e32b20a2674a675d.1505956723.git.daniel@iogearbox.net>
On Thu, Sep 21, 2017 at 1:42 AM, Daniel Borkmann <daniel@iogearbox.net> wrote:
> Move the json printer which is based on json writer into the
> iproute2 library, so it can be used by library code and tools
> other than ip. Should probably have been done from the beginning
> like that given json writer is in the library already anyway.
> No functional changes.
>
> Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
Acked-by: Julien Fortin <julien@cumulusnetworks.com>
> ---
> include/json_print.h | 71 ++++++++++++++++
> ip/Makefile | 2 +-
> ip/ip_common.h | 65 ++------------
> ip/ip_print.c | 233 ---------------------------------------------------
> lib/Makefile | 2 +-
> lib/json_print.c | 231 ++++++++++++++++++++++++++++++++++++++++++++++++++
> 6 files changed, 312 insertions(+), 292 deletions(-)
> create mode 100644 include/json_print.h
> delete mode 100644 ip/ip_print.c
> create mode 100644 lib/json_print.c
>
> diff --git a/include/json_print.h b/include/json_print.h
> new file mode 100644
> index 0000000..44cf5ac
> --- /dev/null
> +++ b/include/json_print.h
> @@ -0,0 +1,71 @@
> +/*
> + * json_print.h "print regular or json output, based on json_writer".
> + *
> + * This program is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU General Public License
> + * as published by the Free Software Foundation; either version
> + * 2 of the License, or (at your option) any later version.
> + *
> + * Authors: Julien Fortin, <julien@cumulusnetworks.com>
> + */
> +
> +#ifndef _JSON_PRINT_H_
> +#define _JSON_PRINT_H_
> +
> +#include "json_writer.h"
> +#include "color.h"
> +
> +json_writer_t *get_json_writer(void);
> +
> +/*
> + * use:
> + * - PRINT_ANY for context based output
> + * - PRINT_FP for non json specific output
> + * - PRINT_JSON for json specific output
> + */
> +enum output_type {
> + PRINT_FP = 1,
> + PRINT_JSON = 2,
> + PRINT_ANY = 4,
> +};
> +
> +void new_json_obj(int json, FILE *fp);
> +void delete_json_obj(void);
> +
> +bool is_json_context(void);
> +
> +void set_current_fp(FILE *fp);
> +
> +void fflush_fp(void);
> +
> +void open_json_object(const char *str);
> +void close_json_object(void);
> +void open_json_array(enum output_type type, const char *delim);
> +void close_json_array(enum output_type type, const char *delim);
> +
> +#define _PRINT_FUNC(type_name, type) \
> + void print_color_##type_name(enum output_type t, \
> + enum color_attr color, \
> + const char *key, \
> + const char *fmt, \
> + type value); \
> + \
> + static inline void print_##type_name(enum output_type t, \
> + const char *key, \
> + const char *fmt, \
> + type value) \
> + { \
> + print_color_##type_name(t, -1, key, fmt, value); \
> + }
> +_PRINT_FUNC(int, int);
> +_PRINT_FUNC(bool, bool);
> +_PRINT_FUNC(null, const char*);
> +_PRINT_FUNC(string, const char*);
> +_PRINT_FUNC(uint, uint64_t);
> +_PRINT_FUNC(hu, unsigned short);
> +_PRINT_FUNC(hex, unsigned int);
> +_PRINT_FUNC(0xhex, unsigned int);
> +_PRINT_FUNC(lluint, unsigned long long int);
> +#undef _PRINT_FUNC
> +
> +#endif /* _JSON_PRINT_H_ */
> diff --git a/ip/Makefile b/ip/Makefile
> index 52c9a2e..5a1c7ad 100644
> --- a/ip/Makefile
> +++ b/ip/Makefile
> @@ -9,7 +9,7 @@ IPOBJ=ip.o ipaddress.o ipaddrlabel.o iproute.o iprule.o ipnetns.o \
> link_iptnl.o link_gre6.o iplink_bond.o iplink_bond_slave.o iplink_hsr.o \
> iplink_bridge.o iplink_bridge_slave.o ipfou.o iplink_ipvlan.o \
> iplink_geneve.o iplink_vrf.o iproute_lwtunnel.o ipmacsec.o ipila.o \
> - ipvrf.o iplink_xstats.o ipseg6.o ip_print.o
> + ipvrf.o iplink_xstats.o ipseg6.o
>
> RTMONOBJ=rtmon.o
>
> diff --git a/ip/ip_common.h b/ip/ip_common.h
> index efc789c..4b8b0a7 100644
> --- a/ip/ip_common.h
> +++ b/ip/ip_common.h
> @@ -1,3 +1,10 @@
> +#ifndef _IP_COMMON_H_
> +#define _IP_COMMON_H_
> +
> +#include <stdbool.h>
> +
> +#include "json_print.h"
> +
> struct link_filter {
> int ifindex;
> int family;
> @@ -101,8 +108,6 @@ static inline int rtm_get_table(struct rtmsg *r, struct rtattr **tb)
>
> extern struct rtnl_handle rth;
>
> -#include <stdbool.h>
> -
> struct link_util {
> struct link_util *next;
> const char *id;
> @@ -141,58 +146,4 @@ int name_is_vrf(const char *name);
>
> void print_num(FILE *fp, unsigned int width, uint64_t count);
>
> -#include "json_writer.h"
> -
> -json_writer_t *get_json_writer(void);
> -/*
> - * use:
> - * - PRINT_ANY for context based output
> - * - PRINT_FP for non json specific output
> - * - PRINT_JSON for json specific output
> - */
> -enum output_type {
> - PRINT_FP = 1,
> - PRINT_JSON = 2,
> - PRINT_ANY = 4,
> -};
> -
> -void new_json_obj(int json, FILE *fp);
> -void delete_json_obj(void);
> -
> -bool is_json_context(void);
> -
> -void set_current_fp(FILE *fp);
> -
> -void fflush_fp(void);
> -
> -void open_json_object(const char *str);
> -void close_json_object(void);
> -void open_json_array(enum output_type type, const char *delim);
> -void close_json_array(enum output_type type, const char *delim);
> -
> -#include "color.h"
> -
> -#define _PRINT_FUNC(type_name, type) \
> - void print_color_##type_name(enum output_type t, \
> - enum color_attr color, \
> - const char *key, \
> - const char *fmt, \
> - type value); \
> - \
> - static inline void print_##type_name(enum output_type t, \
> - const char *key, \
> - const char *fmt, \
> - type value) \
> - { \
> - print_color_##type_name(t, -1, key, fmt, value); \
> - }
> -_PRINT_FUNC(int, int);
> -_PRINT_FUNC(bool, bool);
> -_PRINT_FUNC(null, const char*);
> -_PRINT_FUNC(string, const char*);
> -_PRINT_FUNC(uint, uint64_t);
> -_PRINT_FUNC(hu, unsigned short);
> -_PRINT_FUNC(hex, unsigned int);
> -_PRINT_FUNC(0xhex, unsigned int);
> -_PRINT_FUNC(lluint, unsigned long long int);
> -#undef _PRINT_FUNC
> +#endif /* _IP_COMMON_H_ */
> diff --git a/ip/ip_print.c b/ip/ip_print.c
> deleted file mode 100644
> index 4cd6a0b..0000000
> --- a/ip/ip_print.c
> +++ /dev/null
> @@ -1,233 +0,0 @@
> -/*
> - * ip_print.c "ip print regular or json output".
> - *
> - * This program is free software; you can redistribute it and/or
> - * modify it under the terms of the GNU General Public License
> - * as published by the Free Software Foundation; either version
> - * 2 of the License, or (at your option) any later version.
> - *
> - * Authors: Julien Fortin, <julien@cumulusnetworks.com>
> - *
> - */
> -
> -#include <stdarg.h>
> -#include <stdio.h>
> -
> -#include "utils.h"
> -#include "ip_common.h"
> -#include "json_writer.h"
> -
> -static json_writer_t *_jw;
> -static FILE *_fp;
> -
> -#define _IS_JSON_CONTEXT(type) ((type & PRINT_JSON || type & PRINT_ANY) && _jw)
> -#define _IS_FP_CONTEXT(type) (!_jw && (type & PRINT_FP || type & PRINT_ANY))
> -
> -void new_json_obj(int json, FILE *fp)
> -{
> - if (json) {
> - _jw = jsonw_new(fp);
> - if (!_jw) {
> - perror("json object");
> - exit(1);
> - }
> - jsonw_pretty(_jw, true);
> - jsonw_start_array(_jw);
> - }
> - set_current_fp(fp);
> -}
> -
> -void delete_json_obj(void)
> -{
> - if (_jw) {
> - jsonw_end_array(_jw);
> - jsonw_destroy(&_jw);
> - }
> -}
> -
> -bool is_json_context(void)
> -{
> - return _jw != NULL;
> -}
> -
> -void set_current_fp(FILE *fp)
> -{
> - if (!fp) {
> - fprintf(stderr, "Error: invalid file pointer.\n");
> - exit(1);
> - }
> - _fp = fp;
> -}
> -
> -json_writer_t *get_json_writer(void)
> -{
> - return _jw;
> -}
> -
> -void open_json_object(const char *str)
> -{
> - if (_IS_JSON_CONTEXT(PRINT_JSON)) {
> - if (str)
> - jsonw_name(_jw, str);
> - jsonw_start_object(_jw);
> - }
> -}
> -
> -void close_json_object(void)
> -{
> - if (_IS_JSON_CONTEXT(PRINT_JSON))
> - jsonw_end_object(_jw);
> -}
> -
> -/*
> - * Start json array or string array using
> - * the provided string as json key (if not null)
> - * or as array delimiter in non-json context.
> - */
> -void open_json_array(enum output_type type, const char *str)
> -{
> - if (_IS_JSON_CONTEXT(type)) {
> - if (str)
> - jsonw_name(_jw, str);
> - jsonw_start_array(_jw);
> - } else if (_IS_FP_CONTEXT(type)) {
> - fprintf(_fp, "%s", str);
> - }
> -}
> -
> -/*
> - * End json array or string array
> - */
> -void close_json_array(enum output_type type, const char *str)
> -{
> - if (_IS_JSON_CONTEXT(type)) {
> - jsonw_pretty(_jw, false);
> - jsonw_end_array(_jw);
> - jsonw_pretty(_jw, true);
> - } else if (_IS_FP_CONTEXT(type)) {
> - fprintf(_fp, "%s", str);
> - }
> -}
> -
> -/*
> - * pre-processor directive to generate similar
> - * functions handling different types
> - */
> -#define _PRINT_FUNC(type_name, type) \
> - void print_color_##type_name(enum output_type t, \
> - enum color_attr color, \
> - const char *key, \
> - const char *fmt, \
> - type value) \
> - { \
> - if (_IS_JSON_CONTEXT(t)) { \
> - if (!key) \
> - jsonw_##type_name(_jw, value); \
> - else \
> - jsonw_##type_name##_field(_jw, key, value); \
> - } else if (_IS_FP_CONTEXT(t)) { \
> - color_fprintf(_fp, color, fmt, value); \
> - } \
> - }
> -_PRINT_FUNC(int, int);
> -_PRINT_FUNC(hu, unsigned short);
> -_PRINT_FUNC(uint, uint64_t);
> -_PRINT_FUNC(lluint, unsigned long long int);
> -#undef _PRINT_FUNC
> -
> -void print_color_string(enum output_type type,
> - enum color_attr color,
> - const char *key,
> - const char *fmt,
> - const char *value)
> -{
> - if (_IS_JSON_CONTEXT(type)) {
> - if (key && !value)
> - jsonw_name(_jw, key);
> - else if (!key && value)
> - jsonw_string(_jw, value);
> - else
> - jsonw_string_field(_jw, key, value);
> - } else if (_IS_FP_CONTEXT(type)) {
> - color_fprintf(_fp, color, fmt, value);
> - }
> -}
> -
> -/*
> - * value's type is bool. When using this function in FP context you can't pass
> - * a value to it, you will need to use "is_json_context()" to have different
> - * branch for json and regular output. grep -r "print_bool" for example
> - */
> -void print_color_bool(enum output_type type,
> - enum color_attr color,
> - const char *key,
> - const char *fmt,
> - bool value)
> -{
> - if (_IS_JSON_CONTEXT(type)) {
> - if (key)
> - jsonw_bool_field(_jw, key, value);
> - else
> - jsonw_bool(_jw, value);
> - } else if (_IS_FP_CONTEXT(type)) {
> - color_fprintf(_fp, color, fmt, value ? "true" : "false");
> - }
> -}
> -
> -/*
> - * In JSON context uses hardcode %#x format: 42 -> 0x2a
> - */
> -void print_color_0xhex(enum output_type type,
> - enum color_attr color,
> - const char *key,
> - const char *fmt,
> - unsigned int hex)
> -{
> - if (_IS_JSON_CONTEXT(type)) {
> - SPRINT_BUF(b1);
> -
> - snprintf(b1, sizeof(b1), "%#x", hex);
> - print_string(PRINT_JSON, key, NULL, b1);
> - } else if (_IS_FP_CONTEXT(type)) {
> - color_fprintf(_fp, color, fmt, hex);
> - }
> -}
> -
> -void print_color_hex(enum output_type type,
> - enum color_attr color,
> - const char *key,
> - const char *fmt,
> - unsigned int hex)
> -{
> - if (_IS_JSON_CONTEXT(type)) {
> - SPRINT_BUF(b1);
> -
> - snprintf(b1, sizeof(b1), "%x", hex);
> - if (key)
> - jsonw_string_field(_jw, key, b1);
> - else
> - jsonw_string(_jw, b1);
> - } else if (_IS_FP_CONTEXT(type)) {
> - color_fprintf(_fp, color, fmt, hex);
> - }
> -}
> -
> -/*
> - * In JSON context we don't use the argument "value" we simply call jsonw_null
> - * whereas FP context can use "value" to output anything
> - */
> -void print_color_null(enum output_type type,
> - enum color_attr color,
> - const char *key,
> - const char *fmt,
> - const char *value)
> -{
> - if (_IS_JSON_CONTEXT(type)) {
> - if (key)
> - jsonw_null_field(_jw, key);
> - else
> - jsonw_null(_jw);
> - } else if (_IS_FP_CONTEXT(type)) {
> - color_fprintf(_fp, color, fmt, value);
> - }
> -}
> diff --git a/lib/Makefile b/lib/Makefile
> index 5e9f72f..0fbdf4c 100644
> --- a/lib/Makefile
> +++ b/lib/Makefile
> @@ -3,7 +3,7 @@ include ../config.mk
> CFLAGS += -fPIC
>
> UTILOBJ = utils.o rt_names.o ll_types.o ll_proto.o ll_addr.o \
> - inet_proto.o namespace.o json_writer.o \
> + inet_proto.o namespace.o json_writer.o json_print.o \
> names.o color.o bpf.o exec.o fs.o
>
> NLOBJ=libgenl.o ll_map.o libnetlink.o
> diff --git a/lib/json_print.c b/lib/json_print.c
> new file mode 100644
> index 0000000..93b4119
> --- /dev/null
> +++ b/lib/json_print.c
> @@ -0,0 +1,231 @@
> +/*
> + * json_print.c "print regular or json output, based on json_writer".
> + *
> + * This program is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU General Public License
> + * as published by the Free Software Foundation; either version
> + * 2 of the License, or (at your option) any later version.
> + *
> + * Authors: Julien Fortin, <julien@cumulusnetworks.com>
> + */
> +
> +#include <stdarg.h>
> +#include <stdio.h>
> +
> +#include "utils.h"
> +#include "json_print.h"
> +
> +static json_writer_t *_jw;
> +static FILE *_fp;
> +
> +#define _IS_JSON_CONTEXT(type) ((type & PRINT_JSON || type & PRINT_ANY) && _jw)
> +#define _IS_FP_CONTEXT(type) (!_jw && (type & PRINT_FP || type & PRINT_ANY))
> +
> +void new_json_obj(int json, FILE *fp)
> +{
> + if (json) {
> + _jw = jsonw_new(fp);
> + if (!_jw) {
> + perror("json object");
> + exit(1);
> + }
> + jsonw_pretty(_jw, true);
> + jsonw_start_array(_jw);
> + }
> + set_current_fp(fp);
> +}
> +
> +void delete_json_obj(void)
> +{
> + if (_jw) {
> + jsonw_end_array(_jw);
> + jsonw_destroy(&_jw);
> + }
> +}
> +
> +bool is_json_context(void)
> +{
> + return _jw != NULL;
> +}
> +
> +void set_current_fp(FILE *fp)
> +{
> + if (!fp) {
> + fprintf(stderr, "Error: invalid file pointer.\n");
> + exit(1);
> + }
> + _fp = fp;
> +}
> +
> +json_writer_t *get_json_writer(void)
> +{
> + return _jw;
> +}
> +
> +void open_json_object(const char *str)
> +{
> + if (_IS_JSON_CONTEXT(PRINT_JSON)) {
> + if (str)
> + jsonw_name(_jw, str);
> + jsonw_start_object(_jw);
> + }
> +}
> +
> +void close_json_object(void)
> +{
> + if (_IS_JSON_CONTEXT(PRINT_JSON))
> + jsonw_end_object(_jw);
> +}
> +
> +/*
> + * Start json array or string array using
> + * the provided string as json key (if not null)
> + * or as array delimiter in non-json context.
> + */
> +void open_json_array(enum output_type type, const char *str)
> +{
> + if (_IS_JSON_CONTEXT(type)) {
> + if (str)
> + jsonw_name(_jw, str);
> + jsonw_start_array(_jw);
> + } else if (_IS_FP_CONTEXT(type)) {
> + fprintf(_fp, "%s", str);
> + }
> +}
> +
> +/*
> + * End json array or string array
> + */
> +void close_json_array(enum output_type type, const char *str)
> +{
> + if (_IS_JSON_CONTEXT(type)) {
> + jsonw_pretty(_jw, false);
> + jsonw_end_array(_jw);
> + jsonw_pretty(_jw, true);
> + } else if (_IS_FP_CONTEXT(type)) {
> + fprintf(_fp, "%s", str);
> + }
> +}
> +
> +/*
> + * pre-processor directive to generate similar
> + * functions handling different types
> + */
> +#define _PRINT_FUNC(type_name, type) \
> + void print_color_##type_name(enum output_type t, \
> + enum color_attr color, \
> + const char *key, \
> + const char *fmt, \
> + type value) \
> + { \
> + if (_IS_JSON_CONTEXT(t)) { \
> + if (!key) \
> + jsonw_##type_name(_jw, value); \
> + else \
> + jsonw_##type_name##_field(_jw, key, value); \
> + } else if (_IS_FP_CONTEXT(t)) { \
> + color_fprintf(_fp, color, fmt, value); \
> + } \
> + }
> +_PRINT_FUNC(int, int);
> +_PRINT_FUNC(hu, unsigned short);
> +_PRINT_FUNC(uint, uint64_t);
> +_PRINT_FUNC(lluint, unsigned long long int);
> +#undef _PRINT_FUNC
> +
> +void print_color_string(enum output_type type,
> + enum color_attr color,
> + const char *key,
> + const char *fmt,
> + const char *value)
> +{
> + if (_IS_JSON_CONTEXT(type)) {
> + if (key && !value)
> + jsonw_name(_jw, key);
> + else if (!key && value)
> + jsonw_string(_jw, value);
> + else
> + jsonw_string_field(_jw, key, value);
> + } else if (_IS_FP_CONTEXT(type)) {
> + color_fprintf(_fp, color, fmt, value);
> + }
> +}
> +
> +/*
> + * value's type is bool. When using this function in FP context you can't pass
> + * a value to it, you will need to use "is_json_context()" to have different
> + * branch for json and regular output. grep -r "print_bool" for example
> + */
> +void print_color_bool(enum output_type type,
> + enum color_attr color,
> + const char *key,
> + const char *fmt,
> + bool value)
> +{
> + if (_IS_JSON_CONTEXT(type)) {
> + if (key)
> + jsonw_bool_field(_jw, key, value);
> + else
> + jsonw_bool(_jw, value);
> + } else if (_IS_FP_CONTEXT(type)) {
> + color_fprintf(_fp, color, fmt, value ? "true" : "false");
> + }
> +}
> +
> +/*
> + * In JSON context uses hardcode %#x format: 42 -> 0x2a
> + */
> +void print_color_0xhex(enum output_type type,
> + enum color_attr color,
> + const char *key,
> + const char *fmt,
> + unsigned int hex)
> +{
> + if (_IS_JSON_CONTEXT(type)) {
> + SPRINT_BUF(b1);
> +
> + snprintf(b1, sizeof(b1), "%#x", hex);
> + print_string(PRINT_JSON, key, NULL, b1);
> + } else if (_IS_FP_CONTEXT(type)) {
> + color_fprintf(_fp, color, fmt, hex);
> + }
> +}
> +
> +void print_color_hex(enum output_type type,
> + enum color_attr color,
> + const char *key,
> + const char *fmt,
> + unsigned int hex)
> +{
> + if (_IS_JSON_CONTEXT(type)) {
> + SPRINT_BUF(b1);
> +
> + snprintf(b1, sizeof(b1), "%x", hex);
> + if (key)
> + jsonw_string_field(_jw, key, b1);
> + else
> + jsonw_string(_jw, b1);
> + } else if (_IS_FP_CONTEXT(type)) {
> + color_fprintf(_fp, color, fmt, hex);
> + }
> +}
> +
> +/*
> + * In JSON context we don't use the argument "value" we simply call jsonw_null
> + * whereas FP context can use "value" to output anything
> + */
> +void print_color_null(enum output_type type,
> + enum color_attr color,
> + const char *key,
> + const char *fmt,
> + const char *value)
> +{
> + if (_IS_JSON_CONTEXT(type)) {
> + if (key)
> + jsonw_null_field(_jw, key);
> + else
> + jsonw_null(_jw);
> + } else if (_IS_FP_CONTEXT(type)) {
> + color_fprintf(_fp, color, fmt, value);
> + }
> +}
> --
> 1.9.3
>
^ permalink raw reply
* [PATCH net-next v2 0/4] cxgb4: add support to offload tc flower
From: Rahul Lakkireddy @ 2017-09-21 18:11 UTC (permalink / raw)
To: netdev; +Cc: davem, kumaras, ganeshgr, nirranjan, indranil, Rahul Lakkireddy
This series of patches add support to offload tc flower onto Chelsio
NICs.
Patch 1 adds basic skeleton to prepare for offloading tc flower flows.
Patch 2 adds support to add/remove flows for offload. Flows can have
accompanying masks. Following match and action are currently supported
for offload:
Match: ether-protocol, IPv4/IPv6 addresses, L4 ports (TCP/UDP)
Action: drop, redirect to another port on the device.
Patch 3 adds support to offload tc-flower flows having
vlan actions: pop, push, and modify.
Patch 4 adds support to fetch stats for the offloaded tc flower flows
from hardware.
Support for offloading more match and action types are to be followed
in subsequent series.
Thanks,
Rahul
---
v2:
- Setting ftid to -1 not required after bitmap_find_free_region
in cxgb4_get_free_ftid.
- Direct return can be used as jumping to error path is not needed
if flower entry allocation failed in cxgb4_tc_flower_replace.
Same applies if flower entry not found in cxgb4_tc_flower_destroy.
- Also, removed an extra return from cxgb4_tc_flower_destroy.
- Avoid wrapping line for netdev_err message. Also, use
consistent error message string.
Kumar Sanghvi (4):
cxgb4: add tc flower offload skeleton
cxgb4: add basic tc flower offload support
cxgb4: add support to offload action vlan
cxgb4: fetch stats for offloaded tc flower flows
drivers/net/ethernet/chelsio/cxgb4/Makefile | 4 +-
drivers/net/ethernet/chelsio/cxgb4/cxgb4.h | 4 +
drivers/net/ethernet/chelsio/cxgb4/cxgb4_filter.c | 100 +++++
drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c | 25 ++
.../net/ethernet/chelsio/cxgb4/cxgb4_tc_flower.c | 452 +++++++++++++++++++++
.../net/ethernet/chelsio/cxgb4/cxgb4_tc_flower.h | 66 +++
drivers/net/ethernet/chelsio/cxgb4/cxgb4_uld.h | 3 +
7 files changed, 653 insertions(+), 1 deletion(-)
create mode 100644 drivers/net/ethernet/chelsio/cxgb4/cxgb4_tc_flower.c
create mode 100644 drivers/net/ethernet/chelsio/cxgb4/cxgb4_tc_flower.h
--
2.14.1
^ permalink raw reply
* [PATCH net-next v2 1/4] cxgb4: add tc flower offload skeleton
From: Rahul Lakkireddy @ 2017-09-21 18:11 UTC (permalink / raw)
To: netdev; +Cc: davem, kumaras, ganeshgr, nirranjan, indranil, Rahul Lakkireddy
In-Reply-To: <cover.1506015856.git.rahul.lakkireddy@chelsio.com>
From: Kumar Sanghvi <kumaras@chelsio.com>
Add basic skeleton to prepare for offloading tc-flower flows.
Signed-off-by: Kumar Sanghvi <kumaras@chelsio.com>
Signed-off-by: Rahul Lakkireddy <rahul.lakkireddy@chelsio.com>
Signed-off-by: Ganesh Goudar <ganeshgr@chelsio.com>
---
v2:
- No changes.
drivers/net/ethernet/chelsio/cxgb4/Makefile | 4 +-
drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c | 22 +++++++++
.../net/ethernet/chelsio/cxgb4/cxgb4_tc_flower.c | 57 ++++++++++++++++++++++
.../net/ethernet/chelsio/cxgb4/cxgb4_tc_flower.h | 46 +++++++++++++++++
4 files changed, 128 insertions(+), 1 deletion(-)
create mode 100644 drivers/net/ethernet/chelsio/cxgb4/cxgb4_tc_flower.c
create mode 100644 drivers/net/ethernet/chelsio/cxgb4/cxgb4_tc_flower.h
diff --git a/drivers/net/ethernet/chelsio/cxgb4/Makefile b/drivers/net/ethernet/chelsio/cxgb4/Makefile
index 817212702f0a..fecd7aab673b 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/Makefile
+++ b/drivers/net/ethernet/chelsio/cxgb4/Makefile
@@ -4,7 +4,9 @@
obj-$(CONFIG_CHELSIO_T4) += cxgb4.o
-cxgb4-objs := cxgb4_main.o l2t.o t4_hw.o sge.o clip_tbl.o cxgb4_ethtool.o cxgb4_uld.o sched.o cxgb4_filter.o cxgb4_tc_u32.o cxgb4_ptp.o
+cxgb4-objs := cxgb4_main.o l2t.o t4_hw.o sge.o clip_tbl.o cxgb4_ethtool.o \
+ cxgb4_uld.o sched.o cxgb4_filter.o cxgb4_tc_u32.o \
+ cxgb4_ptp.o cxgb4_tc_flower.o
cxgb4-$(CONFIG_CHELSIO_T4_DCB) += cxgb4_dcb.o
cxgb4-$(CONFIG_CHELSIO_T4_FCOE) += cxgb4_fcoe.o
cxgb4-$(CONFIG_DEBUG_FS) += cxgb4_debugfs.o
diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c
index 92d9d795d874..8923affbdaf8 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c
+++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c
@@ -79,6 +79,7 @@
#include "l2t.h"
#include "sched.h"
#include "cxgb4_tc_u32.h"
+#include "cxgb4_tc_flower.h"
#include "cxgb4_ptp.h"
char cxgb4_driver_name[] = KBUILD_MODNAME;
@@ -2873,6 +2874,25 @@ static int cxgb_set_tx_maxrate(struct net_device *dev, int index, u32 rate)
return err;
}
+static int cxgb_setup_tc_flower(struct net_device *dev,
+ struct tc_cls_flower_offload *cls_flower)
+{
+ if (!is_classid_clsact_ingress(cls_flower->common.classid) ||
+ cls_flower->common.chain_index)
+ return -EOPNOTSUPP;
+
+ switch (cls_flower->command) {
+ case TC_CLSFLOWER_REPLACE:
+ return cxgb4_tc_flower_replace(dev, cls_flower);
+ case TC_CLSFLOWER_DESTROY:
+ return cxgb4_tc_flower_destroy(dev, cls_flower);
+ case TC_CLSFLOWER_STATS:
+ return cxgb4_tc_flower_stats(dev, cls_flower);
+ default:
+ return -EOPNOTSUPP;
+ }
+}
+
static int cxgb_setup_tc_cls_u32(struct net_device *dev,
struct tc_cls_u32_offload *cls_u32)
{
@@ -2907,6 +2927,8 @@ static int cxgb_setup_tc(struct net_device *dev, enum tc_setup_type type,
switch (type) {
case TC_SETUP_CLSU32:
return cxgb_setup_tc_cls_u32(dev, type_data);
+ case TC_SETUP_CLSFLOWER:
+ return cxgb_setup_tc_flower(dev, type_data);
default:
return -EOPNOTSUPP;
}
diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_tc_flower.c b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_tc_flower.c
new file mode 100644
index 000000000000..16dff71e4d02
--- /dev/null
+++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_tc_flower.c
@@ -0,0 +1,57 @@
+/*
+ * This file is part of the Chelsio T4/T5/T6 Ethernet driver for Linux.
+ *
+ * Copyright (c) 2017 Chelsio Communications, Inc. All rights reserved.
+ *
+ * This software is available to you under a choice of one of two
+ * licenses. You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the
+ * OpenIB.org BSD license below:
+ *
+ * Redistribution and use in source and binary forms, with or
+ * without modification, are permitted provided that the following
+ * conditions are met:
+ *
+ * - Redistributions of source code must retain the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer.
+ *
+ * - Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#include <net/tc_act/tc_gact.h>
+#include <net/tc_act/tc_mirred.h>
+
+#include "cxgb4.h"
+#include "cxgb4_tc_flower.h"
+
+int cxgb4_tc_flower_replace(struct net_device *dev,
+ struct tc_cls_flower_offload *cls)
+{
+ return -EOPNOTSUPP;
+}
+
+int cxgb4_tc_flower_destroy(struct net_device *dev,
+ struct tc_cls_flower_offload *cls)
+{
+ return -EOPNOTSUPP;
+}
+
+int cxgb4_tc_flower_stats(struct net_device *dev,
+ struct tc_cls_flower_offload *cls)
+{
+ return -EOPNOTSUPP;
+}
diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_tc_flower.h b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_tc_flower.h
new file mode 100644
index 000000000000..b321fc205b5a
--- /dev/null
+++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_tc_flower.h
@@ -0,0 +1,46 @@
+/*
+ * This file is part of the Chelsio T4/T5/T6 Ethernet driver for Linux.
+ *
+ * Copyright (c) 2017 Chelsio Communications, Inc. All rights reserved.
+ *
+ * This software is available to you under a choice of one of two
+ * licenses. You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the
+ * OpenIB.org BSD license below:
+ *
+ * Redistribution and use in source and binary forms, with or
+ * without modification, are permitted provided that the following
+ * conditions are met:
+ *
+ * - Redistributions of source code must retain the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer.
+ *
+ * - Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#ifndef __CXGB4_TC_FLOWER_H
+#define __CXGB4_TC_FLOWER_H
+
+#include <net/pkt_cls.h>
+
+int cxgb4_tc_flower_replace(struct net_device *dev,
+ struct tc_cls_flower_offload *cls);
+int cxgb4_tc_flower_destroy(struct net_device *dev,
+ struct tc_cls_flower_offload *cls);
+int cxgb4_tc_flower_stats(struct net_device *dev,
+ struct tc_cls_flower_offload *cls);
+#endif /* __CXGB4_TC_FLOWER_H */
--
2.14.1
^ permalink raw reply related
* [PATCH net-next v2 2/4] cxgb4: add basic tc flower offload support
From: Rahul Lakkireddy @ 2017-09-21 18:11 UTC (permalink / raw)
To: netdev; +Cc: davem, kumaras, ganeshgr, nirranjan, indranil, Rahul Lakkireddy
In-Reply-To: <cover.1506015856.git.rahul.lakkireddy@chelsio.com>
From: Kumar Sanghvi <kumaras@chelsio.com>
Add support to add/remove flows for offload. Following match
and action are supported for offloading a flow:
Match: ether-protocol, IPv4/IPv6 addresses, L4 ports (TCP/UDP)
Action: drop, redirect to another port on the device.
The qualifying flows can have accompanying mask information.
Signed-off-by: Kumar Sanghvi <kumaras@chelsio.com>
Signed-off-by: Rahul Lakkireddy <rahul.lakkireddy@chelsio.com>
Signed-off-by: Ganesh Goudar <ganeshgr@chelsio.com>
---
v2:
- Setting ftid to -1 not required after bitmap_find_free_region
in cxgb4_get_free_ftid.
- Direct return can be used as jumping to error path is not needed
if flower entry allocation failed in cxgb4_tc_flower_replace.
Same applies if flower entry not found in cxgb4_tc_flower_destroy.
- Also, removed an extra return from cxgb4_tc_flower_destroy.
drivers/net/ethernet/chelsio/cxgb4/cxgb4.h | 3 +
drivers/net/ethernet/chelsio/cxgb4/cxgb4_filter.c | 24 ++
drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c | 2 +
.../net/ethernet/chelsio/cxgb4/cxgb4_tc_flower.c | 280 ++++++++++++++++++++-
.../net/ethernet/chelsio/cxgb4/cxgb4_tc_flower.h | 17 ++
drivers/net/ethernet/chelsio/cxgb4/cxgb4_uld.h | 1 +
6 files changed, 325 insertions(+), 2 deletions(-)
diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h b/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h
index ea72d2d2e1b4..26eac599ab2c 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h
+++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h
@@ -904,6 +904,9 @@ struct adapter {
/* TC u32 offload */
struct cxgb4_tc_u32_table *tc_u32;
struct chcr_stats_debug chcr_stats;
+
+ /* TC flower offload */
+ DECLARE_HASHTABLE(flower_anymatch_tbl, 9);
};
/* Support for "sched-class" command to allow a TX Scheduling Class to be
diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_filter.c b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_filter.c
index 45b5853ca2f1..a1f644eb0cec 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_filter.c
+++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_filter.c
@@ -148,6 +148,30 @@ static int get_filter_steerq(struct net_device *dev,
return iq;
}
+int cxgb4_get_free_ftid(struct net_device *dev, int family)
+{
+ struct adapter *adap = netdev2adap(dev);
+ struct tid_info *t = &adap->tids;
+ int ftid;
+
+ spin_lock_bh(&t->ftid_lock);
+ if (family == PF_INET) {
+ ftid = find_first_zero_bit(t->ftid_bmap, t->nftids);
+ if (ftid >= t->nftids)
+ ftid = -1;
+ } else {
+ ftid = bitmap_find_free_region(t->ftid_bmap, t->nftids, 2);
+ if (ftid < 0)
+ goto out_unlock;
+
+ /* this is only a lookup, keep the found region unallocated */
+ bitmap_release_region(t->ftid_bmap, ftid, 2);
+ }
+out_unlock:
+ spin_unlock_bh(&t->ftid_lock);
+ return ftid;
+}
+
static int cxgb4_set_ftid(struct tid_info *t, int fidx, int family)
{
spin_lock_bh(&t->ftid_lock);
diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c
index 8923affbdaf8..3ba4e1ff8486 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c
+++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c
@@ -5105,6 +5105,8 @@ static int init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
if (!adapter->tc_u32)
dev_warn(&pdev->dev,
"could not offload tc u32, continuing\n");
+
+ cxgb4_init_tc_flower(adapter);
}
if (is_offload(adapter)) {
diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_tc_flower.c b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_tc_flower.c
index 16dff71e4d02..dda34d5a52fb 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_tc_flower.c
+++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_tc_flower.c
@@ -38,16 +38,287 @@
#include "cxgb4.h"
#include "cxgb4_tc_flower.h"
+static struct ch_tc_flower_entry *allocate_flower_entry(void)
+{
+ struct ch_tc_flower_entry *new = kzalloc(sizeof(*new), GFP_KERNEL);
+ return new;
+}
+
+/* Must be called with either RTNL or rcu_read_lock */
+static struct ch_tc_flower_entry *ch_flower_lookup(struct adapter *adap,
+ unsigned long flower_cookie)
+{
+ struct ch_tc_flower_entry *flower_entry;
+
+ hash_for_each_possible_rcu(adap->flower_anymatch_tbl, flower_entry,
+ link, flower_cookie)
+ if (flower_entry->tc_flower_cookie == flower_cookie)
+ return flower_entry;
+ return NULL;
+}
+
+static void cxgb4_process_flow_match(struct net_device *dev,
+ struct tc_cls_flower_offload *cls,
+ struct ch_filter_specification *fs)
+{
+ u16 addr_type = 0;
+
+ if (dissector_uses_key(cls->dissector, FLOW_DISSECTOR_KEY_CONTROL)) {
+ struct flow_dissector_key_control *key =
+ skb_flow_dissector_target(cls->dissector,
+ FLOW_DISSECTOR_KEY_CONTROL,
+ cls->key);
+
+ addr_type = key->addr_type;
+ }
+
+ if (dissector_uses_key(cls->dissector, FLOW_DISSECTOR_KEY_BASIC)) {
+ struct flow_dissector_key_basic *key =
+ skb_flow_dissector_target(cls->dissector,
+ FLOW_DISSECTOR_KEY_BASIC,
+ cls->key);
+ struct flow_dissector_key_basic *mask =
+ skb_flow_dissector_target(cls->dissector,
+ FLOW_DISSECTOR_KEY_BASIC,
+ cls->mask);
+ u16 ethtype_key = ntohs(key->n_proto);
+ u16 ethtype_mask = ntohs(mask->n_proto);
+
+ if (ethtype_key == ETH_P_ALL) {
+ ethtype_key = 0;
+ ethtype_mask = 0;
+ }
+
+ fs->val.ethtype = ethtype_key;
+ fs->mask.ethtype = ethtype_mask;
+ fs->val.proto = key->ip_proto;
+ fs->mask.proto = mask->ip_proto;
+ }
+
+ if (addr_type == FLOW_DISSECTOR_KEY_IPV4_ADDRS) {
+ struct flow_dissector_key_ipv4_addrs *key =
+ skb_flow_dissector_target(cls->dissector,
+ FLOW_DISSECTOR_KEY_IPV4_ADDRS,
+ cls->key);
+ struct flow_dissector_key_ipv4_addrs *mask =
+ skb_flow_dissector_target(cls->dissector,
+ FLOW_DISSECTOR_KEY_IPV4_ADDRS,
+ cls->mask);
+ fs->type = 0;
+ memcpy(&fs->val.lip[0], &key->dst, sizeof(key->dst));
+ memcpy(&fs->val.fip[0], &key->src, sizeof(key->src));
+ memcpy(&fs->mask.lip[0], &mask->dst, sizeof(mask->dst));
+ memcpy(&fs->mask.fip[0], &mask->src, sizeof(mask->src));
+ }
+
+ if (addr_type == FLOW_DISSECTOR_KEY_IPV6_ADDRS) {
+ struct flow_dissector_key_ipv6_addrs *key =
+ skb_flow_dissector_target(cls->dissector,
+ FLOW_DISSECTOR_KEY_IPV6_ADDRS,
+ cls->key);
+ struct flow_dissector_key_ipv6_addrs *mask =
+ skb_flow_dissector_target(cls->dissector,
+ FLOW_DISSECTOR_KEY_IPV6_ADDRS,
+ cls->mask);
+
+ fs->type = 1;
+ memcpy(&fs->val.lip[0], key->dst.s6_addr, sizeof(key->dst));
+ memcpy(&fs->val.fip[0], key->src.s6_addr, sizeof(key->src));
+ memcpy(&fs->mask.lip[0], mask->dst.s6_addr, sizeof(mask->dst));
+ memcpy(&fs->mask.fip[0], mask->src.s6_addr, sizeof(mask->src));
+ }
+
+ if (dissector_uses_key(cls->dissector, FLOW_DISSECTOR_KEY_PORTS)) {
+ struct flow_dissector_key_ports *key, *mask;
+
+ key = skb_flow_dissector_target(cls->dissector,
+ FLOW_DISSECTOR_KEY_PORTS,
+ cls->key);
+ mask = skb_flow_dissector_target(cls->dissector,
+ FLOW_DISSECTOR_KEY_PORTS,
+ cls->mask);
+ fs->val.lport = cpu_to_be16(key->dst);
+ fs->mask.lport = cpu_to_be16(mask->dst);
+ fs->val.fport = cpu_to_be16(key->src);
+ fs->mask.fport = cpu_to_be16(mask->src);
+ }
+
+ /* Match only packets coming from the ingress port where this
+ * filter will be created.
+ */
+ fs->val.iport = netdev2pinfo(dev)->port_id;
+ fs->mask.iport = ~0;
+}
+
+static int cxgb4_validate_flow_match(struct net_device *dev,
+ struct tc_cls_flower_offload *cls)
+{
+ if (cls->dissector->used_keys &
+ ~(BIT(FLOW_DISSECTOR_KEY_CONTROL) |
+ BIT(FLOW_DISSECTOR_KEY_BASIC) |
+ BIT(FLOW_DISSECTOR_KEY_IPV4_ADDRS) |
+ BIT(FLOW_DISSECTOR_KEY_IPV6_ADDRS) |
+ BIT(FLOW_DISSECTOR_KEY_PORTS))) {
+ netdev_warn(dev, "Unsupported key used: 0x%x\n",
+ cls->dissector->used_keys);
+ return -EOPNOTSUPP;
+ }
+ return 0;
+}
+
+static void cxgb4_process_flow_actions(struct net_device *in,
+ struct tc_cls_flower_offload *cls,
+ struct ch_filter_specification *fs)
+{
+ const struct tc_action *a;
+ LIST_HEAD(actions);
+
+ tcf_exts_to_list(cls->exts, &actions);
+ list_for_each_entry(a, &actions, list) {
+ if (is_tcf_gact_shot(a)) {
+ fs->action = FILTER_DROP;
+ } else if (is_tcf_mirred_egress_redirect(a)) {
+ int ifindex = tcf_mirred_ifindex(a);
+ struct net_device *out = __dev_get_by_index(dev_net(in),
+ ifindex);
+ struct port_info *pi = netdev_priv(out);
+
+ fs->action = FILTER_SWITCH;
+ fs->eport = pi->port_id;
+ }
+ }
+}
+
+static int cxgb4_validate_flow_actions(struct net_device *dev,
+ struct tc_cls_flower_offload *cls)
+{
+ const struct tc_action *a;
+ LIST_HEAD(actions);
+
+ tcf_exts_to_list(cls->exts, &actions);
+ list_for_each_entry(a, &actions, list) {
+ if (is_tcf_gact_shot(a)) {
+ /* Do nothing */
+ } else if (is_tcf_mirred_egress_redirect(a)) {
+ struct adapter *adap = netdev2adap(dev);
+ struct net_device *n_dev;
+ unsigned int i, ifindex;
+ bool found = false;
+
+ ifindex = tcf_mirred_ifindex(a);
+ for_each_port(adap, i) {
+ n_dev = adap->port[i];
+ if (ifindex == n_dev->ifindex) {
+ found = true;
+ break;
+ }
+ }
+
+ /* If interface doesn't belong to our hw, then
+ * the provided output port is not valid
+ */
+ if (!found) {
+ netdev_err(dev, "%s: Out port invalid\n",
+ __func__);
+ return -EINVAL;
+ }
+ } else {
+ netdev_err(dev, "%s: Unsupported action\n", __func__);
+ return -EOPNOTSUPP;
+ }
+ }
+ return 0;
+}
+
int cxgb4_tc_flower_replace(struct net_device *dev,
struct tc_cls_flower_offload *cls)
{
- return -EOPNOTSUPP;
+ struct adapter *adap = netdev2adap(dev);
+ struct ch_tc_flower_entry *ch_flower;
+ struct ch_filter_specification *fs;
+ struct filter_ctx ctx;
+ int fidx;
+ int ret;
+
+ if (cxgb4_validate_flow_actions(dev, cls))
+ return -EOPNOTSUPP;
+
+ if (cxgb4_validate_flow_match(dev, cls))
+ return -EOPNOTSUPP;
+
+ ch_flower = allocate_flower_entry();
+ if (!ch_flower) {
+ netdev_err(dev, "%s: ch_flower alloc failed.\n", __func__);
+ return -ENOMEM;
+ }
+
+ fs = &ch_flower->fs;
+ fs->hitcnts = 1;
+ cxgb4_process_flow_actions(dev, cls, fs);
+ cxgb4_process_flow_match(dev, cls, fs);
+
+ fidx = cxgb4_get_free_ftid(dev, fs->type ? PF_INET6 : PF_INET);
+ if (fidx < 0) {
+ netdev_err(dev, "%s: No fidx for offload.\n", __func__);
+ ret = -ENOMEM;
+ goto free_entry;
+ }
+
+ init_completion(&ctx.completion);
+ ret = __cxgb4_set_filter(dev, fidx, fs, &ctx);
+ if (ret) {
+ netdev_err(dev, "%s: filter creation err %d\n",
+ __func__, ret);
+ goto free_entry;
+ }
+
+ /* Wait for reply */
+ ret = wait_for_completion_timeout(&ctx.completion, 10 * HZ);
+ if (!ret) {
+ ret = -ETIMEDOUT;
+ goto free_entry;
+ }
+
+ ret = ctx.result;
+ /* Check if hw returned error for filter creation */
+ if (ret) {
+ netdev_err(dev, "%s: filter creation err %d\n",
+ __func__, ret);
+ goto free_entry;
+ }
+
+ INIT_HLIST_NODE(&ch_flower->link);
+ ch_flower->tc_flower_cookie = cls->cookie;
+ ch_flower->filter_id = ctx.tid;
+ hash_add_rcu(adap->flower_anymatch_tbl, &ch_flower->link, cls->cookie);
+
+ return ret;
+
+free_entry:
+ kfree(ch_flower);
+ return ret;
}
int cxgb4_tc_flower_destroy(struct net_device *dev,
struct tc_cls_flower_offload *cls)
{
- return -EOPNOTSUPP;
+ struct adapter *adap = netdev2adap(dev);
+ struct ch_tc_flower_entry *ch_flower;
+ int ret;
+
+ ch_flower = ch_flower_lookup(adap, cls->cookie);
+ if (!ch_flower)
+ return -ENOENT;
+
+ ret = cxgb4_del_filter(dev, ch_flower->filter_id);
+ if (ret)
+ goto err;
+
+ hash_del_rcu(&ch_flower->link);
+ kfree_rcu(ch_flower, rcu);
+
+err:
+ return ret;
}
int cxgb4_tc_flower_stats(struct net_device *dev,
@@ -55,3 +326,8 @@ int cxgb4_tc_flower_stats(struct net_device *dev,
{
return -EOPNOTSUPP;
}
+
+void cxgb4_init_tc_flower(struct adapter *adap)
+{
+ hash_init(adap->flower_anymatch_tbl);
+}
diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_tc_flower.h b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_tc_flower.h
index b321fc205b5a..6145a9e056eb 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_tc_flower.h
+++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_tc_flower.h
@@ -37,10 +37,27 @@
#include <net/pkt_cls.h>
+struct ch_tc_flower_stats {
+ u64 packet_count;
+ u64 byte_count;
+ u64 last_used;
+};
+
+struct ch_tc_flower_entry {
+ struct ch_filter_specification fs;
+ struct ch_tc_flower_stats stats;
+ unsigned long tc_flower_cookie;
+ struct hlist_node link;
+ struct rcu_head rcu;
+ u32 filter_id;
+};
+
int cxgb4_tc_flower_replace(struct net_device *dev,
struct tc_cls_flower_offload *cls);
int cxgb4_tc_flower_destroy(struct net_device *dev,
struct tc_cls_flower_offload *cls);
int cxgb4_tc_flower_stats(struct net_device *dev,
struct tc_cls_flower_offload *cls);
+
+void cxgb4_init_tc_flower(struct adapter *adap);
#endif /* __CXGB4_TC_FLOWER_H */
diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_uld.h b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_uld.h
index 84541fce94c5..88487095d14f 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_uld.h
+++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_uld.h
@@ -212,6 +212,7 @@ struct filter_ctx {
struct ch_filter_specification;
+int cxgb4_get_free_ftid(struct net_device *dev, int family);
int __cxgb4_set_filter(struct net_device *dev, int filter_id,
struct ch_filter_specification *fs,
struct filter_ctx *ctx);
--
2.14.1
^ permalink raw reply related
* [PATCH net-next v2 3/4] cxgb4: add support to offload action vlan
From: Rahul Lakkireddy @ 2017-09-21 18:11 UTC (permalink / raw)
To: netdev; +Cc: davem, kumaras, ganeshgr, nirranjan, indranil, Rahul Lakkireddy
In-Reply-To: <cover.1506015856.git.rahul.lakkireddy@chelsio.com>
From: Kumar Sanghvi <kumaras@chelsio.com>
Add support for offloading tc-flower flows having
vlan actions: pop, push and modify.
Signed-off-by: Kumar Sanghvi <kumaras@chelsio.com>
Signed-off-by: Rahul Lakkireddy <rahul.lakkireddy@chelsio.com>
Signed-off-by: Ganesh Goudar <ganeshgr@chelsio.com>
---
v2:
- Avoid wrapping line for netdev_err message. Also, use
consistent error message string.
.../net/ethernet/chelsio/cxgb4/cxgb4_tc_flower.c | 42 ++++++++++++++++++++++
1 file changed, 42 insertions(+)
diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_tc_flower.c b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_tc_flower.c
index dda34d5a52fb..e42d2efc9ea2 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_tc_flower.c
+++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_tc_flower.c
@@ -34,6 +34,7 @@
#include <net/tc_act/tc_gact.h>
#include <net/tc_act/tc_mirred.h>
+#include <net/tc_act/tc_vlan.h>
#include "cxgb4.h"
#include "cxgb4_tc_flower.h"
@@ -185,6 +186,27 @@ static void cxgb4_process_flow_actions(struct net_device *in,
fs->action = FILTER_SWITCH;
fs->eport = pi->port_id;
+ } else if (is_tcf_vlan(a)) {
+ u32 vlan_action = tcf_vlan_action(a);
+ u8 prio = tcf_vlan_push_prio(a);
+ u16 vid = tcf_vlan_push_vid(a);
+ u16 vlan_tci = (prio << VLAN_PRIO_SHIFT) | vid;
+
+ switch (vlan_action) {
+ case TCA_VLAN_ACT_POP:
+ fs->newvlan |= VLAN_REMOVE;
+ break;
+ case TCA_VLAN_ACT_PUSH:
+ fs->newvlan |= VLAN_INSERT;
+ fs->vlan = vlan_tci;
+ break;
+ case TCA_VLAN_ACT_MODIFY:
+ fs->newvlan |= VLAN_REWRITE;
+ fs->vlan = vlan_tci;
+ break;
+ default:
+ break;
+ }
}
}
}
@@ -222,6 +244,26 @@ static int cxgb4_validate_flow_actions(struct net_device *dev,
__func__);
return -EINVAL;
}
+ } else if (is_tcf_vlan(a)) {
+ u16 proto = be16_to_cpu(tcf_vlan_push_proto(a));
+ u32 vlan_action = tcf_vlan_action(a);
+
+ switch (vlan_action) {
+ case TCA_VLAN_ACT_POP:
+ break;
+ case TCA_VLAN_ACT_PUSH:
+ case TCA_VLAN_ACT_MODIFY:
+ if (proto != ETH_P_8021Q) {
+ netdev_err(dev, "%s: Unsupported vlan proto\n",
+ __func__);
+ return -EOPNOTSUPP;
+ }
+ break;
+ default:
+ netdev_err(dev, "%s: Unsupported vlan action\n",
+ __func__);
+ return -EOPNOTSUPP;
+ }
} else {
netdev_err(dev, "%s: Unsupported action\n", __func__);
return -EOPNOTSUPP;
--
2.14.1
^ permalink raw reply related
* [PATCH net-next v2 4/4] cxgb4: fetch stats for offloaded tc flower flows
From: Rahul Lakkireddy @ 2017-09-21 18:11 UTC (permalink / raw)
To: netdev; +Cc: davem, kumaras, ganeshgr, nirranjan, indranil, Rahul Lakkireddy
In-Reply-To: <cover.1506015856.git.rahul.lakkireddy@chelsio.com>
From: Kumar Sanghvi <kumaras@chelsio.com>
Add support to retrieve stats from hardware for offloaded tc flower
flows. Also, poll for the stats of offloaded flows via timer callback.
Signed-off-by: Kumar Sanghvi <kumaras@chelsio.com>
Signed-off-by: Rahul Lakkireddy <rahul.lakkireddy@chelsio.com>
Signed-off-by: Ganesh Goudar <ganeshgr@chelsio.com>
---
v2:
- No changes.
drivers/net/ethernet/chelsio/cxgb4/cxgb4.h | 1 +
drivers/net/ethernet/chelsio/cxgb4/cxgb4_filter.c | 76 +++++++++++++++++++++
drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c | 1 +
.../net/ethernet/chelsio/cxgb4/cxgb4_tc_flower.c | 79 +++++++++++++++++++++-
.../net/ethernet/chelsio/cxgb4/cxgb4_tc_flower.h | 3 +
drivers/net/ethernet/chelsio/cxgb4/cxgb4_uld.h | 2 +
6 files changed, 161 insertions(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h b/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h
index 26eac599ab2c..8a94d97df025 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h
+++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h
@@ -907,6 +907,7 @@ struct adapter {
/* TC flower offload */
DECLARE_HASHTABLE(flower_anymatch_tbl, 9);
+ struct timer_list flower_stats_timer;
};
/* Support for "sched-class" command to allow a TX Scheduling Class to be
diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_filter.c b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_filter.c
index a1f644eb0cec..bdedf3dce51a 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_filter.c
+++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_filter.c
@@ -148,6 +148,82 @@ static int get_filter_steerq(struct net_device *dev,
return iq;
}
+static int get_filter_count(struct adapter *adapter, unsigned int fidx,
+ u64 *pkts, u64 *bytes)
+{
+ unsigned int tcb_base, tcbaddr;
+ unsigned int word_offset;
+ struct filter_entry *f;
+ __be64 be64_byte_count;
+ int ret;
+
+ tcb_base = t4_read_reg(adapter, TP_CMM_TCB_BASE_A);
+ if ((fidx != (adapter->tids.nftids + adapter->tids.nsftids - 1)) &&
+ fidx >= adapter->tids.nftids)
+ return -E2BIG;
+
+ f = &adapter->tids.ftid_tab[fidx];
+ if (!f->valid)
+ return -EINVAL;
+
+ tcbaddr = tcb_base + f->tid * TCB_SIZE;
+
+ spin_lock(&adapter->win0_lock);
+ if (is_t4(adapter->params.chip)) {
+ __be64 be64_count;
+
+ /* T4 doesn't maintain byte counts in hw */
+ *bytes = 0;
+
+ /* Get pkts */
+ word_offset = 4;
+ ret = t4_memory_rw(adapter, MEMWIN_NIC, MEM_EDC0,
+ tcbaddr + (word_offset * sizeof(__be32)),
+ sizeof(be64_count),
+ (__be32 *)&be64_count,
+ T4_MEMORY_READ);
+ if (ret < 0)
+ goto out;
+ *pkts = be64_to_cpu(be64_count);
+ } else {
+ __be32 be32_count;
+
+ /* Get bytes */
+ word_offset = 4;
+ ret = t4_memory_rw(adapter, MEMWIN_NIC, MEM_EDC0,
+ tcbaddr + (word_offset * sizeof(__be32)),
+ sizeof(be64_byte_count),
+ &be64_byte_count,
+ T4_MEMORY_READ);
+ if (ret < 0)
+ goto out;
+ *bytes = be64_to_cpu(be64_byte_count);
+
+ /* Get pkts */
+ word_offset = 6;
+ ret = t4_memory_rw(adapter, MEMWIN_NIC, MEM_EDC0,
+ tcbaddr + (word_offset * sizeof(__be32)),
+ sizeof(be32_count),
+ &be32_count,
+ T4_MEMORY_READ);
+ if (ret < 0)
+ goto out;
+ *pkts = (u64)be32_to_cpu(be32_count);
+ }
+
+out:
+ spin_unlock(&adapter->win0_lock);
+ return ret;
+}
+
+int cxgb4_get_filter_counters(struct net_device *dev, unsigned int fidx,
+ u64 *hitcnt, u64 *bytecnt)
+{
+ struct adapter *adapter = netdev2adap(dev);
+
+ return get_filter_count(adapter, fidx, hitcnt, bytecnt);
+}
+
int cxgb4_get_free_ftid(struct net_device *dev, int family)
{
struct adapter *adap = netdev2adap(dev);
diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c
index 3ba4e1ff8486..d634098d52ab 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c
+++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c
@@ -4637,6 +4637,7 @@ static void free_some_resources(struct adapter *adapter)
kvfree(adapter->l2t);
t4_cleanup_sched(adapter);
kvfree(adapter->tids.tid_tab);
+ cxgb4_cleanup_tc_flower(adapter);
cxgb4_cleanup_tc_u32(adapter);
kfree(adapter->sge.egr_map);
kfree(adapter->sge.ingr_map);
diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_tc_flower.c b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_tc_flower.c
index e42d2efc9ea2..a36bd66d2834 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_tc_flower.c
+++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_tc_flower.c
@@ -39,9 +39,12 @@
#include "cxgb4.h"
#include "cxgb4_tc_flower.h"
+#define STATS_CHECK_PERIOD (HZ / 2)
+
static struct ch_tc_flower_entry *allocate_flower_entry(void)
{
struct ch_tc_flower_entry *new = kzalloc(sizeof(*new), GFP_KERNEL);
+ spin_lock_init(&new->lock);
return new;
}
@@ -363,13 +366,87 @@ int cxgb4_tc_flower_destroy(struct net_device *dev,
return ret;
}
+void ch_flower_stats_cb(unsigned long data)
+{
+ struct adapter *adap = (struct adapter *)data;
+ struct ch_tc_flower_entry *flower_entry;
+ struct ch_tc_flower_stats *ofld_stats;
+ unsigned int i;
+ u64 packets;
+ u64 bytes;
+ int ret;
+
+ rcu_read_lock();
+ hash_for_each_rcu(adap->flower_anymatch_tbl, i, flower_entry, link) {
+ ret = cxgb4_get_filter_counters(adap->port[0],
+ flower_entry->filter_id,
+ &packets, &bytes);
+ if (!ret) {
+ spin_lock(&flower_entry->lock);
+ ofld_stats = &flower_entry->stats;
+
+ if (ofld_stats->prev_packet_count != packets) {
+ ofld_stats->prev_packet_count = packets;
+ ofld_stats->last_used = jiffies;
+ }
+ spin_unlock(&flower_entry->lock);
+ }
+ }
+ rcu_read_unlock();
+ mod_timer(&adap->flower_stats_timer, jiffies + STATS_CHECK_PERIOD);
+}
+
int cxgb4_tc_flower_stats(struct net_device *dev,
struct tc_cls_flower_offload *cls)
{
- return -EOPNOTSUPP;
+ struct adapter *adap = netdev2adap(dev);
+ struct ch_tc_flower_stats *ofld_stats;
+ struct ch_tc_flower_entry *ch_flower;
+ u64 packets;
+ u64 bytes;
+ int ret;
+
+ ch_flower = ch_flower_lookup(adap, cls->cookie);
+ if (!ch_flower) {
+ ret = -ENOENT;
+ goto err;
+ }
+
+ ret = cxgb4_get_filter_counters(dev, ch_flower->filter_id,
+ &packets, &bytes);
+ if (ret < 0)
+ goto err;
+
+ spin_lock_bh(&ch_flower->lock);
+ ofld_stats = &ch_flower->stats;
+ if (ofld_stats->packet_count != packets) {
+ if (ofld_stats->prev_packet_count != packets)
+ ofld_stats->last_used = jiffies;
+ tcf_exts_stats_update(cls->exts, bytes - ofld_stats->byte_count,
+ packets - ofld_stats->packet_count,
+ ofld_stats->last_used);
+
+ ofld_stats->packet_count = packets;
+ ofld_stats->byte_count = bytes;
+ ofld_stats->prev_packet_count = packets;
+ }
+ spin_unlock_bh(&ch_flower->lock);
+ return 0;
+
+err:
+ return ret;
}
void cxgb4_init_tc_flower(struct adapter *adap)
{
hash_init(adap->flower_anymatch_tbl);
+ setup_timer(&adap->flower_stats_timer, ch_flower_stats_cb,
+ (unsigned long)adap);
+ mod_timer(&adap->flower_stats_timer, jiffies + STATS_CHECK_PERIOD);
+}
+
+void cxgb4_cleanup_tc_flower(struct adapter *adap)
+{
+ if (adap->flower_stats_timer.function)
+ del_timer_sync(&adap->flower_stats_timer);
}
diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_tc_flower.h b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_tc_flower.h
index 6145a9e056eb..604feffc752e 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_tc_flower.h
+++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_tc_flower.h
@@ -38,6 +38,7 @@
#include <net/pkt_cls.h>
struct ch_tc_flower_stats {
+ u64 prev_packet_count;
u64 packet_count;
u64 byte_count;
u64 last_used;
@@ -49,6 +50,7 @@ struct ch_tc_flower_entry {
unsigned long tc_flower_cookie;
struct hlist_node link;
struct rcu_head rcu;
+ spinlock_t lock; /* lock for stats */
u32 filter_id;
};
@@ -60,4 +62,5 @@ int cxgb4_tc_flower_stats(struct net_device *dev,
struct tc_cls_flower_offload *cls);
void cxgb4_init_tc_flower(struct adapter *adap);
+void cxgb4_cleanup_tc_flower(struct adapter *adap);
#endif /* __CXGB4_TC_FLOWER_H */
diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_uld.h b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_uld.h
index 88487095d14f..52324c77a4fe 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_uld.h
+++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_uld.h
@@ -221,6 +221,8 @@ int __cxgb4_del_filter(struct net_device *dev, int filter_id,
int cxgb4_set_filter(struct net_device *dev, int filter_id,
struct ch_filter_specification *fs);
int cxgb4_del_filter(struct net_device *dev, int filter_id);
+int cxgb4_get_filter_counters(struct net_device *dev, unsigned int fidx,
+ u64 *hitcnt, u64 *bytecnt);
static inline void set_wr_txq(struct sk_buff *skb, int prio, int queue)
{
--
2.14.1
^ permalink raw reply related
* [PATCH iproute2] man: fix documentation for range of route table ID
From: Thomas Haller @ 2017-09-21 18:14 UTC (permalink / raw)
To: Stephen Hemminger, netdev; +Cc: Thomas Haller
Signed-off-by: Thomas Haller <thaller@redhat.com>
---
man/man8/ip-route.8.in | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/man/man8/ip-route.8.in b/man/man8/ip-route.8.in
index 803de3b9..9717b959 100644
--- a/man/man8/ip-route.8.in
+++ b/man/man8/ip-route.8.in
@@ -322,7 +322,7 @@ normal routing tables.
.P
.B Route tables:
Linux-2.x can pack routes into several routing tables identified
-by a number in the range from 1 to 2^31 or by name from the file
+by a number in the range from 0 to 2^32-1 or by name from the file
.B @SYSCONFDIR@/rt_tables
By default all normal routes are inserted into the
.B main
--
2.13.5
^ permalink raw reply related
* Re: usb/net/p54: trying to register non-static key in p54_unregister_leds
From: Andrey Konovalov @ 2017-09-21 18:22 UTC (permalink / raw)
To: Johannes Berg
Cc: Christian Lamparter, Kalle Valo, linux-wireless, netdev, LKML,
Dmitry Vyukov, Kostya Serebryany, syzkaller, Stephen Boyd,
Tejun Heo, Yong Zhang
In-Reply-To: <1505937307.3026.20.camel@sipsolutions.net>
On Wed, Sep 20, 2017 at 9:55 PM, Johannes Berg
<johannes@sipsolutions.net> wrote:
> On Wed, 2017-09-20 at 21:27 +0200, Christian Lamparter wrote:
>
>> It seems this is caused as a result of:
>> -> lock_map_acquire(&work->lockdep_map);
>> lock_map_release(&work->lockdep_map);
>>
>> in flush_work() [0]
>
> Agree.
>
>> This was added by:
>>
>> commit 0976dfc1d0cd80a4e9dfaf87bd8744612bde475a
>> Author: Stephen Boyd <sboyd@codeaurora.org>
>> Date: Fri Apr 20 17:28:50 2012 -0700
>>
>> workqueue: Catch more locking problems with flush_work()
>
> Yes, but that doesn't matter.
>
>> Looking at the Stephen's patch, it's clear that it was made
>> with "static DECLARE_WORK(work, my_work)" in mind. However
>> p54's led_work is "per-device", hence it is stored in the
>> devices context p54_common, which is dynamically allocated.
>> So, maybe revert Stephen's patch?
>
> I disagree - as the lockdep warning says:
>
>> > INFO: trying to register non-static key.
>> > the code is fine but needs lockdep annotation.
>> > turning off the locking correctness validator.
>
> What it needs is to actually correctly go through initializing the work
> at least once.
>
> Without more information, I can't really say what's going on, but I
> assume that something is failing and p54_unregister_leds() is getting
> invoked without p54_init_leds() having been invoked, so essentially
> it's trying to flush a work that was never initialized?
>
> INIT_DELAYED_WORK() does, after all, initialize the lockdep map
> properly via __INIT_WORK().
Since I'm able to reproduce this, please let me know if you need me to
collect some debug traces to help with the triage.
Thanks!
>
> johannes
>
> --
> You received this message because you are subscribed to the Google Groups "syzkaller" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to syzkaller+unsubscribe@googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.
^ permalink raw reply
* Re: [kernel-hardening] Re: [PATCH v3 03/31] usercopy: Mark kmalloc caches as usercopy caches
From: Kees Cook @ 2017-09-21 18:26 UTC (permalink / raw)
To: Christopher Lameter
Cc: LKML, David Windsor, Pekka Enberg, David Rientjes, Joonsoo Kim,
Andrew Morton, Linux-MM, linux-xfs, linux-fsdevel@vger.kernel.org,
Network Development, kernel-hardening@lists.openwall.com
In-Reply-To: <alpine.DEB.2.20.1709211102320.14742@nuc-kabylake>
On Thu, Sep 21, 2017 at 9:04 AM, Christopher Lameter <cl@linux.com> wrote:
> On Thu, 21 Sep 2017, Kees Cook wrote:
>
>> > So what is the point of this patch?
>>
>> The DMA kmalloc caches are not whitelisted:
>
> The DMA kmalloc caches are pretty obsolete and mostly there for obscure
> drivers.
>
> ??
They may be obsolete, but they're still in the kernel, and they aren't
copied to userspace, so we can mark them.
>> >> kmalloc_dma_caches[i] = create_kmalloc_cache(n,
>> >> - size, SLAB_CACHE_DMA | flags);
>> >> + size, SLAB_CACHE_DMA | flags, 0, 0);
>>
>> So this is creating the distinction between the kmallocs that go to
>> userspace and those that don't. The expectation is that future work
>> can start to distinguish between "for userspace" and "only kernel"
>> kmalloc allocations, as is already done here for DMA.
>
> The creation of the kmalloc caches in earlier patches already setup the
> "whitelisting". Why do it twice?
Patch 1 is to allow for things to mark their whitelists. Patch 30
disables the full whitelisting, since then we've defined them all, so
the kmalloc caches need to mark themselves as whitelisted.
Patch 1 leaves unmarked things whitelisted so we can progressively
tighten the restriction and have a bisectable series. (i.e. if there
is something wrong with one of the whitelists in the series, it will
bisect to that one, not the one that removes the global whitelist from
patch 1.)
-Kees
--
Kees Cook
Pixel Security
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
^ permalink raw reply
* Re: [PATCH iproute2] man: fix documentation for range of route table ID
From: Phil Sutter @ 2017-09-21 18:26 UTC (permalink / raw)
To: Thomas Haller; +Cc: Stephen Hemminger, netdev
In-Reply-To: <20170921181411.17720-1-thaller@redhat.com>
On Thu, Sep 21, 2017 at 08:14:11PM +0200, Thomas Haller wrote:
> Signed-off-by: Thomas Haller <thaller@redhat.com>
Fixes: 4ec1933dfddfc ("Update ip.8 man page to describe route table id values")
(So that bug is over 7 years old. :)
Cheers, Phil
^ permalink raw reply
* Re: [PATCH 1/7] net: qrtr: Invoke sk_error_report() after setting sk_err
From: Chris Lew @ 2017-09-21 18:27 UTC (permalink / raw)
To: Bjorn Andersson, David S. Miller; +Cc: netdev, linux-kernel, linux-arm-msm
In-Reply-To: <20170907060329.32402-2-bjorn.andersson@linaro.org>
On 9/6/2017 11:03 PM, Bjorn Andersson wrote:
> Rather than manually waking up any context sleeping on the sock to
> signal an error we should call sk_error_report(). This has the added
> benefit that in-kernel consumers can override this notificatino with
> its own callback.
>
Typo with notification.
Thanks,
Chris
--
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project
^ permalink raw reply
* Re: [PATCH 00/64] use setup_timer() helper function.
From: David Miller @ 2017-09-21 18:39 UTC (permalink / raw)
To: allen.lkml
Cc: netdev, linux-kernel, m.grzeschik, dmitry.tarnyagin, wg, mkl,
mark.einon, linux, pcnet32, f.fainelli, bcm-kernel-feedback-list,
venza, ajk, jes, romieu, khc, simon, linux-can,
adi-buildroot-devel
In-Reply-To: <1506013525-29291-1-git-send-email-allen.lkml@gmail.com>
From: Allen Pais <allen.lkml@gmail.com>
Date: Thu, 21 Sep 2017 22:34:21 +0530
> This series uses setup_timer() helper function. The series
> addresses the files under drivers/net/*.
I've reviewed this series and will apply it to net-next.
But please send out smaller chunks next time, maybe 10-15
in a bunch? 64 patches at once makes it really hard for
reviewiers.
Thanks.
^ permalink raw reply
* Re: [Patch net] net_sched: remove cls_flower idr on failure
From: Cong Wang @ 2017-09-21 18:47 UTC (permalink / raw)
To: Linux Kernel Network Developers; +Cc: Cong Wang, Chris Mi, Jiri Pirko
In-Reply-To: <20170920161845.28753-1-xiyou.wangcong@gmail.com>
On Wed, Sep 20, 2017 at 9:18 AM, Cong Wang <xiyou.wangcong@gmail.com> wrote:
> +errout_idr:
> + if (fnew->handle)
> + idr_remove_ext(&head->handle_idr, fnew->handle);
Hmm, I should check fold instead of fnew->handle here.
I will update this patch.
^ permalink raw reply
* Re: [Patch net] net_sched: remove cls_flower idr on failure
From: Cong Wang @ 2017-09-21 18:50 UTC (permalink / raw)
To: Linux Kernel Network Developers; +Cc: Cong Wang, Chris Mi, Jiri Pirko
In-Reply-To: <CAM_iQpX2QHqPFJ-vZz+6M4oDW2UgTbYdRuCxtNLm14S4sRVONg@mail.gmail.com>
On Thu, Sep 21, 2017 at 11:47 AM, Cong Wang <xiyou.wangcong@gmail.com> wrote:
> On Wed, Sep 20, 2017 at 9:18 AM, Cong Wang <xiyou.wangcong@gmail.com> wrote:
>> +errout_idr:
>> + if (fnew->handle)
>> + idr_remove_ext(&head->handle_idr, fnew->handle);
>
> Hmm, I should check fold instead of fnew->handle here.
> I will update this patch.
Never mind, it should be the same logic. If fold is non-NULL,
then fnew->handle == 0.
It can be applied as it is.
^ permalink raw reply
* Re: [PATCH net v2] l2tp: fix race condition in l2tp_tunnel_delete
From: David Miller @ 2017-09-21 18:53 UTC (permalink / raw)
To: sd; +Cc: netdev, g.nault, lucien.xin, tparkin
In-Reply-To: <6bfc5aceda47773af4c75fe7e0e3c0d255a2342d.1505828155.git.sd@queasysnail.net>
From: Sabrina Dubroca <sd@queasysnail.net>
Date: Tue, 19 Sep 2017 15:40:40 +0200
> If we try to delete the same tunnel twice, the first delete operation
> does a lookup (l2tp_tunnel_get), finds the tunnel, calls
> l2tp_tunnel_delete, which queues it for deletion by
> l2tp_tunnel_del_work.
>
> The second delete operation also finds the tunnel and calls
> l2tp_tunnel_delete. If the workqueue has already fired and started
> running l2tp_tunnel_del_work, then l2tp_tunnel_delete will queue the
> same tunnel a second time, and try to free the socket again.
>
> Add a dead flag to prevent firing the workqueue twice. Then we can
> remove the check of queue_work's result that was meant to prevent that
> race but doesn't.
>
> Also check the flag in the tunnel lookup functions, to avoid returning a
> tunnel that is already scheduled for destruction.
Sabrina, please respond to Guillaume's feedback.
Thank you.
^ permalink raw reply
* Re: [PATCH] net_sched: always reset qdisc backlog in qdisc_reset()
From: David Miller @ 2017-09-21 18:57 UTC (permalink / raw)
To: khlebnikov; +Cc: netdev, xiyou.wangcong, jiri, jhs
In-Reply-To: <150591153693.113604.8604505743746410801.stgit@buzz>
From: Konstantin Khlebnikov <khlebnikov@yandex-team.ru>
Date: Wed, 20 Sep 2017 15:45:36 +0300
> SKB stored in qdisc->gso_skb also counted into backlog.
>
> Some qdiscs don't reset backlog to zero in ->reset(),
> for example sfq just dequeue and free all queued skb.
>
> Signed-off-by: Konstantin Khlebnikov <khlebnikov@yandex-team.ru>
> Fixes: 2ccccf5fb43f ("net_sched: update hierarchical backlog too")
Applied and queued up for -stable.
^ permalink raw reply
* Re: [PATCH] net_sched/hfsc: fix curve activation in hfsc_change_class()
From: David Miller @ 2017-09-21 18:57 UTC (permalink / raw)
To: khlebnikov; +Cc: netdev, xiyou.wangcong, jiri, jhs
In-Reply-To: <150591157194.113686.4485981339195559372.stgit@buzz>
From: Konstantin Khlebnikov <khlebnikov@yandex-team.ru>
Date: Wed, 20 Sep 2017 15:46:11 +0300
> If real-time or fair-share curves are enabled in hfsc_change_class()
> class isn't inserted into rb-trees yet. Thus init_ed() and init_vf()
> must be called in place of update_ed() and update_vf().
>
> Remove isn't required because for now curves cannot be disabled.
>
> Signed-off-by: Konstantin Khlebnikov <khlebnikov@yandex-team.ru>
Applied.
^ permalink raw reply
* Re: [PATCH v4 0/4] Add cross-compilation support to eBPF samples
From: David Miller @ 2017-09-21 18:59 UTC (permalink / raw)
To: joelaf
Cc: linux-kernel, netdev, alison, juri.lelli, fengc, daniel, ast,
kernel-team
In-Reply-To: <20170920160436.24689-1-joelaf@google.com>
From: Joel Fernandes <joelaf@google.com>
Date: Wed, 20 Sep 2017 09:04:32 -0700
> These patches fix issues seen when cross-compiling eBPF samples on arm64.
> Compared to [1], I dropped the controversial inline-asm patch and exploring
> other options to fix it. However these patches are a step in the right
> direction and I look forward to getting them into -next and the merge window.
>
> Changes since v3:
> - just a repost with acks
>
> [1] https://lkml.org/lkml/2017/8/7/417
Series applied with typo in patch #4 corrected.
Thanks.
^ permalink raw reply
* Re: [PATCH net-next] bpf/verifier: improve disassembly of BPF_END instructions
From: Daniel Borkmann @ 2017-09-21 19:29 UTC (permalink / raw)
To: Edward Cree, Y Song; +Cc: Alexei Starovoitov, David Miller, netdev
In-Reply-To: <207ecd4c-b1b4-3dcd-62a6-30824c19dbf7@solarflare.com>
On 09/21/2017 06:58 PM, Edward Cree wrote:
> On 21/09/17 17:40, Y Song wrote:
>> On Thu, Sep 21, 2017 at 9:24 AM, Edward Cree <ecree@solarflare.com> wrote:
>>> On 21/09/17 16:52, Alexei Starovoitov wrote:
>>>> imo
>>>> (u16) r4 endian be
>>>> isn't intuitive.
>>>> Can we come up with some better syntax?
>>>> Like
>>>> bswap16be r4
>>>> bswap32le r4
>>> Hmm, I don't like these, since bswapbe is a swap on *le* and a nop on be.
Agree, a bit too much 'swap' semantics in the name that could be
confusing perhaps, at least the be/le could be missed easily.
>>>> or
>>>>
>>>> to_be16 r4
>>>> to_le32 r4
>>> And the problem here is that it's not just to_be, it's also from_be.
More intuitive, but agree on the from_be/le. Maybe we should
just drop the "to_" prefix altogether, and leave the rest as is since
it's not surrounded by braces, it's also not a cast but rather an op.
>> Could you explain what is "from_be" here? Do not quite understand.
> Taking the example of a little-endian processor:
> cpu_to_be16() is a byte-swap, converting a u16 (cpu-endian) to a __be16.
> be16_to_cpu(), to convert a __be16 to a u16, is *also* a byte-swap.
> Meanwhile, cpu_to_le16() and le16_to_cpu() are both no-ops.
>
> More generally, the conversions between cpu-endian and fixed-endian for
> any given size are self-inverses. eBPF takes advantage of this by only
> having a single opcode for both the "to" and "from" direction. So to
> specify an endianness conversion, you need only the size and the fixed
> endianness (le or be), not the to/from direction. Conversely, when
> disassembling one of these instructions, you don't know whether it's a
> cpu_to_be16() or a be16_to_cpu(), because they both look the same at an
> instruction level (they only differ in what types the programmer thought
> of the register as holding before and after).
Yeah, exactly to the point. :)
^ permalink raw reply
* Re: [v2,1/3] can: m_can: Make hclk optional
From: Franklin S Cooper Jr @ 2017-09-21 19:35 UTC (permalink / raw)
To: Sekhar Nori, linux-kernel, devicetree, netdev, linux-can, wg, mkl,
robh+dt, quentin.schulz
Cc: Kristo, Tero, Tony Lindgren, Linux OMAP List
In-Reply-To: <895ab55a-fede-3a67-27aa-1ac1af9843d7@ti.com>
On 09/21/2017 09:08 AM, Sekhar Nori wrote:
> On Thursday 21 September 2017 06:01 AM, Franklin S Cooper Jr wrote:
>>
>>
>> On 08/24/2017 03:00 AM, Sekhar Nori wrote:
>>> + some OMAP folks and Linux OMAP list
>>>
>>> On Tuesday 25 July 2017 04:21 AM, Franklin Cooper wrote:
>>>> Hclk is the MCAN's interface clock. However, for OMAP based devices such as
>>>> DRA7 SoC family the interface clock is handled by hwmod. Therefore, this
>>>> interface clock is managed by hwmod driver via pm_runtime_get and
>>>> pm_runtime_put calls. Therefore, this interface clock isn't defined in DT
>>>> and thus the driver shouldn't fail if this clock isn't found.
>>>
>>> I agree that hclk is defined as interface clock for M_CAN IP on DRA76x.
>>>
>>> However, there may be a need for the driver to know the value of hclk to
>>> properly configure the RAM watchdog register which has a counter
>>> counting down using hclk. Looks like the driver does not use the RAM
>>> watchdog today. But if there is a need to configure it in future, it
>>> might be a problem.
>>
>> Honestly the RAM watchdog seems like a fundamental design problem.
>> This RAM watchdog seems to be used in case a request to access the
>> message ram is made but it hangs for what ever reason. Its even more
>> complicated since the Message RAM is external to the MCAN IP so its
>> implementation or how its handled probably differs from device to
>> device. From example say you do have this error it isn't clear how you
>> would recover from it. A logically answer would be to reset the entire
>> IP but that also assumes that Message RAM will be reset along with the
>> ip which likely depends on each SoC.
>>
>> But if a readl/writel command hangs will the kernel eventually throw an
>> error on its on or will the driver just hang? If it does hang can a
>> driver in the ISR do something to properly terminate the driver or even
>> recover from it?
>>>
>>> Is there a restriction in OMAP architecture against passing the
>>> interface clock also in the 'clocks' property in DT. I have not tried it
>>> myself, but wonder if you hit an issue that led to this patch.
>>
>> No but not passing the interface clock is typical.
>
> Okay, then it sounds like it will just be easier to pass the hclk too?
>
> So it can be used if needed in future and also so that the driver can
> stay the same as today.
That is fine. For now I can just drop this patch unless I discover when
enabling it on DRA76x I am unable to add the interface clock to dt.
>
> Thanks,
> Sekhar
>
^ permalink raw reply
* Re: [PATCH net-next] bpf/verifier: improve disassembly of BPF_END instructions
From: Alexei Starovoitov @ 2017-09-21 19:44 UTC (permalink / raw)
To: Daniel Borkmann; +Cc: Edward Cree, Y Song, David Miller, netdev
In-Reply-To: <59C4131D.8050003@iogearbox.net>
On Thu, Sep 21, 2017 at 09:29:33PM +0200, Daniel Borkmann wrote:
> On 09/21/2017 06:58 PM, Edward Cree wrote:
> > On 21/09/17 17:40, Y Song wrote:
> > > On Thu, Sep 21, 2017 at 9:24 AM, Edward Cree <ecree@solarflare.com> wrote:
> > > > On 21/09/17 16:52, Alexei Starovoitov wrote:
> > > > > imo
> > > > > (u16) r4 endian be
> > > > > isn't intuitive.
> > > > > Can we come up with some better syntax?
> > > > > Like
> > > > > bswap16be r4
> > > > > bswap32le r4
> > > > Hmm, I don't like these, since bswapbe is a swap on *le* and a nop on be.
>
> Agree, a bit too much 'swap' semantics in the name that could be
> confusing perhaps, at least the be/le could be missed easily.
>
> > > > > or
> > > > >
> > > > > to_be16 r4
> > > > > to_le32 r4
> > > > And the problem here is that it's not just to_be, it's also from_be.
>
> More intuitive, but agree on the from_be/le. Maybe we should
> just drop the "to_" prefix altogether, and leave the rest as is since
> it's not surrounded by braces, it's also not a cast but rather an op.
'be16 r4' is ambiguous regarding upper bits.
what about my earlier suggestion:
r4 = (be16) (u16) r4
r4 = (le64) (u64) r4
It will be pretty clear what instruction is doing (that upper bits become zero).
^ permalink raw reply
* Re: [PATCH net-next] bpf/verifier: improve disassembly of BPF_END instructions
From: Edward Cree @ 2017-09-21 19:58 UTC (permalink / raw)
To: Alexei Starovoitov, Daniel Borkmann; +Cc: Y Song, David Miller, netdev
In-Reply-To: <20170921194426.tnd5xos5irm3gred@ast-mbp>
On 21/09/17 20:44, Alexei Starovoitov wrote:
> On Thu, Sep 21, 2017 at 09:29:33PM +0200, Daniel Borkmann wrote:
>> More intuitive, but agree on the from_be/le. Maybe we should
>> just drop the "to_" prefix altogether, and leave the rest as is since
>> it's not surrounded by braces, it's also not a cast but rather an op.
That works for me.
> 'be16 r4' is ambiguous regarding upper bits.
>
> what about my earlier suggestion:
> r4 = (be16) (u16) r4
> r4 = (le64) (u64) r4
>
> It will be pretty clear what instruction is doing (that upper bits become zero).
Trouble with that is that's very *not* what C will do with those casts
and it doesn't really capture the bidirectional/symmetry thing. The
closest I could see with that is something like `r4 = (be16/u16) r4`,
but that's quite an ugly mongrel.
I think Daniel's idea of `be16`, `le32` etc one-arg opcodes is the
cleanest and clearest. Should it be
r4 = be16 r4
or just
be16 r4
? Personally I incline towards the latter, but admit it doesn't really
match the syntax of other opcodes.
To shed a few more bikes, I did also wonder about the BPF_NEG opcode,
which (if I'm reading the code correctly) currently renders as
r4 = neg r4 0
(u32) r4 = neg (u32) r4 0
That printing of the insn->imm, while harmless, is needless and
potentially confusing. Should we get rid of it?
^ permalink raw reply
* net: macb: fail when there's no PHY
From: Grant Edwards @ 2017-09-21 19:59 UTC (permalink / raw)
To: netdev
Several years back (circa 2.6.33) I had to hack up macb.c to work on
an at91 board that didn't have a PHY connected to the macb controller.
Now I might need to get a recent kernel version running on that board.
It looks like the macb driver still can't handle boards that don't
have a PHY. Is that correct?
What's the right way to deal with this?
With the older macb driver, I ended up adding code to macb.c that
presented a "fake" PHY that discarded MDIO writes and returned some
hard-wired values for MDIO reads. That seemed like a pretty ugly way
to deal with the situation, so I never bothered to submit a patch.
--
Grant Edwards
grant.b.edwards@gmail.com
^ permalink raw reply
* Re: net: macb: fail when there's no PHY
From: Florian Fainelli @ 2017-09-21 20:05 UTC (permalink / raw)
To: Grant Edwards, netdev
In-Reply-To: <20170921195905.GA29873@grante>
On 09/21/2017 12:59 PM, Grant Edwards wrote:
> Several years back (circa 2.6.33) I had to hack up macb.c to work on
> an at91 board that didn't have a PHY connected to the macb controller.
> Now I might need to get a recent kernel version running on that board.
>
> It looks like the macb driver still can't handle boards that don't
> have a PHY. Is that correct?
Not since:
dacdbb4dfc1a1a1378df8ebc914d4fe82259ed46 ("net: macb: add fixed-link
node support")
>
> What's the right way to deal with this?
Declaring a fixed PHY that will present an emulated link UP, with a
fixed speed/duplex etc. is the way to go.
>
> With the older macb driver, I ended up adding code to macb.c that
> presented a "fake" PHY that discarded MDIO writes and returned some
> hard-wired values for MDIO reads. That seemed like a pretty ugly way
> to deal with the situation, so I never bothered to submit a patch.
>
Yeah, no :)
--
Florian
^ permalink raw reply
* Re: net: macb: fail when there's no PHY
From: Grant Edwards @ 2017-09-21 20:36 UTC (permalink / raw)
To: Florian Fainelli; +Cc: netdev
In-Reply-To: <66c0a032-4d20-69f1-deb4-6c65af6ec740@gmail.com>
On Thu, Sep 21, 2017 at 01:05:57PM -0700, Florian Fainelli wrote:
>> It looks like the macb driver still can't handle boards that don't
>> have a PHY. Is that correct?
>
> Not since:
>
> dacdbb4dfc1a1a1378df8ebc914d4fe82259ed46 ("net: macb: add fixed-link
> node support")
Yep, it's obvious now that I've got the diff in front of me.
Thanks!
[I just started working with device tree for the first time yesterday,
and I must say it's way better than the "old days" which required all
sorts of ugly to produce a kernel that could work on two slightly
different boards.]
--
Grant
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox