Skip to content

Commit 8ec258b

Browse files
authored
Merge pull request #150 from natesales/prefix-communities
Add `prefix-communities` and `only-announce` options
2 parents 93c4f18 + 53ebed6 commit 8ec258b

File tree

6 files changed

+67
-3
lines changed

6 files changed

+67
-3
lines changed

cmd/root.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import (
77
"github.com/natesales/pathvector/pkg/plugin"
88
)
99

10-
// Build process flags
10+
// These are set indirectly by the build process. The cmd.Execute() function takes these from the main package and sets them in this (cmd) package.
1111
var (
1212
version = "devel"
1313
commit = "unknown"
@@ -56,7 +56,7 @@ func init() {
5656
}
5757
}
5858

59-
func Execute(v string, c string, d string) error {
59+
func Execute(v, c, d string) error {
6060
version = v
6161
commit = c
6262
date = d

pkg/config/config.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,10 @@ type Peer struct {
9797
DontAnnounce *[]string `yaml:"dont-announce" description:"Don't announce these prefixes to the peer" default:"-"`
9898
OnlyAnnounce *[]string `yaml:"only-announce" description:"Only announce these prefixes to the peer" default:"-"`
9999

100+
PrefixCommunities *map[string][]string `yaml:"prefix-communities" description:"Map of prefix to community list to add to the prefix" default:"-"`
101+
PrefixStandardCommunities *map[string][]string `yaml:"-" description:"-" default:"-"`
102+
PrefixLargeCommunities *map[string][]string `yaml:"-" description:"-" default:"-"`
103+
100104
AutoImportLimits *bool `yaml:"auto-import-limits" description:"Get import limits automatically from PeeringDB?" default:"false"`
101105
AutoASSet *bool `yaml:"auto-as-set" description:"Get as-set automatically from PeeringDB? If no as-set exists in PeeringDB, a warning will be shown and the peer ASN used instead." default:"false"`
102106
AutoASSetMembers *bool `yaml:"auto-as-set-members" description:"Get AS set members automatically from the peer's IRR as-set? (independent from auto-as-set)" default:"false"`

pkg/embed/templates/peer.tmpl

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,22 @@ protocol bgp {{ UniqueProtocolName $peer.ProtocolName $af $peer.ASN }} {
168168
]) then _reject("prefix in dont-announce list");
169169
{{ end }}
170170

171+
{{ range $prefix, $communities := StrSliceMapDeref $peer.PrefixStandardCommunities }}
172+
if (net = {{ $prefix }}) then {
173+
{{ range $i, $community := $communities }}
174+
bgp_community.add(({{ $community }}));
175+
{{ end }}
176+
}
177+
{{ end }}
178+
179+
{{ range $prefix, $communities := StrSliceMapDeref $peer.PrefixLargeCommunities }}
180+
if (net = {{ $prefix }}) then {
181+
{{ range $i, $community := $communities }}
182+
bgp_large_community.add(({{ $community }}));
183+
{{ end }}
184+
}
185+
{{ end }}
186+
171187
{{ StrDeref $peer.PreExport }}
172188

173189
{{ range $i, $community := StringSliceIter $peer.ExportStandardCommunities }}

pkg/process/process.go

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -256,7 +256,37 @@ func Load(configBlob []byte) (*config.Config, error) {
256256
if peerData.OnlyAnnounce != nil && peerData.AnnounceAll != nil {
257257
log.Fatalf("[%s] only-announce and announce-all cannot both be set", peerName)
258258
}
259-
}
259+
260+
// Categorize prefix-communities
261+
if peerData.PrefixCommunities != nil {
262+
// Initialize community maps
263+
if peerData.PrefixStandardCommunities == nil {
264+
peerData.PrefixStandardCommunities = &map[string][]string{}
265+
}
266+
if peerData.PrefixLargeCommunities == nil {
267+
peerData.PrefixLargeCommunities = &map[string][]string{}
268+
}
269+
270+
for prefix, communities := range *peerData.PrefixCommunities {
271+
for _, community := range communities {
272+
communityType := categorizeCommunity(community)
273+
if communityType == "standard" {
274+
if _, ok := (*peerData.PrefixStandardCommunities)[prefix]; !ok {
275+
(*peerData.PrefixStandardCommunities)[prefix] = []string{}
276+
}
277+
(*peerData.PrefixStandardCommunities)[prefix] = append((*peerData.PrefixStandardCommunities)[prefix], community)
278+
} else if communityType == "large" {
279+
if _, ok := (*peerData.PrefixLargeCommunities)[prefix]; !ok {
280+
(*peerData.PrefixLargeCommunities)[prefix] = []string{}
281+
}
282+
(*peerData.PrefixLargeCommunities)[prefix] = append((*peerData.PrefixLargeCommunities)[prefix], strings.ReplaceAll(community, ":", ","))
283+
} else {
284+
return nil, errors.New("Invalid prefix community: " + community)
285+
}
286+
}
287+
}
288+
}
289+
} // end peer list
260290

261291
// Parse origin routes by assembling OriginIPv{4,6} lists by address family
262292
for _, prefix := range c.Prefixes {

pkg/templating/templating.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,13 @@ var funcMap = template.FuncMap{
144144
return map[uint32]uint32{}
145145
},
146146

147+
"StrSliceMapDeref": func(m *map[string][]string) map[string][]string {
148+
if m != nil {
149+
return *m
150+
}
151+
return map[string][]string{}
152+
},
153+
147154
"Uint32SliceMapDeref": func(m *map[uint32][]uint32) map[uint32][]uint32 {
148155
if m != nil {
149156
return *m

tests/generate-complex.yml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,13 @@ peers:
8686
- 65540
8787
filter-as-set: true
8888
pre-import-accept: 'print "Hello from <pathvector.asn>";'
89+
prefix-communities:
90+
"192.0.2.0/24":
91+
- "123,456"
92+
- "123,000"
93+
- "1:2:3"
94+
dont-announce:
95+
- 192.0.2.100/32
8996
transit-lock:
9097
- 65510
9198
- 65530

0 commit comments

Comments
 (0)