Example #1
0
File: prefix.c Project: yubo/quagga
in_addr_t ipv4_network_addr(in_addr_t hostaddr, int masklen)
{
	struct in_addr mask;

	masklen2ip(masklen, &mask);
	return hostaddr & mask.s_addr;
}
Example #2
0
/* Apply mask to IPv4 prefix (network byte order). */
void
apply_mask_ipv4 (struct prefix_ipv4 *p)
{
  struct in_addr mask;
  masklen2ip(p->prefixlen, &mask);
  p->prefix.s_addr &= mask.s_addr;
}
Example #3
0
/* Set up interface's IP address, netmask (and broadcas? ).  *BSD may
   has ifaliasreq structure.  */
int
if_unset_prefix (struct interface *ifp, struct connected *ifc)
{
  int ret;
  struct ifaliasreq addreq;
  struct sockaddr_in addr;
  struct sockaddr_in mask;
  struct prefix_ipv4 *p;

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

  memset (&addreq, 0, sizeof addreq);
  strncpy ((char *)&addreq.ifra_name, ifp->name, sizeof addreq.ifra_name);

  memset (&addr, 0, sizeof (struct sockaddr_in));
  addr.sin_addr = p->prefix;
  addr.sin_family = p->family;
#ifdef HAVE_SIN_LEN
  addr.sin_len = sizeof (struct sockaddr_in);
#endif
  memcpy (&addreq.ifra_addr, &addr, sizeof (struct sockaddr_in));

  memset (&mask, 0, sizeof (struct sockaddr_in));
  masklen2ip (p->prefixlen, &mask.sin_addr);
  mask.sin_family = p->family;
#ifdef HAVE_SIN_LEN
  mask.sin_len = sizeof (struct sockaddr_in);
#endif
  memcpy (&addreq.ifra_mask, &mask, sizeof (struct sockaddr_in));
  
  ret = if_ioctl (SIOCDIFADDR, (caddr_t) &addreq);
  if (ret < 0)
    return ret;
  return 0;
}
Example #4
0
File: ioctl.c Project: ton31337/frr
/* Set up interface's address, netmask (and broadcas? ).  Linux or
   Solaris uses ifname:number semantics to set IP address aliases. */
int if_set_prefix_ctx(const struct zebra_dplane_ctx *ctx)
{
	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 *)dplane_ctx_get_intf_addr(ctx);

	ifaddr = *p;

	strlcpy(ifreq.ifr_name, dplane_ctx_get_ifname(ctx),
		sizeof(ifreq.ifr_name));

	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 (dplane_ctx_intf_is_broadcast(ctx)) {
		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_addr, &mask, sizeof(struct sockaddr_in));
#endif /* SUNOS5 */
	ret = if_ioctl(SIOCSIFNETMASK, (caddr_t)&ifreq);
	if (ret < 0)
		return ret;

	return 0;
}
Example #5
0
File: prefix.c Project: yubo/quagga
in_addr_t ipv4_broadcast_addr(in_addr_t hostaddr, int masklen)
{
	struct in_addr mask;

	masklen2ip(masklen, &mask);
	return (masklen != IPV4_MAX_PREFIXLEN - 1) ?
	    /* normal case */
	    (hostaddr | ~mask.s_addr) :
	    /* special case for /31 */
	    (hostaddr ^ ~mask.s_addr);
}
Example #6
0
/* Set up interface's address, netmask (and broadcast? ).
   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;

	strncpy(ifreq.ifr_name, ifp->name, IFNAMSIZ);

	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 /* SUNOS_5 */
	ret = if_ioctl(SIOCSIFNETMASK, (caddr_t)&ifreq);

	return ((ret < 0) ? ret : 0);
}
Example #7
0
File: ioctl.c Project: ton31337/frr
/*
 * Helper for interface-addr install, non-netlink
 */
