aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv6/ip6_gre.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/ipv6/ip6_gre.c')
-rw-r--r--net/ipv6/ip6_gre.c40
1 files changed, 12 insertions, 28 deletions
diff --git a/net/ipv6/ip6_gre.c b/net/ipv6/ip6_gre.c
index 0185679c5f53..c727e4712751 100644
--- a/net/ipv6/ip6_gre.c
+++ b/net/ipv6/ip6_gre.c
@@ -109,21 +109,6 @@ static u32 HASH_ADDR(const struct in6_addr *addr)
109#define tunnels_r tunnels[2] 109#define tunnels_r tunnels[2]
110#define tunnels_l tunnels[1] 110#define tunnels_l tunnels[1]
111#define tunnels_wc tunnels[0] 111#define tunnels_wc tunnels[0]
112/*
113 * Locking : hash tables are protected by RCU and RTNL
114 */
115
116#define for_each_ip_tunnel_rcu(start) \
117 for (t = rcu_dereference(start); t; t = rcu_dereference(t->next))
118
119/* often modified stats are per cpu, other are shared (netdev->stats) */
120struct pcpu_tstats {
121 u64 rx_packets;
122 u64 rx_bytes;
123 u64 tx_packets;
124 u64 tx_bytes;
125 struct u64_stats_sync syncp;
126};
127 112
128static struct rtnl_link_stats64 *ip6gre_get_stats64(struct net_device *dev, 113static struct rtnl_link_stats64 *ip6gre_get_stats64(struct net_device *dev,
129 struct rtnl_link_stats64 *tot) 114 struct rtnl_link_stats64 *tot)
@@ -181,7 +166,7 @@ static struct ip6_tnl *ip6gre_tunnel_lookup(struct net_device *dev,
181 ARPHRD_ETHER : ARPHRD_IP6GRE; 166 ARPHRD_ETHER : ARPHRD_IP6GRE;
182 int score, cand_score = 4; 167 int score, cand_score = 4;
183 168
184 for_each_ip_tunnel_rcu(ign->tunnels_r_l[h0 ^ h1]) { 169 for_each_ip_tunnel_rcu(t, ign->tunnels_r_l[h0 ^ h1]) {
185 if (!ipv6_addr_equal(local, &t->parms.laddr) || 170 if (!ipv6_addr_equal(local, &t->parms.laddr) ||
186 !ipv6_addr_equal(remote, &t->parms.raddr) || 171 !ipv6_addr_equal(remote, &t->parms.raddr) ||
187 key != t->parms.i_key || 172 key != t->parms.i_key ||
@@ -206,7 +191,7 @@ static struct ip6_tnl *ip6gre_tunnel_lookup(struct net_device *dev,
206 } 191 }
207 } 192 }
208 193
209 for_each_ip_tunnel_rcu(ign->tunnels_r[h0 ^ h1]) { 194 for_each_ip_tunnel_rcu(t, ign->tunnels_r[h0 ^ h1]) {
210 if (!ipv6_addr_equal(remote, &t->parms.raddr) || 195 if (!ipv6_addr_equal(remote, &t->parms.raddr) ||
211 key != t->parms.i_key || 196 key != t->parms.i_key ||
212 !(t->dev->flags & IFF_UP)) 197 !(t->dev->flags & IFF_UP))
@@ -230,7 +215,7 @@ static struct ip6_tnl *ip6gre_tunnel_lookup(struct net_device *dev,
230 } 215 }
231 } 216 }
232 217
233 for_each_ip_tunnel_rcu(ign->tunnels_l[h1]) { 218 for_each_ip_tunnel_rcu(t, ign->tunnels_l[h1]) {
234 if ((!ipv6_addr_equal(local, &t->parms.laddr) && 219 if ((!ipv6_addr_equal(local, &t->parms.laddr) &&
235 (!ipv6_addr_equal(local, &t->parms.raddr) || 220 (!ipv6_addr_equal(local, &t->parms.raddr) ||
236 !ipv6_addr_is_multicast(local))) || 221 !ipv6_addr_is_multicast(local))) ||
@@ -256,7 +241,7 @@ static struct ip6_tnl *ip6gre_tunnel_lookup(struct net_device *dev,
256 } 241 }
257 } 242 }
258 243
259 for_each_ip_tunnel_rcu(ign->tunnels_wc[h1]) { 244 for_each_ip_tunnel_rcu(t, ign->tunnels_wc[h1]) {
260 if (t->parms.i_key != key || 245 if (t->parms.i_key != key ||
261 !(t->dev->flags & IFF_UP)) 246 !(t->dev->flags & IFF_UP))
262 continue; 247 continue;
@@ -773,8 +758,6 @@ static netdev_tx_t ip6gre_xmit2(struct sk_buff *skb,
773 skb_dst_set_noref(skb, dst); 758 skb_dst_set_noref(skb, dst);
774 } 759 }
775 760
776 skb->transport_header = skb->network_header;
777
778 proto = NEXTHDR_GRE; 761 proto = NEXTHDR_GRE;
779 if (encap_limit >= 0) { 762 if (encap_limit >= 0) {
780 init_tel_txopt(&opt, encap_limit); 763 init_tel_txopt(&opt, encap_limit);
@@ -783,6 +766,7 @@ static netdev_tx_t ip6gre_xmit2(struct sk_buff *skb,
783 766
784 skb_push(skb, gre_hlen); 767 skb_push(skb, gre_hlen);
785 skb_reset_network_header(skb); 768 skb_reset_network_header(skb);
769 skb_set_transport_header(skb, sizeof(*ipv6h));
786 770
787 /* 771 /*
788 * Push down and install the IP header. 772 * Push down and install the IP header.
@@ -1069,7 +1053,7 @@ static void ip6gre_tnl_link_config(struct ip6_tnl *t, int set_mtu)
1069 dev->mtu = IPV6_MIN_MTU; 1053 dev->mtu = IPV6_MIN_MTU;
1070 } 1054 }
1071 } 1055 }
1072 dst_release(&rt->dst); 1056 ip6_rt_put(rt);
1073 } 1057 }
1074 1058
1075 t->hlen = addend; 1059 t->hlen = addend;
@@ -1161,7 +1145,7 @@ static int ip6gre_tunnel_ioctl(struct net_device *dev,
1161 case SIOCADDTUNNEL: 1145 case SIOCADDTUNNEL:
1162 case SIOCCHGTUNNEL: 1146 case SIOCCHGTUNNEL:
1163 err = -EPERM; 1147 err = -EPERM;
1164 if (!capable(CAP_NET_ADMIN)) 1148 if (!ns_capable(net->user_ns, CAP_NET_ADMIN))
1165 goto done; 1149 goto done;
1166 1150
1167 err = -EFAULT; 1151 err = -EFAULT;
@@ -1209,7 +1193,7 @@ static int ip6gre_tunnel_ioctl(struct net_device *dev,
1209 1193
1210 case SIOCDELTUNNEL: 1194 case SIOCDELTUNNEL:
1211 err = -EPERM; 1195 err = -EPERM;
1212 if (!capable(CAP_NET_ADMIN)) 1196 if (!ns_capable(net->user_ns, CAP_NET_ADMIN))
1213 goto done; 1197 goto done;
1214 1198
1215 if (dev == ign->fb_tunnel_dev) { 1199 if (dev == ign->fb_tunnel_dev) {
@@ -1633,9 +1617,9 @@ static size_t ip6gre_get_size(const struct net_device *dev)
1633 /* IFLA_GRE_OKEY */ 1617 /* IFLA_GRE_OKEY */
1634 nla_total_size(4) + 1618 nla_total_size(4) +
1635 /* IFLA_GRE_LOCAL */ 1619 /* IFLA_GRE_LOCAL */
1636 nla_total_size(4) + 1620 nla_total_size(sizeof(struct in6_addr)) +
1637 /* IFLA_GRE_REMOTE */ 1621 /* IFLA_GRE_REMOTE */
1638 nla_total_size(4) + 1622 nla_total_size(sizeof(struct in6_addr)) +
1639 /* IFLA_GRE_TTL */ 1623 /* IFLA_GRE_TTL */
1640 nla_total_size(1) + 1624 nla_total_size(1) +
1641 /* IFLA_GRE_TOS */ 1625 /* IFLA_GRE_TOS */
@@ -1659,8 +1643,8 @@ static int ip6gre_fill_info(struct sk_buff *skb, const struct net_device *dev)
1659 nla_put_be16(skb, IFLA_GRE_OFLAGS, p->o_flags) || 1643 nla_put_be16(skb, IFLA_GRE_OFLAGS, p->o_flags) ||
1660 nla_put_be32(skb, IFLA_GRE_IKEY, p->i_key) || 1644 nla_put_be32(skb, IFLA_GRE_IKEY, p->i_key) ||
1661 nla_put_be32(skb, IFLA_GRE_OKEY, p->o_key) || 1645 nla_put_be32(skb, IFLA_GRE_OKEY, p->o_key) ||
1662 nla_put(skb, IFLA_GRE_LOCAL, sizeof(struct in6_addr), &p->raddr) || 1646 nla_put(skb, IFLA_GRE_LOCAL, sizeof(struct in6_addr), &p->laddr) ||
1663 nla_put(skb, IFLA_GRE_REMOTE, sizeof(struct in6_addr), &p->laddr) || 1647 nla_put(skb, IFLA_GRE_REMOTE, sizeof(struct in6_addr), &p->raddr) ||
1664 nla_put_u8(skb, IFLA_GRE_TTL, p->hop_limit) || 1648 nla_put_u8(skb, IFLA_GRE_TTL, p->hop_limit) ||
1665 /*nla_put_u8(skb, IFLA_GRE_TOS, t->priority) ||*/ 1649 /*nla_put_u8(skb, IFLA_GRE_TOS, t->priority) ||*/
1666 nla_put_u8(skb, IFLA_GRE_ENCAP_LIMIT, p->encap_limit) || 1650 nla_put_u8(skb, IFLA_GRE_ENCAP_LIMIT, p->encap_limit) ||