Netdev List
 help / color / mirror / Atom feed
* Re: [Patch net-next] bridge: add some missing __rcu marks
From: Cong Wang @ 2013-02-14  8:23 UTC (permalink / raw)
  To: Stephen Hemminger; +Cc: netdev, Vlad Yasevich, David S. Miller
In-Reply-To: <20130213223935.122d035b@nehalam.linuxnetplumber.net>

On Wed, 2013-02-13 at 22:39 -0800, Stephen Hemminger wrote:
> On Thu, 14 Feb 2013 14:12:30 +0800
> Cong Wang <amwang@redhat.com> wrote:
> >  #ifdef CONFIG_NET_POLL_CONTROLLER
> > -static inline struct netpoll_info *br_netpoll_info(struct net_bridge *br)
> > +static inline struct netpoll_info __rcu *br_netpoll_info(struct net_bridge *br)
> >  {
> >  	return br->dev->npinfo;
> >  }
> 
> 
> This doesn't seem right since there is no rcu_dereference() here.

But we don't dereference ->npinfo here, we only check if it is NULL.

^ permalink raw reply

* [Patch net-next v2] netpoll: add some missing __rcu marks in several places
From: Cong Wang @ 2013-02-14  8:37 UTC (permalink / raw)
  To: netdev
  Cc: Jiri Pirko, Vlad Yasevich, Stephen Hemminger, David S. Miller,
	Cong Wang
In-Reply-To: <20130213223935.122d035b@nehalam.linuxnetplumber.net>

From: Cong Wang <amwang@redhat.com>

This fixes sparse warnings like the one below:

drivers/net/team/team.c:953:25: warning: incorrect type in return expression (different address spaces)
drivers/net/team/team.c:953:25:    expected struct netpoll_info *
drivers/net/team/team.c:953:25:    got struct netpoll_info [noderef] <asn:4>*npinfo

Cc: Jiri Pirko <jiri@resnulli.us>
Cc: Vlad Yasevich <vyasevic@redhat.com>
Cc: Stephen Hemminger <stephen@networkplumber.org>
Cc: David S. Miller <davem@davemloft.net>
Signed-off-by: Cong Wang <amwang@redhat.com>

---
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
index 94c1534..cc35a3e 100644
--- a/drivers/net/bonding/bond_main.c
+++ b/drivers/net/bonding/bond_main.c
@@ -1300,7 +1300,7 @@ static int bond_netpoll_setup(struct net_device *dev, struct netpoll_info *ni, g
 	return err;
 }
 
-static struct netpoll_info *bond_netpoll_info(struct bonding *bond)
+static struct netpoll_info __rcu *bond_netpoll_info(struct bonding *bond)
 {
 	return bond->dev->npinfo;
 }
diff --git a/drivers/net/team/team.c b/drivers/net/team/team.c
index 05c5efe..004fdd9 100644
--- a/drivers/net/team/team.c
+++ b/drivers/net/team/team.c
@@ -948,7 +948,7 @@ static void team_port_disable_netpoll(struct team_port *port)
 	kfree(np);
 }
 
-static struct netpoll_info *team_netpoll_info(struct team *team)
+static struct netpoll_info __rcu *team_netpoll_info(struct team *team)
 {
 	return team->dev->npinfo;
 }
