From 789772ed4586213d6a7fbb867b9296a01ce1b9c0 Mon Sep 17 00:00:00 2001 From: Ondrej Zajicek Date: Thu, 18 Jun 2009 19:20:07 +0200 Subject: Implements option that changes BGP listening socket parametres. --- conf/conf.c | 6 ++++++ conf/conf.h | 3 +++ lib/socket.h | 7 +++++++ nest/config.Y | 18 ++++++++++++++++++ proto/bgp/bgp.c | 11 +++++++---- sysdep/unix/io.c | 8 +++++++- 6 files changed, 48 insertions(+), 5 deletions(-) diff --git a/conf/conf.c b/conf/conf.c index fefcac51..71e81b5c 100644 --- a/conf/conf.c +++ b/conf/conf.c @@ -175,6 +175,12 @@ global_commit(struct config *new, struct config *old) { if (!old) return 0; + + if (!ipa_equal(old->bind_bgp_addr, new->bind_bgp_addr) || + (old->bind_bgp_port != new->bind_bgp_port) || + (old->bind_bgp_flags != new->bind_bgp_flags)) + log(L_WARN "Reconfiguration of BGP listening socket not implemented, please restart BIRD."); + if (!new->router_id) new->router_id = old->router_id; if (new->router_id != old->router_id) diff --git a/conf/conf.h b/conf/conf.h index 17b975b3..ef27f3f4 100644 --- a/conf/conf.h +++ b/conf/conf.h @@ -22,6 +22,9 @@ struct config { list logfiles; /* Configured log fils (sysdep) */ struct rtable_config *master_rtc; /* Configuration of master routing table */ u32 router_id; /* Our Router ID */ + ip_addr bind_bgp_addr; /* Listening BGP socket should use this address */ + unsigned bind_bgp_port; /* Listening BGP socket should use this port (0 is default) */ + u32 bind_bgp_flags; /* Listening BGP socket should use these flags */ unsigned int proto_default_debug; /* Default protocol debug mask */ int cli_debug; /* Tracing of CLI connections and commands */ char *err_msg; /* Parser error message */ diff --git a/lib/socket.h b/lib/socket.h index 5fe91931..f1922607 100644 --- a/lib/socket.h +++ b/lib/socket.h @@ -20,6 +20,7 @@ typedef struct birdsock { unsigned sport, dport; /* 0 = unspecified (for IP: protocol type) */ int tos; /* TOS and priority, -1 = default */ int ttl; /* Time To Live, -1 = default */ + u32 flags; struct iface *iface; /* Interface; specify this for broad/multicast sockets */ byte *rbuf, *rpos; /* NULL=allocate automatically */ @@ -57,6 +58,12 @@ sk_send_buffer_empty(sock *sk) return sk->tbuf == sk->tpos; } + +/* Socket flags */ + +#define SKF_V6ONLY 1 /* Use IPV6_V6ONLY socket option */ + + /* * Socket types SA SP DA DP IF TTL SendTo (?=may, -=must not, *=must) */ diff --git a/nest/config.Y b/nest/config.Y index 3c6eb7b5..b3dfdf2a 100644 --- a/nest/config.Y +++ b/nest/config.Y @@ -44,6 +44,7 @@ CF_KEYWORDS(ROUTER, ID, PROTOCOL, PREFERENCE, DISABLED, DEBUG, ALL, OFF, DIRECT) CF_KEYWORDS(INTERFACE, IMPORT, EXPORT, FILTER, NONE, TABLE, STATES, ROUTES, FILTERS) CF_KEYWORDS(PASSWORD, FROM, PASSIVE, TO, ID, EVENTS, PACKETS, PROTOCOLS, INTERFACES) CF_KEYWORDS(PRIMARY, STATS, COUNT, FOR, COMMANDS, PREEXPORT, GENERATE) +CF_KEYWORDS(BIND, BGP, V6ONLY, ADDRESS, PORT) CF_ENUM(T_ENUM_RTS, RTS_, DUMMY, STATIC, INHERIT, DEVICE, STATIC_DEVICE, REDIRECT, RIP, OSPF, OSPF_IA, OSPF_EXT1, OSPF_EXT2, BGP, PIPE) @@ -82,6 +83,23 @@ idval: } ; + +CF_ADDTO(conf, bind) + +bind: BIND BGP bind_opts ';' ; + +bind_opts: + /* Nothing */ + | bind_opts bind_opt + ; + +bind_opt: + ADDRESS ipa { new_config->bind_bgp_addr = $2; } + | PORT expr { new_config->bind_bgp_port = $2; } + | V6ONLY { new_config->bind_bgp_flags |= SKF_V6ONLY; } + ; + + /* Creation of routing tables */ CF_ADDTO(conf, newtab) diff --git a/proto/bgp/bgp.c b/proto/bgp/bgp.c index 3b597dcf..2476c660 100644 --- a/proto/bgp/bgp.c +++ b/proto/bgp/bgp.c @@ -74,7 +74,7 @@ static int bgp_counter; /* Number of protocol instances using the listening so static void bgp_close(struct bgp_proto *p, int apply_md5); static void bgp_connect(struct bgp_proto *p); static void bgp_active(struct bgp_proto *p); -static sock *bgp_setup_listen_sk(void); +static sock *bgp_setup_listen_sk(ip_addr addr, unsigned port, u32 flags); /** @@ -90,10 +90,11 @@ static sock *bgp_setup_listen_sk(void); static int bgp_open(struct bgp_proto *p) { + struct config *cfg = p->cf->c.global; bgp_counter++; if (!bgp_listen_sk) - bgp_listen_sk = bgp_setup_listen_sk(); + bgp_listen_sk = bgp_setup_listen_sk(cfg->bind_bgp_addr, cfg->bind_bgp_port, cfg->bind_bgp_flags); if (!bgp_linpool) bgp_linpool = lp_new(&root_pool, 4080); @@ -587,12 +588,14 @@ bgp_incoming_connection(sock *sk, int dummy UNUSED) } static sock * -bgp_setup_listen_sk(void) +bgp_setup_listen_sk(ip_addr addr, unsigned port, u32 flags) { sock *s = sk_new(&root_pool); DBG("BGP: Creating incoming socket\n"); s->type = SK_TCP_PASSIVE; - s->sport = BGP_PORT; + s->saddr = addr; + s->sport = port ? port : BGP_PORT; + s->flags = flags; s->tos = IP_PREC_INTERNET_CONTROL; s->rbsize = BGP_RX_BUFFER_SIZE; s->tbsize = BGP_TX_BUFFER_SIZE; diff --git a/sysdep/unix/io.c b/sysdep/unix/io.c index 50992fb4..58aed4ee 100644 --- a/sysdep/unix/io.c +++ b/sysdep/unix/io.c @@ -703,7 +703,13 @@ sk_setup(sock *s) if ((s->tos >= 0) && setsockopt(fd, SOL_IP, IP_TOS, &s->tos, sizeof(s->tos)) < 0) WARN("IP_TOS"); #endif - + +#ifdef IPV6 + int v = 1; + if ((s->flags & SKF_V6ONLY) && setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, &v, sizeof(v)) < 0) + WARN("IPV6_V6ONLY"); +#endif + if (s->ttl >= 0) err = sk_set_ttl_int(s); else -- cgit v1.2.3