diff options
author | Ralf Baechle <ralf@linux-mips.org> | 2000-07-10 23:18:26 +0000 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 2000-07-10 23:18:26 +0000 |
commit | c7c4310f7fc1485925d800628bf50b3aeab535ef (patch) | |
tree | b12aa4be0e8fb82aaaea97fb475e793e8a347c49 /net/ipv4/ip_gre.c | |
parent | 1ffd1d069ca4c5ffe16fea6175dab1b9bbb15820 (diff) |
Merge with Linux 2.4.0-test3-pre8. Linus has accepted most of what
I've sent him, so we're very close to full integration of the MIPS
port into his sources.
Diffstat (limited to 'net/ipv4/ip_gre.c')
-rw-r--r-- | net/ipv4/ip_gre.c | 51 |
1 files changed, 45 insertions, 6 deletions
diff --git a/net/ipv4/ip_gre.c b/net/ipv4/ip_gre.c index 79dc3d629..a316401b0 100644 --- a/net/ipv4/ip_gre.c +++ b/net/ipv4/ip_gre.c @@ -36,6 +36,7 @@ #include <net/ipip.h> #include <net/arp.h> #include <net/checksum.h> +#include <net/inet_ecn.h> #ifdef CONFIG_IPV6 #include <net/ipv6.h> @@ -119,11 +120,11 @@ static int ipgre_tunnel_init(struct net_device *dev); static int ipgre_fb_tunnel_init(struct net_device *dev); static struct net_device ipgre_fb_tunnel_dev = { - "gre%d", 0x0, 0x0, 0x0, 0x0, 0, 0, 0, 0, 0, NULL, ipgre_fb_tunnel_init, + "gre0", 0x0, 0x0, 0x0, 0x0, 0, 0, 0, 0, 0, NULL, ipgre_fb_tunnel_init, }; static struct ip_tunnel ipgre_fb_tunnel = { - NULL, &ipgre_fb_tunnel_dev, {0, }, 0, 0, 0, 0, 0, 0, 0, {"gre%d", } + NULL, &ipgre_fb_tunnel_dev, {0, }, 0, 0, 0, 0, 0, 0, 0, {"gre0", } }; /* Tunnel hash table */ @@ -530,6 +531,34 @@ out: #endif } +static inline void ipgre_ecn_decapsulate(struct iphdr *iph, struct sk_buff *skb) +{ + if (INET_ECN_is_ce(iph->tos)) { + if (skb->protocol == __constant_htons(ETH_P_IP)) { + if (INET_ECN_is_not_ce(skb->nh.iph->tos)) + IP_ECN_set_ce(skb->nh.iph); + } else if (skb->protocol == __constant_htons(ETH_P_IPV6)) { + if (INET_ECN_is_not_ce(ip6_get_dsfield(skb->nh.ipv6h))) + IP6_ECN_set_ce(skb->nh.ipv6h); + } + } +} + +static inline u8 +ipgre_ecn_encapsulate(u8 tos, struct iphdr *old_iph, struct sk_buff *skb) +{ +#ifdef CONFIG_INET_ECN + u8 inner = 0; + if (skb->protocol == __constant_htons(ETH_P_IP)) + inner = old_iph->tos; + else if (skb->protocol == __constant_htons(ETH_P_IPV6)) + inner = ip6_get_dsfield((struct ipv6hdr*)old_iph); + return INET_ECN_encapsulate(tos, inner); +#else + return tos; +#endif +} + int ipgre_rcv(struct sk_buff *skb, unsigned short len) { struct iphdr *iph = skb->nh.iph; @@ -604,6 +633,7 @@ int ipgre_rcv(struct sk_buff *skb, unsigned short len) nf_conntrack_put(skb->nfct); skb->nfct = NULL; #endif + ipgre_ecn_decapsulate(iph, skb); netif_rx(skb); read_unlock(&ipgre_lock); return(0); @@ -638,6 +668,7 @@ static int ipgre_tunnel_xmit(struct sk_buff *skb, struct net_device *dev) int gre_hlen; u32 dst; int mtu; + int err; if (tunnel->recursion++) { tunnel->stat.collisions++; @@ -789,7 +820,7 @@ static int ipgre_tunnel_xmit(struct sk_buff *skb, struct net_device *dev) iph->ihl = sizeof(struct iphdr) >> 2; iph->frag_off = df; iph->protocol = IPPROTO_GRE; - iph->tos = tos; + iph->tos = ipgre_ecn_encapsulate(tos, old_iph, skb); iph->daddr = rt->rt_dst; iph->saddr = rt->rt_src; @@ -834,10 +865,17 @@ static int ipgre_tunnel_xmit(struct sk_buff *skb, struct net_device *dev) skb->nfct = NULL; #endif + err = NF_HOOK(PF_INET, NF_IP_LOCAL_OUT, skb, NULL, rt->u.dst.dev, + do_ip_send); + if(err < 0) { + if(net_ratelimit()) + printk(KERN_ERR "ipgre_tunnel_xmit: ip_send() failed, err=%d\n", -err); + skb = NULL; + goto tx_error; + } + stats->tx_bytes += skb->len; stats->tx_packets++; - NF_HOOK(PF_INET, NF_IP_LOCAL_OUT, skb, NULL, rt->u.dst.dev, - do_ip_send); tunnel->recursion--; return 0; @@ -846,7 +884,8 @@ tx_error_icmp: tx_error: stats->tx_errors++; - dev_kfree_skb(skb); + if(skb) + dev_kfree_skb(skb); tunnel->recursion--; return 0; } |