static void
ripng_apply_address_add (struct connected *ifc) {
  struct prefix_ipv6 address;
  struct prefix *p;

  if (!ripng)
    return;

  if (! if_is_up(ifc->ifp))
    return;

  p = ifc->address;

  memset (&address, 0, sizeof (address));
  address.family = p->family;
  address.prefix = p->u.prefix6;
  address.prefixlen = p->prefixlen;
  apply_mask_ipv6(&address);

  /* Check if this interface is RIP enabled or not
     or  Check if this address's prefix is RIP enabled */
  if ((ripng_enable_if_lookup(ifc->ifp->name) >= 0) ||
      (ripng_enable_network_lookup2(ifc) >= 0))
    ripng_redistribute_add(ZEBRA_ROUTE_CONNECT, RIPNG_ROUTE_INTERFACE,
                           &address, ifc->ifp->ifindex, NULL);

}
static void
ripng_connect_set (struct interface *ifp, int set)
{
  struct listnode *node, *nnode;
  struct connected *connected;
  struct prefix_ipv6 address;

  for (ALL_LIST_ELEMENTS (ifp->connected, node, nnode, connected))
    {
      struct prefix *p;
      p = connected->address;

      if (p->family != AF_INET6)
        continue;

      address.family = AF_INET6;
      address.prefix = p->u.prefix6;
      address.prefixlen = p->prefixlen;
      apply_mask_ipv6 (&address);

      if (set) {
        /* Check once more wether this prefix is within a "network IF_OR_PREF" one */
        if ((ripng_enable_if_lookup(connected->ifp->name) >= 0) ||
            (ripng_enable_network_lookup2(connected) >= 0))
          ripng_redistribute_add (ZEBRA_ROUTE_CONNECT, RIPNG_ROUTE_INTERFACE,
                                  &address, connected->ifp->ifindex, NULL);
      } else {
        ripng_redistribute_delete (ZEBRA_ROUTE_CONNECT, RIPNG_ROUTE_INTERFACE,
                                   &address, connected->ifp->ifindex);
        if (ripng_redistribute_check (ZEBRA_ROUTE_CONNECT))
          ripng_redistribute_add (ZEBRA_ROUTE_CONNECT, RIPNG_ROUTE_REDISTRIBUTE,
                                  &address, connected->ifp->ifindex, NULL);
      }
    }
}
Esempio n. 3
0
void
connected_up_ipv6 (struct interface *ifp, struct connected *ifc)
{
  struct prefix_ipv6 p;
  struct prefix_ipv6 *addr;
  struct prefix_ipv6 *dest;

  
  if(product != NULL && product->board_type != BOARD_IS_ACTIVE_MASTER)
  	goto skip;
 #if 0
/*ipv6 not support interface loacal*/
  if(product != NULL && product->board_type == BOARD_IS_ACTIVE_MASTER &&CHECK_FLAG(ifp->if_scope, INTERFACE_LOCAL))
  	goto skip;/*local interface , skip the check the ifc->conf, because the ip address not install in the kernel .*/
#endif
  if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_REAL))
    return;

skip:
  addr = (struct prefix_ipv6 *) ifc->address;
  dest = (struct prefix_ipv6 *) ifc->destination;

  memset (&p, 0, sizeof (struct prefix_ipv6));
  p.family = AF_INET6;
  p.prefixlen = addr->prefixlen;

  if (if_is_pointopoint (ifp) && dest)
    {
      if (IN6_IS_ADDR_UNSPECIFIED (&dest->prefix))
	p.prefix = addr->prefix;
      else
	p.prefix = dest->prefix;
    }
  else
    p.prefix = addr->prefix;

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

