* [patch net-next RFC v3 00/10] introduce infrastructure for support of switch chip datapath
@ 2014-04-17 12:14 Jiri Pirko
2014-04-17 12:14 ` [patch net-next RFC v3 02/10] net: rename netdev_phys_port_id to more generic name Jiri Pirko
` (6 more replies)
0 siblings, 7 replies; 24+ messages in thread
From: Jiri Pirko @ 2014-04-17 12:14 UTC (permalink / raw)
To: netdev
Cc: davem, nhorman, andy, tgraf, dborkman, ogerlitz, jesse, pshelar,
azhou, ben, stephen, jeffrey.t.kirsher, vyasevic, xiyou.wangcong,
john.r.fastabend, edumazet, jhs, sfeldma, f.fainelli, roopa,
linville, dev, jasowang, ebiederm, nicolas.dichtel, ryazanov.s.a,
buytenh, aviadr, nbd, alexei.starovoitov, Neil.Jerram
The basic idea is to introduce a generic infractructure to support various
switch chips in kernel.
The current patchset RFC is a heavy rework of the previous ones. The goal is to
be low-intrusive and to use as much as possible from the existing
infrastructure.
Also the idea is to benefit from currently existing Open vSwitch userspace
infrastructure prividing a HW offload for it. Note that this is just one
usecase. Other sw*dev_ndos can be easily added to support many more usecases,
Please see Documentation/networking/switchdev.txt for more details about
the model.
Next step would be to introduce a flag via which OVS userspace could tell if the
flow should be inserted in HW or just in the SW datapath. That would extend current
2 level cashing (kernel, userspace) to 3 level (hw, kernel, userspace).
Next step would be to improve internal kernel notifiers and introduce a listener
which would call sw*dev_ndos to setup the switch according to what the user
wants. This would allow a usecase then a user configures bridges, bonds, etc and
the switch chip underneath gets configured by that.
Any suggestions, feedbacks welcome.
Jiri Pirko (10):
openvswitch: split flow structures into ovs specific and generic ones
net: rename netdev_phys_port_id to more generic name
net: introduce generic switch devices support
rtnl: expose physical switch id for particular device
switchdev: introduce basic support for flows
net: introduce dummy switch
dsa: implement ndo_swdev_get_id
net: add netdev_for_each_all_lower_dev_rcu helper
openvswitch: introduce vport_op get_netdev
openvswitch: add support for datapath hardware offload
Documentation/networking/switchdev.txt | 53 +++++++
drivers/net/Kconfig | 7 +
drivers/net/Makefile | 1 +
drivers/net/dummyswitch.c | 126 +++++++++++++++++
drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c | 2 +-
drivers/net/ethernet/mellanox/mlx4/en_netdev.c | 2 +-
drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c | 2 +-
include/linux/netdevice.h | 74 ++++++++--
include/linux/sw_flow.h | 122 ++++++++++++++++
include/linux/switchdev.h | 55 ++++++++
include/uapi/linux/if_link.h | 10 ++
net/Kconfig | 6 +
net/core/Makefile | 1 +
net/core/dev.c | 28 ++--
net/core/net-sysfs.c | 2 +-
net/core/rtnetlink.c | 30 +++-
net/core/switchdev.c | 90 ++++++++++++
net/dsa/slave.c | 16 +++
net/openvswitch/Makefile | 3 +-
net/openvswitch/datapath.c | 63 +++++----
net/openvswitch/datapath.h | 4 +-
net/openvswitch/dp_notify.c | 7 +-
net/openvswitch/flow.c | 14 +-
net/openvswitch/flow.h | 123 ++++------------
net/openvswitch/flow_netlink.c | 24 ++--
net/openvswitch/flow_netlink.h | 4 +-
net/openvswitch/flow_table.c | 100 ++++++-------
net/openvswitch/flow_table.h | 18 +--
net/openvswitch/hw_offload.c | 170 +++++++++++++++++++++++
net/openvswitch/hw_offload.h | 31 +++++
net/openvswitch/vport-gre.c | 4 +-
net/openvswitch/vport-internal_dev.c | 53 ++++---
net/openvswitch/vport-netdev.c | 16 +++
net/openvswitch/vport-netdev.h | 12 --
net/openvswitch/vport-vxlan.c | 2 +-
net/openvswitch/vport.c | 2 +-
net/openvswitch/vport.h | 4 +-
37 files changed, 1004 insertions(+), 277 deletions(-)
create mode 100644 Documentation/networking/switchdev.txt
create mode 100644 drivers/net/dummyswitch.c
create mode 100644 include/linux/sw_flow.h
create mode 100644 include/linux/switchdev.h
create mode 100644 net/core/switchdev.c
create mode 100644 net/openvswitch/hw_offload.c
create mode 100644 net/openvswitch/hw_offload.h
--
1.9.0
^ permalink raw reply [flat|nested] 24+ messages in thread
* [patch net-next RFC v3 01/10] openvswitch: split flow structures into ovs specific and generic ones
[not found] ` <1397736876-11771-1-git-send-email-jiri-rHqAuBHg3fBzbRFIqnYvSA@public.gmane.org>
@ 2014-04-17 12:14 ` Jiri Pirko
2014-04-17 12:14 ` [patch net-next RFC v3 06/10] net: introduce dummy switch Jiri Pirko
` (3 subsequent siblings)
4 siblings, 0 replies; 24+ messages in thread
From: Jiri Pirko @ 2014-04-17 12:14 UTC (permalink / raw)
To: netdev-u79uwXL29TY76Z2rM5mHXA
Cc: ryazanov.s.a-Re5JQEeQqe8AvxtiuMwx3w,
jasowang-H+wXaHxf7aLQT0dZR+AlfA,
john.r.fastabend-ral2JQCrhuEAvxtiuMwx3w,
Neil.Jerram-QnUH15yq9NYqDJ6do+/SaQ,
edumazet-hpIqsD4AKlfQT0dZR+AlfA, andy-QlMahl40kYEqcZcGjlUOXw,
dev-yBygre7rU0TnMu66kgdUjQ, nbd-p3rKhJxN3npAfugRpC6u6w,
f.fainelli-Re5JQEeQqe8AvxtiuMwx3w,
jeffrey.t.kirsher-ral2JQCrhuEAvxtiuMwx3w,
ogerlitz-VPRAkNaXOzVWk0Htik3J/w, ben-/+tVBieCtBitmTQ+vhA3Yw,
buytenh-OLH4Qvv75CYX/NnBR394Jw,
roopa-qUQiAmfTcIp+XZJcv9eMoEEOCMrvLtNR,
jhs-jkUAjuhPggJWk0Htik3J/w, linville-2XuSBdqkA4R54TAoqtyWWQ,
aviadr-VPRAkNaXOzVWk0Htik3J/w,
nicolas.dichtel-pdR9zngts4EAvxtiuMwx3w,
vyasevic-H+wXaHxf7aLQT0dZR+AlfA, nhorman-2XuSBdqkA4R54TAoqtyWWQ,
sfeldma-qUQiAmfTcIp+XZJcv9eMoEEOCMrvLtNR,
stephen-OTpzqLSitTUnbdJkjeBofR2eb7JE58TQ,
dborkman-H+wXaHxf7aLQT0dZR+AlfA, ebiederm-aS9lmoZGLiVWk0Htik3J/w,
davem-fT/PcQaiUtIeIZ0/mPfg9Q
After this, flow related structures can be used in other code.
Signed-off-by: Jiri Pirko <jiri-rHqAuBHg3fBzbRFIqnYvSA@public.gmane.org>
---
include/linux/sw_flow.h | 108 ++++++++++++++++++++++++++++++++++++
net/openvswitch/datapath.c | 45 +++++++--------
net/openvswitch/datapath.h | 4 +-
net/openvswitch/flow.c | 14 ++---
net/openvswitch/flow.h | 123 +++++++++--------------------------------
net/openvswitch/flow_netlink.c | 24 ++++----
net/openvswitch/flow_netlink.h | 4 +-
net/openvswitch/flow_table.c | 100 +++++++++++++++++----------------
net/openvswitch/flow_table.h | 18 +++---
net/openvswitch/vport-gre.c | 4 +-
net/openvswitch/vport-vxlan.c | 2 +-
net/openvswitch/vport.c | 2 +-
net/openvswitch/vport.h | 2 +-
13 files changed, 245 insertions(+), 205 deletions(-)
create mode 100644 include/linux/sw_flow.h
diff --git a/include/linux/sw_flow.h b/include/linux/sw_flow.h
new file mode 100644
index 0000000..3bbd5aa
--- /dev/null
+++ b/include/linux/sw_flow.h
@@ -0,0 +1,108 @@
+/*
+ * Copyright (c) 2007-2012 Nicira, Inc.
+ * Copyright (c) 2014 Jiri Pirko <jiri-rHqAuBHg3fBzbRFIqnYvSA@public.gmane.org>
+ *
+ * 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.
+ *
+ * This program 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, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA
+ */
+
+#ifndef _LINUX_SW_FLOW_H_
+#define _LINUX_SW_FLOW_H_
+
+struct sw_flow_key_ipv4_tunnel {
+ __be64 tun_id;
+ __be32 ipv4_src;
+ __be32 ipv4_dst;
+ __be16 tun_flags;
+ u8 ipv4_tos;
+ u8 ipv4_ttl;
+};
+
+struct sw_flow_key {
+ struct sw_flow_key_ipv4_tunnel tun_key; /* Encapsulating tunnel key. */
+ struct {
+ u32 priority; /* Packet QoS priority. */
+ u32 skb_mark; /* SKB mark. */
+ u16 in_port; /* Input switch port (or DP_MAX_PORTS). */
+ } phy;
+ struct {
+ u8 src[ETH_ALEN]; /* Ethernet source address. */
+ u8 dst[ETH_ALEN]; /* Ethernet destination address. */
+ __be16 tci; /* 0 if no VLAN, VLAN_TAG_PRESENT set otherwise. */
+ __be16 type; /* Ethernet frame type. */
+ } eth;
+ struct {
+ u8 proto; /* IP protocol or lower 8 bits of ARP opcode. */
+ u8 tos; /* IP ToS. */
+ u8 ttl; /* IP TTL/hop limit. */
+ u8 frag; /* One of OVS_FRAG_TYPE_*. */
+ } ip;
+ union {
+ struct {
+ struct {
+ __be32 src; /* IP source address. */
+ __be32 dst; /* IP destination address. */
+ } addr;
+ union {
+ struct {
+ __be16 src; /* TCP/UDP/SCTP source port. */
+ __be16 dst; /* TCP/UDP/SCTP destination port. */
+ __be16 flags; /* TCP flags. */
+ } tp;
+ struct {
+ u8 sha[ETH_ALEN]; /* ARP source hardware address. */
+ u8 tha[ETH_ALEN]; /* ARP target hardware address. */
+ } arp;
+ };
+ } ipv4;
+ struct {
+ struct {
+ struct in6_addr src; /* IPv6 source address. */
+ struct in6_addr dst; /* IPv6 destination address. */
+ } addr;
+ __be32 label; /* IPv6 flow label. */
+ struct {
+ __be16 src; /* TCP/UDP/SCTP source port. */
+ __be16 dst; /* TCP/UDP/SCTP destination port. */
+ __be16 flags; /* TCP flags. */
+ } tp;
+ struct {
+ struct in6_addr target; /* ND target address. */
+ u8 sll[ETH_ALEN]; /* ND source link layer address. */
+ u8 tll[ETH_ALEN]; /* ND target link layer address. */
+ } nd;
+ } ipv6;
+ };
+} __aligned(BITS_PER_LONG/8); /* Ensure that we can do comparisons as longs. */
+
+struct sw_flow_key_range {
+ unsigned short int start;
+ unsigned short int end;
+};
+
+struct sw_flow_mask {
+ struct sw_flow_key_range range;
+ struct sw_flow_key key;
+};
+
+struct sw_flow {
+ struct sw_flow_key key;
+ struct sw_flow_key unmasked_key;
+ struct sw_flow_mask *mask;
+};
+
+struct sw_flow_action {
+}
+
+#endif /* _LINUX_SW_FLOW_H_ */
diff --git a/net/openvswitch/datapath.c b/net/openvswitch/datapath.c
index a3276e3..fcbdb52 100644
--- a/net/openvswitch/datapath.c
+++ b/net/openvswitch/datapath.c
@@ -216,7 +216,7 @@ void ovs_dp_detach_port(struct vport *p)
void ovs_dp_process_received_packet(struct vport *p, struct sk_buff *skb)
{
struct datapath *dp = p->dp;
- struct sw_flow *flow;
+ struct ovs_flow *flow;
struct dp_stats_percpu *stats;
struct sw_flow_key key;
u64 *stats_counter;
@@ -492,7 +492,7 @@ static int ovs_packet_cmd_execute(struct sk_buff *skb, struct genl_info *info)
struct nlattr **a = info->attrs;
struct sw_flow_actions *acts;
struct sk_buff *packet;
- struct sw_flow *flow;
+ struct ovs_flow *flow;
struct datapath *dp;
struct ethhdr *eth;
int len;
@@ -529,11 +529,11 @@ static int ovs_packet_cmd_execute(struct sk_buff *skb, struct genl_info *info)
if (IS_ERR(flow))
goto err_kfree_skb;
- err = ovs_flow_extract(packet, -1, &flow->key);
+ err = ovs_flow_extract(packet, -1, &flow->flow.key);
if (err)
goto err_flow_free;
- err = ovs_nla_get_flow_metadata(flow, a[OVS_PACKET_ATTR_KEY]);
+ err = ovs_nla_get_flow_metadata(&flow->flow, a[OVS_PACKET_ATTR_KEY]);
if (err)
goto err_flow_free;
acts = ovs_nla_alloc_flow_actions(nla_len(a[OVS_PACKET_ATTR_ACTIONS]));
@@ -542,15 +542,15 @@ static int ovs_packet_cmd_execute(struct sk_buff *skb, struct genl_info *info)
goto err_flow_free;
err = ovs_nla_copy_actions(a[OVS_PACKET_ATTR_ACTIONS],
- &flow->key, 0, &acts);
+ &flow->flow.key, 0, &acts);
rcu_assign_pointer(flow->sf_acts, acts);
if (err)
goto err_flow_free;
OVS_CB(packet)->flow = flow;
- OVS_CB(packet)->pkt_key = &flow->key;
- packet->priority = flow->key.phy.priority;
- packet->mark = flow->key.phy.skb_mark;
+ OVS_CB(packet)->pkt_key = &flow->flow.key;
+ packet->priority = flow->flow.key.phy.priority;
+ packet->mark = flow->flow.key.phy.skb_mark;
rcu_read_lock();
dp = get_dp(sock_net(skb->sk), ovs_header->dp_ifindex);
@@ -653,7 +653,7 @@ static size_t ovs_flow_cmd_msg_size(const struct sw_flow_actions *acts)
}
/* Called with ovs_mutex. */
-static int ovs_flow_cmd_fill_info(struct sw_flow *flow, struct datapath *dp,
+static int ovs_flow_cmd_fill_info(struct ovs_flow *flow, struct datapath *dp,
struct sk_buff *skb, u32 portid,
u32 seq, u32 flags, u8 cmd)
{
@@ -677,7 +677,8 @@ static int ovs_flow_cmd_fill_info(struct sw_flow *flow, struct datapath *dp,
if (!nla)
goto nla_put_failure;
- err = ovs_nla_put_flow(&flow->unmasked_key, &flow->unmasked_key, skb);
+ err = ovs_nla_put_flow(&flow->flow.unmasked_key,
+ &flow->flow.unmasked_key, skb);
if (err)
goto error;
nla_nest_end(skb, nla);
@@ -686,7 +687,7 @@ static int ovs_flow_cmd_fill_info(struct sw_flow *flow, struct datapath *dp,
if (!nla)
goto nla_put_failure;
- err = ovs_nla_put_flow(&flow->key, &flow->mask->key, skb);
+ err = ovs_nla_put_flow(&flow->flow.key, &flow->flow.mask->key, skb);
if (err)
goto error;
@@ -743,7 +744,7 @@ error:
return err;
}
-static struct sk_buff *ovs_flow_cmd_alloc_info(struct sw_flow *flow,
+static struct sk_buff *ovs_flow_cmd_alloc_info(struct ovs_flow *flow,
struct genl_info *info)
{
size_t len;
@@ -753,7 +754,7 @@ static struct sk_buff *ovs_flow_cmd_alloc_info(struct sw_flow *flow,
return genlmsg_new_unicast(len, info, GFP_KERNEL);
}
-static struct sk_buff *ovs_flow_cmd_build_info(struct sw_flow *flow,
+static struct sk_buff *ovs_flow_cmd_build_info(struct ovs_flow *flow,
struct datapath *dp,
struct genl_info *info,
u8 cmd)
@@ -776,12 +777,12 @@ static int ovs_flow_cmd_new_or_set(struct sk_buff *skb, struct genl_info *info)
struct nlattr **a = info->attrs;
struct ovs_header *ovs_header = info->userhdr;
struct sw_flow_key key, masked_key;
- struct sw_flow *flow = NULL;
+ struct ovs_flow *flow = NULL;
struct sw_flow_mask mask;
struct sk_buff *reply;
struct datapath *dp;
struct sw_flow_actions *acts = NULL;
- struct sw_flow_match match;
+ struct ovs_flow_match match;
bool exact_5tuple;
int error;
@@ -836,8 +837,8 @@ static int ovs_flow_cmd_new_or_set(struct sk_buff *skb, struct genl_info *info)
goto err_unlock_ovs;
}
- flow->key = masked_key;
- flow->unmasked_key = key;
+ flow->flow.key = masked_key;
+ flow->flow.unmasked_key = key;
rcu_assign_pointer(flow->sf_acts, acts);
/* Put flow in bucket. */
@@ -903,9 +904,9 @@ static int ovs_flow_cmd_get(struct sk_buff *skb, struct genl_info *info)
struct ovs_header *ovs_header = info->userhdr;
struct sw_flow_key key;
struct sk_buff *reply;
- struct sw_flow *flow;
+ struct ovs_flow *flow;
struct datapath *dp;
- struct sw_flow_match match;
+ struct ovs_flow_match match;
int err;
if (!a[OVS_FLOW_ATTR_KEY]) {
@@ -950,9 +951,9 @@ static int ovs_flow_cmd_del(struct sk_buff *skb, struct genl_info *info)
struct ovs_header *ovs_header = info->userhdr;
struct sw_flow_key key;
struct sk_buff *reply;
- struct sw_flow *flow;
+ struct ovs_flow *flow;
struct datapath *dp;
- struct sw_flow_match match;
+ struct ovs_flow_match match;
int err;
ovs_lock();
@@ -1015,7 +1016,7 @@ static int ovs_flow_cmd_dump(struct sk_buff *skb, struct netlink_callback *cb)
ti = rcu_dereference(dp->table.ti);
for (;;) {
- struct sw_flow *flow;
+ struct ovs_flow *flow;
u32 bucket, obj;
bucket = cb->args[0];
diff --git a/net/openvswitch/datapath.h b/net/openvswitch/datapath.h
index 0531738..5388cac 100644
--- a/net/openvswitch/datapath.h
+++ b/net/openvswitch/datapath.h
@@ -100,9 +100,9 @@ struct datapath {
* packet is not being tunneled.
*/
struct ovs_skb_cb {
- struct sw_flow *flow;
+ struct ovs_flow *flow;
struct sw_flow_key *pkt_key;
- struct ovs_key_ipv4_tunnel *tun_key;
+ struct sw_flow_key_ipv4_tunnel *tun_key;
};
#define OVS_CB(skb) ((struct ovs_skb_cb *)(skb)->cb)
diff --git a/net/openvswitch/flow.c b/net/openvswitch/flow.c
index 2998989..757f9aa 100644
--- a/net/openvswitch/flow.c
+++ b/net/openvswitch/flow.c
@@ -61,7 +61,7 @@ u64 ovs_flow_used_time(unsigned long flow_jiffies)
#define TCP_FLAGS_BE16(tp) (*(__be16 *)&tcp_flag_word(tp) & htons(0x0FFF))
-void ovs_flow_stats_update(struct sw_flow *flow, struct sk_buff *skb)
+void ovs_flow_stats_update(struct ovs_flow *flow, struct sk_buff *skb)
{
struct flow_stats *stats;
__be16 tcp_flags = 0;
@@ -71,10 +71,10 @@ void ovs_flow_stats_update(struct sw_flow *flow, struct sk_buff *skb)
else
stats = this_cpu_ptr(flow->stats.cpu_stats);
- if ((flow->key.eth.type == htons(ETH_P_IP) ||
- flow->key.eth.type == htons(ETH_P_IPV6)) &&
- flow->key.ip.frag != OVS_FRAG_TYPE_LATER &&
- flow->key.ip.proto == IPPROTO_TCP &&
+ if ((flow->flow.key.eth.type == htons(ETH_P_IP) ||
+ flow->flow.key.eth.type == htons(ETH_P_IPV6)) &&
+ flow->flow.key.ip.frag != OVS_FRAG_TYPE_LATER &&
+ flow->flow.key.ip.proto == IPPROTO_TCP &&
likely(skb->len >= skb_transport_offset(skb) + sizeof(struct tcphdr))) {
tcp_flags = TCP_FLAGS_BE16(tcp_hdr(skb));
}
@@ -100,7 +100,7 @@ static void stats_read(struct flow_stats *stats,
spin_unlock(&stats->lock);
}
-void ovs_flow_stats_get(struct sw_flow *flow, struct ovs_flow_stats *ovs_stats,
+void ovs_flow_stats_get(struct ovs_flow *flow, struct ovs_flow_stats *ovs_stats,
unsigned long *used, __be16 *tcp_flags)
{
int cpu;
@@ -133,7 +133,7 @@ static void stats_reset(struct flow_stats *stats)
spin_unlock(&stats->lock);
}
-void ovs_flow_stats_clear(struct sw_flow *flow)
+void ovs_flow_stats_clear(struct ovs_flow *flow)
{
int cpu;
diff --git a/net/openvswitch/flow.h b/net/openvswitch/flow.h
index 2d770e2..1ece896 100644
--- a/net/openvswitch/flow.h
+++ b/net/openvswitch/flow.h
@@ -32,24 +32,16 @@
#include <linux/time.h>
#include <linux/flex_array.h>
#include <net/inet_ecn.h>
+#include <linux/sw_flow.h>
struct sk_buff;
-/* Used to memset ovs_key_ipv4_tunnel padding. */
+/* Used to memset sw_flow_key_ipv4_tunnel padding. */
#define OVS_TUNNEL_KEY_SIZE \
- (offsetof(struct ovs_key_ipv4_tunnel, ipv4_ttl) + \
- FIELD_SIZEOF(struct ovs_key_ipv4_tunnel, ipv4_ttl))
-
-struct ovs_key_ipv4_tunnel {
- __be64 tun_id;
- __be32 ipv4_src;
- __be32 ipv4_dst;
- __be16 tun_flags;
- u8 ipv4_tos;
- u8 ipv4_ttl;
-};
+ (offsetof(struct sw_flow_key_ipv4_tunnel, ipv4_ttl) + \
+ FIELD_SIZEOF(struct sw_flow_key_ipv4_tunnel, ipv4_ttl))
-static inline void ovs_flow_tun_key_init(struct ovs_key_ipv4_tunnel *tun_key,
+static inline void ovs_flow_tun_key_init(struct sw_flow_key_ipv4_tunnel *tun_key,
const struct iphdr *iph, __be64 tun_id,
__be16 tun_flags)
{
@@ -65,77 +57,28 @@ static inline void ovs_flow_tun_key_init(struct ovs_key_ipv4_tunnel *tun_key,
sizeof(*tun_key) - OVS_TUNNEL_KEY_SIZE);
}
-struct sw_flow_key {
- struct ovs_key_ipv4_tunnel tun_key; /* Encapsulating tunnel key. */
- struct {
- u32 priority; /* Packet QoS priority. */
- u32 skb_mark; /* SKB mark. */
- u16 in_port; /* Input switch port (or DP_MAX_PORTS). */
- } phy;
- struct {
- u8 src[ETH_ALEN]; /* Ethernet source address. */
- u8 dst[ETH_ALEN]; /* Ethernet destination address. */
- __be16 tci; /* 0 if no VLAN, VLAN_TAG_PRESENT set otherwise. */
- __be16 type; /* Ethernet frame type. */
- } eth;
- struct {
- u8 proto; /* IP protocol or lower 8 bits of ARP opcode. */
- u8 tos; /* IP ToS. */
- u8 ttl; /* IP TTL/hop limit. */
- u8 frag; /* One of OVS_FRAG_TYPE_*. */
- } ip;
- union {
- struct {
- struct {
- __be32 src; /* IP source address. */
- __be32 dst; /* IP destination address. */
- } addr;
- union {
- struct {
- __be16 src; /* TCP/UDP/SCTP source port. */
- __be16 dst; /* TCP/UDP/SCTP destination port. */
- __be16 flags; /* TCP flags. */
- } tp;
- struct {
- u8 sha[ETH_ALEN]; /* ARP source hardware address. */
- u8 tha[ETH_ALEN]; /* ARP target hardware address. */
- } arp;
- };
- } ipv4;
- struct {
- struct {
- struct in6_addr src; /* IPv6 source address. */
- struct in6_addr dst; /* IPv6 destination address. */
- } addr;
- __be32 label; /* IPv6 flow label. */
- struct {
- __be16 src; /* TCP/UDP/SCTP source port. */
- __be16 dst; /* TCP/UDP/SCTP destination port. */
- __be16 flags; /* TCP flags. */
- } tp;
- struct {
- struct in6_addr target; /* ND target address. */
- u8 sll[ETH_ALEN]; /* ND source link layer address. */
- u8 tll[ETH_ALEN]; /* ND target link layer address. */
- } nd;
- } ipv6;
- };
-} __aligned(BITS_PER_LONG/8); /* Ensure that we can do comparisons as longs. */
+struct arp_eth_header {
+ __be16 ar_hrd; /* format of hardware address */
+ __be16 ar_pro; /* format of protocol address */
+ unsigned char ar_hln; /* length of hardware address */
+ unsigned char ar_pln; /* length of protocol address */
+ __be16 ar_op; /* ARP opcode (command) */
-struct sw_flow_key_range {
- unsigned short int start;
- unsigned short int end;
-};
+ /* Ethernet+IPv4 specific members. */
+ unsigned char ar_sha[ETH_ALEN]; /* sender hardware address */
+ unsigned char ar_sip[4]; /* sender IP address */
+ unsigned char ar_tha[ETH_ALEN]; /* target hardware address */
+ unsigned char ar_tip[4]; /* target IP address */
+} __packed;
-struct sw_flow_mask {
+struct ovs_flow_mask {
int ref_count;
struct rcu_head rcu;
struct list_head list;
- struct sw_flow_key_range range;
- struct sw_flow_key key;
+ struct sw_flow_mask mask;
};
-struct sw_flow_match {
+struct ovs_flow_match {
struct sw_flow_key *key;
struct sw_flow_key_range range;
struct sw_flow_mask *mask;
@@ -163,36 +106,20 @@ struct sw_flow_stats {
};
};
-struct sw_flow {
+struct ovs_flow {
struct rcu_head rcu;
struct hlist_node hash_node[2];
u32 hash;
- struct sw_flow_key key;
- struct sw_flow_key unmasked_key;
- struct sw_flow_mask *mask;
+ struct sw_flow flow;
struct sw_flow_actions __rcu *sf_acts;
struct sw_flow_stats stats;
};
-struct arp_eth_header {
- __be16 ar_hrd; /* format of hardware address */
- __be16 ar_pro; /* format of protocol address */
- unsigned char ar_hln; /* length of hardware address */
- unsigned char ar_pln; /* length of protocol address */
- __be16 ar_op; /* ARP opcode (command) */
-
- /* Ethernet+IPv4 specific members. */
- unsigned char ar_sha[ETH_ALEN]; /* sender hardware address */
- unsigned char ar_sip[4]; /* sender IP address */
- unsigned char ar_tha[ETH_ALEN]; /* target hardware address */
- unsigned char ar_tip[4]; /* target IP address */
-} __packed;
-
-void ovs_flow_stats_update(struct sw_flow *flow, struct sk_buff *skb);
-void ovs_flow_stats_get(struct sw_flow *flow, struct ovs_flow_stats *stats,
+void ovs_flow_stats_update(struct ovs_flow *flow, struct sk_buff *skb);
+void ovs_flow_stats_get(struct ovs_flow *flow, struct ovs_flow_stats *stats,
unsigned long *used, __be16 *tcp_flags);
-void ovs_flow_stats_clear(struct sw_flow *flow);
+void ovs_flow_stats_clear(struct ovs_flow *flow);
u64 ovs_flow_used_time(unsigned long flow_jiffies);
int ovs_flow_extract(struct sk_buff *, u16 in_port, struct sw_flow_key *);
diff --git a/net/openvswitch/flow_netlink.c b/net/openvswitch/flow_netlink.c
index 4d000ac..179ab98 100644
--- a/net/openvswitch/flow_netlink.c
+++ b/net/openvswitch/flow_netlink.c
@@ -46,7 +46,7 @@
#include "flow_netlink.h"
-static void update_range__(struct sw_flow_match *match,
+static void update_range__(struct ovs_flow_match *match,
size_t offset, size_t size, bool is_mask)
{
struct sw_flow_key_range *range = NULL;
@@ -103,7 +103,7 @@ static u16 range_n_bytes(const struct sw_flow_key_range *range)
return range->end - range->start;
}
-static bool match_validate(const struct sw_flow_match *match,
+static bool match_validate(const struct ovs_flow_match *match,
u64 key_attrs, u64 mask_attrs)
{
u64 key_expected = 1 << OVS_KEY_ATTR_ETHERNET;
@@ -339,7 +339,7 @@ static int parse_flow_nlattrs(const struct nlattr *attr,
}
static int ipv4_tun_from_nlattr(const struct nlattr *attr,
- struct sw_flow_match *match, bool is_mask)
+ struct ovs_flow_match *match, bool is_mask)
{
struct nlattr *a;
int rem;
@@ -428,8 +428,8 @@ static int ipv4_tun_from_nlattr(const struct nlattr *attr,
}
static int ipv4_tun_to_nlattr(struct sk_buff *skb,
- const struct ovs_key_ipv4_tunnel *tun_key,
- const struct ovs_key_ipv4_tunnel *output)
+ const struct sw_flow_key_ipv4_tunnel *tun_key,
+ const struct sw_flow_key_ipv4_tunnel *output)
{
struct nlattr *nla;
@@ -463,7 +463,7 @@ static int ipv4_tun_to_nlattr(struct sk_buff *skb,
}
-static int metadata_from_nlattrs(struct sw_flow_match *match, u64 *attrs,
+static int metadata_from_nlattrs(struct ovs_flow_match *match, u64 *attrs,
const struct nlattr **a, bool is_mask)
{
if (*attrs & (1 << OVS_KEY_ATTR_PRIORITY)) {
@@ -501,7 +501,7 @@ static int metadata_from_nlattrs(struct sw_flow_match *match, u64 *attrs,
return 0;
}
-static int ovs_key_from_nlattrs(struct sw_flow_match *match, bool *exact_5tuple,
+static int ovs_key_from_nlattrs(struct ovs_flow_match *match, bool *exact_5tuple,
u64 attrs, const struct nlattr **a,
bool is_mask)
{
@@ -799,7 +799,7 @@ static void sw_flow_mask_set(struct sw_flow_mask *mask,
* @mask: Optional. Netlink attribute holding nested %OVS_KEY_ATTR_* Netlink
* attribute specifies the mask field of the wildcarded flow.
*/
-int ovs_nla_get_match(struct sw_flow_match *match,
+int ovs_nla_get_match(struct ovs_flow_match *match,
bool *exact_5tuple,
const struct nlattr *key,
const struct nlattr *mask)
@@ -922,11 +922,11 @@ int ovs_nla_get_match(struct sw_flow_match *match,
int ovs_nla_get_flow_metadata(struct sw_flow *flow,
const struct nlattr *attr)
{
- struct ovs_key_ipv4_tunnel *tun_key = &flow->key.tun_key;
+ struct sw_flow_key_ipv4_tunnel *tun_key = &flow->key.tun_key;
const struct nlattr *a[OVS_KEY_ATTR_MAX + 1];
u64 attrs = 0;
int err;
- struct sw_flow_match match;
+ struct ovs_flow_match match;
flow->key.phy.in_port = DP_MAX_PORTS;
flow->key.phy.priority = 0;
@@ -1320,7 +1320,7 @@ static int validate_tp_port(const struct sw_flow_key *flow_key)
return -EINVAL;
}
-void ovs_match_init(struct sw_flow_match *match,
+void ovs_match_init(struct ovs_flow_match *match,
struct sw_flow_key *key,
struct sw_flow_mask *mask)
{
@@ -1339,7 +1339,7 @@ void ovs_match_init(struct sw_flow_match *match,
static int validate_and_copy_set_tun(const struct nlattr *attr,
struct sw_flow_actions **sfa)
{
- struct sw_flow_match match;
+ struct ovs_flow_match match;
struct sw_flow_key key;
int err, start;
diff --git a/net/openvswitch/flow_netlink.h b/net/openvswitch/flow_netlink.h
index b31fbe2..f223929 100644
--- a/net/openvswitch/flow_netlink.h
+++ b/net/openvswitch/flow_netlink.h
@@ -37,14 +37,14 @@
#include "flow.h"
-void ovs_match_init(struct sw_flow_match *match,
+void ovs_match_init(struct ovs_flow_match *match,
struct sw_flow_key *key, struct sw_flow_mask *mask);
int ovs_nla_put_flow(const struct sw_flow_key *,
const struct sw_flow_key *, struct sk_buff *);
int ovs_nla_get_flow_metadata(struct sw_flow *flow,
const struct nlattr *attr);
-int ovs_nla_get_match(struct sw_flow_match *match,
+int ovs_nla_get_match(struct ovs_flow_match *match,
bool *exact_5tuple,
const struct nlattr *,
const struct nlattr *);
diff --git a/net/openvswitch/flow_table.c b/net/openvswitch/flow_table.c
index 3c268b3..053ece9 100644
--- a/net/openvswitch/flow_table.c
+++ b/net/openvswitch/flow_table.c
@@ -70,9 +70,9 @@ void ovs_flow_mask_key(struct sw_flow_key *dst, const struct sw_flow_key *src,
*d++ = *s++ & *m++;
}
-struct sw_flow *ovs_flow_alloc(bool percpu_stats)
+struct ovs_flow *ovs_flow_alloc(bool percpu_stats)
{
- struct sw_flow *flow;
+ struct ovs_flow *flow;
int cpu;
flow = kmem_cache_alloc(flow_cache, GFP_KERNEL);
@@ -80,7 +80,7 @@ struct sw_flow *ovs_flow_alloc(bool percpu_stats)
return ERR_PTR(-ENOMEM);
flow->sf_acts = NULL;
- flow->mask = NULL;
+ flow->flow.mask = NULL;
flow->stats.is_percpu = percpu_stats;
@@ -136,7 +136,7 @@ static struct flex_array *alloc_buckets(unsigned int n_buckets)
return buckets;
}
-static void flow_free(struct sw_flow *flow)
+static void flow_free(struct ovs_flow *flow)
{
kfree((struct sf_flow_acts __force *)flow->sf_acts);
if (flow->stats.is_percpu)
@@ -148,18 +148,20 @@ static void flow_free(struct sw_flow *flow)
static void rcu_free_flow_callback(struct rcu_head *rcu)
{
- struct sw_flow *flow = container_of(rcu, struct sw_flow, rcu);
+ struct ovs_flow *flow = container_of(rcu, struct ovs_flow, rcu);
flow_free(flow);
}
-void ovs_flow_free(struct sw_flow *flow, bool deferred)
+void ovs_flow_free(struct ovs_flow *flow, bool deferred)
{
if (!flow)
return;
- if (flow->mask) {
- struct sw_flow_mask *mask = flow->mask;
+ if (flow->flow.mask) {
+ struct ovs_flow_mask *mask = container_of(flow->flow.mask,
+ struct ovs_flow_mask,
+ mask);
/* ovs-lock is required to protect mask-refcount and
* mask list.
@@ -250,7 +252,7 @@ static void table_instance_destroy(struct table_instance *ti, bool deferred)
goto skip_flows;
for (i = 0; i < ti->n_buckets; i++) {
- struct sw_flow *flow;
+ struct ovs_flow *flow;
struct hlist_head *head = flex_array_get(ti->buckets, i);
struct hlist_node *n;
int ver = ti->node_ver;
@@ -275,10 +277,10 @@ void ovs_flow_tbl_destroy(struct flow_table *table, bool deferred)
table_instance_destroy(ti, deferred);
}
-struct sw_flow *ovs_flow_tbl_dump_next(struct table_instance *ti,
+struct ovs_flow *ovs_flow_tbl_dump_next(struct table_instance *ti,
u32 *bucket, u32 *last)
{
- struct sw_flow *flow;
+ struct ovs_flow *flow;
struct hlist_head *head;
int ver;
int i;
@@ -309,7 +311,8 @@ static struct hlist_head *find_bucket(struct table_instance *ti, u32 hash)
(hash & (ti->n_buckets - 1)));
}
-static void table_instance_insert(struct table_instance *ti, struct sw_flow *flow)
+static void table_instance_insert(struct table_instance *ti,
+ struct ovs_flow *flow)
{
struct hlist_head *head;
@@ -328,7 +331,7 @@ static void flow_table_copy_flows(struct table_instance *old,
/* Insert in new table. */
for (i = 0; i < old->n_buckets; i++) {
- struct sw_flow *flow;
+ struct ovs_flow *flow;
struct hlist_head *head;
head = flex_array_get(old->buckets, i);
@@ -415,21 +418,21 @@ static bool flow_cmp_masked_key(const struct sw_flow *flow,
return cmp_key(&flow->key, key, key_start, key_end);
}
-bool ovs_flow_cmp_unmasked_key(const struct sw_flow *flow,
- struct sw_flow_match *match)
+bool ovs_flow_cmp_unmasked_key(const struct ovs_flow *flow,
+ struct ovs_flow_match *match)
{
struct sw_flow_key *key = match->key;
int key_start = flow_key_start(key);
int key_end = match->range.end;
- return cmp_key(&flow->unmasked_key, key, key_start, key_end);
+ return cmp_key(&flow->flow.unmasked_key, key, key_start, key_end);
}
-static struct sw_flow *masked_flow_lookup(struct table_instance *ti,
- const struct sw_flow_key *unmasked,
- struct sw_flow_mask *mask)
+static struct ovs_flow *masked_flow_lookup(struct table_instance *ti,
+ const struct sw_flow_key *unmasked,
+ struct sw_flow_mask *mask)
{
- struct sw_flow *flow;
+ struct ovs_flow *flow;
struct hlist_head *head;
int key_start = mask->range.start;
int key_end = mask->range.end;
@@ -440,34 +443,34 @@ static struct sw_flow *masked_flow_lookup(struct table_instance *ti,
hash = flow_hash(&masked_key, key_start, key_end);
head = find_bucket(ti, hash);
hlist_for_each_entry_rcu(flow, head, hash_node[ti->node_ver]) {
- if (flow->mask == mask && flow->hash == hash &&
- flow_cmp_masked_key(flow, &masked_key,
+ if (flow->flow.mask == mask && flow->hash == hash &&
+ flow_cmp_masked_key(&flow->flow, &masked_key,
key_start, key_end))
return flow;
}
return NULL;
}
-struct sw_flow *ovs_flow_tbl_lookup_stats(struct flow_table *tbl,
- const struct sw_flow_key *key,
- u32 *n_mask_hit)
+struct ovs_flow *ovs_flow_tbl_lookup_stats(struct flow_table *tbl,
+ const struct sw_flow_key *key,
+ u32 *n_mask_hit)
{
struct table_instance *ti = rcu_dereference_ovsl(tbl->ti);
- struct sw_flow_mask *mask;
- struct sw_flow *flow;
+ struct ovs_flow_mask *mask;
+ struct ovs_flow *flow;
*n_mask_hit = 0;
list_for_each_entry_rcu(mask, &tbl->mask_list, list) {
(*n_mask_hit)++;
- flow = masked_flow_lookup(ti, key, mask);
+ flow = masked_flow_lookup(ti, key, &mask->mask);
if (flow) /* Found */
return flow;
}
return NULL;
}
-struct sw_flow *ovs_flow_tbl_lookup(struct flow_table *tbl,
- const struct sw_flow_key *key)
+struct ovs_flow *ovs_flow_tbl_lookup(struct flow_table *tbl,
+ const struct sw_flow_key *key)
{
u32 __always_unused n_mask_hit;
@@ -476,7 +479,7 @@ struct sw_flow *ovs_flow_tbl_lookup(struct flow_table *tbl,
int ovs_flow_tbl_num_masks(const struct flow_table *table)
{
- struct sw_flow_mask *mask;
+ struct ovs_flow_mask *mask;
int num = 0;
list_for_each_entry(mask, &table->mask_list, list)
@@ -490,7 +493,7 @@ static struct table_instance *table_instance_expand(struct table_instance *ti)
return table_instance_rehash(ti, ti->n_buckets * 2);
}
-void ovs_flow_tbl_remove(struct flow_table *table, struct sw_flow *flow)
+void ovs_flow_tbl_remove(struct flow_table *table, struct ovs_flow *flow)
{
struct table_instance *ti = ovsl_dereference(table->ti);
@@ -499,9 +502,9 @@ void ovs_flow_tbl_remove(struct flow_table *table, struct sw_flow *flow)
table->count--;
}
-static struct sw_flow_mask *mask_alloc(void)
+static struct ovs_flow_mask *mask_alloc(void)
{
- struct sw_flow_mask *mask;
+ struct ovs_flow_mask *mask;
mask = kmalloc(sizeof(*mask), GFP_KERNEL);
if (mask)
@@ -521,15 +524,15 @@ static bool mask_equal(const struct sw_flow_mask *a,
&& (memcmp(a_, b_, range_n_bytes(&a->range)) == 0);
}
-static struct sw_flow_mask *flow_mask_find(const struct flow_table *tbl,
- const struct sw_flow_mask *mask)
+static struct ovs_flow_mask *flow_mask_find(const struct flow_table *tbl,
+ const struct sw_flow_mask *mask)
{
struct list_head *ml;
list_for_each(ml, &tbl->mask_list) {
- struct sw_flow_mask *m;
- m = container_of(ml, struct sw_flow_mask, list);
- if (mask_equal(mask, m))
+ struct ovs_flow_mask *m;
+ m = container_of(ml, struct ovs_flow_mask, list);
+ if (mask_equal(mask, &m->mask))
return m;
}
@@ -537,29 +540,30 @@ static struct sw_flow_mask *flow_mask_find(const struct flow_table *tbl,
}
/* Add 'mask' into the mask list, if it is not already there. */
-static int flow_mask_insert(struct flow_table *tbl, struct sw_flow *flow,
+static int flow_mask_insert(struct flow_table *tbl, struct ovs_flow *flow,
struct sw_flow_mask *new)
{
- struct sw_flow_mask *mask;
+ struct ovs_flow_mask *mask;
+
mask = flow_mask_find(tbl, new);
if (!mask) {
/* Allocate a new mask if none exsits. */
mask = mask_alloc();
if (!mask)
return -ENOMEM;
- mask->key = new->key;
- mask->range = new->range;
+ mask->mask.key = new->key;
+ mask->mask.range = new->range;
list_add_rcu(&mask->list, &tbl->mask_list);
} else {
BUG_ON(!mask->ref_count);
mask->ref_count++;
}
- flow->mask = mask;
+ flow->flow.mask = &mask->mask;
return 0;
}
-int ovs_flow_tbl_insert(struct flow_table *table, struct sw_flow *flow,
+int ovs_flow_tbl_insert(struct flow_table *table, struct ovs_flow *flow,
struct sw_flow_mask *mask)
{
struct table_instance *new_ti = NULL;
@@ -570,8 +574,8 @@ int ovs_flow_tbl_insert(struct flow_table *table, struct sw_flow *flow,
if (err)
return err;
- flow->hash = flow_hash(&flow->key, flow->mask->range.start,
- flow->mask->range.end);
+ flow->hash = flow_hash(&flow->flow.key, flow->flow.mask->range.start,
+ flow->flow.mask->range.end);
ti = ovsl_dereference(table->ti);
table_instance_insert(ti, flow);
table->count++;
@@ -597,7 +601,7 @@ int ovs_flow_init(void)
BUILD_BUG_ON(__alignof__(struct sw_flow_key) % __alignof__(long));
BUILD_BUG_ON(sizeof(struct sw_flow_key) % sizeof(long));
- flow_cache = kmem_cache_create("sw_flow", sizeof(struct sw_flow), 0,
+ flow_cache = kmem_cache_create("ovs_flow", sizeof(struct ovs_flow), 0,
0, NULL);
if (flow_cache == NULL)
return -ENOMEM;
diff --git a/net/openvswitch/flow_table.h b/net/openvswitch/flow_table.h
index baaeb10..c6abd84 100644
--- a/net/openvswitch/flow_table.h
+++ b/net/openvswitch/flow_table.h
@@ -55,28 +55,28 @@ struct flow_table {
int ovs_flow_init(void);
void ovs_flow_exit(void);
-struct sw_flow *ovs_flow_alloc(bool percpu_stats);
-void ovs_flow_free(struct sw_flow *, bool deferred);
+struct ovs_flow *ovs_flow_alloc(bool percpu_stats);
+void ovs_flow_free(struct ovs_flow *, bool deferred);
int ovs_flow_tbl_init(struct flow_table *);
int ovs_flow_tbl_count(struct flow_table *table);
void ovs_flow_tbl_destroy(struct flow_table *table, bool deferred);
int ovs_flow_tbl_flush(struct flow_table *flow_table);
-int ovs_flow_tbl_insert(struct flow_table *table, struct sw_flow *flow,
+int ovs_flow_tbl_insert(struct flow_table *table, struct ovs_flow *flow,
struct sw_flow_mask *mask);
-void ovs_flow_tbl_remove(struct flow_table *table, struct sw_flow *flow);
+void ovs_flow_tbl_remove(struct flow_table *table, struct ovs_flow *flow);
int ovs_flow_tbl_num_masks(const struct flow_table *table);
-struct sw_flow *ovs_flow_tbl_dump_next(struct table_instance *table,
+struct ovs_flow *ovs_flow_tbl_dump_next(struct table_instance *table,
u32 *bucket, u32 *idx);
-struct sw_flow *ovs_flow_tbl_lookup_stats(struct flow_table *,
+struct ovs_flow *ovs_flow_tbl_lookup_stats(struct flow_table *,
const struct sw_flow_key *,
u32 *n_mask_hit);
-struct sw_flow *ovs_flow_tbl_lookup(struct flow_table *,
+struct ovs_flow *ovs_flow_tbl_lookup(struct flow_table *,
const struct sw_flow_key *);
-bool ovs_flow_cmp_unmasked_key(const struct sw_flow *flow,
- struct sw_flow_match *match);
+bool ovs_flow_cmp_unmasked_key(const struct ovs_flow *flow,
+ struct ovs_flow_match *match);
void ovs_flow_mask_key(struct sw_flow_key *dst, const struct sw_flow_key *src,
const struct sw_flow_mask *mask);
diff --git a/net/openvswitch/vport-gre.c b/net/openvswitch/vport-gre.c
index a3d6951..f940cbd 100644
--- a/net/openvswitch/vport-gre.c
+++ b/net/openvswitch/vport-gre.c
@@ -63,7 +63,7 @@ static __be16 filter_tnl_flags(__be16 flags)
static struct sk_buff *__build_header(struct sk_buff *skb,
int tunnel_hlen)
{
- const struct ovs_key_ipv4_tunnel *tun_key = OVS_CB(skb)->tun_key;
+ const struct sw_flow_key_ipv4_tunnel *tun_key = OVS_CB(skb)->tun_key;
struct tnl_ptk_info tpi;
skb = gre_handle_offloads(skb, !!(tun_key->tun_flags & TUNNEL_CSUM));
@@ -92,7 +92,7 @@ static __be64 key_to_tunnel_id(__be32 key, __be32 seq)
static int gre_rcv(struct sk_buff *skb,
const struct tnl_ptk_info *tpi)
{
- struct ovs_key_ipv4_tunnel tun_key;
+ struct sw_flow_key_ipv4_tunnel tun_key;
struct ovs_net *ovs_net;
struct vport *vport;
__be64 key;
diff --git a/net/openvswitch/vport-vxlan.c b/net/openvswitch/vport-vxlan.c
index e797a50..e0be18e 100644
--- a/net/openvswitch/vport-vxlan.c
+++ b/net/openvswitch/vport-vxlan.c
@@ -58,7 +58,7 @@ static inline struct vxlan_port *vxlan_vport(const struct vport *vport)
/* Called with rcu_read_lock and BH disabled. */
static void vxlan_rcv(struct vxlan_sock *vs, struct sk_buff *skb, __be32 vx_vni)
{
- struct ovs_key_ipv4_tunnel tun_key;
+ struct sw_flow_key_ipv4_tunnel tun_key;
struct vport *vport = vs->data;
struct iphdr *iph;
__be64 key;
diff --git a/net/openvswitch/vport.c b/net/openvswitch/vport.c
index 42c0f4a..81b083c 100644
--- a/net/openvswitch/vport.c
+++ b/net/openvswitch/vport.c
@@ -337,7 +337,7 @@ int ovs_vport_get_options(const struct vport *vport, struct sk_buff *skb)
* skb->data should point to the Ethernet header.
*/
void ovs_vport_receive(struct vport *vport, struct sk_buff *skb,
- struct ovs_key_ipv4_tunnel *tun_key)
+ struct sw_flow_key_ipv4_tunnel *tun_key)
{
struct pcpu_sw_netstats *stats;
diff --git a/net/openvswitch/vport.h b/net/openvswitch/vport.h
index d7e50a1..0979304 100644
--- a/net/openvswitch/vport.h
+++ b/net/openvswitch/vport.h
@@ -191,7 +191,7 @@ static inline struct vport *vport_from_priv(const void *priv)
}
void ovs_vport_receive(struct vport *, struct sk_buff *,
- struct ovs_key_ipv4_tunnel *);
+ struct sw_flow_key_ipv4_tunnel *);
/* List of statically compiled vport implementations. Don't forget to also
* add yours to the list at the top of vport.c. */
--
1.9.0
^ permalink raw reply related [flat|nested] 24+ messages in thread
* [patch net-next RFC v3 02/10] net: rename netdev_phys_port_id to more generic name
2014-04-17 12:14 [patch net-next RFC v3 00/10] introduce infrastructure for support of switch chip datapath Jiri Pirko
@ 2014-04-17 12:14 ` Jiri Pirko
[not found] ` <1397736876-11771-3-git-send-email-jiri-rHqAuBHg3fBzbRFIqnYvSA@public.gmane.org>
2014-04-17 12:14 ` [patch net-next RFC v3 03/10] net: introduce generic switch devices support Jiri Pirko
` (5 subsequent siblings)
6 siblings, 1 reply; 24+ messages in thread
From: Jiri Pirko @ 2014-04-17 12:14 UTC (permalink / raw)
To: netdev
Cc: davem, nhorman, andy, tgraf, dborkman, ogerlitz, jesse, pshelar,
azhou, ben, stephen, jeffrey.t.kirsher, vyasevic, xiyou.wangcong,
john.r.fastabend, edumazet, jhs, sfeldma, f.fainelli, roopa,
linville, dev, jasowang, ebiederm, nicolas.dichtel, ryazanov.s.a,
buytenh, aviadr, nbd, alexei.starovoitov, Neil.Jerram
So this can be reused for identification of other "items" as well.
Signed-off-by: Jiri Pirko <jiri@resnulli.us>
---
drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c | 2 +-
drivers/net/ethernet/mellanox/mlx4/en_netdev.c | 2 +-
drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c | 2 +-
include/linux/netdevice.h | 16 ++++++++--------
net/core/dev.c | 2 +-
net/core/net-sysfs.c | 2 +-
net/core/rtnetlink.c | 6 +++---
7 files changed, 16 insertions(+), 16 deletions(-)
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
index a78edac..a4b25b1 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
@@ -12360,7 +12360,7 @@ static int bnx2x_validate_addr(struct net_device *dev)
}
static int bnx2x_get_phys_port_id(struct net_device *netdev,
- struct netdev_phys_port_id *ppid)
+ struct netdev_phys_item_id *ppid)
{
struct bnx2x *bp = netdev_priv(netdev);
diff --git a/drivers/net/ethernet/mellanox/mlx4/en_netdev.c b/drivers/net/ethernet/mellanox/mlx4/en_netdev.c
index f085c2d..e784bb4 100644
--- a/drivers/net/ethernet/mellanox/mlx4/en_netdev.c
+++ b/drivers/net/ethernet/mellanox/mlx4/en_netdev.c
@@ -2251,7 +2251,7 @@ static int mlx4_en_set_vf_link_state(struct net_device *dev, int vf, int link_st
#define PORT_ID_BYTE_LEN 8
static int mlx4_en_get_phys_port_id(struct net_device *dev,
- struct netdev_phys_port_id *ppid)
+ struct netdev_phys_item_id *ppid)
{
struct mlx4_en_priv *priv = netdev_priv(dev);
struct mlx4_dev *mdev = priv->mdev->dev;
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c
index 309d056..55af16a 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c
@@ -450,7 +450,7 @@ static void qlcnic_82xx_cancel_idc_work(struct qlcnic_adapter *adapter)
}
static int qlcnic_get_phys_port_id(struct net_device *netdev,
- struct netdev_phys_port_id *ppid)
+ struct netdev_phys_item_id *ppid)
{
struct qlcnic_adapter *adapter = netdev_priv(netdev);
struct qlcnic_hardware_context *ahw = adapter->ahw;
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index 775cc95..8cf4f5e 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -735,13 +735,13 @@ struct netdev_fcoe_hbainfo {
};
#endif
-#define MAX_PHYS_PORT_ID_LEN 32
+#define MAX_PHYS_ITEM_ID_LEN 32
-/* This structure holds a unique identifier to identify the
- * physical port used by a netdevice.
+/* This structure holds a unique identifier to identify some
+ * physical item (port for example) used by a netdevice.
*/
-struct netdev_phys_port_id {
- unsigned char id[MAX_PHYS_PORT_ID_LEN];
+struct netdev_phys_item_id {
+ unsigned char id[MAX_PHYS_ITEM_ID_LEN];
unsigned char id_len;
};
@@ -955,7 +955,7 @@ typedef u16 (*select_queue_fallback_t)(struct net_device *dev,
* USB_CDC_NOTIFY_NETWORK_CONNECTION) should NOT implement this function.
*
* int (*ndo_get_phys_port_id)(struct net_device *dev,
- * struct netdev_phys_port_id *ppid);
+ * struct netdev_phys_item_id *ppid);
* Called to get ID of physical port of this device. If driver does
* not implement this, it is assumed that the hw is not able to have
* multiple net devices on single physical port.
@@ -1121,7 +1121,7 @@ struct net_device_ops {
int (*ndo_change_carrier)(struct net_device *dev,
bool new_carrier);
int (*ndo_get_phys_port_id)(struct net_device *dev,
- struct netdev_phys_port_id *ppid);
+ struct netdev_phys_item_id *ppid);
void (*ndo_add_vxlan_port)(struct net_device *dev,
sa_family_t sa_family,
__be16 port);
@@ -2616,7 +2616,7 @@ void dev_set_group(struct net_device *, int);
int dev_set_mac_address(struct net_device *, struct sockaddr *);
int dev_change_carrier(struct net_device *, bool new_carrier);
int dev_get_phys_port_id(struct net_device *dev,
- struct netdev_phys_port_id *ppid);
+ struct netdev_phys_item_id *ppid);
int dev_hard_start_xmit(struct sk_buff *skb, struct net_device *dev,
struct netdev_queue *txq);
int dev_forward_skb(struct net_device *dev, struct sk_buff *skb);
diff --git a/net/core/dev.c b/net/core/dev.c
index 7570634..a0de81c 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -5512,7 +5512,7 @@ EXPORT_SYMBOL(dev_change_carrier);
* Get device physical port ID
*/
int dev_get_phys_port_id(struct net_device *dev,
- struct netdev_phys_port_id *ppid)
+ struct netdev_phys_item_id *ppid)
{
const struct net_device_ops *ops = dev->netdev_ops;
diff --git a/net/core/net-sysfs.c b/net/core/net-sysfs.c
index 1cac29e..c64426e 100644
--- a/net/core/net-sysfs.c
+++ b/net/core/net-sysfs.c
@@ -368,7 +368,7 @@ static ssize_t phys_port_id_show(struct device *dev,
return restart_syscall();
if (dev_isalive(netdev)) {
- struct netdev_phys_port_id ppid;
+ struct netdev_phys_item_id ppid;
ret = dev_get_phys_port_id(netdev, &ppid);
if (!ret)
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c
index d4ff417..231e043 100644
--- a/net/core/rtnetlink.c
+++ b/net/core/rtnetlink.c
@@ -829,7 +829,7 @@ static noinline size_t if_nlmsg_size(const struct net_device *dev,
+ rtnl_port_size(dev) /* IFLA_VF_PORTS + IFLA_PORT_SELF */
+ rtnl_link_get_size(dev) /* IFLA_LINKINFO */
+ rtnl_link_get_af_size(dev) /* IFLA_AF_SPEC */
- + nla_total_size(MAX_PHYS_PORT_ID_LEN); /* IFLA_PHYS_PORT_ID */
+ + nla_total_size(MAX_PHYS_ITEM_ID_LEN); /* IFLA_PHYS_PORT_ID */
}
static int rtnl_vf_ports_fill(struct sk_buff *skb, struct net_device *dev)
@@ -911,7 +911,7 @@ static int rtnl_port_fill(struct sk_buff *skb, struct net_device *dev)
static int rtnl_phys_port_id_fill(struct sk_buff *skb, struct net_device *dev)
{
int err;
- struct netdev_phys_port_id ppid;
+ struct netdev_phys_item_id ppid;
err = dev_get_phys_port_id(dev, &ppid);
if (err) {
@@ -1149,7 +1149,7 @@ static const struct nla_policy ifla_policy[IFLA_MAX+1] = {
[IFLA_PROMISCUITY] = { .type = NLA_U32 },
[IFLA_NUM_TX_QUEUES] = { .type = NLA_U32 },
[IFLA_NUM_RX_QUEUES] = { .type = NLA_U32 },
- [IFLA_PHYS_PORT_ID] = { .type = NLA_BINARY, .len = MAX_PHYS_PORT_ID_LEN },
+ [IFLA_PHYS_PORT_ID] = { .type = NLA_BINARY, .len = MAX_PHYS_ITEM_ID_LEN },
[IFLA_CARRIER_CHANGES] = { .type = NLA_U32 }, /* ignored */
};
--
1.9.0
^ permalink raw reply related [flat|nested] 24+ messages in thread
* [patch net-next RFC v3 03/10] net: introduce generic switch devices support
2014-04-17 12:14 [patch net-next RFC v3 00/10] introduce infrastructure for support of switch chip datapath Jiri Pirko
2014-04-17 12:14 ` [patch net-next RFC v3 02/10] net: rename netdev_phys_port_id to more generic name Jiri Pirko
@ 2014-04-17 12:14 ` Jiri Pirko
2014-04-17 12:14 ` [patch net-next RFC v3 04/10] rtnl: expose physical switch id for particular device Jiri Pirko
` (4 subsequent siblings)
6 siblings, 0 replies; 24+ messages in thread
From: Jiri Pirko @ 2014-04-17 12:14 UTC (permalink / raw)
To: netdev
Cc: davem, nhorman, andy, tgraf, dborkman, ogerlitz, jesse, pshelar,
azhou, ben, stephen, jeffrey.t.kirsher, vyasevic, xiyou.wangcong,
john.r.fastabend, edumazet, jhs, sfeldma, f.fainelli, roopa,
linville, dev, jasowang, ebiederm, nicolas.dichtel, ryazanov.s.a,
buytenh, aviadr, nbd, alexei.starovoitov, Neil.Jerram
The goal of this is to provide a possibility to suport various switch
chips. Drivers should implement relevant ndos to do so. So far, only one
ndo for getting physical switch id is in place.
Signed-off-by: Jiri Pirko <jiri@resnulli.us>
---
Documentation/networking/switchdev.txt | 53 ++++++++++++++++++++++++++++++++++
include/linux/netdevice.h | 10 +++++++
include/linux/switchdev.h | 30 +++++++++++++++++++
net/Kconfig | 6 ++++
net/core/Makefile | 1 +
net/core/switchdev.c | 32 ++++++++++++++++++++
6 files changed, 132 insertions(+)
create mode 100644 Documentation/networking/switchdev.txt
create mode 100644 include/linux/switchdev.h
create mode 100644 net/core/switchdev.c
diff --git a/Documentation/networking/switchdev.txt b/Documentation/networking/switchdev.txt
new file mode 100644
index 0000000..20345cc
--- /dev/null
+++ b/Documentation/networking/switchdev.txt
@@ -0,0 +1,53 @@
+Switch device drivers HOWTO
+===========================
+
+First lets describe a topology a bit. Imagine the following example:
+
+ +----------------------------+ +---------------+
+ | SOME switch chip | | CPU |
+ +----------------------------+ +---------------+
+ port1 port2 port3 port4 MNGMNT | PCI-E |
+ | | | | | +---------------+
+ PHY PHY | | | | NIC0 NIC1
+ | | | | | |
+ | | +- PCI-E -+ | |
+ | +------- MII -------+ |
+ +------------- MII ------------+
+
+In this example, there are two independent lines between the switch silicon
+and CPU. NIC0 and NIC1 drivers are not aware of a switch presence. They are
+separate from the switch driver. SOME switch chip is by managed by a driver
+via PCI-E device MNGMNT. Note that MNGMNT device, NIC0 and NIC1 may be
+connected to some other type of bus.
+
+Now, for the previous example show the representation in kernel:
+
+ +----------------------------+ +---------------+
+ | SOME switch chip | | CPU |
+ +----------------------------+ +---------------+
+ sw0p0 sw0p1 sw0p2 sw0p3 MNGMNT | PCI-E |
+ | | | | | +---------------+
+ PHY PHY | | | | eth0 eth1
+ | | | | | |
+ | | +- PCI-E -+ | |
+ | +------- MII -------+ |
+ +------------- MII ------------+
+
+Lets call the example switch driver for SOME switch chip "SOMEswitch". This
+driver takes care of PCI-E device MNGMNT. There is a netdevice instance sw0pX
+created for each port of a switch. These netdevices are instances
+of "SOMEswitch" driver. sw0pX netdevices serve as a "representation"
+of the switch chip. eth0 and eth1 are instances of some other existing driver.
+
+The only difference of the switch-port netdevice from the ordinary netdevice
+is that is implements couple more NDOs:
+
+ ndo_swdev_get_id - This returns the same ID for two port netdevices of
+ the same physical switch chip. This is mandatory to
+ be implemented by all switch drivers and serves
+ the caller for recognition of a port netdevice.
+ ndo_swdev_* - Functions that serve for a manipulation of the switch chip
+ itself. They are not port-specific. Caller might use
+ arbitrary port netdevice of the same switch and it will
+ make no difference.
+ ndo_swportdev_* - Functions that serve for a port-specific manipulation.
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index 8cf4f5e..83e38a0 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -991,6 +991,12 @@ typedef u16 (*select_queue_fallback_t)(struct net_device *dev,
* Callback to use for xmit over the accelerated station. This
* is used in place of ndo_start_xmit on accelerated net
* devices.
+ *
+ * int (*ndo_swdev_get_id)(struct net_device *dev,
+ * struct netdev_phys_item_id *psid);
+ * Called to get an ID of the switch chip this port is part of.
+ * If driver implements this, it indicates that it represents a port
+ * of a switch chip.
*/
struct net_device_ops {
int (*ndo_init)(struct net_device *dev);
@@ -1137,6 +1143,10 @@ struct net_device_ops {
netdev_tx_t (*ndo_dfwd_start_xmit) (struct sk_buff *skb,
struct net_device *dev,
void *priv);
+#ifdef CONFIG_NET_SWITCHDEV
+ int (*ndo_swdev_get_id)(struct net_device *dev,
+ struct netdev_phys_item_id *psid);
+#endif
};
/**
diff --git a/include/linux/switchdev.h b/include/linux/switchdev.h
new file mode 100644
index 0000000..b147dde
--- /dev/null
+++ b/include/linux/switchdev.h
@@ -0,0 +1,30 @@
+/*
+ * include/linux/switchdev.h - Switch device API
+ * Copyright (c) 2014 Jiri Pirko <jiri@resnulli.us>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+#ifndef _LINUX_SWITCHDEV_H_
+#define _LINUX_SWITCHDEV_H_
+
+#include <linux/netdevice.h>
+#include <linux/sw_flow.h>
+
+#ifdef CONFIG_NET_SWITCHDEV
+
+int swdev_get_id(struct net_device *dev, struct netdev_phys_item_id *psid);
+
+#else
+
+static inline int swdev_get_id(struct net_device *dev,
+ struct netdev_phys_item_id *psid)
+{
+ return -EOPNOTSUPP;
+}
+
+#endif
+
+#endif /* _LINUX_SWITCHDEV_H_ */
diff --git a/net/Kconfig b/net/Kconfig
index d1f6f96..b13be7c 100644
--- a/net/Kconfig
+++ b/net/Kconfig
@@ -289,6 +289,12 @@ config NET_FLOW_LIMIT
with many clients some protection against DoS by a single (spoofed)
flow that greatly exceeds average workload.
+config NET_SWITCHDEV
+ boolean "Switch device support"
+ depends on INET
+ ---help---
+ This module provides support for hardware switch chips.
+
menu "Network testing"
config NET_PKTGEN
diff --git a/net/core/Makefile b/net/core/Makefile
index 826b925..4b27dff 100644
--- a/net/core/Makefile
+++ b/net/core/Makefile
@@ -24,3 +24,4 @@ obj-$(CONFIG_NETWORK_PHY_TIMESTAMPING) += timestamping.o
obj-$(CONFIG_NET_PTP_CLASSIFY) += ptp_classifier.o
obj-$(CONFIG_CGROUP_NET_PRIO) += netprio_cgroup.o
obj-$(CONFIG_CGROUP_NET_CLASSID) += netclassid_cgroup.o
+obj-$(CONFIG_NET_SWITCHDEV) += switchdev.o
diff --git a/net/core/switchdev.c b/net/core/switchdev.c
new file mode 100644
index 0000000..2d275f5
--- /dev/null
+++ b/net/core/switchdev.c
@@ -0,0 +1,32 @@
+/*
+ * net/core/switchdev.c - Switch device API
+ * Copyright (c) 2014 Jiri Pirko <jiri@resnulli.us>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/init.h>
+#include <linux/netdevice.h>
+#include <linux/switchdev.h>
+
+/**
+ * swdev_get_id - Get ID of a switch
+ * @dev: port device
+ * @psid: switch ID
+ *
+ * Get ID of a switch this port is part of.
+ */
+int swdev_get_id(struct net_device *dev, struct netdev_phys_item_id *psid)
+{
+ const struct net_device_ops *ops = dev->netdev_ops;
+
+ if (!ops->ndo_swdev_get_id)
+ return -EOPNOTSUPP;
+ return ops->ndo_swdev_get_id(dev, psid);
+}
+EXPORT_SYMBOL(swdev_get_id);
--
1.9.0
^ permalink raw reply related [flat|nested] 24+ messages in thread
* [patch net-next RFC v3 04/10] rtnl: expose physical switch id for particular device
2014-04-17 12:14 [patch net-next RFC v3 00/10] introduce infrastructure for support of switch chip datapath Jiri Pirko
2014-04-17 12:14 ` [patch net-next RFC v3 02/10] net: rename netdev_phys_port_id to more generic name Jiri Pirko
2014-04-17 12:14 ` [patch net-next RFC v3 03/10] net: introduce generic switch devices support Jiri Pirko
@ 2014-04-17 12:14 ` Jiri Pirko
2014-04-17 12:40 ` Yegor Yefremov
2014-04-17 12:14 ` [patch net-next RFC v3 05/10] switchdev: introduce basic support for flows Jiri Pirko
` (3 subsequent siblings)
6 siblings, 1 reply; 24+ messages in thread
From: Jiri Pirko @ 2014-04-17 12:14 UTC (permalink / raw)
To: netdev
Cc: davem, nhorman, andy, tgraf, dborkman, ogerlitz, jesse, pshelar,
azhou, ben, stephen, jeffrey.t.kirsher, vyasevic, xiyou.wangcong,
john.r.fastabend, edumazet, jhs, sfeldma, f.fainelli, roopa,
linville, dev, jasowang, ebiederm, nicolas.dichtel, ryazanov.s.a,
buytenh, aviadr, nbd, alexei.starovoitov, Neil.Jerram
The the netdevice represents a port in a switch, it will expose
IFLA_PHYS_SWITCH_ID value via rtnl. Two netdevices with a same value
belong to one physical switch.
Signed-off-by: Jiri Pirko <jiri@resnulli.us>
---
include/uapi/linux/if_link.h | 1 +
net/core/rtnetlink.c | 26 +++++++++++++++++++++++++-
2 files changed, 26 insertions(+), 1 deletion(-)
diff --git a/include/uapi/linux/if_link.h b/include/uapi/linux/if_link.h
index 9a7f7ac..c11f492 100644
--- a/include/uapi/linux/if_link.h
+++ b/include/uapi/linux/if_link.h
@@ -145,6 +145,7 @@ enum {
IFLA_CARRIER,
IFLA_PHYS_PORT_ID,
IFLA_CARRIER_CHANGES,
+ IFLA_PHYS_SWITCH_ID,
__IFLA_MAX
};
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c
index 231e043..7170e24 100644
--- a/net/core/rtnetlink.c
+++ b/net/core/rtnetlink.c
@@ -43,6 +43,7 @@
#include <linux/inet.h>
#include <linux/netdevice.h>
+#include <linux/switchdev.h>
#include <net/ip.h>
#include <net/protocol.h>
#include <net/arp.h>
@@ -829,7 +830,8 @@ static noinline size_t if_nlmsg_size(const struct net_device *dev,
+ rtnl_port_size(dev) /* IFLA_VF_PORTS + IFLA_PORT_SELF */
+ rtnl_link_get_size(dev) /* IFLA_LINKINFO */
+ rtnl_link_get_af_size(dev) /* IFLA_AF_SPEC */
- + nla_total_size(MAX_PHYS_ITEM_ID_LEN); /* IFLA_PHYS_PORT_ID */
+ + nla_total_size(MAX_PHYS_ITEM_ID_LEN) /* IFLA_PHYS_PORT_ID */
+ + nla_total_size(MAX_PHYS_ITEM_ID_LEN); /* IFLA_PHYS_SWITCH_ID */
}
static int rtnl_vf_ports_fill(struct sk_buff *skb, struct net_device *dev)
@@ -926,6 +928,24 @@ static int rtnl_phys_port_id_fill(struct sk_buff *skb, struct net_device *dev)
return 0;
}
+static int rtnl_phys_switch_id_fill(struct sk_buff *skb, struct net_device *dev)
+{
+ int err;
+ struct netdev_phys_item_id psid;
+
+ err = swdev_get_id(dev, &psid);
+ if (err) {
+ if (err == -EOPNOTSUPP)
+ return 0;
+ return err;
+ }
+
+ if (nla_put(skb, IFLA_PHYS_SWITCH_ID, psid.id_len, psid.id))
+ return -EMSGSIZE;
+
+ return 0;
+}
+
static int rtnl_fill_ifinfo(struct sk_buff *skb, struct net_device *dev,
int type, u32 pid, u32 seq, u32 change,
unsigned int flags, u32 ext_filter_mask)
@@ -998,6 +1018,9 @@ static int rtnl_fill_ifinfo(struct sk_buff *skb, struct net_device *dev,
if (rtnl_phys_port_id_fill(skb, dev))
goto nla_put_failure;
+ if (rtnl_phys_switch_id_fill(skb, dev))
+ goto nla_put_failure;
+
attr = nla_reserve(skb, IFLA_STATS,
sizeof(struct rtnl_link_stats));
if (attr == NULL)
@@ -1151,6 +1174,7 @@ static const struct nla_policy ifla_policy[IFLA_MAX+1] = {
[IFLA_NUM_RX_QUEUES] = { .type = NLA_U32 },
[IFLA_PHYS_PORT_ID] = { .type = NLA_BINARY, .len = MAX_PHYS_ITEM_ID_LEN },
[IFLA_CARRIER_CHANGES] = { .type = NLA_U32 }, /* ignored */
+ [IFLA_PHYS_SWITCH_ID] = { .type = NLA_BINARY, .len = MAX_PHYS_ITEM_ID_LEN },
};
static const struct nla_policy ifla_info_policy[IFLA_INFO_MAX+1] = {
--
1.9.0
^ permalink raw reply related [flat|nested] 24+ messages in thread
* [patch net-next RFC v3 05/10] switchdev: introduce basic support for flows
2014-04-17 12:14 [patch net-next RFC v3 00/10] introduce infrastructure for support of switch chip datapath Jiri Pirko
` (2 preceding siblings ...)
2014-04-17 12:14 ` [patch net-next RFC v3 04/10] rtnl: expose physical switch id for particular device Jiri Pirko
@ 2014-04-17 12:14 ` Jiri Pirko
2014-04-17 12:14 ` [patch net-next RFC v3 07/10] dsa: implement ndo_swdev_get_id Jiri Pirko
` (2 subsequent siblings)
6 siblings, 0 replies; 24+ messages in thread
From: Jiri Pirko @ 2014-04-17 12:14 UTC (permalink / raw)
To: netdev
Cc: davem, nhorman, andy, tgraf, dborkman, ogerlitz, jesse, pshelar,
azhou, ben, stephen, jeffrey.t.kirsher, vyasevic, xiyou.wangcong,
john.r.fastabend, edumazet, jhs, sfeldma, f.fainelli, roopa,
linville, dev, jasowang, ebiederm, nicolas.dichtel, ryazanov.s.a,
buytenh, aviadr, nbd, alexei.starovoitov, Neil.Jerram
This patch adds a couple of ndos which can be used to work with flows.
Note that user can use random port netdevice to access the switch.
Signed-off-by: Jiri Pirko <jiri@resnulli.us>
---
include/linux/netdevice.h | 30 ++++++++++++++++++++++++
include/linux/switchdev.h | 25 ++++++++++++++++++++
net/core/switchdev.c | 58 +++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 113 insertions(+)
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index 83e38a0..14bd8b3 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -49,6 +49,8 @@
#include <linux/netdev_features.h>
#include <linux/neighbour.h>
+#include <linux/sw_flow.h>
+
#include <uapi/linux/netdevice.h>
struct netpoll_info;
@@ -997,6 +999,26 @@ typedef u16 (*select_queue_fallback_t)(struct net_device *dev,
* Called to get an ID of the switch chip this port is part of.
* If driver implements this, it indicates that it represents a port
* of a switch chip.
+ *
+ * int (*ndo_swdev_flow_insert)(struct net_device *dev,
+ * const struct sw_flow *flow);
+ * Called to insert a flow into switch device. If driver does
+ * not implement this, it is assumed that the hw does not have
+ * a capability to work with flows.
+ *
+ * int (*ndo_swdev_flow_remove)(struct net_device *dev,
+ * const struct sw_flow *flow);
+ * Called to remove a flow from switch device. If driver does
+ * not implement this, it is assumed that the hw does not have
+ * a capability to work with flows.
+ *
+ * int (*ndo_swdev_flow_action_set)(struct net_device *dev,
+ * const struct sw_flow *flow,
+ * const struct sw_flow_action *action,
+ * size_t action_count);
+ * Called to set actions for a flow inserted in swtich device.
+ * If driver does not implement this, it is assumed that the hw does
+ * not have a capability to work with flows.
*/
struct net_device_ops {
int (*ndo_init)(struct net_device *dev);
@@ -1146,6 +1168,14 @@ struct net_device_ops {
#ifdef CONFIG_NET_SWITCHDEV
int (*ndo_swdev_get_id)(struct net_device *dev,
struct netdev_phys_item_id *psid);
+ int (*ndo_swdev_flow_insert)(struct net_device *dev,
+ const struct sw_flow *flow);
+ int (*ndo_swdev_flow_remove)(struct net_device *dev,
+ const struct sw_flow *flow);
+ int (*ndo_swdev_flow_action_set)(struct net_device *dev,
+ const struct sw_flow *flow,
+ const struct sw_flow_action *action,
+ size_t action_count);
#endif
};
diff --git a/include/linux/switchdev.h b/include/linux/switchdev.h
index b147dde..6f8ce06 100644
--- a/include/linux/switchdev.h
+++ b/include/linux/switchdev.h
@@ -16,6 +16,11 @@
#ifdef CONFIG_NET_SWITCHDEV
int swdev_get_id(struct net_device *dev, struct netdev_phys_item_id *psid);
+int swdev_flow_insert(struct net_device *dev, const struct sw_flow *flow);
+int swdev_flow_remove(struct net_device *dev, const struct sw_flow *flow);
+int swdev_flow_action_set(struct net_device *dev, const struct sw_flow *flow,
+ const struct sw_flow_action *action,
+ size_t action_count);
#else
@@ -25,6 +30,26 @@ static inline int swdev_get_id(struct net_device *dev,
return -EOPNOTSUPP;
}
+static inline int swdev_flow_insert(struct net_device *dev,
+ const struct sw_flow *flow)
+{
+ return -EOPNOTSUPP;
+}
+
+static inline int swdev_flow_remove(struct net_device *dev,
+ const struct sw_flow *flow)
+{
+ return -EOPNOTSUPP;
+}
+
+static inline int swdev_flow_action_set(struct net_device *dev,
+ const struct sw_flow *flow,
+ const struct sw_flow_action *action,
+ size_t action_count)
+{
+ return -EOPNOTSUPP;
+}
+
#endif
#endif /* _LINUX_SWITCHDEV_H_ */
diff --git a/net/core/switchdev.c b/net/core/switchdev.c
index 2d275f5..cb5b6a2 100644
--- a/net/core/switchdev.c
+++ b/net/core/switchdev.c
@@ -30,3 +30,61 @@ int swdev_get_id(struct net_device *dev, struct netdev_phys_item_id *psid)
return ops->ndo_swdev_get_id(dev, psid);
}
EXPORT_SYMBOL(swdev_get_id);
+
+/**
+ * swdev_flow_insert - Insert a flow into switch
+ * @dev: port device
+ * @flow: flow descriptor
+ *
+ * Insert a flow into switch this port is part of.
+ */
+int swdev_flow_insert(struct net_device *dev, const struct sw_flow *flow)
+{
+ const struct net_device_ops *ops = dev->netdev_ops;
+
+ if (!ops->ndo_swdev_flow_insert)
+ return -EOPNOTSUPP;
+ WARN_ON(!ops->ndo_swdev_get_id);
+ return ops->ndo_swdev_flow_insert(dev, flow);
+}
+EXPORT_SYMBOL(swdev_flow_insert);
+
+/**
+ * swdev_flow_remove - Remove a flow from switch
+ * @dev: port device
+ * @flow: flow descriptor
+ *
+ * Remove a flow from switch this port is part of.
+ */
+int swdev_flow_remove(struct net_device *dev, const struct sw_flow *flow)
+{
+ const struct net_device_ops *ops = dev->netdev_ops;
+
+ if (!ops->ndo_swdev_flow_remove)
+ return -EOPNOTSUPP;
+ WARN_ON(!ops->ndo_swdev_get_id);
+ return ops->ndo_swdev_flow_remove(dev, flow);
+}
+EXPORT_SYMBOL(swdev_flow_remove);
+
+/**
+ * swdev_flow_action_set - Set actions for a flow
+ * @dev: port device
+ * @flow: flow descriptor
+ * @action: array of actions
+ * @action_count: length of the array of actions
+ *
+ * Set actions for a flow.
+ */
+int swdev_flow_action_set(struct net_device *dev, const struct sw_flow *flow,
+ const struct sw_flow_action *action,
+ size_t action_count)
+{
+ const struct net_device_ops *ops = dev->netdev_ops;
+
+ if (!ops->ndo_swdev_flow_action_set)
+ return -EOPNOTSUPP;
+ WARN_ON(!ops->ndo_swdev_get_id);
+ return ops->ndo_swdev_flow_action_set(dev, flow, action, action_count);
+}
+EXPORT_SYMBOL(swdev_flow_action_set);
--
1.9.0
^ permalink raw reply related [flat|nested] 24+ messages in thread
* [patch net-next RFC v3 06/10] net: introduce dummy switch
[not found] ` <1397736876-11771-1-git-send-email-jiri-rHqAuBHg3fBzbRFIqnYvSA@public.gmane.org>
2014-04-17 12:14 ` [patch net-next RFC v3 01/10] openvswitch: split flow structures into ovs specific and generic ones Jiri Pirko
@ 2014-04-17 12:14 ` Jiri Pirko
2014-04-17 12:14 ` [patch net-next RFC v3 08/10] net: add netdev_for_each_all_lower_dev_rcu helper Jiri Pirko
` (2 subsequent siblings)
4 siblings, 0 replies; 24+ messages in thread
From: Jiri Pirko @ 2014-04-17 12:14 UTC (permalink / raw)
To: netdev-u79uwXL29TY76Z2rM5mHXA
Cc: ryazanov.s.a-Re5JQEeQqe8AvxtiuMwx3w,
jasowang-H+wXaHxf7aLQT0dZR+AlfA,
john.r.fastabend-ral2JQCrhuEAvxtiuMwx3w,
Neil.Jerram-QnUH15yq9NYqDJ6do+/SaQ,
edumazet-hpIqsD4AKlfQT0dZR+AlfA, andy-QlMahl40kYEqcZcGjlUOXw,
dev-yBygre7rU0TnMu66kgdUjQ, nbd-p3rKhJxN3npAfugRpC6u6w,
f.fainelli-Re5JQEeQqe8AvxtiuMwx3w,
jeffrey.t.kirsher-ral2JQCrhuEAvxtiuMwx3w,
ogerlitz-VPRAkNaXOzVWk0Htik3J/w, ben-/+tVBieCtBitmTQ+vhA3Yw,
buytenh-OLH4Qvv75CYX/NnBR394Jw,
roopa-qUQiAmfTcIp+XZJcv9eMoEEOCMrvLtNR,
jhs-jkUAjuhPggJWk0Htik3J/w, linville-2XuSBdqkA4R54TAoqtyWWQ,
aviadr-VPRAkNaXOzVWk0Htik3J/w,
nicolas.dichtel-pdR9zngts4EAvxtiuMwx3w,
vyasevic-H+wXaHxf7aLQT0dZR+AlfA, nhorman-2XuSBdqkA4R54TAoqtyWWQ,
sfeldma-qUQiAmfTcIp+XZJcv9eMoEEOCMrvLtNR,
stephen-OTpzqLSitTUnbdJkjeBofR2eb7JE58TQ,
dborkman-H+wXaHxf7aLQT0dZR+AlfA, ebiederm-aS9lmoZGLiVWk0Htik3J/w,
davem-fT/PcQaiUtIeIZ0/mPfg9Q
Dummy switch implementation using switchdev interface
Signed-off-by: Jiri Pirko <jiri-rHqAuBHg3fBzbRFIqnYvSA@public.gmane.org>
---
drivers/net/Kconfig | 7 +++
drivers/net/Makefile | 1 +
drivers/net/dummyswitch.c | 126 +++++++++++++++++++++++++++++++++++++++++++
include/uapi/linux/if_link.h | 9 ++++
4 files changed, 143 insertions(+)
create mode 100644 drivers/net/dummyswitch.c
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
index 89402c3..a9629a7 100644
--- a/drivers/net/Kconfig
+++ b/drivers/net/Kconfig
@@ -71,6 +71,13 @@ config DUMMY
To compile this driver as a module, choose M here: the module
will be called dummy.
+config NET_DUMMY_SWITCH
+ tristate "Dummy switch net driver support"
+ depends on NET_SWITCHDEV
+ ---help---
+ To compile this driver as a module, choose M here: the module
+ will be called dummyswitch.
+
config EQUALIZER
tristate "EQL (serial line load balancing) support"
---help---
diff --git a/drivers/net/Makefile b/drivers/net/Makefile
index 3fef8a8..d5d4ce6 100644
--- a/drivers/net/Makefile
+++ b/drivers/net/Makefile
@@ -7,6 +7,7 @@
#
obj-$(CONFIG_BONDING) += bonding/
obj-$(CONFIG_DUMMY) += dummy.o
+obj-$(CONFIG_NET_DUMMY_SWITCH) += dummyswitch.o
obj-$(CONFIG_EQUALIZER) += eql.o
obj-$(CONFIG_IFB) += ifb.o
obj-$(CONFIG_MACVLAN) += macvlan.o
diff --git a/drivers/net/dummyswitch.c b/drivers/net/dummyswitch.c
new file mode 100644
index 0000000..f0d1195
--- /dev/null
+++ b/drivers/net/dummyswitch.c
@@ -0,0 +1,126 @@
+/*
+ * drivers/net/dummyswitch.c - Dummy switch device
+ * Copyright (c) 2014 Jiri Pirko <jiri-rHqAuBHg3fBzbRFIqnYvSA@public.gmane.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/etherdevice.h>
+#include <linux/switchdev.h>
+
+#include <net/rtnetlink.h>
+
+struct dummyswport_priv {
+ struct netdev_phys_item_id psid;
+};
+
+static netdev_tx_t dummyswport_start_xmit(struct sk_buff *skb,
+ struct net_device *dev)
+{
+ dev_kfree_skb(skb);
+ return NETDEV_TX_OK;
+}
+
+static int dummyswport_swdev_get_id(struct net_device *dev,
+ struct netdev_phys_item_id *psid)
+{
+ struct dummyswport_priv *dsp = netdev_priv(dev);
+
+ memcpy(psid, &dsp->psid, sizeof(*psid));
+ return 0;
+}
+
+static const struct net_device_ops dummyswport_netdev_ops = {
+ .ndo_start_xmit = dummyswport_start_xmit,
+ .ndo_swdev_get_id = dummyswport_swdev_get_id,
+};
+
+static void dummyswport_setup(struct net_device *dev)
+{
+ ether_setup(dev);
+
+ /* Initialize the device structure. */
+ dev->netdev_ops = &dummyswport_netdev_ops;
+ dev->destructor = free_netdev;
+
+ /* Fill in device structure with ethernet-generic values. */
+ dev->tx_queue_len = 0;
+ dev->flags |= IFF_NOARP;
+ dev->flags &= ~IFF_MULTICAST;
+ dev->priv_flags |= IFF_LIVE_ADDR_CHANGE;
+ dev->features |= NETIF_F_SG | NETIF_F_FRAGLIST | NETIF_F_TSO;
+ dev->features |= NETIF_F_HW_CSUM | NETIF_F_HIGHDMA | NETIF_F_LLTX;
+ eth_hw_addr_random(dev);
+}
+
+static int dummyswport_validate(struct nlattr *tb[], struct nlattr *data[])
+{
+ if (tb[IFLA_ADDRESS])
+ return -EINVAL;
+ if (!data || !data[IFLA_DYMMYSWPORT_PHYS_SWITCH_ID])
+ return -EINVAL;
+ return 0;
+}
+
+static int dummyswport_newlink(struct net *src_net, struct net_device *dev,
+ struct nlattr *tb[], struct nlattr *data[])
+{
+ struct dummyswport_priv *dsp = netdev_priv(dev);
+ int err;
+
+ dsp->psid.id_len = nla_len(data[IFLA_DYMMYSWPORT_PHYS_SWITCH_ID]);
+ memcpy(dsp->psid.id, nla_data(data[IFLA_DYMMYSWPORT_PHYS_SWITCH_ID]),
+ dsp->psid.id_len);
+
+ err = register_netdevice(dev);
+ if (err)
+ return err;
+
+ netif_carrier_on(dev);
+
+ return 0;
+}
+
+static const struct nla_policy dummyswport_policy[IFLA_DUMMYSWPORT_MAX + 1] = {
+ [IFLA_DYMMYSWPORT_PHYS_SWITCH_ID] = { .type = NLA_BINARY,
+ .len = MAX_PHYS_ITEM_ID_LEN },
+};
+
+static struct rtnl_link_ops dummyswport_link_ops __read_mostly = {
+ .kind = "dummyswport",
+ .priv_size = sizeof(struct dummyswport_priv),
+ .setup = dummyswport_setup,
+ .validate = dummyswport_validate,
+ .newlink = dummyswport_newlink,
+ .policy = dummyswport_policy,
+ .maxtype = IFLA_DUMMYSWPORT_MAX,
+};
+
+
+/*
+ * Module init/exit
+ */
+
+static int __init dummysw_module_init(void)
+{
+ return rtnl_link_register(&dummyswport_link_ops);
+}
+
+static void __exit dummysw_module_exit(void)
+{
+ rtnl_link_unregister(&dummyswport_link_ops);
+}
+
+module_init(dummysw_module_init);
+module_exit(dummysw_module_exit);
+
+MODULE_LICENSE("GPL v2");
+MODULE_AUTHOR("Jiri Pirko <jiri-rHqAuBHg3fBzbRFIqnYvSA@public.gmane.org>");
+MODULE_DESCRIPTION("Dummy switch device");
+MODULE_ALIAS_RTNL_LINK("dummyswport");
diff --git a/include/uapi/linux/if_link.h b/include/uapi/linux/if_link.h
index c11f492..f38e3d9 100644
--- a/include/uapi/linux/if_link.h
+++ b/include/uapi/linux/if_link.h
@@ -546,4 +546,13 @@ enum {
#define IFLA_HSR_MAX (__IFLA_HSR_MAX - 1)
+/* DUMMYSWPORT section */
+enum {
+ IFLA_DUMMYSWPORT_UNSPEC,
+ IFLA_DYMMYSWPORT_PHYS_SWITCH_ID,
+ __IFLA_DUMMYSWPORT_MAX,
+};
+
+#define IFLA_DUMMYSWPORT_MAX (__IFLA_DUMMYSWPORT_MAX - 1)
+
#endif /* _UAPI_LINUX_IF_LINK_H */
--
1.9.0
^ permalink raw reply related [flat|nested] 24+ messages in thread
* [patch net-next RFC v3 07/10] dsa: implement ndo_swdev_get_id
2014-04-17 12:14 [patch net-next RFC v3 00/10] introduce infrastructure for support of switch chip datapath Jiri Pirko
` (3 preceding siblings ...)
2014-04-17 12:14 ` [patch net-next RFC v3 05/10] switchdev: introduce basic support for flows Jiri Pirko
@ 2014-04-17 12:14 ` Jiri Pirko
[not found] ` <1397736876-11771-1-git-send-email-jiri-rHqAuBHg3fBzbRFIqnYvSA@public.gmane.org>
2014-04-17 12:14 ` [patch net-next RFC v3 09/10] openvswitch: introduce vport_op get_netdev Jiri Pirko
6 siblings, 0 replies; 24+ messages in thread
From: Jiri Pirko @ 2014-04-17 12:14 UTC (permalink / raw)
To: netdev
Cc: davem, nhorman, andy, tgraf, dborkman, ogerlitz, jesse, pshelar,
azhou, ben, stephen, jeffrey.t.kirsher, vyasevic, xiyou.wangcong,
john.r.fastabend, edumazet, jhs, sfeldma, f.fainelli, roopa,
linville, dev, jasowang, ebiederm, nicolas.dichtel, ryazanov.s.a,
buytenh, aviadr, nbd, alexei.starovoitov, Neil.Jerram
Signed-off-by: Jiri Pirko <jiri@resnulli.us>
---
net/dsa/slave.c | 16 ++++++++++++++++
1 file changed, 16 insertions(+)
diff --git a/net/dsa/slave.c b/net/dsa/slave.c
index 02c0e17..22855f3 100644
--- a/net/dsa/slave.c
+++ b/net/dsa/slave.c
@@ -171,6 +171,19 @@ static int dsa_slave_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
return -EOPNOTSUPP;
}
+static int dsa_slave_swdev_get_id(struct net_device *dev,
+ struct netdev_phys_item_id *psid)
+{
+ struct dsa_slave_priv *p = netdev_priv(dev);
+ struct dsa_switch *ds = p->parent;
+ u64 tmp = (u64) ds;
+
+ /* TODO: add more sophisticated id generation */
+ memcpy(&psid->id, &tmp, sizeof(tmp));
+ psid->id_len = sizeof(tmp);
+
+ return 0;
+}
/* ethtool operations *******************************************************/
static int
@@ -303,6 +316,7 @@ static const struct net_device_ops dsa_netdev_ops = {
.ndo_set_rx_mode = dsa_slave_set_rx_mode,
.ndo_set_mac_address = dsa_slave_set_mac_address,
.ndo_do_ioctl = dsa_slave_ioctl,
+ .ndo_swdev_get_id = dsa_slave_swdev_get_id,
};
#endif
#ifdef CONFIG_NET_DSA_TAG_EDSA
@@ -315,6 +329,7 @@ static const struct net_device_ops edsa_netdev_ops = {
.ndo_set_rx_mode = dsa_slave_set_rx_mode,
.ndo_set_mac_address = dsa_slave_set_mac_address,
.ndo_do_ioctl = dsa_slave_ioctl,
+ .ndo_swdev_get_id = dsa_slave_swdev_get_id,
};
#endif
#ifdef CONFIG_NET_DSA_TAG_TRAILER
@@ -327,6 +342,7 @@ static const struct net_device_ops trailer_netdev_ops = {
.ndo_set_rx_mode = dsa_slave_set_rx_mode,
.ndo_set_mac_address = dsa_slave_set_mac_address,
.ndo_do_ioctl = dsa_slave_ioctl,
+ .ndo_swdev_get_id = dsa_slave_swdev_get_id,
};
#endif
--
1.9.0
^ permalink raw reply related [flat|nested] 24+ messages in thread
* [patch net-next RFC v3 08/10] net: add netdev_for_each_all_lower_dev_rcu helper
[not found] ` <1397736876-11771-1-git-send-email-jiri-rHqAuBHg3fBzbRFIqnYvSA@public.gmane.org>
2014-04-17 12:14 ` [patch net-next RFC v3 01/10] openvswitch: split flow structures into ovs specific and generic ones Jiri Pirko
2014-04-17 12:14 ` [patch net-next RFC v3 06/10] net: introduce dummy switch Jiri Pirko
@ 2014-04-17 12:14 ` Jiri Pirko
2014-04-17 12:15 ` [patch net-next RFC v3 10/10] openvswitch: add support for datapath hardware offload Jiri Pirko
2014-04-17 12:17 ` [patch net-next RFC v3 0/5] iproute2: support switch chip infrastructure Jiri Pirko
4 siblings, 0 replies; 24+ messages in thread
From: Jiri Pirko @ 2014-04-17 12:14 UTC (permalink / raw)
To: netdev-u79uwXL29TY76Z2rM5mHXA
Cc: ryazanov.s.a-Re5JQEeQqe8AvxtiuMwx3w,
jasowang-H+wXaHxf7aLQT0dZR+AlfA,
john.r.fastabend-ral2JQCrhuEAvxtiuMwx3w,
Neil.Jerram-QnUH15yq9NYqDJ6do+/SaQ,
edumazet-hpIqsD4AKlfQT0dZR+AlfA, andy-QlMahl40kYEqcZcGjlUOXw,
dev-yBygre7rU0TnMu66kgdUjQ, nbd-p3rKhJxN3npAfugRpC6u6w,
f.fainelli-Re5JQEeQqe8AvxtiuMwx3w,
jeffrey.t.kirsher-ral2JQCrhuEAvxtiuMwx3w,
ogerlitz-VPRAkNaXOzVWk0Htik3J/w, ben-/+tVBieCtBitmTQ+vhA3Yw,
buytenh-OLH4Qvv75CYX/NnBR394Jw,
roopa-qUQiAmfTcIp+XZJcv9eMoEEOCMrvLtNR,
jhs-jkUAjuhPggJWk0Htik3J/w, linville-2XuSBdqkA4R54TAoqtyWWQ,
aviadr-VPRAkNaXOzVWk0Htik3J/w,
nicolas.dichtel-pdR9zngts4EAvxtiuMwx3w,
vyasevic-H+wXaHxf7aLQT0dZR+AlfA, nhorman-2XuSBdqkA4R54TAoqtyWWQ,
sfeldma-qUQiAmfTcIp+XZJcv9eMoEEOCMrvLtNR,
stephen-OTpzqLSitTUnbdJkjeBofR2eb7JE58TQ,
dborkman-H+wXaHxf7aLQT0dZR+AlfA, ebiederm-aS9lmoZGLiVWk0Htik3J/w,
davem-fT/PcQaiUtIeIZ0/mPfg9Q
Signed-off-by: Jiri Pirko <jiri-rHqAuBHg3fBzbRFIqnYvSA@public.gmane.org>
---
include/linux/netdevice.h | 18 +++++++++++++-----
net/core/dev.c | 26 ++++++++++++++------------
2 files changed, 27 insertions(+), 17 deletions(-)
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index 14bd8b3..bee9673 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -3076,15 +3076,23 @@ extern int weight_p;
extern int bpf_jit_enable;
bool netdev_has_upper_dev(struct net_device *dev, struct net_device *upper_dev);
-struct net_device *netdev_all_upper_get_next_dev_rcu(struct net_device *dev,
- struct list_head **iter);
+struct net_device *netdev_all_adj_get_next_dev_rcu(struct net_device *dev,
+ struct list_head **iter,
+ struct list_head *adj_list);
/* iterate through upper list, must be called under RCU read lock */
#define netdev_for_each_all_upper_dev_rcu(dev, updev, iter) \
- for (iter = &(dev)->all_adj_list.upper, \
- updev = netdev_all_upper_get_next_dev_rcu(dev, &(iter)); \
+ for (iter = NULL, \
+ updev = netdev_all_adj_get_next_dev_rcu(dev, &(iter), &(dev)->all_adj_list.upper); \
updev; \
- updev = netdev_all_upper_get_next_dev_rcu(dev, &(iter)))
+ updev = netdev_all_adj_get_next_dev_rcu(dev, &(iter), &(dev)->all_adj_list.upper))
+
+/* iterate through lower list, must be called under RCU read lock */
+#define netdev_for_each_all_lower_dev_rcu(dev, lodev, iter) \
+ for (iter = NULL, \
+ lodev = netdev_all_adj_get_next_dev_rcu(dev, &(iter), &(dev)->all_adj_list.lower); \
+ lodev; \
+ lodev = netdev_all_adj_get_next_dev_rcu(dev, &(iter), &(dev)->all_adj_list.lower))
void *netdev_lower_get_next_private(struct net_device *dev,
struct list_head **iter);
diff --git a/net/core/dev.c b/net/core/dev.c
index a0de81c..62bcec9 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -4542,30 +4542,32 @@ void *netdev_adjacent_get_private(struct list_head *adj_list)
EXPORT_SYMBOL(netdev_adjacent_get_private);
/**
- * netdev_all_upper_get_next_dev_rcu - Get the next dev from upper list
+ * netdev_all_adj_get_next_dev_rcu - Get the next dev from adjacent list
* @dev: device
* @iter: list_head ** of the current position
+ * @adj_list: adjacent list to go through
*
- * Gets the next device from the dev's upper list, starting from iter
+ * Gets the next device from the dev's adjacent list, starting from iter
* position. The caller must hold RCU read lock.
*/
-struct net_device *netdev_all_upper_get_next_dev_rcu(struct net_device *dev,
- struct list_head **iter)
+struct net_device *netdev_all_adj_get_next_dev_rcu(struct net_device *dev,
+ struct list_head **iter,
+ struct list_head *adj_list)
{
- struct netdev_adjacent *upper;
+ struct netdev_adjacent *adj;
WARN_ON_ONCE(!rcu_read_lock_held() && !lockdep_rtnl_is_held());
- upper = list_entry_rcu((*iter)->next, struct netdev_adjacent, list);
-
- if (&upper->list == &dev->all_adj_list.upper)
+ if (!*iter)
+ *iter = adj_list;
+ if ((*iter)->next == adj_list)
return NULL;
- *iter = &upper->list;
-
- return upper->dev;
+ adj = list_entry_rcu((*iter)->next, struct netdev_adjacent, list);
+ *iter = &adj->list;
+ return adj->dev;
}
-EXPORT_SYMBOL(netdev_all_upper_get_next_dev_rcu);
+EXPORT_SYMBOL(netdev_all_adj_get_next_dev_rcu);
/**
* netdev_lower_get_next_private - Get the next ->private from the
--
1.9.0
^ permalink raw reply related [flat|nested] 24+ messages in thread
* [patch net-next RFC v3 09/10] openvswitch: introduce vport_op get_netdev
2014-04-17 12:14 [patch net-next RFC v3 00/10] introduce infrastructure for support of switch chip datapath Jiri Pirko
` (5 preceding siblings ...)
[not found] ` <1397736876-11771-1-git-send-email-jiri-rHqAuBHg3fBzbRFIqnYvSA@public.gmane.org>
@ 2014-04-17 12:14 ` Jiri Pirko
6 siblings, 0 replies; 24+ messages in thread
From: Jiri Pirko @ 2014-04-17 12:14 UTC (permalink / raw)
To: netdev
Cc: davem, nhorman, andy, tgraf, dborkman, ogerlitz, jesse, pshelar,
azhou, ben, stephen, jeffrey.t.kirsher, vyasevic, xiyou.wangcong,
john.r.fastabend, edumazet, jhs, sfeldma, f.fainelli, roopa,
linville, dev, jasowang, ebiederm, nicolas.dichtel, ryazanov.s.a,
buytenh, aviadr, nbd, alexei.starovoitov, Neil.Jerram
This will allow to query easily if the vport has netdev. Also it allows
to unexpose netdev_vport_priv and struct netdev_vport.
Signed-off-by: Jiri Pirko <jiri@resnulli.us>
---
net/openvswitch/datapath.c | 2 +-
net/openvswitch/dp_notify.c | 7 ++---
net/openvswitch/vport-internal_dev.c | 53 ++++++++++++++++++++++++------------
net/openvswitch/vport-netdev.c | 16 +++++++++++
net/openvswitch/vport-netdev.h | 12 --------
net/openvswitch/vport.h | 2 ++
6 files changed, 57 insertions(+), 35 deletions(-)
diff --git a/net/openvswitch/datapath.c b/net/openvswitch/datapath.c
index fcbdb52..10ffb0a 100644
--- a/net/openvswitch/datapath.c
+++ b/net/openvswitch/datapath.c
@@ -148,7 +148,7 @@ static int get_dpifindex(struct datapath *dp)
local = ovs_vport_rcu(dp, OVSP_LOCAL);
if (local)
- ifindex = netdev_vport_priv(local)->dev->ifindex;
+ ifindex = local->ops->get_netdev(local)->ifindex;
else
ifindex = 0;
diff --git a/net/openvswitch/dp_notify.c b/net/openvswitch/dp_notify.c
index 2c631fe..d2cc24b 100644
--- a/net/openvswitch/dp_notify.c
+++ b/net/openvswitch/dp_notify.c
@@ -58,13 +58,12 @@ void ovs_dp_notify_wq(struct work_struct *work)
struct hlist_node *n;
hlist_for_each_entry_safe(vport, n, &dp->ports[i], dp_hash_node) {
- struct netdev_vport *netdev_vport;
+ struct net_device *dev;
if (vport->ops->type != OVS_VPORT_TYPE_NETDEV)
continue;
-
- netdev_vport = netdev_vport_priv(vport);
- if (!(netdev_vport->dev->priv_flags & IFF_OVS_DATAPATH))
+ dev = vport->ops->get_netdev(vport);
+ if (!(dev->priv_flags & IFF_OVS_DATAPATH))
dp_detach_port_notify(vport);
}
}
diff --git a/net/openvswitch/vport-internal_dev.c b/net/openvswitch/vport-internal_dev.c
index 729c687..86ba186 100644
--- a/net/openvswitch/vport-internal_dev.c
+++ b/net/openvswitch/vport-internal_dev.c
@@ -31,6 +31,16 @@
#include "vport-internal_dev.h"
#include "vport-netdev.h"
+struct internal_dev_vport {
+ struct rcu_head rcu;
+ struct net_device *dev;
+};
+
+static struct internal_dev_vport *internal_dev_vport_priv(const struct vport *vport)
+{
+ return vport_priv(vport);
+}
+
struct internal_dev {
struct vport *vport;
};
@@ -145,48 +155,49 @@ static void do_setup(struct net_device *netdev)
static struct vport *internal_dev_create(const struct vport_parms *parms)
{
struct vport *vport;
- struct netdev_vport *netdev_vport;
+ struct internal_dev_vport *int_vport;
struct internal_dev *internal_dev;
+ struct net_device *dev;
int err;
- vport = ovs_vport_alloc(sizeof(struct netdev_vport),
+ vport = ovs_vport_alloc(sizeof(struct internal_dev_vport),
&ovs_internal_vport_ops, parms);
if (IS_ERR(vport)) {
err = PTR_ERR(vport);
goto error;
}
- netdev_vport = netdev_vport_priv(vport);
+ int_vport = internal_dev_vport_priv(vport);
- netdev_vport->dev = alloc_netdev(sizeof(struct internal_dev),
- parms->name, do_setup);
- if (!netdev_vport->dev) {
+ dev = alloc_netdev(sizeof(struct internal_dev), parms->name, do_setup);
+ if (!dev) {
err = -ENOMEM;
goto error_free_vport;
}
+ int_vport->dev = dev;
- dev_net_set(netdev_vport->dev, ovs_dp_get_net(vport->dp));
- internal_dev = internal_dev_priv(netdev_vport->dev);
+ dev_net_set(dev, ovs_dp_get_net(vport->dp));
+ internal_dev = internal_dev_priv(dev);
internal_dev->vport = vport;
/* Restrict bridge port to current netns. */
if (vport->port_no == OVSP_LOCAL)
- netdev_vport->dev->features |= NETIF_F_NETNS_LOCAL;
+ dev->features |= NETIF_F_NETNS_LOCAL;
rtnl_lock();
- err = register_netdevice(netdev_vport->dev);
+ err = register_netdevice(dev);
if (err)
goto error_free_netdev;
- dev_set_promiscuity(netdev_vport->dev, 1);
+ dev_set_promiscuity(dev, 1);
rtnl_unlock();
- netif_start_queue(netdev_vport->dev);
+ netif_start_queue(dev);
return vport;
error_free_netdev:
rtnl_unlock();
- free_netdev(netdev_vport->dev);
+ free_netdev(dev);
error_free_vport:
ovs_vport_free(vport);
error:
@@ -195,21 +206,21 @@ error:
static void internal_dev_destroy(struct vport *vport)
{
- struct netdev_vport *netdev_vport = netdev_vport_priv(vport);
+ struct internal_dev_vport *int_vport = internal_dev_vport_priv(vport);
- netif_stop_queue(netdev_vport->dev);
+ netif_stop_queue(int_vport->dev);
rtnl_lock();
- dev_set_promiscuity(netdev_vport->dev, -1);
+ dev_set_promiscuity(int_vport->dev, -1);
/* unregister_netdevice() waits for an RCU grace period. */
- unregister_netdevice(netdev_vport->dev);
+ unregister_netdevice(int_vport->dev);
rtnl_unlock();
}
static int internal_dev_recv(struct vport *vport, struct sk_buff *skb)
{
- struct net_device *netdev = netdev_vport_priv(vport)->dev;
+ struct net_device *netdev = internal_dev_vport_priv(vport)->dev;
int len;
len = skb->len;
@@ -228,12 +239,18 @@ static int internal_dev_recv(struct vport *vport, struct sk_buff *skb)
return len;
}
+static struct net_device *internal_dev_get_netdev(struct vport *vport)
+{
+ return internal_dev_vport_priv(vport)->dev;
+}
+
const struct vport_ops ovs_internal_vport_ops = {
.type = OVS_VPORT_TYPE_INTERNAL,
.create = internal_dev_create,
.destroy = internal_dev_destroy,
.get_name = ovs_netdev_get_name,
.send = internal_dev_recv,
+ .get_netdev = internal_dev_get_netdev,
};
int ovs_is_internal_dev(const struct net_device *netdev)
diff --git a/net/openvswitch/vport-netdev.c b/net/openvswitch/vport-netdev.c
index d21f77d..aaf3d14 100644
--- a/net/openvswitch/vport-netdev.c
+++ b/net/openvswitch/vport-netdev.c
@@ -33,6 +33,16 @@
#include "vport-internal_dev.h"
#include "vport-netdev.h"
+struct netdev_vport {
+ struct rcu_head rcu;
+ struct net_device *dev;
+};
+
+static struct netdev_vport *netdev_vport_priv(const struct vport *vport)
+{
+ return vport_priv(vport);
+}
+
/* Must be called with rcu_read_lock. */
static void netdev_port_receive(struct vport *vport, struct sk_buff *skb)
{
@@ -224,10 +234,16 @@ struct vport *ovs_netdev_get_vport(struct net_device *dev)
return NULL;
}
+static struct net_device *netdev_get_netdev(struct vport *vport)
+{
+ return netdev_vport_priv(vport)->dev;
+}
+
const struct vport_ops ovs_netdev_vport_ops = {
.type = OVS_VPORT_TYPE_NETDEV,
.create = netdev_create,
.destroy = netdev_destroy,
.get_name = ovs_netdev_get_name,
.send = netdev_send,
+ .get_netdev = netdev_get_netdev,
};
diff --git a/net/openvswitch/vport-netdev.h b/net/openvswitch/vport-netdev.h
index 8df01c11..f03d41d 100644
--- a/net/openvswitch/vport-netdev.h
+++ b/net/openvswitch/vport-netdev.h
@@ -26,18 +26,6 @@
struct vport *ovs_netdev_get_vport(struct net_device *dev);
-struct netdev_vport {
- struct rcu_head rcu;
-
- struct net_device *dev;
-};
-
-static inline struct netdev_vport *
-netdev_vport_priv(const struct vport *vport)
-{
- return vport_priv(vport);
-}
-
const char *ovs_netdev_get_name(const struct vport *);
void ovs_netdev_detach_dev(struct vport *);
diff --git a/net/openvswitch/vport.h b/net/openvswitch/vport.h
index 0979304..d7d3af9 100644
--- a/net/openvswitch/vport.h
+++ b/net/openvswitch/vport.h
@@ -145,6 +145,8 @@ struct vport_ops {
const char *(*get_name)(const struct vport *);
int (*send)(struct vport *, struct sk_buff *);
+
+ struct net_device *(*get_netdev)(struct vport *);
};
enum vport_err_type {
--
1.9.0
^ permalink raw reply related [flat|nested] 24+ messages in thread
* [patch net-next RFC v3 10/10] openvswitch: add support for datapath hardware offload
[not found] ` <1397736876-11771-1-git-send-email-jiri-rHqAuBHg3fBzbRFIqnYvSA@public.gmane.org>
` (2 preceding siblings ...)
2014-04-17 12:14 ` [patch net-next RFC v3 08/10] net: add netdev_for_each_all_lower_dev_rcu helper Jiri Pirko
@ 2014-04-17 12:15 ` Jiri Pirko
[not found] ` <1397736938-11838-1-git-send-email-jiri-rHqAuBHg3fBzbRFIqnYvSA@public.gmane.org>
2014-04-17 12:17 ` [patch net-next RFC v3 0/5] iproute2: support switch chip infrastructure Jiri Pirko
4 siblings, 1 reply; 24+ messages in thread
From: Jiri Pirko @ 2014-04-17 12:15 UTC (permalink / raw)
To: netdev-u79uwXL29TY76Z2rM5mHXA
Cc: ryazanov.s.a-Re5JQEeQqe8AvxtiuMwx3w,
jasowang-H+wXaHxf7aLQT0dZR+AlfA,
john.r.fastabend-ral2JQCrhuEAvxtiuMwx3w,
Neil.Jerram-QnUH15yq9NYqDJ6do+/SaQ,
edumazet-hpIqsD4AKlfQT0dZR+AlfA, andy-QlMahl40kYEqcZcGjlUOXw,
dev-yBygre7rU0TnMu66kgdUjQ, nbd-p3rKhJxN3npAfugRpC6u6w,
f.fainelli-Re5JQEeQqe8AvxtiuMwx3w,
jeffrey.t.kirsher-ral2JQCrhuEAvxtiuMwx3w,
ogerlitz-VPRAkNaXOzVWk0Htik3J/w, ben-/+tVBieCtBitmTQ+vhA3Yw,
buytenh-OLH4Qvv75CYX/NnBR394Jw,
roopa-qUQiAmfTcIp+XZJcv9eMoEEOCMrvLtNR,
jhs-jkUAjuhPggJWk0Htik3J/w, linville-2XuSBdqkA4R54TAoqtyWWQ,
aviadr-VPRAkNaXOzVWk0Htik3J/w,
nicolas.dichtel-pdR9zngts4EAvxtiuMwx3w,
vyasevic-H+wXaHxf7aLQT0dZR+AlfA, nhorman-2XuSBdqkA4R54TAoqtyWWQ,
sfeldma-qUQiAmfTcIp+XZJcv9eMoEEOCMrvLtNR,
stephen-OTpzqLSitTUnbdJkjeBofR2eb7JE58TQ,
dborkman-H+wXaHxf7aLQT0dZR+AlfA, ebiederm-aS9lmoZGLiVWk0Htik3J/w,
davem-fT/PcQaiUtIeIZ0/mPfg9Q
Benefit from the possibility to work with flows in switch devices and
use the swdev api to offload flow datapath.
Signed-off-by: Jiri Pirko <jiri-rHqAuBHg3fBzbRFIqnYvSA@public.gmane.org>
---
include/linux/sw_flow.h | 16 +++-
net/openvswitch/Makefile | 3 +-
net/openvswitch/datapath.c | 16 +++-
net/openvswitch/hw_offload.c | 170 +++++++++++++++++++++++++++++++++++++++++++
net/openvswitch/hw_offload.h | 31 ++++++++
5 files changed, 231 insertions(+), 5 deletions(-)
create mode 100644 net/openvswitch/hw_offload.c
create mode 100644 net/openvswitch/hw_offload.h
diff --git a/include/linux/sw_flow.h b/include/linux/sw_flow.h
index 3bbd5aa..12a24f9 100644
--- a/include/linux/sw_flow.h
+++ b/include/linux/sw_flow.h
@@ -102,7 +102,21 @@ struct sw_flow {
struct sw_flow_mask *mask;
};
+enum sw_flow_action_type {
+ SW_FLOW_ACTION_TYPE_OUTPUT,
+ SW_FLOW_ACTION_TYPE_VLAN_PUSH,
+ SW_FLOW_ACTION_TYPE_VLAN_POP,
+};
+
struct sw_flow_action {
-}
+ enum sw_flow_action_type type;
+ union {
+ struct net_device *output_dev;
+ struct {
+ __be16 vlan_proto;
+ u16 vlan_tci;
+ } vlan;
+ };
+};
#endif /* _LINUX_SW_FLOW_H_ */
diff --git a/net/openvswitch/Makefile b/net/openvswitch/Makefile
index 3591cb5..5152437 100644
--- a/net/openvswitch/Makefile
+++ b/net/openvswitch/Makefile
@@ -13,7 +13,8 @@ openvswitch-y := \
flow_table.o \
vport.o \
vport-internal_dev.o \
- vport-netdev.o
+ vport-netdev.o \
+ hw_offload.o
ifneq ($(CONFIG_OPENVSWITCH_VXLAN),)
openvswitch-y += vport-vxlan.o
diff --git a/net/openvswitch/datapath.c b/net/openvswitch/datapath.c
index 10ffb0a..f1e0792 100644
--- a/net/openvswitch/datapath.c
+++ b/net/openvswitch/datapath.c
@@ -59,6 +59,7 @@
#include "flow_netlink.h"
#include "vport-internal_dev.h"
#include "vport-netdev.h"
+#include "hw_offload.h"
int ovs_net_id __read_mostly;
@@ -840,13 +841,15 @@ static int ovs_flow_cmd_new_or_set(struct sk_buff *skb, struct genl_info *info)
flow->flow.key = masked_key;
flow->flow.unmasked_key = key;
rcu_assign_pointer(flow->sf_acts, acts);
+ acts = NULL;
/* Put flow in bucket. */
error = ovs_flow_tbl_insert(&dp->table, flow, &mask);
- if (error) {
- acts = NULL;
+ if (error)
goto err_flow_free;
- }
+ error = ovs_hw_flow_insert(dp, flow, flow->sf_acts);
+ if (error)
+ goto err_flow_tbl_remove;
reply = ovs_flow_cmd_build_info(flow, dp, info, OVS_FLOW_CMD_NEW);
} else {
@@ -868,6 +871,10 @@ static int ovs_flow_cmd_new_or_set(struct sk_buff *skb, struct genl_info *info)
if (!ovs_flow_cmp_unmasked_key(flow, &match))
goto err_unlock_ovs;
+ error = ovs_hw_flow_actions_update(dp, flow, acts);
+ if (error)
+ goto err_unlock_ovs;
+
/* Update actions. */
old_acts = ovsl_dereference(flow->sf_acts);
rcu_assign_pointer(flow->sf_acts, acts);
@@ -888,6 +895,8 @@ static int ovs_flow_cmd_new_or_set(struct sk_buff *skb, struct genl_info *info)
0, PTR_ERR(reply));
return 0;
+err_flow_tbl_remove:
+ ovs_flow_tbl_remove(&dp->table, flow);
err_flow_free:
ovs_flow_free(flow, false);
err_unlock_ovs:
@@ -985,6 +994,7 @@ static int ovs_flow_cmd_del(struct sk_buff *skb, struct genl_info *info)
goto unlock;
}
+ ovs_hw_flow_remove(dp, flow);
ovs_flow_tbl_remove(&dp->table, flow);
err = ovs_flow_cmd_fill_info(flow, dp, reply, info->snd_portid,
diff --git a/net/openvswitch/hw_offload.c b/net/openvswitch/hw_offload.c
new file mode 100644
index 0000000..c4c64d0
--- /dev/null
+++ b/net/openvswitch/hw_offload.c
@@ -0,0 +1,170 @@
+/*
+ * Copyright (c) 2014 Jiri Pirko <jiri-rHqAuBHg3fBzbRFIqnYvSA@public.gmane.org>
+ *
+ * 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.
+ *
+ * This program 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, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA
+ */
+
+#include <linux/kernel.h>
+#include <linux/rcupdate.h>
+#include <linux/netdevice.h>
+#include <linux/sw_flow.h>
+#include <linux/switchdev.h>
+
+#include "datapath.h"
+#include "vport-netdev.h"
+
+static struct net_device *__dp_master(struct datapath *dp)
+{
+ struct vport *local;
+
+ local = ovs_vport_ovsl_rcu(dp, OVSP_LOCAL);
+ BUG_ON(!local);
+ return local->ops->get_netdev(local);
+}
+
+static int sw_flow_action_create(struct datapath *dp,
+ struct sw_flow_action **p_action,
+ size_t *p_action_count,
+ struct sw_flow_actions *acts)
+{
+ const struct nlattr *attr = acts->actions;
+ int len = acts->actions_len;
+ const struct nlattr *a;
+ int rem;
+ struct sw_flow_action *action, *cur;
+ size_t action_count = 0;
+ int err;
+
+ for (a = attr, rem = len; rem > 0; a = nla_next(a, &rem))
+ action_count++;
+
+ action = kzalloc(sizeof(*action) * action_count, GFP_KERNEL);
+ if (!action)
+ return -ENOMEM;
+
+ cur = action;
+ for (a = attr, rem = len; rem > 0; a = nla_next(a, &rem)) {
+ switch (nla_type(a)) {
+ case OVS_ACTION_ATTR_OUTPUT:
+ {
+ struct vport *vport;
+
+ vport = ovs_vport_ovsl_rcu(dp, nla_get_u32(a));
+ if (vport->ops->type != OVS_VPORT_TYPE_NETDEV) {
+ err = -EOPNOTSUPP;
+ goto errout;
+ }
+ cur->type = SW_FLOW_ACTION_TYPE_OUTPUT;
+ cur->output_dev = vport->ops->get_netdev(vport);
+ }
+ break;
+
+ case OVS_ACTION_ATTR_PUSH_VLAN:
+ {
+ const struct ovs_action_push_vlan *vlan;
+
+ vlan = nla_data(a);
+ cur->type = SW_FLOW_ACTION_TYPE_VLAN_PUSH;
+ cur->vlan.vlan_proto = vlan->vlan_tpid;
+ cur->vlan.vlan_tci = vlan->vlan_tci;
+ }
+ break;
+
+ case OVS_ACTION_ATTR_POP_VLAN:
+ cur->type = SW_FLOW_ACTION_TYPE_VLAN_POP;
+ break;
+
+ default:
+ err = -EOPNOTSUPP;
+ goto errout;
+ }
+ action++;
+ }
+ *p_action = action;
+ *p_action_count = action_count;
+ return 0;
+
+errout:
+ kfree(action);
+ return err;
+}
+
+int ovs_hw_flow_insert(struct datapath *dp, struct ovs_flow *flow,
+ struct sw_flow_actions *acts)
+{
+ struct list_head *iter;
+ struct net_device *dev;
+ struct sw_flow_action *action;
+ size_t action_count;
+ int err;
+
+ err = sw_flow_action_create(dp, &action, &action_count, acts);
+ if (err)
+ return err;
+
+ rcu_read_lock();
+ netdev_for_each_all_lower_dev_rcu(__dp_master(dp), dev, iter) {
+ err = swdev_flow_insert(dev, &flow->flow);
+ if (err && err != -EOPNOTSUPP)
+ break;
+ err = swdev_flow_action_set(dev, &flow->flow,
+ action, action_count);
+ if (err && err != -EOPNOTSUPP)
+ break;
+ }
+ rcu_read_unlock();
+
+ kfree(action);
+
+ return err;
+}
+
+void ovs_hw_flow_remove(struct datapath *dp, struct ovs_flow *flow)
+{
+ struct list_head *iter;
+ struct net_device *dev;
+
+ rcu_read_lock();
+ netdev_for_each_all_lower_dev_rcu(__dp_master(dp), dev, iter)
+ swdev_flow_remove(dev, &flow->flow);
+ rcu_read_unlock();
+}
+
+int ovs_hw_flow_actions_update(struct datapath *dp, struct ovs_flow *flow,
+ struct sw_flow_actions *acts)
+{
+ struct list_head *iter;
+ struct net_device *dev;
+ struct sw_flow_action *action;
+ size_t action_count;
+ int err;
+
+ err = sw_flow_action_create(dp, &action, &action_count, acts);
+ if (err)
+ return err;
+
+ rcu_read_lock();
+ netdev_for_each_all_lower_dev_rcu(__dp_master(dp), dev, iter) {
+ err = swdev_flow_action_set(dev, &flow->flow,
+ action, action_count);
+ if (err && err != -EOPNOTSUPP)
+ break;
+ }
+ rcu_read_unlock();
+
+ kfree(action);
+
+ return err;
+}
diff --git a/net/openvswitch/hw_offload.h b/net/openvswitch/hw_offload.h
new file mode 100644
index 0000000..7ecb60f
--- /dev/null
+++ b/net/openvswitch/hw_offload.h
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2014 Jiri Pirko <jiri-rHqAuBHg3fBzbRFIqnYvSA@public.gmane.org>
+ *
+ * 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.
+ *
+ * This program 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, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA
+ */
+
+#ifndef HW_OFFLOAD_H
+#define HW_OFFLOAD_H 1
+
+#include "datapath.h"
+#include "flow.h"
+
+int ovs_hw_flow_insert(struct datapath *dp, struct ovs_flow *flow,
+ struct sw_flow_actions *acts);
+void ovs_hw_flow_remove(struct datapath *dp, struct ovs_flow *flow);
+int ovs_hw_flow_actions_update(struct datapath *dp, struct ovs_flow *flow,
+ struct sw_flow_actions *acts);
+
+#endif
--
1.9.0
^ permalink raw reply related [flat|nested] 24+ messages in thread
* [patch net-next RFC v3 0/5] iproute2: support switch chip infrastructure
[not found] ` <1397736876-11771-1-git-send-email-jiri-rHqAuBHg3fBzbRFIqnYvSA@public.gmane.org>
` (3 preceding siblings ...)
2014-04-17 12:15 ` [patch net-next RFC v3 10/10] openvswitch: add support for datapath hardware offload Jiri Pirko
@ 2014-04-17 12:17 ` Jiri Pirko
[not found] ` <1397737053-11892-1-git-send-email-jiri-rHqAuBHg3fBzbRFIqnYvSA@public.gmane.org>
4 siblings, 1 reply; 24+ messages in thread
From: Jiri Pirko @ 2014-04-17 12:17 UTC (permalink / raw)
To: netdev-u79uwXL29TY76Z2rM5mHXA
Cc: ryazanov.s.a-Re5JQEeQqe8AvxtiuMwx3w,
jasowang-H+wXaHxf7aLQT0dZR+AlfA,
john.r.fastabend-ral2JQCrhuEAvxtiuMwx3w,
Neil.Jerram-QnUH15yq9NYqDJ6do+/SaQ,
edumazet-hpIqsD4AKlfQT0dZR+AlfA, andy-QlMahl40kYEqcZcGjlUOXw,
dev-yBygre7rU0TnMu66kgdUjQ, nbd-p3rKhJxN3npAfugRpC6u6w,
f.fainelli-Re5JQEeQqe8AvxtiuMwx3w,
jeffrey.t.kirsher-ral2JQCrhuEAvxtiuMwx3w,
ogerlitz-VPRAkNaXOzVWk0Htik3J/w, ben-/+tVBieCtBitmTQ+vhA3Yw,
buytenh-OLH4Qvv75CYX/NnBR394Jw,
roopa-qUQiAmfTcIp+XZJcv9eMoEEOCMrvLtNR,
jhs-jkUAjuhPggJWk0Htik3J/w, linville-2XuSBdqkA4R54TAoqtyWWQ,
aviadr-VPRAkNaXOzVWk0Htik3J/w,
nicolas.dichtel-pdR9zngts4EAvxtiuMwx3w,
vyasevic-H+wXaHxf7aLQT0dZR+AlfA, nhorman-2XuSBdqkA4R54TAoqtyWWQ,
sfeldma-qUQiAmfTcIp+XZJcv9eMoEEOCMrvLtNR,
stephen-OTpzqLSitTUnbdJkjeBofR2eb7JE58TQ,
dborkman-H+wXaHxf7aLQT0dZR+AlfA, ebiederm-aS9lmoZGLiVWk0Htik3J/w,
davem-fT/PcQaiUtIeIZ0/mPfg9Q
Jiri Pirko (5):
iproute2: arpd: use ll_addr_a2n and ll_addr_n2a
iproute2: utils: change hexstring_n2a and hexstring_a2n to do not work
with ":"
iproute2: ipa: show switch id
iproute2: add support for dummyswport
iproute2: ipa: show port id
include/linux/if_link.h | 11 ++++++++++
ip/Makefile | 3 ++-
ip/ipaddress.c | 16 ++++++++++++++
ip/iplink_dummyswport.c | 56 +++++++++++++++++++++++++++++++++++++++++++++++++
lib/utils.c | 46 ++++++++++++----------------------------
misc/arpd.c | 6 +++---
6 files changed, 101 insertions(+), 37 deletions(-)
create mode 100644 ip/iplink_dummyswport.c
--
1.9.0
^ permalink raw reply [flat|nested] 24+ messages in thread
* [patch iproute2 RFC v3 1/5] iproute2: arpd: use ll_addr_a2n and ll_addr_n2a
[not found] ` <1397737053-11892-1-git-send-email-jiri-rHqAuBHg3fBzbRFIqnYvSA@public.gmane.org>
@ 2014-04-17 12:17 ` Jiri Pirko
2014-04-17 12:17 ` [patch iproute2 RFC v3 2/5] iproute2: utils: change hexstring_n2a and hexstring_a2n to do not work with ":" Jiri Pirko
` (3 subsequent siblings)
4 siblings, 0 replies; 24+ messages in thread
From: Jiri Pirko @ 2014-04-17 12:17 UTC (permalink / raw)
To: netdev-u79uwXL29TY76Z2rM5mHXA
Cc: ryazanov.s.a-Re5JQEeQqe8AvxtiuMwx3w,
jasowang-H+wXaHxf7aLQT0dZR+AlfA,
john.r.fastabend-ral2JQCrhuEAvxtiuMwx3w,
Neil.Jerram-QnUH15yq9NYqDJ6do+/SaQ,
edumazet-hpIqsD4AKlfQT0dZR+AlfA, andy-QlMahl40kYEqcZcGjlUOXw,
dev-yBygre7rU0TnMu66kgdUjQ, nbd-p3rKhJxN3npAfugRpC6u6w,
f.fainelli-Re5JQEeQqe8AvxtiuMwx3w,
jeffrey.t.kirsher-ral2JQCrhuEAvxtiuMwx3w,
ogerlitz-VPRAkNaXOzVWk0Htik3J/w, ben-/+tVBieCtBitmTQ+vhA3Yw,
buytenh-OLH4Qvv75CYX/NnBR394Jw,
roopa-qUQiAmfTcIp+XZJcv9eMoEEOCMrvLtNR,
jhs-jkUAjuhPggJWk0Htik3J/w, linville-2XuSBdqkA4R54TAoqtyWWQ,
aviadr-VPRAkNaXOzVWk0Htik3J/w,
nicolas.dichtel-pdR9zngts4EAvxtiuMwx3w,
vyasevic-H+wXaHxf7aLQT0dZR+AlfA, nhorman-2XuSBdqkA4R54TAoqtyWWQ,
sfeldma-qUQiAmfTcIp+XZJcv9eMoEEOCMrvLtNR,
stephen-OTpzqLSitTUnbdJkjeBofR2eb7JE58TQ,
dborkman-H+wXaHxf7aLQT0dZR+AlfA, ebiederm-aS9lmoZGLiVWk0Htik3J/w,
davem-fT/PcQaiUtIeIZ0/mPfg9Q
Signed-off-by: Jiri Pirko <jiri-rHqAuBHg3fBzbRFIqnYvSA@public.gmane.org>
---
misc/arpd.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/misc/arpd.c b/misc/arpd.c
index bfe7de9..0839e3f 100644
--- a/misc/arpd.c
+++ b/misc/arpd.c
@@ -36,6 +36,7 @@
#include "libnetlink.h"
#include "utils.h"
+#include "rt_names.h"
int resolve_hosts;
@@ -721,8 +722,7 @@ int main(int argc, char **argv)
goto do_abort;
}
- dbdat.data = hexstring_a2n(macbuf, b1, 6);
- if (dbdat.data == NULL)
+ if (ll_addr_a2n((char *) b1, 6, macbuf) != 6)
goto do_abort;
dbdat.size = 6;
@@ -747,7 +747,7 @@ int main(int argc, char **argv)
printf("%-8d %-15s %s\n",
key->iface,
inet_ntoa(*(struct in_addr*)&key->addr),
- hexstring_n2a(dbdat.data, 6, b1, 18));
+ ll_addr_n2a(dbdat.data, 6, ARPHRD_ETHER, b1, 18));
} else {
printf("%-8d %-15s FAILED: %dsec ago\n",
key->iface,
--
1.9.0
^ permalink raw reply related [flat|nested] 24+ messages in thread
* [patch iproute2 RFC v3 2/5] iproute2: utils: change hexstring_n2a and hexstring_a2n to do not work with ":"
[not found] ` <1397737053-11892-1-git-send-email-jiri-rHqAuBHg3fBzbRFIqnYvSA@public.gmane.org>
2014-04-17 12:17 ` [patch iproute2 RFC v3 1/5] iproute2: arpd: use ll_addr_a2n and ll_addr_n2a Jiri Pirko
@ 2014-04-17 12:17 ` Jiri Pirko
2014-04-17 12:17 ` [patch iproute2 RFC v3 3/5] iproute2: ipa: show switch id Jiri Pirko
` (2 subsequent siblings)
4 siblings, 0 replies; 24+ messages in thread
From: Jiri Pirko @ 2014-04-17 12:17 UTC (permalink / raw)
To: netdev-u79uwXL29TY76Z2rM5mHXA
Cc: ryazanov.s.a-Re5JQEeQqe8AvxtiuMwx3w,
jasowang-H+wXaHxf7aLQT0dZR+AlfA,
john.r.fastabend-ral2JQCrhuEAvxtiuMwx3w,
Neil.Jerram-QnUH15yq9NYqDJ6do+/SaQ,
edumazet-hpIqsD4AKlfQT0dZR+AlfA, andy-QlMahl40kYEqcZcGjlUOXw,
dev-yBygre7rU0TnMu66kgdUjQ, nbd-p3rKhJxN3npAfugRpC6u6w,
f.fainelli-Re5JQEeQqe8AvxtiuMwx3w,
jeffrey.t.kirsher-ral2JQCrhuEAvxtiuMwx3w,
ogerlitz-VPRAkNaXOzVWk0Htik3J/w, ben-/+tVBieCtBitmTQ+vhA3Yw,
buytenh-OLH4Qvv75CYX/NnBR394Jw,
roopa-qUQiAmfTcIp+XZJcv9eMoEEOCMrvLtNR,
jhs-jkUAjuhPggJWk0Htik3J/w, linville-2XuSBdqkA4R54TAoqtyWWQ,
aviadr-VPRAkNaXOzVWk0Htik3J/w,
nicolas.dichtel-pdR9zngts4EAvxtiuMwx3w,
vyasevic-H+wXaHxf7aLQT0dZR+AlfA, nhorman-2XuSBdqkA4R54TAoqtyWWQ,
sfeldma-qUQiAmfTcIp+XZJcv9eMoEEOCMrvLtNR,
stephen-OTpzqLSitTUnbdJkjeBofR2eb7JE58TQ,
dborkman-H+wXaHxf7aLQT0dZR+AlfA, ebiederm-aS9lmoZGLiVWk0Htik3J/w,
davem-fT/PcQaiUtIeIZ0/mPfg9Q
Signed-off-by: Jiri Pirko <jiri-rHqAuBHg3fBzbRFIqnYvSA@public.gmane.org>
---
lib/utils.c | 46 +++++++++++++---------------------------------
1 file changed, 13 insertions(+), 33 deletions(-)
diff --git a/lib/utils.c b/lib/utils.c
index 4e9c719..e9e1040 100644
--- a/lib/utils.c
+++ b/lib/utils.c
@@ -743,10 +743,6 @@ char *hexstring_n2a(const __u8 *str, int len, char *buf, int blen)
sprintf(ptr, "%02x", str[i]);
ptr += 2;
blen -= 2;
- if (i != len-1 && blen > 1) {
- *ptr++ = ':';
- blen--;
- }
}
return buf;
}
@@ -754,38 +750,22 @@ char *hexstring_n2a(const __u8 *str, int len, char *buf, int blen)
__u8* hexstring_a2n(const char *str, __u8 *buf, int blen)
{
int cnt = 0;
+ char *endptr;
- for (;;) {
- unsigned acc;
- char ch;
-
- acc = 0;
-
- while ((ch = *str) != ':' && ch != 0) {
- if (ch >= '0' && ch <= '9')
- ch -= '0';
- else if (ch >= 'a' && ch <= 'f')
- ch -= 'a'-10;
- else if (ch >= 'A' && ch <= 'F')
- ch -= 'A'-10;
- else
- return NULL;
- acc = (acc<<4) + ch;
- str++;
- }
-
- if (acc > 255)
+ if (strlen(str) % 2)
+ return NULL;
+ while (cnt < blen && strlen(str) > 1) {
+ unsigned int tmp;
+ char tmpstr[3];
+
+ strncpy(tmpstr, str, 2);
+ tmpstr[2] = '\0';
+ tmp = strtoul(tmpstr, &endptr, 16);
+ if (errno != 0 || tmp > 0xFF || *endptr != '\0')
return NULL;
- if (cnt < blen) {
- buf[cnt] = acc;
- cnt++;
- }
- if (ch == 0)
- break;
- ++str;
+ buf[cnt++] = tmp;
+ str += 2;
}
- if (cnt < blen)
- memset(buf+cnt, 0, blen-cnt);
return buf;
}
--
1.9.0
^ permalink raw reply related [flat|nested] 24+ messages in thread
* [patch iproute2 RFC v3 3/5] iproute2: ipa: show switch id
[not found] ` <1397737053-11892-1-git-send-email-jiri-rHqAuBHg3fBzbRFIqnYvSA@public.gmane.org>
2014-04-17 12:17 ` [patch iproute2 RFC v3 1/5] iproute2: arpd: use ll_addr_a2n and ll_addr_n2a Jiri Pirko
2014-04-17 12:17 ` [patch iproute2 RFC v3 2/5] iproute2: utils: change hexstring_n2a and hexstring_a2n to do not work with ":" Jiri Pirko
@ 2014-04-17 12:17 ` Jiri Pirko
2014-04-17 12:17 ` [patch iproute2 RFC v3 4/5] iproute2: add support for dummyswport Jiri Pirko
2014-04-17 12:17 ` [patch iproute2 RFC v3 5/5] iproute2: ipa: show port id Jiri Pirko
4 siblings, 0 replies; 24+ messages in thread
From: Jiri Pirko @ 2014-04-17 12:17 UTC (permalink / raw)
To: netdev-u79uwXL29TY76Z2rM5mHXA
Cc: ryazanov.s.a-Re5JQEeQqe8AvxtiuMwx3w,
jasowang-H+wXaHxf7aLQT0dZR+AlfA,
john.r.fastabend-ral2JQCrhuEAvxtiuMwx3w,
Neil.Jerram-QnUH15yq9NYqDJ6do+/SaQ,
edumazet-hpIqsD4AKlfQT0dZR+AlfA, andy-QlMahl40kYEqcZcGjlUOXw,
dev-yBygre7rU0TnMu66kgdUjQ, nbd-p3rKhJxN3npAfugRpC6u6w,
f.fainelli-Re5JQEeQqe8AvxtiuMwx3w,
jeffrey.t.kirsher-ral2JQCrhuEAvxtiuMwx3w,
ogerlitz-VPRAkNaXOzVWk0Htik3J/w, ben-/+tVBieCtBitmTQ+vhA3Yw,
buytenh-OLH4Qvv75CYX/NnBR394Jw,
roopa-qUQiAmfTcIp+XZJcv9eMoEEOCMrvLtNR,
jhs-jkUAjuhPggJWk0Htik3J/w, linville-2XuSBdqkA4R54TAoqtyWWQ,
aviadr-VPRAkNaXOzVWk0Htik3J/w,
nicolas.dichtel-pdR9zngts4EAvxtiuMwx3w,
vyasevic-H+wXaHxf7aLQT0dZR+AlfA, nhorman-2XuSBdqkA4R54TAoqtyWWQ,
sfeldma-qUQiAmfTcIp+XZJcv9eMoEEOCMrvLtNR,
stephen-OTpzqLSitTUnbdJkjeBofR2eb7JE58TQ,
dborkman-H+wXaHxf7aLQT0dZR+AlfA, ebiederm-aS9lmoZGLiVWk0Htik3J/w,
davem-fT/PcQaiUtIeIZ0/mPfg9Q
Signed-off-by: Jiri Pirko <jiri-rHqAuBHg3fBzbRFIqnYvSA@public.gmane.org>
---
include/linux/if_link.h | 2 ++
ip/ipaddress.c | 8 ++++++++
2 files changed, 10 insertions(+)
diff --git a/include/linux/if_link.h b/include/linux/if_link.h
index f08505c..2932453 100644
--- a/include/linux/if_link.h
+++ b/include/linux/if_link.h
@@ -144,6 +144,8 @@ enum {
IFLA_NUM_RX_QUEUES,
IFLA_CARRIER,
IFLA_PHYS_PORT_ID,
+ IFLA_CARRIER_CHANGES,
+ IFLA_PHYS_SWITCH_ID,
__IFLA_MAX
};
diff --git a/ip/ipaddress.c b/ip/ipaddress.c
index 14d1720..43f7296 100644
--- a/ip/ipaddress.c
+++ b/ip/ipaddress.c
@@ -470,6 +470,14 @@ int print_linkinfo(const struct sockaddr_nl *who,
fprintf(fp, "master %s ", ll_idx_n2a(*(int*)RTA_DATA(tb[IFLA_MASTER]), b1));
}
+ if (tb[IFLA_PHYS_SWITCH_ID]) {
+ SPRINT_BUF(b1);
+ fprintf(fp, "swid %s ",
+ hexstring_n2a(RTA_DATA(tb[IFLA_PHYS_SWITCH_ID]),
+ RTA_PAYLOAD(tb[IFLA_PHYS_SWITCH_ID]),
+ b1, sizeof(b1)));
+ }
+
if (tb[IFLA_OPERSTATE])
print_operstate(fp, rta_getattr_u8(tb[IFLA_OPERSTATE]));
--
1.9.0
^ permalink raw reply related [flat|nested] 24+ messages in thread
* [patch iproute2 RFC v3 4/5] iproute2: add support for dummyswport
[not found] ` <1397737053-11892-1-git-send-email-jiri-rHqAuBHg3fBzbRFIqnYvSA@public.gmane.org>
` (2 preceding siblings ...)
2014-04-17 12:17 ` [patch iproute2 RFC v3 3/5] iproute2: ipa: show switch id Jiri Pirko
@ 2014-04-17 12:17 ` Jiri Pirko
2014-04-17 13:19 ` Nicolas Dichtel
2014-04-17 12:17 ` [patch iproute2 RFC v3 5/5] iproute2: ipa: show port id Jiri Pirko
4 siblings, 1 reply; 24+ messages in thread
From: Jiri Pirko @ 2014-04-17 12:17 UTC (permalink / raw)
To: netdev-u79uwXL29TY76Z2rM5mHXA
Cc: ryazanov.s.a-Re5JQEeQqe8AvxtiuMwx3w,
jasowang-H+wXaHxf7aLQT0dZR+AlfA,
john.r.fastabend-ral2JQCrhuEAvxtiuMwx3w,
Neil.Jerram-QnUH15yq9NYqDJ6do+/SaQ,
edumazet-hpIqsD4AKlfQT0dZR+AlfA, andy-QlMahl40kYEqcZcGjlUOXw,
dev-yBygre7rU0TnMu66kgdUjQ, nbd-p3rKhJxN3npAfugRpC6u6w,
f.fainelli-Re5JQEeQqe8AvxtiuMwx3w,
jeffrey.t.kirsher-ral2JQCrhuEAvxtiuMwx3w,
ogerlitz-VPRAkNaXOzVWk0Htik3J/w, ben-/+tVBieCtBitmTQ+vhA3Yw,
buytenh-OLH4Qvv75CYX/NnBR394Jw,
roopa-qUQiAmfTcIp+XZJcv9eMoEEOCMrvLtNR,
jhs-jkUAjuhPggJWk0Htik3J/w, linville-2XuSBdqkA4R54TAoqtyWWQ,
aviadr-VPRAkNaXOzVWk0Htik3J/w,
nicolas.dichtel-pdR9zngts4EAvxtiuMwx3w,
vyasevic-H+wXaHxf7aLQT0dZR+AlfA, nhorman-2XuSBdqkA4R54TAoqtyWWQ,
sfeldma-qUQiAmfTcIp+XZJcv9eMoEEOCMrvLtNR,
stephen-OTpzqLSitTUnbdJkjeBofR2eb7JE58TQ,
dborkman-H+wXaHxf7aLQT0dZR+AlfA, ebiederm-aS9lmoZGLiVWk0Htik3J/w,
davem-fT/PcQaiUtIeIZ0/mPfg9Q
Signed-off-by: Jiri Pirko <jiri-rHqAuBHg3fBzbRFIqnYvSA@public.gmane.org>
---
include/linux/if_link.h | 9 ++++++++
ip/Makefile | 3 ++-
ip/iplink_dummyswport.c | 56 +++++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 67 insertions(+), 1 deletion(-)
create mode 100644 ip/iplink_dummyswport.c
diff --git a/include/linux/if_link.h b/include/linux/if_link.h
index 2932453..f2fdb85 100644
--- a/include/linux/if_link.h
+++ b/include/linux/if_link.h
@@ -544,4 +544,13 @@ enum {
#define IFLA_HSR_MAX (__IFLA_HSR_MAX - 1)
+/* DUMMYSWPORT section */
+enum {
+ IFLA_DUMMYSWPORT_UNSPEC,
+ IFLA_DYMMYSWPORT_PHYS_SWITCH_ID,
+ __IFLA_DUMMYSWPORT_MAX,
+};
+
+#define IFLA_DUMMYSWPORT_MAX (__IFLA_DUMMYSWPORT_MAX - 1)
+
#endif /* _LINUX_IF_LINK_H */
diff --git a/ip/Makefile b/ip/Makefile
index 713adf5..35546e5 100644
--- a/ip/Makefile
+++ b/ip/Makefile
@@ -5,7 +5,8 @@ IPOBJ=ip.o ipaddress.o ipaddrlabel.o iproute.o iprule.o ipnetns.o \
iplink_vlan.o link_veth.o link_gre.o iplink_can.o \
iplink_macvlan.o iplink_macvtap.o ipl2tp.o link_vti.o \
iplink_vxlan.o tcp_metrics.o iplink_ipoib.o ipnetconf.o link_ip6tnl.o \
- link_iptnl.o link_gre6.o iplink_bond.o iplink_bond_slave.o iplink_hsr.o
+ link_iptnl.o link_gre6.o iplink_bond.o iplink_bond_slave.o iplink_hsr.o \
+ iplink_dummyswport.o \
RTMONOBJ=rtmon.o
diff --git a/ip/iplink_dummyswport.c b/ip/iplink_dummyswport.c
new file mode 100644
index 0000000..64f1a02
--- /dev/null
+++ b/ip/iplink_dummyswport.c
@@ -0,0 +1,56 @@
+/*
+ * iplink_dummyswport.c dummy switch port device support
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ *
+ * Authors: Jiri Pirko <jiri-rHqAuBHg3fBzbRFIqnYvSA@public.gmane.org>
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/socket.h>
+#include <sys/types.h>
+#include <asm/types.h>
+#include <linux/if_link.h>
+#include <net/if.h>
+
+#include "rt_names.h"
+#include "utils.h"
+#include "ip_common.h"
+
+static void explain(void)
+{
+ fprintf(stderr, "Usage: ... dummyswport swid SWITCH_ID\n");
+}
+
+static int dummyswport_parse_opt(struct link_util *lu, int argc, char **argv,
+ struct nlmsghdr *n)
+{
+ while (argc > 0) {
+ if (matches(*argv, "swid") == 0) {
+ __u8 buf[32];
+
+ NEXT_ARG();
+ if (!hexstring_a2n(*argv, buf, sizeof(buf)))
+ invarg("invalid \"swid\" value\n", *argv);
+ addattr_l(n, 1024, IFLA_DYMMYSWPORT_PHYS_SWITCH_ID,
+ buf, strlen(*argv) / 2);
+ } else {
+ fprintf(stderr, "dummyswport: unknown option \"%s\"?\n", *argv);
+ explain();
+ return -1;
+ }
+ argc--, argv++;
+ }
+ return 0;
+}
+
+struct link_util dummyswport_link_util = {
+ .id = "dummyswport",
+ .maxattr = IFLA_DUMMYSWPORT_MAX,
+ .parse_opt = dummyswport_parse_opt,
+};
--
1.9.0
^ permalink raw reply related [flat|nested] 24+ messages in thread
* [patch iproute2 RFC v3 5/5] iproute2: ipa: show port id
[not found] ` <1397737053-11892-1-git-send-email-jiri-rHqAuBHg3fBzbRFIqnYvSA@public.gmane.org>
` (3 preceding siblings ...)
2014-04-17 12:17 ` [patch iproute2 RFC v3 4/5] iproute2: add support for dummyswport Jiri Pirko
@ 2014-04-17 12:17 ` Jiri Pirko
4 siblings, 0 replies; 24+ messages in thread
From: Jiri Pirko @ 2014-04-17 12:17 UTC (permalink / raw)
To: netdev-u79uwXL29TY76Z2rM5mHXA
Cc: ryazanov.s.a-Re5JQEeQqe8AvxtiuMwx3w,
jasowang-H+wXaHxf7aLQT0dZR+AlfA,
john.r.fastabend-ral2JQCrhuEAvxtiuMwx3w,
Neil.Jerram-QnUH15yq9NYqDJ6do+/SaQ,
edumazet-hpIqsD4AKlfQT0dZR+AlfA, andy-QlMahl40kYEqcZcGjlUOXw,
dev-yBygre7rU0TnMu66kgdUjQ, nbd-p3rKhJxN3npAfugRpC6u6w,
f.fainelli-Re5JQEeQqe8AvxtiuMwx3w,
jeffrey.t.kirsher-ral2JQCrhuEAvxtiuMwx3w,
ogerlitz-VPRAkNaXOzVWk0Htik3J/w, ben-/+tVBieCtBitmTQ+vhA3Yw,
buytenh-OLH4Qvv75CYX/NnBR394Jw,
roopa-qUQiAmfTcIp+XZJcv9eMoEEOCMrvLtNR,
jhs-jkUAjuhPggJWk0Htik3J/w, linville-2XuSBdqkA4R54TAoqtyWWQ,
aviadr-VPRAkNaXOzVWk0Htik3J/w,
nicolas.dichtel-pdR9zngts4EAvxtiuMwx3w,
vyasevic-H+wXaHxf7aLQT0dZR+AlfA, nhorman-2XuSBdqkA4R54TAoqtyWWQ,
sfeldma-qUQiAmfTcIp+XZJcv9eMoEEOCMrvLtNR,
stephen-OTpzqLSitTUnbdJkjeBofR2eb7JE58TQ,
dborkman-H+wXaHxf7aLQT0dZR+AlfA, ebiederm-aS9lmoZGLiVWk0Htik3J/w,
davem-fT/PcQaiUtIeIZ0/mPfg9Q
Signed-off-by: Jiri Pirko <jiri-rHqAuBHg3fBzbRFIqnYvSA@public.gmane.org>
---
ip/ipaddress.c | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/ip/ipaddress.c b/ip/ipaddress.c
index 43f7296..f794d02 100644
--- a/ip/ipaddress.c
+++ b/ip/ipaddress.c
@@ -470,6 +470,14 @@ int print_linkinfo(const struct sockaddr_nl *who,
fprintf(fp, "master %s ", ll_idx_n2a(*(int*)RTA_DATA(tb[IFLA_MASTER]), b1));
}
+ if (tb[IFLA_PHYS_PORT_ID]) {
+ SPRINT_BUF(b1);
+ fprintf(fp, "portid %s ",
+ hexstring_n2a(RTA_DATA(tb[IFLA_PHYS_PORT_ID]),
+ RTA_PAYLOAD(tb[IFLA_PHYS_PORT_ID]),
+ b1, sizeof(b1)));
+ }
+
if (tb[IFLA_PHYS_SWITCH_ID]) {
SPRINT_BUF(b1);
fprintf(fp, "swid %s ",
--
1.9.0
^ permalink raw reply related [flat|nested] 24+ messages in thread
* Re: [patch net-next RFC v3 04/10] rtnl: expose physical switch id for particular device
2014-04-17 12:14 ` [patch net-next RFC v3 04/10] rtnl: expose physical switch id for particular device Jiri Pirko
@ 2014-04-17 12:40 ` Yegor Yefremov
0 siblings, 0 replies; 24+ messages in thread
From: Yegor Yefremov @ 2014-04-17 12:40 UTC (permalink / raw)
To: Jiri Pirko
Cc: netdev, David Miller, nhorman, andy, tgraf, dborkman, ogerlitz,
jesse, pshelar, azhou, Ben Hutchings, stephen, jeffrey.t.kirsher,
vyasevic, xiyou.wangcong, john.r.fastabend, edumazet, jhs,
sfeldma, Florian Fainelli, roopa, linville, dev, jasowang,
ebiederm, nicolas.dichtel, ryazanov.s.a, buytenh, aviadr,
Felix Fietkau, alexei.starovoitov, Neil.Jerram
On Thu, Apr 17, 2014 at 2:14 PM, Jiri Pirko <jiri@resnulli.us> wrote:
> The the netdevice represents a port in a switch, it will expose
remove one 'the'
> IFLA_PHYS_SWITCH_ID value via rtnl. Two netdevices with a same value
s/a same/the same
> belong to one physical switch.
>
> Signed-off-by: Jiri Pirko <jiri@resnulli.us>
Reviewed-by: Yegor Yefremov <yegorslists@googlemail.com>
> ---
> include/uapi/linux/if_link.h | 1 +
> net/core/rtnetlink.c | 26 +++++++++++++++++++++++++-
> 2 files changed, 26 insertions(+), 1 deletion(-)
>
> diff --git a/include/uapi/linux/if_link.h b/include/uapi/linux/if_link.h
> index 9a7f7ac..c11f492 100644
> --- a/include/uapi/linux/if_link.h
> +++ b/include/uapi/linux/if_link.h
> @@ -145,6 +145,7 @@ enum {
> IFLA_CARRIER,
> IFLA_PHYS_PORT_ID,
> IFLA_CARRIER_CHANGES,
> + IFLA_PHYS_SWITCH_ID,
> __IFLA_MAX
> };
>
> diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c
> index 231e043..7170e24 100644
> --- a/net/core/rtnetlink.c
> +++ b/net/core/rtnetlink.c
> @@ -43,6 +43,7 @@
>
> #include <linux/inet.h>
> #include <linux/netdevice.h>
> +#include <linux/switchdev.h>
> #include <net/ip.h>
> #include <net/protocol.h>
> #include <net/arp.h>
> @@ -829,7 +830,8 @@ static noinline size_t if_nlmsg_size(const struct net_device *dev,
> + rtnl_port_size(dev) /* IFLA_VF_PORTS + IFLA_PORT_SELF */
> + rtnl_link_get_size(dev) /* IFLA_LINKINFO */
> + rtnl_link_get_af_size(dev) /* IFLA_AF_SPEC */
> - + nla_total_size(MAX_PHYS_ITEM_ID_LEN); /* IFLA_PHYS_PORT_ID */
> + + nla_total_size(MAX_PHYS_ITEM_ID_LEN) /* IFLA_PHYS_PORT_ID */
> + + nla_total_size(MAX_PHYS_ITEM_ID_LEN); /* IFLA_PHYS_SWITCH_ID */
> }
>
> static int rtnl_vf_ports_fill(struct sk_buff *skb, struct net_device *dev)
> @@ -926,6 +928,24 @@ static int rtnl_phys_port_id_fill(struct sk_buff *skb, struct net_device *dev)
> return 0;
> }
>
> +static int rtnl_phys_switch_id_fill(struct sk_buff *skb, struct net_device *dev)
> +{
> + int err;
> + struct netdev_phys_item_id psid;
> +
> + err = swdev_get_id(dev, &psid);
> + if (err) {
> + if (err == -EOPNOTSUPP)
> + return 0;
> + return err;
> + }
> +
> + if (nla_put(skb, IFLA_PHYS_SWITCH_ID, psid.id_len, psid.id))
> + return -EMSGSIZE;
> +
> + return 0;
> +}
> +
> static int rtnl_fill_ifinfo(struct sk_buff *skb, struct net_device *dev,
> int type, u32 pid, u32 seq, u32 change,
> unsigned int flags, u32 ext_filter_mask)
> @@ -998,6 +1018,9 @@ static int rtnl_fill_ifinfo(struct sk_buff *skb, struct net_device *dev,
> if (rtnl_phys_port_id_fill(skb, dev))
> goto nla_put_failure;
>
> + if (rtnl_phys_switch_id_fill(skb, dev))
> + goto nla_put_failure;
> +
> attr = nla_reserve(skb, IFLA_STATS,
> sizeof(struct rtnl_link_stats));
> if (attr == NULL)
> @@ -1151,6 +1174,7 @@ static const struct nla_policy ifla_policy[IFLA_MAX+1] = {
> [IFLA_NUM_RX_QUEUES] = { .type = NLA_U32 },
> [IFLA_PHYS_PORT_ID] = { .type = NLA_BINARY, .len = MAX_PHYS_ITEM_ID_LEN },
> [IFLA_CARRIER_CHANGES] = { .type = NLA_U32 }, /* ignored */
> + [IFLA_PHYS_SWITCH_ID] = { .type = NLA_BINARY, .len = MAX_PHYS_ITEM_ID_LEN },
> };
>
> static const struct nla_policy ifla_info_policy[IFLA_INFO_MAX+1] = {
> --
> 1.9.0
>
> --
> To unsubscribe from this list: send the line "unsubscribe netdev" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [patch iproute2 RFC v3 4/5] iproute2: add support for dummyswport
2014-04-17 12:17 ` [patch iproute2 RFC v3 4/5] iproute2: add support for dummyswport Jiri Pirko
@ 2014-04-17 13:19 ` Nicolas Dichtel
0 siblings, 0 replies; 24+ messages in thread
From: Nicolas Dichtel @ 2014-04-17 13:19 UTC (permalink / raw)
To: Jiri Pirko, netdev
Cc: davem, nhorman, andy, tgraf, dborkman, ogerlitz, jesse, pshelar,
azhou, ben, stephen, jeffrey.t.kirsher, vyasevic, xiyou.wangcong,
john.r.fastabend, edumazet, jhs, sfeldma, f.fainelli, roopa,
linville, dev, jasowang, ebiederm, ryazanov.s.a, buytenh, aviadr,
nbd, alexei.starovoitov, Neil.Jerram
Le 17/04/2014 14:17, Jiri Pirko a écrit :
> Signed-off-by: Jiri Pirko <jiri@resnulli.us>
> ---
> include/linux/if_link.h | 9 ++++++++
> ip/Makefile | 3 ++-
> ip/iplink_dummyswport.c | 56 +++++++++++++++++++++++++++++++++++++++++++++++++
> 3 files changed, 67 insertions(+), 1 deletion(-)
> create mode 100644 ip/iplink_dummyswport.c
Don't forget to update iplink_usage() in ip/iplink.c, with the new type.
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [patch net-next RFC v3 02/10] net: rename netdev_phys_port_id to more generic name
[not found] ` <1397736876-11771-3-git-send-email-jiri-rHqAuBHg3fBzbRFIqnYvSA@public.gmane.org>
@ 2014-04-17 15:01 ` Stephen Hemminger
[not found] ` <20140417080110.73485409-We1ePj4FEcvRI77zikRAJc56i+j3xesD0e7PPNI6Mm0@public.gmane.org>
0 siblings, 1 reply; 24+ messages in thread
From: Stephen Hemminger @ 2014-04-17 15:01 UTC (permalink / raw)
To: Jiri Pirko
Cc: ryazanov.s.a-Re5JQEeQqe8AvxtiuMwx3w,
jasowang-H+wXaHxf7aLQT0dZR+AlfA,
john.r.fastabend-ral2JQCrhuEAvxtiuMwx3w,
Neil.Jerram-QnUH15yq9NYqDJ6do+/SaQ,
edumazet-hpIqsD4AKlfQT0dZR+AlfA, andy-QlMahl40kYEqcZcGjlUOXw,
dev-yBygre7rU0TnMu66kgdUjQ, nbd-p3rKhJxN3npAfugRpC6u6w,
f.fainelli-Re5JQEeQqe8AvxtiuMwx3w,
jeffrey.t.kirsher-ral2JQCrhuEAvxtiuMwx3w,
ogerlitz-VPRAkNaXOzVWk0Htik3J/w, ben-/+tVBieCtBitmTQ+vhA3Yw,
buytenh-OLH4Qvv75CYX/NnBR394Jw,
roopa-qUQiAmfTcIp+XZJcv9eMoEEOCMrvLtNR,
jhs-jkUAjuhPggJWk0Htik3J/w, linville-2XuSBdqkA4R54TAoqtyWWQ,
aviadr-VPRAkNaXOzVWk0Htik3J/w,
nicolas.dichtel-pdR9zngts4EAvxtiuMwx3w,
vyasevic-H+wXaHxf7aLQT0dZR+AlfA, nhorman-2XuSBdqkA4R54TAoqtyWWQ,
sfeldma-qUQiAmfTcIp+XZJcv9eMoEEOCMrvLtNR,
netdev-u79uwXL29TY76Z2rM5mHXA, dborkman-H+wXaHxf7aLQT0dZR+AlfA,
ebiederm-aS9lmoZGLiVWk0Htik3J/w, davem-fT/PcQaiUtIeIZ0/mPfg9Q
On Thu, 17 Apr 2014 14:14:29 +0200
Jiri Pirko <jiri-rHqAuBHg3fBzbRFIqnYvSA@public.gmane.org> wrote:
> So this can be reused for identification of other "items" as well.
>
> Signed-off-by: Jiri Pirko <jiri-rHqAuBHg3fBzbRFIqnYvSA@public.gmane.org>
> ---
> drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c | 2 +-
> drivers/net/ethernet/mellanox/mlx4/en_netdev.c | 2 +-
> drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c | 2 +-
> include/linux/netdevice.h | 16 ++++++++--------
> net/core/dev.c | 2 +-
> net/core/net-sysfs.c | 2 +-
> net/core/rtnetlink.c | 6 +++---
> 7 files changed, 16 insertions(+), 16 deletions(-)
>
> diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
> index a78edac..a4b25b1 100644
> --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
> +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
> @@ -12360,7 +12360,7 @@ static int bnx2x_validate_addr(struct net_device *dev)
> }
>
> static int bnx2x_get_phys_port_id(struct net_device *netdev,
> - struct netdev_phys_port_id *ppid)
> + struct netdev_phys_item_id *ppid)
> {
> struct bnx2x *bp = netdev_priv(netdev);
>
> diff --git a/drivers/net/ethernet/mellanox/mlx4/en_netdev.c b/drivers/net/ethernet/mellanox/mlx4/en_netdev.c
> index f085c2d..e784bb4 100644
> --- a/drivers/net/ethernet/mellanox/mlx4/en_netdev.c
> +++ b/drivers/net/ethernet/mellanox/mlx4/en_netdev.c
> @@ -2251,7 +2251,7 @@ static int mlx4_en_set_vf_link_state(struct net_device *dev, int vf, int link_st
>
> #define PORT_ID_BYTE_LEN 8
> static int mlx4_en_get_phys_port_id(struct net_device *dev,
> - struct netdev_phys_port_id *ppid)
> + struct netdev_phys_item_id *ppid)
> {
> struct mlx4_en_priv *priv = netdev_priv(dev);
> struct mlx4_dev *mdev = priv->mdev->dev;
> diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c
> index 309d056..55af16a 100644
> --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c
> +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c
> @@ -450,7 +450,7 @@ static void qlcnic_82xx_cancel_idc_work(struct qlcnic_adapter *adapter)
> }
>
> static int qlcnic_get_phys_port_id(struct net_device *netdev,
> - struct netdev_phys_port_id *ppid)
> + struct netdev_phys_item_id *ppid)
> {
> struct qlcnic_adapter *adapter = netdev_priv(netdev);
> struct qlcnic_hardware_context *ahw = adapter->ahw;
> diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
> index 775cc95..8cf4f5e 100644
> --- a/include/linux/netdevice.h
> +++ b/include/linux/netdevice.h
> @@ -735,13 +735,13 @@ struct netdev_fcoe_hbainfo {
> };
> #endif
>
> -#define MAX_PHYS_PORT_ID_LEN 32
> +#define MAX_PHYS_ITEM_ID_LEN 32
>
Why the rename?
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [patch net-next RFC v3 02/10] net: rename netdev_phys_port_id to more generic name
[not found] ` <20140417080110.73485409-We1ePj4FEcvRI77zikRAJc56i+j3xesD0e7PPNI6Mm0@public.gmane.org>
@ 2014-04-17 15:05 ` Jiri Pirko
0 siblings, 0 replies; 24+ messages in thread
From: Jiri Pirko @ 2014-04-17 15:05 UTC (permalink / raw)
To: Stephen Hemminger
Cc: ryazanov.s.a-Re5JQEeQqe8AvxtiuMwx3w,
jasowang-H+wXaHxf7aLQT0dZR+AlfA,
john.r.fastabend-ral2JQCrhuEAvxtiuMwx3w,
Neil.Jerram-QnUH15yq9NYqDJ6do+/SaQ,
edumazet-hpIqsD4AKlfQT0dZR+AlfA, andy-QlMahl40kYEqcZcGjlUOXw,
dev-yBygre7rU0TnMu66kgdUjQ, nbd-p3rKhJxN3npAfugRpC6u6w,
f.fainelli-Re5JQEeQqe8AvxtiuMwx3w,
jeffrey.t.kirsher-ral2JQCrhuEAvxtiuMwx3w,
ogerlitz-VPRAkNaXOzVWk0Htik3J/w, ben-/+tVBieCtBitmTQ+vhA3Yw,
buytenh-OLH4Qvv75CYX/NnBR394Jw,
roopa-qUQiAmfTcIp+XZJcv9eMoEEOCMrvLtNR,
jhs-jkUAjuhPggJWk0Htik3J/w, linville-2XuSBdqkA4R54TAoqtyWWQ,
aviadr-VPRAkNaXOzVWk0Htik3J/w,
nicolas.dichtel-pdR9zngts4EAvxtiuMwx3w,
vyasevic-H+wXaHxf7aLQT0dZR+AlfA, nhorman-2XuSBdqkA4R54TAoqtyWWQ,
sfeldma-qUQiAmfTcIp+XZJcv9eMoEEOCMrvLtNR,
netdev-u79uwXL29TY76Z2rM5mHXA, dborkman-H+wXaHxf7aLQT0dZR+AlfA,
ebiederm-aS9lmoZGLiVWk0Htik3J/w, davem-fT/PcQaiUtIeIZ0/mPfg9Q
Thu, Apr 17, 2014 at 05:01:10PM CEST, stephen-OTpzqLSitTUnbdJkjeBofR2eb7JE58TQ@public.gmane.org wrote:
>On Thu, 17 Apr 2014 14:14:29 +0200
>Jiri Pirko <jiri-rHqAuBHg3fBzbRFIqnYvSA@public.gmane.org> wrote:
>
>> So this can be reused for identification of other "items" as well.
>>
>> Signed-off-by: Jiri Pirko <jiri-rHqAuBHg3fBzbRFIqnYvSA@public.gmane.org>
>> ---
>> drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c | 2 +-
>> drivers/net/ethernet/mellanox/mlx4/en_netdev.c | 2 +-
>> drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c | 2 +-
>> include/linux/netdevice.h | 16 ++++++++--------
>> net/core/dev.c | 2 +-
>> net/core/net-sysfs.c | 2 +-
>> net/core/rtnetlink.c | 6 +++---
>> 7 files changed, 16 insertions(+), 16 deletions(-)
>>
>> diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
>> index a78edac..a4b25b1 100644
>> --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
>> +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
>> @@ -12360,7 +12360,7 @@ static int bnx2x_validate_addr(struct net_device *dev)
>> }
>>
>> static int bnx2x_get_phys_port_id(struct net_device *netdev,
>> - struct netdev_phys_port_id *ppid)
>> + struct netdev_phys_item_id *ppid)
>> {
>> struct bnx2x *bp = netdev_priv(netdev);
>>
>> diff --git a/drivers/net/ethernet/mellanox/mlx4/en_netdev.c b/drivers/net/ethernet/mellanox/mlx4/en_netdev.c
>> index f085c2d..e784bb4 100644
>> --- a/drivers/net/ethernet/mellanox/mlx4/en_netdev.c
>> +++ b/drivers/net/ethernet/mellanox/mlx4/en_netdev.c
>> @@ -2251,7 +2251,7 @@ static int mlx4_en_set_vf_link_state(struct net_device *dev, int vf, int link_st
>>
>> #define PORT_ID_BYTE_LEN 8
>> static int mlx4_en_get_phys_port_id(struct net_device *dev,
>> - struct netdev_phys_port_id *ppid)
>> + struct netdev_phys_item_id *ppid)
>> {
>> struct mlx4_en_priv *priv = netdev_priv(dev);
>> struct mlx4_dev *mdev = priv->mdev->dev;
>> diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c
>> index 309d056..55af16a 100644
>> --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c
>> +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c
>> @@ -450,7 +450,7 @@ static void qlcnic_82xx_cancel_idc_work(struct qlcnic_adapter *adapter)
>> }
>>
>> static int qlcnic_get_phys_port_id(struct net_device *netdev,
>> - struct netdev_phys_port_id *ppid)
>> + struct netdev_phys_item_id *ppid)
>> {
>> struct qlcnic_adapter *adapter = netdev_priv(netdev);
>> struct qlcnic_hardware_context *ahw = adapter->ahw;
>> diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
>> index 775cc95..8cf4f5e 100644
>> --- a/include/linux/netdevice.h
>> +++ b/include/linux/netdevice.h
>> @@ -735,13 +735,13 @@ struct netdev_fcoe_hbainfo {
>> };
>> #endif
>>
>> -#define MAX_PHYS_PORT_ID_LEN 32
>> +#define MAX_PHYS_ITEM_ID_LEN 32
>>
>
>Why the rename?
I use the same struct in "net: introduce generic switch devices support"
to identify switch. So that is no longer only a "port id"
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [patch net-next RFC v3 10/10] openvswitch: add support for datapath hardware offload
[not found] ` <1397736938-11838-1-git-send-email-jiri-rHqAuBHg3fBzbRFIqnYvSA@public.gmane.org>
@ 2014-04-24 14:54 ` John Fastabend
[not found] ` <5359259B.3020402-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
0 siblings, 1 reply; 24+ messages in thread
From: John Fastabend @ 2014-04-24 14:54 UTC (permalink / raw)
To: Jiri Pirko
Cc: ryazanov.s.a-Re5JQEeQqe8AvxtiuMwx3w,
jasowang-H+wXaHxf7aLQT0dZR+AlfA,
john.r.fastabend-ral2JQCrhuEAvxtiuMwx3w,
Neil.Jerram-QnUH15yq9NYqDJ6do+/SaQ,
edumazet-hpIqsD4AKlfQT0dZR+AlfA, andy-QlMahl40kYEqcZcGjlUOXw,
dev-yBygre7rU0TnMu66kgdUjQ, nbd-p3rKhJxN3npAfugRpC6u6w,
f.fainelli-Re5JQEeQqe8AvxtiuMwx3w,
jeffrey.t.kirsher-ral2JQCrhuEAvxtiuMwx3w,
ogerlitz-VPRAkNaXOzVWk0Htik3J/w, ben-/+tVBieCtBitmTQ+vhA3Yw,
buytenh-OLH4Qvv75CYX/NnBR394Jw,
roopa-qUQiAmfTcIp+XZJcv9eMoEEOCMrvLtNR,
jhs-jkUAjuhPggJWk0Htik3J/w, linville-2XuSBdqkA4R54TAoqtyWWQ,
aviadr-VPRAkNaXOzVWk0Htik3J/w,
nicolas.dichtel-pdR9zngts4EAvxtiuMwx3w,
vyasevic-H+wXaHxf7aLQT0dZR+AlfA, nhorman-2XuSBdqkA4R54TAoqtyWWQ,
sfeldma-qUQiAmfTcIp+XZJcv9eMoEEOCMrvLtNR,
netdev-u79uwXL29TY76Z2rM5mHXA,
stephen-OTpzqLSitTUnbdJkjeBofR2eb7JE58TQ,
dborkman-H+wXaHxf7aLQT0dZR+AlfA, ebiederm-aS9lmoZGLiVWk0Htik3J/w,
davem-fT/PcQaiUtIeIZ0/mPfg9Q
On 04/17/2014 05:15 AM, Jiri Pirko wrote:
> Benefit from the possibility to work with flows in switch devices and
> use the swdev api to offload flow datapath.
>
> Signed-off-by: Jiri Pirko <jiri-rHqAuBHg3fBzbRFIqnYvSA@public.gmane.org>
> ---
[...]
>
> @@ -840,13 +841,15 @@ static int ovs_flow_cmd_new_or_set(struct sk_buff *skb, struct genl_info *info)
> flow->flow.key = masked_key;
> flow->flow.unmasked_key = key;
> rcu_assign_pointer(flow->sf_acts, acts);
> + acts = NULL;
>
> /* Put flow in bucket. */
> error = ovs_flow_tbl_insert(&dp->table, flow, &mask);
> - if (error) {
> - acts = NULL;
> + if (error)
> goto err_flow_free;
> - }
> + error = ovs_hw_flow_insert(dp, flow, flow->sf_acts);
> + if (error)
> + goto err_flow_tbl_remove;
>
> reply = ovs_flow_cmd_build_info(flow, dp, info, OVS_FLOW_CMD_NEW);
> } else {
Hi Jiri,
If I read this correctly it looks like you do a insert into software
flow tables and then an insert into the hardware flow tables. Into
all lowerdevs. Let me know if I got this wrong.
This might break on some rules (an insert tag for example) and also
underutilize the switch resources by pushing rules into the switch that
we really only need in software tables or maybe only on some set of
ports.
I think we need to allow applications direct access to the flow table
via netlink so I can write my policy in user space and not require
OVS. If OVS wants to support a mode where it does this automagically
it can support it in userspace and the kernel side does not need to
change.
Thanks,
John
--
John Fastabend Intel Corporation
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [patch net-next RFC v3 10/10] openvswitch: add support for datapath hardware offload
[not found] ` <5359259B.3020402-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
@ 2014-04-24 15:46 ` Jiri Pirko
[not found] ` <20140424154614.GB2864-RDzucLLXGGI88b5SBfVpbw@public.gmane.org>
0 siblings, 1 reply; 24+ messages in thread
From: Jiri Pirko @ 2014-04-24 15:46 UTC (permalink / raw)
To: John Fastabend
Cc: ryazanov.s.a-Re5JQEeQqe8AvxtiuMwx3w,
jasowang-H+wXaHxf7aLQT0dZR+AlfA,
john.r.fastabend-ral2JQCrhuEAvxtiuMwx3w,
Neil.Jerram-QnUH15yq9NYqDJ6do+/SaQ,
edumazet-hpIqsD4AKlfQT0dZR+AlfA, andy-QlMahl40kYEqcZcGjlUOXw,
dev-yBygre7rU0TnMu66kgdUjQ, nbd-p3rKhJxN3npAfugRpC6u6w,
f.fainelli-Re5JQEeQqe8AvxtiuMwx3w,
jeffrey.t.kirsher-ral2JQCrhuEAvxtiuMwx3w,
ogerlitz-VPRAkNaXOzVWk0Htik3J/w, ben-/+tVBieCtBitmTQ+vhA3Yw,
buytenh-OLH4Qvv75CYX/NnBR394Jw,
roopa-qUQiAmfTcIp+XZJcv9eMoEEOCMrvLtNR,
jhs-jkUAjuhPggJWk0Htik3J/w, linville-2XuSBdqkA4R54TAoqtyWWQ,
aviadr-VPRAkNaXOzVWk0Htik3J/w,
nicolas.dichtel-pdR9zngts4EAvxtiuMwx3w,
vyasevic-H+wXaHxf7aLQT0dZR+AlfA, nhorman-2XuSBdqkA4R54TAoqtyWWQ,
sfeldma-qUQiAmfTcIp+XZJcv9eMoEEOCMrvLtNR,
netdev-u79uwXL29TY76Z2rM5mHXA,
stephen-OTpzqLSitTUnbdJkjeBofR2eb7JE58TQ,
dborkman-H+wXaHxf7aLQT0dZR+AlfA, ebiederm-aS9lmoZGLiVWk0Htik3J/w,
davem-fT/PcQaiUtIeIZ0/mPfg9Q
Thu, Apr 24, 2014 at 04:54:19PM CEST, john.fastabend-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org wrote:
>On 04/17/2014 05:15 AM, Jiri Pirko wrote:
>>Benefit from the possibility to work with flows in switch devices and
>>use the swdev api to offload flow datapath.
>>
>>Signed-off-by: Jiri Pirko <jiri-rHqAuBHg3fBzbRFIqnYvSA@public.gmane.org>
>>---
>
>
>[...]
>
>>
>>@@ -840,13 +841,15 @@ static int ovs_flow_cmd_new_or_set(struct sk_buff *skb, struct genl_info *info)
>> flow->flow.key = masked_key;
>> flow->flow.unmasked_key = key;
>> rcu_assign_pointer(flow->sf_acts, acts);
>>+ acts = NULL;
>>
>> /* Put flow in bucket. */
>> error = ovs_flow_tbl_insert(&dp->table, flow, &mask);
>>- if (error) {
>>- acts = NULL;
>>+ if (error)
>> goto err_flow_free;
>>- }
>>+ error = ovs_hw_flow_insert(dp, flow, flow->sf_acts);
>>+ if (error)
>>+ goto err_flow_tbl_remove;
>>
>> reply = ovs_flow_cmd_build_info(flow, dp, info, OVS_FLOW_CMD_NEW);
>> } else {
>
>Hi Jiri,
>
>If I read this correctly it looks like you do a insert into software
>flow tables and then an insert into the hardware flow tables. Into
>all lowerdevs. Let me know if I got this wrong.
It should be sufficient to use one-port-per-switch to insert this. I
just insert it to all and if 2 ports of the same switch are used the
switch should see that the flow is already there and bail out. This is
rough so far. Needs some polishing.
>
>This might break on some rules (an insert tag for example) and also
>underutilize the switch resources by pushing rules into the switch that
>we really only need in software tables or maybe only on some set of
>ports.
I thought that I would introduce a flag that would say "push this flow
to hw".
>
>I think we need to allow applications direct access to the flow table
>via netlink so I can write my policy in user space and not require
>OVS. If OVS wants to support a mode where it does this automagically
>it can support it in userspace and the kernel side does not need to
>change.
The idea was to use the existing ovs api for this so it would be smooth
to userspace. For non-ovs usage there is certainly possible to introduce
new iface which would just call same ndos.
>
>Thanks,
>John
>
>
>--
>John Fastabend Intel Corporation
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [patch net-next RFC v3 10/10] openvswitch: add support for datapath hardware offload
[not found] ` <20140424154614.GB2864-RDzucLLXGGI88b5SBfVpbw@public.gmane.org>
@ 2014-04-24 15:58 ` John Fastabend
0 siblings, 0 replies; 24+ messages in thread
From: John Fastabend @ 2014-04-24 15:58 UTC (permalink / raw)
To: Jiri Pirko
Cc: ryazanov.s.a-Re5JQEeQqe8AvxtiuMwx3w,
jasowang-H+wXaHxf7aLQT0dZR+AlfA,
Neil.Jerram-QnUH15yq9NYqDJ6do+/SaQ,
edumazet-hpIqsD4AKlfQT0dZR+AlfA, andy-QlMahl40kYEqcZcGjlUOXw,
dev-yBygre7rU0TnMu66kgdUjQ, nbd-p3rKhJxN3npAfugRpC6u6w,
f.fainelli-Re5JQEeQqe8AvxtiuMwx3w, John Fastabend,
jeffrey.t.kirsher-ral2JQCrhuEAvxtiuMwx3w,
ogerlitz-VPRAkNaXOzVWk0Htik3J/w, ben-/+tVBieCtBitmTQ+vhA3Yw,
buytenh-OLH4Qvv75CYX/NnBR394Jw,
roopa-qUQiAmfTcIp+XZJcv9eMoEEOCMrvLtNR,
jhs-jkUAjuhPggJWk0Htik3J/w, linville-2XuSBdqkA4R54TAoqtyWWQ,
aviadr-VPRAkNaXOzVWk0Htik3J/w,
nicolas.dichtel-pdR9zngts4EAvxtiuMwx3w,
vyasevic-H+wXaHxf7aLQT0dZR+AlfA, nhorman-2XuSBdqkA4R54TAoqtyWWQ,
sfeldma-qUQiAmfTcIp+XZJcv9eMoEEOCMrvLtNR,
netdev-u79uwXL29TY76Z2rM5mHXA,
stephen-OTpzqLSitTUnbdJkjeBofR2eb7JE58TQ,
dborkman-H+wXaHxf7aLQT0dZR+AlfA, ebiederm-aS9lmoZGLiVWk0Htik3J/w,
davem-fT/PcQaiUtIeIZ0/mPfg9Q
On 4/24/2014 8:46 AM, Jiri Pirko wrote:
> Thu, Apr 24, 2014 at 04:54:19PM CEST, john.fastabend-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org wrote:
>> On 04/17/2014 05:15 AM, Jiri Pirko wrote:
>>> Benefit from the possibility to work with flows in switch devices and
>>> use the swdev api to offload flow datapath.
>>>
>>> Signed-off-by: Jiri Pirko <jiri-rHqAuBHg3fBzbRFIqnYvSA@public.gmane.org>
>>> ---
>>
>>
>> [...]
>>
>>>
>>> @@ -840,13 +841,15 @@ static int ovs_flow_cmd_new_or_set(struct sk_buff *skb, struct genl_info *info)
>>> flow->flow.key = masked_key;
>>> flow->flow.unmasked_key = key;
>>> rcu_assign_pointer(flow->sf_acts, acts);
>>> + acts = NULL;
>>>
>>> /* Put flow in bucket. */
>>> error = ovs_flow_tbl_insert(&dp->table, flow, &mask);
>>> - if (error) {
>>> - acts = NULL;
>>> + if (error)
>>> goto err_flow_free;
>>> - }
>>> + error = ovs_hw_flow_insert(dp, flow, flow->sf_acts);
>>> + if (error)
>>> + goto err_flow_tbl_remove;
>>>
>>> reply = ovs_flow_cmd_build_info(flow, dp, info, OVS_FLOW_CMD_NEW);
>>> } else {
>>
>> Hi Jiri,
>>
>> If I read this correctly it looks like you do a insert into software
>> flow tables and then an insert into the hardware flow tables. Into
>> all lowerdevs. Let me know if I got this wrong.
>
> It should be sufficient to use one-port-per-switch to insert this. I
> just insert it to all and if 2 ports of the same switch are used the
> switch should see that the flow is already there and bail out. This is
> rough so far. Needs some polishing.
>
>
OK that seems fine.
>>
>> This might break on some rules (an insert tag for example) and also
>> underutilize the switch resources by pushing rules into the switch that
>> we really only need in software tables or maybe only on some set of
>> ports.
>
> I thought that I would introduce a flag that would say "push this flow
> to hw".
>
Great this would align with how the FDB interface works. I think this
is a good model although I would prefer a bitfield so I can push it
to hardware, or sw, or both.
>>
>> I think we need to allow applications direct access to the flow table
>> via netlink so I can write my policy in user space and not require
>> OVS. If OVS wants to support a mode where it does this automagically
>> it can support it in userspace and the kernel side does not need to
>> change.
>
> The idea was to use the existing ovs api for this so it would be smooth
> to userspace. For non-ovs usage there is certainly possible to introduce
> new iface which would just call same ndos.
>
If we get a bitfield to push to just hardware and just software then
using the OVS interface is probably ok. We also need someway to expose
capabilities.
Anyways not a bad start. We can clean it up when the hardware support
is ready.
.John
^ permalink raw reply [flat|nested] 24+ messages in thread
end of thread, other threads:[~2014-04-24 15:58 UTC | newest]
Thread overview: 24+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2014-04-17 12:14 [patch net-next RFC v3 00/10] introduce infrastructure for support of switch chip datapath Jiri Pirko
2014-04-17 12:14 ` [patch net-next RFC v3 02/10] net: rename netdev_phys_port_id to more generic name Jiri Pirko
[not found] ` <1397736876-11771-3-git-send-email-jiri-rHqAuBHg3fBzbRFIqnYvSA@public.gmane.org>
2014-04-17 15:01 ` Stephen Hemminger
[not found] ` <20140417080110.73485409-We1ePj4FEcvRI77zikRAJc56i+j3xesD0e7PPNI6Mm0@public.gmane.org>
2014-04-17 15:05 ` Jiri Pirko
2014-04-17 12:14 ` [patch net-next RFC v3 03/10] net: introduce generic switch devices support Jiri Pirko
2014-04-17 12:14 ` [patch net-next RFC v3 04/10] rtnl: expose physical switch id for particular device Jiri Pirko
2014-04-17 12:40 ` Yegor Yefremov
2014-04-17 12:14 ` [patch net-next RFC v3 05/10] switchdev: introduce basic support for flows Jiri Pirko
2014-04-17 12:14 ` [patch net-next RFC v3 07/10] dsa: implement ndo_swdev_get_id Jiri Pirko
[not found] ` <1397736876-11771-1-git-send-email-jiri-rHqAuBHg3fBzbRFIqnYvSA@public.gmane.org>
2014-04-17 12:14 ` [patch net-next RFC v3 01/10] openvswitch: split flow structures into ovs specific and generic ones Jiri Pirko
2014-04-17 12:14 ` [patch net-next RFC v3 06/10] net: introduce dummy switch Jiri Pirko
2014-04-17 12:14 ` [patch net-next RFC v3 08/10] net: add netdev_for_each_all_lower_dev_rcu helper Jiri Pirko
2014-04-17 12:15 ` [patch net-next RFC v3 10/10] openvswitch: add support for datapath hardware offload Jiri Pirko
[not found] ` <1397736938-11838-1-git-send-email-jiri-rHqAuBHg3fBzbRFIqnYvSA@public.gmane.org>
2014-04-24 14:54 ` John Fastabend
[not found] ` <5359259B.3020402-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
2014-04-24 15:46 ` Jiri Pirko
[not found] ` <20140424154614.GB2864-RDzucLLXGGI88b5SBfVpbw@public.gmane.org>
2014-04-24 15:58 ` John Fastabend
2014-04-17 12:17 ` [patch net-next RFC v3 0/5] iproute2: support switch chip infrastructure Jiri Pirko
[not found] ` <1397737053-11892-1-git-send-email-jiri-rHqAuBHg3fBzbRFIqnYvSA@public.gmane.org>
2014-04-17 12:17 ` [patch iproute2 RFC v3 1/5] iproute2: arpd: use ll_addr_a2n and ll_addr_n2a Jiri Pirko
2014-04-17 12:17 ` [patch iproute2 RFC v3 2/5] iproute2: utils: change hexstring_n2a and hexstring_a2n to do not work with ":" Jiri Pirko
2014-04-17 12:17 ` [patch iproute2 RFC v3 3/5] iproute2: ipa: show switch id Jiri Pirko
2014-04-17 12:17 ` [patch iproute2 RFC v3 4/5] iproute2: add support for dummyswport Jiri Pirko
2014-04-17 13:19 ` Nicolas Dichtel
2014-04-17 12:17 ` [patch iproute2 RFC v3 5/5] iproute2: ipa: show port id Jiri Pirko
2014-04-17 12:14 ` [patch net-next RFC v3 09/10] openvswitch: introduce vport_op get_netdev Jiri Pirko
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).