#include <string.h>
#include "hash.h"
#include "ofpbuf.h"
-#include "openflow.h"
+#include "openflow/openflow.h"
#include "packets.h"
#include "vlog.h"
return ofpbuf_try_pull(packet, UDP_HEADER_LEN);
}
+static struct icmp_header *
+pull_icmp(struct ofpbuf *packet)
+{
+ return ofpbuf_try_pull(packet, ICMP_HEADER_LEN);
+}
+
static struct eth_header *
pull_eth(struct ofpbuf *packet)
{
struct eth_header *eth;
int retval = 0;
- if (b.size < ETH_TOTAL_MIN) {
- /* This message is not too useful since there are various ways that we
- * can end up with runt frames, e.g. frames that only ever passed
- * through virtual network devices and never touched a physical
- * Ethernet. */
- static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(5, 60);
- VLOG_DBG_RL(&rl, "packet length %zu less than minimum size %d",
- b.size, ETH_TOTAL_MIN);
- }
-
memset(flow, 0, sizeof *flow);
flow->dl_vlan = htons(OFP_VLAN_NONE);
flow->in_port = htons(in_port);
struct vlan_header *vh = pull_vlan(&b);
if (vh) {
flow->dl_type = vh->vlan_next_type;
- flow->dl_vlan = vh->vlan_tci & htons(VLAN_VID);
+ flow->dl_vlan = vh->vlan_tci & htons(VLAN_VID_MASK);
}
}
memcpy(flow->dl_src, eth->eth_src, ETH_ADDR_LEN);
* this packet has an L4 header. */
flow->nw_proto = 0;
}
+ } else if (flow->nw_proto == IP_TYPE_ICMP) {
+ const struct icmp_header *icmp = pull_icmp(&b);
+ if (icmp) {
+ flow->icmp_type = htons(icmp->icmp_type);
+ flow->icmp_code = htons(icmp->icmp_code);
+ packet->l7 = b.data;
+ } else {
+ /* Avoid tricking other code into thinking that
+ * this packet has an L4 header. */
+ flow->nw_proto = 0;
+ }
}
} else {
retval = 1;