* [PATCH] vsprintf: do not append unset Scope ID to IPv6
@ 2016-02-03 10:41 Jason A. Donenfeld
2016-02-03 12:13 ` [PATCH] vsprintf: flowinfo in IPv6 is optional too Jason A. Donenfeld
2016-02-03 21:07 ` [PATCH] vsprintf: do not append unset Scope ID to IPv6 Daniel Borkmann
0 siblings, 2 replies; 22+ messages in thread
From: Jason A. Donenfeld @ 2016-02-03 10:41 UTC (permalink / raw)
To: akpm, linux, andriy.shevchenko, linux-kernel, dborkman; +Cc: Jason A. Donenfeld
The sockaddr_in6 has the sin6_scope_id parameter. This contains the
netdev index of the output device. When set to 0, sin6_scope_id is
considered to be "unset" -- it has no Scope ID (see RFC4007). When it is
set to >0, it has a Scope ID.
Other parts of the kernel respect htis. For example, code like this is
sometimes used to populate a sockaddr_in6 from a skb:
sin6->sin6_scope_id = ipv6_iface_scope_id(ipv6_hdr(skb)->saddr, skb->skb_iif);
Such a code example makes a call to the ipv6_iface_scope_id function
which is defined as follows (in ipv6.h):
static inline __u32 ipv6_iface_scope_id(const struct in6_addr *addr, int iface)
{
return __ipv6_addr_needs_scope_id(__ipv6_addr_type(addr)) ? iface : 0;
}
So, here, either it has Scope ID, in which case it's returned, or it
doesn't need a Scope ID, in which case 0 - "no scope id" - is returned.
Therefore, vsprintf should treat the 0 Scope ID the same way the rest of
the v6 stack and the RFC treats it: 0 Scope ID means no Scope ID. And if
there is no Scope ID, there is nothing to be printed.
So, this patch only prints the Scope ID when one exists, and does not
print a Scope ID when one does not exist.
It turns out, too, that this is what developers want. The most common
purpose of %pISpfsc is to show "what is in that sockaddr so that I can
have some idea of how to connect to it?"
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
---
lib/vsprintf.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/lib/vsprintf.c b/lib/vsprintf.c
index 48ff9c3..1b1b1c8 100644
--- a/lib/vsprintf.c
+++ b/lib/vsprintf.c
@@ -1194,7 +1194,7 @@ char *ip6_addr_string_sa(char *buf, char *end, const struct sockaddr_in6 *sa,
p = number(p, pend, ntohl(sa->sin6_flowinfo &
IPV6_FLOWINFO_MASK), spec);
}
- if (have_s) {
+ if (have_s && sa->sin6_scope_id) {
*p++ = '%';
p = number(p, pend, sa->sin6_scope_id, spec);
}
--
2.7.0
^ permalink raw reply related [flat|nested] 22+ messages in thread* [PATCH] vsprintf: flowinfo in IPv6 is optional too 2016-02-03 10:41 [PATCH] vsprintf: do not append unset Scope ID to IPv6 Jason A. Donenfeld @ 2016-02-03 12:13 ` Jason A. Donenfeld 2016-02-03 17:56 ` IRe: " Joe Perches 2016-02-03 21:07 ` [PATCH] vsprintf: do not append unset Scope ID to IPv6 Daniel Borkmann 1 sibling, 1 reply; 22+ messages in thread From: Jason A. Donenfeld @ 2016-02-03 12:13 UTC (permalink / raw) To: akpm, linux, andriy.shevchenko, linux-kernel, dborkman; +Cc: Jason A. Donenfeld Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com> --- lib/vsprintf.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/vsprintf.c b/lib/vsprintf.c index 1b1b1c8..85e6645 100644 --- a/lib/vsprintf.c +++ b/lib/vsprintf.c @@ -1189,7 +1189,7 @@ char *ip6_addr_string_sa(char *buf, char *end, const struct sockaddr_in6 *sa, *p++ = ':'; p = number(p, pend, ntohs(sa->sin6_port), spec); } - if (have_f) { + if (have_f && (sa->sin6_flowinfo & IPV6_FLOWINFO_MASK)) { *p++ = '/'; p = number(p, pend, ntohl(sa->sin6_flowinfo & IPV6_FLOWINFO_MASK), spec); -- 2.7.0 ^ permalink raw reply related [flat|nested] 22+ messages in thread
* IRe: [PATCH] vsprintf: flowinfo in IPv6 is optional too 2016-02-03 12:13 ` [PATCH] vsprintf: flowinfo in IPv6 is optional too Jason A. Donenfeld @ 2016-02-03 17:56 ` Joe Perches 2016-02-03 21:09 ` Jason A. Donenfeld 2016-02-03 21:13 ` IRe: " Daniel Borkmann 0 siblings, 2 replies; 22+ messages in thread From: Joe Perches @ 2016-02-03 17:56 UTC (permalink / raw) To: Jason A. Donenfeld, akpm, linux, andriy.shevchenko, linux-kernel, dborkman On Wed, 2016-02-03 at 13:13 +0100, Jason A. Donenfeld wrote: > Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com> > --- > lib/vsprintf.c | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > > diff --git a/lib/vsprintf.c b/lib/vsprintf.c > index 1b1b1c8..85e6645 100644 > --- a/lib/vsprintf.c > +++ b/lib/vsprintf.c > @@ -1189,7 +1189,7 @@ char *ip6_addr_string_sa(char *buf, char *end, const struct sockaddr_in6 *sa, > *p++ = ':'; > p = number(p, pend, ntohs(sa->sin6_port), spec); > } > - if (have_f) { > + if (have_f && (sa->sin6_flowinfo & IPV6_FLOWINFO_MASK)) { > *p++ = '/'; > p = number(p, pend, ntohl(sa->sin6_flowinfo & > IPV6_FLOWINFO_MASK), spec); Why does this matter at all? The format string "%pIS[...]f" is not used currently in the kernel. If one were to call out this 'f' qualifier to %pIS, wouldn't it be better to show /0 than elide the / output completely? ^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: IRe: [PATCH] vsprintf: flowinfo in IPv6 is optional too 2016-02-03 17:56 ` IRe: " Joe Perches @ 2016-02-03 21:09 ` Jason A. Donenfeld 2016-02-03 21:13 ` Andy Shevchenko 2016-02-03 21:13 ` IRe: " Daniel Borkmann 1 sibling, 1 reply; 22+ messages in thread From: Jason A. Donenfeld @ 2016-02-03 21:09 UTC (permalink / raw) To: Joe Perches; +Cc: Andrew Morton, linux, andriy.shevchenko, LKML, dborkman On Wed, Feb 3, 2016 at 6:56 PM, Joe Perches <joe@perches.com> wrote: > Why does this matter at all? Because I want to printk a sockaddr_in6, and have the most complete yet valid and standard representation I can. Displaying a /0 when there is no flow is confusing, ugly, and unhelpful, not to mention it doesn't accurately reflect what's happening. A flowlabel of zero means no flowlabel. ^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH] vsprintf: flowinfo in IPv6 is optional too 2016-02-03 21:09 ` Jason A. Donenfeld @ 2016-02-03 21:13 ` Andy Shevchenko 0 siblings, 0 replies; 22+ messages in thread From: Andy Shevchenko @ 2016-02-03 21:13 UTC (permalink / raw) To: Jason A. Donenfeld, Joe Perches; +Cc: Andrew Morton, linux, LKML, dborkman On Wed, 2016-02-03 at 22:09 +0100, Jason A. Donenfeld wrote: > On Wed, Feb 3, 2016 at 6:56 PM, Joe Perches <joe@perches.com> wrote: > > Why does this matter at all? > > Because I want to printk a sockaddr_in6, and have the most complete > yet valid and standard representation I can. Displaying a /0 when > there is no flow is confusing, ugly, and unhelpful, not to mention it > doesn't accurately reflect what's happening. A flowlabel of zero > means > no flowlabel. So, where do you want to put your result? dmesg? User-space application via sysfs? Seems like here is discussion debug vs. release version of printed data in the kernel. -- Andy Shevchenko <andriy.shevchenko@linux.intel.com> Intel Finland Oy ^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: IRe: [PATCH] vsprintf: flowinfo in IPv6 is optional too 2016-02-03 17:56 ` IRe: " Joe Perches 2016-02-03 21:09 ` Jason A. Donenfeld @ 2016-02-03 21:13 ` Daniel Borkmann 2016-02-03 21:15 ` Jason A. Donenfeld 1 sibling, 1 reply; 22+ messages in thread From: Daniel Borkmann @ 2016-02-03 21:13 UTC (permalink / raw) To: Joe Perches, Jason A. Donenfeld, akpm, linux, andriy.shevchenko, linux-kernel, dborkman On 02/03/2016 06:56 PM, Joe Perches wrote: > On Wed, 2016-02-03 at 13:13 +0100, Jason A. Donenfeld wrote: >> Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com> >> --- >> lib/vsprintf.c | 2 +- >> 1 file changed, 1 insertion(+), 1 deletion(-) >> >> diff --git a/lib/vsprintf.c b/lib/vsprintf.c >> index 1b1b1c8..85e6645 100644 >> --- a/lib/vsprintf.c >> +++ b/lib/vsprintf.c >> @@ -1189,7 +1189,7 @@ char *ip6_addr_string_sa(char *buf, char *end, const struct sockaddr_in6 *sa, >> *p++ = ':'; >> p = number(p, pend, ntohs(sa->sin6_port), spec); >> } >> - if (have_f) { >> + if (have_f && (sa->sin6_flowinfo & IPV6_FLOWINFO_MASK)) { >> *p++ = '/'; >> p = number(p, pend, ntohl(sa->sin6_flowinfo & >> IPV6_FLOWINFO_MASK), spec); > > Why does this matter at all? > > The format string "%pIS[...]f" is not used currently in the kernel. > > If one were to call out this 'f' qualifier to %pIS, wouldn't it > be better to show /0 than elide the / output completely? +1 Another possibility also in regards to your other patch would be to have a different format string char option instead of 'f'/'s' that would then allow a developer for having both options to choose from. Dunno if it's really worth it, but if you have a use case that definitely needs it, then it'd be probably better. Less surprises during debugging, at least. ^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: IRe: [PATCH] vsprintf: flowinfo in IPv6 is optional too 2016-02-03 21:13 ` IRe: " Daniel Borkmann @ 2016-02-03 21:15 ` Jason A. Donenfeld 0 siblings, 0 replies; 22+ messages in thread From: Jason A. Donenfeld @ 2016-02-03 21:15 UTC (permalink / raw) To: Daniel Borkmann Cc: Joe Perches, Andrew Morton, linux, andriy.shevchenko, LKML, dborkman On Wed, Feb 3, 2016 at 10:13 PM, Daniel Borkmann <daniel@iogearbox.net> wrote: > Another possibility also in regards to your other patch would be to have > a different format string char option instead of 'f'/'s' that would then > allow a developer for having both options to choose from. Dunno if it's > really worth it, but if you have a use case that definitely needs it, then > it'd be probably better. Less surprises during debugging, at least. Just came to this too over in the other patch thread. I'll cook this up now. ^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH] vsprintf: do not append unset Scope ID to IPv6 2016-02-03 10:41 [PATCH] vsprintf: do not append unset Scope ID to IPv6 Jason A. Donenfeld 2016-02-03 12:13 ` [PATCH] vsprintf: flowinfo in IPv6 is optional too Jason A. Donenfeld @ 2016-02-03 21:07 ` Daniel Borkmann 2016-02-03 21:14 ` Jason A. Donenfeld 1 sibling, 1 reply; 22+ messages in thread From: Daniel Borkmann @ 2016-02-03 21:07 UTC (permalink / raw) To: Jason A. Donenfeld; +Cc: akpm, linux, andriy.shevchenko, linux-kernel, joe On 02/03/2016 11:41 AM, Jason A. Donenfeld wrote: > The sockaddr_in6 has the sin6_scope_id parameter. This contains the > netdev index of the output device. When set to 0, sin6_scope_id is > considered to be "unset" -- it has no Scope ID (see RFC4007). When it is > set to >0, it has a Scope ID. [...] > So, here, either it has Scope ID, in which case it's returned, or it > doesn't need a Scope ID, in which case 0 - "no scope id" - is returned. > > Therefore, vsprintf should treat the 0 Scope ID the same way the rest of > the v6 stack and the RFC treats it: 0 Scope ID means no Scope ID. And if > there is no Scope ID, there is nothing to be printed. I don't see an "issue" here. I.e. if the developer requested to append 's' to the specifier, then it's expected to dump what is in the scope id, even if that is 0 meaning "unset" scope. It would be principle of least surprise -- I could imagine if not dumped, then a developer would check the source code to find out whether he did a mistake or it's expected behavior, just to make sure. That's what I would do probably. Is this causing a _real_ issue somewhere (I couldn't parse one out of your commit message other than 'it would be nice to have')? > So, this patch only prints the Scope ID when one exists, and does not > print a Scope ID when one does not exist. > > It turns out, too, that this is what developers want. The most common > purpose of %pISpfsc is to show "what is in that sockaddr so that I can > have some idea of how to connect to it?" > > Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com> > --- > lib/vsprintf.c | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > > diff --git a/lib/vsprintf.c b/lib/vsprintf.c > index 48ff9c3..1b1b1c8 100644 > --- a/lib/vsprintf.c > +++ b/lib/vsprintf.c > @@ -1194,7 +1194,7 @@ char *ip6_addr_string_sa(char *buf, char *end, const struct sockaddr_in6 *sa, > p = number(p, pend, ntohl(sa->sin6_flowinfo & > IPV6_FLOWINFO_MASK), spec); > } > - if (have_s) { > + if (have_s && sa->sin6_scope_id) { > *p++ = '%'; > p = number(p, pend, sa->sin6_scope_id, spec); > } > ^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH] vsprintf: do not append unset Scope ID to IPv6 2016-02-03 21:07 ` [PATCH] vsprintf: do not append unset Scope ID to IPv6 Daniel Borkmann @ 2016-02-03 21:14 ` Jason A. Donenfeld 2016-02-03 21:47 ` Joe Perches 0 siblings, 1 reply; 22+ messages in thread From: Jason A. Donenfeld @ 2016-02-03 21:14 UTC (permalink / raw) To: Daniel Borkmann Cc: Andrew Morton, linux, andriy.shevchenko, LKML, Joe Perches On Wed, Feb 3, 2016 at 10:07 PM, Daniel Borkmann <daniel@iogearbox.net> wrote: > I don't see an "issue" here. I.e. if the developer requested to append 's' > to the specifier, then it's expected to dump what is in the scope id, even > if that is 0 meaning "unset" scope. > > It would be principle of least surprise -- I could imagine if not dumped, > then a developer would check the source code to find out whether he did a > mistake or it's expected behavior, just to make sure. That's what I would > do probably. Showing something that's "unset" seems counter-intuitive. The idea here is to be able to printk a sockaddr_in6, and have it show something that looks like what the user would naturally pass to getaddrinfo(3), which is entirely complete. However, I could be convinced that this kind of behavior belongs in it's own flag. Maybe I'll cook up a flag for that instead. > > Is this causing a _real_ issue somewhere (I couldn't parse one out of your > commit message other than 'it would be nice to have')? Nice to have. ^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH] vsprintf: do not append unset Scope ID to IPv6 2016-02-03 21:14 ` Jason A. Donenfeld @ 2016-02-03 21:47 ` Joe Perches 2016-02-03 22:09 ` Daniel Borkmann ` (2 more replies) 0 siblings, 3 replies; 22+ messages in thread From: Joe Perches @ 2016-02-03 21:47 UTC (permalink / raw) To: Jason A. Donenfeld, Daniel Borkmann Cc: Andrew Morton, linux, andriy.shevchenko, LKML On Wed, 2016-02-03 at 22:14 +0100, Jason A. Donenfeld wrote: > The idea here is to be able to printk a sockaddr_in6, and have it show > something that looks like what the user would naturally pass to > getaddrinfo(3), which is entirely complete. > > However, I could be convinced that this kind of behavior belongs in > it's own flag. Maybe I'll cook up a flag for that instead. I think that'd be best. Maybe using something like %pISG for this that would optionally show these flow and scope values only when non-zero. Something like: --- lib/vsprintf.c | 30 +++++++++++++++++++----------- 1 file changed, 19 insertions(+), 11 deletions(-) diff --git a/lib/vsprintf.c b/lib/vsprintf.c index 6dc4288..2003c6f 100644 --- a/lib/vsprintf.c +++ b/lib/vsprintf.c @@ -1147,7 +1147,8 @@ static noinline_for_stack char *ip6_addr_string_sa(char *buf, char *end, const struct sockaddr_in6 *sa, struct printf_spec spec, const char *fmt) { - bool have_p = false, have_s = false, have_f = false, have_c = false; + u8 show_p = 0, show_s = 0, show_f = 0; + bool use_c = false; char ip6_addr[sizeof("[xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:255.255.255.255]") + sizeof(":12345") + sizeof("/123456789") + sizeof("%1234567890")]; @@ -1160,43 +1161,50 @@ char *ip6_addr_string_sa(char *buf, char *end, const struct sockaddr_in6 *sa, while (isalpha(*++fmt)) { switch (*fmt) { case 'p': - have_p = true; + show_p = 1; break; case 'f': - have_f = true; + show_f = 1; break; case 's': - have_s = true; + show_s = 1; + break; + case 'G': + show_p = 2; + show_f = 2; + show_s = 2; break; case 'c': - have_c = true; + use_c = true; break; } } - if (have_p || have_s || have_f) { + if (show_p || show_s || show_f) { *p = '['; off = 1; } - if (fmt6[0] == 'I' && have_c) + if (fmt6[0] == 'I' && use_c) p = ip6_compressed_string(ip6_addr + off, addr); else p = ip6_string(ip6_addr + off, addr, fmt6); - if (have_p || have_s || have_f) + if (show_p || show_s || show_f) *p++ = ']'; - if (have_p) { + if (show_p) { *p++ = ':'; p = number(p, pend, ntohs(sa->sin6_port), spec); } - if (have_f) { + if (show_f == 1 || + (show_f == 2 && (sa->sin6_flowinfo & IPV6_FLOWINFO_MASK))) { *p++ = '/'; p = number(p, pend, ntohl(sa->sin6_flowinfo & IPV6_FLOWINFO_MASK), spec); } - if (have_s) { + if (show_s == 1 || + (show_s == 2 && sa->sin6_scope_id)) { *p++ = '%'; p = number(p, pend, sa->sin6_scope_id, spec); } ^ permalink raw reply related [flat|nested] 22+ messages in thread
* Re: [PATCH] vsprintf: do not append unset Scope ID to IPv6 2016-02-03 21:47 ` Joe Perches @ 2016-02-03 22:09 ` Daniel Borkmann 2016-02-03 22:42 ` Jason A. Donenfeld 2016-02-03 22:53 ` [PATCH] vsprintf: automatic parameters for %pIS via 'a' Jason A. Donenfeld 2 siblings, 0 replies; 22+ messages in thread From: Daniel Borkmann @ 2016-02-03 22:09 UTC (permalink / raw) To: Joe Perches, Jason A. Donenfeld Cc: Andrew Morton, linux, andriy.shevchenko, LKML On 02/03/2016 10:47 PM, Joe Perches wrote: > On Wed, 2016-02-03 at 22:14 +0100, Jason A. Donenfeld wrote: >> The idea here is to be able to printk a sockaddr_in6, and have it show >> something that looks like what the user would naturally pass to >> getaddrinfo(3), which is entirely complete. >> >> However, I could be convinced that this kind of behavior belongs in >> it's own flag. Maybe I'll cook up a flag for that instead. > > I think that'd be best. Agreed. > Maybe using something like %pISG for this that > would optionally show these flow and scope values > only when non-zero. > > Something like: Looks good to me, having this as a single generic option seems even cleaner. Thanks! ^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH] vsprintf: do not append unset Scope ID to IPv6 2016-02-03 21:47 ` Joe Perches 2016-02-03 22:09 ` Daniel Borkmann @ 2016-02-03 22:42 ` Jason A. Donenfeld 2016-02-03 22:53 ` [PATCH] vsprintf: automatic parameters for %pIS via 'a' Jason A. Donenfeld 2 siblings, 0 replies; 22+ messages in thread From: Jason A. Donenfeld @ 2016-02-03 22:42 UTC (permalink / raw) To: Joe Perches Cc: Daniel Borkmann, Andrew Morton, linux, andriy.shevchenko, LKML I've got something a bit cleaner that more accurately reflects this use case. Five minutes and I'll send over the patch. ^ permalink raw reply [flat|nested] 22+ messages in thread
* [PATCH] vsprintf: automatic parameters for %pIS via 'a' 2016-02-03 21:47 ` Joe Perches 2016-02-03 22:09 ` Daniel Borkmann 2016-02-03 22:42 ` Jason A. Donenfeld @ 2016-02-03 22:53 ` Jason A. Donenfeld 2016-02-03 23:05 ` Joe Perches 2 siblings, 1 reply; 22+ messages in thread From: Jason A. Donenfeld @ 2016-02-03 22:53 UTC (permalink / raw) To: Joe Perches, Daniel Borkmann, Andrew Morton, linux, andriy.shevchenko, LKML Cc: Jason A. Donenfeld This patch adds a variable 'a' which indicates that the 'p', 'f', and 's' options should be toggled on or off depending on whether or not those parameters are actually valid inside the passed sockaddr. This is something that probably most users of the %pIS family of functions will prefer to use. Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com> --- Documentation/printk-formats.txt | 6 ++++-- lib/vsprintf.c | 19 +++++++++++++++++-- 2 files changed, 21 insertions(+), 4 deletions(-) diff --git a/Documentation/printk-formats.txt b/Documentation/printk-formats.txt index 5d1128b..22bae97 100644 --- a/Documentation/printk-formats.txt +++ b/Documentation/printk-formats.txt @@ -193,7 +193,7 @@ IPv4/IPv6 addresses (generic, with port, flowinfo, scope): %piS 001.002.003.004 or 00010002000300040005000600070008 %pISc 1.2.3.4 or 1:2:3:4:5:6:7:8 %pISpc 1.2.3.4:12345 or [1:2:3:4:5:6:7:8]:12345 - %p[Ii]S[pfschnbl] + %p[Ii]S[pfsachnbl] For printing an IP address without the need to distinguish whether it's of type AF_INET or AF_INET6, a pointer to a valid 'struct sockaddr', @@ -201,7 +201,9 @@ IPv4/IPv6 addresses (generic, with port, flowinfo, scope): The additional 'p', 'f', and 's' specifiers are used to specify port (IPv4, IPv6), flowinfo (IPv6) and scope (IPv6). Ports have a ':' prefix, - flowinfo a '/' and scope a '%', each followed by the actual value. + flowinfo a '/' and scope a '%', each followed by the actual value. If 'a' + is given, 'p', 'f', and 's' are activated or deactivated depending on + whether or not the sockaddr has a non-zero port, flowinfo, and scope. In case of an IPv6 address the compressed IPv6 address as described by http://tools.ietf.org/html/rfc5952 is being used if the additional diff --git a/lib/vsprintf.c b/lib/vsprintf.c index 48ff9c3..b414a22 100644 --- a/lib/vsprintf.c +++ b/lib/vsprintf.c @@ -1145,7 +1145,7 @@ static noinline_for_stack char *ip6_addr_string_sa(char *buf, char *end, const struct sockaddr_in6 *sa, struct printf_spec spec, const char *fmt) { - bool have_p = false, have_s = false, have_f = false, have_c = false; + bool have_p = false, have_s = false, have_f = false, have_c = false, have_a = false; char ip6_addr[sizeof("[xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:255.255.255.255]") + sizeof(":12345") + sizeof("/123456789") + sizeof("%1234567890")]; @@ -1169,9 +1169,18 @@ char *ip6_addr_string_sa(char *buf, char *end, const struct sockaddr_in6 *sa, case 'c': have_c = true; break; + case 'a': + have_a = true; + break; } } + if (have_a) { + have_p = sa->sin6_port != 0; + have_s = sa->sin6_scope_id != 0; + have_f = sa->sin6_flowinfo != 0; + } + if (have_p || have_s || have_f) { *p = '['; off = 1; @@ -1207,7 +1216,7 @@ static noinline_for_stack char *ip4_addr_string_sa(char *buf, char *end, const struct sockaddr_in *sa, struct printf_spec spec, const char *fmt) { - bool have_p = false; + bool have_p = false, have_a = false; char *p, ip4_addr[sizeof("255.255.255.255") + sizeof(":12345")]; char *pend = ip4_addr + sizeof(ip4_addr); const u8 *addr = (const u8 *) &sa->sin_addr.s_addr; @@ -1225,9 +1234,15 @@ char *ip4_addr_string_sa(char *buf, char *end, const struct sockaddr_in *sa, case 'b': fmt4[2] = *fmt; break; + case 'a': + have_a = true; + break; } } + if (have_a) + have_p = sa->sin_port != 0; + p = ip4_string(ip4_addr, addr, fmt4); if (have_p) { *p++ = ':'; -- 2.7.0 ^ permalink raw reply related [flat|nested] 22+ messages in thread
* Re: [PATCH] vsprintf: automatic parameters for %pIS via 'a' 2016-02-03 22:53 ` [PATCH] vsprintf: automatic parameters for %pIS via 'a' Jason A. Donenfeld @ 2016-02-03 23:05 ` Joe Perches 2016-02-03 23:25 ` Jason A. Donenfeld 2016-02-03 23:29 ` [PATCH v2] " Jason A. Donenfeld 0 siblings, 2 replies; 22+ messages in thread From: Joe Perches @ 2016-02-03 23:05 UTC (permalink / raw) To: Jason A. Donenfeld, Daniel Borkmann, Andrew Morton, linux, andriy.shevchenko, LKML On Wed, 2016-02-03 at 23:53 +0100, Jason A. Donenfeld wrote: > This patch adds a variable 'a' which indicates that the 'p', > 'f', and 's' options should be toggled on or off depending on > whether or not those parameters are actually valid inside the > passed sockaddr. OK > This is something that probably most users of > the %pIS family of functions will prefer to use. More doubtful. There isn't a single user of flowinfo or scope today. These are the current uses of %pIS 8 %pIS 11 %pISc 5 %pIScp 2 %pISp 23 %pISpc > diff --git a/lib/vsprintf.c b/lib/vsprintf.c [] > @@ -1169,9 +1169,18 @@ char *ip6_addr_string_sa(char *buf, char *end, const struct sockaddr_in6 *sa, > case 'c': > have_c = true; > break; > + case 'a': > + have_a = true; > + break; > } > } > > + if (have_a) { > + have_p = sa->sin6_port != 0; > + have_s = sa->sin6_scope_id != 0; > + have_f = sa->sin6_flowinfo != 0; Doesn't this needs the mask tested? sa->sin6_flowinfo & IPV6_FLOWINFO_MASK given the use of bool, the != 0 are unnecessary. Other than that, looks good to me. ^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH] vsprintf: automatic parameters for %pIS via 'a' 2016-02-03 23:05 ` Joe Perches @ 2016-02-03 23:25 ` Jason A. Donenfeld 2016-02-03 23:29 ` [PATCH v2] " Jason A. Donenfeld 1 sibling, 0 replies; 22+ messages in thread From: Jason A. Donenfeld @ 2016-02-03 23:25 UTC (permalink / raw) To: Joe Perches Cc: Daniel Borkmann, Andrew Morton, Rasmus Villemoes, andriy.shevchenko, LKML On Thu, Feb 4, 2016 at 12:05 AM, Joe Perches <joe@perches.com> wrote: > > Doesn't this needs the mask tested? > > sa->sin6_flowinfo & IPV6_FLOWINFO_MASK Good catch. Fixing and will submit another. > > given the use of bool, the != 0 are unnecessary. True. > Other than that, looks good to me. Great! ^ permalink raw reply [flat|nested] 22+ messages in thread
* [PATCH v2] vsprintf: automatic parameters for %pIS via 'a' 2016-02-03 23:05 ` Joe Perches 2016-02-03 23:25 ` Jason A. Donenfeld @ 2016-02-03 23:29 ` Jason A. Donenfeld 2016-02-03 23:37 ` Joe Perches 2016-02-05 0:06 ` [PATCH v2] " Rasmus Villemoes 1 sibling, 2 replies; 22+ messages in thread From: Jason A. Donenfeld @ 2016-02-03 23:29 UTC (permalink / raw) To: Joe Perches, Daniel Borkmann, Andrew Morton, linux, andriy.shevchenko, LKML Cc: Jason A. Donenfeld This patch adds a variable 'a' which indicates that the 'p', 'f', and 's' options should be toggled on or off depending on whether or not those parameters are actually valid inside the passed sockaddr. Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com> --- Documentation/printk-formats.txt | 6 ++++-- lib/vsprintf.c | 19 +++++++++++++++++-- 2 files changed, 21 insertions(+), 4 deletions(-) diff --git a/Documentation/printk-formats.txt b/Documentation/printk-formats.txt index 5d1128b..22bae97 100644 --- a/Documentation/printk-formats.txt +++ b/Documentation/printk-formats.txt @@ -193,7 +193,7 @@ IPv4/IPv6 addresses (generic, with port, flowinfo, scope): %piS 001.002.003.004 or 00010002000300040005000600070008 %pISc 1.2.3.4 or 1:2:3:4:5:6:7:8 %pISpc 1.2.3.4:12345 or [1:2:3:4:5:6:7:8]:12345 - %p[Ii]S[pfschnbl] + %p[Ii]S[pfsachnbl] For printing an IP address without the need to distinguish whether it's of type AF_INET or AF_INET6, a pointer to a valid 'struct sockaddr', @@ -201,7 +201,9 @@ IPv4/IPv6 addresses (generic, with port, flowinfo, scope): The additional 'p', 'f', and 's' specifiers are used to specify port (IPv4, IPv6), flowinfo (IPv6) and scope (IPv6). Ports have a ':' prefix, - flowinfo a '/' and scope a '%', each followed by the actual value. + flowinfo a '/' and scope a '%', each followed by the actual value. If 'a' + is given, 'p', 'f', and 's' are activated or deactivated depending on + whether or not the sockaddr has a non-zero port, flowinfo, and scope. In case of an IPv6 address the compressed IPv6 address as described by http://tools.ietf.org/html/rfc5952 is being used if the additional diff --git a/lib/vsprintf.c b/lib/vsprintf.c index 48ff9c3..9a07284 100644 --- a/lib/vsprintf.c +++ b/lib/vsprintf.c @@ -1145,7 +1145,7 @@ static noinline_for_stack char *ip6_addr_string_sa(char *buf, char *end, const struct sockaddr_in6 *sa, struct printf_spec spec, const char *fmt) { - bool have_p = false, have_s = false, have_f = false, have_c = false; + bool have_p = false, have_s = false, have_f = false, have_c = false, have_a = false; char ip6_addr[sizeof("[xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:255.255.255.255]") + sizeof(":12345") + sizeof("/123456789") + sizeof("%1234567890")]; @@ -1169,9 +1169,18 @@ char *ip6_addr_string_sa(char *buf, char *end, const struct sockaddr_in6 *sa, case 'c': have_c = true; break; + case 'a': + have_a = true; + break; } } + if (have_a) { + have_p = sa->sin6_port; + have_s = sa->sin6_scope_id; + have_f = sa->sin6_flowinfo & IPV6_FLOWINFO_MASK; + } + if (have_p || have_s || have_f) { *p = '['; off = 1; @@ -1207,7 +1216,7 @@ static noinline_for_stack char *ip4_addr_string_sa(char *buf, char *end, const struct sockaddr_in *sa, struct printf_spec spec, const char *fmt) { - bool have_p = false; + bool have_p = false, have_a = false; char *p, ip4_addr[sizeof("255.255.255.255") + sizeof(":12345")]; char *pend = ip4_addr + sizeof(ip4_addr); const u8 *addr = (const u8 *) &sa->sin_addr.s_addr; @@ -1225,9 +1234,15 @@ char *ip4_addr_string_sa(char *buf, char *end, const struct sockaddr_in *sa, case 'b': fmt4[2] = *fmt; break; + case 'a': + have_a = true; + break; } } + if (have_a) + have_p = sa->sin_port != 0; + p = ip4_string(ip4_addr, addr, fmt4); if (have_p) { *p++ = ':'; -- 2.7.0 ^ permalink raw reply related [flat|nested] 22+ messages in thread
* Re: [PATCH v2] vsprintf: automatic parameters for %pIS via 'a' 2016-02-03 23:29 ` [PATCH v2] " Jason A. Donenfeld @ 2016-02-03 23:37 ` Joe Perches 2016-02-04 0:59 ` [PATCH v3] " Jason A. Donenfeld 2016-02-05 0:06 ` [PATCH v2] " Rasmus Villemoes 1 sibling, 1 reply; 22+ messages in thread From: Joe Perches @ 2016-02-03 23:37 UTC (permalink / raw) To: Jason A. Donenfeld Cc: Daniel Borkmann, Andrew Morton, linux, andriy.shevchenko, LKML On Thu, 2016-02-04 at 00:29 +0100, Jason A. Donenfeld wrote: > This patch adds a variable 'a' which indicates that the 'p', > 'f', and 's' options should be toggled on or off depending on > whether or not those parameters are actually valid inside the > passed sockaddr. trivia: > diff --git a/lib/vsprintf.c b/lib/vsprintf.c [] > @@ -1225,9 +1234,15 @@ char *ip4_addr_string_sa(char *buf, char *end, const struct sockaddr_in *sa, [] > + if (have_a) > + have_p = sa->sin_port != 0; > + different style than the v6 tests ^ permalink raw reply [flat|nested] 22+ messages in thread
* [PATCH v3] vsprintf: automatic parameters for %pIS via 'a' 2016-02-03 23:37 ` Joe Perches @ 2016-02-04 0:59 ` Jason A. Donenfeld 0 siblings, 0 replies; 22+ messages in thread From: Jason A. Donenfeld @ 2016-02-04 0:59 UTC (permalink / raw) To: Joe Perches, Daniel Borkmann, Andrew Morton, linux, andriy.shevchenko, LKML Cc: Jason A. Donenfeld This patch adds a variable 'a' which indicates that the 'p', 'f', and 's' options should be toggled on or off depending on whether or not those parameters are actually valid inside the passed sockaddr. Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com> --- Documentation/printk-formats.txt | 6 ++++-- lib/vsprintf.c | 19 +++++++++++++++++-- 2 files changed, 21 insertions(+), 4 deletions(-) diff --git a/Documentation/printk-formats.txt b/Documentation/printk-formats.txt index 5d1128b..22bae97 100644 --- a/Documentation/printk-formats.txt +++ b/Documentation/printk-formats.txt @@ -193,7 +193,7 @@ IPv4/IPv6 addresses (generic, with port, flowinfo, scope): %piS 001.002.003.004 or 00010002000300040005000600070008 %pISc 1.2.3.4 or 1:2:3:4:5:6:7:8 %pISpc 1.2.3.4:12345 or [1:2:3:4:5:6:7:8]:12345 - %p[Ii]S[pfschnbl] + %p[Ii]S[pfsachnbl] For printing an IP address without the need to distinguish whether it's of type AF_INET or AF_INET6, a pointer to a valid 'struct sockaddr', @@ -201,7 +201,9 @@ IPv4/IPv6 addresses (generic, with port, flowinfo, scope): The additional 'p', 'f', and 's' specifiers are used to specify port (IPv4, IPv6), flowinfo (IPv6) and scope (IPv6). Ports have a ':' prefix, - flowinfo a '/' and scope a '%', each followed by the actual value. + flowinfo a '/' and scope a '%', each followed by the actual value. If 'a' + is given, 'p', 'f', and 's' are activated or deactivated depending on + whether or not the sockaddr has a non-zero port, flowinfo, and scope. In case of an IPv6 address the compressed IPv6 address as described by http://tools.ietf.org/html/rfc5952 is being used if the additional diff --git a/lib/vsprintf.c b/lib/vsprintf.c index 48ff9c3..cda27b4 100644 --- a/lib/vsprintf.c +++ b/lib/vsprintf.c @@ -1145,7 +1145,7 @@ static noinline_for_stack char *ip6_addr_string_sa(char *buf, char *end, const struct sockaddr_in6 *sa, struct printf_spec spec, const char *fmt) { - bool have_p = false, have_s = false, have_f = false, have_c = false; + bool have_p = false, have_s = false, have_f = false, have_c = false, have_a = false; char ip6_addr[sizeof("[xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:255.255.255.255]") + sizeof(":12345") + sizeof("/123456789") + sizeof("%1234567890")]; @@ -1169,9 +1169,18 @@ char *ip6_addr_string_sa(char *buf, char *end, const struct sockaddr_in6 *sa, case 'c': have_c = true; break; + case 'a': + have_a = true; + break; } } + if (have_a) { + have_p = sa->sin6_port; + have_s = sa->sin6_scope_id; + have_f = sa->sin6_flowinfo & IPV6_FLOWINFO_MASK; + } + if (have_p || have_s || have_f) { *p = '['; off = 1; @@ -1207,7 +1216,7 @@ static noinline_for_stack char *ip4_addr_string_sa(char *buf, char *end, const struct sockaddr_in *sa, struct printf_spec spec, const char *fmt) { - bool have_p = false; + bool have_p = false, have_a = false; char *p, ip4_addr[sizeof("255.255.255.255") + sizeof(":12345")]; char *pend = ip4_addr + sizeof(ip4_addr); const u8 *addr = (const u8 *) &sa->sin_addr.s_addr; @@ -1225,9 +1234,15 @@ char *ip4_addr_string_sa(char *buf, char *end, const struct sockaddr_in *sa, case 'b': fmt4[2] = *fmt; break; + case 'a': + have_a = true; + break; } } + if (have_a) + have_p = sa->sin_port; + p = ip4_string(ip4_addr, addr, fmt4); if (have_p) { *p++ = ':'; -- 2.7.0 ^ permalink raw reply related [flat|nested] 22+ messages in thread
* Re: [PATCH v2] vsprintf: automatic parameters for %pIS via 'a' 2016-02-03 23:29 ` [PATCH v2] " Jason A. Donenfeld 2016-02-03 23:37 ` Joe Perches @ 2016-02-05 0:06 ` Rasmus Villemoes 2016-02-05 13:06 ` Jason A. Donenfeld ` (2 more replies) 1 sibling, 3 replies; 22+ messages in thread From: Rasmus Villemoes @ 2016-02-05 0:06 UTC (permalink / raw) To: Jason A. Donenfeld Cc: Joe Perches, Daniel Borkmann, Andrew Morton, andriy.shevchenko, LKML On Thu, Feb 04 2016, "Jason A. Donenfeld" <Jason@zx2c4.com> wrote: > This patch adds a variable 'a' which indicates that the 'p', > 'f', and 's' options should be toggled on or off depending on > whether or not those parameters are actually valid inside the > passed sockaddr. > > Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com> > --- > Documentation/printk-formats.txt | 6 ++++-- > lib/vsprintf.c | 19 +++++++++++++++++-- > 2 files changed, 21 insertions(+), 4 deletions(-) > > diff --git a/Documentation/printk-formats.txt b/Documentation/printk-formats.txt > index 5d1128b..22bae97 100644 > --- a/Documentation/printk-formats.txt > +++ b/Documentation/printk-formats.txt > @@ -193,7 +193,7 @@ IPv4/IPv6 addresses (generic, with port, flowinfo, scope): > %piS 001.002.003.004 or 00010002000300040005000600070008 > %pISc 1.2.3.4 or 1:2:3:4:5:6:7:8 > %pISpc 1.2.3.4:12345 or [1:2:3:4:5:6:7:8]:12345 > - %p[Ii]S[pfschnbl] > + %p[Ii]S[pfsachnbl] > > For printing an IP address without the need to distinguish whether it's > of type AF_INET or AF_INET6, a pointer to a valid 'struct sockaddr', > @@ -201,7 +201,9 @@ IPv4/IPv6 addresses (generic, with port, flowinfo, scope): > > The additional 'p', 'f', and 's' specifiers are used to specify port > (IPv4, IPv6), flowinfo (IPv6) and scope (IPv6). Ports have a ':' prefix, > - flowinfo a '/' and scope a '%', each followed by the actual value. > + flowinfo a '/' and scope a '%', each followed by the actual value. If 'a' > + is given, 'p', 'f', and 's' are activated or deactivated depending on > + whether or not the sockaddr has a non-zero port, flowinfo, and scope. > > In case of an IPv6 address the compressed IPv6 address as described by > http://tools.ietf.org/html/rfc5952 is being used if the additional > diff --git a/lib/vsprintf.c b/lib/vsprintf.c > index 48ff9c3..9a07284 100644 > --- a/lib/vsprintf.c > +++ b/lib/vsprintf.c > @@ -1145,7 +1145,7 @@ static noinline_for_stack > char *ip6_addr_string_sa(char *buf, char *end, const struct sockaddr_in6 *sa, > struct printf_spec spec, const char *fmt) > { > - bool have_p = false, have_s = false, have_f = false, have_c = false; > + bool have_p = false, have_s = false, have_f = false, have_c = false, have_a = false; > char ip6_addr[sizeof("[xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:255.255.255.255]") + > sizeof(":12345") + sizeof("/123456789") + > sizeof("%1234567890")]; > @@ -1169,9 +1169,18 @@ char *ip6_addr_string_sa(char *buf, char *end, const struct sockaddr_in6 *sa, > case 'c': > have_c = true; > break; > + case 'a': > + have_a = true; > + break; > } > } > > + if (have_a) { > + have_p = sa->sin6_port; > + have_s = sa->sin6_scope_id; > + have_f = sa->sin6_flowinfo & IPV6_FLOWINFO_MASK; > + } > + First of all I don't think vsprintf.c should be extended with yet another piece of unused code, so I hope there's an actual user coming. Second, please add tests to lib/test_printf.c. Third, wouldn't it be more convenient/flexible if a meant "print those that are present _and_ requested"; that is, the above would be > + have_p = have_p && sa->sin6_port; > + have_s = have_s && sa->sin6_scope_id; > + have_f = have_f && sa->sin6_flowinfo & IPV6_FLOWINFO_MASK; that way one could say %pISaf and have the flowinfo if and only if it's present, without also unintentionally turning on port or scope_id. Rasmus ^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH v2] vsprintf: automatic parameters for %pIS via 'a' 2016-02-05 0:06 ` [PATCH v2] " Rasmus Villemoes @ 2016-02-05 13:06 ` Jason A. Donenfeld 2016-02-05 13:37 ` [PATCH] " Jason A. Donenfeld 2016-02-05 13:39 ` [PATCH v4] " Jason A. Donenfeld 2 siblings, 0 replies; 22+ messages in thread From: Jason A. Donenfeld @ 2016-02-05 13:06 UTC (permalink / raw) To: Rasmus Villemoes Cc: Joe Perches, Daniel Borkmann, Andrew Morton, andriy.shevchenko, LKML On Fri, Feb 5, 2016 at 1:06 AM, Rasmus Villemoes <linux@rasmusvillemoes.dk> wrote: > First of all I don't think vsprintf.c should be extended with yet > another piece of unused code, so I hope there's an actual user coming. There is. Don't worry. > > Second, please add tests to lib/test_printf.c. Sure, no problem. I'll add this in the next version. > > Third, wouldn't it be more convenient/flexible if a meant "print those > that are present _and_ requested"; that is, the above would be > >> + have_p = have_p && sa->sin6_port; >> + have_s = have_s && sa->sin6_scope_id; >> + have_f = have_f && sa->sin6_flowinfo & IPV6_FLOWINFO_MASK; > > that way one could say %pISaf and have the flowinfo if and only if it's > present, without also unintentionally turning on port or scope_id. That's a great idea. I'll make this change too for the next version. ^ permalink raw reply [flat|nested] 22+ messages in thread
* [PATCH] vsprintf: automatic parameters for %pIS via 'a' 2016-02-05 0:06 ` [PATCH v2] " Rasmus Villemoes 2016-02-05 13:06 ` Jason A. Donenfeld @ 2016-02-05 13:37 ` Jason A. Donenfeld 2016-02-05 13:39 ` [PATCH v4] " Jason A. Donenfeld 2 siblings, 0 replies; 22+ messages in thread From: Jason A. Donenfeld @ 2016-02-05 13:37 UTC (permalink / raw) To: Rasmus Villemoes, Joe Perches, Daniel Borkmann, Andrew Morton, andriy.shevchenko, LKML Cc: Jason A. Donenfeld This patch adds a variable 'a' which indicates that the 'p', 'f', and 's' options should active depending on whether or not those parameters are actually valid inside the passed sockaddr. Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com> --- Documentation/printk-formats.txt | 7 +++++-- lib/test_printf.c | 23 +++++++++++++++++++++++ lib/vsprintf.c | 19 +++++++++++++++++-- 3 files changed, 45 insertions(+), 4 deletions(-) diff --git a/Documentation/printk-formats.txt b/Documentation/printk-formats.txt index 5d1128b..5c45db4 100644 --- a/Documentation/printk-formats.txt +++ b/Documentation/printk-formats.txt @@ -193,7 +193,7 @@ IPv4/IPv6 addresses (generic, with port, flowinfo, scope): %piS 001.002.003.004 or 00010002000300040005000600070008 %pISc 1.2.3.4 or 1:2:3:4:5:6:7:8 %pISpc 1.2.3.4:12345 or [1:2:3:4:5:6:7:8]:12345 - %p[Ii]S[pfschnbl] + %p[Ii]S[pfsachnbl] For printing an IP address without the need to distinguish whether it's of type AF_INET or AF_INET6, a pointer to a valid 'struct sockaddr', @@ -201,7 +201,10 @@ IPv4/IPv6 addresses (generic, with port, flowinfo, scope): The additional 'p', 'f', and 's' specifiers are used to specify port (IPv4, IPv6), flowinfo (IPv6) and scope (IPv6). Ports have a ':' prefix, - flowinfo a '/' and scope a '%', each followed by the actual value. + flowinfo a '/' and scope a '%', each followed by the actual value. If 'a' + is given, 'p', 'f', and 's', when also specified, are only printed + depending on whether or not the socketaddr has a non-zero port, + flowinfo, and scope. In case of an IPv6 address the compressed IPv6 address as described by http://tools.ietf.org/html/rfc5952 is being used if the additional diff --git a/lib/test_printf.c b/lib/test_printf.c index 4f6ae60..c3f975e 100644 --- a/lib/test_printf.c +++ b/lib/test_printf.c @@ -16,6 +16,7 @@ #include <linux/dcache.h> #include <linux/socket.h> #include <linux/in.h> +#include <linux/in6.h> #define BUF_SIZE 256 #define PAD_SIZE 16 @@ -301,11 +302,33 @@ ip4(void) test("127.000.000.001|127.0.0.1", "%piS|%pIS", &sa, &sa); sa.sin_addr.s_addr = cpu_to_be32(0x01020304); test("001.002.003.004:12345|1.2.3.4:12345", "%piSp|%pISp", &sa, &sa); + test("1.2.3.4:12345", "%pISpa", &sa); + test("1.2.3.4", "%pISa", &sa); + sa.sin_port = 0; + test("1.2.3.4", "%pISpa", &sa); } static void __init ip6(void) { + struct sockaddr_in6 sa = { 0 }; + + sa.sin6_family = AF_INET6; + sa.sin6_port = cpu_to_be16(12345); + sa.sin6_addr.in6_u.u6_addr16[0] = cpu_to_be16(0xabcd); + sa.sin6_addr.in6_u.u6_addr16[7] = cpu_to_be16(0x1234); + sa.sin6_flowinfo = cpu_to_be32(20); + sa.sin6_scope_id = 98; + + test("[abcd::1234]:12345", "%pISpca", &sa); + test("[abcd::1234]:12345/20", "%pISpfca", &sa); + test("[abcd::1234]:12345/20%98", "%pISpfsca", &sa); + sa.sin6_flowinfo = 0; + test("[abcd::1234]:12345%98", "%pISpsfca", &sa); + sa.sin6_port = 0; + test("[abcd::1234]%98", "%pISpfsca", &sa); + sa.sin6_scope_id = 0; + test("abcd::1234", "%pISpfsca", &sa); } static void __init diff --git a/lib/vsprintf.c b/lib/vsprintf.c index 48ff9c3..80d8ce5 100644 --- a/lib/vsprintf.c +++ b/lib/vsprintf.c @@ -1145,7 +1145,7 @@ static noinline_for_stack char *ip6_addr_string_sa(char *buf, char *end, const struct sockaddr_in6 *sa, struct printf_spec spec, const char *fmt) { - bool have_p = false, have_s = false, have_f = false, have_c = false; + bool have_p = false, have_s = false, have_f = false, have_c = false, have_a = false; char ip6_addr[sizeof("[xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:255.255.255.255]") + sizeof(":12345") + sizeof("/123456789") + sizeof("%1234567890")]; @@ -1169,9 +1169,18 @@ char *ip6_addr_string_sa(char *buf, char *end, const struct sockaddr_in6 *sa, case 'c': have_c = true; break; + case 'a': + have_a = true; + break; } } + if (have_a) { + have_p = have_p && sa->sin6_port; + have_s = have_s && sa->sin6_scope_id; + have_f = have_f && (sa->sin6_flowinfo & IPV6_FLOWINFO_MASK); + } + if (have_p || have_s || have_f) { *p = '['; off = 1; @@ -1207,7 +1216,7 @@ static noinline_for_stack char *ip4_addr_string_sa(char *buf, char *end, const struct sockaddr_in *sa, struct printf_spec spec, const char *fmt) { - bool have_p = false; + bool have_p = false, have_a = false; char *p, ip4_addr[sizeof("255.255.255.255") + sizeof(":12345")]; char *pend = ip4_addr + sizeof(ip4_addr); const u8 *addr = (const u8 *) &sa->sin_addr.s_addr; @@ -1225,9 +1234,15 @@ char *ip4_addr_string_sa(char *buf, char *end, const struct sockaddr_in *sa, case 'b': fmt4[2] = *fmt; break; + case 'a': + have_a = true; + break; } } + if (have_a) + have_p = have_p && sa->sin_port; + p = ip4_string(ip4_addr, addr, fmt4); if (have_p) { *p++ = ':'; -- 2.7.0 ^ permalink raw reply related [flat|nested] 22+ messages in thread
* [PATCH v4] vsprintf: automatic parameters for %pIS via 'a' 2016-02-05 0:06 ` [PATCH v2] " Rasmus Villemoes 2016-02-05 13:06 ` Jason A. Donenfeld 2016-02-05 13:37 ` [PATCH] " Jason A. Donenfeld @ 2016-02-05 13:39 ` Jason A. Donenfeld 2 siblings, 0 replies; 22+ messages in thread From: Jason A. Donenfeld @ 2016-02-05 13:39 UTC (permalink / raw) To: linux, joe, daniel, akpm, andriy.shevchenko, linux-kernel Cc: Jason A. Donenfeld This patch adds a variable 'a' which indicates that the 'p', 'f', and 's' options should active depending on whether or not those parameters are actually valid inside the passed sockaddr. Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com> --- Documentation/printk-formats.txt | 7 +++++-- lib/test_printf.c | 23 +++++++++++++++++++++++ lib/vsprintf.c | 19 +++++++++++++++++-- 3 files changed, 45 insertions(+), 4 deletions(-) diff --git a/Documentation/printk-formats.txt b/Documentation/printk-formats.txt index 5d1128b..5c45db4 100644 --- a/Documentation/printk-formats.txt +++ b/Documentation/printk-formats.txt @@ -193,7 +193,7 @@ IPv4/IPv6 addresses (generic, with port, flowinfo, scope): %piS 001.002.003.004 or 00010002000300040005000600070008 %pISc 1.2.3.4 or 1:2:3:4:5:6:7:8 %pISpc 1.2.3.4:12345 or [1:2:3:4:5:6:7:8]:12345 - %p[Ii]S[pfschnbl] + %p[Ii]S[pfsachnbl] For printing an IP address without the need to distinguish whether it's of type AF_INET or AF_INET6, a pointer to a valid 'struct sockaddr', @@ -201,7 +201,10 @@ IPv4/IPv6 addresses (generic, with port, flowinfo, scope): The additional 'p', 'f', and 's' specifiers are used to specify port (IPv4, IPv6), flowinfo (IPv6) and scope (IPv6). Ports have a ':' prefix, - flowinfo a '/' and scope a '%', each followed by the actual value. + flowinfo a '/' and scope a '%', each followed by the actual value. If 'a' + is given, 'p', 'f', and 's', when also specified, are only printed + depending on whether or not the socketaddr has a non-zero port, + flowinfo, and scope. In case of an IPv6 address the compressed IPv6 address as described by http://tools.ietf.org/html/rfc5952 is being used if the additional diff --git a/lib/test_printf.c b/lib/test_printf.c index 4f6ae60..c3f975e 100644 --- a/lib/test_printf.c +++ b/lib/test_printf.c @@ -16,6 +16,7 @@ #include <linux/dcache.h> #include <linux/socket.h> #include <linux/in.h> +#include <linux/in6.h> #define BUF_SIZE 256 #define PAD_SIZE 16 @@ -301,11 +302,33 @@ ip4(void) test("127.000.000.001|127.0.0.1", "%piS|%pIS", &sa, &sa); sa.sin_addr.s_addr = cpu_to_be32(0x01020304); test("001.002.003.004:12345|1.2.3.4:12345", "%piSp|%pISp", &sa, &sa); + test("1.2.3.4:12345", "%pISpa", &sa); + test("1.2.3.4", "%pISa", &sa); + sa.sin_port = 0; + test("1.2.3.4", "%pISpa", &sa); } static void __init ip6(void) { + struct sockaddr_in6 sa = { 0 }; + + sa.sin6_family = AF_INET6; + sa.sin6_port = cpu_to_be16(12345); + sa.sin6_addr.in6_u.u6_addr16[0] = cpu_to_be16(0xabcd); + sa.sin6_addr.in6_u.u6_addr16[7] = cpu_to_be16(0x1234); + sa.sin6_flowinfo = cpu_to_be32(20); + sa.sin6_scope_id = 98; + + test("[abcd::1234]:12345", "%pISpca", &sa); + test("[abcd::1234]:12345/20", "%pISpfca", &sa); + test("[abcd::1234]:12345/20%98", "%pISpfsca", &sa); + sa.sin6_flowinfo = 0; + test("[abcd::1234]:12345%98", "%pISpsfca", &sa); + sa.sin6_port = 0; + test("[abcd::1234]%98", "%pISpfsca", &sa); + sa.sin6_scope_id = 0; + test("abcd::1234", "%pISpfsca", &sa); } static void __init diff --git a/lib/vsprintf.c b/lib/vsprintf.c index 48ff9c3..80d8ce5 100644 --- a/lib/vsprintf.c +++ b/lib/vsprintf.c @@ -1145,7 +1145,7 @@ static noinline_for_stack char *ip6_addr_string_sa(char *buf, char *end, const struct sockaddr_in6 *sa, struct printf_spec spec, const char *fmt) { - bool have_p = false, have_s = false, have_f = false, have_c = false; + bool have_p = false, have_s = false, have_f = false, have_c = false, have_a = false; char ip6_addr[sizeof("[xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:255.255.255.255]") + sizeof(":12345") + sizeof("/123456789") + sizeof("%1234567890")]; @@ -1169,9 +1169,18 @@ char *ip6_addr_string_sa(char *buf, char *end, const struct sockaddr_in6 *sa, case 'c': have_c = true; break; + case 'a': + have_a = true; + break; } } + if (have_a) { + have_p = have_p && sa->sin6_port; + have_s = have_s && sa->sin6_scope_id; + have_f = have_f && (sa->sin6_flowinfo & IPV6_FLOWINFO_MASK); + } + if (have_p || have_s || have_f) { *p = '['; off = 1; @@ -1207,7 +1216,7 @@ static noinline_for_stack char *ip4_addr_string_sa(char *buf, char *end, const struct sockaddr_in *sa, struct printf_spec spec, const char *fmt) { - bool have_p = false; + bool have_p = false, have_a = false; char *p, ip4_addr[sizeof("255.255.255.255") + sizeof(":12345")]; char *pend = ip4_addr + sizeof(ip4_addr); const u8 *addr = (const u8 *) &sa->sin_addr.s_addr; @@ -1225,9 +1234,15 @@ char *ip4_addr_string_sa(char *buf, char *end, const struct sockaddr_in *sa, case 'b': fmt4[2] = *fmt; break; + case 'a': + have_a = true; + break; } } + if (have_a) + have_p = have_p && sa->sin_port; + p = ip4_string(ip4_addr, addr, fmt4); if (have_p) { *p++ = ':'; -- 2.7.0 ^ permalink raw reply related [flat|nested] 22+ messages in thread
end of thread, other threads:[~2016-02-05 13:38 UTC | newest] Thread overview: 22+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2016-02-03 10:41 [PATCH] vsprintf: do not append unset Scope ID to IPv6 Jason A. Donenfeld 2016-02-03 12:13 ` [PATCH] vsprintf: flowinfo in IPv6 is optional too Jason A. Donenfeld 2016-02-03 17:56 ` IRe: " Joe Perches 2016-02-03 21:09 ` Jason A. Donenfeld 2016-02-03 21:13 ` Andy Shevchenko 2016-02-03 21:13 ` IRe: " Daniel Borkmann 2016-02-03 21:15 ` Jason A. Donenfeld 2016-02-03 21:07 ` [PATCH] vsprintf: do not append unset Scope ID to IPv6 Daniel Borkmann 2016-02-03 21:14 ` Jason A. Donenfeld 2016-02-03 21:47 ` Joe Perches 2016-02-03 22:09 ` Daniel Borkmann 2016-02-03 22:42 ` Jason A. Donenfeld 2016-02-03 22:53 ` [PATCH] vsprintf: automatic parameters for %pIS via 'a' Jason A. Donenfeld 2016-02-03 23:05 ` Joe Perches 2016-02-03 23:25 ` Jason A. Donenfeld 2016-02-03 23:29 ` [PATCH v2] " Jason A. Donenfeld 2016-02-03 23:37 ` Joe Perches 2016-02-04 0:59 ` [PATCH v3] " Jason A. Donenfeld 2016-02-05 0:06 ` [PATCH v2] " Rasmus Villemoes 2016-02-05 13:06 ` Jason A. Donenfeld 2016-02-05 13:37 ` [PATCH] " Jason A. Donenfeld 2016-02-05 13:39 ` [PATCH v4] " Jason A. Donenfeld
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).