unix: add SetsockoptCanRawFilter for linux

Add the SetsockoptCanRawFilter func and CanFilter type to allow kernel
message filtering on AF_CAN sockets.

Fixes golang/go#29638

Change-Id: I4042825527ba2bc9aeb8dbe70d1960a06b15c29e
Reviewed-on: https://go-review.googlesource.com/c/163318
Run-TryBot: Tobias Klauser <tobias.klauser@gmail.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
diff --git a/unix/linux/types.go b/unix/linux/types.go
index ee87081..f3238a3 100644
--- a/unix/linux/types.go
+++ b/unix/linux/types.go
@@ -493,6 +493,8 @@
 
 type TCPInfo C.struct_tcp_info
 
+type CanFilter C.struct_can_filter
+
 const (
 	SizeofSockaddrInet4     = C.sizeof_struct_sockaddr_in
 	SizeofSockaddrInet6     = C.sizeof_struct_sockaddr_in6
@@ -522,6 +524,7 @@
 	SizeofICMPv6Filter      = C.sizeof_struct_icmp6_filter
 	SizeofUcred             = C.sizeof_struct_ucred
 	SizeofTCPInfo           = C.sizeof_struct_tcp_info
+	SizeofCanFilter         = C.sizeof_struct_can_filter
 )
 
 // Netlink routing and interface messages
diff --git a/unix/syscall_linux.go b/unix/syscall_linux.go
index 9a53ae2..4bb86aa 100644
--- a/unix/syscall_linux.go
+++ b/unix/syscall_linux.go
@@ -1000,6 +1000,14 @@
 	return setsockopt(fd, level, opt, unsafe.Pointer(fprog), unsafe.Sizeof(*fprog))
 }
 
+func SetsockoptCanRawFilter(fd, level, opt int, filter []CanFilter) error {
+	var p unsafe.Pointer
+	if len(filter) > 0 {
+		p = unsafe.Pointer(&filter[0])
+	}
+	return setsockopt(fd, level, opt, p, uintptr(len(filter)*SizeofCanFilter))
+}
+
 // Keyctl Commands (http://man7.org/linux/man-pages/man2/keyctl.2.html)
 
 // KeyctlInt calls keyctl commands in which each argument is an int.
diff --git a/unix/ztypes_linux_386.go b/unix/ztypes_linux_386.go
index d262150..3e9c18e 100644
--- a/unix/ztypes_linux_386.go
+++ b/unix/ztypes_linux_386.go
@@ -405,6 +405,11 @@
 	Total_retrans  uint32
 }
 
+type CanFilter struct {
+	Id   uint32
+	Mask uint32
+}
+
 const (
 	SizeofSockaddrInet4     = 0x10
 	SizeofSockaddrInet6     = 0x1c
@@ -434,6 +439,7 @@
 	SizeofICMPv6Filter      = 0x20
 	SizeofUcred             = 0xc
 	SizeofTCPInfo           = 0x68
+	SizeofCanFilter         = 0x8
 )
 
 const (
diff --git a/unix/ztypes_linux_amd64.go b/unix/ztypes_linux_amd64.go
index e492caa..14365ff 100644
--- a/unix/ztypes_linux_amd64.go
+++ b/unix/ztypes_linux_amd64.go
@@ -406,6 +406,11 @@
 	Total_retrans  uint32
 }
 
+type CanFilter struct {
+	Id   uint32
+	Mask uint32
+}
+
 const (
 	SizeofSockaddrInet4     = 0x10
 	SizeofSockaddrInet6     = 0x1c
@@ -435,6 +440,7 @@
 	SizeofICMPv6Filter      = 0x20
 	SizeofUcred             = 0xc
 	SizeofTCPInfo           = 0x68
+	SizeofCanFilter         = 0x8
 )
 
 const (
diff --git a/unix/ztypes_linux_arm.go b/unix/ztypes_linux_arm.go
index ad43421..80ad473 100644
--- a/unix/ztypes_linux_arm.go
+++ b/unix/ztypes_linux_arm.go
@@ -409,6 +409,11 @@
 	Total_retrans  uint32
 }
 
