Re: [ovs-dev] [PATCH 3/3] lisp: avoid using stale lisp socket.

2016-10-31 Thread Joe Stringer
On 29 October 2016 at 21:33, Pravin B Shelar  wrote:
> This patch is similar to earlier vxlan patch.
> Lisp device close operation frees lisp socket. This
> operation can race with lisp-xmit function which
> dereferences lisp socket. Following patch uses RCU
> mechanism to avoid this situation.
>
> Signed-off-by: Pravin B Shelar 

Thanks, one style comment below. Otherwise:

Acked-by: Joe Stringer 

> @@ -442,11 +449,13 @@ static int lisp_open(struct net_device *dev)
> struct lisp_dev *lisp = netdev_priv(dev);
> struct udp_tunnel_sock_cfg tunnel_cfg;
> struct net *net = lisp->net;
> +   struct socket *sock;
>
> -   lisp->sock = create_sock(net, false, lisp->dst_port);
> -   if (IS_ERR(lisp->sock))
> -   return PTR_ERR(lisp->sock);
> +   sock = create_sock(net, false, lisp->dst_port);
> +   if (IS_ERR(sock))
> +   return PTR_ERR(sock);
>
> +   rcu_assign_pointer(lisp->sock, sock);
> /* Mark socket as an encapsulation socket */
> tunnel_cfg.sk_user_data = dev;
> tunnel_cfg.encap_type = 1;

At the end of lisp_open(), we pass lisp->sock directly to another
function. I think it's ok, but you could remove all direct
dereferences of 'lisp->sock' if you rolled in this incremental patch:

diff --git a/datapath/linux/compat/lisp.c b/datapath/linux/compat/lisp.c
index 193196c7e328..15f851de9ff4 100644
--- a/datapath/linux/compat/lisp.c
+++ b/datapath/linux/compat/lisp.c
@@ -461,7 +461,7 @@ static int lisp_open(struct net_device *dev)
   tunnel_cfg.encap_type = 1;
   tunnel_cfg.encap_rcv = lisp_rcv;
   tunnel_cfg.encap_destroy = NULL;
-   setup_udp_tunnel_sock(net, lisp->sock, _cfg);
+   setup_udp_tunnel_sock(net, sock, _cfg);
   return 0;
}
___
dev mailing list
dev@openvswitch.org
http://openvswitch.org/mailman/listinfo/dev


[ovs-dev] [PATCH 3/3] lisp: avoid using stale lisp socket.

2016-10-29 Thread Pravin B Shelar
This patch is similar to earlier vxlan patch.
Lisp device close operation frees lisp socket. This
operation can race with lisp-xmit function which
dereferences lisp socket. Following patch uses RCU
mechanism to avoid this situation.

Signed-off-by: Pravin B Shelar 
---
 datapath/linux/compat/lisp.c | 32 
 1 file changed, 24 insertions(+), 8 deletions(-)

diff --git a/datapath/linux/compat/lisp.c b/datapath/linux/compat/lisp.c
index 3a4bebc..193196c 100644
--- a/datapath/linux/compat/lisp.c
+++ b/datapath/linux/compat/lisp.c
@@ -49,7 +49,7 @@ static int lisp_net_id;
 struct lisp_dev {
struct net *net;/* netns for packet i/o */
struct net_device  *dev;/* netdev for lisp tunnel */
-   struct socket   *sock;
+   struct socket __rcu  *sock;
__be16 dst_port;
struct list_head   next;
 };
@@ -318,9 +318,10 @@ netdev_tx_t rpl_lisp_xmit(struct sk_buff *skb)
int network_offset = skb_network_offset(skb);
struct ip_tunnel_info *info;
struct ip_tunnel_key *tun_key;
+   __be16 src_port, dst_port;
struct rtable *rt;
int min_headroom;
-   __be16 src_port, dst_port;
+   struct socket *sock;
struct flowi4 fl;
__be16 df;
int err;
@@ -331,6 +332,12 @@ netdev_tx_t rpl_lisp_xmit(struct sk_buff *skb)
goto error;
}
 
+   sock = rcu_dereference(lisp_dev->sock);
+   if (!sock) {
+   err = -EIO;
+   goto error;
+   }
+
if (skb->protocol != htons(ETH_P_IP) &&
skb->protocol != htons(ETH_P_IPV6)) {
err = 0;
@@ -381,7 +388,7 @@ netdev_tx_t rpl_lisp_xmit(struct sk_buff *skb)
ovs_skb_set_inner_protocol(skb, skb->protocol);
 
df = tun_key->tun_flags & TUNNEL_DONT_FRAGMENT ? htons(IP_DF) : 0;
-   udp_tunnel_xmit_skb(rt, lisp_dev->sock->sk, skb,
+   udp_tunnel_xmit_skb(rt, sock->sk, skb,
fl.saddr, tun_key->u.ipv4.dst,
tun_key->tos, tun_key->ttl,
df, src_port, dst_port, false, true);
@@ -442,11 +449,13 @@ static int lisp_open(struct net_device *dev)
struct lisp_dev *lisp = netdev_priv(dev);
struct udp_tunnel_sock_cfg tunnel_cfg;
struct net *net = lisp->net;
+   struct socket *sock;
 
-   lisp->sock = create_sock(net, false, lisp->dst_port);
-   if (IS_ERR(lisp->sock))
-   return PTR_ERR(lisp->sock);
+   sock = create_sock(net, false, lisp->dst_port);
+   if (IS_ERR(sock))
+   return PTR_ERR(sock);
 
+   rcu_assign_pointer(lisp->sock, sock);
/* Mark socket as an encapsulation socket */
tunnel_cfg.sk_user_data = dev;
tunnel_cfg.encap_type = 1;
@@ -459,9 +468,16 @@ static int lisp_open(struct net_device *dev)
 static int lisp_stop(struct net_device *dev)
 {
struct lisp_dev *lisp = netdev_priv(dev);
+   struct socket *socket;
+
+   socket = rtnl_dereference(lisp->sock);
+   if (!socket)
+   return 0;
+
+   rcu_assign_pointer(lisp->sock, NULL);
 
-   udp_tunnel_sock_release(lisp->sock);
-   lisp->sock = NULL;
+   synchronize_net();
+   udp_tunnel_sock_release(socket);
return 0;
 }
 
-- 
1.8.3.1

___
dev mailing list
dev@openvswitch.org
http://openvswitch.org/mailman/listinfo/dev