Commit aec15924 authored by Pravin B Shelar's avatar Pravin B Shelar Committed by David S. Miller

openvswitch: Use dev_queue_xmit for vport send.

With use of lwtunnel, we can directly call dev_queue_xmit()
rather than calling netdev vport send operation.
Following change make tunnel vport code bit cleaner.
Signed-off-by: default avatarPravin B Shelar <pshelar@nicira.com>
Acked-by: default avatarThomas Graf <tgraf@suug.ch>
Acked-by: default avatarJiri Benc <jbenc@redhat.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 99e28f18
...@@ -128,7 +128,7 @@ static struct vport_ops ovs_geneve_vport_ops = { ...@@ -128,7 +128,7 @@ static struct vport_ops ovs_geneve_vport_ops = {
.create = geneve_create, .create = geneve_create,
.destroy = ovs_netdev_tunnel_destroy, .destroy = ovs_netdev_tunnel_destroy,
.get_options = geneve_get_options, .get_options = geneve_get_options,
.send = ovs_netdev_send, .send = dev_queue_xmit,
.owner = THIS_MODULE, .owner = THIS_MODULE,
.get_egress_tun_info = geneve_get_egress_tun_info, .get_egress_tun_info = geneve_get_egress_tun_info,
}; };
......
...@@ -94,7 +94,7 @@ static int gre_get_egress_tun_info(struct vport *vport, struct sk_buff *skb, ...@@ -94,7 +94,7 @@ static int gre_get_egress_tun_info(struct vport *vport, struct sk_buff *skb,
static struct vport_ops ovs_gre_vport_ops = { static struct vport_ops ovs_gre_vport_ops = {
.type = OVS_VPORT_TYPE_GRE, .type = OVS_VPORT_TYPE_GRE,
.create = gre_create, .create = gre_create,
.send = ovs_netdev_send, .send = dev_queue_xmit,
.get_egress_tun_info = gre_get_egress_tun_info, .get_egress_tun_info = gre_get_egress_tun_info,
.destroy = ovs_netdev_tunnel_destroy, .destroy = ovs_netdev_tunnel_destroy,
.owner = THIS_MODULE, .owner = THIS_MODULE,
......
...@@ -202,22 +202,21 @@ static void internal_dev_destroy(struct vport *vport) ...@@ -202,22 +202,21 @@ static void internal_dev_destroy(struct vport *vport)
rtnl_unlock(); rtnl_unlock();
} }
static void internal_dev_recv(struct vport *vport, struct sk_buff *skb) static netdev_tx_t internal_dev_recv(struct sk_buff *skb)
{ {
struct net_device *netdev = vport->dev; struct net_device *netdev = skb->dev;
struct pcpu_sw_netstats *stats; struct pcpu_sw_netstats *stats;
if (unlikely(!(netdev->flags & IFF_UP))) { if (unlikely(!(netdev->flags & IFF_UP))) {
kfree_skb(skb); kfree_skb(skb);
netdev->stats.rx_dropped++; netdev->stats.rx_dropped++;
return; return NETDEV_TX_OK;
} }
skb_dst_drop(skb); skb_dst_drop(skb);
nf_reset(skb); nf_reset(skb);
secpath_reset(skb); secpath_reset(skb);
skb->dev = netdev;
skb->pkt_type = PACKET_HOST; skb->pkt_type = PACKET_HOST;
skb->protocol = eth_type_trans(skb, netdev); skb->protocol = eth_type_trans(skb, netdev);
skb_postpull_rcsum(skb, eth_hdr(skb), ETH_HLEN); skb_postpull_rcsum(skb, eth_hdr(skb), ETH_HLEN);
...@@ -229,6 +228,7 @@ static void internal_dev_recv(struct vport *vport, struct sk_buff *skb) ...@@ -229,6 +228,7 @@ static void internal_dev_recv(struct vport *vport, struct sk_buff *skb)
u64_stats_update_end(&stats->syncp); u64_stats_update_end(&stats->syncp);
netif_rx(skb); netif_rx(skb);
return NETDEV_TX_OK;
} }
static struct vport_ops ovs_internal_vport_ops = { static struct vport_ops ovs_internal_vport_ops = {
......
...@@ -190,37 +190,6 @@ void ovs_netdev_tunnel_destroy(struct vport *vport) ...@@ -190,37 +190,6 @@ void ovs_netdev_tunnel_destroy(struct vport *vport)
} }
EXPORT_SYMBOL_GPL(ovs_netdev_tunnel_destroy); EXPORT_SYMBOL_GPL(ovs_netdev_tunnel_destroy);
static unsigned int packet_length(const struct sk_buff *skb)
{
unsigned int length = skb->len - ETH_HLEN;
if (skb->protocol == htons(ETH_P_8021Q))
length -= VLAN_HLEN;
return length;
}
void ovs_netdev_send(struct vport *vport, struct sk_buff *skb)
{
int mtu = vport->dev->mtu;
if (unlikely(packet_length(skb) > mtu && !skb_is_gso(skb))) {
net_warn_ratelimited("%s: dropped over-mtu packet: %d > %d\n",
vport->dev->name,
packet_length(skb), mtu);
vport->dev->stats.tx_errors++;
goto drop;
}
skb->dev = vport->dev;
dev_queue_xmit(skb);
return;
drop:
kfree_skb(skb);
}
EXPORT_SYMBOL_GPL(ovs_netdev_send);
/* Returns null if this device is not attached to a datapath. */ /* Returns null if this device is not attached to a datapath. */
struct vport *ovs_netdev_get_vport(struct net_device *dev) struct vport *ovs_netdev_get_vport(struct net_device *dev)
{ {
...@@ -235,7 +204,7 @@ static struct vport_ops ovs_netdev_vport_ops = { ...@@ -235,7 +204,7 @@ static struct vport_ops ovs_netdev_vport_ops = {
.type = OVS_VPORT_TYPE_NETDEV, .type = OVS_VPORT_TYPE_NETDEV,
.create = netdev_create, .create = netdev_create,
.destroy = netdev_destroy, .destroy = netdev_destroy,
.send = ovs_netdev_send, .send = dev_queue_xmit,
}; };
int __init ovs_netdev_init(void) int __init ovs_netdev_init(void)
......
...@@ -27,7 +27,6 @@ ...@@ -27,7 +27,6 @@
struct vport *ovs_netdev_get_vport(struct net_device *dev); struct vport *ovs_netdev_get_vport(struct net_device *dev);
struct vport *ovs_netdev_link(struct vport *vport, const char *name); struct vport *ovs_netdev_link(struct vport *vport, const char *name);
void ovs_netdev_send(struct vport *vport, struct sk_buff *skb);
void ovs_netdev_detach_dev(struct vport *); void ovs_netdev_detach_dev(struct vport *);
int __init ovs_netdev_init(void); int __init ovs_netdev_init(void);
......
...@@ -170,7 +170,7 @@ static struct vport_ops ovs_vxlan_netdev_vport_ops = { ...@@ -170,7 +170,7 @@ static struct vport_ops ovs_vxlan_netdev_vport_ops = {
.create = vxlan_create, .create = vxlan_create,
.destroy = ovs_netdev_tunnel_destroy, .destroy = ovs_netdev_tunnel_destroy,
.get_options = vxlan_get_options, .get_options = vxlan_get_options,
.send = ovs_netdev_send, .send = dev_queue_xmit,
.get_egress_tun_info = vxlan_get_egress_tun_info, .get_egress_tun_info = vxlan_get_egress_tun_info,
}; };
......
...@@ -537,3 +537,33 @@ int ovs_vport_get_egress_tun_info(struct vport *vport, struct sk_buff *skb, ...@@ -537,3 +537,33 @@ int ovs_vport_get_egress_tun_info(struct vport *vport, struct sk_buff *skb,
return vport->ops->get_egress_tun_info(vport, skb, upcall); return vport->ops->get_egress_tun_info(vport, skb, upcall);
} }
static unsigned int packet_length(const struct sk_buff *skb)
{
unsigned int length = skb->len - ETH_HLEN;
if (skb->protocol == htons(ETH_P_8021Q))
length -= VLAN_HLEN;
return length;
}
void ovs_vport_send(struct vport *vport, struct sk_buff *skb)
{
int mtu = vport->dev->mtu;
if (unlikely(packet_length(skb) > mtu && !skb_is_gso(skb))) {
net_warn_ratelimited("%s: dropped over-mtu packet: %d > %d\n",
vport->dev->name,
packet_length(skb), mtu);
vport->dev->stats.tx_errors++;
goto drop;
}
skb->dev = vport->dev;
vport->ops->send(skb);
return;
drop:
kfree_skb(skb);
}
...@@ -153,7 +153,7 @@ struct vport_ops { ...@@ -153,7 +153,7 @@ struct vport_ops {
int (*set_options)(struct vport *, struct nlattr *); int (*set_options)(struct vport *, struct nlattr *);
int (*get_options)(const struct vport *, struct sk_buff *); int (*get_options)(const struct vport *, struct sk_buff *);
void (*send)(struct vport *, struct sk_buff *); netdev_tx_t (*send) (struct sk_buff *skb);
int (*get_egress_tun_info)(struct vport *, struct sk_buff *, int (*get_egress_tun_info)(struct vport *, struct sk_buff *,
struct dp_upcall_info *upcall); struct dp_upcall_info *upcall);
...@@ -234,9 +234,6 @@ static inline struct rtable *ovs_tunnel_route_lookup(struct net *net, ...@@ -234,9 +234,6 @@ static inline struct rtable *ovs_tunnel_route_lookup(struct net *net,
return rt; return rt;
} }
static inline void ovs_vport_send(struct vport *vport, struct sk_buff *skb) void ovs_vport_send(struct vport *vport, struct sk_buff *skb);
{
vport->ops->send(vport, skb);
}
#endif /* vport.h */ #endif /* vport.h */
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment