예제 #1
0
func addRoa(addr string, tree *radix.Tree, as uint32, prefix []byte, prefixLen, maxLen uint8) {
	key := table.IpToRadixkey(prefix, prefixLen)
	b, _ := tree.Get(key)
	if b == nil {
		p := make([]byte, len(prefix))
		copy(p, prefix)

		b := &RoaBucket{
			PrefixLen: prefixLen,
			Prefix:    p,
			entries:   []*Roa{NewRoa(addr, maxLen, as)},
		}

		tree.Insert(key, b)
	} else {
		bucket := b.(*RoaBucket)
		for _, r := range bucket.entries {
			if r.MaxLen == maxLen && r.Src == addr {
				// we already have?
				for _, a := range r.AS {
					if a == as {
						return
					}
				}
				r.AS = append(r.AS, as)
				return
			}
		}
		bucket.entries = append(bucket.entries, NewRoa(addr, maxLen, as))
	}
}
예제 #2
0
파일: rpki.go 프로젝트: mfeed/gobgp
func (m *roaManager) roa2tree(roa *ROA) (*radix.Tree, string) {
	tree := m.Roas[bgp.RF_IPv4_UC]
	if roa.Family == bgp.AFI_IP6 {
		tree = m.Roas[bgp.RF_IPv6_UC]
	}
	return tree, table.IpToRadixkey(roa.Prefix.Prefix, roa.Prefix.Length)
}
예제 #3
0
파일: rpki.go 프로젝트: thomas-mangin/gobgp
func validateOne(tree *radix.Tree, cidr string, as uint32) config.RpkiValidationResultType {
	_, n, _ := net.ParseCIDR(cidr)
	ones, _ := n.Mask.Size()
	prefixLen := uint8(ones)
	_, b, _ := tree.LongestPrefix(table.IpToRadixkey(n.IP, prefixLen))
	if b == nil {
		return config.RPKI_VALIDATION_RESULT_TYPE_NOT_FOUND
	} else {
		result := config.RPKI_VALIDATION_RESULT_TYPE_INVALID
		bucket, _ := b.(*roaBucket)
		for _, r := range bucket.entries {
			if prefixLen > r.MaxLen {
				continue
			}

			y := func(x uint32, asList []uint32) bool {
				for _, as := range asList {
					if x == as {
						return true
					}
				}
				return false
			}(as, r.AS)

			if y {
				result = config.RPKI_VALIDATION_RESULT_TYPE_VALID
				break
			}
		}
		return result
	}
}
예제 #4
0
파일: rpki.go 프로젝트: rguliyev/gobgp
func validatePath(ownAs uint32, tree *radix.Tree, cidr string, asPath *bgp.PathAttributeAsPath) (config.RpkiValidationResultType, []*roa) {
	var as uint32
	if asPath == nil || len(asPath.Value) == 0 {
		return config.RPKI_VALIDATION_RESULT_TYPE_NOT_FOUND, []*roa{}
	}
	asParam := asPath.Value[len(asPath.Value)-1].(*bgp.As4PathParam)
	switch asParam.Type {
	case bgp.BGP_ASPATH_ATTR_TYPE_SEQ:
		if len(asParam.AS) == 0 {
			return config.RPKI_VALIDATION_RESULT_TYPE_NOT_FOUND, []*roa{}
		}
		as = asParam.AS[len(asParam.AS)-1]
	case bgp.BGP_ASPATH_ATTR_TYPE_CONFED_SET, bgp.BGP_ASPATH_ATTR_TYPE_CONFED_SEQ:
		as = ownAs
	default:
		return config.RPKI_VALIDATION_RESULT_TYPE_NOT_FOUND, []*roa{}
	}
	_, n, _ := net.ParseCIDR(cidr)
	ones, _ := n.Mask.Size()
	prefixLen := uint8(ones)
	_, b, _ := tree.LongestPrefix(table.IpToRadixkey(n.IP, prefixLen))
	if b == nil {
		return config.RPKI_VALIDATION_RESULT_TYPE_NOT_FOUND, []*roa{}
	}

	roaList := make([]*roa, 0)

	result := config.RPKI_VALIDATION_RESULT_TYPE_INVALID
	bucket, _ := b.(*roaBucket)
	for _, r := range bucket.entries {
		if prefixLen > r.MaxLen {
			continue
		}

		y := func(x uint32, asList []uint32) bool {
			for _, as := range asList {
				if x == as {
					return true
				}
			}
			return false
		}(as, r.AS)

		if y {
			return config.RPKI_VALIDATION_RESULT_TYPE_VALID, []*roa{r}
		}
		roaList = append(roaList, r)
	}
	return result, roaList
}
예제 #5
0
파일: rpki.go 프로젝트: rguliyev/gobgp
func deleteROA(client *roaClient, family int, tree *radix.Tree, as uint32, prefix []byte, prefixLen, maxLen uint8) {
	host := client.host
	key := table.IpToRadixkey(prefix, prefixLen)
	b, _ := tree.Get(key)
	isDeleted := func() bool {
		if b != nil {
			bucket := b.(*roaBucket)
			for _, r := range bucket.entries {
				if r.MaxLen == maxLen && r.Src == host {
					for idx, a := range r.AS {
						if a == as {
							r.AS = append(r.AS[:idx], r.AS[idx+1:]...)
							if len(bucket.entries) == 0 {
								tree.Delete(key)
							}
							return true
						}
					}
				}
			}
		}
		return false
	}()
	if isDeleted {
		client.records[family]--
		isNoPrefix := func() bool {
			if b, _ := tree.Get(key); b != nil {
				bucket := b.(*roaBucket)
				for _, r := range bucket.entries {
					if r.Src == host {
						return false
					}
				}
				return true
			} else {
				return true
			}
		}()
		if isNoPrefix {
			client.prefixes[family]--
		}
	} else {
		log.Info("can't withdraw a roa", net.IP(prefix).String(), as, prefixLen, maxLen)
	}
}
예제 #6
0
파일: rpki.go 프로젝트: mfeed/gobgp
func validatePath(ownAs uint32, tree *radix.Tree, cidr string, asPath *bgp.PathAttributeAsPath) config.RpkiValidationResultType {
	var as uint32

	if len(asPath.Value) == 0 {
		as = ownAs
	} else {
		asParam := asPath.Value[len(asPath.Value)-1].(*bgp.As4PathParam)
		switch asParam.Type {
		case bgp.BGP_ASPATH_ATTR_TYPE_SEQ:
			if len(asParam.AS) == 0 {
				as = ownAs
			} else {
				as = asParam.AS[len(asParam.AS)-1]
			}
		case bgp.BGP_ASPATH_ATTR_TYPE_CONFED_SET, bgp.BGP_ASPATH_ATTR_TYPE_CONFED_SEQ:
			as = ownAs
		default:
			return config.RPKI_VALIDATION_RESULT_TYPE_NOT_FOUND
		}
	}
	_, n, _ := net.ParseCIDR(cidr)
	ones, _ := n.Mask.Size()
	prefixLen := uint8(ones)
	_, b, _ := tree.LongestPrefix(table.IpToRadixkey(n.IP, prefixLen))
	if b == nil {
		return config.RPKI_VALIDATION_RESULT_TYPE_NOT_FOUND
	}

	bucket, _ := b.(*roaBucket)
	for _, r := range bucket.entries {
		if prefixLen > r.MaxLen {
			continue
		}
		if r.AS == as {
			return config.RPKI_VALIDATION_RESULT_TYPE_VALID
		}
	}
	return config.RPKI_VALIDATION_RESULT_TYPE_INVALID
}
예제 #7
0
파일: rpki.go 프로젝트: hzhou8/gobgp
func addROA(tree *radix.Tree, as uint32, prefix []byte, prefixLen, maxLen uint8) {
	key := table.IpToRadixkey(prefix, prefixLen)
	b, _ := tree.Get(key)
	if b == nil {
		p := make([]byte, len(prefix))
		copy(p, prefix)

		r := &roa{
			AS:     []uint32{as},
			MaxLen: maxLen,
		}

		b := &roaBucket{
			PrefixLen: prefixLen,
			Prefix:    p,
			entries:   []*roa{r},
		}

		tree.Insert(key, b)
	} else {
		bucket := b.(*roaBucket)
		found := false
		for _, r := range bucket.entries {
			if r.MaxLen == maxLen {
				found = true
				r.AS = append(r.AS, as)
			}
		}
		if found == false {
			r := &roa{
				MaxLen: maxLen,
				AS:     []uint32{as},
			}
			bucket.entries = append(bucket.entries, r)
		}
	}
}
예제 #8
0
파일: rpki.go 프로젝트: rguliyev/gobgp
func addROA(client *roaClient, family int, tree *radix.Tree, as uint32, prefix []byte, prefixLen, maxLen uint8) {
	host := client.host
	key := table.IpToRadixkey(prefix, prefixLen)
	b, _ := tree.Get(key)
	if b == nil {
		p := make([]byte, len(prefix))
		copy(p, prefix)

		r := &roa{
			AS:     []uint32{as},
			MaxLen: maxLen,
			Src:    host,
		}

		b := &roaBucket{
			PrefixLen: prefixLen,
			Prefix:    p,
			entries:   []*roa{r},
		}
		r.bucket = b

		tree.Insert(key, b)
		client.prefixes[family]++
		client.records[family]++
	} else {
		bucket := b.(*roaBucket)
		isNewPrefix := func() bool {
			for _, r := range bucket.entries {
				if r.Src == host {
					return false
				}
			}
			return true
		}()
		if isNewPrefix {
			client.prefixes[family]++
		}

		for _, r := range bucket.entries {
			if r.MaxLen == maxLen && r.Src == host {
				// we already have?
				for _, a := range r.AS {
					if a == as {
						return
					}
				}
				r.AS = append(r.AS, as)
				client.records[family]++
				return
			}
		}
		r := &roa{
			bucket: bucket,
			MaxLen: maxLen,
			AS:     []uint32{as},
			Src:    host,
		}
		bucket.entries = append(bucket.entries, r)
		client.records[family]++
	}
}