Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

[インデックス 15390] ファイルの概要

コミット

commit e82286075674df84b9435445d48c5b8a4eeeeaa2
Author: Mikio Hara <mikioh.mikioh@gmail.com>
Date:   Sat Feb 23 08:42:04 2013 +0900

    syscall: add netlink constants for linux
    
    R=golang-dev, r
    CC=golang-dev
    https://golang.org/cl/7403049

GitHub上でのコミットページへのリンク

https://github.com/golang/go/commit/e82286075674df84b9435445d48c5b8a4eeeeaa2

元コミット内容

syscall: add netlink constants for linux

このコミットは、LinuxシステムコールパッケージにNetlink関連の定数を追加するものです。

変更の背景

このコミットの背景には、Go言語のsyscallパッケージがLinuxカーネルとのより深い連携を可能にする必要があったことが挙げられます。NetlinkはLinuxカーネルとユーザー空間のプロセス間で情報をやり取りするためのソケットベースのメカニズムであり、ネットワーク設定、ルーティング、ファイアウォールなどの管理に不可欠です。

以前のsyscallパッケージでは、Netlinkプログラミングに必要な一部の定数が不足していた可能性があります。特に、RTNLGRP_で始まる定数は、Netlinkのルーティングソケットを介して特定のイベントグループを購読するために使用されます。これらの定数がGo言語のsyscallパッケージに存在しない場合、GoプログラムからLinuxの高度なネットワーク機能を直接操作することが困難になります。

このコミットは、GoプログラムがNetlinkを介してネットワークインターフェースの状態変更、ルーティングテーブルの更新、ネイバーキャッシュの変更など、様々なカーネルイベントを監視・制御できるようにするために、これらの重要な定数を追加することを目的としています。これにより、Go言語で書かれたネットワークツールやデーモンが、より低レベルで効率的なカーネルとの対話を実現できるようになります。

前提知識の解説

Netlinkは、Linuxカーネルとユーザー空間のプロセス間で通信を行うためのソケットファミリーです。従来のioctlベースのシステムコールに代わる、より柔軟で拡張性の高いメカニズムとして設計されました。Netlinkは、ネットワーク設定、ルーティング、ファイアウォール、プロセス間通信など、多岐にわたるカーネル機能へのアクセスを提供します。

Netlink通信は、標準的なソケットAPI(socket(), bind(), sendmsg(), recvmsg()など)を使用して行われます。Netlinkメッセージは、nlmsghdr構造体で始まり、その後にペイロード(データ)が続きます。ペイロードには、nlattr(Netlink属性)と呼ばれるTLV(Type-Length-Value)形式のデータ構造が含まれることが一般的です。

Netlinkグループ (RTNLGRP_)

Netlinkには、特定の種類のイベントをブロードキャストするための「グループ」という概念があります。ユーザー空間のアプリケーションは、関心のあるグループを購読することで、そのグループに属するカーネルイベント通知を受け取ることができます。

RTNLGRP_で始まる定数は、主にルーティングNetlink (RTNETLINK) ソケットに関連するグループ識別子です。RTNETLINKは、ネットワークインターフェース、IPアドレス、ルーティングテーブル、ネイバーキャッシュなどのネットワーク設定情報を管理するために使用されます。

以下は、このコミットで追加された主要なRTNLGRP_定数とその意味です。

  • RTNLGRP_NONE: どのグループにも属さないことを示す。
  • RTNLGRP_LINK: ネットワークインターフェースの状態変更(UP/DOWN、MTU変更など)に関するイベント。
  • RTNLGRP_NOTIFY: 一般的な通知。
  • RTNLGRP_NEIGH: ネイバーキャッシュ(ARP/NDPエントリ)の変更に関するイベント。
  • RTNLGRP_TC: トラフィック制御(Traffic Control)に関するイベント。
  • RTNLGRP_IPV4_IFADDR: IPv4アドレスの追加/削除に関するイベント。
  • RTNLGRP_IPV4_MROUTE: IPv4マルチキャストルーティングに関するイベント。
  • RTNLGRP_IPV4_ROUTE: IPv4ルーティングテーブルの変更に関するイベント。
  • RTNLGRP_IPV4_RULE: IPv4ルーティングルールの変更に関するイベント。
  • RTNLGRP_IPV6_IFADDR: IPv6アドレスの追加/削除に関するイベント。
  • RTNLGRP_IPV6_MROUTE: IPv6マルチキャストルーティングに関するイベント。
  • RTNLGRP_IPV6_ROUTE: IPv6ルーティングテーブルの変更に関するイベント。
  • RTNLGRP_IPV6_IFINFO: IPv6インターフェース情報に関するイベント。
  • RTNLGRP_IPV6_PREFIX: IPv6プレフィックスに関するイベント。
  • RTNLGRP_IPV6_RULE: IPv6ルーティングルールの変更に関するイベント。
  • RTNLGRP_ND_USEROPT: Neighbor Discovery (ND) ユーザーオプションに関するイベント。

これらの定数を使用することで、Goプログラムは特定のネットワークイベントのみを効率的に監視し、不要な通知をフィルタリングすることができます。

Go言語のsyscallパッケージ

Go言語のsyscallパッケージは、オペレーティングシステムが提供する低レベルのプリミティブ(システムコール)へのアクセスを提供します。これにより、Goプログラムはファイルシステム、ネットワーク、プロセス管理など、OSのコア機能と直接対話できます。このパッケージは、OS固有の定数、構造体、関数を定義しており、クロスプラットフォームの抽象化ではなく、各OSのネイティブなインターフェースをGoから利用できるように設計されています。

このコミットでは、Linux固有のNetlink定数をsyscallパッケージに追加することで、GoプログラムがLinuxのネットワークスタックとより密接に連携できるようになります。

技術的詳細

このコミットの主要な変更は、src/pkg/syscall/types_linux.goおよび各アーキテクチャ(386, amd64, arm)ごとのztypes_linux_*.goファイルに、Linux Netlinkの定数を追加したことです。

types_linux.goでは、C言語のヘッダーファイルで定義されている定数をGoの定数としてマッピングしています。例えば、IFA_UNSPEC = C.IFA_UNSPECのように、Cパッケージを介してC言語の定数を参照しています。これは、GoのcgoツールがC言語のヘッダーファイルを解析し、対応するGoの定数や型を生成する仕組みを利用しています。

一方、ztypes_linux_*.goファイルは、go generateコマンドによって自動生成されるファイルであり、各アーキテクチャにおけるこれらの定数の具体的な数値(16進数)がハードコードされています。例えば、IFA_UNSPEC = 0x0のように定義されています。これは、クロスコンパイルや、Cヘッダーファイルへの依存なしに定数を利用できるようにするために重要です。

このコミットでは、既存のIFA_, IFLA_, RT_SCOPE_, RT_TABLE_, RTA_, RTN_といったNetlink関連の定数に加えて、新たにRTNLGRP_で始まるNetlinkグループ関連の定数が多数追加されています。これらの定数は、Netlinkソケットを介して特定のイベントグループを購読する際に使用されます。

具体的には、RTNLGRP_NONEからRTNLGRP_ND_USEROPTまでの定数が追加されており、それぞれが異なる種類のネットワークイベント通知に対応しています。これにより、GoプログラムはNetlinkソケットのsetsockopt関数などを用いて、必要なイベントグループを明示的に指定し、カーネルからの関連する通知のみを受け取ることが可能になります。

また、既存の定数定義において、一部の定数名がより明確になるように修正されている箇所も見られます(例: IFA_UNSPECのインデント調整など)。これは、コードの可読性と一貫性を向上させるための軽微な変更です。

コアとなるコードの変更箇所