static int if_set_prefix_ctx(const struct zebra_dplane_ctx *ctx)
{
	int ret;
	struct ifaliasreq addreq;
	struct sockaddr_in addr, mask, peer;
	struct prefix_ipv4 *p;

	p = (struct prefix_ipv4 *)dplane_ctx_get_intf_addr(ctx);

	memset(&addreq, 0, sizeof(addreq));
	strlcpy((char *)&addreq.ifra_name, dplane_ctx_get_ifname(ctx),
		sizeof(addreq.ifra_name));

	memset(&addr, 0, sizeof(struct sockaddr_in));
	addr.sin_addr = p->prefix;
	addr.sin_family = p->family;
#ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
	addr.sin_len = sizeof(struct sockaddr_in);
#endif
	memcpy(&addreq.ifra_addr, &addr, sizeof(struct sockaddr_in));

	if (dplane_ctx_intf_is_connected(ctx)) {
		p = (struct prefix_ipv4 *)dplane_ctx_get_intf_dest(ctx);
		memset(&mask, 0, sizeof(struct sockaddr_in));
		peer.sin_addr = p->prefix;
		peer.sin_family = p->family;
#ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
		peer.sin_len = sizeof(struct sockaddr_in);
#endif
		memcpy(&addreq.ifra_broadaddr, &peer,
		       sizeof(struct sockaddr_in));
	}

	memset(&mask, 0, sizeof(struct sockaddr_in));
	masklen2ip(p->prefixlen, &mask.sin_addr);
	mask.sin_family = p->family;
#ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
	mask.sin_len = sizeof(struct sockaddr_in);
#endif
	memcpy(&addreq.ifra_mask, &mask, sizeof(struct sockaddr_in));

	ret = if_ioctl(SIOCAIFADDR, (caddr_t)&addreq);
	if (ret < 0)
		return ret;
	return 0;

}
Example #8
0
/* Interface between zebra message and rtm message. */
static int
kernel_rtm_ipv4(int cmd, struct prefix *p, struct rib *rib, int family)
{
	struct sockaddr_in *mask = NULL;
	struct sockaddr_in sin_dest, sin_mask, sin_gate;
	struct nexthop *nexthop, *tnexthop;
	int recursing;
	int nexthop_num = 0;
	unsigned int ifindex = 0;
	int gate = 0;
	int error;
	char prefix_buf[INET_ADDRSTRLEN];

	if (IS_ZEBRA_DEBUG_RIB)
		inet_ntop(AF_INET, &p->u.prefix, prefix_buf, INET_ADDRSTRLEN);
	memset(&sin_dest, 0, sizeof(struct sockaddr_in));
	sin_dest.sin_family = AF_INET;
#ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
	sin_dest.sin_len = sizeof(struct sockaddr_in);
#endif /* HAVE_STRUCT_SOCKADDR_IN_SIN_LEN */
	sin_dest.sin_addr = p->u.prefix4;

	memset(&sin_mask, 0, sizeof(struct sockaddr_in));

	memset(&sin_gate, 0, sizeof(struct sockaddr_in));
	sin_gate.sin_family = AF_INET;
#ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
	sin_gate.sin_len = sizeof(struct sockaddr_in);
#endif /* HAVE_STRUCT_SOCKADDR_IN_SIN_LEN */

	/* Make gateway. */
	for (ALL_NEXTHOPS_RO(rib->nexthop, nexthop, tnexthop, recursing)) {
		if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_RECURSIVE))
			continue;

		gate = 0;
		char gate_buf[INET_ADDRSTRLEN] = "NULL";

		/*
		 * XXX We need to refrain from kernel operations in some cases,
		 * but this if statement seems overly cautious - what about
		 * other than ADD and DELETE?
		 */
		if ((cmd == RTM_ADD
		     && CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE))
		    || (cmd == RTM_DELETE
			&& CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_FIB)
		    )) {
			if (nexthop->type == NEXTHOP_TYPE_IPV4 ||
			    nexthop->type == NEXTHOP_TYPE_IPV4_IFINDEX) {
				sin_gate.sin_addr = nexthop->gate.ipv4;
				gate = 1;
			}
			if (nexthop->type == NEXTHOP_TYPE_IFINDEX
			    || nexthop->type == NEXTHOP_TYPE_IFNAME
			    || nexthop->type == NEXTHOP_TYPE_IPV4_IFINDEX)
				ifindex = nexthop->ifindex;
			if (nexthop->type == NEXTHOP_TYPE_BLACKHOLE) {
				struct in_addr loopback;
				loopback.s_addr = htonl(INADDR_LOOPBACK);
				sin_gate.sin_addr = loopback;
				gate = 1;
			}

			if (gate && p->prefixlen == 32)
				mask = NULL;
			else {
				masklen2ip(p->prefixlen, &sin_mask.sin_addr);
				sin_mask.sin_family = AF_INET;
#ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
				sin_mask.sin_len =
				    sin_masklen(sin_mask.sin_addr);
#endif /* HAVE_STRUCT_SOCKADDR_IN_SIN_LEN */
				mask = &sin_mask;
			}

			error = rtm_write(cmd,
					  (union sockunion *)&sin_dest,
					  (union sockunion *)mask,
					  gate ? (union sockunion *)&sin_gate :
					  NULL, ifindex, rib->flags,
					  rib->metric);

			if (IS_ZEBRA_DEBUG_RIB) {
				if (!gate) {
					zlog_debug
					    ("%s: %s/%d: attention! gate not found for rib %p",
					     __func__, prefix_buf, p->prefixlen,
					     rib);
					rib_dump(p, rib);
				} else
					inet_ntop(AF_INET, &sin_gate.sin_addr,
						  gate_buf, INET_ADDRSTRLEN);
			}

			switch (error) {
				/* We only flag nexthops as being in FIB if rtm_write() did its work. */
			case ZEBRA_ERR_NOERROR:
				nexthop_num++;
				if (IS_ZEBRA_DEBUG_RIB)
					zlog_debug
					    ("%s: %s/%d: successfully did NH %s",
					     __func__, prefix_buf, p->prefixlen,
					     gate_buf);
				if (cmd == RTM_ADD)
					SET_FLAG(nexthop->flags,
						 NEXTHOP_FLAG_FIB);
				break;

				/* The only valid case for this error is kernel's failure to install
				 * a multipath route, which is common for FreeBSD. This should be
				 * ignored silently, but logged as an error otherwise.
				 */
			case ZEBRA_ERR_RTEXIST:
				if (cmd != RTM_ADD)
					zlog_err
					    ("%s: rtm_write() returned %d for command %d",
					     __func__, error, cmd);
				continue;
				break;

				/* Given that our NEXTHOP_FLAG_FIB matches real kernel FIB, it isn't
				 * normal to get any other messages in ANY case.
				 */
			case ZEBRA_ERR_RTNOEXIST:
			case ZEBRA_ERR_RTUNREACH:
			default:
				/* This point is reachable regardless of debugging mode. */
				if (!IS_ZEBRA_DEBUG_RIB)
					inet_ntop(AF_INET, &p->u.prefix,
						  prefix_buf, INET_ADDRSTRLEN);
				zlog_err
				    ("%s: %s/%d: rtm_write() unexpectedly returned %d for command %s",
				     __func__, prefix_buf, p->prefixlen, error,
				     lookup(rtm_type_str, cmd));
				break;
			}
		} /* if (cmd and flags make sense) */
		else if (IS_ZEBRA_DEBUG_RIB)
			zlog_debug("%s: odd command %s for flags %d",
				   __func__, lookup(rtm_type_str, cmd),
				   nexthop->flags);
	}			/* for (ALL_NEXTHOPS_RO(...)) */

	/* If there was no useful nexthop, then complain. */
	if (nexthop_num == 0 && IS_ZEBRA_DEBUG_KERNEL)
		zlog_debug("%s: No useful nexthops were found in RIB entry %p",
			   __func__, rib);

	return 0;
 /*XXX*/}
