github.com/cilium/cilium@v1.16.2/pkg/datapath/linux/ipsec/probe_linux.go (about) 1 // SPDX-License-Identifier: Apache-2.0 2 // Copyright Authors of Cilium 3 4 //go:build linux 5 6 package ipsec 7 8 import ( 9 "encoding/hex" 10 "errors" 11 "net" 12 13 "github.com/vishvananda/netlink" 14 15 "github.com/cilium/cilium/pkg/datapath/linux/linux_defaults" 16 ) 17 18 const ( 19 dummyIP = "169.254.169.254" 20 aeadKey = "4242424242424242424242424242424242424242" 21 aeadAlgo = "rfc4106(gcm(aes))" 22 stateId = 42 23 ) 24 25 func initDummyXfrmState() *netlink.XfrmState { 26 k, _ := hex.DecodeString(aeadKey) 27 return &netlink.XfrmState{ 28 Mode: netlink.XFRM_MODE_TUNNEL, 29 Proto: netlink.XFRM_PROTO_ESP, 30 ESN: false, 31 Spi: stateId, 32 Reqid: stateId, 33 Aead: &netlink.XfrmStateAlgo{ 34 Name: aeadAlgo, 35 Key: k, 36 ICVLen: 128, 37 }, 38 Src: net.ParseIP(dummyIP), 39 Dst: net.ParseIP(dummyIP), 40 } 41 } 42 43 func createDummyXfrmState(state *netlink.XfrmState) error { 44 state.Mark = &netlink.XfrmMark{ 45 Value: linux_defaults.RouteMarkDecrypt, 46 Mask: linux_defaults.IPsecMarkMaskIn, 47 } 48 state.OutputMark = &netlink.XfrmMark{ 49 Value: linux_defaults.RouteMarkDecrypt, 50 Mask: linux_defaults.RouteMarkMask, 51 } 52 return netlink.XfrmStateAdd(state) 53 } 54 55 // ProbeXfrmStateOutputMask probes the kernel to determine if it supports 56 // setting the xfrm state output mask (Linux 4.19+). It returns an error if 57 // the output mask is not supported or if an error occurred, nil otherwise. 58 func ProbeXfrmStateOutputMask() (e error) { 59 state := initDummyXfrmState() 60 err := createDummyXfrmState(state) 61 if err != nil { 62 return err 63 } 64 defer func() { 65 e = errors.Join(e, netlink.XfrmStateDel(state)) 66 }() 67 68 var probedState *netlink.XfrmState 69 if probedState, err = netlink.XfrmStateGet(state); err != nil { 70 return err 71 } 72 if probedState == nil || probedState.OutputMark == nil { 73 return errors.New("IPSec output mark attribute missing from xfrm probe") 74 } 75 if probedState.OutputMark.Mask != linux_defaults.RouteMarkMask { 76 return errors.New("incorrect value for probed IPSec output mask attribute") 77 } 78 return 79 }