diff options
Diffstat (limited to 'proto')
-rw-r--r-- | proto/bgp/attrs.c | 31 | ||||
-rw-r--r-- | proto/bgp/bgp.c | 5 | ||||
-rw-r--r-- | proto/bgp/bgp.h | 1 | ||||
-rw-r--r-- | proto/bgp/config.Y | 3 |
4 files changed, 31 insertions, 9 deletions
diff --git a/proto/bgp/attrs.c b/proto/bgp/attrs.c index f7d7b788..1a75884e 100644 --- a/proto/bgp/attrs.c +++ b/proto/bgp/attrs.c @@ -6,9 +6,6 @@ * Can be freely distributed and used under the terms of the GNU GPL. */ -/* FIXME: Latest draft says that LOCAL_PREF is mandatory for iBGP */ -/* FIXME: Mandatory attributes may be missing in messages that don't contain NLRI */ - #define LOCAL_DEBUG #include <stdlib.h> @@ -352,7 +349,7 @@ bgp_get_bucket(struct bgp_proto *p, ea_list *old, ea_list *tmp, int originate) new = alloca(ea_scan(tmp)); ea_merge(tmp, new); t->next = NULL; - ea_sort(tmp); + ea_sort(new); /* Normalize attributes */ d = new->attrs; @@ -470,14 +467,14 @@ bgp_rt_notify(struct proto *P, net *n, rte *new, rte *old, ea_list *tmpa) static int bgp_create_attrs(struct bgp_proto *p, rte *e, ea_list **attrs, struct linpool *pool) { - ea_list *ea = lp_alloc(pool, sizeof(ea_list) + 3*sizeof(eattr)); + ea_list *ea = lp_alloc(pool, sizeof(ea_list) + 4*sizeof(eattr)); eattr *a = ea->attrs; rta *rta = e->attrs; ea->next = *attrs; *attrs = ea; ea->flags = EALF_SORTED; - ea->count = 3; + ea->count = 4; a->id = EA_CODE(EAP_BGP, BA_ORIGIN); a->flags = BAF_TRANSITIVE; @@ -502,7 +499,7 @@ bgp_create_attrs(struct bgp_proto *p, rte *e, ea_list **attrs, struct linpool *p a->u.ptr = lp_alloc(pool, sizeof(struct adata) + 4); a->u.ptr->length = 4; z = a->u.ptr->data; - z[0] = 2; /* AS_SEQUENCE */ + z[0] = AS_PATH_SEQUENCE; z[1] = 1; /* 1 AS */ put_u16(z+2, p->local_as); } @@ -519,6 +516,12 @@ bgp_create_attrs(struct bgp_proto *p, rte *e, ea_list **attrs, struct linpool *p *(ip_addr *)a->u.ptr->data = p->local_addr; else *(ip_addr *)a->u.ptr->data = e->attrs->gw; + a++; + + a->id = EA_CODE(EAP_BGP, BA_LOCAL_PREF); + a->flags = BAF_OPTIONAL; + a->type = EAF_TYPE_INT; + a->u.data = 0; return 0; /* Leave decision to the filters */ } @@ -822,6 +825,20 @@ bgp_decode_attrs(struct bgp_conn *conn, byte *attr, unsigned int len, struct lin return NULL; } + /* If there's no local preference, define one */ + if (!(seen[0] && (1 << BA_LOCAL_PREF))) + { + ea = lp_alloc(pool, sizeof(ea_list) + sizeof(eattr)); + ea->next = a->eattrs; + a->eattrs = ea; + ea->flags = 0; + ea->count = 1; + ea->attrs[0].id = EA_CODE(EAP_BGP, BA_LOCAL_PREF); + ea->attrs[0].flags = BAF_OPTIONAL; + ea->attrs[0].type = EAF_TYPE_INT; + ea->attrs[0].u.data = 0; + } + /* Fill in the remaining rta fields */ e = ea_find(a->eattrs, EA_CODE(EAP_BGP, BA_NEXT_HOP)); ASSERT(e); diff --git a/proto/bgp/bgp.c b/proto/bgp/bgp.c index 933ced83..27ade8ed 100644 --- a/proto/bgp/bgp.c +++ b/proto/bgp/bgp.c @@ -210,7 +210,10 @@ bgp_connect(struct bgp_proto *p) /* Enter Connect state and start establishing c DBG("BGP: Connecting\n"); s = sk_new(p->p.pool); s->type = SK_TCP_ACTIVE; - s->saddr = p->local_addr; + if (ipa_nonzero(p->cf->source_addr)) + s->saddr = p->cf->source_addr; + else + s->saddr = p->local_addr; s->daddr = p->cf->remote_ip; s->dport = BGP_PORT; bgp_setup_sk(p, conn, s); diff --git a/proto/bgp/bgp.h b/proto/bgp/bgp.h index b8e1abcf..2e22111d 100644 --- a/proto/bgp/bgp.h +++ b/proto/bgp/bgp.h @@ -20,6 +20,7 @@ struct bgp_config { ip_addr remote_ip; int multihop; /* Number of hops if multihop */ ip_addr multihop_via; /* Multihop: address to route to */ + ip_addr source_addr; /* Source address to use */ int next_hop_self; /* Always set next hop to local IP address */ int compare_path_lengths; /* Use path lengths when selecting best route */ u32 default_local_pref; /* Default value for LOCAL_PREF attribute */ diff --git a/proto/bgp/config.Y b/proto/bgp/config.Y index 37f90aaf..36356c50 100644 --- a/proto/bgp/config.Y +++ b/proto/bgp/config.Y @@ -17,7 +17,7 @@ CF_DECLS CF_KEYWORDS(BGP, LOCAL, NEIGHBOR, AS, HOLD, TIME, CONNECT, RETRY, KEEPALIVE, MULTIHOP, STARTUP, VIA, NEXT, HOP, SELF, DEFAULT, PATH, METRIC, BGP_PATH, BGP_LOCAL_PREF, BGP_MED, BGP_ORIGIN, BGP_NEXT_HOP, - BGP_ATOMIC_AGGR, BGP_AGGREGATOR, BGP_COMMUNITY) + BGP_ATOMIC_AGGR, BGP_AGGREGATOR, BGP_COMMUNITY, SOURCE, ADDRESS) CF_GRAMMAR @@ -55,6 +55,7 @@ bgp_proto: | bgp_proto PATH METRIC NUM ';' { BGP_CFG->compare_path_lengths = $4; } | bgp_proto DEFAULT BGP_MED NUM ';' { BGP_CFG->default_med = $4; } | bgp_proto DEFAULT BGP_LOCAL_PREF NUM ';' { BGP_CFG->default_local_pref = $4; } + | bgp_proto SOURCE ADDRESS IPA ';' { BGP_CFG->source_addr = $4; } ; CF_ADDTO(dynamic_attr, BGP_PATH |