p.mousavizadeh_protonmail.com created this revision.
p.mousavizadeh_protonmail.com added reviewers: manpages, network.
p.mousavizadeh_protonmail.com added a project: network.
Herald added subscribers: glebius, melifaro, donner, imp.
p.mousavizadeh_protonmail.com requested review of this revision.

REVISION SUMMARY
  Add IPv6 support for address parsing and unparsing in ng_ksocket.
  
  - Fix issues related to D23788 <https://reviews.freebsd.org/D23788>.
  - Validate square brackets as a requirement. (src, man)
  
  Co-authored by: Neel Chauhan <neel AT neelc DOT org>
  
  Note: Phabricator won't let me use the update diff function from the original 
revision.

TEST PLAN
  Here is my current netflow export configuration and it works:
  
    kldstat -qm ng_netflow || kldload ng_netflow
    kldstat -qm ng_ether || kldload ng_ether
    kldload ./ng_ksocket.ko
    ngctl mkpeer vtnet0: netflow lower iface0
    ngctl name vtnet0:lower netflow          
    ngctl connect vtnet0: netflow: upper out0
    ngctl mkpeer netflow: ksocket export9 inet6/dgram/udp6
    ngctl name netflow:export9 ngk
    ngctl msg ngk: connect inet6/[fdb5:c59b:114e:8db4::1]:4444
  
  I have tested this for tcp6 protocol, msg bind, and link-local with 
[fe80::1%vtnet0]:4444.

REPOSITORY
  rG FreeBSD src repository

REVISION DETAIL
  https://reviews.freebsd.org/D48204

AFFECTED FILES
  share/man/man4/ng_ksocket.4
  sys/netgraph/ng_ksocket.c

EMAIL PREFERENCES
  https://reviews.freebsd.org/settings/panel/emailpreferences/

To: p.mousavizadeh_protonmail.com, #manpages, #network
Cc: imp, nc, donner, freebsd-net-list, melifaro, glebius, #src_committers, 
p.mousavizadeh_protonmail.com, ghislain_smartix.llc, 
konrad.kreciwilk_korbank.pl, cmiller_netapp.com, rajeshasp, mmacy, 
kpraveen.lkml_gmail.com, chris_cretaforce.gr, simonvella_gmail.com, 
novice_techie.com, herbert_mailbox.org, tommi.pernila_iki.fi, zec, delphij, 
pstef
diff --git a/sys/netgraph/ng_ksocket.c b/sys/netgraph/ng_ksocket.c
--- a/sys/netgraph/ng_ksocket.c
+++ b/sys/netgraph/ng_ksocket.c
@@ -58,6 +58,9 @@
 #include <sys/uio.h>
 #include <sys/un.h>
 
+#include <net/if.h>
+#include <net/if_var.h>
+
 #include <netgraph/ng_message.h>
 #include <netgraph/netgraph.h>
 #include <netgraph/ng_parse.h>
@@ -66,6 +69,8 @@
 #include <netinet/in.h>
 #include <netinet/ip.h>
 
+#include <netinet6/scope6_var.h>
+
 #ifdef NG_SEPARATE_MALLOC
 static MALLOC_DEFINE(M_NETGRAPH_KSOCKET, "netgraph_ksock",
     "netgraph ksock node");
@@ -147,6 +152,19 @@
 	{ "swipe",	IPPROTO_SWIPE,		PF_INET		},
 	{ "encap",	IPPROTO_ENCAP,		PF_INET		},
 	{ "pim",	IPPROTO_PIM,		PF_INET		},
+	{ "ip6",	IPPROTO_IPV6,		PF_INET6	},
+	{ "raw6",	IPPROTO_RAW,		PF_INET6	},
+	{ "icmp6",	IPPROTO_ICMPV6,		PF_INET6	},
+	{ "igmp6",	IPPROTO_IGMP,		PF_INET6	},
+	{ "tcp6",	IPPROTO_TCP,		PF_INET6	},
+	{ "udp6",	IPPROTO_UDP,		PF_INET6	},
+	{ "gre6",	IPPROTO_GRE,		PF_INET6	},
+	{ "esp6",	IPPROTO_ESP,		PF_INET6	},
+	{ "ah6",	IPPROTO_AH,		PF_INET6	},
+	{ "swipe6",	IPPROTO_SWIPE,		PF_INET6	},
+	{ "encap6",	IPPROTO_ENCAP,		PF_INET6	},
+	{ "divert6",	IPPROTO_DIVERT,		PF_INET6	},
+	{ "pim6",	IPPROTO_PIM,		PF_INET6	},
 	{ NULL,		-1					},
 };
 
@@ -296,9 +314,58 @@
 		break;
 	    }
 