@@ -962,7 +962,7 @@ static int team_port_enable_netpoll(struct team *team, struct team_port *port,
 static void team_port_disable_netpoll(struct team_port *port)
 {
 }
-static struct netpoll_info *team_netpoll_info(struct team *team)
+static struct netpoll_info __rcu *team_netpoll_info(struct team *team)
 {
 	return NULL;
 }
diff --git a/net/bridge/br_private.h b/net/bridge/br_private.h
index 6d314c4..0f115ba 100644
--- a/net/bridge/br_private.h
+++ b/net/bridge/br_private.h
@@ -328,7 +328,7 @@ extern void br_dev_delete(struct net_device *dev, struct list_head *list);
 extern netdev_tx_t br_dev_xmit(struct sk_buff *skb,
 			       struct net_device *dev);
 #ifdef CONFIG_NET_POLL_CONTROLLER
-static inline struct netpoll_info *br_netpoll_info(struct net_bridge *br)
+static inline struct netpoll_info __rcu *br_netpoll_info(struct net_bridge *br)
 {
 	return br->dev->npinfo;
 }
@@ -345,7 +345,7 @@ static inline void br_netpoll_send_skb(const struct net_bridge_port *p,
 extern int br_netpoll_enable(struct net_bridge_port *p, gfp_t gfp);
 extern void br_netpoll_disable(struct net_bridge_port *p);
 #else
-static inline struct netpoll_info *br_netpoll_info(struct net_bridge *br)
+static inline struct netpoll_info __rcu *br_netpoll_info(struct net_bridge *br)
 {
 	return NULL;
 }
@@ -469,7 +469,7 @@ extern void br_multicast_free_pg(struct rcu_head *head);
 extern struct net_bridge_port_group *br_multicast_new_port_group(
 				struct net_bridge_port *port,
 				struct br_ip *group,
-				struct net_bridge_port_group *next,
+				struct net_bridge_port_group __rcu *next,
 				unsigned char state);
 extern void br_mdb_init(void);
 extern void br_mdb_uninit(void);

^ permalink raw reply related

* Re: [PATCH 1/1] VSOCK: Introduce VM Sockets
From: Gerd Hoffmann @ 2013-02-14  9:28 UTC (permalink / raw)
  To: Andy King; +Cc: pv-drivers, netdev, linux-kernel, virtualization, gregkh, davem
In-Reply-To: <1218897172.1425846.1360812023655.JavaMail.root@vmware.com>

[-- Attachment #1: Type: text/plain, Size: 3920 bytes --]

  Hi,

>> I've seen you have a notify_ops in the vmci bits.  Do you have different
>> notify ops depending on socket type or something?  Does it make sense to
>> move the notify ops ptr into "struct vsock_sock" maybe?
> 
> The notify stuff only applies to STREAMs.  However, we have two different
> notify impls, one for legacy ESX and one for newer, and we figure out at
> runtime which protocol we're using with the hypervisor and set the
> callbacks appropriately.

Ok.

> The difference between the two is that the
> newer one is much smarter and knows not to signal (the peer) quite so much,
> i.e., it has some basic but sensible flow-control, which improves
> performance quite a bit.

Yea, with that background it makes more sense.  I think we can reduce
number of hooks though.

Looking at vsock_stream_sendmsg:
  * notify_send_init -- needed I guess.
  * notify_send_pre_block -- needed too, I guess you'll force signaling
    the peer here (buffers full and there is more data).
  * notify_send_pre_enqueue + notify_send_post_enqueue look like they
    could easily be folded into stream_enqueue.

> Again, that might not make any sense at all
> for virtio.  Do you need to signal when you enqueue to a ring?  And is
> there coalescing?

Sure virtio signals, we have to if we don't want poll ;)

Usually virtio only signals in case it finds the ring empty, if there
are requests not yet processed by the peer there is no need to signal.
The ring lives in guest memory and to figure whenever the peer has seen
the requests in there we only need a memory barrier, not a vmexit.

In the end it is up to the driver when he signals the peer.  The virtio
net driver goes beyond the simple "signal-when-the-ring-is-empty" and
has some logic for coalescing things when there is a high network load,
while trying to not trade that for high latencies when the virtual nic
is almost idle.

I guess you try archiving something simliar with vsock/vmci using the
notifications, and yes, we might want use them with virtio too some day.
 Most likely not for the first revision though, there are more important
issues to tackle first.

>> And can we make it optional please (i.e. allow the function pointers to
>> be NULL)?
> 
> They were originally allowed to be NULL, but I changed it in the last
> round of patches while moving them into the transport, since I disliked
> the NULL checks so much.  I can put them back, but that's a bigger
> change, and I'm not sure we want to push large patches to Dave right
> now :)

Yea, it's probably better to discuss+collect the refinements and send
them batched.

>> Which problem you are trying to tackle with the notifications?
> 
> It's to do with signaling the peer, or more appropriately, trying to
> avoid signaling the peer when possible.  The naive impl. is to signal
> every time we enqueue or dequeue data (into our VMCI queuepairs).
> But signaling is slow, since it involves a world exit, so we prefer
> not to.  Which means we need to keep track of rate of flow and figure
> out when we should and should not, and that's what all the notification
> stuff does.  It's...ugly...

But makes sense even if it isn't that pretty.

But /me wonders why you maintain the notify state per-call and not
per-socket/queuepair.  For the data flow it shouldn't make a difference
whenever the application does a few send(big-buffer) or many
send(small-buffer) calls.

>>> For the VMCI transport, it indicates if the underlying queuepair is
>>> still around (i.e., make sure we haven't torn it down while sleeping
>>> in a blocking send or receive).  Perhaps it's not the best name?
>>
>> How you'd hit that?  Peer closing the socket while sleeping?  Other
>> thread closing the socket wile sleeping?  Both?
>>
>> I think a state field in struct vsock_sock would be a better solution here.
> 
> Hrm, lemme think about this one.

There is already vsock->sk.sk_state ...

cheers,
  Gerd

[-- Attachment #2: 0002-af_vsock-don-t-overwrite-sock-state.patch --]
[-- Type: text/plain, Size: 1209 bytes --]

From e085c81d3fc95a7e2e938deec65843ba7c00afe3 Mon Sep 17 00:00:00 2001
From: Gerd Hoffmann <kraxel@redhat.com>
Date: Wed, 13 Feb 2013 18:00:19 +0100
Subject: [PATCH 2/4] af_vsock: don't overwrite sock->state

We set sock->state to SS_CONNECTING before calling the transport,
no need to do that again afterwards, thereby overwriting any
updates the transport's connect function might have done.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 net/vmw_vsock/af_vsock.c |    6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/net/vmw_vsock/af_vsock.c b/net/vmw_vsock/af_vsock.c
index 54bb7bd..e5d1467 100644
--- a/net/vmw_vsock/af_vsock.c
+++ b/net/vmw_vsock/af_vsock.c
@@ -1184,11 +1184,11 @@ static int vsock_stream_connect(struct socket *sock, struct sockaddr *addr,
 		if (err < 0)
 			goto out;
 
-		/* Mark sock as connecting and set the error code to in
+		/* When still connecting set the error code to in
 		 * progress in case this is a non-blocking connect.
 		 */
-		sock->state = SS_CONNECTING;
-		err = -EINPROGRESS;
+		if (sock->state == SS_CONNECTING)
+			err = -EINPROGRESS;
 	}
 
 	/* The receive path will handle all communication until we are able to
-- 
1.7.9.7


[-- Attachment #3: Type: text/plain, Size: 183 bytes --]

_______________________________________________
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization

^ permalink raw reply related

* failure when attempting to build vmci_transport on net-next
From: Or Gerlitz @ 2013-02-14  9:50 UTC (permalink / raw)
  To: Andy king; +Cc: David Miller, netdev, Dmitry Torokhov, George Zhang

Hi Andy & Co

I didn't manage to get the VMWARE_VMCI_VSOCKETS directive to be set, 
unless I added the below patch, and
once that done got the tons of errors below, am I doing something wrong?

Or.

diff --git a/net/vmw_vsock/Kconfig b/net/vmw_vsock/Kconfig
index b5fa7e4..620982c 100644
--- a/net/vmw_vsock/Kconfig
+++ b/net/vmw_vsock/Kconfig
@@ -15,6 +15,9 @@ config VSOCKETS
           To compile this driver as a module, choose M here: the module
           will be called vsock. If unsure, say N.

+config VMWARE_VMCI
+       def_bool y
+
  config VMWARE_VMCI_VSOCKETS
         tristate "VMware VMCI transport for Virtual Sockets"
         depends on VSOCKETS && VMWARE_VMCI


>  CC [M]  net/vmw_vsock/vmci_transport.o
> In file included from net/vmw_vsock/vmci_transport.c:41:
> net/vmw_vsock/vmci_transport_notify.h:20:33: error: 
> linux/vmw_vmci_defs.h: No such file or directory
> net/vmw_vsock/vmci_transport_notify.h:21:32: error: 
> linux/vmw_vmci_api.h: No such file or directory
> In file included from net/vmw_vsock/vmci_transport_notify.h:24,
>                  from net/vmw_vsock/vmci_transport.c:41:
> net/vmw_vsock/vmci_transport.h:66: error: field ?dg? has incomplete type
> net/vmw_vsock/vmci_transport.h:76: error: field ?handle? has 
> incomplete type
> net/vmw_vsock/vmci_transport.h:110: error: field ?dg_handle? has 
> incomplete type
> net/vmw_vsock/vmci_transport.h:112: error: field ?qp_handle? has 
> incomplete type
> net/vmw_vsock/vmci_transport.c:47: warning: ?struct vmci_event_data? 
> declared inside parameter list
> net/vmw_vsock/vmci_transport.c:47: warning: its scope is only this 
> definition or declaration, which is probably not what you want
> net/vmw_vsock/vmci_transport.c:50: warning: ?struct vmci_event_data? 
> declared inside parameter list
> net/vmw_vsock/vmci_transport.c:80: error: variable 
> ?vmci_transport_stream_handle? has initializer but incomplete type
> net/vmw_vsock/vmci_transport.c:80: error: ?VMCI_INVALID_ID? undeclared 
> here (not in a function)
> net/vmw_vsock/vmci_transport.c:80: warning: excess elements in struct 
> initializer
> net/vmw_vsock/vmci_transport.c:80: warning: (near initialization for 
> ?vmci_transport_stream_handle?)
> net/vmw_vsock/vmci_transport.c:81: warning: excess elements in struct 
> initializer
> net/vmw_vsock/vmci_transport.c:81: warning: (near initialization for 
> ?vmci_transport_stream_handle?)
> net/vmw_vsock/vmci_transport.c: In function 
> ?vmci_transport_error_to_vsock_error?:
> net/vmw_vsock/vmci_transport.c:104: error: ?VMCI_ERROR_NO_MEM? 
> undeclared (first use in this function)
> net/vmw_vsock/vmci_transport.c:104: error: (Each undeclared identifier 
> is reported only once
> net/vmw_vsock/vmci_transport.c:104: error: for each function it 
> appears in.)
> net/vmw_vsock/vmci_transport.c:107: error: 
> ?VMCI_ERROR_DUPLICATE_ENTRY? undeclared (first use in this function)
> net/vmw_vsock/vmci_transport.c:108: error: ?VMCI_ERROR_ALREADY_EXISTS? 
> undeclared (first use in this function)
> net/vmw_vsock/vmci_transport.c:111: error: ?VMCI_ERROR_NO_ACCESS? 
> undeclared (first use in this function)
> net/vmw_vsock/vmci_transport.c:114: error: ?VMCI_ERROR_NO_RESOURCES? 
> undeclared (first use in this function)
> net/vmw_vsock/vmci_transport.c:117: error: 
> ?VMCI_ERROR_INVALID_RESOURCE? undeclared (first use in this function)
> net/vmw_vsock/vmci_transport.c:120: error: ?VMCI_ERROR_INVALID_ARGS? 
> undeclared (first use in this function)
> net/vmw_vsock/vmci_transport.c: At top level:
> net/vmw_vsock/vmci_transport.c:137: error: parameter 9 (?handle?) has 
> incomplete type
> net/vmw_vsock/vmci_transport.c: In function ?vmci_transport_packet_init?:
> net/vmw_vsock/vmci_transport.c:142: error: implicit declaration of 
> function ?vmci_make_handle?
> net/vmw_vsock/vmci_transport.c: At top level:
> net/vmw_vsock/vmci_transport.c:210: error: parameter 9 (?handle?) has 
> incomplete type
> net/vmw_vsock/vmci_transport.c: In function 
> ?__vmci_transport_send_control_pkt?:
> net/vmw_vsock/vmci_transport.c:216: error: type of formal parameter 9 
> is incomplete
> net/vmw_vsock/vmci_transport.c:217: error: implicit declaration of 
> function ?vmci_datagram_send?
> net/vmw_vsock/vmci_transport.c: At top level:
> net/vmw_vsock/vmci_transport.c:230: error: parameter 6 (?handle?) has 
> incomplete type
> net/vmw_vsock/vmci_transport.c: In function 
> ?vmci_transport_reply_control_pkt_fast?:
> net/vmw_vsock/vmci_transport.c:243: error: type of formal parameter 9 
> is incomplete
> net/vmw_vsock/vmci_transport.c: At top level:
> net/vmw_vsock/vmci_transport.c:254: error: parameter 7 (?handle?) has 
> incomplete type
> net/vmw_vsock/vmci_transport.c: In function 
> ?vmci_transport_send_control_pkt_bh?:
> net/vmw_vsock/vmci_transport.c:266: error: type of formal parameter 9 
> is incomplete
> net/vmw_vsock/vmci_transport.c: At top level:
> net/vmw_vsock/vmci_transport.c:276: error: parameter 7 (?handle?) has 
> incomplete type
> net/vmw_vsock/vmci_transport.c: In function 
> ?vmci_transport_send_control_pkt?:
> net/vmw_vsock/vmci_transport.c:297: error: type of formal parameter 9 
> is incomplete
> net/vmw_vsock/vmci_transport.c: In function 
> ?vmci_transport_send_reset_bh?:
> net/vmw_vsock/vmci_transport.c:312: error: ?VMCI_INVALID_HANDLE? 
> undeclared (first use in this function)
> net/vmw_vsock/vmci_transport.c:312: error: type of formal parameter 7 
> is incomplete
> net/vmw_vsock/vmci_transport.c: In function ?vmci_transport_send_reset?:
> net/vmw_vsock/vmci_transport.c:323: error: ?VMCI_INVALID_HANDLE? 
> undeclared (first use in this function)
> net/vmw_vsock/vmci_transport.c:323: error: type of formal parameter 7 
> is incomplete
> net/vmw_vsock/vmci_transport.c: In function 
> ?vmci_transport_send_negotiate?:
> net/vmw_vsock/vmci_transport.c:333: error: ?VMCI_INVALID_HANDLE? 
> undeclared (first use in this function)
> net/vmw_vsock/vmci_transport.c:333: error: type of formal parameter 7 
> is incomplete
> net/vmw_vsock/vmci_transport.c: In function 
> ?vmci_transport_send_negotiate2?:
> net/vmw_vsock/vmci_transport.c:343: error: ?VMCI_INVALID_HANDLE? 
> undeclared (first use in this function)
> net/vmw_vsock/vmci_transport.c:343: error: type of formal parameter 7 
> is incomplete
> net/vmw_vsock/vmci_transport.c: At top level:
> net/vmw_vsock/vmci_transport.c:347: error: parameter 2 (?handle?) has 
> incomplete type
> net/vmw_vsock/vmci_transport.c: In function 
> ?vmci_transport_send_qp_offer?:
> net/vmw_vsock/vmci_transport.c:352: error: type of formal parameter 7 
> is incomplete
> net/vmw_vsock/vmci_transport.c: At top level:
> net/vmw_vsock/vmci_transport.c:356: error: parameter 2 (?handle?) has 
> incomplete type
> net/vmw_vsock/vmci_transport.c: In function ?vmci_transport_send_attach?:
> net/vmw_vsock/vmci_transport.c:361: error: type of formal parameter 7 
> is incomplete
> net/vmw_vsock/vmci_transport.c: In function ?vmci_transport_reply_reset?:
> net/vmw_vsock/vmci_transport.c:370: error: ?VMCI_INVALID_HANDLE? 
> undeclared (first use in this function)
> net/vmw_vsock/vmci_transport.c:370: error: type of formal parameter 6 
> is incomplete
> net/vmw_vsock/vmci_transport.c: In function 
> ?vmci_transport_send_invalid_bh?:
> net/vmw_vsock/vmci_transport.c:379: error: ?VMCI_INVALID_HANDLE? 
> undeclared (first use in this function)
> net/vmw_vsock/vmci_transport.c:379: error: type of formal parameter 7 
> is incomplete
> net/vmw_vsock/vmci_transport.c: In function 
> ?vmci_transport_send_wrote_bh?:
> net/vmw_vsock/vmci_transport.c:388: error: ?VMCI_INVALID_HANDLE? 
> undeclared (first use in this function)
> net/vmw_vsock/vmci_transport.c:388: error: type of formal parameter 7 
> is incomplete
> net/vmw_vsock/vmci_transport.c: In function ?vmci_transport_send_read_bh?:
> net/vmw_vsock/vmci_transport.c:397: error: ?VMCI_INVALID_HANDLE? 
> undeclared (first use in this function)
> net/vmw_vsock/vmci_transport.c:397: error: type of formal parameter 7 
> is incomplete
> net/vmw_vsock/vmci_transport.c: In function ?vmci_transport_send_wrote?:
> net/vmw_vsock/vmci_transport.c:405: error: ?VMCI_INVALID_HANDLE? 
> undeclared (first use in this function)
> net/vmw_vsock/vmci_transport.c:405: error: type of formal parameter 7 
> is incomplete
> net/vmw_vsock/vmci_transport.c: In function ?vmci_transport_send_read?:
> net/vmw_vsock/vmci_transport.c:413: error: ?VMCI_INVALID_HANDLE? 
> undeclared (first use in this function)
> net/vmw_vsock/vmci_transport.c:413: error: type of formal parameter 7 
> is incomplete
> net/vmw_vsock/vmci_transport.c: In function 
> ?vmci_transport_send_waiting_write?:
> net/vmw_vsock/vmci_transport.c:422: error: ?VMCI_INVALID_HANDLE? 
> undeclared (first use in this function)
> net/vmw_vsock/vmci_transport.c:422: error: type of formal parameter 7 
> is incomplete
> net/vmw_vsock/vmci_transport.c: In function 
> ?vmci_transport_send_waiting_read?:
> net/vmw_vsock/vmci_transport.c:431: error: ?VMCI_INVALID_HANDLE? 
> undeclared (first use in this function)
> net/vmw_vsock/vmci_transport.c:431: error: type of formal parameter 7 
> is incomplete
> net/vmw_vsock/vmci_transport.c: In function ?vmci_transport_shutdown?:
> net/vmw_vsock/vmci_transport.c:441: error: ?VMCI_INVALID_HANDLE? 
> undeclared (first use in this function)
> net/vmw_vsock/vmci_transport.c:441: error: type of formal parameter 7 
> is incomplete
> net/vmw_vsock/vmci_transport.c: In function 
> ?vmci_transport_send_conn_request?:
> net/vmw_vsock/vmci_transport.c:450: error: ?VMCI_INVALID_HANDLE? 
> undeclared (first use in this function)
> net/vmw_vsock/vmci_transport.c:450: error: type of formal parameter 7 
> is incomplete
> net/vmw_vsock/vmci_transport.c: In function 
> ?vmci_transport_send_conn_request2?:
> net/vmw_vsock/vmci_transport.c:459: error: ?VMCI_INVALID_HANDLE? 
> undeclared (first use in this function)
> net/vmw_vsock/vmci_transport.c:459: error: type of formal parameter 7 
> is incomplete
> net/vmw_vsock/vmci_transport.c: In function ?vmci_transport_is_trusted?:
> net/vmw_vsock/vmci_transport.c:507: error: implicit declaration of 
> function ?vmci_is_context_owner?
> net/vmw_vsock/vmci_transport.c: In function ?vmci_transport_allow_dgram?:
> net/vmw_vsock/vmci_transport.c:519: error: implicit declaration of 
> function ?vmci_context_get_priv_flags?
> net/vmw_vsock/vmci_transport.c:520: error: 
> ?VMCI_PRIVILEGE_FLAG_RESTRICTED? undeclared (first use in this function)
> net/vmw_vsock/vmci_transport.c: In function 
> ?vmci_transport_queue_pair_alloc?:
> net/vmw_vsock/vmci_transport.c:544: error: implicit declaration of 
> function ?vmci_qpair_alloc?
> net/vmw_vsock/vmci_transport.c:547: error: 
> ?VMCI_PRIVILEGE_FLAG_TRUSTED? undeclared (first use in this function)
> net/vmw_vsock/vmci_transport.c:548: error: ?VMCI_ERROR_NO_ACCESS? 
> undeclared (first use in this function)
> net/vmw_vsock/vmci_transport.c:554: error: ?VMCI_NO_PRIVILEGE_FLAGS? 
> undeclared (first use in this function)
> net/vmw_vsock/vmci_transport.c: At top level:
> net/vmw_vsock/vmci_transport.c:568: error: expected declaration 
> specifiers or ?...? before ?vmci_datagram_recv_cb?
> net/vmw_vsock/vmci_transport.c: In function 
> ?vmci_transport_datagram_create_hnd?:
> net/vmw_vsock/vmci_transport.c:578: error: implicit declaration of 
> function ?vmci_datagram_create_handle_priv?
> net/vmw_vsock/vmci_transport.c:579: error: 
> ?VMCI_PRIVILEGE_FLAG_TRUSTED? undeclared (first use in this function)
> net/vmw_vsock/vmci_transport.c:580: error: ?recv_cb? undeclared (first 
> use in this function)
> net/vmw_vsock/vmci_transport.c:583: error: ?VMCI_ERROR_NO_ACCESS? 
> undeclared (first use in this function)
> net/vmw_vsock/vmci_transport.c:584: error: implicit declaration of 
> function ?vmci_datagram_create_handle?
> net/vmw_vsock/vmci_transport.c: In function 
> ?vmci_transport_recv_dgram_cb?:
> net/vmw_vsock/vmci_transport.c:615: error: dereferencing pointer to 
> incomplete type
> net/vmw_vsock/vmci_transport.c:616: error: ?VMCI_ERROR_NO_ACCESS? 
> undeclared (first use in this function)
> net/vmw_vsock/vmci_transport.c:618: error: implicit declaration of 
> function ?VMCI_DG_SIZE?
> net/vmw_vsock/vmci_transport.c:630: error: ?VMCI_SUCCESS? undeclared 
> (first use in this function)
> net/vmw_vsock/vmci_transport.c: In function 
> ?vmci_transport_recv_stream_cb?:
> net/vmw_vsock/vmci_transport.c:667: error: ?VMCI_SUCCESS? undeclared 
> (first use in this function)
> net/vmw_vsock/vmci_transport.c:674: error: dereferencing pointer to 
> incomplete type
> net/vmw_vsock/vmci_transport.c:675: error: dereferencing pointer to 
> incomplete type
> net/vmw_vsock/vmci_transport.c:676: error: ?VMCI_ERROR_NO_ACCESS? 
> undeclared (first use in this function)
> net/vmw_vsock/vmci_transport.c:680: error: ?VMCI_ERROR_INVALID_ARGS? 
> undeclared (first use in this function)
> net/vmw_vsock/vmci_transport.c:707: error: ?VMCI_ERROR_NOT_FOUND? 
> undeclared (first use in this function)
> net/vmw_vsock/vmci_transport.c:759: error: ?VMCI_ERROR_NO_MEM? 
> undeclared (first use in this function)
> net/vmw_vsock/vmci_transport.c: At top level:
> net/vmw_vsock/vmci_transport.c:785: warning: ?struct vmci_event_data? 
> declared inside parameter list
> net/vmw_vsock/vmci_transport.c:783: error: conflicting types for 
> ?vmci_transport_peer_attach_cb?
> net/vmw_vsock/vmci_transport.c:45: note: previous declaration of 
> ?vmci_transport_peer_attach_cb? was here
> net/vmw_vsock/vmci_transport.c: In function 
> ?vmci_transport_peer_attach_cb?:
> net/vmw_vsock/vmci_transport.c:791: error: implicit declaration of 
> function ?vmci_event_data_const_payload?
> net/vmw_vsock/vmci_transport.c:791: warning: assignment makes pointer 
> from integer without a cast
> net/vmw_vsock/vmci_transport.c:807: error: implicit declaration of 
> function ?vmci_handle_is_equal?
> net/vmw_vsock/vmci_transport.c:808: error: dereferencing pointer to 
> incomplete type
> net/vmw_vsock/vmci_transport.c: In function 
> ?vmci_transport_handle_detach?:
> net/vmw_vsock/vmci_transport.c:826: error: implicit declaration of 
> function ?vmci_handle_is_invalid?
> net/vmw_vsock/vmci_transport.c: At top level:
> net/vmw_vsock/vmci_transport.c:861: warning: ?struct vmci_event_data? 
> declared inside parameter list
> net/vmw_vsock/vmci_transport.c:859: error: conflicting types for 
> ?vmci_transport_peer_detach_cb?
> net/vmw_vsock/vmci_transport.c:48: note: previous declaration of 
> ?vmci_transport_peer_detach_cb? was here
> net/vmw_vsock/vmci_transport.c: In function 
> ?vmci_transport_peer_detach_cb?:
> net/vmw_vsock/vmci_transport.c:867: warning: assignment makes pointer 
> from integer without a cast
> net/vmw_vsock/vmci_transport.c:869: error: dereferencing pointer to 
> incomplete type
> net/vmw_vsock/vmci_transport.c:880: error: dereferencing pointer to 
> incomplete type
> net/vmw_vsock/vmci_transport.c: At top level:
> net/vmw_vsock/vmci_transport.c:889: warning: ?struct vmci_event_data? 
> declared inside parameter list
> net/vmw_vsock/vmci_transport.c: In function 
> ?vmci_transport_recv_connecting_server?:
> net/vmw_vsock/vmci_transport.c:1126: error: storage size of ?handle? 
> isn?t known
> net/vmw_vsock/vmci_transport.c:1165: error: implicit declaration of 
> function ?vmci_event_subscribe?
> net/vmw_vsock/vmci_transport.c:1165: error: 
> ?VMCI_EVENT_QP_PEER_DETACH? undeclared (first use in this function)
> net/vmw_vsock/vmci_transport.c:1168: error: ?VMCI_SUCCESS? undeclared 
> (first use in this function)
> net/vmw_vsock/vmci_transport.c:1185: error: ?VMCI_QPFLAG_ATTACH_ONLY? 
> undeclared (first use in this function)
> net/vmw_vsock/vmci_transport.c:1186: error: ?VMCI_QPFLAG_LOCAL? 
> undeclared (first use in this function)
> net/vmw_vsock/vmci_transport.c:1228: error: type of formal parameter 2 
> is incomplete
> net/vmw_vsock/vmci_transport.c:1126: warning: unused variable ?handle?
> net/vmw_vsock/vmci_transport.c: In function 
> ?vmci_transport_recv_connecting_client_negotiate?:
> net/vmw_vsock/vmci_transport.c:1373: error: storage size of ?handle? 
> isn?t known
> net/vmw_vsock/vmci_transport.c:1384: error: ?VMCI_INVALID_HANDLE? 
> undeclared (first use in this function)
> net/vmw_vsock/vmci_transport.c:1436: error: 
> ?VMCI_EVENT_QP_PEER_ATTACH? undeclared (first use in this function)
> net/vmw_vsock/vmci_transport.c:1439: error: ?VMCI_SUCCESS? undeclared 
> (first use in this function)
> net/vmw_vsock/vmci_transport.c:1444: error: 
> ?VMCI_EVENT_QP_PEER_DETACH? undeclared (first use in this function)
> net/vmw_vsock/vmci_transport.c:1455: error: ?VMCI_QPFLAG_LOCAL? 
> undeclared (first use in this function)
> net/vmw_vsock/vmci_transport.c:1470: error: type of formal parameter 2 
> is incomplete
> net/vmw_vsock/vmci_transport.c:1491: error: implicit declaration of 
> function ?vmci_event_unsubscribe?
> net/vmw_vsock/vmci_transport.c:1497: error: implicit declaration of 
> function ?vmci_qpair_detach?
> net/vmw_vsock/vmci_transport.c:1373: warning: unused variable ?handle?
> net/vmw_vsock/vmci_transport.c: In function ?vmci_transport_socket_init?:
> net/vmw_vsock/vmci_transport.c:1589: error: ?VMCI_INVALID_HANDLE? 
> undeclared (first use in this function)
> net/vmw_vsock/vmci_transport.c: In function ?vmci_transport_destruct?:
> net/vmw_vsock/vmci_transport.c:1629: error: ?VMCI_INVALID_HANDLE? 
> undeclared (first use in this function)
> net/vmw_vsock/vmci_transport.c: In function ?vmci_transport_release?:
> net/vmw_vsock/vmci_transport.c:1644: error: implicit declaration of 
> function ?vmci_datagram_destroy_handle?
> net/vmw_vsock/vmci_transport.c:1645: error: ?VMCI_INVALID_HANDLE? 
> undeclared (first use in this function)
> net/vmw_vsock/vmci_transport.c: In function ?vmci_transport_dgram_bind?:
> net/vmw_vsock/vmci_transport.c:1666: error: ?VMCI_FLAG_ANYCID_DG_HND? 
> undeclared (first use in this function)
> net/vmw_vsock/vmci_transport.c:1671: warning: passing argument 4 of 
> ?vmci_transport_datagram_create_hnd? from incompatible pointer type
> net/vmw_vsock/vmci_transport.c:566: note: expected ?struct vmci_handle 
> *? but argument is of type ?struct sock *?
> net/vmw_vsock/vmci_transport.c:1671: error: too many arguments to 
> function ?vmci_transport_datagram_create_hnd?
> net/vmw_vsock/vmci_transport.c:1672: error: ?VMCI_SUCCESS? undeclared 
> (first use in this function)
> net/vmw_vsock/vmci_transport.c: In function 
> ?vmci_transport_dgram_enqueue?:
> net/vmw_vsock/vmci_transport.c:1689: error: ?VMCI_MAX_DG_PAYLOAD_SIZE? 
> undeclared (first use in this function)
> net/vmw_vsock/vmci_transport.c:1696: error: dereferencing pointer to 
> incomplete type
> net/vmw_vsock/vmci_transport.c:1700: error: implicit declaration of 
> function ?VMCI_DG_PAYLOAD?
> net/vmw_vsock/vmci_transport.c:1700: warning: passing argument 1 of 
> ?memcpy_fromiovec? makes pointer from integer without a cast
> include/linux/socket.h:307: note: expected ?unsigned char *? but 
> argument is of type ?int?
> net/vmw_vsock/vmci_transport.c:1702: error: dereferencing pointer to 
> incomplete type
> net/vmw_vsock/vmci_transport.c:1704: error: dereferencing pointer to 
> incomplete type
> net/vmw_vsock/vmci_transport.c:1706: error: dereferencing pointer to 
> incomplete type
> net/vmw_vsock/vmci_transport.c:1713: error: dereferencing pointer to 
> incomplete type
> net/vmw_vsock/vmci_transport.c: In function 
> ?vmci_transport_dgram_dequeue?:
> net/vmw_vsock/vmci_transport.c:1746: error: dereferencing pointer to 
> incomplete type
> net/vmw_vsock/vmci_transport.c:1748: error: dereferencing pointer to 
> incomplete type
> net/vmw_vsock/vmci_transport.c:1759: error: dereferencing pointer to 
> incomplete type
> net/vmw_vsock/vmci_transport.c:1770: error: dereferencing pointer to 
> incomplete type
> net/vmw_vsock/vmci_transport.c:1770: error: dereferencing pointer to 
> incomplete type
> net/vmw_vsock/vmci_transport.c: In function ?vmci_transport_dgram_allow?:
> net/vmw_vsock/vmci_transport.c:1786: error: 
> ?VMCI_UNITY_PBRPC_REGISTER? undeclared (first use in this function)
> net/vmw_vsock/vmci_transport.c: In function 
> ?vmci_transport_stream_dequeue?:
> net/vmw_vsock/vmci_transport.c:1830: error: implicit declaration of 
> function ?vmci_qpair_peekv?
> net/vmw_vsock/vmci_transport.c:1832: error: implicit declaration of 
> function ?vmci_qpair_dequev?
> net/vmw_vsock/vmci_transport.c: In function 
> ?vmci_transport_stream_enqueue?:
> net/vmw_vsock/vmci_transport.c:1840: error: implicit declaration of 
> function ?vmci_qpair_enquev?
> net/vmw_vsock/vmci_transport.c: In function 
> ?vmci_transport_stream_has_data?:
> net/vmw_vsock/vmci_transport.c:1845: error: implicit declaration of 
> function ?vmci_qpair_consume_buf_ready?
> net/vmw_vsock/vmci_transport.c: In function 
> ?vmci_transport_stream_has_space?:
> net/vmw_vsock/vmci_transport.c:1850: error: implicit declaration of 
> function ?vmci_qpair_produce_free_space?
> net/vmw_vsock/vmci_transport.c: In function 
> ?vmci_transport_get_local_cid?:
> net/vmw_vsock/vmci_transport.c:2055: error: implicit declaration of 
> function ?vmci_get_context_id?
> net/vmw_vsock/vmci_transport.c: In function ?vmci_transport_init?:
> net/vmw_vsock/vmci_transport.c:2102: error: ?VMCI_FLAG_ANYCID_DG_HND? 
> undeclared (first use in this function)
> net/vmw_vsock/vmci_transport.c:2105: error: too many arguments to 
> function ?vmci_transport_datagram_create_hnd?
> net/vmw_vsock/vmci_transport.c:2106: error: ?VMCI_SUCCESS? undeclared 
> (first use in this function)
> net/vmw_vsock/vmci_transport.c:2111: error: ?VMCI_EVENT_QP_RESUMED? 
> undeclared (first use in this function)
> net/vmw_vsock/vmci_transport.c:2130: error: 
> ?vmci_transport_stream_handle? has an incomplete type
> net/vmw_vsock/vmci_transport.c: In function ?vmci_transport_exit?:
> net/vmw_vsock/vmci_transport.c:2137: error: 
> ?vmci_transport_stream_handle? has an incomplete type
> net/vmw_vsock/vmci_transport.c:2139: error: 
> ?vmci_transport_stream_handle? has an incomplete type
> net/vmw_vsock/vmci_transport.c:2139: error: ?VMCI_SUCCESS? undeclared 
> (first use in this function)
> net/vmw_vsock/vmci_transport.c:2141: error: ?VMCI_INVALID_HANDLE? 
> undeclared (first use in this function)
> net/vmw_vsock/vmci_transport.c:2141: error: 
> ?vmci_transport_stream_handle? has an incomplete type
> make[2]: *** [net/vmw_vsock/vmci_transport.o] Error 1
> make[1]: *** [net/vmw_vsock] Error 2
> make: *** [net] Error 2

^ permalink raw reply related

* Query/Help: Enabling net-sched config cause IXGE tx hang and continuous NMIs
From: Sasikanth babu @ 2013-02-14  9:59 UTC (permalink / raw)
  To: netdev

Hi all,

   After enabling Queueing/Scheduling and Classification, I'm getting
NMI's continuously and also observed RCU stall. I had truned off
gro,lro,tso and gso settings too.

IGB version:        3.2.9
IXGBE version :  3.4.24

TX HANG
=======

[   68.353583] ixgbe 0000:82:00.0: eth8: Detected Tx Unit Hang
[   68.353585]   Tx Queue             <0>
[   68.353586]   TDH, TDT             <0>, <e>
[   68.353587]   next_to_use          <e>
[   68.353587]   next_to_clean        <2>
[   68.353591] ixgbe 0000:82:00.0: eth8: tx_buffer_info[next_to_clean]
[   68.353592]   time_stamp           <ffffa375>
[   68.353592]   jiffies              <ffffa582>
[   68.353595] ixgbe 0000:82:00.0: eth8: tx hang 1 detected on queue
0, resetting adapter
[   68.353611] ixgbe 0000:82:00.0: eth8: Reset adapter
[   69.232095] ixgbe 0000:82:00.0: eth8: NIC Link is Up 10 Gbps, Flow
Control: RX/TX
[   71.670656] eth0: no IPv6 routers present
[   72.099976] ------------[ cut here ]------------
[   72.099984] WARNING: at linux/net/sched/sch_generic.c:
256 dev_watchdog+0x1fa/0x210()
[   72.099988] Hardware name: To be filled by O.E.M.
[   72.099990] NETDEV WATCHDOG: eth0 (igb): transmit queue 0 timed out
[   72.099991] Modules linked in: ixgbe pmbus_core igb ltc2978 i2c_mux
pca954x ip_tables iptable_filter ip6_tables ip6table_filter mloopback
[last unloaded: scsi_wait_scan]
[   72.100001] Pid: 102, comm: softirq-net-tx/ Not tainted 2.6.34.12 #1
[   72.100004] Call Trace:
[   72.100006]  <IRQ>  [<ffffffff810455a3>] ? warn_slowpath_common+0x73/0xb0
[   72.100020]  [<ffffffff81038737>] ? __enqueue_rt_entity+0x107/0x2b0
[   72.100024]  [<ffffffff81045640>] ? warn_slowpath_fmt+0x40/0x50
[   72.100031]  [<ffffffff81668dc0>] ? dcbnl_app_nest+0x1100c0/0x11a300
[   72.100038]  [<ffffffff81240451>] ? strlcpy+0x41/0x50
[   72.100040]  [<ffffffff813e2e7a>] ? dev_watchdog+0x1fa/0x210
[   72.100043]  [<ffffffff813e2c80>] ? dev_watchdog+0x0/0x210
[   72.100043]  [<ffffffff813e2c80>] ? dev_watchdog+0x0/0x210
[   72.100049]  [<ffffffff81051cec>] ? run_timer_softirq+0x13c/0x210
[   72.100056]  [<ffffffff8101c618>] ? lapic_next_event+0x18/0x20
[   72.100060]  [<ffffffff8104bb59>] ? __do_softirq+0x99/0x140
[   72.100065]  [<ffffffff81063277>] ? hrtimer_interrupt+0x147/0x260
[   72.100071]  [<ffffffff81003d0c>] ? call_softirq+0x1c/0x30
[   72.100074]  [<ffffffff81005f5d>] ? do_softirq+0x4d/0x80
[   72.100078]  [<ffffffff8101d05a>] ? smp_apic_timer_interrupt+0x6a/0xa0
[   72.100081]  [<ffffffff810037d8>] ? apic_timer_interrupt+0x18/0x20
[   72.100083]  <EOI>  [<ffffffff814d0cd0>] ? _cond_resched+0x0/0x40
[   72.100090]  [<ffffffff8104b9a9>] ? run_ksoftirqd+0x129/0x240
[   72.100093]  [<ffffffff8104b880>] ? run_ksoftirqd+0x0/0x240
[   72.100096]  [<ffffffff8105e8ae>] ? kthread+0x8e/0xa0
[   72.100099]  [<ffffffff81003c14>] ? kernel_thread_helper+0x4/0x10
[   72.100104]  [<ffffffff814d2b11>] ? restore_args+0x0/0x30
[   72.100106]  [<ffffffff8105e820>] ? kthread+0x0/0xa0
[   72.100109]  [<ffffffff81003c10>] ? kernel_thread_helper+0x0/0x10
[   72.100112] ---[ end trace 5434e21c964b684e ]---
[  143.940213] ---[ end trace c9fd33f6d69e8670 ]---
[  143.940216] ixgbe 0000:82:00.0: eth8: Fake Tx hang detected with
timeout of 5 seconds
[  149.934687] ixgbe 0000:82:00.1: eth9: NIC Link is Up 10 Gbps, Flow
Control: RX/TX
[  149.936083] ADDRCONF(NETDEV_CHANGE): eth9: link becomes ready
[  152.824920] ixgbe 0000:82:00.1: eth9: NIC Link is Down
[  153.924681] ixgbe 0000:82:00.0: eth8: Fake Tx hang detected with
timeout of 10 seconds

RCU STALL
=========
[   93.832690] INFO: RCU detected CPU 0 stall (t=1000 jiffies)
[   93.832693] sending NMI to all CPUs:
[   93.832698] NMI backtrace for cpu 0
[   93.832699] CPU 0
[   93.832759] Process softirq-net-tx/ (pid: 6, threadinfo
ffff88027691a000, task ffff880276902cb0)
[   93.832761] Stack:
[   93.834759]  ffffffff8101d0aa 00000015db168963 0000000000000002
0000000000006280
[   93.834762] <0> ffffffff8101d72c ffff880009403df8 ffff880000000002
ffff880009403e08
[   93.834765] <0> 0000000000000000 ffffffff84ade880 ffffffff84ade980
0000000000000000
[   93.834769] Call Trace:
[   93.837207]  <IRQ>
[   93.839308]  [<ffffffff8101d0aa>] ? native_safe_apic_wait_icr_idle+0x1a/0x50
[   93.839313]  [<ffffffff8101d72c>] ?
default_send_IPI_mask_sequence_phys+0xcc/0xe0
[   93.839317]  [<ffffffff8101d839>] ? arch_trigger_all_cpu_backtrace+0x49/0x80
[   93.839322]  [<ffffffff81091fbb>] ? __rcu_pending+0x7b/0x330
[   93.839325]  [<ffffffff810922af>] ? rcu_check_callbacks+0x3f/0x150
[   93.839329]  [<ffffffff8105277f>] ? update_process_times+0x3f/0x70
[   93.839334]  [<ffffffff8106dd78>] ? tick_sched_timer+0x58/0x150
[   93.839338]  [<ffffffff81062f19>] ? __run_hrtimer+0x49/0xe0
[   93.839341]  [<ffffffff81063217>] ? hrtimer_interrupt+0xe7/0x260
[   93.839345]  [<ffffffff8101d055>] ? smp_apic_timer_interrupt+0x65/0xa0
[   93.839349]  [<ffffffff810037d8>] ? apic_timer_interrupt+0x18/0x20
[   93.839351]  <EOI>
[   93.841457]  [<ffffffff813c80aa>] ? __netif_schedule+0xa/0x50
[   93.841461]  [<ffffffff813e3642>] ? sch_direct_xmit+0x122/0x1b0
[   93.841463]  [<ffffffff813e3733>] ? __qdisc_run+0x63/0xe0
[   93.841467]  [<ffffffff813c8a08>] ? net_tx_action+0xe8/0x130
[   93.841471]  [<ffffffff8104b994>] ? run_ksoftirqd+0x114/0x240
[   93.841474]  [<ffffffff8104b880>] ? run_ksoftirqd+0x0/0x240
[   93.841477]  [<ffffffff8105e8ae>] ? kthread+0x8e/0xa0
[   93.841481]  [<ffffffff81003c14>] ? kernel_thread_helper+0x4/0x10
[   93.841486]  [<ffffffff814d2b11>] ? restore_args+0x0/0x30
[   93.841488]  [<ffffffff8105e820>] ? kthread+0x0/0xa0
[   93.841491]  [<ffffffff81003c10>] ? kernel_thread_helper+0x0/0x10
[   93.841493] Code: 66 66 2e 0f 1f


    Newly add config
    -----------------------------

    CONFIG_NET_SCHED=y
    #
    # Queueing/Scheduling
    #
    CONFIG_NET_SCH_CBQ=m
    CONFIG_NET_SCH_HTB=m
    CONFIG_NET_SCH_HFSC=m
    CONFIG_NET_SCH_PRIO=m
    CONFIG_NET_SCH_MULTIQ=m
    CONFIG_NET_SCH_RED=m
    CONFIG_NET_SCH_SFQ=m
    CONFIG_NET_SCH_TEQL=m
    CONFIG_NET_SCH_TBF=m
    CONFIG_NET_SCH_GRED=m
    CONFIG_NET_SCH_DSMARK=m
    CONFIG_NET_SCH_NETEM=m
    CONFIG_NET_SCH_DRR=m
    CONFIG_NET_SCH_INGRESS=m
    #
    # Classification
    #
    CONFIG_NET_CLS=y
    CONFIG_NET_CLS_BASIC=m
    CONFIG_NET_CLS_TCINDEX=m
    CONFIG_NET_CLS_ROUTE4=m
    CONFIG_NET_CLS_FW=m
    CONFIG_NET_CLS_U32=m
    CONFIG_CLS_U32_PERF=y
    CONFIG_CLS_U32_MARK=y
    CONFIG_NET_CLS_RSVP=m
    CONFIG_NET_CLS_RSVP6=m
    CONFIG_NET_CLS_FLOW=m
    CONFIG_NET_CLS_CGROUP=m
    CONFIG_NET_EMATCH=y
    CONFIG_NET_EMATCH_STACK=32
    CONFIG_NET_EMATCH_CMP=m
    CONFIG_NET_EMATCH_NBYTE=m
    CONFIG_NET_EMATCH_U32=m
    CONFIG_NET_EMATCH_META=m
    CONFIG_NET_EMATCH_TEXT=m
    CONFIG_NET_CLS_ACT=y
    CONFIG_NET_ACT_POLICE=m
    CONFIG_NET_ACT_GACT=m
    CONFIG_GACT_PROB=y
    CONFIG_NET_ACT_MIRRED=m
    CONFIG_NET_ACT_IPT=m
    CONFIG_NET_ACT_NAT=m
    CONFIG_NET_ACT_PEDIT=m
    CONFIG_NET_ACT_SIMP=m
    CONFIG_NET_ACT_SKBEDIT=m
    CONFIG_NET_CLS_IND=y
    CONFIG_NET_SCH_FIFO=y


Thanks In Advance

^ permalink raw reply

* Re: [PATCH] net: Convert skb->csum_(start|offset) integrity BUG_ON() to WARN_ON() & drop
From: Thomas Graf @ 2013-02-14 10:18 UTC (permalink / raw)
  To: David Miller; +Cc: netdev
In-Reply-To: <20130213.193759.1094469499685059296.davem@davemloft.net>

On 02/13/13 at 07:37pm, David Miller wrote:
> From: Thomas Graf <tgraf@suug.ch>
> Date: Wed, 13 Feb 2013 23:48:43 +0000
[...]
> >  b) No longer collapse if the new skb would result in a
> >     a headroom + data that exceeds 64K. This seems to be the
> >     most trivial fix.
[...]
> > Other ideas?
> 
> "b" is a good idea.

OK, patch to do so being tested by original reporter.

> Let's not paper over this, this BUG_ON() is really a BUG_ON()
> meaning "FIX ME NOW" :-)

Maybe it's my general dislike of BUG_ON() in the processing
path, especially if the bug condition can be influenced remotely.
It looks absolutely doable to trigger the previously mentioned
partial acking & collapsing on purpose by a malicious receiver
even with an MTU of 1500. I believe we should avoid total DoS
in future similar situations that we don't think of yet.

^ permalink raw reply

* Re: [PATCH 1/1] VSOCK: Introduce VM Sockets
From: Gerd Hoffmann @ 2013-02-14 11:05 UTC (permalink / raw)
  To: Andy King; +Cc: pv-drivers, netdev, linux-kernel, virtualization, gregkh, davem
In-Reply-To: <1360196636-9357-2-git-send-email-acking@vmware.com>

On 02/07/13 01:23, Andy King wrote:
> +		written = transport->stream_enqueue(
> +				vsk, msg->msg_iov,
> +				len - total_written);

Hmm, shouldn't we pass total_written to stream_enqueue here?

In case a blocking send(big-buffer) call gets splitted into multiple
stream_enqueue calls the second (and further) stream_enqueue calls need
to know at which msg offset they should continue sending the data, no?

cheers,
  Gerd

^ permalink raw reply

* pull request (net-next): ipsec-next 2013-02-14
From: Steffen Klassert @ 2013-02-14 11:47 UTC (permalink / raw)
  To: David Miller; +Cc: Herbert Xu, Steffen Klassert, netdev

1) Remove a duplicated call to skb_orphan() in pf_key, from Cong Wang.

2) Prepare xfrm and pf_key for algorithms without pf_key support,
   from Jussi Kivilinna.

3) Fix an unbalanced lock in xfrm_output_one(), from Li RongQing.

4) Add an IPsec state resolution packet queue to handle
   packets that are send before the states are resolved.

5) xfrm4_policy_fini() is unused since 2.6.11, time to remove it.
   From Michal Kubecek.

6) The xfrm gc threshold was configurable just in the initial
   namespace, make it configurable in all namespaces. From
   Michal Kubecek.

7) We currently can not insert policies with mark and mask
   such that some flows would be matched from both policies.
   Allow this if the priorities of these policies are different,
   the one with the higher priority is used in this case.

Please pull or let me know if there are problems.

Thanks!

The following changes since commit cef401de7be8c4e155c6746bfccf721a4fa5fab9:

  net: fix possible wrong checksum generation (2013-01-28 00:27:15 -0500)

are available in the git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/klassert/ipsec-next.git master

for you to fetch changes up to 7cb8a93968e395e40a72a50da0b6114e752304b4:

  xfrm: Allow inserting policies with matching mark and different priorities (2013-02-11 14:07:01 +0100)

----------------------------------------------------------------
Cong Wang (1):
      af_key: remove a duplicated skb_orphan()

Jussi Kivilinna (1):
      pf_key/xfrm_algo: prepare pf_key and xfrm_algo for new algorithms without pfkey support

Li RongQing (1):
      xfrm: fix a unbalanced lock

Michal Kubecek (2):
      xfrm: remove unused xfrm4_policy_fini()
      xfrm: make gc_thresh configurable in all namespaces

Steffen Klassert (2):
      xfrm: Add a state resolution packet queue
      xfrm: Allow inserting policies with matching mark and different priorities

 include/net/dst.h        |    1 +
 include/net/netns/ipv4.h |    1 +
 include/net/netns/ipv6.h |    1 +
 include/net/xfrm.h       |   12 ++-
 net/ipv4/xfrm4_policy.c  |   58 ++++++++---
 net/ipv6/xfrm6_policy.c  |   52 +++++++++-
 net/key/af_key.c         |   40 ++++++--
 net/xfrm/xfrm_algo.c     |   65 ++++++++++--
 net/xfrm/xfrm_output.c   |    2 +-
 net/xfrm/xfrm_policy.c   |  247 ++++++++++++++++++++++++++++++++++++++++++++--
 10 files changed, 438 insertions(+), 41 deletions(-)

^ permalink raw reply

* [PATCH 1/7] af_key: remove a duplicated skb_orphan()
From: Steffen Klassert @ 2013-02-14 11:47 UTC (permalink / raw)
  To: David Miller; +Cc: Herbert Xu, Steffen Klassert, netdev
In-Reply-To: <1360842447-3344-1-git-send-email-steffen.klassert@secunet.com>

From: Cong Wang <xiyou.wangcong@gmail.com>

skb_set_owner_r() will call skb_orphan(), I don't
see any reason to call it twice.

Cc: Steffen Klassert <steffen.klassert@secunet.com>
Cc: Herbert Xu <herbert@gondor.apana.org.au>
Cc: "David S. Miller" <davem@davemloft.net>
Signed-off-by: Cong Wang <xiyou.wangcong@gmail.com>
Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
---
 net/key/af_key.c |    1 -
 1 file changed, 1 deletion(-)

diff --git a/net/key/af_key.c b/net/key/af_key.c
index 5b426a6..6a6e684 100644
--- a/net/key/af_key.c
+++ b/net/key/af_key.c
@@ -203,7 +203,6 @@ static int pfkey_broadcast_one(struct sk_buff *skb, struct sk_buff **skb2,
 	}
 	if (*skb2 != NULL) {
 		if (atomic_read(&sk->sk_rmem_alloc) <= sk->sk_rcvbuf) {
-			skb_orphan(*skb2);
 			skb_set_owner_r(*skb2, sk);
 			skb_queue_tail(&sk->sk_receive_queue, *skb2);
 			sk->sk_data_ready(sk, (*skb2)->len);
-- 
1.7.9.5

^ permalink raw reply related

* [PATCH 2/7] pf_key/xfrm_algo: prepare pf_key and xfrm_algo for new algorithms without pfkey support
From: Steffen Klassert @ 2013-02-14 11:47 UTC (permalink / raw)
  To: David Miller; +Cc: Herbert Xu, Steffen Klassert, netdev
In-Reply-To: <1360842447-3344-1-git-send-email-steffen.klassert@secunet.com>

From: Jussi Kivilinna <jussi.kivilinna@mbnet.fi>

Mark existing algorithms as pfkey supported and make pfkey only use algorithms
that have pfkey_supported set.

Signed-off-by: Jussi Kivilinna <jussi.kivilinna@mbnet.fi>
Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
---
 include/net/xfrm.h   |    5 ++--
 net/key/af_key.c     |   39 +++++++++++++++++++++++-------
 net/xfrm/xfrm_algo.c |   65 +++++++++++++++++++++++++++++++++++++++++++++-----
 3 files changed, 93 insertions(+), 16 deletions(-)

diff --git a/include/net/xfrm.h b/include/net/xfrm.h
index 421f764..814a1ba 100644
--- a/include/net/xfrm.h
+++ b/include/net/xfrm.h
@@ -1320,6 +1320,7 @@ struct xfrm_algo_desc {
 	char *name;
 	char *compat;
 	u8 available:1;
+	u8 pfkey_supported:1;
 	union {
 		struct xfrm_algo_aead_info aead;
 		struct xfrm_algo_auth_info auth;
@@ -1561,8 +1562,8 @@ extern void xfrm_input_init(void);
 extern int xfrm_parse_spi(struct sk_buff *skb, u8 nexthdr, __be32 *spi, __be32 *seq);
 
 extern void xfrm_probe_algs(void);
-extern int xfrm_count_auth_supported(void);
-extern int xfrm_count_enc_supported(void);
+extern int xfrm_count_pfkey_auth_supported(void);
+extern int xfrm_count_pfkey_enc_supported(void);
 extern struct xfrm_algo_desc *xfrm_aalg_get_byidx(unsigned int idx);
 extern struct xfrm_algo_desc *xfrm_ealg_get_byidx(unsigned int idx);
 extern struct xfrm_algo_desc *xfrm_aalg_get_byid(int alg_id);
diff --git a/net/key/af_key.c b/net/key/af_key.c
index 6a6e684..cb75f9b 100644
--- a/net/key/af_key.c
+++ b/net/key/af_key.c
@@ -815,18 +815,21 @@ static struct sk_buff *__pfkey_xfrm_state2msg(const struct xfrm_state *x,
 	sa->sadb_sa_auth = 0;
 	if (x->aalg) {
 		struct xfrm_algo_desc *a = xfrm_aalg_get_byname(x->aalg->alg_name, 0);
-		sa->sadb_sa_auth = a ? a->desc.sadb_alg_id : 0;
+		sa->sadb_sa_auth = (a && a->pfkey_supported) ?
+					a->desc.sadb_alg_id : 0;
 	}
 	sa->sadb_sa_encrypt = 0;
 	BUG_ON(x->ealg && x->calg);
 	if (x->ealg) {
 		struct xfrm_algo_desc *a = xfrm_ealg_get_byname(x->ealg->alg_name, 0);
-		sa->sadb_sa_encrypt = a ? a->desc.sadb_alg_id : 0;
+		sa->sadb_sa_encrypt = (a && a->pfkey_supported) ?
+					a->desc.sadb_alg_id : 0;
 	}
 	/* KAME compatible: sadb_sa_encrypt is overloaded with calg id */
 	if (x->calg) {
 		struct xfrm_algo_desc *a = xfrm_calg_get_byname(x->calg->alg_name, 0);
-		sa->sadb_sa_encrypt = a ? a->desc.sadb_alg_id : 0;
+		sa->sadb_sa_encrypt = (a && a->pfkey_supported) ?
+					a->desc.sadb_alg_id : 0;
 	}
 
 	sa->sadb_sa_flags = 0;
@@ -1137,7 +1140,7 @@ static struct xfrm_state * pfkey_msg2xfrm_state(struct net *net,
 	if (sa->sadb_sa_auth) {
 		int keysize = 0;
 		struct xfrm_algo_desc *a = xfrm_aalg_get_byid(sa->sadb_sa_auth);
-		if (!a) {
+		if (!a || !a->pfkey_supported) {
 			err = -ENOSYS;
 			goto out;
 		}
@@ -1159,7 +1162,7 @@ static struct xfrm_state * pfkey_msg2xfrm_state(struct net *net,
 	if (sa->sadb_sa_encrypt) {
 		if (hdr->sadb_msg_satype == SADB_X_SATYPE_IPCOMP) {
 			struct xfrm_algo_desc *a = xfrm_calg_get_byid(sa->sadb_sa_encrypt);
-			if (!a) {
+			if (!a || !a->pfkey_supported) {
 				err = -ENOSYS;
 				goto out;
 			}
@@ -1171,7 +1174,7 @@ static struct xfrm_state * pfkey_msg2xfrm_state(struct net *net,
 		} else {
 			int keysize = 0;
 			struct xfrm_algo_desc *a = xfrm_ealg_get_byid(sa->sadb_sa_encrypt);
-			if (!a) {
+			if (!a || !a->pfkey_supported) {
 				err = -ENOSYS;
 				goto out;
 			}
@@ -1577,13 +1580,13 @@ static struct sk_buff *compose_sadb_supported(const struct sadb_msg *orig,
 	struct sadb_msg *hdr;
 	int len, auth_len, enc_len, i;
 
-	auth_len = xfrm_count_auth_supported();
+	auth_len = xfrm_count_pfkey_auth_supported();
 	if (auth_len) {
 		auth_len *= sizeof(struct sadb_alg);
 		auth_len += sizeof(struct sadb_supported);
 	}
 
-	enc_len = xfrm_count_enc_supported();
+	enc_len = xfrm_count_pfkey_enc_supported();
 	if (enc_len) {
 		enc_len *= sizeof(struct sadb_alg);
 		enc_len += sizeof(struct sadb_supported);
@@ -1614,6 +1617,8 @@ static struct sk_buff *compose_sadb_supported(const struct sadb_msg *orig,
 			struct xfrm_algo_desc *aalg = xfrm_aalg_get_byidx(i);
 			if (!aalg)
 				break;
+			if (!aalg->pfkey_supported)
+				continue;
 			if (aalg->available)
 				*ap++ = aalg->desc;
 		}
@@ -1633,6 +1638,8 @@ static struct sk_buff *compose_sadb_supported(const struct sadb_msg *orig,
 			struct xfrm_algo_desc *ealg = xfrm_ealg_get_byidx(i);
 			if (!ealg)
 				break;
+			if (!ealg->pfkey_supported)
+				continue;
 			if (ealg->available)
 				*ap++ = ealg->desc;
 		}
@@ -2824,6 +2831,8 @@ static int count_ah_combs(const struct xfrm_tmpl *t)
 		const struct xfrm_algo_desc *aalg = xfrm_aalg_get_byidx(i);
 		if (!aalg)
 			break;
+		if (!aalg->pfkey_supported)
+			continue;
 		if (aalg_tmpl_set(t, aalg) && aalg->available)
 			sz += sizeof(struct sadb_comb);
 	}
@@ -2839,6 +2848,9 @@ static int count_esp_combs(const struct xfrm_tmpl *t)
 		if (!ealg)
 			break;
 
+		if (!ealg->pfkey_supported)
+			continue;
+
 		if (!(ealg_tmpl_set(t, ealg) && ealg->available))
 			continue;
 
@@ -2847,6 +2859,9 @@ static int count_esp_combs(const struct xfrm_tmpl *t)
 			if (!aalg)
 				break;
 
+			if (!aalg->pfkey_supported)
+				continue;
+
 			if (aalg_tmpl_set(t, aalg) && aalg->available)
 				sz += sizeof(struct sadb_comb);
 		}
@@ -2870,6 +2885,9 @@ static void dump_ah_combs(struct sk_buff *skb, const struct xfrm_tmpl *t)
 		if (!aalg)
 			break;
 
+		if (!aalg->pfkey_supported)
+			continue;
+
 		if (aalg_tmpl_set(t, aalg) && aalg->available) {
 			struct sadb_comb *c;
 			c = (struct sadb_comb*)skb_put(skb, sizeof(struct sadb_comb));
@@ -2902,6 +2920,9 @@ static void dump_esp_combs(struct sk_buff *skb, const struct xfrm_tmpl *t)
 		if (!ealg)
 			break;
 
+		if (!ealg->pfkey_supported)
+			continue;
+
 		if (!(ealg_tmpl_set(t, ealg) && ealg->available))
 			continue;
 
@@ -2910,6 +2931,8 @@ static void dump_esp_combs(struct sk_buff *skb, const struct xfrm_tmpl *t)
 			const struct xfrm_algo_desc *aalg = xfrm_aalg_get_byidx(k);
 			if (!aalg)
 				break;
+			if (!aalg->pfkey_supported)
+				continue;
 			if (!(aalg_tmpl_set(t, aalg) && aalg->available))
 				continue;
 			c = (struct sadb_comb*)skb_put(skb, sizeof(struct sadb_comb));
diff --git a/net/xfrm/xfrm_algo.c b/net/xfrm/xfrm_algo.c
index f9a5495..6fb9d00 100644
--- a/net/xfrm/xfrm_algo.c
+++ b/net/xfrm/xfrm_algo.c
@@ -35,6 +35,8 @@ static struct xfrm_algo_desc aead_list[] = {
 		}
 	},
 
+	.pfkey_supported = 1,
+
 	.desc = {
 		.sadb_alg_id = SADB_X_EALG_AES_GCM_ICV8,
 		.sadb_alg_ivlen = 8,
@@ -51,6 +53,8 @@ static struct xfrm_algo_desc aead_list[] = {
 		}
 	},
 
+	.pfkey_supported = 1,
+
 	.desc = {
 		.sadb_alg_id = SADB_X_EALG_AES_GCM_ICV12,
 		.sadb_alg_ivlen = 8,
@@ -67,6 +71,8 @@ static struct xfrm_algo_desc aead_list[] = {
 		}
 	},
 
+	.pfkey_supported = 1,
+
 	.desc = {
 		.sadb_alg_id = SADB_X_EALG_AES_GCM_ICV16,
 		.sadb_alg_ivlen = 8,
@@ -83,6 +89,8 @@ static struct xfrm_algo_desc aead_list[] = {
 		}
 	},
 
+	.pfkey_supported = 1,
+
 	.desc = {
 		.sadb_alg_id = SADB_X_EALG_AES_CCM_ICV8,
 		.sadb_alg_ivlen = 8,
@@ -99,6 +107,8 @@ static struct xfrm_algo_desc aead_list[] = {
 		}
 	},
 
+	.pfkey_supported = 1,
+
 	.desc = {
 		.sadb_alg_id = SADB_X_EALG_AES_CCM_ICV12,
 		.sadb_alg_ivlen = 8,
@@ -115,6 +125,8 @@ static struct xfrm_algo_desc aead_list[] = {
 		}
 	},
 
+	.pfkey_supported = 1,
+
 	.desc = {
 		.sadb_alg_id = SADB_X_EALG_AES_CCM_ICV16,
 		.sadb_alg_ivlen = 8,
@@ -131,6 +143,8 @@ static struct xfrm_algo_desc aead_list[] = {
 		}
 	},
 
+	.pfkey_supported = 1,
+
 	.desc = {
 		.sadb_alg_id = SADB_X_EALG_NULL_AES_GMAC,
 		.sadb_alg_ivlen = 8,
@@ -151,6 +165,8 @@ static struct xfrm_algo_desc aalg_list[] = {
 		}
 	},
 
+	.pfkey_supported = 1,
+
 	.desc = {
 		.sadb_alg_id = SADB_X_AALG_NULL,
 		.sadb_alg_ivlen = 0,
@@ -169,6 +185,8 @@ static struct xfrm_algo_desc aalg_list[] = {
 		}
 	},
 
+	.pfkey_supported = 1,
+
 	.desc = {
 		.sadb_alg_id = SADB_AALG_MD5HMAC,
 		.sadb_alg_ivlen = 0,
@@ -187,6 +205,8 @@ static struct xfrm_algo_desc aalg_list[] = {
 		}
 	},
 
+	.pfkey_supported = 1,
+
 	.desc = {
 		.sadb_alg_id = SADB_AALG_SHA1HMAC,
 		.sadb_alg_ivlen = 0,
@@ -205,6 +225,8 @@ static struct xfrm_algo_desc aalg_list[] = {
 		}
 	},
 
+	.pfkey_supported = 1,
+
 	.desc = {
 		.sadb_alg_id = SADB_X_AALG_SHA2_256HMAC,
 		.sadb_alg_ivlen = 0,
@@ -222,6 +244,8 @@ static struct xfrm_algo_desc aalg_list[] = {
 		}
 	},
 
+	.pfkey_supported = 1,
+
 	.desc = {
 		.sadb_alg_id = SADB_X_AALG_SHA2_384HMAC,
 		.sadb_alg_ivlen = 0,
@@ -239,6 +263,8 @@ static struct xfrm_algo_desc aalg_list[] = {
 		}
 	},
 
+	.pfkey_supported = 1,
+
 	.desc = {
 		.sadb_alg_id = SADB_X_AALG_SHA2_512HMAC,
 		.sadb_alg_ivlen = 0,
@@ -257,6 +283,8 @@ static struct xfrm_algo_desc aalg_list[] = {
 		}
 	},
 
+	.pfkey_supported = 1,
+
 	.desc = {
 		.sadb_alg_id = SADB_X_AALG_RIPEMD160HMAC,
 		.sadb_alg_ivlen = 0,
@@ -274,6 +302,8 @@ static struct xfrm_algo_desc aalg_list[] = {
 		}
 	},
 
+	.pfkey_supported = 1,
+
 	.desc = {
 		.sadb_alg_id = SADB_X_AALG_AES_XCBC_MAC,
 		.sadb_alg_ivlen = 0,
@@ -295,6 +325,8 @@ static struct xfrm_algo_desc ealg_list[] = {
 		}
 	},
 
+	.pfkey_supported = 1,
+
 	.desc = {
 		.sadb_alg_id =	SADB_EALG_NULL,
 		.sadb_alg_ivlen = 0,
@@ -313,6 +345,8 @@ static struct xfrm_algo_desc ealg_list[] = {
 		}
 	},
 
+	.pfkey_supported = 1,
+
 	.desc = {
 		.sadb_alg_id = SADB_EALG_DESCBC,
 		.sadb_alg_ivlen = 8,
@@ -331,6 +365,8 @@ static struct xfrm_algo_desc ealg_list[] = {
 		}
 	},
 
+	.pfkey_supported = 1,
+
 	.desc = {
 		.sadb_alg_id = SADB_EALG_3DESCBC,
 		.sadb_alg_ivlen = 8,
@@ -349,6 +385,8 @@ static struct xfrm_algo_desc ealg_list[] = {
 		}
 	},
 
+	.pfkey_supported = 1,
+
 	.desc = {
 		.sadb_alg_id = SADB_X_EALG_CASTCBC,
 		.sadb_alg_ivlen = 8,
@@ -367,6 +405,8 @@ static struct xfrm_algo_desc ealg_list[] = {
 		}
 	},
 
+	.pfkey_supported = 1,
+
 	.desc = {
 		.sadb_alg_id = SADB_X_EALG_BLOWFISHCBC,
 		.sadb_alg_ivlen = 8,
@@ -385,6 +425,8 @@ static struct xfrm_algo_desc ealg_list[] = {
 		}
 	},
 
+	.pfkey_supported = 1,
+
 	.desc = {
 		.sadb_alg_id = SADB_X_EALG_AESCBC,
 		.sadb_alg_ivlen = 8,
@@ -403,6 +445,8 @@ static struct xfrm_algo_desc ealg_list[] = {
 		}
 	},
 
+	.pfkey_supported = 1,
+
 	.desc = {
 		.sadb_alg_id = SADB_X_EALG_SERPENTCBC,
 		.sadb_alg_ivlen = 8,
@@ -421,6 +465,8 @@ static struct xfrm_algo_desc ealg_list[] = {
 		}
 	},
 
+	.pfkey_supported = 1,
+
 	.desc = {
 		.sadb_alg_id = SADB_X_EALG_CAMELLIACBC,
 		.sadb_alg_ivlen = 8,
@@ -439,6 +485,8 @@ static struct xfrm_algo_desc ealg_list[] = {
 		}
 	},
 
+	.pfkey_supported = 1,
+
 	.desc = {
 		.sadb_alg_id = SADB_X_EALG_TWOFISHCBC,
 		.sadb_alg_ivlen = 8,
@@ -456,6 +504,8 @@ static struct xfrm_algo_desc ealg_list[] = {
 		}
 	},
 
+	.pfkey_supported = 1,
+
 	.desc = {
 		.sadb_alg_id = SADB_X_EALG_AESCTR,
 		.sadb_alg_ivlen	= 8,
@@ -473,6 +523,7 @@ static struct xfrm_algo_desc calg_list[] = {
 			.threshold = 90,
 		}
 	},
+	.pfkey_supported = 1,
 	.desc = { .sadb_alg_id = SADB_X_CALG_DEFLATE }
 },
 {
@@ -482,6 +533,7 @@ static struct xfrm_algo_desc calg_list[] = {
 			.threshold = 90,
 		}
 	},
+	.pfkey_supported = 1,
 	.desc = { .sadb_alg_id = SADB_X_CALG_LZS }
 },
 {
@@ -491,6 +543,7 @@ static struct xfrm_algo_desc calg_list[] = {
 			.threshold = 50,
 		}
 	},
+	.pfkey_supported = 1,
 	.desc = { .sadb_alg_id = SADB_X_CALG_LZJH }
 },
 };
@@ -714,27 +767,27 @@ void xfrm_probe_algs(void)
 }
 EXPORT_SYMBOL_GPL(xfrm_probe_algs);
 
-int xfrm_count_auth_supported(void)
+int xfrm_count_pfkey_auth_supported(void)
 {
 	int i, n;
 
 	for (i = 0, n = 0; i < aalg_entries(); i++)
-		if (aalg_list[i].available)
+		if (aalg_list[i].available && aalg_list[i].pfkey_supported)
 			n++;
 	return n;
 }
-EXPORT_SYMBOL_GPL(xfrm_count_auth_supported);
+EXPORT_SYMBOL_GPL(xfrm_count_pfkey_auth_supported);
 
-int xfrm_count_enc_supported(void)
+int xfrm_count_pfkey_enc_supported(void)
 {
 	int i, n;
 
 	for (i = 0, n = 0; i < ealg_entries(); i++)
-		if (ealg_list[i].available)
+		if (ealg_list[i].available && ealg_list[i].pfkey_supported)
 			n++;
 	return n;
 }
-EXPORT_SYMBOL_GPL(xfrm_count_enc_supported);
+EXPORT_SYMBOL_GPL(xfrm_count_pfkey_enc_supported);
 
 #if defined(CONFIG_INET_ESP) || defined(CONFIG_INET_ESP_MODULE) || defined(CONFIG_INET6_ESP) || defined(CONFIG_INET6_ESP_MODULE)
 
-- 
1.7.9.5

^ permalink raw reply related

* [PATCH 4/7] xfrm: Add a state resolution packet queue
From: Steffen Klassert @ 2013-02-14 11:47 UTC (permalink / raw)
  To: David Miller; +Cc: Herbert Xu, Steffen Klassert, netdev
In-Reply-To: <1360842447-3344-1-git-send-email-steffen.klassert@secunet.com>

As the default, we blackhole packets until the key manager resolves
the states. This patch implements a packet queue where IPsec packets
are queued until the states are resolved. We generate a dummy xfrm
bundle, the output routine of the returned route enqueues the packet
to a per policy queue and arms a timer that checks for state resolution
when dst_output() is called. Once the states are resolved, the packets
are sent out of the queue. If the states are not resolved after some
time, the queue is flushed.

This patch keeps the defaut behaviour to blackhole packets as long
as we have no states. To enable the packet queue the sysctl
xfrm_larval_drop must be switched off.

Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
---
 include/net/dst.h      |    1 +
 include/net/xfrm.h     |    7 ++
 net/xfrm/xfrm_policy.c |  229 +++++++++++++++++++++++++++++++++++++++++++++++-
 3 files changed, 233 insertions(+), 4 deletions(-)

diff --git a/include/net/dst.h b/include/net/dst.h
index 9a78810..3da47e0 100644
--- a/include/net/dst.h
+++ b/include/net/dst.h
@@ -61,6 +61,7 @@ struct dst_entry {
 #define DST_NOPEER		0x0040
 #define DST_FAKE_RTABLE		0x0080
 #define DST_XFRM_TUNNEL		0x0100
+#define DST_XFRM_QUEUE		0x0200
 
 	unsigned short		pending_confirm;
 
diff --git a/include/net/xfrm.h b/include/net/xfrm.h
index 814a1ba..30f3e5b 100644
--- a/include/net/xfrm.h
+++ b/include/net/xfrm.h
@@ -501,6 +501,12 @@ struct xfrm_policy_walk {
 	u32 seq;
 };
 
+struct xfrm_policy_queue {
+	struct sk_buff_head	hold_queue;
+	struct timer_list	hold_timer;
+	unsigned long		timeout;
+};
+
 struct xfrm_policy {
 #ifdef CONFIG_NET_NS
 	struct net		*xp_net;
@@ -522,6 +528,7 @@ struct xfrm_policy {
 	struct xfrm_lifetime_cfg lft;
 	struct xfrm_lifetime_cur curlft;
 	struct xfrm_policy_walk_entry walk;
+	struct xfrm_policy_queue polq;
 	u8			type;
 	u8			action;
 	u8			flags;
diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c
index 41eabc4..456b11b 100644
--- a/net/xfrm/xfrm_policy.c
+++ b/net/xfrm/xfrm_policy.c
@@ -35,6 +35,10 @@
 
 #include "xfrm_hash.h"
 
+#define XFRM_QUEUE_TMO_MIN ((unsigned)(HZ/10))
+#define XFRM_QUEUE_TMO_MAX ((unsigned)(60*HZ))
+#define XFRM_MAX_QUEUE_LEN	100
+
 DEFINE_MUTEX(xfrm_cfg_mutex);
 EXPORT_SYMBOL(xfrm_cfg_mutex);
 
@@ -51,7 +55,7 @@ static struct kmem_cache *xfrm_dst_cache __read_mostly;
 static void xfrm_init_pmtu(struct dst_entry *dst);
 static int stale_bundle(struct dst_entry *dst);
 static int xfrm_bundle_ok(struct xfrm_dst *xdst);
-
+static void xfrm_policy_queue_process(unsigned long arg);
 
 static struct xfrm_policy *__xfrm_policy_unlink(struct xfrm_policy *pol,
 						int dir);
@@ -287,8 +291,11 @@ struct xfrm_policy *xfrm_policy_alloc(struct net *net, gfp_t gfp)
 		INIT_HLIST_NODE(&policy->byidx);
 		rwlock_init(&policy->lock);
 		atomic_set(&policy->refcnt, 1);
+		skb_queue_head_init(&policy->polq.hold_queue);
 		setup_timer(&policy->timer, xfrm_policy_timer,
 				(unsigned long)policy);
+		setup_timer(&policy->polq.hold_timer, xfrm_policy_queue_process,
+			    (unsigned long)policy);
 		policy->flo.ops = &xfrm_policy_fc_ops;
 	}
 	return policy;
@@ -309,6 +316,16 @@ void xfrm_policy_destroy(struct xfrm_policy *policy)
 }
 EXPORT_SYMBOL(xfrm_policy_destroy);
 
+static void xfrm_queue_purge(struct sk_buff_head *list)
+{
+	struct sk_buff *skb;
+
+	while ((skb = skb_dequeue(list)) != NULL) {
+		dev_put(skb->dev);
+		kfree_skb(skb);
+	}
+}
+
 /* Rule must be locked. Release descentant resources, announce
  * entry dead. The rule must be unlinked from lists to the moment.
  */
@@ -319,6 +336,9 @@ static void xfrm_policy_kill(struct xfrm_policy *policy)
 
 	atomic_inc(&policy->genid);
 
+	del_timer(&policy->polq.hold_timer);
+	xfrm_queue_purge(&policy->polq.hold_queue);
+
 	if (del_timer(&policy->timer))
 		xfrm_pol_put(policy);
 
@@ -562,6 +582,31 @@ static inline int selector_cmp(struct xfrm_selector *s1, struct xfrm_selector *s
 	return 0;
 }
 
+static void xfrm_policy_requeue(struct xfrm_policy *old,
+				struct xfrm_policy *new)
+{
+	struct xfrm_policy_queue *pq = &old->polq;
+	struct sk_buff_head list;
+
+	__skb_queue_head_init(&list);
+
+	spin_lock_bh(&pq->hold_queue.lock);
+	skb_queue_splice_init(&pq->hold_queue, &list);
+	del_timer(&pq->hold_timer);
+	spin_unlock_bh(&pq->hold_queue.lock);
+
+	if (skb_queue_empty(&list))
+		return;
+
+	pq = &new->polq;
+
+	spin_lock_bh(&pq->hold_queue.lock);
+	skb_queue_splice(&list, &pq->hold_queue);
+	pq->timeout = XFRM_QUEUE_TMO_MIN;
+	mod_timer(&pq->hold_timer, jiffies);
+	spin_unlock_bh(&pq->hold_queue.lock);
+}
+
 int xfrm_policy_insert(int dir, struct xfrm_policy *policy, int excl)
 {
 	struct net *net = xp_net(policy);
@@ -603,8 +648,10 @@ int xfrm_policy_insert(int dir, struct xfrm_policy *policy, int excl)
 	net->xfrm.policy_count[dir]++;
 	atomic_inc(&flow_cache_genid);
 	rt_genid_bump(net);
-	if (delpol)
+	if (delpol) {
+		xfrm_policy_requeue(delpol, policy);
 		__xfrm_policy_unlink(delpol, dir);
+	}
 	policy->index = delpol ? delpol->index : xfrm_gen_index(net, dir);
 	hlist_add_head(&policy->byidx, net->xfrm.policy_byidx+idx_hash(net, policy->index));
 	policy->curlft.add_time = get_seconds();
@@ -1115,11 +1162,15 @@ int xfrm_sk_policy_insert(struct sock *sk, int dir, struct xfrm_policy *pol)
 		pol->index = xfrm_gen_index(net, XFRM_POLICY_MAX+dir);
 		__xfrm_policy_link(pol, XFRM_POLICY_MAX+dir);
 	}
-	if (old_pol)
+	if (old_pol) {
+		if (pol)
+			xfrm_policy_requeue(old_pol, pol);
+
 		/* Unlinking succeeds always. This is the only function
 		 * allowed to delete or replace socket policy.
 		 */
 		__xfrm_policy_unlink(old_pol, XFRM_POLICY_MAX+dir);
+	}
 	write_unlock_bh(&xfrm_policy_lock);
 
 	if (old_pol) {
@@ -1310,6 +1361,8 @@ static struct flow_cache_object *xfrm_bundle_flo_get(struct flow_cache_object *f
 		 * It means we need to try again resolving. */
 		if (xdst->num_xfrms > 0)
 			return NULL;
+	} else if (dst->flags & DST_XFRM_QUEUE) {
+		return NULL;
 	} else {
 		/* Real bundle */
 		if (stale_bundle(dst))
@@ -1673,6 +1726,171 @@ xfrm_resolve_and_create_bundle(struct xfrm_policy **pols, int num_pols,
 	return xdst;
 }
 
+static void xfrm_policy_queue_process(unsigned long arg)
+{
+	int err = 0;
+	struct sk_buff *skb;
+	struct sock *sk;
+	struct dst_entry *dst;
+	struct net_device *dev;
+	struct xfrm_policy *pol = (struct xfrm_policy *)arg;
+	struct xfrm_policy_queue *pq = &pol->polq;
+	struct flowi fl;
+	struct sk_buff_head list;
+
+	spin_lock(&pq->hold_queue.lock);
+	skb = skb_peek(&pq->hold_queue);
+	dst = skb_dst(skb);
+	sk = skb->sk;
+	xfrm_decode_session(skb, &fl, dst->ops->family);
+	spin_unlock(&pq->hold_queue.lock);
+
+	dst_hold(dst->path);
+	dst = xfrm_lookup(xp_net(pol), dst->path, &fl,
+			  sk, 0);
+	if (IS_ERR(dst))
+		goto purge_queue;
+
+	if (dst->flags & DST_XFRM_QUEUE) {
+		dst_release(dst);
+
+		if (pq->timeout >= XFRM_QUEUE_TMO_MAX)
+			goto purge_queue;
+
+		pq->timeout = pq->timeout << 1;
+		mod_timer(&pq->hold_timer, jiffies + pq->timeout);
+		return;
+	}
+
+	dst_release(dst);
+
+	__skb_queue_head_init(&list);
+
+	spin_lock(&pq->hold_queue.lock);
+	pq->timeout = 0;
+	skb_queue_splice_init(&pq->hold_queue, &list);
+	spin_unlock(&pq->hold_queue.lock);
+
+	while (!skb_queue_empty(&list)) {
+		skb = __skb_dequeue(&list);
+
+		xfrm_decode_session(skb, &fl, skb_dst(skb)->ops->family);
+		dst_hold(skb_dst(skb)->path);
+		dst = xfrm_lookup(xp_net(pol), skb_dst(skb)->path,
+				  &fl, skb->sk, 0);
+		if (IS_ERR(dst)) {
+			dev_put(skb->dev);
+			kfree_skb(skb);
+			continue;
+		}
+
+		nf_reset(skb);
+		skb_dst_drop(skb);
+		skb_dst_set(skb, dst);
+
+		dev = skb->dev;
+		err = dst_output(skb);
+		dev_put(dev);
+	}
+
+	return;
+
+purge_queue:
+	pq->timeout = 0;
+	xfrm_queue_purge(&pq->hold_queue);
+}
+
+static int xdst_queue_output(struct sk_buff *skb)
+{
+	unsigned long sched_next;
+	struct dst_entry *dst = skb_dst(skb);
+	struct xfrm_dst *xdst = (struct xfrm_dst *) dst;
+	struct xfrm_policy_queue *pq = &xdst->pols[0]->polq;
+
+	if (pq->hold_queue.qlen > XFRM_MAX_QUEUE_LEN) {
+		kfree_skb(skb);
+		return -EAGAIN;
+	}
+
+	skb_dst_force(skb);
+	dev_hold(skb->dev);
+
+	spin_lock_bh(&pq->hold_queue.lock);
+
+	if (!pq->timeout)
+		pq->timeout = XFRM_QUEUE_TMO_MIN;
+
+	sched_next = jiffies + pq->timeout;
+
+	if (del_timer(&pq->hold_timer)) {
+		if (time_before(pq->hold_timer.expires, sched_next))
+			sched_next = pq->hold_timer.expires;
+	}
+
+	__skb_queue_tail(&pq->hold_queue, skb);
+	mod_timer(&pq->hold_timer, sched_next);
+
+	spin_unlock_bh(&pq->hold_queue.lock);
+
+	return 0;
+}
+
+static struct xfrm_dst *xfrm_create_dummy_bundle(struct net *net,
+						 struct dst_entry *dst,
+						 const struct flowi *fl,
+						 int num_xfrms,
+						 u16 family)
+{
+	int err;
+	struct net_device *dev;
+	struct dst_entry *dst1;
+	struct xfrm_dst *xdst;
+
+	xdst = xfrm_alloc_dst(net, family);
+	if (IS_ERR(xdst))
+		return xdst;
+
+	if (net->xfrm.sysctl_larval_drop || num_xfrms <= 0 ||
+	    (fl->flowi_flags & FLOWI_FLAG_CAN_SLEEP))
+		return xdst;
+
+	dst1 = &xdst->u.dst;
+	dst_hold(dst);
+	xdst->route = dst;
+
+	dst_copy_metrics(dst1, dst);
+
+	dst1->obsolete = DST_OBSOLETE_FORCE_CHK;
+	dst1->flags |= DST_HOST | DST_XFRM_QUEUE;
+	dst1->lastuse = jiffies;
+
+	dst1->input = dst_discard;
+	dst1->output = xdst_queue_output;
+
+	dst_hold(dst);
+	dst1->child = dst;
+	dst1->path = dst;
+
+	xfrm_init_path((struct xfrm_dst *)dst1, dst, 0);
+
+	err = -ENODEV;
+	dev = dst->dev;
+	if (!dev)
+		goto free_dst;
+
+	err = xfrm_fill_dst(xdst, dev, fl);
+	if (err)
+		goto free_dst;
+
+out:
+	return xdst;
+
+free_dst:
+	dst_release(dst1);
+	xdst = ERR_PTR(err);
+	goto out;
+}
+
 static struct flow_cache_object *
 xfrm_bundle_lookup(struct net *net, const struct flowi *fl, u16 family, u8 dir,
 		   struct flow_cache_object *oldflo, void *ctx)
@@ -1751,7 +1969,7 @@ make_dummy_bundle:
 	/* We found policies, but there's no bundles to instantiate:
 	 * either because the policy blocks, has no transformations or
 	 * we could not build template (no xfrm_states).*/
-	xdst = xfrm_alloc_dst(net, family);
+	xdst = xfrm_create_dummy_bundle(net, dst_orig, fl, num_xfrms, family);
 	if (IS_ERR(xdst)) {
 		xfrm_pols_put(pols, num_pols);
 		return ERR_CAST(xdst);
@@ -2359,6 +2577,9 @@ static int xfrm_bundle_ok(struct xfrm_dst *first)
 	    (dst->dev && !netif_running(dst->dev)))
 		return 0;
 
+	if (dst->flags & DST_XFRM_QUEUE)
+		return 1;
+
 	last = NULL;
 
 	do {
-- 
1.7.9.5

^ permalink raw reply related

* [PATCH 5/7] xfrm: remove unused xfrm4_policy_fini()
From: Steffen Klassert @ 2013-02-14 11:47 UTC (permalink / raw)
  To: David Miller; +Cc: Herbert Xu, Steffen Klassert, netdev
In-Reply-To: <1360842447-3344-1-git-send-email-steffen.klassert@secunet.com>

From: Michal Kubecek <mkubecek@suse.cz>

Function xfrm4_policy_fini() is unused since xfrm4_fini() was
removed in 2.6.11.

Signed-off-by: Michal Kubecek <mkubecek@suse.cz>
Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
---
 net/ipv4/xfrm4_policy.c |    9 ---------
 1 file changed, 9 deletions(-)

diff --git a/net/ipv4/xfrm4_policy.c b/net/ipv4/xfrm4_policy.c
index 3be0ac2..0e28383 100644
--- a/net/ipv4/xfrm4_policy.c
+++ b/net/ipv4/xfrm4_policy.c
@@ -270,15 +270,6 @@ static void __init xfrm4_policy_init(void)
 	xfrm_policy_register_afinfo(&xfrm4_policy_afinfo);
 }
 
-static void __exit xfrm4_policy_fini(void)
-{
-#ifdef CONFIG_SYSCTL
-	if (sysctl_hdr)
-		unregister_net_sysctl_table(sysctl_hdr);
-#endif
-	xfrm_policy_unregister_afinfo(&xfrm4_policy_afinfo);
-}
-
 void __init xfrm4_init(void)
 {
 	dst_entries_init(&xfrm4_dst_ops);
-- 
1.7.9.5

^ permalink raw reply related

* [PATCH 3/7] xfrm: fix a unbalanced lock
From: Steffen Klassert @ 2013-02-14 11:47 UTC (permalink / raw)
  To: David Miller; +Cc: Herbert Xu, Steffen Klassert, netdev
In-Reply-To: <1360842447-3344-1-git-send-email-steffen.klassert@secunet.com>

From: Li RongQing <roy.qing.li@gmail.com>

Signed-off-by: Li RongQing <roy.qing.li@gmail.com>
Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
---
 net/xfrm/xfrm_output.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/net/xfrm/xfrm_output.c b/net/xfrm/xfrm_output.c
index 3670526..bcfda89 100644
--- a/net/xfrm/xfrm_output.c
+++ b/net/xfrm/xfrm_output.c
@@ -64,7 +64,7 @@ static int xfrm_output_one(struct sk_buff *skb, int err)
 
 		if (unlikely(x->km.state != XFRM_STATE_VALID)) {
 			XFRM_INC_STATS(net, LINUX_MIB_XFRMOUTSTATEINVALID);
-			goto error_nolock;
+			goto error;
 		}
 
 		err = xfrm_state_check_expire(x);
-- 
1.7.9.5

^ permalink raw reply related

* [PATCH 6/7] xfrm: make gc_thresh configurable in all namespaces
From: Steffen Klassert @ 2013-02-14 11:47 UTC (permalink / raw)
  To: David Miller; +Cc: Herbert Xu, Steffen Klassert, netdev
In-Reply-To: <1360842447-3344-1-git-send-email-steffen.klassert@secunet.com>

From: Michal Kubecek <mkubecek@suse.cz>

The xfrm gc threshold can be configured via xfrm{4,6}_gc_thresh
sysctl but currently only in init_net, other namespaces always
use the default value. This can substantially limit the number
of IPsec tunnels that can be effectively used.

Signed-off-by: Michal Kubecek <mkubecek@suse.cz>
Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
---
 include/net/netns/ipv4.h |    1 +
 include/net/netns/ipv6.h |    1 +
 net/ipv4/xfrm4_policy.c  |   49 ++++++++++++++++++++++++++++++++++++++++---
 net/ipv6/xfrm6_policy.c  |   52 +++++++++++++++++++++++++++++++++++++++++-----
 4 files changed, 95 insertions(+), 8 deletions(-)

diff --git a/include/net/netns/ipv4.h b/include/net/netns/ipv4.h
index 9b78862..2ba9de8 100644
--- a/include/net/netns/ipv4.h
+++ b/include/net/netns/ipv4.h
@@ -22,6 +22,7 @@ struct netns_ipv4 {
 	struct ctl_table_header	*frags_hdr;
 	struct ctl_table_header	*ipv4_hdr;
 	struct ctl_table_header *route_hdr;
+	struct ctl_table_header *xfrm4_hdr;
 #endif
 	struct ipv4_devconf	*devconf_all;
 	struct ipv4_devconf	*devconf_dflt;
diff --git a/include/net/netns/ipv6.h b/include/net/netns/ipv6.h
index 214cb0a..1242f37 100644
--- a/include/net/netns/ipv6.h
+++ b/include/net/netns/ipv6.h
@@ -16,6 +16,7 @@ struct netns_sysctl_ipv6 {
 	struct ctl_table_header *route_hdr;
 	struct ctl_table_header *icmp_hdr;
 	struct ctl_table_header *frags_hdr;
+	struct ctl_table_header *xfrm6_hdr;
 #endif
 	int bindv6only;
 	int flush_delay;
diff --git a/net/ipv4/xfrm4_policy.c b/net/ipv4/xfrm4_policy.c
index 0e28383..9a459be 100644
--- a/net/ipv4/xfrm4_policy.c
+++ b/net/ipv4/xfrm4_policy.c
@@ -262,7 +262,51 @@ static struct ctl_table xfrm4_policy_table[] = {
 	{ }
 };
 
-static struct ctl_table_header *sysctl_hdr;
+static int __net_init xfrm4_net_init(struct net *net)
+{
+	struct ctl_table *table;
+	struct ctl_table_header *hdr;
+
+	table = xfrm4_policy_table;
+	if (!net_eq(net, &init_net)) {
+		table = kmemdup(table, sizeof(xfrm4_policy_table), GFP_KERNEL);
+		if (!table)
+			goto err_alloc;
+
+		table[0].data = &net->xfrm.xfrm4_dst_ops.gc_thresh;
+	}
+
+	hdr = register_net_sysctl(net, "net/ipv4", table);
+	if (!hdr)
+		goto err_reg;
+
+	net->ipv4.xfrm4_hdr = hdr;
+	return 0;
+
+err_reg:
+	if (!net_eq(net, &init_net))
+		kfree(table);
+err_alloc:
+	return -ENOMEM;
+}
+
+static void __net_exit xfrm4_net_exit(struct net *net)
+{
+	struct ctl_table *table;
+
+	if (net->ipv4.xfrm4_hdr == NULL)
+		return;
+
+	table = net->ipv4.xfrm4_hdr->ctl_table_arg;
+	unregister_net_sysctl_table(net->ipv4.xfrm4_hdr);
+	if (!net_eq(net, &init_net))
+		kfree(table);
+}
+
+static struct pernet_operations __net_initdata xfrm4_net_ops = {
+	.init	= xfrm4_net_init,
+	.exit	= xfrm4_net_exit,
+};
 #endif
 
 static void __init xfrm4_policy_init(void)
@@ -277,8 +321,7 @@ void __init xfrm4_init(void)
 	xfrm4_state_init();
 	xfrm4_policy_init();
 #ifdef CONFIG_SYSCTL
-	sysctl_hdr = register_net_sysctl(&init_net, "net/ipv4",
-					 xfrm4_policy_table);
+	register_pernet_subsys(&xfrm4_net_ops);
 #endif
 }
 
diff --git a/net/ipv6/xfrm6_policy.c b/net/ipv6/xfrm6_policy.c
index 1282737..4ef7bdb 100644
--- a/net/ipv6/xfrm6_policy.c
+++ b/net/ipv6/xfrm6_policy.c
@@ -320,7 +320,51 @@ static struct ctl_table xfrm6_policy_table[] = {
 	{ }
 };
 
-static struct ctl_table_header *sysctl_hdr;
+static int __net_init xfrm6_net_init(struct net *net)
+{
+	struct ctl_table *table;
+	struct ctl_table_header *hdr;
+
+	table = xfrm6_policy_table;
+	if (!net_eq(net, &init_net)) {
+		table = kmemdup(table, sizeof(xfrm6_policy_table), GFP_KERNEL);
+		if (!table)
+			goto err_alloc;
+
+		table[0].data = &net->xfrm.xfrm6_dst_ops.gc_thresh;
+	}
+
+	hdr = register_net_sysctl(net, "net/ipv6", table);
+	if (!hdr)
+		goto err_reg;
+
+	net->ipv6.sysctl.xfrm6_hdr = hdr;
+	return 0;
+
+err_reg:
+	if (!net_eq(net, &init_net))
+		kfree(table);
+err_alloc:
+	return -ENOMEM;
+}
+
+static void __net_exit xfrm6_net_exit(struct net *net)
+{
+	struct ctl_table *table;
+
+	if (net->ipv6.sysctl.xfrm6_hdr == NULL)
+		return;
+
+	table = net->ipv6.sysctl.xfrm6_hdr->ctl_table_arg;
+	unregister_net_sysctl_table(net->ipv6.sysctl.xfrm6_hdr);
+	if (!net_eq(net, &init_net))
+		kfree(table);
+}
+
+static struct pernet_operations xfrm6_net_ops = {
+	.init	= xfrm6_net_init,
+	.exit	= xfrm6_net_exit,
+};
 #endif
 
 int __init xfrm6_init(void)
@@ -339,8 +383,7 @@ int __init xfrm6_init(void)
 		goto out_policy;
 
 #ifdef CONFIG_SYSCTL
-	sysctl_hdr = register_net_sysctl(&init_net, "net/ipv6",
-					 xfrm6_policy_table);
+	register_pernet_subsys(&xfrm6_net_ops);
 #endif
 out:
 	return ret;
@@ -352,8 +395,7 @@ out_policy:
 void xfrm6_fini(void)
 {
 #ifdef CONFIG_SYSCTL
-	if (sysctl_hdr)
-		unregister_net_sysctl_table(sysctl_hdr);
+	unregister_pernet_subsys(&xfrm6_net_ops);
 #endif
 	xfrm6_policy_fini();
 	xfrm6_state_fini();
-- 
1.7.9.5

^ permalink raw reply related

* [PATCH 7/7] xfrm: Allow inserting policies with matching mark and different priorities
From: Steffen Klassert @ 2013-02-14 11:47 UTC (permalink / raw)
  To: David Miller; +Cc: Herbert Xu, Steffen Klassert, netdev
In-Reply-To: <1360842447-3344-1-git-send-email-steffen.klassert@secunet.com>

We currently can not insert policies with mark and mask
such that some flows would be matched from both policies.
We make this possible when the priority of these policies
are different. If both policies match a flow, the one with
the higher priority is used.

Reported-by: Emmanuel Thierry <emmanuel.thierry@telecom-bretagne.eu>
Reported-by: Romain Kuntz <r.kuntz@ipflavors.com>
Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
---
 net/xfrm/xfrm_policy.c |   18 ++++++++++++++++--
 1 file changed, 16 insertions(+), 2 deletions(-)

diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c
index 456b11b..257dfb1 100644
--- a/net/xfrm/xfrm_policy.c
+++ b/net/xfrm/xfrm_policy.c
@@ -607,6 +607,21 @@ static void xfrm_policy_requeue(struct xfrm_policy *old,
 	spin_unlock_bh(&pq->hold_queue.lock);
 }
 
+static bool xfrm_policy_mark_match(struct xfrm_policy *policy,
+				   struct xfrm_policy *pol)
+{
+	u32 mark = policy->mark.v & policy->mark.m;
+
+	if (policy->mark.v == pol->mark.v && policy->mark.m == pol->mark.m)
+		return true;
+
+	if ((mark & pol->mark.m) == pol->mark.v &&
+	    policy->priority == pol->priority)
+		return true;
+
+	return false;
+}
+
 int xfrm_policy_insert(int dir, struct xfrm_policy *policy, int excl)
 {
 	struct net *net = xp_net(policy);
@@ -614,7 +629,6 @@ int xfrm_policy_insert(int dir, struct xfrm_policy *policy, int excl)
 	struct xfrm_policy *delpol;
 	struct hlist_head *chain;
 	struct hlist_node *entry, *newpos;
-	u32 mark = policy->mark.v & policy->mark.m;
 
 	write_lock_bh(&xfrm_policy_lock);
 	chain = policy_hash_bysel(net, &policy->selector, policy->family, dir);
@@ -623,7 +637,7 @@ int xfrm_policy_insert(int dir, struct xfrm_policy *policy, int excl)
 	hlist_for_each_entry(pol, entry, chain, bydst) {
 		if (pol->type == policy->type &&
 		    !selector_cmp(&pol->selector, &policy->selector) &&
-		    (mark & pol->mark.m) == pol->mark.v &&
+		    xfrm_policy_mark_match(policy, pol) &&
 		    xfrm_sec_ctx_match(pol->security, policy->security) &&
 		    !WARN_ON(delpol)) {
 			if (excl) {
-- 
1.7.9.5

^ permalink raw reply related

* tuntap: Overload handling
From: Sebastian Pöhn @ 2013-02-14 11:50 UTC (permalink / raw)
  To: netdev
In-Reply-To: <CAGUzgdK9U3hreLxtc6eP3CSpLsfhkn2ZKpFp9_VJhWr2gz0uCQ@mail.gmail.com>

I am having a look on the tun driver to realize an userspace network
driver ( TAP + UIO ). Maybe that's not the use-case tun is intended
for.

What I've noticed is that in tun.c Line 741

static netdev_tx_t tun_net_xmit(struct sk_buff *skb, struct net_device *dev)

/* Limit the number of packets queued by dividing txq length with the
 * number of queues.
 */
if (skb_queue_len(&tfile->socket.sk->sk_receive_queue)
 >= dev->tx_queue_len / tun->numqueues)
goto drop;

If a frame can not be tx it is dropped by the driver.
Wouldn't it be more correct to netif_tx_stop_queue() so that packet
drops are performed by the overlying traffic control code?

Of course this is not very likely in virtual environments but as soon
as any real network hop is involved it could be important.

(I also had a look on some two year old version of tun.c. There
queue/tx stopping was done correctly.)

---

^ permalink raw reply

* xen-netback: fix oopes during shutdown and error handling
From: David Vrabel @ 2013-02-14 13:18 UTC (permalink / raw)
  To: xen-devel
  Cc: David Vrabel, Konrad Rzeszutek Wilk, Ian Campbell, Jan Beulich,
	Wei Liu, netdev

These two netback patches fix oopes that may occur during shutdown or
if a specific fatal error occurs.

They are stable candidants.

David

^ permalink raw reply

* [PATCH 2/2] xen-netback: cancel the credit timer when taking the vif down
From: David Vrabel @ 2013-02-14 13:18 UTC (permalink / raw)
  To: xen-devel
  Cc: David Vrabel, Konrad Rzeszutek Wilk, Ian Campbell, Jan Beulich,
	Wei Liu, netdev
In-Reply-To: <1360847938-11185-1-git-send-email-david.vrabel@citrix.com>

From: David Vrabel <david.vrabel@citrix.com>

If the credit timer is left armed after calling
xen_netbk_remove_xenvif(), then it may fire and attempt to schedule
the vif which will then oops as vif->netbk == NULL.

This may happen both in the fatal error path and during normal
disconnection from the front end.

The sequencing during shutdown is critical to ensure that: a)
vif->netbk doesn't become unexpectedly NULL; and b) the net device/vif
is not freed.

1. Mark as unschedulable (netif_carrier_off()).
2. Synchronously cancel the timer.
3. Remove the vif from the schedule list.
4. Remove it from it netback thread group.
5. Wait for vif->refcnt to become 0.

Signed-off-by: David Vrabel <david.vrabel@citrix.com>
---
 drivers/net/xen-netback/interface.c |    3 +--
 1 files changed, 1 insertions(+), 2 deletions(-)

diff --git a/drivers/net/xen-netback/interface.c b/drivers/net/xen-netback/interface.c
index b8c5193..221f426 100644
--- a/drivers/net/xen-netback/interface.c
+++ b/drivers/net/xen-netback/interface.c
@@ -132,6 +132,7 @@ static void xenvif_up(struct xenvif *vif)
 static void xenvif_down(struct xenvif *vif)
 {
 	disable_irq(vif->irq);
+	del_timer_sync(&vif->credit_timeout);
 	xen_netbk_deschedule_xenvif(vif);
 	xen_netbk_remove_xenvif(vif);
 }
@@ -363,8 +364,6 @@ void xenvif_disconnect(struct xenvif *vif)
 	atomic_dec(&vif->refcnt);
 	wait_event(vif->waiting_to_free, atomic_read(&vif->refcnt) == 0);
 
-	del_timer_sync(&vif->credit_timeout);
-
 	if (vif->irq)
 		unbind_from_irqhandler(vif->irq, vif);
 
-- 
1.7.2.5

^ permalink raw reply related

* [PATCH 1/2] xen-netback: correctly return errors from netbk_count_requests()
From: David Vrabel @ 2013-02-14 13:18 UTC (permalink / raw)
  To: xen-devel
  Cc: David Vrabel, Konrad Rzeszutek Wilk, Ian Campbell, Jan Beulich,
	Wei Liu, netdev, Wei Liu, Jan Beulich
In-Reply-To: <1360847938-11185-1-git-send-email-david.vrabel@citrix.com>

From: David Vrabel <david.vrabel@citrix.com>

netbk_count_requests() could detect an error, call
netbk_fatal_tx_error() but return 0.  The vif may then be used
afterwards (e.g., in a call to netbk_tx_error().

Since netbk_fatal_tx_error() could set vif->refcnt to 1, the vif may
be freed immediately after the call to netbk_fatal_tx_error() (e.g.,
if the vif is also removed).

Netback thread              Xenwatch thread
-------------------------------------------
netbk_fatal_tx_err()        netback_remove()
                              xenvif_disconnect()
                                ...
                                free_netdev()
netbk_tx_err() Oops!

Signed-off-by: Wei Liu <wei.liu2@citrix.com>
Signed-off-by: Jan Beulich <JBeulich@suse.com>
Signed-off-by: David Vrabel <david.vrabel@citrix.com>
---
 drivers/net/xen-netback/netback.c |    8 ++++----
 1 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/net/xen-netback/netback.c b/drivers/net/xen-netback/netback.c
index 2b9520c..cd49ba9 100644
--- a/drivers/net/xen-netback/netback.c
+++ b/drivers/net/xen-netback/netback.c
@@ -911,13 +911,13 @@ static int netbk_count_requests(struct xenvif *vif,
 		if (frags >= work_to_do) {
 			netdev_err(vif->dev, "Need more frags\n");
 			netbk_fatal_tx_err(vif);
-			return -frags;
+			return -ENODATA;
 		}
 
 		if (unlikely(frags >= MAX_SKB_FRAGS)) {
 			netdev_err(vif->dev, "Too many frags\n");
 			netbk_fatal_tx_err(vif);
-			return -frags;
+			return -E2BIG;
 		}
 
 		memcpy(txp, RING_GET_REQUEST(&vif->tx, cons + frags),
@@ -925,7 +925,7 @@ static int netbk_count_requests(struct xenvif *vif,
 		if (txp->size > first->size) {
 			netdev_err(vif->dev, "Frag is bigger than frame.\n");
 			netbk_fatal_tx_err(vif);
-			return -frags;
+			return -EIO;
 		}
 
 		first->size -= txp->size;
@@ -935,7 +935,7 @@ static int netbk_count_requests(struct xenvif *vif,
 			netdev_err(vif->dev, "txp->offset: %x, size: %u\n",
 				 txp->offset, txp->size);
 			netbk_fatal_tx_err(vif);
-			return -frags;
+			return -EINVAL;
 		}
 	} while ((txp++)->flags & XEN_NETTXF_more_data);
 	return frags;
-- 
1.7.2.5

^ permalink raw reply related

* Re: [Xen-devel] [PATCH 2/2] xen-netback: cancel the credit timer when taking the vif down
From: Wei Liu @ 2013-02-14 13:53 UTC (permalink / raw)
  To: David Vrabel
  Cc: wei.liu2, xen-devel@lists.xen.org, Ian Campbell,
	Konrad Rzeszutek Wilk, netdev@vger.kernel.org, Jan Beulich,
	Wei Liu (3P)
In-Reply-To: <1360847938-11185-3-git-send-email-david.vrabel@citrix.com>

On Thu, 2013-02-14 at 13:18 +0000, David Vrabel wrote:
> From: David Vrabel <david.vrabel@citrix.com>
> 
> If the credit timer is left armed after calling
> xen_netbk_remove_xenvif(), then it may fire and attempt to schedule
> the vif which will then oops as vif->netbk == NULL.
> 
> This may happen both in the fatal error path and during normal
> disconnection from the front end.
> 
> The sequencing during shutdown is critical to ensure that: a)
> vif->netbk doesn't become unexpectedly NULL; and b) the net device/vif
> is not freed.
> 
> 1. Mark as unschedulable (netif_carrier_off()).
> 2. Synchronously cancel the timer.
> 3. Remove the vif from the schedule list.
> 4. Remove it from it netback thread group.
> 5. Wait for vif->refcnt to become 0.
> 
> Signed-off-by: David Vrabel <david.vrabel@citrix.com>

You would need to reinitialize the timer in xenvif_up, given that user
might `ifconfig vifX.X down; ifconfig vifX.X up`.

Another less desired but simpler fix would be leave the timer alone but
check for vif->netbk != NULL in the timer callback.


Wei.

> ---
>  drivers/net/xen-netback/interface.c |    3 +--
>  1 files changed, 1 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/net/xen-netback/interface.c b/drivers/net/xen-netback/interface.c
> index b8c5193..221f426 100644
> --- a/drivers/net/xen-netback/interface.c
> +++ b/drivers/net/xen-netback/interface.c
> @@ -132,6 +132,7 @@ static void xenvif_up(struct xenvif *vif)
>  static void xenvif_down(struct xenvif *vif)
>  {
>  	disable_irq(vif->irq);
> +	del_timer_sync(&vif->credit_timeout);
>  	xen_netbk_deschedule_xenvif(vif);
>  	xen_netbk_remove_xenvif(vif);
>  }
> @@ -363,8 +364,6 @@ void xenvif_disconnect(struct xenvif *vif)
>  	atomic_dec(&vif->refcnt);
>  	wait_event(vif->waiting_to_free, atomic_read(&vif->refcnt) == 0);
>  
> -	del_timer_sync(&vif->credit_timeout);
> -
>  	if (vif->irq)
>  		unbind_from_irqhandler(vif->irq, vif);
>  

^ permalink raw reply

* Re: [Xen-devel] [PATCH 2/2] xen-netback: cancel the credit timer when taking the vif down
From: David Vrabel @ 2013-02-14 13:56 UTC (permalink / raw)
  To: Wei Liu
  Cc: xen-devel@lists.xen.org, Ian Campbell, Konrad Rzeszutek Wilk,
	netdev@vger.kernel.org, Jan Beulich, Wei Liu (3P)
In-Reply-To: <1360849999.16636.135.camel@zion.uk.xensource.com>

On 14/02/13 13:53, Wei Liu wrote:
> On Thu, 2013-02-14 at 13:18 +0000, David Vrabel wrote:
>> From: David Vrabel <david.vrabel@citrix.com>
>>
>> If the credit timer is left armed after calling
>> xen_netbk_remove_xenvif(), then it may fire and attempt to schedule
>> the vif which will then oops as vif->netbk == NULL.
>>
>> This may happen both in the fatal error path and during normal
>> disconnection from the front end.
>>
>> The sequencing during shutdown is critical to ensure that: a)
>> vif->netbk doesn't become unexpectedly NULL; and b) the net device/vif
>> is not freed.
>>
>> 1. Mark as unschedulable (netif_carrier_off()).
>> 2. Synchronously cancel the timer.
>> 3. Remove the vif from the schedule list.
>> 4. Remove it from it netback thread group.
>> 5. Wait for vif->refcnt to become 0.
>>
>> Signed-off-by: David Vrabel <david.vrabel@citrix.com>
> 
> You would need to reinitialize the timer in xenvif_up, given that user
> might `ifconfig vifX.X down; ifconfig vifX.X up`.

No.  Deleted timers do not need to be reinitialized.  The timer will be
armed as usual with mod_timer() when credit is next exhausted.

David

^ permalink raw reply

* Re: [Xen-devel] [PATCH 2/2] xen-netback: cancel the credit timer when taking the vif down
From: Wei Liu @ 2013-02-14 14:10 UTC (permalink / raw)
  To: David Vrabel
  Cc: wei.liu2, xen-devel@lists.xen.org, Ian Campbell,
	Konrad Rzeszutek Wilk, netdev@vger.kernel.org, Jan Beulich,
	Wei Liu (3P)
In-Reply-To: <511CED08.9080902@citrix.com>

On Thu, 2013-02-14 at 13:56 +0000, David Vrabel wrote:
> On 14/02/13 13:53, Wei Liu wrote:
> > On Thu, 2013-02-14 at 13:18 +0000, David Vrabel wrote:
> >> From: David Vrabel <david.vrabel@citrix.com>
> >>
> >> If the credit timer is left armed after calling
> >> xen_netbk_remove_xenvif(), then it may fire and attempt to schedule
> >> the vif which will then oops as vif->netbk == NULL.
> >>
> >> This may happen both in the fatal error path and during normal
> >> disconnection from the front end.
> >>
> >> The sequencing during shutdown is critical to ensure that: a)
> >> vif->netbk doesn't become unexpectedly NULL; and b) the net device/vif
> >> is not freed.
> >>
> >> 1. Mark as unschedulable (netif_carrier_off()).
> >> 2. Synchronously cancel the timer.
> >> 3. Remove the vif from the schedule list.
> >> 4. Remove it from it netback thread group.
> >> 5. Wait for vif->refcnt to become 0.
> >>
> >> Signed-off-by: David Vrabel <david.vrabel@citrix.com>
> > 
> > You would need to reinitialize the timer in xenvif_up, given that user
> > might `ifconfig vifX.X down; ifconfig vifX.X up`.
> 
> No.  Deleted timers do not need to be reinitialized.  The timer will be

What I really meant was to "rearm"...

> armed as usual with mod_timer() when credit is next exhausted.
> 

Ah, ok.


Wei.

^ permalink raw reply

* Re: [Xen-devel] [PATCH 2/2] xen-netback: cancel the credit timer when taking the vif down
From: Jan Beulich @ 2013-02-14 14:15 UTC (permalink / raw)
  To: Ian Campbell, Wei Liu
  Cc: David Vrabel, Wei Liu (3P), xen-devel@lists.xen.org,
	KonradRzeszutek Wilk, netdev@vger.kernel.org
In-Reply-To: <1360849999.16636.135.camel@zion.uk.xensource.com>

>>> On 14.02.13 at 14:53, Wei Liu <wei.liu2@citrix.com> wrote:
> On Thu, 2013-02-14 at 13:18 +0000, David Vrabel wrote:
>> From: David Vrabel <david.vrabel@citrix.com>
>> 
>> If the credit timer is left armed after calling
>> xen_netbk_remove_xenvif(), then it may fire and attempt to schedule
>> the vif which will then oops as vif->netbk == NULL.
>> 
>> This may happen both in the fatal error path and during normal
>> disconnection from the front end.
>> 
>> The sequencing during shutdown is critical to ensure that: a)
>> vif->netbk doesn't become unexpectedly NULL; and b) the net device/vif
>> is not freed.
>> 
>> 1. Mark as unschedulable (netif_carrier_off()).
>> 2. Synchronously cancel the timer.
>> 3. Remove the vif from the schedule list.
>> 4. Remove it from it netback thread group.
>> 5. Wait for vif->refcnt to become 0.
>> 
>> Signed-off-by: David Vrabel <david.vrabel@citrix.com>
> 
> You would need to reinitialize the timer in xenvif_up, given that user
> might `ifconfig vifX.X down; ifconfig vifX.X up`.

Which gets us to another aspect of the original fix that I don't
think was considered: Is there anything preventing the interface
to be brought back up after fatal_tx_err() shut it down?

Jan

^ permalink raw reply

* Re: [Xen-devel] [PATCH 2/2] xen-netback: cancel the credit timer when taking the vif down
From: Wei Liu @ 2013-02-14 14:21 UTC (permalink / raw)
  To: Jan Beulich
  Cc: wei.liu2, Ian Campbell, David Vrabel, xen-devel@lists.xen.org,
	KonradRzeszutek Wilk, netdev@vger.kernel.org
In-Reply-To: <511CFF8A02000078000BE4B2@nat28.tlf.novell.com>

On Thu, 2013-02-14 at 14:15 +0000, Jan Beulich wrote:
> >>> On 14.02.13 at 14:53, Wei Liu <wei.liu2@citrix.com> wrote:
> > On Thu, 2013-02-14 at 13:18 +0000, David Vrabel wrote:
> >> From: David Vrabel <david.vrabel@citrix.com>
> >> 
> >> If the credit timer is left armed after calling
> >> xen_netbk_remove_xenvif(), then it may fire and attempt to schedule
> >> the vif which will then oops as vif->netbk == NULL.
> >> 
> >> This may happen both in the fatal error path and during normal
> >> disconnection from the front end.
> >> 
> >> The sequencing during shutdown is critical to ensure that: a)
> >> vif->netbk doesn't become unexpectedly NULL; and b) the net device/vif
> >> is not freed.
> >> 
> >> 1. Mark as unschedulable (netif_carrier_off()).
> >> 2. Synchronously cancel the timer.
> >> 3. Remove the vif from the schedule list.
> >> 4. Remove it from it netback thread group.
> >> 5. Wait for vif->refcnt to become 0.
> >> 
> >> Signed-off-by: David Vrabel <david.vrabel@citrix.com>
> > 
> > You would need to reinitialize the timer in xenvif_up, given that user
> > might `ifconfig vifX.X down; ifconfig vifX.X up`.
> 
> Which gets us to another aspect of the original fix that I don't
> think was considered: Is there anything preventing the interface
> to be brought back up after fatal_tx_err() shut it down?
> 

I don't think so. Code could / should not prevent host admin from doing
anything he wants - even it is re-enabling a malicious vif. ;-)


Wei.

> Jan
> 

^ permalink raw reply

* Re: failure when attempting to build vmci_transport on net-next
From: Andy King @ 2013-02-14 14:54 UTC (permalink / raw)
  To: Or Gerlitz; +Cc: David Miller, netdev, Dmitry Torokhov, George Zhang
In-Reply-To: <511CB353.3000704@mellanox.com>

Hi Or,

> I didn't manage to get the VMWARE_VMCI_VSOCKETS directive to be set,
> unless I added the below patch, and
> once that done got the tons of errors below, am I doing something wrong?

That's because VMCI, which is necessary for the vSock vmci_transport,
came in via Greg's char-misc-next tree, and it hasn't yet merged all the
way over to Dave's net-next tree.

However, I just checked the top-level linux-next tree and it has both,
so perhaps you could try that instead?

http://git.kernel.org/?p=linux/kernel/git/next/linux-next.git;a=summary

Thanks!
- Andy

^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox