* Re: [PATCH v1 net-next] ip6_tunnel: Adding support of mapping rules for MAP-E tunnel
From: David Miller @ 2018-11-23 19:06 UTC (permalink / raw)
To: felix.jia; +Cc: blair.steven, netdev, sheena.mira-ato, masakazu.asama
In-Reply-To: <20181120015324.24394-1-felix.jia@alliedtelesis.co.nz>
From: Felix Jia <felix.jia@alliedtelesis.co.nz>
Date: Tue, 20 Nov 2018 14:53:24 +1300
> +struct ip6_tnl_rule {
> + u8 version;
> + struct in6_addr ipv6_subnet;
> + u8 ipv6_prefixlen;
> + struct in_addr ipv4_subnet;
> + u8 ipv4_prefixlen;
> + u8 ea_length;
> + u8 psid_offset;
Please arrange the members of this structure better so that there is no
internal padding. Putting a u8 before an in6_addr puts at least 3 bytes
of wasted padding after the u8, for example.
> + u8 *ptr;
> + struct iphdr *icmpiph = NULL;
> + struct tcphdr *tcph, *icmptcph;
> + struct udphdr *udph, *icmpudph;
> + struct icmphdr *icmph, *icmpicmph;
Please arrange all local variables from longest to shortest line, ie. reverse
christmas tree format.
> + int i, pbw0, pbi0, pbi1;
> + __u32 addr[4];
> + __u32 psid = 0;
> + __u32 mask = 0;
> + __u32 a = ntohl(addr4);
> + __u16 p = ntohs(port4);
> + int psid_prefix_length = 0;
> + int psid_mask;
> + __u32 id0 = 0;
> + __u32 id1 = 0;
Likewise.
Also, many of these explicit "= 0" initializations are unnecessary and
make the declarations more ugly than they need to be.
> +static void
> +ip6_tnl_mape_dst(struct net_device *dev, struct sk_buff *skb,
> + struct flowi6 *fl6)
> +{
> + struct ip6_tnl *t = netdev_priv(dev);
> + struct iphdr *iph;
> + __be32 saddr4, daddr4, addr;
> + __be16 sport4, dport4, port;
> + __u8 proto;
> + int icmperr;
> + struct ip6_tnl_rule *mr = NULL;
Reverse christmas tree please.
> +static struct ip6_tnl __rcu **
> +ip6_tnl_bucket_r_any(struct ip6_tnl_net *ip6n, const struct __ip6_tnl_parm *p)
> +{
> + const struct in6_addr *local = &p->laddr;
> + unsigned int h = 0;
> + int prio = 0;
> + struct in6_addr any;
Likewise.
And so on and so forth for your entire patch.
^ permalink raw reply
* Re: [PATCH bpf-next 1/2] libbpf: Add version script for DSO
From: Martin Lau @ 2018-11-23 18:44 UTC (permalink / raw)
To: Alexei Starovoitov
Cc: Yonghong Song, Andrey Ignatov, netdev@vger.kernel.org,
ast@kernel.org, daniel@iogearbox.net, Kernel Team
In-Reply-To: <45175828-13df-6cf1-6817-ddffa381f0ec@fb.com>
On Wed, Nov 21, 2018 at 02:22:14PM -0800, Alexei Starovoitov wrote:
> On 11/21/18 12:18 PM, Yonghong Song wrote:
> >
> >
> > On 11/21/18 9:40 AM, Andrey Ignatov wrote:
> >> More and more projects use libbpf and one day it'll likely be packaged
> >> and distributed as DSO and that requires ABI versioning so that both
> >> compatible and incompatible changes to ABI can be introduced in a safe
> >> way in the future without breaking executables dynamically linked with a
> >> previous version of the library.
> >>
> >> Usual way to do ABI versioning is version script for the linker. Add
> >> such a script for libbpf. All global symbols currently exported via
> >> LIBBPF_API macro are added to the version script libbpf.map.
> >>
> >> The version name LIBBPF_0.0.1 is constructed from the name of the
> >> library + version specified by $(LIBBPF_VERSION) in Makefile.
> >>
> >> Version script does not duplicate the work done by LIBBPF_API macro, it
> >> rather complements it. The macro is used at compile time and can be used
> >> by compiler to do optimization that can't be done at link time, it is
> >> purely about global symbol visibility. The version script, in turn, is
> >> used at link time and takes care of ABI versioning. Both techniques are
> >> described in details in [1].
> >>
> >> Whenever ABI is changed in the future, version script should be changed
> >> appropriately.
> >
> > Maybe we should clarify the policy of how version numbers should be
> > change? Each commit which changes default global symbol ABI? Each kernel
> > release?
> >
> >>
> >> [1] https://www.akkadia.org/drepper/dsohowto.pdf
> >>
> >> Signed-off-by: Andrey Ignatov <rdna@fb.com>
> >> ---
> >> tools/lib/bpf/Makefile | 4 +-
> >> tools/lib/bpf/libbpf.map | 120 +++++++++++++++++++++++++++++++++++++++
> >> 2 files changed, 123 insertions(+), 1 deletion(-)
> >> create mode 100644 tools/lib/bpf/libbpf.map
> >>
> >> diff --git a/tools/lib/bpf/Makefile b/tools/lib/bpf/Makefile
> >> index 425b480bda75..d76c41fa2d39 100644
> >> --- a/tools/lib/bpf/Makefile
> >> +++ b/tools/lib/bpf/Makefile
> >> @@ -145,6 +145,7 @@ include $(srctree)/tools/build/Makefile.include
> >>
> >> BPF_IN := $(OUTPUT)libbpf-in.o
> >> LIB_FILE := $(addprefix $(OUTPUT),$(LIB_FILE))
> >> +VERSION_SCRIPT := libbpf.map
> >>
> >> CMD_TARGETS = $(LIB_FILE)
> >>
> >> @@ -170,7 +171,8 @@ $(BPF_IN): force elfdep bpfdep
> >> $(Q)$(MAKE) $(build)=libbpf
> >>
> >> $(OUTPUT)libbpf.so: $(BPF_IN)
> >> - $(QUIET_LINK)$(CC) --shared $^ -o $@
> >> + $(QUIET_LINK)$(CC) --shared -Wl,--version-script=$(VERSION_SCRIPT) \
> >> + $^ -o $@
> >>
> >> $(OUTPUT)libbpf.a: $(BPF_IN)
> >> $(QUIET_LINK)$(RM) $@; $(AR) rcs $@ $^
> >> diff --git a/tools/lib/bpf/libbpf.map b/tools/lib/bpf/libbpf.map
> >> new file mode 100644
> >> index 000000000000..9fe416b68c7d
> >> --- /dev/null
> >> +++ b/tools/lib/bpf/libbpf.map
> >> @@ -0,0 +1,120 @@
> >> +LIBBPF_0.0.1 {
> >> + global:
> >> + bpf_btf_get_fd_by_id;
> >
> > Do you think we could use this opportunities to
> > make naming more consistent? For example,
> > bpf_btf_get_fd_by_id => btf__get_fd_by_id?
>
> I think this one is fine since it matches
> bpf_[map|prog]_get_fd_by_id()
> and it's a wrapper.
Agree with keeping btf's get_fd_by_id() name to match with
other get_fd_by_id() interfaces.
>
> >> + bpf_create_map;
> >> + bpf_create_map_in_map;
> >> + bpf_create_map_in_map_node;
> >> + bpf_create_map_name;
> >> + bpf_create_map_node;
> >> + bpf_create_map_xattr;
> >> + bpf_load_btf;
> >> + bpf_load_program;
> >> + bpf_load_program_xattr;
> >> + bpf_map__btf_key_type_id;
> >> + bpf_map__btf_value_type_id;
> >> + bpf_map__def;
> >> + bpf_map_delete_elem; > + bpf_map__fd;
> >> + bpf_map_get_fd_by_id;
> >> + bpf_map_get_next_id;
> >> + bpf_map_get_next_key; > + bpf_map__is_offload_neutral;
> >> + bpf_map_lookup_and_delete_elem;
> >> + bpf_map_lookup_elem;
> >> + bpf_map__name;
> >> + bpf_map__next;
> >> + bpf_map__pin;
> >> + bpf_map__prev;
> >> + bpf_map__priv;
> >> + bpf_map__reuse_fd;
> >> + bpf_map__set_ifindex;
> >> + bpf_map__set_priv;
> >> + bpf_map__unpin;
> >> + bpf_map_update_elem;
> >> + bpf_object__btf_fd;
> >> + bpf_object__close;
> >> + bpf_object__find_map_by_name;
> >> + bpf_object__find_map_by_offset;
> >> + bpf_object__find_program_by_title;
> >> + bpf_object__kversion;
> >> + bpf_object__load;
> >> + bpf_object__name;
> >> + bpf_object__next;
> >> + bpf_object__open;
> >> + bpf_object__open_buffer;
> >> + bpf_object__open_xattr;
> >> + bpf_object__pin;
> >> + bpf_object__pin_maps;
> >> + bpf_object__pin_programs;
> >> + bpf_object__priv;
> >> + bpf_object__set_priv;
> >> + bpf_object__unload;
> >> + bpf_object__unpin_maps;
> >> + bpf_object__unpin_programs;
> >> + bpf_obj_get;
> >> + bpf_obj_get_info_by_fd;
> >> + bpf_obj_pin;
> >> + bpf_perf_event_read_simple;
> >> + bpf_prog_attach;
> >> + bpf_prog_detach;
> >> + bpf_prog_detach2;
> >> + bpf_prog_get_fd_by_id;
> >> + bpf_prog_get_next_id;
> >> + bpf_prog_load;
> >> + bpf_prog_load_xattr;
> >> + bpf_prog_query;
> >> + bpf_program__fd;
> >> + bpf_program__is_kprobe;
> >> + bpf_program__is_perf_event;
> >> + bpf_program__is_raw_tracepoint;
> >> + bpf_program__is_sched_act;
> >> + bpf_program__is_sched_cls;
> >> + bpf_program__is_socket_filter;
> >> + bpf_program__is_tracepoint;
> >> + bpf_program__is_xdp;
> >> + bpf_program__load;
> >> + bpf_program__next;
> >> + bpf_program__nth_fd;
> >> + bpf_program__pin;
> >> + bpf_program__pin_instance;
> >> + bpf_program__prev;
> >> + bpf_program__priv;
> >> + bpf_program__set_expected_attach_type;
> >> + bpf_program__set_ifindex;
> >> + bpf_program__set_kprobe;
> >> + bpf_program__set_perf_event;
> >> + bpf_program__set_prep;
> >> + bpf_program__set_priv;
> >> + bpf_program__set_raw_tracepoint;
> >> + bpf_program__set_sched_act;
> >> + bpf_program__set_sched_cls;
> >> + bpf_program__set_socket_filter;
> >> + bpf_program__set_tracepoint;
> >> + bpf_program__set_type;
> >> + bpf_program__set_xdp;
> >> + bpf_program__title;
> >> + bpf_program__unload;
> >> + bpf_program__unpin;
> >> + bpf_program__unpin_instance;
> >> + bpf_prog_test_run;
> >> + bpf_raw_tracepoint_open;
> >> + bpf_set_link_xdp_fd;
> >> + bpf_task_fd_query;
> >> + bpf_verify_program;
> >> + btf__fd;
> >> + btf__find_by_name;
> >> + btf__free;
> >> + btf_get_from_id;
> > btf_get_from_id => btf__get_from_id?
>
> this one makes sense indeed. Martin, thoughts?
Agree. We overlooked this in the earlier func_info patch set.
I also have this change locally in my current working patchset.
I think it makes sense to have the change go with this libbpf version
patchset as a cleanup effort. It is what I have. Feel free
to reuse any of it:
>From 32a1489619184d7965f235a86f082f2710a2ba3c Mon Sep 17 00:00:00 2001
From: Martin KaFai Lau <kafai@fb.com>
Date: Wed, 21 Nov 2018 09:21:17 -0800
Subject: [PATCH 3/8] bpf: libbpf: Name changing for btf_get_from_id
s/btf_get_from_id/btf__get_from_id/ to restore the API naming convention.
Signed-off-by: Martin KaFai Lau <kafai@fb.com>
---
tools/bpf/bpftool/map.c | 4 ++--
tools/bpf/bpftool/prog.c | 2 +-
tools/lib/bpf/btf.c | 2 +-
tools/lib/bpf/btf.h | 2 +-
tools/testing/selftests/bpf/test_btf.c | 2 +-
5 files changed, 6 insertions(+), 6 deletions(-)
diff --git a/tools/bpf/bpftool/map.c b/tools/bpf/bpftool/map.c
index a1ae2a3e9fef..96be42f288f5 100644
--- a/tools/bpf/bpftool/map.c
+++ b/tools/bpf/bpftool/map.c
@@ -711,7 +711,7 @@ static int do_dump(int argc, char **argv)
prev_key = NULL;
- err = btf_get_from_id(info.btf_id, &btf);
+ err = btf__get_from_id(info.btf_id, &btf);
if (err) {
p_err("failed to get btf");
goto exit_free;
@@ -855,7 +855,7 @@ static int do_lookup(int argc, char **argv)
}
/* here means bpf_map_lookup_elem() succeeded */
- err = btf_get_from_id(info.btf_id, &btf);
+ err = btf__get_from_id(info.btf_id, &btf);
if (err) {
p_err("failed to get btf");
goto exit_free;
diff --git a/tools/bpf/bpftool/prog.c b/tools/bpf/bpftool/prog.c
index 37b1daf19da6..521a1073d1b4 100644
--- a/tools/bpf/bpftool/prog.c
+++ b/tools/bpf/bpftool/prog.c
@@ -622,7 +622,7 @@ static int do_dump(int argc, char **argv)
goto err_free;
}
- if (info.btf_id && btf_get_from_id(info.btf_id, &btf)) {
+ if (info.btf_id && btf__get_from_id(info.btf_id, &btf)) {
p_err("failed to get btf");
goto err_free;
}
diff --git a/tools/lib/bpf/btf.c b/tools/lib/bpf/btf.c
index 13ddc4bd24ee..eadcf8dfd295 100644
--- a/tools/lib/bpf/btf.c
+++ b/tools/lib/bpf/btf.c
@@ -415,7 +415,7 @@ const char *btf__name_by_offset(const struct btf *btf, __u32 offset)
return NULL;
}
-int btf_get_from_id(__u32 id, struct btf **btf)
+int btf__get_from_id(__u32 id, struct btf **btf)
{
struct bpf_btf_info btf_info = { 0 };
__u32 len = sizeof(btf_info);
diff --git a/tools/lib/bpf/btf.h b/tools/lib/bpf/btf.h
index 386b2ffc32a3..2991b9f93e16 100644
--- a/tools/lib/bpf/btf.h
+++ b/tools/lib/bpf/btf.h
@@ -69,7 +69,7 @@ LIBBPF_API __s64 btf__resolve_size(const struct btf *btf, __u32 type_id);
LIBBPF_API int btf__resolve_type(const struct btf *btf, __u32 type_id);
LIBBPF_API int btf__fd(const struct btf *btf);
LIBBPF_API const char *btf__name_by_offset(const struct btf *btf, __u32 offset);
-LIBBPF_API int btf_get_from_id(__u32 id, struct btf **btf);
+LIBBPF_API int btf__get_from_id(__u32 id, struct btf **btf);
struct btf_ext *btf_ext__new(__u8 *data, __u32 size, btf_print_fn_t err_log);
void btf_ext__free(struct btf_ext *btf_ext);
diff --git a/tools/testing/selftests/bpf/test_btf.c b/tools/testing/selftests/bpf/test_btf.c
index 7b1b160d6e67..aa779f48cc2b 100644
--- a/tools/testing/selftests/bpf/test_btf.c
+++ b/tools/testing/selftests/bpf/test_btf.c
@@ -2604,7 +2604,7 @@ static int do_test_file(unsigned int test_num)
goto done;
}
- err = btf_get_from_id(info.btf_id, &btf);
+ err = btf__get_from_id(info.btf_id, &btf);
if (CHECK(err, "cannot get btf from kernel, err: %d", err))
goto done;
--
2.17.1
>
> >> + btf__name_by_offset;
> >> + btf__new;
> >> + btf__resolve_size;
> >> + btf__resolve_type;
> >> + btf__type_by_id;
> >> + libbpf_attach_type_by_name;
> >> + libbpf_get_error;
> >> + libbpf_prog_type_by_name;
> >> + libbpf_set_print;
> >> + libbpf_strerror;
> >
> > Anything else? We have btf__, bpf_program__ prefixes with double "_"
> > while with libbpf_, bpf_<wrapper> as single "_". Not sure whether they
> > need change or not.
>
> the convention is that syscall wrappers like bpf_map_lookup_elem()
> have single _ and map one-to-one to syscall commands.
> Double _ is for objects. That's a coding style of perf.
> Today btf, bpf_program, bpf_map, bpf_objects are objects.
> libbpf_ is a prefix for auxiliary funcs.
>
> We need to document it in a readme file.
^ permalink raw reply related
* [PATCH net] net: phy: add workaround for issue where PHY driver doesn't bind to the device
From: Heiner Kallweit @ 2018-11-23 18:41 UTC (permalink / raw)
To: Andrew Lunn, Florian Fainelli, David Miller; +Cc: netdev@vger.kernel.org
After switching the r8169 driver to use phylib some user reported that
their network is broken. This was caused by the genphy PHY driver being
used instead of the dedicated PHY driver for the RTL8211B. Users
reported that loading the Realtek PHY driver module upfront fixes the
issue. See also this mail thread:
https://marc.info/?t=154279781800003&r=1&w=2
The issue is quite weird and the root cause seems to be somewhere in
the base driver core. The patch works around the issue and may be
removed once the actual issue is fixed.
The Fixes tag refers to the first reported occurrence of the issue.
The issue itself may have been existing much longer and it may affect
users of other network chips as well. Users typically will recognize
this issue only if their PHY stops working when being used with the
genphy driver.
Fixes: f1e911d5d0df ("r8169: add basic phylib support")
Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
---
I'm not sure how long it will take to find and fix the root cause of
the issue. With this workaround affected users have a working network
again from 4.19.5 at least.
---
drivers/net/phy/phy_device.c | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c
index e06613f2d..0904002b1 100644
--- a/drivers/net/phy/phy_device.c
+++ b/drivers/net/phy/phy_device.c
@@ -2255,6 +2255,14 @@ int phy_driver_register(struct phy_driver *new_driver, struct module *owner)
new_driver->mdiodrv.driver.remove = phy_remove;
new_driver->mdiodrv.driver.owner = owner;
+ /* The following works around an issue where the PHY driver doesn't bind
+ * to the device, resulting in the genphy driver being used instead of
+ * the dedicated driver. The root cause of the issue isn't known yet
+ * and seems to be in the base driver core. Once this is fixed we may
+ * remove this workaround.
+ */
+ new_driver->mdiodrv.driver.probe_type = PROBE_FORCE_SYNCHRONOUS;
+
retval = driver_register(&new_driver->mdiodrv.driver);
if (retval) {
pr_err("%s: Error %d in registering driver\n",
--
2.19.1
^ permalink raw reply related
* Re: [PATCH] dt-bindings: dsa: Fix typo in "probed"
From: Andrew Lunn @ 2018-11-23 18:02 UTC (permalink / raw)
To: Fabio Estevam; +Cc: davem, netdev, f.fainelli
In-Reply-To: <1542995210-22428-1-git-send-email-festevam@gmail.com>
On Fri, Nov 23, 2018 at 03:46:50PM -0200, Fabio Estevam wrote:
> The correct form is "can be probed", so fix the typo.
>
> Signed-off-by: Fabio Estevam <festevam@gmail.com>
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
Andrew
^ permalink raw reply
* [PATCH] dt-bindings: dsa: Fix typo in "probed"
From: Fabio Estevam @ 2018-11-23 17:46 UTC (permalink / raw)
To: davem; +Cc: andrew, netdev, f.fainelli, Fabio Estevam
The correct form is "can be probed", so fix the typo.
Signed-off-by: Fabio Estevam <festevam@gmail.com>
---
Documentation/devicetree/bindings/net/dsa/dsa.txt | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Documentation/devicetree/bindings/net/dsa/dsa.txt b/Documentation/devicetree/bindings/net/dsa/dsa.txt
index 3ceeb8d..35694c0 100644
--- a/Documentation/devicetree/bindings/net/dsa/dsa.txt
+++ b/Documentation/devicetree/bindings/net/dsa/dsa.txt
@@ -7,7 +7,7 @@ limitations.
Current Binding
---------------
-Switches are true Linux devices and can be probes by any means. Once
+Switches are true Linux devices and can be probed by any means. Once
probed, they register to the DSA framework, passing a node
pointer. This node is expected to fulfil the following binding, and
may contain additional properties as required by the device it is
--
2.7.4
^ permalink raw reply related
* [PATCH net] net: thunderx: set tso_hdrs pointer to NULL in nicvf_free_snd_queue
From: Lorenzo Bianconi @ 2018-11-23 17:28 UTC (permalink / raw)
To: netdev; +Cc: davem, Sunil.Goutham
In-Reply-To: <cover.1542993848.git.lorenzo.bianconi@redhat.com>
Reset snd_queue tso_hdrs pointer to NULL in nicvf_free_snd_queue routine
since it is used to check if tso dma descriptor queue has been previously
allocated. The issue can be triggered with the following reproducer:
$ip link set dev enP2p1s0v0 xdpdrv obj xdp_dummy.o
$ip link set dev enP2p1s0v0 xdpdrv off
[ 341.467649] WARNING: CPU: 74 PID: 2158 at mm/vmalloc.c:1511 __vunmap+0x98/0xe0
[ 341.515010] Hardware name: GIGABYTE H270-T70/MT70-HD0, BIOS T49 02/02/2018
[ 341.521874] pstate: 60400005 (nZCv daif +PAN -UAO)
[ 341.526654] pc : __vunmap+0x98/0xe0
[ 341.530132] lr : __vunmap+0x98/0xe0
[ 341.533609] sp : ffff00001c5db860
[ 341.536913] x29: ffff00001c5db860 x28: 0000000000020000
[ 341.542214] x27: ffff810feb5090b0 x26: ffff000017e57000
[ 341.547515] x25: 0000000000000000 x24: 00000000fbd00000
[ 341.552816] x23: 0000000000000000 x22: ffff810feb5090b0
[ 341.558117] x21: 0000000000000000 x20: 0000000000000000
[ 341.563418] x19: ffff000017e57000 x18: 0000000000000000
[ 341.568719] x17: 0000000000000000 x16: 0000000000000000
[ 341.574020] x15: 0000000000000010 x14: ffffffffffffffff
[ 341.579321] x13: ffff00008985eb27 x12: ffff00000985eb2f
[ 341.584622] x11: ffff0000096b3000 x10: ffff00001c5db510
[ 341.589923] x9 : 00000000ffffffd0 x8 : ffff0000086868e8
[ 341.595224] x7 : 3430303030303030 x6 : 00000000000006ef
[ 341.600525] x5 : 00000000003fffff x4 : 0000000000000000
[ 341.605825] x3 : 0000000000000000 x2 : ffffffffffffffff
[ 341.611126] x1 : ffff0000096b3728 x0 : 0000000000000038
[ 341.616428] Call trace:
[ 341.618866] __vunmap+0x98/0xe0
[ 341.621997] vunmap+0x3c/0x50
[ 341.624961] arch_dma_free+0x68/0xa0
[ 341.628534] dma_direct_free+0x50/0x80
[ 341.632285] nicvf_free_resources+0x160/0x2d8 [nicvf]
[ 341.637327] nicvf_config_data_transfer+0x174/0x5e8 [nicvf]
[ 341.642890] nicvf_stop+0x298/0x340 [nicvf]
[ 341.647066] __dev_close_many+0x9c/0x108
[ 341.650977] dev_close_many+0xa4/0x158
[ 341.654720] rollback_registered_many+0x140/0x530
[ 341.659414] rollback_registered+0x54/0x80
[ 341.663499] unregister_netdevice_queue+0x9c/0xe8
[ 341.668192] unregister_netdev+0x28/0x38
[ 341.672106] nicvf_remove+0xa4/0xa8 [nicvf]
[ 341.676280] nicvf_shutdown+0x20/0x30 [nicvf]
[ 341.680630] pci_device_shutdown+0x44/0x88
[ 341.684720] device_shutdown+0x144/0x250
[ 341.688640] kernel_restart_prepare+0x44/0x50
[ 341.692986] kernel_restart+0x20/0x68
[ 341.696638] __se_sys_reboot+0x210/0x238
[ 341.700550] __arm64_sys_reboot+0x24/0x30
[ 341.704555] el0_svc_handler+0x94/0x110
[ 341.708382] el0_svc+0x8/0xc
[ 341.711252] ---[ end trace 3f4019c8439959c9 ]---
[ 341.715874] page:ffff7e0003ef4000 count:0 mapcount:0 mapping:0000000000000000 index:0x4
[ 341.723872] flags: 0x1fffe000000000()
[ 341.727527] raw: 001fffe000000000 ffff7e0003f1a008 ffff7e0003ef4048 0000000000000000
[ 341.735263] raw: 0000000000000004 0000000000000000 00000000ffffffff 0000000000000000
[ 341.742994] page dumped because: VM_BUG_ON_PAGE(page_ref_count(page) == 0)
where xdp_dummy.c is a simple bpf program that forwards the incoming
frames to the network stack (available here:
https://github.com/altoor/xdp_walkthrough_examples/blob/master/sample_1/xdp_dummy.c)
Fixes: 05c773f52b96 ("net: thunderx: Add basic XDP support")
Fixes: 4863dea3fab0 ("net: Adding support for Cavium ThunderX network
controller")
Signed-off-by: Lorenzo Bianconi <lorenzo.bianconi@redhat.com>
---
drivers/net/ethernet/cavium/thunder/nicvf_queues.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/cavium/thunder/nicvf_queues.c b/drivers/net/ethernet/cavium/thunder/nicvf_queues.c
index 187a249ff2d1..fcaf18fa3904 100644
--- a/drivers/net/ethernet/cavium/thunder/nicvf_queues.c
+++ b/drivers/net/ethernet/cavium/thunder/nicvf_queues.c
@@ -585,10 +585,12 @@ static void nicvf_free_snd_queue(struct nicvf *nic, struct snd_queue *sq)
if (!sq->dmem.base)
return;
- if (sq->tso_hdrs)
+ if (sq->tso_hdrs) {
dma_free_coherent(&nic->pdev->dev,
sq->dmem.q_len * TSO_HEADER_SIZE,
sq->tso_hdrs, sq->tso_hdrs_phys);
+ sq->tso_hdrs = NULL;
+ }
/* Free pending skbs in the queue */
smp_rmb();
--
2.19.1
^ permalink raw reply related
* Fw: [Bug 201773] New: IP_FREEBIND doesn’t counteract global
From: Stephen Hemminger @ 2018-11-23 17:23 UTC (permalink / raw)
To: netdev
Could be a bug, or just how it works?
Begin forwarded message:
Date: Thu, 22 Nov 2018 22:51:12 +0000
From: bugzilla-daemon@bugzilla.kernel.org
To: stephen@networkplumber.org
Subject: [Bug 201773] New: IP_FREEBIND doesn’t counteract global
https://bugzilla.kernel.org/show_bug.cgi?id=201773
Bug ID: 201773
Summary: IP_FREEBIND doesn’t counteract global
Product: Networking
Version: 2.5
Kernel Version: 3.10.0-862.11.6.el7.x86_64
Hardware: All
OS: Linux
Tree: Mainline
Status: NEW
Severity: normal
Priority: P1
Component: IPV4
Assignee: stephen@networkplumber.org
Reporter: felipe@felipegasper.com
Regression: No
The following should fail, regardless of /proc/sys/net/ipv4/ip_nonlocal_bind:
-----
> strace -e socket,setsockopt,bind perl -MSocket -Mautodie -e'socket my $s,
> PF_INET, SOCK_STREAM, 0; setsockopt( $s, IPPROTO_IP, 15, 0 ); bind( $s,
> pack_sockaddr_in( 0, inet_aton("1.2.3.4") ) );'
socket(AF_INET, SOCK_STREAM, IPPROTO_IP) = 3
setsockopt(3, SOL_IP, IP_FREEBIND, [0], 4) = 0
bind(3, {sa_family=AF_INET, sin_port=htons(0), sin_addr=inet_addr("1.2.3.4")},
16) = 0
+++ exited with 0 +++
-----
… however, it appears that setsockopt() doesn’t disable IP_FREEBIND if
ip_nonlocal_bind is set via /proc.
--
You are receiving this mail because:
You are the assignee for the bug.
^ permalink raw reply
* [PATCH net-next 6/8] dpaa2-eth: Add support for XDP_TX
From: Ioana Ciocoi Radulescu @ 2018-11-23 16:56 UTC (permalink / raw)
To: netdev@vger.kernel.org, davem@davemloft.net; +Cc: Ioana Ciornei
In-Reply-To: <1542992186-26028-1-git-send-email-ruxandra.radulescu@nxp.com>
Send frames back on the same port for XDP_TX action.
Since the frame buffers have been allocated by us, we can recycle
them directly into the Rx buffer pool instead of requesting a
confirmation frame upon transmission complete.
Signed-off-by: Ioana Radulescu <ruxandra.radulescu@nxp.com>
---
drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c | 43 +++++++++++++++++++++++-
drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.h | 2 ++
2 files changed, 44 insertions(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c b/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c
index 1bdcd71..3dabee0 100644
--- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c
+++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c
@@ -240,14 +240,50 @@ static void xdp_release_buf(struct dpaa2_eth_priv *priv,
ch->xdp.drop_cnt = 0;
}
+static int xdp_enqueue(struct dpaa2_eth_priv *priv, struct dpaa2_fd *fd,
+ void *buf_start, u16 queue_id)
+{
+ struct dpaa2_eth_fq *fq;
+ struct dpaa2_faead *faead;
+ u32 ctrl, frc;
+ int i, err;
+
+ /* Mark the egress frame hardware annotation area as valid */
+ frc = dpaa2_fd_get_frc(fd);
+ dpaa2_fd_set_frc(fd, frc | DPAA2_FD_FRC_FAEADV);
+ dpaa2_fd_set_ctrl(fd, DPAA2_FD_CTRL_ASAL);
+
+ /* Instruct hardware to release the FD buffer directly into
+ * the buffer pool once transmission is completed, instead of
+ * sending a Tx confirmation frame to us
+ */
+ ctrl = DPAA2_FAEAD_A4V | DPAA2_FAEAD_A2V | DPAA2_FAEAD_EBDDV;
+ faead = dpaa2_get_faead(buf_start, false);
+ faead->ctrl = cpu_to_le32(ctrl);
+ faead->conf_fqid = 0;
+
+ fq = &priv->fq[queue_id];
+ for (i = 0; i < DPAA2_ETH_ENQUEUE_RETRIES; i++) {
+ err = dpaa2_io_service_enqueue_qd(fq->channel->dpio,
+ priv->tx_qdid, 0,
+ fq->tx_qdbin, fd);
+ if (err != -EBUSY)
+ break;
+ }
+
+ return err;
+}
+
static u32 run_xdp(struct dpaa2_eth_priv *priv,
struct dpaa2_eth_channel *ch,
+ struct dpaa2_eth_fq *rx_fq,
struct dpaa2_fd *fd, void *vaddr)
{
dma_addr_t addr = dpaa2_fd_get_addr(fd);
struct bpf_prog *xdp_prog;
struct xdp_buff xdp;
u32 xdp_act = XDP_PASS;
+ int err;
rcu_read_lock();
@@ -269,6 +305,11 @@ static u32 run_xdp(struct dpaa2_eth_priv *priv,
switch (xdp_act) {
case XDP_PASS:
break;
+ case XDP_TX:
+ err = xdp_enqueue(priv, fd, vaddr, rx_fq->flowid);
+ if (err)
+ xdp_release_buf(priv, ch, addr);
+ break;
default:
bpf_warn_invalid_xdp_action(xdp_act);
case XDP_ABORTED:
@@ -317,7 +358,7 @@ static void dpaa2_eth_rx(struct dpaa2_eth_priv *priv,
percpu_extras = this_cpu_ptr(priv->percpu_extras);
if (fd_format == dpaa2_fd_single) {
- xdp_act = run_xdp(priv, ch, (struct dpaa2_fd *)fd, vaddr);
+ xdp_act = run_xdp(priv, ch, fq, (struct dpaa2_fd *)fd, vaddr);
if (xdp_act != XDP_PASS)
return;
diff --git a/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.h b/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.h
index 23cf9d9..5530a0e 100644
--- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.h
+++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.h
@@ -139,7 +139,9 @@ struct dpaa2_faead {
};
#define DPAA2_FAEAD_A2V 0x20000000
+#define DPAA2_FAEAD_A4V 0x08000000
#define DPAA2_FAEAD_UPDV 0x00001000
+#define DPAA2_FAEAD_EBDDV 0x00002000
#define DPAA2_FAEAD_UPD 0x00000010
/* Accessors for the hardware annotation fields that we use */
--
2.7.4
^ permalink raw reply related
* [PATCH net-next 5/8] dpaa2-eth: Map Rx buffers as bidirectional
From: Ioana Ciocoi Radulescu @ 2018-11-23 16:56 UTC (permalink / raw)
To: netdev@vger.kernel.org, davem@davemloft.net; +Cc: Ioana Ciornei
In-Reply-To: <1542992186-26028-1-git-send-email-ruxandra.radulescu@nxp.com>
In order to support enqueueing Rx FDs back to hardware, we need to
DMA map Rx buffers as bidirectional.
Signed-off-by: Ioana Radulescu <ruxandra.radulescu@nxp.com>
---
drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c | 14 +++++++-------
1 file changed, 7 insertions(+), 7 deletions(-)
diff --git a/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c b/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c
index 6256154..1bdcd71 100644
--- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c
+++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c
@@ -87,7 +87,7 @@ static void free_rx_fd(struct dpaa2_eth_priv *priv,
addr = dpaa2_sg_get_addr(&sgt[i]);
sg_vaddr = dpaa2_iova_to_virt(priv->iommu_domain, addr);
dma_unmap_single(dev, addr, DPAA2_ETH_RX_BUF_SIZE,
- DMA_FROM_DEVICE);
+ DMA_BIDIRECTIONAL);
skb_free_frag(sg_vaddr);
if (dpaa2_sg_is_final(&sgt[i]))
@@ -145,7 +145,7 @@ static struct sk_buff *build_frag_skb(struct dpaa2_eth_priv *priv,
sg_addr = dpaa2_sg_get_addr(sge);
sg_vaddr = dpaa2_iova_to_virt(priv->iommu_domain, sg_addr);
dma_unmap_single(dev, sg_addr, DPAA2_ETH_RX_BUF_SIZE,
- DMA_FROM_DEVICE);
+ DMA_BIDIRECTIONAL);
sg_length = dpaa2_sg_get_len(sge);
@@ -212,7 +212,7 @@ static void free_bufs(struct dpaa2_eth_priv *priv, u64 *buf_array, int count)
for (i = 0; i < count; i++) {
vaddr = dpaa2_iova_to_virt(priv->iommu_domain, buf_array[i]);
dma_unmap_single(dev, buf_array[i], DPAA2_ETH_RX_BUF_SIZE,
- DMA_FROM_DEVICE);
+ DMA_BIDIRECTIONAL);
skb_free_frag(vaddr);
}
}
@@ -306,7 +306,7 @@ static void dpaa2_eth_rx(struct dpaa2_eth_priv *priv,
vaddr = dpaa2_iova_to_virt(priv->iommu_domain, addr);
dma_sync_single_for_cpu(dev, addr, DPAA2_ETH_RX_BUF_SIZE,
- DMA_FROM_DEVICE);
+ DMA_BIDIRECTIONAL);
fas = dpaa2_get_fas(vaddr, false);
prefetch(fas);
@@ -322,13 +322,13 @@ static void dpaa2_eth_rx(struct dpaa2_eth_priv *priv,
return;
dma_unmap_single(dev, addr, DPAA2_ETH_RX_BUF_SIZE,
- DMA_FROM_DEVICE);
+ DMA_BIDIRECTIONAL);
skb = build_linear_skb(ch, fd, vaddr);
} else if (fd_format == dpaa2_fd_sg) {
WARN_ON(priv->xdp_prog);
dma_unmap_single(dev, addr, DPAA2_ETH_RX_BUF_SIZE,
- DMA_FROM_DEVICE);
+ DMA_BIDIRECTIONAL);
skb = build_frag_skb(priv, ch, buf_data);
skb_free_frag(vaddr);
percpu_extras->rx_sg_frames++;
@@ -862,7 +862,7 @@ static int add_bufs(struct dpaa2_eth_priv *priv,
buf = PTR_ALIGN(buf, priv->rx_buf_align);
addr = dma_map_single(dev, buf, DPAA2_ETH_RX_BUF_SIZE,
- DMA_FROM_DEVICE);
+ DMA_BIDIRECTIONAL);
if (unlikely(dma_mapping_error(dev, addr)))
goto err_map;
--
2.7.4
^ permalink raw reply related
* [PATCH net-next 7/8] dpaa2-eth: Cleanup channel stats
From: Ioana Ciocoi Radulescu @ 2018-11-23 16:56 UTC (permalink / raw)
To: netdev@vger.kernel.org, davem@davemloft.net; +Cc: Ioana Ciornei
In-Reply-To: <1542992186-26028-1-git-send-email-ruxandra.radulescu@nxp.com>
Remove one unused counter. Move the Tx portal busy counter to
the channel stats, since it logically belongs here.
Reorder fields in channel stats structure to match the ethtool
strings order and make it easier to print them with ethtool -S.
Signed-off-by: Ioana Radulescu <ruxandra.radulescu@nxp.com>
---
drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c | 3 +--
drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.h | 10 ++++------
drivers/net/ethernet/freescale/dpaa2/dpaa2-ethtool.c | 18 ++++++------------
3 files changed, 11 insertions(+), 20 deletions(-)
diff --git a/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c b/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c
index 3dabee0..995a17d 100644
--- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c
+++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c
@@ -456,7 +456,6 @@ static int consume_frames(struct dpaa2_eth_channel *ch,
return 0;
fq->stats.frames += cleaned;
- ch->stats.frames += cleaned;
/* A dequeue operation only pulls frames from a single queue
* into the store. Return the frame queue as an out param.
@@ -776,7 +775,7 @@ static netdev_tx_t dpaa2_eth_tx(struct sk_buff *skb, struct net_device *net_dev)
if (err != -EBUSY)
break;
}
- percpu_extras->tx_portal_busy += i;
+ fq->channel->stats.tx_portal_busy += i;
if (unlikely(err < 0)) {
percpu_stats->tx_errors++;
/* Clean up everything, including freeing the skb */
diff --git a/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.h b/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.h
index 5530a0e..320c0d0 100644
--- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.h
+++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.h
@@ -231,8 +231,6 @@ struct dpaa2_eth_drv_stats {
__u64 tx_reallocs;
__u64 rx_sg_frames;
__u64 rx_sg_bytes;
- /* Enqueues retried due to portal busy */
- __u64 tx_portal_busy;
};
/* Per-FQ statistics */
@@ -243,14 +241,14 @@ struct dpaa2_eth_fq_stats {
/* Per-channel statistics */
struct dpaa2_eth_ch_stats {
+ /* Enqueues retried due to portal busy */
+ __u64 tx_portal_busy;
/* Volatile dequeues retried due to portal busy */
__u64 dequeue_portal_busy;
- /* Number of CDANs; useful to estimate avg NAPI len */
- __u64 cdan;
- /* Number of frames received on queues from this channel */
- __u64 frames;
/* Pull errors */
__u64 pull_err;
+ /* Number of CDANs; useful to estimate avg NAPI len */
+ __u64 cdan;
};
/* Maximum number of queues associated with a DPNI */
diff --git a/drivers/net/ethernet/freescale/dpaa2/dpaa2-ethtool.c b/drivers/net/ethernet/freescale/dpaa2/dpaa2-ethtool.c
index 26bd5a2..3aa7885 100644
--- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-ethtool.c
+++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-ethtool.c
@@ -40,8 +40,8 @@ static char dpaa2_ethtool_extras[][ETH_GSTRING_LEN] = {
"[drv] tx realloc frames",
"[drv] rx sg frames",
"[drv] rx sg bytes",
- "[drv] enqueue portal busy",
/* Channel stats */
+ "[drv] enqueue portal busy",
"[drv] dequeue portal busy",
"[drv] channel pull errors",
"[drv] cdan",
@@ -174,8 +174,6 @@ static void dpaa2_eth_get_ethtool_stats(struct net_device *net_dev,
int j, k, err;
int num_cnt;
union dpni_statistics dpni_stats;
- u64 cdan = 0;
- u64 portal_busy = 0, pull_err = 0;
struct dpaa2_eth_priv *priv = netdev_priv(net_dev);
struct dpaa2_eth_drv_stats *extras;
struct dpaa2_eth_ch_stats *ch_stats;
@@ -212,16 +210,12 @@ static void dpaa2_eth_get_ethtool_stats(struct net_device *net_dev,
}
i += j;
- for (j = 0; j < priv->num_channels; j++) {
- ch_stats = &priv->channel[j]->stats;
- cdan += ch_stats->cdan;
- portal_busy += ch_stats->dequeue_portal_busy;
- pull_err += ch_stats->pull_err;
+ /* Per-channel stats */
+ for (k = 0; k < priv->num_channels; k++) {
+ ch_stats = &priv->channel[k]->stats;
+ for (j = 0; j < sizeof(*ch_stats) / sizeof(__u64); j++)
+ *((__u64 *)data + i + j) += *((__u64 *)ch_stats + j);
}
-
- *(data + i++) = portal_busy;
- *(data + i++) = pull_err;
- *(data + i++) = cdan;
}
static int prep_eth_rule(struct ethhdr *eth_value, struct ethhdr *eth_mask,
--
2.7.4
^ permalink raw reply related
* [PATCH net-next 4/8] dpaa2-eth: Release buffers back to pool on XDP_DROP
From: Ioana Ciocoi Radulescu @ 2018-11-23 16:56 UTC (permalink / raw)
To: netdev@vger.kernel.org, davem@davemloft.net; +Cc: Ioana Ciornei
In-Reply-To: <1542992186-26028-1-git-send-email-ruxandra.radulescu@nxp.com>
Instead of freeing the RX buffers, release them back into the pool.
We wait for the maximum number of buffers supported by a single
release command to accumulate before issuing the command.
Also, don't unmap the Rx buffers at the beginning of the Rx routine
anymore, since that would require remapping them before release.
Instead, just do a DMA sync at first and only unmap if the frame is
meant for the stack.
Signed-off-by: Ioana Radulescu <ruxandra.radulescu@nxp.com>
---
drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c | 34 +++++++++++++++++++++---
drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.h | 2 ++
2 files changed, 33 insertions(+), 3 deletions(-)
diff --git a/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c b/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c
index 9ed4d8e..6256154 100644
--- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c
+++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c
@@ -217,10 +217,34 @@ static void free_bufs(struct dpaa2_eth_priv *priv, u64 *buf_array, int count)
}
}
+static void xdp_release_buf(struct dpaa2_eth_priv *priv,
+ struct dpaa2_eth_channel *ch,
+ dma_addr_t addr)
+{
+ int err;
+
+ ch->xdp.drop_bufs[ch->xdp.drop_cnt++] = addr;
+ if (ch->xdp.drop_cnt < DPAA2_ETH_BUFS_PER_CMD)
+ return;
+
+ while ((err = dpaa2_io_service_release(ch->dpio, priv->bpid,
+ ch->xdp.drop_bufs,
+ ch->xdp.drop_cnt)) == -EBUSY)
+ cpu_relax();
+
+ if (err) {
+ free_bufs(priv, ch->xdp.drop_bufs, ch->xdp.drop_cnt);
+ ch->buf_count -= ch->xdp.drop_cnt;
+ }
+
+ ch->xdp.drop_cnt = 0;
+}
+
static u32 run_xdp(struct dpaa2_eth_priv *priv,
struct dpaa2_eth_channel *ch,
struct dpaa2_fd *fd, void *vaddr)
{
+ dma_addr_t addr = dpaa2_fd_get_addr(fd);
struct bpf_prog *xdp_prog;
struct xdp_buff xdp;
u32 xdp_act = XDP_PASS;
@@ -250,8 +274,7 @@ static u32 run_xdp(struct dpaa2_eth_priv *priv,
case XDP_ABORTED:
trace_xdp_exception(priv->net_dev, xdp_prog, xdp_act);
case XDP_DROP:
- ch->buf_count--;
- free_rx_fd(priv, fd, vaddr);
+ xdp_release_buf(priv, ch, addr);
break;
}
@@ -282,7 +305,8 @@ static void dpaa2_eth_rx(struct dpaa2_eth_priv *priv,
trace_dpaa2_rx_fd(priv->net_dev, fd);
vaddr = dpaa2_iova_to_virt(priv->iommu_domain, addr);
- dma_unmap_single(dev, addr, DPAA2_ETH_RX_BUF_SIZE, DMA_FROM_DEVICE);
+ dma_sync_single_for_cpu(dev, addr, DPAA2_ETH_RX_BUF_SIZE,
+ DMA_FROM_DEVICE);
fas = dpaa2_get_fas(vaddr, false);
prefetch(fas);
@@ -297,10 +321,14 @@ static void dpaa2_eth_rx(struct dpaa2_eth_priv *priv,
if (xdp_act != XDP_PASS)
return;
+ dma_unmap_single(dev, addr, DPAA2_ETH_RX_BUF_SIZE,
+ DMA_FROM_DEVICE);
skb = build_linear_skb(ch, fd, vaddr);
} else if (fd_format == dpaa2_fd_sg) {
WARN_ON(priv->xdp_prog);
+ dma_unmap_single(dev, addr, DPAA2_ETH_RX_BUF_SIZE,
+ DMA_FROM_DEVICE);
skb = build_frag_skb(priv, ch, buf_data);
skb_free_frag(vaddr);
percpu_extras->rx_sg_frames++;
diff --git a/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.h b/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.h
index 2873a15..23cf9d9 100644
--- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.h
+++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.h
@@ -285,6 +285,8 @@ struct dpaa2_eth_fq {
struct dpaa2_eth_ch_xdp {
struct bpf_prog *prog;
+ u64 drop_bufs[DPAA2_ETH_BUFS_PER_CMD];
+ int drop_cnt;
};
struct dpaa2_eth_channel {
--
2.7.4
^ permalink raw reply related
* [PATCH net-next 3/8] dpaa2-eth: Move function
From: Ioana Ciocoi Radulescu @ 2018-11-23 16:56 UTC (permalink / raw)
To: netdev@vger.kernel.org, davem@davemloft.net; +Cc: Ioana Ciornei
In-Reply-To: <1542992186-26028-1-git-send-email-ruxandra.radulescu@nxp.com>
We'll use function free_bufs() on the XDP path as well, so move
it higher in order to avoid a forward declaration.
Signed-off-by: Ioana Radulescu <ruxandra.radulescu@nxp.com>
---
drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c | 34 ++++++++++++------------
1 file changed, 17 insertions(+), 17 deletions(-)
diff --git a/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c b/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c
index 5be3008..9ed4d8e 100644
--- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c
+++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c
@@ -200,6 +200,23 @@ static struct sk_buff *build_frag_skb(struct dpaa2_eth_priv *priv,
return skb;
}
+/* Free buffers acquired from the buffer pool or which were meant to
+ * be released in the pool
+ */
+static void free_bufs(struct dpaa2_eth_priv *priv, u64 *buf_array, int count)
+{
+ struct device *dev = priv->net_dev->dev.parent;
+ void *vaddr;
+ int i;
+
+ for (i = 0; i < count; i++) {
+ vaddr = dpaa2_iova_to_virt(priv->iommu_domain, buf_array[i]);
+ dma_unmap_single(dev, buf_array[i], DPAA2_ETH_RX_BUF_SIZE,
+ DMA_FROM_DEVICE);
+ skb_free_frag(vaddr);
+ }
+}
+
static u32 run_xdp(struct dpaa2_eth_priv *priv,
struct dpaa2_eth_channel *ch,
struct dpaa2_fd *fd, void *vaddr)
@@ -794,23 +811,6 @@ static int set_tx_csum(struct dpaa2_eth_priv *priv, bool enable)
return 0;
}
-/* Free buffers acquired from the buffer pool or which were meant to
- * be released in the pool
- */
-static void free_bufs(struct dpaa2_eth_priv *priv, u64 *buf_array, int count)
-{
- struct device *dev = priv->net_dev->dev.parent;
- void *vaddr;
- int i;
-
- for (i = 0; i < count; i++) {
- vaddr = dpaa2_iova_to_virt(priv->iommu_domain, buf_array[i]);
- dma_unmap_single(dev, buf_array[i], DPAA2_ETH_RX_BUF_SIZE,
- DMA_FROM_DEVICE);
- skb_free_frag(vaddr);
- }
-}
-
/* Perform a single release command to add buffers
* to the specified buffer pool
*/
--
2.7.4
^ permalink raw reply related
* [PATCH net-next 2/8] dpaa2-eth: Allow XDP header adjustments
From: Ioana Ciocoi Radulescu @ 2018-11-23 16:56 UTC (permalink / raw)
To: netdev@vger.kernel.org, davem@davemloft.net; +Cc: Ioana Ciornei
In-Reply-To: <1542992186-26028-1-git-send-email-ruxandra.radulescu@nxp.com>
Reserve XDP_PACKET_HEADROOM bytes in Rx buffers to allow XDP
programs to increase frame header size.
Signed-off-by: Ioana Radulescu <ruxandra.radulescu@nxp.com>
---
drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c | 43 ++++++++++++++++++++++--
1 file changed, 40 insertions(+), 3 deletions(-)
diff --git a/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c b/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c
index 5340ac9..5be3008 100644
--- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c
+++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c
@@ -216,11 +216,15 @@ static u32 run_xdp(struct dpaa2_eth_priv *priv,
xdp.data = vaddr + dpaa2_fd_get_offset(fd);
xdp.data_end = xdp.data + dpaa2_fd_get_len(fd);
- xdp.data_hard_start = xdp.data;
+ xdp.data_hard_start = xdp.data - XDP_PACKET_HEADROOM;
xdp_set_data_meta_invalid(&xdp);
xdp_act = bpf_prog_run_xdp(xdp_prog, &xdp);
+ /* xdp.data pointer may have changed */
+ dpaa2_fd_set_offset(fd, xdp.data - vaddr);
+ dpaa2_fd_set_len(fd, xdp.data_end - xdp.data);
+
switch (xdp_act) {
case XDP_PASS:
break;
@@ -1480,7 +1484,7 @@ static bool xdp_mtu_valid(struct dpaa2_eth_priv *priv, int mtu)
mfl = DPAA2_ETH_L2_MAX_FRM(mtu);
linear_mfl = DPAA2_ETH_RX_BUF_SIZE - DPAA2_ETH_RX_HWA_SIZE -
- dpaa2_eth_rx_head_room(priv);
+ dpaa2_eth_rx_head_room(priv) - XDP_PACKET_HEADROOM;
return (mfl <= linear_mfl);
}
@@ -1528,6 +1532,32 @@ static int dpaa2_eth_change_mtu(struct net_device *dev, int new_mtu)
return 0;
}
+static int update_rx_buffer_headroom(struct dpaa2_eth_priv *priv, bool has_xdp)
+{
+ struct dpni_buffer_layout buf_layout = {0};
+ int err;
+
+ err = dpni_get_buffer_layout(priv->mc_io, 0, priv->mc_token,
+ DPNI_QUEUE_RX, &buf_layout);
+ if (err) {
+ netdev_err(priv->net_dev, "dpni_get_buffer_layout failed\n");
+ return err;
+ }
+
+ /* Reserve extra headroom for XDP header size changes */
+ buf_layout.data_head_room = dpaa2_eth_rx_head_room(priv) +
+ (has_xdp ? XDP_PACKET_HEADROOM : 0);
+ buf_layout.options = DPNI_BUF_LAYOUT_OPT_DATA_HEAD_ROOM;
+ err = dpni_set_buffer_layout(priv->mc_io, 0, priv->mc_token,
+ DPNI_QUEUE_RX, &buf_layout);
+ if (err) {
+ netdev_err(priv->net_dev, "dpni_set_buffer_layout failed\n");
+ return err;
+ }
+
+ return 0;
+}
+
static int setup_xdp(struct net_device *dev, struct bpf_prog *prog)
{
struct dpaa2_eth_priv *priv = netdev_priv(dev);
@@ -1553,11 +1583,18 @@ static int setup_xdp(struct net_device *dev, struct bpf_prog *prog)
if (up)
dpaa2_eth_stop(dev);
- /* While in xdp mode, enforce a maximum Rx frame size based on MTU */
+ /* While in xdp mode, enforce a maximum Rx frame size based on MTU.
+ * Also, when switching between xdp/non-xdp modes we need to reconfigure
+ * our Rx buffer layout. Buffer pool was drained on dpaa2_eth_stop,
+ * so we are sure no old format buffers will be used from now on.
+ */
if (update_settings) {
err = set_rx_mfl(priv, dev->mtu, !!prog);
if (err)
goto out_err;
+ err = update_rx_buffer_headroom(priv, !!prog);
+ if (err)
+ goto out_err;
}
old = xchg(&priv->xdp_prog, prog);
--
2.7.4
^ permalink raw reply related
* [PATCH net-next 8/8] dpaa2-eth: Add xdp counters
From: Ioana Ciocoi Radulescu @ 2018-11-23 16:56 UTC (permalink / raw)
To: netdev@vger.kernel.org, davem@davemloft.net; +Cc: Ioana Ciornei
In-Reply-To: <1542992186-26028-1-git-send-email-ruxandra.radulescu@nxp.com>
Add counters for xdp processed frames to the channel statistics.
Signed-off-by: Ioana Radulescu <ruxandra.radulescu@nxp.com>
---
drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c | 7 ++++++-
drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.h | 4 ++++
drivers/net/ethernet/freescale/dpaa2/dpaa2-ethtool.c | 3 +++
3 files changed, 13 insertions(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c b/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c
index 995a17d..4305e76 100644
--- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c
+++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c
@@ -307,8 +307,12 @@ static u32 run_xdp(struct dpaa2_eth_priv *priv,
break;
case XDP_TX:
err = xdp_enqueue(priv, fd, vaddr, rx_fq->flowid);
- if (err)
+ if (err) {
xdp_release_buf(priv, ch, addr);
+ ch->stats.xdp_tx_err++;
+ } else {
+ ch->stats.xdp_tx++;
+ }
break;
default:
bpf_warn_invalid_xdp_action(xdp_act);
@@ -316,6 +320,7 @@ static u32 run_xdp(struct dpaa2_eth_priv *priv,
trace_xdp_exception(priv->net_dev, xdp_prog, xdp_act);
case XDP_DROP:
xdp_release_buf(priv, ch, addr);
+ ch->stats.xdp_drop++;
break;
}
diff --git a/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.h b/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.h
index 320c0d0..1690fc1 100644
--- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.h
+++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.h
@@ -249,6 +249,10 @@ struct dpaa2_eth_ch_stats {
__u64 pull_err;
/* Number of CDANs; useful to estimate avg NAPI len */
__u64 cdan;
+ /* XDP counters */
+ __u64 xdp_drop;
+ __u64 xdp_tx;
+ __u64 xdp_tx_err;
};
/* Maximum number of queues associated with a DPNI */
diff --git a/drivers/net/ethernet/freescale/dpaa2/dpaa2-ethtool.c b/drivers/net/ethernet/freescale/dpaa2/dpaa2-ethtool.c
index 3aa7885..dddc437 100644
--- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-ethtool.c
+++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-ethtool.c
@@ -45,6 +45,9 @@ static char dpaa2_ethtool_extras[][ETH_GSTRING_LEN] = {
"[drv] dequeue portal busy",
"[drv] channel pull errors",
"[drv] cdan",
+ "[drv] xdp drop",
+ "[drv] xdp tx",
+ "[drv] xdp tx errors",
};
#define DPAA2_ETH_NUM_EXTRA_STATS ARRAY_SIZE(dpaa2_ethtool_extras)
--
2.7.4
^ permalink raw reply related
* [PATCH net-next 1/8] dpaa2-eth: Add basic XDP support
From: Ioana Ciocoi Radulescu @ 2018-11-23 16:56 UTC (permalink / raw)
To: netdev@vger.kernel.org, davem@davemloft.net; +Cc: Ioana Ciornei
In-Reply-To: <1542992186-26028-1-git-send-email-ruxandra.radulescu@nxp.com>
We keep one XDP program reference per channel. The only actions
supported for now are XDP_DROP and XDP_PASS.
Until now we didn't enforce a maximum size for Rx frames based
on MTU value. Change that, since for XDP mode we must ensure no
scatter-gather frames can be received.
Signed-off-by: Ioana Radulescu <ruxandra.radulescu@nxp.com>
---
drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c | 182 ++++++++++++++++++++++-
drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.h | 6 +
2 files changed, 187 insertions(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c b/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c
index 640967a..5340ac9 100644
--- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c
+++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c
@@ -13,7 +13,8 @@
#include <linux/iommu.h>
#include <linux/net_tstamp.h>
#include <linux/fsl/mc.h>
-
+#include <linux/bpf.h>
+#include <linux/bpf_trace.h>
#include <net/sock.h>
#include "dpaa2-eth.h"
@@ -199,6 +200,45 @@ static struct sk_buff *build_frag_skb(struct dpaa2_eth_priv *priv,
return skb;
}
+static u32 run_xdp(struct dpaa2_eth_priv *priv,
+ struct dpaa2_eth_channel *ch,
+ struct dpaa2_fd *fd, void *vaddr)
+{
+ struct bpf_prog *xdp_prog;
+ struct xdp_buff xdp;
+ u32 xdp_act = XDP_PASS;
+
+ rcu_read_lock();
+
+ xdp_prog = READ_ONCE(ch->xdp.prog);
+ if (!xdp_prog)
+ goto out;
+
+ xdp.data = vaddr + dpaa2_fd_get_offset(fd);
+ xdp.data_end = xdp.data + dpaa2_fd_get_len(fd);
+ xdp.data_hard_start = xdp.data;
+ xdp_set_data_meta_invalid(&xdp);
+
+ xdp_act = bpf_prog_run_xdp(xdp_prog, &xdp);
+
+ switch (xdp_act) {
+ case XDP_PASS:
+ break;
+ default:
+ bpf_warn_invalid_xdp_action(xdp_act);
+ case XDP_ABORTED:
+ trace_xdp_exception(priv->net_dev, xdp_prog, xdp_act);
+ case XDP_DROP:
+ ch->buf_count--;
+ free_rx_fd(priv, fd, vaddr);
+ break;
+ }
+
+out:
+ rcu_read_unlock();
+ return xdp_act;
+}
+
/* Main Rx frame processing routine */
static void dpaa2_eth_rx(struct dpaa2_eth_priv *priv,
struct dpaa2_eth_channel *ch,
@@ -215,6 +255,7 @@ static void dpaa2_eth_rx(struct dpaa2_eth_priv *priv,
struct dpaa2_fas *fas;
void *buf_data;
u32 status = 0;
+ u32 xdp_act;
/* Tracing point */
trace_dpaa2_rx_fd(priv->net_dev, fd);
@@ -231,8 +272,14 @@ static void dpaa2_eth_rx(struct dpaa2_eth_priv *priv,
percpu_extras = this_cpu_ptr(priv->percpu_extras);
if (fd_format == dpaa2_fd_single) {
+ xdp_act = run_xdp(priv, ch, (struct dpaa2_fd *)fd, vaddr);
+ if (xdp_act != XDP_PASS)
+ return;
+
skb = build_linear_skb(ch, fd, vaddr);
} else if (fd_format == dpaa2_fd_sg) {
+ WARN_ON(priv->xdp_prog);
+
skb = build_frag_skb(priv, ch, buf_data);
skb_free_frag(vaddr);
percpu_extras->rx_sg_frames++;
@@ -1427,6 +1474,137 @@ static int dpaa2_eth_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
return -EINVAL;
}
+static bool xdp_mtu_valid(struct dpaa2_eth_priv *priv, int mtu)
+{
+ int mfl, linear_mfl;
+
+ mfl = DPAA2_ETH_L2_MAX_FRM(mtu);
+ linear_mfl = DPAA2_ETH_RX_BUF_SIZE - DPAA2_ETH_RX_HWA_SIZE -
+ dpaa2_eth_rx_head_room(priv);
+
+ return (mfl <= linear_mfl);
+}
+
+static int set_rx_mfl(struct dpaa2_eth_priv *priv, int mtu, bool has_xdp)
+{
+ int mfl, err;
+
+ /* We enforce a maximum Rx frame length based on MTU only if we have
+ * an XDP program attached (in order to avoid Rx S/G frames).
+ * Otherwise, we accept all incoming frames as long as they are not
+ * larger than maximum size supported in hardware
+ */
+ if (has_xdp)
+ mfl = DPAA2_ETH_L2_MAX_FRM(mtu);
+ else
+ mfl = DPAA2_ETH_MFL;
+
+ err = dpni_set_max_frame_length(priv->mc_io, 0, priv->mc_token, mfl);
+ if (err) {
+ netdev_err(priv->net_dev, "dpni_set_max_frame_length failed\n");
+ return err;
+ }
+
+ return 0;
+}
+
+static int dpaa2_eth_change_mtu(struct net_device *dev, int new_mtu)
+{
+ struct dpaa2_eth_priv *priv = netdev_priv(dev);
+ int err;
+
+ if (!priv->xdp_prog)
+ goto out;
+
+ if (!xdp_mtu_valid(priv, new_mtu))
+ return -EINVAL;
+
+ err = set_rx_mfl(priv, new_mtu, true);
+ if (err)
+ return err;
+
+out:
+ dev->mtu = new_mtu;
+ return 0;
+}
+
+static int setup_xdp(struct net_device *dev, struct bpf_prog *prog)
+{
+ struct dpaa2_eth_priv *priv = netdev_priv(dev);
+ struct dpaa2_eth_channel *ch;
+ struct bpf_prog *old;
+ bool up, update_settings;
+ int i, err;
+
+ if (prog && !xdp_mtu_valid(priv, dev->mtu)) {
+ netdev_warn(dev, "XDP not supported for MTU %d\n", dev->mtu);
+ return -EINVAL;
+ }
+
+ if (prog) {
+ prog = bpf_prog_add(prog, priv->num_channels);
+ if (IS_ERR(prog))
+ return PTR_ERR(prog);
+ }
+
+ up = netif_running(dev);
+ update_settings = (!!priv->xdp_prog != !!prog);
+
+ if (up)
+ dpaa2_eth_stop(dev);
+
+ /* While in xdp mode, enforce a maximum Rx frame size based on MTU */
+ if (update_settings) {
+ err = set_rx_mfl(priv, dev->mtu, !!prog);
+ if (err)
+ goto out_err;
+ }
+
+ old = xchg(&priv->xdp_prog, prog);
+ if (old)
+ bpf_prog_put(old);
+
+ for (i = 0; i < priv->num_channels; i++) {
+ ch = priv->channel[i];
+ old = xchg(&ch->xdp.prog, prog);
+ if (old)
+ bpf_prog_put(old);
+ }
+
+ if (up) {
+ err = dpaa2_eth_open(dev);
+ if (err)
+ return err;
+ }
+
+ return 0;
+
+out_err:
+ if (prog)
+ bpf_prog_sub(prog, priv->num_channels);
+ if (up)
+ dpaa2_eth_open(dev);
+
+ return err;
+}
+
+static int dpaa2_eth_xdp(struct net_device *dev, struct netdev_bpf *xdp)
+{
+ struct dpaa2_eth_priv *priv = netdev_priv(dev);
+
+ switch (xdp->command) {
+ case XDP_SETUP_PROG:
+ return setup_xdp(dev, xdp->prog);
+ case XDP_QUERY_PROG:
+ xdp->prog_id = priv->xdp_prog ? priv->xdp_prog->aux->id : 0;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
static const struct net_device_ops dpaa2_eth_ops = {
.ndo_open = dpaa2_eth_open,
.ndo_start_xmit = dpaa2_eth_tx,
@@ -1436,6 +1614,8 @@ static const struct net_device_ops dpaa2_eth_ops = {
.ndo_set_rx_mode = dpaa2_eth_set_rx_mode,
.ndo_set_features = dpaa2_eth_set_features,
.ndo_do_ioctl = dpaa2_eth_ioctl,
+ .ndo_change_mtu = dpaa2_eth_change_mtu,
+ .ndo_bpf = dpaa2_eth_xdp,
};
static void cdan_cb(struct dpaa2_io_notification_ctx *ctx)
diff --git a/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.h b/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.h
index 16545e9..2873a15 100644
--- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.h
+++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.h
@@ -283,6 +283,10 @@ struct dpaa2_eth_fq {
struct dpaa2_eth_fq_stats stats;
};
+struct dpaa2_eth_ch_xdp {
+ struct bpf_prog *prog;
+};
+
struct dpaa2_eth_channel {
struct dpaa2_io_notification_ctx nctx;
struct fsl_mc_device *dpcon;
@@ -294,6 +298,7 @@ struct dpaa2_eth_channel {
struct dpaa2_eth_priv *priv;
int buf_count;
struct dpaa2_eth_ch_stats stats;
+ struct dpaa2_eth_ch_xdp xdp;
};
struct dpaa2_eth_dist_fields {
@@ -353,6 +358,7 @@ struct dpaa2_eth_priv {
u64 rx_hash_fields;
struct dpaa2_eth_cls_rule *cls_rules;
u8 rx_cls_enabled;
+ struct bpf_prog *xdp_prog;
};
#define DPAA2_RXH_SUPPORTED (RXH_L2DA | RXH_VLAN | RXH_L3_PROTO \
--
2.7.4
^ permalink raw reply related
* [PATCH net-next 0/8] dpaa2-eth: Introduce XDP support
From: Ioana Ciocoi Radulescu @ 2018-11-23 16:56 UTC (permalink / raw)
To: netdev@vger.kernel.org, davem@davemloft.net; +Cc: Ioana Ciornei
Add support for XDP programs. Only XDP_PASS, XDP_DROP and XDP_TX
actions are supported for now. Frame header changes are also
allowed.
Ioana Radulescu (8):
dpaa2-eth: Add basic XDP support
dpaa2-eth: Allow XDP header adjustments
dpaa2-eth: Move function
dpaa2-eth: Release buffers back to pool on XDP_DROP
dpaa2-eth: Map Rx buffers as bidirectional
dpaa2-eth: Add support for XDP_TX
dpaa2-eth: Cleanup channel stats
dpaa2-eth: Add xdp counters
drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c | 336 +++++++++++++++++++--
drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.h | 20 +-
.../net/ethernet/freescale/dpaa2/dpaa2-ethtool.c | 19 +-
3 files changed, 337 insertions(+), 38 deletions(-)
--
2.7.4
^ permalink raw reply
* [PATCH v2] bpf: fix check of allowed specifiers in bpf_trace_printk
From: Martynas Pumputis @ 2018-11-23 16:43 UTC (permalink / raw)
To: netdev; +Cc: ast, daniel, m
A format string consisting of "%p" or "%s" followed by an invalid
specifier (e.g. "%p%\n" or "%s%") could pass the check which
would make format_decode (lib/vsprintf.c) to warn.
Reported-by: syzbot+1ec5c5ec949c4adaa0c4@syzkaller.appspotmail.com
Signed-off-by: Martynas Pumputis <m@lambda.lt>
---
kernel/trace/bpf_trace.c | 8 +++++---
1 file changed, 5 insertions(+), 3 deletions(-)
diff --git a/kernel/trace/bpf_trace.c b/kernel/trace/bpf_trace.c
index 08fcfe440c63..9864a35c8bb5 100644
--- a/kernel/trace/bpf_trace.c
+++ b/kernel/trace/bpf_trace.c
@@ -196,11 +196,13 @@ BPF_CALL_5(bpf_trace_printk, char *, fmt, u32, fmt_size, u64, arg1,
i++;
} else if (fmt[i] == 'p' || fmt[i] == 's') {
mod[fmt_cnt]++;
- i++;
- if (!isspace(fmt[i]) && !ispunct(fmt[i]) && fmt[i] != 0)
+ /* disallow any further format extensions */
+ if (fmt[i + 1] != 0 &&
+ !isspace(fmt[i + 1]) &&
+ !ispunct(fmt[i + 1]))
return -EINVAL;
fmt_cnt++;
- if (fmt[i - 1] == 's') {
+ if (fmt[i] == 's') {
if (str_seen)
/* allow only one '%s' per fmt string */
return -EINVAL;
--
2.19.1
^ permalink raw reply related
* [PATCH 1/1] drivers/net/i40e: define proper net_device::neigh_priv_len
From: Konstantin Khorenko @ 2018-11-23 16:10 UTC (permalink / raw)
To: Jeff Kirsher
Cc: Konstantin Khorenko, netdev, linux-kernel, intel-wired-lan,
David S . Miller
In-Reply-To: <20181123161028.22633-1-khorenko@virtuozzo.com>
Out of bound read reported by KASan.
i40iw_net_event() reads unconditionally 16 bytes from
neigh->primary_key while the memory allocated for
"neighbour" struct is evaluated in neigh_alloc() as
tbl->entry_size + dev->neigh_priv_len
where "dev" is a net_device.
But the driver does not setup dev->neigh_priv_len and
we read beyond the neigh entry allocated memory,
so the patch in the next mail fixes this.
Signed-off-by: Konstantin Khorenko <khorenko@virtuozzo.com>
---
drivers/net/ethernet/intel/i40e/i40e_main.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/drivers/net/ethernet/intel/i40e/i40e_main.c b/drivers/net/ethernet/intel/i40e/i40e_main.c
index 21c2688d6308..539b8f3738e6 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_main.c
+++ b/drivers/net/ethernet/intel/i40e/i40e_main.c
@@ -12334,6 +12334,9 @@ static int i40e_config_netdev(struct i40e_vsi *vsi)
ether_addr_copy(netdev->dev_addr, mac_addr);
ether_addr_copy(netdev->perm_addr, mac_addr);
+ /* i40iw_net_event() reads 16 bytes from neigh->primary_key */
+ netdev->neigh_priv_len = sizeof(u32) * 4;
+
netdev->priv_flags |= IFF_UNICAST_FLT;
netdev->priv_flags |= IFF_SUPP_NOFCS;
/* Setup netdev TC information */
--
2.15.1
^ permalink raw reply related
* ixgbe driver hits null pointer in net/core/dev.c
From: Nathanael Davison @ 2018-11-23 15:46 UTC (permalink / raw)
To: netdev@vger.kernel.org; +Cc: Andrew Cooper, Paul Durrant
Hi all,
Running Kernel 4.19.x on Xen in machines using intel ixgbe driver the driver crashes on startup with the kernel trace below.
It appears that the loop on line 2432 of net/core/dev.c iterates beyond the end of the dev_maps->attr_map array, resulting in dereferencing garbage. A workaround is to add the condition tci<nr_ids at lines 2434, 2436, and 2439; but this does not appear to deal with the root case of the problem.
Nov 23 12:49:47 localhost kernel: [ 63.471784] BUG: unable to handle kernel paging request at 0000001400000001
Nov 23 12:49:47 localhost kernel: [ 63.471804] PGD 0 P4D 0
Nov 23 12:49:47 localhost kernel: [ 63.471811] Oops: 0000 [#1] SMP NOPTI
Nov 23 12:49:47 localhost kernel: [ 63.471818] CPU: 1 PID: 1665 Comm: lldpad Not tainted 4.19.0+0.kernel #37
Nov 23 12:49:47 localhost kernel: [ 63.471827] Hardware name: Dell Inc. PowerEdge R310/0P229K, BIOS 1.0.0 02/11/2010
Nov 23 12:49:47 localhost kernel: [ 63.471842] RIP: e030:remove_xps_queue+0x17/0x80
Nov 23 12:49:47 localhost kernel: [ 63.471849] Code: ff 0f 0b e9 31 ff ff ff 90 66 2e 0f 1f 84 00 00 00 00 00 66 66 66 66 90 48 85 ff 74 49 48 63 f6 48 8b 4c f7 10 48 85 c9 74 3c <44> 8b 11 45 8d 4a ff 44 89 c8 83 f8 ff 4c 63 c0 74 2d 49 83 c0 08
Nov 23 12:49:47 localhost kernel: [ 63.471870] RSP: e02b:ffffc90040ccf9e0 EFLAGS: 00010202
Nov 23 12:49:47 localhost kernel: [ 63.471878] RAX: 0000000000000000 RBX: ffff88000456d280 RCX: 0000001400000001
Nov 23 12:49:47 localhost kernel: [ 63.471921] RDX: 0000000000000000 RSI: 0000000000000006 RDI: ffff88000456d280
Nov 23 12:49:47 localhost kernel: [ 63.471930] RBP: 0000000000000001 R08: ffffffffffffffff R09: 0000000000000000
Nov 23 12:49:47 localhost kernel: [ 63.471940] R10: 0000000000000001 R11: 000000000000cd40 R12: 0000000000000000
Nov 23 12:49:47 localhost kernel: [ 63.471949] R13: 0000000000000006 R14: 0000000100000000 R15: 0000000000000002
Nov 23 12:49:47 localhost kernel: [ 63.471966] FS: 00007f77bf9a3740(0000) GS:ffff88002d840000(0000) knlGS:0000000000000000
Nov 23 12:49:47 localhost kernel: [ 63.471976] CS: e033 DS: 0000 ES: 0000 CR0: 0000000080050033
Nov 23 12:49:47 localhost kernel: [ 63.471985] CR2: 0000001400000001 CR3: 000000002738c000 CR4: 0000000000002660
Nov 23 12:49:47 localhost kernel: [ 63.471999] Call Trace:
Nov 23 12:49:47 localhost kernel: [ 63.472008] __netif_set_xps_queue+0x735/0x910
Nov 23 12:49:47 localhost kernel: [ 63.472018] netif_set_xps_queue+0x28/0x40
Nov 23 12:49:47 localhost kernel: [ 63.472028] ixgbe_configure_tx_ring+0x16d/0x270 [ixgbe]
Nov 23 12:49:47 localhost kernel: [ 63.472039] ixgbe_configure_rx_ring+0x693/0x11f0 [ixgbe]
Nov 23 12:49:47 localhost kernel: [ 63.472049] ixgbe_open+0x21b/0x7b0 [ixgbe]
Nov 23 12:49:47 localhost kernel: [ 63.472059] ixgbe_dcb_hw_config_82599+0xab2/0x1360 [ixgbe]
Nov 23 12:49:47 localhost kernel: [ 63.472069] dcbnl_setstate+0x3f/0x90
Nov 23 12:49:47 localhost kernel: [ 63.472076] dcb_doit+0x124/0x1d0
Nov 23 12:49:47 localhost kernel: [ 63.472085] rtnetlink_rcv_msg+0x2a2/0x320
Nov 23 12:49:47 localhost kernel: [ 63.472093] ? _raw_spin_unlock_irqrestore+0x14/0x20
Nov 23 12:49:47 localhost kernel: [ 63.472101] ? __skb_try_recv_datagram+0xd3/0x180
Nov 23 12:49:47 localhost kernel: [ 63.472109] ? rtnl_calcit.isra.31+0x110/0x110
Nov 23 12:49:47 localhost kernel: [ 63.472118] netlink_rcv_skb+0xd4/0x110
Nov 23 12:49:47 localhost kernel: [ 63.472126] netlink_unicast+0x182/0x230
Nov 23 12:49:47 localhost kernel: [ 63.472133] netlink_sendmsg+0x2ed/0x3e0
Nov 23 12:49:47 localhost kernel: [ 63.472142] sock_sendmsg+0x36/0x50
Nov 23 12:49:47 localhost kernel: [ 63.472149] __sys_sendto+0xdc/0x160
Nov 23 12:49:47 localhost kernel: [ 63.472158] ? __call_rcu.constprop.74+0xc8/0x1d0
Nov 23 12:49:47 localhost kernel: [ 63.472167] __x64_sys_sendto+0x24/0x30
Nov 23 12:49:47 localhost kernel: [ 63.472175] do_syscall_64+0x4e/0x100
Nov 23 12:49:47 localhost kernel: [ 63.472183] entry_SYSCALL_64_after_hwframe+0x44/0xa9
Nov 23 12:49:47 localhost kernel: [ 63.472191] RIP: 0033:0x7f77bee96353
Nov 23 12:49:47 localhost kernel: [ 63.472198] Code: 48 8b 0d 38 2b 2c 00 f7 d8 64 89 01 48 83 c8 ff c3 66 0f 1f 44 00 00 83 3d ad 8c 2c 00 00 75 13 49 89 ca b8 2c 00 00 00 0f 05 <48> 3d 01 f0 ff ff 73 34 c3 48 83 ec 08 e8 1b c9 00 00 48 89 04 24
Nov 23 12:49:47 localhost kernel: [ 63.472219] RSP: 002b:00007fff3d4a1568 EFLAGS: 00000246 ORIG_RAX: 000000000000002c
Nov 23 12:49:47 localhost kernel: [ 63.472230] RAX: ffffffffffffffda RBX: 0000562e22ccc970 RCX: 00007f77bee96353
Nov 23 12:49:47 localhost kernel: [ 63.472239] RDX: 0000000000000028 RSI: 0000562e22ccc970 RDI: 0000000000000005
Nov 23 12:49:47 localhost kernel: [ 63.472249] RBP: 0000562e22ccc970 R08: 00007fff3d4a1570 R09: 000000000000000c
Nov 23 12:49:47 localhost kernel: [ 63.472259] R10: 0000000000000000 R11: 0000000000000246 R12: 00007fff3d4a1570
Nov 23 12:49:47 localhost kernel: [ 63.472269] R13: 0000000000000028 R14: 0000000000000000 R15: 0000000000000009
Nov 23 12:49:47 localhost kernel: [ 63.472279] Modules linked in: 8021q garp mrp stp llc openvswitch nsh nf_nat_ipv6 nf_nat_ipv4 nf_conncount nf_nat ipt_REJECT nf_reject_ipv4 xt_tcpudp xt_multiport xt_conntrack nf_conntrack nf_defrag_ipv6 nf_defrag_ipv4 libcrc32c iptable_filter dm_multipath dm_mod dcdbas intel_powerclamp coretemp sg ipmi_si bnx2 ipmi_devintf ixgbe ipmi_msghandler i7core_edac acpi_power_meter lpc_ich hed mdio nls_utf8 isofs loop nfsd auth_rpcgss oid_registry nfs_acl lockd grace sunrpc ip_tables x_tables sha1_ssse3 sha1_generic ipv6 sd_mod sr_mod cdrom hid_generic ata_generic pata_acpi usbhid hid ata_piix libata mptsas scsi_transport_sas mptscsih mptbase ehci_pci ehci_hcd scsi_dh_rdac scsi_dh_hp_sw scsi_dh_emc scsi_dh_alua scsi_mod xen_wdt crc_ccitt
Nov 23 12:49:47 localhost kernel: [ 63.472381] CR2: 0000001400000001
Nov 23 12:49:47 localhost kernel: [ 63.472388] ---[ end trace 44555ed63c956ad6 ]---
Nov 23 12:49:47 localhost kernel: [ 63.475033] RIP: e030:remove_xps_queue+0x17/0x80
Nov 23 12:49:47 localhost kernel: [ 63.475045] Code: ff 0f 0b e9 31 ff ff ff 90 66 2e 0f 1f 84 00 00 00 00 00 66 66 66 66 90 48 85 ff 74 49 48 63 f6 48 8b 4c f7 10 48 85 c9 74 3c <44> 8b 11 45 8d 4a ff 44 89 c8 83 f8 ff 4c 63 c0 74 2d 49 83 c0 08
Nov 23 12:49:47 localhost kernel: [ 63.475071] RSP: e02b:ffffc90040ccf9e0 EFLAGS: 00010202
Nov 23 12:49:47 localhost kernel: [ 63.475084] RAX: 0000000000000000 RBX: ffff88000456d280 RCX: 0000001400000001
Nov 23 12:49:47 localhost kernel: [ 63.475094] RDX: 0000000000000000 RSI: 0000000000000006 RDI: ffff88000456d280
Nov 23 12:49:47 localhost kernel: [ 63.475105] RBP: 0000000000000001 R08: ffffffffffffffff R09: 0000000000000000
Nov 23 12:49:47 localhost kernel: [ 63.475114] R10: 0000000000000001 R11: 000000000000cd40 R12: 0000000000000000
Nov 23 12:49:47 localhost kernel: [ 63.475124] R13: 0000000000000006 R14: 0000000100000000 R15: 0000000000000002
Nov 23 12:49:47 localhost kernel: [ 63.475141] FS: 00007f77bf9a3740(0000) GS:ffff88002d840000(0000) knlGS:0000000000000000
Nov 23 12:49:47 localhost kernel: [ 63.475152] CS: e033 DS: 0000 ES: 0000 CR0: 0000000080050033
Nov 23 12:49:47 localhost kernel: [ 63.475162] CR2: 0000001400000001 CR3: 000000002738c000 CR4: 0000000000002660
0000000000000000 <remove_xps_queue>:
0: 0f 1f 44 00 00 nopl 0x0(%rax,%rax,1)
// if (dev_maps)
5: 48 85 ff test %rdi,%rdi
8: 74 49 je 0x53
// map = xmap_dereference(dev_maps->attr_map[tci]);
a: 48 63 f6 movslq %esi,%rsi
d: 48 8b 4c f7 10 mov 0x10(%rdi,%rsi,8),%rcx // Results in a bogus, non-NULL pointer
// if (!map)
12: 48 85 c9 test %rcx,%rcx
15: 74 3c je 0x53
// for (pos = map->len; ...
17: 44 8b 11 mov (%rcx),%r10d // <- Fault on dereferencing map
1a: 45 8d 4a ff lea -0x1(%r10),%r9d
1e: 44 89 c8 mov %r9d,%eax
21: 83 f8 ff cmp $0xffffffff,%eax
24: 4c 63 c0 movslq %eax,%r8
27: 74 2d je 0x56
29: 49 83 c0 08 add $0x8,%r8
Regards,
Nathanael
^ permalink raw reply
* [PATCH 8/8] socket: Add SO_TIMESTAMPING_NEW
From: Deepa Dinamani @ 2018-11-24 2:20 UTC (permalink / raw)
To: davem, linux-kernel
Cc: netdev, viro, arnd, y2038, chris, fenghua.yu, rth, tglx, ubraun,
linux-alpha, linux-arch, linux-ia64, linux-mips, linux-s390,
linux-xtensa, sparclinux
In-Reply-To: <20181124022035.17519-1-deepa.kernel@gmail.com>
Add SO_TIMESTAMPING_NEW variant of socket timestamp options.
This is the y2038 safe versions of the SO_TIMESTAMPING_OLD
for all architectures.
Signed-off-by: Deepa Dinamani <deepa.kernel@gmail.com>
Cc: chris@zankel.net
Cc: fenghua.yu@intel.com
Cc: rth@twiddle.net
Cc: tglx@linutronix.de
Cc: ubraun@linux.ibm.com
Cc: linux-alpha@vger.kernel.org
Cc: linux-arch@vger.kernel.org
Cc: linux-ia64@vger.kernel.org
Cc: linux-mips@linux-mips.org
Cc: linux-s390@vger.kernel.org
Cc: linux-xtensa@linux-xtensa.org
Cc: sparclinux@vger.kernel.org
---
arch/alpha/include/uapi/asm/socket.h | 5 +-
arch/mips/include/uapi/asm/socket.h | 5 +-
arch/parisc/include/uapi/asm/socket.h | 5 +-
arch/sparc/include/uapi/asm/socket.h | 8 +--
include/linux/socket.h | 7 +++
include/uapi/asm-generic/socket.h | 5 +-
include/uapi/linux/errqueue.h | 4 ++
net/core/scm.c | 27 ++++++++++
net/core/sock.c | 73 +++++++++++++++------------
net/ipv4/tcp.c | 29 ++++++-----
net/smc/af_smc.c | 3 +-
net/socket.c | 16 +++---
12 files changed, 122 insertions(+), 65 deletions(-)
diff --git a/arch/alpha/include/uapi/asm/socket.h b/arch/alpha/include/uapi/asm/socket.h
index 352e3dc0b3d9..8b9f6f7f8087 100644
--- a/arch/alpha/include/uapi/asm/socket.h
+++ b/arch/alpha/include/uapi/asm/socket.h
@@ -116,19 +116,20 @@
#define SO_TIMESTAMP_NEW 62
#define SO_TIMESTAMPNS_NEW 63
+#define SO_TIMESTAMPING_NEW 64
#if !defined(__KERNEL__)
#if __BITS_PER_LONG == 64
#define SO_TIMESTAMP SO_TIMESTAMP_OLD
#define SO_TIMESTAMPNS SO_TIMESTAMPNS_OLD
+#define SO_TIMESTAMPING SO_TIMESTAMPING_OLD
#else
#define SO_TIMESTAMP (sizeof(time_t) == sizeof(__kernel_long_t) ? SO_TIMESTAMP_OLD : SO_TIMESTAMP_NEW)
#define SO_TIMESTAMPNS (sizeof(time_t) == sizeof(__kernel_long_t) ? SO_TIMESTAMPNS_OLD : SO_TIMESTAMPNS_NEW)
+#define SO_TIMESTAMPING (sizeof(time_t) == sizeof(__kernel_long_t) ? SO_TIMESTAMPING_OLD : SO_TIMESTAMPING_NEW)
#endif
-#define SO_TIMESTAMPING SO_TIMESTAMPING_OLD
-
#define SCM_TIMESTAMP SO_TIMESTAMP
#define SCM_TIMESTAMPNS SO_TIMESTAMPNS
#define SCM_TIMESTAMPING SO_TIMESTAMPING
diff --git a/arch/mips/include/uapi/asm/socket.h b/arch/mips/include/uapi/asm/socket.h
index d1752e3f1248..9fc80c5d54e4 100644
--- a/arch/mips/include/uapi/asm/socket.h
+++ b/arch/mips/include/uapi/asm/socket.h
@@ -126,19 +126,20 @@
#define SO_TIMESTAMP_NEW 62
#define SO_TIMESTAMPNS_NEW 63
+#define SO_TIMESTAMPING_NEW 64
#if !defined(__KERNEL__)
#if __BITS_PER_LONG == 64
#define SO_TIMESTAMP SO_TIMESTAMP_OLD
#define SO_TIMESTAMPNS SO_TIMESTAMPNS_OLD
+#define SO_TIMESTAMPING SO_TIMESTAMPING_OLD
#else
#define SO_TIMESTAMP (sizeof(time_t) == sizeof(__kernel_long_t) ? SO_TIMESTAMP_OLD : SO_TIMESTAMP_NEW)
#define SO_TIMESTAMPNS (sizeof(time_t) == sizeof(__kernel_long_t) ? SO_TIMESTAMPNS_OLD : SO_TIMESTAMPNS_NEW)
+#define SO_TIMESTAMPING (sizeof(time_t) == sizeof(__kernel_long_t) ? SO_TIMESTAMPING_OLD : SO_TIMESTAMPING_NEW)
#endif
-#define SO_TIMESTAMPING SO_TIMESTAMPING_OLD
-
#define SCM_TIMESTAMP SO_TIMESTAMP
#define SCM_TIMESTAMPNS SO_TIMESTAMPNS
#define SCM_TIMESTAMPING SO_TIMESTAMPING
diff --git a/arch/parisc/include/uapi/asm/socket.h b/arch/parisc/include/uapi/asm/socket.h
index 0a45b668abd1..82f1c9447d6b 100644
--- a/arch/parisc/include/uapi/asm/socket.h
+++ b/arch/parisc/include/uapi/asm/socket.h
@@ -107,19 +107,20 @@
#define SO_TIMESTAMP_NEW 0x4037
#define SO_TIMESTAMPNS_NEW 0x4038
+#define SO_TIMESTAMPING_NEW 0x4039
#if !defined(__KERNEL__)
#if __BITS_PER_LONG == 64
#define SO_TIMESTAMP SO_TIMESTAMP_OLD
#define SO_TIMESTAMPNS SO_TIMESTAMPNS_OLD
+#define SO_TIMESTAMPING SO_TIMESTAMPING_OLD
#else
#define SO_TIMESTAMP (sizeof(time_t) == sizeof(__kernel_long_t) ? SO_TIMESTAMP_OLD : SO_TIMESTAMP_NEW)
#define SO_TIMESTAMPNS (sizeof(time_t) == sizeof(__kernel_long_t) ? SO_TIMESTAMPNS_OLD : SO_TIMESTAMPNS_NEW)
+#define SO_TIMESTAMPING (sizeof(time_t) == sizeof(__kernel_long_t) ? SO_TIMESTAMPING_OLD : SO_TIMESTAMPING_NEW)
#endif
-#define SO_TIMESTAMPING SO_TIMESTAMPING_OLD
-
#define SCM_TIMESTAMP SO_TIMESTAMP
#define SCM_TIMESTAMPNS SO_TIMESTAMPNS
#define SCM_TIMESTAMPING SO_TIMESTAMPING
diff --git a/arch/sparc/include/uapi/asm/socket.h b/arch/sparc/include/uapi/asm/socket.h
index dc8527cae5a7..5bdbb25c28d2 100644
--- a/arch/sparc/include/uapi/asm/socket.h
+++ b/arch/sparc/include/uapi/asm/socket.h
@@ -106,20 +106,22 @@
#define SO_TIMESTAMPNS_OLD 0x0021
#define SO_TIMESTAMPING_OLD 0x0023
-#define SO_TIMESTAMP_NEW 0x0040
-#define SO_TIMESTAMPNS_NEW 0x0041
+#define SO_TIMESTAMP_NEW 0x0041
+#define SO_TIMESTAMPNS_NEW 0x0042
+#define SO_TIMESTAMPING_NEW 0x0043
#if !defined(__KERNEL__)
#if __BITS_PER_LONG == 64
#define SO_TIMESTAMP SO_TIMESTAMP_OLD
#define SO_TIMESTAMPNS SO_TIMESTAMPNS_OLD
+#define SO_TIMESTAMPING SO_TIMESTAMPING_OLD
#else
#define SO_TIMESTAMP (sizeof(time_t) == sizeof(__kernel_long_t) ? SO_TIMESTAMP_OLD : SO_TIMESTAMP_NEW)
#define SO_TIMESTAMPNS (sizeof(time_t) == sizeof(__kernel_long_t) ? SO_TIMESTAMPNS_OLD : SO_TIMESTAMPNS_NEW)
+#define SO_TIMESTAMPING (sizeof(time_t) == sizeof(__kernel_long_t) ? SO_TIMESTAMPING_OLD : SO_TIMESTAMPING_NEW)
#endif
-#define SO_TIMESTAMPING SO_TIMESTAMPING_OLD
#define SCM_TIMESTAMP SO_TIMESTAMP
#define SCM_TIMESTAMPNS SO_TIMESTAMPNS
diff --git a/include/linux/socket.h b/include/linux/socket.h
index 8b571e9b9f76..372fd77698a2 100644
--- a/include/linux/socket.h
+++ b/include/linux/socket.h
@@ -350,6 +350,13 @@ extern int put_cmsg(struct msghdr*, int level, int type, int len, void *data);
struct timespec64;
+struct scm_timestamping_internal {
+ struct timespec64 ts[3];
+};
+
+extern void put_cmsg_scm_timestamping64(struct msghdr *msg, struct scm_timestamping_internal *tss);
+extern void put_cmsg_scm_timestamping(struct msghdr *msg, struct scm_timestamping_internal *tss);
+
/* The __sys_...msg variants allow MSG_CMSG_COMPAT iff
* forbid_cmsg_compat==false
*/
diff --git a/include/uapi/asm-generic/socket.h b/include/uapi/asm-generic/socket.h
index 0b0fae6b57a9..2fdfb6126246 100644
--- a/include/uapi/asm-generic/socket.h
+++ b/include/uapi/asm-generic/socket.h
@@ -110,6 +110,7 @@
#define SO_TIMESTAMP_NEW 62
#define SO_TIMESTAMPNS_NEW 63
+#define SO_TIMESTAMPING_NEW 64
#if !defined(__KERNEL__)
@@ -117,13 +118,13 @@
/* on 64-bit and x32, avoid the ?: operator */
#define SO_TIMESTAMP SO_TIMESTAMP_OLD
#define SO_TIMESTAMPNS SO_TIMESTAMPNS_OLD
+#define SO_TIMESTAMPING SO_TIMESTAMPING_OLD
#else
#define SO_TIMESTAMP (sizeof(time_t) == sizeof(__kernel_long_t) ? SO_TIMESTAMP_OLD : SO_TIMESTAMP_NEW)
#define SO_TIMESTAMPNS (sizeof(time_t) == sizeof(__kernel_long_t) ? SO_TIMESTAMPNS_OLD : SO_TIMESTAMPNS_NEW)
+#define SO_TIMESTAMPING (sizeof(time_t) == sizeof(__kernel_long_t) ? SO_TIMESTAMPING_OLD : SO_TIMESTAMPING_NEW)
#endif
-#define SO_TIMESTAMPING SO_TIMESTAMPING_OLD
-
#define SCM_TIMESTAMP SO_TIMESTAMP
#define SCM_TIMESTAMPNS SO_TIMESTAMPNS
#define SCM_TIMESTAMPING SO_TIMESTAMPING
diff --git a/include/uapi/linux/errqueue.h b/include/uapi/linux/errqueue.h
index c0151200f7d1..d955b9e32288 100644
--- a/include/uapi/linux/errqueue.h
+++ b/include/uapi/linux/errqueue.h
@@ -41,6 +41,10 @@ struct scm_timestamping {
struct timespec ts[3];
};
+struct scm_timestamping64 {
+ struct __kernel_timespec ts[3];
+};
+
/* The type of scm_timestamping, passed in sock_extended_err ee_info.
* This defines the type of ts[0]. For SCM_TSTAMP_SND only, if ts[0]
* is zero, then this is a hardware timestamp and recorded in ts[2].
diff --git a/net/core/scm.c b/net/core/scm.c
index b1ff8a441748..52ef219cf6df 100644
--- a/net/core/scm.c
+++ b/net/core/scm.c
@@ -29,6 +29,7 @@
#include <linux/pid.h>
#include <linux/nsproxy.h>
#include <linux/slab.h>
+#include <linux/errqueue.h>
#include <linux/uaccess.h>
@@ -252,6 +253,32 @@ int put_cmsg(struct msghdr * msg, int level, int type, int len, void *data)
}
EXPORT_SYMBOL(put_cmsg);
+void put_cmsg_scm_timestamping64(struct msghdr *msg, struct scm_timestamping_internal *tss_internal)
+{
+ struct scm_timestamping64 tss;
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(tss.ts); i++) {
+ tss.ts[i].tv_sec = tss_internal->ts[i].tv_sec;
+ tss.ts[i].tv_nsec = tss_internal->ts[i].tv_nsec;
+ }
+
+ put_cmsg(msg, SOL_SOCKET, SO_TIMESTAMPING_NEW, sizeof(tss), &tss);
+}
+EXPORT_SYMBOL(put_cmsg_scm_timestamping64);
+
+void put_cmsg_scm_timestamping(struct msghdr *msg, struct scm_timestamping_internal *tss_internal)
+{
+ struct scm_timestamping tss;
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(tss.ts); i++)
+ tss.ts[i] = timespec64_to_timespec(tss_internal->ts[i]);
+
+ put_cmsg(msg, SOL_SOCKET, SO_TIMESTAMPING_OLD, sizeof(tss), &tss);
+}
+EXPORT_SYMBOL(put_cmsg_scm_timestamping);
+
void scm_detach_fds(struct msghdr *msg, struct scm_cookie *scm)
{
struct cmsghdr __user *cm
diff --git a/net/core/sock.c b/net/core/sock.c
index 7b485dfaa400..29cc1f0f0071 100644
--- a/net/core/sock.c
+++ b/net/core/sock.c
@@ -677,6 +677,45 @@ static void setsockopt_timestamp(struct sock *sk, int type, int val)
sock_enable_timestamp(sk, SOCK_TIMESTAMP);
}
+static int setsockopt_timestamping(struct sock *sk, int type, int val)
+{
+ if (type == SO_TIMESTAMPING_NEW)
+ sock_set_flag(sk, SOCK_TSTAMP_NEW);
+
+ if (val & ~SOF_TIMESTAMPING_MASK)
+ return -EINVAL;
+
+ if (val & SOF_TIMESTAMPING_OPT_ID &&
+ !(sk->sk_tsflags & SOF_TIMESTAMPING_OPT_ID)) {
+ if (sk->sk_protocol == IPPROTO_TCP &&
+ sk->sk_type == SOCK_STREAM) {
+ if ((1 << sk->sk_state) &
+ (TCPF_CLOSE | TCPF_LISTEN))
+ return -EINVAL;
+ sk->sk_tskey = tcp_sk(sk)->snd_una;
+ } else {
+ sk->sk_tskey = 0;
+ }
+ }
+
+ if (val & SOF_TIMESTAMPING_OPT_STATS &&
+ !(val & SOF_TIMESTAMPING_OPT_TSONLY))
+ return -EINVAL;
+
+ sk->sk_tsflags = val;
+ if (val & SOF_TIMESTAMPING_RX_SOFTWARE) {
+ sock_enable_timestamp(sk,
+ SOCK_TIMESTAMPING_RX_SOFTWARE);
+ } else {
+ if (type == SO_TIMESTAMPING_NEW)
+ sock_reset_flag(sk, SOCK_TSTAMP_NEW);
+ sock_disable_timestamp(sk,
+ (1UL << SOCK_TIMESTAMPING_RX_SOFTWARE));
+ }
+
+ return 0;
+}
+
/*
* This is meant for all protocols to use and covers goings on
* at the socket level. Everything here is generic.
@@ -852,39 +891,7 @@ int sock_setsockopt(struct socket *sock, int level, int optname,
break;
case SO_TIMESTAMPING_OLD:
- if (val & ~SOF_TIMESTAMPING_MASK) {
- ret = -EINVAL;
- break;
- }
-
- if (val & SOF_TIMESTAMPING_OPT_ID &&
- !(sk->sk_tsflags & SOF_TIMESTAMPING_OPT_ID)) {
- if (sk->sk_protocol == IPPROTO_TCP &&
- sk->sk_type == SOCK_STREAM) {
- if ((1 << sk->sk_state) &
- (TCPF_CLOSE | TCPF_LISTEN)) {
- ret = -EINVAL;
- break;
- }
- sk->sk_tskey = tcp_sk(sk)->snd_una;
- } else {
- sk->sk_tskey = 0;
- }
- }
-
- if (val & SOF_TIMESTAMPING_OPT_STATS &&
- !(val & SOF_TIMESTAMPING_OPT_TSONLY)) {
- ret = -EINVAL;
- break;
- }
-
- sk->sk_tsflags = val;
- if (val & SOF_TIMESTAMPING_RX_SOFTWARE)
- sock_enable_timestamp(sk,
- SOCK_TIMESTAMPING_RX_SOFTWARE);
- else
- sock_disable_timestamp(sk,
- (1UL << SOCK_TIMESTAMPING_RX_SOFTWARE));
+ ret = setsockopt_timestamping(sk, optname, val);
break;
case SO_RCVLOWAT:
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
index b470f470343a..09ef0d8141fb 100644
--- a/net/ipv4/tcp.c
+++ b/net/ipv4/tcp.c
@@ -1847,17 +1847,17 @@ static int tcp_zerocopy_receive(struct sock *sk,
#endif
static void tcp_update_recv_tstamps(struct sk_buff *skb,
- struct scm_timestamping *tss)
+ struct scm_timestamping_internal *tss)
{
if (skb->tstamp)
- tss->ts[0] = ktime_to_timespec(skb->tstamp);
+ tss->ts[0] = ktime_to_timespec64(skb->tstamp);
else
- tss->ts[0] = (struct timespec) {0};
+ tss->ts[0] = (struct timespec64) {0};
if (skb_hwtstamps(skb)->hwtstamp)
- tss->ts[2] = ktime_to_timespec(skb_hwtstamps(skb)->hwtstamp);
+ tss->ts[2] = ktime_to_timespec64(skb_hwtstamps(skb)->hwtstamp);
else
- tss->ts[2] = (struct timespec) {0};
+ tss->ts[2] = (struct timespec64) {0};
}
static void tcp_recv_sw_timestamp(struct msghdr *msg, const struct sock *sk, struct timespec64 *ts)
@@ -1900,29 +1900,30 @@ static void tcp_recv_sw_timestamp(struct msghdr *msg, const struct sock *sk, str
/* Similar to __sock_recv_timestamp, but does not require an skb */
static void tcp_recv_timestamp(struct msghdr *msg, const struct sock *sk,
- struct scm_timestamping *tss)
+ struct scm_timestamping_internal *tss)
{
bool has_timestamping = false;
- struct timespec64 ts = timespec_to_timespec64(tss->ts[0]);
- tcp_recv_sw_timestamp(msg, sk, &ts);
+ tcp_recv_sw_timestamp(msg, sk, &tss->ts[0]);
if (sk->sk_tsflags & SOF_TIMESTAMPING_SOFTWARE)
has_timestamping = true;
else
- tss->ts[0] = (struct timespec) {0};
+ tss->ts[0] = (struct timespec64) {0};
if (tss->ts[2].tv_sec || tss->ts[2].tv_nsec) {
if (sk->sk_tsflags & SOF_TIMESTAMPING_RAW_HARDWARE)
has_timestamping = true;
else
- tss->ts[2] = (struct timespec) {0};
+ tss->ts[2] = (struct timespec64) {0};
}
if (has_timestamping) {
- tss->ts[1] = (struct timespec) {0};
- put_cmsg(msg, SOL_SOCKET, SO_TIMESTAMPING_OLD,
- sizeof(*tss), tss);
+ tss->ts[1] = (struct timespec64) {0};
+ if (sock_flag(sk, SOCK_TSTAMP_NEW))
+ put_cmsg_scm_timestamping64(msg, tss);
+ else
+ put_cmsg_scm_timestamping(msg, tss);
}
}
@@ -1963,7 +1964,7 @@ int tcp_recvmsg(struct sock *sk, struct msghdr *msg, size_t len, int nonblock,
long timeo;
struct sk_buff *skb, *last;
u32 urg_hole = 0;
- struct scm_timestamping tss;
+ struct scm_timestamping_internal tss;
bool has_tss = false;
bool has_cmsg;
diff --git a/net/smc/af_smc.c b/net/smc/af_smc.c
index 80e2119f1c70..e588305e9cf4 100644
--- a/net/smc/af_smc.c
+++ b/net/smc/af_smc.c
@@ -280,7 +280,8 @@ static void smc_copy_sock_settings(struct sock *nsk, struct sock *osk,
(1UL << SOCK_RXQ_OVFL) | \
(1UL << SOCK_WIFI_STATUS) | \
(1UL << SOCK_NOFCS) | \
- (1UL << SOCK_FILTER_LOCKED))
+ (1UL << SOCK_FILTER_LOCKED) | \
+ (1UL << SOCK_TSTAMP_NEW))
/* copy only relevant settings and flags of SOL_SOCKET level from smc to
* clc socket (since smc is not called for these options from net/core)
*/
diff --git a/net/socket.c b/net/socket.c
index 9abeb6bc9cfe..14fa6febfc3d 100644
--- a/net/socket.c
+++ b/net/socket.c
@@ -731,6 +731,7 @@ static void sock_recv_sw_timestamp(struct msghdr *msg, struct sock *sk,
sizeof(ts), &ts);
}
}
+
/*
* called from sock_recv_timestamp() if sock_flag(sk, SOCK_RCVTSTAMP)
* or sock_flag(sk, SOCK_RCVTSTAMPNS)
@@ -739,8 +740,8 @@ void __sock_recv_timestamp(struct msghdr *msg, struct sock *sk,
struct sk_buff *skb)
{
int need_software_tstamp = sock_flag(sk, SOCK_RCVTSTAMP) || sock_flag(sk, SOCK_RCVTSTAMPNS);
- struct scm_timestamping tss;
- int empty = 1, false_tstamp = 0;
+ struct scm_timestamping_internal tss;
+ int empty = 1, false_tstamp = 0, new_tstamp = 0;
struct skb_shared_hwtstamps *shhwtstamps =
skb_hwtstamps(skb);
@@ -756,20 +757,23 @@ void __sock_recv_timestamp(struct msghdr *msg, struct sock *sk,
memset(&tss, 0, sizeof(tss));
if ((sk->sk_tsflags & SOF_TIMESTAMPING_SOFTWARE) &&
- ktime_to_timespec_cond(skb->tstamp, tss.ts + 0))
+ ktime_to_timespec64_cond(skb->tstamp, tss.ts + 0))
empty = 0;
if (shhwtstamps &&
(sk->sk_tsflags & SOF_TIMESTAMPING_RAW_HARDWARE) &&
!skb_is_swtx_tstamp(skb, false_tstamp) &&
- ktime_to_timespec_cond(shhwtstamps->hwtstamp, tss.ts + 2)) {
+ ktime_to_timespec64_cond(shhwtstamps->hwtstamp, tss.ts + 2)) {
empty = 0;
if ((sk->sk_tsflags & SOF_TIMESTAMPING_OPT_PKTINFO) &&
!skb_is_err_queue(skb))
put_ts_pktinfo(msg, skb);
}
if (!empty) {
- put_cmsg(msg, SOL_SOCKET,
- SO_TIMESTAMPING_OLD, sizeof(tss), &tss);
+ new_tstamp = sock_flag(sk, SOCK_TSTAMP_NEW);
+ if (new_tstamp)
+ put_cmsg_scm_timestamping64(msg, &tss);
+ else
+ put_cmsg_scm_timestamping(msg, &tss);
if (skb_is_err_queue(skb) && skb->len &&
SKB_EXT_ERR(skb)->opt_stats)
--
2.17.1
^ permalink raw reply related
* [PATCH 7/8] socket: Add SO_TIMESTAMP[NS]_NEW
From: Deepa Dinamani @ 2018-11-24 2:20 UTC (permalink / raw)
To: davem, linux-kernel
Cc: netdev, viro, arnd, y2038, jejb, ralf, rth, linux-alpha,
linux-mips, linux-parisc, linux-rdma, sparclinux
In-Reply-To: <20181124022035.17519-1-deepa.kernel@gmail.com>
Add SO_TIMESTAMP_NEW and SO_TIMESTAMPNS_NEW variants of
socket timestamp options.
These are the y2038 safe versions of the SO_TIMESTAMP_OLD
and SO_TIMESTAMPNS_OLD for all architectures.
Note that the format of scm_timestamping.ts[0] is not changed
in this patch.
Signed-off-by: Deepa Dinamani <deepa.kernel@gmail.com>
Cc: jejb@parisc-linux.org
Cc: ralf@linux-mips.org
Cc: rth@twiddle.net
Cc: linux-alpha@vger.kernel.org
Cc: linux-mips@linux-mips.org
Cc: linux-parisc@vger.kernel.org
Cc: linux-rdma@vger.kernel.org
Cc: netdev@vger.kernel.org
Cc: sparclinux@vger.kernel.org
---
arch/alpha/include/uapi/asm/socket.h | 15 ++++++-
arch/mips/include/uapi/asm/socket.h | 14 +++++-
arch/parisc/include/uapi/asm/socket.h | 14 +++++-
arch/sparc/include/uapi/asm/socket.h | 14 +++++-
include/linux/skbuff.h | 18 ++++++++
include/net/sock.h | 1 +
include/uapi/asm-generic/socket.h | 15 ++++++-
net/core/sock.c | 18 ++++++++
net/ipv4/tcp.c | 61 +++++++++++++++++++--------
net/rds/af_rds.c | 8 +++-
net/rds/recv.c | 16 ++++++-
net/socket.c | 47 +++++++++++++++------
12 files changed, 197 insertions(+), 44 deletions(-)
diff --git a/arch/alpha/include/uapi/asm/socket.h b/arch/alpha/include/uapi/asm/socket.h
index 00e45c80e574..352e3dc0b3d9 100644
--- a/arch/alpha/include/uapi/asm/socket.h
+++ b/arch/alpha/include/uapi/asm/socket.h
@@ -3,6 +3,7 @@
#define _UAPI_ASM_SOCKET_H
#include <asm/sockios.h>
+#include <asm/bitsperlong.h>
/* For setsockopt(2) */
/*
@@ -110,12 +111,22 @@
#define SO_TIMESTAMP_OLD 29
#define SO_TIMESTAMPNS_OLD 35
+
#define SO_TIMESTAMPING_OLD 37
+#define SO_TIMESTAMP_NEW 62
+#define SO_TIMESTAMPNS_NEW 63
+
#if !defined(__KERNEL__)
-#define SO_TIMESTAMP SO_TIMESTAMP_OLD
-#define SO_TIMESTAMPNS SO_TIMESTAMPNS_OLD
+#if __BITS_PER_LONG == 64
+#define SO_TIMESTAMP SO_TIMESTAMP_OLD
+#define SO_TIMESTAMPNS SO_TIMESTAMPNS_OLD
+#else
+#define SO_TIMESTAMP (sizeof(time_t) == sizeof(__kernel_long_t) ? SO_TIMESTAMP_OLD : SO_TIMESTAMP_NEW)
+#define SO_TIMESTAMPNS (sizeof(time_t) == sizeof(__kernel_long_t) ? SO_TIMESTAMPNS_OLD : SO_TIMESTAMPNS_NEW)
+#endif
+
#define SO_TIMESTAMPING SO_TIMESTAMPING_OLD
#define SCM_TIMESTAMP SO_TIMESTAMP
diff --git a/arch/mips/include/uapi/asm/socket.h b/arch/mips/include/uapi/asm/socket.h
index b9553f770346..d1752e3f1248 100644
--- a/arch/mips/include/uapi/asm/socket.h
+++ b/arch/mips/include/uapi/asm/socket.h
@@ -11,6 +11,7 @@
#define _UAPI_ASM_SOCKET_H
#include <asm/sockios.h>
+#include <asm/bitsperlong.h>
/*
* For setsockopt(2)
@@ -123,10 +124,19 @@
#define SO_TIMESTAMPNS_OLD 35
#define SO_TIMESTAMPING_OLD 37
+#define SO_TIMESTAMP_NEW 62
+#define SO_TIMESTAMPNS_NEW 63
+
#if !defined(__KERNEL__)
-#define SO_TIMESTAMP SO_TIMESTAMP_OLD
-#define SO_TIMESTAMPNS SO_TIMESTAMPNS_OLD
+#if __BITS_PER_LONG == 64
+#define SO_TIMESTAMP SO_TIMESTAMP_OLD
+#define SO_TIMESTAMPNS SO_TIMESTAMPNS_OLD
+#else
+#define SO_TIMESTAMP (sizeof(time_t) == sizeof(__kernel_long_t) ? SO_TIMESTAMP_OLD : SO_TIMESTAMP_NEW)
+#define SO_TIMESTAMPNS (sizeof(time_t) == sizeof(__kernel_long_t) ? SO_TIMESTAMPNS_OLD : SO_TIMESTAMPNS_NEW)
+#endif
+
#define SO_TIMESTAMPING SO_TIMESTAMPING_OLD
#define SCM_TIMESTAMP SO_TIMESTAMP
diff --git a/arch/parisc/include/uapi/asm/socket.h b/arch/parisc/include/uapi/asm/socket.h
index 37cdfe64bb27..0a45b668abd1 100644
--- a/arch/parisc/include/uapi/asm/socket.h
+++ b/arch/parisc/include/uapi/asm/socket.h
@@ -3,6 +3,7 @@
#define _UAPI_ASM_SOCKET_H
#include <asm/sockios.h>
+#include <asm/bitsperlong.h>
/* For setsockopt(2) */
#define SOL_SOCKET 0xffff
@@ -104,10 +105,19 @@
#define SO_TIMESTAMPNS_OLD 0x4013
#define SO_TIMESTAMPING_OLD 0x4020
+#define SO_TIMESTAMP_NEW 0x4037
+#define SO_TIMESTAMPNS_NEW 0x4038
+
#if !defined(__KERNEL__)
-#define SO_TIMESTAMP SO_TIMESTAMP_OLD
-#define SO_TIMESTAMPNS SO_TIMESTAMPNS_OLD
+#if __BITS_PER_LONG == 64
+#define SO_TIMESTAMP SO_TIMESTAMP_OLD
+#define SO_TIMESTAMPNS SO_TIMESTAMPNS_OLD
+#else
+#define SO_TIMESTAMP (sizeof(time_t) == sizeof(__kernel_long_t) ? SO_TIMESTAMP_OLD : SO_TIMESTAMP_NEW)
+#define SO_TIMESTAMPNS (sizeof(time_t) == sizeof(__kernel_long_t) ? SO_TIMESTAMPNS_OLD : SO_TIMESTAMPNS_NEW)
+#endif
+
#define SO_TIMESTAMPING SO_TIMESTAMPING_OLD
#define SCM_TIMESTAMP SO_TIMESTAMP
diff --git a/arch/sparc/include/uapi/asm/socket.h b/arch/sparc/include/uapi/asm/socket.h
index ca573641fc6c..dc8527cae5a7 100644
--- a/arch/sparc/include/uapi/asm/socket.h
+++ b/arch/sparc/include/uapi/asm/socket.h
@@ -3,6 +3,7 @@
#define _ASM_SOCKET_H
#include <asm/sockios.h>
+#include <asm/bitsperlong.h>
/* For setsockopt(2) */
#define SOL_SOCKET 0xffff
@@ -105,10 +106,19 @@
#define SO_TIMESTAMPNS_OLD 0x0021
#define SO_TIMESTAMPING_OLD 0x0023
+#define SO_TIMESTAMP_NEW 0x0040
+#define SO_TIMESTAMPNS_NEW 0x0041
+
#if !defined(__KERNEL__)
-#define SO_TIMESTAMP SO_TIMESTAMP_OLD
-#define SO_TIMESTAMPNS SO_TIMESTAMPNS_OLD
+#if __BITS_PER_LONG == 64
+#define SO_TIMESTAMP SO_TIMESTAMP_OLD
+#define SO_TIMESTAMPNS SO_TIMESTAMPNS_OLD
+#else
+#define SO_TIMESTAMP (sizeof(time_t) == sizeof(__kernel_long_t) ? SO_TIMESTAMP_OLD : SO_TIMESTAMP_NEW)
+#define SO_TIMESTAMPNS (sizeof(time_t) == sizeof(__kernel_long_t) ? SO_TIMESTAMPNS_OLD : SO_TIMESTAMPNS_NEW)
+#endif
+
#define SO_TIMESTAMPING SO_TIMESTAMPING_OLD
#define SCM_TIMESTAMP SO_TIMESTAMP
diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h
index e2dc01330cb1..1e42c4a2209d 100644
--- a/include/linux/skbuff.h
+++ b/include/linux/skbuff.h
@@ -3465,12 +3465,30 @@ static inline void skb_get_timestamp(const struct sk_buff *skb,
*stamp = ns_to_kernel_old_timeval(skb->tstamp);
}
+static inline void skb_get_new_timestamp(const struct sk_buff *skb,
+ struct sock_timeval *stamp)
+{
+ struct timespec64 ts = ktime_to_timespec64(skb->tstamp);
+
+ stamp->tv_sec = ts.tv_sec;
+ stamp->tv_usec = ts.tv_nsec / 1000;
+}
+
static inline void skb_get_timestampns(const struct sk_buff *skb,
struct timespec *stamp)
{
*stamp = ktime_to_timespec(skb->tstamp);
}
+static inline void skb_get_new_timestampns(const struct sk_buff *skb,
+ struct __kernel_timespec *stamp)
+{
+ struct timespec64 ts = ktime_to_timespec64(skb->tstamp);
+
+ stamp->tv_sec = ts.tv_sec;
+ stamp->tv_nsec = ts.tv_nsec;
+}
+
static inline void __net_timestamp(struct sk_buff *skb)
{
skb->tstamp = ktime_get_real();
diff --git a/include/net/sock.h b/include/net/sock.h
index 8143c4c1a49d..9edf909dc176 100644
--- a/include/net/sock.h
+++ b/include/net/sock.h
@@ -801,6 +801,7 @@ enum sock_flags {
SOCK_RCU_FREE, /* wait rcu grace period in sk_destruct() */
SOCK_TXTIME,
SOCK_XDP, /* XDP is attached */
+ SOCK_TSTAMP_NEW, /* Indicates 64 bit timestamps always */
};
#define SK_FLAGS_TIMESTAMP ((1UL << SOCK_TIMESTAMP) | (1UL << SOCK_TIMESTAMPING_RX_SOFTWARE))
diff --git a/include/uapi/asm-generic/socket.h b/include/uapi/asm-generic/socket.h
index dc704e41203d..0b0fae6b57a9 100644
--- a/include/uapi/asm-generic/socket.h
+++ b/include/uapi/asm-generic/socket.h
@@ -3,6 +3,7 @@
#define __ASM_GENERIC_SOCKET_H
#include <asm/sockios.h>
+#include <asm/bitsperlong.h>
/* For setsockopt(2) */
#define SOL_SOCKET 1
@@ -107,10 +108,20 @@
#define SO_TIMESTAMPNS_OLD 35
#define SO_TIMESTAMPING_OLD 37
+#define SO_TIMESTAMP_NEW 62
+#define SO_TIMESTAMPNS_NEW 63
+
#if !defined(__KERNEL__)
-#define SO_TIMESTAMP SO_TIMESTAMP_OLD
-#define SO_TIMESTAMPNS SO_TIMESTAMPNS_OLD
+#if __BITS_PER_LONG == 64 || (defined(__x86_64__) && defined(__ILP32__))
+/* on 64-bit and x32, avoid the ?: operator */
+#define SO_TIMESTAMP SO_TIMESTAMP_OLD
+#define SO_TIMESTAMPNS SO_TIMESTAMPNS_OLD
+#else
+#define SO_TIMESTAMP (sizeof(time_t) == sizeof(__kernel_long_t) ? SO_TIMESTAMP_OLD : SO_TIMESTAMP_NEW)
+#define SO_TIMESTAMPNS (sizeof(time_t) == sizeof(__kernel_long_t) ? SO_TIMESTAMPNS_OLD : SO_TIMESTAMPNS_NEW)
+#endif
+
#define SO_TIMESTAMPING SO_TIMESTAMPING_OLD
#define SCM_TIMESTAMP SO_TIMESTAMP
diff --git a/net/core/sock.c b/net/core/sock.c
index e60036618205..7b485dfaa400 100644
--- a/net/core/sock.c
+++ b/net/core/sock.c
@@ -652,15 +652,23 @@ static void setsockopt_timestamp(struct sock *sk, int type, int val)
if (!val) {
sock_reset_flag(sk, SOCK_RCVTSTAMP);
sock_reset_flag(sk, SOCK_RCVTSTAMPNS);
+ sock_reset_flag(sk, SOCK_TSTAMP_NEW);
return;
}
+ if (type == SO_TIMESTAMP_NEW || type == SO_TIMESTAMPNS_NEW)
+ sock_set_flag(sk, SOCK_TSTAMP_NEW);
+ else
+ sock_reset_flag(sk, SOCK_TSTAMP_NEW);
+
switch (type) {
case SO_TIMESTAMP_OLD:
+ case SO_TIMESTAMP_NEW:
sock_reset_flag(sk, SOCK_RCVTSTAMPNS);
sock_set_flag(sk, SOCK_RCVTSTAMP);
break;
case SO_TIMESTAMPNS_OLD:
+ case SO_TIMESTAMPNS_NEW:
sock_reset_flag(sk, SOCK_RCVTSTAMP);
sock_set_flag(sk, SOCK_RCVTSTAMPNS);
break;
@@ -837,7 +845,9 @@ int sock_setsockopt(struct socket *sock, int level, int optname,
break;
case SO_TIMESTAMP_OLD:
+ case SO_TIMESTAMP_NEW:
case SO_TIMESTAMPNS_OLD:
+ case SO_TIMESTAMPNS_NEW:
setsockopt_timestamp(sk, optname, valbool);
break;
@@ -1202,6 +1212,14 @@ int sock_getsockopt(struct socket *sock, int level, int optname,
v.val = sock_flag(sk, SOCK_RCVTSTAMPNS);
break;
+ case SO_TIMESTAMP_NEW:
+ v.val = sock_flag(sk, SOCK_RCVTSTAMP) && sock_flag(sk, SOCK_TSTAMP_NEW);
+ break;
+
+ case SO_TIMESTAMPNS_NEW:
+ v.val = sock_flag(sk, SOCK_RCVTSTAMPNS) && sock_flag(sk, SOCK_TSTAMP_NEW);
+ break;
+
case SO_TIMESTAMPING_OLD:
v.val = sk->sk_tsflags;
break;
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
index 805d9965a210..b470f470343a 100644
--- a/net/ipv4/tcp.c
+++ b/net/ipv4/tcp.c
@@ -1860,30 +1860,57 @@ static void tcp_update_recv_tstamps(struct sk_buff *skb,
tss->ts[2] = (struct timespec) {0};
}
-/* Similar to __sock_recv_timestamp, but does not require an skb */
-static void tcp_recv_timestamp(struct msghdr *msg, const struct sock *sk,
- struct scm_timestamping *tss)
+static void tcp_recv_sw_timestamp(struct msghdr *msg, const struct sock *sk, struct timespec64 *ts)
{
- struct __kernel_old_timeval tv;
- bool has_timestamping = false;
+ int new_tstamp = sock_flag(sk, SOCK_TSTAMP_NEW);
- if (tss->ts[0].tv_sec || tss->ts[0].tv_nsec) {
+ if (ts->tv_sec || ts->tv_nsec) {
if (sock_flag(sk, SOCK_RCVTSTAMPNS)) {
- put_cmsg(msg, SOL_SOCKET, SO_TIMESTAMPNS_OLD,
- sizeof(tss->ts[0]), &tss->ts[0]);
+ if (new_tstamp) {
+ struct __kernel_timespec kts = {ts->tv_sec, ts->tv_nsec};
+
+ put_cmsg(msg, SOL_SOCKET, SO_TIMESTAMPNS_NEW,
+ sizeof(kts), &kts);
+ } else {
+ struct timespec ts_old = timespec64_to_timespec(*ts);
+
+ put_cmsg(msg, SOL_SOCKET, SO_TIMESTAMPNS_OLD,
+ sizeof(ts), &ts_old);
+ }
} else if (sock_flag(sk, SOCK_RCVTSTAMP)) {
- tv.tv_sec = tss->ts[0].tv_sec;
- tv.tv_usec = tss->ts[0].tv_nsec / 1000;
+ if (new_tstamp) {
+ struct sock_timeval stv;
- put_cmsg(msg, SOL_SOCKET, SO_TIMESTAMP_OLD,
- sizeof(tv), &tv);
- }
+ stv.tv_sec = ts->tv_sec;
+ stv.tv_usec = ts->tv_nsec / 1000;
- if (sk->sk_tsflags & SOF_TIMESTAMPING_SOFTWARE)
- has_timestamping = true;
- else
- tss->ts[0] = (struct timespec) {0};
+ put_cmsg(msg, SOL_SOCKET, SO_TIMESTAMP_NEW,
+ sizeof(stv), &stv);
+ } else {
+ struct __kernel_old_timeval tv;
+
+ tv.tv_sec = ts->tv_sec;
+ tv.tv_usec = ts->tv_nsec / 1000;
+ put_cmsg(msg, SOL_SOCKET, SO_TIMESTAMP_NEW,
+ sizeof(tv), &tv);
+ }
+ }
}
+}
+
+/* Similar to __sock_recv_timestamp, but does not require an skb */
+static void tcp_recv_timestamp(struct msghdr *msg, const struct sock *sk,
+ struct scm_timestamping *tss)
+{
+ bool has_timestamping = false;
+ struct timespec64 ts = timespec_to_timespec64(tss->ts[0]);
+
+ tcp_recv_sw_timestamp(msg, sk, &ts);
+
+ if (sk->sk_tsflags & SOF_TIMESTAMPING_SOFTWARE)
+ has_timestamping = true;
+ else
+ tss->ts[0] = (struct timespec) {0};
if (tss->ts[2].tv_sec || tss->ts[2].tv_nsec) {
if (sk->sk_tsflags & SOF_TIMESTAMPING_RAW_HARDWARE)
diff --git a/net/rds/af_rds.c b/net/rds/af_rds.c
index eeb4639adbe5..65571a6273c3 100644
--- a/net/rds/af_rds.c
+++ b/net/rds/af_rds.c
@@ -348,7 +348,7 @@ static int rds_set_transport(struct rds_sock *rs, char __user *optval,
}
static int rds_enable_recvtstamp(struct sock *sk, char __user *optval,
- int optlen)
+ int optlen, int optname)
{
int val, valbool;
@@ -360,6 +360,9 @@ static int rds_enable_recvtstamp(struct sock *sk, char __user *optval,
valbool = val ? 1 : 0;
+ if (optname == SO_TIMESTAMP_NEW)
+ sock_set_flag(sk, SOCK_TSTAMP_NEW);
+
if (valbool)
sock_set_flag(sk, SOCK_RCVTSTAMP);
else
@@ -431,8 +434,9 @@ static int rds_setsockopt(struct socket *sock, int level, int optname,
release_sock(sock->sk);
break;
case SO_TIMESTAMP_OLD:
+ case SO_TIMESTAMP_NEW:
lock_sock(sock->sk);
- ret = rds_enable_recvtstamp(sock->sk, optval, optlen);
+ ret = rds_enable_recvtstamp(sock->sk, optval, optlen, optname);
release_sock(sock->sk);
break;
case SO_RDS_MSG_RXPATH_LATENCY:
diff --git a/net/rds/recv.c b/net/rds/recv.c
index 435bf2320cd3..4c3fd56dc4ca 100644
--- a/net/rds/recv.c
+++ b/net/rds/recv.c
@@ -550,8 +550,20 @@ static int rds_cmsg_recv(struct rds_incoming *inc, struct msghdr *msg,
if ((inc->i_rx_tstamp != 0) &&
sock_flag(rds_rs_to_sk(rs), SOCK_RCVTSTAMP)) {
struct __kernel_old_timeval tv = ns_to_kernel_old_timeval(inc->i_rx_tstamp);
- ret = put_cmsg(msg, SOL_SOCKET, SO_TIMESTAMP_OLD,
- sizeof(tv), &tv);
+
+ if (!sock_flag(rds_rs_to_sk(rs), SOCK_TSTAMP_NEW)) {
+ ret = put_cmsg(msg, SOL_SOCKET, SO_TIMESTAMP_OLD,
+ sizeof(tv), &tv);
+ } else {
+ struct sock_timeval sk_tv;
+
+ sk_tv.tv_sec = tv.tv_sec;
+ sk_tv.tv_usec = tv.tv_usec;
+
+ ret = put_cmsg(msg, SOL_SOCKET, SO_TIMESTAMP_NEW,
+ sizeof(sk_tv), &sk_tv);
+ }
+
if (ret)
goto out;
}
diff --git a/net/socket.c b/net/socket.c
index d3defba55547..9abeb6bc9cfe 100644
--- a/net/socket.c
+++ b/net/socket.c
@@ -699,6 +699,38 @@ static void put_ts_pktinfo(struct msghdr *msg, struct sk_buff *skb)
sizeof(ts_pktinfo), &ts_pktinfo);
}
+static void sock_recv_sw_timestamp(struct msghdr *msg, struct sock *sk,
+ struct sk_buff *skb)
+{
+ if (sock_flag(sk, SOCK_TSTAMP_NEW)) {
+ if (!sock_flag(sk, SOCK_RCVTSTAMPNS)) {
+ struct sock_timeval tv;
+
+ skb_get_new_timestamp(skb, &tv);
+ put_cmsg(msg, SOL_SOCKET, SO_TIMESTAMP_NEW,
+ sizeof(tv), &tv);
+ } else {
+ struct __kernel_timespec ts;
+
+ skb_get_new_timestampns(skb, &ts);
+ put_cmsg(msg, SOL_SOCKET, SO_TIMESTAMPNS_NEW,
+ sizeof(ts), &ts);
+ }
+ }
+ if (!sock_flag(sk, SOCK_RCVTSTAMPNS)) {
+ struct __kernel_old_timeval tv;
+
+ skb_get_timestamp(skb, &tv);
+ put_cmsg(msg, SOL_SOCKET, SO_TIMESTAMP_OLD,
+ sizeof(tv), &tv);
+ } else {
+ struct timespec ts;
+
+ skb_get_timestampns(skb, &ts);
+ put_cmsg(msg, SOL_SOCKET, SO_TIMESTAMPNS_OLD,
+ sizeof(ts), &ts);
+ }
+}
/*
* called from sock_recv_timestamp() if sock_flag(sk, SOCK_RCVTSTAMP)
* or sock_flag(sk, SOCK_RCVTSTAMPNS)
@@ -719,19 +751,8 @@ void __sock_recv_timestamp(struct msghdr *msg, struct sock *sk,
false_tstamp = 1;
}
- if (need_software_tstamp) {
- if (!sock_flag(sk, SOCK_RCVTSTAMPNS)) {
- struct __kernel_old_timeval tv;
- skb_get_timestamp(skb, &tv);
- put_cmsg(msg, SOL_SOCKET, SO_TIMESTAMP_OLD,
- sizeof(tv), &tv);
- } else {
- struct timespec ts;
- skb_get_timestampns(skb, &ts);
- put_cmsg(msg, SOL_SOCKET, SO_TIMESTAMPNS_OLD,
- sizeof(ts), &ts);
- }
- }
+ if (need_software_tstamp)
+ sock_recv_sw_timestamp(msg, sk, skb);
memset(&tss, 0, sizeof(tss));
if ((sk->sk_tsflags & SOF_TIMESTAMPING_SOFTWARE) &&
--
2.17.1
^ permalink raw reply related
* [PATCH 5/8] socket: Use old_timeval types for socket timestamps
From: Deepa Dinamani @ 2018-11-24 2:20 UTC (permalink / raw)
To: davem, linux-kernel; +Cc: netdev, viro, arnd, y2038, isdn
In-Reply-To: <20181124022035.17519-1-deepa.kernel@gmail.com>
As part of y2038 solution, all internal uses of
struct timeval are replaced by struct __kernel_old_timeval
and struct compat_timeval by struct old_timeval32.
Make socket timestamps use these new types.
This is mainly to be able to verify that the kernel build
is y2038 safe when such non y2038 safe types are not
supported anymore.
Signed-off-by: Deepa Dinamani <deepa.kernel@gmail.com>
Cc: isdn@linux-pingi.de
---
drivers/isdn/mISDN/socket.c | 2 +-
include/linux/skbuff.h | 6 +++---
net/bluetooth/hci_sock.c | 4 ++--
net/compat.c | 6 +++---
net/ipv4/tcp.c | 2 +-
net/rds/recv.c | 2 +-
net/socket.c | 2 +-
7 files changed, 12 insertions(+), 12 deletions(-)
diff --git a/drivers/isdn/mISDN/socket.c b/drivers/isdn/mISDN/socket.c
index 15d3ca37669a..4ab8b1b6608f 100644
--- a/drivers/isdn/mISDN/socket.c
+++ b/drivers/isdn/mISDN/socket.c
@@ -103,7 +103,7 @@ mISDN_ctrl(struct mISDNchannel *ch, u_int cmd, void *arg)
static inline void
mISDN_sock_cmsg(struct sock *sk, struct msghdr *msg, struct sk_buff *skb)
{
- struct timeval tv;
+ struct __kernel_old_timeval tv;
if (_pms(sk)->cmask & MISDN_TIME_STAMP) {
skb_get_timestamp(skb, &tv);
diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h
index a2e8297a5b00..e2dc01330cb1 100644
--- a/include/linux/skbuff.h
+++ b/include/linux/skbuff.h
@@ -3453,16 +3453,16 @@ static inline ktime_t skb_get_ktime(const struct sk_buff *skb)
/**
* skb_get_timestamp - get timestamp from a skb
* @skb: skb to get stamp from
- * @stamp: pointer to struct timeval to store stamp in
+ * @stamp: pointer to struct __kernel_old_timeval to store stamp in
*
* Timestamps are stored in the skb as offsets to a base timestamp.
* This function converts the offset back to a struct timeval and stores
* it in stamp.
*/
static inline void skb_get_timestamp(const struct sk_buff *skb,
- struct timeval *stamp)
+ struct __kernel_old_timeval *stamp)
{
- *stamp = ktime_to_timeval(skb->tstamp);
+ *stamp = ns_to_kernel_old_timeval(skb->tstamp);
}
static inline void skb_get_timestampns(const struct sk_buff *skb,
diff --git a/net/bluetooth/hci_sock.c b/net/bluetooth/hci_sock.c
index 10dfd20c748e..32aff3755480 100644
--- a/net/bluetooth/hci_sock.c
+++ b/net/bluetooth/hci_sock.c
@@ -1400,9 +1400,9 @@ static void hci_sock_cmsg(struct sock *sk, struct msghdr *msg,
if (mask & HCI_CMSG_TSTAMP) {
#ifdef CONFIG_COMPAT
- struct compat_timeval ctv;
+ struct old_timeval32 ctv;
#endif
- struct timeval tv;
+ struct __kernel_old_timeval tv;
void *data;
int len;
diff --git a/net/compat.c b/net/compat.c
index 720ab07276b0..8dea66c96926 100644
--- a/net/compat.c
+++ b/net/compat.c
@@ -209,8 +209,8 @@ int put_cmsg_compat(struct msghdr *kmsg, int level, int type, int len, void *dat
{
struct compat_cmsghdr __user *cm = (struct compat_cmsghdr __user *) kmsg->msg_control;
struct compat_cmsghdr cmhdr;
- struct compat_timeval ctv;
- struct compat_timespec cts[3];
+ struct old_timeval32 ctv;
+ struct old_timespec32 cts[3];
int cmlen;
if (cm == NULL || kmsg->msg_controllen < sizeof(*cm)) {
@@ -220,7 +220,7 @@ int put_cmsg_compat(struct msghdr *kmsg, int level, int type, int len, void *dat
if (!COMPAT_USE_64BIT_TIME) {
if (level == SOL_SOCKET && type == SO_TIMESTAMP_OLD) {
- struct timeval *tv = (struct timeval *)data;
+ struct __kernel_old_timeval *tv = (struct __kernel_old_timeval *)data;
ctv.tv_sec = tv->tv_sec;
ctv.tv_usec = tv->tv_usec;
data = &ctv;
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
index d6eb5f542fcf..805d9965a210 100644
--- a/net/ipv4/tcp.c
+++ b/net/ipv4/tcp.c
@@ -1864,7 +1864,7 @@ static void tcp_update_recv_tstamps(struct sk_buff *skb,
static void tcp_recv_timestamp(struct msghdr *msg, const struct sock *sk,
struct scm_timestamping *tss)
{
- struct timeval tv;
+ struct __kernel_old_timeval tv;
bool has_timestamping = false;
if (tss->ts[0].tv_sec || tss->ts[0].tv_nsec) {
diff --git a/net/rds/recv.c b/net/rds/recv.c
index 04e30d63a159..435bf2320cd3 100644
--- a/net/rds/recv.c
+++ b/net/rds/recv.c
@@ -549,7 +549,7 @@ static int rds_cmsg_recv(struct rds_incoming *inc, struct msghdr *msg,
if ((inc->i_rx_tstamp != 0) &&
sock_flag(rds_rs_to_sk(rs), SOCK_RCVTSTAMP)) {
- struct timeval tv = ktime_to_timeval(inc->i_rx_tstamp);
+ struct __kernel_old_timeval tv = ns_to_kernel_old_timeval(inc->i_rx_tstamp);
ret = put_cmsg(msg, SOL_SOCKET, SO_TIMESTAMP_OLD,
sizeof(tv), &tv);
if (ret)
diff --git a/net/socket.c b/net/socket.c
index c7455349a3c1..d3defba55547 100644
--- a/net/socket.c
+++ b/net/socket.c
@@ -721,7 +721,7 @@ void __sock_recv_timestamp(struct msghdr *msg, struct sock *sk,
if (need_software_tstamp) {
if (!sock_flag(sk, SOCK_RCVTSTAMPNS)) {
- struct timeval tv;
+ struct __kernel_old_timeval tv;
skb_get_timestamp(skb, &tv);
put_cmsg(msg, SOL_SOCKET, SO_TIMESTAMP_OLD,
sizeof(tv), &tv);
--
2.17.1
^ permalink raw reply related
* [PATCH 4/8] arch: sparc: Override struct __kernel_old_timeval
From: Deepa Dinamani @ 2018-11-24 2:20 UTC (permalink / raw)
To: davem, linux-kernel; +Cc: netdev, viro, arnd, y2038, sparclinux
In-Reply-To: <20181124022035.17519-1-deepa.kernel@gmail.com>
struct __kernel_old_timeval is supposed to have the same
layout as struct timeval. But, it was inadvarently missed
that __kernel_suseconds has a different definition for
sparc64.
Provide an asm-specific override that fixes it.
Reported-by: Arnd Bergmann <arnd@arndb.de>
Suggested-by: Arnd Bergmann <arnd@arndb.de>
Signed-off-by: Deepa Dinamani <deepa.kernel@gmail.com>
Cc: sparclinux@vger.kernel.org
---
arch/sparc/include/uapi/asm/posix_types.h | 10 ++++++++++
include/uapi/linux/time.h | 2 ++
2 files changed, 12 insertions(+)
diff --git a/arch/sparc/include/uapi/asm/posix_types.h b/arch/sparc/include/uapi/asm/posix_types.h
index fec499d6efb7..f139e0048628 100644
--- a/arch/sparc/include/uapi/asm/posix_types.h
+++ b/arch/sparc/include/uapi/asm/posix_types.h
@@ -19,6 +19,16 @@ typedef unsigned short __kernel_old_gid_t;
typedef int __kernel_suseconds_t;
#define __kernel_suseconds_t __kernel_suseconds_t
+typedef long __kernel_long_t;
+typedef unsigned long __kernel_ulong_t;
+#define __kernel_long_t __kernel_long_t
+
+struct __kernel_old_timeval {
+ __kernel_long_t tv_sec;
+ __kernel_suseconds_t tv_usec;
+};
+#define __kernel_old_timeval __kernel_old_timeval
+
#else
/* sparc 32 bit */
diff --git a/include/uapi/linux/time.h b/include/uapi/linux/time.h
index 6b56a2208be7..04d5587f30d3 100644
--- a/include/uapi/linux/time.h
+++ b/include/uapi/linux/time.h
@@ -63,10 +63,12 @@ struct __kernel_itimerspec {
* here, this is probably because it is not y2038 safe and needs to
* be changed to use another interface.
*/
+#ifndef __kernel_old_timeval
struct __kernel_old_timeval {
__kernel_long_t tv_sec;
__kernel_long_t tv_usec;
};
+#endif
/*
* The IDs of the various system clocks (for POSIX.1b interval timers):
--
2.17.1
^ permalink raw reply related
* [PATCH 3/8] socket: Disentangle SOCK_RCVTSTAMPNS from SOCK_RCVTSTAMP
From: Deepa Dinamani @ 2018-11-24 2:20 UTC (permalink / raw)
To: davem, linux-kernel; +Cc: netdev, viro, arnd, y2038
In-Reply-To: <20181124022035.17519-1-deepa.kernel@gmail.com>
SOCK_RCVTSTAMPNS is never set alone. SOCK_RCVTSTAMP
is always set along with SOCK_RCVTSTAMPNS. This leads to
checking for two flag states whenever we need to check for
SOCK_RCVTSTAMPS.
Also SOCK_RCVTSTAMPS was the only flag that needed to be
checked in order to verify if either of the two flags are
set. But, the two features are not actually dependent on
each other. This artificial dependency creates more
confusion.
The change does away with this logic as well.
Note that RDS seems to be supporting only SO_TIMESTAMP at
SOL_RDS level. And, it uses the same SOCK_RCVTSTAMP to track
this. Hence, the updates to rds_incoming->i_rx_tstamp only
track SOCK_RCVTSTAMP and not SOCK_RCVTSTAMPNS.
Signed-off-by: Deepa Dinamani <deepa.kernel@gmail.com>
---
include/net/sock.h | 4 +++-
net/core/sock.c | 37 ++++++++++++++++++++++++-------------
net/ipv4/tcp.c | 20 +++++++++-----------
net/socket.c | 3 ++-
net/unix/af_unix.c | 4 ++--
5 files changed, 40 insertions(+), 28 deletions(-)
diff --git a/include/net/sock.h b/include/net/sock.h
index f665d74ae509..8143c4c1a49d 100644
--- a/include/net/sock.h
+++ b/include/net/sock.h
@@ -2305,6 +2305,7 @@ sock_recv_timestamp(struct msghdr *msg, struct sock *sk, struct sk_buff *skb)
* - hardware time stamps available and wanted
*/
if (sock_flag(sk, SOCK_RCVTSTAMP) ||
+ sock_flag(sk, SOCK_RCVTSTAMPNS) ||
(sk->sk_tsflags & SOF_TIMESTAMPING_RX_SOFTWARE) ||
(kt && sk->sk_tsflags & SOF_TIMESTAMPING_SOFTWARE) ||
(hwtstamps->hwtstamp &&
@@ -2325,7 +2326,8 @@ static inline void sock_recv_ts_and_drops(struct msghdr *msg, struct sock *sk,
struct sk_buff *skb)
{
#define FLAGS_TS_OR_DROPS ((1UL << SOCK_RXQ_OVFL) | \
- (1UL << SOCK_RCVTSTAMP))
+ (1UL << SOCK_RCVTSTAMP) | \
+ (1UL << SOCK_RCVTSTAMPNS))
#define TSFLAGS_ANY (SOF_TIMESTAMPING_SOFTWARE | \
SOF_TIMESTAMPING_RAW_HARDWARE)
diff --git a/net/core/sock.c b/net/core/sock.c
index cf990db9b2a0..e60036618205 100644
--- a/net/core/sock.c
+++ b/net/core/sock.c
@@ -647,6 +647,28 @@ bool sk_mc_loop(struct sock *sk)
}
EXPORT_SYMBOL(sk_mc_loop);
+static void setsockopt_timestamp(struct sock *sk, int type, int val)
+{
+ if (!val) {
+ sock_reset_flag(sk, SOCK_RCVTSTAMP);
+ sock_reset_flag(sk, SOCK_RCVTSTAMPNS);
+ return;
+ }
+
+ switch (type) {
+ case SO_TIMESTAMP_OLD:
+ sock_reset_flag(sk, SOCK_RCVTSTAMPNS);
+ sock_set_flag(sk, SOCK_RCVTSTAMP);
+ break;
+ case SO_TIMESTAMPNS_OLD:
+ sock_reset_flag(sk, SOCK_RCVTSTAMP);
+ sock_set_flag(sk, SOCK_RCVTSTAMPNS);
+ break;
+ }
+
+ sock_enable_timestamp(sk, SOCK_TIMESTAMP);
+}
+
/*
* This is meant for all protocols to use and covers goings on
* at the socket level. Everything here is generic.
@@ -816,17 +838,7 @@ int sock_setsockopt(struct socket *sock, int level, int optname,
case SO_TIMESTAMP_OLD:
case SO_TIMESTAMPNS_OLD:
- if (valbool) {
- if (optname == SO_TIMESTAMP_OLD)
- sock_reset_flag(sk, SOCK_RCVTSTAMPNS);
- else
- sock_set_flag(sk, SOCK_RCVTSTAMPNS);
- sock_set_flag(sk, SOCK_RCVTSTAMP);
- sock_enable_timestamp(sk, SOCK_TIMESTAMP);
- } else {
- sock_reset_flag(sk, SOCK_RCVTSTAMP);
- sock_reset_flag(sk, SOCK_RCVTSTAMPNS);
- }
+ setsockopt_timestamp(sk, optname, valbool);
break;
case SO_TIMESTAMPING_OLD:
@@ -1183,8 +1195,7 @@ int sock_getsockopt(struct socket *sock, int level, int optname,
break;
case SO_TIMESTAMP_OLD:
- v.val = sock_flag(sk, SOCK_RCVTSTAMP) &&
- !sock_flag(sk, SOCK_RCVTSTAMPNS);
+ v.val = sock_flag(sk, SOCK_RCVTSTAMP);
break;
case SO_TIMESTAMPNS_OLD:
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
index 496848ab0269..d6eb5f542fcf 100644
--- a/net/ipv4/tcp.c
+++ b/net/ipv4/tcp.c
@@ -1868,17 +1868,15 @@ static void tcp_recv_timestamp(struct msghdr *msg, const struct sock *sk,
bool has_timestamping = false;
if (tss->ts[0].tv_sec || tss->ts[0].tv_nsec) {
- if (sock_flag(sk, SOCK_RCVTSTAMP)) {
- if (sock_flag(sk, SOCK_RCVTSTAMPNS)) {
- put_cmsg(msg, SOL_SOCKET, SO_TIMESTAMPNS_OLD,
- sizeof(tss->ts[0]), &tss->ts[0]);
- } else {
- tv.tv_sec = tss->ts[0].tv_sec;
- tv.tv_usec = tss->ts[0].tv_nsec / 1000;
-
- put_cmsg(msg, SOL_SOCKET, SO_TIMESTAMP_OLD,
- sizeof(tv), &tv);
- }
+ if (sock_flag(sk, SOCK_RCVTSTAMPNS)) {
+ put_cmsg(msg, SOL_SOCKET, SO_TIMESTAMPNS_OLD,
+ sizeof(tss->ts[0]), &tss->ts[0]);
+ } else if (sock_flag(sk, SOCK_RCVTSTAMP)) {
+ tv.tv_sec = tss->ts[0].tv_sec;
+ tv.tv_usec = tss->ts[0].tv_nsec / 1000;
+
+ put_cmsg(msg, SOL_SOCKET, SO_TIMESTAMP_OLD,
+ sizeof(tv), &tv);
}
if (sk->sk_tsflags & SOF_TIMESTAMPING_SOFTWARE)
diff --git a/net/socket.c b/net/socket.c
index dfc5742ccfbb..c7455349a3c1 100644
--- a/net/socket.c
+++ b/net/socket.c
@@ -701,11 +701,12 @@ static void put_ts_pktinfo(struct msghdr *msg, struct sk_buff *skb)
/*
* called from sock_recv_timestamp() if sock_flag(sk, SOCK_RCVTSTAMP)
+ * or sock_flag(sk, SOCK_RCVTSTAMPNS)
*/
void __sock_recv_timestamp(struct msghdr *msg, struct sock *sk,
struct sk_buff *skb)
{
- int need_software_tstamp = sock_flag(sk, SOCK_RCVTSTAMP);
+ int need_software_tstamp = sock_flag(sk, SOCK_RCVTSTAMP) || sock_flag(sk, SOCK_RCVTSTAMPNS);
struct scm_timestamping tss;
int empty = 1, false_tstamp = 0;
struct skb_shared_hwtstamps *shhwtstamps =
diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c
index 74d1eed7cbd4..531efd0ddeb1 100644
--- a/net/unix/af_unix.c
+++ b/net/unix/af_unix.c
@@ -1798,7 +1798,7 @@ static int unix_dgram_sendmsg(struct socket *sock, struct msghdr *msg,
if (unlikely(sk_locked))
unix_state_unlock(sk);
- if (sock_flag(other, SOCK_RCVTSTAMP))
+ if (sock_flag(other, SOCK_RCVTSTAMP) || sock_flag(other, SOCK_RCVTSTAMPNS))
__net_timestamp(skb);
maybe_add_creds(skb, sock, other);
skb_queue_tail(&other->sk_receive_queue, skb);
@@ -2141,7 +2141,7 @@ static int unix_dgram_recvmsg(struct socket *sock, struct msghdr *msg,
if (err)
goto out_free;
- if (sock_flag(sk, SOCK_RCVTSTAMP))
+ if (sock_flag(sk, SOCK_RCVTSTAMP) || sock_flag(sk, SOCK_RCVTSTAMPNS))
__sock_recv_timestamp(msg, sk, skb);
memset(&scm, 0, sizeof(scm));
--
2.17.1
^ permalink raw reply related
* [PATCH 2/8] sockopt: Rename SO_TIMESTAMP* to SO_TIMESTAMP*_OLD
From: Deepa Dinamani @ 2018-11-24 2:20 UTC (permalink / raw)
To: davem, linux-kernel
Cc: netdev, viro, arnd, y2038, deller, dhowells, jejb, ralf, rth,
linux-afs, linux-alpha, linux-arch, linux-mips, linux-parisc,
linux-rdma, sparclinux
In-Reply-To: <20181124022035.17519-1-deepa.kernel@gmail.com>
SO_TIMESTAMP, SO_TIMESTAMPNS and SO_TIMESTAMPING options, the
way they are currently defined, are not y2038 safe.
Subsequent patches in the series add new y2038 safe versions
of these options which provide 64 bit timestamps on all
architectures uniformly.
Hence, rename existing options with OLD tag suffixes.
Also note that kernel will not use the untagged SO_TIMESTAMP*
and SCM_TIMESTAMP* options internally anymore.
Signed-off-by: Deepa Dinamani <deepa.kernel@gmail.com>
Cc: deller@gmx.de
Cc: dhowells@redhat.com
Cc: jejb@parisc-linux.org
Cc: ralf@linux-mips.org
Cc: rth@twiddle.net
Cc: linux-afs@lists.infradead.org
Cc: linux-alpha@vger.kernel.org
Cc: linux-arch@vger.kernel.org
Cc: linux-mips@linux-mips.org
Cc: linux-parisc@vger.kernel.org
Cc: linux-rdma@vger.kernel.org
Cc: sparclinux@vger.kernel.org
---
arch/alpha/include/uapi/asm/socket.h | 23 ++++++++++++++++-------
arch/mips/include/uapi/asm/socket.h | 23 ++++++++++++++++-------
arch/parisc/include/uapi/asm/socket.h | 23 ++++++++++++++++-------
arch/sparc/include/uapi/asm/socket.h | 24 ++++++++++++++++--------
include/uapi/asm-generic/socket.h | 23 ++++++++++++++++-------
net/compat.c | 6 +++---
net/core/sock.c | 16 ++++++++--------
net/ipv4/tcp.c | 6 +++---
net/rds/af_rds.c | 2 +-
net/rds/recv.c | 2 +-
net/rxrpc/local_object.c | 2 +-
net/socket.c | 8 ++++----
12 files changed, 101 insertions(+), 57 deletions(-)
diff --git a/arch/alpha/include/uapi/asm/socket.h b/arch/alpha/include/uapi/asm/socket.h
index 065fb372e355..00e45c80e574 100644
--- a/arch/alpha/include/uapi/asm/socket.h
+++ b/arch/alpha/include/uapi/asm/socket.h
@@ -51,13 +51,9 @@
#define SO_GET_FILTER SO_ATTACH_FILTER
#define SO_PEERNAME 28
-#define SO_TIMESTAMP 29
-#define SCM_TIMESTAMP SO_TIMESTAMP
#define SO_PEERSEC 30
#define SO_PASSSEC 34
-#define SO_TIMESTAMPNS 35
-#define SCM_TIMESTAMPNS SO_TIMESTAMPNS
/* Security levels - as per NRL IPv6 - don't actually do anything */
#define SO_SECURITY_AUTHENTICATION 19
@@ -66,9 +62,6 @@
#define SO_MARK 36
-#define SO_TIMESTAMPING 37
-#define SCM_TIMESTAMPING SO_TIMESTAMPING
-
#define SO_RXQ_OVFL 40
#define SO_WIFI_STATUS 41
@@ -115,4 +108,20 @@
#define SO_TXTIME 61
#define SCM_TXTIME SO_TXTIME
+#define SO_TIMESTAMP_OLD 29
+#define SO_TIMESTAMPNS_OLD 35
+#define SO_TIMESTAMPING_OLD 37
+
+#if !defined(__KERNEL__)
+
+#define SO_TIMESTAMP SO_TIMESTAMP_OLD
+#define SO_TIMESTAMPNS SO_TIMESTAMPNS_OLD
+#define SO_TIMESTAMPING SO_TIMESTAMPING_OLD
+
+#define SCM_TIMESTAMP SO_TIMESTAMP
+#define SCM_TIMESTAMPNS SO_TIMESTAMPNS
+#define SCM_TIMESTAMPING SO_TIMESTAMPING
+
+#endif
+
#endif /* _UAPI_ASM_SOCKET_H */
diff --git a/arch/mips/include/uapi/asm/socket.h b/arch/mips/include/uapi/asm/socket.h
index 71370fb3ceef..b9553f770346 100644
--- a/arch/mips/include/uapi/asm/socket.h
+++ b/arch/mips/include/uapi/asm/socket.h
@@ -65,21 +65,14 @@
#define SO_GET_FILTER SO_ATTACH_FILTER
#define SO_PEERNAME 28
-#define SO_TIMESTAMP 29
-#define SCM_TIMESTAMP SO_TIMESTAMP
#define SO_PEERSEC 30
#define SO_SNDBUFFORCE 31
#define SO_RCVBUFFORCE 33
#define SO_PASSSEC 34
-#define SO_TIMESTAMPNS 35
-#define SCM_TIMESTAMPNS SO_TIMESTAMPNS
#define SO_MARK 36
-#define SO_TIMESTAMPING 37
-#define SCM_TIMESTAMPING SO_TIMESTAMPING
-
#define SO_RXQ_OVFL 40
#define SO_WIFI_STATUS 41
@@ -126,4 +119,20 @@
#define SO_TXTIME 61
#define SCM_TXTIME SO_TXTIME
+#define SO_TIMESTAMP_OLD 29
+#define SO_TIMESTAMPNS_OLD 35
+#define SO_TIMESTAMPING_OLD 37
+
+#if !defined(__KERNEL__)
+
+#define SO_TIMESTAMP SO_TIMESTAMP_OLD
+#define SO_TIMESTAMPNS SO_TIMESTAMPNS_OLD
+#define SO_TIMESTAMPING SO_TIMESTAMPING_OLD
+
+#define SCM_TIMESTAMP SO_TIMESTAMP
+#define SCM_TIMESTAMPNS SO_TIMESTAMPNS
+#define SCM_TIMESTAMPING SO_TIMESTAMPING
+
+#endif
+
#endif /* _UAPI_ASM_SOCKET_H */
diff --git a/arch/parisc/include/uapi/asm/socket.h b/arch/parisc/include/uapi/asm/socket.h
index 061b9cf2a779..37cdfe64bb27 100644
--- a/arch/parisc/include/uapi/asm/socket.h
+++ b/arch/parisc/include/uapi/asm/socket.h
@@ -34,10 +34,6 @@
#define SO_BSDCOMPAT 0x400e
#define SO_PASSCRED 0x4010
#define SO_PEERCRED 0x4011
-#define SO_TIMESTAMP 0x4012
-#define SCM_TIMESTAMP SO_TIMESTAMP
-#define SO_TIMESTAMPNS 0x4013
-#define SCM_TIMESTAMPNS SO_TIMESTAMPNS
/* Security levels - as per NRL IPv6 - don't actually do anything */
#define SO_SECURITY_AUTHENTICATION 0x4016
@@ -58,9 +54,6 @@
#define SO_MARK 0x401f
-#define SO_TIMESTAMPING 0x4020
-#define SCM_TIMESTAMPING SO_TIMESTAMPING
-
#define SO_RXQ_OVFL 0x4021
#define SO_WIFI_STATUS 0x4022
@@ -107,4 +100,20 @@
#define SO_TXTIME 0x4036
#define SCM_TXTIME SO_TXTIME
+#define SO_TIMESTAMP_OLD 0x4012
+#define SO_TIMESTAMPNS_OLD 0x4013
+#define SO_TIMESTAMPING_OLD 0x4020
+
+#if !defined(__KERNEL__)
+
+#define SO_TIMESTAMP SO_TIMESTAMP_OLD
+#define SO_TIMESTAMPNS SO_TIMESTAMPNS_OLD
+#define SO_TIMESTAMPING SO_TIMESTAMPING_OLD
+
+#define SCM_TIMESTAMP SO_TIMESTAMP
+#define SCM_TIMESTAMPNS SO_TIMESTAMPNS
+#define SCM_TIMESTAMPING SO_TIMESTAMPING
+
+#endif
+
#endif /* _UAPI_ASM_SOCKET_H */
diff --git a/arch/sparc/include/uapi/asm/socket.h b/arch/sparc/include/uapi/asm/socket.h
index 7ea35e5601b6..ca573641fc6c 100644
--- a/arch/sparc/include/uapi/asm/socket.h
+++ b/arch/sparc/include/uapi/asm/socket.h
@@ -33,7 +33,6 @@
#define SO_PROTOCOL 0x1028
#define SO_DOMAIN 0x1029
-
/* Linux specific, keep the same. */
#define SO_NO_CHECK 0x000b
#define SO_PRIORITY 0x000c
@@ -45,19 +44,12 @@
#define SO_GET_FILTER SO_ATTACH_FILTER
#define SO_PEERNAME 0x001c
-#define SO_TIMESTAMP 0x001d
-#define SCM_TIMESTAMP SO_TIMESTAMP
#define SO_PEERSEC 0x001e
#define SO_PASSSEC 0x001f
-#define SO_TIMESTAMPNS 0x0021
-#define SCM_TIMESTAMPNS SO_TIMESTAMPNS
#define SO_MARK 0x0022
-#define SO_TIMESTAMPING 0x0023
-#define SCM_TIMESTAMPING SO_TIMESTAMPING
-
#define SO_RXQ_OVFL 0x0024
#define SO_WIFI_STATUS 0x0025
@@ -109,4 +101,20 @@
#define SO_SECURITY_ENCRYPTION_TRANSPORT 0x5002
#define SO_SECURITY_ENCRYPTION_NETWORK 0x5004
+#define SO_TIMESTAMP_OLD 0x001d
+#define SO_TIMESTAMPNS_OLD 0x0021
+#define SO_TIMESTAMPING_OLD 0x0023
+
+#if !defined(__KERNEL__)
+
+#define SO_TIMESTAMP SO_TIMESTAMP_OLD
+#define SO_TIMESTAMPNS SO_TIMESTAMPNS_OLD
+#define SO_TIMESTAMPING SO_TIMESTAMPING_OLD
+
+#define SCM_TIMESTAMP SO_TIMESTAMP
+#define SCM_TIMESTAMPNS SO_TIMESTAMPNS
+#define SCM_TIMESTAMPING SO_TIMESTAMPING
+
+#endif
+
#endif /* _ASM_SOCKET_H */
diff --git a/include/uapi/asm-generic/socket.h b/include/uapi/asm-generic/socket.h
index a12692e5f7a8..dc704e41203d 100644
--- a/include/uapi/asm-generic/socket.h
+++ b/include/uapi/asm-generic/socket.h
@@ -46,21 +46,14 @@
#define SO_GET_FILTER SO_ATTACH_FILTER
#define SO_PEERNAME 28
-#define SO_TIMESTAMP 29
-#define SCM_TIMESTAMP SO_TIMESTAMP
#define SO_ACCEPTCONN 30
#define SO_PEERSEC 31
#define SO_PASSSEC 34
-#define SO_TIMESTAMPNS 35
-#define SCM_TIMESTAMPNS SO_TIMESTAMPNS
#define SO_MARK 36
-#define SO_TIMESTAMPING 37
-#define SCM_TIMESTAMPING SO_TIMESTAMPING
-
#define SO_PROTOCOL 38
#define SO_DOMAIN 39
@@ -110,4 +103,20 @@
#define SO_TXTIME 61
#define SCM_TXTIME SO_TXTIME
+#define SO_TIMESTAMP_OLD 29
+#define SO_TIMESTAMPNS_OLD 35
+#define SO_TIMESTAMPING_OLD 37
+
+#if !defined(__KERNEL__)
+
+#define SO_TIMESTAMP SO_TIMESTAMP_OLD
+#define SO_TIMESTAMPNS SO_TIMESTAMPNS_OLD
+#define SO_TIMESTAMPING SO_TIMESTAMPING_OLD
+
+#define SCM_TIMESTAMP SO_TIMESTAMP
+#define SCM_TIMESTAMPNS SO_TIMESTAMPNS
+#define SCM_TIMESTAMPING SO_TIMESTAMPING
+
+#endif
+
#endif /* __ASM_GENERIC_SOCKET_H */
diff --git a/net/compat.c b/net/compat.c
index 47a614b370cd..720ab07276b0 100644
--- a/net/compat.c
+++ b/net/compat.c
@@ -219,7 +219,7 @@ int put_cmsg_compat(struct msghdr *kmsg, int level, int type, int len, void *dat
}
if (!COMPAT_USE_64BIT_TIME) {
- if (level == SOL_SOCKET && type == SCM_TIMESTAMP) {
+ if (level == SOL_SOCKET && type == SO_TIMESTAMP_OLD) {
struct timeval *tv = (struct timeval *)data;
ctv.tv_sec = tv->tv_sec;
ctv.tv_usec = tv->tv_usec;
@@ -227,8 +227,8 @@ int put_cmsg_compat(struct msghdr *kmsg, int level, int type, int len, void *dat
len = sizeof(ctv);
}
if (level == SOL_SOCKET &&
- (type == SCM_TIMESTAMPNS || type == SCM_TIMESTAMPING)) {
- int count = type == SCM_TIMESTAMPNS ? 1 : 3;
+ (type == SO_TIMESTAMPNS_OLD || type == SO_TIMESTAMPING_OLD)) {
+ int count = type == SO_TIMESTAMPNS_OLD ? 1 : 3;
int i;
struct timespec *ts = (struct timespec *)data;
for (i = 0; i < count; i++) {
diff --git a/net/core/sock.c b/net/core/sock.c
index 6d7e189e3cd9..cf990db9b2a0 100644
--- a/net/core/sock.c
+++ b/net/core/sock.c
@@ -814,10 +814,10 @@ int sock_setsockopt(struct socket *sock, int level, int optname,
clear_bit(SOCK_PASSCRED, &sock->flags);
break;
- case SO_TIMESTAMP:
- case SO_TIMESTAMPNS:
+ case SO_TIMESTAMP_OLD:
+ case SO_TIMESTAMPNS_OLD:
if (valbool) {
- if (optname == SO_TIMESTAMP)
+ if (optname == SO_TIMESTAMP_OLD)
sock_reset_flag(sk, SOCK_RCVTSTAMPNS);
else
sock_set_flag(sk, SOCK_RCVTSTAMPNS);
@@ -829,7 +829,7 @@ int sock_setsockopt(struct socket *sock, int level, int optname,
}
break;
- case SO_TIMESTAMPING:
+ case SO_TIMESTAMPING_OLD:
if (val & ~SOF_TIMESTAMPING_MASK) {
ret = -EINVAL;
break;
@@ -1182,16 +1182,16 @@ int sock_getsockopt(struct socket *sock, int level, int optname,
sock_warn_obsolete_bsdism("getsockopt");
break;
- case SO_TIMESTAMP:
+ case SO_TIMESTAMP_OLD:
v.val = sock_flag(sk, SOCK_RCVTSTAMP) &&
!sock_flag(sk, SOCK_RCVTSTAMPNS);
break;
- case SO_TIMESTAMPNS:
+ case SO_TIMESTAMPNS_OLD:
v.val = sock_flag(sk, SOCK_RCVTSTAMPNS);
break;
- case SO_TIMESTAMPING:
+ case SO_TIMESTAMPING_OLD:
v.val = sk->sk_tsflags;
break;
@@ -2118,7 +2118,7 @@ int __sock_cmsg_send(struct sock *sk, struct msghdr *msg, struct cmsghdr *cmsg,
return -EINVAL;
sockc->mark = *(u32 *)CMSG_DATA(cmsg);
break;
- case SO_TIMESTAMPING:
+ case SO_TIMESTAMPING_OLD:
if (cmsg->cmsg_len != CMSG_LEN(sizeof(u32)))
return -EINVAL;
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
index 252048776dbb..496848ab0269 100644
--- a/net/ipv4/tcp.c
+++ b/net/ipv4/tcp.c
@@ -1870,13 +1870,13 @@ static void tcp_recv_timestamp(struct msghdr *msg, const struct sock *sk,
if (tss->ts[0].tv_sec || tss->ts[0].tv_nsec) {
if (sock_flag(sk, SOCK_RCVTSTAMP)) {
if (sock_flag(sk, SOCK_RCVTSTAMPNS)) {
- put_cmsg(msg, SOL_SOCKET, SCM_TIMESTAMPNS,
+ put_cmsg(msg, SOL_SOCKET, SO_TIMESTAMPNS_OLD,
sizeof(tss->ts[0]), &tss->ts[0]);
} else {
tv.tv_sec = tss->ts[0].tv_sec;
tv.tv_usec = tss->ts[0].tv_nsec / 1000;
- put_cmsg(msg, SOL_SOCKET, SCM_TIMESTAMP,
+ put_cmsg(msg, SOL_SOCKET, SO_TIMESTAMP_OLD,
sizeof(tv), &tv);
}
}
@@ -1896,7 +1896,7 @@ static void tcp_recv_timestamp(struct msghdr *msg, const struct sock *sk,
if (has_timestamping) {
tss->ts[1] = (struct timespec) {0};
- put_cmsg(msg, SOL_SOCKET, SCM_TIMESTAMPING,
+ put_cmsg(msg, SOL_SOCKET, SO_TIMESTAMPING_OLD,
sizeof(*tss), tss);
}
}
diff --git a/net/rds/af_rds.c b/net/rds/af_rds.c
index 65387e1e6964..eeb4639adbe5 100644
--- a/net/rds/af_rds.c
+++ b/net/rds/af_rds.c
@@ -430,7 +430,7 @@ static int rds_setsockopt(struct socket *sock, int level, int optname,
ret = rds_set_transport(rs, optval, optlen);
release_sock(sock->sk);
break;
- case SO_TIMESTAMP:
+ case SO_TIMESTAMP_OLD:
lock_sock(sock->sk);
ret = rds_enable_recvtstamp(sock->sk, optval, optlen);
release_sock(sock->sk);
diff --git a/net/rds/recv.c b/net/rds/recv.c
index 727639dac8a7..04e30d63a159 100644
--- a/net/rds/recv.c
+++ b/net/rds/recv.c
@@ -550,7 +550,7 @@ static int rds_cmsg_recv(struct rds_incoming *inc, struct msghdr *msg,
if ((inc->i_rx_tstamp != 0) &&
sock_flag(rds_rs_to_sk(rs), SOCK_RCVTSTAMP)) {
struct timeval tv = ktime_to_timeval(inc->i_rx_tstamp);
- ret = put_cmsg(msg, SOL_SOCKET, SCM_TIMESTAMP,
+ ret = put_cmsg(msg, SOL_SOCKET, SO_TIMESTAMP_OLD,
sizeof(tv), &tv);
if (ret)
goto out;
diff --git a/net/rxrpc/local_object.c b/net/rxrpc/local_object.c
index 0906e51d3cfb..15cf42d5b53a 100644
--- a/net/rxrpc/local_object.c
+++ b/net/rxrpc/local_object.c
@@ -202,7 +202,7 @@ static int rxrpc_open_socket(struct rxrpc_local *local, struct net *net)
/* We want receive timestamps. */
opt = 1;
- ret = kernel_setsockopt(local->socket, SOL_SOCKET, SO_TIMESTAMPNS,
+ ret = kernel_setsockopt(local->socket, SOL_SOCKET, SO_TIMESTAMPNS_OLD,
(char *)&opt, sizeof(opt));
if (ret < 0) {
_debug("setsockopt failed");
diff --git a/net/socket.c b/net/socket.c
index f1ede2a64985..dfc5742ccfbb 100644
--- a/net/socket.c
+++ b/net/socket.c
@@ -670,7 +670,7 @@ static bool skb_is_err_queue(const struct sk_buff *skb)
* before the software timestamp is received, a hardware TX timestamp may be
* returned only if there is no software TX timestamp. Ignore false software
* timestamps, which may be made in the __sock_recv_timestamp() call when the
- * option SO_TIMESTAMP(NS) is enabled on the socket, even when the skb has a
+ * option SO_TIMESTAMP_OLD(NS) is enabled on the socket, even when the skb has a
* hardware timestamp.
*/
static bool skb_is_swtx_tstamp(const struct sk_buff *skb, int false_tstamp)
@@ -722,12 +722,12 @@ void __sock_recv_timestamp(struct msghdr *msg, struct sock *sk,
if (!sock_flag(sk, SOCK_RCVTSTAMPNS)) {
struct timeval tv;
skb_get_timestamp(skb, &tv);
- put_cmsg(msg, SOL_SOCKET, SCM_TIMESTAMP,
+ put_cmsg(msg, SOL_SOCKET, SO_TIMESTAMP_OLD,
sizeof(tv), &tv);
} else {
struct timespec ts;
skb_get_timestampns(skb, &ts);
- put_cmsg(msg, SOL_SOCKET, SCM_TIMESTAMPNS,
+ put_cmsg(msg, SOL_SOCKET, SO_TIMESTAMPNS_OLD,
sizeof(ts), &ts);
}
}
@@ -747,7 +747,7 @@ void __sock_recv_timestamp(struct msghdr *msg, struct sock *sk,
}
if (!empty) {
put_cmsg(msg, SOL_SOCKET,
- SCM_TIMESTAMPING, sizeof(tss), &tss);
+ SO_TIMESTAMPING_OLD, sizeof(tss), &tss);
if (skb_is_err_queue(skb) && skb->len &&
SKB_EXT_ERR(skb)->opt_stats)
--
2.17.1
^ 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