func modVrf(typ string, args []string) error { var err error switch typ { case CMD_ADD: a := extractReserved(args, []string{"rd", "rt", "id"}) if len(a[""]) != 1 || len(a["rd"]) != 1 || len(a["rt"]) < 2 || len(a["id"]) > 1 { return fmt.Errorf("Usage: gobgp vrf add <vrf name> [ id <id> ] rd <rd> rt { import | export | both } <rt>...") } name := a[""][0] rd, err := bgp.ParseRouteDistinguisher(a["rd"][0]) if err != nil { return err } cur := "" importRt := make([]bgp.ExtendedCommunityInterface, 0) exportRt := make([]bgp.ExtendedCommunityInterface, 0) for _, elem := range a["rt"] { if elem == "import" || elem == "export" || elem == "both" { cur = elem continue } rt, err := bgp.ParseRouteTarget(elem) if err != nil { return err } switch cur { case "import": importRt = append(importRt, rt) case "export": exportRt = append(exportRt, rt) case "both": importRt = append(importRt, rt) exportRt = append(exportRt, rt) default: return fmt.Errorf("Usage: gobgp vrf add <vrf name> rd <rd> rt { import | export | both } <rt>...") } } vrfId := 0 if len(a["id"]) > 0 { vrfId, err = strconv.Atoi(a["id"][0]) if err != nil { return err } } err = client.AddVRF(name, vrfId, rd, importRt, exportRt) case CMD_DEL: if len(args) != 1 { return fmt.Errorf("Usage: gobgp vrf del <vrf name>") } err = client.DeleteVRF(args[0]) } return err }
func rtParser(args []string) ([]bgp.ExtendedCommunityInterface, error) { if len(args) < 2 || args[0] != ExtCommNameMap[RT] { return nil, fmt.Errorf("invalid rt") } exts := make([]bgp.ExtendedCommunityInterface, 0, len(args[1:])) for _, arg := range args[1:] { rt, err := bgp.ParseRouteTarget(arg) if err != nil { return nil, err } exts = append(exts, rt) } return exts, nil }
func redirectParser(args []string) ([]bgp.ExtendedCommunityInterface, error) { if len(args) < 2 || args[0] != ExtCommNameMap[REDIRECT] { return nil, fmt.Errorf("invalid redirect") } rt, err := bgp.ParseRouteTarget(strings.Join(args[1:], " ")) if err != nil { return nil, err } t, _ := rt.GetTypes() switch t { case bgp.EC_TYPE_TRANSITIVE_TWO_OCTET_AS_SPECIFIC: r := rt.(*bgp.TwoOctetAsSpecificExtended) return []bgp.ExtendedCommunityInterface{bgp.NewRedirectTwoOctetAsSpecificExtended(r.AS, r.LocalAdmin)}, nil case bgp.EC_TYPE_TRANSITIVE_IP4_SPECIFIC: r := rt.(*bgp.IPv4AddressSpecificExtended) return []bgp.ExtendedCommunityInterface{bgp.NewRedirectIPv4AddressSpecificExtended(r.IPv4.String(), r.LocalAdmin)}, nil case bgp.EC_TYPE_TRANSITIVE_FOUR_OCTET_AS_SPECIFIC: r := rt.(*bgp.FourOctetAsSpecificExtended) return []bgp.ExtendedCommunityInterface{bgp.NewRedirectFourOctetAsSpecificExtended(r.AS, r.LocalAdmin)}, nil } return nil, fmt.Errorf("invalid redirect") }
func modVrf(typ string, args []string) error { var err error switch typ { case CMD_ADD: if len(args) < 6 || args[1] != "rd" || args[3] != "rt" { return fmt.Errorf("Usage: gobgp vrf add <vrf name> rd <rd> rt { import | export | both } <rt>...") } name := args[0] rd, err := bgp.ParseRouteDistinguisher(args[2]) if err != nil { return err } cur := "" importRt := make([][]byte, 0) exportRt := make([][]byte, 0) for _, elem := range args[4:] { if elem == "import" || elem == "export" || elem == "both" { cur = elem continue } rt, err := bgp.ParseRouteTarget(elem) if err != nil { return err } buf, err := rt.Serialize() if err != nil { return err } switch cur { case "import": importRt = append(importRt, buf) case "export": exportRt = append(exportRt, buf) case "both": importRt = append(importRt, buf) exportRt = append(exportRt, buf) default: return fmt.Errorf("Usage: gobgp vrf add <vrf name> rd <rd> rt { import | export | both } <rt>...") } } buf, _ := rd.Serialize() arg := &api.AddVrfRequest{ Vrf: &api.Vrf{ Name: name, Rd: buf, ImportRt: importRt, ExportRt: exportRt, }, } _, err = client.AddVrf(context.Background(), arg) case CMD_DEL: if len(args) != 1 { return fmt.Errorf("Usage: gobgp vrf del <vrf name>") } arg := &api.DeleteVrfRequest{ Vrf: &api.Vrf{ Name: args[0], }, } _, err = client.DeleteVrf(context.Background(), arg) } return err }