Example #9
0
u_char *
ipFwTable (struct variable *v, oid objid[], size_t *objid_len,
	   int exact, size_t *val_len, WriteMethod **write_method)
{
  struct route_node *np;
  struct rib *rib;
  static int result;
  static int resarr[2];
  static struct in_addr netmask;
  struct nexthop *nexthop;

  get_fwtable_route_node(v, objid, objid_len, exact, &np, &rib);
  if (!np)
    return NULL;

  nexthop = rib->nexthop;
  if (! nexthop)
    return NULL;

  switch (v->magic)
    {
    case IPFORWARDDEST:
      *val_len = 4;
      return &np->p.u.prefix;
      break;
    case IPFORWARDMASK:
      masklen2ip(np->p.prefixlen, &netmask);
      *val_len = 4;
      return (u_char *)&netmask;
      break;
    case IPFORWARDPOLICY:
      result = 0;
      *val_len  = sizeof(int);
      return (u_char *)&result;
      break;
    case IPFORWARDNEXTHOP:
      *val_len = 4;
      return (u_char *)&nexthop->gate.ipv4;
      break;
    case IPFORWARDIFINDEX:
      *val_len = sizeof(int);
      return (u_char *)&nexthop->ifindex;
      break;
    case IPFORWARDTYPE:
      if (nexthop->type == NEXTHOP_TYPE_IFINDEX
	  || nexthop->type == NEXTHOP_TYPE_IFNAME)
        result = 3;
      else
        result = 4;
      *val_len  = sizeof(int);
      return (u_char *)&result;
      break;
    case IPFORWARDPROTO:
      result = proto_trans(rib->type);
      *val_len  = sizeof(int);
      return (u_char *)&result;
      break;
    case IPFORWARDAGE:
      result = 0;
      *val_len  = sizeof(int);
      return (u_char *)&result;
      break;
    case IPFORWARDINFO:
      resarr[0] = 0;
      resarr[1] = 0;
      *val_len  = 2 * sizeof(int);
      return (u_char *)resarr;
      break;
    case IPFORWARDNEXTHOPAS:
      result = -1;
      *val_len  = sizeof(int);
      return (u_char *)&result;
      break;
    case IPFORWARDMETRIC1:
      result = 0;
      *val_len  = sizeof(int);
      return (u_char *)&result;
      break;
    case IPFORWARDMETRIC2:
      result = 0;
      *val_len  = sizeof(int);
      return (u_char *)&result;
      break;
    case IPFORWARDMETRIC3:
      result = 0;
      *val_len  = sizeof(int);
      return (u_char *)&result;
      break;
    case IPFORWARDMETRIC4:
      result = 0;
      *val_len  = sizeof(int);
      return (u_char *)&result;
      break;
    case IPFORWARDMETRIC5:
      result = 0;
      *val_len  = sizeof(int);
      return (u_char *)&result;
      break;
    default:
      return NULL;
      break;
    }  
  return NULL;
}
Example #10
0
/* Interface between zebra message and rtm message. */
static int
kernel_rtm_ipv4 (int cmd, struct prefix *p, struct rib *rib, int family)

{
  struct sockaddr_in *mask = NULL;
  struct sockaddr_in sin_dest, sin_mask, sin_gate;
  struct nexthop *nexthop;
  int nexthop_num = 0;
  unsigned int ifindex = 0;
  int gate = 0;
  int error;

  memset (&sin_dest, 0, sizeof (struct sockaddr_in));
  sin_dest.sin_family = AF_INET;
#ifdef HAVE_SIN_LEN
  sin_dest.sin_len = sizeof (struct sockaddr_in);
#endif /* HAVE_SIN_LEN */
  sin_dest.sin_addr = p->u.prefix4;

  memset (&sin_mask, 0, sizeof (struct sockaddr_in));

  memset (&sin_gate, 0, sizeof (struct sockaddr_in));
  sin_gate.sin_family = AF_INET;
#ifdef HAVE_SIN_LEN
  sin_gate.sin_len = sizeof (struct sockaddr_in);
#endif /* HAVE_SIN_LEN */

  /* Make gateway. */
  for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
    {
      gate = 0;

      if ((cmd == RTM_ADD
	   && CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE))
	  || (cmd == RTM_DELETE
#if 0
	      && CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB)
#endif
	      ))
	{
	  if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE))
	    {
	      if (nexthop->rtype == NEXTHOP_TYPE_IPV4 ||
		  nexthop->rtype == NEXTHOP_TYPE_IPV4_IFINDEX)
		{
		  sin_gate.sin_addr = nexthop->rgate.ipv4;
		  gate = 1;
		}
	      if (nexthop->rtype == NEXTHOP_TYPE_IFINDEX
		  || nexthop->rtype == NEXTHOP_TYPE_IFNAME
		  || nexthop->rtype == NEXTHOP_TYPE_IPV4_IFINDEX)
		ifindex = nexthop->rifindex;
	    }
	  else
	    {
	      if (nexthop->type == NEXTHOP_TYPE_IPV4 ||
		  nexthop->type == NEXTHOP_TYPE_IPV4_IFINDEX)
		{
		  sin_gate.sin_addr = nexthop->gate.ipv4;
		  gate = 1;
		}
	      if (nexthop->type == NEXTHOP_TYPE_IFINDEX
		  || nexthop->type == NEXTHOP_TYPE_IFNAME
		  || nexthop->type == NEXTHOP_TYPE_IPV4_IFINDEX)
		ifindex = nexthop->ifindex;
	  if (nexthop->type == NEXTHOP_TYPE_BLACKHOLE)
      {
        struct in_addr loopback;
        loopback.s_addr = htonl (INADDR_LOOPBACK);
        sin_gate.sin_addr = loopback;
        gate = 1;
      }
	  }

	  if (cmd == RTM_ADD)
	    SET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);

	  if (gate && p->prefixlen == 32)
	    mask = NULL;
	  else
	    {
	      masklen2ip (p->prefixlen, &sin_mask.sin_addr);
	      sin_mask.sin_family = AF_INET;
#ifdef HAVE_SIN_LEN
	      sin_mask.sin_len = sin_masklen (sin_mask.sin_addr);
#endif /* HAVE_SIN_LEN */
	      mask = &sin_mask;
	    }
	}

      error = rtm_write (cmd,
			(union sockunion *)&sin_dest, 
			(union sockunion *)mask, 
			gate ? (union sockunion *)&sin_gate : NULL,
			ifindex,
			rib->flags,
			rib->metric);

