mac80211: allow using AP_LINK_PS with mac80211-generated TIM IE
[cascardo/linux.git] / net / ipv4 / ip_output.c
index 4bd4921..05d1058 100644 (file)
@@ -73,6 +73,7 @@
 #include <net/icmp.h>
 #include <net/checksum.h>
 #include <net/inetpeer.h>
+#include <net/lwtunnel.h>
 #include <linux/igmp.h>
 #include <linux/netfilter_ipv4.h>
 #include <linux/netfilter_bridge.h>
@@ -98,6 +99,14 @@ int __ip_local_out(struct net *net, struct sock *sk, struct sk_buff *skb)
 
        iph->tot_len = htons(skb->len);
        ip_send_check(iph);
+
+       /* if egress device is enslaved to an L3 master device pass the
+        * skb to its handler for processing
+        */
+       skb = l3mdev_ip_out(sk, skb);
+       if (unlikely(!skb))
+               return 0;
+
        return nf_hook(NFPROTO_IPV4, NF_INET_LOCAL_OUT,
                       net, sk, skb, NULL, skb_dst(skb)->dev,
                       dst_output);
@@ -197,6 +206,13 @@ static int ip_finish_output2(struct net *net, struct sock *sk, struct sk_buff *s
                skb = skb2;
        }
 
+       if (lwtunnel_xmit_redirect(dst->lwtstate)) {
+               int res = lwtunnel_xmit(skb);
+
+               if (res < 0 || res == LWTUNNEL_XMIT_DONE)
+                       return res;
+       }
+
        rcu_read_lock_bh();
        nexthop = (__force u32) rt_nexthop(rt, ip_hdr(skb)->daddr);
        neigh = __ipv4_neigh_lookup_noref(dev, nexthop);
@@ -223,9 +239,11 @@ static int ip_finish_output_gso(struct net *net, struct sock *sk,
        struct sk_buff *segs;
        int ret = 0;
 
-       /* common case: locally created skb or seglen is <= mtu */
-       if (((IPCB(skb)->flags & IPSKB_FORWARDED) == 0) ||
-             skb_gso_network_seglen(skb) <= mtu)
+       /* common case: fragmentation of segments is not allowed,
+        * or seglen is <= mtu
+        */
+       if (((IPCB(skb)->flags & IPSKB_FRAG_SEGS) == 0) ||
+             skb_gso_validate_mtu(skb, mtu))
                return ip_finish_output2(net, sk, skb);
 
        /* Slowpath -  GSO segment length is exceeding the dst MTU.
@@ -480,7 +498,7 @@ static void ip_copy_metadata(struct sk_buff *to, struct sk_buff *from)
        to->tc_index = from->tc_index;
 #endif
        nf_copy(to, from);
-#if defined(CONFIG_IP_VS) || defined(CONFIG_IP_VS_MODULE)
+#if IS_ENABLED(CONFIG_IP_VS)
        to->ipvs_property = from->ipvs_property;
 #endif
        skb_copy_secmark(to, from);
@@ -1564,8 +1582,7 @@ void ip_send_unicast_reply(struct sock *sk, struct sk_buff *skb,
        }
 
        oif = arg->bound_dev_if;
-       if (!oif && netif_index_is_l3_master(net, skb->skb_iif))
-               oif = skb->skb_iif;
+       oif = oif ? : skb->skb_iif;
 
        flowi4_init_output(&fl4, oif,
                           IP4_REPLY_MARK(net, skb->mark),