Skip to content

Commit

Permalink
Add fluent support for IPv6 entries.
Browse files Browse the repository at this point in the history
 * (M) fluent/fluent.go
  - Add IPv6 entry support within the gRIBIgo fluent library.
 * (M) fluent/fluent_test.go
  - Add testing for IPv6 builder, and additional coverage for MPLS.
  • Loading branch information
robshakir committed Nov 11, 2023
1 parent ef39224 commit c524db9
Show file tree
Hide file tree
Showing 2 changed files with 125 additions and 3 deletions.
91 changes: 91 additions & 0 deletions fluent/fluent.go
Original file line number Diff line number Diff line change
Expand Up @@ -311,6 +311,8 @@ const (
NextHopGroup
// NextHop references the NextHop AFT.
NextHop
// IPv6 references the IPv6Entry AFT.
IPv6
)

// aftMap provides mapping between the AFT enumerated type within the fluent
Expand All @@ -320,6 +322,7 @@ var aftMap = map[AFT]spb.AFTType{
IPv4: spb.AFTType_IPV4,
NextHopGroup: spb.AFTType_NEXTHOP_GROUP,
NextHop: spb.AFTType_NEXTHOP,
IPv6: spb.AFTType_IPV6,
}

// WithAFT specifies the AFT for which the Get request is made. The AllAFTs
Expand Down Expand Up @@ -603,6 +606,94 @@ func (i *ipv4Entry) EntryProto() (*spb.AFTEntry, error) {
}, nil
}

// ipv6Entry is the internal representation of a gRIBI IPv6Entry.
type ipv6Entry struct {
// pb is the gRIBI IPv4Entry that is being composed.
pb *aftpb.Afts_Ipv6EntryKey
// ni is the network instance to which the IPv4Entry is applied.
ni string
// electionID is an explicit election ID to be used for an
// operation using the entry.
electionID *spb.Uint128
}

// IPv6Entry returns a new gRIBI IPv6Entry builder.
func IPv6Entry() *ipv6Entry {
return &ipv6Entry{
pb: &aftpb.Afts_Ipv6EntryKey{
Ipv6Entry: &aftpb.Afts_Ipv6Entry{},
},
}
}

// WithPrefix sets the prefix of the IPv6Entry to the specified value, which
// must be a valid IPv6 prefix in the form prefix/mask.
func (i *ipv6Entry) WithPrefix(p string) *ipv6Entry {
i.pb.Prefix = p
return i
}

// WithNetworkInstance specifies the network instance to which the IPv6Entry
// is being applied.
func (i *ipv6Entry) WithNetworkInstance(n string) *ipv6Entry {
i.ni = n
return i
}

// WithNextHopGroup specifies the next-hop group that the IPv6Entry points to.
func (i *ipv6Entry) WithNextHopGroup(u uint64) *ipv6Entry {
i.pb.Ipv6Entry.NextHopGroup = &wpb.UintValue{Value: u}
return i
}

// WithNextHopGroupNetworkInstance specifies the network-instance within which
// the next-hop-group for the IPv6 entry should be resolved.
func (i *ipv6Entry) WithNextHopGroupNetworkInstance(n string) *ipv6Entry {
i.pb.Ipv6Entry.NextHopGroupNetworkInstance = &wpb.StringValue{Value: n}
return i
}

// WithMetadata specifies a byte slice that is stored as metadata alongside
// the IPV6 entry on the gRIBI server.
func (i *ipv6Entry) WithMetadata(b []byte) *ipv6Entry {
i.pb.Ipv6Entry.EntryMetadata = &wpb.BytesValue{Value: b}
return i
}

// WithElectionID specifies an explicit election ID to be used for the Entry.
// The election ID is made up of the concatenation of the low and high uint64
// values provided.
func (i *ipv6Entry) WithElectionID(low, high uint64) *ipv6Entry {
i.electionID = &spb.Uint128{
Low: low,
High: high,
}
return i
}

// OpProto implements the gRIBIEntry interface, returning a gRIBI AFTOperation. ID
// is explicitly not populated such that they can be populated by
// the function (e.g., AddEntry) to which they are an argument.
func (i *ipv6Entry) OpProto() (*spb.AFTOperation, error) {
return &spb.AFTOperation{
NetworkInstance: i.ni,
Entry: &spb.AFTOperation_Ipv6{
Ipv6: proto.Clone(i.pb).(*aftpb.Afts_Ipv6EntryKey),
},
ElectionId: i.electionID,
}, nil
}

// EntryProto implements the GRIBIEntry interface, building a gRIBI AFTEntry.
func (i *ipv6Entry) EntryProto() (*spb.AFTEntry, error) {
return &spb.AFTEntry{
NetworkInstance: i.ni,
Entry: &spb.AFTEntry_Ipv6{
Ipv6: proto.Clone(i.pb).(*aftpb.Afts_Ipv6EntryKey),
},
}, nil
}

