Example #1
0
/*
 * get interface metric
 *   -- if value is not avaliable set -1
 */
void
if_get_metric (struct interface *ifp)
{
  struct lifreq lifreq;
  int ret;

  lifreq_set_name (&lifreq, ifp->name);

  if (ifp->flags & IFF_IPV4)
    ret = AF_IOCTL (AF_INET, SIOCGLIFMETRIC, (caddr_t) & lifreq);
#ifdef SOLARIS_IPV6
  else if (ifp->flags & IFF_IPV6)
    ret = AF_IOCTL (AF_INET6, SIOCGLIFMETRIC, (caddr_t) & lifreq);
#endif /* SOLARIS_IPV6 */
  else
    ret = -1;
    
  if (ret < 0)
    return;

  ifp->metric = lifreq.lifr_metric;

  if (ifp->metric == 0)
    ifp->metric = 1;
}
Example #2
0
/* Set interface flags */
int if_set_flags(struct interface *ifp, uint64_t flags)
{
	int ret;
	struct lifreq lifreq;

	lifreq_set_name(&lifreq, ifp->name);

	lifreq.lifr_flags = ifp->flags;
	lifreq.lifr_flags |= flags;

	if (ifp->flags & IFF_IPV4)
		ret = AF_IOCTL(AF_INET, SIOCSLIFFLAGS, (caddr_t)&lifreq);
	else if (ifp->flags & IFF_IPV6)
		ret = AF_IOCTL(AF_INET6, SIOCSLIFFLAGS, (caddr_t)&lifreq);
	else
		ret = -1;

	if (ret < 0)
		zlog_info("can't set interface flags on %s: %s", ifp->name,
			  safe_strerror(errno));
	else
		ret = 0;

	return ret;
}
Example #3
0
/* Get interface's index by ioctl. */
static int
if_get_index (struct interface *ifp)
{
  int ret;
  struct lifreq lifreq;

  lifreq_set_name (&lifreq, ifp->name);

  if (ifp->flags & IFF_IPV4)
    ret = AF_IOCTL (AF_INET, SIOCGLIFINDEX, (caddr_t) & lifreq);
  else if (ifp->flags & IFF_IPV6)
    ret = AF_IOCTL (AF_INET6, SIOCGLIFINDEX, (caddr_t) & lifreq);
  else
    ret = -1;

  if (ret < 0)
    {
      zlog_warn ("SIOCGLIFINDEX(%s) failed", ifp->name);
      return ret;
    }

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

}
/* Unset interface's flag. */
int
if_unset_flags (struct interface_FOO *ifp, uint64_t flags)
{
  int ret;
  struct lifreq lifreq;

  lifreq_set_name (&lifreq, ifp->name);

  lifreq.lifr_flags = ifp->flags;
  lifreq.lifr_flags &= ~flags;

  if (ifp->flags & IFF_IPV4)
    ret = AF_IOCTL (AF_INET, SIOCSLIFFLAGS, (caddr_t) & lifreq);
  else if (ifp->flags & IFF_IPV6)
    ret = AF_IOCTL (AF_INET6, SIOCSLIFFLAGS, (caddr_t) & lifreq);
  else
    ret = -1;

  if (ret < 0)
    zlog_info ("can't unset interface flags");
  else
    ret = 0;
  
  return ret;
}
Example #5
0
/* get interface MTU */
void
if_get_mtu (struct interface *ifp)
{
  struct lifreq lifreq;
  int ret;
  u_char changed = 0;
  
  if (ifp->flags & IFF_IPV4)
    {
      lifreq_set_name (&lifreq, ifp->name);
      ret = AF_IOCTL (AF_INET, SIOCGLIFMTU, (caddr_t) & lifreq);
      if (ret < 0)
        {
          zlog_info ("Can't lookup mtu on %s by ioctl(SIOCGLIFMTU)",
                     ifp->name);
          ifp->mtu = -1;
        }
      else
        {
          ifp->mtu = lifreq.lifr_metric;
          changed = 1;
        }
    }

#ifdef HAVE_IPV6
  if (ifp->flags & IFF_IPV6)
  {
    memset(&lifreq, 0, sizeof(lifreq));
    lifreq_set_name (&lifreq, ifp->name);

    ret = AF_IOCTL (AF_INET6, SIOCGLIFMTU, (caddr_t) & lifreq);
    if (ret < 0)
    {
      zlog_info ("Can't lookup mtu6 on %s by ioctl(SIOCGIFMTU)", ifp->name);
      ifp->mtu6 = -1;
    }
    else
    {
      ifp->mtu6 = lifreq.lifr_metric;
      changed = 1;
    }
  }
#endif /* HAVE_IPV6 */

  if (changed)
    zebra_interface_up_update(ifp);
}
Example #6
0
/* Get just the flags for the given name.
 * Used by the normal 'if_get_flags' function, as well
 * as the bootup interface-list code, which has to peek at per-address
 * flags in order to figure out which ones should be ignored..
 */
