Пример #1
0
void connected_down_ipv4(struct interface *ifp, struct connected *ifc)
{
	struct prefix_ipv4 p;

	if (!CHECK_FLAG(ifc->conf, ZEBRA_IFC_REAL))
		return;

	PREFIX_COPY_IPV4(&p, CONNECTED_PREFIX(ifc));

	/* Apply mask to the network. */
	apply_mask_ipv4(&p);

	/* In case of connected address is 0.0.0.0/0 we treat it tunnel
	   address. */
	if (prefix_ipv4_any(&p))
		return;

	/* Same logic as for connected_up_ipv4(): push the changes into the head. */
	rib_delete_ipv4(ZEBRA_ROUTE_CONNECT, 0, &p, NULL, ifp->ifindex, 0,
			SAFI_UNICAST);

	rib_delete_ipv4(ZEBRA_ROUTE_CONNECT, 0, &p, NULL, ifp->ifindex, 0,
			SAFI_MULTICAST);

	rib_update();
}
Пример #2
0
/* Lookup interface by IPv4 address. */
struct interface * if_lookup_address (struct in_addr src)
{
	struct prefix addr;
	int bestlen = 0;
	struct listnode *cnode;
	struct interface *ifp = NULL;
	struct connected *c;
	struct interface *match = NULL;
        int idx = 0;

	addr.family = AF_INET;
	addr.u.prefix4 = src;
	addr.prefixlen = IPV4_MAX_BITLEN;

        while (idx < get_max_port ()) {
		for (ALL_LIST_ELEMENTS_RO (ifp->connected, cnode, c))
		{
			if (c->address && (c->address->family == AF_INET) &&
					prefix_match(CONNECTED_PREFIX(c), &addr) &&
					(c->address->prefixlen > bestlen))
			{
				bestlen = c->address->prefixlen;
				match = ifp;
			}
		}
                idx++;
        }
	return match;
}
Пример #3
0
/* determine receiving interface by source of packet */
struct ospf_interface *
ospf_if_lookup_recv_if (struct ospf *ospf, struct in_addr src)
{
  struct listnode *node;
  struct prefix_ipv4 addr;
  struct ospf_interface *oi, *match;

  addr.family = AF_INET;
  addr.prefix = src;
  addr.prefixlen = IPV4_MAX_BITLEN;

  match = NULL;

  for (ALL_LIST_ELEMENTS_RO (ospf->oiflist, node, oi))
    {
      if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
	continue;
      
      if (if_is_loopback (oi->ifp))
        continue;

      if (prefix_match (CONNECTED_PREFIX(oi->connected),
      			(struct prefix *) &addr))
	{
	  if ( (match == NULL) || 
	       (match->address->prefixlen < oi->address->prefixlen)
	     )
	    match = oi;
	}
    }

  return match;
}
Пример #4
0
/* Called from if_up(). */
void connected_up_ipv4(struct interface *ifp, struct connected *ifc)
{
	struct prefix_ipv4 p;

	if (!CHECK_FLAG(ifc->conf, ZEBRA_IFC_REAL))
		return;

	PREFIX_COPY_IPV4(&p, CONNECTED_PREFIX(ifc));

	/* Apply mask to the network. */
	apply_mask_ipv4(&p);

	/* In case of connected address is 0.0.0.0/0 we treat it tunnel
	   address. */
	if (prefix_ipv4_any(&p))
		return;

	rib_add_ipv4(ZEBRA_ROUTE_CONNECT, 0, &p, NULL, NULL, ifp->ifindex,
		     RT_TABLE_MAIN, ifp->metric, 0, SAFI_UNICAST);

	rib_add_ipv4(ZEBRA_ROUTE_CONNECT, 0, &p, NULL, NULL, ifp->ifindex,
		     RT_TABLE_MAIN, ifp->metric, 0, SAFI_MULTICAST);

	rib_update();
}
Пример #5
0
/*
*  check if interface with given address is configured and
*  return it if yes.  special treatment for PtP networks.
*/
struct ospf_interface *
ospf_if_is_configured (struct ospf *ospf, struct in_addr *address)
{
  struct listnode *node, *nnode;
  struct ospf_interface *oi;
  struct prefix_ipv4 addr;

  addr.family = AF_INET;
  addr.prefix = *address;
  addr.prefixlen = IPV4_MAX_PREFIXLEN;

  for (ALL_LIST_ELEMENTS (ospf->oiflist, node, nnode, oi))
    if (oi->type != OSPF_IFTYPE_VIRTUALLINK)
      {
        if (oi->type == OSPF_IFTYPE_POINTOPOINT)
	  {
	    /* special leniency: match if addr is anywhere on peer subnet */
	    if (prefix_match(CONNECTED_PREFIX(oi->connected),
			     (struct prefix *)&addr))
	      return oi;
	  }
        else
	  {
	    if (IPV4_ADDR_SAME (address, &oi->address->u.prefix4))
	      return oi;
	  }
      }
  return NULL;
}
Пример #6
0
/* Lookup interface by IPv4 address. */
struct interface *
if_lookup_address_vrf (struct in_addr src, vrf_id_t vrf_id)
{
  struct listnode *node;
  struct prefix addr;
  int bestlen = 0;
  struct listnode *cnode;
  struct interface *ifp;
  struct connected *c;
  struct interface *match;

  addr.family = AF_INET;
  addr.u.prefix4 = src;
  addr.prefixlen = IPV4_MAX_BITLEN;

  match = NULL;

  for (ALL_LIST_ELEMENTS_RO (vrf_iflist (vrf_id), node, ifp))
    {
      for (ALL_LIST_ELEMENTS_RO (ifp->connected, cnode, c))
	{
	  if (c->address && (c->address->family == AF_INET) &&
	      prefix_match(CONNECTED_PREFIX(c), &addr) &&
	      (c->address->prefixlen > bestlen))
	    {
	      bestlen = c->address->prefixlen;
	      match = ifp;
	    }
	}
    }
  return match;
}
Пример #7
0
void connected_down_ipv6(struct interface *ifp, struct connected *ifc)
{
	struct prefix_ipv6 p;

	if (!CHECK_FLAG(ifc->conf, ZEBRA_IFC_REAL))
		return;

	PREFIX_COPY_IPV6(&p, CONNECTED_PREFIX(ifc));

	apply_mask_ipv6(&p);

	if (IN6_IS_ADDR_UNSPECIFIED(&p.prefix))
		return;

	rib_delete_ipv6(ZEBRA_ROUTE_CONNECT, 0, &p, NULL, ifp->ifindex, 0,
			SAFI_UNICAST);

	rib_update();
}
Пример #8
0
struct ospf_interface *ospf_if_lookup_by_prefix(struct ospf *ospf,
						struct prefix_ipv4 *p)
{
	struct listnode *node;
	struct ospf_interface *oi;

