Beispiel #1
0
/* Interface between zebra message and rtm message. */
static int
kernel_rtm_ipv6 (int message, struct prefix_ipv6 *dest,
		 struct in6_addr *gate, int index, int flags)
{
  struct sockaddr_in6 *mask;
  struct sockaddr_in6 sin_dest, sin_mask, sin_gate;

  memset (&sin_dest, 0, sizeof (struct sockaddr_in6));
  sin_dest.sin6_family = AF_INET6;
#ifdef SIN6_LEN
  sin_dest.sin6_len = sizeof (struct sockaddr_in6);
#endif /* SIN6_LEN */

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

  memset (&sin_gate, 0, sizeof (struct sockaddr_in6));
  sin_gate.sin6_family = AF_INET6;
#ifdef SIN6_LEN
  sin_gate.sin6_len = sizeof (struct sockaddr_in6);
#endif /* SIN6_LEN */

  sin_dest.sin6_addr = dest->prefix;

  if (gate)
    memcpy (&sin_gate.sin6_addr, gate, sizeof (struct in6_addr));

  /* Under kame set interface index to link local address. */
#ifdef KAME

#define SET_IN6_LINKLOCAL_IFINDEX(a, i) \
  do { \
    (a).s6_addr[2] = ((i) >> 8) & 0xff; \
    (a).s6_addr[3] = (i) & 0xff; \
  } while (0)

  if (gate && IN6_IS_ADDR_LINKLOCAL(gate))
    SET_IN6_LINKLOCAL_IFINDEX (sin_gate.sin6_addr, index);
#endif /* KAME */

  if (gate && dest->prefixlen == 128)
    mask = NULL;
  else
    {
      masklen2ip6 (dest->prefixlen, &sin_mask.sin6_addr);
      sin_mask.sin6_family = AF_INET6;
#ifdef SIN6_LEN
      sin_mask.sin6_len = sin6_masklen (sin_mask.sin6_addr);
#endif /* SIN6_LEN */
      mask = &sin_mask;
    }

  return rtm_write (message, 
		    (union sockunion *) &sin_dest,
		    (union sockunion *) mask,
		    gate ? (union sockunion *)&sin_gate : NULL,
		    index,
		    flags,
		    0);
}
Beispiel #2
0
/*
 * Helper for interface-addr install, non-netlink
 */
static int if_set_prefix6_ctx(const struct zebra_dplane_ctx *ctx)
{
	int ret;
	struct in6_aliasreq addreq;
	struct sockaddr_in6 addr;
	struct sockaddr_in6 mask;
	struct prefix_ipv6 *p;

	p = (struct prefix_ipv6 *)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_in6));
	addr.sin6_addr = p->prefix;
	addr.sin6_family = p->family;
#ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
	addr.sin6_len = sizeof(struct sockaddr_in6);
#endif
	memcpy(&addreq.ifra_addr, &addr, sizeof(struct sockaddr_in6));

	memset(&mask, 0, sizeof(struct sockaddr_in6));
	masklen2ip6(p->prefixlen, &mask.sin6_addr);
	mask.sin6_family = p->family;
#ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
	mask.sin6_len = sizeof(struct sockaddr_in6);
#endif
	memcpy(&addreq.ifra_prefixmask, &mask, sizeof(struct sockaddr_in6));

	addreq.ifra_lifetime.ia6t_vltime = 0xffffffff;
	addreq.ifra_lifetime.ia6t_pltime = 0xffffffff;

#ifdef HAVE_STRUCT_IF6_ALIASREQ_IFRA_LIFETIME
	addreq.ifra_lifetime.ia6t_pltime = ND6_INFINITE_LIFETIME;
	addreq.ifra_lifetime.ia6t_vltime = ND6_INFINITE_LIFETIME;
#endif

	ret = if_ioctl_ipv6(SIOCAIFADDR_IN6, (caddr_t)&addreq);
	if (ret < 0)
		return ret;
	return 0;
}
Beispiel #3
0
/* Interface's address add/delete functions. */
int
if_prefix_add_ipv6 (struct interface *ifp, struct connected *ifc)
{
  int ret;
  struct prefix_ipv6 *p;
  struct in6_ifreq ifreq;

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

  memset (&ifreq, 0, sizeof (struct in6_ifreq));

  memcpy (&ifreq.ifr6_addr, &p->prefix, sizeof (struct in6_addr));
  ifreq.ifr6_ifindex = ifp->ifindex;
  ifreq.ifr6_prefixlen = p->prefixlen;

  ret = if_ioctl_ipv6 (SIOCSIFADDR, (caddr_t) &ifreq);

  return ret;
}