// labelEntry is the internal representation of a MPLS label entry in gRIBI.
type labelEntry struct {
// ni is the network instance that the MPLS label entry is within.
Expand Down
37 changes: 34 additions & 3 deletions fluent/fluent_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -385,13 +385,14 @@ func TestEntry(t *testing.T) {
},
}, {
desc: "mpls entry",
in: LabelEntry().WithNetworkInstance("DEFAULT").WithLabel(42).WithNextHopGroupNetworkInstance("DEFAULT").WithPoppedLabelStack(10, 20),
in: LabelEntry().WithNetworkInstance("DEFAULT").WithLabel(42).WithNextHopGroup(1).WithNextHopGroupNetworkInstance("DEFAULT").WithPoppedLabelStack(10, 20),
wantOpProto: &spb.AFTOperation{
NetworkInstance: "DEFAULT",
Entry: &spb.AFTOperation_Mpls{
Mpls: &aftpb.Afts_LabelEntryKey{
Label: &aftpb.Afts_LabelEntryKey_LabelUint64{LabelUint64: 42},
LabelEntry: &aftpb.Afts_LabelEntry{
NextHopGroup: &wpb.UintValue{Value: 1},
NextHopGroupNetworkInstance: &wpb.StringValue{Value: "DEFAULT"},
PoppedMplsLabelStack: []*aftpb.Afts_LabelEntry_PoppedMplsLabelStackUnion{
{PoppedMplsLabelStackUint64: 10},
Expand All @@ -407,6 +408,7 @@ func TestEntry(t *testing.T) {
Mpls: &aftpb.Afts_LabelEntryKey{
Label: &aftpb.Afts_LabelEntryKey_LabelUint64{LabelUint64: 42},
LabelEntry: &aftpb.Afts_LabelEntry{
NextHopGroup: &wpb.UintValue{Value: 1},
NextHopGroupNetworkInstance: &wpb.StringValue{Value: "DEFAULT"},
PoppedMplsLabelStack: []*aftpb.Afts_LabelEntry_PoppedMplsLabelStackUnion{
{PoppedMplsLabelStackUint64: 10},
Expand All @@ -416,6 +418,35 @@ func TestEntry(t *testing.T) {
},
},
},
}, {
desc: "ipv6 entry",
in: IPv6Entry().WithNetworkInstance("DEFAULT").WithPrefix("2001:db8::/42").WithNextHopGroup(1).WithNextHopGroupNetworkInstance("DEFAULT").WithMetadata([]byte{1, 2, 3, 4}),
wantOpProto: &spb.AFTOperation{
NetworkInstance: "DEFAULT",
Entry: &spb.AFTOperation_Ipv6{
Ipv6: &aftpb.Afts_Ipv6EntryKey{
Prefix: "2001:db8::/42",
Ipv6Entry: &aftpb.Afts_Ipv6Entry{
NextHopGroup: &wpb.UintValue{Value: 1},
NextHopGroupNetworkInstance: &wpb.StringValue{Value: "DEFAULT"},
EntryMetadata: &wpb.BytesValue{Value: []byte{1, 2, 3, 4}},
},
},
},
},
wantEntryProto: &spb.AFTEntry{
NetworkInstance: "DEFAULT",
Entry: &spb.AFTEntry_Ipv6{
Ipv6: &aftpb.Afts_Ipv6EntryKey{
Prefix: "2001:db8::/42",
Ipv6Entry: &aftpb.Afts_Ipv6Entry{
NextHopGroup: &wpb.UintValue{Value: 1},
NextHopGroupNetworkInstance: &wpb.StringValue{Value: "DEFAULT"},
EntryMetadata: &wpb.BytesValue{Value: []byte{1, 2, 3, 4}},
},
},
},
},
}}

for _, tt := range tests {
Expand All @@ -425,15 +456,15 @@ func TestEntry(t *testing.T) {
t.Fatalf("did not get expected error for op, got: %v, wantErr? %v", err, tt.wantOpErr)
}
if diff := cmp.Diff(gotop, tt.wantOpProto, protocmp.Transform()); diff != "" {
t.Fatalf("did not get expected proto, diff(-got,+want):\n%s", diff)
t.Fatalf("did not get expected Operation proto, diff(-got,+want):\n%s", diff)
}

gotent, err := tt.in.EntryProto()
if (err != nil) != tt.wantEntryErr {
t.Fatalf("did not get expected error for entry, got: %v, wantErr? %v", err, tt.wantEntryErr)
}
if diff := cmp.Diff(gotent, tt.wantEntryProto, protocmp.Transform()); diff != "" {
t.Fatalf("did not get expexcted proto, diff(-got,+want)\n%s", diff)
t.Fatalf("did not get expected Entry proto, diff(-got,+want)\n%s", diff)
}
})
}
Expand Down

0 comments on commit c524db9

Please sign in to comment.