int if_get_flags_direct(const char *ifname, uint64_t *flags, unsigned int af)
{
	struct lifreq lifreq;
	int ret;

	lifreq_set_name(&lifreq, ifname);

	ret = AF_IOCTL(af, SIOCGLIFFLAGS, (caddr_t)&lifreq);

	if (ret)
		zlog_debug("%s: ifname %s, error %s (%d)", __func__, ifname,
			   safe_strerror(errno), errno);

	*flags = lifreq.lifr_flags;

	return ret;
}
Example #7
0
/* Retrieve address information for the given ifp */
static int
if_get_addr (struct interface *ifp, struct sockaddr *addr, const char *label)
{
  int ret;
  struct lifreq lifreq;
  struct sockaddr_storage mask, dest;
  char *dest_pnt = NULL;
  u_char prefixlen = 0;
  afi_t af;
  int flags = 0;

  /* Interface's name and address family.
   * We need to use the logical interface name / label, if we've been
   * given one, in order to get the right address
   */
  strncpy (lifreq.lifr_name, (label ? label : ifp->name), IFNAMSIZ);

  /* Interface's address. */
  memcpy (&lifreq.lifr_addr, addr, ADDRLEN (addr));
  af = addr->sa_family;

  /* Point to point or broad cast address pointer init. */
  dest_pnt = NULL;

  if (AF_IOCTL (af, SIOCGLIFDSTADDR, (caddr_t) & lifreq) >= 0)
    {
      memcpy (&dest, &lifreq.lifr_dstaddr, ADDRLEN (addr));
      if (af == AF_INET)
        dest_pnt = (char *) &(SIN (&dest)->sin_addr);
      else
        dest_pnt = (char *) &(SIN6 (&dest)->sin6_addr);
      flags = ZEBRA_IFA_PEER;
    }

  if (af == AF_INET)
    {
      ret = if_ioctl (SIOCGLIFNETMASK, (caddr_t) & lifreq);
      
      if (ret < 0)
        {
          if (errno != EADDRNOTAVAIL)
            {
              zlog_warn ("SIOCGLIFNETMASK (%s) fail: %s", ifp->name,
                         safe_strerror (errno));
              return ret;
            }
          return 0;
        }
      memcpy (&mask, &lifreq.lifr_addr, ADDRLEN (addr));

      prefixlen = ip_masklen (SIN (&mask)->sin_addr);
      if (!dest_pnt && (if_ioctl (SIOCGLIFBRDADDR, (caddr_t) & lifreq) >= 0))
	{
          memcpy (&dest, &lifreq.lifr_broadaddr, sizeof (struct sockaddr_in));
          dest_pnt = (char *) &SIN (&dest)->sin_addr;
        }
    }
#ifdef HAVE_IPV6
  else if (af == AF_INET6)
    {
      if (if_ioctl_ipv6 (SIOCGLIFSUBNET, (caddr_t) & lifreq) < 0)
	{
	  if (ifp->flags & IFF_POINTOPOINT)
	    prefixlen = IPV6_MAX_BITLEN;
	  else
	    zlog_warn ("SIOCGLIFSUBNET (%s) fail: %s",
		       ifp->name, safe_strerror (errno));
	}
      else
	{
	  prefixlen = lifreq.lifr_addrlen;
	}
    }
#endif /* HAVE_IPV6 */

  /* Set address to the interface. */
  if (af == AF_INET)
    connected_add_ipv4 (ifp, flags, &SIN (addr)->sin_addr, prefixlen,
                        (struct in_addr *) dest_pnt, label);
#ifdef HAVE_IPV6
  else if (af == AF_INET6)
    connected_add_ipv6 (ifp, flags, &SIN6 (addr)->sin6_addr, prefixlen,
                        (struct in6_addr *) dest_pnt, label);
#endif /* HAVE_IPV6 */

  return 0;
}