このコミットで変更された主要なファイルは以下の通りです。

  • src/pkg/syscall/types_linux.go
  • src/pkg/syscall/ztypes_linux_386.go
  • src/pkg/syscall/ztypes_linux_amd64.go
  • src/pkg/syscall/ztypes_linux_arm.go

これらのファイルにおいて、Netlink関連の定数定義が追加・修正されています。特に、RTNLGRP_で始まる新しい定数が追加された点が重要です。

src/pkg/syscall/types_linux.go の変更点:

--- a/src/pkg/syscall/types_linux.go
+++ b/src/pkg/syscall/types_linux.go
@@ -219,81 +219,97 @@ const (
 // Netlink routing and interface messages
 
 const (
-	IFA_UNSPEC        = C.IFA_UNSPEC
-	IFA_ADDRESS       = C.IFA_ADDRESS
-	IFA_LOCAL         = C.IFA_LOCAL
-	IFA_LABEL         = C.IFA_LABEL
-	IFA_BROADCAST     = C.IFA_BROADCAST
-	IFA_ANYCAST       = C.IFA_ANYCAST
-	IFA_CACHEINFO     = C.IFA_CACHEINFO
-	IFA_MULTICAST     = C.IFA_MULTICAST
-	IFLA_UNSPEC       = C.IFLA_UNSPEC
-	IFLA_ADDRESS      = C.IFLA_ADDRESS
-	IFLA_BROADCAST    = C.IFLA_BROADCAST
-	IFLA_IFNAME       = C.IFLA_IFNAME
-	IFLA_MTU          = C.IFLA_MTU
-	IFLA_LINK         = C.IFLA_LINK
-	IFLA_QDISC        = C.IFLA_QDISC
-	IFLA_STATS        = C.IFLA_STATS
-	IFLA_COST         = C.IFLA_COST
-	IFLA_PRIORITY     = C.IFLA_PRIORITY
-	IFLA_MASTER       = C.IFLA_MASTER
-	IFLA_WIRELESS     = C.IFLA_WIRELESS
-	IFLA_PROTINFO     = C.IFLA_PROTINFO
-	IFLA_TXQLEN       = C.IFLA_TXQLEN
-	IFLA_MAP          = C.IFLA_MAP
-	IFLA_WEIGHT       = C.IFLA_WEIGHT
-	IFLA_OPERSTATE    = C.IFLA_OPERSTATE
-	IFLA_LINKMODE     = C.IFLA_LINKMODE
-	IFLA_LINKINFO     = C.IFLA_LINKINFO
-	IFLA_NET_NS_PID   = C.IFLA_NET_NS_PID
-	IFLA_IFALIAS      = C.IFLA_IFALIAS
-	IFLA_MAX          = C.IFLA_MAX
-	RT_SCOPE_UNIVERSE = C.RT_SCOPE_UNIVERSE
-	RT_SCOPE_SITE     = C.RT_SCOPE_SITE
-	RT_SCOPE_LINK     = C.RT_SCOPE_LINK
-	RT_SCOPE_HOST     = C.RT_SCOPE_HOST
-	RT_SCOPE_NOWHERE  = C.RT_SCOPE_NOWHERE
-	RT_TABLE_UNSPEC   = C.RT_TABLE_UNSPEC
-	RT_TABLE_COMPAT   = C.RT_TABLE_COMPAT
-	RT_TABLE_DEFAULT  = C.RT_TABLE_DEFAULT
-	RT_TABLE_MAIN     = C.RT_TABLE_MAIN
-	RT_TABLE_LOCAL    = C.RT_TABLE_LOCAL
-	RT_TABLE_MAX      = C.RT_TABLE_MAX
-	RTA_UNSPEC        = C.RTA_UNSPEC
-	RTA_DST           = C.RTA_DST
-	RTA_SRC           = C.RTA_SRC
-	RTA_IIF           = C.RTA_IIF
-	RTA_OIF           = C.RTA_OIF
-	RTA_GATEWAY       = C.RTA_GATEWAY
-	RTA_PRIORITY      = C.RTA_PRIORITY
-	RTA_PREFSRC       = C.RTA_PREFSRC
-	RTA_METRICS       = C.RTA_METRICS
-	RTA_MULTIPATH     = C.RTA_MULTIPATH
-	RTA_FLOW          = C.RTA_FLOW
-	RTA_CACHEINFO     = C.RTA_CACHEINFO
-	RTA_TABLE         = C.RTA_TABLE
-	RTN_UNSPEC        = C.RTN_UNSPEC
-	RTN_UNICAST       = C.RTN_UNICAST
-	RTN_LOCAL         = C.RTN_LOCAL
-	RTN_BROADCAST     = C.RTN_BROADCAST
-	RTN_ANYCAST       = C.RTN_ANYCAST
-	RTN_MULTICAST     = C.RTN_MULTICAST
-	RTN_BLACKHOLE     = C.RTN_BLACKHOLE
-	RTN_UNREACHABLE   = C.RTN_UNREACHABLE
-	RTN_PROHIBIT      = C.RTN_PROHIBIT
-	RTN_THROW         = C.RTN_THROW
-	RTN_NAT           = C.RTN_NAT
-	RTN_XRESOLVE      = C.RTN_XRESOLVE
-	SizeofNlMsghdr    = C.sizeof_struct_nlmsghdr
-	SizeofNlMsgerr    = C.sizeof_struct_nlmsgerr
-	SizeofRtGenmsg    = C.sizeof_struct_rtgenmsg
-	SizeofNlAttr      = C.sizeof_struct_nlattr
-	SizeofRtAttr      = C.sizeof_struct_rtattr
-	SizeofIfInfomsg   = C.sizeof_struct_ifinfomsg
-	SizeofIfAddrmsg   = C.sizeof_struct_ifaddrmsg
-	SizeofRtMsg       = C.sizeof_struct_rtmsg
-	SizeofRtNexthop   = C.sizeof_struct_rtnexthop
+	IFA_UNSPEC          = C.IFA_UNSPEC
+	IFA_ADDRESS         = C.IFA_ADDRESS
+	IFA_LOCAL           = C.IFA_LOCAL
+	IFA_LABEL           = C.IFA_LABEL
+	IFA_BROADCAST       = C.IFA_BROADCAST
+	IFA_ANYCAST         = C.IFA_ANYCAST
+	IFA_CACHEINFO       = C.IFA_CACHEINFO
+	IFA_MULTICAST       = C.IFA_MULTICAST
+	IFLA_UNSPEC         = C.IFLA_UNSPEC
+	IFLA_ADDRESS        = C.IFLA_ADDRESS
+	IFLA_BROADCAST      = C.IFLA_BROADCAST
+	IFLA_IFNAME         = C.IFLA_IFNAME
+	IFLA_MTU            = C.IFLA_MTU
+	IFLA_LINK           = C.IFLA_LINK
+	IFLA_QDISC          = C.IFLA_QDISC
+	IFLA_STATS          = C.IFLA_STATS
+	IFLA_COST           = C.IFLA_COST
+	IFLA_PRIORITY       = C.IFLA_PRIORITY
+	IFLA_MASTER         = C.IFLA_MASTER
+	IFLA_WIRELESS       = C.IFLA_WIRELESS
+	IFLA_PROTINFO       = C.IFLA_PROTINFO
+	IFLA_TXQLEN         = C.IFLA_TXQLEN
+	IFLA_MAP            = C.IFA_MAP
+	IFLA_WEIGHT         = C.IFLA_WEIGHT
+	IFLA_OPERSTATE      = C.IFLA_OPERSTATE
+	IFLA_LINKMODE       = C.IFLA_LINKMODE
+	IFLA_LINKINFO       = C.IFLA_LINKINFO
+	IFLA_NET_NS_PID     = C.IFLA_NET_NS_PID
+	IFLA_IFALIAS        = C.IFLA_IFALIAS
+	IFLA_MAX            = C.IFLA_MAX
+	RT_SCOPE_UNIVERSE   = C.RT_SCOPE_UNIVERSE
+	RT_SCOPE_SITE       = C.RT_SCOPE_SITE
+	RT_SCOPE_LINK       = C.RT_SCOPE_LINK
+	RT_SCOPE_HOST       = C.RT_SCOPE_HOST
+	RT_SCOPE_NOWHERE    = C.RT_SCOPE_NOWHERE
+	RT_TABLE_UNSPEC     = C.RT_TABLE_UNSPEC
+	RT_TABLE_COMPAT     = C.RT_TABLE_COMPAT
+	RT_TABLE_DEFAULT    = C.RT_TABLE_DEFAULT
+	RT_TABLE_MAIN       = C.RT_TABLE_MAIN
+	RT_TABLE_LOCAL      = C.RT_TABLE_LOCAL
+	RT_TABLE_MAX        = C.RT_TABLE_MAX
+	RTA_UNSPEC          = C.RTA_UNSPEC
+	RTA_DST             = C.RTA_DST
+	RTA_SRC             = C.RTA_SRC
+	RTA_IIF             = C.RTA_IIF
+	RTA_OIF             = C.RTA_OIF
+	RTA_GATEWAY         = C.RTA_GATEWAY
+	RTA_PRIORITY        = C.RTA_PRIORITY
+	RTA_PREFSRC         = C.RTA_PREFSRC
+	RTA_METRICS         = C.RTA_METRICS
+	RTA_MULTIPATH       = C.RTA_MULTIPATH
+	RTA_FLOW            = C.RTA_FLOW
+	RTA_CACHEINFO       = C.RTA_CACHEINFO
+	RTA_TABLE           = C.RTA_TABLE
+	RTN_UNSPEC          = C.RTN_UNSPEC
+	RTN_UNICAST         = C.RTN_UNICAST
+	RTN_LOCAL           = C.RTN_LOCAL
+	RTN_BROADCAST       = C.RTN_BROADCAST
+	RTN_ANYCAST         = C.RTN_ANYCAST
+	RTN_MULTICAST       = C.RTN_MULTICAST
+	RTN_BLACKHOLE       = C.RTN_BLACKHOLE
+	RTN_UNREACHABLE     = C.RTN_UNREACHABLE
+	RTN_PROHIBIT        = C.RTN_PROHIBIT
+	RTN_THROW           = C.RTN_THROW
+	RTN_NAT             = C.RTN_NAT
+	RTN_XRESOLVE        = C.RTN_XRESOLVE
+	RTNLGRP_NONE        = C.RTNLGRP_NONE
+	RTNLGRP_LINK        = C.RTNLGRP_LINK
+	RTNLGRP_NOTIFY      = C.RTNLGRP_NOTIFY
+	RTNLGRP_NEIGH       = C.RTNLGRP_NEIGH
+	RTNLGRP_TC          = C.RTNLGRP_TC
+	RTNLGRP_IPV4_IFADDR = C.RTNLGRP_IPV4_IFADDR
+	RTNLGRP_IPV4_MROUTE = C.RTNLGRP_IPV4_MROUTE
+	RTNLGRP_IPV4_ROUTE  = C.RTNLGRP_IPV4_ROUTE
+	RTNLGRP_IPV4_RULE   = C.RTNLGRP_IPV4_RULE
+	RTNLGRP_IPV6_IFADDR = C.RTNLGRP_IPV6_IFADDR
+	RTNLGRP_IPV6_MROUTE = C.RTNLGRP_IPV6_MROUTE
+	RTNLGRP_IPV6_ROUTE  = C.RTNLGRP_IPV6_ROUTE
+	RTNLGRP_IPV6_IFINFO = C.RTNLGRP_IPV6_IFINFO
+	RTNLGRP_IPV6_PREFIX = C.RTNLGRP_IPV6_PREFIX
+	RTNLGRP_IPV6_RULE   = C.RTNLGRP_IPV6_RULE
+	RTNLGRP_ND_USEROPT  = C.RTNLGRP_ND_USEROPT
+	SizeofNlMsghdr      = C.sizeof_struct_nlmsghdr
+	SizeofNlMsgerr      = C.sizeof_struct_nlmsgerr
+	SizeofRtGenmsg      = C.sizeof_struct_rtgenmsg
+	SizeofNlAttr        = C.sizeof_struct_nlattr
+	SizeofRtAttr        = C.sizeof_struct_rtattr
+	SizeofIfInfomsg     = C.sizeof_struct_ifinfomsg
+	SizeofIfAddrmsg     = C.sizeof_struct_ifaddrmsg
+	SizeofRtMsg         = C.sizeof_struct_rtmsg
+	SizeofRtNexthop     = C.sizeof_struct_rtnexthop
 )

src/pkg/syscall/ztypes_linux_386.go, src/pkg/syscall/ztypes_linux_amd64.go, src/pkg/syscall/ztypes_linux_arm.go の変更点:

これらのファイルでは、types_linux.goで追加されたRTNLGRP_定数に対応する16進数値が追加されています。例えば、ztypes_linux_386.goでは以下のような行が追加されています。

--- a/src/pkg/syscall/ztypes_linux_386.go
+++ b/src/pkg/syscall/ztypes_linux_386.go
@@ -305,81 +305,97 @@ const (
 )
 
 const (
-	IFA_UNSPEC        = 0x0
-	IFA_ADDRESS       = 0x1
-	IFA_LOCAL         = 0x2
-	IFA_LABEL         = 0x3
-	IFA_BROADCAST     = 0x4
-	IFA_ANYCAST       = 0x5
-	IFA_CACHEINFO     = 0x6
-	IFA_MULTICAST     = 0x7
-	IFLA_UNSPEC       = 0x0
-	IFLA_ADDRESS      = 0x1
-	IFLA_BROADCAST    = 0x2
-	IFLA_IFNAME       = 0x3
-	IFLA_MTU          = 0x4
-	IFLA_LINK         = 0x5
-	IFLA_QDISC        = 0x6
-	IFLA_STATS        = 0x7
-	IFLA_COST         = 0x8
-	IFLA_PRIORITY     = 0x9
-	IFLA_MASTER       = 0xa
-	IFLA_WIRELESS     = 0xb
-	IFLA_PROTINFO     = 0xc
-	IFLA_TXQLEN       = 0xd
-	IFLA_MAP          = 0xe
-	IFLA_WEIGHT       = 0xf
-	IFLA_OPERSTATE    = 0x10
-	IFLA_LINKMODE     = 0x11
-	IFLA_LINKINFO     = 0x12
-	IFLA_NET_NS_PID   = 0x13
-	IFLA_IFALIAS      = 0x14
-	IFLA_MAX          = 0x1d
-	RT_SCOPE_UNIVERSE = 0x0
-	RT_SCOPE_SITE     = 0xc8
-	RT_SCOPE_LINK     = 0xfd
-	RT_SCOPE_HOST     = 0xfe
-	RT_SCOPE_NOWHERE  = 0xff
-	RT_TABLE_UNSPEC   = 0x0
-	RT_TABLE_COMPAT   = 0xfc
-	RT_TABLE_DEFAULT  = 0xfd
-	RT_TABLE_MAIN     = 0xfe
-	RT_TABLE_LOCAL    = 0xff
-	RT_TABLE_MAX      = 0xffffffff
-	RTA_UNSPEC        = 0x0
-	RTA_DST           = 0x1
-	RTA_SRC           = 0x2
-	RTA_IIF           = 0x3
-	RTA_OIF           = 0x4
-	RTA_GATEWAY       = 0x5
-	RTA_PRIORITY      = 0x6
-	RTA_PREFSRC       = 0x7
-	RTA_METRICS       = 0x8
-	RTA_MULTIPATH     = 0x9
-	RTA_FLOW          = 0xb
-	RTA_CACHEINFO     = 0xc
-	RTA_TABLE         = 0xf
-	RTN_UNSPEC        = 0x0
-	RTN_UNICAST       = 0x1
-	RTN_LOCAL         = 0x2
-	RTN_BROADCAST     = 0x3
-	RTN_ANYCAST       = 0x4
-	RTN_MULTICAST     = 0x5
-	RTN_BLACKHOLE     = 0x6
-	RTN_UNREACHABLE   = 0x7
-	RTN_PROHIBIT      = 0x8
-	RTN_THROW         = 0x9
-	RTN_NAT           = 0xa
-	RTN_XRESOLVE      = 0xb
-	SizeofNlMsghdr    = 0x10
-	SizeofNlMsgerr    = 0x14
-	SizeofRtGenmsg    = 0x1
-	SizeofNlAttr      = 0x4
-	SizeofRtAttr      = 0x4
-	SizeofIfInfomsg   = 0x10
-	SizeofIfAddrmsg   = 0x8
-	SizeofRtMsg       = 0xc
-	SizeofRtNexthop   = 0x8
+	IFA_UNSPEC          = 0x0
+	IFA_ADDRESS         = 0x1
+	IFA_LOCAL           = 0x2
+	IFA_LABEL           = 0x3
+	IFA_BROADCAST       = 0x4
+	IFA_ANYCAST         = 0x5
+	IFA_CACHEINFO       = 0x6
+	IFA_MULTICAST       = 0x7
+	IFLA_UNSPEC         = 0x0
+	IFLA_ADDRESS        = 0x1
+	IFLA_BROADCAST      = 0x2
+	IFLA_IFNAME         = 0x3
+	IFLA_MTU            = 0x4
+	IFLA_LINK           = 0x5
+	IFLA_QDISC          = 0x6
+	IFLA_STATS          = 0x7
+	IFLA_COST           = 0x8
+	IFLA_PRIORITY       = 0x9
+	IFLA_MASTER         = 0xa
+	IFLA_WIRELESS       = 0xb
+	IFLA_PROTINFO       = 0xc
+	IFLA_TXQLEN         = 0xd
+	IFLA_MAP            = 0xe
+	IFLA_WEIGHT         = 0xf
+	IFLA_OPERSTATE      = 0x10
+	IFLA_LINKMODE       = 0x11
+	IFLA_LINKINFO       = 0x12
+	IFLA_NET_NS_PID     = 0x13
+	IFLA_IFALIAS        = 0x14
+	IFLA_MAX            = 0x1d
+	RT_SCOPE_UNIVERSE   = 0x0
+	RT_SCOPE_SITE       = 0xc8
+	RT_SCOPE_LINK       = 0xfd
+	RT_SCOPE_HOST       = 0xfe
+	RT_SCOPE_NOWHERE    = 0xff
+	RT_TABLE_UNSPEC     = 0x0
+	RT_TABLE_COMPAT     = 0xfc
+	RT_TABLE_DEFAULT    = 0xfd
+	RT_TABLE_MAIN       = 0xfe
+	RT_TABLE_LOCAL      = 0xff
+	RT_TABLE_MAX        = 0xffffffff
+	RTA_UNSPEC          = 0x0
+	RTA_DST             = 0x1
+	RTA_SRC             = 0x2
+	RTA_IIF             = 0x3
+	RTA_OIF             = 0x4
+	RTA_GATEWAY         = 0x5
+	RTA_PRIORITY        = 0x6
+	RTA_PREFSRC         = 0x7
+	RTA_METRICS         = 0x8
+	RTA_MULTIPATH       = 0x9
+	RTA_FLOW            = 0xb
+	RTA_CACHEINFO       = 0xc
+	RTA_TABLE           = 0xf
+	RTN_UNSPEC          = 0x0
+	RTN_UNICAST         = 0x1
+	RTN_LOCAL           = 0x2
+	RTN_BROADCAST       = 0x3
+	RTN_ANYCAST         = 0x4
+	RTN_MULTICAST       = 0x5
+	RTN_BLACKHOLE       = 0x6
+	RTN_UNREACHABLE     = 0x7
+	RTN_PROHIBIT        = 0x8
+	RTN_THROW           = 0x9
+	RTN_NAT             = 0xa
+	RTN_XRESOLVE        = 0xb
+	RTNLGRP_NONE        = 0x0
+	RTNLGRP_LINK        = 0x1
+	RTNLGRP_NOTIFY      = 0x2
+	RTNLGRP_NEIGH       = 0x3
+	RTNLGRP_TC          = 0x4
+	RTNLGRP_IPV4_IFADDR = 0x5
+	RTNLGRP_IPV4_MROUTE = 0x6
+	RTNLGRP_IPV4_ROUTE  = 0x7
+	RTNLGRP_IPV4_RULE   = 0x8
+	RTNLGRP_IPV6_IFADDR = 0x9
+	RTNLGRP_IPV6_MROUTE = 0xa
+	RTNLGRP_IPV6_ROUTE  = 0xb
+	RTNLGRP_IPV6_IFINFO = 0xc
+	RTNLGRP_IPV6_PREFIX = 0x12
+	RTNLGRP_IPV6_RULE   = 0x13
+	RTNLGRP_ND_USEROPT  = 0x14
+	SizeofNlMsghdr      = 0x10
+	SizeofNlMsgerr      = 0x14
+	SizeofRtGenmsg      = 0x1
+	SizeofNlAttr        = 0x4
+	SizeofRtAttr        = 0x4
+	SizeofIfInfomsg     = 0x10
+	SizeofIfAddrmsg     = 0x8
+	SizeofRtMsg         = 0xc
+	SizeofRtNexthop     = 0x8
 )

コアとなるコードの解説

このコミットの核心は、Go言語のsyscallパッケージがLinuxカーネルのNetlinkインターフェースとより完全に連携できるようにすることです。

types_linux.goでは、C言語のヘッダーファイルからインポートされる定数をGoの定数として公開しています。これは、GoプログラムがC言語のライブラリやカーネルインターフェースと相互運用するための標準的なアプローチです。C.IFA_UNSPECのような表記は、cgoによって生成されたC言語の定数へのバインディングを示しています。

ztypes_linux_*.goファイル群は、特定のアーキテクチャ(386, amd64, arm)向けに、これらのNetlink定数の具体的な数値表現を提供します。これらのファイルは通常、go generateコマンドと、カーネルのヘッダーファイルを解析するツール(例: mkall.shスクリプトなど)によって自動生成されます。これにより、Goのコンパイラは、C言語のヘッダーファイルが利用できない環境でも、これらの定数の正しい値を知ることができます。

追加されたRTNLGRP_定数は、Netlinkソケットのsetsockoptシステムコールで使用されるビットマスクとして機能します。GoプログラムがNetlinkソケットを作成した後、syscall.SetsockoptInt(fd, syscall.SOL_NETLINK, syscall.NETLINK_ADD_MEMBERSHIP, syscall.RTNLGRP_LINK | syscall.RTNLGRP_IPV4_IFADDR)のように呼び出すことで、リンク状態の変更とIPv4アドレスの変更に関するイベント通知を購読できます。これにより、Goで書かれたネットワーク監視ツールやデーモンが、カーネルからのリアルタイムなネットワークイベントを効率的に処理できるようになります。

この変更により、Go言語のネットワークプログラミング能力が向上し、Linuxシステムにおけるより高度なネットワーク管理機能へのアクセスが容易になります。

関連リンク

参考にした情報源リンク

I am now outputting the generated explanation to standard output as requested.

# [インデックス 15390] ファイルの概要

## コミット

commit e82286075674df84b9435445d48c5b8a4eeeeaa2 Author: Mikio Hara mikioh.mikioh@gmail.com Date: Sat Feb 23 08:42:04 2013 +0900

syscall: add netlink constants for linux

R=golang-dev, r
CC=golang-dev
https://golang.org/cl/7403049

## GitHub上でのコミットページへのリンク

[https://github.com/golang/go/commit/e82286075674df84b9435445d48c5b8a4eeeeaa2](https://github.com/golang/go/commit/e82286075674df84b9435445d48c5b8a4eeeeaa2)

## 元コミット内容
`syscall: add netlink constants for linux`

このコミットは、LinuxシステムコールパッケージにNetlink関連の定数を追加するものです。

## 変更の背景

このコミットの背景には、Go言語の`syscall`パッケージがLinuxカーネルとのより深い連携を可能にする必要があったことが挙げられます。NetlinkはLinuxカーネルとユーザー空間のプロセス間で情報をやり取りするためのソケットベースのメカニズムであり、ネットワーク設定、ルーティング、ファイアウォールなどの管理に不可欠です。

以前の`syscall`パッケージでは、Netlinkプログラミングに必要な一部の定数が不足していた可能性があります。特に、`RTNLGRP_`で始まる定数は、Netlinkのルーティングソケットを介して特定のイベントグループを購読するために使用されます。これらの定数がGo言語の`syscall`パッケージに存在しない場合、GoプログラムからLinuxの高度なネットワーク機能を直接操作することが困難になります。

このコミットは、GoプログラムがNetlinkを介してネットワークインターフェースの状態変更、ルーティングテーブルの更新、ネイバーキャッシュの変更など、様々なカーネルイベントを監視・制御できるようにするために、これらの重要な定数を追加することを目的としています。これにより、Go言語で書かれたネットワークツールやデーモンが、より低レベルで効率的なカーネルとの対話を実現できるようになります。

## 前提知識の解説

### Netlink

Netlinkは、Linuxカーネルとユーザー空間のプロセス間で通信を行うためのソケットファミリーです。従来の`ioctl`ベースのシステムコールに代わる、より柔軟で拡張性の高いメカニズムとして設計されました。Netlinkは、ネットワーク設定、ルーティング、ファイアウォール、プロセス間通信など、多岐にわたるカーネル機能へのアクセスを提供します。

Netlink通信は、標準的なソケットAPI(`socket()`, `bind()`, `sendmsg()`, `recvmsg()`など)を使用して行われます。Netlinkメッセージは、`nlmsghdr`構造体で始まり、その後にペイロード(データ)が続きます。ペイロードには、`nlattr`(Netlink属性)と呼ばれるTLV(Type-Length-Value)形式のデータ構造が含まれることが一般的です。

### Netlinkグループ (RTNLGRP_)

Netlinkには、特定の種類のイベントをブロードキャストするための「グループ」という概念があります。ユーザー空間のアプリケーションは、関心のあるグループを購読することで、そのグループに属するカーネルイベント通知を受け取ることができます。

`RTNLGRP_`で始まる定数は、主にルーティングNetlink (RTNETLINK) ソケットに関連するグループ識別子です。RTNETLINKは、ネットワークインターフェース、IPアドレス、ルーティングテーブル、ネイバーキャッシュなどのネットワーク設定情報を管理するために使用されます。

以下は、このコミットで追加された主要な`RTNLGRP_`定数とその意味です。

*   **`RTNLGRP_NONE`**: どのグループにも属さないことを示す。
*   **`RTNLGRP_LINK`**: ネットワークインターフェースの状態変更(UP/DOWN、MTU変更など)に関するイベント。
*   **`RTNLGRP_NOTIFY`**: 一般的な通知。
*   **`RTNLGRP_NEIGH`**: ネイバーキャッシュ(ARP/NDPエントリ)の変更に関するイベント。
*   **`RTNLGRP_TC`**: トラフィック制御(Traffic Control)に関するイベント。
*   **`RTNLGRP_IPV4_IFADDR`**: IPv4アドレスの追加/削除に関するイベント。
*   **`RTNLGRP_IPV4_MROUTE`**: IPv4マルチキャストルーティングに関するイベント。
*   **`RTNLGRP_IPV4_ROUTE`**: IPv4ルーティングテーブルの変更に関するイベント。
*   **`RTNLGRP_IPV4_RULE`**: IPv4ルーティングルールの変更に関するイベント。
*   **`RTNLGRP_IPV6_IFADDR`**: IPv6アドレスの追加/削除に関するイベント。
*   **`RTNLGRP_IPV6_MROUTE`**: IPv6マルチキャストルーティングに関するイベント。
*   **`RTNLGRP_IPV6_ROUTE`**: IPv6ルーティングテーブルの変更に関するイベント。
*   **`RTNLGRP_IPV6_IFINFO`**: IPv6インターフェース情報に関するイベント。
*   **`RTNLGRP_IPV6_PREFIX`**: IPv6プレフィックスに関するイベント。
*   **`RTNLGRP_IPV6_RULE`**: IPv6ルーティングルールの変更に関するイベント。
*   **`RTNLGRP_ND_USEROPT`**: Neighbor Discovery (ND) ユーザーオプションに関するイベント。

これらの定数を使用することで、Goプログラムは特定のネットワークイベントのみを効率的に監視し、不要な通知をフィルタリングすることができます。

### Go言語の`syscall`パッケージ

Go言語の`syscall`パッケージは、オペレーティングシステムが提供する低レベルのプリミティブ(システムコール)へのアクセスを提供します。これにより、Goプログラムはファイルシステム、ネットワーク、プロセス管理など、OSのコア機能と直接対話できます。このパッケージは、OS固有の定数、構造体、関数を定義しており、クロスプラットフォームの抽象化ではなく、各OSのネイティブなインターフェースをGoから利用できるように設計されています。

このコミットでは、Linux固有のNetlink定数を`syscall`パッケージに追加することで、GoプログラムがLinuxのネットワークスタックとより密接に連携できるようになります。

## 技術的詳細

このコミットの主要な変更は、`src/pkg/syscall/types_linux.go`および各アーキテクチャ(`386`, `amd64`, `arm`)ごとの`ztypes_linux_*.go`ファイルに、Linux Netlinkの定数を追加したことです。

`types_linux.go`では、C言語のヘッダーファイルで定義されている定数をGoの定数としてマッピングしています。例えば、`IFA_UNSPEC = C.IFA_UNSPEC`のように、`C`パッケージを介してC言語の定数を参照しています。これは、Goの`cgo`ツールがC言語のヘッダーファイルを解析し、対応するGoの定数や型を生成する仕組みを利用しています。

一方、`ztypes_linux_*.go`ファイルは、`go generate`コマンドによって自動生成されるファイルであり、各アーキテクチャにおけるこれらの定数の具体的な数値(16進数)がハードコードされています。例えば、`IFA_UNSPEC = 0x0`のように定義されています。これは、クロスコンパイルや、Cヘッダーファイルへの依存なしに定数を利用できるようにするために重要です。

このコミットでは、既存の`IFA_`, `IFLA_`, `RT_SCOPE_`, `RT_TABLE_`, `RTA_`, `RTN_`といったNetlink関連の定数に加えて、新たに`RTNLGRP_`で始まるNetlinkグループ関連の定数が多数追加されています。これらの定数は、Netlinkソケットを介して特定のイベントグループを購読する際に使用されます。

具体的には、`RTNLGRP_NONE`から`RTNLGRP_ND_USEROPT`までの定数が追加されており、それぞれが異なる種類のネットワークイベント通知に対応しています。これにより、GoプログラムはNetlinkソケットの`setsockopt`関数などを用いて、必要なイベントグループを明示的に指定し、カーネルからの関連する通知のみを受け取ることが可能です。

また、既存の定数定義において、一部の定数名がより明確になるように修正されている箇所も見られます(例: `IFA_UNSPEC`のインデント調整など)。これは、コードの可読性と一貫性を向上させるための軽微な変更です。

## コアとなるコードの変更箇所

このコミットで変更された主要なファイルは以下の通りです。

*   `src/pkg/syscall/types_linux.go`
*   `src/pkg/syscall/ztypes_linux_386.go`
*   `src/pkg/syscall/ztypes_linux_amd64.go`
*   `src/pkg/syscall/ztypes_linux_arm.go`

これらのファイルにおいて、Netlink関連の定数定義が追加・修正されています。特に、`RTNLGRP_`で始まる新しい定数が追加された点が重要です。

**`src/pkg/syscall/types_linux.go` の変更点:**

```diff
--- a/src/pkg/syscall/types_linux.go
+++ b/src/pkg/syscall/types_linux.go
@@ -219,81 +219,97 @@ const (
 // Netlink routing and interface messages
 
 const (
-	IFA_UNSPEC        = C.IFA_UNSPEC
-	IFA_ADDRESS       = C.IFA_ADDRESS
-	IFA_LOCAL         = C.IFA_LOCAL
-	IFA_LABEL         = C.IFA_LABEL
-	IFA_BROADCAST     = C.IFA_BROADCAST
-	IFA_ANYCAST       = C.IFA_ANYCAST
-	IFA_CACHEINFO     = C.IFA_CACHEINFO
-	IFA_MULTICAST     = C.IFA_MULTICAST
-	IFLA_UNSPEC       = C.IFLA_UNSPEC
-	IFLA_ADDRESS      = C.IFLA_ADDRESS
-	IFLA_BROADCAST    = C.IFLA_BROADCAST
-	IFLA_IFNAME       = C.IFLA_IFNAME
-	IFLA_MTU          = C.IFLA_MTU
-	IFLA_LINK         = C.IFLA_LINK
-	IFLA_QDISC        = C.IFLA_QDISC
-	IFLA_STATS        = C.IFLA_STATS
-	IFLA_COST         = C.IFLA_COST
-	IFLA_PRIORITY     = C.IFLA_PRIORITY
-	IFLA_MASTER       = C.IFLA_MASTER
-	IFLA_WIRELESS     = C.IFLA_WIRELESS
-	IFLA_PROTINFO     = C.IFLA_PROTINFO
-	IFLA_TXQLEN       = C.IFLA_TXQLEN
-	IFLA_MAP          = C.IFLA_MAP
-	IFLA_WEIGHT       = C.IFLA_WEIGHT
-	IFLA_OPERSTATE    = C.IFLA_OPERSTATE
-	IFLA_LINKMODE     = C.IFLA_LINKMODE
-	IFLA_LINKINFO     = C.IFLA_LINKINFO
-	IFLA_NET_NS_PID   = C.IFLA_NET_NS_PID
-	IFLA_IFALIAS      = C.IFLA_IFALIAS
-	IFLA_MAX          = C.IFLA_MAX
-	RT_SCOPE_UNIVERSE = C.RT_SCOPE_UNIVERSE
-	RT_SCOPE_SITE     = C.RT_SCOPE_SITE
-	RT_SCOPE_LINK     = C.RT_SCOPE_LINK
-	RT_SCOPE_HOST     = C.RT_SCOPE_HOST
-	RT_SCOPE_NOWHERE  = C.RT_SCOPE_NOWHERE
-	RT_TABLE_UNSPEC   = C.RT_TABLE_UNSPEC
-	RT_TABLE_COMPAT   = C.RT_TABLE_COMPAT
-	RT_TABLE_DEFAULT  = C.RT_TABLE_DEFAULT
-	RT_TABLE_MAIN     = C.RT_TABLE_MAIN
-	RT_TABLE_LOCAL    = C.RT_TABLE_LOCAL
-	RT_TABLE_MAX      = C.RT_TABLE_MAX
-	RTA_UNSPEC        = C.RTA_UNSPEC
-	RTA_DST           = C.RTA_DST
-	RTA_SRC           = C.RTA_SRC
-	RTA_IIF           = C.RTA_IIF
-	RTA_OIF           = C.RTA_OIF
-	RTA_GATEWAY       = C.RTA_GATEWAY
-	RTA_PRIORITY      = C.RTA_PRIORITY
-	RTA_PREFSRC       = C.RTA_PREFSRC
-	RTA_METRICS       = C.RTA_METRICS
-	RTA_MULTIPATH     = C.RTA_MULTIPATH
-	RTA_FLOW          = C.RTA_FLOW
-	RTA_CACHEINFO     = C.RTA_CACHEINFO
-	RTA_TABLE         = C.RTA_TABLE
-	RTN_UNSPEC        = C.RTN_UNSPEC
-	RTN_UNICAST       = C.RTN_UNICAST
-	RTN_LOCAL         = C.RTN_LOCAL
-	RTN_BROADCAST     = C.RTN_BROADCAST
-	RTN_ANYCAST       = C.RTN_ANYCAST
-	RTN_MULTICAST     = C.RTN_MULTICAST
-	RTN_BLACKHOLE     = C.RTN_BLACKHOLE
-	RTN_UNREACHABLE   = C.RTN_UNREACHABLE
-	RTN_PROHIBIT      = C.RTN_PROHIBIT
-	RTN_THROW         = C.RTN_THROW
-	RTN_NAT           = C.RTN_NAT
-	RTN_XRESOLVE      = C.RTN_XRESOLVE
-	SizeofNlMsghdr    = C.sizeof_struct_nlmsghdr
-	SizeofNlMsgerr    = C.sizeof_struct_nlmsgerr
-	SizeofRtGenmsg    = C.sizeof_struct_rtgenmsg
-	SizeofNlAttr      = C.sizeof_struct_nlattr
-	SizeofRtAttr      = C.sizeof_struct_rtattr
-	SizeofIfInfomsg   = C.sizeof_struct_ifinfomsg
-	SizeofIfAddrmsg   = C.sizeof_struct_ifaddrmsg
-	SizeofRtMsg       = C.sizeof_struct_rtmsg
-	SizeofRtNexthop   = C.sizeof_struct_rtnexthop
+	IFA_UNSPEC          = C.IFA_UNSPEC
+	IFA_ADDRESS         = C.IFA_ADDRESS
+	IFA_LOCAL           = C.IFA_LOCAL
+	IFA_LABEL           = C.IFA_LABEL
+	IFA_BROADCAST       = C.IFA_BROADCAST
+	IFA_ANYCAST         = C.IFA_ANYCAST
+	IFA_CACHEINFO       = C.IFA_CACHEINFO
+	IFA_MULTICAST       = C.IFA_MULTICAST
+	IFLA_UNSPEC         = C.IFLA_UNSPEC
+	IFLA_ADDRESS        = C.IFLA_ADDRESS
+	IFLA_BROADCAST      = C.IFLA_BROADCAST
+	IFLA_IFNAME         = C.IFLA_IFNAME
+	IFLA_MTU            = C.IFLA_MTU
+	IFLA_LINK           = C.IFLA_LINK
+	IFLA_QDISC          = C.IFLA_QDISC
+	IFLA_STATS          = C.IFLA_STATS
+	IFLA_COST           = C.IFLA_COST
+	IFLA_PRIORITY       = C.IFLA_PRIORITY
+	IFLA_MASTER         = C.IFLA_MASTER
+	IFLA_WIRELESS       = C.IFLA_WIRELESS
+	IFLA_PROTINFO       = C.IFLA_PROTINFO
+	IFLA_TXQLEN         = C.IFLA_TXQLEN
+	IFLA_MAP            = C.IFA_MAP
+	IFLA_WEIGHT         = C.IFLA_WEIGHT
+	IFLA_OPERSTATE      = C.IFLA_OPERSTATE
+	IFLA_LINKMODE       = C.IFLA_LINKMODE
+	IFLA_LINKINFO       = C.IFLA_LINKINFO
+	IFLA_NET_NS_PID     = C.IFLA_NET_NS_PID
+	IFLA_IFALIAS        = C.IFLA_IFALIAS
+	IFLA_MAX            = C.IFLA_MAX
+	RT_SCOPE_UNIVERSE   = C.RT_SCOPE_UNIVERSE
+	RT_SCOPE_SITE       = C.RT_SCOPE_SITE
+	RT_SCOPE_LINK       = C.RT_SCOPE_LINK
+	RT_SCOPE_HOST       = C.RT_SCOPE_HOST
+	RT_SCOPE_NOWHERE    = C.RT_SCOPE_NOWHERE
+	RT_TABLE_UNSPEC     = C.RT_TABLE_UNSPEC
+	RT_TABLE_COMPAT     = C.RT_TABLE_COMPAT
+	RT_TABLE_DEFAULT    = C.RT_TABLE_DEFAULT
+	RT_TABLE_MAIN       = C.RT_TABLE_MAIN
+	RT_TABLE_LOCAL      = C.RT_TABLE_LOCAL
+	RT_TABLE_MAX        = C.RT_TABLE_MAX
+	RTA_UNSPEC          = C.RTA_UNSPEC
+	RTA_DST             = C.RTA_DST
+	RTA_SRC             = C.RTA_SRC
+	RTA_IIF             = C.RTA_IIF
+	RTA_OIF             = C.RTA_OIF
+	RTA_GATEWAY         = C.RTA_GATEWAY
+	RTA_PRIORITY        = C.RTA_PRIORITY
+	RTA_PREFSRC         = C.RTA_PREFSRC
+	RTA_METRICS         = C.RTA_METRICS
+	RTA_MULTIPATH       = C.RTA_MULTIPATH
+	RTA_FLOW            = C.RTA_FLOW
+	RTA_CACHEINFO       = C.RTA_CACHEINFO
+	RTA_TABLE           = C.RTA_TABLE
+	RTN_UNSPEC          = C.RTN_UNSPEC
+	RTN_UNICAST         = C.RTN_UNICAST
+	RTN_LOCAL           = C.RTN_LOCAL
+	RTN_BROADCAST       = C.RTN_BROADCAST
+	RTN_ANYCAST         = C.RTN_ANYCAST
+	RTN_MULTICAST       = C.RTN_MULTICAST
+	RTN_BLACKHOLE       = C.RTN_BLACKHOLE
+	RTN_UNREACHABLE     = C.RTN_UNREACHABLE
+	RTN_PROHIBIT        = C.RTN_PROHIBIT
+	RTN_THROW           = C.RTN_THROW
+	RTN_NAT             = C.RTN_NAT
+	RTN_XRESOLVE        = C.RTN_XRESOLVE
+	RTNLGRP_NONE        = C.RTNLGRP_NONE
+	RTNLGRP_LINK        = C.RTNLGRP_LINK
+	RTNLGRP_NOTIFY      = C.RTNLGRP_NOTIFY
+	RTNLGRP_NEIGH       = C.RTNLGRP_NEIGH
+	RTNLGRP_TC          = C.RTNLGRP_TC
+	RTNLGRP_IPV4_IFADDR = C.RTNLGRP_IPV4_IFADDR
+	RTNLGRP_IPV4_MROUTE = C.RTNLGRP_IPV4_MROUTE
+	RTNLGRP_IPV4_ROUTE  = C.RTNLGRP_IPV4_ROUTE
+	RTNLGRP_IPV4_RULE   = C.RTNLGRP_IPV4_RULE
+	RTNLGRP_IPV6_IFADDR = C.RTNLGRP_IPV6_IFADDR
+	RTNLGRP_IPV6_MROUTE = C.RTNLGRP_IPV6_MROUTE
+	RTNLGRP_IPV6_ROUTE  = C.RTNLGRP_IPV6_ROUTE
+	RTNLGRP_IPV6_IFINFO = C.RTNLGRP_IPV6_IFINFO
+	RTNLGRP_IPV6_PREFIX = C.RTNLGRP_IPV6_PREFIX
+	RTNLGRP_IPV6_RULE   = C.RTNLGRP_IPV6_RULE
+	RTNLGRP_ND_USEROPT  = C.RTNLGRP_ND_USEROPT
+	SizeofNlMsghdr      = C.sizeof_struct_nlmsghdr
+	SizeofNlMsgerr      = C.sizeof_struct_nlmsgerr
+	SizeofRtGenmsg      = C.sizeof_struct_rtgenmsg
+	SizeofNlAttr        = C.sizeof_struct_nlattr
+	SizeofRtAttr        = C.sizeof_struct_rtattr
+	SizeofIfInfomsg     = C.sizeof_struct_ifinfomsg
+	SizeofIfAddrmsg     = C.sizeof_struct_ifaddrmsg
+	SizeofRtMsg         = C.sizeof_struct_rtmsg
+	SizeofRtNexthop     = C.sizeof_struct_rtnexthop
 )

src/pkg/syscall/ztypes_linux_386.go, src/pkg/syscall/ztypes_linux_amd64.go, src/pkg/syscall/ztypes_linux_arm.go の変更点:

これらのファイルでは、types_linux.goで追加されたRTNLGRP_定数に対応する16進数値が追加されています。例えば、ztypes_linux_386.goでは以下のような行が追加されています。

--- a/src/pkg/syscall/ztypes_linux_386.go
+++ b/src/pkg/syscall/ztypes_linux_386.go
@@ -305,81 +305,97 @@ const (
 )
 
 const (
-	IFA_UNSPEC        = 0x0
-	IFA_ADDRESS       = 0x1
-	IFA_LOCAL         = 0x2
-	IFA_LABEL         = 0x3
-	IFA_BROADCAST     = 0x4
-	IFA_ANYCAST       = 0x5
-	IFA_CACHEINFO     = 0x6
-	IFA_MULTICAST     = 0x7
-	IFLA_UNSPEC       = 0x0
-	IFLA_ADDRESS      = 0x1
-	IFLA_BROADCAST    = 0x2
-	IFLA_IFNAME       = 0x3
-	IFLA_MTU          = 0x4
-	IFLA_LINK         = 0x5
-	IFLA_QDISC        = 0x6
-	IFLA_STATS        = 0x7
-	IFLA_COST         = 0x8
-	IFLA_PRIORITY     = 0x9
-	IFLA_MASTER       = 0xa
-	IFLA_WIRELESS     = 0xb
-	IFLA_PROTINFO     = 0xc
-	IFLA_TXQLEN       = 0xd
-	IFLA_MAP          = 0xe
-	IFLA_WEIGHT       = 0xf
-	IFLA_OPERSTATE    = 0x10
-	IFLA_LINKMODE     = 0x11
-	IFLA_LINKINFO     = 0x12
-	IFLA_NET_NS_PID   = 0x13
-	IFLA_IFALIAS      = 0x14
-	IFLA_MAX          = 0x1d
-	RT_SCOPE_UNIVERSE = 0x0
-	RT_SCOPE_SITE     = 0xc8
-	RT_SCOPE_LINK     = 0xfd
-	RT_SCOPE_HOST     = 0xfe
-	RT_SCOPE_NOWHERE  = 0xff
-	RT_TABLE_UNSPEC   = 0x0
-	RT_TABLE_COMPAT   = 0xfc
-	RT_TABLE_DEFAULT  = 0xfd
-	RT_TABLE_MAIN     = 0xfe
-	RT_TABLE_LOCAL    = 0xff
-	RT_TABLE_MAX      = 0xffffffff
-	RTA_UNSPEC        = 0x0
-	RTA_DST           = 0x1
-	RTA_SRC           = 0x2
-	RTA_IIF           = 0x3
-	RTA_OIF           = 0x4
-	RTA_GATEWAY       = 0x5
-	RTA_PRIORITY      = 0x6
-	RTA_PREFSRC       = 0x7
-	RTA_METRICS       = 0x8
-	RTA_MULTIPATH     = 0x9
-	RTA_FLOW          = 0xb
-	RTA_CACHEINFO     = 0xc
-	RTA_TABLE         = 0xf
-	RTN_UNSPEC        = 0x0
-	RTN_UNICAST       = 0x1
-	RTN_LOCAL         = 0x2
-	RTN_BROADCAST     = 0x3
-	RTN_ANYCAST       = 0x4
-	RTN_MULTICAST     = 0x5
-	RTN_BLACKHOLE     = 0x6
-	RTN_UNREACHABLE   = 0x7
-	RTN_PROHIBIT      = 0x8
-	RTN_THROW         = 0x9
-	RTN_NAT           = 0xa
-	RTN_XRESOLVE      = 0xb
-	SizeofNlMsghdr    = 0x10
-	SizeofNlMsgerr    = 0x14
-	SizeofRtGenmsg    = 0x1
-	SizeofNlAttr      = 0x4
-	SizeofRtAttr      = 0x4
-	SizeofIfInfomsg   = 0x10
-	SizeofIfAddrmsg   = 0x8
-	SizeofRtMsg       = 0xc
-	SizeofRtNexthop   = 0x8
+	IFA_UNSPEC          = 0x0
+	IFA_ADDRESS         = 0x1
+	IFA_LOCAL           = 0x2
+	IFA_LABEL           = 0x3
+	IFA_BROADCAST       = 0x4
+	IFA_ANYCAST         = 0x5
+	IFA_CACHEINFO       = 0x6
+	IFA_MULTICAST       = 0x7
+	IFLA_UNSPEC         = 0x0
+	IFLA_ADDRESS        = 0x1
+	IFLA_BROADCAST      = 0x2
+	IFLA_IFNAME         = 0x3
+	IFLA_MTU            = 0x4
+	IFLA_LINK           = 0x5
+	IFLA_QDISC          = 0x6
+	IFLA_STATS          = 0x7
+	IFLA_COST           = 0x8
+	IFLA_PRIORITY       = 0x9
+	IFLA_MASTER         = 0xa
+	IFLA_WIRELESS       = 0xb
+	IFLA_PROTINFO       = 0xc
+	IFLA_TXQLEN         = 0xd
+	IFLA_MAP            = 0xe
+	IFLA_WEIGHT         = 0xf
+	IFLA_OPERSTATE      = 0x10
+	IFLA_LINKMODE       = 0x11
+	IFLA_LINKINFO       = 0x12
+	IFLA_NET_NS_PID     = 0x13
+	IFLA_IFALIAS        = 0x14
+	IFLA_MAX            = 0x1d
+	RT_SCOPE_UNIVERSE   = 0x0
+	RT_SCOPE_SITE       = 0xc8
+	RT_SCOPE_LINK       = 0xfd
+	RT_SCOPE_HOST       = 0xfe
+	RT_SCOPE_NOWHERE    = 0xff
+	RT_TABLE_UNSPEC     = 0x0
+	RT_TABLE_COMPAT     = 0xfc
+	RT_TABLE_DEFAULT    = 0xfd
+	RT_TABLE_MAIN       = 0xfe
+	RT_TABLE_LOCAL      = 0xff
+	RT_TABLE_MAX        = 0xffffffff
+	RTA_UNSPEC          = 0x0
+	RTA_DST             = 0x1
+	RTA_SRC             = 0x2
+	RTA_IIF             = 0x3
+	RTA_OIF             = 0x4
+	RTA_GATEWAY         = 0x5
+	RTA_PRIORITY        = 0x6
+	RTA_PREFSRC         = 0x7
+	RTA_METRICS         = 0x8
+	RTA_MULTIPATH       = 0x9
+	RTA_FLOW            = 0xb
+	RTA_CACHEINFO       = 0xc
+	RTA_TABLE           = 0xf
+	RTN_UNSPEC          = 0x0
+	RTN_UNICAST         = 0x1
+	RTN_LOCAL           = 0x2
+	RTN_BROADCAST       = 0x3
+	RTN_ANYCAST         = 0x4
+	RTN_MULTICAST       = 0x5
+	RTN_BLACKHOLE       = 0x6
+	RTN_UNREACHABLE     = 0x7
+	RTN_PROHIBIT        = 0x8
+	RTN_THROW           = 0x9
+	RTN_NAT             = 0xa
+	RTN_XRESOLVE        = 0xb
+	RTNLGRP_NONE        = 0x0
+	RTNLGRP_LINK        = 0x1
+	RTNLGRP_NOTIFY      = 0x2
+	RTNLGRP_NEIGH       = 0x3
+	RTNLGRP_TC          = 0x4
+	RTNLGRP_IPV4_IFADDR = 0x5
+	RTNLGRP_IPV4_MROUTE = 0x6
+	RTNLGRP_IPV4_ROUTE  = 0x7
+	RTNLGRP_IPV4_RULE   = 0x8
+	RTNLGRP_IPV6_IFADDR = 0x9
+	RTNLGRP_IPV6_MROUTE = 0xa
+	RTNLGRP_IPV6_ROUTE  = 0xb
+	RTNLGRP_IPV6_IFINFO = 0xc
+	RTNLGRP_IPV6_PREFIX = 0x12
+	RTNLGRP_IPV6_RULE   = 0x13
+	RTNLGRP_ND_USEROPT  = 0x14
+	SizeofNlMsghdr      = 0x10
+	SizeofNlMsgerr      = 0x14
+	SizeofRtGenmsg      = 0x1
+	SizeofNlAttr        = 0x4
+	SizeofRtAttr        = 0x4
+	SizeofIfInfomsg     = 0x10
+	SizeofIfAddrmsg     = 0x8
+	SizeofRtMsg         = 0xc
+	SizeofRtNexthop     = 0x8
 )

コアとなるコードの解説

このコミットの核心は、Go言語のsyscallパッケージがLinuxカーネルのNetlinkインターフェースとより完全に連携できるようにすることです。

types_linux.goでは、C言語のヘッダーファイルからインポートされる定数をGoの定数として公開しています。これは、GoプログラムがC言語のライブラリやカーネルインターフェースと相互運用するための標準的なアプローチです。C.IFA_UNSPECのような表記は、cgoによって生成されたC言語の定数へのバインディングを示しています。

ztypes_linux_*.goファイル群は、特定のアーキテクチャ(386, amd64, arm)向けに、これらのNetlink定数の具体的な数値表現を提供します。これらのファイルは通常、go generateコマンドと、カーネルのヘッダーファイルを解析するツール(例: mkall.shスクリプトなど)によって自動生成されます。これにより、Goのコンパイラは、C言語のヘッダーファイルが利用できない環境でも、これらの定数の正しい値を知ることができます。

追加されたRTNLGRP_定数は、Netlinkソケットのsetsockoptシステムコールで使用されるビットマスクとして機能します。GoプログラムがNetlinkソケットを作成した後、syscall.SetsockoptInt(fd, syscall.SOL_NETLINK, syscall.NETLINK_ADD_MEMBERSHIP, syscall.RTNLGRP_LINK | syscall.RTNLGRP_IPV4_IFADDR)のように呼び出すことで、リンク状態の変更とIPv4アドレスの変更に関するイベント通知を購読できます。これにより、Goで書かれたネットワーク監視ツールやデーモンが、カーネルからのリアルタイムなネットワークイベントを効率的に処理できるようになります。

この変更により、Go言語のネットワークプログラミング能力が向上し、Linuxシステムにおけるより高度なネットワーク管理機能へのアクセスが容易になります。

関連リンク

参考にした情報源リンク