Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
G
go
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
go
Commits
a0509d85
Commit
a0509d85
authored
Jan 14, 2013
by
Mikio Hara
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
syscall: simplify netlink sockets
R=dave, rsc CC=golang-dev
https://golang.org/cl/7039044
parent
406ca3c2
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
66 additions
and
104 deletions
+66
-104
src/pkg/syscall/netlink_linux.go
src/pkg/syscall/netlink_linux.go
+66
-104
No files found.
src/pkg/syscall/netlink_linux.go
View file @
a0509d85
...
@@ -6,9 +6,7 @@
...
@@ -6,9 +6,7 @@
package
syscall
package
syscall
import
(
import
"unsafe"
"unsafe"
)
// Round the length of a netlink message up to align it properly.
// Round the length of a netlink message up to align it properly.
func
nlmAlignOf
(
msglen
int
)
int
{
func
nlmAlignOf
(
msglen
int
)
int
{
...
@@ -21,8 +19,8 @@ func rtaAlignOf(attrlen int) int {
...
@@ -21,8 +19,8 @@ func rtaAlignOf(attrlen int) int {
return
(
attrlen
+
RTA_ALIGNTO
-
1
)
&
^
(
RTA_ALIGNTO
-
1
)
return
(
attrlen
+
RTA_ALIGNTO
-
1
)
&
^
(
RTA_ALIGNTO
-
1
)
}
}
// NetlinkRouteRequest represents
the request message to receive
// NetlinkRouteRequest represents
a request message to receive routing
//
routing
and link states from the kernel.
// and link states from the kernel.
type
NetlinkRouteRequest
struct
{
type
NetlinkRouteRequest
struct
{
Header
NlMsghdr
Header
NlMsghdr
Data
RtGenmsg
Data
RtGenmsg
...
@@ -49,167 +47,131 @@ func newNetlinkRouteRequest(proto, seq, family int) []byte {
...
@@ -49,167 +47,131 @@ func newNetlinkRouteRequest(proto, seq, family int) []byte {
return
rr
.
toWireFormat
()
return
rr
.
toWireFormat
()
}
}
// NetlinkRIB returns routing information base, as known as RIB,
// NetlinkRIB returns routing information base, as known as RIB, which
// which consists of network facility information, states and
// consists of network facility information, states and parameters.
// parameters.
func
NetlinkRIB
(
proto
,
family
int
)
([]
byte
,
error
)
{
func
NetlinkRIB
(
proto
,
family
int
)
([]
byte
,
error
)
{
var
(
s
,
err
:=
Socket
(
AF_NETLINK
,
SOCK_RAW
,
NETLINK_ROUTE
)
lsanl
SockaddrNetlink
if
err
!=
nil
{
tab
[]
byte
return
nil
,
err
)
s
,
e
:=
Socket
(
AF_NETLINK
,
SOCK_RAW
,
0
)
if
e
!=
nil
{
return
nil
,
e
}
}
defer
Close
(
s
)
defer
Close
(
s
)
lsa
:=
&
SockaddrNetlink
{
Family
:
AF_NETLINK
}
lsanl
.
Family
=
AF_NETLINK
if
err
:=
Bind
(
s
,
lsa
);
err
!=
nil
{
e
=
Bind
(
s
,
&
lsanl
)
return
nil
,
err
if
e
!=
nil
{
return
nil
,
e
}
}
wb
:=
newNetlinkRouteRequest
(
proto
,
1
,
family
)
seq
:=
1
if
err
:=
Sendto
(
s
,
wb
,
0
,
lsa
);
err
!=
nil
{
wb
:=
newNetlinkRouteRequest
(
proto
,
seq
,
family
)
return
nil
,
err
e
=
Sendto
(
s
,
wb
,
0
,
&
lsanl
)
if
e
!=
nil
{
return
nil
,
e
}
}
var
tab
[]
byte
done
:
for
{
for
{
var
(
rb
:=
make
([]
byte
,
Getpagesize
())
rb
[]
byte
nr
,
_
,
err
:=
Recvfrom
(
s
,
rb
,
0
)
nr
int
if
err
!=
nil
{
lsa
Sockaddr
return
nil
,
err
)
rb
=
make
([]
byte
,
Getpagesize
())
nr
,
_
,
e
=
Recvfrom
(
s
,
rb
,
0
)
if
e
!=
nil
{
return
nil
,
e
}
}
if
nr
<
NLMSG_HDRLEN
{
if
nr
<
NLMSG_HDRLEN
{
return
nil
,
EINVAL
return
nil
,
EINVAL
}
}
rb
=
rb
[
:
nr
]
rb
=
rb
[
:
nr
]
tab
=
append
(
tab
,
rb
...
)
tab
=
append
(
tab
,
rb
...
)
msgs
,
err
:=
ParseNetlinkMessage
(
rb
)
msgs
,
_
:=
ParseNetlinkMessage
(
rb
)
if
err
!=
nil
{
return
nil
,
err
}
for
_
,
m
:=
range
msgs
{
for
_
,
m
:=
range
msgs
{
if
lsa
,
e
=
Getsockname
(
s
);
e
!=
nil
{
lsa
,
err
:=
Getsockname
(
s
)
return
nil
,
e
if
err
!=
nil
{
return
nil
,
err
}
}
switch
v
:=
lsa
.
(
type
)
{
switch
v
:=
lsa
.
(
type
)
{
case
*
SockaddrNetlink
:
case
*
SockaddrNetlink
:
if
m
.
Header
.
Seq
!=
uint32
(
seq
)
||
m
.
Header
.
Pid
!=
v
.
Pid
{
if
m
.
Header
.
Seq
!=
1
||
m
.
Header
.
Pid
!=
v
.
Pid
{
return
nil
,
EINVAL
return
nil
,
EINVAL
}
}
default
:
default
:
return
nil
,
EINVAL
return
nil
,
EINVAL
}
}
if
m
.
Header
.
Type
==
NLMSG_DONE
{
if
m
.
Header
.
Type
==
NLMSG_DONE
{
goto
done
break
done
}
}
if
m
.
Header
.
Type
==
NLMSG_ERROR
{
if
m
.
Header
.
Type
==
NLMSG_ERROR
{
return
nil
,
EINVAL
return
nil
,
EINVAL
}
}
}
}
}
}
done
:
return
tab
,
nil
return
tab
,
nil
}
}
// NetlinkMessage represents
the
netlink message.
// NetlinkMessage represents
a
netlink message.
type
NetlinkMessage
struct
{
type
NetlinkMessage
struct
{
Header
NlMsghdr
Header
NlMsghdr
Data
[]
byte
Data
[]
byte
}
}
// ParseNetlinkMessage parses buf as netlink messages and returns
// ParseNetlinkMessage parses b as an array of netlink messages and
// the slice containing the NetlinkMessage structs.
// returns the slice containing the NetlinkMessage structures.
func
ParseNetlinkMessage
(
buf
[]
byte
)
([]
NetlinkMessage
,
error
)
{
func
ParseNetlinkMessage
(
b
[]
byte
)
([]
NetlinkMessage
,
error
)
{
var
(
var
msgs
[]
NetlinkMessage
h
*
NlMsghdr
for
len
(
b
)
>=
NLMSG_HDRLEN
{
dbuf
[]
byte
h
,
dbuf
,
dlen
,
err
:=
netlinkMessageHeaderAndData
(
b
)
dlen
int
if
err
!=
nil
{
e
error
return
nil
,
err
msgs
[]
NetlinkMessage
)
for
len
(
buf
)
>=
NLMSG_HDRLEN
{
h
,
dbuf
,
dlen
,
e
=
netlinkMessageHeaderAndData
(
buf
)
if
e
!=
nil
{
break
}
}
m
:=
NetlinkMessage
{}
m
:=
NetlinkMessage
{
Header
:
*
h
,
Data
:
dbuf
[
:
int
(
h
.
Len
)
-
NLMSG_HDRLEN
]}
m
.
Header
=
*
h
m
.
Data
=
dbuf
[
:
int
(
h
.
Len
)
-
NLMSG_HDRLEN
]
msgs
=
append
(
msgs
,
m
)
msgs
=
append
(
msgs
,
m
)
b
uf
=
buf
[
dlen
:
]
b
=
b
[
dlen
:
]
}
}
return
msgs
,
nil
return
msgs
,
e
}
}
func
netlinkMessageHeaderAndData
(
b
uf
[]
byte
)
(
*
NlMsghdr
,
[]
byte
,
int
,
error
)
{
func
netlinkMessageHeaderAndData
(
b
[]
byte
)
(
*
NlMsghdr
,
[]
byte
,
int
,
error
)
{
h
:=
(
*
NlMsghdr
)(
unsafe
.
Pointer
(
&
b
uf
[
0
]))
h
:=
(
*
NlMsghdr
)(
unsafe
.
Pointer
(
&
b
[
0
]))
if
int
(
h
.
Len
)
<
NLMSG_HDRLEN
||
int
(
h
.
Len
)
>
len
(
b
uf
)
{
if
int
(
h
.
Len
)
<
NLMSG_HDRLEN
||
int
(
h
.
Len
)
>
len
(
b
)
{
return
nil
,
nil
,
0
,
EINVAL
return
nil
,
nil
,
0
,
EINVAL
}
}
return
h
,
b
uf
[
NLMSG_HDRLEN
:
],
nlmAlignOf
(
int
(
h
.
Len
)),
nil
return
h
,
b
[
NLMSG_HDRLEN
:
],
nlmAlignOf
(
int
(
h
.
Len
)),
nil
}
}
// NetlinkRouteAttr represents
the
netlink route attribute.
// NetlinkRouteAttr represents
a
netlink route attribute.
type
NetlinkRouteAttr
struct
{
type
NetlinkRouteAttr
struct
{
Attr
RtAttr
Attr
RtAttr
Value
[]
byte
Value
[]
byte
}
}
// ParseNetlinkRouteAttr parses msg's payload as netlink route
// ParseNetlinkRouteAttr parses m's payload as an array of netlink
// attributes and returns the slice containing the NetlinkRouteAttr
// route attributes and returns the slice containing the
// structs.
// NetlinkRouteAttr structures.
func
ParseNetlinkRouteAttr
(
msg
*
NetlinkMessage
)
([]
NetlinkRouteAttr
,
error
)
{
func
ParseNetlinkRouteAttr
(
m
*
NetlinkMessage
)
([]
NetlinkRouteAttr
,
error
)
{
var
(
var
b
[]
byte
buf
[]
byte
switch
m
.
Header
.
Type
{
a
*
RtAttr
alen
int
vbuf
[]
byte
e
error
attrs
[]
NetlinkRouteAttr
)
switch
msg
.
Header
.
Type
{
case
RTM_NEWLINK
,
RTM_DELLINK
:
case
RTM_NEWLINK
,
RTM_DELLINK
:
b
uf
=
msg
.
Data
[
SizeofIfInfomsg
:
]
b
=
m
.
Data
[
SizeofIfInfomsg
:
]
case
RTM_NEWADDR
,
RTM_DELADDR
:
case
RTM_NEWADDR
,
RTM_DELADDR
:
b
uf
=
msg
.
Data
[
SizeofIfAddrmsg
:
]
b
=
m
.
Data
[
SizeofIfAddrmsg
:
]
case
RTM_NEWROUTE
,
RTM_DELROUTE
:
case
RTM_NEWROUTE
,
RTM_DELROUTE
:
b
uf
=
msg
.
Data
[
SizeofRtMsg
:
]
b
=
m
.
Data
[
SizeofRtMsg
:
]
default
:
default
:
return
nil
,
EINVAL
return
nil
,
EINVAL
}
}
var
attrs
[]
NetlinkRouteAttr
for
len
(
b
uf
)
>=
SizeofRtAttr
{
for
len
(
b
)
>=
SizeofRtAttr
{
a
,
vbuf
,
alen
,
e
=
netlinkRouteAttrAndValue
(
buf
)
a
,
vbuf
,
alen
,
e
rr
:=
netlinkRouteAttrAndValue
(
b
)
if
e
!=
nil
{
if
e
rr
!=
nil
{
break
return
nil
,
err
}
}
ra
:=
NetlinkRouteAttr
{}
ra
:=
NetlinkRouteAttr
{
Attr
:
*
a
,
Value
:
vbuf
[
:
int
(
a
.
Len
)
-
SizeofRtAttr
]}
ra
.
Attr
=
*
a
ra
.
Value
=
vbuf
[
:
int
(
a
.
Len
)
-
SizeofRtAttr
]
attrs
=
append
(
attrs
,
ra
)
attrs
=
append
(
attrs
,
ra
)
b
uf
=
buf
[
alen
:
]
b
=
b
[
alen
:
]
}
}
return
attrs
,
nil
return
attrs
,
nil
}
}
func
netlinkRouteAttrAndValue
(
b
uf
[]
byte
)
(
*
RtAttr
,
[]
byte
,
int
,
error
)
{
func
netlinkRouteAttrAndValue
(
b
[]
byte
)
(
*
RtAttr
,
[]
byte
,
int
,
error
)
{
h
:=
(
*
RtAttr
)(
unsafe
.
Pointer
(
&
buf
[
0
]))
a
:=
(
*
RtAttr
)(
unsafe
.
Pointer
(
&
b
[
0
]))
if
int
(
h
.
Len
)
<
SizeofRtAttr
||
int
(
h
.
Len
)
>
len
(
buf
)
{
if
int
(
a
.
Len
)
<
SizeofRtAttr
||
int
(
a
.
Len
)
>
len
(
b
)
{
return
nil
,
nil
,
0
,
EINVAL
return
nil
,
nil
,
0
,
EINVAL
}
}
return
h
,
buf
[
SizeofRtAttr
:
],
rtaAlignOf
(
int
(
h
.
Len
)),
nil
return
a
,
b
[
SizeofRtAttr
:
],
rtaAlignOf
(
int
(
a
.
Len
)),
nil
}
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment