/
filters.tmpl
68 lines (59 loc) · 3.42 KB
/
filters.tmpl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
{{- define "localpreffilter" -}}
{{$localPrefixListName :=localPrefPrefixList .neighbor .advertisement.LocalPref}}
{{frrIPFamily .advertisement.IPFamily}} prefix-list {{$localPrefixListName}} seq {{counter $localPrefixListName}} permit {{.advertisement.Prefix}}
route-map {{.neighbor.ID}}-out permit {{counter .neighbor.ID}}
match {{frrIPFamily .advertisement.IPFamily}} address prefix-list {{localPrefPrefixList .neighbor .advertisement.LocalPref}}
set local-preference {{.advertisement.LocalPref}}
on-match next
{{- end -}}
{{- define "communityfilter" -}}
{{$communityPrefixlistName :=communityPrefixList .neighbor .community}}
{{frrIPFamily .advertisement.IPFamily}} prefix-list {{$communityPrefixlistName}} seq {{counter $communityPrefixlistName}} permit {{.advertisement.Prefix}}
route-map {{.neighbor.ID}}-out permit {{counter .neighbor.ID}}
match {{frrIPFamily .advertisement.IPFamily}} address prefix-list {{communityPrefixList .neighbor .community}}
set community {{.community}} additive
on-match next
{{- end -}}
{{- define "largecommunityfilter" -}}
{{frrIPFamily .advertisement.IPFamily}} prefix-list {{largeCommunityPrefixList .neighbor .largecommunity}} permit {{.advertisement.Prefix}}
route-map {{.neighbor.ID}}-out permit {{counter .neighbor.ID}}
match {{frrIPFamily .advertisement.IPFamily}} address prefix-list {{largeCommunityPrefixList .neighbor .largecommunity}}
set large-community {{.largecommunity}} additive
on-match next
{{- end -}}
{{- /* The prefixes are per router in FRR, but MetalLB api allows to associate a given BGPAdvertisement to a service IP,
and a given advertisement contains both the properties of the announcement (i.e. community) and the list of peers
we may want to advertise to. Because of this, for each neighbor we must opt-in and allow the advertisement, and
deny all the others.*/ -}}
{{- define "neighborfilters" -}}
route-map {{.neighbor.ID}}-in deny 20
{{- range $a := .neighbor.Advertisements }}
{{/* Advertisements for which we must enable set the local pref */}}
{{- if not (eq $a.LocalPref 0)}}
{{template "localpreffilter" dict "advertisement" $a "neighbor" $.neighbor}}
{{- end -}}
{{/* Advertisements for which we must enable the community property */}}
{{- range $c := $a.Communities }}
{{template "communityfilter" dict "advertisement" $a "neighbor" $.neighbor "community" $c}}
{{- end }}
{{- range $lc := $a.LargeCommunities }}
{{template "largecommunityfilter" dict "advertisement" $a "neighbor" $.neighbor "largecommunity" $lc}}
{{- end }}
{{/* this advertisement is allowed to the specific neighbor */}}
{{$plistName:=allowedPrefixList $.neighbor}}
{{frrIPFamily $a.IPFamily}} prefix-list {{$plistName}} seq {{counter $plistName}} permit {{$a.Prefix}}
{{- end }}
{{/* If the neighbor does not have an advertisement, we need to add a prefix to deny
for when we have a prefix but a given peer is not selected for any prefixes */}}
{{$plistName:=allowedPrefixList $.neighbor}}
{{- if not .neighbor.HasV4Advertisements}}
ip prefix-list {{$plistName}} seq {{counter $plistName}} deny any
{{- end }}
{{- if not .neighbor.HasV6Advertisements}}
ipv6 prefix-list {{$plistName}} seq {{counter $plistName}} deny any
{{- end }}
route-map {{$.neighbor.ID}}-out permit {{counter $.neighbor.ID}}
match ip address prefix-list {{allowedPrefixList $.neighbor}}
route-map {{$.neighbor.ID}}-out permit {{counter $.neighbor.ID}}
match ipv6 address prefix-list {{allowedPrefixList $.neighbor}}
{{- end -}}