From 38aeef15d85c8f7a590ebf3daaeb3f4d72d414a4 Mon Sep 17 00:00:00 2001 From: Jesse Gross Date: Mon, 12 Jul 2010 13:27:57 -0700 Subject: [PATCH] datapath: Move over-MTU checking into vport_send(). We currently check for packets that are over the MTU in do_output(). There is a one-to-one correlation between this function and vport_send() so move the MTU check there for consistency with other error checking. --- datapath/actions.c | 16 ---------------- datapath/vport.c | 41 +++++++++++++++++++++++++++++++++-------- 2 files changed, 33 insertions(+), 24 deletions(-) diff --git a/datapath/actions.c b/datapath/actions.c index f7e51d92..131548c7 100644 --- a/datapath/actions.c +++ b/datapath/actions.c @@ -347,19 +347,10 @@ set_tp_port(struct sk_buff *skb, struct odp_flow_key *key, return skb; } -static inline unsigned packet_length(const struct sk_buff *skb) -{ - unsigned length = skb->len - ETH_HLEN; - if (skb->protocol == htons(ETH_P_8021Q)) - length -= VLAN_HLEN; - return length; -} - static void do_output(struct datapath *dp, struct sk_buff *skb, int out_port) { struct dp_port *p; - int mtu; if (!skb) goto error; @@ -368,13 +359,6 @@ do_output(struct datapath *dp, struct sk_buff *skb, int out_port) if (!p) goto error; - mtu = vport_get_mtu(p->vport); - if (packet_length(skb) > mtu && !skb_is_gso(skb)) { - printk(KERN_WARNING "%s: dropped over-mtu packet: %d > %d\n", - dp_name(dp), packet_length(skb), mtu); - goto error; - } - vport_send(p->vport, skb); return; diff --git a/datapath/vport.c b/datapath/vport.c index 13039505..ef07a091 100644 --- a/datapath/vport.c +++ b/datapath/vport.c @@ -9,6 +9,7 @@ #include #include #include +#include #include #include #include @@ -1275,6 +1276,17 @@ vport_receive(struct vport *vport, struct sk_buff *skb) dp_process_received_packet(dp_port, skb); } +static inline unsigned +packet_length(const struct sk_buff *skb) +{ + unsigned length = skb->len - ETH_HLEN; + + if (skb->protocol == htons(ETH_P_8021Q)) + length -= VLAN_HLEN; + + return length; +} + /** * vport_send - send a packet on a device * @@ -1288,25 +1300,28 @@ int vport_send(struct vport *vport, struct sk_buff *skb) { int *loop_count; + int mtu; int sent; loop_count = &per_cpu_ptr(vport_loop_counter, get_cpu())->count[!!in_interrupt()]; (*loop_count)++; - if (likely(*loop_count <= VPORT_MAX_LOOPS)) { - sent = vport->ops->send(vport, skb); - } else { + if (unlikely(*loop_count > VPORT_MAX_LOOPS)) { if (net_ratelimit()) printk(KERN_WARNING "%s: dropping packet that has looped more than %d times\n", dp_name(vport_get_dp_port(vport)->dp), VPORT_MAX_LOOPS); + goto error; + } - sent = 0; - kfree_skb(skb); - vport_record_error(vport, VPORT_E_TX_DROPPED); + mtu = vport_get_mtu(vport); + if (unlikely(packet_length(skb) > mtu && !skb_is_gso(skb))) { + if (net_ratelimit()) + printk(KERN_WARNING "%s: dropped over-mtu packet: %d > %d\n", + dp_name(vport_get_dp_port(vport)->dp), packet_length(skb), mtu); + goto error; } - (*loop_count)--; - put_cpu(); + sent = vport->ops->send(vport, skb); if (vport->ops->flags & VPORT_F_GEN_STATS && sent > 0) { struct vport_percpu_stats *stats; @@ -1320,6 +1335,16 @@ vport_send(struct vport *vport, struct sk_buff *skb) local_bh_enable(); } + goto out; + +error: + sent = 0; + kfree_skb(skb); + vport_record_error(vport, VPORT_E_TX_DROPPED); +out: + (*loop_count)--; + put_cpu(); + return sent; } -- 2.30.2