summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorSatoshi Fujimoto <satoshi.fujimoto7@gmail.com>2017-12-11 16:19:50 +0900
committerFUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>2017-12-16 20:27:06 +0900
commitb2ca825f6d55fb316a01909aedab44e865d6f53d (patch)
tree516e66df230ba6aca3a6d4745b7add2c6ea79fc0
parent694d364d09ae9d272a7cacefc23b7fcefcf05617 (diff)
table/policy: Support prefix representation in NeighborSet
Currently, "neighbor-set" supports only IP address representation and IP prefix representation(such as "192.168.0.0/24") is not supported. This commit enables to accept the prefix representation for "neighbor-set" to allow neighbors to be specified as range. Signed-off-by: Satoshi Fujimoto <satoshi.fujimoto7@gmail.com>
-rw-r--r--api/grpc_server.go10
-rw-r--r--config/bgp_configs.go2
-rw-r--r--gobgp/cmd/policy.go5
-rw-r--r--table/policy.go32
-rw-r--r--tools/pyang_plugins/gobgp.yang2
5 files changed, 32 insertions, 19 deletions
diff --git a/api/grpc_server.go b/api/grpc_server.go
index 15bf769f..b7c1eb74 100644
--- a/api/grpc_server.go
+++ b/api/grpc_server.go
@@ -1440,13 +1440,13 @@ func NewDefinedSetFromApiStruct(a *DefinedSet) (table.DefinedSet, error) {
}
return table.NewPrefixSetFromApiStruct(a.Name, prefixes)
case table.DEFINED_TYPE_NEIGHBOR:
- list := make([]net.IP, 0, len(a.List))
+ list := make([]net.IPNet, 0, len(a.List))
for _, x := range a.List {
- addr := net.ParseIP(x)
- if addr == nil {
- return nil, fmt.Errorf("invalid ip address format: %s", x)
+ _, addr, err := net.ParseCIDR(x)
+ if err != nil {
+ return nil, fmt.Errorf("invalid address or prefix: %s", x)
}
- list = append(list, addr)
+ list = append(list, *addr)
}
return table.NewNeighborSetFromApiStruct(a.Name, list)
case table.DEFINED_TYPE_AS_PATH:
diff --git a/config/bgp_configs.go b/config/bgp_configs.go
index 1c87bb88..1b219172 100644
--- a/config/bgp_configs.go
+++ b/config/bgp_configs.go
@@ -5986,7 +5986,7 @@ type NeighborSet struct {
NeighborSetName string `mapstructure:"neighbor-set-name" json:"neighbor-set-name,omitempty"`
// original -> gobgp:neighbor-info
// original type is list of inet:ip-address
- // neighbor ip address.
+ // neighbor ip address or prefix.
NeighborInfoList []string `mapstructure:"neighbor-info-list" json:"neighbor-info-list,omitempty"`
}
diff --git a/gobgp/cmd/policy.go b/gobgp/cmd/policy.go
index 8c57b3a3..0edde4c5 100644
--- a/gobgp/cmd/policy.go
+++ b/gobgp/cmd/policy.go
@@ -176,7 +176,10 @@ func parseNeighborSet(args []string) (table.DefinedSet, error) {
for _, arg := range args {
address := net.ParseIP(arg)
if address.To4() == nil && address.To16() == nil {
- return nil, fmt.Errorf("invalid address: %s\nplease enter ipv4 or ipv6 format", arg)
+ _, _, err := net.ParseCIDR(arg)
+ if err != nil {
+ return nil, fmt.Errorf("invalid address or prefix: %s\nplease enter ipv4 or ipv6 format", arg)
+ }
}
}
return table.NewNeighborSet(config.NeighborSet{
diff --git a/table/policy.go b/table/policy.go
index fe153cf4..e1b7d690 100644
--- a/table/policy.go
+++ b/table/policy.go
@@ -536,7 +536,7 @@ func NewPrefixSet(c config.PrefixSet) (*PrefixSet, error) {
type NeighborSet struct {
name string
- list []net.IP
+ list []net.IPNet
}
func (s *NeighborSet) Name() string {
@@ -561,11 +561,11 @@ func (lhs *NeighborSet) Remove(arg DefinedSet) error {
if !ok {
return fmt.Errorf("type cast failed")
}
- ps := make([]net.IP, 0, len(lhs.list))
+ ps := make([]net.IPNet, 0, len(lhs.list))
for _, x := range lhs.list {
found := false
for _, y := range rhs.list {
- if x.Equal(y) {
+ if x.String() == y.String() {
found = true
break
}
@@ -610,7 +610,7 @@ func (s *NeighborSet) MarshalJSON() ([]byte, error) {
return json.Marshal(s.ToConfig())
}
-func NewNeighborSetFromApiStruct(name string, list []net.IP) (*NeighborSet, error) {
+func NewNeighborSetFromApiStruct(name string, list []net.IPNet) (*NeighborSet, error) {
return &NeighborSet{
name: name,
list: list,
@@ -625,13 +625,24 @@ func NewNeighborSet(c config.NeighborSet) (*NeighborSet, error) {
}
return nil, fmt.Errorf("empty neighbor set name")
}
- list := make([]net.IP, 0, len(c.NeighborInfoList))
+ list := make([]net.IPNet, 0, len(c.NeighborInfoList))
for _, x := range c.NeighborInfoList {
- addr := net.ParseIP(x)
- if addr == nil {
- return nil, fmt.Errorf("invalid address: %s", x)
+ _, cidr, err := net.ParseCIDR(x)
+ if err != nil {
+ addr := net.ParseIP(x)
+ if addr == nil {
+ return nil, fmt.Errorf("invalid address or prefix: %s", x)
+ }
+ mask := net.CIDRMask(32, 32)
+ if addr.To4() == nil {
+ mask = net.CIDRMask(128, 128)
+ }
+ cidr = &net.IPNet{
+ IP: addr,
+ Mask: mask,
+ }
}
- list = append(list, addr)
+ list = append(list, *cidr)
}
return &NeighborSet{
name: name,
@@ -1330,7 +1341,6 @@ func (c *NeighborCondition) Option() MatchOption {
// and, subsequent comparisons are skipped if that matches the conditions.
// If NeighborList's length is zero, return true.
func (c *NeighborCondition) Evaluate(path *Path, options *PolicyOptions) bool {
-
if len(c.set.list) == 0 {
log.WithFields(log.Fields{
"Topic": "Policy",
@@ -1348,7 +1358,7 @@ func (c *NeighborCondition) Evaluate(path *Path, options *PolicyOptions) bool {
}
result := false
for _, n := range c.set.list {
- if neighbor.Equal(n) {
+ if n.Contains(neighbor) {
result = true
break
}
diff --git a/tools/pyang_plugins/gobgp.yang b/tools/pyang_plugins/gobgp.yang
index a1c151b0..c6cc3bdd 100644
--- a/tools/pyang_plugins/gobgp.yang
+++ b/tools/pyang_plugins/gobgp.yang
@@ -912,7 +912,7 @@ module gobgp {
leaf-list neighbor-info {
description
- "neighbor ip address";
+ "neighbor ip address or prefix";
type inet:ip-address;
}
}