#if 0
      if (error)
	{
	  zlog_info ("kernel_rtm_ipv4(): nexthop %d add error=%d.",
	    nexthop_num, error);
	}
#endif

      nexthop_num++;
    }

  /* If there is no useful nexthop then return. */
  if (nexthop_num == 0)
    {
      if (IS_ZEBRA_DEBUG_KERNEL)
	zlog_debug ("kernel_rtm_ipv4(): No useful nexthop.");
      return 0;
    }

  return 0; /*XXX*/
}
Example #11
0
/* Interface to ioctl route message. */
int
kernel_add_route (struct prefix_ipv4 *dest, struct in_addr *gate,
		  int index, int flags)
{
  int ret;
  int sock;
  struct rtentry rtentry;
  struct sockaddr_in sin_dest, sin_mask, sin_gate;

  memset (&rtentry, 0, sizeof (struct rtentry));

  /* Make destination. */
  memset (&sin_dest, 0, sizeof (struct sockaddr_in));
  sin_dest.sin_family = AF_INET;
#ifdef HAVE_SIN_LEN
  sin_dest.sin_len = sizeof (struct sockaddr_in);
#endif /* HAVE_SIN_LEN */
  sin_dest.sin_addr = dest->prefix;

  /* Make gateway. */
  if (gate)
    {
      memset (&sin_gate, 0, sizeof (struct sockaddr_in));
      sin_gate.sin_family = AF_INET;
#ifdef HAVE_SIN_LEN
      sin_gate.sin_len = sizeof (struct sockaddr_in);
#endif /* HAVE_SIN_LEN */
      sin_gate.sin_addr = *gate;
    }

  memset (&sin_mask, 0, sizeof (struct sockaddr_in));
  sin_mask.sin_family = AF_INET;
#ifdef HAVE_SIN_LEN
      sin_gate.sin_len = sizeof (struct sockaddr_in);
#endif /* HAVE_SIN_LEN */
  masklen2ip (dest->prefixlen, &sin_mask.sin_addr);

  /* Set destination address, mask and gateway.*/
  memcpy (&rtentry.rt_dst, &sin_dest, sizeof (struct sockaddr_in));
  if (gate)
    memcpy (&rtentry.rt_gateway, &sin_gate, sizeof (struct sockaddr_in));
#ifndef SUNOS_5
  memcpy (&rtentry.rt_genmask, &sin_mask, sizeof (struct sockaddr_in));
#endif /* SUNOS_5 */

  /* Routing entry flag set. */
  if (dest->prefixlen == 32)
    rtentry.rt_flags |= RTF_HOST;

  if (gate && gate->s_addr != INADDR_ANY)
    rtentry.rt_flags |= RTF_GATEWAY;

  rtentry.rt_flags |= RTF_UP;

  /* Additional flags */
  rtentry.rt_flags |= flags;


  /* For tagging route. */
  /* rtentry.rt_flags |= RTF_DYNAMIC; */

  /* Open socket for ioctl. */
  sock = socket (AF_INET, SOCK_DGRAM, 0);
  if (sock < 0)
    {
      zlog_warn ("can't make socket\n");
      return -1;
    }

  /* Send message by ioctl(). */
  ret = ioctl (sock, SIOCADDRT, &rtentry);
  if (ret < 0)
    {
      switch (errno) 
	{
	case EEXIST:
	  close (sock);
	  return ZEBRA_ERR_RTEXIST;
	  break;
	case ENETUNREACH:
	  close (sock);
	  return ZEBRA_ERR_RTUNREACH;
	  break;
	case EPERM:
	  close (sock);
	  return ZEBRA_ERR_EPERM;
	  break;
	}

      close (sock);
      zlog_warn ("write : %s (%d)", strerror (errno), errno);
      return 1;
    }
  close (sock);

  return ret;
}
Example #12
0
/* Interface to ioctl route message. */
int
kernel_ioctl_ipv4 (u_long cmd, struct prefix *p, struct rib *rib, int family)
{
  int ret;
  int sock;
  struct rtentry rtentry;
  struct sockaddr_in sin_dest, sin_mask, sin_gate;
  struct nexthop *nexthop;
  int nexthop_num = 0;
  struct interface *ifp;

  memset (&rtentry, 0, sizeof (struct rtentry));

  /* Make destination. */
  memset (&sin_dest, 0, sizeof (struct sockaddr_in));
  sin_dest.sin_family = AF_INET;
#ifdef HAVE_SIN_LEN
  sin_dest.sin_len = sizeof (struct sockaddr_in);
#endif /* HAVE_SIN_LEN */
  sin_dest.sin_addr = p->u.prefix4;

  if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_BLACKHOLE))
    {
      SET_FLAG (rtentry.rt_flags, RTF_REJECT);

      if (cmd == SIOCADDRT)
	for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
	  SET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);

      goto skip;
    }

  memset (&sin_gate, 0, sizeof (struct sockaddr_in));

  /* Make gateway. */
  for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
    {
      if ((cmd == SIOCADDRT 
	   && CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE))
	  || (cmd == SIOCDELRT
	      && CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB)))
	{
	  if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE))
	    {
	      if (nexthop->rtype == NEXTHOP_TYPE_IPV4 ||
		  nexthop->rtype == NEXTHOP_TYPE_IPV4_IFINDEX)
		{
		  sin_gate.sin_family = AF_INET;
#ifdef HAVE_SIN_LEN
		  sin_gate.sin_len = sizeof (struct sockaddr_in);
#endif /* HAVE_SIN_LEN */
		  sin_gate.sin_addr = nexthop->rgate.ipv4;
		  rtentry.rt_flags |= RTF_GATEWAY;
		}
	      if (nexthop->rtype == NEXTHOP_TYPE_IFINDEX
		  || nexthop->rtype == NEXTHOP_TYPE_IFNAME)
		{
		  ifp = if_lookup_by_index (nexthop->rifindex);
		  if (ifp)
		    rtentry.rt_dev = ifp->name;
		  else
		    return -1;
		}
	    }
	  else
	    {
	      if (nexthop->type == NEXTHOP_TYPE_IPV4 ||
		  nexthop->type == NEXTHOP_TYPE_IPV4_IFINDEX)
		{
		  sin_gate.sin_family = AF_INET;
#ifdef HAVE_SIN_LEN
		  sin_gate.sin_len = sizeof (struct sockaddr_in);
#endif /* HAVE_SIN_LEN */
		  sin_gate.sin_addr = nexthop->gate.ipv4;
		  rtentry.rt_flags |= RTF_GATEWAY;
		}
	      if (nexthop->type == NEXTHOP_TYPE_IFINDEX
		  || nexthop->type == NEXTHOP_TYPE_IFNAME)
		{
		  ifp = if_lookup_by_index (nexthop->ifindex);
		  if (ifp)
		    rtentry.rt_dev = ifp->name;
		  else
		    return -1;
		}
	    }

	  if (cmd == SIOCADDRT)
	    SET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);

	  nexthop_num++;
	  break;
	}
    }

  /* If there is no useful nexthop then return. */
  if (nexthop_num == 0)
    {
      if (IS_ZEBRA_DEBUG_KERNEL)
	zlog_info ("netlink_route_multipath(): No useful nexthop.");
      return 0;
    }

 skip:

  memset (&sin_mask, 0, sizeof (struct sockaddr_in));
  sin_mask.sin_family = AF_INET;
