[ovs-dev] [PATCH v2 1/3] Factor out code for composing benign packets.

Ben Pfaff blp at nicira.com
Tue Sep 15 22:48:13 UTC 2009


The bonding code in vswitch sends out gratuitous learning packets that
are supposed to teach switches but not cause anything else to happen on
the network.  Some upcoming code wants to synthesize packets with similar
properties, so factor this code into a new function so that it can be
used in both places.
---
 lib/automake.mk   |    1 +
 lib/packets.c     |   58 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 lib/packets.h     |    7 ++++++
 vswitchd/bridge.c |   22 +------------------
 4 files changed, 68 insertions(+), 20 deletions(-)
 create mode 100644 lib/packets.c

diff --git a/lib/automake.mk b/lib/automake.mk
index 04850d7..2474dad 100644
--- a/lib/automake.mk
+++ b/lib/automake.mk
@@ -60,6 +60,7 @@ lib_libopenvswitch_a_SOURCES = \
 	lib/ofp-print.h \
 	lib/ofpbuf.c \
 	lib/ofpbuf.h \
+	lib/packets.c \
 	lib/packets.h \
 	lib/pcap.c \
 	lib/pcap.h \
diff --git a/lib/packets.c b/lib/packets.c
new file mode 100644
index 0000000..0547791
--- /dev/null
+++ b/lib/packets.c
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2009 Nicira Networks.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <config.h>
+#include "packets.h"
+#include <netinet/in.h>
+#include "ofpbuf.h"
+
+/* Fills 'b' with an 802.2 SNAP packet with Ethernet source address 'eth_src',
+ * the Nicira OUI as SNAP organization and 'snap_type' as SNAP type.  The text
+ * string in 'tag' is enclosed as the packet payload.
+ *
+ * This function is used by Open vSwitch to compose packets in cases where
+ * context is important but content doesn't (or shouldn't) matter.  For this
+ * purpose, 'snap_type' should be a random number and 'tag' should be an
+ * English phrase that explains the purpose of the packet.  (The English phrase
+ * gives hapless admins running Wireshark the opportunity to figure out what's
+ * going on.) */
+void
+compose_benign_packet(struct ofpbuf *b, const char *tag, uint16_t snap_type,
+                      const uint8_t eth_src[ETH_ADDR_LEN])
+{
+    struct eth_header *eth;
+    struct llc_snap_header *llc_snap;
+
+    /* Compose basic packet structure.  (We need the payload size to stick into
+     * the 802.2 header.) */
+    ofpbuf_clear(b);
+    eth = ofpbuf_put_zeros(b, ETH_HEADER_LEN);
+    llc_snap = ofpbuf_put_zeros(b, LLC_SNAP_HEADER_LEN);
+    ofpbuf_put(b, tag, strlen(tag) + 1); /* Includes null byte. */
+    ofpbuf_put(b, eth_src, ETH_ADDR_LEN);
+
+    /* Compose 802.2 header. */
+    memcpy(eth->eth_dst, eth_addr_broadcast, ETH_ADDR_LEN);
+    memcpy(eth->eth_src, eth_src, ETH_ADDR_LEN);
+    eth->eth_type = htons(b->size - ETH_HEADER_LEN);
+
+    /* Compose LLC, SNAP headers. */
+    llc_snap->llc.llc_dsap = LLC_DSAP_SNAP;
+    llc_snap->llc.llc_ssap = LLC_SSAP_SNAP;
+    llc_snap->llc.llc_cntl = LLC_CNTL_SNAP;
+    memcpy(llc_snap->snap.snap_org, "\x00\x23\x20", 3);
+    llc_snap->snap.snap_type = htons(snap_type);
+}
diff --git a/lib/packets.h b/lib/packets.h
index d12cc04..4595c12 100644
--- a/lib/packets.h
+++ b/lib/packets.h
@@ -13,6 +13,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+
 #ifndef PACKETS_H
 #define PACKETS_H 1
 
@@ -23,6 +24,8 @@
 #include "random.h"
 #include "util.h"
 
+struct ofpbuf;
+
 #define ETH_ADDR_LEN           6
 
 static const uint8_t eth_addr_broadcast[ETH_ADDR_LEN] UNUSED
@@ -98,6 +101,10 @@ static inline bool eth_addr_is_reserved(const uint8_t ea[ETH_ADDR_LEN])
             && (ea[5] & 0xf0) == 0x00);
 }
 
+void compose_benign_packet(struct ofpbuf *, const char *tag,
+                           uint16_t snap_type,
+                           const uint8_t eth_src[ETH_ADDR_LEN]);
+
 /* Example:
  *
  * uint8_t mac[ETH_ADDR_LEN];
diff --git a/vswitchd/bridge.c b/vswitchd/bridge.c
index c39670a..a00799a 100644
--- a/vswitchd/bridge.c
+++ b/vswitchd/bridge.c
@@ -2351,10 +2351,7 @@ bond_send_learning_packets(struct port *port)
     ofpbuf_init(&packet, 128);
     error = n_packets = n_errors = 0;
     LIST_FOR_EACH (e, struct mac_entry, lru_node, &br->ml->lrus) {
-        static const char s[] = "Open vSwitch Bond Failover";
         union ofp_action actions[2], *a;
-        struct eth_header *eth;
-        struct llc_snap_header *llc_snap;
         uint16_t dp_ifidx;
         tag_type tags = 0;
         flow_t flow;
@@ -2365,23 +2362,6 @@ bond_send_learning_packets(struct port *port)
             continue;
         }
 
-        /* Compose packet to send. */
-        ofpbuf_clear(&packet);
-        eth = ofpbuf_put_zeros(&packet, ETH_HEADER_LEN);
-        llc_snap = ofpbuf_put_zeros(&packet, LLC_SNAP_HEADER_LEN);
-        ofpbuf_put(&packet, s, sizeof s); /* Includes null byte. */
-        ofpbuf_put(&packet, e->mac, ETH_ADDR_LEN);
-
-        memcpy(eth->eth_dst, eth_addr_broadcast, ETH_ADDR_LEN);
-        memcpy(eth->eth_src, e->mac, ETH_ADDR_LEN);
-        eth->eth_type = htons(packet.size - ETH_HEADER_LEN);
-
-        llc_snap->llc.llc_dsap = LLC_DSAP_SNAP;
-        llc_snap->llc.llc_ssap = LLC_SSAP_SNAP;
-        llc_snap->llc.llc_cntl = LLC_CNTL_SNAP;
-        memcpy(llc_snap->snap.snap_org, "\x00\x23\x20", 3);
-        llc_snap->snap.snap_type = htons(0xf177); /* Random number. */
-
         /* Compose actions. */
         memset(actions, 0, sizeof actions);
         a = actions;
@@ -2398,6 +2378,8 @@ bond_send_learning_packets(struct port *port)
 
         /* Send packet. */
         n_packets++;
+        compose_benign_packet(&packet, "Open vSwitch Bond Failover", 0xf177,
+                              e->mac);
         flow_extract(&packet, ODPP_NONE, &flow);
         retval = ofproto_send_packet(br->ofproto, &flow, actions, a - actions,
                                      &packet);
-- 
1.6.3.3





More information about the dev mailing list