Skip to content

Commit

Permalink
bpf: Derive host netns cookie via SO_NETNS_COOKIE
Browse files Browse the repository at this point in the history
When running in nested environments (e.g. Kind), cilium-agent does not
run in the host netns. So, in such cases the cookie comparison based on
bpf_get_netns_cookie(NULL) in bpf_sock.c for checking whether a socket
belongs to a host netns does not work. This breaks some socket-lb
functionality.

To fix this, we derive the cookie of the netns in which cilium-agent
runs via getsockopt(...SO_NETNS_COOKIE...) and then use it in the check
above. This is based on an assumption that cilium-agent always runs with
"hostNetwork: true".

Signed-off-by: Martynas Pumputis <m@lambda.lt>
  • Loading branch information
brb committed Jul 30, 2021
1 parent cee08cd commit 76ee0c1
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 1 deletion.
7 changes: 6 additions & 1 deletion bpf/bpf_sock.c
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,12 @@ ctx_in_hostns(void *ctx __maybe_unused, __net_cookie *cookie)

if (cookie)
*cookie = own_cookie;
return own_cookie == get_netns_cookie(NULL);
return own_cookie ==
# ifdef HOST_NETNS_COOKIE
HOST_NETNS_COOKIE;
# else
get_netns_cookie(NULL);
# endif
#else
if (cookie)
*cookie = 0;
Expand Down
13 changes: 13 additions & 0 deletions pkg/datapath/linux/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ import (
"github.com/cilium/cilium/pkg/maps/signalmap"
"github.com/cilium/cilium/pkg/maps/sockmap"
"github.com/cilium/cilium/pkg/maps/tunnel"
"github.com/cilium/cilium/pkg/netns"
"github.com/cilium/cilium/pkg/node"
"github.com/cilium/cilium/pkg/option"

Expand Down Expand Up @@ -253,6 +254,18 @@ func (h *HeaderfileWriter) WriteNodeConfig(w io.Writer, cfg *datapath.LocalNodeC
if option.Config.EnableHostServicesPeer {
cDefinesMap["ENABLE_HOST_SERVICES_PEER"] = "1"
}
if cookie, err := netns.GetNetNSCookie(); err == nil {
// When running in nested environments (e.g. Kind), cilium-agent does
// not run in the host netns. So, in such cases the cookie comparison
// based on bpf_get_netns_cookie(NULL) for checking whether a socket
// belongs to a host netns does not work.
//
// To fix this, we derive the cookie of the netns in which cilium-agent
// runs via getsockopt(...SO_NETNS_COOKIE...) and then use it in the
// check above. This is based on an assumption that cilium-agent
// always runs with "hostNetwork: true".
cDefinesMap["HOST_NETNS_COOKIE"] = fmt.Sprintf("%d", cookie)
}
}

if option.Config.EnableNodePort {
Expand Down
22 changes: 22 additions & 0 deletions pkg/netns/cookie.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package netns

import (
"golang.org/x/sys/unix"
)

const SO_NETNS_COOKIE = 71

// GetNetNSCookie tries to retrieve the cookie of the host netns.
func GetNetNSCookie() (uint64, error) {
s, err := unix.Socket(unix.AF_INET, unix.SOCK_STREAM, 0)
if err != nil {
return 0, err
}

cookie, err := unix.GetsockoptUint64(s, unix.SOL_SOCKET, SO_NETNS_COOKIE)
if err != nil {
return 0, err
}

return cookie, nil
}

0 comments on commit 76ee0c1

Please sign in to comment.