diff options
Diffstat (limited to 'net/ipv4/ip_gre.c')
| -rw-r--r-- | net/ipv4/ip_gre.c | 92 |
1 files changed, 39 insertions, 53 deletions
diff --git a/net/ipv4/ip_gre.c b/net/ipv4/ip_gre.c index 6613edfac28c..8871067560db 100644 --- a/net/ipv4/ip_gre.c +++ b/net/ipv4/ip_gre.c | |||
| @@ -413,11 +413,6 @@ static struct ip_tunnel *ipgre_tunnel_locate(struct net *net, | |||
| 413 | 413 | ||
| 414 | dev_net_set(dev, net); | 414 | dev_net_set(dev, net); |
| 415 | 415 | ||
| 416 | if (strchr(name, '%')) { | ||
| 417 | if (dev_alloc_name(dev, name) < 0) | ||
| 418 | goto failed_free; | ||
| 419 | } | ||
| 420 | |||
| 421 | nt = netdev_priv(dev); | 416 | nt = netdev_priv(dev); |
| 422 | nt->parms = *parms; | 417 | nt->parms = *parms; |
| 423 | dev->rtnl_link_ops = &ipgre_link_ops; | 418 | dev->rtnl_link_ops = &ipgre_link_ops; |
| @@ -462,7 +457,7 @@ static void ipgre_err(struct sk_buff *skb, u32 info) | |||
| 462 | by themself??? | 457 | by themself??? |
| 463 | */ | 458 | */ |
| 464 | 459 | ||
| 465 | struct iphdr *iph = (struct iphdr *)skb->data; | 460 | const struct iphdr *iph = (const struct iphdr *)skb->data; |
| 466 | __be16 *p = (__be16*)(skb->data+(iph->ihl<<2)); | 461 | __be16 *p = (__be16*)(skb->data+(iph->ihl<<2)); |
| 467 | int grehlen = (iph->ihl<<2) + 4; | 462 | int grehlen = (iph->ihl<<2) + 4; |
| 468 | const int type = icmp_hdr(skb)->type; | 463 | const int type = icmp_hdr(skb)->type; |
| @@ -534,7 +529,7 @@ out: | |||
| 534 | rcu_read_unlock(); | 529 | rcu_read_unlock(); |
| 535 | } | 530 | } |
| 536 | 531 | ||
| 537 | static inline void ipgre_ecn_decapsulate(struct iphdr *iph, struct sk_buff *skb) | 532 | static inline void ipgre_ecn_decapsulate(const struct iphdr *iph, struct sk_buff *skb) |
| 538 | { | 533 | { |
| 539 | if (INET_ECN_is_ce(iph->tos)) { | 534 | if (INET_ECN_is_ce(iph->tos)) { |
| 540 | if (skb->protocol == htons(ETH_P_IP)) { | 535 | if (skb->protocol == htons(ETH_P_IP)) { |
| @@ -546,19 +541,19 @@ static inline void ipgre_ecn_decapsulate(struct iphdr *iph, struct sk_buff *skb) | |||
| 546 | } | 541 | } |
| 547 | 542 | ||
| 548 | static inline u8 | 543 | static inline u8 |
| 549 | ipgre_ecn_encapsulate(u8 tos, struct iphdr *old_iph, struct sk_buff *skb) | 544 | ipgre_ecn_encapsulate(u8 tos, const struct iphdr *old_iph, struct sk_buff *skb) |
| 550 | { | 545 | { |
| 551 | u8 inner = 0; | 546 | u8 inner = 0; |
| 552 | if (skb->protocol == htons(ETH_P_IP)) | 547 | if (skb->protocol == htons(ETH_P_IP)) |
| 553 | inner = old_iph->tos; | 548 | inner = old_iph->tos; |
| 554 | else if (skb->protocol == htons(ETH_P_IPV6)) | 549 | else if (skb->protocol == htons(ETH_P_IPV6)) |
| 555 | inner = ipv6_get_dsfield((struct ipv6hdr *)old_iph); | 550 | inner = ipv6_get_dsfield((const struct ipv6hdr *)old_iph); |
| 556 | return INET_ECN_encapsulate(tos, inner); | 551 | return INET_ECN_encapsulate(tos, inner); |
| 557 | } | 552 | } |
| 558 | 553 | ||
| 559 | static int ipgre_rcv(struct sk_buff *skb) | 554 | static int ipgre_rcv(struct sk_buff *skb) |
| 560 | { | 555 | { |
| 561 | struct iphdr *iph; | 556 | const struct iphdr *iph; |
| 562 | u8 *h; | 557 | u8 *h; |
| 563 | __be16 flags; | 558 | __be16 flags; |
| 564 | __sum16 csum = 0; | 559 | __sum16 csum = 0; |
| @@ -697,8 +692,9 @@ static netdev_tx_t ipgre_tunnel_xmit(struct sk_buff *skb, struct net_device *dev | |||
| 697 | { | 692 | { |
| 698 | struct ip_tunnel *tunnel = netdev_priv(dev); | 693 | struct ip_tunnel *tunnel = netdev_priv(dev); |
| 699 | struct pcpu_tstats *tstats; | 694 | struct pcpu_tstats *tstats; |
| 700 | struct iphdr *old_iph = ip_hdr(skb); | 695 | const struct iphdr *old_iph = ip_hdr(skb); |
| 701 | struct iphdr *tiph; | 696 | const struct iphdr *tiph; |
| 697 | struct flowi4 fl4; | ||
| 702 | u8 tos; | 698 | u8 tos; |
| 703 | __be16 df; | 699 | __be16 df; |
| 704 | struct rtable *rt; /* Route to the other host */ | 700 | struct rtable *rt; /* Route to the other host */ |
| @@ -714,7 +710,7 @@ static netdev_tx_t ipgre_tunnel_xmit(struct sk_buff *skb, struct net_device *dev | |||
| 714 | 710 | ||
| 715 | if (dev->header_ops && dev->type == ARPHRD_IPGRE) { | 711 | if (dev->header_ops && dev->type == ARPHRD_IPGRE) { |
| 716 | gre_hlen = 0; | 712 | gre_hlen = 0; |
| 717 | tiph = (struct iphdr *)skb->data; | 713 | tiph = (const struct iphdr *)skb->data; |
| 718 | } else { | 714 | } else { |
| 719 | gre_hlen = tunnel->hlen; | 715 | gre_hlen = tunnel->hlen; |
| 720 | tiph = &tunnel->parms.iph; | 716 | tiph = &tunnel->parms.iph; |
| @@ -735,14 +731,14 @@ static netdev_tx_t ipgre_tunnel_xmit(struct sk_buff *skb, struct net_device *dev | |||
| 735 | } | 731 | } |
| 736 | #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) | 732 | #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) |
| 737 | else if (skb->protocol == htons(ETH_P_IPV6)) { | 733 | else if (skb->protocol == htons(ETH_P_IPV6)) { |
| 738 | struct in6_addr *addr6; | 734 | const struct in6_addr *addr6; |
| 739 | int addr_type; | 735 | int addr_type; |
| 740 | struct neighbour *neigh = skb_dst(skb)->neighbour; | 736 | struct neighbour *neigh = skb_dst(skb)->neighbour; |
| 741 | 737 | ||
| 742 | if (neigh == NULL) | 738 | if (neigh == NULL) |
| 743 | goto tx_error; | 739 | goto tx_error; |
| 744 | 740 | ||
| 745 | addr6 = (struct in6_addr *)&neigh->primary_key; | 741 | addr6 = (const struct in6_addr *)&neigh->primary_key; |
| 746 | addr_type = ipv6_addr_type(addr6); | 742 | addr_type = ipv6_addr_type(addr6); |
| 747 | 743 | ||
| 748 | if (addr_type == IPV6_ADDR_ANY) { | 744 | if (addr_type == IPV6_ADDR_ANY) { |
| @@ -766,22 +762,15 @@ static netdev_tx_t ipgre_tunnel_xmit(struct sk_buff *skb, struct net_device *dev | |||
| 766 | if (skb->protocol == htons(ETH_P_IP)) | 762 | if (skb->protocol == htons(ETH_P_IP)) |
| 767 | tos = old_iph->tos; | 763 | tos = old_iph->tos; |
| 768 | else if (skb->protocol == htons(ETH_P_IPV6)) | 764 | else if (skb->protocol == htons(ETH_P_IPV6)) |
| 769 | tos = ipv6_get_dsfield((struct ipv6hdr *)old_iph); | 765 | tos = ipv6_get_dsfield((const struct ipv6hdr *)old_iph); |
| 770 | } | 766 | } |
| 771 | 767 | ||
| 772 | { | 768 | rt = ip_route_output_gre(dev_net(dev), &fl4, dst, tiph->saddr, |
| 773 | struct flowi fl = { | 769 | tunnel->parms.o_key, RT_TOS(tos), |
| 774 | .oif = tunnel->parms.link, | 770 | tunnel->parms.link); |
| 775 | .fl4_dst = dst, | 771 | if (IS_ERR(rt)) { |
| 776 | .fl4_src = tiph->saddr, | 772 | dev->stats.tx_carrier_errors++; |
| 777 | .fl4_tos = RT_TOS(tos), | 773 | goto tx_error; |
| 778 | .proto = IPPROTO_GRE, | ||
| 779 | .fl_gre_key = tunnel->parms.o_key | ||
| 780 | }; | ||
| 781 | if (ip_route_output_key(dev_net(dev), &rt, &fl)) { | ||
| 782 | dev->stats.tx_carrier_errors++; | ||
| 783 | goto tx_error; | ||
| 784 | } | ||
| 785 | } | 774 | } |
| 786 | tdev = rt->dst.dev; | 775 | tdev = rt->dst.dev; |
| 787 | 776 | ||
| @@ -880,15 +869,15 @@ static netdev_tx_t ipgre_tunnel_xmit(struct sk_buff *skb, struct net_device *dev | |||
| 880 | iph->frag_off = df; | 869 | iph->frag_off = df; |
| 881 | iph->protocol = IPPROTO_GRE; | 870 | iph->protocol = IPPROTO_GRE; |
| 882 | iph->tos = ipgre_ecn_encapsulate(tos, old_iph, skb); | 871 | iph->tos = ipgre_ecn_encapsulate(tos, old_iph, skb); |
| 883 | iph->daddr = rt->rt_dst; | 872 | iph->daddr = fl4.daddr; |
| 884 | iph->saddr = rt->rt_src; | 873 | iph->saddr = fl4.saddr; |
| 885 | 874 | ||
| 886 | if ((iph->ttl = tiph->ttl) == 0) { | 875 | if ((iph->ttl = tiph->ttl) == 0) { |
| 887 | if (skb->protocol == htons(ETH_P_IP)) | 876 | if (skb->protocol == htons(ETH_P_IP)) |
| 888 | iph->ttl = old_iph->ttl; | 877 | iph->ttl = old_iph->ttl; |
| 889 | #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) | 878 | #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) |
| 890 | else if (skb->protocol == htons(ETH_P_IPV6)) | 879 | else if (skb->protocol == htons(ETH_P_IPV6)) |
| 891 | iph->ttl = ((struct ipv6hdr *)old_iph)->hop_limit; | 880 | iph->ttl = ((const struct ipv6hdr *)old_iph)->hop_limit; |
| 892 | #endif | 881 | #endif |
| 893 | else | 882 | else |
| 894 | iph->ttl = ip4_dst_hoplimit(&rt->dst); | 883 | iph->ttl = ip4_dst_hoplimit(&rt->dst); |
| @@ -934,7 +923,7 @@ static int ipgre_tunnel_bind_dev(struct net_device *dev) | |||
| 934 | { | 923 | { |
| 935 | struct net_device *tdev = NULL; | 924 | struct net_device *tdev = NULL; |
| 936 | struct ip_tunnel *tunnel; | 925 | struct ip_tunnel *tunnel; |
| 937 | struct iphdr *iph; | 926 | const struct iphdr *iph; |
| 938 | int hlen = LL_MAX_HEADER; | 927 | int hlen = LL_MAX_HEADER; |
| 939 | int mtu = ETH_DATA_LEN; | 928 | int mtu = ETH_DATA_LEN; |
| 940 | int addend = sizeof(struct iphdr) + 4; | 929 | int addend = sizeof(struct iphdr) + 4; |
| @@ -945,17 +934,15 @@ static int ipgre_tunnel_bind_dev(struct net_device *dev) | |||
| 945 | /* Guess output device to choose reasonable mtu and needed_headroom */ | 934 | /* Guess output device to choose reasonable mtu and needed_headroom */ |
| 946 | 935 | ||
| 947 | if (iph->daddr) { | 936 | if (iph->daddr) { |
| 948 | struct flowi fl = { | 937 | struct flowi4 fl4; |
| 949 | .oif = tunnel->parms.link, | ||
| 950 | .fl4_dst = iph->daddr, | ||
| 951 | .fl4_src = iph->saddr, | ||
| 952 | .fl4_tos = RT_TOS(iph->tos), | ||
| 953 | .proto = IPPROTO_GRE, | ||
| 954 | .fl_gre_key = tunnel->parms.o_key | ||
| 955 | }; | ||
| 956 | struct rtable *rt; | 938 | struct rtable *rt; |
| 957 | 939 | ||
| 958 | if (!ip_route_output_key(dev_net(dev), &rt, &fl)) { | 940 | rt = ip_route_output_gre(dev_net(dev), &fl4, |
| 941 | iph->daddr, iph->saddr, | ||
| 942 | tunnel->parms.o_key, | ||
| 943 | RT_TOS(iph->tos), | ||
| 944 | tunnel->parms.link); | ||
| 945 | if (!IS_ERR(rt)) { | ||
| 959 | tdev = rt->dst.dev; | 946 | tdev = rt->dst.dev; |
| 960 | ip_rt_put(rt); | 947 | ip_rt_put(rt); |
| 961 | } | 948 | } |
| @@ -1191,7 +1178,7 @@ static int ipgre_header(struct sk_buff *skb, struct net_device *dev, | |||
| 1191 | 1178 | ||
| 1192 | static int ipgre_header_parse(const struct sk_buff *skb, unsigned char *haddr) | 1179 | static int ipgre_header_parse(const struct sk_buff *skb, unsigned char *haddr) |
| 1193 | { | 1180 | { |
| 1194 | struct iphdr *iph = (struct iphdr *) skb_mac_header(skb); | 1181 | const struct iphdr *iph = (const struct iphdr *) skb_mac_header(skb); |
| 1195 | memcpy(haddr, &iph->saddr, 4); | 1182 | memcpy(haddr, &iph->saddr, 4); |
| 1196 | return 4; | 1183 | return 4; |
| 1197 | } | 1184 | } |
| @@ -1207,17 +1194,16 @@ static int ipgre_open(struct net_device *dev) | |||
| 1207 | struct ip_tunnel *t = netdev_priv(dev); | 1194 | struct ip_tunnel *t = netdev_priv(dev); |
| 1208 | 1195 | ||
| 1209 | if (ipv4_is_multicast(t->parms.iph.daddr)) { | 1196 | if (ipv4_is_multicast(t->parms.iph.daddr)) { |
| 1210 | struct flowi fl = { | 1197 | struct flowi4 fl4; |
| 1211 | .oif = t->parms.link, | ||
| 1212 | .fl4_dst = t->parms.iph.daddr, | ||
| 1213 | .fl4_src = t->parms.iph.saddr, | ||
| 1214 | .fl4_tos = RT_TOS(t->parms.iph.tos), | ||
| 1215 | .proto = IPPROTO_GRE, | ||
| 1216 | .fl_gre_key = t->parms.o_key | ||
| 1217 | }; | ||
| 1218 | struct rtable *rt; | 1198 | struct rtable *rt; |
| 1219 | 1199 | ||
| 1220 | if (ip_route_output_key(dev_net(dev), &rt, &fl)) | 1200 | rt = ip_route_output_gre(dev_net(dev), &fl4, |
| 1201 | t->parms.iph.daddr, | ||
| 1202 | t->parms.iph.saddr, | ||
| 1203 | t->parms.o_key, | ||
| 1204 | RT_TOS(t->parms.iph.tos), | ||
| 1205 | t->parms.link); | ||
| 1206 | if (IS_ERR(rt)) | ||
| 1221 | return -EADDRNOTAVAIL; | 1207 | return -EADDRNOTAVAIL; |
| 1222 | dev = rt->dst.dev; | 1208 | dev = rt->dst.dev; |
| 1223 | ip_rt_put(rt); | 1209 | ip_rt_put(rt); |
| @@ -1765,4 +1751,4 @@ module_exit(ipgre_fini); | |||
| 1765 | MODULE_LICENSE("GPL"); | 1751 | MODULE_LICENSE("GPL"); |
| 1766 | MODULE_ALIAS_RTNL_LINK("gre"); | 1752 | MODULE_ALIAS_RTNL_LINK("gre"); |
| 1767 | MODULE_ALIAS_RTNL_LINK("gretap"); | 1753 | MODULE_ALIAS_RTNL_LINK("gretap"); |
| 1768 | MODULE_ALIAS("gre0"); | 1754 | MODULE_ALIAS_NETDEV("gre0"); |
