ip6_gre.c (2bf81c8af92dd53890557c5d87875842d573a3e9) | ip6_gre.c (af31f412c7c7a3c0fda4bf4beaf0c85af1f263c8) |
---|---|
1/* 2 * GRE over IPv6 protocol decoder. 3 * 4 * Authors: Dmitry Kozlov (xeb@mail.ru) 5 * 6 * This program is free software; you can redistribute it and/or 7 * modify it under the terms of the GNU General Public License 8 * as published by the Free Software Foundation; either version --- 95 unchanged lines hidden (view full) --- 104 105 return hash_32(hash, HASH_SIZE_SHIFT); 106} 107 108#define tunnels_r_l tunnels[3] 109#define tunnels_r tunnels[2] 110#define tunnels_l tunnels[1] 111#define tunnels_wc tunnels[0] | 1/* 2 * GRE over IPv6 protocol decoder. 3 * 4 * Authors: Dmitry Kozlov (xeb@mail.ru) 5 * 6 * This program is free software; you can redistribute it and/or 7 * modify it under the terms of the GNU General Public License 8 * as published by the Free Software Foundation; either version --- 95 unchanged lines hidden (view full) --- 104 105 return hash_32(hash, HASH_SIZE_SHIFT); 106} 107 108#define tunnels_r_l tunnels[3] 109#define tunnels_r tunnels[2] 110#define tunnels_l tunnels[1] 111#define tunnels_wc tunnels[0] |
112/* 113 * Locking : hash tables are protected by RCU and RTNL 114 */ | |
115 | 112 |
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 | |
128static struct rtnl_link_stats64 *ip6gre_get_stats64(struct net_device *dev, 129 struct rtnl_link_stats64 *tot) 130{ 131 int i; 132 133 for_each_possible_cpu(i) { 134 const struct pcpu_tstats *tstats = per_cpu_ptr(dev->tstats, i); 135 u64 rx_packets, rx_bytes, tx_packets, tx_bytes; --- 40 unchanged lines hidden (view full) --- 176 unsigned int h0 = HASH_ADDR(remote); 177 unsigned int h1 = HASH_KEY(key); 178 struct ip6_tnl *t, *cand = NULL; 179 struct ip6gre_net *ign = net_generic(net, ip6gre_net_id); 180 int dev_type = (gre_proto == htons(ETH_P_TEB)) ? 181 ARPHRD_ETHER : ARPHRD_IP6GRE; 182 int score, cand_score = 4; 183 | 113static struct rtnl_link_stats64 *ip6gre_get_stats64(struct net_device *dev, 114 struct rtnl_link_stats64 *tot) 115{ 116 int i; 117 118 for_each_possible_cpu(i) { 119 const struct pcpu_tstats *tstats = per_cpu_ptr(dev->tstats, i); 120 u64 rx_packets, rx_bytes, tx_packets, tx_bytes; --- 40 unchanged lines hidden (view full) --- 161 unsigned int h0 = HASH_ADDR(remote); 162 unsigned int h1 = HASH_KEY(key); 163 struct ip6_tnl *t, *cand = NULL; 164 struct ip6gre_net *ign = net_generic(net, ip6gre_net_id); 165 int dev_type = (gre_proto == htons(ETH_P_TEB)) ? 166 ARPHRD_ETHER : ARPHRD_IP6GRE; 167 int score, cand_score = 4; 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) || 186 !ipv6_addr_equal(remote, &t->parms.raddr) || 187 key != t->parms.i_key || 188 !(t->dev->flags & IFF_UP)) 189 continue; 190 191 if (t->dev->type != ARPHRD_IP6GRE && 192 t->dev->type != dev_type) --- 8 unchanged lines hidden (view full) --- 201 return t; 202 203 if (score < cand_score) { 204 cand = t; 205 cand_score = score; 206 } 207 } 208 | 170 if (!ipv6_addr_equal(local, &t->parms.laddr) || 171 !ipv6_addr_equal(remote, &t->parms.raddr) || 172 key != t->parms.i_key || 173 !(t->dev->flags & IFF_UP)) 174 continue; 175 176 if (t->dev->type != ARPHRD_IP6GRE && 177 t->dev->type != dev_type) --- 8 unchanged lines hidden (view full) --- 186 return t; 187 188 if (score < cand_score) { 189 cand = t; 190 cand_score = score; 191 } 192 } 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) || 211 key != t->parms.i_key || 212 !(t->dev->flags & IFF_UP)) 213 continue; 214 215 if (t->dev->type != ARPHRD_IP6GRE && 216 t->dev->type != dev_type) 217 continue; --- 7 unchanged lines hidden (view full) --- 225 return t; 226 227 if (score < cand_score) { 228 cand = t; 229 cand_score = score; 230 } 231 } 232 | 195 if (!ipv6_addr_equal(remote, &t->parms.raddr) || 196 key != t->parms.i_key || 197 !(t->dev->flags & IFF_UP)) 198 continue; 199 200 if (t->dev->type != ARPHRD_IP6GRE && 201 t->dev->type != dev_type) 202 continue; --- 7 unchanged lines hidden (view full) --- 210 return t; 211 212 if (score < cand_score) { 213 cand = t; 214 cand_score = score; 215 } 216 } 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) && 235 (!ipv6_addr_equal(local, &t->parms.raddr) || 236 !ipv6_addr_is_multicast(local))) || 237 key != t->parms.i_key || 238 !(t->dev->flags & IFF_UP)) 239 continue; 240 241 if (t->dev->type != ARPHRD_IP6GRE && --- 9 unchanged lines hidden (view full) --- 251 return t; 252 253 if (score < cand_score) { 254 cand = t; 255 cand_score = score; 256 } 257 } 258 | 219 if ((!ipv6_addr_equal(local, &t->parms.laddr) && 220 (!ipv6_addr_equal(local, &t->parms.raddr) || 221 !ipv6_addr_is_multicast(local))) || 222 key != t->parms.i_key || 223 !(t->dev->flags & IFF_UP)) 224 continue; 225 226 if (t->dev->type != ARPHRD_IP6GRE && --- 9 unchanged lines hidden (view full) --- 236 return t; 237 238 if (score < cand_score) { 239 cand = t; 240 cand_score = score; 241 } 242 } 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 || 261 !(t->dev->flags & IFF_UP)) 262 continue; 263 264 if (t->dev->type != ARPHRD_IP6GRE && 265 t->dev->type != dev_type) 266 continue; 267 --- 796 unchanged lines hidden (view full) --- 1064 dev->mtu = rt->dst.dev->mtu - addend; 1065 if (!(t->parms.flags & IP6_TNL_F_IGN_ENCAP_LIMIT)) 1066 dev->mtu -= 8; 1067 1068 if (dev->mtu < IPV6_MIN_MTU) 1069 dev->mtu = IPV6_MIN_MTU; 1070 } 1071 } | 245 if (t->parms.i_key != key || 246 !(t->dev->flags & IFF_UP)) 247 continue; 248 249 if (t->dev->type != ARPHRD_IP6GRE && 250 t->dev->type != dev_type) 251 continue; 252 --- 796 unchanged lines hidden (view full) --- 1049 dev->mtu = rt->dst.dev->mtu - addend; 1050 if (!(t->parms.flags & IP6_TNL_F_IGN_ENCAP_LIMIT)) 1051 dev->mtu -= 8; 1052 1053 if (dev->mtu < IPV6_MIN_MTU) 1054 dev->mtu = IPV6_MIN_MTU; 1055 } 1056 } |
1072 dst_release(&rt->dst); | 1057 ip6_rt_put(rt); |
1073 } 1074 1075 t->hlen = addend; 1076} 1077 1078static int ip6gre_tnl_change(struct ip6_tnl *t, 1079 const struct __ip6_tnl_parm *p, int set_mtu) 1080{ --- 75 unchanged lines hidden (view full) --- 1156 ip6gre_tnl_parm_to_user(&p, &t->parms); 1157 if (copy_to_user(ifr->ifr_ifru.ifru_data, &p, sizeof(p))) 1158 err = -EFAULT; 1159 break; 1160 1161 case SIOCADDTUNNEL: 1162 case SIOCCHGTUNNEL: 1163 err = -EPERM; | 1058 } 1059 1060 t->hlen = addend; 1061} 1062 1063static int ip6gre_tnl_change(struct ip6_tnl *t, 1064 const struct __ip6_tnl_parm *p, int set_mtu) 1065{ --- 75 unchanged lines hidden (view full) --- 1141 ip6gre_tnl_parm_to_user(&p, &t->parms); 1142 if (copy_to_user(ifr->ifr_ifru.ifru_data, &p, sizeof(p))) 1143 err = -EFAULT; 1144 break; 1145 1146 case SIOCADDTUNNEL: 1147 case SIOCCHGTUNNEL: 1148 err = -EPERM; |
1164 if (!capable(CAP_NET_ADMIN)) | 1149 if (!ns_capable(net->user_ns, CAP_NET_ADMIN)) |
1165 goto done; 1166 1167 err = -EFAULT; 1168 if (copy_from_user(&p, ifr->ifr_ifru.ifru_data, sizeof(p))) 1169 goto done; 1170 1171 err = -EINVAL; 1172 if ((p.i_flags|p.o_flags)&(GRE_VERSION|GRE_ROUTING)) --- 31 unchanged lines hidden (view full) --- 1204 if (copy_to_user(ifr->ifr_ifru.ifru_data, &p, sizeof(p))) 1205 err = -EFAULT; 1206 } else 1207 err = (cmd == SIOCADDTUNNEL ? -ENOBUFS : -ENOENT); 1208 break; 1209 1210 case SIOCDELTUNNEL: 1211 err = -EPERM; | 1150 goto done; 1151 1152 err = -EFAULT; 1153 if (copy_from_user(&p, ifr->ifr_ifru.ifru_data, sizeof(p))) 1154 goto done; 1155 1156 err = -EINVAL; 1157 if ((p.i_flags|p.o_flags)&(GRE_VERSION|GRE_ROUTING)) --- 31 unchanged lines hidden (view full) --- 1189 if (copy_to_user(ifr->ifr_ifru.ifru_data, &p, sizeof(p))) 1190 err = -EFAULT; 1191 } else 1192 err = (cmd == SIOCADDTUNNEL ? -ENOBUFS : -ENOENT); 1193 break; 1194 1195 case SIOCDELTUNNEL: 1196 err = -EPERM; |
1212 if (!capable(CAP_NET_ADMIN)) | 1197 if (!ns_capable(net->user_ns, CAP_NET_ADMIN)) |
1213 goto done; 1214 1215 if (dev == ign->fb_tunnel_dev) { 1216 err = -EFAULT; 1217 if (copy_from_user(&p, ifr->ifr_ifru.ifru_data, sizeof(p))) 1218 goto done; 1219 err = -ENOENT; 1220 ip6gre_tnl_parm_from_user(&p1, &p); --- 550 unchanged lines hidden --- | 1198 goto done; 1199 1200 if (dev == ign->fb_tunnel_dev) { 1201 err = -EFAULT; 1202 if (copy_from_user(&p, ifr->ifr_ifru.ifru_data, sizeof(p))) 1203 goto done; 1204 err = -ENOENT; 1205 ip6gre_tnl_parm_from_user(&p1, &p); --- 550 unchanged lines hidden --- |