* [PATCH v3 net-next 2/8] flow_dissector: Move ETH_P_TEB processing to main switch
2017-09-28 21:48 [PATCH v3 net-next 1/8] flow_dissector: Change skbuf argument to be non const Tom Herbert
@ 2017-09-28 21:48 ` Tom Herbert
2017-09-28 21:48 ` [PATCH v3 net-next 3/8] udp: Check static key udp_encap_needed in udp_gro_receive Tom Herbert
` (6 subsequent siblings)
7 siblings, 0 replies; 9+ messages in thread
From: Tom Herbert @ 2017-09-28 21:48 UTC (permalink / raw)
To: davem; +Cc: netdev, rohit, Tom Herbert
Support for processing TEB is currently in GRE flow dissection as a
special case. This can be moved to be a case the main proto switch in
__skb_flow_dissect.
Signed-off-by: Tom Herbert <tom@quantonium.net>
---
net/core/flow_dissector.c | 45 ++++++++++++++++++++++++---------------------
1 file changed, 24 insertions(+), 21 deletions(-)
diff --git a/net/core/flow_dissector.c b/net/core/flow_dissector.c
index 76f5e5bc3177..c15b41f96cbe 100644
--- a/net/core/flow_dissector.c
+++ b/net/core/flow_dissector.c
@@ -282,27 +282,8 @@ __skb_flow_dissect_gre(const struct sk_buff *skb,
if (hdr->flags & GRE_SEQ)
offset += sizeof(((struct pptp_gre_header *) 0)->seq);
- if (gre_ver == 0) {
- if (*p_proto == htons(ETH_P_TEB)) {
- const struct ethhdr *eth;
- struct ethhdr _eth;
-
- eth = __skb_header_pointer(skb, *p_nhoff + offset,
- sizeof(_eth),
- data, *p_hlen, &_eth);
- if (!eth)
- return FLOW_DISSECT_RET_OUT_BAD;
- *p_proto = eth->h_proto;
- offset += sizeof(*eth);
-
- /* Cap headers that we access via pointers at the
- * end of the Ethernet header as our maximum alignment
- * at that point is only 2 bytes.
- */
- if (NET_IP_ALIGN)
- *p_hlen = *p_nhoff + offset;
- }
- } else { /* version 1, must be PPTP */
+ /* version 1, must be PPTP */
+ if (gre_ver == 1) {
u8 _ppp_hdr[PPP_HDRLEN];
u8 *ppp_hdr;
@@ -595,6 +576,28 @@ bool __skb_flow_dissect(struct sk_buff *skb,
break;
}
+ case htons(ETH_P_TEB): {
+ const struct ethhdr *eth;
+ struct ethhdr _eth;
+
+ eth = __skb_header_pointer(skb, nhoff, sizeof(_eth),
+ data, hlen, &_eth);
+ if (!eth)
+ goto out_bad;
+
+ proto = eth->h_proto;
+ nhoff += sizeof(*eth);
+
+ /* Cap headers that we access via pointers at the
+ * end of the Ethernet header as our maximum alignment
+ * at that point is only 2 bytes.
+ */
+ if (NET_IP_ALIGN)
+ hlen = nhoff;
+
+ fdret = FLOW_DISSECT_RET_PROTO_AGAIN;
+ break;
+ }
case htons(ETH_P_8021AD):
case htons(ETH_P_8021Q): {
const struct vlan_hdr *vlan;
--
2.11.0
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH v3 net-next 3/8] udp: Check static key udp_encap_needed in udp_gro_receive
2017-09-28 21:48 [PATCH v3 net-next 1/8] flow_dissector: Change skbuf argument to be non const Tom Herbert
2017-09-28 21:48 ` [PATCH v3 net-next 2/8] flow_dissector: Move ETH_P_TEB processing to main switch Tom Herbert
@ 2017-09-28 21:48 ` Tom Herbert
2017-09-28 21:48 ` [PATCH v3 net-next 4/8] flow_dissector: Add protocol specific flow dissection offload Tom Herbert
` (5 subsequent siblings)
7 siblings, 0 replies; 9+ messages in thread
From: Tom Herbert @ 2017-09-28 21:48 UTC (permalink / raw)
To: davem; +Cc: netdev, rohit, Tom Herbert
Currently, the only support for udp gro is provided by UDP encapsulation
protocols. Since they always set udp_encap_needed we can check that in
udp_gro_receive functions before performing a socket lookup.
Signed-off-by: Tom Herbert <tom@quantonium.net>
---
include/net/udp.h | 2 ++
net/ipv4/udp.c | 4 +++-
net/ipv4/udp_offload.c | 7 +++++++
net/ipv6/udp_offload.c | 7 +++++++
4 files changed, 19 insertions(+), 1 deletion(-)
diff --git a/include/net/udp.h b/include/net/udp.h
index 12dfbfe2e2d7..c6b1c5d8d3c9 100644
--- a/include/net/udp.h
+++ b/include/net/udp.h
@@ -97,6 +97,8 @@ static inline struct udp_hslot *udp_hashslot2(struct udp_table *table,
extern struct proto udp_prot;
+extern struct static_key udp_encap_needed;
+
extern atomic_long_t udp_memory_allocated;
/* sysctl variables for udp */
diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c
index 784ced0b9150..2788843e8eb2 100644
--- a/net/ipv4/udp.c
+++ b/net/ipv4/udp.c
@@ -1813,7 +1813,9 @@ static int __udp_queue_rcv_skb(struct sock *sk, struct sk_buff *skb)
return 0;
}
-static struct static_key udp_encap_needed __read_mostly;
+struct static_key udp_encap_needed __read_mostly;
+EXPORT_SYMBOL(udp_encap_needed);
+
void udp_encap_enable(void)
{
static_key_enable(&udp_encap_needed);
diff --git a/net/ipv4/udp_offload.c b/net/ipv4/udp_offload.c
index 97658bfc1b58..a744bb515455 100644
--- a/net/ipv4/udp_offload.c
+++ b/net/ipv4/udp_offload.c
@@ -261,6 +261,13 @@ static struct sk_buff **udp4_gro_receive(struct sk_buff **head,
{
struct udphdr *uh = udp_gro_udphdr(skb);
+ if (!static_key_false(&udp_encap_needed)) {
+ /* Currently udp_gro_receive only does something if
+ * a UDP encapsulation has been set.
+ */
+ goto flush;
+ }
+
if (unlikely(!uh))
goto flush;
diff --git a/net/ipv6/udp_offload.c b/net/ipv6/udp_offload.c
index 455fd4e39333..111b026e4f03 100644
--- a/net/ipv6/udp_offload.c
+++ b/net/ipv6/udp_offload.c
@@ -34,6 +34,13 @@ static struct sk_buff **udp6_gro_receive(struct sk_buff **head,
{
struct udphdr *uh = udp_gro_udphdr(skb);
+ if (!static_key_false(&udp_encap_needed)) {
+ /* Currently udp_gro_receive only does something if
+ * a UDP encapsulation has been set.
+ */
+ goto flush;
+ }
+
if (unlikely(!uh))
goto flush;
--
2.11.0
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH v3 net-next 4/8] flow_dissector: Add protocol specific flow dissection offload
2017-09-28 21:48 [PATCH v3 net-next 1/8] flow_dissector: Change skbuf argument to be non const Tom Herbert
2017-09-28 21:48 ` [PATCH v3 net-next 2/8] flow_dissector: Move ETH_P_TEB processing to main switch Tom Herbert
2017-09-28 21:48 ` [PATCH v3 net-next 3/8] udp: Check static key udp_encap_needed in udp_gro_receive Tom Herbert
@ 2017-09-28 21:48 ` Tom Herbert
2017-09-28 21:48 ` [PATCH v3 net-next 5/8] ip: Add callbacks to flow dissection by IP protocol Tom Herbert
` (4 subsequent siblings)
7 siblings, 0 replies; 9+ messages in thread
From: Tom Herbert @ 2017-09-28 21:48 UTC (permalink / raw)
To: davem; +Cc: netdev, rohit, Tom Herbert
Add offload capability for performing protocol specific flow dissection
(either by EtherType or IP protocol).
Specifically:
- Add flow_dissect to offload callbacks
- Move flow_dissect_ret enum to flow_dissector.h, cleanup names and add a
couple of values
- Unify handling of functions that return flow_dissect_ret enum
- In __skb_flow_dissect, add default case for switch(proto) as well as
switch(ip_proto) that looks up and calls protocol specific flow
dissection
Signed-off-by: Tom Herbert <tom@quantonium.net>
---
include/linux/netdevice.h | 27 ++++++++++++++++++
include/net/flow_dissector.h | 1 +
net/core/dev.c | 65 ++++++++++++++++++++++++++++++++++++++++++++
net/core/flow_dissector.c | 16 +++++++++--
net/ipv4/route.c | 4 ++-
5 files changed, 110 insertions(+), 3 deletions(-)
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index f535779d9dc1..565d7cdfe967 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -2207,12 +2207,25 @@ struct offload_callbacks {
struct sk_buff **(*gro_receive)(struct sk_buff **head,
struct sk_buff *skb);
int (*gro_complete)(struct sk_buff *skb, int nhoff);
+ enum flow_dissect_ret (*flow_dissect)(struct sk_buff *skb,
+ struct flow_dissector_key_control *key_control,
+ struct flow_dissector *flow_dissector,
+ void *target_container, void *data,
+ __be16 *p_proto, u8 *p_ip_proto, int *p_nhoff,
+ int *p_hlen, unsigned int flags);
};
struct packet_offload {
__be16 type; /* This is really htons(ether_type). */
u16 priority;
struct offload_callbacks callbacks;
+ enum flow_dissect_ret (*proto_flow_dissect)(struct sk_buff *skb,
+ u8 proto,
+ struct flow_dissector_key_control *key_control,
+ struct flow_dissector *flow_dissector,
+ void *target_container, void *data,
+ __be16 *p_proto, u8 *p_ip_proto, int *p_nhoff,
+ int *p_hlen, unsigned int flags);
struct list_head list;
};
@@ -3252,6 +3265,20 @@ struct sk_buff *napi_get_frags(struct napi_struct *napi);
gro_result_t napi_gro_frags(struct napi_struct *napi);
struct packet_offload *gro_find_receive_by_type(__be16 type);
struct packet_offload *gro_find_complete_by_type(__be16 type);
+enum flow_dissect_ret flow_dissect_by_type(struct sk_buff *skb,
+ __be16 type,
+ struct flow_dissector_key_control *key_control,
+ struct flow_dissector *flow_dissector,
+ void *target_container, void *data,
+ __be16 *p_proto, u8 *p_ip_proto, int *p_nhoff,
+ int *p_hlen, unsigned int flags);
+enum flow_dissect_ret flow_dissect_by_type_proto(struct sk_buff *skb,
+ __be16 type, u8 proto,
+ struct flow_dissector_key_control *key_control,
+ struct flow_dissector *flow_dissector,
+ void *target_container, void *data,
+ __be16 *p_proto, u8 *p_ip_proto, int *p_nhoff,
+ int *p_hlen, unsigned int flags);
static inline void napi_free_frags(struct napi_struct *napi)
{
diff --git a/include/net/flow_dissector.h b/include/net/flow_dissector.h
index fc3dce730a6b..ad75bbfd1c9c 100644
--- a/include/net/flow_dissector.h
+++ b/include/net/flow_dissector.h
@@ -213,6 +213,7 @@ enum flow_dissector_key_id {
#define FLOW_DISSECTOR_F_STOP_AT_L3 BIT(1)
#define FLOW_DISSECTOR_F_STOP_AT_FLOW_LABEL BIT(2)
#define FLOW_DISSECTOR_F_STOP_AT_ENCAP BIT(3)
+#define FLOW_DISSECTOR_F_STOP_AT_L4 BIT(4)
struct flow_dissector_key {
enum flow_dissector_key_id key_id;
diff --git a/net/core/dev.c b/net/core/dev.c
index e350c768d4b5..f3cd884bd04b 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -104,6 +104,7 @@
#include <linux/stat.h>
#include <net/dst.h>
#include <net/dst_metadata.h>
+#include <net/flow_dissector.h>
#include <net/pkt_sched.h>
#include <net/pkt_cls.h>
#include <net/checksum.h>
@@ -4907,6 +4908,70 @@ struct packet_offload *gro_find_complete_by_type(__be16 type)
}
EXPORT_SYMBOL(gro_find_complete_by_type);
+enum flow_dissect_ret flow_dissect_by_type(struct sk_buff *skb,
+ __be16 type,
+ struct flow_dissector_key_control *key_control,
+ struct flow_dissector *flow_dissector,
+ void *target_container, void *data,
+ __be16 *p_proto, u8 *p_ip_proto, int *p_nhoff,
+ int *p_hlen, unsigned int flags)
+{
+ enum flow_dissect_ret ret = FLOW_DISSECT_RET_CONTINUE;
+ struct list_head *offload_head = &offload_base;
+ struct packet_offload *ptype;
+
+ rcu_read_lock();
+
+ list_for_each_entry_rcu(ptype, offload_head, list) {
+ if (ptype->type != type || !ptype->callbacks.flow_dissect)
+ continue;
+ ret = ptype->callbacks.flow_dissect(skb, key_control,
+ flow_dissector,
+ target_container,
+ data, p_proto,
+ p_ip_proto, p_nhoff,
+ p_hlen, flags);
+ break;
+ }
+
+ rcu_read_unlock();
+
+ return ret;
+}
+EXPORT_SYMBOL(flow_dissect_by_type);
+
+enum flow_dissect_ret flow_dissect_by_type_proto(struct sk_buff *skb,
+ __be16 type, u8 proto,
+ struct flow_dissector_key_control *key_control,
+ struct flow_dissector *flow_dissector,
+ void *target_container, void *data,
+ __be16 *p_proto, u8 *p_ip_proto, int *p_nhoff,
+ int *p_hlen, unsigned int flags)
+{
+ enum flow_dissect_ret ret = FLOW_DISSECT_RET_CONTINUE;
+ struct list_head *offload_head = &offload_base;
+ struct packet_offload *ptype;
+
+ rcu_read_lock();
+
+ list_for_each_entry_rcu(ptype, offload_head, list) {
+ if (ptype->type != type || !ptype->proto_flow_dissect)
+ continue;
+ ret = ptype->proto_flow_dissect(skb, proto, key_control,
+ flow_dissector,
+ target_container,
+ data, p_proto,
+ p_ip_proto, p_nhoff,
+ p_hlen, flags);
+ break;
+ }
+
+ rcu_read_unlock();
+
+ return ret;
+}
+EXPORT_SYMBOL(flow_dissect_by_type_proto);
+
static void napi_skb_free_stolen_head(struct sk_buff *skb)
{
skb_dst_drop(skb);
diff --git a/net/core/flow_dissector.c b/net/core/flow_dissector.c
index c15b41f96cbe..84b8eb1f6664 100644
--- a/net/core/flow_dissector.c
+++ b/net/core/flow_dissector.c
@@ -9,6 +9,7 @@
#include <net/ipv6.h>
#include <net/gre.h>
#include <net/pptp.h>
+#include <net/protocol.h>
#include <linux/igmp.h>
#include <linux/icmp.h>
#include <linux/sctp.h>
@@ -721,7 +722,11 @@ bool __skb_flow_dissect(struct sk_buff *skb,
break;
default:
- fdret = FLOW_DISSECT_RET_OUT_BAD;
+ fdret = flow_dissect_by_type(skb, proto, key_control,
+ flow_dissector,
+ target_container,
+ data, &proto, &ip_proto, &nhoff,
+ &hlen, flags);
break;
}
@@ -838,6 +843,12 @@ bool __skb_flow_dissect(struct sk_buff *skb,
break;
default:
+ fdret = flow_dissect_by_type_proto(skb, proto,
+ ip_proto, key_control,
+ flow_dissector,
+ target_container,
+ data, &proto, &ip_proto, &nhoff,
+ &hlen, flags);
break;
}
@@ -1022,7 +1033,8 @@ static inline u32 ___skb_get_hash(struct sk_buff *skb,
struct flow_keys *keys, u32 keyval)
{
skb_flow_dissect_flow_keys(skb, keys,
- FLOW_DISSECTOR_F_STOP_AT_FLOW_LABEL);
+ FLOW_DISSECTOR_F_STOP_AT_FLOW_LABEL |
+ FLOW_DISSECTOR_F_STOP_AT_L4);
return __flow_hash_from_keys(keys, keyval);
}
diff --git a/net/ipv4/route.c b/net/ipv4/route.c
index 94c5b81d8f2b..69d6ce7dfa18 100644
--- a/net/ipv4/route.c
+++ b/net/ipv4/route.c
@@ -1811,7 +1811,9 @@ int fib_multipath_hash(const struct fib_info *fi, const struct flowi4 *fl4,
case 1:
/* skb is currently provided only when forwarding */
if (skb) {
- unsigned int flag = FLOW_DISSECTOR_F_STOP_AT_ENCAP;
+ unsigned int flag = FLOW_DISSECTOR_F_STOP_AT_ENCAP |
+ FLOW_DISSECTOR_F_STOP_AT_L4;
+;
struct flow_keys keys;
/* short-circuit if we already have L4 hash present */
--
2.11.0
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH v3 net-next 5/8] ip: Add callbacks to flow dissection by IP protocol
2017-09-28 21:48 [PATCH v3 net-next 1/8] flow_dissector: Change skbuf argument to be non const Tom Herbert
` (2 preceding siblings ...)
2017-09-28 21:48 ` [PATCH v3 net-next 4/8] flow_dissector: Add protocol specific flow dissection offload Tom Herbert
@ 2017-09-28 21:48 ` Tom Herbert
2017-09-28 21:48 ` [PATCH v3 net-next 6/8] udp: flow dissector offload Tom Herbert
` (3 subsequent siblings)
7 siblings, 0 replies; 9+ messages in thread
From: Tom Herbert @ 2017-09-28 21:48 UTC (permalink / raw)
To: davem; +Cc: netdev, rohit, Tom Herbert
Populate the proto_flow_dissect function for IPv4 and IPv6 packet
offloads. This allows the caller to flow dissect a packet starting
at the given IP protocol (as parsed to that point by flow dissector
for instance).
Signed-off-by: Tom Herbert <tom@quantonium.net>
---
net/ipv4/af_inet.c | 27 +++++++++++++++++++++++++++
net/ipv6/ip6_offload.c | 27 +++++++++++++++++++++++++++
2 files changed, 54 insertions(+)
diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c
index e31108e5ef79..18c1d884999a 100644
--- a/net/ipv4/af_inet.c
+++ b/net/ipv4/af_inet.c
@@ -1440,6 +1440,32 @@ static struct sk_buff **ipip_gro_receive(struct sk_buff **head,
return inet_gro_receive(head, skb);
}
+static enum flow_dissect_ret inet_proto_flow_dissect(struct sk_buff *skb,
+ u8 proto,
+ struct flow_dissector_key_control *key_control,
+ struct flow_dissector *flow_dissector,
+ void *target_container, void *data,
+ __be16 *p_proto, u8 *p_ip_proto, int *p_nhoff,
+ int *p_hlen, unsigned int flags)
+{
+ enum flow_dissect_ret ret = FLOW_DISSECT_RET_CONTINUE;
+ const struct net_offload *ops;
+
+ rcu_read_lock();
+
+ ops = rcu_dereference(inet_offloads[proto]);
+ if (ops && ops->callbacks.flow_dissect)
+ ret = ops->callbacks.flow_dissect(skb, key_control,
+ flow_dissector,
+ target_container,
+ data, p_proto, p_ip_proto,
+ p_nhoff, p_hlen, flags);
+
+ rcu_read_unlock();
+
+ return ret;
+}
+
#define SECONDS_PER_DAY 86400
/* inet_current_timestamp - Return IP network timestamp
@@ -1763,6 +1789,7 @@ static int ipv4_proc_init(void);
static struct packet_offload ip_packet_offload __read_mostly = {
.type = cpu_to_be16(ETH_P_IP),
+ .proto_flow_dissect = inet_proto_flow_dissect,
.callbacks = {
.gso_segment = inet_gso_segment,
.gro_receive = inet_gro_receive,
diff --git a/net/ipv6/ip6_offload.c b/net/ipv6/ip6_offload.c
index cdb3728faca7..a33a2b40b3d6 100644
--- a/net/ipv6/ip6_offload.c
+++ b/net/ipv6/ip6_offload.c
@@ -339,8 +339,35 @@ static int ip4ip6_gro_complete(struct sk_buff *skb, int nhoff)
return inet_gro_complete(skb, nhoff);
}
+static enum flow_dissect_ret inet6_proto_flow_dissect(struct sk_buff *skb,
+ u8 proto,
+ struct flow_dissector_key_control *key_control,
+ struct flow_dissector *flow_dissector,
+ void *target_container, void *data,
+ __be16 *p_proto, u8 *p_ip_proto, int *p_nhoff,
+ int *p_hlen, unsigned int flags)
+{
+ enum flow_dissect_ret ret = FLOW_DISSECT_RET_CONTINUE;
+ const struct net_offload *ops;
+
+ rcu_read_lock();
+
+ ops = rcu_dereference(inet6_offloads[proto]);
+ if (ops && ops->callbacks.flow_dissect)
+ ret = ops->callbacks.flow_dissect(skb, key_control,
+ flow_dissector,
+ target_container, data,
+ p_proto, p_ip_proto, p_nhoff,
+ p_hlen, flags);
+
+ rcu_read_unlock();
+
+ return ret;
+}
+
static struct packet_offload ipv6_packet_offload __read_mostly = {
.type = cpu_to_be16(ETH_P_IPV6),
+ .proto_flow_dissect = inet6_proto_flow_dissect,
.callbacks = {
.gso_segment = ipv6_gso_segment,
.gro_receive = ipv6_gro_receive,
--
2.11.0
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH v3 net-next 6/8] udp: flow dissector offload
2017-09-28 21:48 [PATCH v3 net-next 1/8] flow_dissector: Change skbuf argument to be non const Tom Herbert
` (3 preceding siblings ...)
2017-09-28 21:48 ` [PATCH v3 net-next 5/8] ip: Add callbacks to flow dissection by IP protocol Tom Herbert
@ 2017-09-28 21:48 ` Tom Herbert
2017-09-28 21:48 ` [PATCH v3 net-next 7/8] fou: Support flow dissection Tom Herbert
` (2 subsequent siblings)
7 siblings, 0 replies; 9+ messages in thread
From: Tom Herbert @ 2017-09-28 21:48 UTC (permalink / raw)
To: davem; +Cc: netdev, rohit, Tom Herbert
Add support to perform UDP specific flow dissection. This is
primarily intended for dissecting encapsulated packets in UDP
encapsulation.
This patch adds a flow_dissect offload for UDP4 and UDP6. The backend
function performs a socket lookup and calls the flow_dissect function
if a socket is found.
Signed-off-by: Tom Herbert <tom@quantonium.net>
---
include/linux/udp.h | 8 ++++++++
include/net/udp.h | 8 ++++++++
include/net/udp_tunnel.h | 8 ++++++++
net/ipv4/udp_offload.c | 48 ++++++++++++++++++++++++++++++++++++++++++++++++
net/ipv4/udp_tunnel.c | 1 +
net/ipv6/udp_offload.c | 16 ++++++++++++++++
6 files changed, 89 insertions(+)
diff --git a/include/linux/udp.h b/include/linux/udp.h
index eaea63bc79bb..2e90b189ef6a 100644
--- a/include/linux/udp.h
+++ b/include/linux/udp.h
@@ -79,6 +79,14 @@ struct udp_sock {
int (*gro_complete)(struct sock *sk,
struct sk_buff *skb,
int nhoff);
+ /* Flow dissector function for a UDP socket */
+ enum flow_dissect_ret (*flow_dissect)(struct sock *sk,
+ const struct sk_buff *skb,
+ struct flow_dissector_key_control *key_control,
+ struct flow_dissector *flow_dissector,
+ void *target_container, void *data,
+ __be16 *p_proto, u8 *p_ip_proto, int *p_nhoff,
+ int *p_hlen, unsigned int flags);
/* udp_recvmsg try to use this before splicing sk_receive_queue */
struct sk_buff_head reader_queue ____cacheline_aligned_in_smp;
diff --git a/include/net/udp.h b/include/net/udp.h
index c6b1c5d8d3c9..4867f329538c 100644
--- a/include/net/udp.h
+++ b/include/net/udp.h
@@ -176,6 +176,14 @@ struct sk_buff **udp_gro_receive(struct sk_buff **head, struct sk_buff *skb,
struct udphdr *uh, udp_lookup_t lookup);
int udp_gro_complete(struct sk_buff *skb, int nhoff, udp_lookup_t lookup);
+enum flow_dissect_ret udp_flow_dissect(struct sk_buff *skb,
+ udp_lookup_t lookup,
+ struct flow_dissector_key_control *key_control,
+ struct flow_dissector *flow_dissector,
+ void *target_container, void *data,
+ __be16 *p_proto, u8 *p_ip_proto, int *p_nhoff,
+ int *p_hlen, unsigned int flags);
+
static inline struct udphdr *udp_gro_udphdr(struct sk_buff *skb)
{
struct udphdr *uh;
diff --git a/include/net/udp_tunnel.h b/include/net/udp_tunnel.h
index 10cce0dd4450..b7102e0f41a9 100644
--- a/include/net/udp_tunnel.h
+++ b/include/net/udp_tunnel.h
@@ -69,6 +69,13 @@ typedef struct sk_buff **(*udp_tunnel_gro_receive_t)(struct sock *sk,
struct sk_buff *skb);
typedef int (*udp_tunnel_gro_complete_t)(struct sock *sk, struct sk_buff *skb,
int nhoff);
+typedef enum flow_dissect_ret (*udp_tunnel_flow_dissect_t)(struct sock *sk,
+ const struct sk_buff *skb,
+ struct flow_dissector_key_control *key_control,
+ struct flow_dissector *flow_dissector,
+ void *target_container, void *data,
+ __be16 *p_proto, u8 *p_ip_proto, int *p_nhoff,
+ int *p_hlen, unsigned int flags);
struct udp_tunnel_sock_cfg {
void *sk_user_data; /* user data used by encap_rcv call back */
@@ -78,6 +85,7 @@ struct udp_tunnel_sock_cfg {
udp_tunnel_encap_destroy_t encap_destroy;
udp_tunnel_gro_receive_t gro_receive;
udp_tunnel_gro_complete_t gro_complete;
+ udp_tunnel_flow_dissect_t flow_dissect;
};
/* Setup the given (UDP) sock to receive UDP encapsulated packets */
diff --git a/net/ipv4/udp_offload.c b/net/ipv4/udp_offload.c
index a744bb515455..fddf923ef433 100644
--- a/net/ipv4/udp_offload.c
+++ b/net/ipv4/udp_offload.c
@@ -335,11 +335,59 @@ static int udp4_gro_complete(struct sk_buff *skb, int nhoff)
return udp_gro_complete(skb, nhoff, udp4_lib_lookup_skb);
}
+enum flow_dissect_ret udp_flow_dissect(struct sk_buff *skb,
+ udp_lookup_t lookup,
+ struct flow_dissector_key_control *key_control,
+ struct flow_dissector *flow_dissector,
+ void *target_container, void *data,
+ __be16 *p_proto, u8 *p_ip_proto, int *p_nhoff,
+ int *p_hlen, unsigned int flags)
+{
+ enum flow_dissect_ret ret = FLOW_DISSECT_RET_CONTINUE;
+ struct udphdr *uh, _uh;
+ struct sock *sk;
+
+ uh = __skb_header_pointer(skb, *p_nhoff, sizeof(_uh), data,
+ *p_hlen, &_uh);
+ if (!uh)
+ return FLOW_DISSECT_RET_OUT_BAD;
+
+ rcu_read_lock();
+
+ sk = (*lookup)(skb, uh->source, uh->dest);
+
+ if (sk && udp_sk(sk)->flow_dissect)
+ ret = udp_sk(sk)->flow_dissect(sk, skb, key_control,
+ flow_dissector, target_container,
+ data, p_proto, p_ip_proto,
+ p_nhoff, p_hlen, flags);
+ rcu_read_unlock();
+
+ return ret;
+}
+EXPORT_SYMBOL(udp_flow_dissect);
+
+static enum flow_dissect_ret udp4_flow_dissect(struct sk_buff *skb,
+ struct flow_dissector_key_control *key_control,
+ struct flow_dissector *flow_dissector,
+ void *target_container, void *data,
+ __be16 *p_proto, u8 *p_ip_proto, int *p_nhoff,
+ int *p_hlen, unsigned int flags)
+{
+ if (!static_key_false(&udp_encap_needed))
+ return FLOW_DISSECT_RET_CONTINUE;
+
+ return udp_flow_dissect(skb, udp4_lib_lookup_skb, key_control,
+ flow_dissector, target_container, data,
+ p_proto, p_ip_proto, p_nhoff, p_hlen, flags);
+}
+
static const struct net_offload udpv4_offload = {
.callbacks = {
.gso_segment = udp4_tunnel_segment,
.gro_receive = udp4_gro_receive,
.gro_complete = udp4_gro_complete,
+ .flow_dissect = udp4_flow_dissect,
},
};
diff --git a/net/ipv4/udp_tunnel.c b/net/ipv4/udp_tunnel.c
index 6539ff15e9a3..a4eec2a044d2 100644
--- a/net/ipv4/udp_tunnel.c
+++ b/net/ipv4/udp_tunnel.c
@@ -71,6 +71,7 @@ void setup_udp_tunnel_sock(struct net *net, struct socket *sock,
udp_sk(sk)->encap_destroy = cfg->encap_destroy;
udp_sk(sk)->gro_receive = cfg->gro_receive;
udp_sk(sk)->gro_complete = cfg->gro_complete;
+ udp_sk(sk)->flow_dissect = cfg->flow_dissect;
udp_tunnel_encap_enable(sock);
}
diff --git a/net/ipv6/udp_offload.c b/net/ipv6/udp_offload.c
index 111b026e4f03..45b77f92d77d 100644
--- a/net/ipv6/udp_offload.c
+++ b/net/ipv6/udp_offload.c
@@ -80,11 +80,27 @@ static int udp6_gro_complete(struct sk_buff *skb, int nhoff)
return udp_gro_complete(skb, nhoff, udp6_lib_lookup_skb);
}
+static enum flow_dissect_ret udp6_flow_dissect(struct sk_buff *skb,
+ struct flow_dissector_key_control *key_control,
+ struct flow_dissector *flow_dissector,
+ void *target_container, void *data,
+ __be16 *p_proto, u8 *p_ip_proto, int *p_nhoff,
+ int *p_hlen, unsigned int flags)
+{
+ if (!static_key_false(&udp_encap_needed))
+ return FLOW_DISSECT_RET_CONTINUE;
+
+ return udp_flow_dissect(skb, udp6_lib_lookup_skb, key_control,
+ flow_dissector, target_container, data,
+ p_proto, p_ip_proto, p_nhoff, p_hlen, flags);
+}
+
static const struct net_offload udpv6_offload = {
.callbacks = {
.gso_segment = udp6_tunnel_segment,
.gro_receive = udp6_gro_receive,
.gro_complete = udp6_gro_complete,
+ .flow_dissect = udp6_flow_dissect,
},
};
--
2.11.0
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH v3 net-next 7/8] fou: Support flow dissection
2017-09-28 21:48 [PATCH v3 net-next 1/8] flow_dissector: Change skbuf argument to be non const Tom Herbert
` (4 preceding siblings ...)
2017-09-28 21:48 ` [PATCH v3 net-next 6/8] udp: flow dissector offload Tom Herbert
@ 2017-09-28 21:48 ` Tom Herbert
2017-09-28 21:48 ` [PATCH v3 net-next 8/8] vxlan: support flow dissect Tom Herbert
2017-09-30 21:46 ` [PATCH v3 net-next 1/8] flow_dissector: Change skbuf argument to be non const kbuild test robot
7 siblings, 0 replies; 9+ messages in thread
From: Tom Herbert @ 2017-09-28 21:48 UTC (permalink / raw)
To: davem; +Cc: netdev, rohit, Tom Herbert
Populate offload flow_dissect callabck appropriately for fou and gue.
Signed-off-by: Tom Herbert <tom@quantonium.net>
---
net/ipv4/fou.c | 63 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 63 insertions(+)
diff --git a/net/ipv4/fou.c b/net/ipv4/fou.c
index 1540db65241a..a831dd49fb28 100644
--- a/net/ipv4/fou.c
+++ b/net/ipv4/fou.c
@@ -282,6 +282,20 @@ static int fou_gro_complete(struct sock *sk, struct sk_buff *skb,
return err;
}
+static enum flow_dissect_ret fou_flow_dissect(struct sock *sk,
+ const struct sk_buff *skb,
+ struct flow_dissector_key_control *key_control,
+ struct flow_dissector *flow_dissector,
+ void *target_container, void *data,
+ __be16 *p_proto, u8 *p_ip_proto, int *p_nhoff,
+ int *p_hlen, unsigned int flags)
+{
+ *p_ip_proto = fou_from_sock(sk)->protocol;
+ *p_nhoff += sizeof(struct udphdr);
+
+ return FLOW_DISSECT_RET_IPPROTO_AGAIN;
+}
+
static struct guehdr *gue_gro_remcsum(struct sk_buff *skb, unsigned int off,
struct guehdr *guehdr, void *data,
size_t hdrlen, struct gro_remcsum *grc,
@@ -500,6 +514,53 @@ static int gue_gro_complete(struct sock *sk, struct sk_buff *skb, int nhoff)
return err;
}
+static enum flow_dissect_ret gue_flow_dissect(struct sock *sk,
+ const struct sk_buff *skb,
+ struct flow_dissector_key_control *key_control,
+ struct flow_dissector *flow_dissector,
+ void *target_container, void *data,
+ __be16 *p_proto, u8 *p_ip_proto, int *p_nhoff,
+ int *p_hlen, unsigned int flags)
+{
+ struct guehdr *guehdr, _guehdr;
+
+ guehdr = __skb_header_pointer(skb, *p_nhoff + sizeof(struct udphdr),
+ sizeof(_guehdr), data, *p_hlen, &_guehdr);
+ if (!guehdr)
+ return FLOW_DISSECT_RET_OUT_BAD;
+
+ switch (guehdr->version) {
+ case 0:
+ if (unlikely(guehdr->control))
+ return FLOW_DISSECT_RET_CONTINUE;
+
+ *p_ip_proto = guehdr->proto_ctype;
+ *p_nhoff += sizeof(struct udphdr) +
+ sizeof(*guehdr) + (guehdr->hlen << 2);
+
+ break;
+ case 1:
+ switch (((struct iphdr *)guehdr)->version) {
+ case 4:
+ *p_ip_proto = IPPROTO_IPIP;
+ break;
+ case 6:
+ *p_ip_proto = IPPROTO_IPV6;
+ break;
+ default:
+ return FLOW_DISSECT_RET_CONTINUE;
+ }
+
+ *p_nhoff += sizeof(struct udphdr);
+
+ break;
+ default:
+ return FLOW_DISSECT_RET_CONTINUE;
+ }
+
+ return FLOW_DISSECT_RET_IPPROTO_AGAIN;
+}
+
static int fou_add_to_port_list(struct net *net, struct fou *fou)
{
struct fou_net *fn = net_generic(net, fou_net_id);
@@ -570,12 +631,14 @@ static int fou_create(struct net *net, struct fou_cfg *cfg,
tunnel_cfg.encap_rcv = fou_udp_recv;
tunnel_cfg.gro_receive = fou_gro_receive;
tunnel_cfg.gro_complete = fou_gro_complete;
+ tunnel_cfg.flow_dissect = fou_flow_dissect;
fou->protocol = cfg->protocol;
break;
case FOU_ENCAP_GUE:
tunnel_cfg.encap_rcv = gue_udp_recv;
tunnel_cfg.gro_receive = gue_gro_receive;
tunnel_cfg.gro_complete = gue_gro_complete;
+ tunnel_cfg.flow_dissect = gue_flow_dissect;
break;
default:
err = -EINVAL;
--
2.11.0
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH v3 net-next 8/8] vxlan: support flow dissect
2017-09-28 21:48 [PATCH v3 net-next 1/8] flow_dissector: Change skbuf argument to be non const Tom Herbert
` (5 preceding siblings ...)
2017-09-28 21:48 ` [PATCH v3 net-next 7/8] fou: Support flow dissection Tom Herbert
@ 2017-09-28 21:48 ` Tom Herbert
2017-09-30 21:46 ` [PATCH v3 net-next 1/8] flow_dissector: Change skbuf argument to be non const kbuild test robot
7 siblings, 0 replies; 9+ messages in thread
From: Tom Herbert @ 2017-09-28 21:48 UTC (permalink / raw)
To: davem; +Cc: netdev, rohit, Tom Herbert
Populate offload flow_dissect callback appropriately for VXLAN and
VXLAN-GPE.
Signed-off-by: Tom Herbert <tom@quantonium.net>
---
drivers/net/vxlan.c | 40 ++++++++++++++++++++++++++++++++++++++++
1 file changed, 40 insertions(+)
diff --git a/drivers/net/vxlan.c b/drivers/net/vxlan.c
index d7c49cf1d5e9..80227050b2d4 100644
--- a/drivers/net/vxlan.c
+++ b/drivers/net/vxlan.c
@@ -1327,6 +1327,45 @@ static bool vxlan_ecn_decapsulate(struct vxlan_sock *vs, void *oiph,
return err <= 1;
}
+static enum flow_dissect_ret vxlan_flow_dissect(struct sock *sk,
+ const struct sk_buff *skb,
+ struct flow_dissector_key_control *key_control,
+ struct flow_dissector *flow_dissector,
+ void *target_container, void *data,
+ __be16 *p_proto, u8 *p_ip_proto, int *p_nhoff,
+ int *p_hlen, unsigned int flags)
+{
+ __be16 protocol = htons(ETH_P_TEB);
+ struct vxlanhdr *vhdr, _vhdr;
+ struct vxlan_sock *vs;
+
+ vhdr = __skb_header_pointer(skb, *p_nhoff + sizeof(struct udphdr),
+ sizeof(_vhdr), data, *p_hlen, &_vhdr);
+ if (!vhdr)
+ return FLOW_DISSECT_RET_OUT_BAD;
+
+ vs = rcu_dereference_sk_user_data(sk);
+ if (!vs)
+ return FLOW_DISSECT_RET_OUT_BAD;
+
+ if (vs->flags & VXLAN_F_GPE) {
+ struct vxlanhdr_gpe *gpe = (struct vxlanhdr_gpe *)vhdr;
+
+ /* Need to have Next Protocol set for interfaces in GPE mode. */
+ if (gpe->version != 0 || !gpe->np_applied || gpe->oam_flag)
+ return FLOW_DISSECT_RET_CONTINUE;
+
+ protocol = tun_p_from_eth_p(gpe->next_protocol);
+ if (!protocol)
+ return FLOW_DISSECT_RET_CONTINUE;
+ }
+
+ *p_nhoff += sizeof(struct udphdr) + sizeof(_vhdr);
+ *p_proto = protocol;
+
+ return FLOW_DISSECT_RET_PROTO_AGAIN;
+}
+
/* Callback from net/ipv4/udp.c to receive packets */
static int vxlan_rcv(struct sock *sk, struct sk_buff *skb)
{
@@ -2846,6 +2885,7 @@ static struct vxlan_sock *vxlan_socket_create(struct net *net, bool ipv6,
tunnel_cfg.encap_destroy = NULL;
tunnel_cfg.gro_receive = vxlan_gro_receive;
tunnel_cfg.gro_complete = vxlan_gro_complete;
+ tunnel_cfg.flow_dissect = vxlan_flow_dissect;
setup_udp_tunnel_sock(net, sock, &tunnel_cfg);
--
2.11.0
^ permalink raw reply related [flat|nested] 9+ messages in thread
* Re: [PATCH v3 net-next 1/8] flow_dissector: Change skbuf argument to be non const
2017-09-28 21:48 [PATCH v3 net-next 1/8] flow_dissector: Change skbuf argument to be non const Tom Herbert
` (6 preceding siblings ...)
2017-09-28 21:48 ` [PATCH v3 net-next 8/8] vxlan: support flow dissect Tom Herbert
@ 2017-09-30 21:46 ` kbuild test robot
7 siblings, 0 replies; 9+ messages in thread
From: kbuild test robot @ 2017-09-30 21:46 UTC (permalink / raw)
To: Tom Herbert; +Cc: kbuild-all, davem, netdev, rohit, Tom Herbert
[-- Attachment #1: Type: text/plain, Size: 7201 bytes --]
Hi Tom,
[auto build test WARNING on net-next/master]
url: https://github.com/0day-ci/linux/commits/Tom-Herbert/flow_dissector-Change-skbuf-argument-to-be-non-const/20171001-052131
config: x86_64-randconfig-x010-201740 (attached as .config)
compiler: gcc-6 (Debian 6.2.0-3) 6.2.0 20160901
reproduce:
# save the attached .config to linux build tree
make ARCH=x86_64
All warnings (new ones prefixed by >>):
drivers/net/ethernet/sfc/rx.c: In function 'efx_filter_rfs':
>> drivers/net/ethernet/sfc/rx.c:842:34: warning: passing argument 1 of 'skb_flow_dissect_flow_keys' discards 'const' qualifier from pointer target type [-Wdiscarded-qualifiers]
if (!skb_flow_dissect_flow_keys(skb, &fk, 0))
^~~
In file included from include/linux/ip.h:20:0,
from drivers/net/ethernet/sfc/rx.c:14:
include/linux/skbuff.h:1189:20: note: expected 'struct sk_buff *' but argument is of type 'const struct sk_buff *'
static inline bool skb_flow_dissect_flow_keys(struct sk_buff *skb,
^~~~~~~~~~~~~~~~~~~~~~~~~~
--
drivers/net/ethernet/sfc/falcon/rx.c: In function 'ef4_filter_rfs':
>> drivers/net/ethernet/sfc/falcon/rx.c:848:34: warning: passing argument 1 of 'skb_flow_dissect_flow_keys' discards 'const' qualifier from pointer target type [-Wdiscarded-qualifiers]
if (!skb_flow_dissect_flow_keys(skb, &fk, 0))
^~~
In file included from include/linux/ip.h:20:0,
from drivers/net/ethernet/sfc/falcon/rx.c:14:
include/linux/skbuff.h:1189:20: note: expected 'struct sk_buff *' but argument is of type 'const struct sk_buff *'
static inline bool skb_flow_dissect_flow_keys(struct sk_buff *skb,
^~~~~~~~~~~~~~~~~~~~~~~~~~
vim +842 drivers/net/ethernet/sfc/rx.c
add724771 Ben Hutchings 2012-11-08 829
add724771 Ben Hutchings 2012-11-08 830 int efx_filter_rfs(struct net_device *net_dev, const struct sk_buff *skb,
add724771 Ben Hutchings 2012-11-08 831 u16 rxq_index, u32 flow_id)
add724771 Ben Hutchings 2012-11-08 832 {
add724771 Ben Hutchings 2012-11-08 833 struct efx_nic *efx = netdev_priv(net_dev);
add724771 Ben Hutchings 2012-11-08 834 struct efx_channel *channel;
add724771 Ben Hutchings 2012-11-08 835 struct efx_filter_spec spec;
68bb399e6 Edward Cree 2016-05-26 836 struct flow_keys fk;
add724771 Ben Hutchings 2012-11-08 837 int rc;
add724771 Ben Hutchings 2012-11-08 838
faf8dcc12 Jon Cooper 2016-05-31 839 if (flow_id == RPS_FLOW_ID_INVALID)
faf8dcc12 Jon Cooper 2016-05-31 840 return -EINVAL;
faf8dcc12 Jon Cooper 2016-05-31 841
68bb399e6 Edward Cree 2016-05-26 @842 if (!skb_flow_dissect_flow_keys(skb, &fk, 0))
68bb399e6 Edward Cree 2016-05-26 843 return -EPROTONOSUPPORT;
add724771 Ben Hutchings 2012-11-08 844
68bb399e6 Edward Cree 2016-05-26 845 if (fk.basic.n_proto != htons(ETH_P_IP) && fk.basic.n_proto != htons(ETH_P_IPV6))
68bb399e6 Edward Cree 2016-05-26 846 return -EPROTONOSUPPORT;
68bb399e6 Edward Cree 2016-05-26 847 if (fk.control.flags & FLOW_DIS_IS_FRAGMENT)
c47b2d9d5 Ben Hutchings 2013-09-03 848 return -EPROTONOSUPPORT;
c47b2d9d5 Ben Hutchings 2013-09-03 849
c47b2d9d5 Ben Hutchings 2013-09-03 850 efx_filter_init_rx(&spec, EFX_FILTER_PRI_HINT,
c47b2d9d5 Ben Hutchings 2013-09-03 851 efx->rx_scatter ? EFX_FILTER_FLAG_RX_SCATTER : 0,
c47b2d9d5 Ben Hutchings 2013-09-03 852 rxq_index);
c47b2d9d5 Ben Hutchings 2013-09-03 853 spec.match_flags =
c47b2d9d5 Ben Hutchings 2013-09-03 854 EFX_FILTER_MATCH_ETHER_TYPE | EFX_FILTER_MATCH_IP_PROTO |
c47b2d9d5 Ben Hutchings 2013-09-03 855 EFX_FILTER_MATCH_LOC_HOST | EFX_FILTER_MATCH_LOC_PORT |
c47b2d9d5 Ben Hutchings 2013-09-03 856 EFX_FILTER_MATCH_REM_HOST | EFX_FILTER_MATCH_REM_PORT;
68bb399e6 Edward Cree 2016-05-26 857 spec.ether_type = fk.basic.n_proto;
68bb399e6 Edward Cree 2016-05-26 858 spec.ip_proto = fk.basic.ip_proto;
c47b2d9d5 Ben Hutchings 2013-09-03 859
68bb399e6 Edward Cree 2016-05-26 860 if (fk.basic.n_proto == htons(ETH_P_IP)) {
68bb399e6 Edward Cree 2016-05-26 861 spec.rem_host[0] = fk.addrs.v4addrs.src;
68bb399e6 Edward Cree 2016-05-26 862 spec.loc_host[0] = fk.addrs.v4addrs.dst;
c47b2d9d5 Ben Hutchings 2013-09-03 863 } else {
68bb399e6 Edward Cree 2016-05-26 864 memcpy(spec.rem_host, &fk.addrs.v6addrs.src, sizeof(struct in6_addr));
68bb399e6 Edward Cree 2016-05-26 865 memcpy(spec.loc_host, &fk.addrs.v6addrs.dst, sizeof(struct in6_addr));
c47b2d9d5 Ben Hutchings 2013-09-03 866 }
c47b2d9d5 Ben Hutchings 2013-09-03 867
68bb399e6 Edward Cree 2016-05-26 868 spec.rem_port = fk.ports.src;
68bb399e6 Edward Cree 2016-05-26 869 spec.loc_port = fk.ports.dst;
add724771 Ben Hutchings 2012-11-08 870
add724771 Ben Hutchings 2012-11-08 871 rc = efx->type->filter_rfs_insert(efx, &spec);
add724771 Ben Hutchings 2012-11-08 872 if (rc < 0)
add724771 Ben Hutchings 2012-11-08 873 return rc;
add724771 Ben Hutchings 2012-11-08 874
add724771 Ben Hutchings 2012-11-08 875 /* Remember this so we can check whether to expire the filter later */
faf8dcc12 Jon Cooper 2016-05-31 876 channel = efx_get_channel(efx, rxq_index);
faf8dcc12 Jon Cooper 2016-05-31 877 channel->rps_flow_id[rc] = flow_id;
add724771 Ben Hutchings 2012-11-08 878 ++channel->rfs_filters_added;
add724771 Ben Hutchings 2012-11-08 879
68bb399e6 Edward Cree 2016-05-26 880 if (spec.ether_type == htons(ETH_P_IP))
add724771 Ben Hutchings 2012-11-08 881 netif_info(efx, rx_status, efx->net_dev,
add724771 Ben Hutchings 2012-11-08 882 "steering %s %pI4:%u:%pI4:%u to queue %u [flow %u filter %d]\n",
c47b2d9d5 Ben Hutchings 2013-09-03 883 (spec.ip_proto == IPPROTO_TCP) ? "TCP" : "UDP",
68bb399e6 Edward Cree 2016-05-26 884 spec.rem_host, ntohs(spec.rem_port), spec.loc_host,
68bb399e6 Edward Cree 2016-05-26 885 ntohs(spec.loc_port), rxq_index, flow_id, rc);
c47b2d9d5 Ben Hutchings 2013-09-03 886 else
c47b2d9d5 Ben Hutchings 2013-09-03 887 netif_info(efx, rx_status, efx->net_dev,
c47b2d9d5 Ben Hutchings 2013-09-03 888 "steering %s [%pI6]:%u:[%pI6]:%u to queue %u [flow %u filter %d]\n",
c47b2d9d5 Ben Hutchings 2013-09-03 889 (spec.ip_proto == IPPROTO_TCP) ? "TCP" : "UDP",
68bb399e6 Edward Cree 2016-05-26 890 spec.rem_host, ntohs(spec.rem_port), spec.loc_host,
68bb399e6 Edward Cree 2016-05-26 891 ntohs(spec.loc_port), rxq_index, flow_id, rc);
add724771 Ben Hutchings 2012-11-08 892
add724771 Ben Hutchings 2012-11-08 893 return rc;
add724771 Ben Hutchings 2012-11-08 894 }
add724771 Ben Hutchings 2012-11-08 895
:::::: The code at line 842 was first introduced by commit
:::::: 68bb399e656f244d3d173a20a8280c167632fca8 sfc: use flow dissector helpers for aRFS
:::::: TO: Edward Cree <ecree@solarflare.com>
:::::: CC: David S. Miller <davem@davemloft.net>
---
0-DAY kernel test infrastructure Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all Intel Corporation
[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 30375 bytes --]
^ permalink raw reply [flat|nested] 9+ messages in thread