	/* Check each Interface. */
	for (ALL_LIST_ELEMENTS_RO(ospf->oiflist, node, oi)) {
		if (oi->type != OSPF_IFTYPE_VIRTUALLINK) {
			struct prefix ptmp;

			prefix_copy(&ptmp, CONNECTED_PREFIX(oi->connected));
			apply_mask(&ptmp);
			if (prefix_same(&ptmp, (struct prefix *)p))
				return oi;
		}
	}
	return NULL;
}
Пример #9
0
/* determine receiving interface by ifp and source address */
struct ospf_interface *
ospf_if_lookup_recv_if (struct ospf *ospf, struct in_addr src,
			struct interface *ifp)
{
  struct route_node *rn;
  struct prefix_ipv4 addr;
  struct ospf_interface *oi, *match;

  addr.family = AF_INET;
  addr.prefix = src;
  addr.prefixlen = IPV4_MAX_BITLEN;

  match = NULL;

  for (rn = route_top (IF_OIFS (ifp)); rn; rn = route_next (rn))
    {
      oi = rn->info;

      if (!oi) /* oi can be NULL for PtP aliases */
	continue;

      if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
	continue;

      if (if_is_loopback (oi->ifp))
        continue;

      if (prefix_match (CONNECTED_PREFIX(oi->connected),
      			(struct prefix *) &addr))
	{
	  if ( (match == NULL) || 
	       (match->address->prefixlen < oi->address->prefixlen)
	     )
	    match = oi;
	}
    }

  return match;
}
Пример #10
0
void connected_up_ipv6(struct interface *ifp, struct connected *ifc)
{
	struct prefix_ipv6 p;

	if (!CHECK_FLAG(ifc->conf, ZEBRA_IFC_REAL))
		return;

	PREFIX_COPY_IPV6(&p, CONNECTED_PREFIX(ifc));

	/* Apply mask to the network. */
	apply_mask_ipv6(&p);

#ifndef LINUX
	/* XXX: It is already done by rib_bogus_ipv6 within rib_add_ipv6 */
	if (IN6_IS_ADDR_UNSPECIFIED(&p.prefix))
		return;
#endif

	rib_add_ipv6(ZEBRA_ROUTE_CONNECT, 0, &p, NULL, ifp->ifindex,
		     RT_TABLE_MAIN, ifp->metric, 0, SAFI_UNICAST);

	rib_update();
}
Пример #11
0
/* Find the IPv4 address on our side that will be used when packets
   are sent to dst. */
