Skip to content

Commit

Permalink
Support SEG6_LOCAL_ACTION_END_BPF
Browse files Browse the repository at this point in the history
fix unit test

fix end.bpf

fix bug
  • Loading branch information
shu1r0 authored and aboch committed Jul 3, 2024
1 parent dd7e3f1 commit e6a5c0e
Show file tree
Hide file tree
Showing 3 changed files with 56 additions and 1 deletion.
4 changes: 4 additions & 0 deletions nl/seg6local_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ const (
SEG6_LOCAL_NH6
SEG6_LOCAL_IIF
SEG6_LOCAL_OIF
SEG6_LOCAL_BPF
__SEG6_LOCAL_MAX
)
const (
Expand All @@ -34,6 +35,7 @@ const (
SEG6_LOCAL_ACTION_END_S // 12
SEG6_LOCAL_ACTION_END_AS // 13
SEG6_LOCAL_ACTION_END_AM // 14
SEG6_LOCAL_ACTION_END_BPF // 15
__SEG6_LOCAL_ACTION_MAX
)
const (
Expand Down Expand Up @@ -71,6 +73,8 @@ func SEG6LocalActionString(action int) string {
return "End.AS"
case SEG6_LOCAL_ACTION_END_AM:
return "End.AM"
case SEG6_LOCAL_ACTION_END_BPF:
return "End.BPF"
}
return "unknown"
}
41 changes: 40 additions & 1 deletion route_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -273,6 +273,16 @@ type SEG6LocalEncap struct {
In6Addr net.IP
Iif int
Oif int
bpf bpfObj
}

func (e *SEG6LocalEncap) SetProg(progFd int, progName string) error {
if progFd <= 0 {
return fmt.Errorf("seg6local bpf SetProg: invalid fd")
}
e.bpf.progFd = progFd
e.bpf.progName = progName
return nil
}

func (e *SEG6LocalEncap) Type() int {
Expand Down Expand Up @@ -306,6 +316,22 @@ func (e *SEG6LocalEncap) Decode(buf []byte) error {
case nl.SEG6_LOCAL_OIF:
e.Oif = int(native.Uint32(attr.Value[0:4]))
e.Flags[nl.SEG6_LOCAL_OIF] = true
case nl.SEG6_LOCAL_BPF:
var bpfAttrs []syscall.NetlinkRouteAttr
bpfAttrs, err = nl.ParseRouteAttr(attr.Value)
bpfobj := bpfObj{}
for _, bpfAttr := range bpfAttrs {
switch bpfAttr.Attr.Type {
case nl.LWT_BPF_PROG_FD:
bpfobj.progFd = int(native.Uint32(bpfAttr.Value))
case nl.LWT_BPF_PROG_NAME:
bpfobj.progName = string(bpfAttr.Value)
default:
err = fmt.Errorf("seg6local bpf decode: unknown attribute: Type %d", bpfAttr.Attr)
}
}
e.bpf = bpfobj
e.Flags[nl.SEG6_LOCAL_BPF] = true
}
}
return err
Expand Down Expand Up @@ -367,6 +393,16 @@ func (e *SEG6LocalEncap) Encode() ([]byte, error) {
native.PutUint32(attr[4:], uint32(e.Oif))
res = append(res, attr...)
}
if e.Flags[nl.SEG6_LOCAL_BPF] {
attr := nl.NewRtAttr(nl.SEG6_LOCAL_BPF, []byte{})
if e.bpf.progFd != 0 {
attr.AddRtAttr(nl.LWT_BPF_PROG_FD, nl.Uint32Attr(uint32(e.bpf.progFd)))
}
if e.bpf.progName != "" {
attr.AddRtAttr(nl.LWT_BPF_PROG_NAME, nl.ZeroTerminated(e.bpf.progName))
}
res = append(res, attr.Serialize()...)
}
return res, err
}
func (e *SEG6LocalEncap) String() string {
Expand Down Expand Up @@ -406,6 +442,9 @@ func (e *SEG6LocalEncap) String() string {
}
strs = append(strs, fmt.Sprintf("segs %d [ %s ]", len(e.Segments), strings.Join(segs, " ")))
}
if e.Flags[nl.SEG6_LOCAL_BPF] {
strs = append(strs, fmt.Sprintf("bpf %s[%d]", e.bpf.progName, e.bpf.progFd))
}
return strings.Join(strs, " ")
}
func (e *SEG6LocalEncap) Equal(x Encap) bool {
Expand Down Expand Up @@ -437,7 +476,7 @@ func (e *SEG6LocalEncap) Equal(x Encap) bool {
if !e.InAddr.Equal(o.InAddr) || !e.In6Addr.Equal(o.In6Addr) {
return false
}
if e.Action != o.Action || e.Table != o.Table || e.Iif != o.Iif || e.Oif != o.Oif {
if e.Action != o.Action || e.Table != o.Table || e.Iif != o.Iif || e.Oif != o.Oif || e.bpf != o.bpf {
return false
}
return true
Expand Down
12 changes: 12 additions & 0 deletions route_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1767,6 +1767,9 @@ func TestSEG6LocalEqual(t *testing.T) {
var flags_end_b6_encaps [nl.SEG6_LOCAL_MAX]bool
flags_end_b6_encaps[nl.SEG6_LOCAL_ACTION] = true
flags_end_b6_encaps[nl.SEG6_LOCAL_SRH] = true
var flags_end_bpf [nl.SEG6_LOCAL_MAX]bool
flags_end_bpf[nl.SEG6_LOCAL_ACTION] = true
flags_end_bpf[nl.SEG6_LOCAL_BPF] = true

cases := []SEG6LocalEncap{
{
Expand Down Expand Up @@ -1819,6 +1822,15 @@ func TestSEG6LocalEqual(t *testing.T) {
Segments: segs,
},
}

// SEG6_LOCAL_ACTION_END_BPF
endBpf := SEG6LocalEncap{
Flags: flags_end_bpf,
Action: nl.SEG6_LOCAL_ACTION_END_BPF,
}
_ = endBpf.SetProg(1, "firewall")
cases = append(cases, endBpf)

for i1 := range cases {
for i2 := range cases {
got := cases[i1].Equal(&cases[i2])
Expand Down

0 comments on commit e6a5c0e

Please sign in to comment.