bgp_open(struct bgp_proto *p)
{
/* Interface-patterned listening sockets are created from the
- * interface notifier. By default, listen to nothing. */
- if (p->cf->ipatt)
+ * interface notifier. By default, listen to nothing.
+ *
+ * Also dynamically spawned protocol do not need a listening socket,
+ * they already have their parent's one. */
+ if (p->cf->ipatt || p->cf->c.parent)
return 0;
/* We assume that cf->iface is defined iff cf->local_ip is link-local */
req->params = (struct bgp_socket_params) {
.iface = p->cf->strict_bind ? p->cf->iface : NULL,
.vrf = p->p.vrf,
- .addr = p->cf->strict_bind ? p->cf->local_ip :
+ .addr = p->cf->strict_bind && ipa_nonzero(p->cf->local_ip) ? p->cf->local_ip :
(p->ipv4 ? IPA_NONE4 : IPA_NONE6),
.port = p->cf->local_port,
.flags = p->cf->free_bind ? SKF_FREEBIND : 0,
/* Just pass remote_ip to bgp_init() */
struct bgp_config *cf = SKIP_BACK(struct bgp_config, c, sym->proto);
cf->remote_ip = sk->daddr;
+ cf->local_ip = sk->saddr;
cf->iface = sk->iface;
+ cf->ipatt = NULL;
struct bgp_proto *p = SKIP_BACK(struct bgp_proto, p, proto_spawn(sym->proto, 0));
p->postponed_sk = sk;
struct bgp_socket_params params = {
.iface = i,
.vrf = p->p.vrf,
- .addr = p->cf->local_ip,
+ .addr = ipa_nonzero(p->cf->local_ip) ? p->cf->local_ip : (p->ipv4 ? IPA_NONE4 : IPA_NONE6),
.port = p->cf->local_port,
.flags = p->cf->free_bind ? SKF_FREEBIND : 0,
};
p->rs_client = cf->rs_client;
p->rr_client = cf->rr_client;
- p->ipv4 = ipa_nonzero(cf->remote_ip) ?
- ipa_is_ip4(cf->remote_ip) :
- (cf->remote_range && (cf->remote_range->type == NET_IP4));
+ p->ipv4 = cf->ipv4;
p->remote_ip = cf->remote_ip;
p->remote_as = cf->remote_as;
if (cf->check_link < 0)
cf->check_link = !cf->multihop;
+ /* Detect IPv4 */
+ cf->ipv4 = ipa_nonzero(cf->remote_ip) ?
+ ipa_is_ip4(cf->remote_ip) :
+ (cf->remote_range && (cf->remote_range->type == NET_IP4));
if (!cf->local_as)
cf_error("Local AS number must be set");
u32 rr_cluster_id; /* Route reflector cluster ID, if different from local ID */
int rr_client; /* Whether neighbor is RR client of me */
int rs_client; /* Whether neighbor is RS client of me */
+ int ipv4; /* Use IPv4 connection, i.e. remote_ip is IPv4 */
u32 confederation; /* Confederation ID, or zero if confeds not active */
int confederation_member; /* Whether neighbor AS is member of our confederation */
int passive; /* Do not initiate outgoing connection */