#if ! defined (MUSICA) && ! defined (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, 0,
                ifp->metric, 0);

  rib_update ();
}
Esempio n. 4
0
File: prefix.c Progetto: yubo/quagga
void apply_mask(struct prefix *p)
{
	switch (p->family) {
	case AF_INET:
		apply_mask_ipv4((struct prefix_ipv4 *)p);
		break;
#ifdef HAVE_IPV6
	case AF_INET6:
		apply_mask_ipv6((struct prefix_ipv6 *)p);
		break;
#endif /* HAVE_IPV6 */
	default:
		break;
	}
	return;
}
Esempio n. 5
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();
}
Esempio n. 6
0
void
connected_down_ipv6 (struct interface *ifp, struct connected *ifc)
{
  struct prefix_ipv6 p;
  struct prefix_ipv6 *addr;
  struct prefix_ipv6 *dest;

  if(product != NULL && product->board_type != BOARD_IS_ACTIVE_MASTER)
   goto skip;
  
  if(product != NULL && product->board_type == BOARD_IS_ACTIVE_MASTER &&CHECK_FLAG(ifp->if_scope, INTERFACE_LOCAL))
   goto skip;/*local interface , skip the check the ifc->conf, because the ip address not install in the kernel .*/

  if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_REAL))
    return;
  
