[ovs-dev] [PATCH] ofproto-dpif: Use send_packet() instead of netdev_send().

Jesse Gross jesse at nicira.com
Sun Oct 23 02:55:24 UTC 2011


netdev_send() directly sends a packet using Linux mechanisms, skipping
our kernel module. Several upper layer abstractions are built on top of
the kernel module, so this means that we loose stats, sFlow, etc. on
these packets. This changes bonding, LACP, and STP to use send_packet()
as CFM does, which uses the standard kernel mechanisms and provides a
single place that needs to be updated.
---
 lib/bond.c             |    7 ++++---
 lib/bond.h             |    3 ++-
 ofproto/ofproto-dpif.c |   33 +++++++++++++++++++--------------
 3 files changed, 25 insertions(+), 18 deletions(-)

diff --git a/lib/bond.c b/lib/bond.c
index 73ee814..60c36d4 100644
--- a/lib/bond.c
+++ b/lib/bond.c
@@ -511,7 +511,9 @@ bond_should_send_learning_packets(struct bond *bond)
 int
 bond_send_learning_packet(struct bond *bond,
                           const uint8_t eth_src[ETH_ADDR_LEN],
-                          uint16_t vlan)
+                          uint16_t vlan,
+                          int (*send_cb)(void *port_aux,
+                                         struct ofpbuf *packet))
 {
     struct bond_slave *slave;
     struct ofpbuf packet;
@@ -534,8 +536,7 @@ bond_send_learning_packet(struct bond *bond,
     if (vlan) {
         eth_push_vlan(&packet, htons(vlan));
     }
-    error = netdev_send(slave->netdev, &packet);
-    ofpbuf_uninit(&packet);
+    error = send_cb(slave->aux, &packet);
 
     return error;
 }
diff --git a/lib/bond.h b/lib/bond.h
index f955432..9e87db9 100644
--- a/lib/bond.h
+++ b/lib/bond.h
@@ -77,7 +77,8 @@ void bond_slave_set_may_enable(struct bond *, void *slave_, bool may_enable);
 bool bond_should_send_learning_packets(struct bond *);
 int bond_send_learning_packet(struct bond *,
                               const uint8_t eth_src[ETH_ADDR_LEN],
-                              uint16_t vlan);
+                              uint16_t vlan,
+                              int (*send_cb)(void *port_aux, struct ofpbuf *packet));
 
 /* Packet processing. */
 enum bond_verdict {
diff --git a/ofproto/ofproto-dpif.c b/ofproto/ofproto-dpif.c
index 4de5a4e..669c749 100644
--- a/ofproto/ofproto-dpif.c
+++ b/ofproto/ofproto-dpif.c
@@ -949,13 +949,8 @@ send_bpdu_cb(struct ofpbuf *pkt, int port_num, void *ofproto_)
             VLOG_WARN_RL(&rl, "%s: cannot send BPDU on port %d "
                          "with unknown MAC", ofproto->up.name, port_num);
         } else {
-            int error = netdev_send(ofport->up.netdev, pkt);
-            if (error) {
-                VLOG_WARN_RL(&rl, "%s: sending BPDU on port %s failed (%s)",
-                             ofproto->up.name,
-                             netdev_get_name(ofport->up.netdev),
-                             strerror(error));
-            }
+            send_packet(ofproto_dpif_cast(ofport->up.ofproto),
+                        ofport->odp_port, pkt);
         }
     }
     ofpbuf_delete(pkt);
@@ -1549,12 +1544,8 @@ send_pdu_cb(void *port_, const void *pdu, size_t pdu_size)
                                  pdu_size);
         memcpy(packet_pdu, pdu, pdu_size);
 
-        error = netdev_send(port->up.netdev, &packet);
-        if (error) {
-            VLOG_WARN_RL(&rl, "port %s: sending LACP PDU on iface %s failed "
-                         "(%s)", port->bundle->name,
-                         netdev_get_name(port->up.netdev), strerror(error));
-        }
+        send_packet(ofproto_dpif_cast(port->up.ofproto), port->odp_port,
+                    &packet);
         ofpbuf_uninit(&packet);
     } else {
         VLOG_ERR_RL(&rl, "port %s: cannot obtain Ethernet address of iface "
@@ -1563,6 +1554,19 @@ send_pdu_cb(void *port_, const void *pdu, size_t pdu_size)
     }
 }
 
+static int
+send_bond_cb(void *port_, struct ofpbuf *packet)
+{
+    struct ofport_dpif *port = port_;
+    int error;
+
+    error = send_packet(ofproto_dpif_cast(port->up.ofproto),
+                        port->odp_port, packet);
+    ofpbuf_uninit(packet);
+
+    return error;
+} 
+
 static void
 bundle_send_learning_packets(struct ofbundle *bundle)
 {
@@ -1573,7 +1577,8 @@ bundle_send_learning_packets(struct ofbundle *bundle)
     error = n_packets = n_errors = 0;
     LIST_FOR_EACH (e, lru_node, &ofproto->ml->lrus) {
         if (e->port.p != bundle) {
-            int ret = bond_send_learning_packet(bundle->bond, e->mac, e->vlan);
+            int ret = bond_send_learning_packet(bundle->bond, e->mac, e->vlan,
+                                                send_bond_cb);
             if (ret) {
                 error = ret;
                 n_errors++;
-- 
1.7.5.4




More information about the dev mailing list