diff options
Diffstat (limited to 'net/ipv6/ip6_gre.c')
| -rw-r--r-- | net/ipv6/ip6_gre.c | 40 |
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) */ | ||
| 120 | struct 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 | ||
| 128 | static struct rtnl_link_stats64 *ip6gre_get_stats64(struct net_device *dev, | 113 | static 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) || |
