本文整理汇总了C++中ovs_dp_get_net函数的典型用法代码示例。如果您正苦于以下问题:C++ ovs_dp_get_net函数的具体用法?C++ ovs_dp_get_net怎么用?C++ ovs_dp_get_net使用的例子?那么恭喜您, 这里精选的函数代码示例或许可以为您提供帮助。
在下文中一共展示了ovs_dp_get_net函数的20个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于我们的系统推荐出更棒的C++代码示例。
示例1: patch_set_options
static int patch_set_options(struct vport *vport, struct nlattr *options)
{
struct patch_vport *patch_vport = patch_vport_priv(vport);
struct patch_config *patchconf;
int err;
patchconf = kmemdup(rtnl_dereference(patch_vport->patchconf),
sizeof(struct patch_config), GFP_KERNEL);
if (!patchconf) {
err = -ENOMEM;
goto error;
}
err = patch_set_config(vport, options, patchconf);
if (err)
goto error_free;
assign_config_rcu(vport, patchconf);
hlist_del(&patch_vport->hash_node);
rcu_assign_pointer(patch_vport->peer,
ovs_vport_locate(ovs_dp_get_net(vport->dp), patchconf->peer_name));
hlist_add_head(&patch_vport->hash_node,
hash_bucket(ovs_dp_get_net(vport->dp), patchconf->peer_name));
return 0;
error_free:
kfree(patchconf);
error:
return err;
}
开发者ID:AlickHill,项目名称:Lantern,代码行数:33,代码来源:vport-patch.c
示例2: vxlan_tnl_send
static int vxlan_tnl_send(struct vport *vport, struct sk_buff *skb)
{
struct ovs_key_ipv4_tunnel *tun_key;
struct net *net = ovs_dp_get_net(vport->dp);
struct vxlan_port *vxlan_port = vxlan_vport(vport);
__be16 dst_port = inet_sport(vxlan_port->vs->sock->sk);
struct vxlan_metadata md = {0};
struct rtable *rt;
__be16 src_port;
__be32 saddr;
__be16 df;
int err;
u32 vxflags;
if (unlikely(!OVS_CB(skb)->egress_tun_info)) {
err = -EINVAL;
goto error;
}
tun_key = &OVS_CB(skb)->egress_tun_info->tunnel;
/* Route lookup */
saddr = tun_key->ipv4_src;
rt = find_route(ovs_dp_get_net(vport->dp),
&saddr, tun_key->ipv4_dst,
IPPROTO_UDP, tun_key->ipv4_tos,
skb->mark);
if (IS_ERR(rt)) {
err = PTR_ERR(rt);
goto error;
}
df = tun_key->tun_flags & TUNNEL_DONT_FRAGMENT ? htons(IP_DF) : 0;
skb->ignore_df = 1;
src_port = udp_flow_src_port(net, skb, 0, 0, true);
md.vni = htonl(be64_to_cpu(tun_key->tun_id) << 8);
md.gbp = vxlan_ext_gbp(skb);
vxflags = vxlan_port->exts |
(tun_key->tun_flags & TUNNEL_CSUM ? VXLAN_F_UDP_CSUM : 0);
err = vxlan_xmit_skb(vxlan_port->vs, rt, skb,
saddr, tun_key->ipv4_dst,
tun_key->ipv4_tos,
tun_key->ipv4_ttl, df,
src_port, dst_port,
&md, false, vxflags);
if (err < 0)
ip_rt_put(rt);
return err;
error:
kfree_skb(skb);
return err;
}
开发者ID:AlexanderChou,项目名称:ovs,代码行数:54,代码来源:vport-vxlan.c
示例3: lisp_get_egress_tun_info
static int lisp_get_egress_tun_info(struct vport *vport, struct sk_buff *skb,
struct dp_upcall_info *upcall)
{
struct lisp_port *lisp_port = lisp_vport(vport);
struct net *net = ovs_dp_get_net(vport->dp);
__be16 dport = htons(lisp_port->port_no);
__be16 sport = udp_flow_src_port(net, skb, 1, USHRT_MAX, true);
return ovs_tunnel_get_egress_info(upcall, ovs_dp_get_net(vport->dp),
skb, IPPROTO_UDP, sport, dport);
}
开发者ID:fetzerms,项目名称:ovs,代码行数:11,代码来源:vport-lisp.c
示例4: vxlan_tnl_send
static int vxlan_tnl_send(struct vport *vport, struct sk_buff *skb)
{
struct ovs_key_ipv4_tunnel *tun_key;
struct net *net = ovs_dp_get_net(vport->dp);
struct vxlan_port *vxlan_port = vxlan_vport(vport);
__be16 dst_port = inet_sport(vxlan_port->vs->sock->sk);
struct rtable *rt;
__be16 src_port;
__be32 saddr;
__be16 df;
int port_min;
int port_max;
int err;
if (unlikely(!OVS_CB(skb)->egress_tun_info)) {
err = -EINVAL;
goto error;
}
tun_key = &OVS_CB(skb)->egress_tun_info->tunnel;
/* Route lookup */
saddr = tun_key->ipv4_src;
rt = find_route(ovs_dp_get_net(vport->dp),
&saddr, tun_key->ipv4_dst,
IPPROTO_UDP, tun_key->ipv4_tos,
skb->mark);
if (IS_ERR(rt)) {
err = PTR_ERR(rt);
goto error;
}
df = tun_key->tun_flags & TUNNEL_DONT_FRAGMENT ? htons(IP_DF) : 0;
skb->local_df = 1;
inet_get_local_port_range(net, &port_min, &port_max);
src_port = vxlan_src_port(port_min, port_max, skb);
err = vxlan_xmit_skb(vxlan_port->vs, rt, skb,
saddr, tun_key->ipv4_dst,
tun_key->ipv4_tos,
tun_key->ipv4_ttl, df,
src_port, dst_port,
htonl(be64_to_cpu(tun_key->tun_id) << 8));
if (err < 0)
ip_rt_put(rt);
error:
return err;
}
开发者ID:David-B55,项目名称:ovs,代码行数:49,代码来源:vport-vxlan.c
示例5: stt_get_egress_tun_info
static int stt_get_egress_tun_info(struct vport *vport, struct sk_buff *skb,
struct ovs_tunnel_info *egress_tun_info)
{
struct stt_port *stt_port = stt_vport(vport);
struct net *net = ovs_dp_get_net(vport->dp);
__be16 dport = inet_sk(stt_port->stt_sock->sock->sk)->inet_sport;
__be16 sport = udp_flow_src_port(net, skb, 1, USHRT_MAX, true);
/* Get tp_src and tp_dst, refert to stt_build_header().
*/
return ovs_tunnel_get_egress_info(egress_tun_info,
ovs_dp_get_net(vport->dp),
OVS_CB(skb)->egress_tun_info,
IPPROTO_TCP, skb->mark, sport, dport);
}
开发者ID:HaochuanXJTU,项目名称:ovs,代码行数:15,代码来源:vport-stt.c
示例6: ovs_vport_receive
/**
* ovs_vport_receive - pass up received packet to the datapath for processing
*
* @vport: vport that received the packet
* @skb: skb that was received
* @tun_key: tunnel (if any) that carried packet
*
* Must be called with rcu_read_lock. The packet cannot be shared and
* skb->data should point to the Ethernet header.
*/
int ovs_vport_receive(struct vport *vport, struct sk_buff *skb,
const struct ip_tunnel_info *tun_info)
{
struct sw_flow_key key;
int error;
OVS_CB(skb)->input_vport = vport;
OVS_CB(skb)->mru = 0;
OVS_CB(skb)->cutlen = 0;
if (unlikely(dev_net(skb->dev) != ovs_dp_get_net(vport->dp))) {
u32 mark;
mark = skb->mark;
skb_scrub_packet(skb, true);
skb->mark = mark;
tun_info = NULL;
}
ovs_skb_init_inner_protocol(skb);
skb_clear_ovs_gso_cb(skb);
/* Extract flow from 'skb' into 'key'. */
error = ovs_flow_key_extract(tun_info, skb, &key);
if (unlikely(error)) {
kfree_skb(skb);
return error;
}
ovs_dp_process_packet(skb, &key);
return 0;
}
开发者ID:JunoZhu,项目名称:ovs,代码行数:39,代码来源:vport.c
示例7: ovs_dp_get_net
static struct vport *gre_tnl_create(const struct vport_parms *parms)
{
struct net *net = ovs_dp_get_net(parms->dp);
struct net_device *dev;
struct vport *vport;
int err;
vport = ovs_vport_alloc(0, &ovs_gre_vport_ops, parms);
if (IS_ERR(vport))
return vport;
rtnl_lock();
dev = gretap_fb_dev_create(net, parms->name, NET_NAME_USER);
if (IS_ERR(dev)) {
rtnl_unlock();
ovs_vport_free(vport);
return ERR_CAST(dev);
}
err = dev_change_flags(dev, dev->flags | IFF_UP);
if (err < 0) {
rtnl_delete_link(dev);
rtnl_unlock();
ovs_vport_free(vport);
return ERR_PTR(err);
}
rtnl_unlock();
return vport;
}
开发者ID:Grim-lock,项目名称:ovs,代码行数:30,代码来源:vport-gre.c
示例8: __send
static int __send(struct vport *vport, struct sk_buff *skb,
int tunnel_hlen,
__be32 seq, __be16 gre64_flag)
{
struct ovs_key_ipv4_tunnel *tun_key = &OVS_CB(skb)->tun_info->tunnel;
struct rtable *rt;
int min_headroom;
__be16 df;
__be32 saddr;
int err;
/* Route lookup */
saddr = tun_key->ipv4_src;
rt = find_route(ovs_dp_get_net(vport->dp),
&saddr, tun_key->ipv4_dst,
IPPROTO_GRE, tun_key->ipv4_tos,
skb->mark);
if (IS_ERR(rt)) {
err = PTR_ERR(rt);
goto error;
}
min_headroom = LL_RESERVED_SPACE(rt_dst(rt).dev) + rt_dst(rt).header_len
+ tunnel_hlen + sizeof(struct iphdr)
+ (vlan_tx_tag_present(skb) ? VLAN_HLEN : 0);
if (skb_headroom(skb) < min_headroom || skb_header_cloned(skb)) {
int head_delta = SKB_DATA_ALIGN(min_headroom -
skb_headroom(skb) +
16);
err = pskb_expand_head(skb, max_t(int, head_delta, 0),
0, GFP_ATOMIC);
if (unlikely(err))
goto err_free_rt;
}
开发者ID:MatheMatrix,项目名称:ovs,代码行数:35,代码来源:vport-gre.c
示例9: ovs_vport_alloc
static struct vport *netdev_create(const struct vport_parms *parms)
{
struct vport *vport;
struct netdev_vport *netdev_vport;
int err;
vport = ovs_vport_alloc(sizeof(struct netdev_vport),
&ovs_netdev_vport_ops, parms);
if (IS_ERR(vport)) {
err = PTR_ERR(vport);
goto error;
}
netdev_vport = netdev_vport_priv(vport);
netdev_vport->dev = dev_get_by_name(ovs_dp_get_net(vport->dp), parms->name);
if (!netdev_vport->dev) {
err = -ENODEV;
goto error_free_vport;
}
if (netdev_vport->dev->flags & IFF_LOOPBACK ||
netdev_vport->dev->type != ARPHRD_ETHER ||
ovs_is_internal_dev(netdev_vport->dev)) {
err = -EINVAL;
goto error_put;
}
rtnl_lock();
err = netdev_master_upper_dev_link(netdev_vport->dev,
get_dpdev(vport->dp));
if (err)
goto error_unlock;
err = netdev_rx_handler_register(netdev_vport->dev, netdev_frame_hook,
vport);
if (err)
goto error_master_upper_dev_unlink;
dev_set_promiscuity(netdev_vport->dev, 1);
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24)
dev_disable_lro(netdev_vport->dev);
#endif
netdev_vport->dev->priv_flags |= IFF_OVS_DATAPATH;
rtnl_unlock();
netdev_init();
return vport;
error_master_upper_dev_unlink:
netdev_upper_dev_unlink(netdev_vport->dev, get_dpdev(vport->dp));
error_unlock:
rtnl_unlock();
error_put:
dev_put(netdev_vport->dev);
error_free_vport:
ovs_vport_free(vport);
error:
return ERR_PTR(err);
}
开发者ID:ravikondamuru,项目名称:openvswitch,代码行数:60,代码来源:vport-netdev.c
示例10: ovs_vport_alloc
static struct vport *netdev_create(const struct vport_parms *parms)
{
struct vport *vport;
struct netdev_vport *netdev_vport;
int err;
vport = ovs_vport_alloc(sizeof(struct netdev_vport),
&ovs_netdev_vport_ops, parms);
if (IS_ERR(vport)) {
err = PTR_ERR(vport);
goto error;
}
netdev_vport = netdev_vport_priv(vport);
netdev_vport->dev = dev_get_by_name(ovs_dp_get_net(vport->dp), parms->name);
if (!netdev_vport->dev) {
err = -ENODEV;
goto error_free_vport;
}
if (netdev_vport->dev->flags & IFF_LOOPBACK ||
netdev_vport->dev->type != ARPHRD_ETHER ||
ovs_is_internal_dev(netdev_vport->dev)) {
err = -EINVAL;
goto error_put;
}
rtnl_lock();
#ifdef HAVE_RHEL_OVS_HOOK
rcu_assign_pointer(netdev_vport->dev->ax25_ptr, vport);
atomic_inc(&nr_bridges);
rcu_assign_pointer(openvswitch_handle_frame_hook, netdev_frame_hook);
#else
err = netdev_rx_handler_register(netdev_vport->dev, netdev_frame_hook,
vport);
if (err)
goto error_unlock;
#endif
dev_set_promiscuity(netdev_vport->dev, 1);
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24)
dev_disable_lro(netdev_vport->dev);
#endif
netdev_vport->dev->priv_flags |= IFF_OVS_DATAPATH;
rtnl_unlock();
return vport;
#ifndef HAVE_RHEL_OVS_HOOK
error_unlock:
#endif
rtnl_unlock();
error_put:
dev_put(netdev_vport->dev);
error_free_vport:
ovs_vport_free(vport);
error:
return ERR_PTR(err);
}
开发者ID:cardinal27513,项目名称:ovs-vxlan,代码行数:60,代码来源:vport-netdev.c
示例11: PTR_ERR
/**
* ovs_vport_add - add vport device (for kernel callers)
*
* @parms: Information about new vport.
*
* Creates a new vport with the specified configuration (which is dependent on
* device type). ovs_mutex must be held.
*/
struct vport *ovs_vport_add(const struct vport_parms *parms)
{
struct vport *vport;
int err = 0;
int i;
for (i = 0; i < ARRAY_SIZE(vport_ops_list); i++) {
if (vport_ops_list[i]->type == parms->type) {
struct hlist_head *bucket;
vport = vport_ops_list[i]->create(parms);
if (IS_ERR(vport)) {
err = PTR_ERR(vport);
goto out;
}
bucket = hash_bucket(ovs_dp_get_net(vport->dp),
vport->ops->get_name(vport));
hlist_add_head_rcu(&vport->hash_node, bucket);
return vport;
}
}
err = -EAFNOSUPPORT;
out:
return ERR_PTR(err);
}
开发者ID:7799,项目名称:linux,代码行数:36,代码来源:vport.c
示例12: vxlan_tnl_send
static int vxlan_tnl_send(struct vport *vport, struct sk_buff *skb)
{
struct net *net = ovs_dp_get_net(vport->dp);
struct vxlan_port *vxlan_port = vxlan_vport(vport);
__be16 dst_port = inet_sport(vxlan_port->vs->sock->sk);
struct rtable *rt;
__be16 src_port;
__be32 saddr;
__be16 df;
int err;
if (unlikely(!OVS_CB(skb)->tun_key)) {
err = -EINVAL;
goto error;
}
/* Route lookup */
saddr = OVS_CB(skb)->tun_key->ipv4_src;
rt = find_route(ovs_dp_get_net(vport->dp),
&saddr,
OVS_CB(skb)->tun_key->ipv4_dst,
IPPROTO_UDP,
OVS_CB(skb)->tun_key->ipv4_tos,
skb->mark);
if (IS_ERR(rt)) {
err = PTR_ERR(rt);
goto error;
}
df = OVS_CB(skb)->tun_key->tun_flags & TUNNEL_DONT_FRAGMENT ?
htons(IP_DF) : 0;
skb->local_df = 1;
src_port = udp_flow_src_port(net, skb, 0, 0, true);
err = vxlan_xmit_skb(vxlan_port->vs, rt, skb,
saddr, OVS_CB(skb)->tun_key->ipv4_dst,
OVS_CB(skb)->tun_key->ipv4_tos,
OVS_CB(skb)->tun_key->ipv4_ttl, df,
src_port, dst_port,
htonl(be64_to_cpu(OVS_CB(skb)->tun_key->tun_id) << 8));
if (err < 0)
ip_rt_put(rt);
error:
return err;
}
开发者ID:dariobanfi,项目名称:ovs-multipath,代码行数:47,代码来源:vport-vxlan.c
示例13: gre_get_egress_tun_info
static int gre_get_egress_tun_info(struct vport *vport, struct sk_buff *skb,
struct ip_tunnel_info *egress_tun_info)
{
return ovs_tunnel_get_egress_info(egress_tun_info,
ovs_dp_get_net(vport->dp),
OVS_CB(skb)->egress_tun_info,
IPPROTO_GRE, skb->mark, 0, 0);
}
开发者ID:scollison,项目名称:net-next-nuse,代码行数:8,代码来源:vport-gre.c
示例14: patch_destroy
static void patch_destroy(struct vport *vport)
{
struct patch_vport *patch_vport = patch_vport_priv(vport);
update_peers(ovs_dp_get_net(vport->dp), patch_vport->name, NULL);
hlist_del(&patch_vport->hash_node);
call_rcu(&patch_vport->rcu, free_port_rcu);
}
开发者ID:AlickHill,项目名称:Lantern,代码行数:8,代码来源:vport-patch.c
示例15: ovs_vport_alloc
static struct vport *internal_dev_create(const struct vport_parms *parms)
{
struct vport *vport;
struct internal_dev *internal_dev;
int err;
vport = ovs_vport_alloc(0, &ovs_internal_vport_ops, parms);
if (IS_ERR(vport)) {
err = PTR_ERR(vport);
goto error;
}
vport->dev = alloc_netdev(sizeof(struct internal_dev),
parms->name, NET_NAME_USER, do_setup);
if (!vport->dev) {
err = -ENOMEM;
goto error_free_vport;
}
vport->dev->tstats = netdev_alloc_pcpu_stats(struct pcpu_sw_netstats);
if (!vport->dev->tstats) {
err = -ENOMEM;
goto error_free_netdev;
}
#ifdef HAVE_IFF_PHONY_HEADROOM
vport->dev->needed_headroom = vport->dp->max_headroom;
#endif
dev_net_set(vport->dev, ovs_dp_get_net(vport->dp));
internal_dev = internal_dev_priv(vport->dev);
internal_dev->vport = vport;
/* Restrict bridge port to current netns. */
if (vport->port_no == OVSP_LOCAL)
vport->dev->features |= NETIF_F_NETNS_LOCAL;
rtnl_lock();
err = register_netdevice(vport->dev);
if (err)
goto error_unlock;
dev_set_promiscuity(vport->dev, 1);
rtnl_unlock();
netif_start_queue(vport->dev);
return vport;
error_unlock:
rtnl_unlock();
free_percpu(vport->dev->tstats);
error_free_netdev:
free_netdev(vport->dev);
error_free_vport:
ovs_vport_free(vport);
error:
return ERR_PTR(err);
}
开发者ID:Grim-lock,项目名称:ovs,代码行数:56,代码来源:vport-internal_dev.c
示例16: gre64_tnl_destroy
static void gre64_tnl_destroy(struct vport *vport)
{
struct net *net = ovs_dp_get_net(vport->dp);
struct ovs_net *ovs_net;
ovs_net = net_generic(net, ovs_net_id);
rcu_assign_pointer(ovs_net->vport_net.gre64_vport, NULL);
ovs_tnl_destroy(vport);
}
开发者ID:carriercomm,项目名称:openvSwitch.10,代码行数:10,代码来源:vport-gre.c
示例17: destroy_dp_rcu
static void destroy_dp_rcu(struct rcu_head *rcu)
{
struct datapath *dp = container_of(rcu, struct datapath, rcu);
ovs_flow_tbl_destroy((__force struct flow_table *)dp->table);
free_percpu(dp->stats_percpu);
release_net(ovs_dp_get_net(dp));
kfree(dp->ports);
kfree(dp);
}
开发者ID:AiWinters,项目名称:linux,代码行数:10,代码来源:datapath.c
示例18: stt_tnl_send
static int stt_tnl_send(struct vport *vport, struct sk_buff *skb)
{
struct net *net = ovs_dp_get_net(vport->dp);
struct stt_port *stt_port = stt_vport(vport);
__be16 dport = inet_sk(stt_port->stt_sock->sock->sk)->inet_sport;
const struct ovs_key_ipv4_tunnel *tun_key;
const struct ovs_tunnel_info *tun_info;
struct rtable *rt;
__be16 sport;
__be32 saddr;
__be16 df;
int err;
tun_info = OVS_CB(skb)->egress_tun_info;
if (unlikely(!tun_info)) {
err = -EINVAL;
goto error;
}
tun_key = &tun_info->tunnel;
/* Route lookup */
saddr = tun_key->ipv4_src;
rt = find_route(ovs_dp_get_net(vport->dp),
&saddr, tun_key->ipv4_dst,
IPPROTO_TCP, tun_key->ipv4_tos,
skb->mark);
if (IS_ERR(rt)) {
err = PTR_ERR(rt);
goto error;
}
df = tun_key->tun_flags & TUNNEL_DONT_FRAGMENT ? htons(IP_DF) : 0;
sport = udp_flow_src_port(net, skb, 1, USHRT_MAX, true);
skb->ignore_df = 1;
return stt_xmit_skb(skb, rt, saddr, tun_key->ipv4_dst,
tun_key->ipv4_tos, tun_key->ipv4_ttl,
df, sport, dport, tun_key->tun_id);
error:
kfree_skb(skb);
return err;
}
开发者ID:HaochuanXJTU,项目名称:ovs,代码行数:43,代码来源:vport-stt.c
示例19: ovs_dp_get_net
static struct vport *vxlan_tnl_create(const struct vport_parms *parms)
{
struct net *net = ovs_dp_get_net(parms->dp);
struct nlattr *options = parms->options;
struct vxlan_port *vxlan_port;
struct vxlan_sock *vs;
struct vport *vport;
struct nlattr *a;
u16 dst_port;
int err;
if (!options) {
err = -EINVAL;
goto error;
}
a = nla_find_nested(options, OVS_TUNNEL_ATTR_DST_PORT);
if (a && nla_len(a) == sizeof(u16)) {
dst_port = nla_get_u16(a);
} else {
/* Require destination port from userspace. */
err = -EINVAL;
goto error;
}
vport = ovs_vport_alloc(sizeof(struct vxlan_port),
&ovs_vxlan_vport_ops, parms);
if (IS_ERR(vport))
return vport;
vxlan_port = vxlan_vport(vport);
strncpy(vxlan_port->name, parms->name, IFNAMSIZ);
a = nla_find_nested(options, OVS_TUNNEL_ATTR_EXTENSION);
if (a) {
err = vxlan_configure_exts(vport, a);
if (err) {
ovs_vport_free(vport);
goto error;
}
}
vs = vxlan_sock_add(net, htons(dst_port), vxlan_rcv, vport, true,
vxlan_port->exts);
if (IS_ERR(vs)) {
ovs_vport_free(vport);
return (void *)vs;
}
vxlan_port->vs = vs;
return vport;
error:
return ERR_PTR(err);
}
开发者ID:19Dan01,项目名称:linux,代码行数:54,代码来源:vport-vxlan.c
示例20: hash_bucket
/**
* ovs_vport_locate - find a port that has already been created
*
* @name: name of port to find
*
* Must be called with ovs or RCU read lock.
*/
struct vport *ovs_vport_locate(const struct net *net, const char *name)
{
struct hlist_head *bucket = hash_bucket(net, name);
struct vport *vport;
hlist_for_each_entry_rcu(vport, bucket, hash_node)
if (!strcmp(name, ovs_vport_name(vport)) &&
net_eq(ovs_dp_get_net(vport->dp), net))
return vport;
return NULL;
}
开发者ID:JunoZhu,项目名称:ovs,代码行数:19,代码来源:vport.c
注:本文中的ovs_dp_get_net函数示例由纯净天空整理自Github/MSDocs等源码及文档管理平台,相关代码片段筛选自各路编程大神贡献的开源项目,源码版权归原作者所有,传播和使用请参考对应项目的License;未经允许,请勿转载。 |
请发表评论