/* 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); }
/* * 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; }
/* 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; }
/* 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*/}
/******************************************************************************* 函数名称 : 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; }