[PATCH 3/3] FEAT: Add protocol volatile
Thierry FOURNIER
tfournier at exceliance.fr
Fri Aug 23 15:15:33 CEST 2013
---
configure | 4 +-
configure.in | 4 +-
nest/proto.c | 3 +
nest/protocol.h | 2 +-
proto/Doc | 1 +
proto/volatile/Doc | 1 +
proto/volatile/Makefile | 6 ++
proto/volatile/config.Y | 75 ++++++++++++++++++
proto/volatile/volatile.c | 195 ++++++++++++++++++++++++++++++++++++++++++++++
proto/volatile/volatile.h | 46 +++++++++++
10 files changed, 332 insertions(+), 5 deletions(-)
create mode 100644 proto/volatile/Doc
create mode 100644 proto/volatile/Makefile
create mode 100644 proto/volatile/config.Y
create mode 100644 proto/volatile/volatile.c
create mode 100644 proto/volatile/volatile.h
diff --git a/configure b/configure
index 2f4cfd4..8ea9f37 100755
--- a/configure
+++ b/configure
@@ -2355,11 +2355,11 @@ esac
if test "$enable_ipv6" = yes ; then
ip=ipv6
SUFFIX=6
- all_protocols=bgp,ospf,pipe,radv,rip,static
+ all_protocols=bgp,ospf,pipe,radv,rip,static,volatile
else
ip=ipv4
SUFFIX=""
- all_protocols=bgp,ospf,pipe,rip,static
+ all_protocols=bgp,ospf,pipe,rip,static,volatile
fi
if test "$given_suffix" = yes ; then
diff --git a/configure.in b/configure.in
index 96f2a50..227c241 100644
--- a/configure.in
+++ b/configure.in
@@ -47,11 +47,11 @@ AC_SUBST(runtimedir)
if test "$enable_ipv6" = yes ; then
ip=ipv6
SUFFIX=6
- all_protocols=bgp,ospf,pipe,radv,rip,static
+ all_protocols=bgp,ospf,pipe,radv,rip,static,volatile
else
ip=ipv4
SUFFIX=""
- all_protocols=bgp,ospf,pipe,rip,static
+ all_protocols=bgp,ospf,pipe,rip,static,volatile
fi
if test "$given_suffix" = yes ; then
diff --git a/nest/proto.c b/nest/proto.c
index 60495aa..61b3882 100644
--- a/nest/proto.c
+++ b/nest/proto.c
@@ -718,6 +718,9 @@ protos_build(void)
#ifdef CONFIG_BGP
proto_build(&proto_bgp);
#endif
+#ifdef CONFIG_VOLATILE
+ proto_build(&proto_volatile);
+#endif
proto_pool = rp_new(&root_pool, "Protocols");
proto_flush_event = ev_new(proto_pool);
proto_flush_event->hook = proto_flush_loop;
diff --git a/nest/protocol.h b/nest/protocol.h
index 033a0ed..6f54ae4 100644
--- a/nest/protocol.h
+++ b/nest/protocol.h
@@ -75,7 +75,7 @@ void protos_dump_all(void);
extern struct protocol
proto_device, proto_radv, proto_rip, proto_static,
- proto_ospf, proto_pipe, proto_bgp;
+ proto_ospf, proto_pipe, proto_bgp, proto_volatile;
/*
* Routing Protocol Instance
diff --git a/proto/Doc b/proto/Doc
index 16b084f..cb16a43 100644
--- a/proto/Doc
+++ b/proto/Doc
@@ -5,4 +5,5 @@ C pipe
C rip
C radv
C static
+C volatile
S ../nest/rt-dev.c
diff --git a/proto/volatile/Doc b/proto/volatile/Doc
new file mode 100644
index 0000000..2d34a68
--- /dev/null
+++ b/proto/volatile/Doc
@@ -0,0 +1 @@
+S volatile.c
diff --git a/proto/volatile/Makefile b/proto/volatile/Makefile
new file mode 100644
index 0000000..8388e27
--- /dev/null
+++ b/proto/volatile/Makefile
@@ -0,0 +1,6 @@
+source=volatile.c
+root-rel=../../
+dir-name=proto/volatile
+
+include ../../Rules
+
diff --git a/proto/volatile/config.Y b/proto/volatile/config.Y
new file mode 100644
index 0000000..ce9f795
--- /dev/null
+++ b/proto/volatile/config.Y
@@ -0,0 +1,75 @@
+/*
+ * BIRD -- Static Protocol Configuration
+ *
+ * (c) 2013--2013 Thierry FOURNIER <tfournier at exceliance.fr>
+ *
+ * Can be freely distributed and used under the terms of the GNU GPL.
+ */
+
+CF_HDR
+
+#include "proto/volatile/volatile.h"
+
+CF_DEFINES
+
+#define VOLATILE_CFG ((struct volatile_config *) this_proto)
+
+CF_DECLS
+
+%type <px> prefix_autocorrect
+
+CF_KEYWORDS(VOLATILE, SET, DEL, CLEAR, GATEWAY)
+CF_KEYWORDS(MULTIPATH, WEIGHT)
+
+CF_GRAMMAR
+
+CF_ADDTO(proto, volatile_proto '}')
+
+volatile_proto_start: proto_start VOLATILE {
+ this_proto = proto_config_new(&proto_volatile, sizeof(struct volatile_config), $1);
+ }
+ ;
+
+volatile_proto:
+ volatile_proto_start proto_name '{'
+ | volatile_proto GATEWAY ipa ';' {
+ VOLATILE_CFG->gateway = $3;
+ VOLATILE_CFG->use_gateway = 1;
+ }
+ ;
+
+prefix_autocorrect:
+ ipa pxlen {
+ $$.addr = $1;
+ $$.len = $2;
+ ip_addr mask = ipa_mkmask($2);
+ $$.addr = ipa_and($$.addr, mask);
+ }
+ ;
+
+
+CF_CLI_HELP(CONFIGURE VOLATILE, {set|del|clear}, [[Configure volatile routes]])
+
+CF_CLI(CONFIGURE VOLATILE SET, optsym prefix_autocorrect,
+ <name> <network>/<netmask>,
+ [[Add or set volatile routes]])
+{ volatile_configure_set(proto_get_named($4, &proto_volatile), $5); } ;
+
+CF_CLI(CONFIGURE VOLATILE DEL, optsym prefix_autocorrect,
+ <name> <natwork>/<netmask>,
+ [[Delete volatile routes]])
+{ volatile_configure_del(proto_get_named($4, &proto_volatile), $5); } ;
+
+CF_CLI(CONFIGURE VOLATILE CLEAR, optsym,
+ <name>,
+ [[Clear volatile routes]])
+{ volatile_configure_clear(proto_get_named($4, &proto_volatile)); } ;
+
+CF_CLI(SHOW VOLATILE, optsym,
+ <name>,
+ [[Show volatile routes]])
+{ volatile_show(proto_get_named($3, &proto_volatile)); } ;
+
+CF_CODE
+
+CF_END
diff --git a/proto/volatile/volatile.c b/proto/volatile/volatile.c
new file mode 100644
index 0000000..80518b9
--- /dev/null
+++ b/proto/volatile/volatile.c
@@ -0,0 +1,195 @@
+/*
+ * BIRD -- Volatile Route Generator
+ *
+ * (c) 2013--2013 Thierry FOURNIER <tfournier at exceliance.fr>
+ *
+ * Can be freely distributed and used under the terms of the GNU GPL.
+ */
+
+/**
+ * DOC: Volatile
+ *
+ * The volatile protocol take routes from the cli. These routes are annouced
+ * to the peers. These routes cannot be exists on the host or cannot correspond
+ * to any ip address on any interface.
+ *
+ * This type of announce is useful for services using transparent binding.
+ * The transparent binding is used tipically with proxy for proxifying HTTP
+ * connections. The user add route announcement and the destination is rerouted
+ * to the transparent proxy.
+ */
+
+#include "nest/bird.h"
+#include "nest/iface.h"
+#include "nest/protocol.h"
+#include "nest/route.h"
+#include "nest/cli.h"
+#include "conf/conf.h"
+#include "lib/string.h"
+#include "lib/alloca.h"
+
+#include "volatile.h"
+
+struct iface any = {
+ .name = "auto"
+};
+
+static void
+volatile_install(struct volatile_proto *p, ip_addr net, unsigned int masklen)
+{
+ struct network *network;
+ struct rta route_attr_lookup;
+ struct rta *route_attr;
+ struct rte *route;
+ struct neighbor *neigh;
+ struct iface *iface;
+
+ /* find neighbor for the gateway */
+ if (p->cf->use_gateway) {
+ neigh = neigh_find(&p->p, &p->cf->gateway, NEF_STICKY);
+ if (!neigh || !neigh->iface) {
+ log(L_INFO "Cannot find neighbor for the gateway %I", p->cf->gateway);
+ return;
+ }
+ iface = neigh->iface;
+ }
+
+ else
+ iface = &any;
+
+ /* prepare route attrinutes lookup */
+ bzero(&route_attr_lookup, sizeof(struct rta));
+ route_attr_lookup.proto = &p->p;
+ route_attr_lookup.scope = SCOPE_UNIVERSE;
+ route_attr_lookup.cast = RTC_UNICAST;
+ route_attr_lookup.iface = iface;
+ if (p->cf->use_gateway) {
+ route_attr_lookup.gw = p->cf->gateway;
+ route_attr_lookup.source = RTS_STATIC;
+ route_attr_lookup.dest = RTD_ROUTER;
+ }
+ else {
+ route_attr_lookup.source = RTS_DEVICE;
+ route_attr_lookup.dest = RTD_DEVICE;
+ }
+
+ /* lookup or add route attribute entry. This call never fail */
+ route_attr = rta_lookup(&route_attr_lookup);
+
+ /* get network entry into the table. This function never fail */
+ network = net_get(p->p.table, net, masklen);
+
+ /* get temporary route, and set attributes */
+ route = rte_get_temp(route_attr);
+ route->net = network;
+ route->pflags = 0;
+
+ /* update the route */
+ rte_update(p->p.table, network, &p->p, &p->p, route);
+}
+
+static void
+volatile_remove(struct volatile_proto *p, ip_addr net, unsigned int masklen)
+{
+ struct network *network;
+
+ /* lookup for network entry. if found remove it */
+ network = net_find(p->p.table, net, masklen);
+ if (network)
+ rte_update(p->p.table, network, &p->p, &p->p, NULL);
+}
+
+/* this function initialize configuration structs */
+static struct proto *
+volatile_init(struct proto_config *C)
+{
+ struct volatile_config *c = (struct volatile_config *) C;
+ struct proto *P = proto_new(C, sizeof(struct volatile_proto));
+ struct volatile_proto *p = (struct volatile_proto *) P;
+
+ p->cf = c;
+ return P;
+}
+
+struct protocol proto_volatile = {
+ name: "Volatile",
+ template: "volatile%d",
+ init: volatile_init,
+};
+
+/* this fucntion install new route */
+void
+volatile_configure_set(struct proto *P, struct prefix net)
+{
+ struct volatile_proto *p = (struct volatile_proto *) P;
+
+ volatile_install(p, net.addr, net.len);
+ cli_msg(0, "");
+}
+
+/* this fucntion delete known route */
+void
+volatile_configure_del(struct proto *P, struct prefix net)
+{
+ struct volatile_proto *p = (struct volatile_proto *) P;
+
+ volatile_remove(p, net.addr, net.len);
+ cli_msg(0, "");
+}
+
+/* this cli function delete all route with restarting protocol */
+void
+volatile_configure_clear(struct proto *P)
+{
+ proto_cmd_restart(P, 0, 0);
+ cli_msg(0, "");
+}
+
+void
+volatile_show(struct proto *P)
+{
+ struct volatile_proto *p = (struct volatile_proto *) P;
+ struct rte *route;
+ struct rta *attrs;
+ struct network *network;
+
+ FIB_WALK(&p->p.table->fib, fn) {
+ network = (struct network *)fn;
+ for (route = network->routes;
+ route;
+ route = route->next) {
+
+ if (route->attrs->proto != P)
+ continue;
+
+ network = route->net;
+ attrs = route->attrs;
+
+ if (!network) {
+ cli_msg(-1009, "???");
+ continue;
+ }
+
+ switch (attrs->dest) {
+
+ case RTD_ROUTER:
+ cli_msg(-1009, "%I/%2d via %I dev %s",
+ network->n.prefix, network->n.pxlen, attrs->gw,
+ attrs->iface ? attrs->iface->name : "???");
+ break;
+
+ case RTD_DEVICE:
+ cli_msg(-1009, "%I/%2d dev auto",
+ network->n.prefix, network->n.pxlen);
+ break;
+
+ default:
+ cli_msg(-1009, "%I/%2d ???",
+ network->n.prefix, network->n.pxlen);
+ break;
+ }
+ }
+ } FIB_WALK_END;
+
+ cli_msg(0, "");
+}
diff --git a/proto/volatile/volatile.h b/proto/volatile/volatile.h
new file mode 100644
index 0000000..fd43873
--- /dev/null
+++ b/proto/volatile/volatile.h
@@ -0,0 +1,46 @@
+/*
+ * BIRD -- Volatile Route Generator
+ *
+ * (c) 2013--2013 Thierry FOURNIER <tfournier at exceliance.fr>
+ *
+ * Can be freely distributed and used under the terms of the GNU GPL.
+ */
+
+#ifndef _BIRD_VOLATILE_H_
+#define _BIRD_VOLATILE_H_
+
+struct volatile_config {
+ struct proto_config c;
+ int use_gateway;
+ ip_addr gateway;
+};
+
+struct volatile_proto {
+ struct proto p;
+ struct volatile_config *cf; /* Shortcut to volatile configuration */
+};
+
+void volatile_init_config(struct volatile_config *);
+
+struct volatile_route {
+ node n;
+ struct volatile_route *chain; /* Next for the same neighbor */
+ ip_addr net; /* Network we route */
+ int masklen; /* Mask length */
+ int dest; /* Destination type (RTD_*) */
+ ip_addr via; /* Destination router */
+ struct neighbor *neigh;
+ byte *if_name; /* Name for RTD_DEVICE routes */
+ struct volatile_route *mp_next; /* Nexthops for RTD_MULTIPATH routes */
+ int installed; /* Installed in master table */
+};
+
+/* Dummy nodes (parts of multipath route) abuses masklen field for weight
+ and if_name field for a ptr to the master (RTD_MULTIPATH) node. */
+
+void volatile_configure_set(struct proto *P, struct prefix net);
+void volatile_configure_del(struct proto *P, struct prefix net);
+void volatile_configure_clear(struct proto *P);
+void volatile_show(struct proto *P);
+
+#endif
--
1.8.1.1
--Multipart=_Tue__24_Sep_2013_16_35_48_+0200_AMU0Imo+Flc+Ayzu--
More information about the Bird-users
mailing list