summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--docs/sources/zebra.md29
-rw-r--r--internal/pkg/config/bgp_configs.go4
-rw-r--r--internal/pkg/zebra/apitype_string.go140
-rw-r--r--internal/pkg/zebra/routetype_string.go10
-rw-r--r--internal/pkg/zebra/zapi.go351
-rw-r--r--internal/pkg/zebra/zapi_test.go97
-rw-r--r--tools/pyang_plugins/gobgp.yang2
7 files changed, 438 insertions, 195 deletions
diff --git a/docs/sources/zebra.md b/docs/sources/zebra.md
index 7c0b8881..fe7b8bda 100644
--- a/docs/sources/zebra.md
+++ b/docs/sources/zebra.md
@@ -50,25 +50,27 @@ You need to enable the zebra feature in the Global configuration as follows.
To enable the Next-Hop Tracking features, please specify `3` or later.
For connecting to FRRouting 3.0.x, please specify `4`.
For connecting to FRRouting 5.0.x, please specify `5`.
- For connecting to FRRouting 7.3.x, please specify `6`.
+ For connecting to FRRouting 7.5.x, please specify `6`.
- `mpls-label-range-size` specifies mpls label range size for
requesting to Zebra. It works with FRRouting 5.0.x, FRRouting 6.0.x,
- FRRouting 7.0.x, FRRouting 7.1.x and FRRouting 7.2.x.
+ FRRouting 7.0.x, FRRouting 7.1.x, FRRouting 7.2.x, FRRouting 7.3.x
+ and FRRouting 7.5.x.
- `sotware-name` specifies software name for zebra when only `version`
configuration cannot specify software uniquely. This configuration
is used with 'version' configuration. For connecting to FRRouting
- 7.2.x, please specify `6` as `version` and `frr7.2` as
- `software-name`. For connecting to FRRouting 7.1.x and 7.0.x, please
- specify `6` as `version` and `frr7` as `software-name`. For
- connecting to FRRouting 6.0.x, please specify `6` as `version` and
- `frr6` as `software-name`. For connecting to FRRouting 4.0.x,
- please specify `5` as `version` and `frr4` as `software-name`. For
- connecting to Cumulus Linux please specify `5` as `version` and
- `cumulus` as `software-name`. GoBGP is tested with Cumulus Linux VX
- 3.7.7 whose zebra version is 4.0+cl3u13 and its Zebra API version is
- 5.
+ 7.3.x, please specify `6` as `version` and `frr7.3` as
+ `software-name`. For connecting to FRRouting 7.2.x, please specify
+ `6` as `version` and `frr7.2` as `software-name`. For connecting to
+ FRRouting 7.1.x and 7.0.x, please specify `6` as `version` and
+ `frr7` as `software-name`. For connecting to FRRouting 6.0.x, please
+ specify `6` as `version` and `frr6` as `software-name`. For
+ connecting to FRRouting 4.0.x, please specify `5` as `version` and
+ `frr4` as `software-name`. For connecting to Cumulus Linux please
+ specify `5` as `version` and `cumulus` as `software-name`. GoBGP is
+ tested with Cumulus Linux VX 3.7.7 whose zebra version is 4.0+cl3u13
+ and its Zebra API version is 5.
### Summary of combination of version and software-name configrations
@@ -80,7 +82,8 @@ You need to enable the zebra feature in the Global configuration as follows.
|5 | |FRRouting 5.0.x | |
|5 |cumulus |Cumulus Linux VX 3.7.7 | |
|5 |frr4 |FRRouting 4.0.x | |
-|6 | |FRRouting 7.3.x and 7.4.x|stable version of frr|
+|6 | |FRRouting 7.5.x | |
+|6 |frr7.3 |FRRouting 7.3.x | |
|6 |frr7.2 |FRRouting 7.2.x |Ubuntu 20.04 |
|6 |frr7 |FRRouting 7.0.x and 7.1.x|CentOS8 |
|6 |frr6 |FRRouting 6.0.x | |
diff --git a/internal/pkg/config/bgp_configs.go b/internal/pkg/config/bgp_configs.go
index 6d8fd26c..7777cacb 100644
--- a/internal/pkg/config/bgp_configs.go
+++ b/internal/pkg/config/bgp_configs.go
@@ -1141,7 +1141,7 @@ type ZebraState struct {
MplsLabelRangeSize uint32 `mapstructure:"mpls-label-range-size" json:"mpls-label-range-size,omitempty"`
// original -> gobgp:software-name
// Configure zebra software name.
- // frr4, cumulus, frr6, frr7, and frr7.2 can be used.
+ // frr4, cumulus, frr6, frr7, frr7.2, and frr7.3 can be used.
SoftwareName string `mapstructure:"software-name" json:"software-name,omitempty"`
}
@@ -1171,7 +1171,7 @@ type ZebraConfig struct {
MplsLabelRangeSize uint32 `mapstructure:"mpls-label-range-size" json:"mpls-label-range-size,omitempty"`
// original -> gobgp:software-name
// Configure zebra software name.
- // frr4, cumulus, frr6, frr7, and frr7.2 can be used.
+ // frr4, cumulus, frr6, frr7, frr7.2, and frr7.3 can be used.
SoftwareName string `mapstructure:"software-name" json:"software-name,omitempty"`
}
diff --git a/internal/pkg/zebra/apitype_string.go b/internal/pkg/zebra/apitype_string.go
index 8e517bd7..5ebeabd2 100644
--- a/internal/pkg/zebra/apitype_string.go
+++ b/internal/pkg/zebra/apitype_string.go
@@ -57,71 +57,87 @@ func _() {
_ = x[_mplsLabelsAdd-46]
_ = x[_mplsLabelsDelete-47]
_ = x[_mplsLabelsReplace-48]
- _ = x[_ipmrRouteStats-49]
- _ = x[labelManagerConnect-50]
- _ = x[labelManagerConnectAsync-51]
- _ = x[getLabelChunk-52]
- _ = x[releaseLabelChunk-53]
- _ = x[_fecRegister-54]
- _ = x[_fecUnregister-55]
- _ = x[_fecUpdate-56]
- _ = x[_advertiseDefaultGW-57]
- _ = x[_advertiseSviMACIP-58]
- _ = x[_advertiseSubnet-59]
- _ = x[_advertiseAllVNI-60]
- _ = x[_localESAdd-61]
- _ = x[_localESDel-62]
- _ = x[_vniAdd-63]
- _ = x[_vniDel-64]
- _ = x[_l3VNIAdd-65]
- _ = x[_l3VNIDel-66]
- _ = x[_remoteVTEPAdd-67]
- _ = x[_remoteVTEPDel-68]
- _ = x[_macIPAdd-69]
- _ = x[_macIPDel-70]
- _ = x[_ipPrefixRouteAdd-71]
- _ = x[_ipPrefixRouteDel-72]
- _ = x[_remoteMACIPAdd-73]
- _ = x[_remoteMACIPDel-74]
- _ = x[_duplicateAddrDetection-75]
- _ = x[_pwAdd-76]
- _ = x[_pwDelete-77]
- _ = x[_pwSet-78]
- _ = x[_pwUnset-79]
- _ = x[_pwStatusUpdate-80]
- _ = x[_ruleAdd-81]
- _ = x[_ruleDelete-82]
- _ = x[_ruleNotifyOwner-83]
- _ = x[_tableManagerConnect-84]
- _ = x[_getTableChunk-85]
- _ = x[_releaseTableChunk-86]
- _ = x[_ipSetCreate-87]
- _ = x[_ipSetDestroy-88]
- _ = x[_ipSetEntryAdd-89]
- _ = x[_ipSetEntryDelete-90]
- _ = x[_ipSetNotifyOwner-91]
- _ = x[_ipSetEntryNotifyOwner-92]
- _ = x[_ipTableAdd-93]
- _ = x[_ipTableDelete-94]
- _ = x[_ipTableNotifyOwner-95]
- _ = x[_vxlanFloodControl-96]
- _ = x[_vxlanSgAdd-97]
- _ = x[_vxlanSgDel-98]
- _ = x[_vxlanSgReplay-99]
- _ = x[_mlagProcessUp-100]
- _ = x[_mlagProcessDown-101]
- _ = x[_mlagClientRegister-102]
- _ = x[_mlagClientUnregister-103]
- _ = x[_mlagClientForwardMsg-104]
- _ = x[zebraError-105]
- _ = x[_clientCapabilities-106]
- _ = x[BackwardIPv6RouteAdd-107]
- _ = x[BackwardIPv6RouteDelete-108]
+ _ = x[_srPolicySet-49]
+ _ = x[_srPolicyDelete-50]
+ _ = x[_srPolicyNotifyStatus-51]
+ _ = x[_ipmrRouteStats-52]
+ _ = x[labelManagerConnect-53]
+ _ = x[labelManagerConnectAsync-54]
+ _ = x[getLabelChunk-55]
+ _ = x[releaseLabelChunk-56]
+ _ = x[_fecRegister-57]
+ _ = x[_fecUnregister-58]
+ _ = x[_fecUpdate-59]
+ _ = x[_advertiseDefaultGW-60]
+ _ = x[_advertiseSviMACIP-61]
+ _ = x[_advertiseSubnet-62]
+ _ = x[_advertiseAllVNI-63]
+ _ = x[_localESAdd-64]
+ _ = x[_localESDel-65]
+ _ = x[_remoteESVTEPAdd-66]
+ _ = x[_remoteESVTEPDel-67]
+ _ = x[_localESEVIAdd-68]
+ _ = x[_localESEVIDel-69]
+ _ = x[_vniAdd-70]
+ _ = x[_vniDel-71]
+ _ = x[_l3VNIAdd-72]
+ _ = x[_l3VNIDel-73]
+ _ = x[_remoteVTEPAdd-74]
+ _ = x[_remoteVTEPDel-75]
+ _ = x[_macIPAdd-76]
+ _ = x[_macIPDel-77]
+ _ = x[_ipPrefixRouteAdd-78]
+ _ = x[_ipPrefixRouteDel-79]
+ _ = x[_remoteMACIPAdd-80]
+ _ = x[_remoteMACIPDel-81]
+ _ = x[_duplicateAddrDetection-82]
+ _ = x[_pwAdd-83]
+ _ = x[_pwDelete-84]
+ _ = x[_pwSet-85]
+ _ = x[_pwUnset-86]
+ _ = x[_pwStatusUpdate-87]
+ _ = x[_ruleAdd-88]
+ _ = x[_ruleDelete-89]
+ _ = x[_ruleNotifyOwner-90]
+ _ = x[_tableManagerConnect-91]
+ _ = x[_getTableChunk-92]
+ _ = x[_releaseTableChunk-93]
+ _ = x[_ipSetCreate-94]
+ _ = x[_ipSetDestroy-95]
+ _ = x[_ipSetEntryAdd-96]
+ _ = x[_ipSetEntryDelete-97]
+ _ = x[_ipSetNotifyOwner-98]
+ _ = x[_ipSetEntryNotifyOwner-99]
+ _ = x[_ipTableAdd-100]
+ _ = x[_ipTableDelete-101]
+ _ = x[_ipTableNotifyOwner-102]
+ _ = x[_vxlanFloodControl-103]
+ _ = x[_vxlanSgAdd-104]
+ _ = x[_vxlanSgDel-105]
+ _ = x[_vxlanSgReplay-106]
+ _ = x[_mlagProcessUp-107]
+ _ = x[_mlagProcessDown-108]
+ _ = x[_mlagClientRegister-109]
+ _ = x[_mlagClientUnregister-110]
+ _ = x[_mlagClientForwardMsg-111]
+ _ = x[zebraError-112]
+ _ = x[_clientCapabilities-113]
+ _ = x[_opaqueMessage-114]
+ _ = x[_opaqueRegister-115]
+ _ = x[_opaqueUnregister-116]
+ _ = x[_neighDiscover-117]
+ _ = x[BackwardIPv6RouteAdd-118]
+ _ = x[BackwardIPv6RouteDelete-119]
+ _ = x[zapi6Frr7dot3MinDifferentAPIType-49]
_ = x[zapi6Frr7dot2MinDifferentAPIType-48]
_ = x[zapi5ClMinDifferentAPIType-19]
_ = x[zapi5MinDifferentAPIType-7]
_ = x[zapi4MinDifferentAPIType-6]
_ = x[zapi3MinDifferentAPIType-0]
+ _ = x[zapi6Frr7dot3LabelManagerConnect-50]
+ _ = x[zapi6Frr7dot3LabelManagerConnectAsync-51]
+ _ = x[zapi6Frr7dot3GetLabelChunk-52]
+ _ = x[zapi6Frr7dot3ReleaseLabelChunk-53]
_ = x[zapi6Frr7dot2LabelManagerConnect-49]
_ = x[zapi6Frr7dot2LabelManagerConnectAsync-50]
_ = x[zapi6Frr7dot2GetLabelChunk-51]
@@ -212,9 +228,9 @@ func _() {
_ = x[zapi3NexthopUpdate-29]
}
-const _APIType_name = "interfaceAddinterfaceDeleteinterfaceAddressAddinterfaceAddressDeleteinterfaceUpinterfaceDown_interfaceSetMaster_interfaceSetProtoDownRouteAddRouteDelete_routeNotifyOwnerredistributeAdd_redistributeDelete_redistributeDefaultAdd_redistributeDefaultDeleterouterIDAdd_routerIDDeleterouterIDUpdatehello_capabilitiesnexthopRegisternexthopUnregisternexthopUpdate_interfaceNBRAddressAdd_interfaceNBRAddressDelete_interfaceBFDDestUpdate_importRouteRegister_importRouteUnregister_importCheckUpdate_bfdDestRegister_bfdDestDeregister_bfdDestUpdate_bfdDestReplayredistributeRouteAddredistributeRouteDel_vrfUnregister_vrfAdd_vrfDeletevrfLabel_interfaceVRFUpdate_bfdClientRegister_bfdClientDeregister_interfaceEnableRADV_interfaceDisableRADVipv4NexthopLookupMRIB_interfaceLinkParams_mplsLabelsAdd_mplsLabelsDelete_mplsLabelsReplace_ipmrRouteStatslabelManagerConnectlabelManagerConnectAsyncgetLabelChunkreleaseLabelChunk_fecRegister_fecUnregister_fecUpdate_advertiseDefaultGW_advertiseSviMACIP_advertiseSubnet_advertiseAllVNI_localESAdd_localESDel_vniAdd_vniDel_l3VNIAdd_l3VNIDel_remoteVTEPAdd_remoteVTEPDel_macIPAdd_macIPDel_ipPrefixRouteAdd_ipPrefixRouteDel_remoteMACIPAdd_remoteMACIPDel_duplicateAddrDetection_pwAdd_pwDelete_pwSet_pwUnset_pwStatusUpdate_ruleAdd_ruleDelete_ruleNotifyOwner_tableManagerConnect_getTableChunk_releaseTableChunk_ipSetCreate_ipSetDestroy_ipSetEntryAdd_ipSetEntryDelete_ipSetNotifyOwner_ipSetEntryNotifyOwner_ipTableAdd_ipTableDelete_ipTableNotifyOwner_vxlanFloodControl_vxlanSgAdd_vxlanSgDel_vxlanSgReplay_mlagProcessUp_mlagProcessDown_mlagClientRegister_mlagClientUnregister_mlagClientForwardMsgzebraError_clientCapabilitiesBackwardIPv6RouteAddBackwardIPv6RouteDelete"
+const _APIType_name = "interfaceAddinterfaceDeleteinterfaceAddressAddinterfaceAddressDeleteinterfaceUpinterfaceDown_interfaceSetMaster_interfaceSetProtoDownRouteAddRouteDelete_routeNotifyOwnerredistributeAdd_redistributeDelete_redistributeDefaultAdd_redistributeDefaultDeleterouterIDAdd_routerIDDeleterouterIDUpdatehello_capabilitiesnexthopRegisternexthopUnregisternexthopUpdate_interfaceNBRAddressAdd_interfaceNBRAddressDelete_interfaceBFDDestUpdate_importRouteRegister_importRouteUnregister_importCheckUpdate_bfdDestRegister_bfdDestDeregister_bfdDestUpdate_bfdDestReplayredistributeRouteAddredistributeRouteDel_vrfUnregister_vrfAdd_vrfDeletevrfLabel_interfaceVRFUpdate_bfdClientRegister_bfdClientDeregister_interfaceEnableRADV_interfaceDisableRADVipv4NexthopLookupMRIB_interfaceLinkParams_mplsLabelsAdd_mplsLabelsDelete_mplsLabelsReplace_srPolicySet_srPolicyDelete_srPolicyNotifyStatus_ipmrRouteStatslabelManagerConnectlabelManagerConnectAsyncgetLabelChunkreleaseLabelChunk_fecRegister_fecUnregister_fecUpdate_advertiseDefaultGW_advertiseSviMACIP_advertiseSubnet_advertiseAllVNI_localESAdd_localESDel_remoteESVTEPAdd_remoteESVTEPDel_localESEVIAdd_localESEVIDel_vniAdd_vniDel_l3VNIAdd_l3VNIDel_remoteVTEPAdd_remoteVTEPDel_macIPAdd_macIPDel_ipPrefixRouteAdd_ipPrefixRouteDel_remoteMACIPAdd_remoteMACIPDel_duplicateAddrDetection_pwAdd_pwDelete_pwSet_pwUnset_pwStatusUpdate_ruleAdd_ruleDelete_ruleNotifyOwner_tableManagerConnect_getTableChunk_releaseTableChunk_ipSetCreate_ipSetDestroy_ipSetEntryAdd_ipSetEntryDelete_ipSetNotifyOwner_ipSetEntryNotifyOwner_ipTableAdd_ipTableDelete_ipTableNotifyOwner_vxlanFloodControl_vxlanSgAdd_vxlanSgDel_vxlanSgReplay_mlagProcessUp_mlagProcessDown_mlagClientRegister_mlagClientUnregister_mlagClientForwardMsgzebraError_clientCapabilities_opaqueMessage_opaqueRegister_opaqueUnregister_neighDiscoverBackwardIPv6RouteAddBackwardIPv6RouteDelete"
-var _APIType_index = [...]uint16{0, 12, 27, 46, 68, 79, 92, 111, 133, 141, 152, 169, 184, 203, 226, 252, 263, 278, 292, 297, 310, 325, 342, 355, 378, 404, 427, 447, 469, 487, 503, 521, 535, 549, 569, 589, 603, 610, 620, 628, 647, 665, 685, 705, 726, 747, 767, 781, 798, 816, 831, 850, 874, 887, 904, 916, 930, 940, 959, 977, 993, 1009, 1020, 1031, 1038, 1045, 1054, 1063, 1077, 1091, 1100, 1109, 1126, 1143, 1158, 1173, 1196, 1202, 1211, 1217, 1225, 1240, 1248, 1259, 1275, 1295, 1309, 1327, 1339, 1352, 1366, 1383, 1400, 1422, 1433, 1447, 1466, 1484, 1495, 1506, 1520, 1534, 1550, 1569, 1590, 1611, 1621, 1640, 1660, 1683}
+var _APIType_index = [...]uint16{0, 12, 27, 46, 68, 79, 92, 111, 133, 141, 152, 169, 184, 203, 226, 252, 263, 278, 292, 297, 310, 325, 342, 355, 378, 404, 427, 447, 469, 487, 503, 521, 535, 549, 569, 589, 603, 610, 620, 628, 647, 665, 685, 705, 726, 747, 767, 781, 798, 816, 828, 843, 864, 879, 898, 922, 935, 952, 964, 978, 988, 1007, 1025, 1041, 1057, 1068, 1079, 1095, 1111, 1125, 1139, 1146, 1153, 1162, 1171, 1185, 1199, 1208, 1217, 1234, 1251, 1266, 1281, 1304, 1310, 1319, 1325, 1333, 1348, 1356, 1367, 1383, 1403, 1417, 1435, 1447, 1460, 1474, 1491, 1508, 1530, 1541, 1555, 1574, 1592, 1603, 1614, 1628, 1642, 1658, 1677, 1698, 1719, 1729, 1748, 1762, 1777, 1794, 1808, 1828, 1851}
func (i APIType) String() string {
if i >= APIType(len(_APIType_index)-1) {
diff --git a/internal/pkg/zebra/routetype_string.go b/internal/pkg/zebra/routetype_string.go
index 4016b586..ee15413f 100644
--- a/internal/pkg/zebra/routetype_string.go
+++ b/internal/pkg/zebra/routetype_string.go
@@ -37,13 +37,15 @@ func _() {
_ = x[routeOpenfabric-26]
_ = x[routeVRRP-27]
_ = x[routeNHG-28]
- _ = x[routeAll-29]
- _ = x[routeMax-30]
+ _ = x[routeSRTE-29]
+ _ = x[routeAll-30]
+ _ = x[routeMax-31]
_ = x[zapi5Frr4RouteAll-24]
_ = x[zapi5Frr5RouteAll-25]
_ = x[zapi6Frr6RouteAll-26]
_ = x[zapi6Frr7RouteAll-27]
_ = x[zapi6Frr7dot2RouteAll-28]
+ _ = x[zapi6Frr7dot3RouteAll-29]
_ = x[zapi4RouteNHRP-11]
_ = x[zapi4RouteHSLS-12]
_ = x[zapi4RouteOLSR-13]
@@ -61,9 +63,9 @@ func _() {
_ = x[zapi3RouteNHRP-14]
}
-const _RouteType_name = "routeSystemrouteKernelrouteConnectRouteStaticrouteRIProuteRIPNGrouteOSPFrouteOSPF6routeISISRouteBGProutePIMrouteEIGRProuteNHRProuteHSLSrouteOLSRrouteTABLErouteLDProuteVNCrouteVNCDirectrouteVNCDirectRHrouteBGPDirectrouteBGPDirectEXTrouteBABELrouteSHARProutePBRrouteBFDrouteOpenfabricrouteVRRProuteNHGrouteAllrouteMax"
+const _RouteType_name = "routeSystemrouteKernelrouteConnectRouteStaticrouteRIProuteRIPNGrouteOSPFrouteOSPF6routeISISRouteBGProutePIMrouteEIGRProuteNHRProuteHSLSrouteOLSRrouteTABLErouteLDProuteVNCrouteVNCDirectrouteVNCDirectRHrouteBGPDirectrouteBGPDirectEXTrouteBABELrouteSHARProutePBRrouteBFDrouteOpenfabricrouteVRRProuteNHGrouteSRTErouteAllrouteMax"
-var _RouteType_index = [...]uint16{0, 11, 22, 34, 45, 53, 63, 72, 82, 91, 99, 107, 117, 126, 135, 144, 154, 162, 170, 184, 200, 214, 231, 241, 251, 259, 267, 282, 291, 299, 307, 315}
+var _RouteType_index = [...]uint16{0, 11, 22, 34, 45, 53, 63, 72, 82, 91, 99, 107, 117, 126, 135, 144, 154, 162, 170, 184, 200, 214, 231, 241, 251, 259, 267, 282, 291, 299, 308, 316, 324}
func (i RouteType) String() string {
if i >= RouteType(len(_RouteType_index)-1) {
diff --git a/internal/pkg/zebra/zapi.go b/internal/pkg/zebra/zapi.go
index 32e9d8d2..9cc78107 100644
--- a/internal/pkg/zebra/zapi.go
+++ b/internal/pkg/zebra/zapi.go
@@ -115,8 +115,8 @@ const (
const softwareNameMinimumVersion uint8 = 5
var allowableSoftwareNameArrays = [][]string{
- {"frr4", "cumulus"}, //version:5
- {"frr7.2", "frr7", "frr6"}, //version:6
+ {"frr4", "cumulus"}, //version:5
+ {"frr7.3", "frr7.2", "frr7", "frr6"}, //version:6
}
// IsAllowableSoftwareName returns bool from version number and softwareName
@@ -317,71 +317,83 @@ const (
_interfaceLinkParams
_mplsLabelsAdd
_mplsLabelsDelete
- _mplsLabelsReplace // add in frr7.3
+ _mplsLabelsReplace // add in frr7.3
+ _srPolicySet // add in frr7.5
+ _srPolicyDelete // 50 // add in frr7.5
+ _srPolicyNotifyStatus // add in frr7.5
_ipmrRouteStats
- labelManagerConnect // 50
+ labelManagerConnect // 53
labelManagerConnectAsync // add in frr5
getLabelChunk
releaseLabelChunk
_fecRegister
_fecUnregister
_fecUpdate
- _advertiseDefaultGW
- _advertiseSviMACIP // add in frr7.1
+ _advertiseDefaultGW // 60
+ _advertiseSviMACIP // add in frr7.1
_advertiseSubnet
- _advertiseAllVNI // 60
+ _advertiseAllVNI // 63
_localESAdd
- _localESDel
- _vniAdd
+ _localESDel // 65
+ _remoteESVTEPAdd // add in frr7.5
+ _remoteESVTEPDel // add in frr7.5
+ _localESEVIAdd // add in frr7.5
+ _localESEVIDel // add in frr7.5
+ _vniAdd // 70
_vniDel
_l3VNIAdd
_l3VNIDel
_remoteVTEPAdd
_remoteVTEPDel
_macIPAdd
- _macIPDel // 70
+ _macIPDel // 77
_ipPrefixRouteAdd
_ipPrefixRouteDel
- _remoteMACIPAdd
+ _remoteMACIPAdd // 80
_remoteMACIPDel
_duplicateAddrDetection
_pwAdd
_pwDelete
_pwSet
_pwUnset
- _pwStatusUpdate // 80
+ _pwStatusUpdate // 87
_ruleAdd
_ruleDelete
- _ruleNotifyOwner
+ _ruleNotifyOwner // 90
_tableManagerConnect
_getTableChunk
_releaseTableChunk
_ipSetCreate
_ipSetDestroy
_ipSetEntryAdd
- _ipSetEntryDelete // 90
+ _ipSetEntryDelete // 97
_ipSetNotifyOwner
_ipSetEntryNotifyOwner
- _ipTableAdd
+ _ipTableAdd // 100
_ipTableDelete
_ipTableNotifyOwner
_vxlanFloodControl
_vxlanSgAdd
_vxlanSgDel
_vxlanSgReplay
- _mlagProcessUp // 100 // add in frr7.3
+ _mlagProcessUp // 107 // add in frr7.3
_mlagProcessDown // add in frr7.3
_mlagClientRegister // add in frr7.3
- _mlagClientUnregister // add in frr7.3
+ _mlagClientUnregister // 110 // add in frr7.3
_mlagClientForwardMsg // add in frr7.3
zebraError // add in frr7.3
_clientCapabilities // add in frr7.4
+ _opaqueMessage // add in frr7.5
+ _opaqueRegister // add in frr7.5
+ _opaqueUnregister // add in frr7.5
+ _neighDiscover // 117 // add in frr7.5
// BackwardIPv6RouteAdd is referred in zclient_test
BackwardIPv6RouteAdd // quagga, frr3, frr4, frr5
// BackwardIPv6RouteDelete is referred in zclient_test
BackwardIPv6RouteDelete // quagga, frr3, frr4, frr5
)
const (
+ zapi6Frr7dot3MinDifferentAPIType APIType = 49 //frr7.3(zapi6)
zapi6Frr7dot2MinDifferentAPIType APIType = 48 //frr7.2(zapi6)
zapi5ClMinDifferentAPIType APIType = 19 //cumuluslinux3.7.7, zebra4.0+cl3u13(zapi5)
zapi5MinDifferentAPIType APIType = 7 //frr4&5(zapi5), frr6&7.0&7.1(zapi6)
@@ -399,15 +411,31 @@ func minDifferentAPIType(version uint8, softwareName string) APIType {
} else if version == 5 ||
(version == 6 && (softwareName == "frr6" || softwareName == "frr7")) {
return zapi5MinDifferentAPIType
+ } else if version == 6 && softwareName == "frr7.2" {
+ return zapi6Frr7dot2MinDifferentAPIType
}
- return zapi6Frr7dot2MinDifferentAPIType
+ return zapi6Frr7dot3MinDifferentAPIType
}
const (
- zapi6Frr7dot2LabelManagerConnect APIType = 49 // difference from frr7.3
- zapi6Frr7dot2LabelManagerConnectAsync APIType = 50 // difference from frr7.3
- zapi6Frr7dot2GetLabelChunk APIType = 51 // difference from frr7.3
- zapi6Frr7dot2ReleaseLabelChunk APIType = 52 // difference from frr7.3
+ zapi6Frr7dot3LabelManagerConnect APIType = 50 // difference from frr7.5
+ zapi6Frr7dot3LabelManagerConnectAsync APIType = 51 // difference from frr7.5
+ zapi6Frr7dot3GetLabelChunk APIType = 52 // difference from frr7.5
+ zapi6Frr7dot3ReleaseLabelChunk APIType = 53 // difference from frr7.5
+)
+
+var apiTypeZapi6Frr7dot3Map = map[APIType]APIType{
+ labelManagerConnect: zapi6Frr7dot3LabelManagerConnect,
+ labelManagerConnectAsync: zapi6Frr7dot3LabelManagerConnectAsync,
+ getLabelChunk: zapi6Frr7dot3GetLabelChunk,
+ releaseLabelChunk: zapi6Frr7dot3ReleaseLabelChunk,
+}
+
+const (
+ zapi6Frr7dot2LabelManagerConnect APIType = 49 // difference from frr7.5
+ zapi6Frr7dot2LabelManagerConnectAsync APIType = 50 // difference from frr7.5
+ zapi6Frr7dot2GetLabelChunk APIType = 51 // difference from frr7.5
+ zapi6Frr7dot2ReleaseLabelChunk APIType = 52 // difference from frr7.5
)
var apiTypeZapi6Frr7dot2Map = map[APIType]APIType{
@@ -656,7 +684,9 @@ func (t APIType) doesNeedConversion(version uint8, softwareName string) bool {
return true
}
func apiTypeMap(version uint8, softwareName string) map[APIType]APIType {
- if version == 6 && softwareName == "frr7" {
+ if version == 6 && softwareName == "frr7.2" {
+ return apiTypeZapi6Frr7dot2Map
+ } else if version == 6 && softwareName == "frr7" {
return apiTypeZapi6Frr7Map
} else if version == 6 && softwareName == "frr6" {
return apiTypeZapi6Frr6Map
@@ -672,7 +702,7 @@ func apiTypeMap(version uint8, softwareName string) map[APIType]APIType {
} else if version < 4 {
return apiTypeZapi3Map
}
- return apiTypeZapi6Frr7dot2Map
+ return apiTypeZapi6Frr7dot3Map
}
// ToEach is referred in zclient_test
@@ -762,6 +792,7 @@ const (
routeOpenfabric // FRRRouting version 7 (Zapi6) adds.
routeVRRP // FRRRouting version 7.2 (Zapi6) adds.
routeNHG // FRRRouting version 7.3 (Zapi6) adds.
+ routeSRTE // FRRRouting version 7.5 (Zapi6) adds.
routeAll
routeMax // max value for error
)
@@ -771,6 +802,7 @@ const (
zapi6Frr6RouteAll RouteType = 26
zapi6Frr7RouteAll RouteType = 27
zapi6Frr7dot2RouteAll RouteType = 28
+ zapi6Frr7dot3RouteAll RouteType = 29
)
func getRouteAll(version uint8, softwareName string) RouteType {
@@ -786,6 +818,8 @@ func getRouteAll(version uint8, softwareName string) RouteType {
return zapi6Frr7RouteAll
} else if softwareName == "frr7.2" {
return zapi6Frr7dot2RouteAll
+ } else if softwareName == "frr7.3" {
+ return zapi6Frr7dot3RouteAll
}
}
return routeAll
@@ -881,6 +915,7 @@ var routeTypeValueMap = map[string]RouteType{
"openfabric": routeOpenfabric, // add in frr7.0(zapi6)
"vrrp": routeVRRP, // add in frr7.2(zapi6)
"nhg": routeNHG, // add in frr7.3(zapi6)
+ "srte": routeSRTE, // add in frr7.5(zapi6)
"wildcard": routeAll,
}
@@ -918,7 +953,7 @@ func ipFromFamily(family uint8, buf []byte) net.IP {
}
// MessageFlag is the type of API Message Flags.
-type MessageFlag uint8
+type MessageFlag uint32 // MESSAGE_FLAG is 32bit after frr7.5, 8bit before frr7.4
const ( // For FRRouting version 4, 5 and 6 (ZAPI version 5 and 6).
// MessageNexthop is referred in zclient
@@ -932,9 +967,10 @@ const ( // For FRRouting version 4, 5 and 6 (ZAPI version 5 and 6).
MessageMTU MessageFlag = 0x10
messageSRCPFX MessageFlag = 0x20
// MessageLabel is referred in zclient
- MessageLabel MessageFlag = 0x40 // deleted in frr7.3
- messageBackupNexthops MessageFlag = 0x40 // added in frr7.4
- messageTableID MessageFlag = 0x80 // introduced in frr5
+ MessageLabel MessageFlag = 0x40 // deleted in frr7.3
+ messageBackupNexthops MessageFlag = 0x40 // added in frr7.4
+ messageTableID MessageFlag = 0x80 // introduced in frr5
+ messageSRTE MessageFlag = 0x100 // introduced in frr7.5
)
const ( // For FRRouting.
@@ -993,7 +1029,7 @@ func (f MessageFlag) string(version uint8, softwareName string) string {
if version > 3 && f&messageSRCPFX.ToEach(version) > 0 {
ss = append(ss, "SRCPFX")
}
- if version == 6 && softwareName == "" && f&messageBackupNexthops > 0 { // added in frr7.4
+ if version == 6 && softwareName == "" && f&messageBackupNexthops > 0 { // added in frr7.4, frr7.5
ss = append(ss, "BACKUP_NEXTHOPS")
} else if version > 4 && f&MessageLabel > 0 {
ss = append(ss, "LABEL")
@@ -1001,6 +1037,9 @@ func (f MessageFlag) string(version uint8, softwareName string) string {
if version > 5 && f&messageTableID > 0 {
ss = append(ss, "TABLEID")
}
+ if version == 6 && softwareName == "" && f&messageSRTE > 0 { // added in frr7.5
+ ss = append(ss, "SRTE")
+ }
return strings.Join(ss, "|")
}
@@ -1407,7 +1446,16 @@ func (c *Client) SendHello() error {
// SendRouterIDAdd sends ROUTER_ID_ADD message to zebra daemon.
func (c *Client) SendRouterIDAdd() error {
- return c.sendCommand(routerIDAdd, DefaultVrf, nil)
+ bodies := make([]*routerIDUpdateBody, 0)
+ for _, afi := range []afi{afiIP, afiIP6} {
+ bodies = append(bodies, &routerIDUpdateBody{
+ afi: afi,
+ })
+ }
+ for _, body := range bodies {
+ c.sendCommand(routerIDAdd, DefaultVrf, body)
+ }
+ return nil
}
// SendInterfaceAdd sends INTERFACE_ADD message to zebra daemon.
@@ -1417,7 +1465,6 @@ func (c *Client) SendInterfaceAdd() error {
// SendRedistribute sends REDISTRIBUTE message to zebra daemon.
func (c *Client) SendRedistribute(t RouteType, vrfID uint32) error {
-
if c.redistDefault != t {
bodies := make([]*redistributeBody, 0)
if c.Version <= 3 {
@@ -1435,7 +1482,7 @@ func (c *Client) SendRedistribute(t RouteType, vrfID uint32) error {
}
for _, body := range bodies {
- return c.sendCommand(redistributeAdd, vrfID, body)
+ c.sendCommand(redistributeAdd, vrfID, body)
}
}
return nil
@@ -1634,16 +1681,22 @@ func (b *unknownBody) string(version uint8, softwareName string) string {
type helloBody struct {
redistDefault RouteType
instance uint16
+ sessionID uint32 // frr7.4, frr7.5
receiveNotify uint8
+ synchronous uint8 // frr7.4, frr7.5
}
// Ref: zread_hello in zebra/zserv.c of Quagga1.2&FRR3 (ZAPI3&4)
// Ref: zread_hello in zebra/zapi_msg.c of FRR5 (ZAPI5)
func (b *helloBody) decodeFromBytes(data []byte, version uint8, softwareName string) error {
b.redistDefault = RouteType(data[0])
- if version >= 4 {
+ if version > 3 { //frr
b.instance = binary.BigEndian.Uint16(data[1:3])
- if version >= 5 {
+ if version == 6 && softwareName == "" { // frr7.5
+ b.sessionID = binary.BigEndian.Uint32(data[3:7])
+ b.receiveNotify = data[7]
+ b.synchronous = data[8]
+ } else if version > 4 {
b.receiveNotify = data[3]
}
}
@@ -1656,14 +1709,20 @@ func (b *helloBody) serialize(version uint8, softwareName string) ([]byte, error
return []byte{uint8(b.redistDefault)}, nil
}
var buf []byte
- if version == 4 {
- buf = make([]byte, 3)
+ if version == 6 && softwareName == "" { // frr7.5
+ buf = make([]byte, 9)
} else if version > 4 {
buf = make([]byte, 4)
+ } else if version == 4 {
+ buf = make([]byte, 3)
}
buf[0] = uint8(b.redistDefault)
binary.BigEndian.PutUint16(buf[1:3], b.instance)
- if version > 4 {
+ if version == 6 && softwareName == "" { // frr7.5
+ binary.BigEndian.PutUint32(buf[3:7], b.sessionID)
+ buf[7] = b.receiveNotify
+ buf[8] = b.synchronous
+ } else if version > 4 {
buf[3] = b.receiveNotify
}
return buf, nil
@@ -1870,6 +1929,7 @@ func (b *interfaceAddressUpdateBody) string(version uint8, softwareName string)
type routerIDUpdateBody struct {
length uint8
prefix net.IP
+ afi afi
}
// Ref: zebra_router_id_update_read in lib/zclient.c of Quagga1.2&FRR3&FRR5 (ZAPI3&4&5)
@@ -1885,7 +1945,12 @@ func (b *routerIDUpdateBody) decodeFromBytes(data []byte, version uint8, softwar
return nil
}
+// Ref: zclient_send_router_id_update in lib/zclient.c of FRR7.5
func (b *routerIDUpdateBody) serialize(version uint8, softwareName string) ([]byte, error) {
+ if version == 6 && softwareName == "" {
+ //stream_putw(s, afi);
+ return []byte{0x00, uint8(b.afi)}, nil
+ }
return []byte{}, nil
}
@@ -1894,9 +1959,11 @@ func (b *routerIDUpdateBody) string(version uint8, softwareName string) string {
}
const (
- zapiNexthopFlagOnlink uint8 = 0x01 // frr7.1, 7.2, 7.3, 7.4
- zapiNexthopFlagLabel uint8 = 0x02 // frr7.3, 7.4
- zapiNexthopFlagWeight uint8 = 0x04 // frr7.3, 7.4
+ zapiNexthopFlagOnlink uint8 = 0x01 // frr7.1, 7.2, 7.3, 7.4, 7.5
+ zapiNexthopFlagLabel uint8 = 0x02 // frr7.3, 7.4, 7.5
+ zapiNexthopFlagWeight uint8 = 0x04 // frr7.3, 7.4, 7.5
+ zapiNexthopFlagHasBackup uint8 = 0x08 // frr7.4, 7.5
+
)
// Flag for nexthop processing. It is gobgp's internal flag.
@@ -1921,7 +1988,7 @@ func nexthopProcessFlagForIPRouteBody(version uint8, softwareName string, isDeco
processFlag := (nexthopHasVrfID | nexthopHasType) // frr4, 5, 6, 7
if version == 6 {
switch softwareName {
- case "":
+ case "", "frr7.3":
processFlag |= (nexthopHasFlag | nexthopProcessIPToIPIFindex)
case "frr7.2", "frr7.0":
processFlag |= nexthopHasOnlink
@@ -1942,6 +2009,9 @@ type Nexthop struct {
MplsLabels []uint32
weight uint32
rmac [6]byte
+ srteColor uint32
+ backupNum uint8
+ backupIndex []uint8
}
func (n Nexthop) string() string {
@@ -1994,6 +2064,9 @@ func (n Nexthop) encode(version uint8, softwareName string, processFlag nexthopP
if n.weight > 0 {
n.flags |= zapiNexthopFlagWeight
}
+ if n.backupNum > 0 {
+ n.flags |= zapiNexthopFlagHasBackup
+ }
}
if processFlag&nexthopHasFlag > 0 || processFlag&nexthopHasOnlink > 0 {
// frr7.1, 7.2 has onlink, 7.3 has flag
@@ -2051,6 +2124,20 @@ func (n Nexthop) encode(version uint8, softwareName string, processFlag nexthopP
//frr: stream_put(s, &(api_nh->rmac), sizeof(struct ethaddr));
buf = append(buf, n.rmac[:]...)
}
+ // added in frr7.5 (Color for Segment Routing TE.)
+ if message&messageSRTE > 0 && (version == 6 && softwareName == "") {
+ tmpbuf := make([]byte, 4)
+ binary.BigEndian.PutUint32(tmpbuf, uint32(n.srteColor))
+ buf = append(buf, tmpbuf...) //frr: stream_putl(s, api_nh->srte_color);
+ }
+ if n.flags&zapiNexthopFlagHasBackup > 0 {
+ tmpbuf := make([]byte, 1+1*n.backupNum)
+ tmpbuf[0] = n.backupNum //frr: stream_putc(s, api_nh->backup_num);
+ for i := uint8(0); i < n.backupNum; i++ {
+ tmpbuf[i+1] = n.backupIndex[i]
+ }
+ buf = append(buf, tmpbuf...)
+ }
return buf
}
@@ -2109,7 +2196,10 @@ func (n *Nexthop) decode(data []byte, version uint8, softwareName string, family
n.blackholeType = data[offset] //frr: STREAM_GETC(s, api_nh->bh_type);
offset++
}
- if n.flags&zapiNexthopFlagLabel > 0 || message&MessageLabel > 0 {
+ if n.flags&zapiNexthopFlagLabel > 0 || (message&MessageLabel > 0 &&
+ (version == 5 || version == 6 &&
+ (softwareName == "frr6" || softwareName == "frr7" ||
+ softwareName == "frr7.2"))) {
n.LabelNum = uint8(data[offset]) //frr: STREAM_GETC(s, api_nh->label_num);
offset++
if n.LabelNum > maxMplsLabel {
@@ -2136,6 +2226,25 @@ func (n *Nexthop) decode(data []byte, version uint8, softwareName string, family
copy(n.rmac[0:], data[offset:offset+6])
offset += 6
}
+ // added in frr7.5 (Color for Segment Routing TE.)
+ if message&messageSRTE > 0 && (version == 6 && softwareName == "") {
+ //STREAM_GETL(s, api_nh->srte_color);
+ n.srteColor = binary.BigEndian.Uint32(data[offset:])
+ offset += 4
+ }
+ // added in frr7.4 (Index of backup nexthop)
+ if n.flags&zapiNexthopFlagHasBackup > 0 {
+ n.backupNum = data[offset] //frr: STREAM_GETC(s, api_nh->backup_num);
+ offset++
+ if n.backupNum > 0 {
+ n.backupIndex = make([]uint8, n.backupNum)
+ for i := uint8(0); i < n.backupNum; i++ {
+ //frr STREAM_GETC(s, api_nh->backup_idx[i]);
+ n.backupIndex[i] = data[offset]
+ offset++
+ }
+ }
+ }
return offset, nil
}
@@ -2186,6 +2295,7 @@ type IPRouteBody struct {
Mtu uint32
tag uint32
tableID uint32
+ srteColor uint32
API APIType // API is referred in zclient_test
}
@@ -2261,13 +2371,25 @@ func (b *IPRouteBody) IsWithdraw(version uint8, softwareName string) bool {
func (b *IPRouteBody) serialize(version uint8, softwareName string) ([]byte, error) {
var buf []byte
numNexthop := len(b.Nexthops)
- if version <= 3 {
- buf = make([]byte, 5)
- } else if version == 4 {
- buf = make([]byte, 10)
- } else { // version >= 5
- buf = make([]byte, 9) //type(1)+instance(2)+flags(4)+message(1)+safi(1)
+
+ bufInitSize := 12
+ switch version {
+ case 2, 3:
+ bufInitSize = 5
+ case 4:
+ bufInitSize = 10
+ case 5:
+ bufInitSize = 9 //type(1)+instance(2)+flags(4)+message(1)+safi(1)
+ case 6:
+ switch softwareName {
+ case "frr6", "frr7", "frr7.2", "frr7.3":
+ bufInitSize = 9 //type(1)+instance(2)+flags(4)+message(1)+safi(1)
+ default:
+ bufInitSize = 12 //type(1)+instance(2)+flags(4)+message(4)+safi(1)
+ }
}
+ buf = make([]byte, bufInitSize)
+
buf[0] = uint8(b.Type.toEach(version, softwareName)) //frr: stream_putc(s, api->type);
if version < 4 {
buf[1] = uint8(b.Flags)
@@ -2278,27 +2400,33 @@ func (b *IPRouteBody) serialize(version uint8, softwareName string) ([]byte, err
binary.BigEndian.PutUint16(buf[1:3], uint16(b.instance))
//frr: stream_putl(s, api->flags);
binary.BigEndian.PutUint32(buf[3:7], uint32(b.Flags))
- //frr: stream_putc(s, api->message);
- buf[7] = uint8(b.Message)
- if version == 4 {
- binary.BigEndian.PutUint16(buf[8:10], uint16(b.Safi))
- } else { // version >= 5
- //frr: stream_putc(s, api->safi);
- buf[8] = uint8(b.Safi)
-
- // only zapi version 5 (frr4.0.x) have evpn routes
- if version == 5 && b.Flags&flagEvpnRoute.ToEach(version, softwareName) > 0 {
- // size of struct ethaddr is 6 octets defined by ETH_ALEN
- buf = append(buf, b.Nexthops[numNexthop-1].rmac[:6]...)
- }
-
- if b.Prefix.Family == syscall.AF_UNSPEC {
- b.Prefix.Family = familyFromPrefix(b.Prefix.Prefix)
+ if version == 6 && softwareName == "" {
+ //frr7.5: stream_putl(s, api->message);
+ binary.BigEndian.PutUint32(buf[7:11], uint32(b.Message))
+ buf[11] = uint8(b.Safi)
+ } else {
+ //before frr7.4: stream_putc(s, api->message);
+ buf[7] = uint8(b.Message)
+ if version > 4 {
+ //frr: stream_putc(s, api->safi);
+ buf[8] = uint8(b.Safi)
+ } else { // version 2,3 and 4 (quagga, frr3)
+ binary.BigEndian.PutUint16(buf[8:10], uint16(b.Safi))
}
- //frr: stream_putc(s, api->prefix.family);
- buf = append(buf, b.Prefix.Family)
}
}
+ // only zapi version 5 (frr4.0.x) have evpn routes
+ if version == 5 && b.Flags&flagEvpnRoute.ToEach(version, softwareName) > 0 {
+ // size of struct ethaddr is 6 octets defined by ETH_ALEN
+ buf = append(buf, b.Nexthops[numNexthop-1].rmac[:6]...)
+ }
+ if version > 4 { // version 5, 6 (after frr4)
+ if b.Prefix.Family == syscall.AF_UNSPEC {
+ b.Prefix.Family = familyFromPrefix(b.Prefix.Prefix)
+ }
+ //frr: stream_putc(s, api->prefix.family);
+ buf = append(buf, b.Prefix.Family)
+ }
byteLen := (int(b.Prefix.PrefixLen) + 7) / 8
buf = append(buf, b.Prefix.PrefixLen) //frr: stream_putc(s, api->prefix.prefixlen);
//frr: stream_write(s, (uint8_t *)&api->prefix.u.prefix, psize);
@@ -2329,7 +2457,8 @@ func (b *IPRouteBody) serialize(version uint8, softwareName string) ([]byte, err
buf = append(buf, nexthop.encode(version, softwareName, processFlag, b.Message, b.Flags)...)
}
}
- if b.Message&messageBackupNexthops > 0 { // added in frr7.4
+ // MESSAGE_BACKUP_NEXTHOPS is added in frr7.4
+ if version == 6 && softwareName == "" && b.Message&messageBackupNexthops > 0 {
tmpbuf := make([]byte, 2)
binary.BigEndian.PutUint16(tmpbuf, uint16(len(b.backupNexthops)))
buf = append(buf, tmpbuf...) //frr: stream_putw(s, api->nexthop_num);
@@ -2428,17 +2557,23 @@ func (b *IPRouteBody) decodeFromBytes(data []byte, version uint8, softwareName s
b.Flags = Flag(binary.BigEndian.Uint32(data[3:7]))
data = data[7:]
}
-
- b.Message = MessageFlag(data[0]) //frr: STREAM_GETC(s, api->message);
+ if version == 6 && softwareName == "" {
+ //frr7.5: STREAM_GETL(s, api->message);
+ b.Message = MessageFlag(binary.BigEndian.Uint32(data[0:4]))
+ data = data[4:]
+ } else {
+ b.Message = MessageFlag(data[0]) //frr: STREAM_GETC(s, api->message);
+ data = data[1:]
+ }
b.Safi = Safi(SafiUnicast)
b.Prefix.Family = b.API.addressFamily(version) // return AF_UNSPEC if version > 4
var evpnNexthop Nexthop
if version > 4 {
- b.Safi = Safi(data[1]) //frr: STREAM_GETC(s, api->safi);
+ b.Safi = Safi(data[0]) //frr: STREAM_GETC(s, api->safi);
if b.Safi > safiMax { //frr5 and later work, ToDo: fix for older version
return fmt.Errorf("unknown safi type: %d in version: %d (%s)", b.Type, version, softwareName)
}
- data = data[2:]
+ data = data[1:]
// zapi version 5 only
if version == 5 && b.Flags&flagEvpnRoute.ToEach(version, softwareName) > 0 {
@@ -2448,6 +2583,7 @@ func (b *IPRouteBody) decodeFromBytes(data []byte, version uint8, softwareName s
}
b.Prefix.Family = data[0] //frr: STREAM_GETC(s, api->prefix.family);
+ data = data[1:]
}
addrByteLen, err := addressByteLength(b.Prefix.Family)
@@ -2457,11 +2593,11 @@ func (b *IPRouteBody) decodeFromBytes(data []byte, version uint8, softwareName s
addrBitLen := uint8(addrByteLen * 8)
- b.Prefix.PrefixLen = data[1] //frr: STREAM_GETC(s, api->prefix.prefixlen);
+ b.Prefix.PrefixLen = data[0] //frr: STREAM_GETC(s, api->prefix.prefixlen);
if b.Prefix.PrefixLen > addrBitLen {
return fmt.Errorf("prefix length %d is greater than %d", b.Prefix.PrefixLen, addrBitLen)
}
- data = data[2:]
+ data = data[1:]
pos := 0
rest := len(data)
@@ -2474,6 +2610,7 @@ func (b *IPRouteBody) decodeFromBytes(data []byte, version uint8, softwareName s
copy(buf, data[pos:pos+byteLen])
b.Prefix.Prefix = ipFromFamily(b.Prefix.Family, buf)
pos += byteLen
+
if version > 3 && b.Message&messageSRCPFX.ToEach(version) > 0 {
if pos+1 > rest {
return fmt.Errorf("MessageSRCPFX message length invalid pos:%d rest:%d", pos, rest)
@@ -2496,21 +2633,28 @@ func (b *IPRouteBody) decodeFromBytes(data []byte, version uint8, softwareName s
}
b.Nexthops = []Nexthop{}
- offset, err := b.decodeMessageNexthopFromBytes(data[pos:], version, softwareName, false)
- if err != nil {
- return err
+ if b.Message&MessageNexthop.ToEach(version) > 0 {
+ offset, err := b.decodeMessageNexthopFromBytes(data[pos:], version, softwareName, false)
+ if err != nil {
+ return err
+ }
+ pos += offset
}
- pos += offset
+
b.backupNexthops = []Nexthop{} // backupNexthops is added in frr7.4
- offset, err = b.decodeMessageNexthopFromBytes(data[pos:], version, softwareName, true)
- if err != nil {
- return err
+ if b.Message&messageBackupNexthops.ToEach(version) > 0 {
+ offset, err := b.decodeMessageNexthopFromBytes(data[pos:], version, softwareName, true)
+ if err != nil {
+ return err
+ }
+ pos += offset
}
- pos += offset
+
// version 5 only, In version 6, EvpnRoute is processed in MessageNexthop
if version == 5 && b.Flags&flagEvpnRoute.ToEach(version, softwareName) > 0 {
b.Nexthops = append(b.Nexthops, evpnNexthop)
}
+
if version < 5 && b.Message&messageIFIndex > 0 { // version 4, 3, 2
if pos+1 > rest {
return fmt.Errorf("MessageIFIndex message length invalid pos:%d rest:%d", pos, rest)
@@ -2792,17 +2936,27 @@ func (b *NexthopRegisterBody) string(version uint8, softwareName string) string
// NexthopUpdateBody uses same data structure as IPRoute (zapi_route) after frr4 (Zapi5)
type NexthopUpdateBody IPRouteBody
-// Ref: send_client in zebra/zebra_rnh.c of Quagga1.2&FRR3&FRR5(ZAPI3&4$5)
+// Ref: send_client in zebra/zebra_rnh.c of Quagga1.2&FRR3&FRR5(ZAPI3&4$5) and befre FRR7.4
+// Ref: zebra_send_rnh_update zebra/zebra_rnh.c of FRR7.5
func (b *NexthopUpdateBody) serialize(version uint8, softwareName string) ([]byte, error) {
+ var buf []byte
+ offset := 0
+ if version == 6 && softwareName == "" { // after frr7.5
+ buf = make([]byte, 7)
+ binary.BigEndian.PutUint32(buf, uint32(b.Message))
+ offset += 4
+ } else { // before frr7.4
+ buf = make([]byte, 3)
+ }
+
// Address Family (2 bytes)
- buf := make([]byte, 3)
- binary.BigEndian.PutUint16(buf, uint16(b.Prefix.Family))
+ binary.BigEndian.PutUint16(buf[offset:], uint16(b.Prefix.Family))
addrByteLen, err := addressByteLength(b.Prefix.Family)
if err != nil {
return nil, err
}
- buf[2] = byte(addrByteLen * 8)
+ buf[offset+2] = byte(addrByteLen * 8)
// Prefix Length (1 byte) + Prefix (variable)
switch b.Prefix.Family {
case syscall.AF_INET:
@@ -2812,6 +2966,11 @@ func (b *NexthopUpdateBody) serialize(version uint8, softwareName string) ([]byt
default:
return nil, fmt.Errorf("invalid address family: %d", b.Prefix.Family)
}
+ if b.Message&messageSRTE > 0 { // frr 7.5
+ tmpbuf := make([]byte, 4)
+ binary.BigEndian.PutUint32(tmpbuf, b.srteColor)
+ buf = append(buf, tmpbuf...)
+ }
if version >= 5 {
// Type (1 byte) (if version>=5)
// instance (2 bytes) (if version>=5)
@@ -2837,6 +2996,11 @@ func (b *NexthopUpdateBody) serialize(version uint8, softwareName string) ([]byt
// Ref: bgp_parse_nexthop_update in bgpd/bgp_nht.c of Quagga1.2&FRR3 (ZAPI3&4)
// Ref: zapi_nexthop_update_decode in lib/zclient.c of FRR5.x (ZAPI5)
func (b *NexthopUpdateBody) decodeFromBytes(data []byte, version uint8, softwareName string) error {
+ if version == 6 && softwareName == "" { // frr7.5
+ //frr7.5: STREAM_GETL(s, nhr->message);
+ b.Message = MessageFlag(binary.BigEndian.Uint32(data[0:4]))
+ data = data[4:]
+ }
// Address Family (2 bytes)
prefixFamily := binary.BigEndian.Uint16(data[0:2])
b.Prefix.Family = uint8(prefixFamily)
@@ -2851,6 +3015,11 @@ func (b *NexthopUpdateBody) decodeFromBytes(data []byte, version uint8, software
b.Prefix.Prefix = ipFromFamily(b.Prefix.Family, data[offset:offset+addrByteLen])
offset += addrByteLen
+ if b.Message&messageSRTE > 0 { // frr 7.5
+ b.srteColor = binary.BigEndian.Uint32(data[offset : offset+4])
+ offset += 4
+ }
+
if version > 4 {
b.Type = RouteType(data[offset])
b.instance = binary.BigEndian.Uint16(data[offset+1 : offset+3])
@@ -2876,7 +3045,7 @@ func (b *NexthopUpdateBody) decodeFromBytes(data []byte, version uint8, software
processFlag := nexthopProcessFlag(nexthopHasType)
if version == 6 {
switch softwareName {
- case "":
+ case "", "frr7.3":
processFlag |= (nexthopHasVrfID | nexthopHasFlag | nexthopProcessIPToIPIFindex)
case "frr7.0", "frr7.2":
processFlag |= (nexthopHasVrfID | nexthopProcessIPToIPIFindex)
@@ -2885,20 +3054,20 @@ func (b *NexthopUpdateBody) decodeFromBytes(data []byte, version uint8, software
}
} else if version == 5 {
switch softwareName {
- case "frr5", "":
+ case "":
processFlag |= nexthopProcessIPToIPIFindex
}
} else if version < 4 { // quagga
processFlag |= nexthopProcessIFnameToIFindex
}
- message := MessageFlag(0)
+ // after frr7.3, MessageLabel is deleted
if (version == 6 && !(softwareName == "frr7.3" || softwareName == "")) ||
- (version == 5 && (softwareName == "frr5" || softwareName == "")) {
- message |= MessageLabel
+ (version == 5 && softwareName == "") {
+ b.Message |= MessageLabel
}
- nexthopsByteLen, err := decodeNexthops(&b.Nexthops, data[offset:], version, softwareName, b.Prefix.Family, numNexthop, processFlag, message, Flag(0), nexthopType(0))
+ nexthopsByteLen, err := decodeNexthops(&b.Nexthops, data[offset:], version, softwareName, b.Prefix.Family, numNexthop, processFlag, b.Message, Flag(0), nexthopType(0))
if err != nil {
return err
}
diff --git a/internal/pkg/zebra/zapi_test.go b/internal/pkg/zebra/zapi_test.go
index 61ccf94b..b110b4ff 100644
--- a/internal/pkg/zebra/zapi_test.go
+++ b/internal/pkg/zebra/zapi_test.go
@@ -211,13 +211,13 @@ func Test_routerIDUpdateBody(t *testing.T) {
func Test_IPRouteBody_IPv4(t *testing.T) {
assert := assert.New(t)
- size := map[uint8]uint8{2: 26, 3: 26, 4: 31, 5: 38, 6: 39}
+ size := map[uint8]uint8{2: 26, 3: 26, 4: 31, 5: 38, 6: 42}
command := map[uint8]APIType{
2: zapi3IPv4RouteAdd,
3: zapi3IPv4RouteAdd,
4: zapi4IPv4RouteAdd,
5: zapi6Frr7RouteAdd,
- 6: zapi6Frr7RouteAdd,
+ 6: RouteAdd,
}
routeType := routeConnect
message := map[uint8]MessageFlag{
@@ -237,7 +237,6 @@ func Test_IPRouteBody_IPv4(t *testing.T) {
for v := MinZapiVer; v <= MaxZapiVer; v++ {
//decodeFromBytes IPV4_ROUTE
buf := make([]byte, size[v])
- //buf[0] = byte(routeType[v])
buf[0] = byte(routeType)
pos := 1
switch v {
@@ -250,8 +249,13 @@ func Test_IPRouteBody_IPv4(t *testing.T) {
binary.BigEndian.PutUint32(buf[pos:], uint32(FlagSelected.ToEach(v, "")))
pos += 4
}
- buf[pos] = byte(message[v])
- pos++
+ if v == 6 {
+ binary.BigEndian.PutUint32(buf[pos:], uint32(message[v])) // frr7.5: 32bit
+ pos += 4
+ } else {
+ buf[pos] = uint8(message[v]) // before frr7.4: 8bit
+ pos++
+ }
if v > 4 {
buf[pos] = byte(SafiUnicast) //SAFI
pos++
@@ -318,10 +322,14 @@ func Test_IPRouteBody_IPv4(t *testing.T) {
case 2, 3:
assert.Equal([]byte{0x2, 0x10, byte(message[v])}, buf[0:3])
pos = 3
- case 4, 5, 6:
+ case 4, 5:
tmpFlag := byte(0xff & FlagSelected.ToEach(v, ""))
assert.Equal([]byte{0x2, 0x00, 0x00, 0x00, 0x00, 0x00, tmpFlag, byte(message[v])}, buf[0:8])
pos = 8
+ case 6: // frr 7.5: MessageFlag: 32bit
+ tmpFlag := byte(0xff & FlagSelected.ToEach(v, ""))
+ assert.Equal([]byte{0x2, 0x00, 0x00, 0x00, 0x00, 0x00, tmpFlag, 0x00, 0x00, 0x00, byte(message[v])}, buf[0:11])
+ pos = 11
}
switch v {
case 2, 3, 4:
@@ -334,6 +342,7 @@ func Test_IPRouteBody_IPv4(t *testing.T) {
pos++
}
+
assert.Equal(byte(24), buf[pos])
pos++
ip = net.ParseIP("192.168.100.0").To4()
@@ -374,7 +383,6 @@ func Test_IPRouteBody_IPv4(t *testing.T) {
// length invalid
buf = make([]byte, size[v]-8)
- //buf[0] = byte(routeType[v])
buf[0] = byte(routeConnect)
pos = 1
switch v {
@@ -387,8 +395,14 @@ func Test_IPRouteBody_IPv4(t *testing.T) {
binary.BigEndian.PutUint32(buf[pos:], uint32(FlagSelected.ToEach(v, "")))
pos += 4
}
- buf[pos] = byte(message[v])
- pos++
+ if v == 6 {
+ binary.BigEndian.PutUint32(buf[pos:], uint32(message[v])) // frr7.5: 32bit
+ pos += 4
+ } else {
+ buf[pos] = uint8(message[v]) // before frr7.4: 8bit
+ pos++
+ }
+
if v > 4 {
buf[pos] = byte(SafiUnicast) //SAFI
pos++
@@ -458,8 +472,15 @@ func Test_IPRouteBody_IPv4(t *testing.T) {
binary.BigEndian.PutUint32(buf[pos:], uint32(FlagSelected.ToEach(v, "")))
pos += 4
}
- buf[pos] = byte(messageWithoutNexthop[v])
- pos++
+
+ if v == 6 {
+ binary.BigEndian.PutUint32(buf[pos:], uint32(messageWithoutNexthop[v])) // frr7.5: 32bit
+ pos += 4
+ } else {
+ buf[pos] = byte(messageWithoutNexthop[v]) // before frr7.4: 8bit
+ pos++
+ }
+
if v > 4 {
buf[pos] = byte(SafiUnicast) //SAFI
pos++
@@ -483,7 +504,7 @@ func Test_IPRouteBody_IPv4(t *testing.T) {
func Test_IPRouteBody_IPv6(t *testing.T) {
assert := assert.New(t)
- size := map[uint8]uint8{2: 43, 3: 43, 4: 48, 5: 55, 6: 56}
+ size := map[uint8]uint8{2: 43, 3: 43, 4: 48, 5: 55, 6: 59}
command := map[uint8]APIType{
2: zapi3IPv6RouteAdd,
3: zapi3IPv6RouteAdd,
@@ -528,8 +549,15 @@ func Test_IPRouteBody_IPv6(t *testing.T) {
binary.BigEndian.PutUint32(buf[pos:], uint32(FlagSelected.ToEach(v, "")))
pos += 4
}
- buf[pos] = byte(message[v])
- pos++
+
+ if v == 6 {
+ binary.BigEndian.PutUint32(buf[pos:], uint32(message[v])) // frr7.5: 32bit
+ pos += 4
+ } else {
+ buf[pos] = uint8(message[v]) // before frr7.4: 8bit
+ pos++
+ }
+
if v > 4 {
buf[pos] = byte(SafiUnicast) //SAFI
pos++
@@ -596,10 +624,14 @@ func Test_IPRouteBody_IPv6(t *testing.T) {
case 2, 3:
assert.Equal([]byte{0x2, 0x10, byte(message[v])}, buf[0:3])
pos = 3
- case 4, 5, 6:
+ case 4, 5:
tmpFlag := byte(0xff & FlagSelected.ToEach(v, ""))
assert.Equal([]byte{0x2, 0x00, 0x00, 0x00, 0x00, 0x00, tmpFlag, byte(message[v])}, buf[0:8])
pos = 8
+ case 6: // frr 7.5: MessageFlag: 32bit
+ tmpFlag := byte(0xff & FlagSelected.ToEach(v, ""))
+ assert.Equal([]byte{0x2, 0x00, 0x00, 0x00, 0x00, 0x00, tmpFlag, 0x00, 0x00, 0x00, byte(message[v])}, buf[0:11])
+ pos = 11
}
switch v {
case 2, 3, 4:
@@ -665,8 +697,15 @@ func Test_IPRouteBody_IPv6(t *testing.T) {
binary.BigEndian.PutUint32(buf[pos:], uint32(FlagSelected.ToEach(v, "")))
pos += 4
}
- buf[pos] = byte(message[v])
- pos++
+
+ if v == 6 {
+ binary.BigEndian.PutUint32(buf[pos:], uint32(message[v])) // frr7.5: 32bit
+ pos += 4
+ } else {
+ buf[pos] = uint8(message[v]) // before frr7.4: 8bit
+ pos++
+ }
+
if v > 4 {
buf[pos] = byte(SafiUnicast) //SAFI
pos++
@@ -738,8 +777,15 @@ func Test_IPRouteBody_IPv6(t *testing.T) {
binary.BigEndian.PutUint32(buf[pos:], uint32(FlagSelected.ToEach(v, "")))
pos += 4
}
- buf[pos] = byte(messageWithoutNexthop[v])
- pos++
+
+ if v == 6 {
+ binary.BigEndian.PutUint32(buf[pos:], uint32(messageWithoutNexthop[v])) // frr7.5: 32bit
+ pos += 4
+ } else {
+ buf[pos] = byte(messageWithoutNexthop[v]) // before frr7.4: 8bit
+ pos++
+ }
+
if v > 4 {
buf[pos] = byte(SafiUnicast) //SAFI
pos++
@@ -935,7 +981,7 @@ func Test_NexthopRegisterBody(t *testing.T) {
func Test_NexthopUpdateBody(t *testing.T) {
assert := assert.New(t)
- size := map[uint8]uint8{2: 21, 3: 21, 4: 22, 5: 26, 6: 30}
+ size := map[uint8]uint8{2: 21, 3: 21, 4: 22, 5: 26, 6: 34}
command := map[uint8]APIType{
2: zapi3NexthopUpdate,
3: zapi3NexthopUpdate,
@@ -954,9 +1000,16 @@ func Test_NexthopUpdateBody(t *testing.T) {
for v := MinZapiVer; v <= MaxZapiVer; v++ {
// Input binary
bufIn := make([]byte, size[v])
+ pos := 0
+ if v == 6 { // frr7.5
+ // message flag
+ copy(bufIn[pos:pos+4], []byte{0x00, 0x00, 0x00, 0x00})
+ pos += 4
+ }
// afi(2 bytes)=AF_INET, prefix_len(1 byte)=32, prefix(4 bytes)="192.168.1.1"
- copy(bufIn[0:7], []byte{0x00, 0x02, 0x20, 0xc0, 0xa8, 0x01, 0x01})
- pos := 7
+ copy(bufIn[pos:pos+7], []byte{0x00, 0x02, 0x20, 0xc0, 0xa8, 0x01, 0x01})
+ pos += 7
+
if v > 4 { // Type(1byte), Instance(2byte)
copy(bufIn[pos:pos+3], []byte{byte(routeConnect), 0x00, 0x00})
pos += 3
diff --git a/tools/pyang_plugins/gobgp.yang b/tools/pyang_plugins/gobgp.yang
index e00e1c41..b93be424 100644
--- a/tools/pyang_plugins/gobgp.yang
+++ b/tools/pyang_plugins/gobgp.yang
@@ -1262,7 +1262,7 @@ module gobgp {
type string;
description
"Configure zebra software name.
- frr4, cumulus, frr6, frr7, and frr7.2 can be used.";
+ frr4, cumulus, frr6, frr7, frr7.2 and frr7.3 can be used.";
}
}