* [PATCH net-next v7 2/8] vxlan: Restructure vxlan receive.
From: Pravin B Shelar @ 2013-08-05 17:47 UTC (permalink / raw)
To: netdev; +Cc: stephen, Pravin B Shelar
Use iptunnel_pull_header() for better code sharing.
Signed-off-by: Pravin B Shelar <pshelar@nicira.com>
---
v5-v6:
split from second patch from v5 series.
---
drivers/net/vxlan.c | 22 +++++++---------------
1 files changed, 7 insertions(+), 15 deletions(-)
diff --git a/drivers/net/vxlan.c b/drivers/net/vxlan.c
index 9c3d4f0..1cb55bf 100644
--- a/drivers/net/vxlan.c
+++ b/drivers/net/vxlan.c
@@ -57,6 +57,7 @@
#define VXLAN_VID_MASK (VXLAN_N_VID - 1)
/* IP header + UDP + VXLAN + Ethernet header */
#define VXLAN_HEADROOM (20 + 8 + 8 + 14)
+#define VXLAN_HLEN (sizeof(struct udphdr) + sizeof(struct vxlanhdr))
#define VXLAN_FLAGS 0x08000000 /* struct vxlanhdr.vx_flags required value. */
@@ -868,15 +869,12 @@ static int vxlan_udp_encap_recv(struct sock *sk, struct sk_buff *skb)
__u32 vni;
int err;
- /* pop off outer UDP header */
- __skb_pull(skb, sizeof(struct udphdr));
-
/* Need Vxlan and inner Ethernet header to be present */
- if (!pskb_may_pull(skb, sizeof(struct vxlanhdr)))
+ if (!pskb_may_pull(skb, VXLAN_HLEN))
goto error;
- /* Drop packets with reserved bits set */
- vxh = (struct vxlanhdr *) skb->data;
+ /* Return packets with reserved bits set */
+ vxh = (struct vxlanhdr *)(udp_hdr(skb) + 1);
if (vxh->vx_flags != htonl(VXLAN_FLAGS) ||
(vxh->vx_vni & htonl(0xff))) {
netdev_dbg(skb->dev, "invalid vxlan flags=%#x vni=%#x\n",
@@ -884,8 +882,6 @@ static int vxlan_udp_encap_recv(struct sock *sk, struct sk_buff *skb)
goto error;
}
- __skb_pull(skb, sizeof(struct vxlanhdr));
-
/* Is this VNI defined? */
vni = ntohl(vxh->vx_vni) >> 8;
port = inet_sk(sk)->inet_sport;
@@ -896,7 +892,7 @@ static int vxlan_udp_encap_recv(struct sock *sk, struct sk_buff *skb)
goto drop;
}
- if (!pskb_may_pull(skb, ETH_HLEN)) {
+ if (iptunnel_pull_header(skb, VXLAN_HLEN, htons(ETH_P_TEB))) {
vxlan->dev->stats.rx_length_errors++;
vxlan->dev->stats.rx_errors++;
goto drop;
@@ -904,8 +900,6 @@ static int vxlan_udp_encap_recv(struct sock *sk, struct sk_buff *skb)
skb_reset_mac_header(skb);
- /* Re-examine inner Ethernet packet */
- oip = ip_hdr(skb);
skb->protocol = eth_type_trans(skb, vxlan->dev);
/* Ignore packet loops (and multicast echo) */
@@ -913,11 +907,12 @@ static int vxlan_udp_encap_recv(struct sock *sk, struct sk_buff *skb)
vxlan->dev->dev_addr) == 0)
goto drop;
+ /* Re-examine inner Ethernet packet */
+ oip = ip_hdr(skb);
if ((vxlan->flags & VXLAN_F_LEARN) &&
vxlan_snoop(skb->dev, oip->saddr, eth_hdr(skb)->h_source))
goto drop;
- __skb_tunnel_rx(skb, vxlan->dev);
skb_reset_network_header(skb);
/* If the NIC driver gave us an encapsulated packet with
@@ -953,9 +948,6 @@ static int vxlan_udp_encap_recv(struct sock *sk, struct sk_buff *skb)
return 0;
error:
- /* Put UDP header back */
- __skb_push(skb, sizeof(struct udphdr));
-
return 1;
drop:
/* Consume bad packet */
--
1.7.1
^ permalink raw reply related
* [PATCH net-next v7 7/8] vxlan: Add tx-vlan offload support.
From: Pravin B Shelar @ 2013-08-05 17:47 UTC (permalink / raw)
To: netdev; +Cc: stephen, Pravin B Shelar
Following patch allows transmit side vlan offload for vxlan
devices.
Signed-off-by: Pravin B Shelar <pshelar@nicira.com>
---
v5-v6:
- WARN_ON() style fix.
v2-v3:
- Set NETIF_F_HW_VLAN_STAG_TX feature.
- Added WARN on vlan tag push.
- Fixed hw_features.
---
drivers/net/vxlan.c | 16 +++++++++++++++-
1 files changed, 15 insertions(+), 1 deletions(-)
diff --git a/drivers/net/vxlan.c b/drivers/net/vxlan.c
index 6c52b68..2e3d396 100644
--- a/drivers/net/vxlan.c
+++ b/drivers/net/vxlan.c
@@ -27,6 +27,7 @@
#include <linux/igmp.h>
#include <linux/etherdevice.h>
#include <linux/if_ether.h>
+#include <linux/if_vlan.h>
#include <linux/hash.h>
#include <linux/ethtool.h>
#include <net/arp.h>
@@ -1139,13 +1140,23 @@ int vxlan_xmit_skb(struct net *net, struct vxlan_sock *vs,
}
min_headroom = LL_RESERVED_SPACE(rt->dst.dev) + rt->dst.header_len
- + VXLAN_HLEN + sizeof(struct iphdr);
+ + VXLAN_HLEN + sizeof(struct iphdr)
+ + (vlan_tx_tag_present(skb) ? VLAN_HLEN : 0);
/* Need space for new headers (invalidates iph ptr) */
err = skb_cow_head(skb, min_headroom);
if (unlikely(err))
return err;
+ if (vlan_tx_tag_present(skb)) {
+ if (WARN_ON(!__vlan_put_tag(skb,
+ skb->vlan_proto,
+ vlan_tx_tag_get(skb))))
+ return -ENOMEM;
+
+ skb->vlan_tci = 0;
+ }
+
vxh = (struct vxlanhdr *) __skb_push(skb, sizeof(*vxh));
vxh->vx_flags = htonl(VXLAN_FLAGS);
vxh->vx_vni = vni;
@@ -1560,8 +1571,11 @@ static void vxlan_setup(struct net_device *dev)
dev->features |= NETIF_F_RXCSUM;
dev->features |= NETIF_F_GSO_SOFTWARE;
+ dev->vlan_features = dev->features;
+ dev->features |= NETIF_F_HW_VLAN_CTAG_TX | NETIF_F_HW_VLAN_STAG_TX;
dev->hw_features |= NETIF_F_SG | NETIF_F_HW_CSUM | NETIF_F_RXCSUM;
dev->hw_features |= NETIF_F_GSO_SOFTWARE;
+ dev->hw_features |= NETIF_F_HW_VLAN_CTAG_TX | NETIF_F_HW_VLAN_STAG_TX;
dev->priv_flags &= ~IFF_XMIT_DST_RELEASE;
dev->priv_flags |= IFF_LIVE_ADDR_CHANGE;
--
1.7.1
^ permalink raw reply related
* [PATCH net-next v7 6/8] vxlan: Improve vxlan headroom calculation.
From: Pravin B Shelar @ 2013-08-05 17:47 UTC (permalink / raw)
To: netdev; +Cc: stephen, Pravin B Shelar
Rather than having static headroom calculation, adjust headroom
according to target device.
Signed-off-by: Pravin B Shelar <pshelar@nicira.com>
---
drivers/net/vxlan.c | 13 +++++++++----
1 files changed, 9 insertions(+), 4 deletions(-)
diff --git a/drivers/net/vxlan.c b/drivers/net/vxlan.c
index 190d548..6c52b68 100644
--- a/drivers/net/vxlan.c
+++ b/drivers/net/vxlan.c
@@ -1130,6 +1130,7 @@ int vxlan_xmit_skb(struct net *net, struct vxlan_sock *vs,
{
struct vxlanhdr *vxh;
struct udphdr *uh;
+ int min_headroom;
int err;
if (!skb->encapsulation) {
@@ -1137,6 +1138,14 @@ int vxlan_xmit_skb(struct net *net, struct vxlan_sock *vs,
skb->encapsulation = 1;
}
+ min_headroom = LL_RESERVED_SPACE(rt->dst.dev) + rt->dst.header_len
+ + VXLAN_HLEN + sizeof(struct iphdr);
+
+ /* Need space for new headers (invalidates iph ptr) */
+ err = skb_cow_head(skb, min_headroom);
+ if (unlikely(err))
+ return err;
+
vxh = (struct vxlanhdr *) __skb_push(skb, sizeof(*vxh));
vxh->vx_flags = htonl(VXLAN_FLAGS);
vxh->vx_vni = vni;
@@ -1220,10 +1229,6 @@ static void vxlan_xmit_one(struct sk_buff *skb, struct net_device *dev,
goto drop;
}
- /* Need space for new headers (invalidates iph ptr) */
- if (skb_cow_head(skb, VXLAN_HEADROOM))
- goto drop;
-
old_iph = ip_hdr(skb);
ttl = vxlan->ttl;
--
1.7.1
^ permalink raw reply related
* [PATCH net-next v7 5/8] vxlan: Factor out vxlan send api.
From: Pravin B Shelar @ 2013-08-05 17:47 UTC (permalink / raw)
To: netdev; +Cc: stephen, Pravin B Shelar
Following patch allows more code sharing between vxlan and ovs-vxlan.
Signed-off-by: Pravin B Shelar <pshelar@nicira.com>
---
v1-v2:
- revert back to original names.
---
drivers/net/vxlan.c | 91 ++++++++++++++++++++++++++++++---------------------
include/net/vxlan.h | 8 ++++
2 files changed, 62 insertions(+), 37 deletions(-)
diff --git a/drivers/net/vxlan.c b/drivers/net/vxlan.c
index 8c5a931..190d548 100644
--- a/drivers/net/vxlan.c
+++ b/drivers/net/vxlan.c
@@ -1082,11 +1082,8 @@ static void vxlan_sock_put(struct sk_buff *skb)
}
/* On transmit, associate with the tunnel socket */
-static void vxlan_set_owner(struct net_device *dev, struct sk_buff *skb)
+static void vxlan_set_owner(struct sock *sk, struct sk_buff *skb)
{
- struct vxlan_dev *vxlan = netdev_priv(dev);
- struct sock *sk = vxlan->vn_sock->sock->sk;
-
skb_orphan(skb);
sock_hold(sk);
skb->sk = sk;
@@ -1098,9 +1095,9 @@ static void vxlan_set_owner(struct net_device *dev, struct sk_buff *skb)
* better and maybe available from hardware
* secondary choice is to use jhash on the Ethernet header
*/
-static __be16 vxlan_src_port(const struct vxlan_dev *vxlan, struct sk_buff *skb)
+__be16 vxlan_src_port(__u16 port_min, __u16 port_max, struct sk_buff *skb)
{
- unsigned int range = (vxlan->port_max - vxlan->port_min) + 1;
+ unsigned int range = (port_max - port_min) + 1;
u32 hash;
hash = skb_get_rxhash(skb);
@@ -1108,8 +1105,9 @@ static __be16 vxlan_src_port(const struct vxlan_dev *vxlan, struct sk_buff *skb)
hash = jhash(skb->data, 2 * ETH_ALEN,
(__force u32) skb->protocol);
- return htons((((u64) hash * range) >> 32) + vxlan->port_min);
+ return htons((((u64) hash * range) >> 32) + port_min);
}
+EXPORT_SYMBOL_GPL(vxlan_src_port);
static int handle_offloads(struct sk_buff *skb)
{
@@ -1125,6 +1123,45 @@ static int handle_offloads(struct sk_buff *skb)
return 0;
}
+int vxlan_xmit_skb(struct net *net, struct vxlan_sock *vs,
+ struct rtable *rt, struct sk_buff *skb,
+ __be32 src, __be32 dst, __u8 tos, __u8 ttl, __be16 df,
+ __be16 src_port, __be16 dst_port, __be32 vni)
+{
+ struct vxlanhdr *vxh;
+ struct udphdr *uh;
+ int err;
+
+ if (!skb->encapsulation) {
+ skb_reset_inner_headers(skb);
+ skb->encapsulation = 1;
+ }
+
+ vxh = (struct vxlanhdr *) __skb_push(skb, sizeof(*vxh));
+ vxh->vx_flags = htonl(VXLAN_FLAGS);
+ vxh->vx_vni = vni;
+
+ __skb_push(skb, sizeof(*uh));
+ skb_reset_transport_header(skb);
+ uh = udp_hdr(skb);
+
+ uh->dest = dst_port;
+ uh->source = src_port;
+
+ uh->len = htons(skb->len);
+ uh->check = 0;
+
+ vxlan_set_owner(vs->sock->sk, skb);
+
+ err = handle_offloads(skb);
+ if (err)
+ return err;
+
+ return iptunnel_xmit(net, rt, skb, src, dst,
+ IPPROTO_UDP, tos, ttl, df);
+}
+EXPORT_SYMBOL_GPL(vxlan_xmit_skb);
+
/* Bypass encapsulation if the destination is local */
static void vxlan_encap_bypass(struct sk_buff *skb, struct vxlan_dev *src_vxlan,
struct vxlan_dev *dst_vxlan)
@@ -1162,8 +1199,6 @@ static void vxlan_xmit_one(struct sk_buff *skb, struct net_device *dev,
struct vxlan_dev *vxlan = netdev_priv(dev);
struct rtable *rt;
const struct iphdr *old_iph;
- struct vxlanhdr *vxh;
- struct udphdr *uh;
struct flowi4 fl4;
__be32 dst;
__be16 src_port, dst_port;
@@ -1185,11 +1220,6 @@ static void vxlan_xmit_one(struct sk_buff *skb, struct net_device *dev,
goto drop;
}
- if (!skb->encapsulation) {
- skb_reset_inner_headers(skb);
- skb->encapsulation = 1;
- }
-
/* Need space for new headers (invalidates iph ptr) */
if (skb_cow_head(skb, VXLAN_HEADROOM))
goto drop;
@@ -1204,7 +1234,7 @@ static void vxlan_xmit_one(struct sk_buff *skb, struct net_device *dev,
if (tos == 1)
tos = ip_tunnel_get_dsfield(old_iph, skb);
- src_port = vxlan_src_port(vxlan, skb);
+ src_port = vxlan_src_port(vxlan->port_min, vxlan->port_max, skb);
memset(&fl4, 0, sizeof(fl4));
fl4.flowi4_oif = rdst->remote_ifindex;
@@ -1221,9 +1251,8 @@ static void vxlan_xmit_one(struct sk_buff *skb, struct net_device *dev,
if (rt->dst.dev == dev) {
netdev_dbg(dev, "circular route to %pI4\n", &dst);
- ip_rt_put(rt);
dev->stats.collisions++;
- goto tx_error;
+ goto rt_tx_error;
}
/* Bypass encapsulation if the destination is local */
@@ -1238,30 +1267,16 @@ static void vxlan_xmit_one(struct sk_buff *skb, struct net_device *dev,
vxlan_encap_bypass(skb, vxlan, dst_vxlan);
return;
}
- vxh = (struct vxlanhdr *) __skb_push(skb, sizeof(*vxh));
- vxh->vx_flags = htonl(VXLAN_FLAGS);
- vxh->vx_vni = htonl(vni << 8);
-
- __skb_push(skb, sizeof(*uh));
- skb_reset_transport_header(skb);
- uh = udp_hdr(skb);
-
- uh->dest = dst_port;
- uh->source = src_port;
-
- uh->len = htons(skb->len);
- uh->check = 0;
-
- vxlan_set_owner(dev, skb);
-
- if (handle_offloads(skb))
- goto drop;
tos = ip_tunnel_ecn_encap(tos, old_iph, skb);
ttl = ttl ? : ip4_dst_hoplimit(&rt->dst);
- err = iptunnel_xmit(dev_net(dev), rt, skb, fl4.saddr, dst,
- IPPROTO_UDP, tos, ttl, df);
+ err = vxlan_xmit_skb(dev_net(dev), vxlan->vn_sock, rt, skb,
+ fl4.saddr, dst, tos, ttl, df,
+ src_port, dst_port, htonl(vni << 8));
+
+ if (err < 0)
+ goto rt_tx_error;
iptunnel_xmit_stats(err, &dev->stats, dev->tstats);
return;
@@ -1270,6 +1285,8 @@ drop:
dev->stats.tx_dropped++;
goto tx_free;
+rt_tx_error:
+ ip_rt_put(rt);
tx_error:
dev->stats.tx_errors++;
tx_free:
diff --git a/include/net/vxlan.h b/include/net/vxlan.h
index 43de275..ad342e3 100644
--- a/include/net/vxlan.h
+++ b/include/net/vxlan.h
@@ -28,4 +28,12 @@ struct vxlan_sock *vxlan_sock_add(struct net *net, __be16 port,
bool no_share);
void vxlan_sock_release(struct vxlan_sock *vs);
+
+int vxlan_xmit_skb(struct net *net, struct vxlan_sock *vs,
+ struct rtable *rt, struct sk_buff *skb,
+ __be32 src, __be32 dst, __u8 tos, __u8 ttl, __be16 df,
+ __be16 src_port, __be16 dst_port, __be32 vni);
+
+__be16 vxlan_src_port(__u16 port_min, __u16 port_max, struct sk_buff *skb);
+
#endif
--
1.7.1
^ permalink raw reply related
* [PATCH net-next v7 4/8] vxlan: Extend vxlan handlers for openvswitch.
From: Pravin B Shelar @ 2013-08-05 17:47 UTC (permalink / raw)
To: netdev; +Cc: stephen, Pravin B Shelar
Following patch adds data field to vxlan socket and export
vxlan handler api.
vh->data is required to store private data per vxlan handler.
Signed-off-by: Pravin B Shelar <pshelar@nicira.com>
---
drivers/net/vxlan.c | 45 +++++++++++++++++++--------------------------
include/net/vxlan.h | 31 +++++++++++++++++++++++++++++++
2 files changed, 50 insertions(+), 26 deletions(-)
create mode 100644 include/net/vxlan.h
diff --git a/drivers/net/vxlan.c b/drivers/net/vxlan.c
index b54953a..8c5a931 100644
--- a/drivers/net/vxlan.c
+++ b/drivers/net/vxlan.c
@@ -41,6 +41,7 @@
#include <net/inet_ecn.h>
#include <net/net_namespace.h>
#include <net/netns/generic.h>
+#include <net/vxlan.h>
#define VXLAN_VERSION "0.1"
@@ -83,20 +84,6 @@ static int vxlan_net_id;
static const u8 all_zeros_mac[ETH_ALEN];
-struct vxlan_sock;
-typedef void (vxlan_rcv_t)(struct vxlan_sock *vh, struct sk_buff *skb, __be32 key);
-
-/* per UDP socket information */
-struct vxlan_sock {
- vxlan_rcv_t *rcv;
- struct hlist_node hlist;
- struct rcu_head rcu;
- struct work_struct del_work;
- atomic_t refcnt;
- struct socket *sock;
- struct hlist_head vni_list[VNI_HASH_SIZE];
-};
-
/* per-network namespace private data for this module */
struct vxlan_net {
struct list_head vxlan_list;
@@ -813,8 +800,10 @@ static void vxlan_sock_hold(struct vxlan_sock *vs)
atomic_inc(&vs->refcnt);
}
-static void vxlan_sock_release(struct vxlan_net *vn, struct vxlan_sock *vs)
+void vxlan_sock_release(struct vxlan_sock *vs)
{
+ struct vxlan_net *vn = net_generic(sock_net(vs->sock->sk), vxlan_net_id);
+
if (!atomic_dec_and_test(&vs->refcnt))
return;
@@ -824,6 +813,7 @@ static void vxlan_sock_release(struct vxlan_net *vn, struct vxlan_sock *vs)
queue_work(vxlan_wq, &vs->del_work);
}
+EXPORT_SYMBOL_GPL(vxlan_sock_release);
/* Callback to update multicast group membership when first VNI on
* multicast asddress is brought up
@@ -832,7 +822,6 @@ static void vxlan_sock_release(struct vxlan_net *vn, struct vxlan_sock *vs)
static void vxlan_igmp_join(struct work_struct *work)
{
struct vxlan_dev *vxlan = container_of(work, struct vxlan_dev, igmp_join);
- struct vxlan_net *vn = net_generic(dev_net(vxlan->dev), vxlan_net_id);
struct vxlan_sock *vs = vxlan->vn_sock;
struct sock *sk = vs->sock->sk;
struct ip_mreqn mreq = {
@@ -844,7 +833,7 @@ static void vxlan_igmp_join(struct work_struct *work)
ip_mc_join_group(sk, &mreq);
release_sock(sk);
- vxlan_sock_release(vn, vs);
+ vxlan_sock_release(vs);
dev_put(vxlan->dev);
}
@@ -852,7 +841,6 @@ static void vxlan_igmp_join(struct work_struct *work)
static void vxlan_igmp_leave(struct work_struct *work)
{
struct vxlan_dev *vxlan = container_of(work, struct vxlan_dev, igmp_leave);
- struct vxlan_net *vn = net_generic(dev_net(vxlan->dev), vxlan_net_id);
struct vxlan_sock *vs = vxlan->vn_sock;
struct sock *sk = vs->sock->sk;
struct ip_mreqn mreq = {
@@ -864,7 +852,7 @@ static void vxlan_igmp_leave(struct work_struct *work)
ip_mc_leave_group(sk, &mreq);
release_sock(sk);
- vxlan_sock_release(vn, vs);
+ vxlan_sock_release(vs);
dev_put(vxlan->dev);
}
@@ -1429,13 +1417,12 @@ static void vxlan_fdb_delete_default(struct vxlan_dev *vxlan)
static void vxlan_uninit(struct net_device *dev)
{
struct vxlan_dev *vxlan = netdev_priv(dev);
- struct vxlan_net *vn = net_generic(dev_net(dev), vxlan_net_id);
struct vxlan_sock *vs = vxlan->vn_sock;
vxlan_fdb_delete_default(vxlan);
if (vs)
- vxlan_sock_release(vn, vs);
+ vxlan_sock_release(vs);
free_percpu(dev->tstats);
}
@@ -1653,7 +1640,7 @@ static void vxlan_del_work(struct work_struct *work)
}
static struct vxlan_sock *vxlan_socket_create(struct net *net, __be16 port,
- vxlan_rcv_t *rcv)
+ vxlan_rcv_t *rcv, void *data)
{
struct vxlan_net *vn = net_generic(net, vxlan_net_id);
struct vxlan_sock *vs;
@@ -1700,6 +1687,7 @@ static struct vxlan_sock *vxlan_socket_create(struct net *net, __be16 port,
}
atomic_set(&vs->refcnt, 1);
vs->rcv = rcv;
+ vs->data = data;
/* Disable multicast loopback */
inet_sk(sk)->mc_loop = 0;
@@ -1714,16 +1702,20 @@ static struct vxlan_sock *vxlan_socket_create(struct net *net, __be16 port,
return vs;
}
-static struct vxlan_sock *vxlan_sock_add(struct net *net, __be16 port,
- vxlan_rcv_t *rcv)
+struct vxlan_sock *vxlan_sock_add(struct net *net, __be16 port,
+ vxlan_rcv_t *rcv, void *data,
+ bool no_share)
{
struct vxlan_net *vn = net_generic(net, vxlan_net_id);
struct vxlan_sock *vs;
- vs = vxlan_socket_create(net, port, rcv);
+ vs = vxlan_socket_create(net, port, rcv, data);
if (!IS_ERR(vs))
return vs;
+ if (no_share) /* Return error if sharing is not allowed. */
+ return vs;
+
spin_lock(&vn->sock_lock);
vs = vxlan_find_sock(net, port);
if (vs) {
@@ -1739,6 +1731,7 @@ static struct vxlan_sock *vxlan_sock_add(struct net *net, __be16 port,
return vs;
}
+EXPORT_SYMBOL_GPL(vxlan_sock_add);
/* Scheduled at device creation to bind to a socket */
static void vxlan_sock_work(struct work_struct *work)
@@ -1749,7 +1742,7 @@ static void vxlan_sock_work(struct work_struct *work)
__be16 port = vxlan->dst_port;
struct vxlan_sock *nvs;
- nvs = vxlan_sock_add(net, port, vxlan_rcv);
+ nvs = vxlan_sock_add(net, port, vxlan_rcv, NULL, false);
spin_lock(&vn->sock_lock);
if (!IS_ERR(nvs))
vxlan_vs_add_dev(nvs, vxlan);
diff --git a/include/net/vxlan.h b/include/net/vxlan.h
new file mode 100644
index 0000000..43de275
--- /dev/null
+++ b/include/net/vxlan.h
@@ -0,0 +1,31 @@
+#ifndef __NET_VXLAN_H
+#define __NET_VXLAN_H 1
+
+#include <linux/skbuff.h>
+#include <linux/netdevice.h>
+#include <linux/udp.h>
+
+#define VNI_HASH_BITS 10
+#define VNI_HASH_SIZE (1<<VNI_HASH_BITS)
+
+struct vxlan_sock;
+typedef void (vxlan_rcv_t)(struct vxlan_sock *vh, struct sk_buff *skb, __be32 key);
+
+/* per UDP socket information */
+struct vxlan_sock {
+ struct hlist_node hlist;
+ vxlan_rcv_t *rcv;
+ void *data;
+ struct work_struct del_work;
+ struct socket *sock;
+ struct rcu_head rcu;
+ struct hlist_head vni_list[VNI_HASH_SIZE];
+ atomic_t refcnt;
+};
+
+struct vxlan_sock *vxlan_sock_add(struct net *net, __be16 port,
+ vxlan_rcv_t *rcv, void *data,
+ bool no_share);
+
+void vxlan_sock_release(struct vxlan_sock *vs);
+#endif
--
1.7.1
^ permalink raw reply related
* [PATCH net-next v7 0/8] openvswitch: VXLAN tunneling.
From: Pravin B Shelar @ 2013-08-05 17:47 UTC (permalink / raw)
To: netdev; +Cc: stephen, Pravin B Shelar
First four vxlan patches extends vxlan so that openvswitch
can share vxlan recv code. Rest of patches refactors vxlan
data plane so that ovs can share that code with vxlan module.
Last patch adds vxlan-vport to openvswitch.
v7 fixed first patch as suggested by Stephen Hemminger.
v6 series splits second patch into two and has few style fixes.
v5 series disallow any udp port sharing between
kernel-vxlan and ovs-vxlan as suggested by Stephen Hemminger.
Pravin B Shelar (8):
vxlan: Restructure vxlan socket apis.
vxlan: Restructure vxlan receive.
vxlan: Add vxlan recv demux.
vxlan: Extend vxlan handlers for openvswitch.
vxlan: Factor out vxlan send api.
vxlan: Improve vxlan headroom calculation.
vxlan: Add tx-vlan offload support.
openvswitch: Add vxlan tunneling support.
drivers/net/vxlan.c | 342 ++++++++++++++++++++++----------------
include/net/vxlan.h | 39 +++++
include/uapi/linux/openvswitch.h | 11 ++
net/openvswitch/Kconfig | 13 ++
net/openvswitch/Makefile | 4 +
net/openvswitch/vport-vxlan.c | 204 +++++++++++++++++++++++
net/openvswitch/vport.c | 3 +
net/openvswitch/vport.h | 1 +
8 files changed, 477 insertions(+), 140 deletions(-)
create mode 100644 include/net/vxlan.h
create mode 100644 net/openvswitch/vport-vxlan.c
^ permalink raw reply
* [PATCH net-next v7 3/8] vxlan: Add vxlan recv demux.
From: Pravin B Shelar @ 2013-08-05 17:47 UTC (permalink / raw)
To: netdev; +Cc: stephen, Pravin B Shelar
Once we have ovs-vxlan functionality, one UDP port can be assigned
to kernel-vxlan or ovs-vxlan port. Therefore following patch adds
vxlan demux functionality, so that vxlan or ovs module can
register for particular port.
Signed-off-by: Pravin B Shelar <pshelar@nicira.com>
---
v5-v6:
split from second patch from v5 patch series.
---
drivers/net/vxlan.c | 103 +++++++++++++++++++++++++++++++++------------------
1 files changed, 67 insertions(+), 36 deletions(-)
diff --git a/drivers/net/vxlan.c b/drivers/net/vxlan.c
index 1cb55bf..b54953a 100644
--- a/drivers/net/vxlan.c
+++ b/drivers/net/vxlan.c
@@ -83,8 +83,12 @@ static int vxlan_net_id;
static const u8 all_zeros_mac[ETH_ALEN];
+struct vxlan_sock;
+typedef void (vxlan_rcv_t)(struct vxlan_sock *vh, struct sk_buff *skb, __be32 key);
+
/* per UDP socket information */
struct vxlan_sock {
+ vxlan_rcv_t *rcv;
struct hlist_node hlist;
struct rcu_head rcu;
struct work_struct del_work;
@@ -200,16 +204,10 @@ static struct vxlan_sock *vxlan_find_sock(struct net *net, __be16 port)
return NULL;
}
-/* Look up VNI in a per net namespace table */
-static struct vxlan_dev *vxlan_find_vni(struct net *net, u32 id, __be16 port)
+static struct vxlan_dev *vxlan_vs_find_vni(struct vxlan_sock *vs, u32 id)
{
- struct vxlan_sock *vs;
struct vxlan_dev *vxlan;
- vs = vxlan_find_sock(net, port);
- if (!vs)
- return NULL;
-
hlist_for_each_entry_rcu(vxlan, vni_head(vs, id), hlist) {
if (vxlan->default_dst.remote_vni == id)
return vxlan;
@@ -218,6 +216,18 @@ static struct vxlan_dev *vxlan_find_vni(struct net *net, u32 id, __be16 port)
return NULL;
}
+/* Look up VNI in a per net namespace table */
+static struct vxlan_dev *vxlan_find_vni(struct net *net, u32 id, __be16 port)
+{
+ struct vxlan_sock *vs;
+
+ vs = vxlan_find_sock(net, port);
+ if (!vs)
+ return NULL;
+
+ return vxlan_vs_find_vni(vs, id);
+}
+
/* Fill in neighbour message in skbuff. */
static int vxlan_fdb_info(struct sk_buff *skb, struct vxlan_dev *vxlan,
const struct vxlan_fdb *fdb,
@@ -861,13 +871,9 @@ static void vxlan_igmp_leave(struct work_struct *work)
/* Callback from net/ipv4/udp.c to receive packets */
static int vxlan_udp_encap_recv(struct sock *sk, struct sk_buff *skb)
{
- struct iphdr *oip;
+ struct vxlan_sock *vs;
struct vxlanhdr *vxh;
- struct vxlan_dev *vxlan;
- struct pcpu_tstats *stats;
__be16 port;
- __u32 vni;
- int err;
/* Need Vxlan and inner Ethernet header to be present */
if (!pskb_may_pull(skb, VXLAN_HLEN))
@@ -882,24 +888,44 @@ static int vxlan_udp_encap_recv(struct sock *sk, struct sk_buff *skb)
goto error;
}
- /* Is this VNI defined? */
- vni = ntohl(vxh->vx_vni) >> 8;
+ if (iptunnel_pull_header(skb, VXLAN_HLEN, htons(ETH_P_TEB)))
+ goto drop;
+
port = inet_sk(sk)->inet_sport;
- vxlan = vxlan_find_vni(sock_net(sk), vni, port);
- if (!vxlan) {
- netdev_dbg(skb->dev, "unknown vni %d port %u\n",
- vni, ntohs(port));
+
+ vs = vxlan_find_sock(sock_net(sk), port);
+ if (!vs)
goto drop;
- }
- if (iptunnel_pull_header(skb, VXLAN_HLEN, htons(ETH_P_TEB))) {
- vxlan->dev->stats.rx_length_errors++;
- vxlan->dev->stats.rx_errors++;
+ vs->rcv(vs, skb, vxh->vx_vni);
+ return 0;
+
+drop:
+ /* Consume bad packet */
+ kfree_skb(skb);
+ return 0;
+
+error:
+ /* Return non vxlan pkt */
+ return 1;
+}
+
+static void vxlan_rcv(struct vxlan_sock *vs,
+ struct sk_buff *skb, __be32 vx_vni)
+{
+ struct iphdr *oip;
+ struct vxlan_dev *vxlan;
+ struct pcpu_tstats *stats;
+ __u32 vni;
+ int err;
+
+ vni = ntohl(vx_vni) >> 8;
+ /* Is this VNI defined? */
+ vxlan = vxlan_vs_find_vni(vs, vni);
+ if (!vxlan)
goto drop;
- }
skb_reset_mac_header(skb);
-
skb->protocol = eth_type_trans(skb, vxlan->dev);
/* Ignore packet loops (and multicast echo) */
@@ -946,13 +972,10 @@ static int vxlan_udp_encap_recv(struct sock *sk, struct sk_buff *skb)
netif_rx(skb);
- return 0;
-error:
- return 1;
+ return;
drop:
/* Consume bad packet */
kfree_skb(skb);
- return 0;
}
static int arp_reduce(struct net_device *dev, struct sk_buff *skb)
@@ -1629,7 +1652,8 @@ static void vxlan_del_work(struct work_struct *work)
kfree_rcu(vs, rcu);
}
-static struct vxlan_sock *vxlan_socket_create(struct net *net, __be16 port)
+static struct vxlan_sock *vxlan_socket_create(struct net *net, __be16 port,
+ vxlan_rcv_t *rcv)
{
struct vxlan_net *vn = net_generic(net, vxlan_net_id);
struct vxlan_sock *vs;
@@ -1675,6 +1699,7 @@ static struct vxlan_sock *vxlan_socket_create(struct net *net, __be16 port)
return ERR_PTR(rc);
}
atomic_set(&vs->refcnt, 1);
+ vs->rcv = rcv;
/* Disable multicast loopback */
inet_sk(sk)->mc_loop = 0;
@@ -1689,23 +1714,29 @@ static struct vxlan_sock *vxlan_socket_create(struct net *net, __be16 port)
return vs;
}
-static struct vxlan_sock *vxlan_sock_add(struct net *net, __be16 port)
+static struct vxlan_sock *vxlan_sock_add(struct net *net, __be16 port,
+ vxlan_rcv_t *rcv)
{
struct vxlan_net *vn = net_generic(net, vxlan_net_id);
struct vxlan_sock *vs;
- vs = vxlan_socket_create(net, port);
+ vs = vxlan_socket_create(net, port, rcv);
if (!IS_ERR(vs))
return vs;
spin_lock(&vn->sock_lock);
vs = vxlan_find_sock(net, port);
- if (vs)
- atomic_inc(&vs->refcnt);
- else
+ if (vs) {
+ if (vs->rcv == rcv)
+ atomic_inc(&vs->refcnt);
+ else
+ vs = ERR_PTR(-EBUSY);
+ }
+ spin_unlock(&vn->sock_lock);
+
+ if (!vs)
vs = ERR_PTR(-EINVAL);
- spin_unlock(&vn->sock_lock);
return vs;
}
@@ -1718,7 +1749,7 @@ static void vxlan_sock_work(struct work_struct *work)
__be16 port = vxlan->dst_port;
struct vxlan_sock *nvs;
- nvs = vxlan_sock_add(net, port);
+ nvs = vxlan_sock_add(net, port, vxlan_rcv);
spin_lock(&vn->sock_lock);
if (!IS_ERR(nvs))
vxlan_vs_add_dev(nvs, vxlan);
--
1.7.1
^ permalink raw reply related
* [PATCH net-next v7 1/8] vxlan: Restructure vxlan socket apis.
From: Pravin B Shelar @ 2013-08-05 17:47 UTC (permalink / raw)
To: netdev; +Cc: stephen, Pravin B Shelar
Restructure vxlan-socket management APIs so that it can be
shared between ovs.
This patch does not change any functionality.
Signed-off-by: Pravin B Shelar <pshelar@nicira.com>
v6-v7:
- get rid of zero refcnt vs from hashtable.
---
drivers/net/vxlan.c | 92 ++++++++++++++++++++++++++++----------------------
1 files changed, 51 insertions(+), 41 deletions(-)
diff --git a/drivers/net/vxlan.c b/drivers/net/vxlan.c
index 8bf31d9..9c3d4f0 100644
--- a/drivers/net/vxlan.c
+++ b/drivers/net/vxlan.c
@@ -188,7 +188,7 @@ static inline struct vxlan_rdst *first_remote_rtnl(struct vxlan_fdb *fdb)
}
/* Find VXLAN socket based on network namespace and UDP port */
-static struct vxlan_sock *vxlan_find_port(struct net *net, __be16 port)
+static struct vxlan_sock *vxlan_find_sock(struct net *net, __be16 port)
{
struct vxlan_sock *vs;
@@ -205,7 +205,7 @@ static struct vxlan_dev *vxlan_find_vni(struct net *net, u32 id, __be16 port)
struct vxlan_sock *vs;
struct vxlan_dev *vxlan;
- vs = vxlan_find_port(net, port);
+ vs = vxlan_find_sock(net, port);
if (!vs)
return NULL;
@@ -1365,25 +1365,31 @@ static void vxlan_cleanup(unsigned long arg)
mod_timer(&vxlan->age_timer, next_timer);
}
+static void vxlan_vs_add_dev(struct vxlan_sock *vs, struct vxlan_dev *vxlan)
+{
+ __u32 vni = vxlan->default_dst.remote_vni;
+
+ vxlan->vn_sock = vs;
+ hlist_add_head_rcu(&vxlan->hlist, vni_head(vs, vni));
+}
+
/* Setup stats when device is created */
static int vxlan_init(struct net_device *dev)
{
struct vxlan_dev *vxlan = netdev_priv(dev);
struct vxlan_net *vn = net_generic(dev_net(dev), vxlan_net_id);
struct vxlan_sock *vs;
- __u32 vni = vxlan->default_dst.remote_vni;
dev->tstats = alloc_percpu(struct pcpu_tstats);
if (!dev->tstats)
return -ENOMEM;
spin_lock(&vn->sock_lock);
- vs = vxlan_find_port(dev_net(dev), vxlan->dst_port);
+ vs = vxlan_find_sock(dev_net(dev), vxlan->dst_port);
if (vs) {
/* If we have a socket with same port already, reuse it */
atomic_inc(&vs->refcnt);
- vxlan->vn_sock = vs;
- hlist_add_head_rcu(&vxlan->hlist, vni_head(vs, vni));
+ vxlan_vs_add_dev(vs, vxlan);
} else {
/* otherwise make new socket outside of RTNL */
dev_hold(dev);
@@ -1633,6 +1639,7 @@ static void vxlan_del_work(struct work_struct *work)
static struct vxlan_sock *vxlan_socket_create(struct net *net, __be16 port)
{
+ struct vxlan_net *vn = net_generic(net, vxlan_net_id);
struct vxlan_sock *vs;
struct sock *sk;
struct sockaddr_in vxlan_addr = {
@@ -1644,8 +1651,10 @@ static struct vxlan_sock *vxlan_socket_create(struct net *net, __be16 port)
unsigned int h;
vs = kmalloc(sizeof(*vs), GFP_KERNEL);
- if (!vs)
+ if (!vs) {
+ pr_debug("memory alocation failure\n");
return ERR_PTR(-ENOMEM);
+ }
for (h = 0; h < VNI_HASH_SIZE; ++h)
INIT_HLIST_HEAD(&vs->vni_list[h]);
@@ -1673,57 +1682,57 @@ static struct vxlan_sock *vxlan_socket_create(struct net *net, __be16 port)
kfree(vs);
return ERR_PTR(rc);
}
+ atomic_set(&vs->refcnt, 1);
/* Disable multicast loopback */
inet_sk(sk)->mc_loop = 0;
+ spin_lock(&vn->sock_lock);
+ hlist_add_head_rcu(&vs->hlist, vs_head(net, port));
+ spin_unlock(&vn->sock_lock);
/* Mark socket as an encapsulation socket. */
udp_sk(sk)->encap_type = 1;
udp_sk(sk)->encap_rcv = vxlan_udp_encap_recv;
udp_encap_enable();
- atomic_set(&vs->refcnt, 1);
+ return vs;
+}
+
+static struct vxlan_sock *vxlan_sock_add(struct net *net, __be16 port)
+{
+ struct vxlan_net *vn = net_generic(net, vxlan_net_id);
+ struct vxlan_sock *vs;
+
+ vs = vxlan_socket_create(net, port);
+ if (!IS_ERR(vs))
+ return vs;
+ spin_lock(&vn->sock_lock);
+ vs = vxlan_find_sock(net, port);
+ if (vs)
+ atomic_inc(&vs->refcnt);
+ else
+ vs = ERR_PTR(-EINVAL);
+
+ spin_unlock(&vn->sock_lock);
return vs;
}
/* Scheduled at device creation to bind to a socket */
static void vxlan_sock_work(struct work_struct *work)
{
- struct vxlan_dev *vxlan
- = container_of(work, struct vxlan_dev, sock_work);
- struct net_device *dev = vxlan->dev;
- struct net *net = dev_net(dev);
- __u32 vni = vxlan->default_dst.remote_vni;
- __be16 port = vxlan->dst_port;
+ struct vxlan_dev *vxlan = container_of(work, struct vxlan_dev, sock_work);
+ struct net *net = dev_net(vxlan->dev);
struct vxlan_net *vn = net_generic(net, vxlan_net_id);
- struct vxlan_sock *nvs, *ovs;
-
- nvs = vxlan_socket_create(net, port);
- if (IS_ERR(nvs)) {
- netdev_err(vxlan->dev, "Can not create UDP socket, %ld\n",
- PTR_ERR(nvs));
- goto out;
- }
+ __be16 port = vxlan->dst_port;
+ struct vxlan_sock *nvs;
+ nvs = vxlan_sock_add(net, port);
spin_lock(&vn->sock_lock);
- /* Look again to see if can reuse socket */
- ovs = vxlan_find_port(net, port);
- if (ovs) {
- atomic_inc(&ovs->refcnt);
- vxlan->vn_sock = ovs;
- hlist_add_head_rcu(&vxlan->hlist, vni_head(ovs, vni));
- spin_unlock(&vn->sock_lock);
-
- sk_release_kernel(nvs->sock->sk);
- kfree(nvs);
- } else {
- vxlan->vn_sock = nvs;
- hlist_add_head_rcu(&nvs->hlist, vs_head(net, port));
- hlist_add_head_rcu(&vxlan->hlist, vni_head(nvs, vni));
- spin_unlock(&vn->sock_lock);
- }
-out:
- dev_put(dev);
+ if (!IS_ERR(nvs))
+ vxlan_vs_add_dev(nvs, vxlan);
+ spin_unlock(&vn->sock_lock);
+
+ dev_put(vxlan->dev);
}
static int vxlan_newlink(struct net *net, struct net_device *dev,
@@ -1840,7 +1849,8 @@ static void vxlan_dellink(struct net_device *dev, struct list_head *head)
flush_workqueue(vxlan_wq);
spin_lock(&vn->sock_lock);
- hlist_del_rcu(&vxlan->hlist);
+ if (!hlist_unhashed(&vxlan->hlist))
+ hlist_del_rcu(&vxlan->hlist);
spin_unlock(&vn->sock_lock);
list_del(&vxlan->next);
--
1.7.1
^ permalink raw reply related
* Re: locating the 'tc actions' hook
From: John Fastabend @ 2013-08-05 16:11 UTC (permalink / raw)
To: Jamal Hadi Salim
Cc: John Fastabend, Stephen Hemminger, Eric Dumazet, Tom Herbert,
netdev
In-Reply-To: <51FCEDCF.8010107@mojatatu.com>
On 08/03/2013 04:47 AM, Jamal Hadi Salim wrote:
> On 13-08-01 07:18 PM, John Fastabend wrote:
>
> [..]
>
>> The first being directly related to the previous per queue rate limiter
>> patch. With rate limiters per queue on a multiqueue device using mq or
>> mqprio I need some mechanism to steer packets to queues. One way to do
>> this is to use mqprio and create a 'tc' with a single queue in it.
>> And then use iptables or netprio_cgroup to steer packets. Another way
>> to do this would be to use 'skbedit queue_mapping' to set the queue from
>> 'tc' but unfortunately with the existing flows the queue has already
>> been selected by the time the classifiers are called.
>
> I am assuming the skb (mark) will be tagged with a proper meaningful
> tag maybe by the driver. Such a tag can be used later up-stack.
>
Actually in the first case here I was considering egress traffic.
Separating the classifier chain from the qdisc allows using the
classifiers to pick a qdisc via queue_mapping because qdisc's are
attached to queues when using sch_mq.
>> Calling into the
>> classifier chain before picking the qdisc would fix this. For flow based
>> QOS with multiqueue devices this type of functionality would be useful.
>>
>
> From your description this seems to be ingress side; so we should be
> able to use that tag if you set it.
>
Sorry I mucked two examples one egress and one ingress together without
clearly stating it. The second case here was ingress the first egress.
>
>> The second thought that I've been piecing together would be to populate
>> the rxhash (or maybe some other field) using the hardware flow
>> classifier in some meaningful way for the ingress qdisc.
>
>
> The rxhash would be useful for further classification or avoiding
> further classification.
>
>> Some of the
>> existing Intel NICs can do this and I believe other vendors have similar
>> capabilities. Although currently with the qdisc lock running around the
>> ingress qdisc the multiqueue devices take a perf hit just by
>> instantiating the ingress qdisc which really is only using the lock to
>> guard some stats and keep the classifier/action chains sane.
>>
>
> Instantiating any qdisc is not a problem. You do it once and are done.
> There are penalties with using qdiscs in terms of locking.
> The locks penalties really have to do with the design of the netdev
> not qdiscs i.e queues are centered around netdevs and netdevs
> are shared across processors.
>
But currently we have a situation on egress where multiqueue devices
use mq or mqprio which aligns qdisc's with queues. This fixes the
performance penalties but you lose the ability to have state across
multiple queues and the ability to bind flows to queues.
For example a SW rate limiter that applies to a set of queues or a set
of tuned low latency queues. To fix this we can attach a qdisc (htb,
whatever) to the netdev but this has performance penalties. So we are
left with a trade off between functionality and performance.
On the ingress side we may have many queues but as soon as we add a
qdisc/classifier/action we have a single lock.
>
>> If you have some good examples it would be great to see them and drop
>> them in my testbed. Go ahead and send them to me offlist if you can.
>>
>
> will do.
>
Thanks. I'll see if I can draw up what I'm thinking here a bit more
clearly and send it your way.
> cheers,
> jamal
>
>
>> .John
>>
--
John Fastabend Intel Corporation
^ permalink raw reply
* Re: [PATCH net-next v6 3/8] vxlan: Add vxlan recv demux.
From: Pravin Shelar @ 2013-08-05 15:58 UTC (permalink / raw)
To: Stephen Hemminger; +Cc: netdev
In-Reply-To: <20130804144526.4b2e189c@nehalam.linuxnetplumber.net>
On Sun, Aug 4, 2013 at 2:45 PM, Stephen Hemminger
<stephen@networkplumber.org> wrote:
> On Thu, 1 Aug 2013 11:44:49 -0700
> Pravin B Shelar <pshelar@nicira.com> wrote:
>
>> +static struct vxlan_sock *vxlan_sock_add(struct net *net, __be16 port,
>> + vxlan_rcv_t *rcv)
>> {
>> struct vxlan_net *vn = net_generic(net, vxlan_net_id);
>> struct vxlan_sock *vs;
>>
>> - vxlan_socket_create(net, port);
>> + vxlan_socket_create(net, port, rcv);
>>
>> spin_lock(&vn->sock_lock);
>> vs = vxlan_find_sock(net, port);
>> - if (vs)
>> - atomic_inc(&vs->refcnt);
>> - else
>> + if (vs) {
>> + if (vs->rcv == rcv)
>> + atomic_inc(&vs->refcnt);
>> + else
>> + vs = ERR_PTR(-EBUSY);
>> + }
>> + spin_unlock(&vn->sock_lock);
>> +
>
> I think the ref counting needs to be the same for the
> kernel and OVS handling of a VXLAN.
Ref counting is same for ovs and vxlan.
In this patch ovs and vxlan module vxlan-rcv function pointers are
checked for port sharing.
^ permalink raw reply
* Re: [PATCH net-next v6 1/8] vxlan: Restructure vxlan socket apis.
From: Pravin Shelar @ 2013-08-05 15:49 UTC (permalink / raw)
To: Stephen Hemminger; +Cc: netdev
In-Reply-To: <20130804144215.640c9336@nehalam.linuxnetplumber.net>
On Sun, Aug 4, 2013 at 2:42 PM, Stephen Hemminger
<stephen@networkplumber.org> wrote:
> On Thu, 1 Aug 2013 11:44:40 -0700
> Pravin B Shelar <pshelar@nicira.com> wrote:
>
>> @@ -1642,59 +1651,56 @@ static struct vxlan_sock *vxlan_socket_create(struct net *net, __be16 port)
>> &vxlan_addr.sin_addr, ntohs(vxlan_addr.sin_port), rc);
>> sk_release_kernel(sk);
>> kfree(vs);
>> - return ERR_PTR(rc);
>> + return;
>> }
>> + atomic_set(&vs->refcnt, 0);
>>
>> /* Disable multicast loopback */
>> inet_sk(sk)->mc_loop = 0;
>> + spin_lock(&vn->sock_lock);
>> + hlist_add_head_rcu(&vs->hlist, vs_head(net, port));
>> + spin_unlock(&vn->sock_lock);
>
> Overall I am fine with this set, except for this.
> The change causes a socket to be put into the hash list with a ref count
> of 0 and then you increment the ref count. If some other thread
> finds the socket and then decrements the ref count, it would go
> below zero and might leak, crash or delete it prematurely.
>
> This concerns me.
There is no code path which decrements ref-cnt after lookup. Therefore
above case is not possible.
But I agree this does not look good, so I will change it so not to
have refcnt zero vs on hash-table.
^ permalink raw reply
* [PATCH v3] macvlan: validate flags
From: Michael S. Tsirkin @ 2013-08-05 15:25 UTC (permalink / raw)
To: linux-kernel; +Cc: David S. Miller, John Fastabend, Patrick McHardy, netdev
commit df8ef8f3aaa6692970a436204c4429210addb23a
macvlan: add FDB bridge ops and macvlan flags
added a flags field to macvlan, which can be
controlled from userspace.
The idea is to make the interface future-proof
so we can add flags and not new fields.
However, flags value isn't validated, as a result,
userspace can't detect which flags are supported.
Cc: "David S. Miller" <davem@davemloft.net>
Cc: John Fastabend <john.r.fastabend@intel.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
---
Changes from v2:
drop chunk in macvlan_common_newlink -
not necessary since macvlan_validate is always
called first
Changes from v1:
tweaked commit message
no code changes
Please consider this patch for -stable.
The idea is by the time we add more flags,
everyone has updated to a kernel that
detects errors, so userspace will be able
to detect supported flags cleanly.
drivers/net/macvlan.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/drivers/net/macvlan.c b/drivers/net/macvlan.c
index 18373b6..8445a94 100644
--- a/drivers/net/macvlan.c
+++ b/drivers/net/macvlan.c
@@ -736,6 +736,10 @@ static int macvlan_validate(struct nlattr *tb[], struct nlattr *data[])
return -EADDRNOTAVAIL;
}
+ if (data && data[IFLA_MACVLAN_FLAGS] &&
+ nla_get_u16(data[IFLA_MACVLAN_FLAGS]) & ~MACVLAN_FLAG_NOPROMISC)
+ return -EINVAL;
+
if (data && data[IFLA_MACVLAN_MODE]) {
switch (nla_get_u32(data[IFLA_MACVLAN_MODE])) {
case MACVLAN_MODE_PRIVATE:
--
MST
^ permalink raw reply related
* Re: [PATCH -next] tile: fix missing unlock on error in tile_net_open()
From: Chris Metcalf @ 2013-08-05 15:10 UTC (permalink / raw)
To: Wei Yongjun; +Cc: davem, yongjun_wei, netdev
In-Reply-To: <CAPgLHd8k5yfO4G1Fvz86VSC-HbwgGEb8OwTShAa5e+owRvaMqg@mail.gmail.com>
On 8/5/2013 12:42 AM, Wei Yongjun wrote:
> From: Wei Yongjun <yongjun_wei@trendmicro.com.cn>
>
> Add the missing unlock before return from function tile_net_open()
> in the error handling case.
>
> Introduced by commit f3286a3af89d6db7a488f3e8f02b98d67d50f00c.
> (tile: support multiple mPIPE shims in tilegx network driver)
>
> Signed-off-by: Wei Yongjun <yongjun_wei@trendmicro.com.cn>
> ---
> drivers/net/ethernet/tile/tilegx.c | 4 +++-
> 1 file changed, 3 insertions(+), 1 deletion(-)
Thanks!
Acked-by: Chris Metcalf <cmetcalf@tilera.com>
--
Chris Metcalf, Tilera Corp.
http://www.tilera.com
^ permalink raw reply
* [PATCH] net/vmw_vsock/af_vsock.c: drop unneeded semicolon
From: Julia Lawall @ 2013-08-05 14:47 UTC (permalink / raw)
To: David S. Miller; +Cc: kernel-janitors, netdev, linux-kernel
In-Reply-To: <1375714059-29567-1-git-send-email-Julia.Lawall@lip6.fr>
From: Julia Lawall <Julia.Lawall@lip6.fr>
Drop the semicolon at the end of the list_for_each_entry loop header.
Signed-off-by: Julia Lawall <Julia.Lawall@lip6.fr>
---
Not tested, but I can't imagine how the current code could work, since vsk
should end up pointing to a dummy value.
net/vmw_vsock/af_vsock.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/net/vmw_vsock/af_vsock.c b/net/vmw_vsock/af_vsock.c
index 593071d..4d93346 100644
--- a/net/vmw_vsock/af_vsock.c
+++ b/net/vmw_vsock/af_vsock.c
@@ -347,7 +347,7 @@ void vsock_for_each_connected_socket(void (*fn)(struct sock *sk))
for (i = 0; i < ARRAY_SIZE(vsock_connected_table); i++) {
struct vsock_sock *vsk;
list_for_each_entry(vsk, &vsock_connected_table[i],
- connected_table);
+ connected_table)
fn(sk_vsock(vsk));
}
^ permalink raw reply related
* Re: [PATCH net] net: esp{4,6}: fix potential MTU calculation overflows
From: Benjamin Poirier @ 2013-08-05 14:38 UTC (permalink / raw)
To: Daniel Borkmann; +Cc: davem, netdev, Steffen Klassert
In-Reply-To: <1375699775-13769-1-git-send-email-dborkman@redhat.com>
On 2013/08/05 12:49, Daniel Borkmann wrote:
> Commit 91657eafb ("xfrm: take net hdr len into account for esp payload
> size calculation") introduced a possible interger overflow in
> esp{4,6}_get_mtu() handlers in case of x->props.mode equals
> XFRM_MODE_TUNNEL. Thus, the following expression will overflow
>
> unsigned int net_adj;
> ...
> <case ipv{4,6} XFRM_MODE_TUNNEL>
> net_adj = 0;
> ...
> return ((mtu - x->props.header_len - crypto_aead_authsize(esp->aead) -
> net_adj) & ~(align - 1)) + (net_adj - 2);
>
> where (net_adj - 2) would be evaluated as <foo> + (0 - 2) in an unsigned
> context. Fix it by simply removing brackets as those operations here
I can see this creating problems if there was comparison or type
promotion, but I don't see an integer overflow.
In any case, it is right to remove the parentheses. They are dubious
style at the expense of correctness. They have no effect in this case.
Acked-by: Benjamin Poirier <bpoirier@suse.de>
> do not need to have special precedence.
>
> Signed-off-by: Daniel Borkmann <dborkman@redhat.com>
> Cc: Benjamin Poirier <bpoirier@suse.de>
> Cc: Steffen Klassert <steffen.klassert@secunet.com>
> ---
> Note: only compile tested, maybe Benjamin can comment on why he added
> brackets around this expression. *If* this is valid (which I do
> not think), then this needs at least a big comment explaining so.
>
> net/ipv4/esp4.c | 2 +-
> net/ipv6/esp6.c | 2 +-
> 2 files changed, 2 insertions(+), 2 deletions(-)
>
> diff --git a/net/ipv4/esp4.c b/net/ipv4/esp4.c
> index ab3d814..109ee89 100644
> --- a/net/ipv4/esp4.c
> +++ b/net/ipv4/esp4.c
> @@ -477,7 +477,7 @@ static u32 esp4_get_mtu(struct xfrm_state *x, int mtu)
> }
>
> return ((mtu - x->props.header_len - crypto_aead_authsize(esp->aead) -
> - net_adj) & ~(align - 1)) + (net_adj - 2);
> + net_adj) & ~(align - 1)) + net_adj - 2;
> }
>
> static void esp4_err(struct sk_buff *skb, u32 info)
> diff --git a/net/ipv6/esp6.c b/net/ipv6/esp6.c
> index 40ffd72..aeac0dc 100644
> --- a/net/ipv6/esp6.c
> +++ b/net/ipv6/esp6.c
> @@ -425,7 +425,7 @@ static u32 esp6_get_mtu(struct xfrm_state *x, int mtu)
> net_adj = 0;
>
> return ((mtu - x->props.header_len - crypto_aead_authsize(esp->aead) -
> - net_adj) & ~(align - 1)) + (net_adj - 2);
> + net_adj) & ~(align - 1)) + net_adj - 2;
> }
>
> static void esp6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
> --
> 1.7.11.7
>
^ permalink raw reply
* Re: [PATCH v2 1/4] USB: introduce usb_device_no_sg_constraint() helper
From: Ming Lei @ 2013-08-05 14:33 UTC (permalink / raw)
To: Alan Stern
Cc: David S. Miller, Greg Kroah-Hartman, Oliver Neukum, Sarah Sharp,
netdev-u79uwXL29TY76Z2rM5mHXA, linux-usb-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <Pine.LNX.4.44L0.1308051005150.1239-100000-IYeN2dnnYyZXsRXLowluHWD2FQJk+8+b@public.gmane.org>
On Mon, Aug 5, 2013 at 10:07 PM, Alan Stern <stern-nwvwT67g6+6dFdvTe/nMLpVzexx5G7lz@public.gmane.org> wrote:
> On Mon, 5 Aug 2013, Ming Lei wrote:
>
>> Some host controllers(such as xHCI) can support building
>> packet from discontinuous buffers, so introduce one flag
>> and helper for this kind of host controllers, then the
>> feature can help some applications(such as usbnet) by
>> supporting arbitrary length of sg buffers.
>
>> +static inline bool usb_device_no_sg_constraint(struct usb_device *udev)
>> +{
>> + if (udev && udev->bus && udev->bus->no_sg_constraint)
>> + return true;
>> + else
>> + return false;
>> +}
>
> A more elegant implementation would be:
>
> return udev && udev->bus && udev->bus->no_sg_constraint;
>
> I doubt it will make any difference to the object code, though. Apart
> from that, this looks fine.
OK, this can save 3 line code, and I will take it in v3.
>
> Acked-by: Alan Stern <stern-nwvwT67g6+6dFdvTe/nMLpVzexx5G7lz@public.gmane.org>
Thanks for your Ack and review.
Thanks,
--
Ming Lei
--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* [PATCH 1/2][net-next] gianfar: Fix Tx csum generation errata handling
From: Claudiu Manoil @ 2013-08-05 14:20 UTC (permalink / raw)
To: netdev; +Cc: David S. Miller, Paul Gortmaker
In-Reply-To: <1375712410-11760-1-git-send-email-claudiu.manoil@freescale.com>
Both [eTSEC76] and [eTSEC12] errata relate to Tx checksum generation
(for some MPC83xx and MCP8548 older revisions). They require the same
workaround: manual checksum computation and insertion, and disabling
the H/W Tx csum acceleration feature (per frame) through Tx FCB
(Frame Control Block) csum offload settings.
The workaround for [eTSEC76] needs to be fixed because it currently
fails to disable H/W Tx csum insertion via FCB. This patch fixes it
and provides a common workaround implementation for both Tx csum errata.
Signed-off-by: Claudiu Manoil <claudiu.manoil@freescale.com>
---
drivers/net/ethernet/freescale/gianfar.c | 44 ++++++++++++++++++--------------
1 file changed, 25 insertions(+), 19 deletions(-)
diff --git a/drivers/net/ethernet/freescale/gianfar.c b/drivers/net/ethernet/freescale/gianfar.c
index 0f05b96..3a543f7 100644
--- a/drivers/net/ethernet/freescale/gianfar.c
+++ b/drivers/net/ethernet/freescale/gianfar.c
@@ -2054,6 +2054,24 @@ static inline struct txbd8 *next_txbd(struct txbd8 *bdp, struct txbd8 *base,
return skip_txbd(bdp, 1, base, ring_size);
}
+/* eTSEC12: csum generation not supported for some fcb offsets */
+static inline bool gfar_csum_errata_12(struct gfar_private *priv,
+ unsigned long fcb_addr)
+{
+ return (gfar_has_errata(priv, GFAR_ERRATA_12) &&
+ (fcb_addr % 0x20) > 0x18);
+}
+
+/* eTSEC76: csum generation for frames larger than 2500 may
+ * cause excess delays before start of transmission
+ */
+static inline bool gfar_csum_errata_76(struct gfar_private *priv,
+ unsigned int len)
+{
+ return (gfar_has_errata(priv, GFAR_ERRATA_76) &&
+ (len > 2500));
+}
+
/* This is called by the kernel when a frame is ready for transmission.
* It is pointed to by the dev->hard_start_xmit function pointer
*/
@@ -2071,19 +2089,6 @@ static int gfar_start_xmit(struct sk_buff *skb, struct net_device *dev)
unsigned long flags;
unsigned int nr_frags, nr_txbds, length, fcb_length = GMAC_FCB_LEN;
- /* TOE=1 frames larger than 2500 bytes may see excess delays
- * before start of transmission.
- */
- if (unlikely(gfar_has_errata(priv, GFAR_ERRATA_76) &&
- skb->ip_summed == CHECKSUM_PARTIAL &&
- skb->len > 2500)) {
- int ret;
-
- ret = skb_checksum_help(skb);
- if (ret)
- return ret;
- }
-
rq = skb->queue_mapping;
tx_queue = priv->tx_queue[rq];
txq = netdev_get_tx_queue(dev, rq);
@@ -2190,14 +2195,15 @@ static int gfar_start_xmit(struct sk_buff *skb, struct net_device *dev)
/* Set up checksumming */
if (CHECKSUM_PARTIAL == skb->ip_summed) {
fcb = gfar_add_fcb(skb);
- /* as specified by errata */
- if (unlikely(gfar_has_errata(priv, GFAR_ERRATA_12) &&
- ((unsigned long)fcb % 0x20) > 0x18)) {
+ lstatus |= BD_LFLAG(TXBD_TOE);
+ gfar_tx_checksum(skb, fcb, fcb_length);
+
+ if (unlikely(gfar_csum_errata_12(priv, (unsigned long)fcb)) ||
+ unlikely(gfar_csum_errata_76(priv, skb->len))) {
__skb_pull(skb, GMAC_FCB_LEN);
skb_checksum_help(skb);
- } else {
- lstatus |= BD_LFLAG(TXBD_TOE);
- gfar_tx_checksum(skb, fcb, fcb_length);
+ lstatus &= ~(BD_LFLAG(TXBD_TOE));
+ fcb = NULL;
}
}
--
1.7.11.7
^ permalink raw reply related
* [PATCH 0/2][net-next] gianfar: xmit - fix errata workaround and cleanup
From: Claudiu Manoil @ 2013-08-05 14:20 UTC (permalink / raw)
To: netdev; +Cc: David S. Miller, Paul Gortmaker
Hi David,
Please find these cleanup patches for the gfar_start_xmit() function,
including a fix for an old errata workaround implementation (eTSEC76,
for MPC8313 and MPC837x). I find this cleanup quite necessary to make
future fixes and improvements in xmit (and Tx processing) easier.
Thanks,
Claudiu Manoil (2):
gianfar: Fix Tx csum generation errata handling
gianfar: Cleanup TxFCB insertion on xmit
drivers/net/ethernet/freescale/gianfar.c | 100 +++++++++++++++++--------------
1 file changed, 55 insertions(+), 45 deletions(-)
--
1.7.11.7
^ permalink raw reply
* [PATCH 2/2][net-next] gianfar: Cleanup TxFCB insertion on xmit
From: Claudiu Manoil @ 2013-08-05 14:20 UTC (permalink / raw)
To: netdev; +Cc: David S. Miller, Paul Gortmaker
In-Reply-To: <1375712410-11760-1-git-send-email-claudiu.manoil@freescale.com>
Cleanup gfar_start_xmit()'s fast path by factoring out "redundant"
FCB insertion code (repeated gfar_add_fcb() calls and related)
and by reducing the number of if() clauses (i.e. if(fcb) checks).
Improve maintainability (e.g. there's less code and easier to read)
also by introducing do_csum and do_vlan to mark the other 2 Tx TOE
functionalities, following the same model as do_tstamp.
fcb_len may also be 0 now, to mark that Tx FCB insertion conditions
(do_csum, do_vlan, do_tstamp) have not been met.
Signed-off-by: Claudiu Manoil <claudiu.manoil@freescale.com>
---
drivers/net/ethernet/freescale/gianfar.c | 62 +++++++++++++++++---------------
1 file changed, 33 insertions(+), 29 deletions(-)
diff --git a/drivers/net/ethernet/freescale/gianfar.c b/drivers/net/ethernet/freescale/gianfar.c
index 3a543f7..d4f22c6 100644
--- a/drivers/net/ethernet/freescale/gianfar.c
+++ b/drivers/net/ethernet/freescale/gianfar.c
@@ -2084,10 +2084,11 @@ static int gfar_start_xmit(struct sk_buff *skb, struct net_device *dev)
struct txfcb *fcb = NULL;
struct txbd8 *txbdp, *txbdp_start, *base, *txbdp_tstamp = NULL;
u32 lstatus;
- int i, rq = 0, do_tstamp = 0;
+ int i, rq = 0;
+ int do_tstamp, do_csum, do_vlan;
u32 bufaddr;
unsigned long flags;
- unsigned int nr_frags, nr_txbds, length, fcb_length = GMAC_FCB_LEN;
+ unsigned int nr_frags, nr_txbds, length, fcb_len = 0;
rq = skb->queue_mapping;
tx_queue = priv->tx_queue[rq];
@@ -2095,21 +2096,23 @@ static int gfar_start_xmit(struct sk_buff *skb, struct net_device *dev)
base = tx_queue->tx_bd_base;
regs = tx_queue->grp->regs;
+ do_csum = (CHECKSUM_PARTIAL == skb->ip_summed);
+ do_vlan = vlan_tx_tag_present(skb);
+ do_tstamp = (skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP) &&
+ priv->hwts_tx_en;
+
+ if (do_csum || do_vlan)
+ fcb_len = GMAC_FCB_LEN;
+
/* check if time stamp should be generated */
- if (unlikely(skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP &&
- priv->hwts_tx_en)) {
- do_tstamp = 1;
- fcb_length = GMAC_FCB_LEN + GMAC_TXPAL_LEN;
- }
+ if (unlikely(do_tstamp))
+ fcb_len = GMAC_FCB_LEN + GMAC_TXPAL_LEN;
/* make space for additional header when fcb is needed */
- if (((skb->ip_summed == CHECKSUM_PARTIAL) ||
- vlan_tx_tag_present(skb) ||
- unlikely(do_tstamp)) &&
- (skb_headroom(skb) < fcb_length)) {
+ if (fcb_len && unlikely(skb_headroom(skb) < fcb_len)) {
struct sk_buff *skb_new;
- skb_new = skb_realloc_headroom(skb, fcb_length);
+ skb_new = skb_realloc_headroom(skb, fcb_len);
if (!skb_new) {
dev->stats.tx_errors++;
kfree_skb(skb);
@@ -2192,37 +2195,38 @@ static int gfar_start_xmit(struct sk_buff *skb, struct net_device *dev)
memset(skb->data, 0, GMAC_TXPAL_LEN);
}
- /* Set up checksumming */
- if (CHECKSUM_PARTIAL == skb->ip_summed) {
+ /* Add TxFCB if required */
+ if (fcb_len) {
fcb = gfar_add_fcb(skb);
lstatus |= BD_LFLAG(TXBD_TOE);
- gfar_tx_checksum(skb, fcb, fcb_length);
+ }
+
+ /* Set up checksumming */
+ if (do_csum) {
+ gfar_tx_checksum(skb, fcb, fcb_len);
if (unlikely(gfar_csum_errata_12(priv, (unsigned long)fcb)) ||
unlikely(gfar_csum_errata_76(priv, skb->len))) {
__skb_pull(skb, GMAC_FCB_LEN);
skb_checksum_help(skb);
- lstatus &= ~(BD_LFLAG(TXBD_TOE));
- fcb = NULL;
+ if (do_vlan || do_tstamp) {
+ /* put back a new fcb for vlan/tstamp TOE */
+ fcb = gfar_add_fcb(skb);
+ } else {
+ /* Tx TOE not used */
+ lstatus &= ~(BD_LFLAG(TXBD_TOE));
+ fcb = NULL;
+ }
}
}
- if (vlan_tx_tag_present(skb)) {
- if (unlikely(NULL == fcb)) {
- fcb = gfar_add_fcb(skb);
- lstatus |= BD_LFLAG(TXBD_TOE);
- }
-
+ if (do_vlan)
gfar_tx_vlan(skb, fcb);
- }
/* Setup tx hardware time stamping if requested */
if (unlikely(do_tstamp)) {
skb_shinfo(skb)->tx_flags |= SKBTX_IN_PROGRESS;
- if (fcb == NULL)
- fcb = gfar_add_fcb(skb);
fcb->ptp = 1;
- lstatus |= BD_LFLAG(TXBD_TOE);
}
txbdp_start->bufPtr = dma_map_single(priv->dev, skb->data,
@@ -2234,9 +2238,9 @@ static int gfar_start_xmit(struct sk_buff *skb, struct net_device *dev)
* the full frame length.
*/
if (unlikely(do_tstamp)) {
- txbdp_tstamp->bufPtr = txbdp_start->bufPtr + fcb_length;
+ txbdp_tstamp->bufPtr = txbdp_start->bufPtr + fcb_len;
txbdp_tstamp->lstatus |= BD_LFLAG(TXBD_READY) |
- (skb_headlen(skb) - fcb_length);
+ (skb_headlen(skb) - fcb_len);
lstatus |= BD_LFLAG(TXBD_CRC | TXBD_READY) | GMAC_FCB_LEN;
} else {
lstatus |= BD_LFLAG(TXBD_CRC | TXBD_READY) | skb_headlen(skb);
--
1.7.11.7
^ permalink raw reply related
* Re: [PATCH v2 1/4] USB: introduce usb_device_no_sg_constraint() helper
From: Alan Stern @ 2013-08-05 14:07 UTC (permalink / raw)
To: Ming Lei
Cc: David S. Miller, Greg Kroah-Hartman, Oliver Neukum, Sarah Sharp,
netdev-u79uwXL29TY76Z2rM5mHXA, linux-usb-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <1375692423-9497-2-git-send-email-ming.lei-Z7WLFzj8eWMS+FvcfC7Uqw@public.gmane.org>
On Mon, 5 Aug 2013, Ming Lei wrote:
> Some host controllers(such as xHCI) can support building
> packet from discontinuous buffers, so introduce one flag
> and helper for this kind of host controllers, then the
> feature can help some applications(such as usbnet) by
> supporting arbitrary length of sg buffers.
> +static inline bool usb_device_no_sg_constraint(struct usb_device *udev)
> +{
> + if (udev && udev->bus && udev->bus->no_sg_constraint)
> + return true;
> + else
> + return false;
> +}
A more elegant implementation would be:
return udev && udev->bus && udev->bus->no_sg_constraint;
I doubt it will make any difference to the object code, though. Apart
from that, this looks fine.
Acked-by: Alan Stern <stern-nwvwT67g6+6dFdvTe/nMLpVzexx5G7lz@public.gmane.org>
--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* Re: changing dev->needed_headroom/needed_tailroom?
From: Johannes Berg @ 2013-08-05 14:00 UTC (permalink / raw)
To: Eric Dumazet; +Cc: Ben Hutchings, netdev, linux-wireless
In-Reply-To: <1375449082.3927.5.camel@edumazet-glaptop>
On Fri, 2013-08-02 at 06:11 -0700, Eric Dumazet wrote:
> On Fri, 2013-08-02 at 10:55 +0200, Ben Hutchings wrote:
>
> > I don't think this is safe when the interface is running (even if
> > carrier is off). Some functions may read dev->needed_headroom twice and
> > rely on getting the same value each time.
>
> It should be no problem. Remaining unsafe places should be fixed.
Most interesting would be stack devs, which I hadn't even considered. In
any case, since I can't completely _rely_ on it, it's an optimisation,
the only bugs would be around the double-access and then running
over/under the SKB or so?
> We already had this discussion in the past, and some patches were
> issued. Check commit ae641949df01b85117845bec45328eab6d6fada1
> ("net: Remove all uses of LL_ALLOCATED_SPACE")
That would have addressed some of that, I guess.
I'm asking because some of the crypto stuff we do has fairly large
head/tailroom requirements and it seems I may need to add more. But if
you don't have crypto, it would be much smaller, so I figured we could
switch it.
johannes
^ permalink raw reply
* Re: [PATCH net-next 0/2] fix bonding neighbour setup handling
From: Nikolay Aleksandrov @ 2013-08-05 13:49 UTC (permalink / raw)
To: David Miller; +Cc: vfalico, netdev, fubar, andy, ebiederm, joe
In-Reply-To: <20130802.154539.237539535236462726.davem@davemloft.net>
On 08/03/2013 12:45 AM, David Miller wrote:
>
> Thanks for the detailed explanation of the situation, it made your patches
> trivial to review.
>
> Applied, thanks.
Hi all,
Vaeceslav thanks for fixing this.
Since the cat is out of the bag about this bug, as Vaeceslav discovered it
independently and wasn't aware that there's a CVE number pending because it
poses a security threat since the dereferenced first_slave pointer is
taken from the struct vlan_dev_priv's ingress_priority map array which is
user-controllable and any memory address can be dereferenced in that way,
and taking after that first_slave->dev->netdev_ops and calling a function
from the ops is making it even easier. Of course for that to happen the
user must have CAP_NET_ADMIN.
I've tested these patches and they apply cleanly on -net as well, so please
queue them for -net and stable.
Also apologies for the late reply but it wasn't up to me when to reveal this.
Thank you,
Nik
^ permalink raw reply
* Re: [PATCH net-next] bonding: remove locking from bond_set_rx_mode()
From: Nikolay Aleksandrov @ 2013-08-05 13:45 UTC (permalink / raw)
To: Veaceslav Falico; +Cc: netdev, Jay Vosburgh, Andy Gospodarek
In-Reply-To: <1375707366-6762-1-git-send-email-vfalico@redhat.com>
On 08/05/2013 02:56 PM, Veaceslav Falico wrote:
> We're already protected by RTNL lock, so nothing can happen to bond/its
> slaves, and thus the locking is useless here (both bond->lock and
> bond->curr_active_slave).
>
> Also, add ASSERT_RTNL() both to bond_set_rx_mode() and bond_hw_addr_swap()
> to catch possible uses of it without RTNL locking.
>
> This patch also saves us from a lockdep false-positive in
> bond_set_rx_mode() vs bond_hw_addr_swap().
>
> CC: Jay Vosburgh <fubar@us.ibm.com>
> CC: Andy Gospodarek <andy@greyhouse.net>
> CC: Nikolay Aleksandrov <nikolay@redhat.com>
> Signed-off-by: Veaceslav Falico <vfalico@redhat.com>
> ---
Signed-off-by: Nikolay Aleksandrov <nikolay@redhat.com>
^ permalink raw reply
* Re: Alcatel X220S HSDPA modem
From: Enrico Mioso @ 2013-08-05 13:34 UTC (permalink / raw)
To: Dan Williams; +Cc: netdev, linux-usb
In-Reply-To: <1375709684.5454.2.camel@dcbw.foobar.com>
Oh - something like it happens for the E173!
I'm sorry - I do not have a Windows machine, nor sighted assistance needed to
install Windows somewhere.
So I will have to wait... Or could someone help?
Thank you infinitely for your reply!!
On Mon, 5 Aug 2013, Dan Williams wrote:
==Date: Mon, 05 Aug 2013 08:34:44 -0500
==From: Dan Williams <dcbw@redhat.com>
==To: Enrico Mioso <mrkiko.rs@gmail.com>
==Cc: netdev@vger.kernel.org, linux-usb@vger.kernel.org
==Subject: Re: Alcatel X220S HSDPA modem
==
==On Sun, 2013-08-04 at 01:59 +0200, Enrico Mioso wrote:
==> Hello everybody!
==> I'm going to investigate a little bit on an obscure Alcatel device - the
==> Alcatel X220s, manifactured by TCT Mobile Phones.
==>
==> It supports a NDIS network interface, as you will be able to discover looking
==> at the driver package, still: don't know what's the protocol used.
==> At a first glance, I would just like to avoid option.ko binding to non-serial
==> interface as it happens now. So I would appreciate it a lot if you help me
==> distinguish non-serial interfaces from serial ones, looking at this lsusb
==> listing and the driver package (see link below).
==>
==> Another strange thing is - the device interface referred as the WAN one is "06"
==> but here we ave from 0 to 5 interfaces!
==> Looking at this msdn article, it seems Windows does no elaboration regarding
==> the InterfaceNumber field. So - am I missing an interface or does Windows start
==> numbering interfaces from 1?
==
==Some devices expose different USB layouts based on the command that's
==sent to them to "switch" them from fake-driver-CD mode to modem mode.
==If you're at all able to sniff the modeswitch command maybe we could see
==if it's the same one as what usb_modeswitch sends on Linux?
==
==Dan
==
==> Driver package link:
==> http://www.gstorm.eu/dgm/alcdrv.tar.xz
==> (I simply decompressed the Innosetup installer to let you browse these files
==> with no major issues!)
==>
==> Any help and documentation would be greatly apreciated!!
==>
==>
==> Bus 001 Device 002: ID 1bbb:0017 T & A Mobile Phones
==> Device Descriptor:
==> bLength 18
==> bDescriptorType 1
==> bcdUSB 2.00
==> bDeviceClass 0 (Defined at Interface level)
==> bDeviceSubClass 0
==> bDeviceProtocol 0
==> bMaxPacketSize0 64
==> idVendor 0x1bbb T & A Mobile Phones
==> idProduct 0x0017
==> bcdDevice 0.00
==> iManufacturer 3 USBModem
==> iProduct 2 HSPA Data Card
==> iSerial 4 1234567890ABCDEF
==> bNumConfigurations 1
==> Configuration Descriptor:
==> bLength 9
==> bDescriptorType 2
==> wTotalLength 154
==> bNumInterfaces 6
==> bConfigurationValue 1
==> iConfiguration 1 USBModem Configuration
==> bmAttributes 0xa0
==> (Bus Powered)
==> Remote Wakeup
==> MaxPower 500mA
==> Interface Descriptor:
==> bLength 9
==> bDescriptorType 4
==> bInterfaceNumber 0
==> bAlternateSetting 0
==> bNumEndpoints 2
==> bInterfaceClass 255 Vendor Specific Class
==> bInterfaceSubClass 255 Vendor Specific Subclass
==> bInterfaceProtocol 255 Vendor Specific Protocol
==> iInterface 0
==> Endpoint Descriptor:
==> bLength 7
==> bDescriptorType 5
==> bEndpointAddress 0x81 EP 1 IN
==> bmAttributes 2
==> Transfer Type Bulk
==> Synch Type None
==> Usage Type Data
==> wMaxPacketSize 0x0200 1x 512 bytes
==> bInterval 32
==> Endpoint Descriptor:
==> bLength 7
==> bDescriptorType 5
==> bEndpointAddress 0x01 EP 1 OUT
==> bmAttributes 2
==> Transfer Type Bulk
==> Synch Type None
==> Usage Type Data
==> wMaxPacketSize 0x0200 1x 512 bytes
==> bInterval 32
==> Interface Descriptor:
==> bLength 9
==> bDescriptorType 4
==> bInterfaceNumber 1
==> bAlternateSetting 0
==> bNumEndpoints 2
==> bInterfaceClass 255 Vendor Specific Class
==> bInterfaceSubClass 255 Vendor Specific Subclass
==> bInterfaceProtocol 255 Vendor Specific Protocol
==> iInterface 0
==> Endpoint Descriptor:
==> bLength 7
==> bDescriptorType 5
==> bEndpointAddress 0x82 EP 2 IN
==> bmAttributes 2
==> Transfer Type Bulk
==> Synch Type None
==> Usage Type Data
==> wMaxPacketSize 0x0200 1x 512 bytes
==> bInterval 32
==> Endpoint Descriptor:
==> bLength 7
==> bDescriptorType 5
==> bEndpointAddress 0x02 EP 2 OUT
==> bmAttributes 2
==> Transfer Type Bulk
==> Synch Type None
==> Usage Type Data
==> wMaxPacketSize 0x0200 1x 512 bytes
==> bInterval 32
==> Interface Descriptor:
==> bLength 9
==> bDescriptorType 4
==> bInterfaceNumber 2
==> bAlternateSetting 0
==> bNumEndpoints 2
==> bInterfaceClass 255 Vendor Specific Class
==> bInterfaceSubClass 255 Vendor Specific Subclass
==> bInterfaceProtocol 255 Vendor Specific Protocol
==> iInterface 0
==> Endpoint Descriptor:
==> bLength 7
==> bDescriptorType 5
==> bEndpointAddress 0x83 EP 3 IN
==> bmAttributes 2
==> Transfer Type Bulk
==> Synch Type None
==> Usage Type Data
==> wMaxPacketSize 0x0200 1x 512 bytes
==> bInterval 32
==> Endpoint Descriptor:
==> bLength 7
==> bDescriptorType 5
==> bEndpointAddress 0x03 EP 3 OUT
==> bmAttributes 2
==> Transfer Type Bulk
==> Synch Type None
==> Usage Type Data
==> wMaxPacketSize 0x0200 1x 512 bytes
==> bInterval 32
==> Interface Descriptor:
==> bLength 9
==> bDescriptorType 4
==> bInterfaceNumber 3
==> bAlternateSetting 0
==> bNumEndpoints 2
==> bInterfaceClass 255 Vendor Specific Class
==> bInterfaceSubClass 255 Vendor Specific Subclass
==> bInterfaceProtocol 255 Vendor Specific Protocol
==> iInterface 0
==> Endpoint Descriptor:
==> bLength 7
==> bDescriptorType 5
==> bEndpointAddress 0x84 EP 4 IN
==> bmAttributes 2
==> Transfer Type Bulk
==> Synch Type None
==> Usage Type Data
==> wMaxPacketSize 0x0200 1x 512 bytes
==> bInterval 32
==> Endpoint Descriptor:
==> bLength 7
==> bDescriptorType 5
==> bEndpointAddress 0x04 EP 4 OUT
==> bmAttributes 2
==> Transfer Type Bulk
==> Synch Type None
==> Usage Type Data
==> wMaxPacketSize 0x0200 1x 512 bytes
==> bInterval 32
==> Interface Descriptor:
==> bLength 9
==> bDescriptorType 4
==> bInterfaceNumber 4
==> bAlternateSetting 0
==> bNumEndpoints 2
==> bInterfaceClass 8 Mass Storage
==> bInterfaceSubClass 6 SCSI
==> bInterfaceProtocol 80 Bulk-Only
==> iInterface 0
==> Endpoint Descriptor:
==> bLength 7
==> bDescriptorType 5
==> bEndpointAddress 0x05 EP 5 OUT
==> bmAttributes 2
==> Transfer Type Bulk
==> Synch Type None
==> Usage Type Data
==> wMaxPacketSize 0x0200 1x 512 bytes
==> bInterval 0
==> Endpoint Descriptor:
==> bLength 7
==> bDescriptorType 5
==> bEndpointAddress 0x85 EP 5 IN
==> bmAttributes 2
==> Transfer Type Bulk
==> Synch Type None
==> Usage Type Data
==> wMaxPacketSize 0x0200 1x 512 bytes
==> bInterval 0
==> Interface Descriptor:
==> bLength 9
==> bDescriptorType 4
==> bInterfaceNumber 5
==> bAlternateSetting 0
==> bNumEndpoints 3
==> bInterfaceClass 255 Vendor Specific Class
==> bInterfaceSubClass 255 Vendor Specific Subclass
==> bInterfaceProtocol 255 Vendor Specific Protocol
==> iInterface 0
==> Endpoint Descriptor:
==> bLength 7
==> bDescriptorType 5
==> bEndpointAddress 0x86 EP 6 IN
==> bmAttributes 3
==> Transfer Type Interrupt
==> Synch Type None
==> Usage Type Data
==> wMaxPacketSize 0x0040 1x 64 bytes
==> bInterval 5
==> Endpoint Descriptor:
==> bLength 7
==> bDescriptorType 5
==> bEndpointAddress 0x87 EP 7 IN
==> bmAttributes 2
==> Transfer Type Bulk
==> Synch Type None
==> Usage Type Data
==> wMaxPacketSize 0x0200 1x 512 bytes
==> bInterval 32
==> Endpoint Descriptor:
==> bLength 7
==> bDescriptorType 5
==> bEndpointAddress 0x06 EP 6 OUT
==> bmAttributes 2
==> Transfer Type Bulk
==> Synch Type None
==> Usage Type Data
==> wMaxPacketSize 0x0200 1x 512 bytes
==> bInterval 32
==> Device Qualifier (for other device speed):
==> bLength 10
==> bDescriptorType 6
==> bcdUSB 2.00
==> bDeviceClass 0 (Defined at Interface level)
==> bDeviceSubClass 0
==> bDeviceProtocol 0
==> bMaxPacketSize0 64
==> bNumConfigurations 1
==> Device Status: 0x0001
==> Self Powered
==>
==>
==>
==> --
==> To unsubscribe from this list: send the line "unsubscribe netdev" in
==> the body of a message to majordomo@vger.kernel.org
==> More majordomo info at http://vger.kernel.org/majordomo-info.html
==
==
==
^ permalink raw reply
* [PATCH net-next 0/3] bonding: vlan handling changes
From: Nikolay Aleksandrov @ 2013-08-05 13:28 UTC (permalink / raw)
To: netdev; +Cc: fubar, andy, davem
From: Nikolay Aleksandrov <Nikolay Aleksandrov nikolay@redhat.com>
Hi,
I've queued all of these patches to net-next since they're tightly related
and the bugs that get fixed are not critical, so it's better to soak the
changes a bit. Also I'd much rather fix this with the slave list change in.
If you decide that they need to be posted for -net, let me know.
Patch 01 - fixes vlan 0 addition/removal since when we have 8021q module
loaded it gets added to all network devices, this causes the bonding to
output false warnings, output tagged learning packets (though with 0 tag)
The fix is by denying the addition/removal of vlan 0 through the ndo_vlan
functions and do it ourselves in the bond's netdev event handler when a
vlan 0 is added/removed from a bonding device. Also a small comment fix
which adds the missing proto parameter.
Patch 02 - switches the bonding to the now standard vlan syncing functions
vlan_vids_add/del_by_dev() and removes the bonding specific ones.
Patch 03 - reverts vlan addition in case of bond_add_vlan failure because
otherwise we may get bad vlan refcounts in the slaves.
Best regards,
Nikolay Aleksandrov
Nikolay Aleksandrov (3):
bonding: fix vlan 0 addition and removal
bonding: change the bond's vlan syncing functions with the standard
ones
bonding: unwind on bond_add_vlan add failure
drivers/net/bonding/bond_main.c | 86 +++++++++++++++++++++++++----------------
1 file changed, 52 insertions(+), 34 deletions(-)
--
1.8.1.4
^ 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