1 package PVE
::Network
::SDN
::FrrPlugin
;
5 use PVE
::Network
::SDN
::Plugin
;
8 use PVE
::JSONSchema
qw(get_standard_option);
10 use base
('PVE::Network::SDN::Plugin');
20 description
=> "autonomous system number",
23 description
=> "peers address list.",
24 type
=> 'string', #fixme: format
26 'gateway-nodes' => get_standard_option
('pve-node-list'),
27 'gateway-external-peers' => {
28 description
=> "upstream bgp peers address list.",
29 type
=> 'string', #fixme: format
37 'uplink-id' => { optional
=> 0 },
38 'asn' => { optional
=> 0 },
39 'peers' => { optional
=> 0 },
40 'gateway-nodes' => { optional
=> 1 },
41 'gateway-external-peers' => { optional
=> 1 },
45 # Plugin implementation
46 sub generate_frr_config
{
47 my ($class, $plugin_config, $router, $id, $uplinks, $config) = @_;
49 my @peers = split(',', $plugin_config->{'peers'}) if $plugin_config->{'peers'};
51 my $asn = $plugin_config->{asn
};
52 my $uplink = $plugin_config->{'uplink-id'};
53 my $gatewaynodes = $plugin_config->{'gateway-nodes'};
54 my @gatewaypeers = split(',', $plugin_config->{'gateway-external-peers'}) if $plugin_config->{'gateway-external-peers'};
58 my $iface = "uplink$uplink";
61 if($uplinks->{$uplink}->{name
}) {
62 $iface = $uplinks->{$uplink}->{name
};
63 $ifaceip = PVE
::Network
::SDN
::Plugin
::get_first_local_ipv4_from_interface
($iface);
66 my $is_gateway = undef;
67 my $local_node = PVE
::INotify
::nodename
();
69 foreach my $gatewaynode (PVE
::Tools
::split_list
($gatewaynodes)) {
70 $is_gateway = 1 if $gatewaynode eq $local_node;
73 my @router_config = ();
75 push @router_config, "bgp router-id $ifaceip";
76 push @router_config, "no bgp default ipv4-unicast";
77 push @router_config, "no bgp default ipv6-unicast";
78 push @router_config, "coalesce-time 1000";
80 foreach my $address (@peers) {
81 next if $address eq $ifaceip;
82 push @router_config, "neighbor $address remote-as $asn";
86 foreach my $address (@gatewaypeers) {
87 push @router_config, "neighbor $address remote-as external";
90 push(@{$config->{router
}->{"bgp $asn"}->{""}}, @router_config);
93 foreach my $address (@peers) {
94 next if $address eq $ifaceip;
95 push @router_config, "neighbor $address activate";
97 push @router_config, "advertise-all-vni";
98 push(@{$config->{router
}->{"bgp $asn"}->{"address-family"}->{"l2vpn evpn"}}, @router_config);
103 #import /32 routes of evpn network from vrf1 to default vrf (for packet return)
104 #frr 7.1 tag is bugged -> works fine with 7.1 stable branch(20190829-02-g6ba76bbc1)
105 #https://github.com/FRRouting/frr/issues/4905
106 foreach my $address (@gatewaypeers) {
107 push @router_config, "neighbor $address activate";
109 push(@{$config->{router
}->{"bgp $asn"}->{"address-family"}->{"ipv4 unicast"}}, @router_config);
110 push(@{$config->{router
}->{"bgp $asn"}->{"address-family"}->{"ipv6 unicast"}}, @router_config);
118 my ($class, $routerid, $sdn_cfg) = @_;
120 # verify that transport is associated to this router
121 foreach my $id (keys %{$sdn_cfg->{ids
}}) {
122 my $sdn = $sdn_cfg->{ids
}->{$id};
123 die "router $routerid is used by $id"
124 if (defined($sdn->{router
}) && $sdn->{router
} eq $routerid);
129 my ($class, $routerid, $sdn_cfg) = @_;
131 # verify that asn is not already used by another router
132 my $asn = $sdn_cfg->{ids
}->{$routerid}->{asn
};
133 foreach my $id (keys %{$sdn_cfg->{ids
}}) {
134 next if $id eq $routerid;
135 my $sdn = $sdn_cfg->{ids
}->{$id};
136 die "asn $asn is already used by $id"
137 if (defined($sdn->{asn
}) && $sdn->{asn
} eq $asn);