Exemple #1
0
/* IPv6 route add and delete test. */
void
zebra_test_v6 (int sock)
{
    struct prefix_ipv6 p;
    struct in6_addr nexthop;

    str2prefix_ipv6 ("3ffe:506::2/128", &p);
    inet_pton (AF_INET6, "::1", &nexthop);

    /* zebra_ipv6_add (sock, ZEBRA_ROUTE_STATIC, 0, &p, &nexthop, 1); */

    sleep (5);
    /* zebra_ipv6_delete (sock, ZEBRA_ROUTE_STATIC, 0, &p, &nexthop, 1); */
}
Exemple #2
0
/* Generic function for conversion string to struct prefix. */
int str2prefix(const char *str, struct prefix *p)
{
	int ret;

	/* First we try to convert string to struct prefix_ipv4. */
	ret = str2prefix_ipv4(str, (struct prefix_ipv4 *)p);
	if (ret)
		return ret;

#ifdef HAVE_IPV6
	/* Next we try to convert string to struct prefix_ipv6. */
	ret = str2prefix_ipv6(str, (struct prefix_ipv6 *)p);
	if (ret)
		return ret;
#endif /* HAVE_IPV6 */

	return 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;
}