/* 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); */ }
/* 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; }