Exemple #1
0
/* get interface MTU */
void if_get_mtu(struct interface *ifp)
{
	struct ifreq ifreq;

	ifreq_set_name(&ifreq, ifp);

#if defined(SIOCGIFMTU)
	if (vrf_if_ioctl(SIOCGIFMTU, (caddr_t)&ifreq, ifp->vrf_id) < 0) {
		zlog_info("Can't lookup mtu by ioctl(SIOCGIFMTU)");
		ifp->mtu6 = ifp->mtu = -1;
		return;
	}

#ifdef SUNOS_5
	ifp->mtu6 = ifp->mtu = ifreq.ifr_metric;
#else
	ifp->mtu6 = ifp->mtu = ifreq.ifr_mtu;
#endif /* SUNOS_5 */

	/* propogate */
	zebra_interface_up_update(ifp);

#else
	zlog_info("Can't lookup mtu on this system");
	ifp->mtu6 = ifp->mtu = -1;
#endif
}
Exemple #2
0
/* get interface MTU */
void
if_get_mtu (struct interface *ifp)
{
  struct ifreq ifreq;

  ifreq_set_name (&ifreq, ifp);

#if defined(SIOCGIFMTU)
  if (if_ioctl (SIOCGIFMTU, (caddr_t) & ifreq) < 0) 
    {
      zlog_info ("Can't lookup mtu by ioctl(SIOCGIFMTU)");
      ifp->mtu = -1;
      return;
    }

#ifdef SUNOS_5
  ifp->mtu = ifreq.ifr_metric;
#else
  ifp->mtu = ifreq.ifr_mtu;
#endif /* SUNOS_5 */

#else
  zlog (NULL, LOG_INFO, "Can't lookup mtu on this system");
  ifp->mtu = -1;
#endif
}
Exemple #3
0
/* Set up interface's address, netmask (and broadcas? ).  Linux or
   Solaris uses ifname:number semantics to set IP address aliases. */
int
if_set_prefix (struct interface *ifp, struct connected *ifc)
{
  int ret;
  struct ifreq ifreq;
  struct sockaddr_in addr;
  struct sockaddr_in broad;
  struct sockaddr_in mask;
  struct prefix_ipv4 ifaddr;
  struct prefix_ipv4 *p;

  p = (struct prefix_ipv4 *) ifc->address;

  ifaddr = *p;

  ifreq_set_name (&ifreq, ifp);

  addr.sin_addr = p->prefix;
  addr.sin_family = p->family;
  memcpy (&ifreq.ifr_addr, &addr, sizeof (struct sockaddr_in));
  ret = if_ioctl (SIOCSIFADDR, (caddr_t) &ifreq);
  if (ret < 0)
    return ret;
  
  /* We need mask for make broadcast addr. */
  masklen2ip (p->prefixlen, &mask.sin_addr);

  if (if_is_broadcast (ifp))
    {
      apply_mask_ipv4 (&ifaddr);
      addr.sin_addr = ifaddr.prefix;

      broad.sin_addr.s_addr = (addr.sin_addr.s_addr | ~mask.sin_addr.s_addr);
      broad.sin_family = p->family;

      memcpy (&ifreq.ifr_broadaddr, &broad, sizeof (struct sockaddr_in));
      ret = if_ioctl (SIOCSIFBRDADDR, (caddr_t) &ifreq);
      if (ret < 0)
	return ret;
    }

  mask.sin_family = p->family;
#ifdef SUNOS_5
  memcpy (&mask, &ifreq.ifr_addr, sizeof (mask));
#else
  memcpy (&ifreq.ifr_netmask, &mask, sizeof (struct sockaddr_in));
#endif /* SUNOS5 */
  ret = if_ioctl (SIOCSIFNETMASK, (caddr_t) &ifreq);
  if (ret < 0)
    return ret;

  return 0;
}
Exemple #4
0
/*
 * get interface metric
 *   -- if value is not avaliable set -1
 */
