From b9e8b45a3936441bd0fd1fd156cae498bf72cac8 Mon Sep 17 00:00:00 2001 From: Ben Pfaff Date: Tue, 15 Sep 2009 15:22:17 -0700 Subject: [PATCH] Factor out code for composing benign packets. 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 04850d70..2474dad8 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 00000000..0547791a --- /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 +#include "packets.h" +#include +#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 d12cc040..4595c12c 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 c39670a3..a00799a1 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); -- 2.30.2