Exemple #1
0
/* Internal server test. Call with locks applied.
   May test a single server ip or several collectively.
 */
static void retest(int i, int j)
{
  time_t s_ts;
  servparm_t *srv=&DA_INDEX(servers,i);
  int nsrvs=DA_NEL(srv->atup_a);

  if(!nsrvs) return;
  if(j>=0) {
    if(j<nsrvs) nsrvs=j+1;  /* test just one */
  }
  else {
    j=0;        /* test a range of servers */
  }

  if(!scheme_ok(srv)) {
    s_ts=time(NULL);

    for(;j<nsrvs;++j) {
      atup_t *at=&DA_INDEX(srv->atup_a,j);
      at->is_up=0;
      at->i_ts=s_ts;
    }
  }
  else if(srv->uptest==C_NONE) {
    s_ts=time(NULL);

    for(;j<nsrvs;++j) {
	DA_INDEX(srv->atup_a,j).i_ts=s_ts;
    }
  }
  else if(srv->uptest==C_QUERY || (srv->uptest==C_PING && is_inaddr_any(&srv->ping_a))) {  /* test each ip address separately */
    for(;j<nsrvs;++j) {
	atup_t *at=&DA_INDEX(srv->atup_a,j);
	s_ts=time(NULL);
	at->is_up=uptest(srv,j);
	if(signal_interrupt)
	  break;
	at->i_ts=s_ts;
    }
  }
  else {  /* test ip addresses collectively */
    int res;

    s_ts=time(NULL);
    res=uptest(srv,j);
    for(;j<nsrvs;++j) {
      atup_t *at=&DA_INDEX(srv->atup_a,j);
      at->is_up=res;
      if(signal_interrupt && srv->uptest==C_PING)
	continue;
      at->i_ts=s_ts;
    }
  }
}
Exemple #2
0
bool is_filter_exact_match(struct adapter *adap,
			   struct ch_filter_specification *fs)
{
	struct tp_params *tp = &adap->params.tp;
	u64 hash_filter_mask = tp->hash_filter_mask;
	u32 mask;

	if (!is_hashfilter(adap))
		return false;

	if (fs->type) {
		if (is_inaddr_any(fs->val.fip, AF_INET6) ||
		    !is_addr_all_mask(fs->mask.fip, AF_INET6))
			return false;

		if (is_inaddr_any(fs->val.lip, AF_INET6) ||
		    !is_addr_all_mask(fs->mask.lip, AF_INET6))
			return false;
	} else {
		if (is_inaddr_any(fs->val.fip, AF_INET) ||
		    !is_addr_all_mask(fs->mask.fip, AF_INET))
			return false;

		if (is_inaddr_any(fs->val.lip, AF_INET) ||
		    !is_addr_all_mask(fs->mask.lip, AF_INET))
			return false;
	}

	if (!fs->val.lport || fs->mask.lport != 0xffff)
		return false;

	if (!fs->val.fport || fs->mask.fport != 0xffff)
		return false;

