diff options
-rw-r--r-- | docs/sources/flowspec.md | 18 | ||||
-rw-r--r-- | gobgp/cmd/global.go | 1 | ||||
-rw-r--r-- | packet/bgp/bgp.go | 28 |
3 files changed, 23 insertions, 24 deletions
diff --git a/docs/sources/flowspec.md b/docs/sources/flowspec.md index 1181cce8..8fddcccc 100644 --- a/docs/sources/flowspec.md +++ b/docs/sources/flowspec.md @@ -44,15 +44,15 @@ CLI syntax to add ipv4/ipv6 flowspec rule is ```shell % global rib add match <MATCH_EXPR> then <THEN_EXPR> -a [ipv4-flowspec|ipv6-flowspec] - <MATCH_EXPR> : { destination <PREFIX> | source <PREFIX> | - protocol <PROTO>... | fragment <FRAGMENT_TYPE> | tcp-flags <TCPFLAG>... | - { port | destination-port | source-port | icmp-type | icmp-code | packet-length | dscp } <ITEM>... }... - <PROTO> : ipip, sctp, unknown, igmp, tcp, egp, rsvp, pim, icmp, igp, udp, gre, ospf - <FRAGMENT_TYPE> : dont-fragment, is-fragment, first-fragment, last-fragment, not-a-fragment - <TCPFLAG> : push, ack, urgent, fin, syn, rst - <ITEM> : &?{<|>|=}<value> - <THEN_EXPR> : { accept | discard | rate-limit <value> | redirect <RT> | mark <value> | action { sample | terminal | sample-terminal } | rt <RT>... }... - <RT> : xxx:yyy, xx.xx.xx.xx:yyy, xxx.xxx:yyy + <MATCH_EXPR> : { destination <PREFIX> [<OFFSET>] | source <PREFIX> [<OFFSET>] | + protocol <PROTO>... | fragment <FRAGMENT_TYPE> | tcp-flags [not] [match] <TCPFLAG>... | + { port | destination-port | source-port | icmp-type | icmp-code | packet-length | dscp | label } <ITEM>... }... + <PROTO> : ospf, pim, igp, udp, igmp, tcp, egp, rsvp, gre, ipip, unknown, icmp, sctp, <VALUE> + <FRAGMENT_TYPE> : dont-fragment, is-fragment, first-fragment, last-fragment, not-a-fragment + <TCPFLAG> : rst, push, ack, urgent, fin, syn + <ITEM> : &?{<|>|=}<value> + <THEN_EXPR> : { accept | discard | rate-limit <value> | redirect <RT> | mark <value> | action { sample | terminal | sample-terminal } | rt <RT>... }... + <RT> : xxx:yyy, xx.xx.xx.xx:yyy, xxx.xxx:yyy ``` that for l2vpn flowspec rule is diff --git a/gobgp/cmd/global.go b/gobgp/cmd/global.go index c9bc97d6..98a1e1ed 100644 --- a/gobgp/cmd/global.go +++ b/gobgp/cmd/global.go @@ -767,6 +767,7 @@ func modPath(resource api.Resource, name, modtype string, args []string) error { for _, v := range bgp.ProtocolNameMap { ss = append(ss, v) } + ss = append(ss, "<VALUE>") protos := strings.Join(ss, ", ") ss = make([]string, 0, len(bgp.TCPFlagNameMap)) for _, v := range bgp.TCPFlagNameMap { diff --git a/packet/bgp/bgp.go b/packet/bgp/bgp.go index b74aa838..cd767937 100644 --- a/packet/bgp/bgp.go +++ b/packet/bgp/bgp.go @@ -2218,28 +2218,26 @@ func flowSpecPrefixParser(rf RouteFamily, args []string) (FlowSpecComponentInter } func flowSpecIpProtoParser(rf RouteFamily, args []string) (FlowSpecComponentInterface, error) { - ss := make([]string, 0, len(ProtocolNameMap)) - for _, v := range ProtocolNameMap { - ss = append(ss, v) - } - protos := strings.Join(ss, "|") - exp := regexp.MustCompile(fmt.Sprintf("^%s (((%s) )*)(%s)$", FlowSpecNameMap[FLOW_SPEC_TYPE_IP_PROTO], protos, protos)) - elems := exp.FindStringSubmatch(strings.Join(args, " ")) - if len(elems) < 2 { + if len(args) < 2 || args[0] != FlowSpecNameMap[FLOW_SPEC_TYPE_IP_PROTO] { return nil, fmt.Errorf("invalid ip-proto format") } items := make([]*FlowSpecComponentItem, 0) eq := 0x1 - if elems[1] != "" { - for _, v := range strings.Split(elems[1], " ") { - p, ok := ProtocolValueMap[v] - if !ok { - continue - } + for _, v := range args[1:] { + if v == "" { + continue + } + p, ok := ProtocolValueMap[v] + if ok { items = append(items, NewFlowSpecComponentItem(eq, int(p))) + continue + } + i, err := strconv.ParseUint(v, 10, 8) + if err != nil { + return nil, fmt.Errorf("invalid ip-proto format: failed to parse %s", v) } + items = append(items, NewFlowSpecComponentItem(eq, int(i))) } - items = append(items, NewFlowSpecComponentItem(eq, int(ProtocolValueMap[elems[4]]))) return NewFlowSpecComponent(FLOW_SPEC_TYPE_IP_PROTO, items), nil } |