diff options
Diffstat (limited to 'datapath')
-rw-r--r-- | datapath/linux/compat/stt.c | 16 |
1 files changed, 11 insertions, 5 deletions
diff --git a/datapath/linux/compat/stt.c b/datapath/linux/compat/stt.c index 8e001125b..85ddbe7ca 100644 --- a/datapath/linux/compat/stt.c +++ b/datapath/linux/compat/stt.c @@ -62,6 +62,7 @@ struct stt_dev { struct net_device *dev; struct net *net; struct list_head next; + struct list_head up_next; struct socket *sock; __be16 dst_port; }; @@ -150,6 +151,7 @@ struct frag_skb_cb { /* per-network namespace private data for this module */ struct stt_net { struct list_head stt_list; + struct list_head stt_up_list; /* Devices which are in IFF_UP state. */ int n_tunnels; }; @@ -167,12 +169,12 @@ static DEFINE_PER_CPU(u32, pkt_seq_counter); static void clean_percpu(struct work_struct *work); static DECLARE_DELAYED_WORK(clean_percpu_wq, clean_percpu); -static struct stt_dev *stt_find_sock(struct net *net, __be16 port) +static struct stt_dev *stt_find_up_dev(struct net *net, __be16 port) { struct stt_net *sn = net_generic(net, stt_net_id); struct stt_dev *stt_dev; - list_for_each_entry_rcu(stt_dev, &sn->stt_list, next) { + list_for_each_entry_rcu(stt_dev, &sn->stt_up_list, up_next) { if (stt_dev->dst_port == port) return stt_dev; } @@ -1481,7 +1483,7 @@ static unsigned int nf_ip_hook(FIRST_PARAM, struct sk_buff *skb, LAST_PARAM) skb_set_transport_header(skb, ip_hdr_len); - stt_dev = stt_find_sock(dev_net(skb->dev), tcp_hdr(skb)->dest); + stt_dev = stt_find_up_dev(dev_net(skb->dev), tcp_hdr(skb)->dest); if (!stt_dev) return NF_ACCEPT; @@ -1646,6 +1648,7 @@ static int stt_open(struct net_device *dev) { struct stt_dev *stt = netdev_priv(dev); struct net *net = stt->net; + struct stt_net *sn = net_generic(net, stt_net_id); int err; err = stt_start(net); @@ -1655,6 +1658,7 @@ static int stt_open(struct net_device *dev) err = tcp_sock_create4(net, stt->dst_port, &stt->sock); if (err) return err; + list_add_rcu(&stt->up_next, &sn->stt_up_list); return 0; } @@ -1663,6 +1667,7 @@ static int stt_stop(struct net_device *dev) struct stt_dev *stt_dev = netdev_priv(dev); struct net *net = stt_dev->net; + list_del_rcu(&stt_dev->up_next); tcp_sock_release(stt_dev->sock); stt_dev->sock = NULL; stt_cleanup(net); @@ -1772,7 +1777,7 @@ static int stt_configure(struct net *net, struct net_device *dev, if (err) return err; - list_add_rcu(&stt->next, &sn->stt_list); + list_add(&stt->next, &sn->stt_list); return 0; } @@ -1791,7 +1796,7 @@ static void stt_dellink(struct net_device *dev, struct list_head *head) { struct stt_dev *stt = netdev_priv(dev); - list_del_rcu(&stt->next); + list_del(&stt->next); unregister_netdevice_queue(dev, head); } @@ -1853,6 +1858,7 @@ static int stt_init_net(struct net *net) struct stt_net *sn = net_generic(net, stt_net_id); INIT_LIST_HEAD(&sn->stt_list); + INIT_LIST_HEAD(&sn->stt_up_list); return 0; } |