mirror of
				https://gitlab.labs.nic.cz/labs/bird.git
				synced 2024-05-11 16:54:54 +00:00 
			
		
		
		
	Make BGP protocol instance search a separate function
Thanks to Alexander V. Chernikov for the patch.
This commit is contained in:
		
							
								
								
									
										106
									
								
								proto/bgp/bgp.c
									
									
									
									
									
								
							
							
						
						
									
										106
									
								
								proto/bgp/bgp.c
									
									
									
									
									
								
							@@ -712,6 +712,28 @@ bgp_connect(struct bgp_proto *p)	/* Enter Connect state and start establishing c
 | 
			
		||||
  return;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * bgp_find_proto - find existing proto for incoming connection
 | 
			
		||||
 * @sk: TCP socket
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
static struct bgp_proto *
 | 
			
		||||
bgp_find_proto(sock *sk)
 | 
			
		||||
{
 | 
			
		||||
  struct proto_config *pc;
 | 
			
		||||
 | 
			
		||||
  WALK_LIST(pc, config->protos)
 | 
			
		||||
    if ((pc->protocol == &proto_bgp) && pc->proto)
 | 
			
		||||
      {
 | 
			
		||||
	struct bgp_proto *p = (struct bgp_proto *) pc->proto;
 | 
			
		||||
	if (ipa_equal(p->cf->remote_ip, sk->daddr) &&
 | 
			
		||||
	    (!ipa_is_link_local(sk->daddr) || (p->cf->iface == sk->iface)))
 | 
			
		||||
	  return p;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
  return NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * bgp_incoming_connection - handle an incoming connection
 | 
			
		||||
 * @sk: TCP socket
 | 
			
		||||
@@ -727,60 +749,58 @@ bgp_connect(struct bgp_proto *p)	/* Enter Connect state and start establishing c
 | 
			
		||||
static int
 | 
			
		||||
bgp_incoming_connection(sock *sk, int dummy UNUSED)
 | 
			
		||||
{
 | 
			
		||||
  struct proto_config *pc;
 | 
			
		||||
  struct bgp_proto *p;
 | 
			
		||||
  int acc, hops;
 | 
			
		||||
 | 
			
		||||
  DBG("BGP: Incoming connection from %I port %d\n", sk->daddr, sk->dport);
 | 
			
		||||
  WALK_LIST(pc, config->protos)
 | 
			
		||||
    if (pc->protocol == &proto_bgp && pc->proto)
 | 
			
		||||
      {
 | 
			
		||||
	struct bgp_proto *p = (struct bgp_proto *) pc->proto;
 | 
			
		||||
	if (ipa_equal(p->cf->remote_ip, sk->daddr) &&
 | 
			
		||||
	    (!ipa_is_link_local(sk->daddr) || (p->cf->iface == sk->iface)))
 | 
			
		||||
	  {
 | 
			
		||||
	    /* We are in proper state and there is no other incoming connection */
 | 
			
		||||
	    int acc = (p->p.proto_state == PS_START || p->p.proto_state == PS_UP) &&
 | 
			
		||||
	      (p->start_state >= BSS_CONNECT) && (!p->incoming_conn.sk);
 | 
			
		||||
  p = bgp_find_proto(sk);
 | 
			
		||||
  if (!p)
 | 
			
		||||
    {
 | 
			
		||||
      log(L_WARN "BGP: Unexpected connect from unknown address %I%J (port %d)",
 | 
			
		||||
	  sk->daddr, ipa_is_link_local(sk->daddr) ? sk->iface : NULL, sk->dport);
 | 
			
		||||
      rfree(sk);
 | 
			
		||||
      return 0;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
	    if (p->conn && (p->conn->state == BS_ESTABLISHED) && p->gr_ready)
 | 
			
		||||
	    {
 | 
			
		||||
	      bgp_store_error(p, NULL, BE_MISC, BEM_GRACEFUL_RESTART);
 | 
			
		||||
	      bgp_handle_graceful_restart(p);
 | 
			
		||||
	      bgp_conn_enter_idle_state(p->conn);
 | 
			
		||||
	      acc = 1;
 | 
			
		||||
	    }
 | 
			
		||||
  /* We are in proper state and there is no other incoming connection */
 | 
			
		||||
  acc = (p->p.proto_state == PS_START || p->p.proto_state == PS_UP) &&
 | 
			
		||||
    (p->start_state >= BSS_CONNECT) && (!p->incoming_conn.sk);
 | 
			
		||||
 | 
			
		||||
	    BGP_TRACE(D_EVENTS, "Incoming connection from %I%J (port %d) %s",
 | 
			
		||||
		      sk->daddr, ipa_is_link_local(sk->daddr) ? sk->iface : NULL,
 | 
			
		||||
		      sk->dport, acc ? "accepted" : "rejected");
 | 
			
		||||
  if (p->conn && (p->conn->state == BS_ESTABLISHED) && p->gr_ready)
 | 
			
		||||
    {
 | 
			
		||||
      bgp_store_error(p, NULL, BE_MISC, BEM_GRACEFUL_RESTART);
 | 
			
		||||
      bgp_handle_graceful_restart(p);
 | 
			
		||||
      bgp_conn_enter_idle_state(p->conn);
 | 
			
		||||
      acc = 1;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
	    if (!acc)
 | 
			
		||||
	      goto reject;
 | 
			
		||||
  BGP_TRACE(D_EVENTS, "Incoming connection from %I%J (port %d) %s",
 | 
			
		||||
	    sk->daddr, ipa_is_link_local(sk->daddr) ? sk->iface : NULL,
 | 
			
		||||
	    sk->dport, acc ? "accepted" : "rejected");
 | 
			
		||||
 | 
			
		||||
	    int hops = p->cf->multihop ? : 1;
 | 
			
		||||
  if (!acc)
 | 
			
		||||
    {
 | 
			
		||||
      rfree(sk);
 | 
			
		||||
      return 0;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
	    if (sk_set_ttl(sk, p->cf->ttl_security ? 255 : hops) < 0)
 | 
			
		||||
	      goto err;
 | 
			
		||||
  hops = p->cf->multihop ? : 1;
 | 
			
		||||
 | 
			
		||||
	    if (p->cf->ttl_security)
 | 
			
		||||
	      if (sk_set_min_ttl(sk, 256 - hops) < 0)
 | 
			
		||||
		goto err;
 | 
			
		||||
  if (sk_set_ttl(sk, p->cf->ttl_security ? 255 : hops) < 0)
 | 
			
		||||
    goto err;
 | 
			
		||||
 | 
			
		||||
	    bgp_setup_conn(p, &p->incoming_conn);
 | 
			
		||||
	    bgp_setup_sk(&p->incoming_conn, sk);
 | 
			
		||||
	    bgp_send_open(&p->incoming_conn);
 | 
			
		||||
	    return 0;
 | 
			
		||||
  if (p->cf->ttl_security)
 | 
			
		||||
    if (sk_set_min_ttl(sk, 256 - hops) < 0)
 | 
			
		||||
      goto err;
 | 
			
		||||
 | 
			
		||||
	  err:
 | 
			
		||||
	    sk_log_error(sk, p->p.name);
 | 
			
		||||
	    log(L_ERR "%s: Incoming connection aborted", p->p.name);
 | 
			
		||||
	    rfree(sk);
 | 
			
		||||
	    return 0;
 | 
			
		||||
	  }
 | 
			
		||||
      }
 | 
			
		||||
  bgp_setup_conn(p, &p->incoming_conn);
 | 
			
		||||
  bgp_setup_sk(&p->incoming_conn, sk);
 | 
			
		||||
  bgp_send_open(&p->incoming_conn);
 | 
			
		||||
  return 0;
 | 
			
		||||
 | 
			
		||||
  log(L_WARN "BGP: Unexpected connect from unknown address %I%J (port %d)",
 | 
			
		||||
      sk->daddr, ipa_is_link_local(sk->daddr) ? sk->iface : NULL, sk->dport);
 | 
			
		||||
 reject:
 | 
			
		||||
err:
 | 
			
		||||
  sk_log_error(sk, p->p.name);
 | 
			
		||||
  log(L_ERR "%s: Incoming connection aborted", p->p.name);
 | 
			
		||||
  rfree(sk);
 | 
			
		||||
  return 0;
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user