]>
Commit | Line | Data |
---|---|---|
32602a38 AD |
1 | package PVE::Network::SDN::FrrPlugin; |
2 | ||
3 | use strict; | |
4 | use warnings; | |
5 | use PVE::Network::SDN::Plugin; | |
6 | use PVE::Tools; | |
7 | ||
8 | use base('PVE::Network::SDN::Plugin'); | |
9 | ||
10 | sub type { | |
11 | return 'frr'; | |
12 | } | |
13 | ||
14 | sub properties { | |
15 | return { | |
16 | 'asn' => { | |
17 | type => 'integer', | |
18 | description => "autonomous system number", | |
19 | }, | |
20 | 'peers' => { | |
21 | description => "peers address list.", | |
7d35eaf5 | 22 | type => 'string', #fixme: format |
32602a38 AD |
23 | }, |
24 | }; | |
25 | } | |
26 | ||
27 | sub options { | |
28 | ||
29 | return { | |
30 | 'uplink-id' => { optional => 0 }, | |
31 | 'asn' => { optional => 0 }, | |
32 | 'peers' => { optional => 0 }, | |
33 | }; | |
34 | } | |
35 | ||
36 | # Plugin implementation | |
87d8b623 AD |
37 | sub generate_frr_config { |
38 | my ($class, $plugin_config, $asn, $id, $uplinks, $config) = @_; | |
32602a38 | 39 | |
32602a38 AD |
40 | my @peers = split(',', $plugin_config->{'peers'}) if $plugin_config->{'peers'}; |
41 | ||
42 | my $uplink = $plugin_config->{'uplink-id'}; | |
43 | ||
32602a38 AD |
44 | my $iface = "uplink$uplink"; |
45 | my $ifaceip = ""; | |
46 | ||
47 | if($uplinks->{$uplink}->{name}) { | |
48 | $iface = $uplinks->{$uplink}->{name}; | |
87d8b623 | 49 | $ifaceip = PVE::Network::SDN::Plugin::get_first_local_ipv4_from_interface($iface); |
32602a38 AD |
50 | } |
51 | ||
17854295 | 52 | |
93dea3aa AD |
53 | my @router_config = (); |
54 | ||
93dea3aa AD |
55 | push @router_config, "bgp router-id $ifaceip"; |
56 | push @router_config, "coalesce-time 1000"; | |
32602a38 AD |
57 | |
58 | foreach my $address (@peers) { | |
59 | next if $address eq $ifaceip; | |
93dea3aa | 60 | push @router_config, "neighbor $address remote-as $asn"; |
7d35eaf5 | 61 | } |
17854295 AD |
62 | push(@{$config->{router}->{"bgp $asn"}->{""}}, @router_config); |
63 | @router_config = (); | |
32602a38 AD |
64 | foreach my $address (@peers) { |
65 | next if $address eq $ifaceip; | |
17854295 | 66 | push @router_config, "neighbor $address activate"; |
32602a38 | 67 | } |
17854295 AD |
68 | push @router_config, "advertise-all-vni"; |
69 | push(@{$config->{router}->{"bgp $asn"}->{"address-family"}->{"l2vpn evpn"}}, @router_config); | |
32602a38 | 70 | |
6c8d2382 AD |
71 | #don't distribute default vrf route to other peers |
72 | @router_config = (); | |
73 | foreach my $address (@peers) { | |
74 | next if $address eq $ifaceip; | |
75 | push @router_config, "neighbor $address prefix-list deny out"; | |
76 | } | |
77 | push(@{$config->{router}->{"bgp $asn"}->{"address-family"}->{"ipv4 unicast"}}, @router_config); | |
78 | ||
32602a38 AD |
79 | return $config; |
80 | } | |
81 | ||
82 | sub on_delete_hook { | |
5bda8607 | 83 | my ($class, $routerid, $sdn_cfg) = @_; |
32602a38 | 84 | |
5bda8607 AD |
85 | # verify that transport is associated to this router |
86 | foreach my $id (keys %{$sdn_cfg->{ids}}) { | |
87 | my $sdn = $sdn_cfg->{ids}->{$id}; | |
88 | die "router $routerid is used by $id" | |
89 | if (defined($sdn->{router}) && $sdn->{router} eq $routerid); | |
90 | } | |
32602a38 AD |
91 | } |
92 | ||
93 | sub on_update_hook { | |
5bda8607 AD |
94 | my ($class, $routerid, $sdn_cfg) = @_; |
95 | ||
96 | # verify that asn is not already used by another router | |
97 | my $asn = $sdn_cfg->{ids}->{$routerid}->{asn}; | |
98 | foreach my $id (keys %{$sdn_cfg->{ids}}) { | |
99 | next if $id eq $routerid; | |
100 | my $sdn = $sdn_cfg->{ids}->{$id}; | |
101 | die "asn $asn is already used by $id" | |
102 | if (defined($sdn->{asn}) && $sdn->{asn} eq $asn); | |
103 | } | |
32602a38 AD |
104 | } |
105 | ||
106 | 1; | |
107 | ||
108 |