+type CanFilter struct {
+	Id   uint32
+	Mask uint32
+}
+
 const (
 	SizeofSockaddrInet4     = 0x10
 	SizeofSockaddrInet6     = 0x1c
@@ -438,6 +443,7 @@
 	SizeofICMPv6Filter      = 0x20
 	SizeofUcred             = 0xc
 	SizeofTCPInfo           = 0x68
+	SizeofCanFilter         = 0x8
 )
 
 const (
diff --git a/unix/ztypes_linux_arm64.go b/unix/ztypes_linux_arm64.go
index ef76a36..20e78cc 100644
--- a/unix/ztypes_linux_arm64.go
+++ b/unix/ztypes_linux_arm64.go
@@ -407,6 +407,11 @@
 	Total_retrans  uint32
 }
 
+type CanFilter struct {
+	Id   uint32
+	Mask uint32
+}
+
 const (
 	SizeofSockaddrInet4     = 0x10
 	SizeofSockaddrInet6     = 0x1c
@@ -436,6 +441,7 @@
 	SizeofICMPv6Filter      = 0x20
 	SizeofUcred             = 0xc
 	SizeofTCPInfo           = 0x68
+	SizeofCanFilter         = 0x8
 )
 
 const (
diff --git a/unix/ztypes_linux_mips.go b/unix/ztypes_linux_mips.go
index dbf0590..bdeb0cb 100644
--- a/unix/ztypes_linux_mips.go
+++ b/unix/ztypes_linux_mips.go
@@ -408,6 +408,11 @@
 	Total_retrans  uint32
 }
 
+type CanFilter struct {
+	Id   uint32
+	Mask uint32
+}
+
 const (
 	SizeofSockaddrInet4     = 0x10
 	SizeofSockaddrInet6     = 0x1c
@@ -437,6 +442,7 @@
 	SizeofICMPv6Filter      = 0x20
 	SizeofUcred             = 0xc
 	SizeofTCPInfo           = 0x68
+	SizeofCanFilter         = 0x8
 )
 
 const (
diff --git a/unix/ztypes_linux_mips64.go b/unix/ztypes_linux_mips64.go
index 1b7e670..2d3f591 100644
--- a/unix/ztypes_linux_mips64.go
+++ b/unix/ztypes_linux_mips64.go
@@ -407,6 +407,11 @@
 	Total_retrans  uint32
 }
 
+type CanFilter struct {
+	Id   uint32
+	Mask uint32
+}
+
 const (
 	SizeofSockaddrInet4     = 0x10
 	SizeofSockaddrInet6     = 0x1c
@@ -436,6 +441,7 @@
 	SizeofICMPv6Filter      = 0x20
 	SizeofUcred             = 0xc
 	SizeofTCPInfo           = 0x68
+	SizeofCanFilter         = 0x8
 )
 
 const (
diff --git a/unix/ztypes_linux_mips64le.go b/unix/ztypes_linux_mips64le.go
index 5737900..5fb57ff 100644
--- a/unix/ztypes_linux_mips64le.go
+++ b/unix/ztypes_linux_mips64le.go
@@ -407,6 +407,11 @@
 	Total_retrans  uint32
 }
 
+type CanFilter struct {
+	Id   uint32
+	Mask uint32
+}
+
 const (
 	SizeofSockaddrInet4     = 0x10
 	SizeofSockaddrInet6     = 0x1c
@@ -436,6 +441,7 @@
 	SizeofICMPv6Filter      = 0x20
 	SizeofUcred             = 0xc
 	SizeofTCPInfo           = 0x68
+	SizeofCanFilter         = 0x8
 )
 
 const (
diff --git a/unix/ztypes_linux_mipsle.go b/unix/ztypes_linux_mipsle.go
index 0e88bf4..b46b26f 100644
--- a/unix/ztypes_linux_mipsle.go
+++ b/unix/ztypes_linux_mipsle.go
@@ -408,6 +408,11 @@
 	Total_retrans  uint32
 }
 
