Commit f4a60a9b authored by Ondřej Zajíček's avatar Ondřej Zajíček Committed by Jan Moskyto Matejka

Channels - explicit links between protocols and tables

The patch adds support for channels, structures connecting protocols and
tables and handling most interactions between them. The documentation is
missing yet.
parent 9f5782d9
......@@ -136,12 +136,14 @@ config_parse(struct config *c)
protos_preconfig(c);
rt_preconfig(c);
cf_parse();
protos_postconfig(c);
if (EMPTY_LIST(c->protos))
cf_error("No protocol is specified in the config file");
/* XXXX */
/*
if (!c->router_id)
cf_error("Router ID must be configured manually");
*/
done = 1;
......
......@@ -24,7 +24,7 @@ struct config {
int mrtdump_file; /* Configured MRTDump file (sysdep, fd in unix) */
char *syslog_name; /* Name used for syslog (NULL -> no syslog) */
struct rtable_config *master_rtc; /* Configuration of master routing table */
struct rtable_config *def_tables[NET_MAX]; /* Default routing tables for each network */
struct iface_patt *router_id_from; /* Configured list of router ID iface patterns */
u32 router_id; /* Our Router ID */
......
......@@ -46,6 +46,7 @@ CF_DECLS
struct symbol *s;
char *t;
struct rtable_config *r;
struct channel_config *cc;
struct f_inst *x;
struct filter *f;
struct f_tree *e;
......@@ -61,6 +62,7 @@ CF_DECLS
bird_clock_t time;
struct f_prefix px;
struct proto_spec ps;
struct channel_limit cl;
struct timeformat *tf;
}
......
......@@ -34,6 +34,7 @@
#define ABS(a) ((a)>=0 ? (a) : -(a))
#define DELTA(a,b) (((a)>=(b))?(a)-(b):(b)-(a))
#define ARRAY_SIZE(a) (sizeof(a)/sizeof(*(a)))
#define CALL(fn, args...) ({ if (fn) fn(args); })
static inline int uint_cmp(uint i1, uint i2)
{ return (int)(i1 > i2) - (int)(i1 < i2); }
......
......@@ -39,7 +39,10 @@ typedef struct list { /* In fact two overlayed nodes */
#define WALK_LIST2(n,nn,list,pos) \
for(nn=(list).head; NODE_VALID(nn) && (n=SKIP_BACK(typeof(*n),pos,nn)); nn=nn->next)
#define WALK_LIST_DELSAFE(n,nxt,list) \
for(n=HEAD(list); nxt=NODE_NEXT(n); n=(void *) nxt)
for(n=HEAD(list); nxt=NODE_NEXT(n); n=(void *) nxt)
#define WALK_LIST2_DELSAFE(n,nn,nxt,list,pos) \
for(nn=HEAD(list); (nxt=nn->next) && (n=SKIP_BACK(typeof(*n),pos,nn)); nn=nxt)
/* WALK_LIST_FIRST supposes that called code removes each processed node */
#define WALK_LIST_FIRST(n,list) \
while(n=HEAD(list), (NODE (n))->next)
......
......@@ -4,6 +4,13 @@
#include "lib/net.h"
const char * const net_label[] = {
[NET_IP4] = "ipv4",
[NET_IP6] = "ipv6",
[NET_VPN4] = "vpn4",
[NET_VPN6] = "vpn6"
};
const u16 net_addr_length[] = {
[NET_IP4] = sizeof(net_addr_ip4),
[NET_IP6] = sizeof(net_addr_ip6),
......
......@@ -21,6 +21,15 @@
#define NET_ROA6 6
#define NET_MAX 7
#define NB_IP4 (1 << NET_IP4)
#define NB_IP6 (1 << NET_IP6)
#define NB_VPN4 (1 << NET_VPN4)
#define NB_VPN6 (1 << NET_VPN6)
#define NB_IP (NB_IP4 | NB_IP6)
#define NB_ANY 0xffffffff
typedef struct net_addr {
u8 type;
u8 pxlen;
......@@ -88,6 +97,7 @@ typedef union net_addr_union {
} net_addr_union;
extern const char * const net_label[];
extern const u16 net_addr_length[];
extern const u8 net_max_prefix_length[];
extern const u16 net_max_text_length[];
......@@ -149,6 +159,13 @@ static inline void net_fill_ip_host(net_addr *a, ip_addr prefix)
net_fill_ip6(a, ipa_to_ip6(prefix), IP6_MAX_PREFIX_LENGTH);
}
static inline int net_val_match(u8 type, u32 mask)
{ return !!((1 << type) & mask); }
static inline int net_type_match(const net_addr *a, u32 mask)
{ return net_val_match(a->type, mask); }
static inline int net_is_ip(const net_addr *a)
{ return (a->type == NET_IP4) || (a->type == NET_IP6); }
......
......@@ -17,6 +17,7 @@ CF_HDR
CF_DEFINES
static struct proto_config *this_proto;
static struct channel_config *this_channel;
static struct iface_patt *this_ipatt;
static struct iface_patt_node *this_ipn;
/* static struct roa_table_config *this_roa_table; */
......@@ -49,6 +50,15 @@ get_passwords(void)
return rv;
}
static void
proto_postconfig(void)
{
CALL(this_proto->protocol->postconfig, this_proto);
this_channel = NULL;
this_proto = NULL;
}
#define DIRECT_CFG ((struct rt_dev_config *) this_proto)
CF_DECLS
......@@ -76,9 +86,10 @@ CF_ENUM(T_ENUM_ROA, ROA_, UNKNOWN, VALID, INVALID)
%type <s> optsym
%type <ra> r_args
%type <sd> sym_args
%type <i> proto_start echo_mask echo_size debug_mask debug_list debug_flag mrtdump_mask mrtdump_list mrtdump_flag export_mode limit_action table_type table_sorted tos
%type <i> proto_start echo_mask echo_size debug_mask debug_list debug_flag mrtdump_mask mrtdump_list mrtdump_flag export_mode limit_action net_type table_sorted tos
%type <ps> proto_patt proto_patt2
%type <g> limit_spec
%type <cc> channel_start proto_channel
%type <cl> limit_spec
CF_GRAMMAR
......@@ -115,7 +126,7 @@ listen_opts:
| listen_opts listen_opt
;
listen_opt:
listen_opt:
ADDRESS ipa { new_config->listen_bgp_addr = $2; }
| PORT expr { new_config->listen_bgp_port = $2; }
| V6ONLY { new_config->listen_bgp_flags = 0; }
......@@ -128,13 +139,10 @@ CF_ADDTO(conf, gr_opts)
gr_opts: GRACEFUL RESTART WAIT expr ';' { new_config->gr_wait = $4; } ;
/* Creation of routing tables */
/* Network types (for tables, channels) */
CF_ADDTO(conf, table)
table_type:
/* empty */ { $$ = NET_IP4; }
| IPV4 { $$ = NET_IP4; }
net_type:
IPV4 { $$ = NET_IP4; }
| IPV6 { $$ = NET_IP6; }
| VPN4 { $$ = NET_VPN4; }
| VPN6 { $$ = NET_VPN6; }
......@@ -142,21 +150,27 @@ table_type:
| ROA6 { $$ = NET_ROA6; }
;
/* Creation of routing tables */
CF_ADDTO(conf, table)
table_sorted:
{ $$ = 0; }
| SORTED { $$ = 1; }
;
table: table_type TABLE SYM table_sorted {
table: net_type TABLE SYM table_sorted {
struct rtable_config *cf;
cf = rt_new_table($3, $1);
cf->sorted = $4;
}
;
/* Definition of protocols */
CF_ADDTO(conf, proto)
CF_ADDTO(conf, proto { proto_postconfig(); })
proto_start:
PROTOCOL { $$ = SYM_PROTO; }
......@@ -194,24 +208,62 @@ proto_name:
proto_item:
/* EMPTY */
| PREFERENCE expr {
if ($2 < 0 || $2 > 0xFFFF) cf_error("Invalid preference");
this_proto->preference = $2;
}
| DISABLED bool { this_proto->disabled = $2; }
| DEBUG debug_mask { this_proto->debug = $2; }
| MRTDUMP mrtdump_mask { this_proto->mrtdump = $2; }
| IMPORT imexport { this_proto->in_filter = $2; }
| EXPORT imexport { this_proto->out_filter = $2; }
| RECEIVE LIMIT limit_spec { this_proto->rx_limit = $3; }
| IMPORT LIMIT limit_spec { this_proto->in_limit = $3; }
| EXPORT LIMIT limit_spec { this_proto->out_limit = $3; }
| IMPORT KEEP FILTERED bool { this_proto->in_keep_filtered = $4; }
| TABLE rtable { this_proto->table = $2; }
| ROUTER ID idval { this_proto->router_id = $3; }
| DESCRIPTION text { this_proto->dsc = $2; }
;
channel_start: net_type
{
$$ = this_channel = channel_config_new(NULL, $1, this_proto);
};
channel_item:
TABLE rtable {
if (this_channel->net_type && ($2->addr_type != this_channel->net_type))
cf_error("Incompatible table type");
this_channel->table = $2;
}
| IMPORT imexport { this_channel->in_filter = $2; }
| EXPORT imexport { this_channel->out_filter = $2; }
| RECEIVE LIMIT limit_spec { this_channel->rx_limit = $3; }
| IMPORT LIMIT limit_spec { this_channel->in_limit = $3; }
| EXPORT LIMIT limit_spec { this_channel->out_limit = $3; }
| PREFERENCE expr { this_channel->preference = $2; check_u16($2); }
| IMPORT KEEP FILTERED bool { this_channel->in_keep_filtered = $4; }
;
channel_opts:
/* empty */
| channel_opts channel_item ';'
;
channel_opt_list:
/* empty */
| '{' channel_opts '}'
;
channel_end:
{
if (!this_channel->table)
cf_error("Routing table not specified");
this_channel = NULL;
};
proto_channel: channel_start channel_opt_list channel_end;
rtable:
SYM {
if ($1->class != SYM_TABLE) cf_error("Table expected");
$$ = $1->def;
}
;
imexport:
FILTER filter { $$ = $2; }
| where_filter
......@@ -228,20 +280,8 @@ limit_action:
;
limit_spec:
expr limit_action {
struct proto_limit *l = cfg_allocz(sizeof(struct proto_limit));
l->limit = $1;
l->action = $2;
$$ = l;
}
| OFF { $$ = NULL; }
;
rtable:
SYM {
if ($1->class != SYM_TABLE) cf_error("Table name expected");
$$ = $1->def;
}
expr limit_action { $$ = (struct channel_limit){ .limit = $1, $$.action = $2 }; }
| OFF { $$ = (struct channel_limit){}; }
;
CF_ADDTO(conf, debug_default)
......@@ -315,6 +355,7 @@ dev_proto_start: proto_start DIRECT {
dev_proto:
dev_proto_start proto_name '{'
| dev_proto proto_item ';'
| dev_proto proto_channel ';'
| dev_proto dev_iface_patt ';'
;
......
......@@ -138,7 +138,7 @@ if_copy(struct iface *to, struct iface *from)
static inline void
ifa_send_notify(struct proto *p, unsigned c, struct ifa *a)
{
if (p->ifa_notify)
if (p->ifa_notify && (p->proto_state != PS_DOWN))
{
if (p->debug & D_IFACES)
log(L_TRACE "%s < %s address %N on interface %s %s",
......@@ -155,7 +155,7 @@ ifa_notify_change_(unsigned c, struct ifa *a)
DBG("IFA change notification (%x) for %s:%I\n", c, a->iface->name, a->ip);
WALK_LIST(p, active_proto_list)
WALK_LIST(p, proto_list)
ifa_send_notify(p, c, a);
}
......@@ -174,7 +174,7 @@ ifa_notify_change(unsigned c, struct ifa *a)
static inline void
if_send_notify(struct proto *p, unsigned c, struct iface *i)
{
if (p->if_notify)
if (p->if_notify && (p->proto_state != PS_DOWN))
{
if (p->debug & D_IFACES)
log(L_TRACE "%s < interface %s %s", p->name, i->name,
......@@ -215,7 +215,7 @@ if_notify_change(unsigned c, struct iface *i)
ifa_notify_change_(IF_CHANGE_DOWN, a);
}
WALK_LIST(p, active_proto_list)
WALK_LIST(p, proto_list)
if_send_notify(p, c, i);
if (c & IF_CHANGE_UP)
......
......@@ -239,7 +239,7 @@ neigh_up(neighbor *n, struct iface *i, int scope, struct ifa *a)
rem_node(&n->n);
add_tail(&neigh_hash_table[neigh_hash(n->proto, &n->addr)], &n->n);
DBG("Waking up sticky neighbor %I\n", n->addr);
if (n->proto->neigh_notify && n->proto->core_state != FS_FLUSHING)
if (n->proto->neigh_notify && (n->proto->proto_state != PS_STOP))
n->proto->neigh_notify(n);
}
......@@ -252,7 +252,7 @@ neigh_down(neighbor *n)
n->iface = NULL;
n->ifa = NULL;
n->scope = -1;
if (n->proto->neigh_notify && n->proto->core_state != FS_FLUSHING)
if (n->proto->neigh_notify && (n->proto->proto_state != PS_STOP))
n->proto->neigh_notify(n);
rem_node(&n->n);
if (n->flags & NEF_STICKY)
......@@ -333,7 +333,7 @@ neigh_if_link(struct iface *i)
WALK_LIST_DELSAFE(x, y, i->neighbors)
{
neighbor *n = SKIP_BACK(neighbor, if_n, x);
if (n->proto->neigh_notify && n->proto->core_state != FS_FLUSHING)
if (n->proto->neigh_notify && (n->proto->proto_state != PS_STOP))
n->proto->neigh_notify(n);
}
}
......
This diff is collapsed.
......@@ -69,23 +69,6 @@ its state by calling the <func/proto_notify_state/ function.
<p>At any time, the core code can ask the protocol to shut itself down by calling its stop() hook.
<p>The <em/core state machine/ takes care of the core view of protocol state.
The states are traversed according to changes of the protocol state machine, but
sometimes the transitions are delayed if the core needs to finish some actions
(for example sending of new routes to the protocol) before proceeding to the
new state. There are the following core states:
<descrip>
<tag/FS_HUNGRY/ The protocol is down, it doesn't have any routes and
doesn't want them.
<tag/FS_FEEDING/ The protocol has reached the <tt/PS_UP/ state, but
we are still busy sending the initial set of routes to it.
<tag/FS_HAPPY/ The protocol is up and has complete routing information.
<tag/FS_FLUSHING/ The protocol is shutting down (it's in either <tt/PS_STOP/
or <tt/PS_DOWN/ state) and we're flushing all of its routes from the
routing tables.
</descrip>
<sect1>Functions of the protocol module
<p>The protocol module provides the following functions:
This diff is collapsed.
......@@ -12,10 +12,12 @@
#include "lib/lists.h"
#include "lib/resource.h"
#include "lib/timer.h"
#include "nest/protocol.h"
//#include "nest/protocol.h"
struct ea_list;
struct protocol;
struct proto;
struct rte_src;
struct symbol;
struct filter;
struct cli;
......@@ -57,8 +59,8 @@ struct fib {
uint hash_order; /* Binary logarithm of hash_size */
uint hash_shift; /* 32 - hash_order */
uint addr_type; /* Type of address data stored in fib (NET_*) */
uint node_size; /* XXXX */
uint node_offset; /* XXXX */
uint node_size; /* FIB node size, 0 for nonuniform */
uint node_offset; /* Offset of fib_node struct inside of user data */
uint entries; /* Number of entries */
uint entries_min, entries_max; /* Entry count limits (else start rehashing) */
fib_init_fn init; /* Constructor */
......@@ -146,7 +148,7 @@ typedef struct rtable {
node n; /* Node in list of all tables */
struct fib fib;
char *name; /* Name of this table */
list hooks; /* List of announcement hooks */
list channels; /* List of attached channels (struct channel) */
uint addr_type; /* Type of address data stored in table (NET_*) */
int pipe_busy; /* Pipe loop detection */
int use_count; /* Number of protocols using this table */
......@@ -159,7 +161,6 @@ typedef struct rtable {
struct event *rt_event; /* Routing table event */
int gc_counter; /* Number of operations since last GC */
bird_clock_t gc_time; /* Time of last GC */
byte gc_scheduled; /* GC is scheduled */
byte prune_state; /* Table prune state, 1 -> scheduled, 2-> running */
byte hcu_scheduled; /* Hostcache update is scheduled */
byte nhu_state; /* Next Hop Update state */
......@@ -167,10 +168,6 @@ typedef struct rtable {
struct fib_iterator nhu_fit; /* Next Hop Update FIB iterator */
} rtable;
#define RPS_NONE 0
#define RPS_SCHEDULED 1
#define RPS_RUNNING 2
typedef struct network {
struct rte *routes; /* Available routes for this network */
struct fib_node n; /* FIB flags reserved for kernel syncer */
......@@ -206,7 +203,7 @@ struct hostentry {
typedef struct rte {
struct rte *next;
net *net; /* Network this RTE belongs to */
struct announce_hook *sender; /* Announce hook used to send the route to the routing table */
struct channel *sender; /* Channel used to send the route to the routing table */
struct rta *attrs; /* Attributes of this route */
byte flags; /* Flags (REF_...) */
byte pflags; /* Protocol-specific flags */
......@@ -279,13 +276,14 @@ static inline net *net_get(rtable *tab, const net_addr *addr) { return (net *) f
rte *rte_find(net *net, struct rte_src *src);
rte *rte_get_temp(struct rta *);
void rte_update2(struct announce_hook *ah, net *net, rte *new, struct rte_src *src);
static inline void rte_update(struct proto *p, net *net, rte *new) { rte_update2(p->main_ahook, net, new, p->main_source); }
void rte_update2(struct channel *c, net *net, rte *new, struct rte_src *src);
/* rte_update() moved to protocol.h to avoid dependency conflicts */
void rte_discard(rtable *tab, rte *old);
int rt_examine(rtable *t, net_addr *a, struct proto *p, struct filter *filter);
rte *rt_export_merged(struct announce_hook *ah, net *net, rte **rt_free, struct ea_list **tmpa, int silent);
void rt_refresh_begin(rtable *t, struct announce_hook *ah);
void rt_refresh_end(rtable *t, struct announce_hook *ah);
rte *rt_export_merged(struct channel *c, net *net, rte **rt_free, struct ea_list **tmpa, int silent);
void rt_refresh_begin(rtable *t, struct channel *c);
void rt_refresh_end(rtable *t, struct channel *c);
void rt_schedule_prune(rtable *t);
void rte_dump(rte *);
void rte_free(rte *);
rte *rte_do_cow(rte *);
......@@ -293,19 +291,10 @@ static inline rte * rte_cow(rte *r) { return (r->flags & REF_COW) ? rte_do_cow(r
rte *rte_cow_rta(rte *r, linpool *lp);
void rt_dump(rtable *);
void rt_dump_all(void);
int rt_feed_baby(struct proto *p);
void rt_feed_baby_abort(struct proto *p);
int rt_prune_loop(void);
int rt_feed_channel(struct channel *c);
void rt_feed_channel_abort(struct channel *c);
struct rtable_config *rt_new_table(struct symbol *s, uint addr_type);
static inline void
rt_mark_for_prune(rtable *tab)
{
if (tab->prune_state == RPS_RUNNING)
fit_get(&tab->fib, &tab->prune_fit);
tab->prune_state = RPS_SCHEDULED;
}
struct rt_show_data {
net_addr *addr;
......@@ -315,6 +304,7 @@ struct rt_show_data {
struct fib_iterator fit;
struct proto *show_protocol;
struct proto *export_protocol;
struct channel *export_channel;
int export_mode, primary_only, filtered;
struct config *running_on_config;
int net_counter, rt_counter, show_counter;
......@@ -561,7 +551,6 @@ extern struct protocol *attr_class_to_protocol[EAP_MAX];
#define DEF_PREF_OSPF 150 /* OSPF intra-area, inter-area and type 1 external routes */
#define DEF_PREF_RIP 120 /* RIP */
#define DEF_PREF_BGP 100 /* BGP */
#define DEF_PREF_PIPE 70 /* Routes piped from other tables */
#define DEF_PREF_INHERITED 10 /* Routes inherited from other routing daemons */
/*
......
......@@ -24,13 +24,16 @@
#include "lib/resource.h"
#include "lib/string.h"
static void
dev_ifa_notify(struct proto *p, unsigned c, struct ifa *ad)
dev_ifa_notify(struct proto *P, uint flags, struct ifa *ad)
{
struct rt_dev_config *P = (void *) p->cf;
struct rt_dev_proto *p = (void *) P;
struct rt_dev_config *cf = (void *) P->cf;
struct channel *c;
if (!EMPTY_LIST(P->iface_list) &&
!iface_patt_find(&P->iface_list, ad->iface, ad->iface->addr))
if (!EMPTY_LIST(cf->iface_list) &&
!iface_patt_find(&cf->iface_list, ad->iface, ad->iface->addr))
/* Empty list is automagically treated as "*" */
return;
......@@ -40,12 +43,22 @@ dev_ifa_notify(struct proto *p, unsigned c, struct ifa *ad)
if (ad->scope <= SCOPE_LINK)
return;
if (c & IF_CHANGE_DOWN)
if (ad->prefix.type == NET_IP4)
c = p->ip4_channel;
else if (ad->prefix.type == NET_IP6)
c = p->ip6_channel;
else
return;
if (!c)
return;
if (flags & IF_CHANGE_DOWN)
{
net *n;
DBG("dev_if_notify: %s:%I going down\n", ad->iface->name, ad->ip);
n = net_find(p->table, &ad->prefix);
n = net_find(c->table, &ad->prefix);
if (!n)
{
DBG("dev_if_notify: device shutdown: prefix not found\n");
......@@ -53,10 +66,10 @@ dev_ifa_notify(struct proto *p, unsigned c, struct ifa *ad)
}
/* Use iface ID as local source ID */
struct rte_src *src = rt_get_source(p, ad->iface->index);
rte_update2(p->main_ahook, n, NULL, src);
struct rte_src *src = rt_get_source(P, ad->iface->index);
rte_update2(c, n, NULL, src);
}
else if (c & IF_CHANGE_UP)
else if (flags & IF_CHANGE_UP)
{
rta *a;
net *n;
......@@ -65,7 +78,7 @@ dev_ifa_notify(struct proto *p, unsigned c, struct ifa *ad)
DBG("dev_if_notify: %s:%I going up\n", ad->iface->name, ad->ip);
/* Use iface ID as local source ID */
struct rte_src *src = rt_get_source(p, ad->iface->index);
struct rte_src *src = rt_get_source(P, ad->iface->index);
rta a0 = {
.src = src,
......@@ -77,37 +90,51 @@ dev_ifa_notify(struct proto *p, unsigned c, struct ifa *ad)
};
a = rta_lookup(&a0);
n = net_get(p->table, &ad->prefix);
n = net_get(c->table, &ad->prefix);
e = rte_get_temp(a);
e->net = n;
e->pflags = 0;
rte_update2(p->main_ahook, n, e, src);
rte_update2(c, n, e, src);
}
}
static struct proto *
dev_init(struct proto_config *c)
dev_init(struct proto_config *CF)
{
struct proto *p = proto_new(c, sizeof(struct proto));
struct proto *P = proto_new(CF);
struct rt_dev_proto *p = (void *) P;
// struct rt_dev_config *cf = (void *) CF;
p->ifa_notify = dev_ifa_notify;
return p;
proto_configure_channel(P, &p->ip4_channel, proto_cf_find_channel(CF, NET_IP4));
proto_configure_channel(P, &p->ip6_channel, proto_cf_find_channel(CF, NET_IP6));
P->ifa_notify = dev_ifa_notify;
return P;
}
static int
dev_reconfigure(struct proto *p, struct proto_config *new)
dev_reconfigure(struct proto *P, struct proto_config *CF)
{
struct rt_dev_config *o = (struct rt_dev_config *) p->cf;
struct rt_dev_config *n = (struct rt_dev_config *) new;
struct rt_dev_proto *p = (void *) P;
struct rt_dev_config *o = (void *) P->cf;
struct rt_dev_config *n = (void *) CF;
if (!iface_patts_equal(&o->iface_list, &n->iface_list, NULL))
return 0;
return
proto_configure_channel(P, &p->ip4_channel, proto_cf_find_channel(CF, NET_IP4)) &&
proto_configure_channel(P, &p->ip6_channel, proto_cf_find_channel(CF, NET_IP6));
return iface_patts_equal(&o->iface_list, &n->iface_list, NULL);
return 1;
}
static void
dev_copy_config(struct proto_config *dest, struct proto_config *src)
{
struct rt_dev_config *d = (struct rt_dev_config *) dest;
struct rt_dev_config *s = (struct rt_dev_config *) src;
struct rt_dev_config *d = (void *) dest;
struct rt_dev_config *s = (void *) src;
/*
* We copy iface_list as ifaces can be shared by more direct protocols.
......@@ -120,7 +147,9 @@ dev_copy_config(struct proto_config *dest, struct proto_config *src)
struct protocol proto_device = {
.name = "Direct",
.template = "direct%d",
.preference = DEF_PREF_DIRECT,
.preference = DEF_PREF_DIRECT,
.channel_mask = NB_IP,
.proto_size = sizeof(struct rt_dev_proto),
.config_size = sizeof(struct rt_dev_config),
.init = dev_init,
.reconfigure = dev_reconfigure,
......
......@@ -14,4 +14,10 @@ struct rt_dev_config {
list iface_list; /* list of struct iface_patt */
};
struct rt_dev_proto {
struct proto p;
struct channel *ip4_channel;
struct channel *ip6_channel;
};
#endif
This diff is collapsed.
......@@ -952,7 +952,7 @@ bfd_init_all(void)
static struct proto *
bfd_init(struct proto_config *c)
{
struct proto *p = proto_new(c, sizeof(struct bfd_proto));
struct proto *p = proto_new(c);
p->neigh_notify = bfd_neigh_notify;
......@@ -1118,6 +1118,7 @@ bfd_show_sessions(struct proto *P)
struct protocol proto_bfd = {
.name = "BFD",
.template = "bfd%d",
.proto_size = sizeof(struct bfd_proto),
.config_size = sizeof(struct bfd_config),
.init = bfd_init,
.start = bfd_start,
......
......@@ -1372,7 +1372,6 @@ static void
bgp_copy_config(struct proto_config *dest, struct proto_config *src)
{
/* Just a shallow copy */
proto_copy_rest(dest, src, sizeof(struct bgp_config));
}
......
......@@ -112,12 +112,6 @@ bgp_proto:
| bgp_proto CAPABILITIES bool ';' { BGP_CFG->capabilities = $3; }
| bgp_proto ADVERTISE IPV4 bool ';' { BGP_CFG->advertise_ipv4 = $4; }
| bgp_proto PASSWORD text ';' { BGP_CFG->password = $3; }
| bgp_proto ROUTE LIMIT expr ';' {
this_proto->in_limit = cfg_allocz(sizeof(struct proto_limit));
this_proto->in_limit->limit = $4;
this_proto->in_limit->action = PLA_RESTART;
log(L_WARN "%s: Route limit option is deprecated, use import limit", this_proto->name);
}
| bgp_proto PASSIVE bool ';' { BGP_CFG->passive = $3; }
| bgp_proto INTERPRET COMMUNITIES bool ';' { BGP_CFG->interpret_communities = $4; }
| bgp_proto SECONDARY bool ';' { BGP_CFG->secondary = $3; }
......
......@@ -68,6 +68,10 @@ ospf_proto_finish(void)
if (EMPTY_LIST(cf->area_list))
cf_error( "No configured areas in OSPF");
/* Define default channel */
if (EMPTY_LIST(this_proto->channels))
channel_config_new(NULL, this_proto->net_type, this_proto);
int areano = 0;
int backbone = 0;
int nssa = 0;
......@@ -84,7 +88,7 @@ ospf_proto_finish(void)
cf->abr = areano > 1;
/* Route export or NSSA translation (RFC 3101 3.1) */
cf->asbr = (this_proto->out_filter != FILTER_REJECT) || (nssa && cf->abr);
cf->asbr = (proto_cf_main_channel(this_proto)->out_filter != FILTER_REJECT) || (nssa && cf->abr);
if (cf->abr && !backbone)
{
......@@ -145,14 +149,16 @@ ospf_variant:
| OSPF3 { $$ = 0; }
;
ospf_proto_start: proto_start ospf_variant {
this_proto = proto_config_new(&proto_ospf, $1);
init_list(&OSPF_CFG->area_list);
init_list(&OSPF_CFG->vlink_list);
OSPF_CFG->tick = OSPF_DEFAULT_TICK;
OSPF_CFG->ospf2 = $2;
}
;
ospf_proto_start: proto_start ospf_variant
{
this_proto = proto_config_new(&proto_ospf, $1);