summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--gobgp/cmd/global.go95
1 files changed, 55 insertions, 40 deletions
diff --git a/gobgp/cmd/global.go b/gobgp/cmd/global.go
index bebe6358..a9508f77 100644
--- a/gobgp/cmd/global.go
+++ b/gobgp/cmd/global.go
@@ -235,7 +235,7 @@ func ParseExtendedCommunities(input string) ([]bgp.ExtendedCommunityInterface, e
return exts, nil
}
-func ParseFlowSpecArgs(args []string) (bgp.AddrPrefixInterface, string, []string, error) {
+func ParseFlowSpecArgs(args []string) (bgp.AddrPrefixInterface, []string, error) {
thenPos := len(args)
for idx, v := range args {
if v == "then" {
@@ -243,34 +243,34 @@ func ParseFlowSpecArgs(args []string) (bgp.AddrPrefixInterface, string, []string
}
}
if len(args) < 4 || args[0] != "match" || thenPos > len(args)-2 {
- return nil, "", nil, fmt.Errorf("invalid format")
+ return nil, nil, fmt.Errorf("invalid format")
}
matchArgs := args[1:thenPos]
cmp, err := bgp.ParseFlowSpecComponents(strings.Join(matchArgs, " "))
if err != nil {
- return nil, "", nil, err
+ return nil, nil, err
}
nlri := bgp.NewFlowSpecIPv4Unicast(cmp)
- return nlri, "0.0.0.0", args[thenPos:], nil
+ extcomms := args[thenPos:]
+ return nlri, extcomms, nil
}
-func ParseEvpnMacAdvArgs(args []string) (bgp.AddrPrefixInterface, string, []string, error) {
+func ParseEvpnMacAdvArgs(args []string) (bgp.AddrPrefixInterface, []string, error) {
if len(args) < 4 {
- return nil, "", nil, fmt.Errorf("lack of number of args needs 4 but %d", len(args))
+ return nil, nil, fmt.Errorf("lack of number of args needs 4 but %d", len(args))
}
var nlri bgp.AddrPrefixInterface
- var rts []string
var ip net.IP
iplen := 0
mac, err := net.ParseMAC(args[0])
if err != nil {
- return nil, "", nil, fmt.Errorf("invalid mac: %s", args[0])
+ return nil, nil, fmt.Errorf("invalid mac: %s", args[0])
}
if args[1] != "0.0.0.0" || args[1] != "::" {
ip = net.ParseIP(args[1])
if ip == nil {
- return nil, "", nil, fmt.Errorf("invalid ip prefix: %s", args[1])
+ return nil, nil, fmt.Errorf("invalid ip prefix: %s", args[1])
}
iplen = net.IPv4len * 8
if ip.To4() == nil {
@@ -279,25 +279,21 @@ func ParseEvpnMacAdvArgs(args []string) (bgp.AddrPrefixInterface, string, []stri
}
eTag, err := strconv.Atoi(args[2])
if err != nil {
- return nil, "", nil, fmt.Errorf("invalid eTag: %s. err: %s", args[2], err)
+ return nil, nil, fmt.Errorf("invalid eTag: %s. err: %s", args[2], err)
}
label, err := strconv.Atoi(args[3])
if err != nil {
- return nil, "", nil, fmt.Errorf("invalid label: %s. err: %s", args[3], err)
+ return nil, nil, fmt.Errorf("invalid label: %s. err: %s", args[3], err)
}
var rd bgp.RouteDistinguisherInterface
if args[4] == "rd" && len(args) > 5 {
rd, err = bgp.ParseRouteDistinguisher(args[5])
if err != nil {
- return nil, "", nil, err
+ return nil, nil, err
}
}
- if len(args) > 6 {
- rts = args[6:]
- }
-
macIpAdv := &bgp.EVPNMacIPAdvertisementRoute{
RD: rd,
ESI: bgp.EthernetSegmentIdentifier{
@@ -311,22 +307,22 @@ func ParseEvpnMacAdvArgs(args []string) (bgp.AddrPrefixInterface, string, []stri
ETag: uint32(eTag),
}
nlri = bgp.NewEVPNNLRI(bgp.EVPN_ROUTE_TYPE_MAC_IP_ADVERTISEMENT, 0, macIpAdv)
- return nlri, "0.0.0.0", rts, nil
+ extcomms := args[6:]
+ return nlri, extcomms, nil
}
-func ParseEvpnMulticastArgs(args []string) (bgp.AddrPrefixInterface, string, []string, error) {
+func ParseEvpnMulticastArgs(args []string) (bgp.AddrPrefixInterface, []string, error) {
if len(args) < 2 {
- return nil, "", nil, fmt.Errorf("lack of number of args needs 2 but %d", len(args))
+ return nil, nil, fmt.Errorf("lack of number of args needs 2 but %d", len(args))
}
var nlri bgp.AddrPrefixInterface
- var rts []string
var ip net.IP
iplen := 0
if args[0] != "0.0.0.0" || args[0] != "::" {
ip = net.ParseIP(args[0])
if ip == nil {
- return nil, "", nil, fmt.Errorf("invalid ip prefix: %s", args[0])
+ return nil, nil, fmt.Errorf("invalid ip prefix: %s", args[0])
}
iplen = net.IPv4len * 8
if ip.To4() == nil {
@@ -336,34 +332,32 @@ func ParseEvpnMulticastArgs(args []string) (bgp.AddrPrefixInterface, string, []s
eTag, err := strconv.Atoi(args[1])
if err != nil {
- return nil, "", nil, fmt.Errorf("invalid eTag: %s. err: %s", args[1], err)
+ return nil, nil, fmt.Errorf("invalid eTag: %s. err: %s", args[1], err)
}
var rd bgp.RouteDistinguisherInterface
if args[2] == "rd" && len(args) > 3 {
rd, err = bgp.ParseRouteDistinguisher(args[3])
if err != nil {
- return nil, "", nil, err
+ return nil, nil, err
}
}
- if len(args) > 4 {
- rts = args[4:]
- }
multicastEtag := &bgp.EVPNMulticastEthernetTagRoute{
RD: rd,
IPAddressLength: uint8(iplen),
IPAddress: ip,
ETag: uint32(eTag),
}
+ extcomms := args[4:]
nlri = bgp.NewEVPNNLRI(bgp.EVPN_INCLUSIVE_MULTICAST_ETHERNET_TAG, 0, multicastEtag)
- return nlri, "0.0.0.0", rts, nil
+ return nlri, extcomms, nil
}
-func ParseEvpnArgs(args []string) (bgp.AddrPrefixInterface, string, []string, error) {
+func ParseEvpnArgs(args []string) (bgp.AddrPrefixInterface, []string, error) {
if len(args) < 1 {
- return nil, "", nil, fmt.Errorf("lack of args. need 1 but %d", len(args))
+ return nil, nil, fmt.Errorf("lack of args. need 1 but %d", len(args))
}
subtype := args[0]
args = args[1:]
@@ -373,14 +367,38 @@ func ParseEvpnArgs(args []string) (bgp.AddrPrefixInterface, string, []string, er
case "multicast":
return ParseEvpnMulticastArgs(args)
}
- return nil, "", nil, fmt.Errorf("invalid subtype. expect [macadv|multicast] but %s", subtype)
+ return nil, nil, fmt.Errorf("invalid subtype. expect [macadv|multicast] but %s", subtype)
+}
+
+func extractNexthop(rf bgp.RouteFamily, args []string) ([]string, string, error) {
+ afi, _ := bgp.RouteFamilyToAfiSafi(rf)
+ nexthop := "0.0.0.0"
+ if afi == bgp.AFI_IP6 {
+ nexthop = "::"
+ }
+ for idx, arg := range args {
+ if arg == "nexthop" && len(args) > (idx+1) {
+ if net.ParseIP(args[idx+1]) == nil {
+ return nil, "", fmt.Errorf("invalid nexthop address")
+ }
+ nexthop = args[idx+1]
+ args = append(args[:idx], args[idx+2:]...)
+ break
+ }
+ }
+ return args, nexthop, nil
}
func ParsePath(rf bgp.RouteFamily, args []string) (*api.Path, error) {
var nlri bgp.AddrPrefixInterface
- var nexthop string
var extcomms []string
var err error
+
+ args, nexthop, err := extractNexthop(rf, args)
+ if err != nil {
+ return nil, err
+ }
+
switch rf {
case bgp.RF_IPv4_UC, bgp.RF_IPv6_UC:
if len(args) != 1 {
@@ -395,13 +413,11 @@ func ParsePath(rf bgp.RouteFamily, args []string) (*api.Path, error) {
if ip.To4() == nil {
return nil, fmt.Errorf("invalid ipv4 prefix")
}
- nexthop = "0.0.0.0"
nlri = bgp.NewIPAddrPrefix(uint8(ones), ip.String())
} else {
if ip.To16() == nil {
return nil, fmt.Errorf("invalid ipv6 prefix")
}
- nexthop = "::"
nlri = bgp.NewIPv6AddrPrefix(uint8(ones), ip.String())
}
case bgp.RF_IPv4_VPN, bgp.RF_IPv6_VPN:
@@ -424,20 +440,17 @@ func ParsePath(rf bgp.RouteFamily, args []string) (*api.Path, error) {
if ip.To4() == nil {
return nil, fmt.Errorf("invalid ipv4 prefix")
}
- nexthop = "0.0.0.0"
nlri = bgp.NewLabeledVPNIPAddrPrefix(uint8(ones), ip.String(), *mpls, rd)
} else {
if ip.To16() == nil {
return nil, fmt.Errorf("invalid ipv6 prefix")
}
- nexthop = "::"
nlri = bgp.NewLabeledVPNIPv6AddrPrefix(uint8(ones), ip.String(), *mpls, rd)
}
-
case bgp.RF_EVPN:
- nlri, nexthop, extcomms, err = ParseEvpnArgs(args)
+ nlri, extcomms, err = ParseEvpnArgs(args)
case bgp.RF_FS_IPv4_UC:
- nlri, nexthop, extcomms, err = ParseFlowSpecArgs(args)
+ nlri, extcomms, err = ParseFlowSpecArgs(args)
default:
return nil, fmt.Errorf("Unsupported route family: %s", rf)
}
@@ -505,7 +518,9 @@ func modPath(resource api.Resource, name, modtype string, args []string) error {
}
flags := strings.Join(ss, ", ")
helpErrMap := map[bgp.RouteFamily]error{}
- helpErrMap[bgp.RF_FS_IPv4_UC] = fmt.Errorf(`usage: %s rib %s match <MATCH_EXPR> then <THEN_EXPR> -a ipv4-flowspec
+ helpErrMap[bgp.RF_IPv4_UC] = fmt.Errorf("usage: %s rib %s <PREFIX> [nexthop <ADDRESS>] -a ipv4")
+ helpErrMap[bgp.RF_IPv6_UC] = fmt.Errorf("usage: %s rib %s <PREFIX> [nexthop <ADDRESS>] -a ipv6")
+ helpErrMap[bgp.RF_FS_IPv4_UC] = fmt.Errorf(`usage: %s rib %s match <MATCH_EXPR> then <THEN_EXPR> [nexthop <ADDRESS>] -a ipv4-flowspec
<MATCH_EXPR> : { %s <PREFIX> | %s <PREFIX> |
%s <PROTO>... | %s <FRAGMENT_TYPE> | %s <TCPFLAG>... |
{ %s | %s | %s | %s | %s | %s | %s } <ITEM>... }...
@@ -531,7 +546,7 @@ func modPath(resource api.Resource, name, modtype string, args []string) error {
ExtCommNameMap[ACCEPT], ExtCommNameMap[DISCARD],
ExtCommNameMap[RATE], ExtCommNameMap[REDIRECT],
ExtCommNameMap[MARK], ExtCommNameMap[ACTION], ExtCommNameMap[RT])
- helpErrMap[bgp.RF_EVPN] = fmt.Errorf(`usage: %s rib %s { macadv <MACADV> | multicast <MULTICAST> } -a evpn
+ helpErrMap[bgp.RF_EVPN] = fmt.Errorf(`usage: %s rib %s { macadv <MACADV> | multicast <MULTICAST> } [nexthop <ADDRESS>] -a evpn
<MACADV> : <mac address> <ip address> <etag> <label> rd <rd> rt <rt>... [encap <encap type>]
<MULTICAST> : <ip address> <etag> rd <rd> rt <rt>... [encap <encap type>]`, cmdstr, modtype)
if err, ok := helpErrMap[rf]; ok {