From 602aa1f26c6e516c83e8cdde64b1e0e917c99350 Mon Sep 17 00:00:00 2001 From: Thierry FOURNIER Date: Fri, 23 Aug 2013 14:46:09 +0200 Subject: [PATCH 3/3] ALOHA/HAPEE: PROTOCOL VOLATILE: protocol implementation This patch adds the main code of the protocol volatile. --- proto/volatile/Doc | 1 + proto/volatile/Makefile | 6 ++ proto/volatile/config.Y | 75 +++++++++++++++++ proto/volatile/volatile.c | 195 +++++++++++++++++++++++++++++++++++++++++++++ proto/volatile/volatile.h | 46 +++++++++++ 5 files changed, 323 insertions(+) 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/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 + * + * 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 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, + /, + [[Add or set volatile routes]]) +{ volatile_configure_set(proto_get_named($4, &proto_volatile), $5); } ; + +CF_CLI(CONFIGURE VOLATILE DEL, optsym prefix_autocorrect, + /, + [[Delete volatile routes]]) +{ volatile_configure_del(proto_get_named($4, &proto_volatile), $5); } ; + +CF_CLI(CONFIGURE VOLATILE CLEAR, optsym, + , + [[Clear volatile routes]]) +{ volatile_configure_clear(proto_get_named($4, &proto_volatile)); } ; + +CF_CLI(SHOW VOLATILE, optsym, + , + [[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..bd4b88c --- /dev/null +++ b/proto/volatile/volatile.c @@ -0,0 +1,195 @@ +/* + * BIRD -- Volatile Route Generator + * + * (c) 2013--2013 Thierry FOURNIER + * + * 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.src = p->p.main_source; + 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, network, 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, network, 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->src != p->p.main_source) + 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 + * + * 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.7.10.4