Skip to content

Commit

Permalink
Add option to register BGP-LS Attribute in gobgp command
Browse files Browse the repository at this point in the history
Co-authored-by: watal <watal.i27e@gmail.com>
  • Loading branch information
Enigamict and watal committed May 21, 2023
1 parent 1a6dc92 commit cbd1492
Showing 1 changed file with 131 additions and 23 deletions.
154 changes: 131 additions & 23 deletions cmd/gobgp/global.go
Original file line number Diff line number Diff line change
Expand Up @@ -1295,25 +1295,25 @@ func parseMUPArgs(args []string, afi uint16, nexthop string) (bgp.AddrPrefixInte
return nil, nil, nil, fmt.Errorf("invalid subtype. expect [isd|dsd|t1st|t2st] but %s", subtype)
}

func parseLsLinkProtocol(args []string, afi uint16) (bgp.AddrPrefixInterface, error) {
func parseLsLinkProtocol(args []string, afi uint16) (bgp.AddrPrefixInterface, *bgp.PathAttributeLs, error) {
if len(args) < 2 {
return nil, fmt.Errorf("lack of protocolType")
return nil, nil, fmt.Errorf("lack of protocolType")
}
protocolType := args[1]
switch protocolType {
// TODO case ospf/isis
case "bgp":
return parseLsLinkNLRIType(args, afi)
}
return nil, fmt.Errorf("invalid protocolType. expect [bgp] but %s", protocolType)
return nil, nil, fmt.Errorf("invalid protocolType. expect [bgp] but %s", protocolType)
}

func parseLsLinkNLRIType(args []string, afi uint16) (bgp.AddrPrefixInterface, error) {
func parseLsLinkNLRIType(args []string, afi uint16) (bgp.AddrPrefixInterface, *bgp.PathAttributeLs, error) {
// Format:
// <ip prefix> identifier <identifier> asn <asn> bgp-ls-id <bgp-ls-id> ospf
req := 26
if len(args) < req {
return nil, fmt.Errorf("%d args required at least, but got %d", req, len(args))
return nil, nil, fmt.Errorf("%d args required at least, but got %d", req, len(args))
}

m, err := extractReserved(args, map[string]int{
Expand All @@ -1332,29 +1332,34 @@ func parseLsLinkNLRIType(args []string, afi uint16) (bgp.AddrPrefixInterface, er
"ipv6-neighbor-address": paramSingle,
"sid": paramSingle,
"sid-type": paramSingle,
"v-flag": paramFlag,
"l-flag": paramFlag,
"b-flag": paramFlag,
"p-flag": paramFlag,
"weight": paramSingle,
})
if err != nil {
return nil, err
return nil, nil, err
}

identifier, err := strconv.ParseUint(m["identifier"][0], 10, 64)
if err != nil {
return nil, err
return nil, nil, err
}

localAsn, err := strconv.ParseUint(m["local-asn"][0], 10, 64)
if err != nil {
return nil, err
return nil, nil, err

}
localBgpLsId, err := strconv.ParseUint(m["local-bgp-ls-id"][0], 10, 64)
if err != nil {
return nil, err
return nil, nil, err

}
localBgpConfederationMember, err := strconv.ParseUint(m["local-bgp-confederation-member"][0], 10, 64)
if err != nil {
return nil, err
return nil, nil, err

}
lnd := &bgp.LsNodeDescriptor{
Expand All @@ -1368,17 +1373,17 @@ func parseLsLinkNLRIType(args []string, afi uint16) (bgp.AddrPrefixInterface, er
}
RemoteAsn, err := strconv.ParseUint(m["remote-asn"][0], 10, 64)
if err != nil {
return nil, err
return nil, nil, err

}
RemoteBgpLsId, err := strconv.ParseUint(m["remote-bgp-ls-id"][0], 10, 64)
if err != nil {
return nil, err
return nil, nil, err

}
RemoteBgpConfederationMember, err := strconv.ParseUint(m["remote-bgp-confederation-member"][0], 10, 64)
if err != nil {
return nil, err
return nil, nil, err

}
rnd := &bgp.LsNodeDescriptor{
Expand Down Expand Up @@ -1414,9 +1419,94 @@ func parseLsLinkNLRIType(args []string, afi uint16) (bgp.AddrPrefixInterface, er
rndTLV := bgp.NewLsTLVNodeDescriptor(rnd, bgp.LS_TLV_REMOTE_NODE_DESC)
ldTLV := bgp.NewLsLinkTLVs(ld)

sidTypeString := m["sid-type"][0]

sidtype := lsTLVTypeSelect(sidTypeString)

var peerNodeFlag uint8

if _, ok := m["v-flag"]; ok {
peerNodeFlag = peerNodeFlag | 0x80
}
if _, ok := m["l-flag"]; ok {
peerNodeFlag = peerNodeFlag | 0x40
}
if _, ok := m["b-flag"]; ok {
peerNodeFlag = peerNodeFlag | 0x20
}
if _, ok := m["p-flag"]; ok {
peerNodeFlag = peerNodeFlag | 0x10
}

lsTLVWeight, err := strconv.ParseUint(m["weight"][0], 10, 64)
if err != nil {
return nil, nil, err
}
lsTLVSid, err := strconv.ParseUint(m["sid"][0], 10, 64)
if err != nil {
return nil, nil, err
}

const lsTlvLen = 7
const t = bgp.BGP_ATTR_TYPE_LS
const pathAttrHdrLen = 4
var tlvs []bgp.LsTLVInterface
length := uint16(pathAttrHdrLen + lsTlvLen)

switch sidtype {
case bgp.LS_TLV_PEER_NODE_SID:

lsTLV := &bgp.LsTLVPeerNodeSID{
LsTLV: bgp.LsTLV{
Type: sidtype,
Length: uint16(lsTlvLen),
},
Flags: peerNodeFlag,
Weight: uint8(lsTLVWeight),
SID: uint32(lsTLVSid),
}
tlvs = append(tlvs, lsTLV)
case bgp.LS_TLV_ADJACENCY_SID:
lsTLV := &bgp.LsTLVAdjacencySID{
LsTLV: bgp.LsTLV{
Type: sidtype,
Length: uint16(lsTlvLen),
},
Flags: peerNodeFlag,
Weight: uint8(lsTLVWeight),
SID: uint32(lsTLVSid),
}
tlvs = append(tlvs, lsTLV)
case bgp.LS_TLV_PEER_SET_SID:
lsTLV := &bgp.LsTLVPeerSetSID{
LsTLV: bgp.LsTLV{
Type: sidtype,
Length: uint16(lsTlvLen),
},
Flags: peerNodeFlag,
Weight: uint8(lsTLVWeight),
SID: uint32(lsTLVSid),
}
tlvs = append(tlvs, lsTLV)
}

pathAttributeLs := &bgp.PathAttributeLs{
PathAttribute: bgp.PathAttribute{
Flags: bgp.PathAttrFlags[t],
Type: t,
Length: length,
},
TLVs: tlvs,
}
len := len(ldTLV)
var sum int
for i := 0; i < len; i++ {
sum += ldTLV[i].Len()
}

const CodeLen = 1
const topologyLen = 8
LsNLRIhdrlen := lndTLV.Len() + rndTLV.Len() + topologyLen + CodeLen
LsNLRIhdrlen := sum + lndTLV.Len() + rndTLV.Len() + topologyLen + CodeLen
lsNlri := bgp.LsNLRI{
NLRIType: bgp.LS_NLRI_TYPE_NODE,
Length: uint16(LsNLRIhdrlen),
Expand All @@ -1433,12 +1523,26 @@ func parseLsLinkNLRIType(args []string, afi uint16) (bgp.AddrPrefixInterface, er
LinkDesc: ldTLV,
},
}
return nlri, nil
return nlri, pathAttributeLs, nil
}

func parseLsArgs(args []string, afi uint16) (bgp.AddrPrefixInterface, error) {
func lsTLVTypeSelect(s string) bgp.LsTLVType {
switch s {
case "node":
return bgp.LS_TLV_PEER_NODE_SID
case "adj":
return bgp.LS_TLV_ADJACENCY_SID
case "set":
return bgp.LS_TLV_PEER_SET_SID
}

return bgp.LS_TLV_UNKNOWN

}

func parseLsArgs(args []string, afi uint16) (bgp.AddrPrefixInterface, *bgp.PathAttributeLs, error) {
if len(args) < 1 {
return nil, fmt.Errorf("lack of nlriType")
return nil, nil, fmt.Errorf("lack of nlriType")
}
nlriType := args[0]
switch nlriType {
Expand All @@ -1447,7 +1551,7 @@ func parseLsArgs(args []string, afi uint16) (bgp.AddrPrefixInterface, error) {
// TODO: case node / IPv4 Topology Prefix / IPv6 Topology Prefix / TE Policy / SRv6 SID
}

return nil, fmt.Errorf("invalid nlriType. expect [link] but %s", nlriType)
return nil, nil, fmt.Errorf("invalid nlriType. expect [link] but %s", nlriType)
}

func extractOrigin(args []string) ([]string, bgp.PathAttributeInterface, error) {
Expand Down Expand Up @@ -1691,6 +1795,7 @@ func parsePath(rf bgp.RouteFamily, args []string) (*api.Path, error) {
var nlri bgp.AddrPrefixInterface
var extcomms []string
var psid *bgp.PathAttributePrefixSID
var ls *bgp.PathAttributeLs
var err error
attrs := make([]bgp.PathAttributeInterface, 0, 1)

Expand Down Expand Up @@ -1842,13 +1947,16 @@ func parsePath(rf bgp.RouteFamily, args []string) (*api.Path, error) {
case bgp.RF_MUP_IPv6:
nlri, psid, extcomms, err = parseMUPArgs(args, bgp.AFI_IP6, nexthop)
case bgp.RF_LS:
nlri, err = parseLsArgs(args, bgp.AFI_LS)
nlri, ls, err = parseLsArgs(args, bgp.AFI_LS)
default:
return nil, fmt.Errorf("unsupported route family: %s", rf)
}
if err != nil {
return nil, err
}
if ls != nil {
attrs = append(attrs, ls)
}

if rf == bgp.RF_IPv4_UC && net.ParseIP(nexthop).To4() != nil {
attrs = append(attrs, bgp.NewPathAttributeNextHop(nexthop))
Expand Down Expand Up @@ -1930,10 +2038,10 @@ func modPath(resource string, name, modtype string, args []string) error {
helpErrMap := map[bgp.RouteFamily]error{}
baseHelpMsgFmt := fmt.Sprintf(`error: %s
usage: %s rib -a %%s %s <PREFIX> %%s [origin { igp | egp | incomplete }] [aspath <ASPATH>] [nexthop <ADDRESS>] [med <NUM>] [local-pref <NUM>] [community <COMMUNITY>] [aigp metric <NUM>] [large-community <LARGE_COMMUNITY>] [aggregator <AGGREGATOR>]
<ASPATH>: <AS>[,<AS>],
<COMMUNITY>: xxx:xxx|internet|planned-shut|accept-own|route-filter-translated-v4|route-filter-v4|route-filter-translated-v6|route-filter-v6|llgr-stale|no-llgr|blackhole|no-export|no-advertise|no-export-subconfed|no-peer,
<LARGE_COMMUNITY>: xxx:xxx:xxx[,<LARGE_COMMUNITY>],
<AGGREGATOR>: <AS>:<ADDRESS>`,
<ASPATH>: <AS>[,<AS>],
<COMMUNITY>: xxx:xxx|internet|planned-shut|accept-own|route-filter-translated-v4|route-filter-v4|route-filter-translated-v6|route-filter-v6|llgr-stale|no-llgr|blackhole|no-export|no-advertise|no-export-subconfed|no-peer,
<LARGE_COMMUNITY>: xxx:xxx:xxx[,<LARGE_COMMUNITY>],
<AGGREGATOR>: <AS>:<ADDRESS>`,
err,
cmdstr,
// <address family>
Expand Down

0 comments on commit cbd1492

Please sign in to comment.