Factor out code for composing benign packets.
authorBen Pfaff <blp@nicira.com>
Tue, 15 Sep 2009 22:22:17 +0000 (15:22 -0700)
committerBen Pfaff <blp@nicira.com>
Wed, 16 Sep 2009 22:12:27 +0000 (15:12 -0700)
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
lib/packets.c [new file with mode: 0644]
lib/packets.h
vswitchd/bridge.c

index 04850d70eb3a950b5bdf70fbb6ceb52fb83a8f22..2474dad8d690b8214ac9821c6dd806c7a72bc15b 100644 (file)
@@ -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 (file)
index 0000000..0547791
--- /dev/null
@@ -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);
+}
index d12cc0403e417eb62222e25b41c281dfa8ebddae..4595c12cba74ec492944c895c7d43f0f12274587 100644 (file)
@@ -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];
index c39670a3b2a0d90f01a470e26cf8fa40479a9fd4..a00799a11b66ab09a114831d741a08dca515da39 100644 (file)
@@ -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);