From: Ben Pfaff Date: Fri, 28 Mar 2008 00:34:05 +0000 (-0700) Subject: Set l4 pointer properly in buffers that contain IP options. X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=18f6c89fb07488ae331bc69f523d07b368dfff4d;p=openvswitch Set l4 pointer properly in buffers that contain IP options. The important part of this change is handling of IP options. The rest is intended to ensure that packet->l3 and packet->l4 never point outside the valid range of a packet in the presence of a minimum-length Ethernet frame. Other code (particularly in forward.c) assumes that if the IP protocol is TCP or UDP, then packet->l4 points to a tcp_header or udp_header. Whether this is a good idea is debatable--it probably warrants clean-up, at least--but that what's there now. --- diff --git a/lib/flow.c b/lib/flow.c index 2ba560c9..ab065acb 100644 --- a/lib/flow.c +++ b/lib/flow.c @@ -72,18 +72,25 @@ flow_extract(struct buffer *packet, uint16_t in_port, struct flow *flow) if (flow->dl_type == htons(ETH_TYPE_IP)) { const struct ip_header *nh = buffer_at(&b, 0, sizeof *nh); if (nh) { + int ip_len = IP_IHL(nh->ip_ihl_ver) * 4; + if (ip_len < IP_HEADER_LEN) { + return; + } + flow->nw_src = nh->ip_src; flow->nw_dst = nh->ip_dst; flow->nw_proto = nh->ip_proto; - packet->l4 = b.data + IP_HEADER_LEN; if (flow->nw_proto == IP_TYPE_TCP || flow->nw_proto == IP_TYPE_UDP) { - int udp_ofs = IP_IHL(nh->ip_ihl_ver) * 4; - const struct udp_header *th - = buffer_at(&b, udp_ofs, sizeof *th); + const struct udp_header *th; + th = packet->l4 = buffer_at(&b, ip_len, sizeof *th); if (th) { flow->tp_src = th->udp_src; flow->tp_dst = th->udp_dst; + } else { + /* Avoid tricking other code into thinking that this + * packet has an L4 header. */ + flow->nw_proto = 0; } } }