* [patch net-next] net: mvneta: Indent some statements
From: Dan Carpenter @ 2016-12-07 11:32 UTC (permalink / raw)
To: Thomas Petazzoni, Marcin Wojtas; +Cc: netdev, kernel-janitors
These two statements were not indented correctly so it's sort of
confusing.
Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com>
diff --git a/drivers/net/ethernet/marvell/mvneta.c b/drivers/net/ethernet/marvell/mvneta.c
index 5e5b259dd2cc..e05e22705cf7 100644
--- a/drivers/net/ethernet/marvell/mvneta.c
+++ b/drivers/net/ethernet/marvell/mvneta.c
@@ -3578,9 +3578,10 @@ static int mvneta_stop(struct net_device *dev)
mvneta_stop_dev(pp);
mvneta_mdio_remove(pp);
- cpuhp_state_remove_instance_nocalls(online_hpstate, &pp->node_online);
- cpuhp_state_remove_instance_nocalls(CPUHP_NET_MVNETA_DEAD,
- &pp->node_dead);
+ cpuhp_state_remove_instance_nocalls(online_hpstate,
+ &pp->node_online);
+ cpuhp_state_remove_instance_nocalls(CPUHP_NET_MVNETA_DEAD,
+ &pp->node_dead);
on_each_cpu(mvneta_percpu_disable, pp, true);
free_percpu_irq(dev->irq, pp->ports);
} else {
^ permalink raw reply related
* Re: [PATCH net-next v4 2/2] net/sched: cls_flower: Support matching on ICMP type and code
From: Jiri Pirko @ 2016-12-07 11:39 UTC (permalink / raw)
To: Simon Horman; +Cc: Jiri Pirko, Tom Herbert, David Miller, netdev
In-Reply-To: <1481110452-3129-3-git-send-email-simon.horman@netronome.com>
Wed, Dec 07, 2016 at 12:34:12PM CET, simon.horman@netronome.com wrote:
>Support matching on ICMP type and code.
>
>Example usage:
>
>tc qdisc add dev eth0 ingress
>
>tc filter add dev eth0 protocol ip parent ffff: flower \
> indev eth0 ip_proto icmp type 8 code 0 action drop
>
>tc filter add dev eth0 protocol ipv6 parent ffff: flower \
> indev eth0 ip_proto icmpv6 type 128 code 0 action drop
>
>Signed-off-by: Simon Horman <simon.horman@netronome.com>
>---
>v3
>* Use separate dissector key FLOW_DISSECTOR_KEY_ICMP
>* Use separate structure to hold icmp fields, this does not share
> storage with ports
>
>v2
>* Move helpers to another patch
>---
> include/uapi/linux/pkt_cls.h | 10 +++++++++
> net/sched/cls_flower.c | 49 ++++++++++++++++++++++++++++++++++++++++++++
> 2 files changed, 59 insertions(+)
>
>diff --git a/include/uapi/linux/pkt_cls.h b/include/uapi/linux/pkt_cls.h
>index 1adc0b654996..884c5aa515c4 100644
>--- a/include/uapi/linux/pkt_cls.h
>+++ b/include/uapi/linux/pkt_cls.h
>@@ -458,6 +458,16 @@ enum {
> TCA_FLOWER_KEY_ENC_UDP_SRC_PORT_MASK, /* be16 */
> TCA_FLOWER_KEY_ENC_UDP_DST_PORT, /* be16 */
> TCA_FLOWER_KEY_ENC_UDP_DST_PORT_MASK, /* be16 */
>+
>+ TCA_FLOWER_KEY_ICMPV4_CODE, /* u8 */
>+ TCA_FLOWER_KEY_ICMPV4_CODE_MASK,/* u8 */
>+ TCA_FLOWER_KEY_ICMPV4_TYPE, /* u8 */
>+ TCA_FLOWER_KEY_ICMPV4_TYPE_MASK,/* u8 */
>+ TCA_FLOWER_KEY_ICMPV6_CODE, /* u8 */
>+ TCA_FLOWER_KEY_ICMPV6_CODE_MASK,/* u8 */
>+ TCA_FLOWER_KEY_ICMPV6_TYPE, /* u8 */
>+ TCA_FLOWER_KEY_ICMPV6_TYPE_MASK,/* u8 */
>+
> __TCA_FLOWER_MAX,
> };
>
>diff --git a/net/sched/cls_flower.c b/net/sched/cls_flower.c
>index 29a9e6d9f274..56df0368125a 100644
>--- a/net/sched/cls_flower.c
>+++ b/net/sched/cls_flower.c
>@@ -39,6 +39,7 @@ struct fl_flow_key {
> struct flow_dissector_key_ipv6_addrs ipv6;
> };
> struct flow_dissector_key_ports tp;
>+ struct flow_dissector_key_icmp icmp;
> struct flow_dissector_key_keyid enc_key_id;
> union {
> struct flow_dissector_key_ipv4_addrs enc_ipv4;
>@@ -386,6 +387,14 @@ static const struct nla_policy fl_policy[TCA_FLOWER_MAX + 1] = {
> [TCA_FLOWER_KEY_ENC_UDP_SRC_PORT_MASK] = { .type = NLA_U16 },
> [TCA_FLOWER_KEY_ENC_UDP_DST_PORT] = { .type = NLA_U16 },
> [TCA_FLOWER_KEY_ENC_UDP_DST_PORT_MASK] = { .type = NLA_U16 },
>+ [TCA_FLOWER_KEY_ICMPV4_TYPE] = { .type = NLA_U8 },
>+ [TCA_FLOWER_KEY_ICMPV4_TYPE_MASK] = { .type = NLA_U8 },
>+ [TCA_FLOWER_KEY_ICMPV4_CODE] = { .type = NLA_U8 },
>+ [TCA_FLOWER_KEY_ICMPV4_CODE_MASK] = { .type = NLA_U8 },
>+ [TCA_FLOWER_KEY_ICMPV6_TYPE] = { .type = NLA_U8 },
>+ [TCA_FLOWER_KEY_ICMPV6_TYPE_MASK] = { .type = NLA_U8 },
>+ [TCA_FLOWER_KEY_ICMPV6_CODE] = { .type = NLA_U8 },
>+ [TCA_FLOWER_KEY_ICMPV6_CODE_MASK] = { .type = NLA_U8 },
> };
>
> static void fl_set_key_val(struct nlattr **tb,
>@@ -502,6 +511,24 @@ static int fl_set_key(struct net *net, struct nlattr **tb,
> fl_set_key_val(tb, &key->tp.dst, TCA_FLOWER_KEY_SCTP_DST,
> &mask->tp.dst, TCA_FLOWER_KEY_SCTP_DST_MASK,
> sizeof(key->tp.dst));
>+ } else if (flow_basic_key_is_icmpv4(&key->basic)) {
Please just use:
key->basic.n_proto and key->basic.ip_proto
like the rest of the code. And drop the helpers.
The rest looks fine to me.
>+ fl_set_key_val(tb, &key->icmp.type, TCA_FLOWER_KEY_ICMPV4_TYPE,
>+ &mask->icmp.type,
>+ TCA_FLOWER_KEY_ICMPV4_TYPE_MASK,
>+ sizeof(key->icmp.type));
>+ fl_set_key_val(tb, &key->icmp.code, TCA_FLOWER_KEY_ICMPV4_CODE,
>+ &mask->icmp.code,
>+ TCA_FLOWER_KEY_ICMPV4_CODE_MASK,
>+ sizeof(key->icmp.code));
>+ } else if (flow_basic_key_is_icmpv6(&key->basic)) {
>+ fl_set_key_val(tb, &key->icmp.type, TCA_FLOWER_KEY_ICMPV6_TYPE,
>+ &mask->icmp.type,
>+ TCA_FLOWER_KEY_ICMPV6_TYPE_MASK,
>+ sizeof(key->icmp.type));
>+ fl_set_key_val(tb, &key->icmp.code, TCA_FLOWER_KEY_ICMPV4_CODE,
>+ &mask->icmp.code,
>+ TCA_FLOWER_KEY_ICMPV4_CODE_MASK,
>+ sizeof(key->icmp.code));
> }
>
> if (tb[TCA_FLOWER_KEY_ENC_IPV4_SRC] ||
>@@ -612,6 +639,8 @@ static void fl_init_dissector(struct cls_fl_head *head,
> FL_KEY_SET_IF_MASKED(&mask->key, keys, cnt,
> FLOW_DISSECTOR_KEY_PORTS, tp);
> FL_KEY_SET_IF_MASKED(&mask->key, keys, cnt,
>+ FLOW_DISSECTOR_KEY_ICMP, icmp);
>+ FL_KEY_SET_IF_MASKED(&mask->key, keys, cnt,
> FLOW_DISSECTOR_KEY_VLAN, vlan);
> FL_KEY_SET_IF_MASKED(&mask->key, keys, cnt,
> FLOW_DISSECTOR_KEY_ENC_KEYID, enc_key_id);
>@@ -977,6 +1006,26 @@ static int fl_dump(struct net *net, struct tcf_proto *tp, unsigned long fh,
> &mask->tp.dst, TCA_FLOWER_KEY_SCTP_DST_MASK,
> sizeof(key->tp.dst))))
> goto nla_put_failure;
>+ else if (flow_basic_key_is_icmpv4(&key->basic) &&
>+ (fl_dump_key_val(skb, &key->icmp.type,
>+ TCA_FLOWER_KEY_ICMPV4_TYPE, &mask->icmp.type,
>+ TCA_FLOWER_KEY_ICMPV4_TYPE_MASK,
>+ sizeof(key->icmp.type)) ||
>+ fl_dump_key_val(skb, &key->icmp.code,
>+ TCA_FLOWER_KEY_ICMPV4_CODE, &mask->icmp.code,
>+ TCA_FLOWER_KEY_ICMPV4_CODE_MASK,
>+ sizeof(key->icmp.code))))
>+ goto nla_put_failure;
>+ else if (flow_basic_key_is_icmpv6(&key->basic) &&
>+ (fl_dump_key_val(skb, &key->icmp.type,
>+ TCA_FLOWER_KEY_ICMPV6_TYPE, &mask->icmp.type,
>+ TCA_FLOWER_KEY_ICMPV6_TYPE_MASK,
>+ sizeof(key->icmp.type)) ||
>+ fl_dump_key_val(skb, &key->icmp.code,
>+ TCA_FLOWER_KEY_ICMPV6_CODE, &mask->icmp.code,
>+ TCA_FLOWER_KEY_ICMPV6_CODE_MASK,
>+ sizeof(key->icmp.code))))
>+ goto nla_put_failure;
>
> if (key->enc_control.addr_type == FLOW_DISSECTOR_KEY_IPV4_ADDRS &&
> (fl_dump_key_val(skb, &key->enc_ipv4.src,
>--
>2.7.0.rc3.207.g0ac5344
>
^ permalink raw reply
* [PATCH net-next v4 2/2] net/sched: cls_flower: Support matching on ICMP type and code
From: Simon Horman @ 2016-12-07 11:34 UTC (permalink / raw)
To: Jiri Pirko; +Cc: Tom Herbert, David Miller, netdev, Simon Horman
In-Reply-To: <1481110452-3129-1-git-send-email-simon.horman@netronome.com>
Support matching on ICMP type and code.
Example usage:
tc qdisc add dev eth0 ingress
tc filter add dev eth0 protocol ip parent ffff: flower \
indev eth0 ip_proto icmp type 8 code 0 action drop
tc filter add dev eth0 protocol ipv6 parent ffff: flower \
indev eth0 ip_proto icmpv6 type 128 code 0 action drop
Signed-off-by: Simon Horman <simon.horman@netronome.com>
---
v3
* Use separate dissector key FLOW_DISSECTOR_KEY_ICMP
* Use separate structure to hold icmp fields, this does not share
storage with ports
v2
* Move helpers to another patch
---
include/uapi/linux/pkt_cls.h | 10 +++++++++
net/sched/cls_flower.c | 49 ++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 59 insertions(+)
diff --git a/include/uapi/linux/pkt_cls.h b/include/uapi/linux/pkt_cls.h
index 1adc0b654996..884c5aa515c4 100644
--- a/include/uapi/linux/pkt_cls.h
+++ b/include/uapi/linux/pkt_cls.h
@@ -458,6 +458,16 @@ enum {
TCA_FLOWER_KEY_ENC_UDP_SRC_PORT_MASK, /* be16 */
TCA_FLOWER_KEY_ENC_UDP_DST_PORT, /* be16 */
TCA_FLOWER_KEY_ENC_UDP_DST_PORT_MASK, /* be16 */
+
+ TCA_FLOWER_KEY_ICMPV4_CODE, /* u8 */
+ TCA_FLOWER_KEY_ICMPV4_CODE_MASK,/* u8 */
+ TCA_FLOWER_KEY_ICMPV4_TYPE, /* u8 */
+ TCA_FLOWER_KEY_ICMPV4_TYPE_MASK,/* u8 */
+ TCA_FLOWER_KEY_ICMPV6_CODE, /* u8 */
+ TCA_FLOWER_KEY_ICMPV6_CODE_MASK,/* u8 */
+ TCA_FLOWER_KEY_ICMPV6_TYPE, /* u8 */
+ TCA_FLOWER_KEY_ICMPV6_TYPE_MASK,/* u8 */
+
__TCA_FLOWER_MAX,
};
diff --git a/net/sched/cls_flower.c b/net/sched/cls_flower.c
index 29a9e6d9f274..56df0368125a 100644
--- a/net/sched/cls_flower.c
+++ b/net/sched/cls_flower.c
@@ -39,6 +39,7 @@ struct fl_flow_key {
struct flow_dissector_key_ipv6_addrs ipv6;
};
struct flow_dissector_key_ports tp;
+ struct flow_dissector_key_icmp icmp;
struct flow_dissector_key_keyid enc_key_id;
union {
struct flow_dissector_key_ipv4_addrs enc_ipv4;
@@ -386,6 +387,14 @@ static const struct nla_policy fl_policy[TCA_FLOWER_MAX + 1] = {
[TCA_FLOWER_KEY_ENC_UDP_SRC_PORT_MASK] = { .type = NLA_U16 },
[TCA_FLOWER_KEY_ENC_UDP_DST_PORT] = { .type = NLA_U16 },
[TCA_FLOWER_KEY_ENC_UDP_DST_PORT_MASK] = { .type = NLA_U16 },
+ [TCA_FLOWER_KEY_ICMPV4_TYPE] = { .type = NLA_U8 },
+ [TCA_FLOWER_KEY_ICMPV4_TYPE_MASK] = { .type = NLA_U8 },
+ [TCA_FLOWER_KEY_ICMPV4_CODE] = { .type = NLA_U8 },
+ [TCA_FLOWER_KEY_ICMPV4_CODE_MASK] = { .type = NLA_U8 },
+ [TCA_FLOWER_KEY_ICMPV6_TYPE] = { .type = NLA_U8 },
+ [TCA_FLOWER_KEY_ICMPV6_TYPE_MASK] = { .type = NLA_U8 },
+ [TCA_FLOWER_KEY_ICMPV6_CODE] = { .type = NLA_U8 },
+ [TCA_FLOWER_KEY_ICMPV6_CODE_MASK] = { .type = NLA_U8 },
};
static void fl_set_key_val(struct nlattr **tb,
@@ -502,6 +511,24 @@ static int fl_set_key(struct net *net, struct nlattr **tb,
fl_set_key_val(tb, &key->tp.dst, TCA_FLOWER_KEY_SCTP_DST,
&mask->tp.dst, TCA_FLOWER_KEY_SCTP_DST_MASK,
sizeof(key->tp.dst));
+ } else if (flow_basic_key_is_icmpv4(&key->basic)) {
+ fl_set_key_val(tb, &key->icmp.type, TCA_FLOWER_KEY_ICMPV4_TYPE,
+ &mask->icmp.type,
+ TCA_FLOWER_KEY_ICMPV4_TYPE_MASK,
+ sizeof(key->icmp.type));
+ fl_set_key_val(tb, &key->icmp.code, TCA_FLOWER_KEY_ICMPV4_CODE,
+ &mask->icmp.code,
+ TCA_FLOWER_KEY_ICMPV4_CODE_MASK,
+ sizeof(key->icmp.code));
+ } else if (flow_basic_key_is_icmpv6(&key->basic)) {
+ fl_set_key_val(tb, &key->icmp.type, TCA_FLOWER_KEY_ICMPV6_TYPE,
+ &mask->icmp.type,
+ TCA_FLOWER_KEY_ICMPV6_TYPE_MASK,
+ sizeof(key->icmp.type));
+ fl_set_key_val(tb, &key->icmp.code, TCA_FLOWER_KEY_ICMPV4_CODE,
+ &mask->icmp.code,
+ TCA_FLOWER_KEY_ICMPV4_CODE_MASK,
+ sizeof(key->icmp.code));
}
if (tb[TCA_FLOWER_KEY_ENC_IPV4_SRC] ||
@@ -612,6 +639,8 @@ static void fl_init_dissector(struct cls_fl_head *head,
FL_KEY_SET_IF_MASKED(&mask->key, keys, cnt,
FLOW_DISSECTOR_KEY_PORTS, tp);
FL_KEY_SET_IF_MASKED(&mask->key, keys, cnt,
+ FLOW_DISSECTOR_KEY_ICMP, icmp);
+ FL_KEY_SET_IF_MASKED(&mask->key, keys, cnt,
FLOW_DISSECTOR_KEY_VLAN, vlan);
FL_KEY_SET_IF_MASKED(&mask->key, keys, cnt,
FLOW_DISSECTOR_KEY_ENC_KEYID, enc_key_id);
@@ -977,6 +1006,26 @@ static int fl_dump(struct net *net, struct tcf_proto *tp, unsigned long fh,
&mask->tp.dst, TCA_FLOWER_KEY_SCTP_DST_MASK,
sizeof(key->tp.dst))))
goto nla_put_failure;
+ else if (flow_basic_key_is_icmpv4(&key->basic) &&
+ (fl_dump_key_val(skb, &key->icmp.type,
+ TCA_FLOWER_KEY_ICMPV4_TYPE, &mask->icmp.type,
+ TCA_FLOWER_KEY_ICMPV4_TYPE_MASK,
+ sizeof(key->icmp.type)) ||
+ fl_dump_key_val(skb, &key->icmp.code,
+ TCA_FLOWER_KEY_ICMPV4_CODE, &mask->icmp.code,
+ TCA_FLOWER_KEY_ICMPV4_CODE_MASK,
+ sizeof(key->icmp.code))))
+ goto nla_put_failure;
+ else if (flow_basic_key_is_icmpv6(&key->basic) &&
+ (fl_dump_key_val(skb, &key->icmp.type,
+ TCA_FLOWER_KEY_ICMPV6_TYPE, &mask->icmp.type,
+ TCA_FLOWER_KEY_ICMPV6_TYPE_MASK,
+ sizeof(key->icmp.type)) ||
+ fl_dump_key_val(skb, &key->icmp.code,
+ TCA_FLOWER_KEY_ICMPV6_CODE, &mask->icmp.code,
+ TCA_FLOWER_KEY_ICMPV6_CODE_MASK,
+ sizeof(key->icmp.code))))
+ goto nla_put_failure;
if (key->enc_control.addr_type == FLOW_DISSECTOR_KEY_IPV4_ADDRS &&
(fl_dump_key_val(skb, &key->enc_ipv4.src,
--
2.7.0.rc3.207.g0ac5344
^ permalink raw reply related
* [PATCH net-next v4 1/2] flow dissector: ICMP support
From: Simon Horman @ 2016-12-07 11:34 UTC (permalink / raw)
To: Jiri Pirko; +Cc: Tom Herbert, David Miller, netdev, Simon Horman
In-Reply-To: <1481110452-3129-1-git-send-email-simon.horman@netronome.com>
Allow dissection of ICMP(V6) type and code. This should only occur
if a packet is ICMP(V6) and the dissector has FLOW_DISSECTOR_KEY_ICMP set.
There are currently no users of FLOW_DISSECTOR_KEY_ICMP.
A follow-up patch will allow FLOW_DISSECTOR_KEY_ICMP to be used by
the flower classifier.
---
v4
* Do not add icmp to struct flow_keys, it is not needed
* Do not test for ICMP protocols in packet in __skb_flow_dissect,
this is also not needed
* Drop now unnecessary helpers
v3
* Add FLOW_DISSECTOR_KEY_ICMP and use separate structure for ICMP, struct
flow_dissector_key_icmp, which is a union with struct
flow_dissector_key_ports in struct flow_keys.
* Drop checks for !ICMP before accessing port field
v2
* Include all helpers in this patch
---
include/net/flow_dissector.h | 30 ++++++++++++++++++++++++++++++
net/core/flow_dissector.c | 31 +++++++++++++++++++++++++++++++
2 files changed, 61 insertions(+)
diff --git a/include/net/flow_dissector.h b/include/net/flow_dissector.h
index c4f31666afd2..0b94812cfe09 100644
--- a/include/net/flow_dissector.h
+++ b/include/net/flow_dissector.h
@@ -2,6 +2,7 @@
#define _NET_FLOW_DISSECTOR_H
#include <linux/types.h>
+#include <linux/in.h>
#include <linux/in6.h>
#include <uapi/linux/if_ether.h>
@@ -104,6 +105,22 @@ struct flow_dissector_key_ports {
};
};
+/**
+ * flow_dissector_key_icmp:
+ * @ports: type and code of ICMP header
+ * icmp: ICMP type (high) and code (low)
+ * type: ICMP type
+ * code: ICMP code
+ */
+struct flow_dissector_key_icmp {
+ union {
+ __be16 icmp;
+ struct {
+ u8 type;
+ u8 code;
+ };
+ };
+};
/**
* struct flow_dissector_key_eth_addrs:
@@ -122,6 +139,7 @@ enum flow_dissector_key_id {
FLOW_DISSECTOR_KEY_IPV4_ADDRS, /* struct flow_dissector_key_ipv4_addrs */
FLOW_DISSECTOR_KEY_IPV6_ADDRS, /* struct flow_dissector_key_ipv6_addrs */
FLOW_DISSECTOR_KEY_PORTS, /* struct flow_dissector_key_ports */
+ FLOW_DISSECTOR_KEY_ICMP, /* struct flow_dissector_key_icmp */
FLOW_DISSECTOR_KEY_ETH_ADDRS, /* struct flow_dissector_key_eth_addrs */
FLOW_DISSECTOR_KEY_TIPC_ADDRS, /* struct flow_dissector_key_tipc_addrs */
FLOW_DISSECTOR_KEY_VLAN, /* struct flow_dissector_key_flow_vlan */
@@ -188,6 +206,18 @@ struct flow_keys_digest {
void make_flow_keys_digest(struct flow_keys_digest *digest,
const struct flow_keys *flow);
+static inline bool flow_basic_key_is_icmpv4(const struct flow_dissector_key_basic *basic)
+{
+ return basic->n_proto == htons(ETH_P_IP) &&
+ basic->ip_proto == IPPROTO_ICMP;
+}
+
+static inline bool flow_basic_key_is_icmpv6(const struct flow_dissector_key_basic *basic)
+{
+ return basic->n_proto == htons(ETH_P_IPV6) &&
+ basic->ip_proto == IPPROTO_ICMPV6;
+}
+
static inline bool flow_keys_have_l4(const struct flow_keys *keys)
{
return (keys->ports.ports || keys->tags.flow_label);
diff --git a/net/core/flow_dissector.c b/net/core/flow_dissector.c
index 1eb6f949e5b2..d6447dc10371 100644
--- a/net/core/flow_dissector.c
+++ b/net/core/flow_dissector.c
@@ -58,6 +58,28 @@ void skb_flow_dissector_init(struct flow_dissector *flow_dissector,
EXPORT_SYMBOL(skb_flow_dissector_init);
/**
+ * skb_flow_get_be16 - extract be16 entity
+ * @skb: sk_buff to extract from
+ * @poff: offset to extract at
+ * @data: raw buffer pointer to the packet
+ * @hlen: packet header length
+ *
+ * The function will try to retrieve a be32 entity at
+ * offset poff
+ */
+__be16 skb_flow_get_be16(const struct sk_buff *skb, int poff, void *data,
+ int hlen)
+{
+ __be16 *u, _u;
+
+ u = __skb_header_pointer(skb, poff, sizeof(_u), data, hlen, &_u);
+ if (u)
+ return *u;
+
+ return 0;
+}
+
+/**
* __skb_flow_get_ports - extract the upper layer ports and return them
* @skb: sk_buff to extract the ports from
* @thoff: transport header offset
@@ -117,6 +139,7 @@ bool __skb_flow_dissect(const struct sk_buff *skb,
struct flow_dissector_key_basic *key_basic;
struct flow_dissector_key_addrs *key_addrs;
struct flow_dissector_key_ports *key_ports;
+ struct flow_dissector_key_icmp *key_icmp;
struct flow_dissector_key_tags *key_tags;
struct flow_dissector_key_vlan *key_vlan;
struct flow_dissector_key_keyid *key_keyid;
@@ -546,6 +569,14 @@ bool __skb_flow_dissect(const struct sk_buff *skb,
data, hlen);
}
+ if (dissector_uses_key(flow_dissector,
+ FLOW_DISSECTOR_KEY_ICMP)) {
+ key_icmp = skb_flow_dissector_target(flow_dissector,
+ FLOW_DISSECTOR_KEY_ICMP,
+ target_container);
+ key_icmp->icmp = skb_flow_get_be16(skb, nhoff, data, hlen);
+ }
+
out_good:
ret = true;
--
2.7.0.rc3.207.g0ac5344
^ permalink raw reply related
* [PATCH net-next v4 0/2] net/sched: cls_flower: Support matching on ICMP
From: Simon Horman @ 2016-12-07 11:34 UTC (permalink / raw)
To: Jiri Pirko; +Cc: Tom Herbert, David Miller, netdev, Simon Horman
Hi,
this series adds support for matching on ICMP type and code to cls_flower.
Changes v3->v4:
* Do not add icmp to struct flow_keys, it is not needed
* Do not test for ICMP protocols in packet in __skb_flow_dissect,
this is also not needed
Changes v2->v3:
* Add FLOW_DISSECTOR_KEY_ICMP and use separate structure for ICMP
Changes v1->v2:
* Include all dissector helpers in first patch
Simon Horman (2):
flow dissector: ICMP support
net/sched: cls_flower: Support matching on ICMP type and code
include/net/flow_dissector.h | 30 +++++++++++++++++++++++++++
include/uapi/linux/pkt_cls.h | 10 +++++++++
net/core/flow_dissector.c | 31 ++++++++++++++++++++++++++++
net/sched/cls_flower.c | 49 ++++++++++++++++++++++++++++++++++++++++++++
4 files changed, 120 insertions(+)
--
2.7.0.rc3.207.g0ac5344
^ permalink raw reply
* [patch] ser_gigaset: return -ENOMEM on error instead of success
From: Dan Carpenter @ 2016-12-07 11:22 UTC (permalink / raw)
To: Paul Bolle, Tilman Schmidt
Cc: Karsten Keil, David S. Miller, gigaset307x-common, netdev,
kernel-janitors
If we can't allocate the resources in gigaset_initdriver() then we
should return -ENOMEM instead of zero.
Fixes: 2869b23e4b95 ("[PATCH] drivers/isdn/gigaset: new M101 driver (v2)")
Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com>
---
Ancient code.
diff --git a/drivers/isdn/gigaset/ser-gigaset.c b/drivers/isdn/gigaset/ser-gigaset.c
index d1f8ab915b15..b90776ef56ec 100644
--- a/drivers/isdn/gigaset/ser-gigaset.c
+++ b/drivers/isdn/gigaset/ser-gigaset.c
@@ -755,8 +755,10 @@ static int __init ser_gigaset_init(void)
driver = gigaset_initdriver(GIGASET_MINOR, GIGASET_MINORS,
GIGASET_MODULENAME, GIGASET_DEVNAME,
&ops, THIS_MODULE);
- if (!driver)
+ if (!driver) {
+ rc = -ENOMEM;
goto error;
+ }
rc = tty_register_ldisc(N_GIGASET_M101, &gigaset_ldisc);
if (rc != 0) {
^ permalink raw reply related
* [patch] drivers: net: xgene: uninitialized variable in xgene_enet_free_pagepool()
From: Dan Carpenter @ 2016-12-07 11:14 UTC (permalink / raw)
To: Iyappan Subramanian; +Cc: Keyur Chudgar, netdev, linux-kernel, kernel-janitors
We never set "slots" in this function.
Fixes: a9380b0f7be8 ("drivers: net: xgene: Add support for Jumbo frame")
Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com>
---
I copied how slots gets set in xgene_enet_rx_frame(). Static analysis.
Not tested.
diff --git a/drivers/net/ethernet/apm/xgene/xgene_enet_main.c b/drivers/net/ethernet/apm/xgene/xgene_enet_main.c
index 6c7eea8b36af..884a334e82d0 100644
--- a/drivers/net/ethernet/apm/xgene/xgene_enet_main.c
+++ b/drivers/net/ethernet/apm/xgene/xgene_enet_main.c
@@ -635,6 +635,7 @@ static void xgene_enet_free_pagepool(struct xgene_enet_desc_ring *buf_pool,
return;
dev = ndev_to_dev(buf_pool->ndev);
+ slots = buf_pool->slots - 1;
head = buf_pool->head;
for (i = 0; i < 4; i++) {
^ permalink raw reply related
* Re: [PATCH net-next v3 1/2] flow dissector: ICMP support
From: Simon Horman @ 2016-12-07 11:11 UTC (permalink / raw)
To: Jiri Pirko; +Cc: Jiri Pirko, Tom Herbert, David Miller, netdev
In-Reply-To: <20161207100148.GA1987@nanopsycho>
On Wed, Dec 07, 2016 at 11:01:48AM +0100, Jiri Pirko wrote:
> Wed, Dec 07, 2016 at 10:41:36AM CET, simon.horman@netronome.com wrote:
> >Allow dissection of ICMP(V6) type and code. This should only occur
> >if a packet is ICMP(V6) and the dissector has FLOW_DISSECTOR_KEY_ICMP set.
> >
> >There are currently no users of FLOW_DISSECTOR_KEY_ICMP.
> >A follow-up patch will allow FLOW_DISSECTOR_KEY_ICMP to be used by
> >the flower classifier.
> >---
> >v3
> >* Add FLOW_DISSECTOR_KEY_ICMP and use separate structure for ICMP, struct
> > flow_dissector_key_icmp, which is a union with struct
> > flow_dissector_key_ports in struct flow_keys.
> >* Drop checks for !ICMP before accessing port field
> >
> >v2
> >* Include all helpers in this patch
> >---
> > include/net/flow_dissector.h | 55 +++++++++++++++++++++++++++++++++++++++++++-
> > net/core/flow_dissector.c | 49 +++++++++++++++++++++++++++++++++------
> > 2 files changed, 96 insertions(+), 8 deletions(-)
> >
> >diff --git a/include/net/flow_dissector.h b/include/net/flow_dissector.h
> >index c4f31666afd2..aefb7a8138a6 100644
> >--- a/include/net/flow_dissector.h
> >+++ b/include/net/flow_dissector.h
> >@@ -2,6 +2,7 @@
> > #define _NET_FLOW_DISSECTOR_H
> >
> > #include <linux/types.h>
> >+#include <linux/in.h>
> > #include <linux/in6.h>
> > #include <uapi/linux/if_ether.h>
> >
> >@@ -104,6 +105,22 @@ struct flow_dissector_key_ports {
> > };
> > };
> >
> >+/**
> >+ * flow_dissector_key_icmp:
> >+ * @ports: type and code of ICMP header
> >+ * icmp: ICMP type (high) and code (low)
> >+ * type: ICMP type
> >+ * code: ICMP code
> >+ */
> >+struct flow_dissector_key_icmp {
> >+ union {
> >+ __be16 icmp;
> >+ struct {
> >+ u8 type;
> >+ u8 code;
> >+ };
> >+ };
> >+};
> >
> > /**
> > * struct flow_dissector_key_eth_addrs:
> >@@ -122,6 +139,7 @@ enum flow_dissector_key_id {
> > FLOW_DISSECTOR_KEY_IPV4_ADDRS, /* struct flow_dissector_key_ipv4_addrs */
> > FLOW_DISSECTOR_KEY_IPV6_ADDRS, /* struct flow_dissector_key_ipv6_addrs */
> > FLOW_DISSECTOR_KEY_PORTS, /* struct flow_dissector_key_ports */
> >+ FLOW_DISSECTOR_KEY_ICMP, /* struct flow_dissector_key_icmp */
> > FLOW_DISSECTOR_KEY_ETH_ADDRS, /* struct flow_dissector_key_eth_addrs */
> > FLOW_DISSECTOR_KEY_TIPC_ADDRS, /* struct flow_dissector_key_tipc_addrs */
> > FLOW_DISSECTOR_KEY_VLAN, /* struct flow_dissector_key_flow_vlan */
> >@@ -160,7 +178,10 @@ struct flow_keys {
> > struct flow_dissector_key_tags tags;
> > struct flow_dissector_key_vlan vlan;
> > struct flow_dissector_key_keyid keyid;
> >- struct flow_dissector_key_ports ports;
> >+ union {
> >+ struct flow_dissector_key_ports ports;
> >+ struct flow_dissector_key_icmp icmp;
> >+ };
>
> Why? You don't need this here.
Thanks, I will remove drop that hunk.
> > struct flow_dissector_key_addrs addrs;
> > };
> >
> >@@ -188,6 +209,38 @@ struct flow_keys_digest {
> > void make_flow_keys_digest(struct flow_keys_digest *digest,
> > const struct flow_keys *flow);
> >
> >+static inline bool flow_protos_are_icmpv4(__be16 n_proto, u8 ip_proto)
> >+{
> >+ return n_proto == htons(ETH_P_IP) && ip_proto == IPPROTO_ICMP;
> >+}
> >+
> >+static inline bool flow_protos_are_icmpv6(__be16 n_proto, u8 ip_proto)
> >+{
> >+ return n_proto == htons(ETH_P_IPV6) && ip_proto == IPPROTO_ICMPV6;
> >+}
> >+
> >+static inline bool flow_protos_are_icmp_any(__be16 n_proto, u8 ip_proto)
> >+{
> >+ return flow_protos_are_icmpv4(n_proto, ip_proto) ||
> >+ flow_protos_are_icmpv6(n_proto, ip_proto);
> >+}
> >+
> >+static inline bool flow_basic_key_is_icmpv4(const struct flow_dissector_key_basic *basic)
> >+{
> >+ return flow_protos_are_icmpv4(basic->n_proto, basic->ip_proto);
> >+}
> >+
> >+static inline bool flow_basic_key_is_icmpv6(const struct flow_dissector_key_basic *basic)
> >+{
> >+ return flow_protos_are_icmpv6(basic->n_proto, basic->ip_proto);
> >+}
> >+
> >+static inline bool flow_keys_are_icmp_any(const struct flow_keys *keys)
> >+{
> >+ return flow_protos_are_icmp_any(keys->basic.n_proto,
> >+ keys->basic.ip_proto);
> >+}
> >+
> > static inline bool flow_keys_have_l4(const struct flow_keys *keys)
> > {
> > return (keys->ports.ports || keys->tags.flow_label);
> >diff --git a/net/core/flow_dissector.c b/net/core/flow_dissector.c
> >index 1eb6f949e5b2..e37ff021a19e 100644
> >--- a/net/core/flow_dissector.c
> >+++ b/net/core/flow_dissector.c
> >@@ -58,6 +58,28 @@ void skb_flow_dissector_init(struct flow_dissector *flow_dissector,
> > EXPORT_SYMBOL(skb_flow_dissector_init);
> >
> > /**
> >+ * skb_flow_get_be16 - extract be16 entity
> >+ * @skb: sk_buff to extract from
> >+ * @poff: offset to extract at
> >+ * @data: raw buffer pointer to the packet
> >+ * @hlen: packet header length
> >+ *
> >+ * The function will try to retrieve a be32 entity at
> >+ * offset poff
> >+ */
> >+__be16 skb_flow_get_be16(const struct sk_buff *skb, int poff, void *data,
> >+ int hlen)
> >+{
> >+ __be16 *u, _u;
> >+
> >+ u = __skb_header_pointer(skb, poff, sizeof(_u), data, hlen, &_u);
> >+ if (u)
> >+ return *u;
> >+
> >+ return 0;
> >+}
> >+
> >+/**
> > * __skb_flow_get_ports - extract the upper layer ports and return them
> > * @skb: sk_buff to extract the ports from
> > * @thoff: transport header offset
> >@@ -117,6 +139,7 @@ bool __skb_flow_dissect(const struct sk_buff *skb,
> > struct flow_dissector_key_basic *key_basic;
> > struct flow_dissector_key_addrs *key_addrs;
> > struct flow_dissector_key_ports *key_ports;
> >+ struct flow_dissector_key_icmp *key_icmp;
> > struct flow_dissector_key_tags *key_tags;
> > struct flow_dissector_key_vlan *key_vlan;
> > struct flow_dissector_key_keyid *key_keyid;
> >@@ -537,13 +560,25 @@ bool __skb_flow_dissect(const struct sk_buff *skb,
> > break;
> > }
> >
> >- if (dissector_uses_key(flow_dissector,
> >- FLOW_DISSECTOR_KEY_PORTS)) {
> >- key_ports = skb_flow_dissector_target(flow_dissector,
> >- FLOW_DISSECTOR_KEY_PORTS,
> >- target_container);
> >- key_ports->ports = __skb_flow_get_ports(skb, nhoff, ip_proto,
> >- data, hlen);
> >+ if (flow_protos_are_icmp_any(proto, ip_proto)) {
>
> You don't need this.
>
> Just left FLOW_DISSECTOR_KEY_PORTS untouched, and add:
>
> if (dissector_uses_key(flow_dissector,
> FLOW_DISSECTOR_KEY_ICMP)) {
> ....
Thanks, will do.
>
>
> >+ if (dissector_uses_key(flow_dissector,
> >+ FLOW_DISSECTOR_KEY_ICMP)) {
> >+ key_icmp = skb_flow_dissector_target(flow_dissector,
> >+ FLOW_DISSECTOR_KEY_ICMP,
> >+ target_container);
> >+ key_icmp->icmp = skb_flow_get_be16(skb, nhoff, data,
> >+ hlen);
> >+ }
> >+ } else {
> >+ if (dissector_uses_key(flow_dissector,
> >+ FLOW_DISSECTOR_KEY_PORTS)) {
> >+ key_ports = skb_flow_dissector_target(flow_dissector,
> >+ FLOW_DISSECTOR_KEY_PORTS,
> >+ target_container);
> >+ key_ports->ports = __skb_flow_get_ports(skb, nhoff,
> >+ ip_proto, data,
> >+ hlen);
> >+ }
> > }
> >
> > out_good:
> >--
> >2.7.0.rc3.207.g0ac5344
> >
^ permalink raw reply
* Re: [PATCH] net:dsa:mv88e6xxx: delete timer and cancel ppu_work
From: Volodymyr Bendiuga @ 2016-12-07 10:38 UTC (permalink / raw)
To: Andrew Lunn
Cc: vivien.didelot, f.fainelli, netdev, volodymyr.bendiuga,
Jonas Johansson
In-Reply-To: <20161206142226.GD26615@lunn.ch>
OK, will check it.
/Volodymyr
On 2016-12-06 15:22, Andrew Lunn wrote:
> On Tue, Dec 06, 2016 at 01:57:42PM +0100, Volodymyr Bendiuga wrote:
>> Signed-off-by: Jonas Johansson <jonas.johansson@westermo.se>
>> Signed-off-by: Volodymyr Bendiuga <volodymyr.bendiuga@westermo.se>
>> ---
>> drivers/net/dsa/mv88e6xxx/chip.c | 5 ++++-
>> 1 file changed, 4 insertions(+), 1 deletion(-)
>>
>> diff --git a/drivers/net/dsa/mv88e6xxx/chip.c b/drivers/net/dsa/mv88e6xxx/chip.c
>> index ca453f3..4212fb6 100644
>> --- a/drivers/net/dsa/mv88e6xxx/chip.c
>> +++ b/drivers/net/dsa/mv88e6xxx/chip.c
>> @@ -4528,8 +4528,11 @@ static int mv88e6xxx_probe(struct mdio_device *mdiodev)
>> out_mdio:
>> mv88e6xxx_mdio_unregister(chip);
>> out_g2_irq:
>> - if (mv88e6xxx_has(chip, MV88E6XXX_FLAG_G2_INT) && chip->irq > 0)
>> + if (mv88e6xxx_has(chip, MV88E6XXX_FLAG_G2_INT) && chip->irq > 0) {
>> mv88e6xxx_g2_irq_free(chip);
>> + del_timer(&chip->ppu_timer);
>> + cancel_work_sync(&chip->ppu_work);
>> + }
> Why do this here, inside this if statement?
>
> Vivien has also just reworked the PPU code. Please take a look at his
> patches and see if they fix the issue.
>
> Thanks
> Andrew
^ permalink raw reply
* RE: [PATCH 3/3] netns: fix net_generic() "id - 1" bloat
From: David Laight @ 2016-12-07 10:49 UTC (permalink / raw)
To: 'Alexey Dobriyan'
Cc: davem@davemloft.net, netdev@vger.kernel.org, xemul@openvz.org
In-Reply-To: <CACVxJT8axg6i0Lvem=fvKqrjTuOzwg63BDbAuR6bzTPrtLuP+g@mail.gmail.com>
From: Alexey Dobriyan
> Sent: 05 December 2016 14:48
> On Mon, Dec 5, 2016 at 3:49 PM, David Laight <David.Laight@aculab.com> wrote:
> > From: Alexey Dobriyan
> >> Sent: 02 December 2016 01:22
> >> net_generic() function is both a) inline and b) used ~600 times.
> >>
> >> It has the following code inside
> >>
> >> ...
> >> ptr = ng->ptr[id - 1];
> >> ...
> >>
> >> "id" is never compile time constant so compiler is forced to subtract 1.
> >> And those decrements or LEA [r32 - 1] instructions add up.
> >>
> >> We also start id'ing from 1 to catch bugs where pernet sybsystem id
> >> is not initialized and 0. This is quite pointless idea (nothing will
> >> work or immediate interference with first registered subsystem) in
> >> general but it hints what needs to be done for code size reduction.
> >>
> >> Namely, overlaying allocation of pointer array and fixed part of
> >> structure in the beginning and using usual base-0 addressing.
> >>
> >> Ids are just cookies, their exact values do not matter, so lets start
> >> with 3 on x86_64.
> > ...
> >> struct net_generic {
> >> - struct {
> >> - unsigned int len;
> >> - struct rcu_head rcu;
> >> - } s;
> >> -
> >> - void *ptr[0];
> >> + union {
> >> + struct {
> >> + unsigned int len;
> >> + struct rcu_head rcu;
> >> + } s;
> >> +
> >> + void *ptr[0];
> >> + };
> >> };
> >
> > That union is an accident waiting to happen.
>
> I kind of disagree. Module authors should not be given matches,
> but it is hard to screw up if net_generic() is all you're given.
>
> > What might work is to offset the Ids by
> > (offsetof(struct net_generic, ptr)/sizeof (void *)) instead of by 1.
> > The subtract from the offset will then counter the structure offset
> > - which is what you are trying to achieve.
>
> If you suggest this layout
>
> struct net_generic {
> struct {
> } s;
> void *ptr[0];
> };
>
> then is it not optimal because offset of "ptr" needs to be somewhere in code
> either in some LEA or imm8 of the final MOV which is 1 byte more bloaty.
>
> Here is test program
>
> struct ng1 {
> union {
> struct {
> unsigned int len;
> } s;
> void *ptr[0];
> };
> };
> struct ng2 {
> struct {
> unsigned int len;
> } s;
> void *ptr[0];
> };
> struct net {
> int x;
> struct ng1 *gen1;
> struct ng2 *gen2;
> };
> void *ng1(const struct net *net, unsigned int id)
> {
> return net->gen1->ptr[id];
> }
> void *ng2(const struct net *net, unsigned int id)
> {
> return net->gen2->ptr[id];
> }
>
>
> 0000000000000000 <ng1>:
> 0: 48 8b 47 08 mov rax,QWORD PTR [rdi+0x8]
> 4: 89 f6 mov esi,esi
> 6: 48 8b 04 f0 mov rax,QWORD PTR [rax+rsi*8]
> a: c3 ret
>
>
> 0000000000000010 <ng2>:
> 10: 48 8b 47 10 mov rax,QWORD PTR [rdi+0x10]
> 14: 89 f6 mov esi,esi
> 16: 48 8b 44 f0 [[[08]]] mov rax,QWORD PTR [rax+rsi*8+0x8]
> 1b: c3 ret
On x86 that will make ~0 difference since the offset (in that sequence)
doesn't require an extra instruction.
However if you offset the 'id' values so that only
values 2 up are valid the code becomes:
return net->gen2->ptr[id - 2];
which will be exactly the same code as:
return net->gen1->ptr[id];
but it is much more obvious that 'id' values must be >= 2.
The '2' should be generated from the structure offset, but with my method
is doesn't actually matter if it is wrong.
David
^ permalink raw reply
* Re: [PATCH v3 net-next 4/4] bpf: xdp: Add XDP example for head adjustment
From: Jesper Dangaard Brouer @ 2016-12-07 10:34 UTC (permalink / raw)
To: Martin KaFai Lau
Cc: netdev, Alexei Starovoitov, Brenden Blanco, Daniel Borkmann,
David Miller, Jakub Kicinski, John Fastabend, Saeed Mahameed,
Tariq Toukan, Kernel Team, brouer
In-Reply-To: <1481088714-54512-5-git-send-email-kafai@fb.com>
On Tue, 6 Dec 2016 21:31:54 -0800
Martin KaFai Lau <kafai@fb.com> wrote:
> The XDP prog checks if the incoming packet matches any VIP:PORT
> combination in the BPF hashmap. If it is, it will encapsulate
> the packet with a IPv4/v6 header as instructed by the value of
> the BPF hashmap and then XDP_TX it out.
>
> The VIP:PORT -> IP-Encap-Info can be specified by the cmd args
> of the user prog.
>
> Acked-by: Alexei Starovoitov <ast@kernel.org>
> Signed-off-by: Martin KaFai Lau <kafai@fb.com>
> ---
> samples/bpf/Makefile | 4 +
> samples/bpf/bpf_helpers.h | 2 +
> samples/bpf/bpf_load.c | 94 ++++++++++++++
> samples/bpf/bpf_load.h | 1 +
> samples/bpf/xdp1_user.c | 93 --------------
> samples/bpf/xdp_tx_iptnl_common.h | 37 ++++++
> samples/bpf/xdp_tx_iptnl_kern.c | 232 ++++++++++++++++++++++++++++++++++
> samples/bpf/xdp_tx_iptnl_user.c | 253 ++++++++++++++++++++++++++++++++++++++
I got confused by the file name "iptnl", I didn't realize this was
short for iptunnel, before after reading the actually XDP program code.
These are "samples" XDP programs that normal people are expected to
find/discover, could we name it "xdp_tx_tunnel" or "xdp_tx_iptunnel"?
(To guide peoples search for this)
I will likely add a "xdp_tx_vlan" example as I have a customer use-case
that needs this for DDoS scrubbing[1]
[1] http://prototype-kernel.readthedocs.io/en/latest/networking/XDP/use-cases/xdp_use_case_ddos_scrubber.html#forward-clean-traffic
[...]
> diff --git a/samples/bpf/xdp_tx_iptnl_kern.c b/samples/bpf/xdp_tx_iptnl_kern.c
> new file mode 100644
> index 000000000000..d88c064175aa
> --- /dev/null
> +++ b/samples/bpf/xdp_tx_iptnl_kern.c
> @@ -0,0 +1,232 @@
> +/* Copyright (c) 2016 Facebook
> + *
> + * This program is free software; you can redistribute it and/or
> + * modify it under the terms of version 2 of the GNU General Public
> + * License as published by the Free Software Foundation.
Can we add short description of the program, to let readers know if
this is the sample they are looking for. Max 3 lines, like:
This program demonstrate how XDP does packet header adjustment, here
by adding an encapsulation tunnel header based on a BPF hashmap.
> + */
> +#include <uapi/linux/bpf.h>
> +#include <linux/in.h>
> +#include <linux/if_ether.h>
> +#include <linux/if_packet.h>
> +#include <linux/if_vlan.h>
> +#include <linux/ip.h>
> +#include <linux/ipv6.h>
> +#include "bpf_helpers.h"
> +#include "xdp_tx_iptnl_common.h"
> +
> +struct bpf_map_def SEC("maps") rxcnt = {
> + .type = BPF_MAP_TYPE_PERCPU_ARRAY,
> + .key_size = sizeof(__u32),
> + .value_size = sizeof(__u64),
> + .max_entries = 256,
> +};
> +
> +struct bpf_map_def SEC("maps") vip2tnl = {
> + .type = BPF_MAP_TYPE_HASH,
> + .key_size = sizeof(struct vip),
> + .value_size = sizeof(struct iptnl_info),
> + .max_entries = MAX_IPTNL_ENTRIES,
> +};
[...]
> diff --git a/samples/bpf/xdp_tx_iptnl_user.c b/samples/bpf/xdp_tx_iptnl_user.c
> new file mode 100644
> index 000000000000..9aeef7579af4
> --- /dev/null
> +++ b/samples/bpf/xdp_tx_iptnl_user.c
> @@ -0,0 +1,253 @@
> +/* Copyright (c) 2016 Facebook
> + *
> + * This program is free software; you can redistribute it and/or
> + * modify it under the terms of version 2 of the GNU General Public
> + * License as published by the Free Software Foundation.
> + */
[...]
> +
> +static void usage(const char *cmd)
> +{
Wondering if there should be a descriptive header, that says e.g.
"XDP tunnel sample" or if command filename "xdp_tx_iptunnel" or
"xdp_tx_tunnel" would be descriptive enough.
> + printf("Usage: %s [...]\n", cmd);
> + printf(" -i <ifindex> Interface Index\n");
> + printf(" -a <vip-service-address> IPv4 or IPv6\n");
> + printf(" -p <vip-service-port> A port range (e.g. 433-444) is also allowed\n");
> + printf(" -s <source-ip> Used in the IPTunnel Header\n");
> + printf(" -d <dest-ip> Used in the IPTunnel header>\n");
> + printf(" -m <dest-MAC> Used in sending the IP Tunneled pkt>\n");
> + printf(" -T <stop-after-X-seconds> Default: 0 (forever)\n");
> + printf(" -P <IP-Protocol> Default is TCP\n");
> + printf(" -h Display this help\n");
> +}
--
Best regards,
Jesper Dangaard Brouer
MSc.CS, Principal Kernel Engineer at Red Hat
LinkedIn: http://www.linkedin.com/in/brouer
^ permalink raw reply
* Re: [net-next] dummy: expend mtu range for dummy device
From: Sergei Shtylyov @ 2016-12-07 10:14 UTC (permalink / raw)
To: Zhang Shengju, jarod, netdev
In-Reply-To: <1481103693-16394-1-git-send-email-zhangshengju@cmss.chinamobile.com>
Hello!
On 12/7/2016 12:41 PM, Zhang Shengju wrote:
> After commit 61e84623ace3 ("net: centralize net_device min/max MTU checking"),
> the mtu range for dummy device becomes [68, 1500].
>
> This patch expends it to [0, 65535].
"Extend" here and in the subject.
> Signed-off-by: Zhang Shengju <zhangshengju@cmss.chinamobile.com>
[...]
MBR, Sergei
^ permalink raw reply
* Re: [net-next 20/20] i40e: don't allow i40e_vsi_(add|kill)_vlan to operate when VID<1
From: Sergei Shtylyov @ 2016-12-07 10:10 UTC (permalink / raw)
To: Jeff Kirsher, davem
Cc: Jacob Keller, netdev, nhorman, sassmann, jogreene,
guru.anbalagane
In-Reply-To: <20161207073354.88568-21-jeffrey.t.kirsher@intel.com>
Hello!
On 12/7/2016 10:33 AM, Jeff Kirsher wrote:
> From: Jacob Keller <jacob.e.keller@intel.com>
>
> Now that we have the separate i40e_(add|rm)_vlan_all_mac functions, we
> should not be using the i40e_vsi_kill_vlan or i40e_vsi_add_vlan
> functions when PVID is set or when VID is less than 1. This allows us to
> remove some checks in i40e_vsi_add_vlan and ensures that callers which
> need to handle VID=0 or VID=-1 don't accidentally invoke the VLAN mode
> handling used to convert filters when entering VLAN mode. We also update
> the functions to take u16 instead of s16 as well since they no longer
> expect to be called with VID=I40E_VLAN_ANY.
>
> Change-ID: Ibddf44a8bb840dde8ceef2a4fdb92fd953b05a57
> Signed-off-by: Jacob Keller <jacob.e.keller@intel.com>
> Tested-by: Andrew Bowers <andrewx.bowers@intel.com>
> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
[...]
> diff --git a/drivers/net/ethernet/intel/i40e/i40e_main.c b/drivers/net/ethernet/intel/i40e/i40e_main.c
> index da4cbe3..148a678 100644
> --- a/drivers/net/ethernet/intel/i40e/i40e_main.c
> +++ b/drivers/net/ethernet/intel/i40e/i40e_main.c
> @@ -2575,12 +2575,15 @@ int i40e_add_vlan_all_mac(struct i40e_vsi *vsi, s16 vid)
> /**
> * i40e_vsi_add_vlan - Add VSI membership for given VLAN
> * @vsi: the VSI being configured
> - * @vid: VLAN id to be added (0 = untagged only , -1 = any)
> + * @vid: VLAN id to be added
> **/
> -int i40e_vsi_add_vlan(struct i40e_vsi *vsi, s16 vid)
> +int i40e_vsi_add_vlan(struct i40e_vsi *vsi, u16 vid)
> {
> int err;
>
> + if (!(vid > 0) || vsi->info.pvid)
Why not just '!vid'?
> + return -EINVAL;
> +
> /* Locked once because all functions invoked below iterates list*/
> spin_lock_bh(&vsi->mac_filter_hash_lock);
> err = i40e_add_vlan_all_mac(vsi, vid);
> @@ -2623,10 +2626,13 @@ void i40e_rm_vlan_all_mac(struct i40e_vsi *vsi, s16 vid)
> /**
> * i40e_vsi_kill_vlan - Remove VSI membership for given VLAN
> * @vsi: the VSI being configured
> - * @vid: VLAN id to be removed (0 = untagged only , -1 = any)
> + * @vid: VLAN id to be removed
> **/
> -void i40e_vsi_kill_vlan(struct i40e_vsi *vsi, s16 vid)
> +void i40e_vsi_kill_vlan(struct i40e_vsi *vsi, u16 vid)
> {
> + if (!(vid > 0) || vsi->info.pvid)
Likewise.
> + return;
> +
> spin_lock_bh(&vsi->mac_filter_hash_lock);
> i40e_rm_vlan_all_mac(vsi, vid);
> spin_unlock_bh(&vsi->mac_filter_hash_lock);
MBR, Sergei
^ permalink raw reply
* [PATCH 3/4] vsock: add pkt cancel capability
From: Peng Tao @ 2016-12-07 10:00 UTC (permalink / raw)
To: Stefan Hajnoczi; +Cc: kvm, virtualization, netdev, Peng Tao
In-Reply-To: <1481104821-77294-1-git-send-email-bergwolf@gmail.com>
Signed-off-by: Peng Tao <bergwolf@gmail.com>
---
net/vmw_vsock/virtio_transport.c | 36 ++++++++++++++++++++++++++++++++++++
1 file changed, 36 insertions(+)
diff --git a/net/vmw_vsock/virtio_transport.c b/net/vmw_vsock/virtio_transport.c
index 936d7ee..f88b6ed 100644
--- a/net/vmw_vsock/virtio_transport.c
+++ b/net/vmw_vsock/virtio_transport.c
@@ -170,6 +170,41 @@ virtio_transport_send_pkt(struct virtio_vsock_pkt *pkt)
return len;
}
+static int
+virtio_transport_cancel_pkt(struct vsock_sock *vsk)
+{
+ struct virtio_vsock *vsock;
+ struct virtio_vsock_pkt *pkt, *n;
+ int cnt = 0;
+ LIST_HEAD(freeme);
+
+ vsock = virtio_vsock_get();
+ if (!vsock) {
+ return -ENODEV;
+ }
+
+ if (pkt->reply)
+ cnt++;
+
+ spin_lock_bh(&vsock->send_pkt_list_lock);
+ list_for_each_entry_safe(pkt, n, &vsock->send_pkt_list, list) {
+ if (pkt->vsk != vsk)
+ continue;
+ list_move(&pkt->list, &freeme);
+ }
+ spin_unlock_bh(&vsock->send_pkt_list_lock);
+
+ list_for_each_entry_safe(pkt, n, &freeme, list) {
+ if (pkt->reply)
+ cnt++;
+ list_del(&pkt->list);
+ virtio_transport_free_pkt(pkt);
+ }
+ atomic_sub(cnt, &vsock->queued_replies);
+
+ return 0;
+}
+
static void virtio_vsock_rx_fill(struct virtio_vsock *vsock)
{
int buf_len = VIRTIO_VSOCK_DEFAULT_RX_BUF_SIZE;
@@ -453,6 +488,7 @@ static struct virtio_transport virtio_transport = {
},
.send_pkt = virtio_transport_send_pkt,
+ .cancel_pkt = virtio_transport_cancel_pkt,
};
static int virtio_vsock_probe(struct virtio_device *vdev)
--
2.7.4
^ permalink raw reply related
* [PATCH 4/4] vsock: cancel packets when failing to connect
From: Peng Tao @ 2016-12-07 10:00 UTC (permalink / raw)
To: Stefan Hajnoczi; +Cc: kvm, virtualization, netdev, Peng Tao
In-Reply-To: <1481104821-77294-1-git-send-email-bergwolf@gmail.com>
Otherwise we'll leave the packets queued until releasing vsock device.
E.g., if guest is slow to start up, resulting ETIMEDOUT on connect, guest
will get the connect requests from failed host sockets.
Signed-off-by: Peng Tao <bergwolf@gmail.com>
---
include/linux/virtio_vsock.h | 7 +++++++
net/vmw_vsock/af_vsock.c | 7 +++++++
net/vmw_vsock/virtio_transport_common.c | 7 -------
3 files changed, 14 insertions(+), 7 deletions(-)
diff --git a/include/linux/virtio_vsock.h b/include/linux/virtio_vsock.h
index b92e88d..ff6850a 100644
--- a/include/linux/virtio_vsock.h
+++ b/include/linux/virtio_vsock.h
@@ -156,4 +156,11 @@ void virtio_transport_inc_tx_pkt(struct virtio_vsock_sock *vvs, struct virtio_vs
u32 virtio_transport_get_credit(struct virtio_vsock_sock *vvs, u32 wanted);
void virtio_transport_put_credit(struct virtio_vsock_sock *vvs, u32 credit);
+static inline const struct virtio_transport *virtio_transport_get_ops(void)
+{
+ const struct vsock_transport *t = vsock_core_get_transport();
+
+ return container_of(t, struct virtio_transport, transport);
+}
+
#endif /* _LINUX_VIRTIO_VSOCK_H */
diff --git a/net/vmw_vsock/af_vsock.c b/net/vmw_vsock/af_vsock.c
index 8a398b3..ebb50d6 100644
--- a/net/vmw_vsock/af_vsock.c
+++ b/net/vmw_vsock/af_vsock.c
@@ -104,6 +104,7 @@
#include <linux/unistd.h>
#include <linux/wait.h>
#include <linux/workqueue.h>
+#include <linux/virtio_vsock.h>
#include <net/sock.h>
#include <net/af_vsock.h>
@@ -1105,6 +1106,7 @@ static void vsock_connect_timeout(struct work_struct *work)
{
struct sock *sk;
struct vsock_sock *vsk;
+ int cancel = 0;
vsk = container_of(work, struct vsock_sock, dwork.work);
sk = sk_vsock(vsk);
@@ -1115,8 +1117,11 @@ static void vsock_connect_timeout(struct work_struct *work)
sk->sk_state = SS_UNCONNECTED;
sk->sk_err = ETIMEDOUT;
sk->sk_error_report(sk);
+ cancel = 1;
}
release_sock(sk);
+ if (cancel)
+ virtio_transport_get_ops()->cancel_pkt(vsk);
sock_put(sk);
}
@@ -1223,11 +1228,13 @@ static int vsock_stream_connect(struct socket *sock, struct sockaddr *addr,
err = sock_intr_errno(timeout);
sk->sk_state = SS_UNCONNECTED;
sock->state = SS_UNCONNECTED;
+ virtio_transport_get_ops()->cancel_pkt(vsk);
goto out_wait;
} else if (timeout == 0) {
err = -ETIMEDOUT;
sk->sk_state = SS_UNCONNECTED;
sock->state = SS_UNCONNECTED;
+ virtio_transport_get_ops()->cancel_pkt(vsk);
goto out_wait;
}
diff --git a/net/vmw_vsock/virtio_transport_common.c b/net/vmw_vsock/virtio_transport_common.c
index cc1eeb5..72c5dff 100644
--- a/net/vmw_vsock/virtio_transport_common.c
+++ b/net/vmw_vsock/virtio_transport_common.c
@@ -25,13 +25,6 @@
/* How long to wait for graceful shutdown of a connection */
#define VSOCK_CLOSE_TIMEOUT (8 * HZ)
-static const struct virtio_transport *virtio_transport_get_ops(void)
-{
- const struct vsock_transport *t = vsock_core_get_transport();
-
- return container_of(t, struct virtio_transport, transport);
-}
-
struct virtio_vsock_pkt *
virtio_transport_alloc_pkt(struct virtio_vsock_pkt_info *info,
size_t len,
--
2.7.4
^ permalink raw reply related
* [PATCH 0/4] vsock: cancel connect packets when failing to connect
From: Peng Tao @ 2016-12-07 10:00 UTC (permalink / raw)
To: Stefan Hajnoczi; +Cc: kvm, virtualization, netdev, Peng Tao
Currently, if a connect call fails on a signal or timeout (e.g., guest is still
in the process of starting up), we'll just return to caller and leave the connect
packet queued and they are sent even though the connection is considered a failure,
which can confuse applications with unwanted false connect attempt.
The patchset enables vsock (both host and guest) to cancel queued packets when
a connect attempt is considered to fail.
Peng Tao (4):
vsock: track pkt owner vsock
vhost-vsock: add pkt cancel capability
vsock: add pkt cancel capability
vsock: cancel packets when failing to connect
drivers/vhost/vsock.c | 29 ++++++++++++++++++++++++++
include/linux/virtio_vsock.h | 12 +++++++++++
net/vmw_vsock/af_vsock.c | 7 +++++++
net/vmw_vsock/virtio_transport.c | 36 +++++++++++++++++++++++++++++++++
net/vmw_vsock/virtio_transport_common.c | 14 ++++++-------
5 files changed, 91 insertions(+), 7 deletions(-)
--
2.7.4
^ permalink raw reply
* [PATCH 1/4] vsock: track pkt owner vsock
From: Peng Tao @ 2016-12-07 10:00 UTC (permalink / raw)
To: Stefan Hajnoczi; +Cc: kvm, virtualization, netdev, Peng Tao
In-Reply-To: <1481104821-77294-1-git-send-email-bergwolf@gmail.com>
So that we can cancel a queued pkt later if necessary.
Signed-off-by: Peng Tao <bergwolf@gmail.com>
---
include/linux/virtio_vsock.h | 2 ++
net/vmw_vsock/virtio_transport_common.c | 7 +++++++
2 files changed, 9 insertions(+)
diff --git a/include/linux/virtio_vsock.h b/include/linux/virtio_vsock.h
index 9638bfe..6dd3242 100644
--- a/include/linux/virtio_vsock.h
+++ b/include/linux/virtio_vsock.h
@@ -48,6 +48,7 @@ struct virtio_vsock_pkt {
struct virtio_vsock_hdr hdr;
struct work_struct work;
struct list_head list;
+ struct vsock_sock *vsk;
void *buf;
u32 len;
u32 off;
@@ -56,6 +57,7 @@ struct virtio_vsock_pkt {
struct virtio_vsock_pkt_info {
u32 remote_cid, remote_port;
+ struct vsock_sock *vsk;
struct msghdr *msg;
u32 pkt_len;
u16 type;
diff --git a/net/vmw_vsock/virtio_transport_common.c b/net/vmw_vsock/virtio_transport_common.c
index a53b3a1..cc1eeb5 100644
--- a/net/vmw_vsock/virtio_transport_common.c
+++ b/net/vmw_vsock/virtio_transport_common.c
@@ -57,6 +57,7 @@ virtio_transport_alloc_pkt(struct virtio_vsock_pkt_info *info,
pkt->len = len;
pkt->hdr.len = cpu_to_le32(len);
pkt->reply = info->reply;
+ pkt->vsk = info->vsk;
if (info->msg && len > 0) {
pkt->buf = kmalloc(len, GFP_KERNEL);
@@ -180,6 +181,7 @@ static int virtio_transport_send_credit_update(struct vsock_sock *vsk,
struct virtio_vsock_pkt_info info = {
.op = VIRTIO_VSOCK_OP_CREDIT_UPDATE,
.type = type,
+ .vsk = vsk,
};
return virtio_transport_send_pkt_info(vsk, &info);
@@ -519,6 +521,7 @@ int virtio_transport_connect(struct vsock_sock *vsk)
struct virtio_vsock_pkt_info info = {
.op = VIRTIO_VSOCK_OP_REQUEST,
.type = VIRTIO_VSOCK_TYPE_STREAM,
+ .vsk = vsk,
};
return virtio_transport_send_pkt_info(vsk, &info);
@@ -534,6 +537,7 @@ int virtio_transport_shutdown(struct vsock_sock *vsk, int mode)
VIRTIO_VSOCK_SHUTDOWN_RCV : 0) |
(mode & SEND_SHUTDOWN ?
VIRTIO_VSOCK_SHUTDOWN_SEND : 0),
+ .vsk = vsk,
};
return virtio_transport_send_pkt_info(vsk, &info);
@@ -560,6 +564,7 @@ virtio_transport_stream_enqueue(struct vsock_sock *vsk,
.type = VIRTIO_VSOCK_TYPE_STREAM,
.msg = msg,
.pkt_len = len,
+ .vsk = vsk,
};
return virtio_transport_send_pkt_info(vsk, &info);
@@ -581,6 +586,7 @@ static int virtio_transport_reset(struct vsock_sock *vsk,
.op = VIRTIO_VSOCK_OP_RST,
.type = VIRTIO_VSOCK_TYPE_STREAM,
.reply = !!pkt,
+ .vsk = vsk,
};
/* Send RST only if the original pkt is not a RST pkt */
@@ -826,6 +832,7 @@ virtio_transport_send_response(struct vsock_sock *vsk,
.remote_cid = le32_to_cpu(pkt->hdr.src_cid),
.remote_port = le32_to_cpu(pkt->hdr.src_port),
.reply = true,
+ .vsk = vsk,
};
return virtio_transport_send_pkt_info(vsk, &info);
--
2.7.4
^ permalink raw reply related
* Re: [PATCH net-next v3 1/2] flow dissector: ICMP support
From: Jiri Pirko @ 2016-12-07 10:01 UTC (permalink / raw)
To: Simon Horman; +Cc: Jiri Pirko, Tom Herbert, David Miller, netdev
In-Reply-To: <1481103697-19835-2-git-send-email-simon.horman@netronome.com>
Wed, Dec 07, 2016 at 10:41:36AM CET, simon.horman@netronome.com wrote:
>Allow dissection of ICMP(V6) type and code. This should only occur
>if a packet is ICMP(V6) and the dissector has FLOW_DISSECTOR_KEY_ICMP set.
>
>There are currently no users of FLOW_DISSECTOR_KEY_ICMP.
>A follow-up patch will allow FLOW_DISSECTOR_KEY_ICMP to be used by
>the flower classifier.
>---
>v3
>* Add FLOW_DISSECTOR_KEY_ICMP and use separate structure for ICMP, struct
> flow_dissector_key_icmp, which is a union with struct
> flow_dissector_key_ports in struct flow_keys.
>* Drop checks for !ICMP before accessing port field
>
>v2
>* Include all helpers in this patch
>---
> include/net/flow_dissector.h | 55 +++++++++++++++++++++++++++++++++++++++++++-
> net/core/flow_dissector.c | 49 +++++++++++++++++++++++++++++++++------
> 2 files changed, 96 insertions(+), 8 deletions(-)
>
>diff --git a/include/net/flow_dissector.h b/include/net/flow_dissector.h
>index c4f31666afd2..aefb7a8138a6 100644
>--- a/include/net/flow_dissector.h
>+++ b/include/net/flow_dissector.h
>@@ -2,6 +2,7 @@
> #define _NET_FLOW_DISSECTOR_H
>
> #include <linux/types.h>
>+#include <linux/in.h>
> #include <linux/in6.h>
> #include <uapi/linux/if_ether.h>
>
>@@ -104,6 +105,22 @@ struct flow_dissector_key_ports {
> };
> };
>
>+/**
>+ * flow_dissector_key_icmp:
>+ * @ports: type and code of ICMP header
>+ * icmp: ICMP type (high) and code (low)
>+ * type: ICMP type
>+ * code: ICMP code
>+ */
>+struct flow_dissector_key_icmp {
>+ union {
>+ __be16 icmp;
>+ struct {
>+ u8 type;
>+ u8 code;
>+ };
>+ };
>+};
>
> /**
> * struct flow_dissector_key_eth_addrs:
>@@ -122,6 +139,7 @@ enum flow_dissector_key_id {
> FLOW_DISSECTOR_KEY_IPV4_ADDRS, /* struct flow_dissector_key_ipv4_addrs */
> FLOW_DISSECTOR_KEY_IPV6_ADDRS, /* struct flow_dissector_key_ipv6_addrs */
> FLOW_DISSECTOR_KEY_PORTS, /* struct flow_dissector_key_ports */
>+ FLOW_DISSECTOR_KEY_ICMP, /* struct flow_dissector_key_icmp */
> FLOW_DISSECTOR_KEY_ETH_ADDRS, /* struct flow_dissector_key_eth_addrs */
> FLOW_DISSECTOR_KEY_TIPC_ADDRS, /* struct flow_dissector_key_tipc_addrs */
> FLOW_DISSECTOR_KEY_VLAN, /* struct flow_dissector_key_flow_vlan */
>@@ -160,7 +178,10 @@ struct flow_keys {
> struct flow_dissector_key_tags tags;
> struct flow_dissector_key_vlan vlan;
> struct flow_dissector_key_keyid keyid;
>- struct flow_dissector_key_ports ports;
>+ union {
>+ struct flow_dissector_key_ports ports;
>+ struct flow_dissector_key_icmp icmp;
>+ };
Why? You don't need this here.
> struct flow_dissector_key_addrs addrs;
> };
>
>@@ -188,6 +209,38 @@ struct flow_keys_digest {
> void make_flow_keys_digest(struct flow_keys_digest *digest,
> const struct flow_keys *flow);
>
>+static inline bool flow_protos_are_icmpv4(__be16 n_proto, u8 ip_proto)
>+{
>+ return n_proto == htons(ETH_P_IP) && ip_proto == IPPROTO_ICMP;
>+}
>+
>+static inline bool flow_protos_are_icmpv6(__be16 n_proto, u8 ip_proto)
>+{
>+ return n_proto == htons(ETH_P_IPV6) && ip_proto == IPPROTO_ICMPV6;
>+}
>+
>+static inline bool flow_protos_are_icmp_any(__be16 n_proto, u8 ip_proto)
>+{
>+ return flow_protos_are_icmpv4(n_proto, ip_proto) ||
>+ flow_protos_are_icmpv6(n_proto, ip_proto);
>+}
>+
>+static inline bool flow_basic_key_is_icmpv4(const struct flow_dissector_key_basic *basic)
>+{
>+ return flow_protos_are_icmpv4(basic->n_proto, basic->ip_proto);
>+}
>+
>+static inline bool flow_basic_key_is_icmpv6(const struct flow_dissector_key_basic *basic)
>+{
>+ return flow_protos_are_icmpv6(basic->n_proto, basic->ip_proto);
>+}
>+
>+static inline bool flow_keys_are_icmp_any(const struct flow_keys *keys)
>+{
>+ return flow_protos_are_icmp_any(keys->basic.n_proto,
>+ keys->basic.ip_proto);
>+}
>+
> static inline bool flow_keys_have_l4(const struct flow_keys *keys)
> {
> return (keys->ports.ports || keys->tags.flow_label);
>diff --git a/net/core/flow_dissector.c b/net/core/flow_dissector.c
>index 1eb6f949e5b2..e37ff021a19e 100644
>--- a/net/core/flow_dissector.c
>+++ b/net/core/flow_dissector.c
>@@ -58,6 +58,28 @@ void skb_flow_dissector_init(struct flow_dissector *flow_dissector,
> EXPORT_SYMBOL(skb_flow_dissector_init);
>
> /**
>+ * skb_flow_get_be16 - extract be16 entity
>+ * @skb: sk_buff to extract from
>+ * @poff: offset to extract at
>+ * @data: raw buffer pointer to the packet
>+ * @hlen: packet header length
>+ *
>+ * The function will try to retrieve a be32 entity at
>+ * offset poff
>+ */
>+__be16 skb_flow_get_be16(const struct sk_buff *skb, int poff, void *data,
>+ int hlen)
>+{
>+ __be16 *u, _u;
>+
>+ u = __skb_header_pointer(skb, poff, sizeof(_u), data, hlen, &_u);
>+ if (u)
>+ return *u;
>+
>+ return 0;
>+}
>+
>+/**
> * __skb_flow_get_ports - extract the upper layer ports and return them
> * @skb: sk_buff to extract the ports from
> * @thoff: transport header offset
>@@ -117,6 +139,7 @@ bool __skb_flow_dissect(const struct sk_buff *skb,
> struct flow_dissector_key_basic *key_basic;
> struct flow_dissector_key_addrs *key_addrs;
> struct flow_dissector_key_ports *key_ports;
>+ struct flow_dissector_key_icmp *key_icmp;
> struct flow_dissector_key_tags *key_tags;
> struct flow_dissector_key_vlan *key_vlan;
> struct flow_dissector_key_keyid *key_keyid;
>@@ -537,13 +560,25 @@ bool __skb_flow_dissect(const struct sk_buff *skb,
> break;
> }
>
>- if (dissector_uses_key(flow_dissector,
>- FLOW_DISSECTOR_KEY_PORTS)) {
>- key_ports = skb_flow_dissector_target(flow_dissector,
>- FLOW_DISSECTOR_KEY_PORTS,
>- target_container);
>- key_ports->ports = __skb_flow_get_ports(skb, nhoff, ip_proto,
>- data, hlen);
>+ if (flow_protos_are_icmp_any(proto, ip_proto)) {
You don't need this.
Just left FLOW_DISSECTOR_KEY_PORTS untouched, and add:
if (dissector_uses_key(flow_dissector,
FLOW_DISSECTOR_KEY_ICMP)) {
....
>+ if (dissector_uses_key(flow_dissector,
>+ FLOW_DISSECTOR_KEY_ICMP)) {
>+ key_icmp = skb_flow_dissector_target(flow_dissector,
>+ FLOW_DISSECTOR_KEY_ICMP,
>+ target_container);
>+ key_icmp->icmp = skb_flow_get_be16(skb, nhoff, data,
>+ hlen);
>+ }
>+ } else {
>+ if (dissector_uses_key(flow_dissector,
>+ FLOW_DISSECTOR_KEY_PORTS)) {
>+ key_ports = skb_flow_dissector_target(flow_dissector,
>+ FLOW_DISSECTOR_KEY_PORTS,
>+ target_container);
>+ key_ports->ports = __skb_flow_get_ports(skb, nhoff,
>+ ip_proto, data,
>+ hlen);
>+ }
> }
>
> out_good:
>--
>2.7.0.rc3.207.g0ac5344
>
^ permalink raw reply
* [PATCH 2/4] vhost-vsock: add pkt cancel capability
From: Peng Tao @ 2016-12-07 10:00 UTC (permalink / raw)
To: Stefan Hajnoczi; +Cc: kvm, virtualization, netdev, Peng Tao
In-Reply-To: <1481104821-77294-1-git-send-email-bergwolf@gmail.com>
To allow canceling all packets of a connection.
Signed-off-by: Peng Tao <bergwolf@gmail.com>
---
drivers/vhost/vsock.c | 29 +++++++++++++++++++++++++++++
include/linux/virtio_vsock.h | 3 +++
2 files changed, 32 insertions(+)
diff --git a/drivers/vhost/vsock.c b/drivers/vhost/vsock.c
index a504e2e0..0c23b55 100644
--- a/drivers/vhost/vsock.c
+++ b/drivers/vhost/vsock.c
@@ -218,6 +218,34 @@ vhost_transport_send_pkt(struct virtio_vsock_pkt *pkt)
return len;
}
+static int
+vhost_transport_cancel_pkt(struct vsock_sock *vsk)
+{
+ struct vhost_vsock *vsock;
+ struct virtio_vsock_pkt *pkt, *n;
+ LIST_HEAD(freeme);
+
+ /* Find the vhost_vsock according to guest context id */
+ vsock = vhost_vsock_get(vsk->remote_addr.svm_cid);
+ if (!vsock)
+ return -ENODEV;
+
+ spin_lock_bh(&vsock->send_pkt_list_lock);
+ list_for_each_entry_safe(pkt, n, &vsock->send_pkt_list, list) {
+ if (pkt->vsk != vsk)
+ continue;
+ list_move(&pkt->list, &freeme);
+ }
+ spin_unlock_bh(&vsock->send_pkt_list_lock);
+
+ list_for_each_entry_safe(pkt, n, &freeme, list) {
+ list_del(&pkt->list);
+ virtio_transport_free_pkt(pkt);
+ }
+
+ return 0;
+}
+
static struct virtio_vsock_pkt *
vhost_vsock_alloc_pkt(struct vhost_virtqueue *vq,
unsigned int out, unsigned int in)
@@ -698,6 +726,7 @@ static struct virtio_transport vhost_transport = {
},
.send_pkt = vhost_transport_send_pkt,
+ .cancel_pkt = vhost_transport_cancel_pkt,
};
static int __init vhost_vsock_init(void)
diff --git a/include/linux/virtio_vsock.h b/include/linux/virtio_vsock.h
index 6dd3242..b92e88d 100644
--- a/include/linux/virtio_vsock.h
+++ b/include/linux/virtio_vsock.h
@@ -72,6 +72,9 @@ struct virtio_transport {
/* Takes ownership of the packet */
int (*send_pkt)(struct virtio_vsock_pkt *pkt);
+
+ /* Cancel packets belonging the same vsock */
+ int (*cancel_pkt)(struct vsock_sock *vsk);
};
ssize_t
--
2.7.4
^ permalink raw reply related
* [PATCH 2/2] vhost: remove unnecessary smp_mb from vhost_work_queue
From: Peng Tao @ 2016-12-07 9:52 UTC (permalink / raw)
To: Stefan Hajnoczi; +Cc: kvm, virtualization, netdev, Peng Tao
In-Reply-To: <1481104340-77035-1-git-send-email-bergwolf@gmail.com>
test_and_set_bit() already implies a memory barrier.
Signed-off-by: Peng Tao <bergwolf@gmail.com>
---
drivers/vhost/vhost.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/vhost/vhost.c b/drivers/vhost/vhost.c
index c6f2d89..2663543 100644
--- a/drivers/vhost/vhost.c
+++ b/drivers/vhost/vhost.c
@@ -261,8 +261,8 @@ void vhost_work_queue(struct vhost_dev *dev, struct vhost_work *work)
if (!test_and_set_bit(VHOST_WORK_QUEUED, &work->flags)) {
/* We can only add the work to the list after we're
* sure it was not in the list.
+ * test_and_set_bit() implies a memory barrier.
*/
- smp_mb();
llist_add(&work->node, &dev->work_list);
wake_up_process(dev->worker);
}
--
2.7.4
^ permalink raw reply related
* [PATCH 1/2] vhost-vsock: remove unused vq variable
From: Peng Tao @ 2016-12-07 9:52 UTC (permalink / raw)
To: Stefan Hajnoczi; +Cc: kvm, virtualization, netdev, Peng Tao
Signed-off-by: Peng Tao <bergwolf@gmail.com>
---
drivers/vhost/vsock.c | 3 ---
1 file changed, 3 deletions(-)
diff --git a/drivers/vhost/vsock.c b/drivers/vhost/vsock.c
index 0c23b55..3e01d58 100644
--- a/drivers/vhost/vsock.c
+++ b/drivers/vhost/vsock.c
@@ -195,7 +195,6 @@ static int
vhost_transport_send_pkt(struct virtio_vsock_pkt *pkt)
{
struct vhost_vsock *vsock;
- struct vhost_virtqueue *vq;
int len = pkt->len;
/* Find the vhost_vsock according to guest context id */
@@ -205,8 +204,6 @@ vhost_transport_send_pkt(struct virtio_vsock_pkt *pkt)
return -ENODEV;
}
- vq = &vsock->vqs[VSOCK_VQ_RX];
-
if (pkt->reply)
atomic_inc(&vsock->queued_replies);
--
2.7.4
^ permalink raw reply related
* Re: [PATCH net-next] bpf: fix loading of BPF_MAXINSNS sized programs
From: Daniel Borkmann @ 2016-12-07 9:53 UTC (permalink / raw)
To: Sergei Shtylyov, davem; +Cc: alexei.starovoitov, netdev
In-Reply-To: <7039f9c2-c1d8-7549-7448-e369875ad9c1@cogentembedded.com>
On 12/07/2016 10:42 AM, Sergei Shtylyov wrote:
> Hello!
>
> On 12/7/2016 3:15 AM, Daniel Borkmann wrote:
>
>> General assumption is that single program can hold up to BPF_MAXINSNS,
>> that is, 4096 number of instructions. It is the case with cBPF and
>
> Up to BPF_MAXINSNS (that is 4096) instructions.
Thanks for nitpicking, I think it's just fine as-is.
>> that limit was carried over to eBPF. When recently testing digest, I
>> noticed that it's actually not possible to feed 4096 instructions
>> via bpf(2).
>>
>> The check for > BPF_MAXINSNS was added back then to bpf_check() in
>> cbd357008604 ("bpf: verifier (add ability to receive verification log)").
>> However, 09756af46893 ("bpf: expand BPF syscall with program load/unload")
>> added yet another check that comes before that into bpf_prog_load(),
>> but this time bails out already in case of >= BPF_MAXINSNS.
>>
>> Fix it up and perform the check early in bpf_prog_load(), so we can drop
>> the second one in bpf_check(). It makes sense, because also a 0 insn
>> program is useless and we don't want to waste any resources doing work
>> up to bpf_check() point. The existing bpf(2) man page documents E2BIG
>> as the official error for such cases, so just stick with it as well.
>>
>> Fixes: 09756af46893 ("bpf: expand BPF syscall with program load/unload")
>> Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
>> Acked-by: Alexei Starovoitov <ast@kernel.org>
> [...]
>
> MBR, Sergei
^ permalink raw reply
* [PATCH] can: raw: raw_setsockopt: limit number of can_filter that can be set
From: Marc Kleine-Budde @ 2016-12-07 9:50 UTC (permalink / raw)
To: netdev; +Cc: davem, linux-can, kernel, Marc Kleine-Budde, linux-stable
In-Reply-To: <20161207095040.5003-1-mkl@pengutronix.de>
This patch adds a check to limit the number of can_filters that can be
set via setsockopt on CAN_RAW sockets. Otherwise allocations > MAX_ORDER
are not prevented resulting in a warning.
Reference: https://lkml.org/lkml/2016/12/2/230
Reported-by: Andrey Konovalov <andreyknvl@google.com>
Tested-by: Andrey Konovalov <andreyknvl@google.com>
Cc: linux-stable <stable@vger.kernel.org>
Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
---
include/uapi/linux/can.h | 1 +
net/can/raw.c | 3 +++
2 files changed, 4 insertions(+)
diff --git a/include/uapi/linux/can.h b/include/uapi/linux/can.h
index 9692cda5f8fc..c48d93a28d1a 100644
--- a/include/uapi/linux/can.h
+++ b/include/uapi/linux/can.h
@@ -196,5 +196,6 @@ struct can_filter {
};
#define CAN_INV_FILTER 0x20000000U /* to be set in can_filter.can_id */
+#define CAN_RAW_FILTER_MAX 512 /* maximum number of can_filter set via setsockopt() */
#endif /* !_UAPI_CAN_H */
diff --git a/net/can/raw.c b/net/can/raw.c
index 972c187d40ab..b075f028d7e2 100644
--- a/net/can/raw.c
+++ b/net/can/raw.c
@@ -499,6 +499,9 @@ static int raw_setsockopt(struct socket *sock, int level, int optname,
if (optlen % sizeof(struct can_filter) != 0)
return -EINVAL;
+ if (optlen > CAN_RAW_FILTER_MAX * sizeof(struct can_filter))
+ return -EINVAL;
+
count = optlen / sizeof(struct can_filter);
if (count > 1) {
--
2.10.2
^ permalink raw reply related
* pull-request: can 2016-12-07
From: Marc Kleine-Budde @ 2016-12-07 9:50 UTC (permalink / raw)
To: netdev; +Cc: davem, linux-can, kernel
Hello David,
Andrey Konovalov triggered a warning in the CAN RAW layer, which is fixed by a
patch by me.
regards,
Marc
---
The following changes since commit bc3913a5378cd0ddefd1dfec6917cc12eb23a946:
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/sparc (2016-12-06 09:24:11 -0800)
are available in the git repository at:
git://git.kernel.org/pub/scm/linux/kernel/git/mkl/linux-can.git tags/linux-can-fixes-for-4.9-20161207
for you to fetch changes up to 332b05ca7a438f857c61a3c21a88489a21532364:
can: raw: raw_setsockopt: limit number of can_filter that can be set (2016-12-07 10:45:57 +0100)
----------------------------------------------------------------
linux-can-fixes-for-4.9-20161207
----------------------------------------------------------------
Marc Kleine-Budde (1):
can: raw: raw_setsockopt: limit number of can_filter that can be set
include/uapi/linux/can.h | 1 +
net/can/raw.c | 3 +++
2 files changed, 4 insertions(+)
^ permalink raw reply
* Re: [PATCH net-next 2/2] net: ethernet: Initial driver for Synopsys DWC XLGMAC
From: Pavel Machek @ 2016-12-07 9:48 UTC (permalink / raw)
To: Jie Deng
Cc: davem, f.fainelli, netdev, linux-kernel, CARLOS.PALMINHA,
lars.persson, thomas.lendacky
In-Reply-To: <3fe82457c51f8437797eae27d03cdb0dcbef039b.1481075763.git.jiedeng@synopsys.com>
[-- Attachment #1: Type: text/plain, Size: 3897 bytes --]
Hi!
> This patch provides the initial driver for 25/40/50/100 GbE
> devices using Synopsys DWC Enterprise Ethernet (XLGMAC)
>
> Signed-off-by: Jie Deng <jiedeng@synopsys.com>
I trust this is different hardware from stmmac?
> diff --git a/MAINTAINERS b/MAINTAINERS
> index 331f6af..738f818 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -10639,6 +10639,12 @@ S: Supported
> F: Documentation/devicetree/bindings/net/snps,dwc-qos-ethernet.txt
> F: drivers/net/ethernet/synopsys/dwc_eth_qos.c
>
> +SYNOPSYS DESIGNWARE ENTERPRISE ETHERNET (XLGMAC) DRIVER
> +M: jiedeng <jiedeng@synopsys.com>
Jie Deng here?
> @@ -0,0 +1,228 @@
> +/*
> + * Synopsys DesignWare Ethernet Driver
Your patch title names hardware differently...?
> + *
> + * Copyright (c) 2014-2016 Synopsys, Inc. (www.synopsys.com)
> + *
> + * This file is free software; you may copy, redistribute 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.
> + *
> + * This file is distributed in the hope that it will be useful, but
> + * WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
> + * General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program. If not, see <http://www.gnu.org/licenses/>.
> + *
> + * This file incorporates work covered by the following copyright and
> + * permission notice:
> + * The Synopsys DWC ETHER XGMAC Software Driver and documentation
> + * (hereinafter "Software") is an unsupported proprietary work of Synopsys,
> + * Inc. unless otherwise expressly agreed to in writing between Synopsys
> + * and you.
> + *
> + * The Software IS NOT an item of Licensed Software or Licensed Product
> + * under any End User Software License Agreement or Agreement for Licensed
> + * Product with Synopsys or any supplement thereto. Permission is hereby
> + * granted, free of charge, to any person obtaining a copy of this software
> + * annotated with this license and the Software, to deal in the Software
> + * without restriction, including without limitation the rights to use,
> + * copy, modify, merge, publish, distribute, sublicense, and/or sell copies
> + * of the Software, and to permit persons to whom the Software is furnished
> + * to do so, subject to the following conditions:
> + *
> + * The above copyright notice and this permission notice shall be included
> + * in all copies or substantial portions of the Software.
> + * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS"
> + * BASIS AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
> + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
> + * PARTICULAR PURPOSE ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS
> + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
> + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
> + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
> + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
> + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
> + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
> + * THE POSSIBILITY OF SUCH DAMAGE.
Are you sure this is GPL compatible? Can we get a version without this
lenghty legaleese?
Thanks,
Pavel
--
(english) http://www.livejournal.com/~pavelmachek
(cesky, pictures) http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html
[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 181 bytes --]
^ 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