Diff for /embedaddon/quagga/bgpd/bgp_network.c between versions 1.1.1.1 and 1.1.1.2

version 1.1.1.1, 2012/02/21 17:26:12 version 1.1.1.2, 2012/10/09 09:22:28
Line 238  bgp_bind (struct peer *peer) Line 238  bgp_bind (struct peer *peer)
 }  }
   
 static int  static int
bgp_bind_address (int sock, struct in_addr *addr)bgp_update_address (struct interface *ifp, const union sockunion *dst,
                     union sockunion *addr)
 {  {
  int ret;  struct prefix *p, *sel, *d;
  struct sockaddr_in local; 
 
  memset (&local, 0, sizeof (struct sockaddr_in)); 
  local.sin_family = AF_INET; 
#ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN 
  local.sin_len = sizeof(struct sockaddr_in); 
#endif /* HAVE_STRUCT_SOCKADDR_IN_SIN_LEN */ 
  memcpy (&local.sin_addr, addr, sizeof (struct in_addr)); 
 
  if ( bgpd_privs.change (ZPRIVS_RAISE) ) 
    zlog_err ("bgp_bind_address: could not raise privs"); 
     
  ret = bind (sock, (struct sockaddr *)&local, sizeof (struct sockaddr_in)); 
  if (ret < 0) 
    ; 
     
  if (bgpd_privs.change (ZPRIVS_LOWER) ) 
    zlog_err ("bgp_bind_address: could not lower privs"); 
     
  return 0; 
} 
 
static struct in_addr * 
bgp_update_address (struct interface *ifp) 
{ 
  struct prefix_ipv4 *p; 
   struct connected *connected;    struct connected *connected;
   struct listnode *node;    struct listnode *node;
     int common;
   
     d = sockunion2hostprefix (dst);
     sel = NULL;
     common = -1;
   
   for (ALL_LIST_ELEMENTS_RO (ifp->connected, node, connected))    for (ALL_LIST_ELEMENTS_RO (ifp->connected, node, connected))
     {      {
      p = (struct prefix_ipv4 *) connected->address;      p = connected->address;
      if (p->family != d->family)
      if (p->family == AF_INET)        continue;
        return &p->prefix;      if (prefix_common_bits (p, d) > common)
         {
           sel = p;
           common = prefix_common_bits (sel, d);
         }
     }      }
  return NULL;
   prefix_free (d);
   if (!sel)
     return 1;
 
   prefix2sockunion (sel, addr);
   return 0;
 }  }
   
 /* Update source selection.  */  /* Update source selection.  */
Line 285  static void Line 275  static void
 bgp_update_source (struct peer *peer)  bgp_update_source (struct peer *peer)
 {  {
   struct interface *ifp;    struct interface *ifp;
  struct in_addr *addr;  union sockunion addr;
   
   /* Source is specified with interface name.  */    /* Source is specified with interface name.  */
   if (peer->update_if)    if (peer->update_if)
Line 294  bgp_update_source (struct peer *peer) Line 284  bgp_update_source (struct peer *peer)
       if (! ifp)        if (! ifp)
         return;          return;
   
      addr = bgp_update_address (ifp);      if (bgp_update_address (ifp, &peer->su, &addr))
      if (! addr) 
         return;          return;
   
      bgp_bind_address (peer->fd, addr);      sockunion_bind (peer->fd, &addr, 0, &addr);
     }      }
   
   /* Source is specified with IP address.  */    /* Source is specified with IP address.  */
Line 328  bgp_connect (struct peer *peer) Line 317  bgp_connect (struct peer *peer)
   sockopt_reuseport (peer->fd);    sockopt_reuseport (peer->fd);
       
 #ifdef IPTOS_PREC_INTERNETCONTROL  #ifdef IPTOS_PREC_INTERNETCONTROL
     if (bgpd_privs.change (ZPRIVS_RAISE))
       zlog_err ("%s: could not raise privs", __func__);
   if (sockunion_family (&peer->su) == AF_INET)    if (sockunion_family (&peer->su) == AF_INET)
     setsockopt_ipv4_tos (peer->fd, IPTOS_PREC_INTERNETCONTROL);      setsockopt_ipv4_tos (peer->fd, IPTOS_PREC_INTERNETCONTROL);
   # ifdef HAVE_IPV6
     else if (sockunion_family (&peer->su) == AF_INET6)
       setsockopt_ipv6_tclass (peer->fd, IPTOS_PREC_INTERNETCONTROL);
   # endif
     if (bgpd_privs.change (ZPRIVS_LOWER))
       zlog_err ("%s: could not lower privs", __func__);
 #endif  #endif
   
   if (peer->password)    if (peer->password)
Line 386  bgp_listener (int sock, struct sockaddr *sa, socklen_t Line 383  bgp_listener (int sock, struct sockaddr *sa, socklen_t
   sockopt_reuseaddr (sock);    sockopt_reuseaddr (sock);
   sockopt_reuseport (sock);    sockopt_reuseport (sock);
   
     if (bgpd_privs.change (ZPRIVS_RAISE))
       zlog_err ("%s: could not raise privs", __func__);
   
 #ifdef IPTOS_PREC_INTERNETCONTROL  #ifdef IPTOS_PREC_INTERNETCONTROL
   if (sa->sa_family == AF_INET)    if (sa->sa_family == AF_INET)
     setsockopt_ipv4_tos (sock, IPTOS_PREC_INTERNETCONTROL);      setsockopt_ipv4_tos (sock, IPTOS_PREC_INTERNETCONTROL);
   #  ifdef HAVE_IPV6
     else if (sa->sa_family == AF_INET6)
       setsockopt_ipv6_tclass (sock, IPTOS_PREC_INTERNETCONTROL);
   #  endif
 #endif  #endif
   
#ifdef IPV6_V6ONLY  sockopt_v6only (sa->sa_family, sock);
  /* Want only IPV6 on ipv6 socket (not mapped addresses) */ 
  if (sa->sa_family == AF_INET6) { 
    int on = 1; 
    setsockopt (sock, IPPROTO_IPV6, IPV6_V6ONLY, 
                (void *) &on, sizeof (on)); 
  } 
#endif 
   
   if (bgpd_privs.change (ZPRIVS_RAISE) )  
     zlog_err ("bgp_socket: could not raise privs");  
   
   ret = bind (sock, sa, salen);    ret = bind (sock, sa, salen);
   en = errno;    en = errno;
  if (bgpd_privs.change (ZPRIVS_LOWER) )  if (bgpd_privs.change (ZPRIVS_LOWER))
    zlog_err ("bgp_bind_address: could not lower privs");    zlog_err ("%s: could not lower privs", __func__);
   
   if (ret < 0)    if (ret < 0)
     {      {

Removed from v.1.1.1.1  
changed lines
  Added in v.1.1.1.2


FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>