Skip to content

Commit

Permalink
Merge pull request #1270 from ligato/dev
Browse files Browse the repository at this point in the history
Dev to master
  • Loading branch information
ondrej-fabry authored Apr 5, 2019
2 parents 63cc3b5 + daf36d4 commit 9513fcb
Show file tree
Hide file tree
Showing 7 changed files with 135 additions and 57 deletions.
4 changes: 2 additions & 2 deletions Gopkg.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

17 changes: 17 additions & 0 deletions api/models/vpp/l3/keys.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ package vpp_l3

import (
"fmt"
"strconv"
"strings"

"github.com/ligato/vpp-agent/pkg/models"
Expand Down Expand Up @@ -106,3 +107,19 @@ func ParseProxyARPInterfaceKey(key string) (iface string, isProxyARPInterfaceKey
func RouteVrfPrefix(vrf uint32) string {
return ModelRoute.KeyPrefix() + "vrf/" + fmt.Sprint(vrf) + "/"
}

// ParseRouteKey parses VRF label and route address from a route key.
func ParseRouteKey(key string) (vrfIndex string, dstNetAddr string, dstNetMask int, nextHopAddr string, isRouteKey bool) {
if routeKey := strings.TrimPrefix(key, ModelRoute.KeyPrefix()); routeKey != key {
keyParts := strings.Split(routeKey, "/")
if len(keyParts) >= 7 &&
keyParts[0] == "vrf" &&
keyParts[2] == "dst" &&
keyParts[5] == "gw" {
if mask, err := strconv.Atoi(keyParts[4]); err == nil {
return keyParts[1], keyParts[3], mask, keyParts[6], true
}
}
}
return "", "", 0, "", false
}
50 changes: 21 additions & 29 deletions api/models/vpp/l3/keys_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,12 @@

package vpp_l3

import (
"testing"

. "github.com/onsi/gomega"
)

/*func TestRouteKey(t *testing.T) {
tests := []struct {
name string
Expand Down Expand Up @@ -85,7 +91,9 @@ package vpp_l3
})
}
}
*/

// TestParseRouteKey test different cases for ParseRouteKey(...)
func TestParseRouteKey(t *testing.T) {
tests := []struct {
name string
Expand All @@ -98,7 +106,7 @@ func TestParseRouteKey(t *testing.T) {
}{
{
name: "route-ipv4",
routeKey: "vpp/config/v2/route/vrf/0/dst/10.10.0.0/16/gw/0.0.0.0",
routeKey: "config/vpp/v2/route/vrf/0/dst/10.10.0.0/16/gw/0.0.0.0",
expectedIsRouteKey: true,
expectedVrfIndex: "0",
expectedDstNetAddr: "10.10.0.0",
Expand All @@ -107,7 +115,7 @@ func TestParseRouteKey(t *testing.T) {
},
{
name: "route-ipv6",
routeKey: "vpp/config/v2/route/vrf/0/dst/2001:db8::/32/gw/::",
routeKey: "config/vpp/v2/route/vrf/0/dst/2001:db8::/32/gw/::",
expectedIsRouteKey: true,
expectedVrfIndex: "0",
expectedDstNetAddr: "2001:db8::",
Expand All @@ -116,42 +124,26 @@ func TestParseRouteKey(t *testing.T) {
},
{
name: "invalid-key",
routeKey: "vpp/config/v2/route/vrf/0/dst/2001:db8::/32/",
routeKey: "config/vpp/v2/route/vrf/0/dst/2001:db8::/32/",
expectedIsRouteKey: false,
},
{
name: "invalid-key-missing-dst",
routeKey: "vpp/config/v2/route/vrf/0/10.10.0.0/16/gw/0.0.0.0",
routeKey: "config/vpp/v2/route/vrf/0/10.10.0.0/16/gw/0.0.0.0",
expectedIsRouteKey: false,
},
}
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
name, isRouteKey := models.Model(&Route{}).ParseKey(test.routeKey)
nameParts := strings.Split(name, "/")
if len(nameParts) != 7 {
t.Fatalf("invalid name: %q", name)
}
vrfIndex, dstNetAddr, nextHopAddr := nameParts[1], nameParts[3], nameParts[6]
dstNetMask, err := strconv.Atoi(nameParts[4])
if err != nil {
t.Fatalf("invalid mask: %v", dstNetMask)
}
if isRouteKey != test.expectedIsRouteKey {
t.Errorf("expected isRouteKey: %v\tgot: %v", test.expectedIsRouteKey, isRouteKey)
}
if vrfIndex != test.expectedVrfIndex {
t.Errorf("expected vrfIndex: %q\tgot: %q", test.expectedVrfIndex, vrfIndex)
}
if dstNetAddr != test.expectedDstNetAddr {
t.Errorf("expected dstNetAddr: %q\tgot: %q", test.expectedDstNetAddr, dstNetAddr)
}
if dstNetMask != test.expectedDstNetMask {
t.Errorf("expected dstNetMask: %v\tgot: %v", test.expectedDstNetMask, dstNetMask)
}
if nextHopAddr != test.expectedNextHopAddr {
t.Errorf("expected nextHopAddr: %q\tgot: %q", test.expectedNextHopAddr, nextHopAddr)
RegisterTestingT(t)
vrfIndex, dstNetAddr, dstNetMask, nextHopAddr, isRouteKey := ParseRouteKey(test.routeKey)
Expect(isRouteKey).To(BeEquivalentTo(test.expectedIsRouteKey), "Route/Non-route key should be properly detected")
if isRouteKey {
Expect(vrfIndex).To(BeEquivalentTo(test.expectedVrfIndex), "VRF should be properly extracted by parsing route key")
Expect(dstNetAddr).To(BeEquivalentTo(test.expectedDstNetAddr), "Destination network address should be properly extracted by parsing route key")
Expect(dstNetMask).To(BeEquivalentTo(test.expectedDstNetMask), "Destination network mask should be properly extracted by parsing route key")
Expect(nextHopAddr).To(BeEquivalentTo(test.expectedNextHopAddr), "Next hop address should be properly extracted by parsing route key")
}
})
}
}*/
}
33 changes: 33 additions & 0 deletions plugins/vpp/srplugin/descriptor/localsid.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,13 @@
package descriptor

import (
"fmt"
"net"
"reflect"
"strings"

"github.com/ligato/cn-infra/logging"
"github.com/ligato/cn-infra/utils/addrs"
interfaces "github.com/ligato/vpp-agent/api/models/vpp/interfaces"
"github.com/ligato/vpp-agent/api/models/vpp/l3"
srv6 "github.com/ligato/vpp-agent/api/models/vpp/srv6"
Expand Down Expand Up @@ -198,6 +200,7 @@ func (d *LocalSIDDescriptor) Dependencies(key string, localSID *srv6.LocalSID) (
Label: localsidVRFDep,
AnyOf: scheduler.AnyOfDependency{
KeyPrefixes: []string{vpp_l3.RouteVrfPrefix(ef.EndFunction_T.VrfId)}, // waiting for VRF table creation (route creation creates also VRF table if it doesn't exist)
KeySelector: d.isIPv6RouteKey, // T refers to IPv6 VRF table
},
})
}
Expand Down Expand Up @@ -227,6 +230,7 @@ func (d *LocalSIDDescriptor) Dependencies(key string, localSID *srv6.LocalSID) (
Label: localsidVRFDep,
AnyOf: scheduler.AnyOfDependency{
KeyPrefixes: []string{vpp_l3.RouteVrfPrefix(ef.EndFunction_DT4.VrfId)}, // waiting for VRF table creation (route creation creates also VRF table if it doesn't exist)
KeySelector: d.isIPv4RouteKey, // we want ipv4 VRF because DT4
},
})
}
Expand All @@ -236,6 +240,7 @@ func (d *LocalSIDDescriptor) Dependencies(key string, localSID *srv6.LocalSID) (
Label: localsidVRFDep,
AnyOf: scheduler.AnyOfDependency{
KeyPrefixes: []string{vpp_l3.RouteVrfPrefix(ef.EndFunction_DT6.VrfId)}, // waiting for VRF table creation (route creation creates also VRF table if it doesn't exist)
KeySelector: d.isIPv6RouteKey, // we want ipv6 VRF because DT6
},
})
}
Expand All @@ -253,6 +258,24 @@ func (d *LocalSIDDescriptor) Dependencies(key string, localSID *srv6.LocalSID) (
return dependencies
}

