示例#1
0
s32 bgp_fec_announce_6pe(struct zclient *zc, struct prefix *p, struct bgp_info *info, struct bgp *bgp)
{
    u32 flags = 0;
    struct stream * s  = zc->obuf ;
    struct peer * peer = info->peer ;
    u32 gateway ,label ;
    struct rtm_fec_info_key key;
    struct in6_addr *nexthop = NULL;

    if( !info || !info->attr || !info->attr->extra ) 
        return -1 ;
        
    if (info->attr->extra->mp_nexthop_len == 16)
    {
    	nexthop = &info->attr->extra->mp_nexthop_global;
    }  
    /* If both global and link-local address present. */
    else if (info->attr->extra->mp_nexthop_len == 32)
	{
	    /* Workaround for Cisco's nexthop bug.  */
	    if (IN6_IS_ADDR_UNSPECIFIED (&info->attr->extra->mp_nexthop_global)
	        && peer->su_remote->sa.sa_family == AF_INET6)
	    	nexthop = &peer->su_remote->sin6.sin6_addr;
	    else
	    	nexthop = &info->attr->extra->mp_nexthop_local;
	}
	if(NULL == nexthop || !IN6_IS_ADDR_V4MAPPED(nexthop))
	{
	    return -1;
	}
	memcpy (&gateway , ((s8 *)nexthop) + 12, 4);
    label  = decode_label ( bgp_info_extra_get(info)->tag) ;

    SET_FLAG(flags, ZAPI_FEC_GATEWAY);
    stream_reset(s);
    zclient_create_header(s,ZEBRA_MPLS_FEC6_INFO_ADD);
    stream_put_prefix(s,p);
	stream_putl(s, flags);
    stream_putl(s, ZEBRA_FEC_TYPE_6PE);
    if( peer )
        stream_putl(s,peer->nexthop.v4.s_addr);
    else
        stream_putl(s,0); // lsr_id = 0 
    stream_putl(s,label);
    stream_putl(s,gateway);

    stream_putw_at (s, 0, stream_get_endp (s));
    key.peer_addr = gateway;

    return rtm_fec_send(ZEBRA_MPLS_FEC6_INFO_ADD, zc, p, s, &key) ;
}
示例#2
0
s32 bgp_fec_announce_6vpe(bgp_litevrf_config_t *litevrf, struct prefix *p, struct bgp_info *info)
{
    u32 flags = 0;
    struct stream * s  = zclient->obuf ;
    struct peer * peer = info->peer ;
    u32 gateway ,label ;
    struct rtm_fec_info_key key;
    struct in6_addr *nexthop = NULL;

    if( !info || !info->attr || !info->attr->extra ) 
        return -1 ;
        
    nexthop = &info->attr->extra->mp_nexthop_global;

    
	if(NULL == nexthop || !IN6_IS_ADDR_V4MAPPED(nexthop))
	{
	    return -1;
	}
	memcpy (&gateway , ((s8 *)nexthop) + 12, 4);
    label  = decode_label ( bgp_info_extra_get(info)->tag) ;

    SET_FLAG(flags, ZAPI_FEC_GATEWAY|ZAPI_FEC_LITEVRF);
    stream_reset(s);
    zclient_create_header(s,ZEBRA_MPLS_FEC6_INFO_ADD);
    stream_put_prefix(s,p);
	stream_putl(s, flags);
	stream_putl(s,litevrf->id);
    stream_putl(s, ZEBRA_FEC_TYPE_6VPE);
    if( peer )
        stream_putl(s,peer->nexthop.v4.s_addr);
    else
        stream_putl(s,0); // lsr_id = 0 
    stream_putl(s,label);
    stream_putl(s,gateway);

    stream_putw_at (s, 0, stream_get_endp (s));
    key.peer_addr = gateway;

    return rtm_fec_send(ZEBRA_MPLS_FEC6_INFO_ADD, zclient, p, s, &key) ;
}
示例#3
0
文件: zebra_rnh.c 项目: Quagga/quagga
static int
send_client (struct rnh *rnh, struct zserv *client, vrf_id_t vrf_id)
{
  struct stream *s;
  struct rib *rib;
  unsigned long nump;
  u_char num;
  struct nexthop *nexthop;
  struct route_node *rn;

  rn = rnh->node;
  rib = rnh->state;

  /* Get output stream. */
  s = client->obuf;
  stream_reset (s);

  zserv_create_header (s, ZEBRA_NEXTHOP_UPDATE, vrf_id);

  stream_putw(s, rn->p.family);
  stream_put_prefix (s, &rn->p);

  if (rib)
    {
      stream_putl (s, rib->metric);
      num = 0;
      nump = stream_get_endp(s);
      stream_putc (s, 0);
      for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
	if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB) &&
            ! CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE) &&
	    CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE))
	  {
	    stream_putc (s, nexthop->type);
	    switch (nexthop->type)
	      {
	      case ZEBRA_NEXTHOP_IPV4:
		stream_put_in_addr (s, &nexthop->gate.ipv4);
		break;
	      case ZEBRA_NEXTHOP_IFINDEX:
	      case ZEBRA_NEXTHOP_IFNAME:
		stream_putl (s, nexthop->ifindex);
		break;
	      case ZEBRA_NEXTHOP_IPV4_IFINDEX:
	      case ZEBRA_NEXTHOP_IPV4_IFNAME:
		stream_put_in_addr (s, &nexthop->gate.ipv4);
		stream_putl (s, nexthop->ifindex);
		break;
#ifdef HAVE_IPV6
	      case ZEBRA_NEXTHOP_IPV6:
		stream_put (s, &nexthop->gate.ipv6, 16);
		break;
	      case ZEBRA_NEXTHOP_IPV6_IFINDEX:
	      case ZEBRA_NEXTHOP_IPV6_IFNAME:
		stream_put (s, &nexthop->gate.ipv6, 16);
		stream_putl (s, nexthop->ifindex);
		break;
#endif /* HAVE_IPV6 */
	      default:
                /* do nothing */
		break;
	      }
	    num++;
	  }
      stream_putc_at (s, nump, num);
    }
  else
    {
      stream_putl (s, 0);
      stream_putc (s, 0);
    }
  stream_putw_at (s, 0, stream_get_endp (s));

  client->nh_last_upd_time = quagga_time(NULL);
  client->last_write_cmd = ZEBRA_NEXTHOP_UPDATE;
  return zebra_server_send_message(client);
}