	if (tp->fcoe_shift >= 0) {
		mask = (hash_filter_mask >> tp->fcoe_shift) & FT_FCOE_W;
		if (mask && !fs->mask.fcoe)
			return false;
	}
Exemple #3
0
/* Report the current configuration to the file descriptor f (for the status fifo, see status.c) */
int report_conf_stat(int f)
{
	int i,n,retval=0;

	fsprintf_or_return(f,"\nConfiguration:\n==============\nGlobal:\n-------\n");
	fsprintf_or_return(f,"\tCache size: %li kB\n",global.perm_cache);
	fsprintf_or_return(f,"\tServer directory: %s\n",global.cache_dir);
	fsprintf_or_return(f,"\tScheme file (for Linux pcmcia support): %s\n",global.scheme_file);
	fsprintf_or_return(f,"\tServer port: %i\n",global.port);
	{
	  char buf[ADDRSTR_MAXLEN];
	  fsprintf_or_return(f,"\tServer IP (%s=any available one): %s\n", SEL_IPVER("0.0.0.0","::"),
			     pdnsd_a2str(&global.a,buf,ADDRSTR_MAXLEN));
	  if(!is_inaddr_any(&global.out_a)) {
	    fsprintf_or_return(f,"\tIP bound to interface used for querying remote servers: %s\n",
			       pdnsd_a2str(&global.out_a,buf,ADDRSTR_MAXLEN));
	  }
	}
#ifdef ENABLE_IPV6
	if(!run_ipv4) {
	  char buf[ADDRSTR_MAXLEN];
	  fsprintf_or_return(f,"\tIPv4 to IPv6 prefix: %s\n",inet_ntop(AF_INET6,&global.ipv4_6_prefix,buf,ADDRSTR_MAXLEN)?:"?.?.?.?");
	}
bool is_filter_exact_match(struct adapter *adap,
			   struct ch_filter_specification *fs)
{
	struct tp_params *tp = &adap->params.tp;
	u64 hash_filter_mask = tp->hash_filter_mask;
	u64 ntuple_mask = 0;

	if (!is_hashfilter(adap))
		return false;

	if (fs->type) {
		if (is_inaddr_any(fs->val.fip, AF_INET6) ||
		    !is_addr_all_mask(fs->mask.fip, AF_INET6))
			return false;

		if (is_inaddr_any(fs->val.lip, AF_INET6) ||
		    !is_addr_all_mask(fs->mask.lip, AF_INET6))
			return false;
	} else {
		if (is_inaddr_any(fs->val.fip, AF_INET) ||
		    !is_addr_all_mask(fs->mask.fip, AF_INET))
			return false;

		if (is_inaddr_any(fs->val.lip, AF_INET) ||
		    !is_addr_all_mask(fs->mask.lip, AF_INET))
			return false;
	}

	if (!fs->val.lport || fs->mask.lport != 0xffff)
		return false;

	if (!fs->val.fport || fs->mask.fport != 0xffff)
		return false;

	/* calculate tuple mask and compare with mask configured in hw */
	if (tp->fcoe_shift >= 0)
		ntuple_mask |= (u64)fs->mask.fcoe << tp->fcoe_shift;

	if (tp->port_shift >= 0)
		ntuple_mask |= (u64)fs->mask.iport << tp->port_shift;

	if (tp->vnic_shift >= 0) {
		if ((adap->params.tp.ingress_config & VNIC_F))
			ntuple_mask |= (u64)fs->mask.pfvf_vld << tp->vnic_shift;
		else
			ntuple_mask |= (u64)fs->mask.ovlan_vld <<
				tp->vnic_shift;
	}

	if (tp->vlan_shift >= 0)
		ntuple_mask |= (u64)fs->mask.ivlan << tp->vlan_shift;

	if (tp->tos_shift >= 0)
		ntuple_mask |= (u64)fs->mask.tos << tp->tos_shift;

	if (tp->protocol_shift >= 0)
		ntuple_mask |= (u64)fs->mask.proto << tp->protocol_shift;

	if (tp->ethertype_shift >= 0)
		ntuple_mask |= (u64)fs->mask.ethtype << tp->ethertype_shift;

	if (tp->macmatch_shift >= 0)
		ntuple_mask |= (u64)fs->mask.macidx << tp->macmatch_shift;

	if (tp->matchtype_shift >= 0)
		ntuple_mask |= (u64)fs->mask.matchtype << tp->matchtype_shift;

	if (tp->frag_shift >= 0)
		ntuple_mask |= (u64)fs->mask.frag << tp->frag_shift;

	if (ntuple_mask != hash_filter_mask)
		return false;

	return true;
}
Exemple #5
0
/*
 * Execute an individual uptest. Call with locks applied 
 */
static int uptest (servparm_t *serv, int j)
{
	int ret=0, count_running_ping=0;
	pdnsd_a *s_addr= PDNSD_A2_TO_A(&DA_INDEX(serv->atup_a,j).a);

	DEBUG_PDNSDA_MSG("performing uptest (type=%s) for %s\n",const_name(serv->uptest),PDNSDA2STR(s_addr));

	/* Unlock the mutex because some of the tests may take a while. */
	++server_data_users;
	if((serv->uptest==C_PING || serv->uptest==C_QUERY) && pthread_equal(pthread_self(),servstat_thrid)) {
		/* Inform other threads that a ping is in progress. */
		count_running_ping=1;
		++server_status_ping;
	}
	pthread_mutex_unlock(&servers_lock);

	switch (serv->uptest) {
	case C_NONE:
		/* Don't change */
		ret=DA_INDEX(serv->atup_a,j).is_up;
		break;
	case C_PING:
		ret=ping(is_inaddr_any(&serv->ping_a) ? s_addr : &serv->ping_a, serv->ping_timeout,PINGREPEAT)!=-1;
		break;
	case C_IF:
 	case C_DEV:
	case C_DIALD:
 		ret=if_up(serv->interface);
#if (TARGET==TARGET_LINUX)
 		if (ret!=0) {
			if(serv->uptest==C_DEV)
				ret=dev_up(serv->interface,serv->device);
			else if (serv->uptest==C_DIALD)
				ret=dev_up("diald",serv->device);
 		}
#endif
		break;
	case C_EXEC: {
	  	pid_t pid;

		if ((pid=fork())==-1) {
			DEBUG_MSG("Could not fork to perform exec uptest: %s\n",strerror(errno));
			break;
		} else if (pid==0) { /* child */
			/*
			 * If we ran as setuid or setgid, do not inherit this to the
			 * command. This is just a last guard. Running pdnsd as setuid()
			 * or setgid() is a no-no.
			 */
			if (setgid(getgid()) == -1 || setuid(getuid()) == -1) {
				log_error("Could not reset uid or gid: %s",strerror(errno));
				_exit(1);
			}
			/* Try to setuid() to a different user as specified. Good when you
			   don't want the test command to run as root */
			if (!run_as(serv->uptest_usr)) {
				_exit(1);
			}
			{
			    struct rlimit rl; int i;
			    /*
			     * Mark all open fd's FD_CLOEXEC for paranoia reasons.
			     */
			    if (getrlimit(RLIMIT_NOFILE, &rl) == -1) {
				    log_error("getrlimit() failed: %s",strerror(errno));
				    _exit(1);
			    }
			    for (i = 0; i < rl.rlim_max; i++) {
				    if (fcntl(i, F_SETFD, FD_CLOEXEC) == -1 && errno != EBADF) {
					    log_error("fcntl(F_SETFD) failed: %s",strerror(errno));
					    _exit(1);
				    }
			    }
			}
			execl("/bin/sh", "uptest_sh","-c",serv->uptest_cmd,(char *)NULL);
			_exit(1); /* failed execl */
		} else { /* parent */
			int status;
			pid_t wpid = waitpid(pid,&status,0);
			if (wpid==pid) {
				if(WIFEXITED(status)) {
					int exitstatus=WEXITSTATUS(status);
					DEBUG_MSG("uptest command \"%s\" exited with status %d\n",
						  serv->uptest_cmd, exitstatus);
					ret=(exitstatus==0);
				}
#if DEBUG>0
				else if(WIFSIGNALED(status)) {
					DEBUG_MSG("uptest command \"%s\" was terminated by signal %d\n",
						  serv->uptest_cmd, WTERMSIG(status));
				}
				else {
					DEBUG_MSG("status of uptest command \"%s\" is of unkown type (0x%x)\n",
						  serv->uptest_cmd, status);
				}
#endif
			}
#if DEBUG>0
			else if (wpid==-1) {
				DEBUG_MSG("Error while waiting for uptest command \"%s\" to terminate: "
					  "waitpid for pid %d failed: %s\n",
					  serv->uptest_cmd, pid, strerror(errno));
			}
			else {
				DEBUG_MSG("Error while waiting for uptest command \"%s\" to terminate: "
					  "waitpid returned %d, expected pid %d\n",
					  serv->uptest_cmd, wpid, pid);
			}
#endif
		}
	}
		break;
	case C_QUERY:
		ret=query_uptest(s_addr, serv->port,
				 serv->timeout>=global.timeout?serv->timeout:global.timeout,
				 PINGREPEAT);
	} /* end of switch */

	pthread_mutex_lock(&servers_lock);
	if(count_running_ping)
		--server_status_ping;
	PDNSD_ASSERT(server_data_users>0, "server_data_users non-positive before attempt to decrement it");
	if (--server_data_users==0) pthread_cond_broadcast(&server_data_cond);

	DEBUG_PDNSDA_MSG("result of uptest for %s: %s\n",
			 PDNSDA2STR(s_addr),
			 ret?"OK":"failed");
	return ret;
}