Commit 4847a894 authored by Ondřej Zajíček's avatar Ondřej Zajíček

Implementation of route reflection for BGP

parent d51aa281
......@@ -11,6 +11,7 @@
#include "lib/resource.h"
#include "lib/ip.h"
#include "nest/route.h"
#include "nest/attrs.h"
struct f_inst { /* Instruction */
......
......@@ -40,10 +40,12 @@ int_set_format(struct adata *set, byte *buf, unsigned int size)
struct adata *
int_set_add(struct linpool *pool, struct adata *list, u32 val)
{
struct adata *res = lp_alloc(pool, list->length + sizeof(struct adata) + 4);
res->length = list->length+4;
int len = list ? list->length : 0;
struct adata *res = lp_alloc(pool, len + sizeof(struct adata) + 4);
res->length = len + 4;
* (u32 *) res->data = val;
memcpy((char *) res->data + 4, list->data, list->length);
if (list)
memcpy((char *) res->data + 4, list->data, list->length);
return res;
}
......
......@@ -47,4 +47,7 @@ struct adata *int_set_add(struct linpool *pool, struct adata *list, u32 val);
int int_set_contains(struct adata *list, u32 val);
struct adata *int_set_del(struct linpool *pool, struct adata *list, u32 val);
static inline int int_set_get_size(struct adata *list)
{ return list->length / 4; }
#endif
This diff is collapsed.
......@@ -485,6 +485,13 @@ bgp_start_locked(struct object_lock *lock)
p->local_id = cf->c.global->router_id;
p->next_hop = cf->multihop ? cf->multihop_via : cf->remote_ip;
p->neigh = neigh_find(&p->p, &p->next_hop, NEF_STICKY);
if (cf->rr_client)
{
p->rr_cluster_id = cf->rr_cluster_id ? cf->rr_cluster_id : p->local_id;
p->rr_client = cf->rr_client;
}
if (!p->neigh)
{
log(L_ERR "%s: Invalid next hop %I", p->p.name, p->next_hop);
......@@ -633,6 +640,8 @@ bgp_check(struct bgp_config *c)
cf_error("Local AS number out of range");
if (!bgp_as4_support && (c->remote_as > 0xFFFF))
cf_error("Neighbor AS number out of range");
if ((c->local_as != c->remote_as) && (c->rr_client))
cf_error("Only internal neighbor can be RR client");
}
static void
......
......@@ -25,6 +25,8 @@ struct bgp_config {
int compare_path_lengths; /* Use path lengths when selecting best route */
u32 default_local_pref; /* Default value for LOCAL_PREF attribute */
u32 default_med; /* Default value for MULTI_EXIT_DISC attribute */
u32 rr_cluster_id; /* Route reflector cluster ID, if different from local ID */
int rr_client; /* Whether neighbor is RR client of me */
unsigned connect_retry_time;
unsigned hold_time, initial_hold_time;
unsigned keepalive_time;
......@@ -60,6 +62,8 @@ struct bgp_proto {
int as4_support; /* Peer supports 4B AS numbers [RFC4893] */
u32 local_id; /* BGP identifier of this router */
u32 remote_id; /* BGP identifier of the neighbor */
u32 rr_cluster_id; /* Route reflector cluster ID */
int rr_client; /* Whether neighbor is RR client of me */
struct bgp_conn *conn; /* Connection we have established */
struct bgp_conn outgoing_conn; /* Outgoing connection we're working with */
struct bgp_conn incoming_conn; /* Incoming connection we have neither accepted nor rejected yet */
......@@ -121,7 +125,8 @@ void bgp_close_conn(struct bgp_conn *c);
/* attrs.c */
byte *bgp_attach_attr(struct ea_list **to, struct linpool *, unsigned attr, unsigned val);
void bgp_attach_attr(struct ea_list **to, struct linpool *pool, unsigned attr, uintptr_t val);
byte *bgp_attach_attr_wa(struct ea_list **to, struct linpool *pool, unsigned attr, unsigned len);
struct rta *bgp_decode_attrs(struct bgp_conn *conn, byte *a, unsigned int len, struct linpool *pool, int mandatory);
int bgp_get_attr(struct eattr *e, byte *buf);
int bgp_rte_better(struct rte *, struct rte *);
......@@ -132,6 +137,9 @@ unsigned int bgp_encode_attrs(struct bgp_proto *p, byte *w, ea_list *attrs, int
void bgp_free_bucket(struct bgp_proto *p, struct bgp_bucket *buck);
void bgp_get_route_info(struct rte *, byte *buf, struct ea_list *attrs);
inline static void bgp_attach_attr_ip(struct ea_list **to, struct linpool *pool, unsigned attr, ip_addr a)
{ *(ip_addr *) bgp_attach_attr_wa(to, pool, attr, sizeof(ip_addr)) = a; }
/* packets.c */
void bgp_schedule_packet(struct bgp_conn *conn, int type);
......
......@@ -20,7 +20,8 @@ CF_KEYWORDS(BGP, LOCAL, NEIGHBOR, AS, HOLD, TIME, CONNECT, RETRY, KEEPALIVE,
MULTIHOP, STARTUP, VIA, NEXT, HOP, SELF, DEFAULT, PATH, METRIC,
ERROR, START, DELAY, FORGET, WAIT, DISABLE, AFTER,
BGP_PATH, BGP_LOCAL_PREF, BGP_MED, BGP_ORIGIN, BGP_NEXT_HOP,
BGP_ATOMIC_AGGR, BGP_AGGREGATOR, BGP_COMMUNITY, SOURCE, ADDRESS, PASSWORD)
BGP_ATOMIC_AGGR, BGP_AGGREGATOR, BGP_COMMUNITY, SOURCE, ADDRESS,
PASSWORD, RR, CLIENT, CLUSTER, ID)
CF_GRAMMAR
......@@ -38,7 +39,6 @@ bgp_proto_start: proto_start BGP {
BGP_CFG->error_amnesia_time = 300;
BGP_CFG->error_delay_time_min = 60;
BGP_CFG->error_delay_time_max = 300;
BGP_CFG->password = NULL;
}
;
......@@ -52,6 +52,8 @@ bgp_proto:
BGP_CFG->remote_ip = $3;
BGP_CFG->remote_as = $5;
}
| bgp_proto RR CLUSTER ID expr ';' { BGP_CFG->rr_cluster_id = $5; }
| bgp_proto RR CLIENT ';' { BGP_CFG->rr_client = 1; }
| bgp_proto HOLD TIME expr ';' { BGP_CFG->hold_time = $4; }
| bgp_proto STARTUP HOLD TIME expr ';' { BGP_CFG->initial_hold_time = $5; }
| bgp_proto CONNECT RETRY TIME expr ';' { BGP_CFG->connect_retry_time = $5; }
......
......@@ -193,7 +193,7 @@ bgp_create_update(struct bgp_conn *conn, byte *buf)
if ((buck = p->withdraw_bucket) && !EMPTY_LIST(buck->prefixes))
{
DBG("Withdrawn routes:\n");
tmp = bgp_attach_attr(&ea, bgp_linpool, BA_MP_UNREACH_NLRI, remains-8);
tmp = bgp_attach_attr_wa(&ea, bgp_linpool, BA_MP_UNREACH_NLRI, remains-8);
*tmp++ = 0;
*tmp++ = BGP_AF_IPV6;
*tmp++ = 1;
......@@ -218,7 +218,7 @@ bgp_create_update(struct bgp_conn *conn, byte *buf)
size = bgp_encode_attrs(p, w, buck->eattrs, 1024);
w += size;
remains -= size;
tstart = tmp = bgp_attach_attr(&ea, bgp_linpool, BA_MP_REACH_NLRI, remains-8);
tstart = tmp = bgp_attach_attr_wa(&ea, bgp_linpool, BA_MP_REACH_NLRI, remains-8);
*tmp++ = 0;
*tmp++ = BGP_AF_IPV6;
*tmp++ = 1;
......@@ -702,7 +702,7 @@ bgp_do_rx_update(struct bgp_conn *conn,
/* Create fake NEXT_HOP attribute */
if (len < 1 || (*x != 16 && *x != 32) || len < *x + 2)
goto bad;
memcpy(bgp_attach_attr(&a0->eattrs, bgp_linpool, BA_NEXT_HOP, 16), x+1, 16);
bgp_attach_attr_ip(&a0->eattrs, bgp_linpool, BA_NEXT_HOP, x[1]);
len -= *x + 2;
x += *x + 1;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment