mirror of
				https://gitlab.labs.nic.cz/labs/bird.git
				synced 2024-05-11 16:54:54 +00:00 
			
		
		
		
	IO: Support nonlocal bind in socket interface
Add option to socket interface for nonlocal binding, i.e. binding to an IP address that is not present on interfaces. This behaviour is enabled when SKF_FREEBIND socket flag is set. For Linux systems, it is implemented by IP_FREEBIND socket flag. Minor changes done by commiter.
This commit is contained in:
		
				
					committed by
					
						
						Ondrej Zajicek (work)
					
				
			
			
				
	
			
			
			
						parent
						
							bcb25084d3
						
					
				
				
					commit
					87a02489f3
				
			@@ -123,6 +123,7 @@ extern int sk_priority_control;		/* Suggested priority for control traffic, shou
 | 
			
		||||
#define SKF_TTL_RX	0x08	/* Report TTL / Hop Limit for RX packets */
 | 
			
		||||
#define SKF_BIND	0x10	/* Bind datagram socket to given source address */
 | 
			
		||||
#define SKF_HIGH_PORT	0x20	/* Choose port from high range if possible */
 | 
			
		||||
#define SKF_FREEBIND	0x40	/* Allow socket to bind to a nonlocal address */
 | 
			
		||||
 | 
			
		||||
#define SKF_THREAD	0x100	/* Socked used in thread, Do not add to main loop */
 | 
			
		||||
#define SKF_TRUNCATED	0x200	/* Received packet was truncated, set by IO layer */
 | 
			
		||||
 
 | 
			
		||||
@@ -271,3 +271,9 @@ sk_set_priority(sock *s, int prio UNUSED)
 | 
			
		||||
{
 | 
			
		||||
  ERR_MSG("Socket priority not supported");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline int
 | 
			
		||||
sk_set_freebind(sock *s)
 | 
			
		||||
{
 | 
			
		||||
  ERR_MSG("Freebind is not supported");
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -10,6 +10,10 @@
 | 
			
		||||
#define IPV6_MINHOPCOUNT 73
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef IPV6_FREEBIND
 | 
			
		||||
#define IPV6_FREEBIND 78
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef TCP_MD5SIG_EXT
 | 
			
		||||
#define TCP_MD5SIG_EXT 32
 | 
			
		||||
#endif
 | 
			
		||||
@@ -266,3 +270,18 @@ sk_set_priority(sock *s, int prio)
 | 
			
		||||
  return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline int
 | 
			
		||||
sk_set_freebind(sock *s)
 | 
			
		||||
{
 | 
			
		||||
  int y = 1;
 | 
			
		||||
 | 
			
		||||
  if (sk_is_ipv4(s))
 | 
			
		||||
    if (setsockopt(s->fd, SOL_IP, IP_FREEBIND, &y, sizeof(y)) < 0)
 | 
			
		||||
      ERR("IP_FREEBIND");
 | 
			
		||||
 | 
			
		||||
  if (sk_is_ipv6(s))
 | 
			
		||||
    if (setsockopt(s->fd, SOL_IPV6, IPV6_FREEBIND, &y, sizeof(y)) < 0)
 | 
			
		||||
      ERR("IPV6_FREEBIND");
 | 
			
		||||
 | 
			
		||||
  return 0;
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -1436,6 +1436,10 @@ sk_open(sock *s)
 | 
			
		||||
	if (sk_set_high_port(s) < 0)
 | 
			
		||||
	  log(L_WARN "Socket error: %s%#m", s->err);
 | 
			
		||||
 | 
			
		||||
    if (s->flags & SKF_FREEBIND)
 | 
			
		||||
      if (sk_set_freebind(s) < 0)
 | 
			
		||||
        log(L_WARN "Socket error: %s%#m", s->err);
 | 
			
		||||
 | 
			
		||||
    sockaddr_fill(&sa, s->af, bind_addr, s->iface, bind_port);
 | 
			
		||||
    if (bind(fd, &sa.sa, SA_LEN(sa)) < 0)
 | 
			
		||||
      ERR2("bind");
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user