summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--docs/sources/flowspec.md18
-rw-r--r--gobgp/cmd/global.go1
-rw-r--r--packet/bgp/bgp.go28
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
}