#ifdef HAVE_SIN_LEN
  sin_mask.sin_len = sizeof (struct sockaddr_in);
#endif /* HAVE_SIN_LEN */
  masklen2ip (p->prefixlen, &sin_mask.sin_addr);

  /* Set destination address, mask and gateway.*/
  memcpy (&rtentry.rt_dst, &sin_dest, sizeof (struct sockaddr_in));

  if (rtentry.rt_flags & RTF_GATEWAY)
    memcpy (&rtentry.rt_gateway, &sin_gate, sizeof (struct sockaddr_in));

#ifndef SUNOS_5
  memcpy (&rtentry.rt_genmask, &sin_mask, sizeof (struct sockaddr_in));
#endif /* SUNOS_5 */

  /* Metric.  It seems metric minus one value is installed... */
  rtentry.rt_metric = rib->metric;

  /* Routing entry flag set. */
  if (p->prefixlen == 32)
    rtentry.rt_flags |= RTF_HOST;

  rtentry.rt_flags |= RTF_UP;

  /* Additional flags */
  /* rtentry.rt_flags |= flags; */

  /* For tagging route. */
  /* rtentry.rt_flags |= RTF_DYNAMIC; */

  /* Open socket for ioctl. */
  sock = socket (AF_INET, SOCK_DGRAM, 0);
  if (sock < 0)
    {
      zlog_warn ("can't make socket\n");
      return -1;
    }

  /* Send message by ioctl(). */
  ret = ioctl (sock, cmd, &rtentry);
  if (ret < 0)
    {
      switch (errno) 
	{
	case EEXIST:
	  close (sock);
	  return ZEBRA_ERR_RTEXIST;
	  break;
	case ENETUNREACH:
	  close (sock);
	  return ZEBRA_ERR_RTUNREACH;
	  break;
	case EPERM:
	  close (sock);
	  return ZEBRA_ERR_EPERM;
	  break;
	}

      close (sock);
      zlog_warn ("write : %s (%d)", strerror (errno), errno);
      return ret;
    }
  close (sock);

  return ret;
}
Example #13
0
void rt_policy_for_logic_restore_dbtable(void)
{
    s32  i = 0;
    u32  count = 0;
	s32  sys_ret = 0;
    s32  sequence   = 0;
    u32  policyid   = 0;
    s8   *src       = NULL;
    s8   *dest      = NULL;
    s8   *iifname   = NULL;
    s32  protocol;
    s32  minsrcport, maxsrcport, mindstport, maxdstport;
    s32  flag       = 0;
    s32   tos       = 0;
    s8   sql_select[512] = {0};
    s32  iifindex;
    s32  sys_error_code  = 0;
    sqlite3_res     res  = NULL;
    rtp_logicplcy_s     add;
    struct prefix_ipv4  prefix_src;
    struct prefix_ipv4  prefix_dest;
    struct in_addr  srcmask;
    struct in_addr  dstmask;
    void *buffer = NULL;

    /*打开数据库连接*/
    if (NULL == db)
    {
        db = sqlite3_open_ex(1, DATABASE_RT_POLICY_PATH);
        if (NULL == db)
        {
            return;
        }
    }
    /*查询策略个数*/
    sprintf(sql_select, "select count(*) as count from tb_logic_policy;");
	if ( SQLITE_OK != sqlite3_exec_query_ex(db, sql_select, &res) )
    {
        goto lable_ret;
    }
    sqlite3_get_u32_ex(res, 0, "count", &count);
	sqlite3_res_free_ex(res);
	res = NULL;
    if(0 == count)
    {
        goto lable_ret;
    }

    /*按sequence排序*/
    sprintf(sql_select, "select * from tb_logic_policy order by sequence;");
	if ( SQLITE_OK != sqlite3_exec_query_ex(db, sql_select, &res) )
	{
        goto lable_ret;
	}
	for (i = 0; i <(s32) count; i++)
	{
        sqlite3_get_u32_ex(res, i, "policy_id", &policyid);

        sqlite3_get_str_ex(res, i, "src", &src);

        sqlite3_get_str_ex(res, i, "dest", &dest);

		sqlite3_get_str_ex(res, i, "iifname", &iifname);

        sqlite3_get_s32_ex(res, i, "tos", &tos);

        sqlite3_get_s32_ex(res, i, "protocol", &protocol);

        sqlite3_get_s32_ex(res, i, "minsrcport", &minsrcport);

        sqlite3_get_s32_ex(res, i, "maxsrcport", &maxsrcport);

        sqlite3_get_s32_ex(res, i, "mindstport", &mindstport);

        sqlite3_get_s32_ex(res, i, "maxdstport", &maxdstport);
        
        sqlite3_get_s32_ex(res, i, "flag", &flag);


        /*将公网地址由点分十进制转换为网络二进制数*/
        if (0 == str2prefix_ipv4(src, &prefix_src))
        {
            goto lable_ret;
        }
        if (0 == str2prefix_ipv4(dest, &prefix_dest))
        {
            goto lable_ret;
        }

        masklen2ip ((s32)prefix_src.prefixlen, &srcmask);
        prefix_src.prefix.s_addr &= srcmask.s_addr;
        masklen2ip ((s32)prefix_dest.prefixlen, &dstmask);
        prefix_dest.prefix.s_addr &= dstmask.s_addr;

        /*将接口名转换成接口索引*/
        if ((!strcmp("any", iifname))||(!strcmp("Any", iifname)))
        {
            iifindex = 0;
        }
        else
        {
            if (0 != if_get_index_by_name(iifname, &iifindex))
            {
                goto lable_ret;
            }
        }

        /*填充要向数据面发送的数据*/
        add.id            = policyid;
        add.src           = prefix_src.prefix.s_addr;
        add.srcmask       = srcmask.s_addr;
        add.dst           = prefix_dest.prefix.s_addr;
        add.dstmask       = dstmask.s_addr;
        add.iifindex      = iifindex;
        add.tos           = (u8)tos;
        add.protocol      = (u8)protocol;
        add.srcminportnum = (u16)minsrcport;
        add.srcmaxportnum = (u16)maxsrcport;
        add.dstminportnum = (u16)mindstport;
        add.dstmaxportnum = (u16)maxdstport;
        add.flag          = (u16)flag;

        buffer = malloc(sizeof(s32) + sizeof(rtp_logicplcy_s));
        if(NULL == buffer)
        {
            goto lable_ret;
        }
        *(s32 *)buffer = sequence;
        memcpy(buffer + sizeof(s32), &add, sizeof(rtp_logicplcy_s));

        sys_ret = conplat_syscall(MODULEID_RT_POLICY, RTP_LOGICPLCY_SYSCALL_ADD_OR_MODIFY, buffer, sizeof(s32) + sizeof(rtp_logicplcy_s), (s32*)&sys_error_code);
        /* 如果系统调用不成功,返回系统错误 */
	    if((0 != sys_error_code && 1 != sys_error_code) || 0 != sys_ret)
	    {
            goto lable_ret;
	    }

	    cpuproxy_list_item_addmod(sequence, &add);
	}

lable_ret:

    if (NULL != buffer)
    {
        free (buffer);
        buffer = NULL;
    }
	/*释放结果集*/
	if (NULL != res)
	{
	    sqlite3_res_free_ex(res);
		res = NULL;
    }
	return;
}
Example #14
0
/*******************************************************************************
函数名称  : rt_policy_restore_dbtable
函数功能  : 策略路由配置恢复
输入参数  : 无
输出参数  : 无
返回结果  : 无
--------------------------------------------------------------------------------
最近一次修改记录 :
修改作者	: wangchao
修改目的	:将策略路由配置恢复移至策略路由deamon进程
修改日期	: 2010年12月30日
*******************************************************************************/
void rt_policy_restore_dbtable(s32 listflag, u32 *dcdm_needed)
{
    s32  i = 0, j = 0;
    u32  count = 0;
	s32  sys_ret = 0;
    s32  sequence   = 0;
    u32  policyid   = 0;
    s8   *src       = NULL;
    s8   *dest      = NULL;
    s8   *iifname   = NULL;
    s8   *oifname;
    s8   *nexthop;
    s8   *weight;
    s32  nexthop_count, protocol, netappid;
    u32 flag = 0;
    s32  minsrcport, maxsrcport, mindstport, maxdstport;
    s8   *tos       = NULL;
    s8   sql_select[512] = {0};
    s8   tb_name[32] = {0};
    s32  iifindex;
    s32  sys_error_code  = 0;
    sqlite3_res     res  = NULL;
	rt_policy_s     add;
    struct prefix_ipv4  prefix_src = {0};
    struct prefix_ipv4  prefix_dest = {0};
	struct in_addr  nexthop_addr[RT_POLICY_MAX_NEXTHOP];
    struct in_addr  srcmask = {0};
    struct in_addr  dstmask = {0};
    u32 srcgroup = 0;
	u32 destgroup = 0;
    void *buffer = NULL;
    s8  oifname_str[RT_POLICY_MAX_NEXTHOP][20];
	s8  nexthop_str[RT_POLICY_MAX_NEXTHOP][100];
	s8  weight_str[RT_POLICY_MAX_NEXTHOP][10];
	s8  *str_point[3], *line_point[3];
	s32  oifindex[RT_POLICY_MAX_NEXTHOP];  
	s32  weightvalue[RT_POLICY_MAX_NEXTHOP]; 	

    switch (listflag)
    {
        case RT_POLICY_BEFORE_ROUTE:
            strcpy(tb_name, "tb_rt_policy_pre");
            break;
        case RT_POLICY_AFTER_ROUTE:
            strcpy(tb_name, "tb_rt_policy_aft");
            break;
        case RT_POLICY_LOCAL_ROUTE:
            strcpy(tb_name, "tb_rt_policy_loc");
            break;
        case RT_POLICY_PRE_LOCAL_ROUTE:
            strcpy(tb_name, "tb_rt_policy_pre_loc");
            break;
    }

    /*打开数据库连接*/
    if (NULL == db)
    {
        db = sqlite3_open_ex(2, DATABASE_RT_POLICY_PATH, "/config/db/netaddr_cfg.db");
        if (NULL == db)
        {
            return;
        }
    }
    /*查询策略个数*/
    sprintf(sql_select, "select count(*) as count from %s;", tb_name);
	sys_error_code = sqlite3_exec_query_ex(db, sql_select, &res);
	if ( SQLITE_OK != sys_error_code )
    {
        goto lable_ret;
    }
    sqlite3_get_u32_ex(res, 0, "count", &count);
	sqlite3_res_free_ex(res);
	res = NULL;
    if(0 == count)
    {
        goto lable_ret;
    }
    memset(sql_select, 0, 512);

    /*按sequence排序*/
    sprintf(sql_select, "select * from %s order by sequence;", tb_name);
	sys_error_code = sqlite3_exec_query_ex(db, sql_select, &res);
	if ( SQLITE_OK != sys_error_code )
	{
        goto lable_ret;
	}

    buffer = calloc(1, sizeof(s32) * 2 + sizeof(rt_policy_s));
    if(NULL == buffer)
    {
        goto lable_ret;
    }

    /*赋值*/
	for (i = 0; i <(s32) count; i++)
	{
        sqlite3_get_u32_ex(res, i, "policy_id", &policyid);

        sqlite3_get_str_ex(res, i, "src", &src);

        sqlite3_get_str_ex(res, i, "dest", &dest);

		sqlite3_get_str_ex(res, i, "iifname", &iifname);

        sqlite3_get_str_ex(res, i, "oifname", &oifname);

        sqlite3_get_str_ex(res, i, "nexthop", &nexthop);

        sqlite3_get_str_ex(res, i, "weight", &weight);

        sqlite3_get_str_ex(res, i, "tos", &tos);

        sqlite3_get_s32_ex(res, i, "nexthopcount", &nexthop_count);

        sqlite3_get_s32_ex(res, i, "netappid", &netappid);
        
        sqlite3_get_s32_ex(res, i, "protocol", &protocol);

        sqlite3_get_s32_ex(res, i, "minsrcport", &minsrcport);

        sqlite3_get_s32_ex(res, i, "maxsrcport", &maxsrcport);

        sqlite3_get_s32_ex(res, i, "mindstport", &mindstport);

        sqlite3_get_s32_ex(res, i, "maxdstport", &maxdstport);

        sqlite3_get_u32_ex(res, i, "flag", &flag);


		str_point[0] = oifname;
		str_point[1] = weight;
		str_point[2] = nexthop;
		/*解析下一跳信息*/
		for(j = 0; j < nexthop_count; j++)
		{
		   if(j != (nexthop_count - 1))
		   {
			  line_point[0] = static_strchr(str_point[0],';');
			  static_strncpy(oifname_str[j], str_point[0], line_point[0] - str_point[0]);
			  str_point[0] = line_point[0] + 1;
			  line_point[1] = static_strchr(str_point[1],';');  
			  static_strncpy(weight_str[j], str_point[1], line_point[1] - str_point[1]);	
			  str_point[1] = line_point[1] + 1;
			  line_point[2] = static_strchr(str_point[2],';');
			  static_strncpy(nexthop_str[j], str_point[2], line_point[2] - str_point[2]);	
			  str_point[2] = line_point[2] + 1;
		   }
		   else
		   {
			  line_point[0] = static_strchr(str_point[0],'\0');
			  static_strncpy(oifname_str[j], str_point[0], line_point[0] - str_point[0]);
			  line_point[1] = static_strchr(str_point[1],'\0');	 
			  static_strncpy(weight_str[j], str_point[1], line_point[1] - str_point[1]);	
			  line_point[2] = static_strchr(str_point[2],'\0');
			  static_strncpy(nexthop_str[j], str_point[2], line_point[2] - str_point[2]);	
		   }
		}
		for(j = 0; j < nexthop_count; j++)
		{
		   sys_error_code = if_get_index_by_name(oifname_str[j], &oifindex[j]);
		   if (sys_error_code != ERROR_SUCCESS)
		   {
			   goto lable_ret;
		   }
		   weightvalue[j] = atoi(weight_str[j]);
		   inet_aton (nexthop_str[j], &nexthop_addr[j]);	
		}
		for(; j < RT_POLICY_MAX_NEXTHOP; j++)
		{
			oifindex[j] = 0;
			nexthop_addr[j].s_addr = 0;
			weightvalue[j] = 0;
		}	



        /*将公网地址由点分十进制转换为网络二进制数*/
           if(flag & RT_POLICY_SRC_NETADDR_GROUP)
        {
            if (0 != netaddr_group_get_id_by_name(db, "",src, &srcgroup))
            {
		        flag &= (~RT_POLICY_SRC_NETADDR_GROUP);
		        prefix_src.prefix.s_addr = 0;
	        }
	        else
	        {
		        prefix_src.prefix.s_addr = srcgroup;
	        }
	        srcmask.s_addr = 0;
        }
        else
        {
	        sys_error_code = str2prefix_ipv4(src, &prefix_src);
	        if (sys_error_code <= 0)
	        {
	            goto lable_ret;
	        }
	        masklen2ip ((s32)prefix_src.prefixlen, &srcmask);
	        prefix_src.prefix.s_addr &= srcmask.s_addr;
        }

        if(flag & RT_POLICY_DST_NETADDR_GROUP)
        {
            if (0 != netaddr_group_get_id_by_name(db, "",dest, &destgroup))
            {
		        flag &= (~RT_POLICY_DST_NETADDR_GROUP);
		        prefix_dest.prefix.s_addr = 0;
	        }
	        else
	        {
		        prefix_dest.prefix.s_addr = destgroup;
	        }
	        dstmask.s_addr = 0;
        }
        else
        {
	        sys_error_code = str2prefix_ipv4(dest, &prefix_dest);
	        if (sys_error_code <= 0)
	        {
	            goto lable_ret;
	        }

	        masklen2ip ((s32)prefix_dest.prefixlen, &dstmask);
	        prefix_dest.prefix.s_addr &= dstmask.s_addr;
        }

        /*将接口名转换成接口索引*/
        if (!strcmp("any", iifname))
        {
            iifindex = 0;
        }
        else
        {
            sys_error_code = if_get_index_by_name(iifname, &iifindex);
            if (sys_error_code != 0)
            {
                goto lable_ret;
            }
        }

        /*填充要向数据面发送的数据*/
        add.id            = policyid;
        add.src           = prefix_src.prefix.s_addr;
        add.srcmask       = srcmask.s_addr;
        add.dst           = prefix_dest.prefix.s_addr;
        add.dstmask       = dstmask.s_addr;
        add.iifindex      = iifindex;
        add.nexthopcount  = (u8)nexthop_count;
		for(j = 0; j < RT_POLICY_MAX_NEXTHOP; j++)
		{
		   add.oifindex[j] = oifindex[j];
		   add.nexthop[j]  = nexthop_addr[j].s_addr;
		   add.weight[j]   = (u8)weightvalue[j];
		   add.nhflag[j]   = 0;
		}
        add.tos           = (u8)atoi(tos);
        add.netappid      = (u32)netappid;
        add.protocol      = (u8)protocol;
        add.srcminportnum = (u16)minsrcport;
        add.srcmaxportnum = (u16)maxsrcport;
        add.dstminportnum = (u16)mindstport;
        add.dstmaxportnum = (u16)maxdstport;
        add.flag          =  flag;

        memcpy(buffer, &listflag, sizeof(s32));
        memcpy(buffer + sizeof(s32), &sequence, sizeof(s32));
        memcpy(buffer + sizeof(s32) * 2, &add, sizeof(rt_policy_s));

        sys_ret = conplat_syscall(MODULEID_RT_POLICY, RT_POLICY_SYSCALL_ADD_OR_MODIFY, buffer, 2 * sizeof(s32) + sizeof(rt_policy_s), (s32*)&sys_error_code);
        /* 如果系统调用不成功,返回系统错误 */
	    if((0 != sys_error_code && 1 != sys_error_code) || 0 != sys_ret)
	    {
            goto lable_ret;
	    }

        if ( (0 != netappid) && (0 == *dcdm_needed) )
        {
            *dcdm_needed = 1;
        }
            

	    if(RT_POLICY_BEFORE_ROUTE == listflag)
	    {
	        /* ignore the return value here */
	        rtpolicy_list_item_addmod(sequence, &add);
	        neighindex_list_item_add(&add);
	    }
	}

lable_ret:

    if (NULL != buffer)
    {
        free (buffer);
        buffer = NULL;
    }
	/*释放结果集*/
	if (NULL != res)
	{
	    sqlite3_res_free_ex(res);
		res = NULL;
    }
	return;
}