* [patch net-next v4 14/21] bridge: add brport flags to dflt bridge_getlink
From: Jiri Pirko @ 2014-11-27 10:40 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, jasowang, ebiederm, nicolas.dichtel, ryazanov.s.a,
buytenh, aviadr, nbd, alexei.starovoitov, Neil.Jerram, ronye,
simon.horman, alexander.h.duyck, john.ronciak, mleitner, shrijeet,
gospo, bcrl, hemal
In-Reply-To: <1417084826-9875-1-git-send-email-jiri@resnulli.us>
From: Scott Feldman <sfeldma@gmail.com>
To allow brport device to return current brport flags set on port. Add
returned flags to nested IFLA_PROTINFO netlink msg built in dflt getlink.
With this change, netlink msg returned for bridge_getlink contains the port's
offloaded flag settings (the port's SELF settings).
Signed-off-by: Scott Feldman <sfeldma@gmail.com>
Signed-off-by: Jiri Pirko <jiri@resnulli.us>
Acked-by: Andy Gospodarek <gospo@cumulusnetworks.com>
Acked-by: Thomas Graf <tgraf@suug.ch>
---
v3->v4:
-no change
new in v3
---
drivers/net/ethernet/emulex/benet/be_main.c | 3 ++-
drivers/net/ethernet/intel/ixgbe/ixgbe_main.c | 2 +-
include/linux/rtnetlink.h | 3 ++-
net/core/rtnetlink.c | 39 ++++++++++++++++++++++++++-
4 files changed, 43 insertions(+), 4 deletions(-)
diff --git a/drivers/net/ethernet/emulex/benet/be_main.c b/drivers/net/ethernet/emulex/benet/be_main.c
index 9070b98..6510ec8 100644
--- a/drivers/net/ethernet/emulex/benet/be_main.c
+++ b/drivers/net/ethernet/emulex/benet/be_main.c
@@ -4362,7 +4362,8 @@ static int be_ndo_bridge_getlink(struct sk_buff *skb, u32 pid, u32 seq,
return ndo_dflt_bridge_getlink(skb, pid, seq, dev,
hsw_mode == PORT_FWD_TYPE_VEPA ?
- BRIDGE_MODE_VEPA : BRIDGE_MODE_VEB);
+ BRIDGE_MODE_VEPA : BRIDGE_MODE_VEB,
+ 0, 0);
}
#ifdef CONFIG_BE2NET_VXLAN
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
index 1bad9f4..eb2a04b 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
@@ -7773,7 +7773,7 @@ static int ixgbe_ndo_bridge_getlink(struct sk_buff *skb, u32 pid, u32 seq,
else
mode = BRIDGE_MODE_VEPA;
- return ndo_dflt_bridge_getlink(skb, pid, seq, dev, mode);
+ return ndo_dflt_bridge_getlink(skb, pid, seq, dev, mode, 0, 0);
}
static void *ixgbe_fwd_add(struct net_device *pdev, struct net_device *vdev)
diff --git a/include/linux/rtnetlink.h b/include/linux/rtnetlink.h
index 063f0f5..3b04190 100644
--- a/include/linux/rtnetlink.h
+++ b/include/linux/rtnetlink.h
@@ -103,5 +103,6 @@ extern int ndo_dflt_fdb_del(struct ndmsg *ndm,
u16 vid);
extern int ndo_dflt_bridge_getlink(struct sk_buff *skb, u32 pid, u32 seq,
- struct net_device *dev, u16 mode);
+ struct net_device *dev, u16 mode,
+ u32 flags, u32 mask);
#endif /* __LINUX_RTNETLINK_H */
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c
index b6541f2..7525ba3 100644
--- a/net/core/rtnetlink.c
+++ b/net/core/rtnetlink.c
@@ -2687,12 +2687,22 @@ static int rtnl_fdb_dump(struct sk_buff *skb, struct netlink_callback *cb)
return skb->len;
}
+static int brport_nla_put_flag(struct sk_buff *skb, u32 flags, u32 mask,
+ unsigned int attrnum, unsigned int flag)
+{
+ if (mask & flag)
+ return nla_put_u8(skb, attrnum, !!(flags & flag));
+ return 0;
+}
+
int ndo_dflt_bridge_getlink(struct sk_buff *skb, u32 pid, u32 seq,
- struct net_device *dev, u16 mode)
+ struct net_device *dev, u16 mode,
+ u32 flags, u32 mask)
{
struct nlmsghdr *nlh;
struct ifinfomsg *ifm;
struct nlattr *br_afspec;
+ struct nlattr *protinfo;
u8 operstate = netif_running(dev) ? dev->operstate : IF_OPER_DOWN;
struct net_device *br_dev = netdev_master_upper_dev_get(dev);
@@ -2731,6 +2741,33 @@ int ndo_dflt_bridge_getlink(struct sk_buff *skb, u32 pid, u32 seq,
}
nla_nest_end(skb, br_afspec);
+ protinfo = nla_nest_start(skb, IFLA_PROTINFO | NLA_F_NESTED);
+ if (!protinfo)
+ goto nla_put_failure;
+
+ if (brport_nla_put_flag(skb, flags, mask,
+ IFLA_BRPORT_MODE, BR_HAIRPIN_MODE) ||
+ brport_nla_put_flag(skb, flags, mask,
+ IFLA_BRPORT_GUARD, BR_BPDU_GUARD) ||
+ brport_nla_put_flag(skb, flags, mask,
+ IFLA_BRPORT_FAST_LEAVE,
+ BR_MULTICAST_FAST_LEAVE) ||
+ brport_nla_put_flag(skb, flags, mask,
+ IFLA_BRPORT_PROTECT, BR_ROOT_BLOCK) ||
+ brport_nla_put_flag(skb, flags, mask,
+ IFLA_BRPORT_LEARNING, BR_LEARNING) ||
+ brport_nla_put_flag(skb, flags, mask,
+ IFLA_BRPORT_LEARNING_SYNC, BR_LEARNING_SYNC) ||
+ brport_nla_put_flag(skb, flags, mask,
+ IFLA_BRPORT_UNICAST_FLOOD, BR_FLOOD) ||
+ brport_nla_put_flag(skb, flags, mask,
+ IFLA_BRPORT_PROXYARP, BR_PROXYARP)) {
+ nla_nest_cancel(skb, protinfo);
+ goto nla_put_failure;
+ }
+
+ nla_nest_end(skb, protinfo);
+
return nlmsg_end(skb, nlh);
nla_put_failure:
nlmsg_cancel(skb, nlh);
--
1.9.3
^ permalink raw reply related
* [patch net-next v4 13/21] bridge: add new hwmode swdev
From: Jiri Pirko @ 2014-11-27 10:40 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, jasowang, ebiederm, nicolas.dichtel, ryazanov.s.a,
buytenh, aviadr, nbd, alexei.starovoitov, Neil.Jerram, ronye,
simon.horman, alexander.h.duyck, john.ronciak, mleitner, shrijeet,
gospo, bcrl, hemal
In-Reply-To: <1417084826-9875-1-git-send-email-jiri@resnulli.us>
From: Scott Feldman <sfeldma@gmail.com>
Current hwmode settings are "vepa" or "veb". These are for NIC interfaces
with basic bridging function offloaded to HW. Add new "swdev" for full
switch device offloads.
Signed-off-by: Scott Feldman <sfeldma@gmail.com>
Signed-off-by: Jiri Pirko <jiri@resnulli.us>
---
v3->v4:
-no change
new in v3
---
include/uapi/linux/if_bridge.h | 1 +
1 file changed, 1 insertion(+)
diff --git a/include/uapi/linux/if_bridge.h b/include/uapi/linux/if_bridge.h
index da17e45..60425ca 100644
--- a/include/uapi/linux/if_bridge.h
+++ b/include/uapi/linux/if_bridge.h
@@ -105,6 +105,7 @@ struct __fdb_entry {
#define BRIDGE_MODE_VEB 0 /* Default loopback mode */
#define BRIDGE_MODE_VEPA 1 /* 802.1Qbg defined VEPA mode */
+#define BRIDGE_MODE_SWDEV 2 /* Full switch device offload */
/* Bridge management nested attributes
* [IFLA_AF_SPEC] = {
--
1.9.3
^ permalink raw reply related
* [patch net-next v4 12/21] bridge: add new brport flag LEARNING_SYNC
From: Jiri Pirko @ 2014-11-27 10:40 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, jasowang, ebiederm, nicolas.dichtel, ryazanov.s.a,
buytenh, aviadr, nbd, alexei.starovoitov, Neil.Jerram, ronye,
simon.horman, alexander.h.duyck, john.ronciak, mleitner, shrijeet,
gospo, bcrl, hemal
In-Reply-To: <1417084826-9875-1-git-send-email-jiri@resnulli.us>
From: Scott Feldman <sfeldma@gmail.com>
This policy flag controls syncing of learned FDB entries to bridge's FDB. If
on, FDB entries learned on bridge port device will be synced. If off, device
may still learn new FDB entries but they will not be synced with bridge's FDB.
Signed-off-by: Scott Feldman <sfeldma@gmail.com>
Signed-off-by: Jiri Pirko <jiri@resnulli.us>
Acked-by: Roopa Prabhu <roopa@cumulusnetworks.com>
Acked-by: Jamal Hadi Salim <jhs@mojatatu.com>
Acked-by: Andy Gospodarek <gospo@cumulusnetworks.com>
---
v3->v4:
-just resolved conflict caused by BIT change of previous patch
new in v3
---
include/linux/if_bridge.h | 1 +
include/uapi/linux/if_link.h | 1 +
2 files changed, 2 insertions(+)
diff --git a/include/linux/if_bridge.h b/include/linux/if_bridge.h
index 2c81a8e..0a8ce76 100644
--- a/include/linux/if_bridge.h
+++ b/include/linux/if_bridge.h
@@ -43,6 +43,7 @@ struct br_ip_list {
#define BR_AUTO_MASK (BR_FLOOD | BR_LEARNING)
#define BR_PROMISC BIT(7)
#define BR_PROXYARP BIT(8)
+#define BR_LEARNING_SYNC BIT(9)
extern void brioctl_set(int (*ioctl_hook)(struct net *, unsigned int, void __user *));
diff --git a/include/uapi/linux/if_link.h b/include/uapi/linux/if_link.h
index 623f1a7..f7d0d2d 100644
--- a/include/uapi/linux/if_link.h
+++ b/include/uapi/linux/if_link.h
@@ -245,6 +245,7 @@ enum {
IFLA_BRPORT_LEARNING, /* mac learning */
IFLA_BRPORT_UNICAST_FLOOD, /* flood unicast traffic */
IFLA_BRPORT_PROXYARP, /* proxy ARP */
+ IFLA_BRPORT_LEARNING_SYNC, /* mac learning sync from device */
__IFLA_BRPORT_MAX
};
#define IFLA_BRPORT_MAX (__IFLA_BRPORT_MAX - 1)
--
1.9.3
^ permalink raw reply related
* [patch net-next v4 11/21] bridge: move private brport flags to if_bridge.h so port drivers can use flags
From: Jiri Pirko @ 2014-11-27 10:40 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, jasowang, ebiederm, nicolas.dichtel, ryazanov.s.a,
buytenh, aviadr, nbd, alexei.starovoitov, Neil.Jerram, ronye,
simon.horman, alexander.h.duyck, john.ronciak, mleitner, shrijeet,
gospo, bcrl, hemal
In-Reply-To: <1417084826-9875-1-git-send-email-jiri@resnulli.us>
From: Scott Feldman <sfeldma@gmail.com>
Signed-off-by: Scott Feldman <sfeldma@gmail.com>
Signed-off-by: Jiri Pirko <jiri@resnulli.us>
Acked-by: Jamal Hadi Salim <jhs@mojatatu.com>
Acked-by: Andy Gospodarek <gospo@cumulusnetworks.com>
Acked-by: Florian Fainelli <f.fainelli@gmail.com
---
v3->v4:
-used BIT macro as suggested by Thomas
new in v3
---
include/linux/if_bridge.h | 12 ++++++++++++
net/bridge/br_private.h | 10 ----------
2 files changed, 12 insertions(+), 10 deletions(-)
diff --git a/include/linux/if_bridge.h b/include/linux/if_bridge.h
index fa2eca6..2c81a8e 100644
--- a/include/linux/if_bridge.h
+++ b/include/linux/if_bridge.h
@@ -15,6 +15,7 @@
#include <linux/netdevice.h>
#include <uapi/linux/if_bridge.h>
+#include <linux/bitops.h>
struct br_ip {
union {
@@ -32,6 +33,17 @@ struct br_ip_list {
struct br_ip addr;
};
+#define BR_HAIRPIN_MODE BIT(0)
+#define BR_BPDU_GUARD BIT(1)
+#define BR_ROOT_BLOCK BIT(2)
+#define BR_MULTICAST_FAST_LEAVE BIT(3)
+#define BR_ADMIN_COST BIT(4)
+#define BR_LEARNING BIT(5)
+#define BR_FLOOD BIT(6)
+#define BR_AUTO_MASK (BR_FLOOD | BR_LEARNING)
+#define BR_PROMISC BIT(7)
+#define BR_PROXYARP BIT(8)
+
extern void brioctl_set(int (*ioctl_hook)(struct net *, unsigned int, void __user *));
typedef int br_should_route_hook_t(struct sk_buff *skb);
diff --git a/net/bridge/br_private.h b/net/bridge/br_private.h
index cc36fb3..aea3d13 100644
--- a/net/bridge/br_private.h
+++ b/net/bridge/br_private.h
@@ -164,16 +164,6 @@ struct net_bridge_port
struct rcu_head rcu;
unsigned long flags;
-#define BR_HAIRPIN_MODE 0x00000001
-#define BR_BPDU_GUARD 0x00000002
-#define BR_ROOT_BLOCK 0x00000004
-#define BR_MULTICAST_FAST_LEAVE 0x00000008
-#define BR_ADMIN_COST 0x00000010
-#define BR_LEARNING 0x00000020
-#define BR_FLOOD 0x00000040
-#define BR_AUTO_MASK (BR_FLOOD | BR_LEARNING)
-#define BR_PROMISC 0x00000080
-#define BR_PROXYARP 0x00000100
#ifdef CONFIG_BRIDGE_IGMP_SNOOPING
struct bridge_mcast_own_query ip4_own_query;
--
1.9.3
^ permalink raw reply related
* [patch net-next v4 10/21] bridge: add API to notify bridge driver of learned FBD on offloaded device
From: Jiri Pirko @ 2014-11-27 10:40 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, jasowang, ebiederm, nicolas.dichtel, ryazanov.s.a,
buytenh, aviadr, nbd, alexei.starovoitov, Neil.Jerram, ronye,
simon.horman, alexander.h.duyck, john.ronciak, mleitner, shrijeet,
gospo, bcrl, hemal
In-Reply-To: <1417084826-9875-1-git-send-email-jiri@resnulli.us>
From: Scott Feldman <sfeldma@gmail.com>
When the swdev device learns a new mac/vlan on a port, it sends some async
notification to the driver and the driver installs an FDB in the device.
To give a holistic system view, the learned mac/vlan should be reflected
in the bridge's FBD table, so the user, using normal iproute2 cmds, can view
what is currently learned by the device. This API on the bridge driver gives
a way for the swdev driver to install an FBD entry in the bridge FBD table.
(And remove one).
This is equivalent to the device running these cmds:
bridge fdb [add|del] <mac> dev <dev> vid <vlan id> master
This patch needs some extra eyeballs for review, in paricular around the
locking and contexts.
Signed-off-by: Scott Feldman <sfeldma@gmail.com>
Signed-off-by: Jiri Pirko <jiri@resnulli.us>
Acked-by: Jamal Hadi Salim <jhs@mojatatu.com>
---
v3->v4:
-cosmetic changes to resolve conflicts
-call bh version of spinlock for hash_lock to avoid deadlock
v2->v3:
-added "external" word into function names to emphasize fdbs are learned
externally
-added "added_by_external_learn" to fbd entry struct indicate the entry
was learned externaly and build some logic around that
-expose the fact that fdb entry was learned externally to userspace
v1->v2:
-no change
x
Signed-off-by: Jiri Pirko <jiri@resnulli.us>
---
include/linux/if_bridge.h | 18 +++++++++
include/uapi/linux/neighbour.h | 1 +
net/bridge/br_fdb.c | 91 +++++++++++++++++++++++++++++++++++++++++-
net/bridge/br_private.h | 3 +-
4 files changed, 111 insertions(+), 2 deletions(-)
diff --git a/include/linux/if_bridge.h b/include/linux/if_bridge.h
index 808dcb8..fa2eca6 100644
--- a/include/linux/if_bridge.h
+++ b/include/linux/if_bridge.h
@@ -37,6 +37,24 @@ extern void brioctl_set(int (*ioctl_hook)(struct net *, unsigned int, void __use
typedef int br_should_route_hook_t(struct sk_buff *skb);
extern br_should_route_hook_t __rcu *br_should_route_hook;
+#if IS_ENABLED(CONFIG_BRIDGE)
+int br_fdb_external_learn_add(struct net_device *dev,
+ const unsigned char *addr, u16 vid);
+int br_fdb_external_learn_del(struct net_device *dev,
+ const unsigned char *addr, u16 vid);
+#else
+static inline int br_fdb_external_learn_add(struct net_device *dev,
+ const unsigned char *addr, u16 vid)
+{
+ return 0;
+}
+static inline int br_fdb_external_learn_del(struct net_device *dev,
+ const unsigned char *addr, u16 vid)
+{
+ return 0;
+}
+#endif
+
#if IS_ENABLED(CONFIG_BRIDGE) && IS_ENABLED(CONFIG_BRIDGE_IGMP_SNOOPING)
int br_multicast_list_adjacent(struct net_device *dev,
struct list_head *br_ip_list);
diff --git a/include/uapi/linux/neighbour.h b/include/uapi/linux/neighbour.h
index 2f043af..f3d77f9 100644
--- a/include/uapi/linux/neighbour.h
+++ b/include/uapi/linux/neighbour.h
@@ -38,6 +38,7 @@ enum {
#define NTF_SELF 0x02
#define NTF_MASTER 0x04
#define NTF_PROXY 0x08 /* == ATF_PUBL */
+#define NTF_EXT_LEARNED 0x10
#define NTF_ROUTER 0x80
/*
diff --git a/net/bridge/br_fdb.c b/net/bridge/br_fdb.c
index b1be971..cc36e59 100644
--- a/net/bridge/br_fdb.c
+++ b/net/bridge/br_fdb.c
@@ -481,6 +481,7 @@ static struct net_bridge_fdb_entry *fdb_create(struct hlist_head *head,
fdb->is_local = 0;
fdb->is_static = 0;
fdb->added_by_user = 0;
+ fdb->added_by_external_learn = 0;
fdb->updated = fdb->used = jiffies;
hlist_add_head_rcu(&fdb->hlist, head);
}
@@ -613,7 +614,7 @@ static int fdb_fill_info(struct sk_buff *skb, const struct net_bridge *br,
ndm->ndm_family = AF_BRIDGE;
ndm->ndm_pad1 = 0;
ndm->ndm_pad2 = 0;
- ndm->ndm_flags = 0;
+ ndm->ndm_flags = fdb->added_by_external_learn ? NTF_EXT_LEARNED : 0;
ndm->ndm_type = 0;
ndm->ndm_ifindex = fdb->dst ? fdb->dst->dev->ifindex : br->dev->ifindex;
ndm->ndm_state = fdb_to_nud(fdb);
@@ -983,3 +984,91 @@ void br_fdb_unsync_static(struct net_bridge *br, struct net_bridge_port *p)
}
}
}
+
+int br_fdb_external_learn_add(struct net_device *dev,
+ const unsigned char *addr, u16 vid)
+{
+ struct net_bridge_port *p;
+ struct net_bridge *br;
+ struct hlist_head *head;
+ struct net_bridge_fdb_entry *fdb;
+ int err = 0;
+
+ rtnl_lock();
+
+ p = br_port_get_rtnl(dev);
+ if (!p) {
+ pr_info("bridge: %s not a bridge port\n", dev->name);
+ err = -EINVAL;
+ goto err_rtnl_unlock;
+ }
+
+ br = p->br;
+
+ spin_lock_bh(&br->hash_lock);
+
+ head = &br->hash[br_mac_hash(addr, vid)];
+ fdb = fdb_find(head, addr, vid);
+ if (!fdb) {
+ fdb = fdb_create(head, p, addr, vid);
+ if (!fdb) {
+ err = -ENOMEM;
+ goto err_unlock;
+ }
+ fdb->added_by_external_learn = 1;
+ fdb_notify(br, fdb, RTM_NEWNEIGH);
+ } else if (fdb->added_by_external_learn) {
+ /* Refresh entry */
+ fdb->updated = fdb->used = jiffies;
+ } else if (!fdb->added_by_user) {
+ /* Take over SW learned entry */
+ fdb->added_by_external_learn = 1;
+ fdb->updated = jiffies;
+ fdb_notify(br, fdb, RTM_NEWNEIGH);
+ }
+
+err_unlock:
+ spin_unlock_bh(&br->hash_lock);
+err_rtnl_unlock:
+ rtnl_unlock();
+
+ return err;
+}
+EXPORT_SYMBOL(br_fdb_external_learn_add);
+
+int br_fdb_external_learn_del(struct net_device *dev,
+ const unsigned char *addr, u16 vid)
+{
+ struct net_bridge_port *p;
+ struct net_bridge *br;
+ struct hlist_head *head;
+ struct net_bridge_fdb_entry *fdb;
+ int err = 0;
+
+ rtnl_lock();
+
+ p = br_port_get_rtnl(dev);
+ if (!p) {
+ pr_info("bridge: %s not a bridge port\n", dev->name);
+ err = -EINVAL;
+ goto err_rtnl_unlock;
+ }
+
+ br = p->br;
+
+ spin_lock_bh(&br->hash_lock);
+
+ head = &br->hash[br_mac_hash(addr, vid)];
+ fdb = fdb_find(head, addr, vid);
+ if (fdb && fdb->added_by_external_learn)
+ fdb_delete(br, fdb);
+ else
+ err = -ENOENT;
+
+ spin_unlock_bh(&br->hash_lock);
+err_rtnl_unlock:
+ rtnl_unlock();
+
+ return err;
+}
+EXPORT_SYMBOL(br_fdb_external_learn_del);
diff --git a/net/bridge/br_private.h b/net/bridge/br_private.h
index 1b529da..cc36fb3 100644
--- a/net/bridge/br_private.h
+++ b/net/bridge/br_private.h
@@ -100,7 +100,8 @@ struct net_bridge_fdb_entry
mac_addr addr;
unsigned char is_local:1,
is_static:1,
- added_by_user:1;
+ added_by_user:1,
+ added_by_external_learn:1;
__u16 vlan_id;
};
--
1.9.3
^ permalink raw reply related
* [patch net-next v4 09/21] bridge: call netdev_sw_port_stp_update when bridge port STP status changes
From: Jiri Pirko @ 2014-11-27 10:40 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, jasowang, ebiederm, nicolas.dichtel, ryazanov.s.a,
buytenh, aviadr, nbd, alexei.starovoitov, Neil.Jerram, ronye,
simon.horman, alexander.h.duyck, john.ronciak, mleitner, shrijeet,
gospo, bcrl, hemal
In-Reply-To: <1417084826-9875-1-git-send-email-jiri@resnulli.us>
From: Scott Feldman <sfeldma@gmail.com>
To notify switch driver of change in STP state of bridge port, add new
.ndo op and provide switchdev wrapper func to call ndo op. Use it in bridge
code then.
Signed-off-by: Scott Feldman <sfeldma@gmail.com>
Signed-off-by: Jiri Pirko <jiri@resnulli.us>
Signed-off-by: Andy Gospodarek <gospo@cumulusnetworks.com>
Acked-by: Thomas Graf <tgraf@suug.ch>
Acked-by: Florian Fainelli <f.fainelli@gmail.com>
---
v3->v4:
-added warning when call to netdev_sw_port_stp_update was not successful
suggested by Andy
v2->v3:
-changed "sw" string to "switch" to avoid confusion
v1->v2:
-no change
---
include/linux/netdevice.h | 5 +++++
include/net/switchdev.h | 7 +++++++
net/bridge/br_stp.c | 7 +++++++
net/switchdev/switchdev.c | 19 +++++++++++++++++++
4 files changed, 38 insertions(+)
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index 3603f31..29c92ee 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -1024,6 +1024,9 @@ 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_switch_port_stp_update)(struct net_device *dev, u8 state);
+ * Called to notify switch device port of bridge port STP
+ * state change.
*/
struct net_device_ops {
int (*ndo_init)(struct net_device *dev);
@@ -1180,6 +1183,8 @@ struct net_device_ops {
#ifdef CONFIG_NET_SWITCHDEV
int (*ndo_switch_parent_id_get)(struct net_device *dev,
struct netdev_phys_item_id *psid);
+ int (*ndo_switch_port_stp_update)(struct net_device *dev,
+ u8 state);
#endif
};
diff --git a/include/net/switchdev.h b/include/net/switchdev.h
index 7a52360..8a6d164 100644
--- a/include/net/switchdev.h
+++ b/include/net/switchdev.h
@@ -16,6 +16,7 @@
int netdev_switch_parent_id_get(struct net_device *dev,
struct netdev_phys_item_id *psid);
+int netdev_switch_port_stp_update(struct net_device *dev, u8 state);
#else
@@ -25,6 +26,12 @@ static inline int netdev_switch_parent_id_get(struct net_device *dev,
return -EOPNOTSUPP;
}
+static inline int netdev_switch_port_stp_update(struct net_device *dev,
+ u8 state)
+{
+ return -EOPNOTSUPP;
+}
+
#endif
#endif /* _LINUX_SWITCHDEV_H_ */
diff --git a/net/bridge/br_stp.c b/net/bridge/br_stp.c
index 2b047bc..fb3ebe6 100644
--- a/net/bridge/br_stp.c
+++ b/net/bridge/br_stp.c
@@ -12,6 +12,7 @@
*/
#include <linux/kernel.h>
#include <linux/rculist.h>
+#include <net/switchdev.h>
#include "br_private.h"
#include "br_private_stp.h"
@@ -38,7 +39,13 @@ void br_log_state(const struct net_bridge_port *p)
void br_set_state(struct net_bridge_port *p, unsigned int state)
{
+ int err;
+
p->state = state;
+ err = netdev_switch_port_stp_update(p->dev, state);
+ if (err && err != -EOPNOTSUPP)
+ br_warn(p->br, "error setting offload STP state on port %u(%s)\n",
+ (unsigned int) p->port_no, p->dev->name);
}
/* called under bridge lock */
diff --git a/net/switchdev/switchdev.c b/net/switchdev/switchdev.c
index 66973de..d162b21 100644
--- a/net/switchdev/switchdev.c
+++ b/net/switchdev/switchdev.c
@@ -31,3 +31,22 @@ int netdev_switch_parent_id_get(struct net_device *dev,
return ops->ndo_switch_parent_id_get(dev, psid);
}
EXPORT_SYMBOL(netdev_switch_parent_id_get);
+
+/**
+ * netdev_switch_port_stp_update - Notify switch device port of STP
+ * state change
+ * @dev: port device
+ * @state: port STP state
+ *
+ * Notify switch device port of bridge port STP state change.
+ */
+int netdev_switch_port_stp_update(struct net_device *dev, u8 state)
+{
+ const struct net_device_ops *ops = dev->netdev_ops;
+
+ if (!ops->ndo_switch_port_stp_update)
+ return -EOPNOTSUPP;
+ WARN_ON(!ops->ndo_switch_parent_id_get);
+ return ops->ndo_switch_port_stp_update(dev, state);
+}
+EXPORT_SYMBOL(netdev_switch_port_stp_update);
--
1.9.3
^ permalink raw reply related
* [patch net-next v4 08/21] net-sysfs: expose physical switch id for particular device
From: Jiri Pirko @ 2014-11-27 10:40 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, jasowang, ebiederm, nicolas.dichtel, ryazanov.s.a,
buytenh, aviadr, nbd, alexei.starovoitov, Neil.Jerram, ronye,
simon.horman, alexander.h.duyck, john.ronciak, mleitner, shrijeet,
gospo, bcrl, hemal
In-Reply-To: <1417084826-9875-1-git-send-email-jiri@resnulli.us>
Signed-off-by: Jiri Pirko <jiri@resnulli.us>
Reviewed-by: Thomas Graf <tgraf@suug.ch>
Acked-by: John Fastabend <john.r.fastabend@intel.com>
Acked-by: Andy Gospodarek <gospo@cumulusnetworks.com>
Acked-by: Florian Fainelli <f.fainelli@gmail.com>
---
v3->v4:
-added entry to Documentation/ABI/testing/sysfs-class-net as suggested
by Florian
v2->v3:
-changed "sw" string to "switch" to avoid confusion
v1->v2:
-no change
---
Documentation/ABI/testing/sysfs-class-net | 8 ++++++++
net/core/net-sysfs.c | 24 ++++++++++++++++++++++++
2 files changed, 32 insertions(+)
diff --git a/Documentation/ABI/testing/sysfs-class-net b/Documentation/ABI/testing/sysfs-class-net
index e1b2e78..beb8ec4 100644
--- a/Documentation/ABI/testing/sysfs-class-net
+++ b/Documentation/ABI/testing/sysfs-class-net
@@ -216,3 +216,11 @@ Contact: netdev@vger.kernel.org
Description:
Indicates the interface protocol type as a decimal value. See
include/uapi/linux/if_arp.h for all possible values.
+
+What: /sys/class/net/<iface>/phys_switch_id
+Date: November 2014
+KernelVersion: 3.19
+Contact: netdev@vger.kernel.org
+Description:
+ Indicates the unique physical switch identifier of a switch this
+ port belongs to, as a string.
diff --git a/net/core/net-sysfs.c b/net/core/net-sysfs.c
index 26c46f4..9993412 100644
--- a/net/core/net-sysfs.c
+++ b/net/core/net-sysfs.c
@@ -12,6 +12,7 @@
#include <linux/capability.h>
#include <linux/kernel.h>
#include <linux/netdevice.h>
+#include <net/switchdev.h>
#include <linux/if_arp.h>
#include <linux/slab.h>
#include <linux/nsproxy.h>
@@ -416,6 +417,28 @@ static ssize_t phys_port_id_show(struct device *dev,
}
static DEVICE_ATTR_RO(phys_port_id);
+static ssize_t phys_switch_id_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct net_device *netdev = to_net_dev(dev);
+ ssize_t ret = -EINVAL;
+
+ if (!rtnl_trylock())
+ return restart_syscall();
+
+ if (dev_isalive(netdev)) {
+ struct netdev_phys_item_id ppid;
+
+ ret = netdev_switch_parent_id_get(netdev, &ppid);
+ if (!ret)
+ ret = sprintf(buf, "%*phN\n", ppid.id_len, ppid.id);
+ }
+ rtnl_unlock();
+
+ return ret;
+}
+static DEVICE_ATTR_RO(phys_switch_id);
+
static struct attribute *net_class_attrs[] = {
&dev_attr_netdev_group.attr,
&dev_attr_type.attr,
@@ -441,6 +464,7 @@ static struct attribute *net_class_attrs[] = {
&dev_attr_tx_queue_len.attr,
&dev_attr_gro_flush_timeout.attr,
&dev_attr_phys_port_id.attr,
+ &dev_attr_phys_switch_id.attr,
NULL,
};
ATTRIBUTE_GROUPS(net_class);
--
1.9.3
^ permalink raw reply related
* [patch net-next v4 07/21] rtnl: expose physical switch id for particular device
From: Jiri Pirko @ 2014-11-27 10:40 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, jasowang, ebiederm, nicolas.dichtel, ryazanov.s.a,
buytenh, aviadr, nbd, alexei.starovoitov, Neil.Jerram, ronye,
simon.horman, alexander.h.duyck, john.ronciak, mleitner, shrijeet,
gospo, bcrl, hemal
In-Reply-To: <1417084826-9875-1-git-send-email-jiri@resnulli.us>
The netdevice represents a port in a switch, it will expose
IFLA_PHYS_SWITCH_ID value via rtnl. Two netdevices with the same value
belong to one physical switch.
Signed-off-by: Jiri Pirko <jiri@resnulli.us>
Reviewed-by: Thomas Graf <tgraf@suug.ch>
Acked-by: John Fastabend <john.r.fastabend@intel.com>
Acked-by: Andy Gospodarek <gospo@cumulusnetworks.com>
---
v3->v4:
-no change
v2->v3:
-changed "sw" string to "switch" to avoid confusion
v1->v2:
-no change
---
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 36bddc2..623f1a7 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 7c59c02..b6541f2 100644
--- a/net/core/rtnetlink.c
+++ b/net/core/rtnetlink.c
@@ -44,6 +44,7 @@
#include <linux/inet.h>
#include <linux/netdevice.h>
+#include <net/switchdev.h>
#include <net/ip.h>
#include <net/protocol.h>
#include <net/arp.h>
@@ -869,7 +870,8 @@ static noinline size_t if_nlmsg_size(const struct net_device *dev,
+ rtnl_port_size(dev, ext_filter_mask) /* 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)
@@ -968,6 +970,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 = netdev_switch_parent_id_get(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)
@@ -1040,6 +1060,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)
@@ -1199,6 +1222,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.3
^ permalink raw reply related
* [patch net-next v4 06/21] net: introduce generic switch devices support
From: Jiri Pirko @ 2014-11-27 10:40 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, jasowang, ebiederm, nicolas.dichtel, ryazanov.s.a,
buytenh, aviadr, nbd, alexei.starovoitov, Neil.Jerram, ronye,
simon.horman, alexander.h.duyck, john.ronciak, mleitner, shrijeet,
gospo, bcrl, hemal
In-Reply-To: <1417084826-9875-1-git-send-email-jiri@resnulli.us>
The goal of this is to provide a possibility to support various switch
chips. Drivers should implement relevant ndos to do so. Now there is
only one ndo defined:
- for getting physical switch id is in place.
Note that user can use random port netdevice to access the switch.
Signed-off-by: Jiri Pirko <jiri@resnulli.us>
Reviewed-by: Thomas Graf <tgraf@suug.ch>
Acked-by: Andy Gospodarek <gospo@cumulusnetworks.com>
---
v3->v4:
-no change
v2->v3:
-fixed documentation typo pointed out by M. Braun
-changed "sw" string to "switch" to avoid confusion
v1->v2:
-no change
---
Documentation/networking/switchdev.txt | 59 ++++++++++++++++++++++++++++++++++
MAINTAINERS | 7 ++++
include/linux/netdevice.h | 10 ++++++
include/net/switchdev.h | 30 +++++++++++++++++
net/Kconfig | 1 +
net/Makefile | 3 ++
net/switchdev/Kconfig | 13 ++++++++
net/switchdev/Makefile | 5 +++
net/switchdev/switchdev.c | 33 +++++++++++++++++++
9 files changed, 161 insertions(+)
create mode 100644 Documentation/networking/switchdev.txt
create mode 100644 include/net/switchdev.h
create mode 100644 net/switchdev/Kconfig
create mode 100644 net/switchdev/Makefile
create mode 100644 net/switchdev/switchdev.c
diff --git a/Documentation/networking/switchdev.txt b/Documentation/networking/switchdev.txt
new file mode 100644
index 0000000..f981a92
--- /dev/null
+++ b/Documentation/networking/switchdev.txt
@@ -0,0 +1,59 @@
+Switch (and switch-ish) device drivers HOWTO
+===========================
+
+Please note that the word "switch" is here used in very generic meaning.
+This include devices supporting L2/L3 but also various flow offloading chips,
+including switches embedded into SR-IOV NICs.
+
+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_switch_parent_id_get - 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_switch_parent_* - Functions that serve for a manipulation of the switch
+ chip itself (it can be though of as a "parent" of the
+ port, therefore the name). They are not port-specific.
+ Caller might use arbitrary port netdevice of the same
+ switch and it will make no difference.
+ ndo_switch_port_* - Functions that serve for a port-specific manipulation.
diff --git a/MAINTAINERS b/MAINTAINERS
index a545d68..05addb6 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -9058,6 +9058,13 @@ F: lib/swiotlb.c
F: arch/*/kernel/pci-swiotlb.c
F: include/linux/swiotlb.h
+SWITCHDEV
+M: Jiri Pirko <jiri@resnulli.us>
+L: netdev@vger.kernel.org
+S: Supported
+F: net/switchdev/
+F: include/net/switchdev.h
+
SYNOPSYS ARC ARCHITECTURE
M: Vineet Gupta <vgupta@synopsys.com>
S: Supported
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index 4bd41d7..3603f31 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -1018,6 +1018,12 @@ typedef u16 (*select_queue_fallback_t)(struct net_device *dev,
* performing GSO on a packet. The device returns true if it is
* able to GSO the packet, false otherwise. If the return value is
* false the stack will do software GSO.
+ *
+ * int (*ndo_switch_parent_id_get)(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);
@@ -1171,6 +1177,10 @@ struct net_device_ops {
int (*ndo_get_lock_subclass)(struct net_device *dev);
bool (*ndo_gso_check) (struct sk_buff *skb,
struct net_device *dev);
+#ifdef CONFIG_NET_SWITCHDEV
+ int (*ndo_switch_parent_id_get)(struct net_device *dev,
+ struct netdev_phys_item_id *psid);
+#endif
};
/**
diff --git a/include/net/switchdev.h b/include/net/switchdev.h
new file mode 100644
index 0000000..7a52360
--- /dev/null
+++ b/include/net/switchdev.h
@@ -0,0 +1,30 @@
+/*
+ * include/net/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>
+
+#ifdef CONFIG_NET_SWITCHDEV
+
+int netdev_switch_parent_id_get(struct net_device *dev,
+ struct netdev_phys_item_id *psid);
+
+#else
+
+static inline int netdev_switch_parent_id_get(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 99815b5..ff9ffc1 100644
--- a/net/Kconfig
+++ b/net/Kconfig
@@ -228,6 +228,7 @@ source "net/vmw_vsock/Kconfig"
source "net/netlink/Kconfig"
source "net/mpls/Kconfig"
source "net/hsr/Kconfig"
+source "net/switchdev/Kconfig"
config RPS
boolean
diff --git a/net/Makefile b/net/Makefile
index 7ed1970..95fc694 100644
--- a/net/Makefile
+++ b/net/Makefile
@@ -73,3 +73,6 @@ obj-$(CONFIG_OPENVSWITCH) += openvswitch/
obj-$(CONFIG_VSOCKETS) += vmw_vsock/
obj-$(CONFIG_NET_MPLS_GSO) += mpls/
obj-$(CONFIG_HSR) += hsr/
+ifneq ($(CONFIG_NET_SWITCHDEV),)
+obj-y += switchdev/
+endif
diff --git a/net/switchdev/Kconfig b/net/switchdev/Kconfig
new file mode 100644
index 0000000..1557545
--- /dev/null
+++ b/net/switchdev/Kconfig
@@ -0,0 +1,13 @@
+#
+# Configuration for Switch device support
+#
+
+config NET_SWITCHDEV
+ boolean "Switch (and switch-ish) device support (EXPERIMENTAL)"
+ depends on INET
+ ---help---
+ This module provides glue between core networking code and device
+ drivers in order to support hardware switch chips in very generic
+ meaning of the word "switch". This include devices supporting L2/L3 but
+ also various flow offloading chips, including switches embedded into
+ SR-IOV NICs.
diff --git a/net/switchdev/Makefile b/net/switchdev/Makefile
new file mode 100644
index 0000000..5ed63ed
--- /dev/null
+++ b/net/switchdev/Makefile
@@ -0,0 +1,5 @@
+#
+# Makefile for the Switch device API
+#
+
+obj-$(CONFIG_NET_SWITCHDEV) += switchdev.o
diff --git a/net/switchdev/switchdev.c b/net/switchdev/switchdev.c
new file mode 100644
index 0000000..66973de
--- /dev/null
+++ b/net/switchdev/switchdev.c
@@ -0,0 +1,33 @@
+/*
+ * net/switchdev/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 <net/switchdev.h>
+
+/**
+ * netdev_switch_parent_id_get - Get ID of a switch
+ * @dev: port device
+ * @psid: switch ID
+ *
+ * Get ID of a switch this port is part of.
+ */
+int netdev_switch_parent_id_get(struct net_device *dev,
+ struct netdev_phys_item_id *psid)
+{
+ const struct net_device_ops *ops = dev->netdev_ops;
+
+ if (!ops->ndo_switch_parent_id_get)
+ return -EOPNOTSUPP;
+ return ops->ndo_switch_parent_id_get(dev, psid);
+}
+EXPORT_SYMBOL(netdev_switch_parent_id_get);
--
1.9.3
^ permalink raw reply related
* [patch net-next v4 05/21] net: rename netdev_phys_port_id to more generic name
From: Jiri Pirko @ 2014-11-27 10:40 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, jasowang, ebiederm, nicolas.dichtel, ryazanov.s.a,
buytenh, aviadr, nbd, alexei.starovoitov, Neil.Jerram, ronye,
simon.horman, alexander.h.duyck, john.ronciak, mleitner, shrijeet,
gospo, bcrl, hemal
In-Reply-To: <1417084826-9875-1-git-send-email-jiri@resnulli.us>
So this can be reused for identification of other "items" as well.
Signed-off-by: Jiri Pirko <jiri@resnulli.us>
Reviewed-by: Thomas Graf <tgraf@suug.ch>
Acked-by: John Fastabend <john.r.fastabend@intel.com>
Acked-by: Andy Gospodarek <gospo@cumulusnetworks.com>
Acked-by: Jamal Hadi Salim <jhs@mojatatu.com>
---
v1->v2->v3->v4:
-no change
---
drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c | 2 +-
drivers/net/ethernet/intel/i40e/i40e_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 +++---
8 files changed, 17 insertions(+), 17 deletions(-)
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
index c4bd025..336ef3c 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
@@ -12537,7 +12537,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/intel/i40e/i40e_main.c b/drivers/net/ethernet/intel/i40e/i40e_main.c
index 5ed5e40..9ae4270 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_main.c
+++ b/drivers/net/ethernet/intel/i40e/i40e_main.c
@@ -7511,7 +7511,7 @@ static void i40e_del_vxlan_port(struct net_device *netdev,
#endif
static int i40e_get_phys_port_id(struct net_device *netdev,
- struct netdev_phys_port_id *ppid)
+ struct netdev_phys_item_id *ppid)
{
struct i40e_netdev_priv *np = netdev_priv(netdev);
struct i40e_pf *pf = np->vsi->back;
diff --git a/drivers/net/ethernet/mellanox/mlx4/en_netdev.c b/drivers/net/ethernet/mellanox/mlx4/en_netdev.c
index b7c9978..1597fb0 100644
--- a/drivers/net/ethernet/mellanox/mlx4/en_netdev.c
+++ b/drivers/net/ethernet/mellanox/mlx4/en_netdev.c
@@ -2259,7 +2259,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 3227c80..1aa25b1 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c
@@ -461,7 +461,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 589929c..4bd41d7 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -754,13 +754,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;
};
@@ -976,7 +976,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.
@@ -1152,7 +1152,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);
@@ -2870,7 +2870,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);
struct sk_buff *validate_xmit_skb_list(struct sk_buff *skb, struct net_device *dev);
struct sk_buff *dev_hard_start_xmit(struct sk_buff *skb, struct net_device *dev,
struct netdev_queue *txq, int *ret);
diff --git a/net/core/dev.c b/net/core/dev.c
index ac48362..0814a56 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -5846,7 +5846,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 1a24602..26c46f4 100644
--- a/net/core/net-sysfs.c
+++ b/net/core/net-sysfs.c
@@ -404,7 +404,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 85d1d76..7c59c02 100644
--- a/net/core/rtnetlink.c
+++ b/net/core/rtnetlink.c
@@ -869,7 +869,7 @@ static noinline size_t if_nlmsg_size(const struct net_device *dev,
+ rtnl_port_size(dev, ext_filter_mask) /* 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)
@@ -953,7 +953,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) {
@@ -1197,7 +1197,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.3
^ permalink raw reply related
* [patch net-next v4 04/21] net: make vid as a parameter for ndo_fdb_add/ndo_fdb_del
From: Jiri Pirko @ 2014-11-27 10:40 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, jasowang, ebiederm, nicolas.dichtel, ryazanov.s.a,
buytenh, aviadr, nbd, alexei.starovoitov, Neil.Jerram, ronye,
simon.horman, alexander.h.duyck, john.ronciak, mleitner, shrijeet,
gospo, bcrl, hemal
In-Reply-To: <1417084826-9875-1-git-send-email-jiri@resnulli.us>
Do the work of parsing NDA_VLAN directly in rtnetlink code, pass simple
u16 vid to drivers from there.
Signed-off-by: Jiri Pirko <jiri@resnulli.us>
Acked-by: Andy Gospodarek <gospo@cumulusnetworks.com>
Acked-by: Jamal Hadi Salim <jhs@mojatatu.com>
Acked-by: John Fastabend <john.r.fastabend@intel.com>
---
v3->v4:
-fixed spelling of "fdb" pointed out by Andy
new in v3
---
drivers/net/ethernet/intel/i40e/i40e_main.c | 2 +-
drivers/net/ethernet/intel/ixgbe/ixgbe_main.c | 4 +-
drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c | 9 +++--
drivers/net/macvlan.c | 4 +-
drivers/net/vxlan.c | 4 +-
include/linux/netdevice.h | 8 ++--
include/linux/rtnetlink.h | 6 ++-
net/bridge/br_fdb.c | 39 ++----------------
net/bridge/br_private.h | 4 +-
net/core/rtnetlink.c | 50 ++++++++++++++++++++----
10 files changed, 70 insertions(+), 60 deletions(-)
diff --git a/drivers/net/ethernet/intel/i40e/i40e_main.c b/drivers/net/ethernet/intel/i40e/i40e_main.c
index 7262077..5ed5e40 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_main.c
+++ b/drivers/net/ethernet/intel/i40e/i40e_main.c
@@ -7536,7 +7536,7 @@ static int i40e_get_phys_port_id(struct net_device *netdev,
*/
static int i40e_ndo_fdb_add(struct ndmsg *ndm, struct nlattr *tb[],
struct net_device *dev,
- const unsigned char *addr,
+ const unsigned char *addr, u16 vid,
u16 flags)
{
struct i40e_netdev_priv *np = netdev_priv(dev);
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
index 932f779..1bad9f4 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
@@ -7708,7 +7708,7 @@ static int ixgbe_set_features(struct net_device *netdev,
static int ixgbe_ndo_fdb_add(struct ndmsg *ndm, struct nlattr *tb[],
struct net_device *dev,
- const unsigned char *addr,
+ const unsigned char *addr, u16 vid,
u16 flags)
{
/* guarantee we can provide a unique filter for the unicast address */
@@ -7717,7 +7717,7 @@ static int ixgbe_ndo_fdb_add(struct ndmsg *ndm, struct nlattr *tb[],
return -ENOMEM;
}
- return ndo_dflt_fdb_add(ndm, tb, dev, addr, flags);
+ return ndo_dflt_fdb_add(ndm, tb, dev, addr, vid, flags);
}
static int ixgbe_ndo_bridge_setlink(struct net_device *dev,
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c
index a913b3a..3227c80 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c
@@ -376,13 +376,14 @@ static int qlcnic_set_mac(struct net_device *netdev, void *p)
}
static int qlcnic_fdb_del(struct ndmsg *ndm, struct nlattr *tb[],
- struct net_device *netdev, const unsigned char *addr)
+ struct net_device *netdev,
+ const unsigned char *addr, u16 vid)
{
struct qlcnic_adapter *adapter = netdev_priv(netdev);
int err = -EOPNOTSUPP;
if (!adapter->fdb_mac_learn)
- return ndo_dflt_fdb_del(ndm, tb, netdev, addr);
+ return ndo_dflt_fdb_del(ndm, tb, netdev, addr, vid);
if ((adapter->flags & QLCNIC_ESWITCH_ENABLED) ||
qlcnic_sriov_check(adapter)) {
@@ -401,13 +402,13 @@ static int qlcnic_fdb_del(struct ndmsg *ndm, struct nlattr *tb[],
static int qlcnic_fdb_add(struct ndmsg *ndm, struct nlattr *tb[],
struct net_device *netdev,
- const unsigned char *addr, u16 flags)
+ const unsigned char *addr, u16 vid, u16 flags)
{
struct qlcnic_adapter *adapter = netdev_priv(netdev);
int err = 0;
if (!adapter->fdb_mac_learn)
- return ndo_dflt_fdb_add(ndm, tb, netdev, addr, flags);
+ return ndo_dflt_fdb_add(ndm, tb, netdev, addr, vid, flags);
if (!(adapter->flags & QLCNIC_ESWITCH_ENABLED) &&
!qlcnic_sriov_check(adapter)) {
diff --git a/drivers/net/macvlan.c b/drivers/net/macvlan.c
index bfb0b6e..a1a3e3e 100644
--- a/drivers/net/macvlan.c
+++ b/drivers/net/macvlan.c
@@ -872,7 +872,7 @@ static int macvlan_vlan_rx_kill_vid(struct net_device *dev,
static int macvlan_fdb_add(struct ndmsg *ndm, struct nlattr *tb[],
struct net_device *dev,
- const unsigned char *addr,
+ const unsigned char *addr, u16 vid,
u16 flags)
{
struct macvlan_dev *vlan = netdev_priv(dev);
@@ -897,7 +897,7 @@ static int macvlan_fdb_add(struct ndmsg *ndm, struct nlattr *tb[],
static int macvlan_fdb_del(struct ndmsg *ndm, struct nlattr *tb[],
struct net_device *dev,
- const unsigned char *addr)
+ const unsigned char *addr, u16 vid)
{
struct macvlan_dev *vlan = netdev_priv(dev);
int err = -EINVAL;
diff --git a/drivers/net/vxlan.c b/drivers/net/vxlan.c
index e9f81d4..7d8013d 100644
--- a/drivers/net/vxlan.c
+++ b/drivers/net/vxlan.c
@@ -849,7 +849,7 @@ static int vxlan_fdb_parse(struct nlattr *tb[], struct vxlan_dev *vxlan,
/* Add static entry (via netlink) */
static int vxlan_fdb_add(struct ndmsg *ndm, struct nlattr *tb[],
struct net_device *dev,
- const unsigned char *addr, u16 flags)
+ const unsigned char *addr, u16 vid, u16 flags)
{
struct vxlan_dev *vxlan = netdev_priv(dev);
/* struct net *net = dev_net(vxlan->dev); */
@@ -885,7 +885,7 @@ static int vxlan_fdb_add(struct ndmsg *ndm, struct nlattr *tb[],
/* Delete entry (via netlink) */
static int vxlan_fdb_delete(struct ndmsg *ndm, struct nlattr *tb[],
struct net_device *dev,
- const unsigned char *addr)
+ const unsigned char *addr, u16 vid)
{
struct vxlan_dev *vxlan = netdev_priv(dev);
struct vxlan_fdb *f;
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index 2cb7724..589929c 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -951,11 +951,11 @@ typedef u16 (*select_queue_fallback_t)(struct net_device *dev,
*
* int (*ndo_fdb_add)(struct ndmsg *ndm, struct nlattr *tb[],
* struct net_device *dev,
- * const unsigned char *addr, u16 flags)
+ * const unsigned char *addr, u16 vid, u16 flags)
* Adds an FDB entry to dev for addr.
* int (*ndo_fdb_del)(struct ndmsg *ndm, struct nlattr *tb[],
* struct net_device *dev,
- * const unsigned char *addr)
+ * const unsigned char *addr, u16 vid)
* Deletes the FDB entry from dev coresponding to addr.
* int (*ndo_fdb_dump)(struct sk_buff *skb, struct netlink_callback *cb,
* struct net_device *dev, struct net_device *filter_dev,
@@ -1128,11 +1128,13 @@ struct net_device_ops {
struct nlattr *tb[],
struct net_device *dev,
const unsigned char *addr,
+ u16 vid,
u16 flags);
int (*ndo_fdb_del)(struct ndmsg *ndm,
struct nlattr *tb[],
struct net_device *dev,
- const unsigned char *addr);
+ const unsigned char *addr,
+ u16 vid);
int (*ndo_fdb_dump)(struct sk_buff *skb,
struct netlink_callback *cb,
struct net_device *dev,
diff --git a/include/linux/rtnetlink.h b/include/linux/rtnetlink.h
index 6cacbce..063f0f5 100644
--- a/include/linux/rtnetlink.h
+++ b/include/linux/rtnetlink.h
@@ -94,11 +94,13 @@ extern int ndo_dflt_fdb_add(struct ndmsg *ndm,
struct nlattr *tb[],
struct net_device *dev,
const unsigned char *addr,
- u16 flags);
+ u16 vid,
+ u16 flags);
extern int ndo_dflt_fdb_del(struct ndmsg *ndm,
struct nlattr *tb[],
struct net_device *dev,
- const unsigned char *addr);
+ const unsigned char *addr,
+ u16 vid);
extern int ndo_dflt_bridge_getlink(struct sk_buff *skb, u32 pid, u32 seq,
struct net_device *dev, u16 mode);
diff --git a/net/bridge/br_fdb.c b/net/bridge/br_fdb.c
index 08ef4e7..b1be971 100644
--- a/net/bridge/br_fdb.c
+++ b/net/bridge/br_fdb.c
@@ -805,33 +805,17 @@ static int __br_fdb_add(struct ndmsg *ndm, struct net_bridge_port *p,
/* Add new permanent fdb entry with RTM_NEWNEIGH */
int br_fdb_add(struct ndmsg *ndm, struct nlattr *tb[],
struct net_device *dev,
- const unsigned char *addr, u16 nlh_flags)
+ const unsigned char *addr, u16 vid, u16 nlh_flags)
{
struct net_bridge_port *p;
int err = 0;
struct net_port_vlans *pv;
- unsigned short vid = VLAN_N_VID;
if (!(ndm->ndm_state & (NUD_PERMANENT|NUD_NOARP|NUD_REACHABLE))) {
pr_info("bridge: RTM_NEWNEIGH with invalid state %#x\n", ndm->ndm_state);
return -EINVAL;
}
- if (tb[NDA_VLAN]) {
- if (nla_len(tb[NDA_VLAN]) != sizeof(unsigned short)) {
- pr_info("bridge: RTM_NEWNEIGH with invalid vlan\n");
- return -EINVAL;
- }
-
- vid = nla_get_u16(tb[NDA_VLAN]);
-
- if (!vid || vid >= VLAN_VID_MASK) {
- pr_info("bridge: RTM_NEWNEIGH with invalid vlan id %d\n",
- vid);
- return -EINVAL;
- }
- }
-
if (is_zero_ether_addr(addr)) {
pr_info("bridge: RTM_NEWNEIGH with invalid ether address\n");
return -EINVAL;
@@ -845,7 +829,7 @@ int br_fdb_add(struct ndmsg *ndm, struct nlattr *tb[],
}
pv = nbp_get_vlan_info(p);
- if (vid != VLAN_N_VID) {
+ if (vid) {
if (!pv || !test_bit(vid, pv->vlan_bitmap)) {
pr_info("bridge: RTM_NEWNEIGH with unconfigured "
"vlan %d on port %s\n", vid, dev->name);
@@ -903,27 +887,12 @@ static int __br_fdb_delete(struct net_bridge_port *p,
/* Remove neighbor entry with RTM_DELNEIGH */
int br_fdb_delete(struct ndmsg *ndm, struct nlattr *tb[],
struct net_device *dev,
- const unsigned char *addr)
+ const unsigned char *addr, u16 vid)
{
struct net_bridge_port *p;
int err;
struct net_port_vlans *pv;
- unsigned short vid = VLAN_N_VID;
-
- if (tb[NDA_VLAN]) {
- if (nla_len(tb[NDA_VLAN]) != sizeof(unsigned short)) {
- pr_info("bridge: RTM_NEWNEIGH with invalid vlan\n");
- return -EINVAL;
- }
- vid = nla_get_u16(tb[NDA_VLAN]);
-
- if (!vid || vid >= VLAN_VID_MASK) {
- pr_info("bridge: RTM_NEWNEIGH with invalid vlan id %d\n",
- vid);
- return -EINVAL;
- }
- }
p = br_port_get_rtnl(dev);
if (p == NULL) {
pr_info("bridge: RTM_DELNEIGH %s not a bridge port\n",
@@ -932,7 +901,7 @@ int br_fdb_delete(struct ndmsg *ndm, struct nlattr *tb[],
}
pv = nbp_get_vlan_info(p);
- if (vid != VLAN_N_VID) {
+ if (vid) {
if (!pv || !test_bit(vid, pv->vlan_bitmap)) {
pr_info("bridge: RTM_DELNEIGH with unconfigured "
"vlan %d on port %s\n", vid, dev->name);
diff --git a/net/bridge/br_private.h b/net/bridge/br_private.h
index 5b37077..1b529da 100644
--- a/net/bridge/br_private.h
+++ b/net/bridge/br_private.h
@@ -404,9 +404,9 @@ void br_fdb_update(struct net_bridge *br, struct net_bridge_port *source,
const unsigned char *addr, u16 vid, bool added_by_user);
int br_fdb_delete(struct ndmsg *ndm, struct nlattr *tb[],
- struct net_device *dev, const unsigned char *addr);
+ struct net_device *dev, const unsigned char *addr, u16 vid);
int br_fdb_add(struct ndmsg *nlh, struct nlattr *tb[], struct net_device *dev,
- const unsigned char *addr, u16 nlh_flags);
+ const unsigned char *addr, u16 vid, u16 nlh_flags);
int br_fdb_dump(struct sk_buff *skb, struct netlink_callback *cb,
struct net_device *dev, struct net_device *fdev, int idx);
int br_fdb_sync_static(struct net_bridge *br, struct net_bridge_port *p);
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c
index a688268..85d1d76 100644
--- a/net/core/rtnetlink.c
+++ b/net/core/rtnetlink.c
@@ -36,6 +36,7 @@
#include <linux/mutex.h>
#include <linux/if_addr.h>
#include <linux/if_bridge.h>
+#include <linux/if_vlan.h>
#include <linux/pci.h>
#include <linux/etherdevice.h>
@@ -2312,7 +2313,7 @@ errout:
int ndo_dflt_fdb_add(struct ndmsg *ndm,
struct nlattr *tb[],
struct net_device *dev,
- const unsigned char *addr,
+ const unsigned char *addr, u16 vid,
u16 flags)
{
int err = -EINVAL;
@@ -2338,6 +2339,28 @@ int ndo_dflt_fdb_add(struct ndmsg *ndm,
}
EXPORT_SYMBOL(ndo_dflt_fdb_add);
+static int fdb_vid_parse(struct nlattr *vlan_attr, u16 *p_vid)
+{
+ u16 vid = 0;
+
+ if (vlan_attr) {
+ if (nla_len(vlan_attr) != sizeof(u16)) {
+ pr_info("PF_BRIDGE: RTM_NEWNEIGH with invalid vlan\n");
+ return -EINVAL;
+ }
+
+ vid = nla_get_u16(vlan_attr);
+
+ if (!vid || vid >= VLAN_VID_MASK) {
+ pr_info("PF_BRIDGE: RTM_NEWNEIGH with invalid vlan id %d\n",
+ vid);
+ return -EINVAL;
+ }
+ }
+ *p_vid = vid;
+ return 0;
+}
+
static int rtnl_fdb_add(struct sk_buff *skb, struct nlmsghdr *nlh)
{
struct net *net = sock_net(skb->sk);
@@ -2345,6 +2368,7 @@ static int rtnl_fdb_add(struct sk_buff *skb, struct nlmsghdr *nlh)
struct nlattr *tb[NDA_MAX+1];
struct net_device *dev;
u8 *addr;
+ u16 vid;
int err;
err = nlmsg_parse(nlh, sizeof(*ndm), tb, NDA_MAX, NULL);
@@ -2370,6 +2394,10 @@ static int rtnl_fdb_add(struct sk_buff *skb, struct nlmsghdr *nlh)
addr = nla_data(tb[NDA_LLADDR]);
+ err = fdb_vid_parse(tb[NDA_VLAN], &vid);
+ if (err)
+ return err;
+
err = -EOPNOTSUPP;
/* Support fdb on master device the net/bridge default case */
@@ -2378,7 +2406,8 @@ static int rtnl_fdb_add(struct sk_buff *skb, struct nlmsghdr *nlh)
struct net_device *br_dev = netdev_master_upper_dev_get(dev);
const struct net_device_ops *ops = br_dev->netdev_ops;
- err = ops->ndo_fdb_add(ndm, tb, dev, addr, nlh->nlmsg_flags);
+ err = ops->ndo_fdb_add(ndm, tb, dev, addr, vid,
+ nlh->nlmsg_flags);
if (err)
goto out;
else
@@ -2389,9 +2418,10 @@ static int rtnl_fdb_add(struct sk_buff *skb, struct nlmsghdr *nlh)
if ((ndm->ndm_flags & NTF_SELF)) {
if (dev->netdev_ops->ndo_fdb_add)
err = dev->netdev_ops->ndo_fdb_add(ndm, tb, dev, addr,
+ vid,
nlh->nlmsg_flags);
else
- err = ndo_dflt_fdb_add(ndm, tb, dev, addr,
+ err = ndo_dflt_fdb_add(ndm, tb, dev, addr, vid,
nlh->nlmsg_flags);
if (!err) {
@@ -2409,7 +2439,7 @@ out:
int ndo_dflt_fdb_del(struct ndmsg *ndm,
struct nlattr *tb[],
struct net_device *dev,
- const unsigned char *addr)
+ const unsigned char *addr, u16 vid)
{
int err = -EINVAL;
@@ -2438,6 +2468,7 @@ static int rtnl_fdb_del(struct sk_buff *skb, struct nlmsghdr *nlh)
struct net_device *dev;
int err = -EINVAL;
__u8 *addr;
+ u16 vid;
if (!netlink_capable(skb, CAP_NET_ADMIN))
return -EPERM;
@@ -2465,6 +2496,10 @@ static int rtnl_fdb_del(struct sk_buff *skb, struct nlmsghdr *nlh)
addr = nla_data(tb[NDA_LLADDR]);
+ err = fdb_vid_parse(tb[NDA_VLAN], &vid);
+ if (err)
+ return err;
+
err = -EOPNOTSUPP;
/* Support fdb on master device the net/bridge default case */
@@ -2474,7 +2509,7 @@ static int rtnl_fdb_del(struct sk_buff *skb, struct nlmsghdr *nlh)
const struct net_device_ops *ops = br_dev->netdev_ops;
if (ops->ndo_fdb_del)
- err = ops->ndo_fdb_del(ndm, tb, dev, addr);
+ err = ops->ndo_fdb_del(ndm, tb, dev, addr, vid);
if (err)
goto out;
@@ -2485,9 +2520,10 @@ static int rtnl_fdb_del(struct sk_buff *skb, struct nlmsghdr *nlh)
/* Embedded bridge, macvlan, and any other device support */
if (ndm->ndm_flags & NTF_SELF) {
if (dev->netdev_ops->ndo_fdb_del)
- err = dev->netdev_ops->ndo_fdb_del(ndm, tb, dev, addr);
+ err = dev->netdev_ops->ndo_fdb_del(ndm, tb, dev, addr,
+ vid);
else
- err = ndo_dflt_fdb_del(ndm, tb, dev, addr);
+ err = ndo_dflt_fdb_del(ndm, tb, dev, addr, vid);
if (!err) {
rtnl_fdb_notify(dev, addr, RTM_DELNEIGH);
--
1.9.3
^ permalink raw reply related
* [patch net-next v4 03/21] bridge: convert flags in fbd entry into bitfields
From: Jiri Pirko @ 2014-11-27 10:40 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, jasowang, ebiederm, nicolas.dichtel, ryazanov.s.a,
buytenh, aviadr, nbd, alexei.starovoitov, Neil.Jerram, ronye,
simon.horman, alexander.h.duyck, john.ronciak, mleitner, shrijeet,
gospo, bcrl, hemal
In-Reply-To: <1417084826-9875-1-git-send-email-jiri@resnulli.us>
Suggested-by: Florian Fainelli <f.fainelli@gmail.com>
Signed-off-by: Jiri Pirko <jiri@resnulli.us>
---
new in v4
---
net/bridge/br_private.h | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/net/bridge/br_private.h b/net/bridge/br_private.h
index 8f3f081..5b37077 100644
--- a/net/bridge/br_private.h
+++ b/net/bridge/br_private.h
@@ -98,9 +98,9 @@ struct net_bridge_fdb_entry
unsigned long updated;
unsigned long used;
mac_addr addr;
- unsigned char is_local;
- unsigned char is_static;
- unsigned char added_by_user;
+ unsigned char is_local:1,
+ is_static:1,
+ added_by_user:1;
__u16 vlan_id;
};
--
1.9.3
^ permalink raw reply related
* [patch net-next v4 02/21] neigh: sort Neighbor Cache Entry Flags
From: Jiri Pirko @ 2014-11-27 10:40 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, jasowang, ebiederm, nicolas.dichtel, ryazanov.s.a,
buytenh, aviadr, nbd, alexei.starovoitov, Neil.Jerram, ronye,
simon.horman, alexander.h.duyck, john.ronciak, mleitner, shrijeet,
gospo, bcrl, hemal
In-Reply-To: <1417084826-9875-1-git-send-email-jiri@resnulli.us>
Suggested-by: Florian Fainelli <f.fainelli@gmail.com>
Signed-off-by: Jiri Pirko <jiri@resnulli.us>
---
new in v4
---
include/uapi/linux/neighbour.h | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/include/uapi/linux/neighbour.h b/include/uapi/linux/neighbour.h
index 4a1d7e9..2f043af 100644
--- a/include/uapi/linux/neighbour.h
+++ b/include/uapi/linux/neighbour.h
@@ -35,11 +35,10 @@ enum {
*/
#define NTF_USE 0x01
-#define NTF_PROXY 0x08 /* == ATF_PUBL */
-#define NTF_ROUTER 0x80
-
#define NTF_SELF 0x02
#define NTF_MASTER 0x04
+#define NTF_PROXY 0x08 /* == ATF_PUBL */
+#define NTF_ROUTER 0x80
/*
* Neighbor Cache Entry States.
--
1.9.3
^ permalink raw reply related
* [patch net-next v4 01/21] bridge: rename fdb_*_hw to fdb_*_hw_addr to avoid confusion
From: Jiri Pirko @ 2014-11-27 10:40 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, jasowang, ebiederm, nicolas.dichtel, ryazanov.s.a,
buytenh, aviadr, nbd, alexei.starovoitov, Neil.Jerram, ronye,
simon.horman, alexander.h.duyck, john.ronciak, mleitner, shrijeet,
gospo, bcrl, hemal
In-Reply-To: <1417084826-9875-1-git-send-email-jiri@resnulli.us>
The current name might seem that this actually offloads the fdb entry to
hw. So rename it to clearly present that this for hardware address
addition/removal.
Signed-off-by: Jiri Pirko <jiri@resnulli.us>
Acked-by: Andy Gospodarek <gospo@cumulusnetworks.com>
Acked-by: Jamal Hadi Salim <jhs@mojatatu.com>
Acked-by: Florian Fainelli <f.fainelli@gmail.com>
---
v3->v4:
-no change
v2->v3:
-moved the patch to the patchset head
new in v2 as suggested by DaveM
---
net/bridge/br_fdb.c | 14 +++++++-------
1 file changed, 7 insertions(+), 7 deletions(-)
diff --git a/net/bridge/br_fdb.c b/net/bridge/br_fdb.c
index 6f6c95c..08ef4e7 100644
--- a/net/bridge/br_fdb.c
+++ b/net/bridge/br_fdb.c
@@ -90,7 +90,7 @@ static void fdb_rcu_free(struct rcu_head *head)
* are then updated with the new information.
* Called under RTNL.
*/
-static void fdb_add_hw(struct net_bridge *br, const unsigned char *addr)
+static void fdb_add_hw_addr(struct net_bridge *br, const unsigned char *addr)
{
int err;
struct net_bridge_port *p;
@@ -118,7 +118,7 @@ undo:
* the ports with needed information.
* Called under RTNL.
*/
-static void fdb_del_hw(struct net_bridge *br, const unsigned char *addr)
+static void fdb_del_hw_addr(struct net_bridge *br, const unsigned char *addr)
{
struct net_bridge_port *p;
@@ -133,7 +133,7 @@ static void fdb_del_hw(struct net_bridge *br, const unsigned char *addr)
static void fdb_delete(struct net_bridge *br, struct net_bridge_fdb_entry *f)
{
if (f->is_static)
- fdb_del_hw(br, f->addr.addr);
+ fdb_del_hw_addr(br, f->addr.addr);
hlist_del_rcu(&f->hlist);
fdb_notify(br, f, RTM_DELNEIGH);
@@ -514,7 +514,7 @@ static int fdb_insert(struct net_bridge *br, struct net_bridge_port *source,
return -ENOMEM;
fdb->is_local = fdb->is_static = 1;
- fdb_add_hw(br, addr);
+ fdb_add_hw_addr(br, addr);
fdb_notify(br, fdb, RTM_NEWNEIGH);
return 0;
}
@@ -754,19 +754,19 @@ static int fdb_add_entry(struct net_bridge_port *source, const __u8 *addr,
fdb->is_local = 1;
if (!fdb->is_static) {
fdb->is_static = 1;
- fdb_add_hw(br, addr);
+ fdb_add_hw_addr(br, addr);
}
} else if (state & NUD_NOARP) {
fdb->is_local = 0;
if (!fdb->is_static) {
fdb->is_static = 1;
- fdb_add_hw(br, addr);
+ fdb_add_hw_addr(br, addr);
}
} else {
fdb->is_local = 0;
if (fdb->is_static) {
fdb->is_static = 0;
- fdb_del_hw(br, addr);
+ fdb_del_hw_addr(br, addr);
}
}
--
1.9.3
^ permalink raw reply related
* [patch net-next v4 00/21] introduce rocker switch driver with hardware accelerated datapath api - phase 1: bridge fdb offload
From: Jiri Pirko @ 2014-11-27 10:40 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, jasowang, ebiederm, nicolas.dichtel, ryazanov.s.a,
buytenh, aviadr, nbd, alexei.starovoitov, Neil.Jerram, ronye,
simon.horman, alexander.h.duyck, john.ronciak, mleitner, shrijeet,
gospo, bcrl, hemal
Hi all.
This patchset is just the first phase of switch and switch-ish device
support api in kernel. Note that the api will extend.
So what this patchset includes:
- introduce switchdev api skeleton for implementing switch drivers
- introduce rocker switch driver which implements switchdev api fdb and
bridge set/get link ndos
As to the discussion if there is need to have specific class of device
representing the switch itself, so far we found no need to introduce that.
But we are generally ok with the idea and when the time comes and it will
be needed, it can be easily introduced without any disturbance.
This patchset introduces switch id export through rtnetlink and sysfs,
which is similar to what we have for port id in SR-IOV. I will send iproute2
patchset for showing the switch id for port netdevs once this is applied.
This applies also for the PF_BRIDGE and fdb iproute2 patches.
iproute2 patches are now available here:
https://github.com/jpirko/iproute2-rocker
For detailed description and version history, please see individual patches.
In v4 I reordered the patches leaving rocker patches on the end of the patchset.
Jiri Pirko (10):
bridge: rename fdb_*_hw to fdb_*_hw_addr to avoid confusion
neigh: sort Neighbor Cache Entry Flags
bridge: convert flags in fbd entry into bitfields
net: make vid as a parameter for ndo_fdb_add/ndo_fdb_del
net: rename netdev_phys_port_id to more generic name
net: introduce generic switch devices support
rtnl: expose physical switch id for particular device
net-sysfs: expose physical switch id for particular device
rocker: introduce rocker switch driver
rocker: implement ndo_fdb_dump
Scott Feldman (9):
bridge: call netdev_sw_port_stp_update when bridge port STP status
changes
bridge: add API to notify bridge driver of learned FBD on offloaded
device
bridge: move private brport flags to if_bridge.h so port drivers can
use flags
bridge: add new brport flag LEARNING_SYNC
bridge: add new hwmode swdev
bridge: add brport flags to dflt bridge_getlink
rocker: implement rocker ofdpa flow table manipulation
rocker: implement L2 bridge offloading
rocker: add ndo_bridge_setlink/getlink support for learning policy
Thomas Graf (2):
rocker: Add proper validation of Netlink attributes
rocker: Use logical operators on booleans
Documentation/ABI/testing/sysfs-class-net | 8 +
Documentation/networking/switchdev.txt | 59 +
MAINTAINERS | 14 +
drivers/net/ethernet/Kconfig | 1 +
drivers/net/ethernet/Makefile | 1 +
drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c | 2 +-
drivers/net/ethernet/emulex/benet/be_main.c | 3 +-
drivers/net/ethernet/intel/i40e/i40e_main.c | 4 +-
drivers/net/ethernet/intel/ixgbe/ixgbe_main.c | 6 +-
drivers/net/ethernet/mellanox/mlx4/en_netdev.c | 2 +-
drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c | 11 +-
drivers/net/ethernet/rocker/Kconfig | 27 +
drivers/net/ethernet/rocker/Makefile | 5 +
drivers/net/ethernet/rocker/rocker.c | 4374 ++++++++++++++++++++++
drivers/net/ethernet/rocker/rocker.h | 428 +++
drivers/net/macvlan.c | 4 +-
drivers/net/vxlan.c | 4 +-
include/linux/if_bridge.h | 31 +
include/linux/netdevice.h | 39 +-
include/linux/rtnetlink.h | 9 +-
include/net/switchdev.h | 37 +
include/uapi/linux/if_bridge.h | 1 +
include/uapi/linux/if_link.h | 2 +
include/uapi/linux/neighbour.h | 6 +-
net/Kconfig | 1 +
net/Makefile | 3 +
net/bridge/br_fdb.c | 144 +-
net/bridge/br_private.h | 21 +-
net/bridge/br_stp.c | 7 +
net/core/dev.c | 2 +-
net/core/net-sysfs.c | 26 +-
net/core/rtnetlink.c | 119 +-
net/switchdev/Kconfig | 13 +
net/switchdev/Makefile | 5 +
net/switchdev/switchdev.c | 52 +
35 files changed, 5366 insertions(+), 105 deletions(-)
create mode 100644 Documentation/networking/switchdev.txt
create mode 100644 drivers/net/ethernet/rocker/Kconfig
create mode 100644 drivers/net/ethernet/rocker/Makefile
create mode 100644 drivers/net/ethernet/rocker/rocker.c
create mode 100644 drivers/net/ethernet/rocker/rocker.h
create mode 100644 include/net/switchdev.h
create mode 100644 net/switchdev/Kconfig
create mode 100644 net/switchdev/Makefile
create mode 100644 net/switchdev/switchdev.c
--
1.9.3
^ permalink raw reply
* [PATCH] ixgbe, ixgbevf: Add new mbox API to enable MC promiscuous mode
From: Hiroshi Shimamoto @ 2014-11-27 10:39 UTC (permalink / raw)
To: e1000-devel@lists.sourceforge.net
Cc: netdev@vger.kernel.org, Choi, Sy Jong, Hayato Momma,
linux-kernel@vger.kernel.org
From: Hiroshi Shimamoto <h-shimamoto@ct.jp.nec.com>
The limitation of the number of multicast address for VF is not enough
for the large scale server with SR-IOV feature.
IPv6 requires the multicast MAC address for each IP address to handle
the Neighbor Solicitation message.
We couldn't assign over 30 IPv6 addresses to a single VF interface.
The easy way to solve this is enabling multicast promiscuous mode.
It is good to have a functionality to enable multicast promiscuous mode
for each VF from VF driver.
This patch introduces the new mbox API, IXGBE_VF_SET_MC_PROMISC, to
enable/disable multicast promiscuous mode in VF. If multicast promiscuous
mode is enabled the VF can receive all multicast packets.
With this patch, the ixgbevf driver automatically enable multicast
promiscuous mode when the number of multicast addresses is over than 30
if possible.
This also bump the API version up to 1.2 to check whether the API,
IXGBE_VF_SET_MC_PROMISC is available.
Signed-off-by: Hiroshi Shimamoto <h-shimamoto@ct.jp.nec.com>
CC: Choi, Sy Jong <sy.jong.choi@intel.com>
Reviewed-by: Hayato Momma <h-momma@ce.jp.nec.com>
---
drivers/net/ethernet/intel/ixgbe/ixgbe.h | 1 +
drivers/net/ethernet/intel/ixgbe/ixgbe_mbx.h | 4 ++
drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c | 80 +++++++++++++++++++++++
drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c | 13 +++-
drivers/net/ethernet/intel/ixgbevf/mbx.h | 4 ++
drivers/net/ethernet/intel/ixgbevf/vf.c | 29 +++++++-
drivers/net/ethernet/intel/ixgbevf/vf.h | 1 +
7 files changed, 130 insertions(+), 2 deletions(-)
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe.h b/drivers/net/ethernet/intel/ixgbe/ixgbe.h
index 5032a60..2a5e3d3 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe.h
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe.h
@@ -144,6 +144,7 @@ struct vf_data_storage {
u16 vlans_enabled;
bool clear_to_send;
bool pf_set_mac;
+ bool vf_mc_promisc;
u16 pf_vlan; /* When set, guest VLAN config not allowed. */
u16 pf_qos;
u16 tx_rate;
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_mbx.h b/drivers/net/ethernet/intel/ixgbe/ixgbe_mbx.h
index a5cb755..2963557 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_mbx.h
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_mbx.h
@@ -73,6 +73,7 @@ enum ixgbe_pfvf_api_rev {
ixgbe_mbox_api_10, /* API version 1.0, linux/freebsd VF driver */
ixgbe_mbox_api_20, /* API version 2.0, solaris Phase1 VF driver */
ixgbe_mbox_api_11, /* API version 1.1, linux/freebsd VF driver */
+ ixgbe_mbox_api_12, /* API version 1.2, linux/freebsd VF driver */
/* This value should always be last */
ixgbe_mbox_api_unknown, /* indicates that API version is not known */
};
@@ -91,6 +92,9 @@ enum ixgbe_pfvf_api_rev {
/* mailbox API, version 1.1 VF requests */
#define IXGBE_VF_GET_QUEUES 0x09 /* get queue configuration */
+/* mailbox API, version 1.2 VF requests */
+#define IXGBE_VF_SET_MC_PROMISC 0x0a /* VF requests PF to set MC promiscuous */
+
/* GET_QUEUES return data indices within the mailbox */
#define IXGBE_VF_TX_QUEUES 1 /* number of Tx queues supported */
#define IXGBE_VF_RX_QUEUES 2 /* number of Rx queues supported */
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c
index 01f7081..427993c 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c
@@ -108,6 +108,10 @@ static int __ixgbe_enable_sriov(struct ixgbe_adapter *adapter)
adapter->flags2 &= ~(IXGBE_FLAG2_RSC_CAPABLE |
IXGBE_FLAG2_RSC_ENABLED);
+ /* Disable multicast promiscuous mode of each VF at first */
+ for (i = 0; i < adapter->num_vfs; i++)
+ adapter->vfinfo[i].vf_mc_promisc = false;
+
/* enable spoof checking for all VFs */
for (i = 0; i < adapter->num_vfs; i++)
adapter->vfinfo[i].spoofchk_enabled = true;
@@ -310,6 +314,46 @@ int ixgbe_pci_sriov_configure(struct pci_dev *dev, int num_vfs)
return ixgbe_pci_sriov_enable(dev, num_vfs);
}
+static int ixgbe_enable_vf_mc_promisc(struct ixgbe_adapter * adapter, u32 vf)
+{
+ struct ixgbe_hw *hw;
+ u32 vmolr;
+
+ if (adapter->vfinfo[vf].vf_mc_promisc)
+ return 0;
+
+ hw = &adapter->hw;
+ vmolr = IXGBE_READ_REG(hw, IXGBE_VMOLR(vf));
+
+ e_info(drv, "VF %u: enabling multicast promiscuous\n", vf);
+
+ vmolr |= IXGBE_VMOLR_MPE;
+
+ IXGBE_WRITE_REG(hw, IXGBE_VMOLR(vf), vmolr);
+
+ return 0;
+}
+
+static int ixgbe_disable_vf_mc_promisc(struct ixgbe_adapter * adapter, u32 vf)
+{
+ struct ixgbe_hw *hw;
+ u32 vmolr;
+
+ if (!adapter->vfinfo[vf].vf_mc_promisc)
+ return 0;
+
+ hw = &adapter->hw;
+ vmolr = IXGBE_READ_REG(hw, IXGBE_VMOLR(vf));
+
+ e_info(drv, "VF %u: disabling multicast promiscuous\n", vf);
+
+ vmolr &= ~IXGBE_VMOLR_MPE;
+
+ IXGBE_WRITE_REG(hw, IXGBE_VMOLR(vf), vmolr);
+
+ return 0;
+}
+
static int ixgbe_set_vf_multicasts(struct ixgbe_adapter *adapter,
u32 *msgbuf, u32 vf)
{
@@ -324,6 +368,9 @@ static int ixgbe_set_vf_multicasts(struct ixgbe_adapter *adapter,
u32 mta_reg;
u32 vmolr = IXGBE_READ_REG(hw, IXGBE_VMOLR(vf));
+ /* Disable multicast promiscuous first */
+ ixgbe_disable_vf_mc_promisc(adapter, vf);
+
/* only so many hash values supported */
entries = min(entries, IXGBE_MAX_VF_MC_ENTRIES);
@@ -426,6 +473,7 @@ static s32 ixgbe_set_vf_lpe(struct ixgbe_adapter *adapter, u32 *msgbuf, u32 vf)
#endif /* CONFIG_FCOE */
switch (adapter->vfinfo[vf].vf_api) {
case ixgbe_mbox_api_11:
+ case ixgbe_mbox_api_12:
/*
* Version 1.1 supports jumbo frames on VFs if PF has
* jumbo frames enabled which means legacy VFs are
@@ -696,6 +744,9 @@ static int ixgbe_vf_reset_msg(struct ixgbe_adapter *adapter, u32 vf)
IXGBE_WRITE_REG(hw, IXGBE_PVFTDWBALn(q_per_pool, vf, i), 0);
}
+ /* Disable multicast promiscuous at reset */
+ ixgbe_disable_vf_mc_promisc(adapter, vf);
+
/* reply to reset with ack and vf mac address */
msgbuf[0] = IXGBE_VF_RESET;
if (!is_zero_ether_addr(vf_mac)) {
@@ -884,6 +935,12 @@ static int ixgbe_negotiate_vf_api(struct ixgbe_adapter *adapter,
switch (api) {
case ixgbe_mbox_api_10:
case ixgbe_mbox_api_11:
+ case ixgbe_mbox_api_12:
+ e_info(drv, "VF %d requested api_version %s\n", vf,
+ (api == ixgbe_mbox_api_12) ? "ixgbe_mbox_api_12" :
+ (api == ixgbe_mbox_api_11) ? "ixgbe_mbox_api_11" :
+ (api == ixgbe_mbox_api_10) ? "ixgbe_mbox_api_10" :
+ "unknown");
adapter->vfinfo[vf].vf_api = api;
return 0;
default:
@@ -907,6 +964,7 @@ static int ixgbe_get_vf_queues(struct ixgbe_adapter *adapter,
switch (adapter->vfinfo[vf].vf_api) {
case ixgbe_mbox_api_20:
case ixgbe_mbox_api_11:
+ case ixgbe_mbox_api_12:
break;
default:
return -1;
@@ -934,6 +992,25 @@ static int ixgbe_get_vf_queues(struct ixgbe_adapter *adapter,
return 0;
}
+static int ixgbe_set_vf_mc_promisc(struct ixgbe_adapter *adapter,
+ u32 *msgbuf, u32 vf)
+{
+ bool enable = !!msgbuf[1]; /* msgbuf contains the flag to enable */
+
+ switch (adapter->vfinfo[vf].vf_api) {
+ case ixgbe_mbox_api_12:
+ break;
+ default:
+ return -1;
+ }
+
+ if (enable)
+ return ixgbe_enable_vf_mc_promisc(adapter, vf);
+ else
+ return ixgbe_disable_vf_mc_promisc(adapter, vf);
+}
+
+
static int ixgbe_rcv_msg_from_vf(struct ixgbe_adapter *adapter, u32 vf)
{
u32 mbx_size = IXGBE_VFMAILBOX_SIZE;
@@ -990,6 +1067,9 @@ static int ixgbe_rcv_msg_from_vf(struct ixgbe_adapter *adapter, u32 vf)
case IXGBE_VF_GET_QUEUES:
retval = ixgbe_get_vf_queues(adapter, msgbuf, vf);
break;
+ case IXGBE_VF_SET_MC_PROMISC:
+ retval = ixgbe_set_vf_mc_promisc(adapter, msgbuf, vf);
+ break;
default:
e_err(drv, "Unhandled Msg %8.8x\n", msgbuf[0]);
retval = IXGBE_ERR_MBX;
diff --git a/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c b/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c
index 030a219..3615bdb 100644
--- a/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c
+++ b/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c
@@ -1635,7 +1635,8 @@ static void ixgbevf_init_last_counter_stats(struct ixgbevf_adapter *adapter)
static void ixgbevf_negotiate_api(struct ixgbevf_adapter *adapter)
{
struct ixgbe_hw *hw = &adapter->hw;
- int api[] = { ixgbe_mbox_api_11,
+ int api[] = { ixgbe_mbox_api_12,
+ ixgbe_mbox_api_11,
ixgbe_mbox_api_10,
ixgbe_mbox_api_unknown };
int err = 0, idx = 0;
@@ -1649,6 +1650,12 @@ static void ixgbevf_negotiate_api(struct ixgbevf_adapter *adapter)
idx++;
}
+ dev_info(&adapter->pdev->dev, "mbox api_version = %s\n",
+ (hw->api_version == ixgbe_mbox_api_12) ? "ixgbe_mbox_api_12" :
+ (hw->api_version == ixgbe_mbox_api_11) ? "ixgbe_mbox_api_11" :
+ (hw->api_version == ixgbe_mbox_api_10) ? "ixgbe_mbox_api_10" :
+ "unknown");
+
spin_unlock_bh(&adapter->mbx_lock);
}
@@ -1827,6 +1834,9 @@ void ixgbevf_down(struct ixgbevf_adapter *adapter)
netif_carrier_off(netdev);
+ /* drop multicast promiscuous mode flag */
+ adapter->hw.mac.mc_promisc = false;
+
if (!pci_channel_offline(adapter->pdev))
ixgbevf_reset(adapter);
@@ -3279,6 +3289,7 @@ static int ixgbevf_change_mtu(struct net_device *netdev, int new_mtu)
switch (adapter->hw.api_version) {
case ixgbe_mbox_api_11:
+ case ixgbe_mbox_api_12:
max_possible_frame = IXGBE_MAX_JUMBO_FRAME_SIZE;
break;
default:
diff --git a/drivers/net/ethernet/intel/ixgbevf/mbx.h b/drivers/net/ethernet/intel/ixgbevf/mbx.h
index 0bc3005..62ef0d8 100644
--- a/drivers/net/ethernet/intel/ixgbevf/mbx.h
+++ b/drivers/net/ethernet/intel/ixgbevf/mbx.h
@@ -86,6 +86,7 @@ enum ixgbe_pfvf_api_rev {
ixgbe_mbox_api_10, /* API version 1.0, linux/freebsd VF driver */
ixgbe_mbox_api_20, /* API version 2.0, solaris Phase1 VF driver */
ixgbe_mbox_api_11, /* API version 1.1, linux/freebsd VF driver */
+ ixgbe_mbox_api_12, /* API version 1.2, linux/freebsd VF driver */
/* This value should always be last */
ixgbe_mbox_api_unknown, /* indicates that API version is not known */
};
@@ -104,6 +105,9 @@ enum ixgbe_pfvf_api_rev {
/* mailbox API, version 1.1 VF requests */
#define IXGBE_VF_GET_QUEUE 0x09 /* get queue configuration */
+/* mailbox API, version 1.2 VF requests */
+#define IXGBE_VF_SET_MC_PROMISC 0x0a /* VF requests PF to set MC promiscuous */
+
/* GET_QUEUES return data indices within the mailbox */
#define IXGBE_VF_TX_QUEUES 1 /* number of Tx queues supported */
#define IXGBE_VF_RX_QUEUES 2 /* number of Rx queues supported */
diff --git a/drivers/net/ethernet/intel/ixgbevf/vf.c b/drivers/net/ethernet/intel/ixgbevf/vf.c
index 9cddd56..43c1ee3 100644
--- a/drivers/net/ethernet/intel/ixgbevf/vf.c
+++ b/drivers/net/ethernet/intel/ixgbevf/vf.c
@@ -120,6 +120,9 @@ static s32 ixgbevf_reset_hw_vf(struct ixgbe_hw *hw)
memcpy(hw->mac.perm_addr, addr, ETH_ALEN);
hw->mac.mc_filter_type = msgbuf[IXGBE_VF_MC_TYPE_WORD];
+ /* after reset, MC promiscuous mode is disabled */
+ hw->mac.mc_promisc = false;
+
return 0;
}
@@ -327,8 +330,29 @@ static s32 ixgbevf_update_mc_addr_list_vf(struct ixgbe_hw *hw,
*/
cnt = netdev_mc_count(netdev);
- if (cnt > 30)
+ if (cnt > 30) {
+ /*
+ * If the API has the capability to handle MC promiscuous
+ * mode, turn it on.
+ */
+ if (hw->api_version == ixgbe_mbox_api_12) {
+ if (!hw->mac.mc_promisc) {
+ struct ixgbevf_adapter *adapter = hw->back;
+
+ dev_info(&adapter->pdev->dev, "Request MC PROMISC\n");
+
+ /* enabling multicast promiscuous */
+ msgbuf[0] = IXGBE_VF_SET_MC_PROMISC;
+ msgbuf[1] = 1;
+ ixgbevf_write_msg_read_ack(hw, msgbuf, 2);
+
+ hw->mac.mc_promisc = true;
+ }
+
+ return 0;
+ }
cnt = 30;
+ }
msgbuf[0] = IXGBE_VF_SET_MULTICAST;
msgbuf[0] |= cnt << IXGBE_VT_MSGINFO_SHIFT;
@@ -344,6 +368,8 @@ static s32 ixgbevf_update_mc_addr_list_vf(struct ixgbe_hw *hw,
ixgbevf_write_msg_read_ack(hw, msgbuf, IXGBE_VFMAILBOX_SIZE);
+ hw->mac.mc_promisc = false;
+
return 0;
}
@@ -545,6 +571,7 @@ int ixgbevf_get_queues(struct ixgbe_hw *hw, unsigned int *num_tcs,
/* do nothing if API doesn't support ixgbevf_get_queues */
switch (hw->api_version) {
case ixgbe_mbox_api_11:
+ case ixgbe_mbox_api_12:
break;
default:
return 0;
diff --git a/drivers/net/ethernet/intel/ixgbevf/vf.h b/drivers/net/ethernet/intel/ixgbevf/vf.h
index aa8cc8d..59d8cf3 100644
--- a/drivers/net/ethernet/intel/ixgbevf/vf.h
+++ b/drivers/net/ethernet/intel/ixgbevf/vf.h
@@ -85,6 +85,7 @@ struct ixgbe_mac_info {
enum ixgbe_mac_type type;
s32 mc_filter_type;
+ bool mc_promisc;
bool get_link_status;
u32 max_tx_queues;
--
1.9.0
------------------------------------------------------------------------------
Download BIRT iHub F-Type - The Free Enterprise-Grade BIRT Server
from Actuate! Instantly Supercharge Your Business Reports and Dashboards
with Interactivity, Sharing, Native Excel Exports, App Integration & more
Get technology previously reserved for billion-dollar corporations, FREE
http://pubads.g.doubleclick.net/gampad/clk?id=157005751&iu=/4140/ostg.clktrk
_______________________________________________
E1000-devel mailing list
E1000-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/e1000-devel
To learn more about Intel® Ethernet, visit http://communities.intel.com/community/wired
^ permalink raw reply related
* Re: Is this 32-bit NCM?
From: Bjørn Mork @ 2014-11-27 10:03 UTC (permalink / raw)
To: Enrico Mioso; +Cc: youtux, alexxst, linux-usb, netdev
In-Reply-To: <alpine.LNX.2.03.1411271037050.9464@gmail.com>
Enrico Mioso <mrkiko.rs@gmail.com> writes:
> Ok - we can arrive to some ocnclusions regarding the E3272.
> First of all - the modem seems buggy enough to not be able to handle requests
> for different formats. You need to unplug and re-plug it, but this is onlyan
> impression and is reasonable.
>
> Then - the modem will accept to ndisdup the connection with
> at^ndisdup=1,1,"internet"
> but - if we use huawei_cdc_ncm + cdc_ncm we have no flow handling messages and
> the modem stops here.
> If we use the cdc_ncm 32-bit driver (modified) we get lotfs of
> ^dsflorpt
> that's how it should be.
> So I think we can say that something is changing.
> Then there's the alignment problem you mentioned in your previous reply. And
> this is hard to solve.
> could you try to help me understand where the problem is?
> I feel like we are very close to the solution but something isn't working.
> Or might be just try to change the 16 bit driver?
If you use a recent version of the driver as a basis, then you get the
CDC NCM NTB parameters in sysfs (if not, then you need to enable
debugging and look in the log for these values). For example:
bjorn@nemi:~$ grep . /sys/class/net/wwan0/cdc_ncm/*
/sys/class/net/wwan0/cdc_ncm/bmNtbFormatsSupported:0x0001
/sys/class/net/wwan0/cdc_ncm/dwNtbInMaxSize:15360
/sys/class/net/wwan0/cdc_ncm/dwNtbOutMaxSize:15360
/sys/class/net/wwan0/cdc_ncm/min_tx_pkt:13824
/sys/class/net/wwan0/cdc_ncm/rx_max:15360
/sys/class/net/wwan0/cdc_ncm/tx_max:15360
/sys/class/net/wwan0/cdc_ncm/tx_timer_usecs:400
/sys/class/net/wwan0/cdc_ncm/wNdpInAlignment:4
/sys/class/net/wwan0/cdc_ncm/wNdpInDivisor:1
/sys/class/net/wwan0/cdc_ncm/wNdpInPayloadRemainder:0
/sys/class/net/wwan0/cdc_ncm/wNdpOutAlignment:4
/sys/class/net/wwan0/cdc_ncm/wNdpOutDivisor:32
/sys/class/net/wwan0/cdc_ncm/wNdpOutPayloadRemainder:0
/sys/class/net/wwan0/cdc_ncm/wNtbOutMaxDatagrams:32
The possible problem I am thinking of is proper handling of the
wNdp*PayloadRemainder values. See section 3.3.4 "NCM Ethernet Frame
Alignment" in the spec. Which is confusing as hell, but if I understand
it correctly then we are supposed to align the start of the IP packets
(the "payload", _not_ the ethernet frame) to a whole wNdp*Divisor number
as long as the wNdp*PayloadRemainder is 0.
Bjørn
^ permalink raw reply
* Re: [PATCH net] bpf: x86: fix epilogue generation for eBPF programs
From: Daniel Borkmann @ 2014-11-27 9:52 UTC (permalink / raw)
To: Alexei Starovoitov
Cc: David S. Miller, Zi Shen Lim, Eric Dumazet, H. Peter Anvin,
Thomas Gleixner, Ingo Molnar, netdev, linux-kernel
In-Reply-To: <1417064546-4129-1-git-send-email-ast@plumgrid.com>
On 11/27/2014 06:02 AM, Alexei Starovoitov wrote:
> classic BPF has a restriction that last insn is always BPF_RET.
> eBPF doesn't have BPF_RET instruction and this restriction.
> It has BPF_EXIT insn which can appear anywhere in the program
> one or more times and it doesn't have to be last insn.
> Fix eBPF JIT to emit epilogue when first BPF_EXIT is seen
> and all other BPF_EXIT instructions will be emitted as jump.
>
> Signed-off-by: Alexei Starovoitov <ast@plumgrid.com>
> ---
> Note, this bug is applicable only to native eBPF programs
> which first were introduced in 3.18, so no need to send it
> to stable and therefore no 'Fixes' tag.
Btw, even if it's not sent to -stable, a 'Fixes:' tag is useful
information for backporting and regression tracking, preferably
always mentioned where it can clearly be identified.
> arm64 JIT has the same problem, but the fix is not as trivial,
> so will be done as separate patch.
>
> Since 3.18 can only load eBPF programs and cannot execute them,
> this patch can even be done in net-next only, but I think it's worth
> to apply it to 3.18(net), so that JITed output for native eBPF
> programs is correct when bpf syscall loads it with net.core.bpf_jit_enable=2
Yes, sounds good to me, the condition insn_cnt - 1 is still held
with BPF to eBPF transformations.
> arch/x86/net/bpf_jit_comp.c | 6 ++++--
> 1 file changed, 4 insertions(+), 2 deletions(-)
>
> diff --git a/arch/x86/net/bpf_jit_comp.c b/arch/x86/net/bpf_jit_comp.c
> index 3f62734..7e90244 100644
> --- a/arch/x86/net/bpf_jit_comp.c
> +++ b/arch/x86/net/bpf_jit_comp.c
> @@ -178,7 +178,7 @@ static void jit_fill_hole(void *area, unsigned int size)
> }
>
> struct jit_context {
> - unsigned int cleanup_addr; /* epilogue code offset */
> + int cleanup_addr; /* epilogue code offset */
Why this type change here? This seems a bit out of context (I would
have expected a mention of this in the commit message, otherwise).
> bool seen_ld_abs;
> };
>
> @@ -192,6 +192,7 @@ static int do_jit(struct bpf_prog *bpf_prog, int *addrs, u8 *image,
> struct bpf_insn *insn = bpf_prog->insnsi;
> int insn_cnt = bpf_prog->len;
> bool seen_ld_abs = ctx->seen_ld_abs | (oldproglen == 0);
> + bool seen_exit = false;
> u8 temp[BPF_MAX_INSN_SIZE + BPF_INSN_SAFETY];
> int i;
> int proglen = 0;
> @@ -854,10 +855,11 @@ common_load:
> goto common_load;
>
> case BPF_JMP | BPF_EXIT:
> - if (i != insn_cnt - 1) {
> + if (seen_exit) {
> jmp_offset = ctx->cleanup_addr - addrs[i];
> goto emit_jmp;
> }
> + seen_exit = true;
> /* update cleanup_addr */
> ctx->cleanup_addr = proglen;
> /* mov rbx, qword ptr [rbp-X] */
>
^ permalink raw reply
* Re: Is this 32-bit NCM?
From: Enrico Mioso @ 2014-11-27 9:45 UTC (permalink / raw)
To: Bjørn Mork; +Cc: youtux, alexxst, linux-usb, netdev
In-Reply-To: <87ppc957h1.fsf@nemi.mork.no>
Ok - we can arrive to some ocnclusions regarding the E3272.
First of all - the modem seems buggy enough to not be able to handle requests
for different formats. You need to unplug and re-plug it, but this is onlyan
impression and is reasonable.
Then - the modem will accept to ndisdup the connection with
at^ndisdup=1,1,"internet"
but - if we use huawei_cdc_ncm + cdc_ncm we have no flow handling messages and
the modem stops here.
If we use the cdc_ncm 32-bit driver (modified) we get lotfs of
^dsflorpt
that's how it should be.
So I think we can say that something is changing.
Then there's the alignment problem you mentioned in your previous reply. And
this is hard to solve.
could you try to help me understand where the problem is?
I feel like we are very close to the solution but something isn't working.
Or might be just try to change the 16 bit driver?
http://www.gstorm.eu/cdc_ncm.c
^ permalink raw reply
* Re: Is this 32-bit NCM?
From: Enrico Mioso @ 2014-11-27 9:22 UTC (permalink / raw)
To: Bjørn Mork; +Cc: youtux, linux-usb, netdev, Alex Strizhevsky
In-Reply-To: <87ppc957h1.fsf@nemi.mork.no>
[-- Attachment #1: Type: TEXT/PLAIN, Size: 4772 bytes --]
So ... might be this is happening even in 16 bit mode?
With our test device we are having no luck: the firmware now at least prints
dsflowrpt messages, but we seem to not go farther than this.
so - what should we try in your opinion? Go try with the 16 bit mode and try to
fix the alignment issues?
Any help would be greatly apreciated ... this is becoming a personal challenge,
even facing a possibly growing number of devices.
On Thu, 27 Nov 2014, Bjørn Mork wrote:
==Date: Thu, 27 Nov 2014 10:16:26
==From: Bjørn Mork <bjorn@mork.no>
==To: Enrico Mioso <mrkiko.rs@gmail.com>
==Cc: youtux@gmail.com, linux-usb@vger.kernel.org, netdev@vger.kernel.org
==Subject: Re: Is this 32-bit NCM?
==
==Enrico Mioso <mrkiko.rs@gmail.com> writes:
==
==> I am sorry for the indecent capture - but I didn't manage to get a
==> better one till now.
==> We modified the driver: but I wanted to be sure ... is this 32-bit NCM?
==
==
==Yes, it looks OK to me. I have only looked at it manually, so I could
==have missed something. But the signatures and header field lengths seem
==fine.
==
==I did notice one issue though, which might be related to more generic
==alignment bugs in the driver?
==
==The modem sends this. Notice how the single ethernet frame inside starts
==at 0072, skipping 2 unused bytes, making the IP packet start at a 4-byte
==aligned 0080:
==
==0040 6e 63 6d 68 10 00 c7 00 cd 00 00 00 10 00 00 00 ncmh............
==0050 6e 63 6d 30 20 00 00 00 00 00 00 00 00 00 00 00 ncm0 ...........
==0060 32 00 00 00 9b 00 00 00 00 00 00 00 00 00 00 00 2...............
==0070 00 00 0c 5b 8f 27 9a 64 4c 54 99 45 e5 d5 08 00 ...[.'.dLT.E....
==0080 45 00 00 8d 05 7f 40 00 33 06 af d8 95 9a a7 5b E.....@.3......[
==0090 0a 1f 4a ff 01 bb ce 5c c0 d5 a0 ba 8c 57 85 63 ..J....\.....W.c
==00a0 80 18 09 e6 35 0b 00 00 01 01 08 0a 4d 8b 3f fe ....5.......M.?.
==00b0 00 78 a8 a7 16 1a 21 17 60 0e 73 21 c7 d6 77 cd .x....!.`.s!..w.
==00c0 92 00 69 26 54 28 cb 19 25 2a 16 6b 82 6b bf ba ..i&T(..%*.k.k..
==00d0 46 a7 8a 6e eb 36 59 25 eb 9b e2 bb 4b 53 f2 4d F..n.6Y%....KS.M
==00e0 ce 11 dd 88 06 e8 23 24 8a 96 03 d9 61 31 34 9b ......#$....a14.
==00f0 68 f3 e9 5c fd d1 77 5f 18 75 fd 10 4d cb e7 29 h..\..w_.u..M..)
==0100 96 89 3d 75 fe 11 15 82 28 88 5b ba b0 ..=u....(.[..
==
==
==
==While we, after a large number of unused 0 bytes due to the fixed size
==NDP allocation, start the ethernet frame at 01a8, making the IP packet
==start at a 2-byte aligned offset at 01b6:
==
==0040 6e 63 6d 68 10 00 d5 00 aa 01 00 00 10 00 00 00 ncmh............
==0050 6e 63 6d 30 20 00 00 00 00 00 00 00 00 00 00 00 ncm0 ...........
==0060 68 01 00 00 42 00 00 00 00 00 00 00 00 00 00 00 h...B...........
==0070 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
==0080 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
==0090 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
==00a0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
==00b0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
==00c0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
==00d0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
==00e0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
==00f0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
==0100 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
==0110 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
==0120 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
==0130 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
==0140 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
==0150 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
==0160 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
==0170 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
==0180 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
==0190 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
==01a0 00 00 00 00 00 00 00 00 4c 54 99 45 e5 d5 0c 5b ........LT.E...[
==01b0 8f 27 9a 64 08 00 45 00 00 34 84 0b 40 00 40 06 .'.d..E..4..@.@.
==01c0 24 a5 0a 1f 4a ff 95 9a a7 5b ce 5c 01 bb 8c 57 $...J....[.\...W
==01d0 85 63 c0 d5 a1 13 80 10 03 59 0f 23 00 00 01 01 .c.......Y.#....
==01e0 08 0a 00 79 00 6f 4d 8b 3f fe ...y.oM.?.
==
==
==This is not so nice, and I do wonder if it is according to the requested
==alignment from the modem? If not, then that is more likely to break
==stuff than the 16-bit vs 32-bit header issue.
==
==
==
==Bjørn
==
^ permalink raw reply
* [PATCH net] rtnetlink: release net refcnt on error in do_setlink()
From: Nicolas Dichtel @ 2014-11-27 9:16 UTC (permalink / raw)
To: davem; +Cc: netdev, Nicolas Dichtel, Eric W. Biederman
rtnl_link_get_net() holds a reference on the 'struct net', we need to release
it in case of error.
CC: Eric W. Biederman <ebiederm@xmission.com>
Fixes: b51642f6d77b ("net: Enable a userns root rtnl calls that are safe for unprivilged users")
Signed-off-by: Nicolas Dichtel <nicolas.dichtel@6wind.com>
---
net/core/rtnetlink.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c
index b9b7dfaf202b..76321ea442c3 100644
--- a/net/core/rtnetlink.c
+++ b/net/core/rtnetlink.c
@@ -1498,6 +1498,7 @@ static int do_setlink(const struct sk_buff *skb,
goto errout;
}
if (!netlink_ns_capable(skb, net->user_ns, CAP_NET_ADMIN)) {
+ put_net(net);
err = -EPERM;
goto errout;
}
--
2.1.0
^ permalink raw reply related
* Re: Is this 32-bit NCM?
From: Bjørn Mork @ 2014-11-27 9:16 UTC (permalink / raw)
To: Enrico Mioso; +Cc: youtux, linux-usb, netdev
In-Reply-To: <alpine.LNX.2.03.1411262250160.4356@gmail.com>
Enrico Mioso <mrkiko.rs@gmail.com> writes:
> I am sorry for the indecent capture - but I didn't manage to get a
> better one till now.
> We modified the driver: but I wanted to be sure ... is this 32-bit NCM?
Yes, it looks OK to me. I have only looked at it manually, so I could
have missed something. But the signatures and header field lengths seem
fine.
I did notice one issue though, which might be related to more generic
alignment bugs in the driver?
The modem sends this. Notice how the single ethernet frame inside starts
at 0072, skipping 2 unused bytes, making the IP packet start at a 4-byte
aligned 0080:
0040 6e 63 6d 68 10 00 c7 00 cd 00 00 00 10 00 00 00 ncmh............
0050 6e 63 6d 30 20 00 00 00 00 00 00 00 00 00 00 00 ncm0 ...........
0060 32 00 00 00 9b 00 00 00 00 00 00 00 00 00 00 00 2...............
0070 00 00 0c 5b 8f 27 9a 64 4c 54 99 45 e5 d5 08 00 ...[.'.dLT.E....
0080 45 00 00 8d 05 7f 40 00 33 06 af d8 95 9a a7 5b E.....@.3......[
0090 0a 1f 4a ff 01 bb ce 5c c0 d5 a0 ba 8c 57 85 63 ..J....\.....W.c
00a0 80 18 09 e6 35 0b 00 00 01 01 08 0a 4d 8b 3f fe ....5.......M.?.
00b0 00 78 a8 a7 16 1a 21 17 60 0e 73 21 c7 d6 77 cd .x....!.`.s!..w.
00c0 92 00 69 26 54 28 cb 19 25 2a 16 6b 82 6b bf ba ..i&T(..%*.k.k..
00d0 46 a7 8a 6e eb 36 59 25 eb 9b e2 bb 4b 53 f2 4d F..n.6Y%....KS.M
00e0 ce 11 dd 88 06 e8 23 24 8a 96 03 d9 61 31 34 9b ......#$....a14.
00f0 68 f3 e9 5c fd d1 77 5f 18 75 fd 10 4d cb e7 29 h..\..w_.u..M..)
0100 96 89 3d 75 fe 11 15 82 28 88 5b ba b0 ..=u....(.[..
While we, after a large number of unused 0 bytes due to the fixed size
NDP allocation, start the ethernet frame at 01a8, making the IP packet
start at a 2-byte aligned offset at 01b6:
0040 6e 63 6d 68 10 00 d5 00 aa 01 00 00 10 00 00 00 ncmh............
0050 6e 63 6d 30 20 00 00 00 00 00 00 00 00 00 00 00 ncm0 ...........
0060 68 01 00 00 42 00 00 00 00 00 00 00 00 00 00 00 h...B...........
0070 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
0080 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
0090 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00a0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00b0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00c0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00d0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00e0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00f0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
0100 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
0110 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
0120 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
0130 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
0140 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
0150 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
0160 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
0170 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
0180 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
0190 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
01a0 00 00 00 00 00 00 00 00 4c 54 99 45 e5 d5 0c 5b ........LT.E...[
01b0 8f 27 9a 64 08 00 45 00 00 34 84 0b 40 00 40 06 .'.d..E..4..@.@.
01c0 24 a5 0a 1f 4a ff 95 9a a7 5b ce 5c 01 bb 8c 57 $...J....[.\...W
01d0 85 63 c0 d5 a1 13 80 10 03 59 0f 23 00 00 01 01 .c.......Y.#....
01e0 08 0a 00 79 00 6f 4d 8b 3f fe ...y.oM.?.
This is not so nice, and I do wonder if it is according to the requested
alignment from the modem? If not, then that is more likely to break
stuff than the 16-bit vs 32-bit header issue.
Bjørn
^ permalink raw reply
* Re: [PATCH rfc] packet: zerocopy packet_snd
From: Jason Wang @ 2014-11-27 9:10 UTC (permalink / raw)
To: Michael S. Tsirkin
Cc: Willem de Bruijn, Network Development, David Miller, Eric Dumazet,
Daniel Borkmann
In-Reply-To: <20141126211748.GA11904@redhat.com>
On Thu, Nov 27, 2014 at 5:17 AM, Michael S. Tsirkin <mst@redhat.com>
wrote:
> On Wed, Nov 26, 2014 at 02:59:34PM -0500, Willem de Bruijn wrote:
>> > The main problem with zero copy ATM is with queueing disciplines
>> > which might keep the socket around essentially forever.
>> > The case was described here:
>> > https://lkml.org/lkml/2014/1/17/105
>> > and of course this will make it more serious now that
>> > more applications will be able to do this, so
>> > chances that an administrator enables this
>> > are higher.
>>
>> The denial of service issue raised there, that a single queue can
>> block an entire virtio-net device, is less problematic in the case
>> of
>> packet sockets. A socket can run out of sk_wmem_alloc, but a prudent
>> application can increase the limit or use separate sockets for
>> separate flows.
>
> Socket per flow? Maybe just use TCP then? increasing the limit
> sounds like a wrong solution, it hurts security.
>
>> > One possible solution is some kind of timer orphaning frags
>> > for skbs that have been around for too long.
>>
>> Perhaps this can be approximated without an explicit timer by
>> calling
>> skb_copy_ubufs on enqueue whenever qlen exceeds a threshold value?
>
> Hard to say. Will have to see that patch to judge how robust this is.
This could not work, consider if the threshold is greater than vring
size
or vhost_net pending limit, transmission may still be blocked.
^ permalink raw reply
* Re: 3.12.33 Bug with ipvs
From: Julian Anastasov @ 2014-11-27 8:08 UTC (permalink / raw)
To: Smart Weblications GmbH - Florian Wiessner; +Cc: netdev
In-Reply-To: <54763E3F.4020306@smart-weblications.de>
Hello,
On Wed, 26 Nov 2014, Smart Weblications GmbH - Florian Wiessner wrote:
> Hi netdev,
>
> On 3.12.33 i see this every 3 hours or so on a box with ip_vs running with a
> setup which made no problems on 3.10.40. Could someone give me hints how to
> debug this? It seems to happen instantly, when i add ip_vs_ftp and have some nat
> rules. Setup is like this:
>
> [13230.431740] RIP [<ffffffff814ff2fc>] xfrm_selector_match+0x25/0x2f6
> [13230.431772] RSP <ffff88083fd83a68>
> [13230.431795] CR2: 00000000000600d0
> [13230.432240] ---[ end trace 103912aa204977dc ]---
>
> node01:/ocfs2/usr/src/linux-3.12.33/scripts# ./decodecode </tmp/oops.log
> [13230.431464] Code: 5d 41 5e 41 5f c3 41 55 66 83 fa 02 41 54 55 48 89 fd 53 48
> 89 f3 41 50 74 11 31 c0 66 83 fa 0a 0f 85 ce 02 00 00 e9 fd 00 00 00 <0f> b6 47
> 2a 8b 17 8b 76 18 84 c0 74 1a b9 20 00 00 00 31 f2 29
> All code
> ========
> 0: 5d pop %rbp
> 1: 41 5e pop %r14
> 3: 41 5f pop %r15
> 5: c3 retq
> 6: 41 55 push %r13
> 8: 66 83 fa 02 cmp $0x2,%dx
> c: 41 54 push %r12
> e: 55 push %rbp
> f: 48 89 fd mov %rdi,%rbp
> 12: 53 push %rbx
> 13: 48 89 f3 mov %rsi,%rbx
> 16: 41 50 push %r8
> 18: 74 11 je 0x2b
> 1a: 31 c0 xor %eax,%eax
> 1c: 66 83 fa 0a cmp $0xa,%dx
> 20: 0f 85 ce 02 00 00 jne 0x2f4
> 26: e9 fd 00 00 00 jmpq 0x128
> 2b:* 0f b6 47 2a movzbl 0x2a(%rdi),%eax <-- trapping
> instruction
Above instruction is 'sel->prefixlen_d' from
the addr4_match call in __xfrm4_selector_match. Looks like
we dereference sel (%rdi) with bad value of 00000000000600a6.
xfrm_sk_policy_lookup() provides &pol->selector to
xfrm_selector_match, so pol has a bad value. I don't remember
for such problem, not sure if the 3-hour period is some timer
in xfrm.
> Could someone shed some light on the decoded output and point me somewhere so i
> can debug this further?
If noone else has idea what can be wrong, can you try
some kernels between 3.10.40 and 3.12.33 or even some lastest
kernel?
Regards
--
Julian Anastasov <ja@ssi.bg>
^ permalink raw reply
* RE: [patch net-next v3 09/17] bridge: add API to notify bridge driver of learned FBD on offloaded device
From: Arad, Ronen @ 2014-11-27 7:37 UTC (permalink / raw)
To: Scott Feldman; +Cc: netdev@vger.kernel.org
In-Reply-To: <CAE4R7bC9o4ucO_Erb0tU4EwJNYj8SrapbKxNWvUTL8YD=RMBJQ@mail.gmail.com>
> -----Original Message-----
> From: Scott Feldman [mailto:sfeldma@gmail.com]
> Sent: Wednesday, November 26, 2014 11:04 PM
> To: Arad, Ronen
> Cc: netdev@vger.kernel.org
> Subject: Re: [patch net-next v3 09/17] bridge: add API to notify bridge driver
> of learned FBD on offloaded device
>
> On Tue, Nov 25, 2014 at 9:37 PM, Arad, Ronen <ronen.arad@intel.com>
> wrote:
> >> >>>
> >> >>> Is there any case where this fdb entry gets re-used and is no
> >> >>> longer added by an external learning? Should we clear this flag
> somewhere?
> >> >>
> >> >> Once the FDB entry is marked "added_by_external_learn" it stays
> >> >> marked as such until removed by aging cleanup process (or flushed
> >> >> due to interface down, etc). If aged out (and now deleted), the
> >> >> FDB entry may come back either by SW learn or by HW learn. If SW
> >> >> learn comes first, and then HW learn, HW learn will override and
> >> >> mark the existing FDB entry "added_by_external_learn". So there
> >> >> is take-over by HW but no give-back to SW. And there is no
> >> >> explicit clearing of the mark short of deleting the FDB entry.
> >> >> The mark is mostly for letting user's know which FDB entries where
> >> >> learned by HW and synced to the bridge's FDB.
> >> >
> >> > Thanks, makes sense now. This is probably obvious in this context,
> >> > but maybe it would not hurt to come up with a documentation that
> >> > describe the offload API, FDB entry lifetime and HW/SW ownership etc...
> >>
> >> I have an updated Documentation/networking/switchdev.txt that covers
> >> the swdev APIs and usage and notes, but Jiri is being stingy with it.
> >> Will get this out, either in v4 or follow-on patches. There is
> >> enough going on just with L2 offload that we're going to need some
> >> good documentation to guide implementers.
> >> --
> >
> > To control the lifetime of an externally learned FDB entry, the bridge shall
> provide an API for the switch driver to update the freshness of externally
> learned entries. Otherwise, the bridge aging will age entries which are
> currently or frequently used by the HW.
> > Is this covered in the updated document?
> > Is this functionality planned for v4?
>
> Hi Ronen,
>
> It's already there: driver calls br_fdb_external_learn_add() to refresh FBD
> entry, which updates the fdb->updated and fdb->used timestamps,
> preventing bridge from prematurely aging out the entry.
> We'll make sure that detail gets in the doc. It's up to the driver on how
> frequently it calls br_fdb_external_learn_add(). Maybe it just blindly makes
> the call every 1s. That's what rocker driver does (as long as the FDB entry
> continues to get hits). From the user's perspective, 1s update is nice when
> looking at the stats dump for fdbs, since the timestamps are in secs.
>
> -scott
Hi Scott,
Thanks. This should work. I overlooked that but now I see it in the code with a clear comment.
-ronen
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox