Compare commits
2 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
47dd2ee79f | ||
|
|
f13e087a9f |
25
.github/workflows/semgrep.yml
vendored
25
.github/workflows/semgrep.yml
vendored
@@ -1,25 +0,0 @@
|
||||
|
||||
on:
|
||||
pull_request: {}
|
||||
workflow_dispatch: {}
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
- master
|
||||
schedule:
|
||||
- cron: '0 0 * * *'
|
||||
name: Semgrep config
|
||||
jobs:
|
||||
semgrep:
|
||||
name: semgrep/ci
|
||||
runs-on: ubuntu-20.04
|
||||
env:
|
||||
SEMGREP_APP_TOKEN: ${{ secrets.SEMGREP_APP_TOKEN }}
|
||||
SEMGREP_URL: https://cloudflare.semgrep.dev
|
||||
SEMGREP_APP_URL: https://cloudflare.semgrep.dev
|
||||
SEMGREP_VERSION_CHECK_URL: https://cloudflare.semgrep.dev/api/check-version
|
||||
container:
|
||||
image: returntocorp/semgrep
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- run: semgrep ci
|
||||
@@ -67,47 +67,47 @@ var (
|
||||
73: "FQDN Capability",
|
||||
}
|
||||
BgpAttributes = map[int]string{
|
||||
0: "Reserved",
|
||||
ATTRIBUTE_ORIGIN: "ORIGIN",
|
||||
ATTRIBUTE_ASPATH: "AS_PATH",
|
||||
ATTRIBUTE_NEXTHOP: "NEXT_HOP",
|
||||
ATTRIBUTE_MED: "MULTI_EXIT_DISC",
|
||||
ATTRIBUTE_LOCPREF: "LOCAL_PREF",
|
||||
6: "ATOMIC_AGGREGATE",
|
||||
7: "AGGREGATOR",
|
||||
0: "Reserved",
|
||||
ATTRIBUTE_ORIGIN: "ORIGIN",
|
||||
ATTRIBUTE_ASPATH: "AS_PATH",
|
||||
ATTRIBUTE_NEXTHOP: "NEXT_HOP",
|
||||
ATTRIBUTE_MED: "MULTI_EXIT_DISC",
|
||||
ATTRIBUTE_LOCPREF: "LOCAL_PREF",
|
||||
6: "ATOMIC_AGGREGATE",
|
||||
7: "AGGREGATOR",
|
||||
ATTRIBUTE_COMMUNITIES: "COMMUNITY",
|
||||
9: "ORIGINATOR_ID",
|
||||
10: "CLUSTER_LIST",
|
||||
11: "DPA (deprecated)",
|
||||
12: "ADVERTISER (historic) (deprecated)",
|
||||
13: "RCID_PATH / CLUSTER_ID (Historic) (deprecated)",
|
||||
ATTRIBUTE_REACH: "MP_REACH_NLRI",
|
||||
ATTRIBUTE_UNREACH: "MP_UNREACH_NLRI",
|
||||
16: "EXTENDED COMMUNITIES",
|
||||
ATTRIBUTE_AS4PATH: "AS4_PATH",
|
||||
18: "AS4_AGGREGATOR",
|
||||
19: "SAFI Specific Attribute (SSA) (deprecated)",
|
||||
20: "Connector Attribute (deprecated)",
|
||||
21: "AS_PATHLIMIT (deprecated)",
|
||||
22: "PMSI_TUNNEL",
|
||||
23: "Tunnel Encapsulation Attribute",
|
||||
24: "Traffic Engineering",
|
||||
25: "IPv6 Address Specific Extended Community",
|
||||
26: "AIGP",
|
||||
27: "PE Distinguisher Labels",
|
||||
28: "BGP Entropy Label Capability Attribute (deprecated)",
|
||||
29: "BGP-LS Attribute",
|
||||
30: "Deprecated",
|
||||
31: "Deprecated",
|
||||
32: "LARGE_COMMUNITY",
|
||||
33: "BGPsec_Path",
|
||||
34: "BGP Community Container Attribute",
|
||||
40: "BGP Prefix-SID",
|
||||
128: "ATTR_SET",
|
||||
129: "Deprecated",
|
||||
241: "Deprecated",
|
||||
242: "Deprecated",
|
||||
243: "Deprecated",
|
||||
9: "ORIGINATOR_ID",
|
||||
10: "CLUSTER_LIST",
|
||||
11: "DPA (deprecated)",
|
||||
12: "ADVERTISER (historic) (deprecated)",
|
||||
13: "RCID_PATH / CLUSTER_ID (Historic) (deprecated)",
|
||||
ATTRIBUTE_REACH: "MP_REACH_NLRI",
|
||||
ATTRIBUTE_UNREACH: "MP_UNREACH_NLRI",
|
||||
16: "EXTENDED COMMUNITIES",
|
||||
ATTRIBUTE_AS4PATH: "AS4_PATH",
|
||||
18: "AS4_AGGREGATOR",
|
||||
19: "SAFI Specific Attribute (SSA) (deprecated)",
|
||||
20: "Connector Attribute (deprecated)",
|
||||
21: "AS_PATHLIMIT (deprecated)",
|
||||
22: "PMSI_TUNNEL",
|
||||
23: "Tunnel Encapsulation Attribute",
|
||||
24: "Traffic Engineering",
|
||||
25: "IPv6 Address Specific Extended Community",
|
||||
26: "AIGP",
|
||||
27: "PE Distinguisher Labels",
|
||||
28: "BGP Entropy Label Capability Attribute (deprecated)",
|
||||
29: "BGP-LS Attribute",
|
||||
30: "Deprecated",
|
||||
31: "Deprecated",
|
||||
32: "LARGE_COMMUNITY",
|
||||
33: "BGPsec_Path",
|
||||
34: "BGP Community Container Attribute",
|
||||
40: "BGP Prefix-SID",
|
||||
128: "ATTR_SET",
|
||||
129: "Deprecated",
|
||||
241: "Deprecated",
|
||||
242: "Deprecated",
|
||||
243: "Deprecated",
|
||||
}
|
||||
Afi = map[string]uint16{
|
||||
"ipv4": AFI_IPV4,
|
||||
|
||||
350
rib/rib_lc.go
350
rib/rib_lc.go
@@ -1,350 +0,0 @@
|
||||
package rib
|
||||
|
||||
import (
|
||||
"github.com/cloudflare/fgbgp/messages"
|
||||
"github.com/cloudflare/fgbgp/mrt"
|
||||
"github.com/lspgn/lctrie"
|
||||
"net"
|
||||
"sync"
|
||||
"time"
|
||||
//"fmt"
|
||||
)
|
||||
|
||||
type LcRib struct {
|
||||
PrefixTable *lctrie.Trie
|
||||
Prefix6Table *lctrie.Trie
|
||||
SyncPrefixTable *sync.RWMutex
|
||||
SyncPrefix6Table *sync.RWMutex
|
||||
Countv4 int
|
||||
Countv6 int
|
||||
}
|
||||
|
||||
func NewLcRib() *LcRib {
|
||||
return &LcRib{
|
||||
PrefixTable: lctrie.New(),
|
||||
Prefix6Table: lctrie.New(),
|
||||
SyncPrefixTable: &sync.RWMutex{},
|
||||
SyncPrefix6Table: &sync.RWMutex{},
|
||||
}
|
||||
}
|
||||
|
||||
type dumpWalkArgs struct {
|
||||
f WalkMrt
|
||||
peerid uint16
|
||||
iter uint32
|
||||
isv6 bool
|
||||
afi uint16
|
||||
safi byte
|
||||
curtime time.Time
|
||||
}
|
||||
|
||||
type Walk func(net.IPNet, *messages.BGPMessageUpdate) bool
|
||||
type WalkMrt func(*mrt.MrtTableDumpV2_Rib) bool
|
||||
|
||||
func (args *dumpWalkArgs) dumpWalk(prefix net.IPNet, msg *messages.BGPMessageUpdate) bool {
|
||||
dump := mrt.NewMrtTableDumpV2_RibAfiSafi(args.iter, args.afi, args.safi, messages.NLRI_IPPrefix{Prefix: prefix}, args.curtime)
|
||||
dump.AddEntry(args.peerid, args.curtime, msg.PathAttributes)
|
||||
|
||||
var stop bool
|
||||
if args.f != nil {
|
||||
stop = args.f(dump)
|
||||
}
|
||||
|
||||
args.iter++
|
||||
|
||||
return stop
|
||||
}
|
||||
|
||||
func (rib *LcRib) DumpMrt(peerid uint16, f WalkMrt, ts time.Time) {
|
||||
args := dumpWalkArgs{
|
||||
f: f,
|
||||
peerid: peerid,
|
||||
afi: messages.AFI_IPV4,
|
||||
safi: messages.SAFI_UNICAST,
|
||||
curtime: ts,
|
||||
}
|
||||
rib.Walk(args.dumpWalk, args.isv6)
|
||||
|
||||
args.afi = messages.AFI_IPV6
|
||||
args.isv6 = true
|
||||
|
||||
rib.Walk(args.dumpWalk, args.isv6)
|
||||
}
|
||||
|
||||
func (rib *LcRib) chooseTableByType(ip net.IP) (*lctrie.Trie, *sync.RWMutex) {
|
||||
if ip.To4() != nil {
|
||||
return rib.PrefixTable, rib.SyncPrefixTable
|
||||
} else if ip.To16() != nil {
|
||||
return rib.Prefix6Table, rib.SyncPrefix6Table
|
||||
} else {
|
||||
return nil, nil
|
||||
}
|
||||
}
|
||||
|
||||
type walkArgs struct {
|
||||
f Walk
|
||||
isv6 bool
|
||||
}
|
||||
|
||||
func (rib *LcRib) GetCounts(afisafi messages.AfiSafi) int {
|
||||
if afisafi.Afi == messages.AFI_IPV4 {
|
||||
return rib.Countv4
|
||||
} else if afisafi.Afi == messages.AFI_IPV6 {
|
||||
return rib.Countv6
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (args *walkArgs) walkFunc(b []byte, p byte, item interface{}) bool {
|
||||
prefix := ConvertBytesToPrefix(b, p, args.isv6)
|
||||
|
||||
conv, ok := item.(*messages.BGPMessageUpdate)
|
||||
var stop bool
|
||||
if ok && args.f != nil {
|
||||
stop = args.f(prefix, conv)
|
||||
}
|
||||
return stop
|
||||
}
|
||||
|
||||
func (rib *LcRib) Walk(f Walk, isv6 bool) {
|
||||
args := walkArgs{
|
||||
f: f,
|
||||
isv6: isv6,
|
||||
}
|
||||
|
||||
if !isv6 {
|
||||
rib.SyncPrefixTable.RLock()
|
||||
rib.PrefixTable.ExploreFromRoot(args.walkFunc)
|
||||
rib.SyncPrefixTable.RUnlock()
|
||||
} else {
|
||||
rib.SyncPrefix6Table.RLock()
|
||||
rib.Prefix6Table.ExploreFromRoot(args.walkFunc)
|
||||
rib.SyncPrefix6Table.RUnlock()
|
||||
}
|
||||
}
|
||||
|
||||
func (rib *LcRib) chooseTableByTypePrefix(prefix net.IPNet) (*lctrie.Trie, *sync.RWMutex) {
|
||||
return rib.chooseTableByType(prefix.IP)
|
||||
}
|
||||
|
||||
func (rib *LcRib) LookupPrefix(prefix net.IPNet, exact bool) (net.IPNet, *messages.BGPMessageUpdate) {
|
||||
table, sync := rib.chooseTableByTypePrefix(prefix)
|
||||
|
||||
var pconv net.IPNet
|
||||
if table == nil || sync == nil {
|
||||
return pconv, nil
|
||||
}
|
||||
|
||||
b, p := ConvertPrefixToBytes(prefix)
|
||||
|
||||
var bb []byte
|
||||
var pp byte
|
||||
var i interface{}
|
||||
sync.RLock()
|
||||
|
||||
var isv6 bool
|
||||
if prefix.IP.To4() == nil && prefix.IP.To16() != nil {
|
||||
isv6 = true
|
||||
}
|
||||
|
||||
if !exact {
|
||||
bb, pp, i = table.Get(b, p)
|
||||
pconv = ConvertBytesToPrefix(bb, pp, isv6)
|
||||
} else {
|
||||
i = table.GetExact(b, p)
|
||||
pconv = prefix
|
||||
}
|
||||
sync.RUnlock()
|
||||
|
||||
update, ok := i.(*messages.BGPMessageUpdate)
|
||||
if ok {
|
||||
return pconv, update
|
||||
}
|
||||
|
||||
return pconv, nil
|
||||
}
|
||||
func (rib *LcRib) Lookup(ip net.IP) (net.IPNet, *messages.BGPMessageUpdate) {
|
||||
var mask net.IPMask
|
||||
if ip.To4() != nil {
|
||||
mask = net.CIDRMask(32, 32)
|
||||
} else if ip.To16() != nil {
|
||||
mask = net.CIDRMask(128, 128)
|
||||
}
|
||||
prefix := net.IPNet{
|
||||
IP: ip,
|
||||
Mask: mask,
|
||||
}
|
||||
|
||||
return rib.LookupPrefix(prefix, false)
|
||||
}
|
||||
|
||||
func ConvertBytesToPrefix(b []byte, p byte, ipv6 bool) net.IPNet {
|
||||
var newip []byte
|
||||
var mask net.IPMask
|
||||
|
||||
var size int
|
||||
|
||||
if ipv6 {
|
||||
size = 16
|
||||
} else {
|
||||
size = 4
|
||||
}
|
||||
|
||||
if p == 0 {
|
||||
mask = net.CIDRMask(8*len(b), size*8)
|
||||
} else {
|
||||
modb := b[len(b)-1]
|
||||
|
||||
b[len(b)-1] = (modb >> (8 - p)) << (8 - p)
|
||||
mask = net.CIDRMask(8*(len(b)-1)+int(p), size*8)
|
||||
}
|
||||
|
||||
if size-len(b) > 0 {
|
||||
newip = append(b, make([]byte, size-len(b))...)
|
||||
} else {
|
||||
newip = append(b)
|
||||
}
|
||||
|
||||
return net.IPNet{IP: newip, Mask: mask}
|
||||
}
|
||||
|
||||
func ConvertPrefixToBytes(prefix net.IPNet) ([]byte, byte) {
|
||||
var ipbytes []byte
|
||||
var bytescopy net.IP
|
||||
bytescopy = make([]byte, len(prefix.IP))
|
||||
copy(bytescopy, prefix.IP)
|
||||
if bytescopy.To4() != nil {
|
||||
ipbytes = bytescopy.To4()
|
||||
} else if prefix.IP.To16() != nil {
|
||||
ipbytes = bytescopy.To16()
|
||||
}
|
||||
if ipbytes != nil {
|
||||
s, _ := prefix.Mask.Size()
|
||||
if s == 0 {
|
||||
return []byte{}, 0
|
||||
}
|
||||
cut := s / 8
|
||||
if s%8 != 0 {
|
||||
cut += 1
|
||||
}
|
||||
ipbytes := ipbytes[0:cut]
|
||||
s %= 8
|
||||
return ipbytes, byte(s)
|
||||
}
|
||||
return nil, 0
|
||||
}
|
||||
|
||||
func ConvertNLRIToBytes(nlri messages.NLRI) ([]byte, byte) {
|
||||
ipprefix, ok := nlri.(messages.NLRI_IPPrefix)
|
||||
if ok {
|
||||
return ConvertPrefixToBytes(ipprefix.Prefix)
|
||||
} else {
|
||||
return nil, 0
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func RemoveFromNLRI(nlri messages.NLRI, message *messages.BGPMessageUpdate) {
|
||||
newnlri := make([]messages.NLRI, 0)
|
||||
for i := range message.NLRI {
|
||||
if !nlri.Equals(message.NLRI[i]) {
|
||||
newnlri = append(newnlri, message.NLRI[i])
|
||||
}
|
||||
}
|
||||
if len(newnlri) != len(message.NLRI) {
|
||||
message.NLRI = newnlri
|
||||
}
|
||||
|
||||
newnlri = make([]messages.NLRI, 0)
|
||||
for i := range message.PathAttributes {
|
||||
switch pa := message.PathAttributes[i].(type) {
|
||||
case messages.BGPAttribute_MP_REACH:
|
||||
for j := range pa.NLRI {
|
||||
if !nlri.Equals(pa.NLRI[j]) {
|
||||
newnlri = append(newnlri, pa.NLRI[j])
|
||||
}
|
||||
}
|
||||
if len(newnlri) != len(pa.NLRI) {
|
||||
pa.NLRI = newnlri
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (rib *LcRib) addPrefix(nlri messages.NLRI, trie *lctrie.Trie, message *messages.BGPMessageUpdate, count *int) {
|
||||
b, l := ConvertNLRIToBytes(nlri)
|
||||
//fmt.Printf("Converted %v %v\n", b, l)
|
||||
if b != nil {
|
||||
|
||||
val := trie.GetExact(b, byte(l%8))
|
||||
if val != nil {
|
||||
valupdate, ok := val.(*messages.BGPMessageUpdate)
|
||||
if ok && valupdate != message {
|
||||
RemoveFromNLRI(nlri, valupdate)
|
||||
}
|
||||
} else {
|
||||
(*count)++
|
||||
}
|
||||
trie.Insert(b, byte(l%8), message)
|
||||
}
|
||||
}
|
||||
|
||||
func (rib *LcRib) delPrefix(nlri messages.NLRI, trie *lctrie.Trie, count *int) int {
|
||||
b, l := ConvertNLRIToBytes(nlri)
|
||||
//fmt.Printf("Converted %v %v\n", b, l)
|
||||
if b != nil {
|
||||
|
||||
val := trie.GetExact(b, byte(l%8))
|
||||
if val != nil {
|
||||
valupdate, ok := val.(*messages.BGPMessageUpdate)
|
||||
if ok {
|
||||
RemoveFromNLRI(nlri, valupdate)
|
||||
}
|
||||
(*count)--
|
||||
}
|
||||
return trie.Remove(b, byte(l%8))
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (rib *LcRib) UpdateRib(message *messages.BGPMessageUpdate) {
|
||||
if message == nil {
|
||||
return
|
||||
}
|
||||
rib.SyncPrefixTable.Lock()
|
||||
for i := range message.NLRI {
|
||||
//fmt.Printf("Adding %v (%v/%v)\n", message.NLRI[i], i+1, len(message.NLRI))
|
||||
rib.addPrefix(message.NLRI[i], rib.PrefixTable, message, &rib.Countv4)
|
||||
}
|
||||
rib.SyncPrefixTable.Unlock()
|
||||
|
||||
rib.SyncPrefixTable.Lock()
|
||||
for i := range message.WithdrawnRoutes {
|
||||
//fmt.Printf("Remove %v\n", message.WidthdrawnRoutes[i])
|
||||
rib.delPrefix(message.WithdrawnRoutes[i], rib.PrefixTable, &rib.Countv4)
|
||||
}
|
||||
message.WithdrawnRoutes = make([]messages.NLRI, 0)
|
||||
rib.SyncPrefixTable.Unlock()
|
||||
|
||||
for i := range message.PathAttributes {
|
||||
switch pa := message.PathAttributes[i].(type) {
|
||||
case messages.BGPAttribute_MP_REACH:
|
||||
rib.SyncPrefix6Table.Lock()
|
||||
for j := range pa.NLRI {
|
||||
//fmt.Printf("Adding %v\n", pa.NLRI[j])
|
||||
rib.addPrefix(pa.NLRI[j], rib.Prefix6Table, message, &rib.Countv6)
|
||||
}
|
||||
rib.SyncPrefix6Table.Unlock()
|
||||
|
||||
case messages.BGPAttribute_MP_UNREACH:
|
||||
rib.SyncPrefix6Table.Lock()
|
||||
for j := range pa.NLRI {
|
||||
//fmt.Printf("Remove %v\n", pa.NLRI[j])
|
||||
rib.delPrefix(pa.NLRI[j], rib.Prefix6Table, &rib.Countv6)
|
||||
}
|
||||
pa.NLRI = make([]messages.NLRI, 0)
|
||||
rib.SyncPrefix6Table.Unlock()
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user