aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv4/ip_gre.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/ipv4/ip_gre.c')
-rw-r--r--net/ipv4/ip_gre.c39
1 files changed, 24 insertions, 15 deletions
diff --git a/net/ipv4/ip_gre.c b/net/ipv4/ip_gre.c
index 6b3ca5ba4450..b57532d4742c 100644
--- a/net/ipv4/ip_gre.c
+++ b/net/ipv4/ip_gre.c
@@ -10,6 +10,8 @@
*
*/
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
#include <linux/capability.h>
#include <linux/module.h>
#include <linux/types.h>
@@ -65,7 +67,7 @@
it is infeasible task. The most general solutions would be
to keep skb->encapsulation counter (sort of local ttl),
and silently drop packet when it expires. It is a good
- solution, but it supposes maintaing new variable in ALL
+ solution, but it supposes maintaining new variable in ALL
skb, even if no tunneling is used.
Current solution: xmit_recursion breaks dead loops. This is a percpu
@@ -91,14 +93,14 @@
One of them is to parse packet trying to detect inner encapsulation
made by our node. It is difficult or even impossible, especially,
- taking into account fragmentation. TO be short, tt is not solution at all.
+ taking into account fragmentation. TO be short, ttl is not solution at all.
Current solution: The solution was UNEXPECTEDLY SIMPLE.
We force DF flag on tunnels with preconfigured hop limit,
that is ALL. :-) Well, it does not remove the problem completely,
but exponential growth of network traffic is changed to linear
(branches, that exceed pmtu are pruned) and tunnel mtu
- fastly degrades to value <68, where looping stops.
+ rapidly degrades to value <68, where looping stops.
Yes, it is not good if there exists a router in the loop,
which does not force DF, even when encapsulating packets have DF set.
But it is not our problem! Nobody could accuse us, we made
@@ -457,8 +459,8 @@ static void ipgre_err(struct sk_buff *skb, u32 info)
GRE tunnels with enabled checksum. Tell them "thank you".
Well, I wonder, rfc1812 was written by Cisco employee,
- what the hell these idiots break standrads established
- by themself???
+ what the hell these idiots break standards established
+ by themselves???
*/
const struct iphdr *iph = (const struct iphdr *)skb->data;
@@ -730,15 +732,16 @@ static netdev_tx_t ipgre_tunnel_xmit(struct sk_buff *skb, struct net_device *dev
if (skb->protocol == htons(ETH_P_IP)) {
rt = skb_rtable(skb);
- if ((dst = rt->rt_gateway) == 0)
- goto tx_error_icmp;
+ dst = rt->rt_gateway;
}
#if IS_ENABLED(CONFIG_IPV6)
else if (skb->protocol == htons(ETH_P_IPV6)) {
- struct neighbour *neigh = dst_get_neighbour_noref(skb_dst(skb));
const struct in6_addr *addr6;
+ struct neighbour *neigh;
+ bool do_tx_error_icmp;
int addr_type;
+ neigh = dst_neigh_lookup(skb_dst(skb), &ipv6_hdr(skb)->daddr);
if (neigh == NULL)
goto tx_error;
@@ -751,9 +754,14 @@ static netdev_tx_t ipgre_tunnel_xmit(struct sk_buff *skb, struct net_device *dev
}
if ((addr_type & IPV6_ADDR_COMPATv4) == 0)
+ do_tx_error_icmp = true;
+ else {
+ do_tx_error_icmp = false;
+ dst = addr6->s6_addr32[3];
+ }
+ neigh_release(neigh);
+ if (do_tx_error_icmp)
goto tx_error_icmp;
-
- dst = addr6->s6_addr32[3];
}
#endif
else
@@ -914,9 +922,10 @@ static netdev_tx_t ipgre_tunnel_xmit(struct sk_buff *skb, struct net_device *dev
__IPTUNNEL_XMIT(tstats, &dev->stats);
return NETDEV_TX_OK;
+#if IS_ENABLED(CONFIG_IPV6)
tx_error_icmp:
dst_link_failure(skb);
-
+#endif
tx_error:
dev->stats.tx_errors++;
dev_kfree_skb(skb);
@@ -1529,7 +1538,7 @@ static int ipgre_newlink(struct net *src_net, struct net_device *dev, struct nla
return -EEXIST;
if (dev->type == ARPHRD_ETHER && !tb[IFLA_ADDRESS])
- random_ether_addr(dev->dev_addr);
+ eth_hw_addr_random(dev);
mtu = ipgre_tunnel_bind_dev(dev);
if (!tb[IFLA_MTU])
@@ -1709,7 +1718,7 @@ static int __init ipgre_init(void)
{
int err;
- printk(KERN_INFO "GRE over IPv4 tunneling driver\n");
+ pr_info("GRE over IPv4 tunneling driver\n");
err = register_pernet_device(&ipgre_net_ops);
if (err < 0)
@@ -1717,7 +1726,7 @@ static int __init ipgre_init(void)
err = gre_add_protocol(&ipgre_protocol, GREPROTO_CISCO);
if (err < 0) {
- printk(KERN_INFO "ipgre init: can't add protocol\n");
+ pr_info("%s: can't add protocol\n", __func__);
goto add_proto_failed;
}
@@ -1746,7 +1755,7 @@ static void __exit ipgre_fini(void)
rtnl_link_unregister(&ipgre_tap_ops);
rtnl_link_unregister(&ipgre_link_ops);
if (gre_del_protocol(&ipgre_protocol, GREPROTO_CISCO) < 0)
- printk(KERN_INFO "ipgre close: can't remove protocol\n");
+ pr_info("%s: can't remove protocol\n", __func__);
unregister_pernet_device(&ipgre_net_ops);
}