Example #1
0
File: policy.go Project: osrg/gobgp
func modAction(name, op string, args []string) error {
	stmt := config.Statement{
		Name: name,
	}
	usage := fmt.Sprintf("usage: gobgp policy statement %s %s action", name, op)
	if len(args) < 1 {
		return fmt.Errorf("%s { reject | accept | community | ext-community | large-community | med | local-pref | as-prepend | next-hop }", usage)
	}
	typ := args[0]
	args = args[1:]
	switch typ {
	case "reject":
		stmt.Actions.RouteDisposition = config.ROUTE_DISPOSITION_REJECT_ROUTE
	case "accept":
		stmt.Actions.RouteDisposition = config.ROUTE_DISPOSITION_ACCEPT_ROUTE
	case "community":
		if len(args) < 1 {
			return fmt.Errorf("%s community { add | remove | replace } <value>...", usage)
		}
		stmt.Actions.BgpActions.SetCommunity.SetCommunityMethod.CommunitiesList = args[1:]
		switch strings.ToLower(args[0]) {
		case "add":
			stmt.Actions.BgpActions.SetCommunity.Options = string(config.BGP_SET_COMMUNITY_OPTION_TYPE_ADD)
		case "remove":
			stmt.Actions.BgpActions.SetCommunity.Options = string(config.BGP_SET_COMMUNITY_OPTION_TYPE_REMOVE)
		case "replace":
			stmt.Actions.BgpActions.SetCommunity.Options = string(config.BGP_SET_COMMUNITY_OPTION_TYPE_REPLACE)
		default:
			return fmt.Errorf("%s community { add | remove | replace } <value>...", usage)
		}
	case "ext-community":
		if len(args) < 1 {
			return fmt.Errorf("%s ext-community { add | remove | replace } <value>...", usage)
		}
		stmt.Actions.BgpActions.SetExtCommunity.SetExtCommunityMethod.CommunitiesList = args[1:]
		switch strings.ToLower(args[0]) {
		case "add":
			stmt.Actions.BgpActions.SetExtCommunity.Options = string(config.BGP_SET_COMMUNITY_OPTION_TYPE_ADD)
		case "remove":
			stmt.Actions.BgpActions.SetExtCommunity.Options = string(config.BGP_SET_COMMUNITY_OPTION_TYPE_REMOVE)
		case "replace":
			stmt.Actions.BgpActions.SetExtCommunity.Options = string(config.BGP_SET_COMMUNITY_OPTION_TYPE_REPLACE)
		default:
			return fmt.Errorf("%s ext-community { add | remove | replace } <value>...", usage)
		}
	case "large-community":
		if len(args) < 1 {
			return fmt.Errorf("%s large-community { add | remove | replace } <value>...", usage)
		}
		stmt.Actions.BgpActions.SetLargeCommunity.SetLargeCommunityMethod.CommunitiesList = args[1:]
		switch strings.ToLower(args[0]) {
		case "add":
			stmt.Actions.BgpActions.SetLargeCommunity.Options = config.BGP_SET_COMMUNITY_OPTION_TYPE_ADD
		case "remove":
			stmt.Actions.BgpActions.SetLargeCommunity.Options = config.BGP_SET_COMMUNITY_OPTION_TYPE_REMOVE
		case "replace":
			stmt.Actions.BgpActions.SetLargeCommunity.Options = config.BGP_SET_COMMUNITY_OPTION_TYPE_REPLACE
		default:
			return fmt.Errorf("%s large-community { add | remove | replace } <value>...", usage)
		}
	case "med":
		if len(args) < 2 {
			return fmt.Errorf("%s med { add | sub | set } <value>", usage)
		}
		med, err := strconv.Atoi(args[1])
		if err != nil {
			return err
		}
		switch strings.ToLower(args[0]) {
		case "add":
			stmt.Actions.BgpActions.SetMed = config.BgpSetMedType(fmt.Sprintf("+%d", med))
		case "sub":
			stmt.Actions.BgpActions.SetMed = config.BgpSetMedType(fmt.Sprintf("-%d", med))
		case "set":
			stmt.Actions.BgpActions.SetMed = config.BgpSetMedType(fmt.Sprintf("%d", med))
		default:
			return fmt.Errorf("%s med { add | sub | set } <value>", usage)
		}
	case "local-pref":
		if len(args) < 1 {
			return fmt.Errorf("%s local-pref <value>", usage)
		}
		value, err := strconv.ParseUint(args[0], 10, 32)
		if err != nil {
			return err
		}
		stmt.Actions.BgpActions.SetLocalPref = uint32(value)
	case "as-prepend":
		if len(args) < 2 {
			return fmt.Errorf("%s as-prepend { <asn> | last-as } <repeat-value>", usage)
		}
		stmt.Actions.BgpActions.SetAsPathPrepend.As = args[0]
		repeat, err := strconv.Atoi(args[1])
		if err != nil {
			return err
		}
		stmt.Actions.BgpActions.SetAsPathPrepend.RepeatN = uint8(repeat)
	case "next-hop":
		if len(args) != 1 {
			return fmt.Errorf("%s next-hop { <value> | self }", usage)
		}
		stmt.Actions.BgpActions.SetNextHop = config.BgpNextHopType(args[0])
	}
	t, err := table.NewStatement(stmt)
	switch op {
	case CMD_ADD:
		err = client.AddStatement(t)
	case CMD_DEL:
		err = client.DeleteStatement(t, false)
	case CMD_SET:
		err = client.ReplaceStatement(t)
	default:
		return fmt.Errorf("invalid operation: %s", op)
	}
	return err
}
Example #2
0
File: policy.go Project: osrg/gobgp
func modCondition(name, op string, args []string) error {
	stmt := config.Statement{
		Name: name,
	}
	usage := fmt.Sprintf("usage: gobgp policy statement %s %s condition", name, op)
	if len(args) < 1 {
		return fmt.Errorf("%s { prefix | neighbor | as-path | community | ext-community | large-community | as-path-length | rpki | route-type }", usage)
	}
	typ := args[0]
	args = args[1:]
	switch typ {
	case "prefix":
		if len(args) < 1 {
			return fmt.Errorf("%s prefix <set-name> [{ any | invert }]", usage)
		}
		stmt.Conditions.MatchPrefixSet.PrefixSet = args[0]
		if len(args) == 1 {
			break
		}
		switch strings.ToLower(args[1]) {
		case "any":
			stmt.Conditions.MatchPrefixSet.MatchSetOptions = config.MATCH_SET_OPTIONS_RESTRICTED_TYPE_ANY
		case "invert":
			stmt.Conditions.MatchPrefixSet.MatchSetOptions = config.MATCH_SET_OPTIONS_RESTRICTED_TYPE_INVERT
		default:
			return fmt.Errorf("%s prefix <set-name> [{ any | invert }]", usage)
		}
	case "neighbor":
		if len(args) < 1 {
			return fmt.Errorf("%s neighbor <set-name> [{ any | invert }]", usage)
		}
		stmt.Conditions.MatchNeighborSet.NeighborSet = args[0]
		if len(args) == 1 {
			break
		}
		switch strings.ToLower(args[1]) {
		case "any":
			stmt.Conditions.MatchNeighborSet.MatchSetOptions = config.MATCH_SET_OPTIONS_RESTRICTED_TYPE_ANY
		case "invert":
			stmt.Conditions.MatchNeighborSet.MatchSetOptions = config.MATCH_SET_OPTIONS_RESTRICTED_TYPE_INVERT
		default:
			return fmt.Errorf("%s neighbor <set-name> [{ any | invert }]", usage)
		}
	case "as-path":
		if len(args) < 1 {
			return fmt.Errorf("%s as-path <set-name> [{ any | all | invert }]", usage)
		}
		stmt.Conditions.BgpConditions.MatchAsPathSet.AsPathSet = args[0]
		if len(args) == 1 {
			break
		}
		switch strings.ToLower(args[1]) {
		case "any":
			stmt.Conditions.BgpConditions.MatchAsPathSet.MatchSetOptions = config.MATCH_SET_OPTIONS_TYPE_ANY
		case "all":
			stmt.Conditions.BgpConditions.MatchAsPathSet.MatchSetOptions = config.MATCH_SET_OPTIONS_TYPE_ALL
		case "invert":
			stmt.Conditions.BgpConditions.MatchAsPathSet.MatchSetOptions = config.MATCH_SET_OPTIONS_TYPE_INVERT
		default:
			return fmt.Errorf("%s as-path <set-name> [{ any | all | invert }]", usage)
		}
	case "community":
		if len(args) < 1 {
			return fmt.Errorf("%s community <set-name> [{ any | all | invert }]", usage)
		}
		stmt.Conditions.BgpConditions.MatchCommunitySet.CommunitySet = args[0]
		if len(args) == 1 {
			break
		}
		switch strings.ToLower(args[1]) {
		case "any":
			stmt.Conditions.BgpConditions.MatchCommunitySet.MatchSetOptions = config.MATCH_SET_OPTIONS_TYPE_ANY
		case "all":
			stmt.Conditions.BgpConditions.MatchCommunitySet.MatchSetOptions = config.MATCH_SET_OPTIONS_TYPE_ALL
		case "invert":
			stmt.Conditions.BgpConditions.MatchCommunitySet.MatchSetOptions = config.MATCH_SET_OPTIONS_TYPE_INVERT
		default:
			return fmt.Errorf("%s community <set-name> [{ any | all | invert }]", usage)
		}
	case "ext-community":
		if len(args) < 1 {
			return fmt.Errorf("%s ext-community <set-name> [{ any | all | invert }]", usage)
		}
		stmt.Conditions.BgpConditions.MatchExtCommunitySet.ExtCommunitySet = args[0]
		if len(args) == 1 {
			break
		}
		switch strings.ToLower(args[1]) {
		case "any":
			stmt.Conditions.BgpConditions.MatchExtCommunitySet.MatchSetOptions = config.MATCH_SET_OPTIONS_TYPE_ANY
		case "all":
			stmt.Conditions.BgpConditions.MatchExtCommunitySet.MatchSetOptions = config.MATCH_SET_OPTIONS_TYPE_ALL
		case "invert":
			stmt.Conditions.BgpConditions.MatchExtCommunitySet.MatchSetOptions = config.MATCH_SET_OPTIONS_TYPE_INVERT
		default:
			return fmt.Errorf("%s ext-community <set-name> [{ any | all | invert }]", usage)
		}
	case "large-community":
		if len(args) < 1 {
			return fmt.Errorf("%s large-community <set-name> [{ any | all | invert }]", usage)
		}
		stmt.Conditions.BgpConditions.MatchLargeCommunitySet.LargeCommunitySet = args[0]
		if len(args) == 1 {
			break
		}
		switch strings.ToLower(args[1]) {
		case "any":
			stmt.Conditions.BgpConditions.MatchLargeCommunitySet.MatchSetOptions = config.MATCH_SET_OPTIONS_TYPE_ANY
		case "all":
			stmt.Conditions.BgpConditions.MatchLargeCommunitySet.MatchSetOptions = config.MATCH_SET_OPTIONS_TYPE_ALL
		case "invert":
			stmt.Conditions.BgpConditions.MatchLargeCommunitySet.MatchSetOptions = config.MATCH_SET_OPTIONS_TYPE_INVERT
		default:
			return fmt.Errorf("%s large-community <set-name> [{ any | all | invert }]", usage)
		}
	case "as-path-length":
		if len(args) < 2 {
			return fmt.Errorf("%s as-path-length <length> { eq | ge | le }", usage)
		}
		length, err := strconv.Atoi(args[0])
		if err != nil {
			return err
		}
		stmt.Conditions.BgpConditions.AsPathLength.Value = uint32(length)
		switch strings.ToLower(args[1]) {
		case "eq":
			stmt.Conditions.BgpConditions.AsPathLength.Operator = config.ATTRIBUTE_COMPARISON_EQ
		case "ge":
			stmt.Conditions.BgpConditions.AsPathLength.Operator = config.ATTRIBUTE_COMPARISON_GE
		case "le":
			stmt.Conditions.BgpConditions.AsPathLength.Operator = config.ATTRIBUTE_COMPARISON_LE
		default:
			return fmt.Errorf("%s as-path-length <length> { eq | ge | le }", usage)
		}
	case "rpki":
		if len(args) < 1 {
			return fmt.Errorf("%s rpki { valid | invalid | not-found }", usage)
		}
		switch strings.ToLower(args[0]) {
		case "valid":
			stmt.Conditions.BgpConditions.RpkiValidationResult = config.RPKI_VALIDATION_RESULT_TYPE_VALID
		case "invalid":
			stmt.Conditions.BgpConditions.RpkiValidationResult = config.RPKI_VALIDATION_RESULT_TYPE_INVALID
		case "not-found":
			stmt.Conditions.BgpConditions.RpkiValidationResult = config.RPKI_VALIDATION_RESULT_TYPE_NOT_FOUND
		default:
			return fmt.Errorf("%s rpki { valid | invalid | not-found }", usage)
		}
	case "route-type":
		err := fmt.Errorf("%s route-type { internal | external | local }", usage)
		if len(args) < 1 {
			return err
		}
		switch strings.ToLower(args[0]) {
		case "internal":
			stmt.Conditions.BgpConditions.RouteType = config.ROUTE_TYPE_INTERNAL
		case "external":
			stmt.Conditions.BgpConditions.RouteType = config.ROUTE_TYPE_EXTERNAL
		case "local":
			stmt.Conditions.BgpConditions.RouteType = config.ROUTE_TYPE_LOCAL
		default:
			return err
		}
	default:
		return fmt.Errorf("%s { prefix | neighbor | as-path | community | ext-community | large-community | as-path-length | rpki | route-type }", usage)
	}

	t, err := table.NewStatement(stmt)
	if err != nil {
		return err
	}
	switch op {
	case CMD_ADD:
		err = client.AddStatement(t)
	case CMD_DEL:
		err = client.DeleteStatement(t, false)
	case CMD_SET:
		err = client.ReplaceStatement(t)
	default:
		return fmt.Errorf("invalid operation: %s", op)
	}
	return err
}