summaryrefslogtreecommitdiff
path: root/datapath
diff options
context:
space:
mode:
Diffstat (limited to 'datapath')
-rw-r--r--datapath/linux/compat/stt.c16
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;
}