struct connected *
connected_lookup_address (struct interface *ifp, struct in_addr dst)
{
  struct prefix addr;
  struct listnode *cnode;
  struct connected *c;
  struct connected *match;

  addr.family = AF_INET;
  addr.u.prefix4 = dst;
  addr.prefixlen = IPV4_MAX_BITLEN;

  match = NULL;

  for (ALL_LIST_ELEMENTS_RO (ifp->connected, cnode, c))
    {
      if (c->address && (c->address->family == AF_INET) &&
	  prefix_match(CONNECTED_PREFIX(c), &addr) &&
	  (!match || (c->address->prefixlen > match->address->prefixlen)))
	match = c;
    }
  return match;
}
Пример #12
0
void
bgp_connected_delete (struct connected *ifc)
{
  struct prefix p;
  struct prefix *addr;
  struct interface *ifp;
  struct bgp_node *rn;
  struct bgp_connected_ref *bc;

  ifp = ifc->ifp;

  if (if_is_loopback (ifp))
    return;

  addr = ifc->address;

  if (addr->family == AF_INET)
    {
      PREFIX_COPY_IPV4(&p, CONNECTED_PREFIX(ifc));
      apply_mask_ipv4 ((struct prefix_ipv4 *) &p);

      if (prefix_ipv4_any ((struct prefix_ipv4 *) &p))
	return;

      bgp_address_del (addr);

      rn = bgp_node_lookup (bgp_connected_table[AFI_IP], &p);
      if (! rn)
	return;

      bc = rn->info;
      bc->refcnt--;
      if (bc->refcnt == 0)
	{
	  XFREE (MTYPE_BGP_CONN, bc);
	  rn->info = NULL;
	}
      bgp_unlock_node (rn);
      bgp_unlock_node (rn);
    }
#ifdef HAVE_IPV6
  else if (addr->family == AF_INET6)
    {
      PREFIX_COPY_IPV6(&p, CONNECTED_PREFIX(ifc));
      apply_mask_ipv6 ((struct prefix_ipv6 *) &p);

      if (IN6_IS_ADDR_UNSPECIFIED (&p.u.prefix6))
	return;

      if (IN6_IS_ADDR_LINKLOCAL (&p.u.prefix6))
	return;

      rn = bgp_node_lookup (bgp_connected_table[AFI_IP6], (struct prefix *) &p);
      if (! rn)
	return;

      bc = rn->info;
      bc->refcnt--;
      if (bc->refcnt == 0)
	{
	  XFREE (MTYPE_BGP_CONN, bc);
	  rn->info = NULL;
	}
      bgp_unlock_node (rn);
      bgp_unlock_node (rn);
    }
#endif /* HAVE_IPV6 */
}
Пример #13
0
void
bgp_connected_add (struct connected *ifc)
{
  struct prefix p;
  struct prefix *addr;
  struct interface *ifp;
  struct bgp_node *rn;
  struct bgp_connected_ref *bc;

  ifp = ifc->ifp;

  if (! ifp)
    return;

  if (if_is_loopback (ifp))
    return;

  addr = ifc->address;

  if (addr->family == AF_INET)
    {
      PREFIX_COPY_IPV4(&p, CONNECTED_PREFIX(ifc));
      apply_mask_ipv4 ((struct prefix_ipv4 *) &p);

      if (prefix_ipv4_any ((struct prefix_ipv4 *) &p))
	return;

      bgp_address_add (addr);

      rn = bgp_node_get (bgp_connected_table[AFI_IP], (struct prefix *) &p);
      if (rn->info)
	{
	  bc = rn->info;
	  bc->refcnt++;
	}
      else
	{
	  bc = XCALLOC (MTYPE_BGP_CONN, sizeof (struct bgp_connected_ref));
	  bc->refcnt = 1;
	  rn->info = bc;
	}
    }
#ifdef HAVE_IPV6
  else if (addr->family == AF_INET6)
    {
      PREFIX_COPY_IPV6(&p, CONNECTED_PREFIX(ifc));
      apply_mask_ipv6 ((struct prefix_ipv6 *) &p);

      if (IN6_IS_ADDR_UNSPECIFIED (&p.u.prefix6))
	return;

      if (IN6_IS_ADDR_LINKLOCAL (&p.u.prefix6))
	return;

      rn = bgp_node_get (bgp_connected_table[AFI_IP6], (struct prefix *) &p);
      if (rn->info)
	{
	  bc = rn->info;
	  bc->refcnt++;
	}
      else
	{
	  bc = XCALLOC (MTYPE_BGP_CONN, sizeof (struct bgp_connected_ref));
	  bc->refcnt = 1;
	  rn->info = bc;
	}
    }
#endif /* HAVE_IPV6 */
}