void if_get_metric(struct interface *ifp)
{
#ifdef SIOCGIFMETRIC
	struct ifreq ifreq;

	ifreq_set_name(&ifreq, ifp);

	if (vrf_if_ioctl(SIOCGIFMETRIC, (caddr_t)&ifreq, ifp->vrf_id) < 0)
		return;
	ifp->metric = ifreq.ifr_metric;
	if (ifp->metric == 0)
		ifp->metric = 1;
#else  /* SIOCGIFMETRIC */
	ifp->metric = -1;
#endif /* SIOCGIFMETRIC */
}
Exemple #5
0
/* get interface flags */
void if_get_flags (struct interface *ifp)
{
	int ret = 0;
	struct ifreq ifreq;

	ifreq_set_name (&ifreq, ifp);

	ret = if_ioctl (SIOCGIFFLAGS, (caddr_t) &ifreq);
	if (ret < 0)
	{
		zlog_err("if_ioctl(SIOCGIFFLAGS) failed: %s", safe_strerror(errno));
		return;
	}

	if_flags_update (ifp, (ifreq.ifr_flags & 0x0000ffff));
}
Exemple #6
0
/* get interface flags */
void if_get_flags(struct interface *ifp)
{
	int ret;
	struct ifreq ifreq;
#ifdef HAVE_BSD_LINK_DETECT
	struct ifmediareq ifmr;
#endif /* HAVE_BSD_LINK_DETECT */

	ifreq_set_name(&ifreq, ifp);

	ret = vrf_if_ioctl(SIOCGIFFLAGS, (caddr_t)&ifreq, ifp->vrf_id);
	if (ret < 0) {
		flog_err_sys(EC_LIB_SYSTEM_CALL,
			     "vrf_if_ioctl(SIOCGIFFLAGS) failed: %s",
			     safe_strerror(errno));
		return;
	}
#ifdef HAVE_BSD_LINK_DETECT /* Detect BSD link-state at start-up */

	/* Per-default, IFF_RUNNING is held high, unless link-detect says
	 * otherwise - we abuse IFF_RUNNING inside zebra as a link-state flag,
	 * following practice on Linux and Solaris kernels
	 */
	SET_FLAG(ifreq.ifr_flags, IFF_RUNNING);

	if (CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_LINKDETECTION)) {
		(void)memset(&ifmr, 0, sizeof(ifmr));
		strlcpy(ifmr.ifm_name, ifp->name, sizeof(ifmr.ifm_name));

		/* Seems not all interfaces implement this ioctl */
		if (if_ioctl(SIOCGIFMEDIA, (caddr_t)&ifmr) == -1 &&
		    errno != EINVAL)
			flog_err_sys(EC_LIB_SYSTEM_CALL,
				     "if_ioctl(SIOCGIFMEDIA) failed: %s",
				     safe_strerror(errno));
		else if (ifmr.ifm_status & IFM_AVALID) /* Link state is valid */
		{
			if (ifmr.ifm_status & IFM_ACTIVE)
				SET_FLAG(ifreq.ifr_flags, IFF_RUNNING);
			else
				UNSET_FLAG(ifreq.ifr_flags, IFF_RUNNING);
		}
	}
#endif /* HAVE_BSD_LINK_DETECT */

	if_flags_update(ifp, (ifreq.ifr_flags & 0x0000ffff));
}
/* Get interface's index by ioctl. */
int
if_get_index (struct interface_FOO *ifp)
{
#if defined(HAVE_IF_NAMETOINDEX)
  /* Modern systems should have if_nametoindex(3). */
  ifp->ifindex = if_nametoindex(ifp->name);
#elif defined(SIOCGIFINDEX) && !defined(HAVE_BROKEN_ALIASES)
  /* Fall-back for older linuxes. */
  int ret;
  struct ifreq ifreq;
  static int if_fake_index;

  ifreq_set_name (&ifreq, ifp);

  ret = if_ioctl (SIOCGIFINDEX, (caddr_t) &ifreq);
  if (ret < 0)
    {
      /* Linux 2.0.X does not have interface index. */
      ifp->ifindex = if_fake_index++;
      return ifp->ifindex;
    }

  /* OK we got interface index. */
#ifdef ifr_ifindex
  ifp->ifindex = ifreq.ifr_ifindex;
#else
  ifp->ifindex = ifreq.ifr_index;
#endif

#else
/* Linux 2.2.X does not provide individual interface index 
   for aliases and we know it. For others issue a warning. */
#if !defined(HAVE_BROKEN_ALIASES)
#ifndef _MSC_VER
#warning "Using if_fake_index. You may want to add appropriate"
#endif
#ifndef _MSC_VER
#warning "mapping from ifname to ifindex for your system..."
#endif
#endif
  /* This branch probably won't provide usable results, but anyway... */
  static int if_fake_index = 1;
  ifp->ifindex = if_fake_index++;
#endif

  return ifp->ifindex;
}
Exemple #8
0
/*
 * get interface metric
 *   -- if value is not avaliable set -1
 */
