aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/net/ip6_tunnel.h3
-rw-r--r--net/ipv6/ip6_gre.c2
-rw-r--r--net/ipv6/ip6_tunnel.c23
-rw-r--r--net/ipv6/ip6_vti.c10
4 files changed, 26 insertions, 12 deletions
diff --git a/include/net/ip6_tunnel.h b/include/net/ip6_tunnel.h
index a5593dab6af7..9326c41c2d7f 100644
--- a/include/net/ip6_tunnel.h
+++ b/include/net/ip6_tunnel.h
@@ -65,7 +65,8 @@ void ip6_tnl_dst_reset(struct ip6_tnl *t);
65void ip6_tnl_dst_store(struct ip6_tnl *t, struct dst_entry *dst); 65void ip6_tnl_dst_store(struct ip6_tnl *t, struct dst_entry *dst);
66int ip6_tnl_rcv_ctl(struct ip6_tnl *t, const struct in6_addr *laddr, 66int ip6_tnl_rcv_ctl(struct ip6_tnl *t, const struct in6_addr *laddr,
67 const struct in6_addr *raddr); 67 const struct in6_addr *raddr);
68int ip6_tnl_xmit_ctl(struct ip6_tnl *t); 68int ip6_tnl_xmit_ctl(struct ip6_tnl *t, const struct in6_addr *laddr,
69 const struct in6_addr *raddr);
69__u16 ip6_tnl_parse_tlv_enc_lim(struct sk_buff *skb, __u8 *raw); 70__u16 ip6_tnl_parse_tlv_enc_lim(struct sk_buff *skb, __u8 *raw);
70__u32 ip6_tnl_get_cap(struct ip6_tnl *t, const struct in6_addr *laddr, 71__u32 ip6_tnl_get_cap(struct ip6_tnl *t, const struct in6_addr *laddr,
71 const struct in6_addr *raddr); 72 const struct in6_addr *raddr);
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_tunnel.c b/net/ipv6/ip6_tunnel.c
index 8c97cd1048c2..a8f94ff9c606 100644
--- a/net/ipv6/ip6_tunnel.c
+++ b/net/ipv6/ip6_tunnel.c
@@ -909,24 +909,28 @@ ip6_tnl_addr_conflict(const struct ip6_tnl *t, const struct ipv6hdr *hdr)
909 return ipv6_addr_equal(&t->parms.raddr, &hdr->saddr); 909 return ipv6_addr_equal(&t->parms.raddr, &hdr->saddr);
910} 910}
911 911
912int ip6_tnl_xmit_ctl(struct ip6_tnl *t) 912int ip6_tnl_xmit_ctl(struct ip6_tnl *t,
913 const struct in6_addr *laddr,
914 const struct in6_addr *raddr)
913{ 915{
914 struct __ip6_tnl_parm *p = &t->parms; 916 struct __ip6_tnl_parm *p = &t->parms;
915 int ret = 0; 917 int ret = 0;
916 struct net *net = t->net; 918 struct net *net = t->net;
917 919
918 if (p->flags & IP6_TNL_F_CAP_XMIT) { 920 if ((p->flags & IP6_TNL_F_CAP_XMIT) ||
921 ((p->flags & IP6_TNL_F_CAP_PER_PACKET) &&
922 (ip6_tnl_get_cap(t, laddr, raddr) & IP6_TNL_F_CAP_XMIT))) {
919 struct net_device *ldev = NULL; 923 struct net_device *ldev = NULL;
920 924
921 rcu_read_lock(); 925 rcu_read_lock();
922 if (p->link) 926 if (p->link)
923 ldev = dev_get_by_index_rcu(net, p->link); 927 ldev = dev_get_by_index_rcu(net, p->link);
924 928
925 if (unlikely(!ipv6_chk_addr(net, &p->laddr, ldev, 0))) 929 if (unlikely(!ipv6_chk_addr(net, laddr, ldev, 0)))
926 pr_warn("%s xmit: Local address not yet configured!\n", 930 pr_warn("%s xmit: Local address not yet configured!\n",
927 p->name); 931 p->name);
928 else if (!ipv6_addr_is_multicast(&p->raddr) && 932 else if (!ipv6_addr_is_multicast(raddr) &&
929 unlikely(ipv6_chk_addr(net, &p->raddr, NULL, 0))) 933 unlikely(ipv6_chk_addr(net, raddr, NULL, 0)))
930 pr_warn("%s xmit: Routing loop! Remote address found on this node!\n", 934 pr_warn("%s xmit: Routing loop! Remote address found on this node!\n",
931 p->name); 935 p->name);
932 else 936 else
@@ -977,6 +981,10 @@ static int ip6_tnl_xmit2(struct sk_buff *skb,
977 981
978 if (!fl6->flowi6_mark) 982 if (!fl6->flowi6_mark)
979 dst = ip6_tnl_dst_check(t); 983 dst = ip6_tnl_dst_check(t);
984
985 if (!ip6_tnl_xmit_ctl(t, &fl6->saddr, &fl6->daddr))
986 goto tx_err_link_failure;
987
980 if (!dst) { 988 if (!dst) {
981 ndst = ip6_route_output(net, NULL, fl6); 989 ndst = ip6_route_output(net, NULL, fl6);
982 990
@@ -1086,8 +1094,7 @@ ip4ip6_tnl_xmit(struct sk_buff *skb, struct net_device *dev)
1086 int err; 1094 int err;
1087 1095
1088 tproto = ACCESS_ONCE(t->parms.proto); 1096 tproto = ACCESS_ONCE(t->parms.proto);
1089 if ((tproto != IPPROTO_IPIP && tproto != 0) || 1097 if (tproto != IPPROTO_IPIP && tproto != 0)
1090 !ip6_tnl_xmit_ctl(t))
1091 return -1; 1098 return -1;
1092 1099
1093 if (!(t->parms.flags & IP6_TNL_F_IGN_ENCAP_LIMIT)) 1100 if (!(t->parms.flags & IP6_TNL_F_IGN_ENCAP_LIMIT))
@@ -1131,7 +1138,7 @@ ip6ip6_tnl_xmit(struct sk_buff *skb, struct net_device *dev)
1131 1138
1132 tproto = ACCESS_ONCE(t->parms.proto); 1139 tproto = ACCESS_ONCE(t->parms.proto);
1133 if ((tproto != IPPROTO_IPV6 && tproto != 0) || 1140 if ((tproto != IPPROTO_IPV6 && tproto != 0) ||
1134 !ip6_tnl_xmit_ctl(t) || ip6_tnl_addr_conflict(t, ipv6h)) 1141 ip6_tnl_addr_conflict(t, ipv6h))
1135 return -1; 1142 return -1;
1136 1143
1137 offset = ip6_tnl_parse_tlv_enc_lim(skb, skb_network_header(skb)); 1144 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);