syscall: hoist Getsockname out of NetlinkRIB loops

Calling Getsockname once to fetch the Pid field from the *SockaddrNetlink
is necessary, but this data will remain static for the rest of the netlink
socket's lifetime. Moving this call and type assertion outside of the inner
loops will remove a number of unnecessary system calls.

Change-Id: I7e7e81866af1a31fccdaaf7531efd6cc4cbb8926
Reviewed-on: https://go-review.googlesource.com/c/go/+/336369
Run-TryBot: Matt Layher <mdlayher@gmail.com>
TryBot-Result: Go Bot <gobot@golang.org>
Trust: Matt Layher <mdlayher@gmail.com>
Reviewed-by: Tobias Klauser <tobias.klauser@gmail.com>
This commit is contained in:
Matt Layher 2021-07-21 16:03:34 -04:00
parent 850768bbc9
commit 5c7a460a1c

View file

@ -55,14 +55,22 @@ func NetlinkRIB(proto, family int) ([]byte, error) {
return nil, err
}
defer Close(s)
lsa := &SockaddrNetlink{Family: AF_NETLINK}
if err := Bind(s, lsa); err != nil {
sa := &SockaddrNetlink{Family: AF_NETLINK}
if err := Bind(s, sa); err != nil {
return nil, err
}
wb := newNetlinkRouteRequest(proto, 1, family)
if err := Sendto(s, wb, 0, lsa); err != nil {
if err := Sendto(s, wb, 0, sa); err != nil {
return nil, err
}
lsa, err := Getsockname(s)
if err != nil {
return nil, err
}
lsanl, ok := lsa.(*SockaddrNetlink)
if !ok {
return nil, EINVAL
}
var tab []byte
rbNew := make([]byte, Getpagesize())
done:
@ -82,16 +90,7 @@ done:
return nil, err
}
for _, m := range msgs {
lsa, err := Getsockname(s)
if err != nil {
return nil, err
}
switch v := lsa.(type) {
case *SockaddrNetlink:
if m.Header.Seq != 1 || m.Header.Pid != v.Pid {
return nil, EINVAL
}
default:
if m.Header.Seq != 1 || m.Header.Pid != lsanl.Pid {
return nil, EINVAL
}
if m.Header.Type == NLMSG_DONE {