func (d *LocalSIDDescriptor) isIPv4RouteKey(key string) bool {
isIPv6, err := isRouteDstIpv6(key)
if err != nil {
d.log.Debug("Can't determine whether key %v is for ipv4 route or not due to: %v", key, err)
return false // it fails also in route creation (vpp_calls) and it is before needed vrf creation
}
return !isIPv6
}

func (d *LocalSIDDescriptor) isIPv6RouteKey(key string) bool {
isIPv6, err := isRouteDstIpv6(key)
if err != nil {
d.log.Debug("Can't determine whether key %v is for ipv6 route or not due to: %v", key, err)
return false // it fails also in route creation (vpp_calls) and it is before needed vrf creation
}
return isIPv6
}

// ParseIPv6 parses string <str> to IPv6 address (including IPv4 address converted to IPv6 address)
func ParseIPv6(str string) (net.IP, error) {
ip := net.ParseIP(str)
Expand All @@ -279,6 +302,16 @@ func ParseIPv4(str string) (net.IP, error) {
return ipv4, nil
}

func isRouteDstIpv6(key string) (bool, error) {
_, dstNetAddr, dstNetMask, _, isRouteKey := vpp_l3.ParseRouteKey(key)
if !isRouteKey {
return false, errors.Errorf("Key %v is not route key", key)
}
dstNet := fmt.Sprintf("%s/%d", dstNetAddr, dstNetMask)
_, isIPv6, err := addrs.ParseIPWithPrefix(dstNet)
return isIPv6, err
}

func equivalentSIDs(sid1, sid2 string) bool {
return equivalentIPv6(sid1, sid2)
}
Expand Down
31 changes: 22 additions & 9 deletions vendor/git.fd.io/govpp.git/adapter/socketclient/socketclient.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit 9513fcb

Please sign in to comment.