diff options
Diffstat (limited to 'net/ipv6')
-rw-r--r-- | net/ipv6/esp6.c | 10 | ||||
-rw-r--r-- | net/ipv6/ip6_gre.c | 2 | ||||
-rw-r--r-- | net/ipv6/ip6_output.c | 10 | ||||
-rw-r--r-- | net/ipv6/ip6_tunnel.c | 64 | ||||
-rw-r--r-- | net/ipv6/ip6_vti.c | 10 |
5 files changed, 73 insertions, 23 deletions
diff --git a/net/ipv6/esp6.c b/net/ipv6/esp6.c index 83fc3a385a26..d21d7b22eebc 100644 --- a/net/ipv6/esp6.c +++ b/net/ipv6/esp6.c | |||
@@ -544,12 +544,12 @@ static int esp_init_authenc(struct xfrm_state *x) | |||
544 | BUG_ON(!aalg_desc); | 544 | BUG_ON(!aalg_desc); |
545 | 545 | ||
546 | err = -EINVAL; | 546 | err = -EINVAL; |
547 | if (aalg_desc->uinfo.auth.icv_fullbits/8 != | 547 | if (aalg_desc->uinfo.auth.icv_fullbits / 8 != |
548 | crypto_aead_authsize(aead)) { | 548 | crypto_aead_authsize(aead)) { |
549 | NETDEBUG(KERN_INFO "ESP: %s digestsize %u != %hu\n", | 549 | pr_info("ESP: %s digestsize %u != %hu\n", |
550 | x->aalg->alg_name, | 550 | x->aalg->alg_name, |
551 | crypto_aead_authsize(aead), | 551 | crypto_aead_authsize(aead), |
552 | aalg_desc->uinfo.auth.icv_fullbits/8); | 552 | aalg_desc->uinfo.auth.icv_fullbits / 8); |
553 | goto free_key; | 553 | goto free_key; |
554 | } | 554 | } |
555 | 555 | ||
diff --git a/net/ipv6/ip6_gre.c b/net/ipv6/ip6_gre.c index 12c3c8ef3849..1fcf62ea5eb4 100644 --- a/net/ipv6/ip6_gre.c +++ b/net/ipv6/ip6_gre.c | |||
@@ -902,7 +902,7 @@ static netdev_tx_t ip6gre_tunnel_xmit(struct sk_buff *skb, | |||
902 | struct net_device_stats *stats = &t->dev->stats; | 902 | struct net_device_stats *stats = &t->dev->stats; |
903 | int ret; | 903 | int ret; |
904 | 904 | ||
905 | if (!ip6_tnl_xmit_ctl(t)) | 905 | if (!ip6_tnl_xmit_ctl(t, &t->parms.laddr, &t->parms.raddr)) |
906 | goto tx_err; | 906 | goto tx_err; |
907 | 907 | ||
908 | switch (skb->protocol) { | 908 | switch (skb->protocol) { |
diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c index 8e950c250ada..916d2a166a9b 100644 --- a/net/ipv6/ip6_output.c +++ b/net/ipv6/ip6_output.c | |||
@@ -747,13 +747,11 @@ slow_path: | |||
747 | if (len < left) { | 747 | if (len < left) { |
748 | len &= ~7; | 748 | len &= ~7; |
749 | } | 749 | } |
750 | /* | ||
751 | * Allocate buffer. | ||
752 | */ | ||
753 | 750 | ||
754 | if ((frag = alloc_skb(len + hlen + sizeof(struct frag_hdr) + | 751 | /* Allocate buffer */ |
755 | hroom + troom, GFP_ATOMIC)) == NULL) { | 752 | frag = alloc_skb(len + hlen + sizeof(struct frag_hdr) + |
756 | NETDEBUG(KERN_INFO "IPv6: frag: no memory for new fragment!\n"); | 753 | hroom + troom, GFP_ATOMIC); |
754 | if (!frag) { | ||
757 | IP6_INC_STATS(net, ip6_dst_idev(skb_dst(skb)), | 755 | IP6_INC_STATS(net, ip6_dst_idev(skb_dst(skb)), |
758 | IPSTATS_MIB_FRAGFAILS); | 756 | IPSTATS_MIB_FRAGFAILS); |
759 | err = -ENOMEM; | 757 | err = -ENOMEM; |
diff --git a/net/ipv6/ip6_tunnel.c b/net/ipv6/ip6_tunnel.c index 8c97cd1048c2..4550d08f44de 100644 --- a/net/ipv6/ip6_tunnel.c +++ b/net/ipv6/ip6_tunnel.c | |||
@@ -183,6 +183,7 @@ ip6_tnl_lookup(struct net *net, const struct in6_addr *remote, const struct in6_ | |||
183 | unsigned int hash = HASH(remote, local); | 183 | unsigned int hash = HASH(remote, local); |
184 | struct ip6_tnl *t; | 184 | struct ip6_tnl *t; |
185 | struct ip6_tnl_net *ip6n = net_generic(net, ip6_tnl_net_id); | 185 | struct ip6_tnl_net *ip6n = net_generic(net, ip6_tnl_net_id); |
186 | struct in6_addr any; | ||
186 | 187 | ||
187 | for_each_ip6_tunnel_rcu(ip6n->tnls_r_l[hash]) { | 188 | for_each_ip6_tunnel_rcu(ip6n->tnls_r_l[hash]) { |
188 | if (ipv6_addr_equal(local, &t->parms.laddr) && | 189 | if (ipv6_addr_equal(local, &t->parms.laddr) && |
@@ -190,6 +191,22 @@ ip6_tnl_lookup(struct net *net, const struct in6_addr *remote, const struct in6_ | |||
190 | (t->dev->flags & IFF_UP)) | 191 | (t->dev->flags & IFF_UP)) |
191 | return t; | 192 | return t; |
192 | } | 193 | } |
194 | |||
195 | memset(&any, 0, sizeof(any)); | ||
196 | hash = HASH(&any, local); | ||
197 | for_each_ip6_tunnel_rcu(ip6n->tnls_r_l[hash]) { | ||
198 | if (ipv6_addr_equal(local, &t->parms.laddr) && | ||
199 | (t->dev->flags & IFF_UP)) | ||
200 | return t; | ||
201 | } | ||
202 | |||
203 | hash = HASH(remote, &any); | ||
204 | for_each_ip6_tunnel_rcu(ip6n->tnls_r_l[hash]) { | ||
205 | if (ipv6_addr_equal(remote, &t->parms.raddr) && | ||
206 | (t->dev->flags & IFF_UP)) | ||
207 | return t; | ||
208 | } | ||
209 | |||
193 | t = rcu_dereference(ip6n->tnls_wc[0]); | 210 | t = rcu_dereference(ip6n->tnls_wc[0]); |
194 | if (t && (t->dev->flags & IFF_UP)) | 211 | if (t && (t->dev->flags & IFF_UP)) |
195 | return t; | 212 | return t; |
@@ -909,24 +926,28 @@ ip6_tnl_addr_conflict(const struct ip6_tnl *t, const struct ipv6hdr *hdr) | |||
909 | return ipv6_addr_equal(&t->parms.raddr, &hdr->saddr); | 926 | return ipv6_addr_equal(&t->parms.raddr, &hdr->saddr); |
910 | } | 927 | } |
911 | 928 | ||
912 | int ip6_tnl_xmit_ctl(struct ip6_tnl *t) | 929 | int ip6_tnl_xmit_ctl(struct ip6_tnl *t, |
930 | const struct in6_addr *laddr, | ||
931 | const struct in6_addr *raddr) | ||
913 | { | 932 | { |
914 | struct __ip6_tnl_parm *p = &t->parms; | 933 | struct __ip6_tnl_parm *p = &t->parms; |
915 | int ret = 0; | 934 | int ret = 0; |
916 | struct net *net = t->net; | 935 | struct net *net = t->net; |
917 | 936 | ||
918 | if (p->flags & IP6_TNL_F_CAP_XMIT) { | 937 | if ((p->flags & IP6_TNL_F_CAP_XMIT) || |
938 | ((p->flags & IP6_TNL_F_CAP_PER_PACKET) && | ||
939 | (ip6_tnl_get_cap(t, laddr, raddr) & IP6_TNL_F_CAP_XMIT))) { | ||
919 | struct net_device *ldev = NULL; | 940 | struct net_device *ldev = NULL; |
920 | 941 | ||
921 | rcu_read_lock(); | 942 | rcu_read_lock(); |
922 | if (p->link) | 943 | if (p->link) |
923 | ldev = dev_get_by_index_rcu(net, p->link); | 944 | ldev = dev_get_by_index_rcu(net, p->link); |
924 | 945 | ||
925 | if (unlikely(!ipv6_chk_addr(net, &p->laddr, ldev, 0))) | 946 | if (unlikely(!ipv6_chk_addr(net, laddr, ldev, 0))) |
926 | pr_warn("%s xmit: Local address not yet configured!\n", | 947 | pr_warn("%s xmit: Local address not yet configured!\n", |
927 | p->name); | 948 | p->name); |
928 | else if (!ipv6_addr_is_multicast(&p->raddr) && | 949 | else if (!ipv6_addr_is_multicast(raddr) && |
929 | unlikely(ipv6_chk_addr(net, &p->raddr, NULL, 0))) | 950 | unlikely(ipv6_chk_addr(net, raddr, NULL, 0))) |
930 | pr_warn("%s xmit: Routing loop! Remote address found on this node!\n", | 951 | pr_warn("%s xmit: Routing loop! Remote address found on this node!\n", |
931 | p->name); | 952 | p->name); |
932 | else | 953 | else |
@@ -975,8 +996,34 @@ static int ip6_tnl_xmit2(struct sk_buff *skb, | |||
975 | u8 proto; | 996 | u8 proto; |
976 | int err = -1; | 997 | int err = -1; |
977 | 998 | ||
978 | if (!fl6->flowi6_mark) | 999 | /* NBMA tunnel */ |
1000 | if (ipv6_addr_any(&t->parms.raddr)) { | ||
1001 | struct in6_addr *addr6; | ||
1002 | struct neighbour *neigh; | ||
1003 | int addr_type; | ||
1004 | |||
1005 | if (!skb_dst(skb)) | ||
1006 | goto tx_err_link_failure; | ||
1007 | |||
1008 | neigh = dst_neigh_lookup(skb_dst(skb), | ||
1009 | &ipv6_hdr(skb)->daddr); | ||
1010 | if (!neigh) | ||
1011 | goto tx_err_link_failure; | ||
1012 | |||
1013 | addr6 = (struct in6_addr *)&neigh->primary_key; | ||
1014 | addr_type = ipv6_addr_type(addr6); | ||
1015 | |||
1016 | if (addr_type == IPV6_ADDR_ANY) | ||
1017 | addr6 = &ipv6_hdr(skb)->daddr; | ||
1018 | |||
1019 | memcpy(&fl6->daddr, addr6, sizeof(fl6->daddr)); | ||
1020 | neigh_release(neigh); | ||
1021 | } else if (!fl6->flowi6_mark) | ||
979 | dst = ip6_tnl_dst_check(t); | 1022 | dst = ip6_tnl_dst_check(t); |
1023 | |||
1024 | if (!ip6_tnl_xmit_ctl(t, &fl6->saddr, &fl6->daddr)) | ||
1025 | goto tx_err_link_failure; | ||
1026 | |||
980 | if (!dst) { | 1027 | if (!dst) { |
981 | ndst = ip6_route_output(net, NULL, fl6); | 1028 | ndst = ip6_route_output(net, NULL, fl6); |
982 | 1029 | ||
@@ -1086,8 +1133,7 @@ ip4ip6_tnl_xmit(struct sk_buff *skb, struct net_device *dev) | |||
1086 | int err; | 1133 | int err; |
1087 | 1134 | ||
1088 | tproto = ACCESS_ONCE(t->parms.proto); | 1135 | tproto = ACCESS_ONCE(t->parms.proto); |
1089 | if ((tproto != IPPROTO_IPIP && tproto != 0) || | 1136 | if (tproto != IPPROTO_IPIP && tproto != 0) |
1090 | !ip6_tnl_xmit_ctl(t)) | ||
1091 | return -1; | 1137 | return -1; |
1092 | 1138 | ||
1093 | if (!(t->parms.flags & IP6_TNL_F_IGN_ENCAP_LIMIT)) | 1139 | if (!(t->parms.flags & IP6_TNL_F_IGN_ENCAP_LIMIT)) |
@@ -1131,7 +1177,7 @@ ip6ip6_tnl_xmit(struct sk_buff *skb, struct net_device *dev) | |||
1131 | 1177 | ||
1132 | tproto = ACCESS_ONCE(t->parms.proto); | 1178 | tproto = ACCESS_ONCE(t->parms.proto); |
1133 | if ((tproto != IPPROTO_IPV6 && tproto != 0) || | 1179 | if ((tproto != IPPROTO_IPV6 && tproto != 0) || |
1134 | !ip6_tnl_xmit_ctl(t) || ip6_tnl_addr_conflict(t, ipv6h)) | 1180 | ip6_tnl_addr_conflict(t, ipv6h)) |
1135 | return -1; | 1181 | return -1; |
1136 | 1182 | ||
1137 | offset = ip6_tnl_parse_tlv_enc_lim(skb, skb_network_header(skb)); | 1183 | offset = ip6_tnl_parse_tlv_enc_lim(skb, skb_network_header(skb)); |
diff --git a/net/ipv6/ip6_vti.c b/net/ipv6/ip6_vti.c index d440bb585524..0e8e97e0d38b 100644 --- a/net/ipv6/ip6_vti.c +++ b/net/ipv6/ip6_vti.c | |||
@@ -416,6 +416,7 @@ vti6_xmit(struct sk_buff *skb, struct net_device *dev, struct flowi *fl) | |||
416 | struct net_device_stats *stats = &t->dev->stats; | 416 | struct net_device_stats *stats = &t->dev->stats; |
417 | struct dst_entry *dst = skb_dst(skb); | 417 | struct dst_entry *dst = skb_dst(skb); |
418 | struct net_device *tdev; | 418 | struct net_device *tdev; |
419 | struct xfrm_state *x; | ||
419 | int err = -1; | 420 | int err = -1; |
420 | 421 | ||
421 | if (!dst) | 422 | if (!dst) |
@@ -429,7 +430,12 @@ vti6_xmit(struct sk_buff *skb, struct net_device *dev, struct flowi *fl) | |||
429 | goto tx_err_link_failure; | 430 | goto tx_err_link_failure; |
430 | } | 431 | } |
431 | 432 | ||
432 | if (!vti6_state_check(dst->xfrm, &t->parms.raddr, &t->parms.laddr)) | 433 | x = dst->xfrm; |
434 | if (!vti6_state_check(x, &t->parms.raddr, &t->parms.laddr)) | ||
435 | goto tx_err_link_failure; | ||
436 | |||
437 | if (!ip6_tnl_xmit_ctl(t, (const struct in6_addr *)&x->props.saddr, | ||
438 | (const struct in6_addr *)&x->id.daddr)) | ||
433 | goto tx_err_link_failure; | 439 | goto tx_err_link_failure; |
434 | 440 | ||
435 | tdev = dst->dev; | 441 | tdev = dst->dev; |
@@ -484,7 +490,7 @@ vti6_tnl_xmit(struct sk_buff *skb, struct net_device *dev) | |||
484 | ipv6h = ipv6_hdr(skb); | 490 | ipv6h = ipv6_hdr(skb); |
485 | 491 | ||
486 | if ((t->parms.proto != IPPROTO_IPV6 && t->parms.proto != 0) || | 492 | if ((t->parms.proto != IPPROTO_IPV6 && t->parms.proto != 0) || |
487 | !ip6_tnl_xmit_ctl(t) || vti6_addr_conflict(t, ipv6h)) | 493 | vti6_addr_conflict(t, ipv6h)) |
488 | goto tx_err; | 494 | goto tx_err; |
489 | 495 | ||
490 | xfrm_decode_session(skb, &fl, AF_INET6); | 496 | xfrm_decode_session(skb, &fl, AF_INET6); |