skip:
  addr = (struct prefix_ipv6 *) ifc->address;
  dest = (struct prefix_ipv6 *) ifc->destination;

  memset (&p, 0, sizeof (struct prefix_ipv6));
  p.family = AF_INET6;
  p.prefixlen = addr->prefixlen;

  if (if_is_pointopoint (ifp) && dest)
    {
      if (IN6_IS_ADDR_UNSPECIFIED (&dest->prefix))
	p.prefix = addr->prefix;
      else
	p.prefix = dest->prefix;
    }
  else
    p.prefix = addr->prefix;

  apply_mask_ipv6 (&p);

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

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

  rib_update ();
}
void
connected_up_ipv6 (struct interface *ifp, struct connected *ifc)
{
  struct prefix_ipv6 p;
  struct prefix_ipv6 *addr;
  struct prefix_ipv6 *dest;

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

  addr = (struct prefix_ipv6 *) ifc->address;
  dest = (struct prefix_ipv6 *) ifc->destination;

  memset (&p, 0, sizeof (struct prefix_ipv6));
  p.family = AF_INET6;
  p.prefixlen = addr->prefixlen;

  if (if_is_pointopoint (ifp) && dest)
    {
      if (IN6_IS_ADDR_UNSPECIFIED (&dest->prefix))
	p.prefix = addr->prefix;
      else
	p.prefix = dest->prefix;
    }
  else
    p.prefix = addr->prefix;

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

#if ! defined (MUSICA) && ! defined (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, 0,
                ifp->metric, 0);

  rib_update ();
}
static void
ripng_apply_address_del (struct connected *ifc) {
  struct prefix_ipv6 address;
  struct prefix *p;

  if (!ripng)
    return;

  if (! if_is_up(ifc->ifp))
    return;

  p = ifc->address;

  memset (&address, 0, sizeof (address));
  address.family = p->family;
  address.prefix = p->u.prefix6;
  address.prefixlen = p->prefixlen;
  apply_mask_ipv6(&address);

  ripng_redistribute_delete(ZEBRA_ROUTE_CONNECT, RIPNG_ROUTE_INTERFACE,
                            &address, ifc->ifp->ifindex);
}
Esempio n. 9
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();
}
void
connected_down_ipv6 (struct interface *ifp, struct connected *ifc)
{
  struct prefix_ipv6 p;
  struct prefix_ipv6 *addr;
  struct prefix_ipv6 *dest;

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

  addr = (struct prefix_ipv6 *) ifc->address;
  dest = (struct prefix_ipv6 *) ifc->destination;

  memset (&p, 0, sizeof (struct prefix_ipv6));
  p.family = AF_INET6;
  p.prefixlen = addr->prefixlen;

  if (if_is_pointopoint (ifp) && dest)
    {
      if (IN6_IS_ADDR_UNSPECIFIED (&dest->prefix))
	p.prefix = addr->prefix;
      else
	p.prefix = dest->prefix;
    }
  else
    p.prefix = addr->prefix;

  apply_mask_ipv6 (&p);

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

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

  rib_update ();
}
Esempio n. 11
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 */
}
Esempio n. 12
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 */
}
Esempio n. 13
0
/*******************************************************************************
 函数名称  : ws__addmodRtPolicy
 功能描述  : 该函数实现添加修改策略
 输入参数  : ws_env     ---- web service执行环境
             policyid   ---- 策略的id
             src        ---- 源网段
             src_mask   ---- 源地址掩码
             dest       ---- 目的网段
             dest_mask  ---- 目的地址掩码
             iif        ---- 入接口
             oif        ---- 出接口
             tos        ---- 服务类型
             nexthop    ---- 下一跳地址
 输出参数  : ret        ---- 返回结果
 返 回 值  : WS_OK		---- 执行成功
             soapFault  ---- 执行失败
--------------------------------------------------------------------------------
 最近一次修改记录 : 
 修改作者   : 王朝
 修改目的   : 支持健康检查
 修改日期   : 2010年12月27日
*******************************************************************************/
int ws__addmodRtPolicyIpv6(WS_ENV *soap, s32 listflag, s32 rtpoperation, s32 sequence, s32 policyid,
            s8 *src, s8 *dest, s8 *iifname, s32 protocol, s32 minsrcport, s32 maxsrcport, 
            s32 mindstport, s32 maxdstport, s8 *oifname,  s8 *weight,
            s8 *nexthop, s32 nexthopcount, s32 *ret)      
{
    u32         i = 0;
    u32         count = 0;
    s32         sys_ret = 0;
    s32         iifindex = 0;
    u32         policyid_tmp = 0;
    s32         sequence_insert = 0;
    s32         sys_error_code = ERROR_SUCCESS;
    s8          sql_insert[RT_EX_SQL_LENGTH] = {0};
    s8          sql_update[RT_EX_SQL_LENGTH] = {0};
    s8          sql_select[RT_EX_SQL_LENGTH] = {0};
    s8          oifname_str[RT_POLICY_MAX_NEXTHOP][20];
	s8          nexthop_str[RT_POLICY_MAX_NEXTHOP][100];
	s8          weight_str[RT_POLICY_MAX_NEXTHOP][10];
	s32         oifindex[RT_POLICY_MAX_NEXTHOP];  
	s32         weightvalue[RT_POLICY_MAX_NEXTHOP]; 
    s8          tb_name[32] = {0};
    sqlite3     *db = NULL;
    sqlite3_res res = NULL;
    struct prefix_ipv6 prefix_src;
    struct prefix_ipv6 prefix_dest;
    struct in6_addr srcmask;
    struct in6_addr dstmask;
    struct in6_addr nexthop_addr[RT_POLICY_MAX_NEXTHOP];
    rt_policy_ipv6_s rtpolicy_tmp;
    void *buffer = NULL;
    u8 flag = 0;
	s8  *str_point[3], *line_point[3];

    if( (nexthopcount < 1) || (nexthopcount > 16) )
    {
        *ret = 0;
        return ws_send_soap_error(soap, "nexthop numbers should be no less than 1 and no more than 16!");
    }
    buffer = malloc(sizeof(s32) * 2 + sizeof(rt_policy_ipv6_s));
    if(NULL == buffer)
    {
        sys_error_code = ERR_RT_POLICY_MALLOC;
        goto label_ret;
    }
    
    str_point[0] = oifname;
	str_point[1] = weight;
	str_point[2] = nexthop;
    /*解析下一跳信息*/
    for(i = 0; i < nexthopcount; i++)
    {
       if(i != (nexthopcount - 1))
       {
	      line_point[0] = static_strchr(str_point[0],';');
		  static_strncpy(oifname_str[i], str_point[0], line_point[0] - str_point[0]);
		  oifname_str[i][line_point[0] - str_point[0]] = '\0';
		  str_point[0] = line_point[0] + 1;
		  if (ERROR_SUCCESS != if_get_index_by_name(oifname_str[i], &oifindex[i]))
		  {
		      sys_error_code = ERR_RT_POLICY_IFNAME;
		      goto label_err;
		  }
		  
	      line_point[1] = static_strchr(str_point[1],';');	 
		  static_strncpy(weight_str[i], str_point[1], line_point[1] - str_point[1]);	
		  weight_str[i][line_point[1] - str_point[1]] = '\0';
		  str_point[1] = line_point[1] + 1;
		  weightvalue[i] = atoi(weight_str[i]);
		  
	      line_point[2] = static_strchr(str_point[2],';');
	      static_strncpy(nexthop_str[i], str_point[2], line_point[2] - str_point[2]);  
	      nexthop_str[i][line_point[2] - str_point[2]] = '\0';
		  str_point[2] = line_point[2] + 1;
		  if( 0 >= inet_pton (AF_INET6, nexthop_str[i], &nexthop_addr[i]) )
		  {
		      sys_error_code = ERR_RT_POLICY_ADDRESS;
		      goto label_err;
		  }
       }
	   else
	   {
	      line_point[0] = static_strchr(str_point[0],'\0');
		  static_strncpy(oifname_str[i], str_point[0], line_point[0] - str_point[0]);
		  oifname_str[i][line_point[0] - str_point[0]] = '\0';
		  if (ERROR_SUCCESS != if_get_index_by_name(oifname_str[i], &oifindex[i]))
		  {
		      sys_error_code = ERR_RT_POLICY_IFNAME;
		      goto label_err;
		  }
		  
	      line_point[1] = static_strchr(str_point[1],'\0');	 
		  static_strncpy(weight_str[i], str_point[1], line_point[1] - str_point[1]);	
		  weight_str[i][line_point[1] - str_point[1]] = '\0';
		  weightvalue[i] = atoi(weight_str[i]);
		  
	      line_point[2] = static_strchr(str_point[2],'\0');
	      static_strncpy(nexthop_str[i], str_point[2], line_point[2] - str_point[2]);  
	      nexthop_str[i][line_point[2] - str_point[2]] = '\0';
	      if( 0 >= inet_pton (AF_INET6, nexthop_str[i], &nexthop_addr[i]) )
		  {
		      sys_error_code = ERR_RT_POLICY_ADDRESS;
		      goto label_err;
		  }
	   }
	}
	for(; i < RT_POLICY_MAX_NEXTHOP; i++)
	{
   		oifindex[i] = 0;
		memset(nexthop_addr[i].s6_addr, 0, sizeof(struct in6_addr));
		weightvalue[i] = 0;
	}   
	
    /*将公网地址由点分十进制转换为网络二进制数*/
    if (0 == str2prefix_ipv6 (src, &prefix_src))
    {
        sys_error_code = ERR_RT_POLICY_ADDRESS;
        goto label_err;
    }
    if (0 == str2prefix_ipv6 (dest, &prefix_dest))
    {
        sys_error_code = ERR_RT_POLICY_ADDRESS;
        goto label_err;
    }

    /* 设置源网段flag, 掩码为0 则不设置flag */
    if(0 != prefix_src.prefixlen)
    {
        masklen2ip6 ((s32)prefix_src.prefixlen, &srcmask);
        apply_mask_ipv6(&prefix_src);
        RTPOLICY_SET_FLAG(flag, RT_POLICY_SRCIP);
    }
    else
    { 
        memset(&srcmask, 0, sizeof(struct in6_addr));
    }

    /* 设置目的网段flag */
    if(0 != prefix_dest.prefixlen)
    {
        masklen2ip6 ((s32)prefix_dest.prefixlen, &dstmask);
        apply_mask_ipv6(&prefix_dest);
        RTPOLICY_SET_FLAG(flag, RT_POLICY_DSTIP);
    }
    else
    {
        memset(&dstmask, 0, sizeof(struct in6_addr));
    }

    /* 设置协议flag */
    if(65536 != protocol)
    {
        RTPOLICY_SET_FLAG(flag, RT_POLICY_PROTOCOL);
        if( (IPPROTO_TCP == protocol)||(IPPROTO_UDP == protocol) )
        {
            if( (65536 != minsrcport)&&(65536 != maxsrcport) )
            {
                RTPOLICY_SET_FLAG(flag, RT_POLICY_SRCPORT);
            }
            if( (65536 != mindstport)&&(65536 != maxdstport) )
            {
                RTPOLICY_SET_FLAG(flag, RT_POLICY_DSTPORT);
            }
        }
    }

    /* 设置入接口flag */
    if (strcmp("any", iifname))
    {
        /*将接口名转换成接口索引*/
    	if (ERROR_SUCCESS != if_get_index_by_name(iifname, &iifindex))
    	{
    	    sys_error_code = ERR_RT_POLICY_IFNAME;
            goto label_err;
    	}
        RTPOLICY_SET_FLAG(flag, RT_POLICY_ININTERFACE);
    }


    /* 打开数据库 */
    db = sqlite3_open_ex(1, DATABASE_RT_POLICY_IPV6_PATH);
    if ( NULL == db )
    {
        sys_error_code = ERR_RT_POLICY_DATABASE;
        goto label_err;
    }

    switch (listflag)
    {
        case RT_POLICY_BEFORE_ROUTE:
            strcpy(tb_name, "tb_rt_policy_pre_ipv6");
            break;
        case RT_POLICY_AFTER_ROUTE:
            strcpy(tb_name, "tb_rt_policy_aft_ipv6");
            break;
        case RT_POLICY_LOCAL_ROUTE:
            strcpy(tb_name, "tb_rt_policy_loc_ipv6");
            break;
        default:
            return ws_send_soap_error(soap, "Error in get rtpolicy table!");
    }

    /* 添加事物 */
    SQLITE_TRANSC_BEGIN(db);
    /* 指定policyid_real 和sequence_temp 的值, 修改策略除指定policyid_real 和sequence_temp ( 取默认值0 )的值外, 还需要获取健康检查类型值 */
    if (RT_POLICY_ADD_INS == rtpoperation)
    {
        sprintf(sql_select, "select count(*) as count, MAX(policy_id) as maxpolicyid from %s;", tb_name);
        if (SQLITE_OK != sqlite3_exec_query_ex(db, sql_select, &res))
        {
            sys_error_code = ERR_RT_POLICY_SQL;
            goto label_ret;
        }
        if ( SQLITE_OK != sqlite3_get_u32_ex(res, 0, "count", &count)) 
        {
            sys_error_code = ERR_RT_POLICY_GETRES;
            goto label_ret;
        }
        if ( SQLITE_OK != sqlite3_get_u32_ex(res, 0, "maxpolicyid", &policyid_tmp)) 
        {
            sys_error_code = ERR_RT_POLICY_GETRES;
            goto label_ret;
        }
        sqlite3_res_free_ex(res);
        res = NULL;

        /* 为新加或插入的策略分配policyid */
        policyid_tmp++;
        policyid = policyid_tmp;
        
        /* 0<sequence<=count 插入一条策略 */
        if( (sequence <= count)&&(sequence > 0) )
        {
            sequence_insert = sequence;
            sprintf(sql_update , "update %s set sequence = sequence+1 where sequence >= %d;", tb_name, sequence);
            if (SQLITE_OK != sqlite3_exec_ex(db, sql_update))
            {
                sys_error_code = ERR_RT_POLICY_SQL;
                goto label_ret;
            }
        }
        else if(sequence == count+1)
        {
            /* 内核将新加策略添加到策略链表尾部 */
        	sequence_insert = 0;
        }
        else if(sequence == 0)
        {
            sequence = count+1;
            sequence_insert = 0;
        }
        else
        {
            return ws_send_soap_error(soap, "sequence error!");
        }
    }
    

    /*填充要向内核发送的数据*/
    rtpolicy_tmp.id          = policyid;
    rtpolicy_tmp.src = prefix_src.prefix;
    rtpolicy_tmp.srcmask     = srcmask;
    rtpolicy_tmp.smask       = prefix_src.prefixlen;
    rtpolicy_tmp.dst         = prefix_dest.prefix;
    rtpolicy_tmp.dstmask     = dstmask;
    rtpolicy_tmp.dmask       = prefix_dest.prefixlen;
    rtpolicy_tmp.iifindex    = iifindex;
    rtpolicy_tmp.nexthopcount  = nexthopcount;
	for(i = 0; i < RT_POLICY_MAX_NEXTHOP; i++)
	{
       rtpolicy_tmp.oifindex[i] = oifindex[i];
	   rtpolicy_tmp.nexthop[i]  = nexthop_addr[i];
	   rtpolicy_tmp.weight[i]   = (u8)weightvalue[i];
	   rtpolicy_tmp.nhflag[i]   = 0;
	}
    rtpolicy_tmp.protocol      = (u8)protocol;
    rtpolicy_tmp.srcminportnum = (u16)minsrcport;
    rtpolicy_tmp.srcmaxportnum = (u16)maxsrcport;
    rtpolicy_tmp.dstminportnum = (u16)mindstport;
    rtpolicy_tmp.dstmaxportnum = (u16)maxdstport;
    rtpolicy_tmp.flag          = (u8)flag;

    *(s32 *)buffer = listflag;
    *(s32 *)(buffer + sizeof(s32)) = sequence_insert;
    memcpy(buffer + sizeof(s32) * 2, &rtpolicy_tmp, sizeof(rt_policy_ipv6_s));

    /* 调用conplat_syscall发送数据*/    
    sys_ret = conplat_syscall(MODULEID_RT_POLICY_IPV6 , RT_POLICY_SYSCALL_ADD_OR_MODIFY_IPV6, buffer, 2 * sizeof(s32) + sizeof(rt_policy_ipv6_s), (s32*)&sys_error_code);
	if((ERROR_SUCCESS != sys_error_code && 1 != sys_error_code) || ERROR_SUCCESS != sys_ret)
    {
        sys_error_code = ERR_RT_POLICY_SYSCALL;
        goto label_ret;
    }
    sys_error_code = 0;

    if ( RT_POLICY_ADD_INS == rtpoperation )
    {
        /*向数据库中添加策略*/
        sprintf(sql_insert , "insert into %s (sequence, policy_id, src, dest, iifname, oifname, nexthop, weight, nexthopcount, protocol, minsrcport, maxsrcport, mindstport, maxdstport, flag)"
                             " values('%d', '%d', '%s', '%s', '%s', '%s', '%s', '%s', '%d', '%d', '%d', '%d', '%d', '%d', '%d');" ,
               tb_name, sequence, policyid, src, dest, iifname, oifname, nexthop, weight, (s32)nexthopcount, protocol, minsrcport, maxsrcport, mindstport, maxdstport, (s32)flag);
        if (SQLITE_OK != sqlite3_exec_ex(db, sql_insert))
        {
            sys_error_code = ERR_RT_POLICY_SQL;
            goto label_ret;
        }
        /*记录操作日志*/
        switch (listflag)
        {
            case RT_POLICY_BEFORE_ROUTE:
                WEB_SEND_EX_OPERLOG_QUICK((u32)sys_error_code, 
                    "Add a policy prior than route table: Source Address[%s] Destination Address[%s] "
                    "Interface-In[%s] Interface-Out[%s] Nexthop[%s]", 
                    src, dest, iifname, oifname, nexthop);
                break;
            case RT_POLICY_AFTER_ROUTE:
                WEB_SEND_EX_OPERLOG_QUICK((u32)sys_error_code, 
                    "Add a policy after route table: Source Address[%s] Destination Address[%s] "
                    "Interface-In[%s] Interface-Out[%s] Nexthop[%s]", 
                    src, dest, iifname, oifname, nexthop);
                break;
            case RT_POLICY_LOCAL_ROUTE:
                WEB_SEND_EX_OPERLOG_QUICK((u32)sys_error_code, 
                    "Add local policy: Destination Address[%s] "
                    "Interface-Out[%s] Nexthop[%s]", 
                    dest, oifname, nexthop);
        }
    }
    else
    {
        /*更新数据库*/
        switch (listflag)
        {
            case RT_POLICY_BEFORE_ROUTE:
            case RT_POLICY_AFTER_ROUTE:
                sprintf(sql_update , "update %s set src = '%s',"
                      " dest = '%s', iifname = '%s', oifname = '%s', nexthop = '%s', "
                      " weight = '%s', nexthopcount = '%d', protocol = '%d',"
                      " minsrcport = '%d', maxsrcport = '%d', mindstport = '%d', maxdstport = '%d', flag = '%d'"
                      " where policy_id = %d;" ,
                   tb_name, src, dest, iifname, oifname, nexthop, weight, (s32)nexthopcount, protocol, minsrcport, maxsrcport, mindstport, maxdstport, (s32)flag, policyid);
                if (SQLITE_OK != sqlite3_exec_ex(db, sql_update))
                {
                    sys_error_code = ERR_RT_POLICY_SQL;
                    goto label_ret;
                }
                /*记录操作日志*/
                WEB_SEND_EX_OPERLOG_QUICK((u32)sys_error_code, 
                    "Modify policy route: Source Address[%s] Destination Address[%s] "
                    "Interface-In[%s] Interface-Out[%s] Nexthop[%s] Protocol[%d]", 
                    src, dest, iifname, oifname, nexthop, protocol);
                break;
            case RT_POLICY_LOCAL_ROUTE:
                sprintf(sql_update , "update %s set"
                      " dest = '%s', iifname = '%s', oifname = '%s', nexthop = '%s', "
                      " weight = '%s', nexthopcount = '%d', protocol = '%d',"
                      " minsrcport = '%d', maxsrcport = '%d', mindstport = '%d', maxdstport = '%d', flag = '%d'"
                      " where policy_id = %d;" ,
                   tb_name, dest, iifname, oifname, nexthop, weight, (s32)nexthopcount, protocol, minsrcport, maxsrcport, mindstport, maxdstport, (s32)flag, policyid);
                if (SQLITE_OK != sqlite3_exec_ex(db, sql_update))
                {
                    sys_error_code = ERR_RT_POLICY_SQL;
                    goto label_ret;
                }
                /*记录操作日志*/
                WEB_SEND_EX_OPERLOG_QUICK((u32)sys_error_code, 
                    "Modify policy route: Destination Address[%s] "
                    "Interface-Out[%s] Nexthop[%s] Protocol[%d]", 
                    dest, oifname, nexthop, protocol);
                break;
            }
        
    }

    /* 提交事务 */
    SQLITE_TRANSC_COMMIT(db);


label_ret:

    if (NULL != res)
	{
	    sqlite3_res_free_ex(res);
		res = NULL;
    }

    /*事务未成功*/
    if (SQLITE_OK != ret)
    {
       SQLITE_TRANSC_ROLLBACK(db);
    }
    
    if (NULL != buffer)
    {
        free(buffer);
        buffer = NULL;
    }

    /* 关闭数据库连接 */
    if(NULL != db)
    {
        sqlite3_close_ex(db);
    }

label_err:
    
    *ret = 0;
    if (ERROR_SUCCESS != sys_error_code)
	{   
		return ws_send_soap_error(soap, rt_policy_err_str[sys_error_code]);
	}
    return WS_OK;
}