api/cli: reuse api.Path in ModPathArguments

kill redundant lines

Signed-off-by: ISHIDA Wataru <[email protected]>
This commit is contained in:
ISHIDA Wataru
2015-08-13 20:15:54 +09:00
committed by FUJITA Tomonori
parent af0c03bbec
commit 56ca9eee5f
6 changed files with 120 additions and 252 deletions
+17 -12
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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)