bird-openwrt: BIRD daemon integration with UCI and LuCI configuration

This commit is contained in:
Eloi Carbo 2014-09-10 12:32:10 +02:00
parent 959f053b48
commit 1dc4a6ae00
16 changed files with 2337 additions and 0 deletions

View File

@ -0,0 +1,90 @@
# Copyright (C) 2014 - Eloi Carbó Solé (GSoC2014)
# BGP/Bird integration with OpenWRT and QMP
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
include $(TOPDIR)/rules.mk
include $(INCLUDE_DIR)/kernel.mk
BIRD:=bird4
PKG_NAME:=$(BIRD)-openwrt
PKG_RELEASE:=0.2
PKG_BUILD_DIR := $(BUILD_DIR)/$(PKG_NAME)
uci:=$(BIRD)-uci
luci:=luci-app-$(BIRD)
include $(INCLUDE_DIR)/package.mk
define Build/Prepare
endef
define Build/Compile
endef
define Package/$(uci)
TITLE:=The BIRD UCI module
SECTION:=net
CATEGORY:=Network
SUBMENU:=Routing and Redirection
MAINTAINER:=Eloi Carbo <eloicaso@openmailbox.org>
URL:=https://github.com/eloicaso/bird4-openwrt/
DEPENDS:=+$(BIRD) +libuci +uci
endef
define Package/$(uci)/description
$(BIRD) UCI integration module
endef
define Package/$(uci)/install
$(INSTALL_DIR) $(1)/etc/$(BIRD)/init.d
$(INSTALL_DIR) $(1)/etc/config
$(INSTALL_BIN) ./src/init.d/$(BIRD) $(1)/etc/$(BIRD)/init.d/
$(CP) ./src/uci-defaults/$(uci)-install-init.d $(1)/etc/$(BIRD)/init.d/
$(CP) ./src/config/$(BIRD) $(1)/etc/config/
endef
define Package/$(uci)/postinst
#!/bin/sh
if [ -z $${IPKG_INSTROOT} ]; then
( . /etc/bird4/init.d/bird4-uci-install-init.d ) && rm -f /etc/bird4/init.d/bird4-uci-install-init.d
fi
endef
$(eval $(call BuildPackage,$(uci)))
define Package/$(luci)
TITLE:=LuCI support for $(BIRD)
SECTION:=luci
CATEGORY:=LuCI
SUBMENU:=3. Applications
MAINTAINER:=Eloi Carbo <eloicaso@openmailbox.org>
URL:=https://github.com/eloicaso/bird4-openwrt/
DEPENDS:=+$(BIRD)-uci +luci-base
endef
define Package/$(luci)/description
$(BIRD) application for LuCI
endef
define Package/$(luci)/install
$(INSTALL_DIR) $(1)/usr/lib/lua/luci/controller/
$(INSTALL_DIR) $(1)/usr/lib/lua/luci/model/cbi/$(BIRD)/
$(CP) ./src/model/* $(1)/usr/lib/lua/luci/model/cbi/$(BIRD)/
$(CP) ./src/controller/* $(1)/usr/lib/lua/luci/controller/
endef
$(eval $(call BuildPackage,$(luci)))

View File

@ -0,0 +1,129 @@
config bird 'bird'
option use_UCI_config '1'
#Caution! Enabling this option, Bird will translate this
#UCI file and use it instead of /etc/bird4.conf
option UCI_config_file '/tmp/bird4.conf'
#If you enable useUCIconfig, UCIconfigFile will be Bird's
#configuration file location.
config global 'global'
option log_file '/tmp/bird4.log'
option log 'all'
option debug 'off'
option router_id '172.16.1.6'
config table
option name 'aux'
config kernel kernel1
option table 'aux'
option import 'all'
option export 'all'
option kernel_table '100'
option scan_time '10'
option learn '1'
option persist '0'
option disabled '0'
config device device1
option scan_time '10'
option disabled '0'
config static static1
option table 'aux'
option disabled '0'
config bgp bgp1
option template 'bgp_common'
option description 'Description of the BGP instance'
option neighbor_address '172.16.1.5'
option neighbor_as '65530'
option source_address '172.16.1.6'
option next_hop_self '0'
option next_hop_keep '0'
option rr_client '1'
option rr_cluster_id '172.16.1.6'
config bgp_template bgp_common
option table 'aux'
option import 'all'
option export 'all'
option local_address '172.16.1.6'
option local_as '65001'
option import_limit '100'
option import_limit_action 'warn'
option export_limit '100'
option export_limit_action 'warn'
option receive_limit '100'
option receive_limit_action 'warn'
option disabled '0'
config ospf ospf1
option cfg1583compat '1'
config ospf_area '0.0.0.0'
option instance 'ospf1'
option stub '0'
config ospf_interface '*'
option area '0.0.0.0'
option cost '100'
option type 'broadcast'
option hello '5'
option password '1'
config ospf_password '1'
option authentication 'cryptographic'
option passphrase '1234'
config ospf_networks
option area '0.0.0.0'
list prefix '10.0.0.0/24'
config ospf_hidden_networks
option area '0.0.0.0'
option prefix '12.0.0.0/24'
config ospf_stubnet '11.0.0.0/24'
option area '0.0.0.0'
option hidden '0'
option summary '0'
option cost '101'
config route
option instance 'static1'
option type 'router'
option prefix '192.168.9.0/24'
option via '10.99.105.159'
config route
option instance 'static1'
option type 'special'
option prefix '192.168.2.0/24'
option attribute 'unreachable'
config route
option instance 'static1'
option type 'iface'
option prefix '192.168.3.0/24'
option iface 'mgmt0'
config route
option instance 'static1'
option type 'recursive'
option prefix '192.168.4.0/24'
option ip '192.168.1.1'
config route
option instance 'static1'
option type 'multipath'
option prefix '192.168.30.0/24'
list l_via '172.16.1.5'
list l_via '172.16.1.6'
config filter 'firstFilter'
option type 'bgp'
option instance 'bgp1'
option file_path '/var/filters/f1'

View File

@ -0,0 +1,27 @@
--[[
Copyright (C) 2014 - Eloi Carbó Solé (GSoC2014)
BGP/Bird integration with OpenWRT and QMP
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
--]]
module("luci.controller.bird4", package.seeall)
function index()
entry({"admin","network","bird4"}, cbi("bird4/overview"), "Bird4", 0).dependent=false
entry({"admin","network","bird4","overview"}, cbi("bird4/overview"), "Overview", 1).dependent=false
entry({"admin","network","bird4","proto_general"}, cbi("bird4/gen_proto"), "General protocols", 3).dependent=false
entry({"admin","network","bird4","proto_bgp"}, cbi("bird4/bgp_proto"), "BGP Protocol", 4).dependent=false
end

View File

@ -0,0 +1,411 @@
#!/bin/sh /etc/rc.common
# Copyright (C) 2014 - Eloi Carbó Solé (GSoC2014)
# BGP/Bird integration with OpenWRT and QMP
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
BIRD="bird4"
BIRD_CONFIG="/etc/$BIRD.conf"
START=99
STOP=10
SERVICE_DAEMONIZE=1
SERVICE_USE_PID=1
SERVICE_PID_FILE="/var/run/$BIRD.pid"
BIRD_BIN="/usr/sbin/$BIRD"
# Function: writeToConfig $1
# $1 string.
# Allows to write in the $BIRD_CONFIG file, the string $1. This function does not check the $1 string.
# Example: writeToConfig "value: $N"
writeToConfig() {
echo "$1" >> $BIRD_CONFIG
}
# Function: write $1 $2
# $1 string. $2 string.
# This function checks if $2 is empty. If not, it writes the string $1 in the $BIRD_CONFIG file.
# Use write function to check if $1, value found inside $2, is not empty and can be written in the configuration file.
# Example: N=""; write "value: $N" $N;
write() {
[ -n "$2" ] && writeToConfig "$1"
}
#Function: write_bool $1 $2
# $1 string; $2 boolean
# This function checks if $2 is true or false and write the $1 string into $BIRD_CONFIG file.
# The function writes a # before the $2 string if its false.
# Example: local N=0; write_bool $N
write_bool() {
[ "$2" == 0 ] && writeToConfig "# $1;" || writeToConfig " $1;"
}
# Function: get $1 $2
# $1 string. $2 string
# This function uses the external UCI function "config_get $result $section $option" to obtain a string value from UCI config file.
# To use this function, use the same name of the UCI option for the variable.
# Example: UCI (option id 'abcd'); local id; get id $section
get() {
config_get $1 $2 $1
}
# Function: get_bool $1 $2
# $1 boolean. $2 string
# This function uses the external UCI function "config_get_bool $result $section $option" to obtain a boolean value from UCI config file.
# To use this function, use the same name of the UCI option for the variable $1.
# Example: UCI (option use_ipv6 '1'); local use_ipv6; get use_ipv6 $section
get_bool() {
config_get_bool $1 $2 $1
}
# Function: multipath_list $1
# $1 string
# This function writes the $1 string in the multipath routes.
multipath_list() {
write " via $1" $1
}
# Function: prepare_tables $1
# $1 string
# This function gets each "table" section in the UCI configuration and sets each option in the bird4.conf file.
# $1 is set as the ID of the current UCI table section
prepare_tables() {
local section="$1"; local name
get name $section
write "table $name;" $name
}
# Function: prepare_global $1
# $1 string
# This function gets each "global" section in the UCI configuration and sets each option in the bird4.conf file.
# $1 is set as the ID of the current UCI global section. prepare_global is the first configuration set in the bird4.conf and removes the old file.
prepare_global () {
local section="$1"
local log_file; local log; local debug; local router_id; local table
# Remove old configuration file
rm -f "$BIRD_CONFIG"
get log_file $section
get log $section
get debug $section
get router_id $section
get table $section
# First line of the NEW configuration file
echo "#Bird4 configuration using UCI:" > $BIRD_CONFIG
writeToConfig " "
[ -n "$log_file" -a -n "$log" ] && writeToConfig 'log "'$log_file'" '$log';'
write "debug protocols $debug;" $debug
writeToConfig " "
writeToConfig "#Router ID"
write "router id $router_id;" $router_id
writeToConfig " "
writeToConfig "#Secondary tables"
config_foreach prepare_tables 'table'
writeToConfig " "
}
# Function: prepare_routes $1
# $1 string
# This function gets each "route" section in the UCI configuration and sets each option in the bird4.conf file.
# $1 is set as the ID of the current UCI route section. Each type of route has its own treatment.
prepare_routes() {
local instance; local prefix; local via; local type
local section="$1"
local protoInstance="$2"
get instance $section
if [ "$instance" = "$protoInstance" ]; then
get type $section
case "$type" in
"router")
get prefix $section
get via $section
[ -n "$prefix" -a -n "$via" ] && writeToConfig " route $prefix via $via;"
;;
"special")
get prefix $section
get attribute $section
[ -n "$prefix" -a -n "$attribute" ] && writeToConfig " route $prefix $attribute;"
;;
"iface")
get prefix $section
get iface $section
[ -n "$prefix" -a -n "$iface" ] && writeToConfig ' route '$prefix' via "'$iface'";'
;;
"multipath")
get prefix $section
write " route $prefix multipath" $prefix
config_list_foreach $section l_via multipath_list
writeToConfig " ;"
;;
esac
fi
}
# Function: prepare_kernel $1
# $1 string
# This function gets each "kernel" protocol section in the UCI configuration and sets each option in the bird6.conf file.
# $1 is set as the ID of the current UCI kernel section.
prepare_kernel() {
local section="$1"
write "#$section configuration:" $section
local disabled; local table; local kernel_table; local import; local export; local scan_time; local persist; local learn
get_bool disabled $section
get table $section
get import $section
get export $section
get scan_time $section
get kernel_table $section
get learn $section
get persist $section
writeToConfig "protocol kernel {"
write_bool disabled $disabled
write " table $table;" $table
write " kernel table $kernel_table;" $kernel_table
write_bool learn $learn
write_bool persist $persist
write " scan time $scan_time;" $scan_time
write " import $import;" $import
write " export $export;" $export
writeToConfig "}"
writeToConfig " "
}
# Function: prepare_static $1
# $1 string
# This function gets each "static" protocol section in the UCI configuration and sets each option in the bird6.conf file.
# $1 is set as the ID of the current UCI static section.
prepare_static() {
local section="$1"
local disabled
get disabled $section
if [ "$disabled" -eq 0 ]; then
local table
get table $section
writeToConfig "#$section configration:" $section
writeToConfig "protocol static {"
write " table $table;" $table
config_foreach prepare_routes 'route' $section
writeToConfig "}"
writeToConfig " "
fi
}
# Function: prepare_device $1
# $1 string
# This function gets each "device" protocol section in the UCI configuration and sets each option in the bird4.conf file.
# $1 is set as the ID of the current UCI device section.
prepare_device() {
local section="$1"
local disabled; local scan_time
get disabled $section
get scan_time $section
write "#$section configuration:" $section
writeToConfig "protocol device {"
write_bool disabled $disabled
write " scan time $scan_time;" $scan_time
writeToConfig "}"
writeToConfig " "
}
# Function: prepare_bgp_template $1
# $1 string
# This function gets each "bgp_template" protocol section in the UCI configuration and sets each option in the bird4.conf file.
# $1 is set as the ID of the current UCI bgp_template section.
# Careful! Template options will be replaced by "instance" options if there is any match.
prepare_bgp_template() {
local section="$1"
local disabled; local table; local import; local export; local local_address; local local_as; local neighbor_address; local neighbor_as; local source_address; local next_hop_self; local next_hop_keep; local rr_client; local rr_cluster_id; local import_limit; local import_limit_action; local export_limit; local export_limit_action; local receive_limit; local receive_limit_action
get_bool disabled $section
get_bool next_hop_self $section
get_bool next_hop_keep $section
get table $section
get import $section
get export $section
get local_address $section
get local_as $section
get rr_client $section
get rr_cluster_id $section
get import_limit $section
get import_limit_action $section
get export_limit $section
get export_limit_action $section
get receive_limit $section
get receive_limit_action $section
get neighbor_address $section
get neighbor_as $section
writeToConfig "#$section template:"
writeToConfig "template bgp $section {"
[ -n "$disabled" ] && write_bool disabled $disabled
write " table $table;" $table
write " local as $local_as;" $local_as
write " source address $local_address;" $local_address
write " import $import;" $import
write " export $export;" $export
if [ -n "$next_hop_self" ]; then
[ "$next_hop_self" = "1" ] && writeToConfig " next hop self;" || writeToConfig "# next hop self;"
fi
if [ -n "$next_hop_keep" ]; then
[ "$next_hop_keep" = "1" ] && writeToConfig " next hop keep;" || writeToConfig "# next hop keep;"
fi
[ "$rr_client" = "1" ] && writeToConfig " rr client;" || writeToConfig "# rr client;"
write " rr cluster id $rr_cluster_id;" $rr_cluster_id
if [ -n "$import_limit" -a "$import_limit" > "0" ]; then
[ -z "$import_limit_action" ] && $import_limit_action = "warn"
writeToConfig " import limit $import_limit action $import_limit_action;"
fi
if [ -n "$export_limit" -a "$export_limit" > "0" ]; then
[ -z "$export_limit_action" ] && $export_limit_action = "warn"
writeToConfig " export limit $export_limit action $export_limit_action;"
fi
if [ -n "$receive_limit" -a "$receive_limit" > "0" ]; then
[ -z "$receive_limit_action" ] && $receive_limit_action = "warn"
writeToConfig " receive limit $receive_limit action $receive_limit_action;"
fi
[ -n "$neighbor_address" -a -n "$neighbor_as" ] && writeToConfig " neighbor $neighbor_address as $neighbor_as;"
writeToConfig "}"
writeToConfig " "
}
# Function: prepare_bgp $1
# $1 string
# This function gets each "bgp" protocol section in the UCI configuration and sets each option in the bird6.conf file.
# $1 is set as the ID of the current UCI bgp section.
# Careful! The options set in bgp instances overlap bgp_template ones.
prepare_bgp() {
local section="$1"
local disabled; local table; local template; local description; local import; local export; local local_address; local local_as; local neighbor_address; local neighbor_as; local rr_client; local rr_cluster_id; local import_limit; local import_limit_action; local export_limit; local export_limit_action; local receive_limit; local receive_limit_action
get disabled $section
get table $section
get template $section
get description $section
get import $section
get export $section
get local_address $section
get local_as $section
get rr_client $section
get rr_cluster_id $section
get import_limit $section
get import_limit_action $section
get export_limit $section
get export_limit_action $section
get receive_limit $section
get receive_limit_action $section
get neighbor_address $section
get neighbor_as $section
writeToConfig "#$section configuration:"
[ -n "$template" ] && writeToConfig "protocol bgp $section from $template {" || writeToConfig "protocol bgp $section {"
[ -n "$disabled" ] && write_bool disabled $disabled
write " table $table;" $table
# [ -n "$description" ] && writeToConfig ' description "'$description'";'
write " local as $local_as;" $local_as
write " source address $local_address;" $local_address
write " import $import;" $import
write " export $export;" $export
if [ -n "$next_hop_self" ]; then
[ "$next_hop_self" = "1" ] && writeToConfig " next hop self;" || writeToConfig "# next hop self;"
fi
if [ -n "$next_hop_keep" ]; then
[ "$next_hop_keep" = "1" ] && writeToConfig " next hop keep;" || writeToConfig "# next hop keep;"
fi
[ "$rr_client" = "1" ] && writeToConfig " rr client;" || writeToConfig "# rr client;"
write " rr cluster id $rr_cluster_id;" $rr_cluster_id
if [ -n "$import_limit" -a "$import_limit" > "0" ]; then
[ -z "$import_limit_action" ] && $import_limit_action = "warn"
writeToConfig " import limit $import_limit action $import_limit_action;"
fi
if [ -n "$export_limit" -a "$export_limit" > "0" ]; then
[ -z "$export_limit_action" ] && $export_limit_action = "warn"
writeToConfig " export limit $export_limit action $export_limit_action;"
fi
if [ -n "$receive_limit" -a "$receive_limit" > "0" ]; then
[ -z "$receive_limit_action" ] && $receive_limit_action = "warn"
writeToConfig " receive limit $receive_limit action $receive_limit_action;"
fi
[ -n "$neighbor_address" -a -n "$neighbor_as" ] && writeToConfig " neighbor $neighbor_address as $neighbor_as;"
writeToConfig "}"
writeToConfig " "
}
# Function: prepare_bgp_filters $1
# $1 string
# This function gets each "bgp_filter" protocol section in the UCI configuration and sets each option in the bird4.conf file.
# $1 is set as the ID of the current UCI bgp_filter section.
# This function checks if the filter file exists and, in that case, it writes its content to the configuration file.
prepare_bgp_filters() {
local section="$1"
local type
local file_path
get type $section
get file_path $section
if [ -e "$file_path" ]; then
local filter_content=`cat $file_path`
if [ -n "$type" -a "$type" = "bgp" ]; then
writeToConfig "#Filter $section:"
writeToConfig "${filter_content}"
writeToConfig " "
fi
fi
}
start() {
config_load bird4
local use_UCI_config
get use_UCI_config 'bird'
if [ -z "$use_UCI_config" -o "$use_UCI_config" = "0" ]; then
service_start $BIRD_BIN -d -c $BIRD_CONFIG -P $SERVICE_PID_FILE
else
#Set Bird4 configuration location:
local UCI_config_File
get UCI_config_File 'bird'
BIRD_CONFIG=${UCI_config_File:-/tmp/bird4.conf}
#Setup the basic configuration
prepare_global 'global'
config_foreach prepare_kernel 'kernel'
config_foreach prepare_static 'static'
config_foreach prepare_device 'device'
#config_foreach prepare_direct 'direct'
#Setup the protocols configuration (currently BGP only)
config_foreach prepare_bgp_template 'bgp_template'
config_foreach prepare_bgp 'bgp'
config_foreach prepare_bgp_filters 'filter'
#Start the service
service_start $BIRD_BIN -d -c $BIRD_CONFIG -P $SERVICE_PID_FILE
fi
}
stop() {
service_stop $BIRD_BIN
}
restart() {
stop
start
}
reload() {
service_reload $BIRD_BIN
}

View File

@ -0,0 +1,239 @@
--[[
Copyright (C) 2014 - Eloi Carbó Solé (GSoC2014)
BGP/Bird integration with OpenWRT and QMP
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
--]]
require("luci.sys")
local http = require "luci.http"
local uci = require "luci.model.uci"
local uciout = uci.cursor()
m=Map("bird4", "Bird4 BGP protocol's configuration")
tab_templates = {}
uciout:foreach('bird4', 'bgp_template', function (s)
local name = s[".name"]
if (name ~= nil) then
table.insert(tab_templates, name)
end
end)
-- Section BGP Templates
sect_templates = m:section(TypedSection, "bgp_template", "BGP Templates", "Configuration of the templates used in BGP instances.")
sect_templates.addremove = true
sect_templates.anonymous = false
disabled = sect_templates:option(Flag, "disabled", "Disabled", "Enable/Disable BGP Protocol")
disabled.optional=true
table = sect_templates:option(ListValue, "table", "Table", "Set the table used for BGP Routing")
table.optional=true
uciout:foreach("bird4", "table",
function (s)
table:value(s.name)
end)
table:value("")
import = sect_templates:option(Value, "import", "Import","")
import.optional=true
export = sect_templates:option(Value, "export", "Export", "")
export.optional=true
source_addr = sect_templates:option(Value, "source_address", "Source Address", "Source address for BGP routing. By default uses Router ID")
source_addr.optional = true
description = sect_templates:option(TextValue, "description", "Description", "Description of the current BGP instance")
description.optional = true
next_hop_self = sect_templates:option(Flag, "next_hop_self", "Next hop self", "Avoid next hop calculation and advertise own source address as next hop")
next_hop_self.default = nil
next_hop_self.optional = true
next_hop_keep = sect_templates:option(Flag, "next_hop_keep", "Next hop keep", "Forward the received Next Hop attribute event in situations where the local address should be used instead, like subneting")
next_hop_keep.default = nil
next_hop_keep.optional = true
rr_client = sect_templates:option(Flag, "rr_client", "Route Reflector server", "This router serves as a Route Reflector server and treats neighbors as clients")
rr_client.default = nil
rr_client.optional = true
rr_cluster_id = sect_templates:option(Value, "rr_cluster_id", "Route Reflector Cluster ID", "Identificator of the RR cluster. By default uses the Router ID")
rr_cluster_id.optional = true
import_limit = sect_templates:option(Value, "import_limit", "Routes import limit", "Specify an import route limit. By default is disabled '0'")
import_limit.default= "0"
import_limit.optional = true
import_limit_action = sect_templates:option(ListValue, "import_limit_action", "Routes import limit action", "Action to take when import routes limit ir reached")
import_limit_action:value("warn")
import_limit_action:value("block")
import_limit_action:value("disable")
import_limit_action:value("restart")
import_limit_action.default = "warn"
import_limit_action.optional = true
export_limit = sect_templates:option(Value, "export_limit", "Routes export limit", "Specify an export route limit. By default is disabled '0'")
export_limit.default="0"
export_limit.optional = true
export_limit_action = sect_templates:option(ListValue, "export_limit_action", "Routes export limit action", "Action to take when export routes limit is reached")
export_limit_action:value("warn")
export_limit_action:value("block")
export_limit_action:value("disable")
export_limit_action:value("restart")
export_limit_action.default = "warn"
export_limit_action.optional = true
receive_limit = sect_templates:option(Value, "receive_limit", "Routes received limit", "Specify a received route limit. By default is disabled '0'")
receive_limit.default="0"
receive_limit.optional = true
receive_limit_action = sect_templates:option(ListValue, "receive_limit_action", "Routes received limit action", "Action to take when received routes limit is reached")
receive_limit_action:value("warn")
receive_limit_action:value("block")
receive_limit_action:value("disable")
receive_limit_action:value("restart")
receive_limit_action.default = "warn"
receive_limit_action.optional = true
local_address = sect_templates:option(Value, "local_address", "Local BGP address", "")
local_address.optional=true
local_as = sect_templates:option(Value, "local_as", "Local AS", "")
local_as.optional=true
-- Section BGP Instances:
sect_instances = m:section(TypedSection, "bgp", "BGP Instances", "Configuration of the BGP protocol instances")
sect_instances.addremove = true
sect_instances.anonymous = false
templates = sect_instances:option(ListValue, "template", "Templates", "Available BGP templates")
uciout:foreach("bird4", "bgp_template",
function(s)
templates:value(s[".name"])
end)
templates:value("")
source_addr = sect_instances:option(Value, "source_address", "Source Address", "Source address for BGP routing. By default uses Router ID")
source_addr.optional = true
description = sect_instances:option(TextValue, "description", "Description", "Description of the current BGP instance")
description.optional = true
next_hop_self = sect_instances:option(Flag, "next_hop_self", "Next hop self", "Avoid next hop calculation and advertise own source address as next hop")
next_hop_self.default = nil
next_hop_self.optional = true
next_hop_keep = sect_instances:option(Flag, "next_hop_keep", "Next hop keep", "Forward the received Next Hop attribute event in situations where the local address should be used instead, like subneting")
next_hop_keep.default = nil
next_hop_keep.optional = true
rr_client = sect_instances:option(Flag, "rr_client", "Route Reflector server", "This router serves as a Route Reflector server and treats neighbors as clients")
rr_client.default = nil
rr_client.optional = true
rr_cluster_id = sect_instances:option(Value, "rr_cluster_id", "Route Reflector Cluster ID", "Identificator of the RR cluster. By default uses the Router ID")
rr_cluster_id.optional = true
import_limit = sect_instances:option(Value, "import_limit", "Routes import limit", "Specify an import route limit. By default is disabled '0'")
import_limit.default="0"
import_limit.optional = true
import_limit_action = sect_instances:option(ListValue, "import_limit_action", "Routes import limit action", "Action to take when import routes limit ir reached")
import_limit_action:value("warn")
import_limit_action:value("block")
import_limit_action:value("disable")
import_limit_action:value("restart")
import_limit_action.default = "warn"
import_limit_action.optional = true
export_limit = sect_instances:option(Value, "export_limit", "Routes export limit", "Specify an export route limit. By default is disabled '0'")
export_limit.default="0"
export_limit.optional = true
export_limit_action = sect_instances:option(ListValue, "export_limit_action", "Routes export limit action", "Action to take when export routes limit is reached")
export_limit_action:value("warn")
export_limit_action:value("block")
export_limit_action:value("disable")
export_limit_action:value("restart")
export_limit_action.default = "warn"
export_limit_action.optional = true
receive_limit = sect_instances:option(Value, "receive_limit", "Routes received limit", "Specify a received route limit. By default is disabled '0'")
receive_limit.default="0"
receive_limit.optional = true
receive_limit_action = sect_instances:option(ListValue, "receive_limit_action", "Routes received limit action", "Action to take when received routes limit is reached")
receive_limit_action:value("warn")
receive_limit_action:value("block")
receive_limit_action:value("disable")
receive_limit_action:value("restart")
receive_limit_action.default = "warn"
receive_limit_action.optional = true
neighbor_address = sect_instances:option(Value, "neighbor_address", "Neighbor IP Address", "")
neighbor_as = sect_instances:option(Value, "neighbor_as", "Neighbor AS", "")
disabled = sect_instances:option(Flag, "disabled", "Disabled", "Enable/Disable BGP Protocol")
disabled.optional=true
disabled.default=nil
table = sect_instances:option(ListValue, "table", "Table", "Set the table used for BGP Routing")
table.optional=true
uciout:foreach("bird4", "table",
function (s)
table:value(s.name)
end)
table:value("")
import = sect_instances:option(Value, "import", "Import","")
import.optional=true
export = sect_instances:option(Value, "export", "Export", "")
export.optional=true
local_address = sect_instances:option(Value, "local_address", "Local BGP address", "")
local_address.optional=true
local_as = sect_instances:option(Value, "local_as", "Local AS", "")
local_as.optional=true
-- Section BGP Filters
sect_filters = m:section(TypedSection, "filter", "BGP Filters", "Filters of the BGP instances")
sect_filters.addremove = true
sect_filters.anonymous = false
sect_filters:depends("type", "bgp")
instance = sect_filters:option(ListValue, "instance", "BGP instance", "Filter's BGP instance")
instance:depends("type", "bgp")
uciout:foreach("bird4", "bgp",
function (s)
instance:value(s[".name"])
end)
type = sect_filters:option(Value, "type", "Filter type", "")
type.default = "bgp"
path = sect_filters:option(Value, "file_path", "Filter's file path", "Path to the Filter's file")
path:depends("type", "bgp")
function m.on_commit(self,map)
luci.sys.call('/etc/init.d/bird4 stop; /etc/init.d/bird4 start')
end
return m

View File

@ -0,0 +1,200 @@
--[[
Copyright (C) 2014 - Eloi Carbó Solé (GSoC2014)
BGP/Bird integration with OpenWRT and QMP
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
--]]
require("luci.sys")
local http = require "luci.http"
local uci = require "luci.model.uci"
local uciout = uci.cursor()
m=Map("bird4", "Bird4 general protocol's configuration.")
-- Optional parameters lists
local protoptions = {
{["name"]="table", ["help"]="Auxiliar table for routing", ["depends"]={"static","kernel"}},
{["name"]="import", ["help"]="Set if the protocol must import routes", ["depends"]={"kernel"}},
{["name"]="export", ["help"]="Set if the protocol must export routes", ["depends"]={"kernel"}},
{["name"]="scan_time", ["help"]="Time between scans", ["depends"]={"kernel","device"}},
{["name"]="kernel_table", ["help"]="Set which table must be used as auxiliar kernel table", ["depends"]={"kernel"}},
{["name"]="learn", ["help"]="Learn routes", ["depends"]={"kernel"}},
{["name"]="persist", ["help"]="Store routes. After a restart, routes will be still configured", ["depends"]={"kernel"}}
}
local routeroptions = {
{["name"]="prefix",["help"]="",["depends"]={"router","special","iface","multipath","recursive"}},
{["name"]="via",["help"]="",["depends"]={"router","multipath"}},
{["name"]="attribute",["help"]="",["depends"]={"special"}},
{["name"]="iface",["help"]="",["depends"]={"iface"}},
{["name"]="ip",["help"]="",["depends"]={"recursive"}}
}
--
-- KERNEL PROTOCOL
--
sect_kernel_protos = m:section(TypedSection, "kernel", "Kernel options", "Configuration of the kernel protocols. First Instance MUST be Primary table (no table or kernel_table fields).")
sect_kernel_protos.addremove = true
sect_kernel_protos.anonymous = false
-- Default kernel parameters
disabled = sect_kernel_protos:option(Flag, "disabled", "Disabled", "If this option is true, the protocol will not be configured.")
disabled.default=0
-- Optional parameters
for _,o in ipairs(protoptions) do
if o.name ~= nil then
for _, d in ipairs(o.depends) do
if d == "kernel" then
if o.name == "learn" or o.name == "persist" then
value = sect_kernel_protos:option(Flag, o.name, translate(o.name), translate(o.help))
elseif o.name == "table" then
value = sect_kernel_protos:option(ListValue, o.name, translate(o.name), translate(o.help))
uciout:foreach("bird4", "table",
function (s)
value:value(s.name)
end)
value:value("")
else
value = sect_kernel_protos:option(Value, o.name, translate(o.name), translate(o.help))
end
value.optional = true
value.rmempty = true
end
end
end
end
--
-- DEVICE PROTOCOL
--
sect_device_protos = m:section(TypedSection, "device", "Device options", "Configuration of the device protocols.")
sect_device_protos.addremove = true
sect_device_protos.anonymous = false
-- Default kernel parameters
disabled = sect_device_protos:option(Flag, "disabled", "Disabled", "If this option is true, the protocol will not be configured.")
disabled.default=0
-- Optional parameters
for _,o in ipairs(protoptions) do
if o.name ~= nil then
for _, d in ipairs(o.depends) do
if d == "device" then
value = sect_device_protos:option(Value, o.name, translate(o.name), translate(o.help))
value.optional = true
value.rmempty = true
end
end
end
end
--
-- STATIC PROTOCOL
--
sect_static_protos = m:section(TypedSection, "static", "Static options", "Configuration of the static protocols.")
sect_static_protos.addremove = true
sect_static_protos.anonymous = false
-- Default kernel parameters
disabled = sect_static_protos:option(Flag, "disabled", "Disabled", "If this option is true, the protocol will not be configured.")
disabled.default=0
-- Optional parameters
for _,o in ipairs(protoptions) do
if o.name ~= nil then
for _, d in ipairs(o.depends) do
if d == "static" then
if o.name == "table" then
value = sect_static_protos:option(ListValue, o.name, translate(o.name), translate(o.help))
uciout:foreach("bird4", "table",
function (s)
value:value(s.name)
end)
value:value("")
else
value = sect_static_protos:option(Value, o.name, translate(o.name), translate(o.help))
end
value.optional = true
value.rmempty = true
end
end
end
end
--
-- ROUTES FOR STATIC PROTOCOL
--
sect_routes = m:section(TypedSection, "route", "Routes configuration", "Configuration of the routes used in static protocols.")
sect_routes.addremove = true
sect_routes.anonymous = true
instance = sect_routes:option(ListValue, "instance", "Route instance", "")
i = 0
uciout:foreach("bird4", "static",
function (s)
instance:value(s[".name"])
end)
prefix = sect_routes:option(Value, "prefix", "Route prefix", "")
type = sect_routes:option(ListValue, "type", "Type of route", "")
type:value("router")
type:value("special")
type:value("iface")
type:value("recursive")
type:value("multipath")
valueVia = sect_routes:option(Value, "via", "Via", "")
valueVia.optional = false
valueVia:depends("type", "router")
valueVia.datatype = "ip4addr"
listVia = sect_routes:option(DynamicList, "l_via", "Via", "")
listVia:depends("type", "multipath")
listVia.optional=false
listVia.datatype = "ip4addr"
attribute = sect_routes:option(Value, "attribute", "Attribute", "Types are: unreachable, prohibit and blackhole")
attribute:depends("type", "special")
iface = sect_routes:option(ListValue, "iface", "Interface", "")
iface:depends("type", "iface")
uciout:foreach("wireless", "wifi-iface",
function(section)
iface:value(section[".name"])
end)
ip = sect_routes:option(Value, "ip", "IP address", "")
ip:depends("type", "ip")
ip.datatype = [[ or"ip4addr", "ip6addr" ]]
function m.on_commit(self,map)
luci.sys.call('/etc/init.d/bird4 stop; /etc/init.d/bird4 start')
end
return m

View File

@ -0,0 +1,77 @@
--[[
Copyright (C) 2014 - Eloi Carbó Solé (GSoC2014)
BGP/Bird integration with OpenWRT and QMP
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
]]--
require("luci.sys")
local http = require "luci.http"
local uci = require "luci.model.uci"
local uciout = uci.cursor()
m=Map("bird4", "Bird4 UCI configuration helper", "")
-- Named section: "bird"
s_bird_uci = m:section(NamedSection, "bird", "bird", "Bird4 file settings", "")
s_bird_uci.addremove = False
uuc = s_bird_uci:option(Flag, "use_UCI_config", "Use UCI configuration", "Use UCI configuration instead of the /etc/bird4.conf file")
ucf = s_bird_uci:option(Value, "UCI_config_File", "UCI File", "Specify the file to place the UCI-translated configuration")
ucf.default = "/tmp/bird4.conf"
-- Named Section: "table"
s_bird_table = m:section(TypedSection, "table", "Tables configuration", "Configuration of the tables used in the protocols")
s_bird_table.addremove = true
s_bird_table.anonymous = true
name = s_bird_table:option(Value, "name", "Table name", "Descriptor ID of the table")
-- Named section: "global"
s_bird_global = m:section(NamedSection, "global", "global", "Global options", "Basic Bird4 settings")
s_bird_global.addremove = False
id = s_bird_global:option(Value, "router_id", "Router ID", "Identification number of the router. By default, is the router's IP.")
lf = s_bird_global:option(Value, "log_file", "Log File", "File used to store log related data.")
l = s_bird_global:option(MultiValue, "log", "Log", "Set which elements do you want to log.")
l:value("all", "All")
l:value("info", "Info")
l:value("warning","Warning")
l:value("error","Error")
l:value("fatal","Fatal")
l:value("debug","Debug")
l:value("trace","Trace")
l:value("remote","Remote")
l:value("auth","Auth")
d = s_bird_global:option(MultiValue, "debug", "Debug", "Set which elements do you want to debug.")
d:value("all", "All")
d:value("states","States")
d:value("routes","Routes")
d:value("filters","Filters")
d:value("interfaces","Interfaces")
d:value("events","Events")
d:value("packets","Packets")
function m.on_commit(self,map)
luci.sys.call('/etc/init.d/bird4 stop; /etc/init.d/bird4 start')
end
return m

View File

@ -0,0 +1,7 @@
#!/bin/sh
EXC=`mount -t overlayfs | grep overlayfs -c`
[ $EXC > 0 ] && rm -r /etc/init.d/bird4 || mv /etc/init.d/bird4 /etc/bird4/init.d/bird4.orig
ln -s /etc/bird4/init.d/bird4 /etc/init.d/bird4

View File

@ -0,0 +1,91 @@
# Copyright (C) 2014 - Eloi Carbó Solé (GSoC2014)
# BGP/Bird integration with OpenWRT and QMP
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
include $(TOPDIR)/rules.mk
include $(INCLUDE_DIR)/kernel.mk
BIRD:=bird6
PKG_NAME:=$(BIRD)-openwrt
PKG_RELEASE:=0.2
PKG_BUILD_DIR := $(BUILD_DIR)/$(PKG_NAME)
uci:=$(BIRD)-uci
luci:=luci-app-$(BIRD)
include $(INCLUDE_DIR)/package.mk
define Build/Prepare
endef
define Build/Compile
endef
define Package/$(uci)
TITLE:=The BIRD UCI module
SECTION:=net
CATEGORY:=Network
SUBMENU:=Routing and Redirection
MAINTAINER:=Eloi Carbo <eloicaso@openmailbox.org>
URL:=https://github.com/eloicaso/bird6-openwrt/
DEPENDS:=+$(BIRD) +libuci +uci
endef
define Package/$(uci)/description
$(BIRD) UCI integration module
endef
define Package/$(uci)/install
$(INSTALL_DIR) $(1)/etc/$(BIRD)/init.d
$(INSTALL_DIR) $(1)/etc/config
$(INSTALL_BIN) ./src/init.d/$(BIRD) $(1)/etc/$(BIRD)/init.d/
$(CP) ./src/uci-defaults/$(uci)-install-init.d $(1)/etc/$(BIRD)/init.d/
$(CP) ./src/config/$(BIRD) $(1)/etc/config/
endef
define Package/$(uci)/postinst
#!/bin/sh
if [ -z $${IPKG_INSTROOT} ]; then
( . /etc/bird6/init.d/bird6-uci-install-init.d ) && rm -f /etc/bird6/init.d/bird6-uci-install-init.d
fi
endef
$(eval $(call BuildPackage,$(uci)))
define Package/$(luci)
TITLE:=LuCI support for $(BIRD)
SECTION:=luci
CATEGORY:=LuCI
SUBMENU:=3. Applications
MAINTAINER:=Eloi Carbo <eloicaso@openmailbox.org>
URL:=https://github.com/eloicaso/bird6-openwrt/
DEPENDS:=+$(BIRD)-uci +luci-base
endef
define Package/$(luci)/description
$(BIRD) application for LuCI
endef
define Package/$(luci)/install
$(INSTALL_DIR) $(1)/usr/lib/lua/luci/controller/
$(INSTALL_DIR) $(1)/usr/lib/lua/luci/model/cbi/$(BIRD)/
$(CP) ./src/model/* $(1)/usr/lib/lua/luci/model/cbi/$(BIRD)/
$(CP) ./src/controller/* $(1)/usr/lib/lua/luci/controller/
endef
$(eval $(call BuildPackage,$(luci)))

View File

@ -0,0 +1,86 @@
config bird 'bird'
option use_UCI_config '1'
#Caution! Enabling this option, Bird will translate this
#UCI file and use it instead of /etc/bird6.conf
option UCI_config_file '/tmp/bird6.conf'
#If you enable useUCIconfig, UCIconfigFile will be Bird's
#configuration file location.
config global 'global'
option log_file '/tmp/bird6.log'
option log 'all'
option debug 'off'
option router_id 'fc00::1:5'
option listen_bgp_addr 'fc00::1:5'
option listen_bgp_port '179'
option listen_bgp_dual '1'
config table
option name 'aux'
config kernel kernel1
option table 'aux'
option import 'all'
option export 'all'
option kernel_table '100'
option scan_time '10'
option learn '1'
option persist '0'
option disabled '0'
config device device1
option scan_time '10'
option disabled '0'
config static static1
option table 'aux'
option disabled '0'
config bgp bgp1
option template 'bgp_common'
option description 'Description of the BGP instance'
option neighbor_address 'fc00::1:5'
option neighbor_as '65530'
option next_hop_self '0'
option next_hop_keep '0'
option rr_client '1'
option rr_cluster_id 'fc00::1:5'
config bgp_template bgp_common
option table 'aux'
option import 'all'
option export 'all'
option local_address '2001:B30:1000:19::2'
option local_as '65001'
option import_limit '100'
option import_limit_action 'warn'
option export_limit '100'
option export_limit_action 'warn'
option receive_limit '100'
option receive_limit_action 'warn'
option disabled '0'
config route
option instance 'static1'
option type 'router'
option prefix '2001:db8:0:f103::/64'
option via 'fe80::225:90ff:fe97:a718'
config route
option instance 'static1'
option type 'special'
option prefix '2001:db8:0:f101::/128'
option attribute 'unreachable'
config route
option instance 'static1'
option type 'iface'
option prefix '2001:db8:0:f101::1111/128'
option iface 'eth0'
config filter 'firstFilter'
option type 'bgp'
option instance 'bgp1'
option file_path '/var/filters/f1'

View File

@ -0,0 +1,27 @@
--[[
Copyright (C) 2014 - Eloi Carbó Solé (GSoC2014)
BGP/Bird integration with OpenWRT and QMP
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
--]]
module("luci.controller.bird6", package.seeall)
function index()
entry({"admin","network","bird6"}, cbi("bird6/overview"), "Bird6", 1).dependent=false
entry({"admin","network","bird6","overview"}, cbi("bird6/overview"), "Overview", 2).dependent=false
entry({"admin","network","bird6","proto_general"}, cbi("bird6/gen_proto"), "General protocols", 3).dependent=false
entry({"admin","network","bird6","proto_bgp"}, cbi("bird6/bgp_proto"), "BGP Protocol", 4).dependent=false
end

View File

@ -0,0 +1,421 @@
#!/bin/sh /etc/rc.common
# Copyright (C) 2014 - Eloi Carbó Solé (GSoC2014)
# BGP/Bird integration with OpenWRT and QMP
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
BIRD="bird6"
BIRD_CONFIG="/etc/$BIRD.conf"
START=99
STOP=10
SERVICE_DAEMONIZE=1
SERVICE_USE_PID=1
SERVICE_PID_FILE="/var/run/$BIRD.pid"
BIRD_BIN="/usr/sbin/$BIRD"
# Function: writeToConfig $1
# $1 string.
# Allows to write in the $BIRD_CONFIG file, the string $1. This function does not check the $1 string.
# Example: writeToConfig "value: $N"
writeToConfig() {
echo "$1" >> $BIRD_CONFIG
}
# Function: write $1 $2
# $1 string. $2 string.
# This function checks if $2 is empty. If not, it writes the string $1 in the $BIRD_CONFIG file.
# Use write function to check if $1, value found inside $2, is not empty and can be written in the configuration file.
# Example:
N=""; write "value: $N" $N;
write() {
[ -n "$2" ] && writeToConfig "$1"
}
#Function: write_bool $1 $2
# $1 string; $2 boolean
# This function checks if $2 is true or false and write the $1 string into $BIRD_CONFIG file.
# The function writes a # before the $2 string if its false.
# Example: local N=0; write_bool $N
write_bool() {
[ "$2" == 0 ] && writeToConfig "# $1;" || writeToConfig " $1;"
}
# Function: get $1 $2
# $1 string. $2 string
# This function uses the external UCI function "config_get $result $section $option" to obtain a string value from UCI config file.
# To use this function, use the same name of the UCI option for the variable.
# Example: UCI (option id 'abcd'); local id; get id $section
get() {
config_get $1 $2 $1
}
# Function: get_bool $1 $2
# $1 boolean. $2 string
# This function uses the external UCI function "config_get_bool $result $section $option" to obtain a boolean value from UCI config file.
# To use this function, use the same name of the UCI option for the variable $1.
# Example: UCI (option use_ipv6 '1'); local use_ipv6; get use_ipv6 $section
get_bool() {
config_get_bool $1 $2 $1
}
# Function: multipath_list $1
# $1 string
# This function writes the $1 string in the multipath routes.
multipath_list() {
write " via $1" $1
}
# Function: prepare_tables $1
# $1 string
# This function gets each "table" section in the UCI configuration and sets each option in the bird6.conf file.
# $1 is set as the ID of the current UCI table section
prepare_tables() {
local section="$1"; local name
get name $section
write "table $name;" $name
}
# Function: prepare_global $1
# $1 string
# This function gets each "global" section in the UCI configuration and sets each option in the bird6.conf file.
# $1 is set as the ID of the current UCI global section. prepare_global is the first configuration set in the bird6.conf and removes the old file.
prepare_global () {
local section="$1"
local log_file; local log; local debug; local router_id; local table; local listen_bgp_addr; local listen_bgp_port; local listen_bgp_dual
# Remove old configuration file
rm -f "$BIRD_CONFIG"
get log_file $section
get log $section
get debug $section
get router_id $section
get table $section
get listen_bgp_addr $section
get listen_bgp_port $section
get listen_bgp_dual $section
# First line of the NEW configuration file
echo "#Bird6 configuration using UCI:" > $BIRD_CONFIG
writeToConfig " "
[ -n "$log_file" -a -n "$log" ] && writeToConfig 'log "'$log_file'" '$log';'
write "debug protocols $debug;" $debug
writeToConfig " "
writeToConfig "#Router ID"
write "router id $router_id;" $router_id
writeToConfig " "
writeToConfig "#Secondary tables"
config_foreach prepare_tables 'table'
if [ -n "$listen_bgp_dual" -o "$listen_bgp_dual" = "0" ]; then
writeToConfig "listen bgp $listen_bgp_addr $listen_bgp_port v6only;"
else
writeToConfig "listen bgp $listen_bgp_addr $listen_bgp_port dual;"
fi
writeToConfig " "
}
# Function: prepare_routes $1
# $1 string
# This function gets each "route" section in the UCI configuration and sets each option in the bird6.conf file.
# $1 is set as the ID of the current UCI route section. Each type of route has its own treatment.
prepare_routes() {
local instance; local prefix; local via; local type
local section="$1"
local protoInstance="$2"
get instance $section
if [ "$instance" = "$protoInstance" ]; then
get type $section
case "$type" in
"router")
get prefix $section
get via $section
[ -n "$prefix" -a -n "$via" ] && writeToConfig " route $prefix via $via;"
;;
"special")
get prefix $section
get attribute $section
[ -n "$prefix" -a -n "$attribute" ] && writeToConfig " route $prefix $attribute;"
;;
"iface")
get prefix $section
get iface $section
[ -n "$prefix" -a -n "$iface" ] && writeToConfig ' route '$prefix' via "'$iface'";'
;;
"multipath")
get prefix $section
write " route $prefix multipath" $prefix
config_list_foreach $section l_via multipath_list
writeToConfig " ;"
;;
esac
fi
}
# Function: prepare_kernel $1
# $1 string
# This function gets each "kernel" protocol section in the UCI configuration and sets each option in the bird6.conf file.
# $1 is set as the ID of the current UCI kernel section.
prepare_kernel() {
local section="$1"
write "#$section configuration:" $section
local disabled; local table; local kernel_table; local import; local export; local scan_time; local persist; local learn
get_bool disabled $section
get table $section
get import $section
get export $section
get scan_time $section
get kernel_table $section
get learn $section
get persist $section
writeToConfig "protocol kernel {"
write_bool disabled $disabled
write " table $table;" $table
write " kernel table $kernel_table;" $kernel_table
write_bool learn $learn
write_bool persist $persist
write " scan time $scan_time;" $scan_time
write " import $import;" $import
write " export $export;" $export
writeToConfig "}"
writeToConfig " "
}
# Function: prepare_static $1
# $1 string
# This function gets each "static" protocol section in the UCI configuration and sets each option in the bird6.conf file.
# $1 is set as the ID of the current UCI static section.
prepare_static() {
local section="$1"
local disabled
get disabled $section
if [ "$disabled" -eq 0 ]; then
local table
get table $section
writeToConfig "#$section configration:" $section
writeToConfig "protocol static {"
write " table $table;" $table
config_foreach prepare_routes 'route' $section
writeToConfig "}"
writeToConfig " "
fi
}
# Function: prepare_device $1
# $1 string
# This function gets each "device" protocol section in the UCI configuration and sets each option in the bird6.conf file.
# $1 is set as the ID of the current UCI device section.
prepare_device() {
local section="$1"
local disabled; local scan_time
get disabled $section
get scan_time $section
write "#$section configuration:" $section
writeToConfig "protocol device {"
write_bool disabled $disabled
write " scan time $scan_time;" $scan_time
writeToConfig "}"
writeToConfig " "
}
# Function: prepare_bgp_template $1
# $1 string
# This function gets each "bgp_template" protocol section in the UCI configuration and sets each option in the bird6.conf file.
# $1 is set as the ID of the current UCI bgp_template section.
# Careful! Template options will be replaced by "instance" options if there is any match.
prepare_bgp_template() {
local section="$1"
local disabled; local table; local import; local export; local local_address; local local_as; local neighbor_address; local neighbor_as; local source_address; local next_hop_self; local next_hop_keep; local rr_client; local rr_cluster_id; local import_limit; local import_limit_action; local export_limit; local export_limit_action; local receive_limit; local receive_limit_action
get_bool disabled $section
get_bool next_hop_self $section
get_bool next_hop_keep $section
get table $section
get import $section
get export $section
get local_address $section
get local_as $section
get rr_client $section
get rr_cluster_id $section
get import_limit $section
get import_limit_action $section
get export_limit $section
get export_limit_action $section
get receive_limit $section
get receive_limit_action $section
get neighbor_address $section
get neighbor_as $section
writeToConfig "#$section template:"
writeToConfig "template bgp $section {"
[ -n "$disabled" ] && write_bool disabled $disabled
write " table $table;" $table
write " local as $local_as;" $local_as
write " source address $local_address;" $local_address
write " import $import;" $import
write " export $export;" $export
if [ -n "$next_hop_self" ]; then
[ "$next_hop_self" = "1" ] && writeToConfig " next hop self;" || writeToConfig "# next hop self;"
fi
if [ -n "$next_hop_keep" ]; then
[ "$next_hop_keep" = "1" ] && writeToConfig " next hop keep;" || writeToConfig "# next hop keep;"
fi
[ "$rr_client" = "1" ] && writeToConfig " rr client;" || writeToConfig "# rr client;"
write " rr cluster id $rr_cluster_id;" $rr_cluster_id
if [ -n "$import_limit" -a "$import_limit" > "0" ]; then
[ -z "$import_limit_action" ] && $import_limit_action = "warn"
writeToConfig " import limit $import_limit action $import_limit_action;"
fi
if [ -n "$export_limit" -a "$export_limit" > "0" ]; then
[ -z "$export_limit_action" ] && $export_limit_action = "warn"
writeToConfig " export limit $export_limit action $export_limit_action;"
fi
if [ -n "$receive_limit" -a "$receive_limit" > "0" ]; then
[ -z "$receive_limit_action" ] && $receive_limit_action = "warn"
writeToConfig " receive limit $receive_limit action $receive_limit_action;"
fi
[ -n "$neighbor_address" -a -n "$neighbor_as" ] && writeToConfig " neighbor $neighbor_address as $neighbor_as;"
writeToConfig "}"
writeToConfig " "
}
# Function: prepare_bgp $1
# $1 string
# This function gets each "bgp" protocol section in the UCI configuration and sets each option in the bird6.conf file.
# $1 is set as the ID of the current UCI bgp section.
# Careful! The options set in bgp instances overlap bgp_template ones.
prepare_bgp() {
local section="$1"
local disabled; local table; local template; local description; local import; local export; local local_address; local local_as; local neighbor_address; local neighbor_as; local rr_client; local rr_cluster_id; local import_limit; local import_limit_action; local export_limit; local export_limit_action; local receive_limit; local receive_limit_action
get disabled $section
get table $section
get template $section
get description $section
get import $section
get export $section
get local_address $section
get local_as $section
get rr_client $section
get rr_cluster_id $section
get import_limit $section
get import_limit_action $section
get export_limit $section
get export_limit_action $section
get receive_limit $section
get receive_limit_action $section
get neighbor_address $section
get neighbor_as $section
writeToConfig "#$section configuration:"
[ -n "$template" ] && writeToConfig "protocol bgp $section from $template {" || writeToConfig "protocol bgp $section {"
[ -n "$disabled" ] && write_bool disabled $disabled
write " table $table;" $table
# [ -n "$description" ] && writeToConfig ' description "'$description'";'
write " local as $local_as;" $local_as
write " source address $local_address;" $local_address
write " import $import;" $import
write " export $export;" $export
if [ -n "$next_hop_self" ]; then
[ "$next_hop_self" = "1" ] && writeToConfig " next hop self;" || writeToConfig "# next hop self;"
fi
if [ -n "$next_hop_keep" ]; then
[ "$next_hop_keep" = "1" ] && writeToConfig " next hop keep;" || writeToConfig "# next hop keep;"
fi
[ "$rr_client" = "1" ] && writeToConfig " rr client;" || writeToConfig "# rr client;"
write " rr cluster id $rr_cluster_id;" $rr_cluster_id
if [ -n "$import_limit" -a "$import_limit" > "0" ]; then
[ -z "$import_limit_action" ] && $import_limit_action = "warn"
writeToConfig " import limit $import_limit action $import_limit_action;"
fi
if [ -n "$export_limit" -a "$export_limit" > "0" ]; then
[ -z "$export_limit_action" ] && $export_limit_action = "warn"
writeToConfig " export limit $export_limit action $export_limit_action;"
fi
if [ -n "$receive_limit" -a "$receive_limit" > "0" ]; then
[ -z "$receive_limit_action" ] && $receive_limit_action = "warn"
writeToConfig " receive limit $receive_limit action $receive_limit_action;"
fi
[ -n "$neighbor_address" -a -n "$neighbor_as" ] && writeToConfig " neighbor $neighbor_address as $neighbor_as;"
writeToConfig "}"
writeToConfig " "
}
# Function: prepare_bgp_filters $1
# $1 string
# This function gets each "bgp_filter" protocol section in the UCI configuration and sets each option in the bird6.conf file.
# $1 is set as the ID of the current UCI bgp_filter section.
# This function checks if the filter file exists and, in that case, it writes its content to the configuration file.
prepare_bgp_filters() {
local section="$1"
local type
local file_path
get type $section
get file_path $section
if [ -e "$file_path" ]; then
local filter_content=`cat $file_path`
if [ -n "$type" -a "$type" = "bgp" ]; then
writeToConfig "#Filter $section:"
writeToConfig "${filter_content}"
writeToConfig " "
fi
fi
}
start() {
config_load bird6
local use_UCI_config
get use_UCI_config 'bird'
if [ -z "$use_UCI_config" -o "$use_UCI_config" = "0" ]; then
service_start $BIRD_BIN -d -c $BIRD_CONFIG -P $SERVICE_PID_FILE
else
#Set Bird6 configuration location:
local UCI_config_File
get UCI_config_File 'bird'
BIRD_CONFIG=${UCI_config_File:-/tmp/bird6.conf}
#Setup the basic configuration
prepare_global 'global'
config_foreach prepare_kernel 'kernel'
config_foreach prepare_static 'static'
config_foreach prepare_device 'device'
#config_foreach prepare_direct 'direct'
#Setup the protocols configuration (currently BGP only)
config_foreach prepare_bgp_template 'bgp_template'
config_foreach prepare_bgp 'bgp'
config_foreach prepare_bgp_filters 'filter'
#Start the service
service_start $BIRD_BIN -d -c $BIRD_CONFIG -P $SERVICE_PID_FILE
fi
}
stop() {
service_stop $BIRD_BIN
}
restart() {
stop
start
}
reload() {
service_reload $BIRD_BIN
}

View File

@ -0,0 +1,237 @@
--[[
Copyright (C) 2014 - Eloi Carbó Solé (GSoC2014)
BGP/Bird integration with OpenWRT and QMP
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
--]]
require("luci.sys")
local http = require "luci.http"
local uci = require "luci.model.uci"
local uciout = uci.cursor()
m=Map("bird6", "Bird6 BGP protocol's configuration")
tab_templates = {}
uciout:foreach('bird6', 'bgp_template', function (s)
local name = s[".name"]
if (name ~= nil) then
table.insert(tab_templates, name)
end
end)
-- Section BGP Templates
sect_templates = m:section(TypedSection, "bgp_template", "BGP Templates", "Configuration of the templates used in BGP instances.")
sect_templates.addremove = true
sect_templates.anonymous = false
disabled = sect_templates:option(Flag, "disabled", "Disabled", "Enable/Disable BGP Protocol")
disabled.optional=true
table = sect_templates:option(ListValue, "table", "Table", "Set the table used for BGP Routing")
table.optional=true
uciout:foreach("bird6", "table",
function (s)
table:value(s.name)
end)
table:value("")
import = sect_templates:option(Value, "import", "Import","")
import.optional=true
export = sect_templates:option(Value, "export", "Export", "")
export.optional=true
source_addr = sect_templates:option(Value, "source_address", "Source Address", "Source address for BGP routing. By default uses Router ID")
source_addr.optional = true
description = sect_templates:option(TextValue, "description", "Description", "Description of the current BGP instance")
description.optional = true
next_hop_self = sect_templates:option(Flag, "next_hop_self", "Next hop self", "Avoid next hop calculation and advertise own source address as next hop")
next_hop_self.default = nil
next_hop_self.optional = true
next_hop_keep = sect_templates:option(Flag, "next_hop_keep", "Next hop keep", "Forward the received Next Hop attribute event in situations where the local address should be used instead, like subneting")
next_hop_keep.default = nil
next_hop_keep.optional = true
rr_client = sect_templates:option(Flag, "rr_client", "Route Reflector server", "This router serves as a Route Reflector server and treats neighbors as clients")
rr_client.default = nil
rr_client.optional = true
rr_cluster_id = sect_templates:option(Value, "rr_cluster_id", "Route Reflector Cluster ID", "Identificator of the RR cluster. By default uses the Router ID")
rr_cluster_id.optional = true
import_limit = sect_templates:option(Value, "import_limit", "Routes import limit", "Specify an import route limit. By default is disabled '0'")
import_limit.default= "0"
import_limit.optional = true
import_limit_action = sect_templates:option(ListValue, "import_limit_action", "Routes import limit action", "Action to take when import routes limit ir reached")
import_limit_action:value("warn")
import_limit_action:value("block")
import_limit_action:value("disable")
import_limit_action:value("restart")
import_limit_action.default = "warn"
import_limit_action.optional = true
export_limit = sect_templates:option(Value, "export_limit", "Routes export limit", "Specify an export route limit. By default is disabled '0'")
export_limit.default="0"
export_limit.optional = true
export_limit_action = sect_templates:option(ListValue, "export_limit_action", "Routes export limit action", "Action to take when export routes limit is reached")
export_limit_action:value("warn")
export_limit_action:value("block")
export_limit_action:value("disable")
export_limit_action:value("restart")
export_limit_action.default = "warn"
export_limit_action.optional = true
receive_limit = sect_templates:option(Value, "receive_limit", "Routes received limit", "Specify a received route limit. By default is disabled '0'")
receive_limit.default="0"
receive_limit.optional = true
receive_limit_action = sect_templates:option(ListValue, "receive_limit_action", "Routes received limit action", "Action to take when received routes limit is reached")
receive_limit_action:value("warn")
receive_limit_action:value("block")
receive_limit_action:value("disable")
receive_limit_action:value("restart")
receive_limit_action.default = "warn"
receive_limit_action.optional = true
local_address = sect_templates:option(Value, "local_address", "Local BGP address", "")
local_address.optional=true
local_as = sect_templates:option(Value, "local_as", "Local AS", "")
local_as.optional=true
-- Section BGP Instances:
sect_instances = m:section(TypedSection, "bgp", "BGP Instances", "Configuration of the BGP protocol instances")
sect_instances.addremove = true
sect_instances.anonymous = false
templates = sect_instances:option(ListValue, "template", "Templates", "Available BGP templates")
uciout:foreach("bird6", "bgp_template",
function(s)
templates:value(s[".name"])
end)
templates:value("")
neighbor_address = sect_instances:option(Value, "neighbor_address", "Neighbor IP Address", "")
neighbor_as = sect_instances:option(Value, "neighbor_as", "Neighbor AS", "")
disabled = sect_instances:option(Flag, "disabled", "Disabled", "Enable/Disable BGP Protocol")
disabled.optional=true
disabled.default=nil
table = sect_instances:option(ListValue, "table", "Table", "Set the table used for BGP Routing")
table.optional=true
uciout:foreach("bird6", "table",
function (s)
table:value(s.name)
end)
table:value("")
description = sect_instances:option(TextValue, "description", "Description", "Description of the current BGP instance")
description.optional = true
import = sect_instances:option(Value, "import", "Import","")
import.optional=true
export = sect_instances:option(Value, "export", "Export", "")
export.optional=true
source_addr = sect_instances:option(Value, "source_address", "Source Address", "Source address for BGP routing. By default uses Router ID")
source_addr.optional = true
local_address = sect_instances:option(Value, "local_address", "Local BGP address", "")
local_address.optional=true
local_as = sect_instances:option(Value, "local_as", "Local AS", "")
local_as.optional=true
next_hop_self = sect_instances:option(Flag, "next_hop_self", "Next hop self", "Avoid next hop calculation and advertise own source address as next hop")
next_hop_self.default = nil
next_hop_self.optional = true
next_hop_keep = sect_instances:option(Flag, "next_hop_keep", "Next hop keep", "Forward the received Next Hop attribute event in situations where the local address should be used instead, like subneting")
next_hop_keep.default = nil
next_hop_keep.optional = true
rr_client = sect_instances:option(Flag, "rr_client", "Route Reflector server", "This router serves as a Route Reflector server and treats neighbors as clients")
rr_client.default = nil
rr_client.optional = true
rr_cluster_id = sect_instances:option(Value, "rr_cluster_id", "Route Reflector Cluster ID", "Identificator of the RR cluster. By default uses the Router ID")
rr_cluster_id.optional = true
import_limit = sect_instances:option(Value, "import_limit", "Routes import limit", "Specify an import route limit. By default is disabled '0'")
import_limit.default="0"
import_limit.optional = true
import_limit_action = sect_instances:option(ListValue, "import_limit_action", "Routes import limit action", "Action to take when import routes limit ir reached")
import_limit_action:value("warn")
import_limit_action:value("block")
import_limit_action:value("disable")
import_limit_action:value("restart")
import_limit_action.default = "warn"
import_limit_action.optional = true
export_limit = sect_instances:option(Value, "export_limit", "Routes export limit", "Specify an export route limit. By default is disabled '0'")
export_limit.default="0"
export_limit.optional = true
export_limit_action = sect_instances:option(ListValue, "export_limit_action", "Routes export limit action", "Action to take when export routes limit is reached")
export_limit_action:value("warn")
export_limit_action:value("block")
export_limit_action:value("disable")
export_limit_action:value("restart")
export_limit_action.default = "warn"
export_limit_action.optional = true
receive_limit = sect_instances:option(Value, "receive_limit", "Routes received limit", "Specify a received route limit. By default is disabled '0'")
receive_limit.default="0"
receive_limit.optional = true
receive_limit_action = sect_instances:option(ListValue, "receive_limit_action", "Routes received limit action", "Action to take when received routes limit is reached")
receive_limit_action:value("warn")
receive_limit_action:value("block")
receive_limit_action:value("disable")
receive_limit_action:value("restart")
receive_limit_action.default = "warn"
receive_limit_action.optional = true
-- Section BGP Filters
sect_filters = m:section(TypedSection, "filter", "BGP Filters", "Filters of the BGP instances")
sect_filters.addremove = true
sect_filters.anonymous = false
sect_filters:depends("type", "bgp")
instance = sect_filters:option(ListValue, "instance", "BGP instance", "Filter's BGP instance")
instance:depends("type", "bgp")
uciout:foreach("bird6", "bgp",
function (s)
instance:value(s[".name"])
end)
type = sect_filters:option(Value, "type", "Filter type", "")
type.default = "bgp"
path = sect_filters:option(Value, "file_path", "Filter's file path", "Path to the Filter's file")
path:depends("type", "bgp")
function m.on_commit(self,map)
luci.sys.call('/etc/init.d/bird6 stop; /etc/init.d/bird6 start')
end
return m

View File

@ -0,0 +1,201 @@
--[[
Copyright (C) 2014 - Eloi Carbó Solé (GSoC2014)
BGP/Bird integration with OpenWRT and QMP
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
--]]
require("luci.sys")
local http = require "luci.http"
local uci = require "luci.model.uci"
local uciout = uci.cursor()
m=Map("bird6", "Bird6 general protocol's configuration.")
-- Optional parameters lists
local protoptions = {
{["name"]="table", ["help"]="Auxiliar table for routing", ["depends"]={"static","kernel"}},
{["name"]="import", ["help"]="Set if the protocol must import routes", ["depends"]={"kernel"}},
{["name"]="export", ["help"]="Set if the protocol must export routes", ["depends"]={"kernel"}},
{["name"]="scan_time", ["help"]="Time between scans", ["depends"]={"kernel","device"}},
{["name"]="kernel_table", ["help"]="Set which table must be used as auxiliar kernel table", ["depends"]={"kernel"}},
{["name"]="learn", ["help"]="Learn routes", ["depends"]={"kernel"}},
{["name"]="persist", ["help"]="Store routes. After a restart, routes will be still configured", ["depends"]={"kernel"}}
}
local routeroptions = {
{["name"]="prefix",["help"]="",["depends"]={"router","special","iface","multipath","recursive"}},
{["name"]="via",["help"]="",["depends"]={"router","multipath"}},
{["name"]="attribute",["help"]="",["depends"]={"special"}},
{["name"]="iface",["help"]="",["depends"]={"iface"}},
{["name"]="ip",["help"]="",["depends"]={"recursive"}}
}
--
-- KERNEL PROTOCOL
--
sect_kernel_protos = m:section(TypedSection, "kernel", "Kernel options", "Configuration of the kernel protocols. First Instance MUST be Primary table (no table or kernel_table fields).")
sect_kernel_protos.addremove = true
sect_kernel_protos.anonymous = false
-- Default kernel parameters
disabled = sect_kernel_protos:option(Flag, "disabled", "Disabled", "If this option is true, the protocol will not be configured.")
disabled.default=0
-- Optional parameters
for _,o in ipairs(protoptions) do
if o.name ~= nil then
for _, d in ipairs(o.depends) do
if d == "kernel" then
if o.name == "learn" or o.name == "persist" then
value = sect_kernel_protos:option(Flag, o.name, translate(o.name), translate(o.help))
elseif o.name == "table" then
value = sect_kernel_protos:option(ListValue, o.name, translate(o.name), translate(o.help))
uciout:foreach("bird6", "table",
function (s)
value:value(s.name)
end)
value:value("")
else
value = sect_kernel_protos:option(Value, o.name, translate(o.name), translate(o.help))
end
value.optional = true
value.rmempty = true
end
end
end
end
--
-- DEVICE PROTOCOL
--
sect_device_protos = m:section(TypedSection, "device", "Device options", "Configuration of the device protocols.")
sect_device_protos.addremove = true
sect_device_protos.anonymous = false
-- Default kernel parameters
disabled = sect_device_protos:option(Flag, "disabled", "Disabled", "If this option is true, the protocol will not be configured.")
disabled.default=0
-- Optional parameters
for _,o in ipairs(protoptions) do
if o.name ~= nil then
for _, d in ipairs(o.depends) do
if d == "device" then
value = sect_device_protos:option(Value, o.name, translate(o.name), translate(o.help))
value.optional = true
value.rmempty = true
end
end
end
end
--
-- STATIC PROTOCOL
--
sect_static_protos = m:section(TypedSection, "static", "Static options", "Configuration of the static protocols.")
sect_static_protos.addremove = true
sect_static_protos.anonymous = false
-- Default kernel parameters
disabled = sect_static_protos:option(Flag, "disabled", "Disabled", "If this option is true, the protocol will not be configured.")
disabled.default=0
-- Optional parameters
for _,o in ipairs(protoptions) do
if o.name ~= nil then
for _, d in ipairs(o.depends) do
if d == "static" then
if o.name == "table" then
value = sect_static_protos:option(ListValue, o.name, translate(o.name), translate(o.help))
uciout:foreach("bird6", "table",
function (s)
value:value(s.name)
end)
value:value("")
else
value = sect_static_protos:option(Value, o.name, translate(o.name), translate(o.help))
end
value.optional = true
value.rmempty = true
end
end
end
end
--
-- ROUTES FOR STATIC PROTOCOL
--
sect_routes = m:section(TypedSection, "route", "Routes configuration", "Configuration of the routes used in static protocols.")
sect_routes.addremove = true
sect_routes.anonymous = true
instance = sect_routes:option(ListValue, "instance", "Route instance", "")
i = 0
uciout:foreach("bird6", "static",
function (s)
instance:value(s[".name"])
end)
prefix = sect_routes:option(Value, "prefix", "Route prefix", "")
prefix.datatype = "ip6prefix"
type = sect_routes:option(ListValue, "type", "Type of route", "")
type:value("router")
type:value("special")
type:value("iface")
type:value("recursive")
type:value("multipath")
valueVia = sect_routes:option(Value, "via", "Via", "")
valueVia.optional = false
valueVia:depends("type", "router")
valueVia.datatype = "ip6addr"
listVia = sect_routes:option(DynamicList, "l_via", "Via", "")
listVia:depends("type", "multipath")
listVia.optional=false
listVia.datatype = "ip6addr"
attribute = sect_routes:option(Value, "attribute", "Attribute", "Types are: unreachable, prohibit and blackhole")
attribute:depends("type", "special")
iface = sect_routes:option(ListValue, "iface", "Interface", "")
iface:depends("type", "iface")
uciout:foreach("wireless", "wifi-iface",
function(section)
iface:value(section[".name"])
end)
ip = sect_routes:option(Value, "ip", "IP address", "")
ip:depends("type", "ip")
ip.datatype = [[ or"ip4addr", "ip6addr" ]]
function m.on_commit(self,map)
luci.sys.call('/etc/init.d/bird6 stop; /etc/init.d/bird6 start')
end
return m

View File

@ -0,0 +1,87 @@
--[[
Copyright (C) 2014 - Eloi Carbó Solé (GSoC2014)
BGP/Bird integration with OpenWRT and QMP
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
]]--
require("luci.sys")
local http = require "luci.http"
local uci = require "luci.model.uci"
local uciout = uci.cursor()
m=Map("bird6", "Bird6 UCI configuration helper", "")
-- Named section: "bird"
s_bird_uci = m:section(NamedSection, "bird", "bird", "Bird6 file settings", "")
s_bird_uci.addremove = False
uuc = s_bird_uci:option(Flag, "use_UCI_config", "Use UCI configuration", "Use UCI configuration instead of the /etc/bird6.conf file")
ucf = s_bird_uci:option(Value, "UCI_config_File", "UCI File", "Specify the file to place the UCI-translated configuration")
ucf.default = "/tmp/bird6.conf"
-- Named Section: "table"
s_bird_table = m:section(TypedSection, "table", "Tables configuration", "Configuration of the tables used in the protocols")
s_bird_table.addremove = true
s_bird_table.anonymous = true
name = s_bird_table:option(Value, "name", "Table name", "Descriptor ID of the table")
-- Named section: "global"
s_bird_global = m:section(NamedSection, "global", "global", "Global options", "Basic Bird6 settings")
s_bird_global.addremove = False
id = s_bird_global:option(Value, "router_id", "Router ID", "Identification number of the router. By default, is the router's IP.")
lf = s_bird_global:option(Value, "log_file", "Log File", "File used to store log related data.")
l = s_bird_global:option(MultiValue, "log", "Log", "Set which elements do you want to log.")
l:value("all", "All")
l:value("info", "Info")
l:value("warning","Warning")
l:value("error","Error")
l:value("fatal","Fatal")
l:value("debug","Debug")
l:value("trace","Trace")
l:value("remote","Remote")
l:value("auth","Auth")
d = s_bird_global:option(MultiValue, "debug", "Debug", "Set which elements do you want to debug.")
d:value("all", "All")
d:value("states","States")
d:value("routes","Routes")
d:value("filters","Filters")
d:value("interfaces","Interfaces")
d:value("events","Events")
d:value("packets","Packets")
listen_addr = s_bird_global:option(Value, "listen_bgp_addr", "BGP Address", "Set the Addres that BGP will listen to.")
listen_addr.optional = true
listen_port = s_bird_global:option(Value, "listen_bgp_port", "BGP Port", "Set the port that BGP will listen to.")
listen_port.optional = true
listen_dual = s_bird_global:option(Flag, "listen_bgp_dual", "BGP Dual/ipv6", "Set if BGP connections will listen ipv6 only 'ipv6only' or both ipv4/6 'dual' routes")
listen_dual.optional = true
function m.on_commit(self,map)
luci.sys.call('/etc/init.d/bird6 stop; /etc/init.d/bird6 start')
end
return m

View File

@ -0,0 +1,7 @@
#!/bin/sh
EXC=`mount -t overlayfs | grep overlayfs -c`
[ $EXC > 0 ] && rm -r /etc/init.d/bird6 || mv /etc/init.d/bird6 /etc/bird6/init.d/bird6.orig
ln -s /etc/bird6/init.d/bird6 /etc/init.d/bird6