]> Pileus Git - ~andy/linux/blobdiff - net/ipv4/ip_gre.c
net: Allow userns root to control ipv4
[~andy/linux] / net / ipv4 / ip_gre.c
index 7240f8e2dd4511dde4de0bd08290bb718eab140f..a85ae2f7a21cb15502bd69e9c63a1ec29020fa40 100644 (file)
@@ -164,21 +164,6 @@ struct ipgre_net {
 #define tunnels_r      tunnels[2]
 #define tunnels_l      tunnels[1]
 #define tunnels_wc     tunnels[0]
-/*
- * Locking : hash tables are protected by RCU and RTNL
- */
-
-#define for_each_ip_tunnel_rcu(start) \
-       for (t = rcu_dereference(start); t; t = rcu_dereference(t->next))
-
-/* often modified stats are per cpu, other are shared (netdev->stats) */
-struct pcpu_tstats {
-       u64     rx_packets;
-       u64     rx_bytes;
-       u64     tx_packets;
-       u64     tx_bytes;
-       struct u64_stats_sync   syncp;
-};
 
 static struct rtnl_link_stats64 *ipgre_get_stats64(struct net_device *dev,
                                                   struct rtnl_link_stats64 *tot)
@@ -250,7 +235,7 @@ static struct ip_tunnel *ipgre_tunnel_lookup(struct net_device *dev,
                       ARPHRD_ETHER : ARPHRD_IPGRE;
        int score, cand_score = 4;
 
-       for_each_ip_tunnel_rcu(ign->tunnels_r_l[h0 ^ h1]) {
+       for_each_ip_tunnel_rcu(t, ign->tunnels_r_l[h0 ^ h1]) {
                if (local != t->parms.iph.saddr ||
                    remote != t->parms.iph.daddr ||
                    !(t->dev->flags & IFF_UP))
@@ -277,7 +262,7 @@ static struct ip_tunnel *ipgre_tunnel_lookup(struct net_device *dev,
                }
        }
 
-       for_each_ip_tunnel_rcu(ign->tunnels_r[h0 ^ h1]) {
+       for_each_ip_tunnel_rcu(t, ign->tunnels_r[h0 ^ h1]) {
                if (remote != t->parms.iph.daddr ||
                    !(t->dev->flags & IFF_UP))
                        continue;
@@ -303,7 +288,7 @@ static struct ip_tunnel *ipgre_tunnel_lookup(struct net_device *dev,
                }
        }
 
-       for_each_ip_tunnel_rcu(ign->tunnels_l[h1]) {
+       for_each_ip_tunnel_rcu(t, ign->tunnels_l[h1]) {
                if ((local != t->parms.iph.saddr &&
                     (local != t->parms.iph.daddr ||
                      !ipv4_is_multicast(local))) ||
@@ -331,7 +316,7 @@ static struct ip_tunnel *ipgre_tunnel_lookup(struct net_device *dev,
                }
        }
 
-       for_each_ip_tunnel_rcu(ign->tunnels_wc[h1]) {
+       for_each_ip_tunnel_rcu(t, ign->tunnels_wc[h1]) {
                if (t->parms.i_key != key ||
                    !(t->dev->flags & IFF_UP))
                        continue;
@@ -753,7 +738,6 @@ drop:
 static netdev_tx_t ipgre_tunnel_xmit(struct sk_buff *skb, struct net_device *dev)
 {
        struct ip_tunnel *tunnel = netdev_priv(dev);
-       struct pcpu_tstats *tstats;
        const struct iphdr  *old_iph = ip_hdr(skb);
        const struct iphdr  *tiph;
        struct flowi4 fl4;
@@ -977,9 +961,7 @@ static netdev_tx_t ipgre_tunnel_xmit(struct sk_buff *skb, struct net_device *dev
                }
        }
 
-       nf_reset(skb);
-       tstats = this_cpu_ptr(dev->tstats);
-       __IPTUNNEL_XMIT(tstats, &dev->stats);
+       iptunnel_xmit(skb, dev);
        return NETDEV_TX_OK;
 
 #if IS_ENABLED(CONFIG_IPV6)
@@ -1082,7 +1064,7 @@ ipgre_tunnel_ioctl (struct net_device *dev, struct ifreq *ifr, int cmd)
        case SIOCADDTUNNEL:
        case SIOCCHGTUNNEL:
                err = -EPERM;
-               if (!capable(CAP_NET_ADMIN))
+               if (!ns_capable(net->user_ns, CAP_NET_ADMIN))
                        goto done;
 
                err = -EFAULT;
@@ -1157,7 +1139,7 @@ ipgre_tunnel_ioctl (struct net_device *dev, struct ifreq *ifr, int cmd)
 
        case SIOCDELTUNNEL:
                err = -EPERM;
-               if (!capable(CAP_NET_ADMIN))
+               if (!ns_capable(net->user_ns, CAP_NET_ADMIN))
                        goto done;
 
                if (dev == ign->fb_tunnel_dev) {