void if_get_metric (struct interface *ifp)
{
	struct ifreq ifreq;

	ifreq_set_name (&ifreq, ifp);

	if (if_ioctl (SIOCGIFMETRIC, (caddr_t) &ifreq) < 0)
	{
		return;
	}
	ifp->metric = ifreq.ifr_metric;
	if (ifp->metric == 0)
	{
		ifp->metric = 1;
	}
	return;
}
Exemple #9
0
/* get interface flags */
void
if_get_flags (struct interface *ifp)
{
  int ret;
  struct ifreq ifreq;

  ifreq_set_name (&ifreq, ifp);

  ret = if_ioctl (SIOCGIFFLAGS, (caddr_t) &ifreq);
  if (ret < 0) 
    {
      perror ("ioctl");
      return;
    }

  ifp->flags = ifreq.ifr_flags & 0x0000ffff;
}
Exemple #10
0
/* get interface MTU */
void if_get_mtu (struct interface *ifp)
{
	struct ifreq ifreq;

	ifreq_set_name (&ifreq, ifp);

	if (if_ioctl (SIOCGIFMTU, (caddr_t) & ifreq) < 0)
	{
		zlog_info ("Can't lookup mtu by ioctl(SIOCGIFMTU)");
					ifp->mtu6 = ifp->mtu = -1;
		return;
	}

	ifp->mtu6 = ifp->mtu = ifreq.ifr_mtu;

	/* propogate */
	zebra_interface_up_update(ifp);
}
Exemple #11
0
/* Unset interface's flag. */
int if_unset_flags(struct interface *ifp, uint64_t flags)
{
	int ret;
	struct ifreq ifreq;

	memset(&ifreq, 0, sizeof(struct ifreq));
	ifreq_set_name(&ifreq, ifp);

	ifreq.ifr_flags = ifp->flags;
	ifreq.ifr_flags &= ~flags;

	ret = vrf_if_ioctl(SIOCSIFFLAGS, (caddr_t)&ifreq, ifp->vrf_id);

	if (ret < 0) {
		zlog_info("can't unset interface flags");
		return ret;
	}
	return 0;
}
Exemple #12
0
/* Unset interface's flag. */
int
if_unset_flags (struct interface *ifp, unsigned long flags)
{
  int ret;
  struct ifreq ifreq;

  ifreq_set_name (&ifreq, ifp);

  ifreq.ifr_flags = ifp->flags;
  ifreq.ifr_flags &= ~flags;

  ret = if_ioctl (SIOCSIFFLAGS, (caddr_t) &ifreq);

  if (ret < 0)
    {
      zlog_info ("can't unset interface flags");
      return ret;
    }
  return 0;
}
Exemple #13
0
/* Set up interface's address, netmask (and broadcas? ).  Linux or
   Solaris uses ifname:number semantics to set IP address aliases. */
int
if_unset_prefix (struct interface *ifp, struct connected *ifc)
{
  int ret;
  struct ifreq ifreq;
  struct sockaddr_in addr;
  struct prefix_ipv4 *p;

  p = (struct prefix_ipv4 *) ifc->address;

  ifreq_set_name (&ifreq, ifp);

  memset (&addr, 0, sizeof (struct sockaddr_in));
  addr.sin_family = p->family;
  memcpy (&ifreq.ifr_addr, &addr, sizeof (struct sockaddr_in));
  ret = if_ioctl (SIOCSIFADDR, (caddr_t) &ifreq);
  if (ret < 0)
    return ret;

  return 0;
}
Exemple #14
0
/* Get interface's index by ioctl. */
int
if_get_index (struct interface *ifp)
{
  static int if_fake_index = 1;

#ifdef HAVE_BROKEN_ALIASES
  /* Linux 2.2.X does not provide individual interface index for aliases. */
  ifp->ifindex = if_fake_index++;
  return ifp->ifindex;
#else
#ifdef SIOCGIFINDEX
  int ret;
  struct ifreq ifreq;

  ifreq_set_name (&ifreq, ifp);

  ret = if_ioctl (SIOCGIFINDEX, (caddr_t) &ifreq);
  if (ret < 0)
    {
      /* Linux 2.0.X does not have interface index. */
      ifp->ifindex = if_fake_index++;
      return ifp->ifindex;
    }

  /* OK we got interface index. */
#ifdef ifr_ifindex
  ifp->ifindex = ifreq.ifr_ifindex;
#else
  ifp->ifindex = ifreq.ifr_index;
#endif
  return ifp->ifindex;

#else
  ifp->ifindex = if_fake_index++;
  return ifp->ifindex;
#endif /* SIOCGIFINDEX */
#endif /* HAVE_BROKEN_ALIASES */
}