void ip6_tnl_dst_store(struct ip6_tnl *t, struct dst_entry *dst);
 int ip6_tnl_rcv_ctl(struct ip6_tnl *t, const struct in6_addr *laddr,
                const struct in6_addr *raddr);
-int ip6_tnl_xmit_ctl(struct ip6_tnl *t);
+int ip6_tnl_xmit_ctl(struct ip6_tnl *t, const struct in6_addr *laddr,
+                    const struct in6_addr *raddr);
 __u16 ip6_tnl_parse_tlv_enc_lim(struct sk_buff *skb, __u8 *raw);
 __u32 ip6_tnl_get_cap(struct ip6_tnl *t, const struct in6_addr *laddr,
                             const struct in6_addr *raddr);
 
        return ipv6_addr_equal(&t->parms.raddr, &hdr->saddr);
 }
 
-int ip6_tnl_xmit_ctl(struct ip6_tnl *t)
+int ip6_tnl_xmit_ctl(struct ip6_tnl *t,
+                    const struct in6_addr *laddr,
+                    const struct in6_addr *raddr)
 {
        struct __ip6_tnl_parm *p = &t->parms;
        int ret = 0;
        struct net *net = t->net;
 
-       if (p->flags & IP6_TNL_F_CAP_XMIT) {
+       if ((p->flags & IP6_TNL_F_CAP_XMIT) ||
+           ((p->flags & IP6_TNL_F_CAP_PER_PACKET) &&
+            (ip6_tnl_get_cap(t, laddr, raddr) & IP6_TNL_F_CAP_XMIT))) {
                struct net_device *ldev = NULL;
 
                rcu_read_lock();
                if (p->link)
                        ldev = dev_get_by_index_rcu(net, p->link);
 
-               if (unlikely(!ipv6_chk_addr(net, &p->laddr, ldev, 0)))
+               if (unlikely(!ipv6_chk_addr(net, laddr, ldev, 0)))
                        pr_warn("%s xmit: Local address not yet configured!\n",
                                p->name);
-               else if (!ipv6_addr_is_multicast(&p->raddr) &&
-                        unlikely(ipv6_chk_addr(net, &p->raddr, NULL, 0)))
+               else if (!ipv6_addr_is_multicast(raddr) &&
+                        unlikely(ipv6_chk_addr(net, raddr, NULL, 0)))
                        pr_warn("%s xmit: Routing loop! Remote address found on this node!\n",
                                p->name);
                else
 
        if (!fl6->flowi6_mark)
                dst = ip6_tnl_dst_check(t);
+
+       if (!ip6_tnl_xmit_ctl(t, &fl6->saddr, &fl6->daddr))
+               goto tx_err_link_failure;
+
        if (!dst) {
                ndst = ip6_route_output(net, NULL, fl6);
 
        int err;
 
        tproto = ACCESS_ONCE(t->parms.proto);
-       if ((tproto != IPPROTO_IPIP && tproto != 0) ||
-           !ip6_tnl_xmit_ctl(t))
+       if (tproto != IPPROTO_IPIP && tproto != 0)
                return -1;
 
        if (!(t->parms.flags & IP6_TNL_F_IGN_ENCAP_LIMIT))
 
        tproto = ACCESS_ONCE(t->parms.proto);
        if ((tproto != IPPROTO_IPV6 && tproto != 0) ||
-           !ip6_tnl_xmit_ctl(t) || ip6_tnl_addr_conflict(t, ipv6h))
+           ip6_tnl_addr_conflict(t, ipv6h))
                return -1;
 
        offset = ip6_tnl_parse_tlv_enc_lim(skb, skb_network_header(skb));
 
        struct net_device_stats *stats = &t->dev->stats;
        struct dst_entry *dst = skb_dst(skb);
        struct net_device *tdev;
+       struct xfrm_state *x;
        int err = -1;
 
        if (!dst)
                goto tx_err_link_failure;
        }
 
-       if (!vti6_state_check(dst->xfrm, &t->parms.raddr, &t->parms.laddr))
+       x = dst->xfrm;
+       if (!vti6_state_check(x, &t->parms.raddr, &t->parms.laddr))
+               goto tx_err_link_failure;
+
+       if (!ip6_tnl_xmit_ctl(t, (const struct in6_addr *)&x->props.saddr,
+                             (const struct in6_addr *)&x->id.daddr))
                goto tx_err_link_failure;
 
        tdev = dst->dev;
                ipv6h = ipv6_hdr(skb);
 
                if ((t->parms.proto != IPPROTO_IPV6 && t->parms.proto != 0) ||
-                   !ip6_tnl_xmit_ctl(t) || vti6_addr_conflict(t, ipv6h))
+                   vti6_addr_conflict(t, ipv6h))
                        goto tx_err;
 
                xfrm_decode_session(skb, &fl, AF_INET6);