Skip to content

Commit

Permalink
Merge branch 'master' into dependabot/go_modules/k8s-dependencies-35a…
Browse files Browse the repository at this point in the history
…06a653d
  • Loading branch information
mrueg authored Oct 16, 2024
2 parents 052812a + 24b5da7 commit 841909a
Show file tree
Hide file tree
Showing 16 changed files with 739 additions and 587 deletions.
10 changes: 5 additions & 5 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ module github.com/cloudnativelabs/kube-router/v2
require (
github.com/aws/aws-sdk-go v1.55.5
github.com/coreos/go-iptables v0.8.0
github.com/docker/docker v27.2.1+incompatible
github.com/docker/docker v27.3.1+incompatible
github.com/hashicorp/go-version v1.7.0
github.com/moby/ipvs v1.1.0
github.com/onsi/ginkgo v1.16.5
Expand All @@ -14,8 +14,8 @@ require (
github.com/stretchr/testify v1.9.0
github.com/vishvananda/netlink v1.3.0
github.com/vishvananda/netns v0.0.4
golang.org/x/net v0.29.0
golang.org/x/sys v0.25.0
golang.org/x/net v0.30.0
golang.org/x/sys v0.26.0
google.golang.org/grpc v1.67.1
google.golang.org/protobuf v1.34.2
k8s.io/api v0.31.1
Expand Down Expand Up @@ -97,8 +97,8 @@ require (
go.uber.org/multierr v1.11.0 // indirect
golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 // indirect
golang.org/x/oauth2 v0.22.0 // indirect
golang.org/x/term v0.24.0 // indirect
golang.org/x/text v0.18.0 // indirect
golang.org/x/term v0.25.0 // indirect
golang.org/x/text v0.19.0 // indirect
golang.org/x/time v0.5.0 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20240814211410-ddb44dafa142 // indirect
gopkg.in/evanphx/json-patch.v4 v4.12.0 // indirect
Expand Down
20 changes: 10 additions & 10 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,8 @@ github.com/dgryski/go-farm v0.0.0-20200201041132-a6ae2369ad13 h1:fAjc9m62+UWV/WA
github.com/dgryski/go-farm v0.0.0-20200201041132-a6ae2369ad13/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw=
github.com/distribution/reference v0.6.0 h1:0IXCQ5g4/QMHHkarYzh5l+u8T3t73zM5QvfrDyIgxBk=
github.com/distribution/reference v0.6.0/go.mod h1:BbU0aIcezP1/5jX/8MP0YiH4SdvB5Y4f/wlDRiLyi3E=
github.com/docker/docker v27.2.1+incompatible h1:fQdiLfW7VLscyoeYEBz7/J8soYFDZV1u6VW6gJEjNMI=
github.com/docker/docker v27.2.1+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
github.com/docker/docker v27.3.1+incompatible h1:KttF0XoteNTicmUtBO0L2tP+J7FGRFTjaEF4k6WdhfI=
github.com/docker/docker v27.3.1+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
github.com/docker/go-connections v0.5.0 h1:USnMq7hx7gwdVZq1L49hLXaFtUdTADjXGp+uj1Br63c=
github.com/docker/go-connections v0.5.0/go.mod h1:ov60Kzw0kKElRwhNs9UlUHAE/F9Fe6GLaXnqyDdmEXc=
github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4=
Expand Down Expand Up @@ -246,8 +246,8 @@ golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLL
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/net v0.29.0 h1:5ORfpBpCs4HzDYoodCDBbwHzdR5UrLBZ3sOnUJmFoHo=
golang.org/x/net v0.29.0/go.mod h1:gLkgy8jTGERgjzMic6DS9+SP0ajcu6Xu3Orq/SpETg0=
golang.org/x/net v0.30.0 h1:AcW1SDZMkb8IpzCdQUaIq2sP4sZ4zw+55h6ynffypl4=
golang.org/x/net v0.30.0/go.mod h1:2wGyMJ5iFasEhkwi13ChkO/t1ECNC4X4eBKkVFyYFlU=
golang.org/x/oauth2 v0.22.0 h1:BzDx2FehcG7jJwgWLELCdmLuxk2i+x9UDpSiss2u0ZA=
golang.org/x/oauth2 v0.22.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
Expand All @@ -267,14 +267,14 @@ golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.25.0 h1:r+8e+loiHxRqhXVl6ML1nO3l1+oFoWbnlu2Ehimmi34=
golang.org/x/sys v0.25.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/term v0.24.0 h1:Mh5cbb+Zk2hqqXNO7S1iTjEphVL+jb8ZWaqh/g+JWkM=
golang.org/x/term v0.24.0/go.mod h1:lOBK/LVxemqiMij05LGJ0tzNr8xlmwBRJ81PX6wVLH8=
golang.org/x/sys v0.26.0 h1:KHjCJyddX0LoSTb3J+vWpupP9p0oznkqVk/IfjymZbo=
golang.org/x/sys v0.26.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/term v0.25.0 h1:WtHI/ltw4NvSUig5KARz9h521QvRC8RmF/cuYqifU24=
golang.org/x/term v0.25.0/go.mod h1:RPyXicDX+6vLxogjjRxjgD2TKtmAO6NZBsBRfrOLu7M=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.18.0 h1:XvMDiNzPAl0jr17s6W9lcaIhGUfUORdGCNsuLmPG224=
golang.org/x/text v0.18.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY=
golang.org/x/text v0.19.0 h1:kTxAhCbGbxhK0IwgSKiMO5awPoDQ0RpfiVYBfK860YM=
golang.org/x/text v0.19.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY=
golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk=
golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
Expand Down
66 changes: 66 additions & 0 deletions pkg/bgp/id.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
package bgp

import (
"encoding/binary"
"errors"
"fmt"
"hash/fnv"
"net"
"strconv"
"strings"

"github.com/cloudnativelabs/kube-router/v2/pkg/utils"
gobgp "github.com/osrg/gobgp/v3/pkg/packet/bgp"
)

const (
CommunityMaxSize = 32
CommunityMaxPartSize = 16
)

// GenerateRouterID will generate a router ID based upon the user's configuration (or lack there of) and the node's
// primary IP address if the user has not specified. If the user has configured the router ID as "generate" then we
// will generate a router ID based upon fnv hashing the node's primary IP address.
func GenerateRouterID(nodeIPAware utils.NodeIPAware, configRouterID string) (string, error) {
switch {
case configRouterID == "generate":
h := fnv.New32a()
h.Write(nodeIPAware.GetPrimaryNodeIP())
hs := h.Sum32()
gip := make(net.IP, 4)
binary.BigEndian.PutUint32(gip, hs)
return gip.String(), nil
case configRouterID != "":
return configRouterID, nil
}

if nodeIPAware.GetPrimaryNodeIP().To4() == nil {
return "", errors.New("router-id must be specified when primary node IP is an IPv6 address")
}
return configRouterID, nil
}

// ValidateCommunity takes in a string and attempts to parse a BGP community out of it in a way that is similar to
// gobgp (internal/pkg/table/policy.go:ParseCommunity()). If it is not able to parse the community information it
// returns an error.
func ValidateCommunity(arg string) error {
_, err := strconv.ParseUint(arg, 10, CommunityMaxSize)
if err == nil {
return nil
}

elem1, elem2, found := strings.Cut(arg, ":")
if found {
if _, err := strconv.ParseUint(elem1, 10, CommunityMaxPartSize); err == nil {
if _, err = strconv.ParseUint(elem2, 10, CommunityMaxPartSize); err == nil {
return nil
}
}
}
for _, v := range gobgp.WellKnownCommunityNameMap {
if arg == v {
return nil
}
}
return fmt.Errorf("failed to parse %s as community", arg)
}
39 changes: 39 additions & 0 deletions pkg/bgp/id_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package bgp

import (
"testing"

"github.com/stretchr/testify/assert"
)

func Test_ValidateCommunity(t *testing.T) {
t.Run("BGP community specified as a 32-bit integer should pass validation", func(t *testing.T) {
assert.Nil(t, ValidateCommunity("4294967041"))
assert.Nil(t, ValidateCommunity("4294967295"))
})
t.Run("BGP community specified as 2 16-bit integers should pass validation", func(t *testing.T) {
assert.Nil(t, ValidateCommunity("65535:65281"))
assert.Nil(t, ValidateCommunity("65535:65535"))
})
t.Run("Well known BGP communities passed as a string should pass validation", func(t *testing.T) {
assert.Nil(t, ValidateCommunity("no-export"))
assert.Nil(t, ValidateCommunity("internet"))
assert.Nil(t, ValidateCommunity("planned-shut"))
assert.Nil(t, ValidateCommunity("accept-own"))
assert.Nil(t, ValidateCommunity("blackhole"))
assert.Nil(t, ValidateCommunity("no-advertise"))
assert.Nil(t, ValidateCommunity("no-peer"))
})
t.Run("BGP community that is greater than 32-bit integer should fail validation", func(t *testing.T) {
assert.Error(t, ValidateCommunity("4294967296"))
})
t.Run("BGP community that is greater than 2 16-bit integers should fail validation", func(t *testing.T) {
assert.Error(t, ValidateCommunity("65536:65535"))
assert.Error(t, ValidateCommunity("65535:65536"))
assert.Error(t, ValidateCommunity("65536:65536"))
})
t.Run("BGP community that is not a number should fail validation", func(t *testing.T) {
assert.Error(t, ValidateCommunity("0xFFFFFFFF"))
assert.Error(t, ValidateCommunity("community"))
})
}
63 changes: 63 additions & 0 deletions pkg/bgp/parse.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
package bgp

import (
"fmt"
"net"

gobgpapi "github.com/osrg/gobgp/v3/api"
"github.com/vishvananda/netlink"
)

// ParseNextHop takes in a GoBGP Path and parses out the destination's next hop from its attributes. If it
// can't parse a next hop IP from the GoBGP Path, it returns an error.
func ParseNextHop(path *gobgpapi.Path) (net.IP, error) {
for _, pAttr := range path.GetPattrs() {
unmarshalNew, err := pAttr.UnmarshalNew()
if err != nil {
return nil, fmt.Errorf("failed to unmarshal path attribute: %s", err)
}
switch t := unmarshalNew.(type) {
case *gobgpapi.NextHopAttribute:
// This is the primary way that we receive NextHops and happens when both the client and the server exchange
// next hops on the same IP family that they negotiated BGP on
nextHopIP := net.ParseIP(t.NextHop)
if nextHopIP != nil && (nextHopIP.To4() != nil || nextHopIP.To16() != nil) {
return nextHopIP, nil
}
return nil, fmt.Errorf("invalid nextHop address: %s", t.NextHop)
case *gobgpapi.MpReachNLRIAttribute:
// in the case where the server and the client are exchanging next-hops that don't relate to their primary
// IP family, we get MpReachNLRIAttribute instead of NextHopAttributes
// TODO: here we only take the first next hop, at some point in the future it would probably be best to
// consider multiple next hops
nextHopIP := net.ParseIP(t.NextHops[0])
if nextHopIP != nil && (nextHopIP.To4() != nil || nextHopIP.To16() != nil) {
return nextHopIP, nil
}
return nil, fmt.Errorf("invalid nextHop address: %s", t.NextHops[0])
}
}
return nil, fmt.Errorf("could not parse next hop received from GoBGP for path: %s", path)
}

// ParsePath takes in a GoBGP Path and parses out the destination subnet and the next hop from its attributes.
// If successful, it will return the destination of the BGP path as a subnet form and the next hop. If it
// can't parse the destination or the next hop IP, it returns an error.
func ParsePath(path *gobgpapi.Path) (*net.IPNet, net.IP, error) {
nextHop, err := ParseNextHop(path)
if err != nil {
return nil, nil, err
}

nlri := path.GetNlri()
var prefix gobgpapi.IPAddressPrefix
err = nlri.UnmarshalTo(&prefix)
if err != nil {
return nil, nil, fmt.Errorf("invalid nlri in advertised path")
}
dstSubnet, err := netlink.ParseIPNet(prefix.Prefix + "/" + fmt.Sprint(prefix.PrefixLen))
if err != nil {
return nil, nil, fmt.Errorf("couldn't parse IP subnet from nlri advertised path")
}
return dstSubnet, nextHop, nil
}
20 changes: 3 additions & 17 deletions pkg/controllers/routing/bgp_policies_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@ type PolicyTestCase struct {
customImportRejectDefinedSet *gobgpapi.DefinedSet
exportPolicyStatements []*gobgpapi.Statement
importPolicyStatements []*gobgpapi.Statement
addPolicyErr error
startBGPServerErr error
}

Expand Down Expand Up @@ -171,7 +170,6 @@ func Test_AddPolicies(t *testing.T) {
},
[]*gobgpapi.Statement{},
nil,
nil,
},
{
"has nodes and services with custom import reject annotation",
Expand Down Expand Up @@ -415,7 +413,6 @@ func Test_AddPolicies(t *testing.T) {
},
},
nil,
nil,
},
{
"has nodes, services with external peers",
Expand Down Expand Up @@ -620,7 +617,6 @@ func Test_AddPolicies(t *testing.T) {
},
},
nil,
nil,
},
{
"has nodes, services with external peers and iBGP disabled",
Expand Down Expand Up @@ -808,7 +804,6 @@ func Test_AddPolicies(t *testing.T) {
},
},
nil,
nil,
},
{
"prepends AS with external peers",
Expand Down Expand Up @@ -1019,7 +1014,6 @@ func Test_AddPolicies(t *testing.T) {
},
},
nil,
nil,
},
{
"only prepends AS when both node annotations are present",
Expand Down Expand Up @@ -1228,7 +1222,6 @@ func Test_AddPolicies(t *testing.T) {
},
},
},
nil,
fmt.Errorf("both %s and %s must be set", pathPrependASNAnnotation, pathPrependRepeatNAnnotation),
},
{
Expand Down Expand Up @@ -1444,7 +1437,6 @@ func Test_AddPolicies(t *testing.T) {
},
},
nil,
nil,
},
}

Expand Down Expand Up @@ -1490,15 +1482,9 @@ func Test_AddPolicies(t *testing.T) {
informerFactory := informers.NewSharedInformerFactory(testcase.nrc.clientset, 0)
nodeInformer := informerFactory.Core().V1().Nodes().Informer()
testcase.nrc.nodeLister = nodeInformer.GetIndexer()
err = testcase.nrc.AddPolicies()
if !reflect.DeepEqual(err, testcase.addPolicyErr) {
t.Logf("expected err when invoking AddPolicies(): %v", testcase.addPolicyErr)
t.Logf("actual err from AddPolicies() received: %v", err)
t.Error("unexpected error")
}
// If we expect AddPolicies() to fail we should stop here as there is no point in further evaluating policies
if testcase.addPolicyErr != nil {
return
if err := testcase.nrc.AddPolicies(); err != nil {
// If AddPolicies() failed we should stop here as there is no point in further evaluating policies
t.Fatalf("unexpected error when invoking AddPolicies(): %v", err)
}

err = testcase.nrc.bgpServer.ListDefinedSet(context.Background(),
Expand Down
Loading

0 comments on commit 841909a

Please sign in to comment.