+type CanFilter struct {
+	Id   uint32
+	Mask uint32
+}
+
 const (
 	SizeofSockaddrInet4     = 0x10
 	SizeofSockaddrInet6     = 0x1c
@@ -437,6 +442,7 @@
 	SizeofICMPv6Filter      = 0x20
 	SizeofUcred             = 0xc
 	SizeofTCPInfo           = 0x68
+	SizeofCanFilter         = 0x8
 )
 
 const (
diff --git a/unix/ztypes_linux_ppc64.go b/unix/ztypes_linux_ppc64.go
index 5ac91b3..e14e3c9 100644
--- a/unix/ztypes_linux_ppc64.go
+++ b/unix/ztypes_linux_ppc64.go
@@ -408,6 +408,11 @@
 	Total_retrans  uint32
 }
 
+type CanFilter struct {
+	Id   uint32
+	Mask uint32
+}
+
 const (
 	SizeofSockaddrInet4     = 0x10
 	SizeofSockaddrInet6     = 0x1c
@@ -437,6 +442,7 @@
 	SizeofICMPv6Filter      = 0x20
 	SizeofUcred             = 0xc
 	SizeofTCPInfo           = 0x68
+	SizeofCanFilter         = 0x8
 )
 
 const (
diff --git a/unix/ztypes_linux_ppc64le.go b/unix/ztypes_linux_ppc64le.go
index 1e59b45..2332e8f 100644
--- a/unix/ztypes_linux_ppc64le.go
+++ b/unix/ztypes_linux_ppc64le.go
@@ -408,6 +408,11 @@
 	Total_retrans  uint32
 }
 
+type CanFilter struct {
+	Id   uint32
+	Mask uint32
+}
+
 const (
 	SizeofSockaddrInet4     = 0x10
 	SizeofSockaddrInet6     = 0x1c
@@ -437,6 +442,7 @@
 	SizeofICMPv6Filter      = 0x20
 	SizeofUcred             = 0xc
 	SizeofTCPInfo           = 0x68
+	SizeofCanFilter         = 0x8
 )
 
 const (
diff --git a/unix/ztypes_linux_riscv64.go b/unix/ztypes_linux_riscv64.go
index 508885f..efec4f8 100644
--- a/unix/ztypes_linux_riscv64.go
+++ b/unix/ztypes_linux_riscv64.go
@@ -407,6 +407,11 @@
 	Total_retrans  uint32
 }
 
+type CanFilter struct {
+	Id   uint32
+	Mask uint32
+}
+
 const (
 	SizeofSockaddrInet4     = 0x10
 	SizeofSockaddrInet6     = 0x1c
@@ -436,6 +441,7 @@
 	SizeofICMPv6Filter      = 0x20
 	SizeofUcred             = 0xc
 	SizeofTCPInfo           = 0x68
+	SizeofCanFilter         = 0x8
 )
 
 const (
diff --git a/unix/ztypes_linux_s390x.go b/unix/ztypes_linux_s390x.go
index d315f2c..71cc23f 100644
--- a/unix/ztypes_linux_s390x.go
+++ b/unix/ztypes_linux_s390x.go
@@ -406,6 +406,11 @@
 	Total_retrans  uint32
 }
 
+type CanFilter struct {
+	Id   uint32
+	Mask uint32
+}
+
 const (
 	SizeofSockaddrInet4     = 0x10
 	SizeofSockaddrInet6     = 0x1c
@@ -435,6 +440,7 @@
 	SizeofICMPv6Filter      = 0x20
 	SizeofUcred             = 0xc
 	SizeofTCPInfo           = 0x68
+	SizeofCanFilter         = 0x8
 )
 
 const (
diff --git a/unix/ztypes_linux_sparc64.go b/unix/ztypes_linux_sparc64.go
index a1a9279..48805ba 100644
--- a/unix/ztypes_linux_sparc64.go
+++ b/unix/ztypes_linux_sparc64.go
@@ -410,6 +410,11 @@
 	Total_retrans  uint32
 }
 
+type CanFilter struct {
+	Id   uint32
+	Mask uint32
+}
+
 const (
 	SizeofSockaddrInet4     = 0x10
 	SizeofSockaddrInet6     = 0x1c
@@ -439,6 +444,7 @@
 	SizeofICMPv6Filter      = 0x20
 	SizeofUcred             = 0xc
 	SizeofTCPInfo           = 0x68
+	SizeofCanFilter         = 0x8
 )
 
 const (