-#if 0
-	case PF_INET6:	/* XXX implement this someday */
-#endif
+	case PF_INET6:
+	    {
+		struct sockaddr_in6 *const sin6 = (struct sockaddr_in6 *)sa;
+		char *eptr;
+		char addr[INET6_ADDRSTRLEN];
+		char ifname[16];
+		u_long port;
+		bool hasifname = true;
+
+		/* RFC 3986 Section 3.2.2, Validate IP literal within square brackets. */
+		if (s[*off] == '[' && (strstr(&s[*off], "]")))
+			(*off)++;
+		else
+			return (EINVAL);
+		if ((eptr = strstr(&s[*off], "%")) == NULL) {
+			hasifname = false;
+			eptr = strstr(&s[*off], "]");
+		}
+		snprintf(addr, eptr - (s + *off) + 1, "%s", &s[*off]);
+		*off += (eptr - (s + *off));
+		if (!inet_pton(AF_INET6, addr, &sin6->sin6_addr))
+			return (EINVAL);
+
+		if (hasifname) {
+			uint16_t scope;
+
+			eptr = strstr(&s[*off], "]");
+			(*off)++;
+			snprintf(ifname, eptr - (s + *off) + 1, "%s", &s[*off]);
+			*off += (eptr - (s + *off));
+
+			if (sin6->sin6_addr.s6_addr16[0] != IPV6_ADDR_INT16_ULL)
+				return (EINVAL);
+			scope = in6_getscope(&sin6->sin6_addr);
+			sin6->sin6_scope_id =
+			    in6_getscopezone(ifunit(ifname), scope);
+		}
+
+		(*off)++;
+		if (s[*off] == ':') {
+			(*off)++;
+			port = strtoul(s + *off, &eptr, 10);
+			if (port > 0xffff || eptr == s + *off)
+				return (EINVAL);
+			*off += (eptr - (s + *off));
+			sin6->sin6_port = htons(port);
+		} else
+			sin6->sin6_port = 0;
+
+		sin6->sin6_len = sizeof(*sin6);
+		break;
+	    }
 
 	default:
 		return (EINVAL);
@@ -358,9 +425,24 @@
 		return(0);
 	    }
 
-#if 0
-	case PF_INET6:	/* XXX implement this someday */
-#endif
+	case PF_INET6:
+	    {
+		const struct sockaddr_in6 *sin6 = (const struct sockaddr_in6 *)sa;
+		char addr[INET6_ADDRSTRLEN];
+
+		inet_ntop(AF_INET6, &sin6->sin6_addr, addr, INET6_ADDRSTRLEN);
+		slen += snprintf(cbuf, cbuflen, "inet6/[%s]", addr);
+
+		if (sin6->sin6_port != 0) {
+			slen += snprintf(cbuf + strlen(cbuf),
+			    cbuflen - strlen(cbuf), ":%d",
+			    (u_int)ntohs(sin6->sin6_port));
+		}
+		if (slen >= cbuflen)
+			return (ERANGE);
+		*off += sizeof(*sin6);
+		return(0);
+	    }
 
 	default:
 		return (*ng_ksocket_generic_sockaddr_type.supertype->unparse)
diff --git a/share/man/man4/ng_ksocket.4 b/share/man/man4/ng_ksocket.4
--- a/share/man/man4/ng_ksocket.4
+++ b/share/man/man4/ng_ksocket.4
@@ -183,7 +183,8 @@
 equivalent of the C structure
 is an acceptable form.
 For the
-.Dv PF_INET
+.Dv PF_INET ,
+.Dv PF_INET6
 and
 .Dv PF_LOCAL
 address families, a more convenient form is also used, which is
@@ -191,7 +192,11 @@
 address.
 For
 .Dv PF_INET ,
-the address is an IP address followed by an optional colon and port number.
+the address is an IPv4 address followed by an optional colon and port number.
+For
+.Dv PF_INET6 ,
+the address is an IPv6 address enclosed in square brackets followed
+by an optional colon and port number.
 For
 .Dv PF_LOCAL ,
 the address is the pathname as a doubly quoted string.
@@ -202,6 +207,8 @@
 local/"/tmp/foo.socket"
 .It Dv PF_INET
 inet/192.168.1.1:1234
+.It Dv PF_INET6
+inet6/[2001::1]:1234
 .It Other
 .Dv "\&{ family=16 len=16 data=[0x70 0x00 0x01 0x23] \&}"
 .El

  • [Differe... p.mousavizadeh_protonmail.com (Seyed Pouria Mousavizadeh Tehrani)
    • [Di... glebius (Gleb Smirnoff)
    • [Di... glebius (Gleb Smirnoff)
    • [Di... p.mousavizadeh_protonmail.com (Seyed Pouria Mousavizadeh Tehrani)
    • [Di... p.mousavizadeh_protonmail.com (Seyed Pouria Mousavizadeh Tehrani)
    • [Di... glebius (Gleb Smirnoff)
    • [Di... glebius (Gleb Smirnoff)

Reply via email to