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); }
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); }
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); }
static int vxlan_get_egress_tun_info(struct vport *vport, struct sk_buff *skb, struct ovs_tunnel_info *egress_tun_info) { 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); __be16 src_port; src_port = udp_flow_src_port(net, skb, 0, 0, true); return ovs_tunnel_get_egress_info(egress_tun_info, net, OVS_CB(skb)->egress_tun_info, IPPROTO_UDP, skb->mark, src_port, dst_port); }
static int vxlan_get_egress_tun_info(struct vport *vport, struct sk_buff *skb, struct ovs_tunnel_info *egress_tun_info) { 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); __be16 src_port; int port_min; int port_max; inet_get_local_port_range(net, &port_min, &port_max); src_port = vxlan_src_port(port_min, port_max, skb); return ovs_tunnel_get_egress_info(egress_tun_info, net, OVS_CB(skb)->egress_tun_info, IPPROTO_UDP, skb->mark, src_port, dst_port); }
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 net_device *dev; struct vport *vport; struct nlattr *a; int err; struct vxlan_config conf = { .no_share = true, .flags = VXLAN_F_COLLECT_METADATA, }; if (!options) { err = -EINVAL; goto error; } a = nla_find_nested(options, OVS_TUNNEL_ATTR_DST_PORT); if (a && nla_len(a) == sizeof(u16)) { conf.dst_port = htons(nla_get_u16(a)); } else { /* Require destination port from userspace. */ err = -EINVAL; goto error; } vport = ovs_vport_alloc(0, &ovs_vxlan_netdev_vport_ops, parms); if (IS_ERR(vport)) return vport; a = nla_find_nested(options, OVS_TUNNEL_ATTR_EXTENSION); if (a) { err = vxlan_configure_exts(vport, a, &conf); if (err) { ovs_vport_free(vport); goto error; } } rtnl_lock(); dev = vxlan_dev_create(net, parms->name, NET_NAME_USER, &conf); if (IS_ERR(dev)) { rtnl_unlock(); ovs_vport_free(vport); return ERR_CAST(dev); } dev_change_flags(dev, dev->flags | IFF_UP); rtnl_unlock(); return vport; error: return ERR_PTR(err); } static struct vport *vxlan_create(const struct vport_parms *parms) { struct vport *vport; vport = vxlan_tnl_create(parms); if (IS_ERR(vport)) return vport; return ovs_netdev_link(vport, parms->name); } static int vxlan_get_egress_tun_info(struct vport *vport, struct sk_buff *skb, struct dp_upcall_info *upcall) { struct vxlan_dev *vxlan = netdev_priv(vport->dev); struct net *net = ovs_dp_get_net(vport->dp); unsigned short family = ip_tunnel_info_af(upcall->egress_tun_info); __be16 dst_port = vxlan_dev_dst_port(vxlan, family); __be16 src_port; int port_min; int port_max; inet_get_local_port_range(net, &port_min, &port_max); src_port = udp_flow_src_port(net, skb, 0, 0, true); return ovs_tunnel_get_egress_info(upcall, net, skb, IPPROTO_UDP, src_port, dst_port); } static struct vport_ops ovs_vxlan_netdev_vport_ops = { .type = OVS_VPORT_TYPE_VXLAN, .create = vxlan_create, .destroy = ovs_netdev_tunnel_destroy, .get_options = vxlan_get_options, .send = ovs_netdev_send, .get_egress_tun_info = vxlan_get_egress_tun_info, }; static int __init ovs_vxlan_tnl_init(void) { return ovs_vport_ops_register(&ovs_vxlan_netdev_vport_ops); } static void __exit ovs_vxlan_tnl_exit(void) { ovs_vport_ops_unregister(&ovs_vxlan_netdev_vport_ops); }