mirror of
https://github.com/osrg/gobgp.git
synced 2024-05-11 05:55:10 +00:00
api/cli: reuse api.Path in ModPathArguments
kill redundant lines Signed-off-by: ISHIDA Wataru <[email protected]>
This commit is contained in:
committed by
FUJITA Tomonori
parent
af0c03bbec
commit
56ca9eee5f
+17
-12
@@ -206,18 +206,22 @@ func (m *Arguments) String() string { return proto.CompactTextString(m) }
|
||||
func (*Arguments) ProtoMessage() {}
|
||||
|
||||
type ModPathArguments struct {
|
||||
Resource Resource `protobuf:"varint,1,opt,name=resource,enum=api.Resource" json:"resource,omitempty"`
|
||||
Name string `protobuf:"bytes,2,opt,name=name" json:"name,omitempty"`
|
||||
IsWithdraw bool `protobuf:"varint,3,opt,name=is_withdraw" json:"is_withdraw,omitempty"`
|
||||
RawNlri []byte `protobuf:"bytes,4,opt,name=raw_nlri,proto3" json:"raw_nlri,omitempty"`
|
||||
RawPattrs [][]byte `protobuf:"bytes,5,rep,name=raw_pattrs,proto3" json:"raw_pattrs,omitempty"`
|
||||
NoImplicitWithdraw bool `protobuf:"varint,6,opt,name=no_implicit_withdraw" json:"no_implicit_withdraw,omitempty"`
|
||||
Resource Resource `protobuf:"varint,1,opt,name=resource,enum=api.Resource" json:"resource,omitempty"`
|
||||
Name string `protobuf:"bytes,2,opt,name=name" json:"name,omitempty"`
|
||||
Path *Path `protobuf:"bytes,3,opt,name=path" json:"path,omitempty"`
|
||||
}
|
||||
|
||||
func (m *ModPathArguments) Reset() { *m = ModPathArguments{} }
|
||||
func (m *ModPathArguments) String() string { return proto.CompactTextString(m) }
|
||||
func (*ModPathArguments) ProtoMessage() {}
|
||||
|
||||
func (m *ModPathArguments) GetPath() *Path {
|
||||
if m != nil {
|
||||
return m.Path
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type PolicyArguments struct {
|
||||
Resource Resource `protobuf:"varint,1,opt,name=resource,enum=api.Resource" json:"resource,omitempty"`
|
||||
Operation Operation `protobuf:"varint,2,opt,name=operation,enum=api.Operation" json:"operation,omitempty"`
|
||||
@@ -317,12 +321,13 @@ func (m *Capability) GetGracefulRestart() *GracefulRestart {
|
||||
}
|
||||
|
||||
type Path struct {
|
||||
Nlri []byte `protobuf:"bytes,1,opt,name=nlri,proto3" json:"nlri,omitempty"`
|
||||
Pattrs [][]byte `protobuf:"bytes,2,rep,name=pattrs,proto3" json:"pattrs,omitempty"`
|
||||
Age int64 `protobuf:"varint,3,opt,name=age" json:"age,omitempty"`
|
||||
Best bool `protobuf:"varint,4,opt,name=best" json:"best,omitempty"`
|
||||
IsWithdraw bool `protobuf:"varint,5,opt,name=is_withdraw" json:"is_withdraw,omitempty"`
|
||||
Validation int32 `protobuf:"varint,6,opt,name=validation" json:"validation,omitempty"`
|
||||
Nlri []byte `protobuf:"bytes,1,opt,name=nlri,proto3" json:"nlri,omitempty"`
|
||||
Pattrs [][]byte `protobuf:"bytes,2,rep,name=pattrs,proto3" json:"pattrs,omitempty"`
|
||||
Age int64 `protobuf:"varint,3,opt,name=age" json:"age,omitempty"`
|
||||
Best bool `protobuf:"varint,4,opt,name=best" json:"best,omitempty"`
|
||||
IsWithdraw bool `protobuf:"varint,5,opt,name=is_withdraw" json:"is_withdraw,omitempty"`
|
||||
Validation int32 `protobuf:"varint,6,opt,name=validation" json:"validation,omitempty"`
|
||||
NoImplicitWithdraw bool `protobuf:"varint,7,opt,name=no_implicit_withdraw" json:"no_implicit_withdraw,omitempty"`
|
||||
}
|
||||
|
||||
func (m *Path) Reset() { *m = Path{} }
|
||||
|
||||
+2
-4
@@ -62,10 +62,7 @@ message Arguments {
|
||||
message ModPathArguments {
|
||||
Resource resource = 1;
|
||||
string name = 2;
|
||||
bool is_withdraw = 3;
|
||||
bytes raw_nlri = 4;
|
||||
repeated bytes raw_pattrs = 5;
|
||||
bool no_implicit_withdraw = 6;
|
||||
Path path = 3;
|
||||
}
|
||||
|
||||
message PolicyArguments {
|
||||
@@ -145,6 +142,7 @@ message Path {
|
||||
bool best = 4;
|
||||
bool is_withdraw = 5;
|
||||
int32 validation = 6;
|
||||
bool no_implicit_withdraw = 7;
|
||||
}
|
||||
|
||||
message Destination {
|
||||
|
||||
+84
-61
@@ -203,7 +203,7 @@ func ParseExtendedCommunities(input string) ([]bgp.ExtendedCommunityInterface, e
|
||||
return exts, nil
|
||||
}
|
||||
|
||||
func parseFlowSpecArgs(modtype string, args []string) (bgp.AddrPrefixInterface, string, []string, error) {
|
||||
func parseFlowSpecArgs(resource api.Resource, name, modtype string, args []string) (bgp.AddrPrefixInterface, string, []string, error) {
|
||||
thenPos := len(args)
|
||||
for idx, v := range args {
|
||||
if v == "then" {
|
||||
@@ -258,27 +258,39 @@ func parseFlowSpecArgs(modtype string, args []string) (bgp.AddrPrefixInterface,
|
||||
nlri := bgp.NewFlowSpecIPv4Unicast(cmp)
|
||||
return nlri, "0.0.0.0", args[thenPos:], nil
|
||||
}
|
||||
func parseEvpnArgs(modtype string, args []string) (bgp.AddrPrefixInterface, string, []string, error) {
|
||||
func parseEvpnArgs(resource api.Resource, name, modtype string, args []string) (bgp.AddrPrefixInterface, string, []string, error) {
|
||||
cmdstr := "global"
|
||||
if resource == api.Resource_VRF {
|
||||
cmdstr = fmt.Sprintf("vrf %s", name)
|
||||
}
|
||||
|
||||
if len(args) < 1 {
|
||||
return nil, "", nil, fmt.Errorf("usage: global rib %s { macadv | multicast } ... -a evpn", modtype)
|
||||
return nil, "", nil, fmt.Errorf("usage: %s rib %s { macadv | multicast } ... -a evpn", cmdstr, modtype)
|
||||
}
|
||||
subtype := args[0]
|
||||
args = args[1:]
|
||||
|
||||
var nlri bgp.AddrPrefixInterface
|
||||
var rts []string
|
||||
var ip net.IP
|
||||
iplen := 0
|
||||
|
||||
switch subtype {
|
||||
case "macadv":
|
||||
if len(args) < 6 || args[4] != "rd" || args[6] != "rt" {
|
||||
return nil, "", nil, fmt.Errorf("usage: global rib %s macadv <mac address> <ip address> <etag> <label> rd <rd> rt <rt>... -a evpn", modtype)
|
||||
switch resource {
|
||||
case api.Resource_GLOBAL:
|
||||
if len(args) < 6 || args[4] != "rd" || args[6] != "rt" {
|
||||
return nil, "", nil, fmt.Errorf("usage: rib %s macadv <mac address> <ip address> <etag> <label> rd <rd> rt <rt>... -a evpn", modtype)
|
||||
}
|
||||
case api.Resource_VRF:
|
||||
if len(args) < 4 {
|
||||
return nil, "", nil, fmt.Errorf("usage: vrf %s rib %s macadv <mac address> <ip address> <etag> <label> -a evpn", name, modtype)
|
||||
}
|
||||
}
|
||||
mac, err := net.ParseMAC(args[0])
|
||||
if err != nil {
|
||||
return nil, "", nil, fmt.Errorf("invalid mac: %s", args[0])
|
||||
}
|
||||
var ip net.IP
|
||||
iplen := 0
|
||||
if args[1] != "0.0.0.0" || args[1] != "::" {
|
||||
ip = net.ParseIP(args[1])
|
||||
if ip == nil {
|
||||
@@ -297,13 +309,15 @@ func parseEvpnArgs(modtype string, args []string) (bgp.AddrPrefixInterface, stri
|
||||
if err != nil {
|
||||
return nil, "", nil, fmt.Errorf("invalid label: %s. err: %s", args[3], err)
|
||||
}
|
||||
rd, err := bgp.ParseRouteDistinguisher(args[5])
|
||||
if err != nil {
|
||||
return nil, "", nil, err
|
||||
var rd bgp.RouteDistinguisherInterface
|
||||
if resource == api.Resource_GLOBAL {
|
||||
rd, err = bgp.ParseRouteDistinguisher(args[5])
|
||||
if err != nil {
|
||||
return nil, "", nil, err
|
||||
}
|
||||
rts = args[6:]
|
||||
}
|
||||
|
||||
rts = args[6:]
|
||||
|
||||
macIpAdv := &bgp.EVPNMacIPAdvertisementRoute{
|
||||
RD: rd,
|
||||
ESI: bgp.EthernetSegmentIdentifier{
|
||||
@@ -318,12 +332,16 @@ func parseEvpnArgs(modtype string, args []string) (bgp.AddrPrefixInterface, stri
|
||||
}
|
||||
nlri = bgp.NewEVPNNLRI(bgp.EVPN_ROUTE_TYPE_MAC_IP_ADVERTISEMENT, 0, macIpAdv)
|
||||
case "multicast":
|
||||
if len(args) < 5 || args[2] != "rd" || args[4] != "rt" {
|
||||
return nil, "", nil, fmt.Errorf("usage : global rib %s multicast <ip address> <etag> rd <rd> rt <rt> -a evpn", modtype)
|
||||
switch resource {
|
||||
case api.Resource_GLOBAL:
|
||||
if len(args) < 5 || args[2] != "rd" || args[4] != "rt" {
|
||||
return nil, "", nil, fmt.Errorf("usage : global rib %s multicast <ip address> <etag> rd <rd> rt <rt> -a evpn", modtype)
|
||||
}
|
||||
case api.Resource_VRF:
|
||||
if len(args) < 2 {
|
||||
return nil, "", nil, fmt.Errorf("usage : vrf %s rib %s multicast <ip address> <etag> -a evpn", name, modtype)
|
||||
}
|
||||
}
|
||||
|
||||
var ip net.IP
|
||||
iplen := 0
|
||||
if args[0] != "0.0.0.0" || args[0] != "::" {
|
||||
ip = net.ParseIP(args[0])
|
||||
if ip == nil {
|
||||
@@ -340,13 +358,15 @@ func parseEvpnArgs(modtype string, args []string) (bgp.AddrPrefixInterface, stri
|
||||
return nil, "", nil, fmt.Errorf("invalid eTag: %s. err: %s", args[1], err)
|
||||
}
|
||||
|
||||
rd, err := bgp.ParseRouteDistinguisher(args[3])
|
||||
if err != nil {
|
||||
return nil, "", nil, err
|
||||
var rd bgp.RouteDistinguisherInterface
|
||||
if resource == api.Resource_GLOBAL {
|
||||
rd, err = bgp.ParseRouteDistinguisher(args[3])
|
||||
if err != nil {
|
||||
return nil, "", nil, err
|
||||
}
|
||||
rts = args[4:]
|
||||
}
|
||||
|
||||
rts = args[4:]
|
||||
|
||||
multicastEtag := &bgp.EVPNMulticastEthernetTagRoute{
|
||||
RD: rd,
|
||||
IPAddressLength: uint8(iplen),
|
||||
@@ -360,7 +380,7 @@ func parseEvpnArgs(modtype string, args []string) (bgp.AddrPrefixInterface, stri
|
||||
return nlri, "0.0.0.0", rts, nil
|
||||
}
|
||||
|
||||
func modPath(modtype string, args []string) error {
|
||||
func modPath(resource api.Resource, name, modtype string, args []string) error {
|
||||
rf, err := checkAddressFamily(net.IP{})
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -370,10 +390,15 @@ func modPath(modtype string, args []string) error {
|
||||
var nexthop string
|
||||
var extcomms []string
|
||||
|
||||
cmdstr := "global"
|
||||
if resource == api.Resource_VRF {
|
||||
cmdstr = fmt.Sprintf("vrf %s", name)
|
||||
}
|
||||
|
||||
switch rf {
|
||||
case bgp.RF_IPv4_UC, bgp.RF_IPv6_UC:
|
||||
if len(args) != 1 {
|
||||
return fmt.Errorf("usage: global rib %s <prefix> -a { ipv4 | ipv6 }", modtype)
|
||||
return fmt.Errorf("usage: %s rib %s <prefix> -a { ipv4 | ipv6 }", cmdstr, modtype)
|
||||
}
|
||||
ip, net, _ := net.ParseCIDR(args[0])
|
||||
if rf == bgp.RF_IPv4_UC {
|
||||
@@ -392,8 +417,11 @@ func modPath(modtype string, args []string) error {
|
||||
nlri = bgp.NewIPv6AddrPrefix(uint8(ones), ip.String())
|
||||
}
|
||||
case bgp.RF_IPv4_VPN, bgp.RF_IPv6_VPN:
|
||||
if resource != api.Resource_GLOBAL {
|
||||
return fmt.Errorf("Unsupported route family: %s", rf)
|
||||
}
|
||||
if len(args) < 3 || args[1] != "rd" || args[3] != "rt" {
|
||||
return fmt.Errorf("usage: global rib %s <prefix> rd <rd> rt <rt>... -a { vpn-ipv4 | vpn-ipv6 }", modtype)
|
||||
return fmt.Errorf("usage: %s rib %s <prefix> rd <rd> rt <rt>... -a { vpn-ipv4 | vpn-ipv6 }", cmdstr, modtype)
|
||||
}
|
||||
ip, net, _ := net.ParseCIDR(args[0])
|
||||
ones, _ := net.Mask.Size()
|
||||
@@ -422,12 +450,15 @@ func modPath(modtype string, args []string) error {
|
||||
}
|
||||
|
||||
case bgp.RF_EVPN:
|
||||
nlri, nexthop, extcomms, err = parseEvpnArgs(modtype, args)
|
||||
nlri, nexthop, extcomms, err = parseEvpnArgs(resource, name, modtype, args)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
case bgp.RF_FS_IPv4_UC:
|
||||
nlri, nexthop, extcomms, err = parseFlowSpecArgs(modtype, args)
|
||||
if resource != api.Resource_GLOBAL {
|
||||
return fmt.Errorf("Unsupported route family: %s", rf)
|
||||
}
|
||||
nlri, nexthop, extcomms, err = parseFlowSpecArgs(resource, name, modtype, args)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -435,29 +466,25 @@ func modPath(modtype string, args []string) error {
|
||||
return fmt.Errorf("Unsupported route family: %s", rf)
|
||||
}
|
||||
|
||||
arg := &api.ModPathArguments{
|
||||
Resource: api.Resource_GLOBAL,
|
||||
RawPattrs: make([][]byte, 0),
|
||||
path := &api.Path{
|
||||
Pattrs: make([][]byte, 0),
|
||||
}
|
||||
|
||||
switch modtype {
|
||||
case CMD_ADD:
|
||||
arg.IsWithdraw = false
|
||||
case CMD_DEL:
|
||||
arg.IsWithdraw = true
|
||||
if modtype == CMD_DEL {
|
||||
path.IsWithdraw = true
|
||||
}
|
||||
|
||||
if rf == bgp.RF_IPv4_UC {
|
||||
arg.RawNlri, _ = nlri.Serialize()
|
||||
path.Nlri, _ = nlri.Serialize()
|
||||
n, _ := bgp.NewPathAttributeNextHop(nexthop).Serialize()
|
||||
arg.RawPattrs = append(arg.RawPattrs, n)
|
||||
path.Pattrs = append(path.Pattrs, n)
|
||||
} else {
|
||||
mpreach, _ := bgp.NewPathAttributeMpReachNLRI(nexthop, []bgp.AddrPrefixInterface{nlri}).Serialize()
|
||||
arg.RawPattrs = append(arg.RawPattrs, mpreach)
|
||||
path.Pattrs = append(path.Pattrs, mpreach)
|
||||
}
|
||||
|
||||
origin, _ := bgp.NewPathAttributeOrigin(bgp.BGP_ORIGIN_ATTR_TYPE_IGP).Serialize()
|
||||
arg.RawPattrs = append(arg.RawPattrs, origin)
|
||||
path.Pattrs = append(path.Pattrs, origin)
|
||||
|
||||
if extcomms != nil && len(extcomms) > 0 {
|
||||
extcomms, err := ParseExtendedCommunities(strings.Join(extcomms, " "))
|
||||
@@ -469,13 +496,18 @@ func modPath(modtype string, args []string) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
arg.RawPattrs = append(arg.RawPattrs, buf)
|
||||
path.Pattrs = append(path.Pattrs, buf)
|
||||
}
|
||||
|
||||
stream, err := client.ModPath(context.Background())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
arg := &api.ModPathArguments{
|
||||
Resource: resource,
|
||||
Name: name,
|
||||
Path: path,
|
||||
}
|
||||
err = stream.Send(arg)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -506,29 +538,20 @@ func NewGlobalCmd() *cobra.Command {
|
||||
|
||||
ribCmd.PersistentFlags().StringVarP(&subOpts.AddressFamily, "address-family", "a", "", "address family")
|
||||
|
||||
addCmd := &cobra.Command{
|
||||
Use: CMD_ADD,
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
err := modPath(CMD_ADD, args)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
os.Exit(1)
|
||||
}
|
||||
},
|
||||
for _, v := range []string{CMD_ADD, CMD_DEL} {
|
||||
cmd := &cobra.Command{
|
||||
Use: v,
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
err := modPath(api.Resource_GLOBAL, "", cmd.Use, args)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
os.Exit(1)
|
||||
}
|
||||
},
|
||||
}
|
||||
ribCmd.AddCommand(cmd)
|
||||
}
|
||||
|
||||
delCmd := &cobra.Command{
|
||||
Use: CMD_DEL,
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
err := modPath(CMD_DEL, args)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
os.Exit(1)
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
ribCmd.AddCommand(addCmd, delCmd)
|
||||
globalCmd.AddCommand(ribCmd)
|
||||
return globalCmd
|
||||
}
|
||||
|
||||
+10
-8
@@ -271,9 +271,8 @@ func injectMrt(r string, filename string, count int) error {
|
||||
nlri := rib.Prefix
|
||||
|
||||
for _, e := range rib.Entries {
|
||||
arg := &api.ModPathArguments{
|
||||
Resource: resource,
|
||||
RawPattrs: make([][]byte, 0),
|
||||
path := &api.Path{
|
||||
Pattrs: make([][]byte, 0),
|
||||
NoImplicitWithdraw: true,
|
||||
}
|
||||
|
||||
@@ -284,12 +283,12 @@ func injectMrt(r string, filename string, count int) error {
|
||||
nexthop := peers[e.PeerIndex].IpAddress.String()
|
||||
|
||||
if rf == bgp.RF_IPv4_UC {
|
||||
arg.RawNlri, _ = nlri.Serialize()
|
||||
path.Nlri, _ = nlri.Serialize()
|
||||
n, _ := bgp.NewPathAttributeNextHop(nexthop).Serialize()
|
||||
arg.RawPattrs = append(arg.RawPattrs, n)
|
||||
path.Pattrs = append(path.Pattrs, n)
|
||||
} else {
|
||||
mpreach, _ := bgp.NewPathAttributeMpReachNLRI(nexthop, []bgp.AddrPrefixInterface{nlri}).Serialize()
|
||||
arg.RawPattrs = append(arg.RawPattrs, mpreach)
|
||||
path.Pattrs = append(path.Pattrs, mpreach)
|
||||
}
|
||||
|
||||
for _, p := range e.PathAttributes {
|
||||
@@ -297,10 +296,13 @@ func injectMrt(r string, filename string, count int) error {
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
arg.RawPattrs = append(arg.RawPattrs, b)
|
||||
path.Pattrs = append(path.Pattrs, b)
|
||||
}
|
||||
ch <- arg
|
||||
|
||||
ch <- &api.ModPathArguments{
|
||||
Resource: resource,
|
||||
Path: path,
|
||||
}
|
||||
}
|
||||
|
||||
idx += 1
|
||||
|
||||
+1
-163
@@ -23,10 +23,8 @@ import (
|
||||
"github.com/spf13/cobra"
|
||||
"golang.org/x/net/context"
|
||||
"io"
|
||||
"net"
|
||||
"os"
|
||||
"sort"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
@@ -169,166 +167,6 @@ func modVrf(typ string, args []string) error {
|
||||
return err
|
||||
}
|
||||
|
||||
func modVrfPath(modtype string, vrf string, args []string) error {
|
||||
rf, err := checkAddressFamily(net.IP{})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var nlri bgp.AddrPrefixInterface
|
||||
var nexthop string
|
||||
|
||||
switch rf {
|
||||
case bgp.RF_IPv4_UC, bgp.RF_IPv6_UC:
|
||||
if len(args) != 1 {
|
||||
return fmt.Errorf("usage: vrf %s rib %s <prefix> -a { ipv4 | ipv6 }", vrf, modtype)
|
||||
}
|
||||
ip, net, _ := net.ParseCIDR(args[0])
|
||||
if rf == bgp.RF_IPv4_UC {
|
||||
if ip.To4() == nil {
|
||||
return fmt.Errorf("invalid ipv4 prefix")
|
||||
}
|
||||
nexthop = "0.0.0.0"
|
||||
ones, _ := net.Mask.Size()
|
||||
nlri = bgp.NewNLRInfo(uint8(ones), ip.String())
|
||||
} else {
|
||||
if ip.To16() == nil {
|
||||
return fmt.Errorf("invalid ipv6 prefix")
|
||||
}
|
||||
nexthop = "::"
|
||||
ones, _ := net.Mask.Size()
|
||||
nlri = bgp.NewIPv6AddrPrefix(uint8(ones), ip.String())
|
||||
}
|
||||
case bgp.RF_EVPN:
|
||||
if len(args) < 1 {
|
||||
return fmt.Errorf("usage: vrf %s rib %s { macadv | multicast } ... -a evpn", vrf, modtype)
|
||||
}
|
||||
subtype := args[0]
|
||||
args = args[1:]
|
||||
|
||||
switch subtype {
|
||||
case "macadv":
|
||||
if len(args) < 4 {
|
||||
return fmt.Errorf("usage: vrf %s rib %s macadv <mac address> <ip address> <etag> <label> -a evpn", vrf, modtype)
|
||||
}
|
||||
mac, err := net.ParseMAC(args[0])
|
||||
if err != nil {
|
||||
return fmt.Errorf("invalid mac: %s", args[0])
|
||||
}
|
||||
var ip net.IP
|
||||
iplen := 0
|
||||
if args[1] != "0.0.0.0" || args[1] != "::" {
|
||||
ip = net.ParseIP(args[1])
|
||||
if ip == nil {
|
||||
return fmt.Errorf("invalid ip prefix: %s", args[1])
|
||||
}
|
||||
iplen = net.IPv4len * 8
|
||||
if ip.To4() == nil {
|
||||
iplen = net.IPv6len * 8
|
||||
}
|
||||
}
|
||||
eTag, err := strconv.Atoi(args[2])
|
||||
if err != nil {
|
||||
return fmt.Errorf("invalid eTag: %s. err: %s", args[2], err)
|
||||
}
|
||||
label, err := strconv.Atoi(args[3])
|
||||
if err != nil {
|
||||
return fmt.Errorf("invalid label: %s. err: %s", args[3], err)
|
||||
}
|
||||
macIpAdv := &bgp.EVPNMacIPAdvertisementRoute{
|
||||
ESI: bgp.EthernetSegmentIdentifier{
|
||||
Type: bgp.ESI_ARBITRARY,
|
||||
},
|
||||
MacAddressLength: 48,
|
||||
MacAddress: mac,
|
||||
IPAddressLength: uint8(iplen),
|
||||
IPAddress: ip,
|
||||
Labels: []uint32{uint32(label)},
|
||||
ETag: uint32(eTag),
|
||||
}
|
||||
nlri = bgp.NewEVPNNLRI(bgp.EVPN_ROUTE_TYPE_MAC_IP_ADVERTISEMENT, 0, macIpAdv)
|
||||
case "multicast":
|
||||
if len(args) < 2 {
|
||||
return fmt.Errorf("usage : vrf %s rib %s multicast <ip address> <etag> -a evpn", vrf, modtype)
|
||||
}
|
||||
|
||||
var ip net.IP
|
||||
iplen := 0
|
||||
if args[0] != "0.0.0.0" || args[0] != "::" {
|
||||
ip = net.ParseIP(args[0])
|
||||
if ip == nil {
|
||||
return fmt.Errorf("invalid ip prefix: %s", args[0])
|
||||
}
|
||||
iplen = net.IPv4len * 8
|
||||
if ip.To4() == nil {
|
||||
iplen = net.IPv6len * 8
|
||||
}
|
||||
}
|
||||
|
||||
eTag, err := strconv.Atoi(args[1])
|
||||
if err != nil {
|
||||
return fmt.Errorf("invalid eTag: %s. err: %s", args[1], err)
|
||||
}
|
||||
|
||||
multicastEtag := &bgp.EVPNMulticastEthernetTagRoute{
|
||||
IPAddressLength: uint8(iplen),
|
||||
IPAddress: ip,
|
||||
ETag: uint32(eTag),
|
||||
}
|
||||
nlri = bgp.NewEVPNNLRI(bgp.EVPN_INCLUSIVE_MULTICAST_ETHERNET_TAG, 0, multicastEtag)
|
||||
default:
|
||||
return fmt.Errorf("usage: vrf %s rib %s { macadv | multicast | ... -a evpn", vrf, modtype)
|
||||
}
|
||||
nexthop = "0.0.0.0"
|
||||
default:
|
||||
return fmt.Errorf("Unsupported route family: %s", rf)
|
||||
}
|
||||
|
||||
arg := &api.ModPathArguments{
|
||||
Resource: api.Resource_VRF,
|
||||
Name: vrf,
|
||||
RawPattrs: make([][]byte, 0),
|
||||
}
|
||||
|
||||
switch modtype {
|
||||
case CMD_ADD:
|
||||
arg.IsWithdraw = false
|
||||
case CMD_DEL:
|
||||
arg.IsWithdraw = true
|
||||
}
|
||||
|
||||
if rf == bgp.RF_IPv4_UC {
|
||||
arg.RawNlri, _ = nlri.Serialize()
|
||||
n, _ := bgp.NewPathAttributeNextHop(nexthop).Serialize()
|
||||
arg.RawPattrs = append(arg.RawPattrs, n)
|
||||
} else {
|
||||
mpreach, _ := bgp.NewPathAttributeMpReachNLRI(nexthop, []bgp.AddrPrefixInterface{nlri}).Serialize()
|
||||
arg.RawPattrs = append(arg.RawPattrs, mpreach)
|
||||
}
|
||||
|
||||
origin, _ := bgp.NewPathAttributeOrigin(bgp.BGP_ORIGIN_ATTR_TYPE_IGP).Serialize()
|
||||
arg.RawPattrs = append(arg.RawPattrs, origin)
|
||||
|
||||
stream, err := client.ModPath(context.Background())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = stream.Send(arg)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
stream.CloseSend()
|
||||
|
||||
res, e := stream.CloseAndRecv()
|
||||
if e != nil {
|
||||
return e
|
||||
}
|
||||
if res.Code != api.Error_SUCCESS {
|
||||
return fmt.Errorf("error: code: %d, msg: %s", res.Code, res.Msg)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func NewVrfCmd() *cobra.Command {
|
||||
|
||||
ribCmd := &cobra.Command{
|
||||
@@ -351,7 +189,7 @@ func NewVrfCmd() *cobra.Command {
|
||||
cmd := &cobra.Command{
|
||||
Use: v,
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
err := modVrfPath(cmd.Use, args[len(args)-1], args[:len(args)-1])
|
||||
err := modPath(api.Resource_VRF, args[len(args)-1], cmd.Use, args[:len(args)-1])
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
os.Exit(1)
|
||||
|
||||
+6
-4
@@ -846,23 +846,25 @@ func (server *BgpServer) handleModPathRequest(grpcReq *GrpcRequest, peerInfo *ta
|
||||
extcomms := make([]bgp.ExtendedCommunityInterface, 0)
|
||||
var nexthop string
|
||||
var rf bgp.RouteFamily
|
||||
var path *api.Path
|
||||
|
||||
arg, ok := grpcReq.Data.(*api.ModPathArguments)
|
||||
if !ok {
|
||||
result.ResponseErr = fmt.Errorf("type assertion failed")
|
||||
goto ERR
|
||||
}
|
||||
path = arg.Path
|
||||
|
||||
if len(arg.RawNlri) > 0 {
|
||||
if len(path.Nlri) > 0 {
|
||||
nlri = &bgp.NLRInfo{}
|
||||
err := nlri.DecodeFromBytes(arg.RawNlri)
|
||||
err := nlri.DecodeFromBytes(path.Nlri)
|
||||
if err != nil {
|
||||
result.ResponseErr = err
|
||||
goto ERR
|
||||
}
|
||||
}
|
||||
|
||||
for _, attr := range arg.RawPattrs {
|
||||
for _, attr := range path.Pattrs {
|
||||
p, err := bgp.GetPathAttribute(attr)
|
||||
if err != nil {
|
||||
result.ResponseErr = err
|
||||
@@ -956,7 +958,7 @@ func (server *BgpServer) handleModPathRequest(grpcReq *GrpcRequest, peerInfo *ta
|
||||
pattr = append(pattr, bgp.NewPathAttributeExtendedCommunities(extcomms))
|
||||
}
|
||||
|
||||
return []*table.Path{table.NewPath(peerInfo, nlri, arg.IsWithdraw, pattr, false, time.Now(), arg.NoImplicitWithdraw)}
|
||||
return []*table.Path{table.NewPath(peerInfo, nlri, path.IsWithdraw, pattr, false, time.Now(), path.NoImplicitWithdraw)}
|
||||
ERR:
|
||||
grpcReq.ResponseCh <- result
|
||||
close(grpcReq.ResponseCh)
|
||||
|
||||
Reference in New Issue
Block a user