diff options
author | Pablo Mazzini <pmazzini@gmail.com> | 2022-04-05 06:01:11 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-04-05 06:01:11 +0100 |
commit | 12fbdcb11b41fa90662c34620e09dc7714d67ab3 (patch) | |
tree | 0a6a0bd1f513be7e71a363f2ad4c05a90db879ed | |
parent | 3c283ff8b7dd3a8ea2dbc37d13a35bba7aab00e5 (diff) | |
parent | 9e4611cb531e6234489ccf22973cd6b4d698885d (diff) |
Merge pull request #463 from name29/ciena_dhcpv6
Extending parse_circuit_id and adding support for Ciena
-rw-r--r-- | dhcpv6/ztpv6/README.md | 1 | ||||
-rw-r--r-- | dhcpv6/ztpv6/parse_vendor_options.go | 19 | ||||
-rw-r--r-- | dhcpv6/ztpv6/parse_vendor_options_test.go | 23 |
3 files changed, 38 insertions, 5 deletions
diff --git a/dhcpv6/ztpv6/README.md b/dhcpv6/ztpv6/README.md index f44191b..a3e16f8 100644 --- a/dhcpv6/ztpv6/README.md +++ b/dhcpv6/ztpv6/README.md @@ -3,6 +3,7 @@ ## Currently Supported Vendors For DHCPv6 ZTP - Arista - ZPE + - Ciena ## Why Do We Need This? Many network hardware vendors support features that allow network devices to provision themselves with proper supporting automation/tools. Network devices can rely on DHCP and other methods to gather bootfile info, IPs, etc. DHCPv6 Vendor options provides us Vendor Name, Make, Model, and Serial Number data. This data can be used to uniquely identify individual network devices at provisioning time and can be used by tooling to make decisions necessary to correctly and reliably provision a network device. diff --git a/dhcpv6/ztpv6/parse_vendor_options.go b/dhcpv6/ztpv6/parse_vendor_options.go index 212733c..3d1fd01 100644 --- a/dhcpv6/ztpv6/parse_vendor_options.go +++ b/dhcpv6/ztpv6/parse_vendor_options.go @@ -2,9 +2,11 @@ package ztpv6 import ( "errors" + "strconv" "strings" "github.com/insomniacslk/dhcp/dhcpv6" + "github.com/insomniacslk/dhcp/iana" ) var ( @@ -66,6 +68,23 @@ func ParseVendorData(packet dhcpv6.DHCPv6) (*VendorData, error) { vd.Model = p[1] vd.Serial = p[2] return &vd, nil + + // For Ciena the class identifier (opt 60) is written in the following format: + // {vendor iana code}-{product}-{type} + // For Ciena the iana code is 1271 + // The product type is a number that maps to a Ciena product + // The type is used to identified different subtype of the product. + // An example can be ‘1271-23422Z11-123’. + case strings.HasPrefix(d, strconv.Itoa(int(iana.EnterpriseIDCienaCorporation))): + v := strings.Split(d, "-") + if len(v) < 3 { + return nil, errVendorOptionMalformed + } + duid := packet.(*dhcpv6.Message).Options.ClientID() + vd.VendorName = iana.EnterpriseIDCienaCorporation.String() + vd.Model = v[1] + "-" + v[2] + vd.Serial = string(duid.EnterpriseIdentifier) + return &vd, nil } } return nil, errors.New("failed to parse vendor option data") diff --git a/dhcpv6/ztpv6/parse_vendor_options_test.go b/dhcpv6/ztpv6/parse_vendor_options_test.go index 45b42d6..cd2fb3d 100644 --- a/dhcpv6/ztpv6/parse_vendor_options_test.go +++ b/dhcpv6/ztpv6/parse_vendor_options_test.go @@ -4,6 +4,7 @@ import ( "testing" "github.com/insomniacslk/dhcp/dhcpv6" + "github.com/insomniacslk/dhcp/iana" "github.com/stretchr/testify/require" ) @@ -56,10 +57,11 @@ func TestParseVendorDataWithVendorOpts(t *testing.T) { func TestParseVendorDataWithVendorClass(t *testing.T) { tt := []struct { - name string - vc string - want *VendorData - fail bool + name string + vc string + clientId *dhcpv6.Duid + want *VendorData + fail bool }{ {name: "empty", fail: true}, {name: "unknownVendor", vc: "VendorX;BFR10K;XX12345", fail: true, want: nil}, @@ -74,6 +76,15 @@ func TestParseVendorDataWithVendorClass(t *testing.T) { vc: "ZPESystems:NSC:001234567", want: &VendorData{VendorName: "ZPESystems", Model: "NSC", Serial: "001234567"}, }, + { + name: "Ciena", + vc: "1271-23422Z11-123", + clientId: &dhcpv6.Duid{ + Type: dhcpv6.DUID_EN, + EnterpriseIdentifier: []byte("001234567"), + }, + want: &VendorData{VendorName: iana.EnterpriseIDCienaCorporation.String(), Model: "23422Z11-123", Serial: "001234567"}, + }, } for _, tc := range tt { @@ -85,7 +96,9 @@ func TestParseVendorDataWithVendorClass(t *testing.T) { packet.AddOption(&dhcpv6.OptVendorClass{ EnterpriseNumber: 0000, Data: [][]byte{[]byte(tc.vc)}}) - + if tc.clientId != nil { + packet.AddOption(dhcpv6.OptClientID(*tc.clientId)) + } vd, err := ParseVendorData(packet) if err != nil && !tc.fail { t.Errorf("unexpected failure: %v", err) |