Skip to contentSkip to conversation

printf: Add format for 8-byte EUI-64 type

PATCH Superseded Keith Busch 2 participants 2 messages Dec 9, 2015

Subsystems (4)

v2 of 3 Superseded Latest is v3 →

lore
Share & tools
lore
#0 lore raw

PATCH v2 1/1 printf: Add format for 8-byte EUI-64 type

MAC addresses may be formed using rules based on EUI-64, which is 2 bytes longer than a typical 6-byte MAC. This patch adds a long specifier to the %pM format to support the extended unique identifier.

Since there are now two cases that use the default ':' separator, this initializes the separator during its declaration, and removes the switch fall through case.

Signed-off-by Keith Busch <keith.busch at intel.com>

---
Changed from previos version:

Fixed checks for the 'l' specifier. This can be in fmt[1] or fmt[2], pointed out by Joe Perches from original review (thanks!).

 Documentation/printk-formats.txt | 13 ++++++++++---
 lib/vsprintf.c                   | 31 +++++++++++++++++++++++--------
 2 files changed, 33 insertions(+), 11 deletions(-)
Documentation/printk-formats.txt +10 -3
index b784c27..e2fe4ed 100644
@@ -136,14 +136,21 @@ Raw buffer as a hex string:
 MAC/FDDI addresses:
 
 	%pM	00:01:02:03:04:05
+	%pMl	00:01:02:03:04:05:06:07
 	%pMR	05:04:03:02:01:00
+	%pMRl	07:06:05:04:03:02:01:00
 	%pMF	00-01-02-03-04-05
+	%pMFl	00-01-02-03-04-05-06-07
 	%pm	000102030405
+	%pml	0001020304050607
 	%pmR	050403020100
+	%pmRl	0706050403020100
 
-	For printing 6-byte MAC/FDDI addresses in hex notation. The 'M' and 'm'
-	specifiers result in a printed address with ('M') or without ('m') byte
-	separators. The default byte separator is the colon (':').
+	For printing 6 or 8-byte MAC/FDDI addresses in hex notation. The
+	'M' and 'm' specifiers result in a printed address with ('M')
+	or without ('m') byte separators. The default byte separator is
+	the colon (':'). Append 'l' to specify an 8-byte in accordance
+	with EUI-64 format.
 
 	Where FDDI addresses are concerned the 'F' specifier can be used after
 	the 'M' specifier to use dash ('-') separators instead of the default
lib/vsprintf.c +23 -8
index f9cee8e..a5eb82c 100644
@@ -889,10 +889,10 @@ static noinline_for_stack
 char *mac_address_string(char *buf, char *end, u8 *addr,
 			 struct printf_spec spec, const char *fmt)
 {
-	char mac_addr[sizeof("xx:xx:xx:xx:xx:xx")];
+	char mac_addr[sizeof("xx:xx:xx:xx:xx:xx:xx:xx")];
 	char *p = mac_addr;
-	int i;
-	char separator;
+	int i, bytes = 6;
+	char separator = ':';
 	bool reversed = false;
 
 	switch (fmt[1]) {
@@ -902,20 +902,33 @@ char *mac_address_string(char *buf, char *end, u8 *addr,
 
 	case 'R':
 		reversed = true;
-		/* fall through */
+		break;
+
+	case 'l':
+		bytes = 8;
+		break;
 
 	default:
-		separator = ':';
 		break;
 	}
+	if (separator == '-' || reversed) {
+		/* 'F' and 'R' may take additional length specifier */
+		switch (fmt[2]) {
+		case 'l':
+			bytes = 8;
+			break;
+		default:
+			break;
+		}
+	}
 
-	for (i = 0; i < 6; i++) {
+	for (i = 0; i < bytes; i++) {
 		if (reversed)
-			p = hex_byte_pack(p, addr[5 - i]);
+			p = hex_byte_pack(p, addr[(bytes - 1) - i]);
 		else
 			p = hex_byte_pack(p, addr[i]);
 
-		if (fmt[0] == 'M' && i != 5)
+		if (fmt[0] == 'M' && i != (bytes - 1))
 			*p++ = separator;
 	}
 	*p = '\0';
@@ -1496,6 +1509,8 @@ char *pointer(const char *fmt, char *buf, char *end, void *ptr,
 	case 'm':			/* Contiguous: 000102030405 */
 					/* [mM]F (FDDI) */
 					/* [mM]R (Reverse order; Bluetooth) */
+					/* [mM]l (EUI-64) */
+					/* [mM][FR]l (FDDI/Reverse order EUI-64) */
 		return mac_address_string(buf, end, ptr, spec, fmt);
 	case 'I':			/* Formatted IP supported
 					 * 4:	1.2.3.4
Signature · 1 line
2.6.2.307.g37023ba
#1 lore raw
Quoted 8 lines · Keith Busch

MAC addresses may be formed using rules based on EUI-64, which is 2 bytes longer than a typical 6-byte MAC. This patch adds a long specifier to the %pM format to support the extended unique identifier.

Since there are now two cases that use the default ':' separator, this initializes the separator during its declaration, and removes the switch fall through case.

Quoted 6 lines
Signed-off-by Keith Busch <keith.busch at intel.com>

---
Changed from previos version:

? Fixed checks for the 'l' specifier. This can be in fmt[1] or fmt[2], ? pointed out by Joe Perches from original review (thanks!).

[]

lib/vsprintf.c

Quoted 1 line
lib/vsprintf.c +0 -0

[]

Quoted 16 lines
lib/vsprintf.c +0 -0
@@ -902,20 +902,33 @@ char *mac_address_string(char *buf, char *end, u8 *addr,

?
? case 'R':
? reversed = true;

lib/vsprintf.c +5 -1
-		/* fall through */
+		break;
+
+	case 'l':
+		bytes = 8;
+		break;

?
? default:

lib/vsprintf.c +0 -1
-		separator = ':';

? break;
? }

lib/vsprintf.c char *mac_address_string(char *buf, char *end, u8 *addr, · line 923

Quoted 10 lines
lib/vsprintf.c +10 -0
+	if (separator == '-' || reversed) {
+		/* 'F' and 'R' may take additional length specifier */
+		switch (fmt[2]) {
+		case 'l':
+			bytes = 8;
+			break;
+		default:
+			break;
+		}
+	}

Using a while (isalpha(*++fmt)) loop like ip6_addr_string_sa would probably be simpler.