int
if_prefix_delete_ipv6 (struct interface *ifp, struct connected *ifc)
{
  int ret;
  struct prefix_ipv6 *p;
  struct in6_ifreq ifreq;

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

  memset (&ifreq, 0, sizeof (struct in6_ifreq));

  memcpy (&ifreq.ifr6_addr, &p->prefix, sizeof (struct in6_addr));
  ifreq.ifr6_ifindex = ifp->ifindex;
  ifreq.ifr6_prefixlen = p->prefixlen;

  ret = if_ioctl_ipv6 (SIOCDIFADDR, (caddr_t) &ifreq);

  return ret;
}
#else /* LINUX_IPV6 */
#ifdef HAVE_STRUCT_IN6_ALIASREQ
#ifndef ND6_INFINITE_LIFETIME
#define ND6_INFINITE_LIFETIME 0xffffffffL
#endif /* ND6_INFINITE_LIFETIME */
int
if_prefix_add_ipv6 (struct interface *ifp, struct connected *ifc)
{
  int ret;
  struct in6_aliasreq addreq;
  struct sockaddr_in6 addr;
  struct sockaddr_in6 mask;
  struct prefix_ipv6 *p;

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

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

  memset (&addr, 0, sizeof (struct sockaddr_in6));
  addr.sin6_addr = p->prefix;
  addr.sin6_family = p->family;
#ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
  addr.sin6_len = sizeof (struct sockaddr_in6);
#endif
  memcpy (&addreq.ifra_addr, &addr, sizeof (struct sockaddr_in6));

  memset (&mask, 0, sizeof (struct sockaddr_in6));
  masklen2ip6 (p->prefixlen, &mask.sin6_addr);
  mask.sin6_family = p->family;
#ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
  mask.sin6_len = sizeof (struct sockaddr_in6);
#endif
  memcpy (&addreq.ifra_prefixmask, &mask, sizeof (struct sockaddr_in6));

  addreq.ifra_lifetime.ia6t_vltime = 0xffffffff;
  addreq.ifra_lifetime.ia6t_pltime = 0xffffffff;
  
#ifdef HAVE_STRUCT_IF6_ALIASREQ_IFRA_LIFETIME 
  addreq.ifra_lifetime.ia6t_pltime = ND6_INFINITE_LIFETIME; 
  addreq.ifra_lifetime.ia6t_vltime = ND6_INFINITE_LIFETIME; 
#endif

  ret = if_ioctl_ipv6 (SIOCAIFADDR_IN6, (caddr_t) &addreq);
  if (ret < 0)
    return ret;
  return 0;
}
Beispiel #4
0
/* Interface between zebra message and rtm message. */
static int
kernel_rtm_ipv6_multipath(int cmd, struct prefix *p, struct rib *rib,
			  int family)
{
	struct sockaddr_in6 *mask;
	struct sockaddr_in6 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;

	memset(&sin_dest, 0, sizeof(struct sockaddr_in6));
	sin_dest.sin6_family = AF_INET6;
#ifdef SIN6_LEN
	sin_dest.sin6_len = sizeof(struct sockaddr_in6);
#endif /* SIN6_LEN */
	sin_dest.sin6_addr = p->u.prefix6;

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

	memset(&sin_gate, 0, sizeof(struct sockaddr_in6));
	sin_gate.sin6_family = AF_INET6;
#ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
	sin_gate.sin6_len = sizeof(struct sockaddr_in6);
#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;

		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 (nexthop->type == NEXTHOP_TYPE_IPV6
			    || nexthop->type == NEXTHOP_TYPE_IPV6_IFNAME
			    || nexthop->type == NEXTHOP_TYPE_IPV6_IFINDEX) {
				sin_gate.sin6_addr = nexthop->gate.ipv6;
				gate = 1;
			}
			if (nexthop->type == NEXTHOP_TYPE_IFINDEX
			    || nexthop->type == NEXTHOP_TYPE_IFNAME
			    || nexthop->type == NEXTHOP_TYPE_IPV6_IFNAME
			    || nexthop->type == NEXTHOP_TYPE_IPV6_IFINDEX)
				ifindex = nexthop->ifindex;

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

		/* Under kame set interface index to link local address. */
#ifdef KAME

#define SET_IN6_LINKLOCAL_IFINDEX(a, i) \
      do { \
	(a).s6_addr[2] = ((i) >> 8) & 0xff; \
	(a).s6_addr[3] = (i) & 0xff; \
      } while (0)

		if (gate && IN6_IS_ADDR_LINKLOCAL(&sin_gate.sin6_addr))
			SET_IN6_LINKLOCAL_IFINDEX(sin_gate.sin6_addr, ifindex);
#endif /* KAME */

		if (gate && p->prefixlen == 128)
			mask = NULL;
		else {
			masklen2ip6(p->prefixlen, &sin_mask.sin6_addr);
			sin_mask.sin6_family = AF_INET6;
#ifdef SIN6_LEN
			sin_mask.sin6_len = sin6_masklen(sin_mask.sin6_addr);
#endif /* SIN6_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_ipv6_multipath(): 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_ipv6_multipath(): No useful nexthop.");
		return 0;
	}

	return 0;
 /*XXX*/}
Beispiel #5
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;
}