* [PATCH 3/3] net: ethoc: document OF bindings
From: Max Filippov @ 2014-01-27 3:59 UTC (permalink / raw)
To: linux-xtensa, netdev, devicetree, linux-kernel
Cc: Chris Zankel, Marc Gauthier, David S. Miller, Grant Likely,
Rob Herring, Max Filippov
In-Reply-To: <1390795167-6677-1-git-send-email-jcmvbkbc@gmail.com>
Signed-off-by: Max Filippov <jcmvbkbc@gmail.com>
---
.../devicetree/bindings/net/opencores-ethoc.txt | 25 ++++++++++++++++++++++
1 file changed, 25 insertions(+)
create mode 100644 Documentation/devicetree/bindings/net/opencores-ethoc.txt
diff --git a/Documentation/devicetree/bindings/net/opencores-ethoc.txt b/Documentation/devicetree/bindings/net/opencores-ethoc.txt
new file mode 100644
index 0000000..f7c6c94
--- /dev/null
+++ b/Documentation/devicetree/bindings/net/opencores-ethoc.txt
@@ -0,0 +1,25 @@
+* OpenCores MAC 10/100 Mbps
+
+Required properties:
+- compatible: Should be "opencores,ethoc".
+- reg: Address and length of the register set for the device and of its
+ descriptor memory.
+- interrupts: Should contain ethoc interrupt.
+
+Optional properties:
+- local-mac-address: 6 bytes, mac address
+- clock-frequency: basic MAC frequency.
+- mii-mgmt-clock-frequency: frequency of MII management bus. Together
+ with clock-frequency determines the value programmed into the CLKDIV
+ field of MIIMODER register.
+
+Examples:
+
+ enet0: ethoc@fd030000 {
+ compatible = "opencores,ethoc";
+ reg = <0xfd030000 0x4000 0xfd800000 0x4000>;
+ interrupts = <1>;
+ local-mac-address = [00 50 c2 13 6f 00];
+ clock-frequency = <50000000>;
+ mii-mgmt-clock-frequency = <5000000>;
+ };
--
1.8.1.4
^ permalink raw reply related
* Re: [PATCH V2 1/2] net: add and use skb_gso_transport_seglen()
From: David Miller @ 2014-01-27 6:41 UTC (permalink / raw)
To: fw; +Cc: netdev, eric.dumazet
In-Reply-To: <1390730297-10725-1-git-send-email-fw@strlen.de>
From: Florian Westphal <fw@strlen.de>
Date: Sun, 26 Jan 2014 10:58:16 +0100
> This moves part of Eric Dumazets skb_gso_seglen helper from tbf sched to
> skbuff core so it may be reused by upcoming ip forwarding path patch.
>
> Signed-off-by: Florian Westphal <fw@strlen.de>
Applied.
^ permalink raw reply
* Re: [PATCH V2 2/2] net: ip, ipv6: handle gso skbs in forwarding path
From: David Miller @ 2014-01-27 6:42 UTC (permalink / raw)
To: fw; +Cc: netdev, eric.dumazet
In-Reply-To: <1390730297-10725-2-git-send-email-fw@strlen.de>
From: Florian Westphal <fw@strlen.de>
Date: Sun, 26 Jan 2014 10:58:17 +0100
> +static bool ip_exceeds_mtu(const struct sk_buff *skb, unsigned int mtu)
> +{
> + unsigned len;
> +
> + if (skb->len <= mtu || skb->local_df)
> + return false;
> +
> + if (skb_is_gso(skb) && skb_gso_network_seglen(skb) <= mtu)
> + return false;
> +
> + return true;
> +}
Unused local variable 'len'. Please scan the compiler output for at
least the *.c files you touch, it warns about this case. Also, you
should always explicitly use "unsigned int" as the type instead of
just plain "unsigned".
> @@ -88,8 +147,7 @@ int ip_forward(struct sk_buff *skb)
> if (opt->is_strictroute && rt->rt_uses_gateway)
> goto sr_failed;
>
> - if (unlikely(skb->len > dst_mtu(&rt->dst) && !skb_is_gso(skb) &&
> - (ip_hdr(skb)->frag_off & htons(IP_DF))) && !skb->local_df) {
> + if (!ip_may_fragment(skb) && ip_exceeds_mtu(skb, dst_mtu(&rt->dst))) {
> IP_INC_STATS(dev_net(rt->dst.dev), IPSTATS_MIB_FRAGFAILS);
> icmp_send(skb, ICMP_DEST_UNREACH, ICMP_FRAG_NEEDED,
> htonl(dst_mtu(&rt->dst)));
This hunk rejects, the test here looks a lot different in the current
tree.
^ permalink raw reply
* Re: [PATCH] net/apne: Remove unused variable ei_local
From: David Miller @ 2014-01-27 6:42 UTC (permalink / raw)
To: geert; +Cc: tedheadster, netdev, linux-kernel
In-Reply-To: <1390733063-9077-1-git-send-email-geert@linux-m68k.org>
From: Geert Uytterhoeven <geert@linux-m68k.org>
Date: Sun, 26 Jan 2014 11:44:23 +0100
> drivers/net/ethernet/8390/apne.c: In function ‘apne_probe1’:
> drivers/net/ethernet/8390/apne.c:215: warning: unused variable ‘ei_local’
>
> Introduced by commit c45f812f0280c13f1b7992be5e0de512312a9e8f ("8390 :
> Replace ei_debug with msg_enable/NETIF_MSG_* feature"), which added the
> variable without using it.
>
> Signed-off-by: Geert Uytterhoeven <geert@linux-m68k.org>
Applied.
^ permalink raw reply
* Re: [PATCH 1/2] net: stmmac: Silence PTP init errors on hw without PTP
From: David Miller @ 2014-01-27 6:42 UTC (permalink / raw)
To: hdegoede; +Cc: peppe.cavallaro, netdev
In-Reply-To: <1390747844-25060-1-git-send-email-hdegoede@redhat.com>
From: Hans de Goede <hdegoede@redhat.com>
Date: Sun, 26 Jan 2014 15:50:43 +0100
> Logging a PTP error on hw which simply does not support PTP is not very
> useful. Moreover this message gets logged on every if-up, and if there is
> no cable inserted NetworkManager will re-try the ifup every 50 seconds.
>
> Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Applied.
^ permalink raw reply
* Re: [PATCH 2/2] net: stmmac: Log MAC address only once
From: David Miller @ 2014-01-27 6:43 UTC (permalink / raw)
To: hdegoede; +Cc: peppe.cavallaro, netdev
In-Reply-To: <1390747844-25060-2-git-send-email-hdegoede@redhat.com>
From: Hans de Goede <hdegoede@redhat.com>
Date: Sun, 26 Jan 2014 15:50:44 +0100
> Logging the MAC address on every if-up, is not really useful, and annoying when
> there is no cable inserted and NetworkManager tries the ifup every 50 seconds.
>
> Also change the log level from warning to info, as that is what it is.
>
> Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Applied.
^ permalink raw reply
* [PATCH 1/1] net: ipv4: Use PTR_ERR_OR_ZERO
From: Sachin Kamat @ 2014-01-27 6:43 UTC (permalink / raw)
To: netdev; +Cc: davem, sachin.kamat, patches
PTR_RET is deprecated. Use PTR_ERR_OR_ZERO instead. While at it
also include missing err.h header.
Signed-off-by: Sachin Kamat <sachin.kamat@linaro.org>
---
net/ipv4/ip_tunnel.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/net/ipv4/ip_tunnel.c b/net/ipv4/ip_tunnel.c
index c0e3cb72ad70..bd28f386bd02 100644
--- a/net/ipv4/ip_tunnel.c
+++ b/net/ipv4/ip_tunnel.c
@@ -40,6 +40,7 @@
#include <linux/if_ether.h>
#include <linux/if_vlan.h>
#include <linux/rculist.h>
+#include <linux/err.h>
#include <net/sock.h>
#include <net/ip.h>
@@ -930,7 +931,7 @@ int ip_tunnel_init_net(struct net *net, int ip_tnl_net_id,
}
rtnl_unlock();
- return PTR_RET(itn->fb_tunnel_dev);
+ return PTR_ERR_OR_ZERO(itn->fb_tunnel_dev);
}
EXPORT_SYMBOL_GPL(ip_tunnel_init_net);
--
1.7.9.5
^ permalink raw reply related
* Re: [patch 1/3] qeth: bridgeport support - basic control
From: Frank Blaschka @ 2014-01-27 6:49 UTC (permalink / raw)
To: Paul Gortmaker; +Cc: davem, netdev, linux-s390
In-Reply-To: <CAP=VYLp385bCpGiyDma82sO2zJkzArqUrHXYf0Bft6-WNj92Lg@mail.gmail.com>
On Fri, Jan 24, 2014 at 04:23:01PM -0500, Paul Gortmaker wrote:
> On Tue, Jan 14, 2014 at 9:54 AM, <frank.blaschka@de.ibm.com> wrote:
> > From: Eugene Crosser <Eugene.Crosser@ru.ibm.com>
> >
> > Introduce functions to assign roles and check state of bridgeport-capable
> > HiperSocket devices, and sysfs attributes providing access to these
> > functions from userspace. Introduce udev events emitted when the state
> > of a bridgeport device changes.
> >
> > Signed-off-by: Eugene Crosser <eugene.crosser@ru.ibm.com>
> > Signed-off-by: Frank Blaschka <frank.blaschka@de.ibm.com>
> > Reviewed-by: Ursula Braun <ursula.braun@de.ibm.com>
>
> Hi Eugene,
>
> This commit breaks the linux-next builds of s390 allmodconfig:
>
> Bisecting: 0 revisions left to test after this (roughly 0 steps)
> [b4d72c08b358fc5b259fad0f4971112d949efd1c] qeth: bridgeport support -
> basic control
> running ./x
> scripts/kconfig/conf --allmodconfig Kconfig
> #
> # configuration written to .config
> #
> ERROR: "qeth_wq" [drivers/s390/net/qeth_l2.ko] undefined!
> make[1]: *** [__modpost] Error 1
> make: *** [modules] Error 2
> b4d72c08b358fc5b259fad0f4971112d949efd1c is the first bad commit
> commit b4d72c08b358fc5b259fad0f4971112d949efd1c
> Author: Eugene Crosser <Eugene.Crosser@ru.ibm.com>
> Date: Tue Jan 14 15:54:11 2014 +0100
>
> qeth: bridgeport support - basic control
>
> Introduce functions to assign roles and check state of bridgeport-capable
> HiperSocket devices, and sysfs attributes providing access to these
> functions from userspace. Introduce udev events emitted when the state
> of a bridgeport device changes.
>
> Signed-off-by: Eugene Crosser <eugene.crosser@ru.ibm.com>
> Signed-off-by: Frank Blaschka <frank.blaschka@de.ibm.com>
> Reviewed-by: Ursula Braun <ursula.braun@de.ibm.com>
> Signed-off-by: David S. Miller <davem@davemloft.net>
>
> :040000 040000 1eb4205806a03dbc3de37af46e9447168b0d0e2a
> 0ba638a94d92c41d732bedc54c8108775f689cf3 M Documentation
> :040000 040000 9a9eb7da725785bfe40c77cdee4c181c90f74ef3
> f7e69854a168599f2f191675b449783292b0a4a1 M drivers
> bisect run success
>
> http://kisskb.ellerman.id.au/kisskb/buildresult/10509367/
>
> Paul.
> --
>
Paul, thx for this information. We are working on a fix. Hope I can sent it out
later this day.
> > ---
> > Documentation/s390/qeth.txt | 21 +++
> > drivers/s390/net/Makefile | 2 +-
> > drivers/s390/net/qeth_core.h | 25 +++
> > drivers/s390/net/qeth_core_main.c | 14 +-
> > drivers/s390/net/qeth_core_mpc.c | 1 +
> > drivers/s390/net/qeth_core_mpc.h | 84 +++++++++
> > drivers/s390/net/qeth_l2.h | 15 ++
> > drivers/s390/net/qeth_l2_main.c | 364 ++++++++++++++++++++++++++++++++++++++
> > drivers/s390/net/qeth_l2_sys.c | 161 +++++++++++++++++
> > 9 files changed, 685 insertions(+), 2 deletions(-)
> > create mode 100644 Documentation/s390/qeth.txt
> > create mode 100644 drivers/s390/net/qeth_l2.h
> > create mode 100644 drivers/s390/net/qeth_l2_sys.c
> >
> >
> --
> To unsubscribe from this list: send the line "unsubscribe netdev" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
>
^ permalink raw reply
* [PATCH net] net: hyperv: initialize link status correctly
From: Jason Wang @ 2014-01-27 7:30 UTC (permalink / raw)
To: kys, haiyangz, devel, netdev, linux-kernel; +Cc: Jason Wang
Call netif_carrier_on() after register_device(). Otherwise it won't work since
the device was still in NETREG_UNINITIALIZED state.
Fixes a68f9614614749727286f675d15f1e09d13cb54a
(hyperv: Fix race between probe and open calls)
Cc: Haiyang Zhang <haiyangz@microsoft.com>
Cc: K. Y. Srinivasan <kys@microsoft.com>
Reported-by: Di Nie <dnie@redhat.com>
Tested-by: Di Nie <dnie@redhat.com>
Signed-off-by: Jason Wang <jasowang@redhat.com>
---
drivers/net/hyperv/netvsc_drv.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/net/hyperv/netvsc_drv.c b/drivers/net/hyperv/netvsc_drv.c
index 71baeb3..dc11601 100644
--- a/drivers/net/hyperv/netvsc_drv.c
+++ b/drivers/net/hyperv/netvsc_drv.c
@@ -444,13 +444,13 @@ static int netvsc_probe(struct hv_device *dev,
}
memcpy(net->dev_addr, device_info.mac_adr, ETH_ALEN);
- netif_carrier_on(net);
-
ret = register_netdev(net);
if (ret != 0) {
pr_err("Unable to register netdev.\n");
rndis_filter_device_remove(dev);
free_netdev(net);
+ } else {
+ netif_carrier_on(net);
}
return ret;
--
1.8.3.2
^ permalink raw reply related
* [PATCH 1/2] net: add and use skb_gso_transport_seglen()
From: Florian Westphal @ 2014-01-27 8:22 UTC (permalink / raw)
To: netdev; +Cc: Florian Westphal
This moves part of Eric Dumazets skb_gso_seglen helper from tbf sched to
skbuff core so it may be reused by upcoming ip forwarding path patch.
Acked-by: Eric Dumazet <edumazet@google.com>
Signed-off-by: Florian Westphal <fw@strlen.de>
---
No changes since V2, resending since patch 2/2 had issues
and I don't see 1/2 in net tree.
Changes since V1:
suggestions from Eric Dumazet:
- don't use uapi udp.h
- remove tcp.h include from tbf, its not needed anymore
include/linux/skbuff.h | 1 +
net/core/skbuff.c | 25 +++++++++++++++++++++++++
net/sched/sch_tbf.c | 13 +++----------
3 files changed, 29 insertions(+), 10 deletions(-)
diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h
index 1f689e6..f589c9a 100644
--- a/include/linux/skbuff.h
+++ b/include/linux/skbuff.h
@@ -2456,6 +2456,7 @@ void skb_zerocopy(struct sk_buff *to, const struct sk_buff *from,
void skb_split(struct sk_buff *skb, struct sk_buff *skb1, const u32 len);
int skb_shift(struct sk_buff *tgt, struct sk_buff *skb, int shiftlen);
void skb_scrub_packet(struct sk_buff *skb, bool xnet);
+unsigned int skb_gso_transport_seglen(const struct sk_buff *skb);
struct sk_buff *skb_segment(struct sk_buff *skb, netdev_features_t features);
struct skb_checksum_ops {
diff --git a/net/core/skbuff.c b/net/core/skbuff.c
index 8f519db..9ae6d11 100644
--- a/net/core/skbuff.c
+++ b/net/core/skbuff.c
@@ -47,6 +47,8 @@
#include <linux/in.h>
#include <linux/inet.h>
#include <linux/slab.h>
+#include <linux/tcp.h>
+#include <linux/udp.h>
#include <linux/netdevice.h>
#ifdef CONFIG_NET_CLS_ACT
#include <net/pkt_sched.h>
@@ -3916,3 +3918,26 @@ void skb_scrub_packet(struct sk_buff *skb, bool xnet)
nf_reset_trace(skb);
}
EXPORT_SYMBOL_GPL(skb_scrub_packet);
+
+/**
+ * skb_gso_transport_seglen - Return length of individual segments of a gso packet
+ *
+ * @skb: GSO skb
+ *
+ * skb_gso_transport_seglen is used to determine the real size of the
+ * individual segments, including Layer4 headers (TCP/UDP).
+ *
+ * The MAC/L2 or network (IP, IPv6) headers are not accounted for.
+ */
+unsigned int skb_gso_transport_seglen(const struct sk_buff *skb)
+{
+ const struct skb_shared_info *shinfo = skb_shinfo(skb);
+ unsigned int hdr_len;
+
+ if (likely(shinfo->gso_type & (SKB_GSO_TCPV4 | SKB_GSO_TCPV6)))
+ hdr_len = tcp_hdrlen(skb);
+ else
+ hdr_len = sizeof(struct udphdr);
+ return hdr_len + shinfo->gso_size;
+}
+EXPORT_SYMBOL_GPL(skb_gso_transport_seglen);
diff --git a/net/sched/sch_tbf.c b/net/sched/sch_tbf.c
index fbba5b0..1cb413f 100644
--- a/net/sched/sch_tbf.c
+++ b/net/sched/sch_tbf.c
@@ -21,7 +21,6 @@
#include <net/netlink.h>
#include <net/sch_generic.h>
#include <net/pkt_sched.h>
-#include <net/tcp.h>
/* Simple Token Bucket Filter.
@@ -148,16 +147,10 @@ static u64 psched_ns_t2l(const struct psched_ratecfg *r,
* Return length of individual segments of a gso packet,
* including all headers (MAC, IP, TCP/UDP)
*/
-static unsigned int skb_gso_seglen(const struct sk_buff *skb)
+static unsigned int skb_gso_mac_seglen(const struct sk_buff *skb)
{
unsigned int hdr_len = skb_transport_header(skb) - skb_mac_header(skb);
- const struct skb_shared_info *shinfo = skb_shinfo(skb);
-
- if (likely(shinfo->gso_type & (SKB_GSO_TCPV4 | SKB_GSO_TCPV6)))
- hdr_len += tcp_hdrlen(skb);
- else
- hdr_len += sizeof(struct udphdr);
- return hdr_len + shinfo->gso_size;
+ return hdr_len + skb_gso_transport_seglen(skb);
}
/* GSO packet is too big, segment it so that tbf can transmit
@@ -202,7 +195,7 @@ static int tbf_enqueue(struct sk_buff *skb, struct Qdisc *sch)
int ret;
if (qdisc_pkt_len(skb) > q->max_size) {
- if (skb_is_gso(skb) && skb_gso_seglen(skb) <= q->max_size)
+ if (skb_is_gso(skb) && skb_gso_mac_seglen(skb) <= q->max_size)
return tbf_segment(skb, sch);
return qdisc_reshape_fail(skb, sch);
}
--
1.8.1.5
^ permalink raw reply related
* [PATCH 2/2] net: ip, ipv6: handle gso skbs in forwarding path
From: Florian Westphal @ 2014-01-27 8:22 UTC (permalink / raw)
To: netdev; +Cc: Florian Westphal
In-Reply-To: <1390810971-23959-1-git-send-email-fw@strlen.de>
Marcelo Ricardo Leitner reported problems when the forwarding link
path has a lower mtu than the incoming link if the inbound interface
supports GRO.
Given:
Host <mtu1500> R1 <mtu1200> R2
Host sends tcp stream which is routed via R1 and R2. R1 performs GRO.
In this case, the kernel will fail to send ICMP fragmentation needed
messages (or pkt too big for ipv6), as gso packets currently bypass the
dst mtu checks in forward path. Instead, Linux tries to send out packets
exceeding R1-R2 link mtu.
When locking route MTU on Host (i.e., no ipv4 DF bit set), R1 does
not fragment the packets when forwarding, and again tries to send out
packets exceeding R1-R2 link mtu.
This alters the forwarding dstmtu checks to take the individual gso
segment lengths into account.
For ipv6, we send out pkt too big error for gso if the individual
segments are too big.
For ipv4, we either send icmp fragmentation needed, or, if the DF bit
is not set, perform software segmentation and let the output path
create fragments when the packet is leaving the machine.
It is not 100% correct as the error message will contain the headers of
the GRO skb instead of the original/segmented one, but it seems to
work fine in my (limited) tests.
Signed-off-by: Florian Westphal <fw@strlen.de>
---
Changes since V2:
- make this thing apply to current -net tree
- kill unused variables in ip_forward/ip6_output
Changes since V1:
suggestions from Eric Dumazet:
- skip more expensive computation for small packets in fwd path
- use netif_skb_features() feature mask and remove GSO flags
instead of using 0 feature set.
include/linux/skbuff.h | 17 ++++++++++++++
net/ipv4/ip_forward.c | 60 ++++++++++++++++++++++++++++++++++++++++++++++++--
net/ipv6/ip6_output.c | 17 ++++++++++++--
3 files changed, 90 insertions(+), 4 deletions(-)
diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h
index f589c9a..3ebbbe7 100644
--- a/include/linux/skbuff.h
+++ b/include/linux/skbuff.h
@@ -2916,5 +2916,22 @@ static inline bool skb_head_is_locked(const struct sk_buff *skb)
{
return !skb->head_frag || skb_cloned(skb);
}
+
+/**
+ * skb_gso_network_seglen - Return length of individual segments of a gso packet
+ *
+ * @skb: GSO skb
+ *
+ * skb_gso_network_seglen is used to determine the real size of the
+ * individual segments, including Layer3 (IP, IPv6) and L4 headers (TCP/UDP).
+ *
+ * The MAC/L2 header is not accounted for.
+ */
+static inline unsigned int skb_gso_network_seglen(const struct sk_buff *skb)
+{
+ unsigned int hdr_len = skb_transport_header(skb) -
+ skb_network_header(skb);
+ return hdr_len + skb_gso_transport_seglen(skb);
+}
#endif /* __KERNEL__ */
#endif /* _LINUX_SKBUFF_H */
diff --git a/net/ipv4/ip_forward.c b/net/ipv4/ip_forward.c
index e9f1217..91c8f51 100644
--- a/net/ipv4/ip_forward.c
+++ b/net/ipv4/ip_forward.c
@@ -39,6 +39,60 @@
#include <net/route.h>
#include <net/xfrm.h>
+static bool ip_may_fragment(const struct sk_buff *skb)
+{
+ return unlikely((ip_hdr(skb)->frag_off & htons(IP_DF)) == 0) ||
+ !skb->local_df;
+}
+
+static bool ip_gso_exceeds_dst_mtu(const struct sk_buff *skb)
+{
+ if (skb->local_df || !skb_is_gso(skb))
+ return false;
+ return skb_gso_network_seglen(skb) > dst_mtu(skb_dst(skb));
+}
+
+static bool ip_exceeds_mtu(const struct sk_buff *skb, unsigned int mtu)
+{
+ if (skb->len <= mtu || skb->local_df)
+ return false;
+
+ if (skb_is_gso(skb) && skb_gso_network_seglen(skb) <= mtu)
+ return false;
+
+ return true;
+}
+
+/* called if GSO skb needs to be fragmented on forward. */
+static int ip_forward_finish_gso(struct sk_buff *skb)
+{
+ netdev_features_t features = netif_skb_features(skb);
+ struct sk_buff *segs;
+ int ret = 0;
+
+ segs = skb_gso_segment(skb, features & ~NETIF_F_GSO_MASK);
+ if (IS_ERR(segs)) {
+ kfree_skb(skb);
+ return -ENOMEM;
+ }
+
+ consume_skb(skb);
+
+ do {
+ struct sk_buff *nskb = segs->next;
+ int err;
+
+ segs->next = NULL;
+ err = dst_output(segs);
+
+ if (err && ret == 0)
+ ret = err;
+ segs = nskb;
+ } while (segs);
+
+ return ret;
+}
+
static int ip_forward_finish(struct sk_buff *skb)
{
struct ip_options *opt = &(IPCB(skb)->opt);
@@ -49,6 +103,9 @@ static int ip_forward_finish(struct sk_buff *skb)
if (unlikely(opt->optlen))
ip_forward_options(skb);
+ if (ip_gso_exceeds_dst_mtu(skb))
+ return ip_forward_finish_gso(skb);
+
return dst_output(skb);
}
@@ -91,8 +148,7 @@ int ip_forward(struct sk_buff *skb)
IPCB(skb)->flags |= IPSKB_FORWARDED;
mtu = ip_dst_mtu_maybe_forward(&rt->dst, true);
- if (unlikely(skb->len > mtu && !skb_is_gso(skb) &&
- (ip_hdr(skb)->frag_off & htons(IP_DF))) && !skb->local_df) {
+ if (!ip_may_fragment(skb) && ip_exceeds_mtu(skb, mtu)) {
IP_INC_STATS(dev_net(rt->dst.dev), IPSTATS_MIB_FRAGFAILS);
icmp_send(skb, ICMP_DEST_UNREACH, ICMP_FRAG_NEEDED,
htonl(mtu));
diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c
index ef02b26..070a2fa 100644
--- a/net/ipv6/ip6_output.c
+++ b/net/ipv6/ip6_output.c
@@ -342,6 +342,20 @@ static unsigned int ip6_dst_mtu_forward(const struct dst_entry *dst)
return mtu;
}
+static bool ip6_pkt_too_big(const struct sk_buff *skb, unsigned int mtu)
+{
+ if (skb->len <= mtu || skb->local_df)
+ return false;
+
+ if (IP6CB(skb)->frag_max_size && IP6CB(skb)->frag_max_size > mtu)
+ return true;
+
+ if (skb_is_gso(skb) && skb_gso_network_seglen(skb) <= mtu)
+ return false;
+
+ return true;
+}
+
int ip6_forward(struct sk_buff *skb)
{
struct dst_entry *dst = skb_dst(skb);
@@ -466,8 +480,7 @@ int ip6_forward(struct sk_buff *skb)
if (mtu < IPV6_MIN_MTU)
mtu = IPV6_MIN_MTU;
- if ((!skb->local_df && skb->len > mtu && !skb_is_gso(skb)) ||
- (IP6CB(skb)->frag_max_size && IP6CB(skb)->frag_max_size > mtu)) {
+ if (ip6_pkt_too_big(skb, mtu)) {
/* Again, force OUTPUT device used as source address */
skb->dev = dst->dev;
icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu);
--
1.8.1.5
^ permalink raw reply related
* Re: [PATCH 1/2] net: add and use skb_gso_transport_seglen()
From: David Miller @ 2014-01-27 8:30 UTC (permalink / raw)
To: fw; +Cc: netdev
In-Reply-To: <1390810971-23959-1-git-send-email-fw@strlen.de>
From: Florian Westphal <fw@strlen.de>
Date: Mon, 27 Jan 2014 09:22:50 +0100
> This moves part of Eric Dumazets skb_gso_seglen helper from tbf sched to
> skbuff core so it may be reused by upcoming ip forwarding path patch.
>
> Acked-by: Eric Dumazet <edumazet@google.com>
> Signed-off-by: Florian Westphal <fw@strlen.de>
> ---
> No changes since V2, resending since patch 2/2 had issues
> and I don't see 1/2 in net tree.
Sorry, I forgot to push after my test builds, done.
^ permalink raw reply
* Re: [PATCH 2/2] net: ip, ipv6: handle gso skbs in forwarding path
From: David Miller @ 2014-01-27 8:34 UTC (permalink / raw)
To: fw; +Cc: netdev
In-Reply-To: <1390810971-23959-2-git-send-email-fw@strlen.de>
From: Florian Westphal <fw@strlen.de>
Date: Mon, 27 Jan 2014 09:22:51 +0100
> Changes since V2:
> - make this thing apply to current -net tree
> - kill unused variables in ip_forward/ip6_output
Still need changes.
> + return skb_gso_network_seglen(skb) > dst_mtu(skb_dst(skb));
You can't use dst_mtu() directly, in order to be consistent with the
rest of the forwarding code in this file you must use something like:
> mtu = ip_dst_mtu_maybe_forward(&rt->dst, true);
^ permalink raw reply
* Re: [PATCH net] net: hyperv: initialize link status correctly
From: David Miller @ 2014-01-27 8:35 UTC (permalink / raw)
To: jasowang; +Cc: devel, haiyangz, linux-kernel, netdev
In-Reply-To: <1390807854-4469-1-git-send-email-jasowang@redhat.com>
From: Jason Wang <jasowang@redhat.com>
Date: Mon, 27 Jan 2014 15:30:54 +0800
> Call netif_carrier_on() after register_device(). Otherwise it won't work since
> the device was still in NETREG_UNINITIALIZED state.
>
> Fixes a68f9614614749727286f675d15f1e09d13cb54a
> (hyperv: Fix race between probe and open calls)
>
> Cc: Haiyang Zhang <haiyangz@microsoft.com>
> Cc: K. Y. Srinivasan <kys@microsoft.com>
> Reported-by: Di Nie <dnie@redhat.com>
> Tested-by: Di Nie <dnie@redhat.com>
> Signed-off-by: Jason Wang <jasowang@redhat.com>
A device up can occur at the moment you call register_netdevice(),
therefore that up call can see the carrier as down and fail or
similar. So you really cannot resolve the carrier to be on in this
way.
^ permalink raw reply
* Re: [PATCH 2/2] net: ip, ipv6: handle gso skbs in forwarding path
From: Florian Westphal @ 2014-01-27 8:36 UTC (permalink / raw)
To: David Miller; +Cc: fw, netdev
In-Reply-To: <20140127.003403.165822194531743765.davem@davemloft.net>
David Miller <davem@davemloft.net> wrote:
> From: Florian Westphal <fw@strlen.de>
> Date: Mon, 27 Jan 2014 09:22:51 +0100
> > Changes since V2:
> > - make this thing apply to current -net tree
> > - kill unused variables in ip_forward/ip6_output
>
> Still need changes.
> > + return skb_gso_network_seglen(skb) > dst_mtu(skb_dst(skb));
>
> You can't use dst_mtu() directly, in order to be consistent with the
> rest of the forwarding code in this file you must use something like:
>
> > mtu = ip_dst_mtu_maybe_forward(&rt->dst, true);
You're right of course.
Sorry. I will fix this up and NOT resend soon, its clear I need
to do more homework (aka follow Hannes PMTU changes).
Expect a V4 in a couple of hours.
^ permalink raw reply
* [BUG PATCH] Memory leak on tcp_prot slab with TPROXY and TCP early demux
From: Holger Eitzenberger @ 2014-01-27 9:09 UTC (permalink / raw)
To: netdev, netfilter-devel; +Cc: David S. Miller, Florian Westphal
Hi,
I see a memory leak when using a transparent HTTP proxy using TPROXY together
with TCP early demux and Kernel v3.8.13.15 (Ubuntu stable):
unreferenced object 0xffff88008cba4a40 (size 1696):
comm "softirq", pid 0, jiffies 4294944115 (age 8907.520s)
hex dump (first 32 bytes):
0a e0 20 6a 40 04 1b 37 92 be 32 e2 e8 b4 00 00 .. j@..7..2.....
02 00 07 01 00 00 00 00 00 00 00 00 00 00 00 00 ................
backtrace:
[<ffffffff810b710a>] kmem_cache_alloc+0xad/0xb9
[<ffffffff81270185>] sk_prot_alloc+0x29/0xc5
[<ffffffff812702cf>] sk_clone_lock+0x14/0x283
[<ffffffff812aaf3a>] inet_csk_clone_lock+0xf/0x7b
[<ffffffff8129a893>] netlink_broadcast+0x14/0x16
[<ffffffff812c1573>] tcp_create_openreq_child+0x1b/0x4c3
[<ffffffff812c033e>] tcp_v4_syn_recv_sock+0x38/0x25d
[<ffffffff812c13e4>] tcp_check_req+0x25c/0x3d0
[<ffffffff812bf87a>] tcp_v4_do_rcv+0x287/0x40e
[<ffffffff812a08a7>] ip_route_input_noref+0x843/0xa55
[<ffffffff812bfeca>] tcp_v4_rcv+0x4c9/0x725
[<ffffffff812a26f4>] ip_local_deliver_finish+0xe9/0x154
[<ffffffff8127a927>] __netif_receive_skb+0x4b2/0x514
[<ffffffff8127aa77>] process_backlog+0xee/0x1c5
[<ffffffff8127c949>] net_rx_action+0xa7/0x200
[<ffffffff81209d86>] add_interrupt_randomness+0x39/0x157
But the same issue is present in v3.13 and beyond.
>From looking at the TPROXY code, and with help from Florian, I see that
the memory leak is introduced in tcp_v4_early_demux():
void tcp_v4_early_demux(struct sk_buff *skb)
{
/* ... */
iph = ip_hdr(skb);
th = tcp_hdr(skb);
if (th->doff < sizeof(struct tcphdr) / 4)
return;
sk = __inet_lookup_established(dev_net(skb->dev), &tcp_hashinfo,
iph->saddr, th->source,
iph->daddr, ntohs(th->dest),
skb->skb_iif);
if (sk) {
skb->sk = sk;
where the socket is assigned unconditionally to skb->sk, also
bumping the refcnt on it. This is problematic, because in our
case the skb has already a socket assigned in the TPROXY
target. This then results in the leak I see.
The very same issue seems to be with IPv6, but haven't tested.
Because this codepath is only hit with net.ipv4.ip_early_demux enabled
(default '0') disabling Early Demux prooved to be a valid workaround
for this issue.
The patch which fixes the issue for me is attached for RFC: I simply
skip Early Demux if a local socket already has been assigned
in the target. Both for IPv4 and IPv6.
Please have a look, there may be smarter ways of fixing that.
Cheers,
/Holger
^ permalink raw reply
* [BUG PATCH] Memory leak on tcp_prot slab with TPROXY and TCP early demux
From: Holger Eitzenberger @ 2014-01-27 9:33 UTC (permalink / raw)
To: netdev, netfilter-devel; +Cc: David S. Miller, Florian Westphal
[-- Attachment #1: Type: text/plain, Size: 2569 bytes --]
Hi,
I see a memory leak when using a transparent HTTP proxy using TPROXY together
with TCP early demux and Kernel v3.8.13.15 (Ubuntu stable):
unreferenced object 0xffff88008cba4a40 (size 1696):
comm "softirq", pid 0, jiffies 4294944115 (age 8907.520s)
hex dump (first 32 bytes):
0a e0 20 6a 40 04 1b 37 92 be 32 e2 e8 b4 00 00 .. j@..7..2.....
02 00 07 01 00 00 00 00 00 00 00 00 00 00 00 00 ................
backtrace:
[<ffffffff810b710a>] kmem_cache_alloc+0xad/0xb9
[<ffffffff81270185>] sk_prot_alloc+0x29/0xc5
[<ffffffff812702cf>] sk_clone_lock+0x14/0x283
[<ffffffff812aaf3a>] inet_csk_clone_lock+0xf/0x7b
[<ffffffff8129a893>] netlink_broadcast+0x14/0x16
[<ffffffff812c1573>] tcp_create_openreq_child+0x1b/0x4c3
[<ffffffff812c033e>] tcp_v4_syn_recv_sock+0x38/0x25d
[<ffffffff812c13e4>] tcp_check_req+0x25c/0x3d0
[<ffffffff812bf87a>] tcp_v4_do_rcv+0x287/0x40e
[<ffffffff812a08a7>] ip_route_input_noref+0x843/0xa55
[<ffffffff812bfeca>] tcp_v4_rcv+0x4c9/0x725
[<ffffffff812a26f4>] ip_local_deliver_finish+0xe9/0x154
[<ffffffff8127a927>] __netif_receive_skb+0x4b2/0x514
[<ffffffff8127aa77>] process_backlog+0xee/0x1c5
[<ffffffff8127c949>] net_rx_action+0xa7/0x200
[<ffffffff81209d86>] add_interrupt_randomness+0x39/0x157
But the same issue is present in v3.13 and beyond.
>From looking at the TPROXY code, and with help from Florian, I see that
the memory leak is introduced in tcp_v4_early_demux():
void tcp_v4_early_demux(struct sk_buff *skb)
{
/* ... */
iph = ip_hdr(skb);
th = tcp_hdr(skb);
if (th->doff < sizeof(struct tcphdr) / 4)
return;
sk = __inet_lookup_established(dev_net(skb->dev), &tcp_hashinfo,
iph->saddr, th->source,
iph->daddr, ntohs(th->dest),
skb->skb_iif);
if (sk) {
skb->sk = sk;
where the socket is assigned unconditionally to skb->sk, also
bumping the refcnt on it. This is problematic, because in our
case the skb has already a socket assigned in the TPROXY
target. This then results in the leak I see.
The very same issue seems to be with IPv6, but haven't tested.
Because this codepath is only hit with net.ipv4.ip_early_demux enabled
(default '0') disabling Early Demux prooved to be a valid workaround
for this issue.
The patch which fixes the issue for me is attached for RFC: I simply
skip Early Demux if a local socket already has been assigned
in the target. Both for IPv4 and IPv6.
Please have a look, there could be smarter ways of fixing that.
Cheers,
/Holger
[-- Attachment #2: fix-memleak-if-TPROXY-plus-early-demux.diff --]
[-- Type: text/x-diff, Size: 3335 bytes --]
net: Fix memory leak if TPROXY used with TCP early demux
I see a memory leak when using a transparent HTTP proxy using TPROXY
together with TCP early demux and Kernel v3.8.13.15 (Ubuntu stable):
unreferenced object 0xffff88008cba4a40 (size 1696):
comm "softirq", pid 0, jiffies 4294944115 (age 8907.520s)
hex dump (first 32 bytes):
0a e0 20 6a 40 04 1b 37 92 be 32 e2 e8 b4 00 00 .. j@..7..2.....
02 00 07 01 00 00 00 00 00 00 00 00 00 00 00 00 ................
backtrace:
[<ffffffff810b710a>] kmem_cache_alloc+0xad/0xb9
[<ffffffff81270185>] sk_prot_alloc+0x29/0xc5
[<ffffffff812702cf>] sk_clone_lock+0x14/0x283
[<ffffffff812aaf3a>] inet_csk_clone_lock+0xf/0x7b
[<ffffffff8129a893>] netlink_broadcast+0x14/0x16
[<ffffffff812c1573>] tcp_create_openreq_child+0x1b/0x4c3
[<ffffffff812c033e>] tcp_v4_syn_recv_sock+0x38/0x25d
[<ffffffff812c13e4>] tcp_check_req+0x25c/0x3d0
[<ffffffff812bf87a>] tcp_v4_do_rcv+0x287/0x40e
[<ffffffff812a08a7>] ip_route_input_noref+0x843/0xa55
[<ffffffff812bfeca>] tcp_v4_rcv+0x4c9/0x725
[<ffffffff812a26f4>] ip_local_deliver_finish+0xe9/0x154
[<ffffffff8127a927>] __netif_receive_skb+0x4b2/0x514
[<ffffffff8127aa77>] process_backlog+0xee/0x1c5
[<ffffffff8127c949>] net_rx_action+0xa7/0x200
[<ffffffff81209d86>] add_interrupt_randomness+0x39/0x157
But there are many more, resulting in the machine going OOM after some
days.
>From looking at the TPROXY code, and with help from Florian, I see
that the memory leak is introduced in tcp_v4_early_demux():
void tcp_v4_early_demux(struct sk_buff *skb)
{
/* ... */
iph = ip_hdr(skb);
th = tcp_hdr(skb);
if (th->doff < sizeof(struct tcphdr) / 4)
return;
sk = __inet_lookup_established(dev_net(skb->dev), &tcp_hashinfo,
iph->saddr, th->source,
iph->daddr, ntohs(th->dest),
skb->skb_iif);
if (sk) {
skb->sk = sk;
where the socket is assigned unconditionally to skb->sk, also bumping
the refcnt on it. This is problematic, because in our case the skb
has already a socket assigned in the TPROXY target. This then results
in the leak I see.
The very same issue seems to be with IPv6, but haven't tested.
Reviewed-by: Florian Westphal <fw@strlen.de>
Signed-off-by: Holger Eitzenberger <holger@eitzenberger.org>
Index: net-next/net/ipv4/ip_input.c
===================================================================
--- net-next.orig/net/ipv4/ip_input.c
+++ net-next/net/ipv4/ip_input.c
@@ -314,7 +314,7 @@ static int ip_rcv_finish(struct sk_buff
const struct iphdr *iph = ip_hdr(skb);
struct rtable *rt;
- if (sysctl_ip_early_demux && !skb_dst(skb)) {
+ if (sysctl_ip_early_demux && !skb_dst(skb) && skb->sk == NULL) {
const struct net_protocol *ipprot;
int protocol = iph->protocol;
Index: net-next/net/ipv6/ip6_input.c
===================================================================
--- net-next.orig/net/ipv6/ip6_input.c
+++ net-next/net/ipv6/ip6_input.c
@@ -49,7 +49,7 @@
int ip6_rcv_finish(struct sk_buff *skb)
{
- if (sysctl_ip_early_demux && !skb_dst(skb)) {
+ if (sysctl_ip_early_demux && !skb_dst(skb) && skb->sk == NULL) {
const struct inet6_protocol *ipprot;
ipprot = rcu_dereference(inet6_protos[ipv6_hdr(skb)->nexthdr]);
^ permalink raw reply
* Re: [PATCH net] net: hyperv: initialize link status correctly
From: Jason Wang @ 2014-01-27 9:40 UTC (permalink / raw)
To: David Miller; +Cc: devel, haiyangz, linux-kernel, netdev
In-Reply-To: <20140127.003559.2290408024387922847.davem@davemloft.net>
On 01/27/2014 04:35 PM, David Miller wrote:
> From: Jason Wang <jasowang@redhat.com>
> Date: Mon, 27 Jan 2014 15:30:54 +0800
>
>> Call netif_carrier_on() after register_device(). Otherwise it won't work since
>> the device was still in NETREG_UNINITIALIZED state.
>>
>> Fixes a68f9614614749727286f675d15f1e09d13cb54a
>> (hyperv: Fix race between probe and open calls)
>>
>> Cc: Haiyang Zhang <haiyangz@microsoft.com>
>> Cc: K. Y. Srinivasan <kys@microsoft.com>
>> Reported-by: Di Nie <dnie@redhat.com>
>> Tested-by: Di Nie <dnie@redhat.com>
>> Signed-off-by: Jason Wang <jasowang@redhat.com>
> A device up can occur at the moment you call register_netdevice(),
> therefore that up call can see the carrier as down and fail or
> similar. So you really cannot resolve the carrier to be on in this
> way.
True, we need a workqueue to synchronize them.
^ permalink raw reply
* Re: [PATCH 1/3] net: ethoc: don't advertise gigabit speed on attached PHY
From: Ben Hutchings @ 2014-01-27 10:18 UTC (permalink / raw)
To: Max Filippov
Cc: linux-xtensa-PjhNF2WwrV/0Sa2dR60CXw,
netdev-u79uwXL29TY76Z2rM5mHXA, devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA, Chris Zankel, Marc Gauthier,
David S. Miller, Grant Likely, Rob Herring
In-Reply-To: <1390795167-6677-2-git-send-email-jcmvbkbc-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
[-- Attachment #1: Type: text/plain, Size: 1428 bytes --]
On Mon, 2014-01-27 at 07:59 +0400, Max Filippov wrote:
> OpenCores 10/100 Mbps MAC does not support speeds above 100 Mbps, but does
> not disable advertisement when PHY supports them. This results in
> non-functioning network when the MAC is connected to a gigabit PHY connected
> to a gigabit switch.
>
> The fix is to disable gigabit speed advertisement on attached PHY
> unconditionally.
>
> Signed-off-by: Max Filippov <jcmvbkbc-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
> ---
> drivers/net/ethernet/ethoc.c | 2 ++
> 1 file changed, 2 insertions(+)
>
> diff --git a/drivers/net/ethernet/ethoc.c b/drivers/net/ethernet/ethoc.c
> index 4de8cfd..0aa1a05 100644
> --- a/drivers/net/ethernet/ethoc.c
> +++ b/drivers/net/ethernet/ethoc.c
> @@ -712,6 +712,8 @@ static int ethoc_open(struct net_device *dev)
> netif_start_queue(dev);
> }
>
> + priv->phy->advertising &= ~(ADVERTISED_1000baseT_Full |
> + ADVERTISED_1000baseT_Half);
> phy_start(priv->phy);
> napi_enable(&priv->napi);
>
This is not sufficient to disable gigabit speeds; the supported mask
should also be limited. And it should be done even before the net
device is registered.
Rather than poking into the phy_device structure directly from this
driver, I think you should add a function in phylib for this purpose.
Ben.
--
Ben Hutchings
If at first you don't succeed, you're doing about average.
[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 828 bytes --]
^ permalink raw reply
* Re: [PATCH net] net: hyperv: initialize link status correctly
From: Ben Hutchings @ 2014-01-27 10:22 UTC (permalink / raw)
To: Jason Wang; +Cc: netdev, haiyangz, linux-kernel, devel, David Miller
In-Reply-To: <52E629A8.5010302@redhat.com>
[-- Attachment #1.1: Type: text/plain, Size: 1274 bytes --]
On Mon, 2014-01-27 at 17:40 +0800, Jason Wang wrote:
> On 01/27/2014 04:35 PM, David Miller wrote:
> > From: Jason Wang <jasowang@redhat.com>
> > Date: Mon, 27 Jan 2014 15:30:54 +0800
> >
> >> Call netif_carrier_on() after register_device(). Otherwise it won't work since
> >> the device was still in NETREG_UNINITIALIZED state.
> >>
> >> Fixes a68f9614614749727286f675d15f1e09d13cb54a
> >> (hyperv: Fix race between probe and open calls)
> >>
> >> Cc: Haiyang Zhang <haiyangz@microsoft.com>
> >> Cc: K. Y. Srinivasan <kys@microsoft.com>
> >> Reported-by: Di Nie <dnie@redhat.com>
> >> Tested-by: Di Nie <dnie@redhat.com>
> >> Signed-off-by: Jason Wang <jasowang@redhat.com>
> > A device up can occur at the moment you call register_netdevice(),
> > therefore that up call can see the carrier as down and fail or
> > similar. So you really cannot resolve the carrier to be on in this
> > way.
>
> True, we need a workqueue to synchronize them.
Whatever for? All you need to do is:
rtnl_lock();
register_netdevice();
netif_carrier_on();
rtnl_unlock();
It would be nice if we could make the current code work with a change in
the core, though.
Ben.
--
Ben Hutchings
If at first you don't succeed, you're doing about average.
[-- Attachment #1.2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 828 bytes --]
[-- Attachment #2: Type: text/plain, Size: 169 bytes --]
_______________________________________________
devel mailing list
devel@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
^ permalink raw reply
* Re: [Xen-devel] [PATCH net-next v5] xen-netfront: clean up code in xennet_release_rx_bufs
From: David Vrabel @ 2014-01-27 10:22 UTC (permalink / raw)
To: Annie Li; +Cc: xen-devel, netdev, konrad.wilk, ian.campbell, wei.liu2
In-Reply-To: <1390731147-2424-1-git-send-email-Annie.li@oracle.com>
On 26/01/14 10:12, Annie Li wrote:
> From: Annie Li <annie.li@oracle.com>
>
> This patch removes grant transfer releasing code from netfront, and uses
> gnttab_end_foreign_access to end grant access since
> gnttab_end_foreign_access_ref may fail when the grant entry is
> currently used for reading or writing.
>
> * clean up grant transfer code kept from old netfront(2.6.18) which grants
> pages for access/map and transfer. But grant transfer is deprecated in current
> netfront, so remove corresponding release code for transfer.
>
> * release grant access (through gnttab_end_foreign_access) and skb for tx/rx path,
> use get_page to ensure page is released when grant access is completed successfully.
>
> Xen-blkfront/xen-tpmfront/xen-pcifront also have similar issue, but patches
> for them will be created separately.
>
> V5: Remove unecessary change in xennet_end_access.
>
> V4: Revert put_page in gnttab_end_foreign_access, and keep netfront change in
> single patch.
>
> V3: Changes as suggestion from David Vrabel, ensure pages are not freed untill
> grant acess is ended.
>
> V2: Improve patch comments.
>
> Signed-off-by: Annie Li <annie.li@oracle.com>
Reviewed-by: David Vrabel <david.vrabel@citrix.com>
I think this should be applied to net (and tagged as a stable candidate)
rather than net-next as this fixes are very big resource leak.
David
^ permalink raw reply
* Re: [PATCH net] net: hyperv: initialize link status correctly
From: Jason Wang @ 2014-01-27 10:28 UTC (permalink / raw)
To: Ben Hutchings; +Cc: netdev, haiyangz, linux-kernel, devel, David Miller
In-Reply-To: <1390818121.2735.130.camel@deadeye.wl.decadent.org.uk>
On 01/27/2014 06:22 PM, Ben Hutchings wrote:
> On Mon, 2014-01-27 at 17:40 +0800, Jason Wang wrote:
>> On 01/27/2014 04:35 PM, David Miller wrote:
>>> From: Jason Wang <jasowang@redhat.com>
>>> Date: Mon, 27 Jan 2014 15:30:54 +0800
>>>
>>>> Call netif_carrier_on() after register_device(). Otherwise it won't work since
>>>> the device was still in NETREG_UNINITIALIZED state.
>>>>
>>>> Fixes a68f9614614749727286f675d15f1e09d13cb54a
>>>> (hyperv: Fix race between probe and open calls)
>>>>
>>>> Cc: Haiyang Zhang <haiyangz@microsoft.com>
>>>> Cc: K. Y. Srinivasan <kys@microsoft.com>
>>>> Reported-by: Di Nie <dnie@redhat.com>
>>>> Tested-by: Di Nie <dnie@redhat.com>
>>>> Signed-off-by: Jason Wang <jasowang@redhat.com>
>>> A device up can occur at the moment you call register_netdevice(),
>>> therefore that up call can see the carrier as down and fail or
>>> similar. So you really cannot resolve the carrier to be on in this
>>> way.
>> True, we need a workqueue to synchronize them.
> Whatever for? All you need to do is:
>
> rtnl_lock();
> register_netdevice();
> netif_carrier_on();
> rtnl_unlock();
>
> It would be nice if we could make the current code work with a change in
> the core, though.
>
> Ben.
>
Looks like the link status interrupt may happen during this (after
netvsc_device_add() was called by rndis_filter_device_add()) without any
synchronization. This may lead a wrong link status here.
^ permalink raw reply
* [PATCH RFC v3 0/12] vti4: prepare namespace and interfamily support.
From: Steffen Klassert @ 2014-01-27 10:29 UTC (permalink / raw)
To: netdev; +Cc: Steffen Klassert, Christophe Gouault, Saurabh Mohan
This patchset prepares vti4 for proper namespace and interfamily support.
Currently the receive hook is in the middle of the decapsulation
process, some of the header pointers point still into the IPsec packet
others point already into the decapsulated packet. This makes it
very unflexible and proper namespace and interfamily support can't
be done as it is.
The patchset that implements an IPsec protocol multiplexer, so that vti
can register it's own receive path hooks. Further it makes the i_key
usable for vti and changes the vti code to do the following:
vti uses the IPsec protocol multiplexer to register it's
own receive side hooks for ESP, AH and IPCOMP.
Vti does the following on receive side:
1. Do an input policy check for the IPsec packet we received.
This is required because this packet could be already
processed by IPsec (tunnel in tunnel or a block policy
is present), so an inbound policy check is needed.
2. Mark the packet with the i_key. The policy and the state
must match this key now. Policy and state belong to the vti
namespace and policy enforcement is done at the further layers.
3. Call the generic xfrm layer to do decryption and decapsulation.
4. Wait for a callback from the xfrm layer to properly clean the skb to
not leak informations on namespace transitions and to update the device
statistics.
On transmit side:
1. Mark the packet with the o_key. The policy and the state
must match this key now.
2. Do a xfrm_lookup on the original packet with the mark applied.
3. Check if we got an IPsec route.
4. Clean the skb to not leak informations on namespace
transitions.
5. Attach the dst_enty we got from the xfrm_lookup to the skb.
6. Call dst_output to do the IPsec processing.
7. Do the device statistics.
Changes from v1:
- Rebased to current net-next.
- Fix a rcu lockdep complaint in xfrm protocol registration/deregistration.
- Fix usage of a ipv4 specific callback handler in generic code.
- Use skb_scrub_packet() to clear the skb in vti_rcv(), suggested by
Nicolas Dichtel.
- Add support for IPCOMP.
- Support inter address family tunneling.
Changes from v2:
- Rebased to current net-next.
- Check for matching tunnel endpoints of the xfrm state and
the vti interface.
- Use a own error handler to not create dependencies to the
generic IPsec protocol handlers.
- Change the receive path to do the namespace transition after
decapsulation. With this the xfrm lookups are done in the outer
namespace for xmit and receive, thanks to Christophe Gouault
for pointing this out.
- Enable namespace changing of vti devices.
I'd take this into the ipsec-next tree after the merge window closes
if noone has further suggestions or objections.
^ permalink raw reply
* [PATCH RFC v3 01/12] xfrm4: Add IPsec protocol multiplexer
From: Steffen Klassert @ 2014-01-27 10:29 UTC (permalink / raw)
To: netdev; +Cc: Steffen Klassert, Christophe Gouault, Saurabh Mohan
In-Reply-To: <1390818577-19589-1-git-send-email-steffen.klassert@secunet.com>
This patch add an IPsec protocol multiplexer. With this
it is possible to add alternative protocol handlers as
needed for IPsec virtual tunnel interfaces.
Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
---
include/net/xfrm.h | 24 +++++
net/ipv4/Makefile | 2 +-
net/ipv4/xfrm4_protocol.c | 242 +++++++++++++++++++++++++++++++++++++++++++++
net/xfrm/xfrm_input.c | 18 ++--
4 files changed, 279 insertions(+), 7 deletions(-)
create mode 100644 net/ipv4/xfrm4_protocol.c
diff --git a/include/net/xfrm.h b/include/net/xfrm.h
index afa5730..34aef6f 100644
--- a/include/net/xfrm.h
+++ b/include/net/xfrm.h
@@ -1347,6 +1347,17 @@ struct xfrm_algo_desc {
struct sadb_alg desc;
};
+
+/* XFRM protocol handlers. */
+struct xfrm4_protocol {
+ int (*handler)(struct sk_buff *skb);
+ int (*cb_handler)(struct sk_buff *skb, int err);
+ int (*err_handler)(struct sk_buff *skb, u32 info);
+
+ struct xfrm4_protocol __rcu *next;
+ int priority;
+};
+
/* XFRM tunnel handlers. */
struct xfrm_tunnel {
int (*handler)(struct sk_buff *skb);
@@ -1504,6 +1515,9 @@ int xfrm4_extract_output(struct xfrm_state *x, struct sk_buff *skb);
int xfrm4_prepare_output(struct xfrm_state *x, struct sk_buff *skb);
int xfrm4_output(struct sk_buff *skb);
int xfrm4_output_finish(struct sk_buff *skb);
+void xfrm4_rcv_cb(struct sk_buff *skb, u8 protocol, int err);
+int xfrm4_protocol_register(struct xfrm4_protocol *handler, unsigned char protocol);
+int xfrm4_protocol_deregister(struct xfrm4_protocol *handler, unsigned char protocol);
int xfrm4_tunnel_register(struct xfrm_tunnel *handler, unsigned short family);
int xfrm4_tunnel_deregister(struct xfrm_tunnel *handler, unsigned short family);
void xfrm4_local_error(struct sk_buff *skb, u32 mtu);
@@ -1737,4 +1751,14 @@ static inline int xfrm_mark_put(struct sk_buff *skb, const struct xfrm_mark *m)
return ret;
}
+static inline void xfrm_rcv_cb(struct sk_buff *skb, unsigned int family,
+ u8 protocol, int err)
+{
+ switch(family) {
+ case AF_INET:
+ xfrm4_rcv_cb(skb, protocol, err);
+ break;
+ }
+}
+
#endif /* _NET_XFRM_H */
diff --git a/net/ipv4/Makefile b/net/ipv4/Makefile
index f8c49ce..f032688 100644
--- a/net/ipv4/Makefile
+++ b/net/ipv4/Makefile
@@ -55,4 +55,4 @@ obj-$(CONFIG_MEMCG_KMEM) += tcp_memcontrol.o
obj-$(CONFIG_NETLABEL) += cipso_ipv4.o
obj-$(CONFIG_XFRM) += xfrm4_policy.o xfrm4_state.o xfrm4_input.o \
- xfrm4_output.o
+ xfrm4_output.o xfrm4_protocol.o
diff --git a/net/ipv4/xfrm4_protocol.c b/net/ipv4/xfrm4_protocol.c
new file mode 100644
index 0000000..993ab39
--- /dev/null
+++ b/net/ipv4/xfrm4_protocol.c
@@ -0,0 +1,242 @@
+/* xfrm4_protocol.c - Generic xfrm protocol multiplexer.
+ *
+ * Copyright (C) 2013 secunet Security Networks AG
+ *
+ * Author:
+ * Steffen Klassert <steffen.klassert@secunet.com>
+ *
+ * Based on:
+ * net/ipv4/tunnel4.c
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#include <linux/init.h>
+#include <linux/mutex.h>
+#include <linux/skbuff.h>
+#include <net/icmp.h>
+#include <net/ip.h>
+#include <net/protocol.h>
+#include <net/xfrm.h>
+
+static struct xfrm4_protocol __rcu *esp4_handlers __read_mostly;
+static struct xfrm4_protocol __rcu *ah4_handlers __read_mostly;
+static struct xfrm4_protocol __rcu *ipcomp4_handlers __read_mostly;
+static DEFINE_MUTEX(xfrm4_protocol_mutex);
+
+static inline struct xfrm4_protocol __rcu **proto_handlers(u8 protocol)
+{
+ switch (protocol) {
+ case IPPROTO_ESP:
+ return &esp4_handlers;
+ case IPPROTO_AH:
+ return &ah4_handlers;
+ case IPPROTO_COMP:
+ return &ipcomp4_handlers;
+ }
+
+ return NULL;
+}
+
+#define for_each_protocol_rcu(head, handler) \
+ for (handler = rcu_dereference(head); \
+ handler != NULL; \
+ handler = rcu_dereference(handler->next)) \
+
+void xfrm4_rcv_cb(struct sk_buff *skb, u8 protocol, int err)
+{
+ struct xfrm4_protocol *handler;
+
+ for_each_protocol_rcu(*proto_handlers(protocol), handler)
+ if (!handler->cb_handler(skb, err))
+ return;
+}
+EXPORT_SYMBOL(xfrm4_rcv_cb);
+
+static int xfrm4_esp_rcv(struct sk_buff *skb)
+{
+ struct xfrm4_protocol *handler;
+
+ for_each_protocol_rcu(esp4_handlers, handler)
+ if (!handler->handler(skb))
+ return 0;
+
+ icmp_send(skb, ICMP_DEST_UNREACH, ICMP_PORT_UNREACH, 0);
+
+ kfree_skb(skb);
+ return 0;
+}
+
+static void xfrm4_esp_err(struct sk_buff *skb, u32 info)
+{
+ struct xfrm4_protocol *handler;
+
+ for_each_protocol_rcu(esp4_handlers, handler)
+ if (!handler->err_handler(skb, info))
+ break;
+}
+
+static int xfrm4_ah_rcv(struct sk_buff *skb)
+{
+ struct xfrm4_protocol *handler;
+
+ for_each_protocol_rcu(ah4_handlers, handler)
+ if (!handler->handler(skb))
+ return 0;
+
+ icmp_send(skb, ICMP_DEST_UNREACH, ICMP_PORT_UNREACH, 0);
+
+ kfree_skb(skb);
+ return 0;
+}
+
+static void xfrm4_ah_err(struct sk_buff *skb, u32 info)
+{
+ struct xfrm4_protocol *handler;
+
+ for_each_protocol_rcu(ah4_handlers, handler)
+ if (!handler->err_handler(skb, info))
+ break;
+}
+
+static int xfrm4_ipcomp_rcv(struct sk_buff *skb)
+{
+ struct xfrm4_protocol *handler;
+
+ for_each_protocol_rcu(ipcomp4_handlers, handler)
+ if (!handler->handler(skb))
+ return 0;
+
+ icmp_send(skb, ICMP_DEST_UNREACH, ICMP_PORT_UNREACH, 0);
+
+ kfree_skb(skb);
+ return 0;
+}
+
+static void xfrm4_ipcomp_err(struct sk_buff *skb, u32 info)
+{
+ struct xfrm4_protocol *handler;
+
+ for_each_protocol_rcu(ipcomp4_handlers, handler)
+ if (!handler->err_handler(skb, info))
+ break;
+}
+
+static const struct net_protocol esp4_protocol = {
+ .handler = xfrm4_esp_rcv,
+ .err_handler = xfrm4_esp_err,
+ .no_policy = 1,
+ .netns_ok = 1,
+};
+
+static const struct net_protocol ah4_protocol = {
+ .handler = xfrm4_ah_rcv,
+ .err_handler = xfrm4_ah_err,
+ .no_policy = 1,
+ .netns_ok = 1,
+};
+
+static const struct net_protocol ipcomp4_protocol = {
+ .handler = xfrm4_ipcomp_rcv,
+ .err_handler = xfrm4_ipcomp_err,
+ .no_policy = 1,
+ .netns_ok = 1,
+};
+
+static inline const struct net_protocol *netproto(unsigned char protocol)
+{
+ switch (protocol) {
+ case IPPROTO_ESP:
+ return &esp4_protocol;
+ case IPPROTO_AH:
+ return &ah4_protocol;
+ case IPPROTO_COMP:
+ return &ipcomp4_protocol;
+ }
+
+ return NULL;
+}
+
+int xfrm4_protocol_register(struct xfrm4_protocol *handler,
+ unsigned char protocol)
+{
+ struct xfrm4_protocol __rcu **pprev;
+ struct xfrm4_protocol *t;
+ bool add_netproto = false;
+
+ int ret = -EEXIST;
+ int priority = handler->priority;
+
+ mutex_lock(&xfrm4_protocol_mutex);
+
+ if (!rcu_dereference_protected(*proto_handlers(protocol),
+ lockdep_is_held(&xfrm4_protocol_mutex)))
+ add_netproto = true;
+
+ for (pprev = proto_handlers(protocol);
+ (t = rcu_dereference_protected(*pprev,
+ lockdep_is_held(&xfrm4_protocol_mutex))) != NULL;
+ pprev = &t->next) {
+ if (t->priority < priority)
+ break;
+ if (t->priority == priority)
+ goto err;
+ }
+
+ handler->next = *pprev;
+ rcu_assign_pointer(*pprev, handler);
+
+ ret = 0;
+
+err:
+ mutex_unlock(&xfrm4_protocol_mutex);
+
+ if (add_netproto) {
+ if (inet_add_protocol(netproto(protocol), protocol)) {
+ pr_err("%s: can't add protocol\n", __func__);
+ ret = -EAGAIN;
+ }
+ }
+
+ return ret;
+}
+EXPORT_SYMBOL(xfrm4_protocol_register);
+
+int xfrm4_protocol_deregister(struct xfrm4_protocol *handler,
+ unsigned char protocol)
+{
+ struct xfrm4_protocol __rcu **pprev;
+ struct xfrm4_protocol *t;
+ int ret = -ENOENT;
+
+ mutex_lock(&xfrm4_protocol_mutex);
+
+ for (pprev = proto_handlers(protocol);
+ (t = rcu_dereference_protected(*pprev,
+ lockdep_is_held(&xfrm4_protocol_mutex))) != NULL;
+ pprev = &t->next) {
+ if (t == handler) {
+ *pprev = handler->next;
+ ret = 0;
+ break;
+ }
+ }
+
+ if (!rcu_dereference_protected(*proto_handlers(protocol),
+ lockdep_is_held(&xfrm4_protocol_mutex))) {
+ if (inet_del_protocol(netproto(protocol), protocol) < 0) {
+ pr_err("%s: can't remove protocol\n", __func__);
+ ret = -EAGAIN;
+ }
+ }
+
+ mutex_unlock(&xfrm4_protocol_mutex);
+
+ synchronize_net();
+
+ return ret;
+}
+EXPORT_SYMBOL(xfrm4_protocol_deregister);
diff --git a/net/xfrm/xfrm_input.c b/net/xfrm/xfrm_input.c
index 6c7ac01..9bf7559 100644
--- a/net/xfrm/xfrm_input.c
+++ b/net/xfrm/xfrm_input.c
@@ -108,7 +108,7 @@ int xfrm_input(struct sk_buff *skb, int nexthdr, __be32 spi, int encap_type)
int err;
__be32 seq;
__be32 seq_hi;
- struct xfrm_state *x;
+ struct xfrm_state *x = NULL;
xfrm_address_t *daddr;
struct xfrm_mode *inner_mode;
unsigned int family;
@@ -120,9 +120,14 @@ int xfrm_input(struct sk_buff *skb, int nexthdr, __be32 spi, int encap_type)
async = 1;
x = xfrm_input_state(skb);
seq = XFRM_SKB_CB(skb)->seq.input.low;
+ family = x->outer_mode->afinfo->family;
goto resume;
}
+ daddr = (xfrm_address_t *)(skb_network_header(skb) +
+ XFRM_SPI_SKB_CB(skb)->daddroff);
+ family = XFRM_SPI_SKB_CB(skb)->family;
+
/* Allocate new secpath or COW existing one. */
if (!skb->sp || atomic_read(&skb->sp->refcnt) != 1) {
struct sec_path *sp;
@@ -137,10 +142,6 @@ int xfrm_input(struct sk_buff *skb, int nexthdr, __be32 spi, int encap_type)
skb->sp = sp;
}
- daddr = (xfrm_address_t *)(skb_network_header(skb) +
- XFRM_SPI_SKB_CB(skb)->daddroff);
- family = XFRM_SPI_SKB_CB(skb)->family;
-
seq = 0;
if (!spi && (err = xfrm_parse_spi(skb, nexthdr, &spi, &seq)) != 0) {
XFRM_INC_STATS(net, LINUX_MIB_XFRMINHDRERROR);
@@ -199,8 +200,10 @@ int xfrm_input(struct sk_buff *skb, int nexthdr, __be32 spi, int encap_type)
nexthdr = x->type->input(x, skb);
- if (nexthdr == -EINPROGRESS)
+ if (nexthdr == -EINPROGRESS) {
+ xfrm_rcv_cb(skb, family, x->type->proto, nexthdr);
return 0;
+ }
resume:
spin_lock(&x->lock);
@@ -263,6 +266,8 @@ resume:
}
} while (!err);
+ xfrm_rcv_cb(skb, family, x->type->proto, 0);
+
nf_reset(skb);
if (decaps) {
@@ -276,6 +281,7 @@ resume:
drop_unlock:
spin_unlock(&x->lock);
drop:
+ xfrm_rcv_cb(skb, family, x ? x->type->proto : nexthdr, -1);
kfree_skb(skb);
return 0;
}
--
1.7.9.5
^ permalink raw reply related
* [PATCH RFC v3 02/12] esp4: Use the IPsec protocol multiplexer API
From: Steffen Klassert @ 2014-01-27 10:29 UTC (permalink / raw)
To: netdev; +Cc: Steffen Klassert, Christophe Gouault, Saurabh Mohan
In-Reply-To: <1390818577-19589-1-git-send-email-steffen.klassert@secunet.com>
Switch esp4 to use the new IPsec protocol multiplexer.
Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
---
net/ipv4/esp4.c | 25 ++++++++++++++++---------
1 file changed, 16 insertions(+), 9 deletions(-)
diff --git a/net/ipv4/esp4.c b/net/ipv4/esp4.c
index 7785b28..d1a4ccd 100644
--- a/net/ipv4/esp4.c
+++ b/net/ipv4/esp4.c
@@ -473,7 +473,7 @@ static u32 esp4_get_mtu(struct xfrm_state *x, int mtu)
net_adj) & ~(blksize - 1)) + net_adj - 2;
}
-static void esp4_err(struct sk_buff *skb, u32 info)
+static int esp4_err(struct sk_buff *skb, u32 info)
{
struct net *net = dev_net(skb->dev);
const struct iphdr *iph = (const struct iphdr *)skb->data;
@@ -483,23 +483,25 @@ static void esp4_err(struct sk_buff *skb, u32 info)
switch (icmp_hdr(skb)->type) {
case ICMP_DEST_UNREACH:
if (icmp_hdr(skb)->code != ICMP_FRAG_NEEDED)
- return;
+ return 0;
case ICMP_REDIRECT:
break;
default:
- return;
+ return 0;
}
x = xfrm_state_lookup(net, skb->mark, (const xfrm_address_t *)&iph->daddr,
esph->spi, IPPROTO_ESP, AF_INET);
if (!x)
- return;
+ return 0;
if (icmp_hdr(skb)->type == ICMP_DEST_UNREACH)
ipv4_update_pmtu(skb, net, info, 0, 0, IPPROTO_ESP, 0);
else
ipv4_redirect(skb, net, 0, 0, IPPROTO_ESP, 0);
xfrm_state_put(x);
+
+ return 0;
}
static void esp_destroy(struct xfrm_state *x)
@@ -672,6 +674,11 @@ error:
return err;
}
+static int esp4_rcv_cb(struct sk_buff *skb, int err)
+{
+ return 0;
+}
+
static const struct xfrm_type esp_type =
{
.description = "ESP4",
@@ -685,11 +692,11 @@ static const struct xfrm_type esp_type =
.output = esp_output
};
-static const struct net_protocol esp4_protocol = {
+static struct xfrm4_protocol esp4_protocol = {
.handler = xfrm4_rcv,
+ .cb_handler = esp4_rcv_cb,
.err_handler = esp4_err,
- .no_policy = 1,
- .netns_ok = 1,
+ .priority = 0,
};
static int __init esp4_init(void)
@@ -698,7 +705,7 @@ static int __init esp4_init(void)
pr_info("%s: can't add xfrm type\n", __func__);
return -EAGAIN;
}
- if (inet_add_protocol(&esp4_protocol, IPPROTO_ESP) < 0) {
+ if (xfrm4_protocol_register(&esp4_protocol, IPPROTO_ESP) < 0) {
pr_info("%s: can't add protocol\n", __func__);
xfrm_unregister_type(&esp_type, AF_INET);
return -EAGAIN;
@@ -708,7 +715,7 @@ static int __init esp4_init(void)
static void __exit esp4_fini(void)
{
- if (inet_del_protocol(&esp4_protocol, IPPROTO_ESP) < 0)
+ if (xfrm4_protocol_deregister(&esp4_protocol, IPPROTO_ESP) < 0)
pr_info("%s: can't remove protocol\n", __func__);
if (xfrm_unregister_type(&esp_type, AF_INET) < 0)
pr_info("%s: can't remove xfrm type\n", __func__);
--
1.7.9.5
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox